debuggers.hg

view xen/arch/x86/boot/x86_64.S @ 3632:fec8b1778268

bitkeeper revision 1.1159.212.60 (41febc4bKKSkh9u-Zes9v2CmBuLZxA)

More bootstrap fixes for x86/64. Next thing to do is sort out the IDT and
get traps.c working; then we can get rid of a bunch of dummy labels from
end of boot/x86_64.S. We're also going to need some kind of entry.S before
we can safely enable interrupts. Also bear in mind that not all of physical
RAM may be mapped (only first 1GB) and no m2p table is yet allocated or
mapped. Plenty to be done!
author kaf24@viper.(none)
date Mon Jan 31 23:16:27 2005 +0000 (2005-01-31)
parents eef1949801b8
children ed902e5c4b49
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)
109 mov $(__HYPERVISOR_DS),%ecx
110 mov %ecx,%ds
111 mov %ecx,%es
112 mov %ecx,%ss
114 /* Enable full CR4 features. */
115 mov mmu_cr4_features(%rip),%rcx
116 mov %rcx,%cr4
118 mov stack_start(%rip),%rsp
120 /* Reset EFLAGS (subsumes CLI and CLD). */
121 pushq $0
122 popf
124 /* Jump to high mappings. */
125 mov high_start(%rip),%rax
126 push %rax
127 ret
128 __high_start:
130 lidt idt_descr(%rip)
132 cmp $(SECONDARY_CPU_FLAG),%ebx
133 je start_secondary
135 /* Initialize BSS (no nasty surprises!) */
136 lea __bss_start(%rip),%rdi
137 lea _end(%rip),%rcx
138 sub %rdi,%rcx
139 xor %rax,%rax
140 rep stosb
142 /* Initialise IDT with simple error defaults. */
143 lea ignore_int(%rip),%rdx
144 mov $(__HYPERVISOR_CS64 << 16),%eax
145 mov %dx,%ax /* selector = 0x0010 = cs */
146 mov $0x8E00,%dx /* interrupt gate - dpl=0, present */
147 lea idt_table(%rip),%rdi
148 mov $256,%rcx
149 1: mov %eax,(%rdi)
150 mov %edx,4(%rdi)
151 add $8,%rdi
152 loop 1b
154 /* Pass off the Multiboot info structure to C land. */
155 mov 0x1001e0,%edi
156 lea start(%rip),%rax
157 sub $0x100000,%rax
158 add %rax,%rdi
159 call __start_xen
160 ud2 /* Force a panic (invalid opcode). */
162 /* This is the default interrupt handler. */
163 int_msg:
164 .asciz "Unknown interrupt\n"
165 ignore_int:
166 cld
167 mov $(__HYPERVISOR_DS),%eax
168 mov %eax,%ds
169 mov %eax,%es
170 lea int_msg(%rip),%rdi
171 call SYMBOL_NAME(printf)
172 1: jmp 1b
174 .code32
176 .org 0x1e0
178 /*** DESCRIPTOR TABLES ***/
180 .globl SYMBOL_NAME(idt)
181 .globl SYMBOL_NAME(gdt)
183 .org 0x1f0
184 .word (LAST_RESERVED_GDT_ENTRY*8)+7
185 .long 0x100200 # gdt_table
187 .org 0x200
188 ENTRY(gdt_table)
189 .fill FIRST_RESERVED_GDT_ENTRY,8,0
190 .quad 0x0000000000000000 /* unused */
191 .quad 0x00cf9a000000ffff /* 0x0808 ring 0 code, compatability */
192 .quad 0x00af9a000000ffff /* 0x0810 ring 0 code, 64-bit mode */
193 .quad 0x00cf92000000ffff /* 0x0818 ring 0 data */
194 .quad 0x00cffa000000ffff /* 0x0823 ring 3 code, compatibility */
195 .quad 0x00affa000000ffff /* 0x082b ring 3 code, 64-bit mode */
196 .quad 0x00cff2000000ffff /* 0x0833 ring 3 data */
197 .quad 0x0000000000000000 /* unused */
198 .fill 2*NR_CPUS,8,0 /* space for TSS and LDT per CPU */
200 .word 0
201 gdt_descr:
202 .word (LAST_RESERVED_GDT_ENTRY*8)+7
203 SYMBOL_NAME(gdt):
204 .quad SYMBOL_NAME(gdt_table)
206 .word 0
207 idt_descr:
208 .word 256*8-1
209 SYMBOL_NAME(idt):
210 .quad SYMBOL_NAME(idt_table)
212 ENTRY(stack_start)
213 .quad SYMBOL_NAME(cpu0_stack) + 8100
215 high_start:
216 .quad __high_start
218 /* Initial PML4 -- level-4 page table */
219 .org 0x1000
220 ENTRY(idle_pg_table)
221 ENTRY(idle_pg_table_4)
222 .quad 0x0000000000102007 # PML4[0]
223 .fill 261,8,0
224 .quad 0x0000000000102007 # PML4[262]
226 /* Initial PDP -- level-3 page table */
227 .org 0x2000
228 ENTRY(idle_pg_table_l3)
229 .quad 0x0000000000103007
231 /* Initial PDE -- level-2 page table. */
232 .org 0x3000
233 ENTRY(idle_pg_table_l2)
234 .macro identmap from=0, count=512
235 .if \count-1
236 identmap "(\from+0)","(\count/2)"
237 identmap "(\from+(0x200000*(\count/2)))","(\count/2)"
238 .else
239 .quad 0x00000000000001e3 + \from
240 .endif
241 .endm
242 identmap /* Too orangey for crows :-) */
244 .org 0x4000
245 ENTRY(cpu0_stack) # Initial stack is 8kB
247 .org 0x6000
248 ENTRY(stext)
249 ENTRY(_stext)
251 .globl ret_from_intr, copy_to_user, set_intr_gate, die
252 ret_from_intr:
253 copy_to_user:
254 set_intr_gate:
255 die:
256 .globl copy_from_user, show_registers, do_iopl
257 copy_from_user:
258 show_registers:
259 do_iopl:
260 .globl idt_table, copy_user_generic, idt_tables, new_thread
261 idt_table:
262 copy_user_generic:
263 idt_tables:
264 new_thread:
265 .globl switch_to, __get_user_1, __get_user_4, __get_user_8, trap_init
266 switch_to:
267 __get_user_1:
268 __get_user_4:
269 __get_user_8:
270 trap_init:
271 .globl set_debugreg
272 set_debugreg: