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 */ 129tmpstk: 130 131 .globl bootinfo 132bootinfo: .space BOOTINFO_SIZE /* bootinfo that we can handle */ 133 134 .globl KERNend 135KERNend: .long 0 /* phys addr end of kernel (just after bss) */ 136 .globl physfree 137physfree: .long 0 /* phys addr of next free page */ 138 139 .globl IdlePTD 140IdlePTD: .long 0 /* phys addr of kernel PTD */ 141 142#ifdef PAE 143 .globl IdlePDPT 144IdlePDPT: .long 0 /* phys addr of kernel PDPT */ 145#endif 146 147#ifdef SMP 148 .globl KPTphys 149#endif 150KPTphys: .long 0 /* phys addr of kernel page tables */ 151 .globl gdtset 152gdtset: .long 0 /* GDT is valid */ 153 154 .globl proc0kstack 155proc0kstack: .long 0 /* address of proc 0 kstack space */ 156p0kpa: .long 0 /* phys addr of proc0's STACK */ 157 158vm86phystk: .long 0 /* PA of vm86/bios stack */ 159 160 .globl vm86paddr, vm86pa 161vm86paddr: .long 0 /* address of vm86 region */ 162vm86pa: .long 0 /* phys addr of vm86 region */ 163 164#ifdef PC98 165 .globl pc98_system_parameter 166pc98_system_parameter: 167 .space 0x240 168#endif 169 170 .globl avail_space 171avail_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 ; \ 2091: 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 227tmpstack: 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 236ENTRY(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 */ 246NON_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 */ 296NON_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 */ 3031: 304 movl $SYS_sigreturn,%eax 305 pushl %eax /* junk to fake return addr. */ 306 int $0x80 /* enter kernel with args */ 307 /* on stack */ 3081: 309 jmp 1b 310 311#ifdef COMPAT_FREEBSD4 312 ALIGN_TEXT 313freebsd4_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 */ 3201: 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 */ 3251: 326 jmp 1b 327#endif 328 329#ifdef COMPAT_43 330 ALIGN_TEXT 331osigcode: 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 */ 3389: 339 movl $103,%eax /* 3.x SYS_sigreturn */ 340 pushl %eax /* junk to fake return addr. */ 341 int $0x80 /* enter kernel with args */ 3420: jmp 0b 343#endif /* COMPAT_43 */ 344 345 ALIGN_TEXT 346esigcode: 347 348 .data 349 .globl szsigcode 350szsigcode: 351 .long esigcode-sigcode 352#ifdef COMPAT_FREEBSD4 353 .globl szfreebsd4_sigcode 354szfreebsd4_sigcode: 355 .long esigcode-freebsd4_sigcode 356#endif 357#ifdef COMPAT_43 358 .globl szosigcode 359szosigcode: 360 .long esigcode-osigcode 361#endif 362