Changeset View
Changeset View
Standalone View
Standalone View
sys/amd64/amd64/xen-locore.S
Show First 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | .section __xen_guest | ||||
ELFNOTE(Xen, XEN_ELFNOTE_HV_START_LOW, .quad, HYPERVISOR_VIRT_START) | 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_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_PAE_MODE, .asciz, "yes") | ||||
ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID, .long, PG_V, PG_V) | ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID, .long, PG_V, PG_V) | ||||
ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz, "generic") | ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz, "generic") | ||||
ELFNOTE(Xen, XEN_ELFNOTE_SUSPEND_CANCEL, .long, 0) | ELFNOTE(Xen, XEN_ELFNOTE_SUSPEND_CANCEL, .long, 0) | ||||
ELFNOTE(Xen, XEN_ELFNOTE_BSD_SYMTAB, .asciz, "yes") | ELFNOTE(Xen, XEN_ELFNOTE_BSD_SYMTAB, .asciz, "yes") | ||||
/* For PVHv2 support. */ | /* For PVHv2 support. */ | ||||
ELFNOTE(Xen, XEN_ELFNOTE_PHYS32_ENTRY, .long, VTOP(xen_start32)) | ELFNOTE(Xen, XEN_ELFNOTE_PHYS32_ENTRY, .long, xen_start32) | ||||
.text | .text | ||||
.p2align PAGE_SHIFT, 0x90 /* Hypercall_page needs to be PAGE aligned */ | .p2align PAGE_SHIFT, 0x90 /* Hypercall_page needs to be PAGE aligned */ | ||||
ENTRY(hypercall_page) | ENTRY(hypercall_page) | ||||
.skip 0x1000, 0xcc /* Fill with `int3` to generate a #BP trap. */ | .skip 0x1000, 0xcc /* Fill with `int3` to generate a #BP trap. */ | ||||
/* PVH entry point. */ | /* PVH entry point. */ | ||||
.code32 | .code32 | ||||
.pushsection .text.init32 | |||||
ENTRY(xen_start32) | ENTRY(xen_start32) | ||||
/* Load flat GDT */ | /* Load flat GDT */ | ||||
movl $VTOP(gdtdesc32), %eax | movl $gdt32desc, %eax | ||||
lgdt (%eax) | lgdt (%eax) | ||||
jmp $GDT_CODE, $VTOP(reload_cs) | jmp $GDT_CODE, $reload_cs | ||||
reload_cs: | reload_cs: | ||||
movw $GDT_DATA, %ax | movw $GDT_DATA, %ax | ||||
movw %ax, %ds | movw %ax, %ds | ||||
movw %ax, %es | movw %ax, %es | ||||
movw %ax, %ss | movw %ax, %ss | ||||
movl $VTOP(bootstack), %esp | movl $VTOP(bootstack), %esp | ||||
/* Don't trust what the loader gives for eflags. */ | /* Don't trust what the loader gives for eflags. */ | ||||
pushl $PSL_KERNEL | pushl $PSL_KERNEL | ||||
popfl | popfl | ||||
/* | |||||
* Create the page tables. | |||||
* The first 1GB is mapped using 2MB entries. | |||||
*/ | |||||
movl $0, %eax | |||||
pgbuild: | |||||
cmp $(PAGE_SIZE/ENTRY_SIZE), %eax | |||||
jae pgbuild_done | |||||
/* PT4[i] = VTOP(&PT3[0]) | PG_V | PG_RW | PG_U */ | |||||
movl $VTOP(PT4), %ecx | |||||
movl $VTOP(PT3), %edx | |||||
orl $(PG_V | PG_RW | PG_U), %edx | |||||
movl %edx, (%ecx,%eax,ENTRY_SIZE) | |||||
/* PT3[i] = VTOP(&PT2[0]) | PG_V | PG_RW | PG_U */ | |||||
movl $VTOP(PT3), %ecx | |||||
movl $VTOP(PT2), %edx | |||||
orl $(PG_V | PG_RW | PG_U), %edx | |||||
movl %edx, (%ecx,%eax,ENTRY_SIZE) | |||||
/* PT2[i] = i * 2MiB | PG_V | PG_RW | PG_PS | PG_U */ | |||||
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: | |||||
/* Turn on EFER.LME */ | /* Turn on EFER.LME */ | ||||
movl $MSR_EFER, %ecx | movl $MSR_EFER, %ecx | ||||
rdmsr | rdmsr | ||||
orl $EFER_LME, %eax | orl $EFER_LME, %eax | ||||
wrmsr | wrmsr | ||||
/* Turn on PAE */ | /* Turn on PAE */ | ||||
movl %cr4, %eax | movl %cr4, %eax | ||||
orl $CR4_PAE, %eax | orl $CR4_PAE, %eax | ||||
movl %eax, %cr4 | movl %eax, %cr4 | ||||
/* Set %cr3 for PT4 */ | /* Set %cr3 for PT4 */ | ||||
movl $VTOP(PT4), %eax | call xen_start_pgtable | ||||
movl %eax, %cr3 | movl %eax, %cr3 | ||||
/* Turn on paging (implicitly sets EFER.LMA) */ | /* Turn on paging (implicitly sets EFER.LMA) */ | ||||
movl %cr0, %eax | movl %cr0, %eax | ||||
orl $CR0_PG, %eax | orl $CR0_PG, %eax | ||||
movl %eax, %cr0 | movl %eax, %cr0 | ||||
/* Now we're in compatibility mode. Set %cs for long mode */ | /* Now we're in compatibility mode. Set %cs for long mode */ | ||||
movl $VTOP(gdtdesc), %eax | movl $gdt64desc, %eax | ||||
lgdt (%eax) | lgdt (%eax) | ||||
ljmp $GDT_CODE, $VTOP(longmode) | ljmp $GDT_CODE, $longmode | ||||
.code64 | .code64 | ||||
longmode: | longmode: | ||||
/* We're still running V=P, jump to entry point */ | /* We're still running V=P, jump to entry point */ | ||||
movq $bootstack, %rsp | movq $bootstack, %rsp | ||||
movq $start_kernel, %rax | movq $start_kernel, %rax | ||||
pushq %rax | pushq %rax | ||||
ret | ret | ||||
.popsection | |||||
start_kernel: | start_kernel: | ||||
/* | /* | ||||
* Pass %ebx as the argument to hammer_time_xen, it contains | * Pass %ebx as the argument to hammer_time_xen, it contains | ||||
* the startup info. | * the startup info. | ||||
*/ | */ | ||||
movq %rbx, %rdi | movq %rbx, %rdi | ||||
call hammer_time_xen | call hammer_time_xen | ||||
movq %rax, %rsp | movq %rax, %rsp | ||||
call mi_startup | call mi_startup | ||||
/* NOTREACHED */ | /* NOTREACHED */ | ||||
0: hlt | 0: hlt | ||||
jmp 0b | jmp 0b | ||||
/* Space for initial page tables */ | |||||
.data | |||||
.p2align 12,0x40 | |||||
PT4: | |||||
.space 0x1000 | |||||
PT3: | |||||
.space 0x1000 | |||||
PT2: | |||||
.space 0x1000 | |||||
/* 64bit GDT */ | |||||
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: | |||||
/* 32bit GDT */ | |||||
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: |