aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/boot/x86_64.S
diff options
context:
space:
mode:
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-05-10 18:02:55 +0100
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-05-10 18:02:55 +0100
commit369bafdb1c1dcd2b323206befd7fc4ac5e20816f (patch)
tree79ce88cf129a2b2afa76b7776ce89a95145eb13e /xen/arch/x86/boot/x86_64.S
parent46f15346a6a2121c6319ec186114a2f5c1838e83 (diff)
downloadxen-369bafdb1c1dcd2b323206befd7fc4ac5e20816f.tar.gz
xen-369bafdb1c1dcd2b323206befd7fc4ac5e20816f.tar.bz2
xen-369bafdb1c1dcd2b323206befd7fc4ac5e20816f.zip
xen: Big changes to x86 start-of-day:
1. x86/64 Xen now relocates itself to physical high memory. This is useful if we have devices that need very low memory, or if in future we want to grant a 1:1 mapping of low physical memory to a special 'native client domain'. 2. We now only map low 16MB RAM statically. All other RAM is mapped dynamically within the constraints of the e820 map. It is recommended never to map MMIO regions, and this change means that Xen now obeys this constraint. 3. The CPU bootup trampoline is now permanently installed at 0x90000. This is necessary prereq for CPU hotplug. 4. Start-of-day asm is generally cleaned up and diff between x86/32 and x86/64 is reduced. Signed-off-by: Keir Fraser <keir@xensource.com>
Diffstat (limited to 'xen/arch/x86/boot/x86_64.S')
-rw-r--r--xen/arch/x86/boot/x86_64.S200
1 files changed, 15 insertions, 185 deletions
diff --git a/xen/arch/x86/boot/x86_64.S b/xen/arch/x86/boot/x86_64.S
index fe07e36471..c4f368420d 100644
--- a/xen/arch/x86/boot/x86_64.S
+++ b/xen/arch/x86/boot/x86_64.S
@@ -1,122 +1,13 @@
-#include <xen/config.h>
-#include <xen/multiboot.h>
-#include <public/xen.h>
-#include <asm/asm_defns.h>
-#include <asm/desc.h>
-#include <asm/page.h>
-#include <asm/msr.h>
-
-#define SECONDARY_CPU_FLAG 0xA5A5A5A5
-
- .text
- .code32
-
-#define SYM_PHYS(sym) (sym - __PAGE_OFFSET)
-
-ENTRY(start)
- jmp __start
-
- .org 0x004
-/*** MULTIBOOT HEADER ****/
-#define MULTIBOOT_HEADER_FLAGS (MULTIBOOT_HEADER_MODS_ALIGNED | \
- MULTIBOOT_HEADER_WANT_MEMORY)
- /* Magic number indicating a Multiboot header. */
- .long MULTIBOOT_HEADER_MAGIC
- /* Flags to bootloader (see Multiboot spec). */
- .long MULTIBOOT_HEADER_FLAGS
- /* Checksum: must be the negated sum of the first two fields. */
- .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
-
-.Lbad_cpu_msg: .asciz "ERR: Not a 64-bit CPU!"
-.Lbad_ldr_msg: .asciz "ERR: Not a Multiboot bootloader!"
-
-bad_cpu:
- mov $(SYM_PHYS(.Lbad_cpu_msg)),%esi # Error message
- jmp print_err
-not_multiboot:
- mov $(SYM_PHYS(.Lbad_ldr_msg)),%esi # Error message
-print_err:
- mov $0xB8000,%edi # VGA framebuffer
-1: mov (%esi),%bl
- test %bl,%bl # Terminate on '\0' sentinel
-2: je 2b
- mov $0x3f8+5,%dx # UART Line Status Register
-3: in %dx,%al
- test $0x20,%al # Test THR Empty flag
- je 3b
- mov $0x3f8+0,%dx # UART Transmit Holding Register
- mov %bl,%al
- out %al,%dx # Send a character over the serial line
- movsb # Write a character to the VGA framebuffer
- mov $7,%al
- stosb # Write an attribute to the VGA framebuffer
- jmp 1b
-
-__start:
- cld
- cli
+ .code64
- /* Set up a few descriptors: on entry only CS is guaranteed good. */
- lgdt %cs:SYM_PHYS(nopaging_gdt_descr)
- mov $(__HYPERVISOR_DS32),%ecx
+ /* Install relocated data selectors. */
+ lgdt gdt_descr(%rip)
+ mov $(__HYPERVISOR_DS64),%ecx
mov %ecx,%ds
mov %ecx,%es
-
- cmp $(SECONDARY_CPU_FLAG),%ebx
- je skip_boot_checks
-
- /* Check for Multiboot bootloader */
- cmp $0x2BADB002,%eax
- jne not_multiboot
-
- /* Save the Multiboot info structure for later use. */
- mov %ebx,SYM_PHYS(multiboot_ptr)
-
- /* We begin by interrogating the CPU for the presence of long mode. */
- mov $0x80000000,%eax
- cpuid
- cmp $0x80000000,%eax # any function > 0x80000000?
- jbe bad_cpu
- mov $0x80000001,%eax
- cpuid
- bt $29,%edx # Long mode feature?
- jnc bad_cpu
- mov %edx,SYM_PHYS(cpuid_ext_features)
-skip_boot_checks:
-
- /* Set up FPU. */
- fninit
-
- /* Enable PAE in CR4. */
- mov $0x20,%ecx # X86_CR4_PAE
- mov %ecx,%cr4
-
- /* Load pagetable base register. */
- mov $SYM_PHYS(idle_pg_table),%eax
- mov %eax,%cr3
-
- /* Set up EFER (Extended Feature Enable Register). */
- movl $MSR_EFER,%ecx
- rdmsr
- btsl $_EFER_LME,%eax /* Long Mode */
- btsl $_EFER_SCE,%eax /* SYSCALL/SYSRET */
- mov SYM_PHYS(cpuid_ext_features),%edi
- btl $20,%edi /* CPUID 0x80000001, EDX[20] */
- jnc 1f
- btsl $_EFER_NX,%eax /* No-Execute */
-1: wrmsr
-
- mov $0x80050033,%eax /* hi-to-lo: PG,AM,WP,NE,ET,MP,PE */
- mov %eax,%cr0
- jmp 1f
-
-1: /* Now in compatibility mode. Long-jump into 64-bit mode. */
- ljmp $(__HYPERVISOR_CS64),$SYM_PHYS(start64)
-
- .code64
-start64:
- /* Install relocated selectors (FS/GS unused). */
- lgdt gdt_descr(%rip)
+ mov %ecx,%fs
+ mov %ecx,%gs
+ mov %ecx,%ss
/* Enable full CR4 features. */
mov mmu_cr4_features(%rip),%rcx
@@ -129,30 +20,15 @@ start64:
pushq $0
popf
- /* Jump to high mappings. */
- mov high_start(%rip),%rax
- push %rax
- ret
-__high_start:
-
- mov $(__HYPERVISOR_DS64),%ecx
- mov %ecx,%ds
- mov %ecx,%es
- mov %ecx,%fs
- mov %ecx,%gs
- mov %ecx,%ss
-
- lidt idt_descr(%rip)
-
- cmp $(SECONDARY_CPU_FLAG),%ebx
- je start_secondary
+ /* Reload code selector. */
+ pushq $(__HYPERVISOR_CS64)
+ leaq 1f(%rip),%rax
+ pushq %rax
+ lretq
+1: lidt idt_descr(%rip)
- /* Initialize BSS (no nasty surprises!) */
- lea __bss_start(%rip),%rdi
- lea _end(%rip),%rcx
- sub %rdi,%rcx
- xor %rax,%rax
- rep stosb
+ test %ebx,%ebx
+ jnz start_secondary
/* Initialise IDT with simple error defaults. */
leaq ignore_int(%rip),%rcx
@@ -198,14 +74,6 @@ multiboot_ptr:
.long 0
.word 0
-nopaging_gdt_descr:
- .word LAST_RESERVED_GDT_BYTE
- .quad gdt_table - FIRST_RESERVED_GDT_BYTE - __PAGE_OFFSET
-
-cpuid_ext_features:
- .long 0
-
- .word 0
gdt_descr:
.word LAST_RESERVED_GDT_BYTE
.quad gdt_table - FIRST_RESERVED_GDT_BYTE
@@ -218,9 +86,6 @@ idt_descr:
ENTRY(stack_start)
.quad cpu0_stack
-high_start:
- .quad __high_start
-
.align PAGE_SIZE, 0
ENTRY(gdt_table)
.quad 0x0000000000000000 /* unused */
@@ -234,7 +99,6 @@ ENTRY(gdt_table)
.org gdt_table - FIRST_RESERVED_GDT_BYTE + __TSS(0) * 8
.fill 4*NR_CPUS,8,0 /* space for TSS and LDT per CPU */
-#ifdef CONFIG_COMPAT
.align PAGE_SIZE, 0
/* NB. Even rings != 0 get access to the full 4Gb, as only the */
/* (compatibility) machine->physical mapping table lives there. */
@@ -249,37 +113,3 @@ ENTRY(compat_gdt_table)
.quad 0x00cf9a000000ffff /* 0xe038 ring 0 code, compatibility */
.org compat_gdt_table - FIRST_RESERVED_GDT_BYTE + __TSS(0) * 8
.fill 4*NR_CPUS,8,0 /* space for TSS and LDT per CPU */
-# undef LIMIT
-#endif
-
-/* Initial PML4 -- level-4 page table. */
- .align PAGE_SIZE, 0
-ENTRY(idle_pg_table)
-ENTRY(idle_pg_table_4)
- .quad idle_pg_table_l3 - __PAGE_OFFSET + 7 # PML4[0]
- .fill 261,8,0
- .quad idle_pg_table_l3 - __PAGE_OFFSET + 7 # PML4[262]
-
-/* Initial PDP -- level-3 page table. */
- .align PAGE_SIZE, 0
-ENTRY(idle_pg_table_l3)
- .quad idle_pg_table_l2 - __PAGE_OFFSET + 7
-
-/* Initial PDE -- level-2 page table. Maps first 1GB physical memory. */
- .align PAGE_SIZE, 0
-ENTRY(idle_pg_table_l2)
- .macro identmap from=0, count=512
- .if \count-1
- identmap "(\from+0)","(\count/2)"
- identmap "(\from+(0x200000*(\count/2)))","(\count/2)"
- .else
- .quad 0x00000000000001e3 + \from
- .endif
- .endm
- identmap
-
- .align PAGE_SIZE, 0
-
-.section ".bss.stack_aligned","w"
-ENTRY(cpu0_stack)
- .fill STACK_SIZE,1,0