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
72 NON_GPROF_ENTRY(hypercall_page)
73 .skip 0x1000, 0x90 /* Fill with "nop"s */
74
75 /* Legacy PVH entry point, to be removed. */
76 NON_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 */
95 0: hlt
96 jmp 0b
97
98 /* PVH entry point. */
99 .code32
100 NON_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
107 reload_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
124 pgbuild:
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
150 pgbuild_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
177 longmode:
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
184 start_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 */
195 0: hlt
196 jmp 0b
197
198 /* Space for initial page tables */
199 .data
200 .p2align 12,0x40
201 PT4:
202 .space 0x1000
203 PT3:
204 .space 0x1000
205 PT2:
206 .space 0x1000
207
208 /* 64bit GDT */
209 gdtdesc:
210 .word gdtend - gdt
211 .long VTOP(gdt) # low
212 .long 0 # high
213 gdt:
214 .long 0 # null descriptor
215 .long 0
216 .long 0x00000000 # %cs
217 .long 0x00209800
218 .long 0x00000000 # %ds
219 .long 0x00008000
220 gdtend:
221
222 /* 32bit GDT */
223 gdtdesc32:
224 .word gdt32end - gdt32
225 .long VTOP(gdt32)
226 .long 0
227 gdt32:
228 .long 0 # null descriptor
229 .long 0
230 .long 0x0000ffff # %cs
231 .long 0x00cf9a00
232 .long 0x0000ffff # %ds, %es, %ss
233 .long 0x00cf9200
234 gdt32end:
Cache object: b4928fd67944806b00327a4bfef2236a
|