aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/boot/trampoline.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/trampoline.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/trampoline.S')
-rw-r--r--xen/arch/x86/boot/trampoline.S107
1 files changed, 107 insertions, 0 deletions
diff --git a/xen/arch/x86/boot/trampoline.S b/xen/arch/x86/boot/trampoline.S
new file mode 100644
index 0000000000..6df2ba8c02
--- /dev/null
+++ b/xen/arch/x86/boot/trampoline.S
@@ -0,0 +1,107 @@
+ .code16
+
+ .globl trampoline_realmode_entry
+trampoline_realmode_entry:
+ nop # We use this byte as a progress flag
+ movb $0xA5,trampoline_cpu_started - trampoline_start
+ cld
+ cli
+ lidt %cs:idt_48 - trampoline_start
+ lgdt %cs:gdt_48 - trampoline_start
+ xor %ax, %ax
+ inc %ax
+ lmsw %ax # CR0.PE = 1 (enter protected mode)
+ mov $1,%bl # EBX != 0 indicates we are an AP
+ jmp 1f
+1: ljmpl $TRAMP_CS32,$SYM_TRAMP_PHYS(trampoline_protmode_entry)
+
+idt_48: .word 0, 0, 0 # base = limit = 0
+gdt_48: .word 4*8-1
+ .long SYM_TRAMP_PHYS(trampoline_gdt)
+trampoline_gdt:
+ .quad 0x0000000000000000 /* 0x0000: unused */
+ .quad 0x00cf9a000000ffff /* 0x0008: ring 0 code, 32-bit mode */
+ .quad 0x00af9a000000ffff /* 0x0010: ring 0 code, 64-bit mode */
+ .quad 0x00cf92000000ffff /* 0x0018: ring 0 data */
+
+cpuid_ext_features:
+ .long 0
+
+ .globl trampoline_xen_phys_start
+trampoline_xen_phys_start:
+ .long 0
+
+ .globl trampoline_cpu_started
+trampoline_cpu_started:
+ .byte 0
+
+ .code32
+trampoline_protmode_entry:
+ /* Set up a few descriptors: on entry only CS is guaranteed good. */
+ mov $TRAMP_DS,%eax
+ mov %eax,%ds
+ mov %eax,%es
+
+ /* Set up FPU. */
+ fninit
+
+ /* Initialise CR4. */
+#if CONFIG_PAGING_LEVELS == 2
+ mov $X86_CR4_PSE,%ecx
+#else
+ mov $X86_CR4_PAE,%ecx
+#endif
+ mov %ecx,%cr4
+
+ /* Load pagetable base register. */
+ mov $SYM_PHYS(idle_pg_table),%eax
+ add SYM_TRAMP_PHYS(trampoline_xen_phys_start),%eax
+ mov %eax,%cr3
+
+#if CONFIG_PAGING_LEVELS != 2
+ /* Set up EFER (Extended Feature Enable Register). */
+ movl $MSR_EFER,%ecx
+ rdmsr
+#if CONFIG_PAGING_LEVELS == 4
+ btsl $_EFER_LME,%eax /* Long Mode */
+ btsl $_EFER_SCE,%eax /* SYSCALL/SYSRET */
+#endif
+ mov SYM_TRAMP_PHYS(cpuid_ext_features),%edi
+ btl $20,%edi /* CPUID 0x80000001, EDX[20] */
+ jnc 1f
+ btsl $_EFER_NX,%eax /* No-Execute */
+1: wrmsr
+#endif
+
+ mov $0x80050033,%eax /* hi-to-lo: PG,AM,WP,NE,ET,MP,PE */
+ mov %eax,%cr0
+ jmp 1f
+1:
+
+#if defined(__x86_64__)
+
+ /* Now in compatibility mode. Long-jump into 64-bit mode. */
+ ljmp $TRAMP_CS64,$SYM_TRAMP_PHYS(start64)
+
+ .code64
+start64:
+ /* Jump to high mappings. */
+ mov high_start(%rip),%rax
+ jmpq *%rax
+
+high_start:
+ .quad __high_start
+
+#else /* !defined(__x86_64__) */
+
+ /* Install relocated selectors. */
+ lgdt gdt_descr
+ mov $(__HYPERVISOR_DS),%eax
+ mov %eax,%ds
+ mov %eax,%es
+ mov %eax,%fs
+ mov %eax,%gs
+ mov %eax,%ss
+ ljmp $(__HYPERVISOR_CS),$__high_start
+
+#endif