debuggers.hg

view xen/arch/x86/boot/x86_64.S @ 3635:ed902e5c4b49

bitkeeper revision 1.1159.212.62 (41fff40aESe4aWS82z_rLHeonXpxuQ)

More x86/64 stuff.
Signed-off-by: keir.fraser@cl.cam.ac.uk
author kaf24@scramble.cl.cam.ac.uk
date Tue Feb 01 21:26:34 2005 +0000 (2005-02-01)
parents fec8b1778268
children 9a9c5a491401 e6af5d8f8b39 fd1dd0663b09
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_DS),%ecx
56 mov %ecx,%ds
57 mov %ecx,%es
59 /* Check for Multiboot bootloader */
60 cmp $(SECONDARY_CPU_FLAG),%ebx
61 je skip_multiboot_check
62 cmp $0x2BADB002,%eax
63 jne not_multiboot
64 skip_multiboot_check:
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
79 /* Set up FPU. */
80 fninit
82 /* Enable PAE in CR4. */
83 mov $0x20,%ecx # X86_CR4_PAE
84 mov %ecx,%cr4
86 /* Load pagetable base register. */
87 mov $0x101000,%eax /* idle_pg_table */
88 mov %eax,%cr3
90 /* Set up EFER (Extended Feature Enable Register). */
91 movl $MSR_EFER, %ecx
92 rdmsr
93 /* Long Mode, SYSCALL/SYSRET, No-Execute */
94 movl $(EFER_LME|EFER_SCE|EFER_NX),%eax
95 wrmsr
97 mov $0x80050033,%eax /* hi-to-lo: PG,AM,WP,NE,ET,MP,PE */
98 mov %eax,%cr0
99 jmp 1f
101 1: /* Now in compatibility mode. Long-jump into 64-bit mode. */
102 ljmp $(__HYPERVISOR_CS64),$0x100100
104 .code64
105 .org 0x0100
107 /* Install relocated selectors (FS/GS unused). */
108 lgdt gdt_descr(%rip)
110 /* Enable full CR4 features. */
111 mov mmu_cr4_features(%rip),%rcx
112 mov %rcx,%cr4
114 mov stack_start(%rip),%rsp
116 /* Reset EFLAGS (subsumes CLI and CLD). */
117 pushq $0
118 popf
120 /* Jump to high mappings. */
121 mov high_start(%rip),%rax
122 push %rax
123 ret
124 __high_start:
126 lidt idt_descr(%rip)
128 cmp $(SECONDARY_CPU_FLAG),%ebx
129 je start_secondary
131 /* Initialize BSS (no nasty surprises!) */
132 lea __bss_start(%rip),%rdi
133 lea _end(%rip),%rcx
134 sub %rdi,%rcx
135 xor %rax,%rax
136 rep stosb
138 /* Initialise IDT with simple error defaults. */
139 lea ignore_int(%rip),%rdx
140 mov $(__HYPERVISOR_CS64 << 16),%eax
141 mov %dx,%ax /* selector = 0x0010 = cs */
142 mov $0x8E00,%dx /* interrupt gate - dpl=0, present */
143 lea idt_table(%rip),%rdi
144 mov $256,%rcx
145 1: mov %eax,(%rdi)
146 mov %edx,4(%rdi)
147 add $8,%rdi
148 loop 1b
150 /* Pass off the Multiboot info structure to C land. */
151 mov 0x1001e0,%edi
152 lea start(%rip),%rax
153 sub $0x100000,%rax
154 add %rax,%rdi
155 call __start_xen
156 ud2 /* Force a panic (invalid opcode). */
158 /* This is the default interrupt handler. */
159 int_msg:
160 .asciz "Unknown interrupt\n"
161 ignore_int:
162 cld
163 lea int_msg(%rip),%rdi
164 call SYMBOL_NAME(printf)
165 1: jmp 1b
167 .code32
169 .org 0x1e0
171 /*** DESCRIPTOR TABLES ***/
173 .globl SYMBOL_NAME(idt)
174 .globl SYMBOL_NAME(gdt)
176 .org 0x1f0
177 .word (LAST_RESERVED_GDT_ENTRY*8)+7
178 .long 0x100200 # gdt_table
180 .org 0x200
181 ENTRY(gdt_table)
182 .fill FIRST_RESERVED_GDT_ENTRY,8,0
183 .quad 0x0000000000000000 /* unused */
184 .quad 0x00cf9a000000ffff /* 0x0808 ring 0 code, compatability */
185 .quad 0x00af9a000000ffff /* 0x0810 ring 0 code, 64-bit mode */
186 .quad 0x00cf92000000ffff /* 0x0818 ring 0 data */
187 .quad 0x00cffa000000ffff /* 0x0823 ring 3 code, compatibility */
188 .quad 0x00affa000000ffff /* 0x082b ring 3 code, 64-bit mode */
189 .quad 0x00cff2000000ffff /* 0x0833 ring 3 data */
190 .quad 0x0000000000000000 /* unused */
191 .fill 2*NR_CPUS,8,0 /* space for TSS and LDT per CPU */
193 .word 0
194 gdt_descr:
195 .word (LAST_RESERVED_GDT_ENTRY*8)+7
196 SYMBOL_NAME(gdt):
197 .quad SYMBOL_NAME(gdt_table)
199 .word 0
200 idt_descr:
201 .word 256*8-1
202 SYMBOL_NAME(idt):
203 .quad SYMBOL_NAME(idt_table)
205 ENTRY(stack_start)
206 .quad SYMBOL_NAME(cpu0_stack) + 8100
208 high_start:
209 .quad __high_start
211 /* Initial PML4 -- level-4 page table */
212 .org 0x1000
213 ENTRY(idle_pg_table)
214 ENTRY(idle_pg_table_4)
215 .quad 0x0000000000102007 # PML4[0]
216 .fill 261,8,0
217 .quad 0x0000000000102007 # PML4[262]
219 /* Initial PDP -- level-3 page table */
220 .org 0x2000
221 ENTRY(idle_pg_table_l3)
222 .quad 0x0000000000103007
224 /* Initial PDE -- level-2 page table. */
225 .org 0x3000
226 ENTRY(idle_pg_table_l2)
227 .macro identmap from=0, count=512
228 .if \count-1
229 identmap "(\from+0)","(\count/2)"
230 identmap "(\from+(0x200000*(\count/2)))","(\count/2)"
231 .else
232 .quad 0x00000000000001e3 + \from
233 .endif
234 .endm
235 identmap /* Too orangey for crows :-) */
237 .org 0x4000
238 ENTRY(cpu0_stack) # Initial stack is 8kB
240 .org 0x6000
241 ENTRY(stext)
242 ENTRY(_stext)
244 .globl ret_from_intr, copy_to_user, set_intr_gate, die
245 ret_from_intr:
246 copy_to_user:
247 set_intr_gate:
248 die:
249 .globl copy_from_user, show_registers, do_iopl
250 copy_from_user:
251 show_registers:
252 do_iopl:
253 .globl idt_table, copy_user_generic, idt_tables, new_thread
254 idt_table:
255 copy_user_generic:
256 idt_tables:
257 new_thread:
258 .globl switch_to, __get_user_1, __get_user_4, __get_user_8, trap_init
259 switch_to:
260 __get_user_1:
261 __get_user_4:
262 __get_user_8:
263 trap_init:
264 .globl set_debugreg
265 set_debugreg: