direct-io.hg

view xen/arch/x86/boot/x86_64.S @ 3280:dda5ab69e74a

bitkeeper revision 1.1159.1.477 (41bf20d2wgoxIqhcE0nzBC8W-yFPhg)

sync w/ head.
author cl349@arcadians.cl.cam.ac.uk
date Tue Dec 14 17:20:18 2004 +0000 (2004-12-14)
parents 3f929065a1d1 da409d40699a
children c65b544a8c4e
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 cmain
161 /* This is the default interrupt handler. */
162 int_msg:
163 .asciz "Unknown interrupt\n"
164 ignore_int:
165 cld
166 mov $(__HYPERVISOR_DS),%eax
167 mov %eax,%ds
168 mov %eax,%es
169 lea int_msg(%rip),%rdi
170 call SYMBOL_NAME(printf)
171 1: jmp 1b
173 .code32
175 .org 0x1e0
177 /*** DESCRIPTOR TABLES ***/
179 .globl SYMBOL_NAME(idt)
180 .globl SYMBOL_NAME(gdt)
182 .org 0x1f0
183 .word (LAST_RESERVED_GDT_ENTRY*8)+7
184 .long 0x100200 # gdt_table
186 .org 0x200
187 ENTRY(gdt_table)
188 .fill FIRST_RESERVED_GDT_ENTRY,8,0
189 .quad 0x0000000000000000 /* unused */
190 .quad 0x00cf9a000000ffff /* 0x0808 ring 0 code, compatability */
191 .quad 0x00af9a000000ffff /* 0x0810 ring 0 code, 64-bit mode */
192 .quad 0x00cf92000000ffff /* 0x0818 ring 0 data */
193 .quad 0x00cffa000000ffff /* 0x0823 ring 3 code, compatibility */
194 .quad 0x00affa000000ffff /* 0x082b ring 3 code, 64-bit mode */
195 .quad 0x00cff2000000ffff /* 0x0833 ring 3 data */
196 .quad 0x0000000000000000 /* unused */
197 .fill 2*NR_CPUS,8,0 /* space for TSS and LDT per CPU */
199 .word 0
200 gdt_descr:
201 .word (LAST_RESERVED_GDT_ENTRY*8)+7
202 SYMBOL_NAME(gdt):
203 .quad SYMBOL_NAME(gdt_table)
205 .word 0
206 idt_descr:
207 .word 256*8-1
208 SYMBOL_NAME(idt):
209 .quad SYMBOL_NAME(idt_table)
211 ENTRY(stack_start)
212 .quad SYMBOL_NAME(cpu0_stack) + 8100
214 high_start:
215 .quad __high_start
217 /* Initial PML4 -- level-4 page table */
218 .org 0x1000
219 ENTRY(idle_pg_table)
220 ENTRY(idle_pg_table_4)
221 .quad 0x0000000000102007 # PML4[0]
222 .fill 261,8,0
223 .quad 0x0000000000102007 # PML4[262]
225 /* Initial PDP -- level-3 page table */
226 .org 0x2000
227 ENTRY(idle_pg_table_l3)
228 .quad 0x0000000000103007
230 /* Initial PDE -- level-2 page table. */
231 .org 0x3000
232 ENTRY(idle_pg_table_l2)
233 .macro identmap from=0, count=512
234 .if \count-1
235 identmap "(\from+0)","(\count/2)"
236 identmap "(\from+(0x200000*(\count/2)))","(\count/2)"
237 .else
238 .quad 0x00000000000001e3 + \from
239 .endif
240 .endm
241 identmap /* Too orangey for crows :-) */
243 .org 0x4000
244 ENTRY(cpu0_stack) # Initial stack is 8kB
246 .org 0x6000
247 ENTRY(stext)
248 ENTRY(_stext)
250 .globl map_domain_mem, unmap_domain_mem, ret_from_intr
251 map_domain_mem:
252 unmap_domain_mem:
253 ret_from_intr:
254 #undef machine_to_phys_mapping
255 .globl copy_to_user, set_intr_gate, die, machine_to_phys_mapping
256 copy_to_user:
257 set_intr_gate:
258 die:
259 machine_to_phys_mapping:
260 .globl copy_from_user, show_registers, do_iopl
261 copy_from_user:
262 show_registers:
263 do_iopl:
264 .globl idt_table, copy_user_generic, memcmp, idt_tables, new_thread
265 idt_table:
266 copy_user_generic:
267 memcmp:
268 idt_tables:
269 new_thread:
270 .globl switch_to, __get_user_1, __get_user_4, __get_user_8, trap_init
271 switch_to:
272 __get_user_1:
273 __get_user_4:
274 __get_user_8:
275 trap_init:
276 .globl set_debugreg
277 set_debugreg: