ia64/xen-unstable

view xen/arch/x86/boot/x86_64.S @ 5762:3a4ef6acd545

Fix NX/XD enable on secondary CPUs.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Wed Jul 13 08:25:08 2005 +0000 (2005-07-13)
parents d1e3efb12a27
children 35ccaeaffeb7
line source
1 #include <xen/config.h>
2 #include <public/xen.h>
3 #include <asm/desc.h>
4 #include <asm/page.h>
5 #include <asm/msr.h>
7 #define SECONDARY_CPU_FLAG 0xA5A5A5A5
9 .text
10 .code32
12 ENTRY(start)
13 jmp __start
15 .org 0x004
16 /*** MULTIBOOT HEADER ****/
17 /* Magic number indicating a Multiboot header. */
18 .long 0x1BADB002
19 /* Flags to bootloader (see Multiboot spec). */
20 .long 0x00000003
21 /* Checksum: must be the negated sum of the first two fields. */
22 .long -0x1BADB005
24 .org 0x010
25 .asciz "ERR: Not a 64-bit CPU!"
26 .org 0x028
27 .asciz "ERR: Not a Multiboot bootloader!"
28 bad_cpu:
29 mov $0x100010,%esi # Error message
30 jmp print_err
31 not_multiboot:
32 mov $0x100028,%esi # Error message
33 print_err:
34 mov $0xB8000,%edi # VGA framebuffer
35 1: mov (%esi),%bl
36 test %bl,%bl # Terminate on '\0' sentinel
37 2: je 2b
38 mov $0x3f8+5,%dx # UART Line Status Register
39 3: in %dx,%al
40 test $0x20,%al # Test THR Empty flag
41 je 3b
42 mov $0x3f8+0,%dx # UART Transmit Holding Register
43 mov %bl,%al
44 out %al,%dx # Send a character over the serial line
45 movsb # Write a character to the VGA framebuffer
46 mov $7,%al
47 stosb # Write an attribute to the VGA framebuffer
48 jmp 1b
50 __start:
51 cld
52 cli
54 /* Set up a few descriptors: on entry only CS is guaranteed good. */
55 lgdt %cs:0x100306 # nopaging_gdt_descr
56 mov $(__HYPERVISOR_DS32),%ecx
57 mov %ecx,%ds
58 mov %ecx,%es
60 cmp $(SECONDARY_CPU_FLAG),%ebx
61 je skip_boot_checks
63 /* Check for Multiboot bootloader */
64 cmp $0x2BADB002,%eax
65 jne not_multiboot
67 /* Save the Multiboot info structure for later use. */
68 mov %ebx,0x100300 # multiboot_ptr
70 /* We begin by interrogating the CPU for the presence of long mode. */
71 mov $0x80000000,%eax
72 cpuid
73 cmp $0x80000000,%eax # any function > 0x80000000?
74 jbe bad_cpu
75 mov $0x80000001,%eax
76 cpuid
77 bt $29,%edx # Long mode feature?
78 jnc bad_cpu
79 mov %edx,0x100310 # cpuid_ext_features
80 skip_boot_checks:
82 /* Set up FPU. */
83 fninit
85 /* Enable PAE in CR4. */
86 mov $0x20,%ecx # X86_CR4_PAE
87 mov %ecx,%cr4
89 /* Load pagetable base register. */
90 mov $0x102000,%eax /* idle_pg_table */
91 mov %eax,%cr3
93 /* Set up EFER (Extended Feature Enable Register). */
94 movl $MSR_EFER, %ecx
95 rdmsr
96 btsl $_EFER_LME,%eax /* Long Mode */
97 btsl $_EFER_SCE,%eax /* SYSCALL/SYSRET */
98 mov 0x100310,%edi
99 btl $20,%edi /* CPUID 0x80000001, EDX[20] */
100 jnc 1f
101 btsl $_EFER_NX,%eax /* No-Execute */
102 1: wrmsr
104 mov $0x80050033,%eax /* hi-to-lo: PG,AM,WP,NE,ET,MP,PE */
105 mov %eax,%cr0
106 jmp 1f
108 1: /* Now in compatibility mode. Long-jump into 64-bit mode. */
109 ljmp $(__HYPERVISOR_CS64),$0x100200
111 .code64
112 .org 0x0200
114 /* Install relocated selectors (FS/GS unused). */
115 lgdt gdt_descr(%rip)
117 /* Enable full CR4 features. */
118 mov mmu_cr4_features(%rip),%rcx
119 mov %rcx,%cr4
121 mov stack_start(%rip),%rsp
123 /* Reset EFLAGS (subsumes CLI and CLD). */
124 pushq $0
125 popf
127 /* Jump to high mappings. */
128 mov high_start(%rip),%rax
129 push %rax
130 ret
131 __high_start:
133 mov $(__HYPERVISOR_DS64),%ecx
134 mov %ecx,%ds
135 mov %ecx,%es
136 mov %ecx,%fs
137 mov %ecx,%gs
138 mov %ecx,%ss
140 lidt idt_descr(%rip)
142 cmp $(SECONDARY_CPU_FLAG),%ebx
143 je start_secondary
145 /* Initialize BSS (no nasty surprises!) */
146 lea __bss_start(%rip),%rdi
147 lea _end(%rip),%rcx
148 sub %rdi,%rcx
149 xor %rax,%rax
150 rep stosb
152 /* Initialise IDT with simple error defaults. */
153 leaq ignore_int(%rip),%rcx
154 movl %ecx,%eax
155 andl $0xFFFF0000,%eax
156 orl $0x00008E00,%eax
157 shlq $32,%rax
158 movl %ecx,%edx
159 andl $0x0000FFFF,%edx
160 orl $(__HYPERVISOR_CS64<<16),%edx
161 orq %rdx,%rax
162 shrq $32,%rcx
163 movl %ecx,%edx
164 leaq idt_table(%rip),%rdi
165 movl $256,%ecx
166 1: movq %rax,(%rdi)
167 movq %rdx,8(%rdi)
168 addq $16,%rdi
169 loop 1b
171 /* Pass off the Multiboot info structure to C land. */
172 mov multiboot_ptr(%rip),%edi
173 lea start-0x100000(%rip),%rax
174 add %rax,%rdi
175 call __start_xen
176 ud2 /* Force a panic (invalid opcode). */
178 /* This is the default interrupt handler. */
179 int_msg:
180 .asciz "Unknown interrupt\n"
181 ignore_int:
182 cld
183 leaq int_msg(%rip),%rdi
184 call printf
185 1: jmp 1b
188 /*** DESCRIPTOR TABLES ***/
190 .globl idt
191 .globl gdt
193 .org 0x300
194 .code32
196 multiboot_ptr: /* 0x300 */
197 .long 0
199 .word 0
200 nopaging_gdt_descr: /* 0x306 */
201 .word LAST_RESERVED_GDT_BYTE
202 .quad gdt_table - FIRST_RESERVED_GDT_BYTE - __PAGE_OFFSET
204 cpuid_ext_features: /* 0x310 */
205 .long 0
207 .word 0
208 gdt_descr:
209 .word LAST_RESERVED_GDT_BYTE
210 gdt:
211 .quad gdt_table - FIRST_RESERVED_GDT_BYTE
213 .word 0,0,0
214 idt_descr:
215 .word 256*16-1
216 idt:
217 .quad idt_table
219 ENTRY(stack_start)
220 .quad cpu0_stack + STACK_SIZE - 200
222 high_start:
223 .quad __high_start
225 .org 0x1000
226 ENTRY(gdt_table)
227 .quad 0x0000000000000000 /* unused */
228 .quad 0x00cf9a000000ffff /* 0xe008 ring 0 code, compatibility */
229 .quad 0x00af9a000000ffff /* 0xe010 ring 0 code, 64-bit mode */
230 .quad 0x00cf92000000ffff /* 0xe018 ring 0 data */
231 .quad 0x00cffa000000ffff /* 0xe023 ring 3 code, compatibility */
232 .quad 0x00cff2000000ffff /* 0xe02b ring 3 data */
233 .quad 0x00affa000000ffff /* 0xe033 ring 3 code, 64-bit mode */
234 .quad 0x0000000000000000 /* unused */
235 .fill 4*NR_CPUS,8,0 /* space for TSS and LDT per CPU */
237 /* Initial PML4 -- level-4 page table. */
238 .org 0x2000
239 ENTRY(idle_pg_table)
240 ENTRY(idle_pg_table_4)
241 .quad idle_pg_table_l3 - __PAGE_OFFSET + 7 # PML4[0]
242 .fill 261,8,0
243 .quad idle_pg_table_l3 - __PAGE_OFFSET + 7 # PML4[262]
245 /* Initial PDP -- level-3 page table. */
246 .org 0x3000
247 ENTRY(idle_pg_table_l3)
248 .quad idle_pg_table_l2 - __PAGE_OFFSET + 7
250 .org 0x4000
251 /* Maximum STACK_ORDER for x86/64 is 2. We must therefore ensure that the */
252 /* CPU0 stack is aligned on a 4-page boundary. */
253 ENTRY(cpu0_stack)
255 /* Initial PDE -- level-2 page table. Maps first 64MB physical memory. */
256 .org 0x4000 + STACK_SIZE
257 ENTRY(idle_pg_table_l2)
258 .macro identmap from=0, count=32
259 .if \count-1
260 identmap "(\from+0)","(\count/2)"
261 identmap "(\from+(0x200000*(\count/2)))","(\count/2)"
262 .else
263 .quad 0x00000000000001e3 + \from
264 .endif
265 .endm
266 identmap /* Too orangey for crows :-) */
268 .org 0x4000 + STACK_SIZE + PAGE_SIZE
269 .code64
270 ENTRY(stext)
271 ENTRY(_stext)