1181641Skmacy/*- 2181641Skmacy * Copyright (c) 1990 The Regents of the University of California. 3181641Skmacy * All rights reserved. 4181641Skmacy * 5181641Skmacy * This code is derived from software contributed to Berkeley by 6181641Skmacy * William Jolitz. 7181641Skmacy * 8181641Skmacy * Redistribution and use in source and binary forms, with or without 9181641Skmacy * modification, are permitted provided that the following conditions 10181641Skmacy * are met: 11181641Skmacy * 1. Redistributions of source code must retain the above copyright 12181641Skmacy * notice, this list of conditions and the following disclaimer. 13181641Skmacy * 2. Redistributions in binary form must reproduce the above copyright 14181641Skmacy * notice, this list of conditions and the following disclaimer in the 15181641Skmacy * documentation and/or other materials provided with the distribution. 16181641Skmacy * 4. Neither the name of the University nor the names of its contributors 17181641Skmacy * may be used to endorse or promote products derived from this software 18181641Skmacy * without specific prior written permission. 19181641Skmacy * 20181641Skmacy * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21181641Skmacy * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22181641Skmacy * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23181641Skmacy * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24181641Skmacy * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25181641Skmacy * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26181641Skmacy * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27181641Skmacy * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28181641Skmacy * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29181641Skmacy * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30181641Skmacy * SUCH DAMAGE. 31181641Skmacy * 32181641Skmacy * from: @(#)locore.s 7.3 (Berkeley) 5/13/91 33181641Skmacy * $FreeBSD$ 34181641Skmacy * 35181641Skmacy * originally from: locore.s, by William F. Jolitz 36181641Skmacy * 37181641Skmacy * Substantially rewritten by David Greenman, Rod Grimes, 38181641Skmacy * Bruce Evans, Wolfgang Solfrank, Poul-Henning Kamp 39181641Skmacy * and many others. 40181641Skmacy */ 41181641Skmacy 42181641Skmacy#include "opt_bootp.h" 43181641Skmacy#include "opt_compat.h" 44181641Skmacy#include "opt_nfsroot.h" 45181641Skmacy#include "opt_global.h" 46181641Skmacy#include "opt_pmap.h" 47181641Skmacy 48181641Skmacy#include <sys/syscall.h> 49181641Skmacy#include <sys/reboot.h> 50181641Skmacy 51181641Skmacy#include <machine/asmacros.h> 52181641Skmacy#include <machine/cputypes.h> 53181641Skmacy#include <machine/psl.h> 54181641Skmacy#include <machine/pmap.h> 55181641Skmacy#include <machine/specialreg.h> 56181641Skmacy 57181641Skmacy#define __ASSEMBLY__ 58181641Skmacy#include <xen/interface/elfnote.h> 59181641Skmacy 60181641Skmacy/* The defines below have been lifted out of <machine/xen-public/arch-x86_32.h> */ 61181641Skmacy#define FLAT_RING1_CS 0xe019 /* GDT index 259 */ 62181641Skmacy#define FLAT_RING1_DS 0xe021 /* GDT index 260 */ 63181641Skmacy#define KERNEL_CS FLAT_RING1_CS 64181641Skmacy#define KERNEL_DS FLAT_RING1_DS 65181641Skmacy 66181641Skmacy#include "assym.s" 67181641Skmacy 68181641Skmacy.section __xen_guest 69181641Skmacy .ascii "LOADER=generic,GUEST_OS=freebsd,GUEST_VER=7.0,XEN_VER=xen-3.0,BSD_SYMTAB,VIRT_BASE=0xc0000000" 70181641Skmacy .byte 0 71182697Skmacy 72181641Skmacy ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz, "FreeBSD") 73181641Skmacy ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz, "HEAD") 74181641Skmacy ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz, "xen-3.0") 75181641Skmacy ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE, .long, KERNBASE) 76181641Skmacy ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET, .long, KERNBASE) 77181641Skmacy ELFNOTE(Xen, XEN_ELFNOTE_ENTRY, .long, btext) 78181641Skmacy ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .long, hypercall_page) 79254671Sgibbs ELFNOTE(Xen, XEN_ELFNOTE_HV_START_LOW, .long, XEN_HYPERVISOR_VIRT_START) 80181641Skmacy#if 0 81181641Skmacy ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .asciz, "writable_page_tables|writable_descriptor_tables|auto_translated_physmap|pae_pgdir_above_4gb|supervisor_mode_kernel") 82181641Skmacy#endif 83181641Skmacy ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .asciz, "writable_page_tables|supervisor_mode_kernel|writable_descriptor_tables") 84181641Skmacy 85181641Skmacy#ifdef PAE 86181641Skmacy ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz, "yes") 87181641Skmacy ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID, .long, PG_V, PG_V) 88181641Skmacy#else 89181641Skmacy ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz, "no") 90181641Skmacy ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID, .long, PG_V, PG_V) 91181641Skmacy#endif 92181641Skmacy ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz, "generic") 93181641Skmacy ELFNOTE(Xen, XEN_ELFNOTE_SUSPEND_CANCEL, .long, 1) 94181641Skmacy 95181641Skmacy 96181641Skmacy 97181641Skmacy/* 98181641Skmacy * XXX 99181641Skmacy * 100181641Skmacy * Note: This version greatly munged to avoid various assembler errors 101181641Skmacy * that may be fixed in newer versions of gas. Perhaps newer versions 102181641Skmacy * will have more pleasant appearance. 103181641Skmacy */ 104181641Skmacy 105181641Skmacy/* 106181641Skmacy * PTmap is recursive pagemap at top of virtual address space. 107181641Skmacy * Within PTmap, the page directory can be found (third indirection). 108181641Skmacy */ 109181641Skmacy .globl PTmap,PTD,PTDpde 110181641Skmacy .set PTmap,(PTDPTDI << PDRSHIFT) 111181641Skmacy .set PTD,PTmap + (PTDPTDI * PAGE_SIZE) 112181641Skmacy .set PTDpde,PTD + (PTDPTDI * PDESIZE) 113181641Skmacy 114181641Skmacy/* 115181641Skmacy * Compiled KERNBASE location and the kernel load address 116181641Skmacy */ 117181641Skmacy .globl kernbase 118181641Skmacy .set kernbase,KERNBASE 119181641Skmacy .globl kernload 120181641Skmacy .set kernload,KERNLOAD 121181641Skmacy 122181641Skmacy/* 123181641Skmacy * Globals 124181641Skmacy */ 125181641Skmacy .data 126181641Skmacy ALIGN_DATA /* just to be sure */ 127181641Skmacy 128181641Skmacy .space 0x2000 /* space for tmpstk - temporary stack */ 129181641Skmacytmpstk: 130181641Skmacy 131181641Skmacy .globl bootinfo 132181641Skmacybootinfo: .space BOOTINFO_SIZE /* bootinfo that we can handle */ 133181641Skmacy 134181641Skmacy .globl KERNend 135181641SkmacyKERNend: .long 0 /* phys addr end of kernel (just after bss) */ 136181641Skmacy .globl physfree 137181641Skmacyphysfree: .long 0 /* phys addr of next free page */ 138181641Skmacy 139181641Skmacy .globl IdlePTD 140181641SkmacyIdlePTD: .long 0 /* phys addr of kernel PTD */ 141181641Skmacy 142181641Skmacy#ifdef PAE 143181641Skmacy .globl IdlePDPT 144181641SkmacyIdlePDPT: .long 0 /* phys addr of kernel PDPT */ 145181641Skmacy#endif 146181641Skmacy 147181641Skmacy#ifdef SMP 148181641Skmacy .globl KPTphys 149181641Skmacy#endif 150181641SkmacyKPTphys: .long 0 /* phys addr of kernel page tables */ 151181747Skmacy .globl gdtset 152181747Skmacygdtset: .long 0 /* GDT is valid */ 153181641Skmacy 154181641Skmacy .globl proc0kstack 155181641Skmacyproc0kstack: .long 0 /* address of proc 0 kstack space */ 156181641Skmacyp0kpa: .long 0 /* phys addr of proc0's STACK */ 157181641Skmacy 158181641Skmacyvm86phystk: .long 0 /* PA of vm86/bios stack */ 159181641Skmacy 160181641Skmacy .globl vm86paddr, vm86pa 161181641Skmacyvm86paddr: .long 0 /* address of vm86 region */ 162181641Skmacyvm86pa: .long 0 /* phys addr of vm86 region */ 163181641Skmacy 164181641Skmacy#ifdef PC98 165181641Skmacy .globl pc98_system_parameter 166181641Skmacypc98_system_parameter: 167181641Skmacy .space 0x240 168181641Skmacy#endif 169181641Skmacy 170181641Skmacy .globl avail_space 171181641Skmacyavail_space: .long 0 172181641Skmacy 173181641Skmacy/********************************************************************** 174181641Skmacy * 175181641Skmacy * Some handy macros 176181641Skmacy * 177181641Skmacy */ 178181641Skmacy 179181641Skmacy/* 180181641Skmacy * We're already in protected mode, so no remapping is needed. 181181641Skmacy */ 182181641Skmacy#define R(foo) (foo) 183181641Skmacy 184181641Skmacy#define ALLOCPAGES(foo) \ 185181641Skmacy movl R(physfree), %esi ; \ 186181641Skmacy movl $((foo)*PAGE_SIZE), %eax ; \ 187181641Skmacy addl %esi, %eax ; \ 188181641Skmacy movl %eax, R(physfree) ; \ 189181641Skmacy movl %esi, %edi ; \ 190181641Skmacy movl $((foo)*PAGE_SIZE),%ecx ; \ 191181641Skmacy xorl %eax,%eax ; \ 192181641Skmacy cld ; \ 193181641Skmacy rep ; \ 194181641Skmacy stosb 195181641Skmacy 196181641Skmacy/* 197181641Skmacy * fillkpt 198181641Skmacy * eax = page frame address 199181641Skmacy * ebx = index into page table 200181641Skmacy * ecx = how many pages to map 201181641Skmacy * base = base address of page dir/table 202181641Skmacy * prot = protection bits 203181641Skmacy */ 204181641Skmacy#define fillkpt(base, prot) \ 205181641Skmacy shll $PTESHIFT,%ebx ; \ 206181641Skmacy addl base,%ebx ; \ 207181641Skmacy orl $PG_V,%eax ; \ 208181641Skmacy orl prot,%eax ; \ 209181641Skmacy1: movl %eax,(%ebx) ; \ 210181641Skmacy addl $PAGE_SIZE,%eax ; /* increment physical address */ \ 211181641Skmacy addl $PTESIZE,%ebx ; /* next pte */ \ 212181641Skmacy loop 1b 213181641Skmacy 214181641Skmacy/* 215181641Skmacy * fillkptphys(prot) 216181641Skmacy * eax = physical address 217181641Skmacy * ecx = how many pages to map 218181641Skmacy * prot = protection bits 219181641Skmacy */ 220181641Skmacy#define fillkptphys(prot) \ 221181641Skmacy movl %eax, %ebx ; \ 222181641Skmacy shrl $PAGE_SHIFT, %ebx ; \ 223181641Skmacy fillkpt(R(KPTphys), prot) 224181641Skmacy 225181641Skmacy/* Temporary stack */ 226181641Skmacy.space 8192 227181641Skmacytmpstack: 228181641Skmacy .long tmpstack, KERNEL_DS 229181641Skmacy 230181641Skmacy .text 231181641Skmacy 232181641Skmacy.p2align 12, 0x90 233181641Skmacy 234181641Skmacy#define HYPERCALL_PAGE_OFFSET 0x1000 235181641Skmacy.org HYPERCALL_PAGE_OFFSET 236181641SkmacyENTRY(hypercall_page) 237181641Skmacy .cfi_startproc 238181641Skmacy .skip 0x1000 239181641Skmacy .cfi_endproc 240181641Skmacy 241181641Skmacy/********************************************************************** 242181641Skmacy * 243181641Skmacy * This is where the bootblocks start us, set the ball rolling... 244181641Skmacy * 245181641Skmacy */ 246181641SkmacyNON_GPROF_ENTRY(btext) 247181641Skmacy /* At the end of our stack, we shall have free space - so store it */ 248181641Skmacy movl %esp,%ebx 249181641Skmacy movl %ebx,R(avail_space) 250181641Skmacy 251181641Skmacy lss tmpstack,%esp 252181641Skmacy 253181641Skmacy pushl %esi 254181641Skmacy call initvalues 255181641Skmacy popl %esi 256181641Skmacy 257181641Skmacy /* Store the CPUID information */ 258181641Skmacy xorl %eax,%eax 259181641Skmacy cpuid # cpuid 0 260181641Skmacy movl %eax,R(cpu_high) # highest capability 261181641Skmacy movl %ebx,R(cpu_vendor) # store vendor string 262181641Skmacy movl %edx,R(cpu_vendor+4) 263181641Skmacy movl %ecx,R(cpu_vendor+8) 264181641Skmacy movb $0,R(cpu_vendor+12) 265181641Skmacy 266181641Skmacy movl $1,%eax 267181641Skmacy cpuid # cpuid 1 268181641Skmacy movl %eax,R(cpu_id) # store cpu_id 269181641Skmacy movl %ebx,R(cpu_procinfo) # store cpu_procinfo 270181641Skmacy movl %edx,R(cpu_feature) # store cpu_feature 271181641Skmacy movl %ecx,R(cpu_feature2) # store cpu_feature2 272181641Skmacy rorl $8,%eax # extract family type 273181641Skmacy andl $15,%eax 274181641Skmacy cmpl $5,%eax 275181641Skmacy movl $CPU_686,R(cpu) 276181641Skmacy 277181641Skmacy movl proc0kstack,%eax 278181641Skmacy leal (KSTACK_PAGES*PAGE_SIZE-PCB_SIZE)(%eax),%esp 279181641Skmacy xorl %ebp,%ebp /* mark end of frames */ 280181641Skmacy#ifdef PAE 281181641Skmacy movl IdlePDPT,%esi 282181641Skmacy#else 283181641Skmacy movl IdlePTD,%esi 284181641Skmacy#endif 285181641Skmacy movl %esi,(KSTACK_PAGES*PAGE_SIZE-PCB_SIZE+PCB_CR3)(%eax) 286181641Skmacy pushl physfree 287181641Skmacy call init386 288181641Skmacy addl $4, %esp 289181641Skmacy call mi_startup 290181641Skmacy /* NOTREACHED */ 291181641Skmacy int $3 292181641Skmacy 293181641Skmacy/* 294181641Skmacy * Signal trampoline, copied to top of user stack 295181641Skmacy */ 296181641SkmacyNON_GPROF_ENTRY(sigcode) 297181641Skmacy calll *SIGF_HANDLER(%esp) 298181641Skmacy leal SIGF_UC(%esp),%eax /* get ucontext */ 299181641Skmacy pushl %eax 300181641Skmacy testl $PSL_VM,UC_EFLAGS(%eax) 301181641Skmacy jne 1f 302181641Skmacy mov UC_GS(%eax), %gs /* restore %gs */ 303181641Skmacy1: 304181641Skmacy movl $SYS_sigreturn,%eax 305181641Skmacy pushl %eax /* junk to fake return addr. */ 306181641Skmacy int $0x80 /* enter kernel with args */ 307181641Skmacy /* on stack */ 308181641Skmacy1: 309181641Skmacy jmp 1b 310181641Skmacy 311181641Skmacy#ifdef COMPAT_FREEBSD4 312181641Skmacy ALIGN_TEXT 313181641Skmacyfreebsd4_sigcode: 314181641Skmacy calll *SIGF_HANDLER(%esp) 315181641Skmacy leal SIGF_UC4(%esp),%eax /* get ucontext */ 316181641Skmacy pushl %eax 317181641Skmacy testl $PSL_VM,UC4_EFLAGS(%eax) 318181641Skmacy jne 1f 319181641Skmacy mov UC4_GS(%eax),%gs /* restore %gs */ 320181641Skmacy1: 321181641Skmacy movl $344,%eax /* 4.x SYS_sigreturn */ 322181641Skmacy pushl %eax /* junk to fake return addr. */ 323181641Skmacy int $0x80 /* enter kernel with args */ 324181641Skmacy /* on stack */ 325181641Skmacy1: 326181641Skmacy jmp 1b 327181641Skmacy#endif 328181641Skmacy 329181641Skmacy#ifdef COMPAT_43 330181641Skmacy ALIGN_TEXT 331181641Skmacyosigcode: 332181641Skmacy call *SIGF_HANDLER(%esp) /* call signal handler */ 333181641Skmacy lea SIGF_SC(%esp),%eax /* get sigcontext */ 334181641Skmacy pushl %eax 335181641Skmacy testl $PSL_VM,SC_PS(%eax) 336181641Skmacy jne 9f 337181641Skmacy movl SC_GS(%eax),%gs /* restore %gs */ 338181641Skmacy9: 339181641Skmacy movl $103,%eax /* 3.x SYS_sigreturn */ 340181641Skmacy pushl %eax /* junk to fake return addr. */ 341181641Skmacy int $0x80 /* enter kernel with args */ 342181641Skmacy0: jmp 0b 343181641Skmacy#endif /* COMPAT_43 */ 344181641Skmacy 345181641Skmacy ALIGN_TEXT 346181641Skmacyesigcode: 347181641Skmacy 348181641Skmacy .data 349181641Skmacy .globl szsigcode 350181641Skmacyszsigcode: 351181641Skmacy .long esigcode-sigcode 352181641Skmacy#ifdef COMPAT_FREEBSD4 353181641Skmacy .globl szfreebsd4_sigcode 354181641Skmacyszfreebsd4_sigcode: 355181641Skmacy .long esigcode-freebsd4_sigcode 356181641Skmacy#endif 357181641Skmacy#ifdef COMPAT_43 358181641Skmacy .globl szosigcode 359181641Skmacyszosigcode: 360181641Skmacy .long esigcode-osigcode 361181641Skmacy#endif 362