1/*- 2 * Copyright (c) 2003 Peter Wemm <peter@FreeBSD.org> 3 * Copyright (c) 2011-2012 Spectra Logic Corporation 4 * Copyright (c) 2013 Roger Pau Monne <royger@FreeBSD.org> 5 * All rights reserved. 6 * 7 * This software was developed by Cherry G. Mathew <cherry@zyx.in> 8 * under sponsorship from Spectra Logic Corporation. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32#include <machine/asmacros.h> 33#include <machine/psl.h> 34#include <machine/pmap.h> 35#include <machine/specialreg.h> 36 37#include <xen/xen-os.h> 38#define __ASSEMBLY__ 39#include <contrib/xen/elfnote.h> 40 41#include "assym.inc" 42 43#define VTOP(x) ((x) - KERNBASE) 44#define ENTRY_SIZE 8 /* sizeof(uint64_t) */ 45 46#define GDT_CODE 0x08 47#define GDT_DATA 0x10 48 49.section __xen_guest 50 ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz, "FreeBSD") 51 ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz, __XSTRING(__FreeBSD_version)) 52 ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz, "xen-3.0") 53 ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE, .quad, KERNBASE) 54 ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET, .quad, 0) 55 ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .quad, hypercall_page) 56 ELFNOTE(Xen, XEN_ELFNOTE_HV_START_LOW, .quad, HYPERVISOR_VIRT_START) 57 ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .asciz, "writable_descriptor_tables|auto_translated_physmap|supervisor_mode_kernel|hvm_callback_vector") 58 ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz, "yes") 59 ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID, .long, PG_V, PG_V) 60 ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz, "generic") 61 ELFNOTE(Xen, XEN_ELFNOTE_SUSPEND_CANCEL, .long, 0) 62 ELFNOTE(Xen, XEN_ELFNOTE_BSD_SYMTAB, .asciz, "yes") 63 /* For PVHv2 support. */ 64 ELFNOTE(Xen, XEN_ELFNOTE_PHYS32_ENTRY, .long, VTOP(xen_start32)) 65 66 .text 67.p2align PAGE_SHIFT, 0x90 /* Hypercall_page needs to be PAGE aligned */ 68 69ENTRY(hypercall_page) 70 .skip 0x1000, 0xcc /* Fill with `int3` to generate a #BP trap. */ 71 72/* PVH entry point. */ 73 .code32 74ENTRY(xen_start32) 75 76 /* Load flat GDT */ 77 movl $VTOP(gdtdesc32), %eax 78 lgdt (%eax) 79 jmp $GDT_CODE, $VTOP(reload_cs) 80 81reload_cs: 82 movw $GDT_DATA, %ax 83 movw %ax, %ds 84 movw %ax, %es 85 movw %ax, %ss 86 87 movl $VTOP(bootstack), %esp 88 89 /* Don't trust what the loader gives for eflags. */ 90 pushl $PSL_KERNEL 91 popfl 92 93 /* 94 * Create the page tables. 95 * The first 1GB is mapped using 2MB entries. 96 */ 97 movl $0, %eax 98pgbuild: 99 cmp $(PAGE_SIZE/ENTRY_SIZE), %eax 100 jae pgbuild_done 101 102 /* PT4[i] = VTOP(&PT3[0]) | PG_V | PG_RW | PG_U */ 103 movl $VTOP(PT4), %ecx 104 movl $VTOP(PT3), %edx 105 orl $(PG_V | PG_RW | PG_U), %edx 106 movl %edx, (%ecx,%eax,ENTRY_SIZE) 107 108 /* PT3[i] = VTOP(&PT2[0]) | PG_V | PG_RW | PG_U */ 109 movl $VTOP(PT3), %ecx 110 movl $VTOP(PT2), %edx 111 orl $(PG_V | PG_RW | PG_U), %edx 112 movl %edx, (%ecx,%eax,ENTRY_SIZE) 113 114 /* PT2[i] = i * 2MiB | PG_V | PG_RW | PG_PS | PG_U */ 115 movl $VTOP(PT2), %ecx 116 movl %eax, %edx 117 shll $PDRSHIFT, %edx 118 orl $(PG_V | PG_RW | PG_PS | PG_U), %edx 119 movl %edx, (%ecx,%eax,ENTRY_SIZE) 120 121 inc %eax 122 jmp pgbuild 123 124pgbuild_done: 125 /* Turn on EFER.LME */ 126 movl $MSR_EFER, %ecx 127 rdmsr 128 orl $EFER_LME, %eax 129 wrmsr 130 131 /* Turn on PAE */ 132 movl %cr4, %eax 133 orl $CR4_PAE, %eax 134 movl %eax, %cr4 135 136 /* Set %cr3 for PT4 */ 137 movl $VTOP(PT4), %eax 138 movl %eax, %cr3 139 140 /* Turn on paging (implicitly sets EFER.LMA) */ 141 movl %cr0, %eax 142 orl $CR0_PG, %eax 143 movl %eax, %cr0 144 145 /* Now we're in compatibility mode. Set %cs for long mode */ 146 movl $VTOP(gdtdesc), %eax 147 lgdt (%eax) 148 ljmp $GDT_CODE, $VTOP(longmode) 149 150 .code64 151longmode: 152 /* We're still running V=P, jump to entry point */ 153 movq $bootstack, %rsp 154 movq $start_kernel, %rax 155 pushq %rax 156 ret 157 158start_kernel: 159 /* 160 * Pass %ebx as the argument to hammer_time_xen, it contains 161 * the startup info. 162 */ 163 movq %rbx, %rdi 164 call hammer_time_xen 165 movq %rax, %rsp 166 call mi_startup 167 168 /* NOTREACHED */ 1690: hlt 170 jmp 0b 171 172/* Space for initial page tables */ 173 .data 174 .p2align 12,0x40 175PT4: 176 .space 0x1000 177PT3: 178 .space 0x1000 179PT2: 180 .space 0x1000 181 182/* 64bit GDT */ 183gdtdesc: 184 .word gdtend - gdt - 1 185 .long VTOP(gdt) # low 186 .long 0 # high 187gdt: 188 .long 0 # null descriptor 189 .long 0 190 .long 0x00000000 # %cs 191 .long 0x00209800 192 .long 0x00000000 # %ds 193 .long 0x00008000 194gdtend: 195 196/* 32bit GDT */ 197gdtdesc32: 198 .word gdt32end - gdt32 - 1 199 .long VTOP(gdt32) 200 .long 0 201gdt32: 202 .long 0 # null descriptor 203 .long 0 204 .long 0x0000ffff # %cs 205 .long 0x00cf9a00 206 .long 0x0000ffff # %ds, %es, %ss 207 .long 0x00cf9200 208gdt32end: 209