debuggers.hg

view xen/arch/x86/boot/x86_64.S @ 3659:bf2c38625b39

bitkeeper revision 1.1159.212.72 (42011b79Y7C9nEKFZ5pdQXwp8jC9hw)

More x86/64. Now boot secondary CPUs, but I seem to have problems
executing IRET, so interrupts are fatal.
Signed-off-by: keir.fraser@cl.cam.ac.uk
author kaf24@scramble.cl.cam.ac.uk
date Wed Feb 02 18:27:05 2005 +0000 (2005-02-02)
parents fd1dd0663b09
children 060c1ea52343
line source
1 #include <xen/config.h>
2 #include <public/xen.h>
3 #include <asm/page.h>
4 #include <asm/msr.h>
6 #define SECONDARY_CPU_FLAG 0xA5A5A5A5
8 .text
9 .code32
11 ENTRY(start)
12 jmp __start
14 .org 0x004
15 /*** MULTIBOOT HEADER ****/
16 /* Magic number indicating a Multiboot header. */
17 .long 0x1BADB002
18 /* Flags to bootloader (see Multiboot spec). */
19 .long 0x00000002
20 /* Checksum: must be the negated sum of the first two fields. */
21 .long -0x1BADB004
23 .org 0x010
24 .asciz "ERR: Not a 64-bit CPU!"
25 .org 0x028
26 .asciz "ERR: Not a Multiboot bootloader!"
27 bad_cpu:
28 mov $0x100010,%esi # Error message
29 jmp print_err
30 not_multiboot:
31 mov $0x100028,%esi # Error message
32 print_err:
33 mov $0xB8000,%edi # VGA framebuffer
34 1: mov (%esi),%bl
35 test %bl,%bl # Terminate on '\0' sentinel
36 2: je 2b
37 mov $0x3f8+5,%dx # UART Line Status Register
38 3: in %dx,%al
39 test $0x20,%al # Test THR Empty flag
40 je 3b
41 mov $0x3f8+0,%dx # UART Transmit Holding Register
42 mov %bl,%al
43 out %al,%dx # Send a character over the serial line
44 movsb # Write a character to the VGA framebuffer
45 mov $7,%al
46 stosb # Write an attribute to the VGA framebuffer
47 jmp 1b
49 __start:
50 cld
51 cli
53 /* Set up a few descriptors: on entry only CS is guaranteed good. */
54 lgdt %cs:0x1001f0
55 mov $(__HYPERVISOR_DS32),%ecx
56 mov %ecx,%ds
57 mov %ecx,%es
59 cmp $(SECONDARY_CPU_FLAG),%ebx
60 je skip_boot_checks
62 /* Check for Multiboot bootloader */
63 cmp $0x2BADB002,%eax
64 jne not_multiboot
66 /* Save the Multiboot info structure for later use. */
67 mov %ebx,0x1001e0
69 /* We begin by interrogating the CPU for the presence of long mode. */
70 mov $0x80000000,%eax
71 cpuid
72 cmp $0x80000000,%eax # any function > 0x80000000?
73 jbe bad_cpu
74 mov $0x80000001,%eax
75 cpuid
76 bt $29,%edx # Long mode feature?
77 jnc bad_cpu
78 skip_boot_checks:
80 /* Set up FPU. */
81 fninit
83 /* Enable PAE in CR4. */
84 mov $0x20,%ecx # X86_CR4_PAE
85 mov %ecx,%cr4
87 /* Load pagetable base register. */
88 mov $0x101000,%eax /* idle_pg_table */
89 mov %eax,%cr3
91 /* Set up EFER (Extended Feature Enable Register). */
92 movl $MSR_EFER, %ecx
93 rdmsr
94 /* Long Mode, SYSCALL/SYSRET, No-Execute */
95 movl $(EFER_LME|EFER_SCE|EFER_NX),%eax
96 wrmsr
98 mov $0x80050033,%eax /* hi-to-lo: PG,AM,WP,NE,ET,MP,PE */
99 mov %eax,%cr0
100 jmp 1f
102 1: /* Now in compatibility mode. Long-jump into 64-bit mode. */
103 ljmp $(__HYPERVISOR_CS64),$0x100100
105 .code64
106 .org 0x0100
108 /* Install relocated selectors (FS/GS unused). */
109 lgdt gdt_descr(%rip)
111 /* Enable full CR4 features. */
112 mov mmu_cr4_features(%rip),%rcx
113 mov %rcx,%cr4
115 mov stack_start(%rip),%rsp
117 /* Reset EFLAGS (subsumes CLI and CLD). */
118 pushq $0
119 popf
121 /* Jump to high mappings. */
122 mov high_start(%rip),%rax
123 push %rax
124 ret
125 __high_start:
127 mov $(__HYPERVISOR_DS64),%ecx
128 mov %ecx,%ds
129 mov %ecx,%es
130 mov %ecx,%fs
131 mov %ecx,%gs
132 mov %ecx,%ss
134 lidt idt_descr(%rip)
136 cmp $(SECONDARY_CPU_FLAG),%ebx
137 je start_secondary
139 /* Initialize BSS (no nasty surprises!) */
140 lea __bss_start(%rip),%rdi
141 lea _end(%rip),%rcx
142 sub %rdi,%rcx
143 xor %rax,%rax
144 rep stosb
146 /* Initialise IDT with simple error defaults. */
147 lea ignore_int(%rip),%rdx
148 mov $(__HYPERVISOR_CS64 << 16),%eax
149 mov %dx,%ax /* selector = 0x0010 = cs */
150 mov $0x8E00,%dx /* interrupt gate - dpl=0, present */
151 lea idt_table(%rip),%rdi
152 mov $256,%rcx
153 1: mov %eax,(%rdi)
154 mov %edx,4(%rdi)
155 add $8,%rdi
156 loop 1b
158 /* Pass off the Multiboot info structure to C land. */
159 mov 0x1001e0,%edi
160 lea start(%rip),%rax
161 sub $0x100000,%rax
162 add %rax,%rdi
163 call __start_xen
164 ud2 /* Force a panic (invalid opcode). */
166 /* This is the default interrupt handler. */
167 int_msg:
168 .asciz "Unknown interrupt\n"
169 ignore_int:
170 cld
171 lea int_msg(%rip),%rdi
172 call SYMBOL_NAME(printf)
173 1: jmp 1b
175 .code32
177 .org 0x1e0
179 /*** DESCRIPTOR TABLES ***/
181 .globl SYMBOL_NAME(idt)
182 .globl SYMBOL_NAME(gdt)
184 .org 0x1f0
185 .word (LAST_RESERVED_GDT_ENTRY*8)+7
186 .long 0x100200 # gdt_table
188 .org 0x200
189 ENTRY(gdt_table)
190 .fill FIRST_RESERVED_GDT_ENTRY,8,0
191 .quad 0x0000000000000000 /* unused */
192 .quad 0x00cf9a000000ffff /* 0x0808 ring 0 code, compatability */
193 .quad 0x00af9a000000ffff /* 0x0810 ring 0 code, 64-bit mode */
194 .quad 0x00cf92000000ffff /* 0x0818 ring 0 data */
195 .quad 0x00cffa000000ffff /* 0x0823 ring 3 code, compatibility */
196 .quad 0x00affa000000ffff /* 0x082b ring 3 code, 64-bit mode */
197 .quad 0x00cff2000000ffff /* 0x0833 ring 3 data */
198 .quad 0x0000000000000000 /* unused */
199 .fill 2*NR_CPUS,8,0 /* space for TSS and LDT per CPU */
201 .word 0
202 gdt_descr:
203 .word (LAST_RESERVED_GDT_ENTRY*8)+7
204 SYMBOL_NAME(gdt):
205 .quad SYMBOL_NAME(gdt_table)
207 .word 0
208 idt_descr:
209 .word 256*8-1
210 SYMBOL_NAME(idt):
211 .quad SYMBOL_NAME(idt_table)
213 ENTRY(stack_start)
214 .quad SYMBOL_NAME(cpu0_stack) + 8000
216 high_start:
217 .quad __high_start
219 /* Initial PML4 -- level-4 page table */
220 .org 0x1000
221 ENTRY(idle_pg_table)
222 ENTRY(idle_pg_table_4)
223 .quad 0x0000000000102007 # PML4[0]
224 .fill 261,8,0
225 .quad 0x0000000000102007 # PML4[262]
227 /* Initial PDP -- level-3 page table */
228 .org 0x2000
229 ENTRY(idle_pg_table_l3)
230 .quad 0x0000000000103007
232 /* Initial PDE -- level-2 page table. */
233 .org 0x3000
234 ENTRY(idle_pg_table_l2)
235 .macro identmap from=0, count=512
236 .if \count-1
237 identmap "(\from+0)","(\count/2)"
238 identmap "(\from+(0x200000*(\count/2)))","(\count/2)"
239 .else
240 .quad 0x00000000000001e3 + \from
241 .endif
242 .endm
243 identmap /* Too orangey for crows :-) */
245 .org 0x4000
246 ENTRY(cpu0_stack) # Initial stack is 8kB
248 .org 0x6000
249 ENTRY(stext)
250 ENTRY(_stext)
252 .globl switch_to, do_iopl
253 switch_to:
254 do_iopl:
255 .globl copy_from_user, copy_to_user, copy_user_generic, new_thread
256 copy_from_user:
257 copy_to_user:
258 copy_user_generic:
259 new_thread:
260 .globl __get_user_1, __get_user_4, __get_user_8
261 __get_user_1:
262 __get_user_4:
263 __get_user_8: