xref: /freebsd/sys/amd64/amd64/xen-locore.S (revision 6419bb52)
1/*-
2 * Copyright (c) 2003 Peter Wemm <peter@FreeBSD.org>
3 * Copyright (c) 2011-2012 Spectra Logic Corporation
4 * Copyright (c) 2013 Roger Pau Monne <royger@FreeBSD.org>
5 * All rights reserved.
6 *
7 * This software was developed by Cherry G. Mathew <cherry@zyx.in>
8 * under sponsorship from Spectra Logic Corporation.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 * $FreeBSD$
32 */
33
34#include <machine/asmacros.h>
35#include <machine/psl.h>
36#include <machine/pmap.h>
37#include <machine/specialreg.h>
38
39#include <xen/xen-os.h>
40#define __ASSEMBLY__
41#include <xen/interface/elfnote.h>
42
43#include "assym.inc"
44
45#define	VTOP(x)		((x) - KERNBASE)
46#define	ENTRY_SIZE	8 /* sizeof(uint64_t) */
47
48#define	GDT_CODE	0x08
49#define	GDT_DATA	0x10
50
51.section __xen_guest
52	ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS,       .asciz, "FreeBSD")
53	ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION,  .asciz, __XSTRING(__FreeBSD_version))
54	ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION,    .asciz, "xen-3.0")
55	ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE,      .quad,  KERNBASE)
56	ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET,   .quad,  0)
57	ELFNOTE(Xen, XEN_ELFNOTE_ENTRY,          .quad,  xen_start)
58	ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .quad,	 hypercall_page)
59	ELFNOTE(Xen, XEN_ELFNOTE_HV_START_LOW,   .quad,  HYPERVISOR_VIRT_START)
60	ELFNOTE(Xen, XEN_ELFNOTE_FEATURES,       .asciz, "writable_descriptor_tables|auto_translated_physmap|supervisor_mode_kernel|hvm_callback_vector")
61	ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE,       .asciz, "yes")
62	ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID,   .long,  PG_V, PG_V)
63	ELFNOTE(Xen, XEN_ELFNOTE_LOADER,         .asciz, "generic")
64	ELFNOTE(Xen, XEN_ELFNOTE_SUSPEND_CANCEL, .long,  0)
65	ELFNOTE(Xen, XEN_ELFNOTE_BSD_SYMTAB,	 .asciz, "yes")
66	/* For PVHv2 support. */
67	ELFNOTE(Xen, XEN_ELFNOTE_PHYS32_ENTRY,   .long,  VTOP(xen_start32))
68
69	.text
70.p2align PAGE_SHIFT, 0x90	/* Hypercall_page needs to be PAGE aligned */
71
72NON_GPROF_ENTRY(hypercall_page)
73	.skip	0x1000, 0x90	/* Fill with "nop"s */
74
75/* Legacy PVH entry point, to be removed. */
76NON_GPROF_ENTRY(xen_start)
77	/* Don't trust what the loader gives for rflags. */
78	pushq	$PSL_KERNEL
79	popfq
80
81	/* Parameters for the xen init function */
82	movq	%rsi, %rdi		/* shared_info (arg 1) */
83	movq	%rsp, %rsi		/* xenstack    (arg 2) */
84
85	/* Use our own stack */
86	movq	$bootstack,%rsp
87	xorl	%ebp, %ebp
88
89	/* u_int64_t hammer_time_xen(start_info_t *si, u_int64_t xenstack); */
90	call	hammer_time_xen_legacy
91	movq	%rax, %rsp		/* set up kstack for mi_startup() */
92	call	mi_startup		/* autoconfiguration, mountroot etc */
93
94	/* NOTREACHED */
950:	hlt
96	jmp 	0b
97
98/* PVH entry point. */
99	.code32
100NON_GPROF_ENTRY(xen_start32)
101
102	/* Load flat GDT */
103	movl	$VTOP(gdtdesc32), %eax
104	lgdt	(%eax)
105	jmp	$GDT_CODE, $VTOP(reload_cs)
106
107reload_cs:
108	movw	$GDT_DATA, %ax
109	movw	%ax, %ds
110	movw	%ax, %es
111	movw	%ax, %ss
112
113	movl	$VTOP(bootstack), %esp
114
115	/* Don't trust what the loader gives for eflags. */
116	pushl	$PSL_KERNEL
117	popfl
118
119	/*
120	 * Create the page tables.
121	 * The first 1GB is mapped using 2MB entries.
122	 */
123	movl	$0, %eax
124pgbuild:
125	cmp	$(PAGE_SIZE/ENTRY_SIZE), %eax
126	jae	pgbuild_done
127
128	/* PT4[i] = VTOP(&PT3[0]) | PG_V | PG_RW | PG_U */
129	movl	$VTOP(PT4), %ecx
130	movl	$VTOP(PT3), %edx
131	orl	$(PG_V | PG_RW | PG_U), %edx
132	movl	%edx, (%ecx,%eax,ENTRY_SIZE)
133
134	/* PT3[i] = VTOP(&PT2[0]) | PG_V | PG_RW | PG_U */
135	movl	$VTOP(PT3), %ecx
136	movl	$VTOP(PT2), %edx
137	orl	$(PG_V | PG_RW | PG_U), %edx
138	movl	%edx, (%ecx,%eax,ENTRY_SIZE)
139
140	/* PT2[i] = i * 2MiB | PG_V | PG_RW | PG_PS | PG_U */
141	movl	$VTOP(PT2), %ecx
142	movl	%eax, %edx
143	shll	$PDRSHIFT, %edx
144	orl	$(PG_V | PG_RW | PG_PS | PG_U), %edx
145	movl	%edx, (%ecx,%eax,ENTRY_SIZE)
146
147	inc	%eax
148	jmp	pgbuild
149
150pgbuild_done:
151	/* Turn on EFER.LME */
152	movl	$MSR_EFER, %ecx
153	rdmsr
154	orl	$EFER_LME, %eax
155	wrmsr
156
157	/* Turn on PAE */
158	movl	%cr4, %eax
159	orl	$CR4_PAE, %eax
160	movl	%eax, %cr4
161
162	/* Set %cr3 for PT4 */
163	movl	$VTOP(PT4), %eax
164	movl	%eax, %cr3
165
166	/* Turn on paging (implicitly sets EFER.LMA) */
167	movl	%cr0, %eax
168	orl	$CR0_PG, %eax
169	movl	%eax, %cr0
170
171	/* Now we're in compatibility mode. Set %cs for long mode */
172	movl	$VTOP(gdtdesc), %eax
173	lgdt	(%eax)
174	ljmp	$GDT_CODE, $VTOP(longmode)
175
176	.code64
177longmode:
178	/* We're still running V=P, jump to entry point */
179	movq	$bootstack, %rsp
180	movq	$start_kernel, %rax
181	pushq	%rax
182	ret
183
184start_kernel:
185	/*
186	 * Pass %ebx as the argument to hammer_time_xen, it contains
187	 * the startup info.
188	 */
189	movq	%rbx, %rdi
190	call	hammer_time_xen
191	movq	%rax, %rsp
192	call	mi_startup
193
194	/* NOTREACHED */
1950:	hlt
196	jmp 	0b
197
198/* Space for initial page tables */
199	.data
200	.p2align 12,0x40
201PT4:
202	.space	0x1000
203PT3:
204	.space	0x1000
205PT2:
206	.space	0x1000
207
208/* 64bit GDT */
209gdtdesc:
210	.word	gdtend - gdt - 1
211	.long	VTOP(gdt)		# low
212	.long	0			# high
213gdt:
214	.long	0			# null descriptor
215	.long	0
216	.long	0x00000000		# %cs
217	.long	0x00209800
218	.long	0x00000000		# %ds
219	.long	0x00008000
220gdtend:
221
222/* 32bit GDT */
223gdtdesc32:
224	.word	gdt32end - gdt32 - 1
225	.long	VTOP(gdt32)
226	.long	0
227gdt32:
228	.long	0			# null descriptor
229	.long	0
230	.long	0x0000ffff		# %cs
231	.long	0x00cf9a00
232	.long	0x0000ffff		# %ds, %es, %ss
233	.long	0x00cf9200
234gdt32end:
235