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