ia64/xen-unstable

view xen/arch/x86/boot/head.S @ 16192:118a21c66fd5

x86: small boot-time changes:
* use memory 0x8c000-0x90000 to avoid trampling the area above
0x90000 -- some bootloaders may leave droppings in that region
* reserve 2kB for vga mode table -- limit of 128 VESA modes could
overflow the original 1kB allocation
* remove unnecessary alignment of trampoline GDT
author Keir Fraser <keir@xensource.com>
date Mon Oct 22 21:06:11 2007 +0100 (2007-10-22)
parents 24379dde8ac4
children a7f8ff1ca311
line source
1 #include <xen/config.h>
2 #include <xen/multiboot.h>
3 #include <public/xen.h>
4 #include <asm/asm_defns.h>
5 #include <asm/desc.h>
6 #include <asm/page.h>
7 #include <asm/msr.h>
9 .text
10 .code32
12 #undef bootsym_phys
13 #define sym_phys(sym) ((sym) - __XEN_VIRT_START)
14 #define bootsym_phys(sym) ((sym) - trampoline_start + BOOT_TRAMPOLINE)
16 #define BOOT_CS32 0x0008
17 #define BOOT_CS64 0x0010
18 #define BOOT_DS 0x0018
19 #define BOOT_PSEUDORM_CS 0x0020
20 #define BOOT_PSEUDORM_DS 0x0028
22 ENTRY(start)
23 jmp __start
25 .align 4
26 /*** MULTIBOOT HEADER ****/
27 #define MULTIBOOT_HEADER_FLAGS (MULTIBOOT_HEADER_MODS_ALIGNED | \
28 MULTIBOOT_HEADER_WANT_MEMORY)
29 /* Magic number indicating a Multiboot header. */
30 .long MULTIBOOT_HEADER_MAGIC
31 /* Flags to bootloader (see Multiboot spec). */
32 .long MULTIBOOT_HEADER_FLAGS
33 /* Checksum: must be the negated sum of the first two fields. */
34 .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
36 .section .init.text
38 .Lbad_cpu_msg: .asciz "ERR: Not a 64-bit CPU!"
39 .Lbad_ldr_msg: .asciz "ERR: Not a Multiboot bootloader!"
41 bad_cpu:
42 mov $(sym_phys(.Lbad_cpu_msg)),%esi # Error message
43 jmp print_err
44 not_multiboot:
45 mov $(sym_phys(.Lbad_ldr_msg)),%esi # Error message
46 print_err:
47 mov $0xB8000,%edi # VGA framebuffer
48 1: mov (%esi),%bl
49 test %bl,%bl # Terminate on '\0' sentinel
50 2: je 2b
51 mov $0x3f8+5,%dx # UART Line Status Register
52 3: in %dx,%al
53 test $0x20,%al # Test THR Empty flag
54 je 3b
55 mov $0x3f8+0,%dx # UART Transmit Holding Register
56 mov %bl,%al
57 out %al,%dx # Send a character over the serial line
58 movsb # Write a character to the VGA framebuffer
59 mov $7,%al
60 stosb # Write an attribute to the VGA framebuffer
61 jmp 1b
63 gdt_boot_descr:
64 .word 6*8-1
65 .long sym_phys(trampoline_gdt)
67 __start:
68 cld
69 cli
71 /* Initialise GDT and basic data segments. */
72 lgdt %cs:sym_phys(gdt_boot_descr)
73 mov $BOOT_DS,%ecx
74 mov %ecx,%ds
75 mov %ecx,%es
76 mov %ecx,%ss
78 /* Check for Multiboot bootloader */
79 cmp $0x2BADB002,%eax
80 jne not_multiboot
82 /* Save the Multiboot info structure for later use. */
83 mov %ebx,sym_phys(multiboot_ptr)
85 /* Initialize BSS (no nasty surprises!) */
86 mov $sym_phys(__bss_start),%edi
87 mov $sym_phys(_end),%ecx
88 sub %edi,%ecx
89 xor %eax,%eax
90 rep stosb
92 /* Interrogate CPU extended features via CPUID. */
93 mov $0x80000000,%eax
94 cpuid
95 xor %edx,%edx
96 cmp $0x80000000,%eax # any function > 0x80000000?
97 jbe 1f
98 mov $0x80000001,%eax
99 cpuid
100 1: mov %edx,sym_phys(cpuid_ext_features)
102 #if defined(__x86_64__)
103 /* Check for availability of long mode. */
104 bt $29,%edx
105 jnc bad_cpu
106 /* Initialise L2 identity-map and xen page table entries (16MB). */
107 mov $sym_phys(l2_identmap),%edi
108 mov $sym_phys(l2_xenmap),%esi
109 mov $0x1e3,%eax /* PRESENT+RW+A+D+2MB+GLOBAL */
110 mov $8,%ecx
111 1: mov %eax,(%edi)
112 add $8,%edi
113 mov %eax,(%esi)
114 add $8,%esi
115 add $(1<<L2_PAGETABLE_SHIFT),%eax
116 loop 1b
117 /* Initialise L3 identity-map page directory entries. */
118 mov $sym_phys(l3_identmap),%edi
119 mov $(sym_phys(l2_identmap)+7),%eax
120 mov $4,%ecx
121 1: mov %eax,(%edi)
122 add $8,%edi
123 add $PAGE_SIZE,%eax
124 loop 1b
125 /* Initialise L3 xen-map page directory entry. */
126 mov $(sym_phys(l2_xenmap)+7),%eax
127 mov %eax,sym_phys(l3_xenmap) + (50*8)
128 /* Hook indentity-map and xen-map L3 tables into PML4. */
129 mov $(sym_phys(l3_identmap)+7),%eax
130 mov %eax,sym_phys(idle_pg_table) + ( 0*8) /* PML4[ 0]: 1:1 map */
131 mov %eax,sym_phys(idle_pg_table) + (262*8) /* PML4[262]: 1:1 map */
132 mov $(sym_phys(l3_xenmap)+7),%eax
133 mov %eax,sym_phys(idle_pg_table) + (261*8) /* PML4[261]: xen map */
134 #elif defined(CONFIG_X86_PAE)
135 /* Initialize low and high mappings of memory with 2MB pages */
136 mov $sym_phys(idle_pg_table_l2),%edi
137 mov $0xe3,%eax /* PRESENT+RW+A+D+2MB */
138 1: mov %eax,__PAGE_OFFSET>>18(%edi) /* high mapping */
139 stosl /* low mapping */
140 add $4,%edi
141 add $(1<<L2_PAGETABLE_SHIFT),%eax
142 cmp $DIRECTMAP_PHYS_END+0xe3,%eax
143 jne 1b
144 1: stosl /* low mappings cover up to 16MB */
145 add $4,%edi
146 add $(1<<L2_PAGETABLE_SHIFT),%eax
147 cmp $(16<<20)+0xe3,%eax
148 jne 1b
149 #else
150 /* Initialize low and high mappings of memory with 4MB pages */
151 mov $sym_phys(idle_pg_table),%edi
152 mov $0xe3,%eax /* PRESENT+RW+A+D+4MB */
153 1: mov %eax,__PAGE_OFFSET>>20(%edi) /* high mapping */
154 stosl /* low mapping */
155 add $(1<<L2_PAGETABLE_SHIFT),%eax
156 cmp $DIRECTMAP_PHYS_END+0xe3,%eax
157 jne 1b
158 1: stosl /* low mappings cover up to 16MB */
159 add $(1<<L2_PAGETABLE_SHIFT),%eax
160 cmp $(16<<20)+0xe3,%eax
161 jne 1b
162 #endif
164 /* Copy bootstrap trampoline to low memory, below 1MB. */
165 mov $sym_phys(trampoline_start),%esi
166 mov $bootsym_phys(trampoline_start),%edi
167 mov $trampoline_end - trampoline_start,%ecx
168 rep movsb
170 mov $0x90000,%esp
171 call cmdline_parse_early
173 /* Jump into the relocated trampoline. */
174 jmp $BOOT_CS32,$bootsym_phys(trampoline_boot_cpu_entry)
176 #include "cmdline.S"
178 .align 16
179 .globl trampoline_start, trampoline_end
180 trampoline_start:
181 #include "trampoline.S"
182 #include "wakeup.S"
183 trampoline_end:
185 .text
186 __high_start:
187 #ifdef __x86_64__
188 #include "x86_64.S"
189 #else
190 #include "x86_32.S"
191 #endif