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 * $FreeBSD$ 32 */ 33 34#include <machine/asmacros.h> 35#include <machine/psl.h> 36#include <machine/pmap.h> 37#include <machine/specialreg.h> 38 39#include <xen/xen-os.h> 40#define __ASSEMBLY__ 41#include <xen/interface/elfnote.h> 42 43#include "assym.inc" 44 45#define VTOP(x) ((x) - KERNBASE) 46#define ENTRY_SIZE 8 /* sizeof(uint64_t) */ 47 48#define GDT_CODE 0x08 49#define GDT_DATA 0x10 50 51.section __xen_guest 52 ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz, "FreeBSD") 53 ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz, __XSTRING(__FreeBSD_version)) 54 ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz, "xen-3.0") 55 ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE, .quad, KERNBASE) 56 ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET, .quad, 0) 57 ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .quad, hypercall_page) 58 ELFNOTE(Xen, XEN_ELFNOTE_HV_START_LOW, .quad, HYPERVISOR_VIRT_START) 59 ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .asciz, "writable_descriptor_tables|auto_translated_physmap|supervisor_mode_kernel|hvm_callback_vector") 60 ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz, "yes") 61 ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID, .long, PG_V, PG_V) 62 ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz, "generic") 63 ELFNOTE(Xen, XEN_ELFNOTE_SUSPEND_CANCEL, .long, 0) 64 ELFNOTE(Xen, XEN_ELFNOTE_BSD_SYMTAB, .asciz, "yes") 65 /* For PVHv2 support. */ 66 ELFNOTE(Xen, XEN_ELFNOTE_PHYS32_ENTRY, .long, VTOP(xen_start32)) 67 68 .text 69.p2align PAGE_SHIFT, 0x90 /* Hypercall_page needs to be PAGE aligned */ 70 71ENTRY(hypercall_page) 72 .skip 0x1000, 0x90 /* Fill with "nop"s */ 73 74/* PVH entry point. */ 75 .code32 76ENTRY(xen_start32) 77 78 /* Load flat GDT */ 79 movl $VTOP(gdtdesc32), %eax 80 lgdt (%eax) 81 jmp $GDT_CODE, $VTOP(reload_cs) 82 83reload_cs: 84 movw $GDT_DATA, %ax 85 movw %ax, %ds 86 movw %ax, %es 87 movw %ax, %ss 88 89 movl $VTOP(bootstack), %esp 90 91 /* Don't trust what the loader gives for eflags. */ 92 pushl $PSL_KERNEL 93 popfl 94 95 /* 96 * Create the page tables. 97 * The first 1GB is mapped using 2MB entries. 98 */ 99 movl $0, %eax 100pgbuild: 101 cmp $(PAGE_SIZE/ENTRY_SIZE), %eax 102 jae pgbuild_done 103 104 /* PT4[i] = VTOP(&PT3[0]) | PG_V | PG_RW | PG_U */ 105 movl $VTOP(PT4), %ecx 106 movl $VTOP(PT3), %edx 107 orl $(PG_V | PG_RW | PG_U), %edx 108 movl %edx, (%ecx,%eax,ENTRY_SIZE) 109 110 /* PT3[i] = VTOP(&PT2[0]) | PG_V | PG_RW | PG_U */ 111 movl $VTOP(PT3), %ecx 112 movl $VTOP(PT2), %edx 113 orl $(PG_V | PG_RW | PG_U), %edx 114 movl %edx, (%ecx,%eax,ENTRY_SIZE) 115 116 /* PT2[i] = i * 2MiB | PG_V | PG_RW | PG_PS | PG_U */ 117 movl $VTOP(PT2), %ecx 118 movl %eax, %edx 119 shll $PDRSHIFT, %edx 120 orl $(PG_V | PG_RW | PG_PS | PG_U), %edx 121 movl %edx, (%ecx,%eax,ENTRY_SIZE) 122 123 inc %eax 124 jmp pgbuild 125 126pgbuild_done: 127 /* Turn on EFER.LME */ 128 movl $MSR_EFER, %ecx 129 rdmsr 130 orl $EFER_LME, %eax 131 wrmsr 132 133 /* Turn on PAE */ 134 movl %cr4, %eax 135 orl $CR4_PAE, %eax 136 movl %eax, %cr4 137 138 /* Set %cr3 for PT4 */ 139 movl $VTOP(PT4), %eax 140 movl %eax, %cr3 141 142 /* Turn on paging (implicitly sets EFER.LMA) */ 143 movl %cr0, %eax 144 orl $CR0_PG, %eax 145 movl %eax, %cr0 146 147 /* Now we're in compatibility mode. Set %cs for long mode */ 148 movl $VTOP(gdtdesc), %eax 149 lgdt (%eax) 150 ljmp $GDT_CODE, $VTOP(longmode) 151 152 .code64 153longmode: 154 /* We're still running V=P, jump to entry point */ 155 movq $bootstack, %rsp 156 movq $start_kernel, %rax 157 pushq %rax 158 ret 159 160start_kernel: 161 /* 162 * Pass %ebx as the argument to hammer_time_xen, it contains 163 * the startup info. 164 */ 165 movq %rbx, %rdi 166 call hammer_time_xen 167 movq %rax, %rsp 168 call mi_startup 169 170 /* NOTREACHED */ 1710: hlt 172 jmp 0b 173 174/* Space for initial page tables */ 175 .data 176 .p2align 12,0x40 177PT4: 178 .space 0x1000 179PT3: 180 .space 0x1000 181PT2: 182 .space 0x1000 183 184/* 64bit GDT */ 185gdtdesc: 186 .word gdtend - gdt - 1 187 .long VTOP(gdt) # low 188 .long 0 # high 189gdt: 190 .long 0 # null descriptor 191 .long 0 192 .long 0x00000000 # %cs 193 .long 0x00209800 194 .long 0x00000000 # %ds 195 .long 0x00008000 196gdtend: 197 198/* 32bit GDT */ 199gdtdesc32: 200 .word gdt32end - gdt32 - 1 201 .long VTOP(gdt32) 202 .long 0 203gdt32: 204 .long 0 # null descriptor 205 .long 0 206 .long 0x0000ffff # %cs 207 .long 0x00cf9a00 208 .long 0x0000ffff # %ds, %es, %ss 209 .long 0x00cf9200 210gdt32end: 211