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.4/sys/i386/xen/locore.s 199774 2009-11-25 01:55:34Z 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 .globl gdtset
152 gdtset: .long 0 /* GDT is valid */
153
154 .globl proc0kstack
155 proc0uarea: .long 0 /* address of proc 0 uarea (unused)*/
156 proc0kstack: .long 0 /* address of proc 0 kstack space */
157 p0upa: .long 0 /* phys addr of proc0 UAREA (unused) */
158 p0kpa: .long 0 /* phys addr of proc0's STACK */
159
160 vm86phystk: .long 0 /* PA of vm86/bios stack */
161
162 .globl vm86paddr, vm86pa
163 vm86paddr: .long 0 /* address of vm86 region */
164 vm86pa: .long 0 /* phys addr of vm86 region */
165
166 #ifdef PC98
167 .globl pc98_system_parameter
168 pc98_system_parameter:
169 .space 0x240
170 #endif
171
172 .globl avail_space
173 avail_space: .long 0
174
175 /**********************************************************************
176 *
177 * Some handy macros
178 *
179 */
180
181 /*
182 * We're already in protected mode, so no remapping is needed.
183 */
184 #define R(foo) (foo)
185
186 #define ALLOCPAGES(foo) \
187 movl R(physfree), %esi ; \
188 movl $((foo)*PAGE_SIZE), %eax ; \
189 addl %esi, %eax ; \
190 movl %eax, R(physfree) ; \
191 movl %esi, %edi ; \
192 movl $((foo)*PAGE_SIZE),%ecx ; \
193 xorl %eax,%eax ; \
194 cld ; \
195 rep ; \
196 stosb
197
198 /*
199 * fillkpt
200 * eax = page frame address
201 * ebx = index into page table
202 * ecx = how many pages to map
203 * base = base address of page dir/table
204 * prot = protection bits
205 */
206 #define fillkpt(base, prot) \
207 shll $PTESHIFT,%ebx ; \
208 addl base,%ebx ; \
209 orl $PG_V,%eax ; \
210 orl prot,%eax ; \
211 1: movl %eax,(%ebx) ; \
212 addl $PAGE_SIZE,%eax ; /* increment physical address */ \
213 addl $PTESIZE,%ebx ; /* next pte */ \
214 loop 1b
215
216 /*
217 * fillkptphys(prot)
218 * eax = physical address
219 * ecx = how many pages to map
220 * prot = protection bits
221 */
222 #define fillkptphys(prot) \
223 movl %eax, %ebx ; \
224 shrl $PAGE_SHIFT, %ebx ; \
225 fillkpt(R(KPTphys), prot)
226
227 /* Temporary stack */
228 .space 8192
229 tmpstack:
230 .long tmpstack, KERNEL_DS
231
232 .text
233
234 .p2align 12, 0x90
235
236 #define HYPERCALL_PAGE_OFFSET 0x1000
237 .org HYPERCALL_PAGE_OFFSET
238 ENTRY(hypercall_page)
239 .cfi_startproc
240 .skip 0x1000
241 .cfi_endproc
242
243 /**********************************************************************
244 *
245 * This is where the bootblocks start us, set the ball rolling...
246 *
247 */
248 NON_GPROF_ENTRY(btext)
249 /* At the end of our stack, we shall have free space - so store it */
250 movl %esp,%ebx
251 movl %ebx,R(avail_space)
252
253 lss tmpstack,%esp
254
255 pushl %esi
256 call initvalues
257 popl %esi
258
259 /* Store the CPUID information */
260 xorl %eax,%eax
261 cpuid # cpuid 0
262 movl %eax,R(cpu_high) # highest capability
263 movl %ebx,R(cpu_vendor) # store vendor string
264 movl %edx,R(cpu_vendor+4)
265 movl %ecx,R(cpu_vendor+8)
266 movb $0,R(cpu_vendor+12)
267
268 movl $1,%eax
269 cpuid # cpuid 1
270 movl %eax,R(cpu_id) # store cpu_id
271 movl %ebx,R(cpu_procinfo) # store cpu_procinfo
272 movl %edx,R(cpu_feature) # store cpu_feature
273 movl %ecx,R(cpu_feature2) # store cpu_feature2
274 rorl $8,%eax # extract family type
275 andl $15,%eax
276 cmpl $5,%eax
277 movl $CPU_686,R(cpu)
278
279 movl proc0kstack,%eax
280 leal (KSTACK_PAGES*PAGE_SIZE-PCB_SIZE)(%eax),%esp
281 xorl %ebp,%ebp /* mark end of frames */
282 #ifdef PAE
283 movl IdlePDPT,%esi
284 #else
285 movl IdlePTD,%esi
286 #endif
287 movl %esi,(KSTACK_PAGES*PAGE_SIZE-PCB_SIZE+PCB_CR3)(%eax)
288 pushl physfree
289 call init386
290 addl $4, %esp
291 call mi_startup
292 /* NOTREACHED */
293 int $3
294
295 /*
296 * Signal trampoline, copied to top of user stack
297 */
298 NON_GPROF_ENTRY(sigcode)
299 calll *SIGF_HANDLER(%esp)
300 leal SIGF_UC(%esp),%eax /* get ucontext */
301 pushl %eax
302 testl $PSL_VM,UC_EFLAGS(%eax)
303 jne 1f
304 mov UC_GS(%eax), %gs /* restore %gs */
305 1:
306 movl $SYS_sigreturn,%eax
307 pushl %eax /* junk to fake return addr. */
308 int $0x80 /* enter kernel with args */
309 /* on stack */
310 1:
311 jmp 1b
312
313 #ifdef COMPAT_FREEBSD4
314 ALIGN_TEXT
315 freebsd4_sigcode:
316 calll *SIGF_HANDLER(%esp)
317 leal SIGF_UC4(%esp),%eax /* get ucontext */
318 pushl %eax
319 testl $PSL_VM,UC4_EFLAGS(%eax)
320 jne 1f
321 mov UC4_GS(%eax),%gs /* restore %gs */
322 1:
323 movl $344,%eax /* 4.x SYS_sigreturn */
324 pushl %eax /* junk to fake return addr. */
325 int $0x80 /* enter kernel with args */
326 /* on stack */
327 1:
328 jmp 1b
329 #endif
330
331 #ifdef COMPAT_43
332 ALIGN_TEXT
333 osigcode:
334 call *SIGF_HANDLER(%esp) /* call signal handler */
335 lea SIGF_SC(%esp),%eax /* get sigcontext */
336 pushl %eax
337 testl $PSL_VM,SC_PS(%eax)
338 jne 9f
339 movl SC_GS(%eax),%gs /* restore %gs */
340 9:
341 movl $103,%eax /* 3.x SYS_sigreturn */
342 pushl %eax /* junk to fake return addr. */
343 int $0x80 /* enter kernel with args */
344 0: jmp 0b
345 #endif /* COMPAT_43 */
346
347 ALIGN_TEXT
348 esigcode:
349
350 .data
351 .globl szsigcode
352 szsigcode:
353 .long esigcode-sigcode
354 #ifdef COMPAT_FREEBSD4
355 .globl szfreebsd4_sigcode
356 szfreebsd4_sigcode:
357 .long esigcode-freebsd4_sigcode
358 #endif
359 #ifdef COMPAT_43
360 .globl szosigcode
361 szosigcode:
362 .long esigcode-osigcode
363 #endif
Cache object: 4d24d4ccf58c0a71be5c7deda44c0870
|