ia64/xen-unstable

view xen-2.4.16/arch/i386/boot/boot.S @ 86:4a10fe9b20ec

bitkeeper revision 1.15 (3e24a984iRiWWcgfKCxu2p5q3YbxXw)

Many files:
First half of support for per-domain GDTs and LDTs
author kaf24@labyrinth.cl.cam.ac.uk
date Wed Jan 15 00:21:24 2003 +0000 (2003-01-15)
parents c3e6a52cd801
children b46b05647a32 2c1ef70cc49f
line source
1 #include <xeno/config.h>
2 #include <asm/page.h>
4 #define SECONDARY_CPU_FLAG 0xA5A5A5A5
6 .text
8 ENTRY(start)
9 jmp hal_entry
11 .align 4
13 /*** MULTIBOOT HEADER ****/
14 /* Magic number indicating a Multiboot header. */
15 .long 0x1BADB002
16 /* Flags to bootloader (see Multiboot spec). */
17 .long 0x00000006
18 /* Checksum: must be the negated sum of the first two fields. */
19 .long -0x1BADB008
20 /* Unused loader addresses (ELF header has all this already).*/
21 .long 0,0,0,0,0
22 /* EGA text mode. */
23 .long 1,0,0,0
25 hal_entry:
26 /* Set up a few descriptors: on entry only CS is guaranteed good. */
27 lgdt %cs:nopaging_gdt_descr-__PAGE_OFFSET
28 mov $(__HYPERVISOR_DS),%ecx
29 mov %ecx,%ds
30 mov %ecx,%es
31 ljmp $(__HYPERVISOR_CS),$(1f)-__PAGE_OFFSET
32 1: lss stack_start-__PAGE_OFFSET,%esp
34 /* Reset EFLAGS (subsumes CLI and CLD). */
35 pushl $0
36 popf
38 /* CPU type checks. We need P6+. */
39 mov $0x200000,%edx
40 pushfl
41 pop %ecx
42 and %edx,%ecx
43 jne bad_cpu # ID bit should be clear
44 pushl %edx
45 popfl
46 pushfl
47 pop %ecx
48 and %edx,%ecx
49 je bad_cpu # ID bit should be set
51 /* Set up CR0. */
52 mov %cr0,%ecx
53 and $0x00000011,%ecx # save ET and PE
54 or $0x00050022,%ecx # set AM, WP, NE and MP
55 mov %ecx,%cr0
57 /* Set up FPU. */
58 fninit
60 /* Set up CR4, except global flag which Intel requires should be */
61 /* left until after paging is enabled (IA32 Manual Vol. 3, Sec. 2.5) */
62 mov %cr4,%ecx
63 or mmu_cr4_features-__PAGE_OFFSET,%ecx
64 mov %ecx,mmu_cr4_features-__PAGE_OFFSET
65 and $0x7f,%ecx /* disable GLOBAL bit */
66 mov %ecx,%cr4
68 /* Is this a non-boot processor? */
69 cmp $(SECONDARY_CPU_FLAG),%ebx
70 jne continue_boot_cpu
72 call start_paging
73 lidt idt_descr
74 jmp initialize_secondary
76 continue_boot_cpu:
77 add $__PAGE_OFFSET,%ebx
78 push %ebx /* Multiboot info struct */
79 push %eax /* Multiboot magic value */
81 /* Initialize BSS (no nasty surprises!) */
82 mov $__bss_start-__PAGE_OFFSET,%edi
83 mov $_end-__PAGE_OFFSET,%ecx
84 sub %edi,%ecx
85 xor %eax,%eax
86 rep stosb
88 /* Initialize low and high mappings of all memory with 4MB pages */
89 mov $idle0_pg_table-__PAGE_OFFSET,%edi
90 mov $0x1e3,%eax /* PRESENT+RW+A+D+4MB+GLOBAL */
91 1: mov %eax,__PAGE_OFFSET>>20(%edi) /* high mapping */
92 stosl /* low mapping */
93 add $(1<<L2_PAGETABLE_SHIFT),%eax
94 cmp $MAX_DIRECTMAP_ADDRESS+0x1e3,%eax
95 jne 1b
97 call start_paging
98 call setup_idt
99 lidt idt_descr
101 /* Call into main C routine. This should never return.*/
102 call cmain
103 ud2 /* Force a panic (invalid opcode). */
105 start_paging:
106 mov $idle0_pg_table-__PAGE_OFFSET,%eax
107 mov %eax,%cr3
108 mov %cr0,%eax
109 or $0x80010000,%eax /* set PG and WP bits */
110 mov %eax,%cr0
111 jmp 1f
112 1: /* Install relocated selectors (FS/GS unused). */
113 lgdt gdt_descr
114 mov $(__HYPERVISOR_DS),%ecx
115 mov %ecx,%ds
116 mov %ecx,%es
117 mov %ecx,%ss
118 ljmp $(__HYPERVISOR_CS),$1f
119 1: /* Paging enabled, so we can now enable GLOBAL mappings in CR4. */
120 movl mmu_cr4_features,%ecx
121 movl %ecx,%cr4
122 /* Relocate ESP */
123 add $__PAGE_OFFSET,%esp
124 /* Relocate EIP via return jump */
125 pop %ecx
126 add $__PAGE_OFFSET,%ecx
127 jmp *%ecx
130 /*** INTERRUPT INITIALISATION ***/
132 setup_idt:
133 lea ignore_int,%edx
134 mov $(__HYPERVISOR_CS << 16),%eax
135 mov %dx,%ax /* selector = 0x0010 = cs */
136 mov $0x8E00,%dx /* interrupt gate - dpl=0, present */
138 lea SYMBOL_NAME(idt_table),%edi
139 mov $256,%ecx
140 1: mov %eax,(%edi)
141 mov %edx,4(%edi)
142 add $8,%edi
143 loop 1b
144 ret
146 /* This is the default interrupt handler. */
147 int_msg:
148 .asciz "Unknown interrupt\n"
149 ALIGN
150 ignore_int:
151 cld
152 push %eax
153 push %ecx
154 push %edx
155 pushl %es
156 pushl %ds
157 mov $(__HYPERVISOR_DS),%eax
158 mov %eax,%ds
159 mov %eax,%es
160 pushl $int_msg
161 call SYMBOL_NAME(printf)
162 1: jmp 1b
163 pop %eax
164 popl %ds
165 popl %es
166 pop %edx
167 pop %ecx
168 pop %eax
169 iret
172 bad_cpu_msg:
173 .asciz "Bad CPU type. Need P6+."
174 ALIGN
175 bad_cpu:
176 call init_serial
177 mov $bad_cpu_msg,%esi
178 1: lodsb
179 test %al,%al
180 je 1f
181 push %eax
182 call putchar_serial
183 add $4,%esp
184 jmp 1b
185 1: jmp 1b
188 /*** STACK LOCATION ***/
190 ENTRY(stack_start)
191 .long SYMBOL_NAME(idle0_task_union)+8192-__PAGE_OFFSET
192 .long __HYPERVISOR_DS
194 /*** DESCRIPTOR TABLES ***/
196 .globl SYMBOL_NAME(idt)
197 .globl SYMBOL_NAME(gdt)
199 ALIGN
201 .word 0
202 idt_descr:
203 .word 256*8-1
204 SYMBOL_NAME(idt):
205 .long SYMBOL_NAME(idt_table)
207 .word 0
208 gdt_descr:
209 .word 256*8-1
210 SYMBOL_NAME(gdt):
211 .long SYMBOL_NAME(gdt_table) /* gdt base */
213 .word 0
214 nopaging_gdt_descr:
215 .word 256*8-1
216 .long SYMBOL_NAME(gdt_table)-__PAGE_OFFSET
218 ALIGN
219 ENTRY(gdt_table)
220 .quad 0x0000000000000000 /* NULL descriptor */
221 .quad 0x0000000000000000 /* not used */
222 .quad 0x00cfba000000bfff /* 0x11 ring 1 3.95GB code at 0x0 */
223 .quad 0x00cfb2000000bfff /* 0x19 ring 1 3.95GB data at 0x0 */
224 .quad 0x00cffa000000bfff /* 0x23 ring 3 3.95GB code at 0x0 */
225 .quad 0x00cff2000000bfff /* 0x2b ring 3 3.95GB data at 0x0 */
226 .quad 0x00cf9a000000ffff /* 0x30 ring 0 4.00GB code at 0x0 */
227 .quad 0x00cf92000000ffff /* 0x38 ring 0 4.00GB data at 0x0 */
228 .fill NR_CPUS,8,0 /* space for TSS's */
230 # The following adds 12kB to the kernel file size.
231 .org 0x1000
232 ENTRY(idle0_pg_table)
233 .org 0x2000
234 ENTRY(idle0_task_union)
235 .org 0x4000
236 ENTRY(stext)
237 ENTRY(_stext)