]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - sys/i386/xen/locore.s
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.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         .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