]> CyberLeo.Net >> Repos - FreeBSD/releng/8.0.git/blob - sys/i386/xen/locore.s
Adjust to reflect 8.0-RELEASE.
[FreeBSD/releng/8.0.git] / 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$
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