debuggers.hg
annotate xen/arch/x86/setup.c @ 3658:0ef6e8e6e85d
bitkeeper revision 1.1159.212.71 (4200f0afX_JumfbEHQex6TdFENULMQ)
Merge labyrinth.cl.cam.ac.uk:/auto/groups/xeno-xenod/BK/xen-unstable.bk
into labyrinth.cl.cam.ac.uk:/auto/groups/xeno/users/iap10/xeno-clone/xen-unstable.bk
Merge labyrinth.cl.cam.ac.uk:/auto/groups/xeno-xenod/BK/xen-unstable.bk
into labyrinth.cl.cam.ac.uk:/auto/groups/xeno/users/iap10/xeno-clone/xen-unstable.bk
author | iap10@labyrinth.cl.cam.ac.uk |
---|---|
date | Wed Feb 02 15:24:31 2005 +0000 (2005-02-02) |
parents | fec8b1778268 552dd1f1c64c |
children | 060c1ea52343 |
rev | line source |
---|---|
kaf24@1490 | 1 |
kaf24@1490 | 2 #include <xen/config.h> |
kaf24@1490 | 3 #include <xen/init.h> |
kaf24@1490 | 4 #include <xen/lib.h> |
kaf24@1490 | 5 #include <xen/sched.h> |
kaf24@1490 | 6 #include <xen/pci.h> |
kaf24@1490 | 7 #include <xen/serial.h> |
kaf24@1544 | 8 #include <xen/softirq.h> |
kaf24@1490 | 9 #include <xen/acpi.h> |
kaf24@3376 | 10 #include <xen/console.h> |
kaf24@3376 | 11 #include <xen/trace.h> |
kaf24@3376 | 12 #include <xen/multiboot.h> |
kaf24@1490 | 13 #include <asm/bitops.h> |
kaf24@1490 | 14 #include <asm/smp.h> |
kaf24@1490 | 15 #include <asm/processor.h> |
kaf24@1490 | 16 #include <asm/mpspec.h> |
kaf24@1490 | 17 #include <asm/apic.h> |
kaf24@1490 | 18 #include <asm/desc.h> |
kaf24@1490 | 19 #include <asm/domain_page.h> |
kaf24@1490 | 20 #include <asm/pdb.h> |
kaf24@3376 | 21 #include <asm/shadow.h> |
kaf24@3382 | 22 #include <asm/e820.h> |
kaf24@3376 | 23 |
kaf24@3376 | 24 /* opt_dom0_mem: Kilobytes of memory allocated to domain 0. */ |
kaf24@3376 | 25 static unsigned int opt_dom0_mem = 16000; |
kaf24@3376 | 26 integer_param("dom0_mem", opt_dom0_mem); |
kaf24@3376 | 27 |
kaf24@3376 | 28 /* |
kaf24@3376 | 29 * opt_xenheap_megabytes: Size of Xen heap in megabytes, excluding the |
kaf24@3376 | 30 * pfn_info table and allocation bitmap. |
kaf24@3376 | 31 */ |
kaf24@3376 | 32 static unsigned int opt_xenheap_megabytes = XENHEAP_DEFAULT_MB; |
kaf24@3392 | 33 #if defined(__x86_64__) |
kaf24@3376 | 34 integer_param("xenheap_megabytes", opt_xenheap_megabytes); |
kaf24@3392 | 35 #endif |
kaf24@1490 | 36 |
kaf24@3372 | 37 /* opt_noht: If true, Hyperthreading is ignored. */ |
kaf24@3372 | 38 int opt_noht = 0; |
kaf24@3372 | 39 boolean_param("noht", opt_noht); |
kaf24@3372 | 40 |
kaf24@3372 | 41 /* opt_noacpi: If true, ACPI tables are not parsed. */ |
kaf24@3372 | 42 static int opt_noacpi = 0; |
kaf24@3372 | 43 boolean_param("noacpi", opt_noacpi); |
kaf24@3372 | 44 |
kaf24@3372 | 45 /* opt_nosmp: If true, secondary processors are ignored. */ |
kaf24@3372 | 46 static int opt_nosmp = 0; |
kaf24@3372 | 47 boolean_param("nosmp", opt_nosmp); |
kaf24@3372 | 48 |
kaf24@3372 | 49 /* opt_ignorebiostables: If true, ACPI and MP tables are ignored. */ |
kaf24@3372 | 50 /* NB. This flag implies 'nosmp' and 'noacpi'. */ |
kaf24@3372 | 51 static int opt_ignorebiostables = 0; |
kaf24@3372 | 52 boolean_param("ignorebiostables", opt_ignorebiostables); |
kaf24@3372 | 53 |
kaf24@3372 | 54 /* opt_watchdog: If true, run a watchdog NMI on each processor. */ |
kaf24@3372 | 55 static int opt_watchdog = 0; |
kaf24@3372 | 56 boolean_param("watchdog", opt_watchdog); |
kaf24@3372 | 57 |
kaf24@3632 | 58 int early_boot = 1; |
kaf24@3632 | 59 |
kaf24@3376 | 60 unsigned long xenheap_phys_end; |
kaf24@3376 | 61 |
kaf24@2336 | 62 extern void arch_init_memory(void); |
kaf24@1627 | 63 extern void init_IRQ(void); |
kaf24@1627 | 64 extern void trap_init(void); |
kaf24@1627 | 65 extern void time_init(void); |
kaf24@1627 | 66 extern void ac_timer_init(void); |
kaf24@1627 | 67 extern void initialize_keytable(); |
kaf24@1627 | 68 extern int do_timer_lists_from_pit; |
kaf24@1627 | 69 |
kaf24@1490 | 70 char ignore_irq13; /* set if exception 16 works */ |
kaf24@1518 | 71 struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1 }; |
kaf24@1490 | 72 |
kaf24@1708 | 73 #if defined(__x86_64__) |
kaf24@1708 | 74 unsigned long mmu_cr4_features = X86_CR4_PSE | X86_CR4_PGE | X86_CR4_PAE; |
kaf24@1708 | 75 #else |
kaf24@1490 | 76 unsigned long mmu_cr4_features = X86_CR4_PSE | X86_CR4_PGE; |
kaf24@1708 | 77 #endif |
kaf24@1490 | 78 EXPORT_SYMBOL(mmu_cr4_features); |
kaf24@1490 | 79 |
kaf24@1490 | 80 unsigned long wait_init_idle; |
kaf24@1490 | 81 |
cl349@2957 | 82 struct exec_domain *idle_task[NR_CPUS] = { &idle0_exec_domain }; |
kaf24@1490 | 83 |
kaf24@1490 | 84 #ifdef CONFIG_ACPI_INTERPRETER |
kaf24@1490 | 85 int acpi_disabled = 0; |
kaf24@1490 | 86 #else |
kaf24@1490 | 87 int acpi_disabled = 1; |
kaf24@1490 | 88 #endif |
kaf24@1490 | 89 EXPORT_SYMBOL(acpi_disabled); |
kaf24@1490 | 90 |
kaf24@1490 | 91 int phys_proc_id[NR_CPUS]; |
kaf24@1490 | 92 int logical_proc_id[NR_CPUS]; |
kaf24@1490 | 93 |
kaf24@1710 | 94 #if defined(__i386__) |
kaf24@1710 | 95 |
kaf24@1490 | 96 /* Standard macro to see if a specific flag is changeable */ |
kaf24@1490 | 97 static inline int flag_is_changeable_p(u32 flag) |
kaf24@1490 | 98 { |
kaf24@1490 | 99 u32 f1, f2; |
kaf24@1490 | 100 |
kaf24@1490 | 101 asm("pushfl\n\t" |
kaf24@1490 | 102 "pushfl\n\t" |
kaf24@1490 | 103 "popl %0\n\t" |
kaf24@1490 | 104 "movl %0,%1\n\t" |
kaf24@1490 | 105 "xorl %2,%0\n\t" |
kaf24@1490 | 106 "pushl %0\n\t" |
kaf24@1490 | 107 "popfl\n\t" |
kaf24@1490 | 108 "pushfl\n\t" |
kaf24@1490 | 109 "popl %0\n\t" |
kaf24@1490 | 110 "popfl\n\t" |
kaf24@1490 | 111 : "=&r" (f1), "=&r" (f2) |
kaf24@1490 | 112 : "ir" (flag)); |
kaf24@1490 | 113 |
kaf24@1490 | 114 return ((f1^f2) & flag) != 0; |
kaf24@1490 | 115 } |
kaf24@1490 | 116 |
kaf24@1490 | 117 /* Probe for the CPUID instruction */ |
kaf24@1490 | 118 static int __init have_cpuid_p(void) |
kaf24@1490 | 119 { |
kaf24@1490 | 120 return flag_is_changeable_p(X86_EFLAGS_ID); |
kaf24@1490 | 121 } |
kaf24@1490 | 122 |
kaf24@1710 | 123 #elif defined(__x86_64__) |
kaf24@1710 | 124 |
kaf24@1710 | 125 #define have_cpuid_p() (1) |
kaf24@1710 | 126 |
kaf24@1710 | 127 #endif |
kaf24@1710 | 128 |
kaf24@1490 | 129 void __init get_cpu_vendor(struct cpuinfo_x86 *c) |
kaf24@1490 | 130 { |
kaf24@1490 | 131 char *v = c->x86_vendor_id; |
kaf24@1490 | 132 |
kaf24@1490 | 133 if (!strcmp(v, "GenuineIntel")) |
kaf24@1490 | 134 c->x86_vendor = X86_VENDOR_INTEL; |
kaf24@1490 | 135 else if (!strcmp(v, "AuthenticAMD")) |
kaf24@1490 | 136 c->x86_vendor = X86_VENDOR_AMD; |
kaf24@1490 | 137 else if (!strcmp(v, "CyrixInstead")) |
kaf24@1490 | 138 c->x86_vendor = X86_VENDOR_CYRIX; |
kaf24@1490 | 139 else if (!strcmp(v, "UMC UMC UMC ")) |
kaf24@1490 | 140 c->x86_vendor = X86_VENDOR_UMC; |
kaf24@1490 | 141 else if (!strcmp(v, "CentaurHauls")) |
kaf24@1490 | 142 c->x86_vendor = X86_VENDOR_CENTAUR; |
kaf24@1490 | 143 else if (!strcmp(v, "NexGenDriven")) |
kaf24@1490 | 144 c->x86_vendor = X86_VENDOR_NEXGEN; |
kaf24@1490 | 145 else if (!strcmp(v, "RiseRiseRise")) |
kaf24@1490 | 146 c->x86_vendor = X86_VENDOR_RISE; |
kaf24@1490 | 147 else if (!strcmp(v, "GenuineTMx86") || |
kaf24@1490 | 148 !strcmp(v, "TransmetaCPU")) |
kaf24@1490 | 149 c->x86_vendor = X86_VENDOR_TRANSMETA; |
kaf24@1490 | 150 else |
kaf24@1490 | 151 c->x86_vendor = X86_VENDOR_UNKNOWN; |
kaf24@1490 | 152 } |
kaf24@1490 | 153 |
kaf24@1490 | 154 static void __init init_intel(struct cpuinfo_x86 *c) |
kaf24@1490 | 155 { |
kaf24@1490 | 156 /* SEP CPUID bug: Pentium Pro reports SEP but doesn't have it */ |
kaf24@1490 | 157 if ( c->x86 == 6 && c->x86_model < 3 && c->x86_mask < 3 ) |
kaf24@1490 | 158 clear_bit(X86_FEATURE_SEP, &c->x86_capability); |
kaf24@1490 | 159 |
kaf24@1490 | 160 #ifdef CONFIG_SMP |
kaf24@1490 | 161 if ( test_bit(X86_FEATURE_HT, &c->x86_capability) ) |
kaf24@1490 | 162 { |
kaf24@1490 | 163 u32 eax, ebx, ecx, edx; |
kaf24@1490 | 164 int initial_apic_id, siblings, cpu = smp_processor_id(); |
kaf24@1490 | 165 |
kaf24@1490 | 166 cpuid(1, &eax, &ebx, &ecx, &edx); |
cl349@2741 | 167 ht_per_core = siblings = (ebx & 0xff0000) >> 16; |
cl349@2741 | 168 |
cl349@2741 | 169 if ( opt_noht ) |
cl349@2741 | 170 clear_bit(X86_FEATURE_HT, &c->x86_capability[0]); |
cl349@2741 | 171 |
kaf24@1490 | 172 if ( siblings <= 1 ) |
kaf24@1490 | 173 { |
kaf24@1490 | 174 printk(KERN_INFO "CPU#%d: Hyper-Threading is disabled\n", cpu); |
kaf24@1490 | 175 } |
kaf24@1490 | 176 else if ( siblings > 2 ) |
kaf24@1490 | 177 { |
kaf24@1490 | 178 panic("We don't support more than two logical CPUs per package!"); |
kaf24@1490 | 179 } |
kaf24@1490 | 180 else |
kaf24@1490 | 181 { |
kaf24@1490 | 182 initial_apic_id = ebx >> 24 & 0xff; |
kaf24@1490 | 183 phys_proc_id[cpu] = initial_apic_id >> 1; |
kaf24@1490 | 184 logical_proc_id[cpu] = initial_apic_id & 1; |
kaf24@1490 | 185 printk(KERN_INFO "CPU#%d: Physical ID: %d, Logical ID: %d\n", |
kaf24@1490 | 186 cpu, phys_proc_id[cpu], logical_proc_id[cpu]); |
kaf24@1490 | 187 } |
kaf24@1490 | 188 } |
kaf24@1490 | 189 #endif |
iap10@3328 | 190 |
iap10@3328 | 191 #ifdef CONFIG_VMX |
iap10@3328 | 192 start_vmx(); |
iap10@3328 | 193 #endif |
iap10@3328 | 194 |
kaf24@1490 | 195 } |
kaf24@1490 | 196 |
kaf24@1490 | 197 static void __init init_amd(struct cpuinfo_x86 *c) |
kaf24@1490 | 198 { |
kaf24@1490 | 199 /* Bit 31 in normal CPUID used for nonstandard 3DNow ID; |
kaf24@1490 | 200 3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */ |
kaf24@1490 | 201 clear_bit(0*32+31, &c->x86_capability); |
kaf24@1490 | 202 |
kaf24@1490 | 203 switch(c->x86) |
kaf24@1490 | 204 { |
kaf24@1490 | 205 case 5: |
kaf24@1490 | 206 panic("AMD K6 is not supported.\n"); |
kaf24@1490 | 207 case 6: /* An Athlon/Duron. We can trust the BIOS probably */ |
kaf24@1490 | 208 break; |
kaf24@1490 | 209 } |
kaf24@1490 | 210 } |
kaf24@1490 | 211 |
kaf24@1490 | 212 /* |
kaf24@1490 | 213 * This does the hard work of actually picking apart the CPU stuff... |
kaf24@1490 | 214 */ |
kaf24@1490 | 215 void __init identify_cpu(struct cpuinfo_x86 *c) |
kaf24@1490 | 216 { |
kaf24@1490 | 217 int junk, i, cpu = smp_processor_id(); |
kaf24@1490 | 218 u32 xlvl, tfms; |
kaf24@1490 | 219 |
kaf24@1490 | 220 phys_proc_id[cpu] = cpu; |
kaf24@1490 | 221 logical_proc_id[cpu] = 0; |
kaf24@1490 | 222 |
kaf24@1490 | 223 c->x86_vendor = X86_VENDOR_UNKNOWN; |
kaf24@1490 | 224 c->cpuid_level = -1; /* CPUID not detected */ |
kaf24@1490 | 225 c->x86_model = c->x86_mask = 0; /* So far unknown... */ |
kaf24@1490 | 226 c->x86_vendor_id[0] = '\0'; /* Unset */ |
kaf24@1490 | 227 memset(&c->x86_capability, 0, sizeof c->x86_capability); |
kaf24@1490 | 228 |
kaf24@1490 | 229 if ( !have_cpuid_p() ) |
kaf24@1490 | 230 panic("Ancient processors not supported\n"); |
kaf24@1490 | 231 |
kaf24@1490 | 232 /* Get vendor name */ |
kaf24@1490 | 233 cpuid(0x00000000, &c->cpuid_level, |
kaf24@1490 | 234 (int *)&c->x86_vendor_id[0], |
kaf24@1490 | 235 (int *)&c->x86_vendor_id[8], |
kaf24@1490 | 236 (int *)&c->x86_vendor_id[4]); |
kaf24@1490 | 237 |
kaf24@1490 | 238 get_cpu_vendor(c); |
kaf24@1490 | 239 |
kaf24@1490 | 240 if ( c->cpuid_level == 0 ) |
kaf24@1490 | 241 panic("Decrepit CPUID not supported\n"); |
kaf24@1490 | 242 |
kaf24@1490 | 243 cpuid(0x00000001, &tfms, &junk, &junk, |
kaf24@1490 | 244 &c->x86_capability[0]); |
kaf24@1490 | 245 c->x86 = (tfms >> 8) & 15; |
kaf24@1490 | 246 c->x86_model = (tfms >> 4) & 15; |
kaf24@1490 | 247 c->x86_mask = tfms & 15; |
kaf24@1490 | 248 |
kaf24@1490 | 249 /* AMD-defined flags: level 0x80000001 */ |
kaf24@1490 | 250 xlvl = cpuid_eax(0x80000000); |
kaf24@1490 | 251 if ( (xlvl & 0xffff0000) == 0x80000000 ) { |
kaf24@1490 | 252 if ( xlvl >= 0x80000001 ) |
kaf24@1490 | 253 c->x86_capability[1] = cpuid_edx(0x80000001); |
kaf24@1490 | 254 } |
kaf24@1490 | 255 |
kaf24@1490 | 256 /* Transmeta-defined flags: level 0x80860001 */ |
kaf24@1490 | 257 xlvl = cpuid_eax(0x80860000); |
kaf24@1490 | 258 if ( (xlvl & 0xffff0000) == 0x80860000 ) { |
kaf24@1490 | 259 if ( xlvl >= 0x80860001 ) |
kaf24@1490 | 260 c->x86_capability[2] = cpuid_edx(0x80860001); |
kaf24@1490 | 261 } |
kaf24@1490 | 262 |
kaf24@1490 | 263 printk("CPU%d: Before vendor init, caps: %08x %08x %08x, vendor = %d\n", |
kaf24@1490 | 264 smp_processor_id(), |
kaf24@1490 | 265 c->x86_capability[0], |
kaf24@1490 | 266 c->x86_capability[1], |
kaf24@1490 | 267 c->x86_capability[2], |
kaf24@1490 | 268 c->x86_vendor); |
kaf24@1490 | 269 |
kaf24@1490 | 270 switch ( c->x86_vendor ) { |
kaf24@1490 | 271 case X86_VENDOR_INTEL: |
kaf24@1490 | 272 init_intel(c); |
kaf24@1490 | 273 break; |
kaf24@1490 | 274 case X86_VENDOR_AMD: |
kaf24@1490 | 275 init_amd(c); |
kaf24@1490 | 276 break; |
kaf24@1490 | 277 case X86_VENDOR_UNKNOWN: /* Connectix Virtual PC reports this */ |
kaf24@1490 | 278 break; |
kaf24@1490 | 279 case X86_VENDOR_CENTAUR: |
kaf24@1490 | 280 break; |
kaf24@1490 | 281 default: |
kaf24@1490 | 282 printk("Unknown CPU identifier (%d): continuing anyway, " |
kaf24@1490 | 283 "but might fail.\n", c->x86_vendor); |
kaf24@1490 | 284 } |
kaf24@1490 | 285 |
kaf24@1490 | 286 printk("CPU caps: %08x %08x %08x %08x\n", |
kaf24@1490 | 287 c->x86_capability[0], |
kaf24@1490 | 288 c->x86_capability[1], |
kaf24@1490 | 289 c->x86_capability[2], |
kaf24@1490 | 290 c->x86_capability[3]); |
kaf24@1490 | 291 |
kaf24@1490 | 292 /* |
kaf24@1490 | 293 * On SMP, boot_cpu_data holds the common feature set between |
kaf24@1490 | 294 * all CPUs; so make sure that we indicate which features are |
kaf24@1490 | 295 * common between the CPUs. The first time this routine gets |
kaf24@1490 | 296 * executed, c == &boot_cpu_data. |
kaf24@1490 | 297 */ |
kaf24@1490 | 298 if ( c != &boot_cpu_data ) { |
kaf24@1490 | 299 /* AND the already accumulated flags with these */ |
kaf24@1490 | 300 for ( i = 0 ; i < NCAPINTS ; i++ ) |
kaf24@1490 | 301 boot_cpu_data.x86_capability[i] &= c->x86_capability[i]; |
kaf24@1490 | 302 } |
kaf24@1490 | 303 } |
kaf24@1490 | 304 |
kaf24@1490 | 305 |
kaf24@1490 | 306 unsigned long cpu_initialized; |
kaf24@1490 | 307 void __init cpu_init(void) |
kaf24@1490 | 308 { |
kaf24@1710 | 309 #if defined(__i386__) /* XXX */ |
kaf24@1490 | 310 int nr = smp_processor_id(); |
kaf24@1490 | 311 struct tss_struct * t = &init_tss[nr]; |
kaf24@1490 | 312 |
kaf24@1490 | 313 if ( test_and_set_bit(nr, &cpu_initialized) ) |
kaf24@1490 | 314 panic("CPU#%d already initialized!!!\n", nr); |
kaf24@1490 | 315 printk("Initializing CPU#%d\n", nr); |
kaf24@1490 | 316 |
kaf24@3088 | 317 t->bitmap = IOBMP_INVALID_OFFSET; |
kaf24@1524 | 318 memset(t->io_bitmap, ~0, sizeof(t->io_bitmap)); |
kaf24@1524 | 319 |
kaf24@1490 | 320 /* Set up GDT and IDT. */ |
kaf24@1490 | 321 SET_GDT_ENTRIES(current, DEFAULT_GDT_ENTRIES); |
kaf24@1490 | 322 SET_GDT_ADDRESS(current, DEFAULT_GDT_ADDRESS); |
kaf24@1490 | 323 __asm__ __volatile__("lgdt %0": "=m" (*current->mm.gdt)); |
kaf24@1490 | 324 __asm__ __volatile__("lidt %0": "=m" (idt_descr)); |
kaf24@1490 | 325 |
kaf24@1490 | 326 /* No nested task. */ |
kaf24@1490 | 327 __asm__("pushfl ; andl $0xffffbfff,(%esp) ; popfl"); |
kaf24@1490 | 328 |
kaf24@1490 | 329 /* Ensure FPU gets initialised for each domain. */ |
kaf24@1490 | 330 stts(); |
kaf24@1490 | 331 |
kaf24@1490 | 332 /* Set up and load the per-CPU TSS and LDT. */ |
kaf24@1490 | 333 t->ss0 = __HYPERVISOR_DS; |
kaf24@1490 | 334 t->esp0 = get_stack_top(); |
kaf24@1490 | 335 set_tss_desc(nr,t); |
kaf24@1490 | 336 load_TR(nr); |
kaf24@1490 | 337 __asm__ __volatile__("lldt %%ax"::"a" (0)); |
kaf24@1490 | 338 |
kaf24@1490 | 339 /* Clear all 6 debug registers. */ |
kaf24@1490 | 340 #define CD(register) __asm__("movl %0,%%db" #register ::"r"(0) ); |
kaf24@1490 | 341 CD(0); CD(1); CD(2); CD(3); /* no db4 and db5 */; CD(6); CD(7); |
kaf24@1490 | 342 #undef CD |
kaf24@1490 | 343 |
kaf24@1490 | 344 /* Install correct page table. */ |
kaf24@1490 | 345 write_ptbase(¤t->mm); |
kaf24@1490 | 346 |
kaf24@1490 | 347 init_idle_task(); |
kaf24@1710 | 348 #endif |
kaf24@1490 | 349 } |
kaf24@1490 | 350 |
kaf24@1490 | 351 static void __init do_initcalls(void) |
kaf24@1490 | 352 { |
kaf24@1490 | 353 initcall_t *call; |
kaf24@1490 | 354 for ( call = &__initcall_start; call < &__initcall_end; call++ ) |
kaf24@1490 | 355 (*call)(); |
kaf24@1490 | 356 } |
kaf24@1490 | 357 |
kaf24@1490 | 358 unsigned long pci_mem_start = 0x10000000; |
kaf24@1490 | 359 |
kaf24@3376 | 360 static void __init start_of_day(void) |
kaf24@1490 | 361 { |
kaf24@1490 | 362 unsigned long low_mem_size; |
kaf24@1490 | 363 |
kaf24@1490 | 364 #ifdef MEMORY_GUARD |
kaf24@1490 | 365 /* Unmap the first page of CPU0's stack. */ |
kaf24@1490 | 366 extern unsigned long cpu0_stack[]; |
kaf24@1490 | 367 memguard_guard_range(cpu0_stack, PAGE_SIZE); |
kaf24@1490 | 368 #endif |
kaf24@1490 | 369 |
kaf24@1543 | 370 open_softirq(NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ, new_tlbflush_clock_period); |
kaf24@1490 | 371 |
kaf24@1490 | 372 if ( opt_watchdog ) |
kaf24@1490 | 373 nmi_watchdog = NMI_LOCAL_APIC; |
kaf24@1490 | 374 |
kaf24@3158 | 375 sort_exception_tables(); |
kaf24@3158 | 376 |
kaf24@3310 | 377 arch_do_createdomain(current); |
kaf24@3310 | 378 |
kaf24@1490 | 379 /* Tell the PCI layer not to allocate too close to the RAM area.. */ |
kaf24@1490 | 380 low_mem_size = ((max_page << PAGE_SHIFT) + 0xfffff) & ~0xfffff; |
kaf24@1490 | 381 if ( low_mem_size > pci_mem_start ) pci_mem_start = low_mem_size; |
kaf24@1490 | 382 |
kaf24@1490 | 383 identify_cpu(&boot_cpu_data); /* get CPU type info */ |
kaf24@1490 | 384 if ( cpu_has_fxsr ) set_in_cr4(X86_CR4_OSFXSR); |
kaf24@1490 | 385 if ( cpu_has_xmm ) set_in_cr4(X86_CR4_OSXMMEXCPT); |
kaf24@1490 | 386 #ifdef CONFIG_SMP |
kaf24@1490 | 387 if ( opt_ignorebiostables ) |
kaf24@1490 | 388 { |
kaf24@1490 | 389 opt_nosmp = 1; /* No SMP without configuration */ |
kaf24@1490 | 390 opt_noacpi = 1; /* ACPI will just confuse matters also */ |
kaf24@1490 | 391 } |
kaf24@1490 | 392 else |
kaf24@1490 | 393 { |
kaf24@1490 | 394 find_smp_config(); |
kaf24@1490 | 395 smp_alloc_memory(); /* trampoline which other CPUs jump at */ |
kaf24@1490 | 396 } |
kaf24@1490 | 397 #endif |
kaf24@1490 | 398 paging_init(); /* not much here now, but sets up fixmap */ |
kaf24@1490 | 399 if ( !opt_noacpi ) |
kaf24@1490 | 400 acpi_boot_init(); |
kaf24@1490 | 401 #ifdef CONFIG_SMP |
kaf24@1490 | 402 if ( smp_found_config ) |
kaf24@1490 | 403 get_smp_config(); |
kaf24@1490 | 404 #endif |
kaf24@1490 | 405 scheduler_init(); |
kaf24@1535 | 406 init_IRQ(); /* installs simple interrupt wrappers. Starts HZ clock. */ |
kaf24@1490 | 407 trap_init(); |
kaf24@1490 | 408 time_init(); /* installs software handler for HZ clock. */ |
kaf24@1490 | 409 init_apic_mappings(); /* make APICs addressable in our pagetables. */ |
kaf24@1490 | 410 |
kaf24@2336 | 411 arch_init_memory(); |
kaf24@2336 | 412 |
kaf24@1490 | 413 #ifndef CONFIG_SMP |
kaf24@1490 | 414 APIC_init_uniprocessor(); |
kaf24@1490 | 415 #else |
kaf24@1490 | 416 if ( opt_nosmp ) |
kaf24@1490 | 417 APIC_init_uniprocessor(); |
kaf24@1490 | 418 else |
kaf24@1490 | 419 smp_boot_cpus(); |
kaf24@1490 | 420 /* |
kaf24@1490 | 421 * Does loads of stuff, including kicking the local |
kaf24@1490 | 422 * APIC, and the IO APIC after other CPUs are booted. |
kaf24@1490 | 423 * Each IRQ is preferably handled by IO-APIC, but |
kaf24@1490 | 424 * fall thru to 8259A if we have to (but slower). |
kaf24@1490 | 425 */ |
kaf24@1490 | 426 #endif |
kaf24@1490 | 427 |
kaf24@1490 | 428 __sti(); |
kaf24@1490 | 429 |
kaf24@1543 | 430 initialize_keytable(); /* call back handling for key codes */ |
kaf24@1490 | 431 |
kaf24@1490 | 432 serial_init_stage2(); |
kaf24@1490 | 433 |
kaf24@1490 | 434 #ifdef XEN_DEBUGGER |
kaf24@1490 | 435 initialize_pdb(); /* pervasive debugger */ |
kaf24@1490 | 436 #endif |
kaf24@1490 | 437 |
kaf24@1490 | 438 if ( !cpu_has_apic ) |
kaf24@1490 | 439 { |
kaf24@1490 | 440 do_timer_lists_from_pit = 1; |
kaf24@1490 | 441 if ( smp_num_cpus != 1 ) |
kaf24@1490 | 442 panic("We need local APICs on SMP machines!"); |
kaf24@1490 | 443 } |
kaf24@1490 | 444 |
kaf24@1490 | 445 ac_timer_init(); /* init accurate timers */ |
kaf24@1490 | 446 init_xen_time(); /* initialise the time */ |
kaf24@1490 | 447 schedulers_start(); /* start scheduler for each CPU */ |
kaf24@1490 | 448 |
kaf24@1490 | 449 check_nmi_watchdog(); |
kaf24@1490 | 450 |
kaf24@1490 | 451 #ifdef CONFIG_PCI |
kaf24@1490 | 452 pci_init(); |
kaf24@1490 | 453 #endif |
kaf24@1490 | 454 do_initcalls(); |
kaf24@1490 | 455 |
kaf24@1490 | 456 #ifdef CONFIG_SMP |
kaf24@1490 | 457 wait_init_idle = cpu_online_map; |
kaf24@1490 | 458 clear_bit(smp_processor_id(), &wait_init_idle); |
kaf24@1490 | 459 smp_threads_ready = 1; |
kaf24@1490 | 460 smp_commence(); /* Tell other CPUs that state of the world is stable. */ |
kaf24@2382 | 461 while ( wait_init_idle != 0 ) |
kaf24@1490 | 462 { |
kaf24@1490 | 463 cpu_relax(); |
kaf24@1490 | 464 barrier(); |
kaf24@1490 | 465 } |
kaf24@1490 | 466 #endif |
kaf24@1490 | 467 |
kaf24@1490 | 468 watchdog_on = 1; |
kaf24@1490 | 469 } |
kaf24@3376 | 470 |
kaf24@3376 | 471 void __init __start_xen(multiboot_info_t *mbi) |
kaf24@3376 | 472 { |
kaf24@3376 | 473 unsigned char *cmdline; |
kaf24@3376 | 474 module_t *mod = (module_t *)__va(mbi->mods_addr); |
kaf24@3376 | 475 void *heap_start; |
kaf24@3392 | 476 unsigned long firsthole_start, nr_pages; |
kaf24@3376 | 477 unsigned long dom0_memory_start, dom0_memory_end; |
kaf24@3376 | 478 unsigned long initial_images_start, initial_images_end; |
kaf24@3382 | 479 struct e820entry e820_raw[E820MAX]; |
kaf24@3392 | 480 int i, e820_raw_nr = 0, bytes = 0; |
kaf24@3376 | 481 |
kaf24@3376 | 482 /* Parse the command-line options. */ |
kaf24@3382 | 483 if ( (mbi->flags & MBI_CMDLINE) && (mbi->cmdline != 0) ) |
kaf24@3382 | 484 cmdline_parse(__va(mbi->cmdline)); |
kaf24@3376 | 485 |
kaf24@3376 | 486 /* Must do this early -- e.g., spinlocks rely on get_current(). */ |
kaf24@3378 | 487 set_current(&idle0_exec_domain); |
kaf24@3376 | 488 |
kaf24@3376 | 489 /* We initialise the serial devices very early so we can get debugging. */ |
kaf24@3376 | 490 serial_init_stage1(); |
kaf24@3376 | 491 |
kaf24@3376 | 492 init_console(); |
kaf24@3376 | 493 |
kaf24@3382 | 494 /* Check that we have at least one Multiboot module. */ |
kaf24@3382 | 495 if ( !(mbi->flags & MBI_MODULES) || (mbi->mods_count == 0) ) |
kaf24@3376 | 496 { |
kaf24@3382 | 497 printk("FATAL ERROR: Require at least one Multiboot module.\n"); |
kaf24@3376 | 498 for ( ; ; ) ; |
kaf24@3376 | 499 } |
kaf24@3376 | 500 |
kaf24@3376 | 501 xenheap_phys_end = opt_xenheap_megabytes << 20; |
kaf24@3376 | 502 |
kaf24@3382 | 503 if ( mbi->flags & MBI_MEMMAP ) |
kaf24@3382 | 504 { |
kaf24@3382 | 505 while ( bytes < mbi->mmap_length ) |
kaf24@3382 | 506 { |
kaf24@3382 | 507 memory_map_t *map = __va(mbi->mmap_addr + bytes); |
kaf24@3382 | 508 e820_raw[e820_raw_nr].addr = |
kaf24@3382 | 509 ((u64)map->base_addr_high << 32) | (u64)map->base_addr_low; |
kaf24@3382 | 510 e820_raw[e820_raw_nr].size = |
kaf24@3382 | 511 ((u64)map->length_high << 32) | (u64)map->length_low; |
kaf24@3382 | 512 e820_raw[e820_raw_nr].type = |
kaf24@3384 | 513 (map->type > E820_SHARED_PAGE) ? E820_RESERVED : map->type; |
kaf24@3382 | 514 e820_raw_nr++; |
kaf24@3382 | 515 bytes += map->size + 4; |
kaf24@3382 | 516 } |
kaf24@3382 | 517 } |
kaf24@3382 | 518 else if ( mbi->flags & MBI_MEMLIMITS ) |
kaf24@3382 | 519 { |
kaf24@3382 | 520 e820_raw[0].addr = 0; |
kaf24@3382 | 521 e820_raw[0].size = mbi->mem_lower << 10; |
kaf24@3382 | 522 e820_raw[0].type = E820_RAM; |
kaf24@3392 | 523 e820_raw[1].addr = 0x100000; |
kaf24@3392 | 524 e820_raw[1].size = mbi->mem_upper << 10; |
kaf24@3392 | 525 e820_raw[1].type = E820_RAM; |
kaf24@3382 | 526 e820_raw_nr = 2; |
kaf24@3382 | 527 } |
kaf24@3382 | 528 else |
kaf24@3382 | 529 { |
kaf24@3382 | 530 printk("FATAL ERROR: Bootloader provided no memory information.\n"); |
kaf24@3382 | 531 for ( ; ; ) ; |
kaf24@3382 | 532 } |
kaf24@3382 | 533 |
kaf24@3392 | 534 max_page = init_e820(e820_raw, e820_raw_nr); |
kaf24@3376 | 535 |
kaf24@3392 | 536 /* Find the first high-memory RAM hole. */ |
kaf24@3392 | 537 for ( i = 0; i < e820.nr_map; i++ ) |
kaf24@3392 | 538 if ( (e820.map[i].type == E820_RAM) && |
kaf24@3392 | 539 (e820.map[i].addr >= 0x100000) ) |
kaf24@3392 | 540 break; |
kaf24@3392 | 541 firsthole_start = e820.map[i].addr + e820.map[i].size; |
kaf24@3376 | 542 |
kaf24@3392 | 543 /* Relocate the Multiboot modules. */ |
kaf24@3392 | 544 initial_images_start = xenheap_phys_end; |
kaf24@3376 | 545 initial_images_end = initial_images_start + |
kaf24@3376 | 546 (mod[mbi->mods_count-1].mod_end - mod[0].mod_start); |
kaf24@3392 | 547 if ( initial_images_end > firsthole_start ) |
kaf24@3376 | 548 { |
kaf24@3376 | 549 printk("Not enough memory to stash the DOM0 kernel image.\n"); |
kaf24@3376 | 550 for ( ; ; ) ; |
kaf24@3376 | 551 } |
kaf24@3392 | 552 #if defined(__i386__) |
kaf24@3376 | 553 memmove((void *)initial_images_start, /* use low mapping */ |
kaf24@3376 | 554 (void *)mod[0].mod_start, /* use low mapping */ |
kaf24@3376 | 555 mod[mbi->mods_count-1].mod_end - mod[0].mod_start); |
kaf24@3376 | 556 #elif defined(__x86_64__) |
kaf24@3376 | 557 memmove(__va(initial_images_start), |
kaf24@3376 | 558 __va(mod[0].mod_start), |
kaf24@3376 | 559 mod[mbi->mods_count-1].mod_end - mod[0].mod_start); |
kaf24@3376 | 560 #endif |
kaf24@3376 | 561 |
kaf24@3392 | 562 /* Initialise boot-time allocator with all RAM situated after modules. */ |
kaf24@3392 | 563 heap_start = memguard_init(&_end); |
kaf24@3392 | 564 heap_start = __va(init_boot_allocator(__pa(heap_start))); |
kaf24@3392 | 565 nr_pages = 0; |
kaf24@3392 | 566 for ( i = 0; i < e820.nr_map; i++ ) |
kaf24@3392 | 567 { |
kaf24@3392 | 568 if ( e820.map[i].type != E820_RAM ) |
kaf24@3392 | 569 continue; |
kaf24@3392 | 570 nr_pages += e820.map[i].size >> PAGE_SHIFT; |
kaf24@3392 | 571 if ( (e820.map[i].addr + e820.map[i].size) >= initial_images_end ) |
kaf24@3392 | 572 init_boot_pages((e820.map[i].addr < initial_images_end) ? |
kaf24@3392 | 573 initial_images_end : e820.map[i].addr, |
kaf24@3392 | 574 e820.map[i].addr + e820.map[i].size); |
kaf24@3392 | 575 } |
kaf24@3392 | 576 |
kaf24@3392 | 577 printk("System RAM: %luMB (%lukB)\n", |
kaf24@3392 | 578 nr_pages >> (20 - PAGE_SHIFT), |
kaf24@3392 | 579 nr_pages << (PAGE_SHIFT - 10)); |
kaf24@3392 | 580 |
kaf24@3392 | 581 /* Allocate an aligned chunk of RAM for DOM0. */ |
kaf24@3392 | 582 dom0_memory_start = alloc_boot_pages(opt_dom0_mem << 10, 4UL << 20); |
kaf24@3392 | 583 dom0_memory_end = dom0_memory_start + (opt_dom0_mem << 10); |
kaf24@3392 | 584 if ( dom0_memory_start == 0 ) |
kaf24@3376 | 585 { |
kaf24@3376 | 586 printk("Not enough memory for DOM0 memory reservation.\n"); |
kaf24@3376 | 587 for ( ; ; ) ; |
kaf24@3376 | 588 } |
kaf24@3376 | 589 |
kaf24@3392 | 590 init_frametable(); |
kaf24@3392 | 591 |
kaf24@3392 | 592 end_boot_allocator(); |
kaf24@3376 | 593 |
kaf24@3376 | 594 init_xenheap_pages(__pa(heap_start), xenheap_phys_end); |
kaf24@3392 | 595 printk("Xen heap: %luMB (%lukB)\n", |
kaf24@3392 | 596 (xenheap_phys_end-__pa(heap_start)) >> 20, |
kaf24@3392 | 597 (xenheap_phys_end-__pa(heap_start)) >> 10); |
kaf24@3376 | 598 |
kaf24@3632 | 599 early_boot = 0; |
kaf24@3632 | 600 |
iap10@3654 | 601 /* Initialise the slab allocator. */ |
iap10@3654 | 602 xmem_cache_init(); |
iap10@3654 | 603 xmem_cache_sizes_init(max_page); |
iap10@3654 | 604 |
kaf24@3376 | 605 start_of_day(); |
kaf24@3376 | 606 |
kaf24@3376 | 607 grant_table_init(); |
kaf24@3376 | 608 |
kaf24@3376 | 609 shadow_mode_init(); |
kaf24@3376 | 610 |
kaf24@3376 | 611 /* Create initial domain 0. */ |
kaf24@3376 | 612 dom0 = do_createdomain(0, 0); |
kaf24@3376 | 613 if ( dom0 == NULL ) |
kaf24@3376 | 614 panic("Error creating domain 0\n"); |
kaf24@3376 | 615 |
kaf24@3378 | 616 set_bit(DF_PRIVILEGED, &dom0->d_flags); |
kaf24@3376 | 617 |
kaf24@3376 | 618 /* Grab the DOM0 command line. Skip past the image name. */ |
kaf24@3376 | 619 cmdline = (unsigned char *)(mod[0].string ? __va(mod[0].string) : NULL); |
kaf24@3376 | 620 if ( cmdline != NULL ) |
kaf24@3376 | 621 { |
kaf24@3376 | 622 while ( *cmdline == ' ' ) cmdline++; |
kaf24@3376 | 623 if ( (cmdline = strchr(cmdline, ' ')) != NULL ) |
kaf24@3376 | 624 while ( *cmdline == ' ' ) cmdline++; |
kaf24@3376 | 625 } |
kaf24@3376 | 626 |
kaf24@3376 | 627 /* |
kaf24@3376 | 628 * We're going to setup domain0 using the module(s) that we stashed safely |
kaf24@3376 | 629 * above our heap. The second module, if present, is an initrd ramdisk. |
kaf24@3376 | 630 */ |
kaf24@3376 | 631 if ( construct_dom0(dom0, dom0_memory_start, dom0_memory_end, |
kaf24@3376 | 632 (char *)initial_images_start, |
kaf24@3376 | 633 mod[0].mod_end-mod[0].mod_start, |
kaf24@3376 | 634 (mbi->mods_count == 1) ? 0 : |
kaf24@3376 | 635 (char *)initial_images_start + |
kaf24@3376 | 636 (mod[1].mod_start-mod[0].mod_start), |
kaf24@3376 | 637 (mbi->mods_count == 1) ? 0 : |
kaf24@3376 | 638 mod[mbi->mods_count-1].mod_end - mod[1].mod_start, |
kaf24@3376 | 639 cmdline) != 0) |
kaf24@3376 | 640 panic("Could not set up DOM0 guest OS\n"); |
kaf24@3376 | 641 |
kaf24@3376 | 642 /* The stash space for the initial kernel image can now be freed up. */ |
kaf24@3392 | 643 init_domheap_pages(initial_images_start, initial_images_end); |
kaf24@3376 | 644 |
kaf24@3376 | 645 scrub_heap_pages(); |
kaf24@3376 | 646 |
kaf24@3376 | 647 init_trace_bufs(); |
kaf24@3376 | 648 |
kaf24@3376 | 649 /* Give up the VGA console if DOM0 is configured to grab it. */ |
kaf24@3376 | 650 console_endboot(cmdline && strstr(cmdline, "tty0")); |
kaf24@3376 | 651 |
kaf24@3378 | 652 domain_unpause_by_systemcontroller(current->domain); |
kaf24@3376 | 653 domain_unpause_by_systemcontroller(dom0); |
kaf24@3376 | 654 startup_cpu_idle_loop(); |
kaf24@3376 | 655 } |