FreeBSD/Linux Kernel Cross Reference
sys/i386/xen/locore.s
1 /*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * William Jolitz.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 4. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * from: @(#)locore.s 7.3 (Berkeley) 5/13/91
33 * $FreeBSD: releng/8.0/sys/i386/xen/locore.s 184039 2008-10-19 01:23:30Z kmacy $
34 *
35 * originally from: locore.s, by William F. Jolitz
36 *
37 * Substantially rewritten by David Greenman, Rod Grimes,
38 * Bruce Evans, Wolfgang Solfrank, Poul-Henning Kamp
39 * and many others.
40 */
41
42 #include "opt_bootp.h"
43 #include "opt_compat.h"
44 #include "opt_nfsroot.h"
45 #include "opt_global.h"
46 #include "opt_pmap.h"
47
48 #include <sys/syscall.h>
49 #include <sys/reboot.h>
50
51 #include <machine/asmacros.h>
52 #include <machine/cputypes.h>
53 #include <machine/psl.h>
54 #include <machine/pmap.h>
55 #include <machine/specialreg.h>
56
57 #define __ASSEMBLY__
58 #include <xen/interface/elfnote.h>
59
60 /* The defines below have been lifted out of <machine/xen-public/arch-x86_32.h> */
61 #define FLAT_RING1_CS 0xe019 /* GDT index 259 */
62 #define FLAT_RING1_DS 0xe021 /* GDT index 260 */
63 #define KERNEL_CS FLAT_RING1_CS
64 #define KERNEL_DS FLAT_RING1_DS
65
66 #include "assym.s"
67
68 .section __xen_guest
69 .ascii "LOADER=generic,GUEST_OS=freebsd,GUEST_VER=7.0,XEN_VER=xen-3.0,BSD_SYMTAB,VIRT_BASE=0xc0000000"
70 .byte 0
71
72 ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz, "FreeBSD")
73 ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz, "HEAD")
74 ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz, "xen-3.0")
75 ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE, .long, KERNBASE)
76 ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET, .long, KERNBASE)
77 ELFNOTE(Xen, XEN_ELFNOTE_ENTRY, .long, btext)
78 ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .long, hypercall_page)
79 ELFNOTE(Xen, XEN_ELFNOTE_HV_START_LOW, .long, HYPERVISOR_VIRT_START)
80 #if 0
81 ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .asciz, "writable_page_tables|writable_descriptor_tables|auto_translated_physmap|pae_pgdir_above_4gb|supervisor_mode_kernel")
82 #endif
83 ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .asciz, "writable_page_tables|supervisor_mode_kernel|writable_descriptor_tables")
84
85 #ifdef PAE
86 ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz, "yes")
87 ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID, .long, PG_V, PG_V)
88 #else
89 ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz, "no")
90 ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID, .long, PG_V, PG_V)
91 #endif
92 ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz, "generic")
93 ELFNOTE(Xen, XEN_ELFNOTE_SUSPEND_CANCEL, .long, 1)
94
95
96
97 /*
98 * XXX
99 *
100 * Note: This version greatly munged to avoid various assembler errors
101 * that may be fixed in newer versions of gas. Perhaps newer versions
102 * will have more pleasant appearance.
103 */
104
105 /*
106 * PTmap is recursive pagemap at top of virtual address space.
107 * Within PTmap, the page directory can be found (third indirection).
108 */
109 .globl PTmap,PTD,PTDpde
110 .set PTmap,(PTDPTDI << PDRSHIFT)
111 .set PTD,PTmap + (PTDPTDI * PAGE_SIZE)
112 .set PTDpde,PTD + (PTDPTDI * PDESIZE)
113
114 /*
115 * Compiled KERNBASE location and the kernel load address
116 */
117 .globl kernbase
118 .set kernbase,KERNBASE
119 .globl kernload
120 .set kernload,KERNLOAD
121
122 /*
123 * Globals
124 */
125 .data
126 ALIGN_DATA /* just to be sure */
127
128 .space 0x2000 /* space for tmpstk - temporary stack */
129 tmpstk:
130
131 .globl bootinfo
132 bootinfo: .space BOOTINFO_SIZE /* bootinfo that we can handle */
133
134 .globl KERNend
135 KERNend: .long 0 /* phys addr end of kernel (just after bss) */
136 .globl physfree
137 physfree: .long 0 /* phys addr of next free page */
138
139 .globl IdlePTD
140 IdlePTD: .long 0 /* phys addr of kernel PTD */
141
142 #ifdef PAE
143 .globl IdlePDPT
144 IdlePDPT: .long 0 /* phys addr of kernel PDPT */
145 #endif
146
147 #ifdef SMP
148 .globl KPTphys
149 #endif
150 KPTphys: .long 0 /* phys addr of kernel page tables */
151 #ifdef SMP
152 .globl gdtset
153 #endif
154 gdtset: .long 0 /* GDT is valid */
155
156 .globl proc0kstack
157 proc0uarea: .long 0 /* address of proc 0 uarea (unused)*/
158 proc0kstack: .long 0 /* address of proc 0 kstack space */
159 p0upa: .long 0 /* phys addr of proc0 UAREA (unused) */
160 p0kpa: .long 0 /* phys addr of proc0's STACK */
161
162 vm86phystk: .long 0 /* PA of vm86/bios stack */
163
164 .globl vm86paddr, vm86pa
165 vm86paddr: .long 0 /* address of vm86 region */
166 vm86pa: .long 0 /* phys addr of vm86 region */
167
168 #ifdef PC98
169 .globl pc98_system_parameter
170 pc98_system_parameter:
171 .space 0x240
172 #endif
173
174 .globl avail_space
175 avail_space: .long 0
176
177 /**********************************************************************
178 *
179 * Some handy macros
180 *
181 */
182
183 /*
184 * We're already in protected mode, so no remapping is needed.
185 */
186 #define R(foo) (foo)
187
188 #define ALLOCPAGES(foo) \
189 movl R(physfree), %esi ; \
190 movl $((foo)*PAGE_SIZE), %eax ; \
191 addl %esi, %eax ; \
192 movl %eax, R(physfree) ; \
193 movl %esi, %edi ; \
194 movl $((foo)*PAGE_SIZE),%ecx ; \
195 xorl %eax,%eax ; \
196 cld ; \
197 rep ; \
198 stosb
199
200 /*
201 * fillkpt
202 * eax = page frame address
203 * ebx = index into page table
204 * ecx = how many pages to map
205 * base = base address of page dir/table
206 * prot = protection bits
207 */
208 #define fillkpt(base, prot) \
209 shll $PTESHIFT,%ebx ; \
210 addl base,%ebx ; \
211 orl $PG_V,%eax ; \
212 orl prot,%eax ; \
213 1: movl %eax,(%ebx) ; \
214 addl $PAGE_SIZE,%eax ; /* increment physical address */ \
215 addl $PTESIZE,%ebx ; /* next pte */ \
216 loop 1b
217
218 /*
219 * fillkptphys(prot)
220 * eax = physical address
221 * ecx = how many pages to map
222 * prot = protection bits
223 */
224 #define fillkptphys(prot) \
225 movl %eax, %ebx ; \
226 shrl $PAGE_SHIFT, %ebx ; \
227 fillkpt(R(KPTphys), prot)
228
229 /* Temporary stack */
230 .space 8192
231 tmpstack:
232 .long tmpstack, KERNEL_DS
233
234 .text
235
236 .p2align 12, 0x90
237
238 #define HYPERCALL_PAGE_OFFSET 0x1000
239 .org HYPERCALL_PAGE_OFFSET
240 ENTRY(hypercall_page)
241 .cfi_startproc
242 .skip 0x1000
243 .cfi_endproc
244
245 /**********************************************************************
246 *
247 * This is where the bootblocks start us, set the ball rolling...
248 *
249 */
250 NON_GPROF_ENTRY(btext)
251 /* At the end of our stack, we shall have free space - so store it */
252 movl %esp,%ebx
253 movl %ebx,R(avail_space)
254
255 lss tmpstack,%esp
256
257 pushl %esi
258 call initvalues
259 popl %esi
260
261 /* Store the CPUID information */
262 xorl %eax,%eax
263 cpuid # cpuid 0
264 movl %eax,R(cpu_high) # highest capability
265 movl %ebx,R(cpu_vendor) # store vendor string
266 movl %edx,R(cpu_vendor+4)
267 movl %ecx,R(cpu_vendor+8)
268 movb $0,R(cpu_vendor+12)
269
270 movl $1,%eax
271 cpuid # cpuid 1
272 movl %eax,R(cpu_id) # store cpu_id
273 movl %ebx,R(cpu_procinfo) # store cpu_procinfo
274 movl %edx,R(cpu_feature) # store cpu_feature
275 movl %ecx,R(cpu_feature2) # store cpu_feature2
276 rorl $8,%eax # extract family type
277 andl $15,%eax
278 cmpl $5,%eax
279 movl $CPU_686,R(cpu)
280
281 movl proc0kstack,%eax
282 leal (KSTACK_PAGES*PAGE_SIZE-PCB_SIZE)(%eax),%esp
283 xorl %ebp,%ebp /* mark end of frames */
284 #ifdef PAE
285 movl IdlePDPT,%esi
286 #else
287 movl IdlePTD,%esi
288 #endif
289 movl %esi,(KSTACK_PAGES*PAGE_SIZE-PCB_SIZE+PCB_CR3)(%eax)
290 pushl physfree
291 call init386
292 addl $4, %esp
293 call mi_startup
294 /* NOTREACHED */
295 int $3
296
297 /*
298 * Signal trampoline, copied to top of user stack
299 */
300 NON_GPROF_ENTRY(sigcode)
301 calll *SIGF_HANDLER(%esp)
302 leal SIGF_UC(%esp),%eax /* get ucontext */
303 pushl %eax
304 testl $PSL_VM,UC_EFLAGS(%eax)
305 jne 1f
306 mov UC_GS(%eax), %gs /* restore %gs */
307 1:
308 movl $SYS_sigreturn,%eax
309 pushl %eax /* junk to fake return addr. */
310 int $0x80 /* enter kernel with args */
311 /* on stack */
312 1:
313 jmp 1b
314
315 #ifdef COMPAT_FREEBSD4
316 ALIGN_TEXT
317 freebsd4_sigcode:
318 calll *SIGF_HANDLER(%esp)
319 leal SIGF_UC4(%esp),%eax /* get ucontext */
320 pushl %eax
321 testl $PSL_VM,UC4_EFLAGS(%eax)
322 jne 1f
323 mov UC4_GS(%eax),%gs /* restore %gs */
324 1:
325 movl $344,%eax /* 4.x SYS_sigreturn */
326 pushl %eax /* junk to fake return addr. */
327 int $0x80 /* enter kernel with args */
328 /* on stack */
329 1:
330 jmp 1b
331 #endif
332
333 #ifdef COMPAT_43
334 ALIGN_TEXT
335 osigcode:
336 call *SIGF_HANDLER(%esp) /* call signal handler */
337 lea SIGF_SC(%esp),%eax /* get sigcontext */
338 pushl %eax
339 testl $PSL_VM,SC_PS(%eax)
340 jne 9f
341 movl SC_GS(%eax),%gs /* restore %gs */
342 9:
343 movl $103,%eax /* 3.x SYS_sigreturn */
344 pushl %eax /* junk to fake return addr. */
345 int $0x80 /* enter kernel with args */
346 0: jmp 0b
347 #endif /* COMPAT_43 */
348
349 ALIGN_TEXT
350 esigcode:
351
352 .data
353 .globl szsigcode
354 szsigcode:
355 .long esigcode-sigcode
356 #ifdef COMPAT_FREEBSD4
357 .globl szfreebsd4_sigcode
358 szfreebsd4_sigcode:
359 .long esigcode-freebsd4_sigcode
360 #endif
361 #ifdef COMPAT_43
362 .globl szosigcode
363 szosigcode:
364 .long esigcode-osigcode
365 #endif
Cache object: c2282c596607156b43a00a69e534d25a
|