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