#include <machine/asmacros.h>
#include <machine/psl.h>
#include <machine/pmap.h>
#include <machine/specialreg.h>
#include <xen/xen-os.h>
#define __ASSEMBLY__
#include <contrib/xen/elfnote.h>
#include "assym.inc"
#define VTOP(x) ((x) - KERNBASE)
#define ENTRY_SIZE 8
#define GDT_CODE 0x08
#define GDT_DATA 0x10
.section __xen_guest
ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz, "FreeBSD")
ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz, __XSTRING(__FreeBSD_version))
ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz, "xen-3.0")
ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE, .quad, KERNBASE)
ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET, .quad, 0)
ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .quad, hypercall_page)
ELFNOTE(Xen, XEN_ELFNOTE_HV_START_LOW, .quad, HYPERVISOR_VIRT_START)
ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .asciz, "writable_descriptor_tables|auto_translated_physmap|supervisor_mode_kernel|hvm_callback_vector")
ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz, "yes")
ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID, .long, PG_V, PG_V)
ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz, "generic")
ELFNOTE(Xen, XEN_ELFNOTE_SUSPEND_CANCEL, .long, 0)
ELFNOTE(Xen, XEN_ELFNOTE_BSD_SYMTAB, .asciz, "yes")
ELFNOTE(Xen, XEN_ELFNOTE_PHYS32_ENTRY, .long, VTOP(xen_start32))
.text
.p2align PAGE_SHIFT, 0x90
ENTRY(hypercall_page)
.skip 0x1000, 0xcc
.code32
ENTRY(xen_start32)
movl $VTOP(gdtdesc32), %eax
lgdt (%eax)
jmp $GDT_CODE, $VTOP(reload_cs)
reload_cs:
movw $GDT_DATA, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
movl $VTOP(bootstack), %esp
pushl $PSL_KERNEL
popfl
movl $0, %eax
pgbuild:
cmp $(PAGE_SIZE/ENTRY_SIZE), %eax
jae pgbuild_done
movl $VTOP(PT4), %ecx
movl $VTOP(PT3), %edx
orl $(PG_V | PG_RW | PG_U), %edx
movl %edx, (%ecx,%eax,ENTRY_SIZE)
movl $VTOP(PT3), %ecx
movl $VTOP(PT2), %edx
orl $(PG_V | PG_RW | PG_U), %edx
movl %edx, (%ecx,%eax,ENTRY_SIZE)
movl $VTOP(PT2), %ecx
movl %eax, %edx
shll $PDRSHIFT, %edx
orl $(PG_V | PG_RW | PG_PS | PG_U), %edx
movl %edx, (%ecx,%eax,ENTRY_SIZE)
inc %eax
jmp pgbuild
pgbuild_done:
movl $MSR_EFER, %ecx
rdmsr
orl $EFER_LME, %eax
wrmsr
movl %cr4, %eax
orl $CR4_PAE, %eax
movl %eax, %cr4
movl $VTOP(PT4), %eax
movl %eax, %cr3
movl %cr0, %eax
orl $CR0_PG, %eax
movl %eax, %cr0
movl $VTOP(gdtdesc), %eax
lgdt (%eax)
ljmp $GDT_CODE, $VTOP(longmode)
.code64
longmode:
movq $bootstack, %rsp
movq $start_kernel, %rax
pushq %rax
ret
start_kernel:
movq %rbx, %rdi
call hammer_time_xen
movq %rax, %rsp
call mi_startup
0: hlt
jmp 0b
.data
.p2align 12,0x40
PT4:
.space 0x1000
PT3:
.space 0x1000
PT2:
.space 0x1000
gdtdesc:
.word gdtend - gdt - 1
.long VTOP(gdt) # low
.long 0 # high
gdt:
.long 0 # null descriptor
.long 0
.long 0x00000000 # %cs
.long 0x00209800
.long 0x00000000 # %ds
.long 0x00008000
gdtend:
gdtdesc32:
.word gdt32end - gdt32 - 1
.long VTOP(gdt32)
.long 0
gdt32:
.long 0 # null descriptor
.long 0
.long 0x0000ffff # %cs
.long 0x00cf9a00
.long 0x0000ffff # %ds, %es, %ss
.long 0x00cf9200
gdt32end:
.section .note.GNU-stack,"",%progbits