debuggers.hg

annotate xen/arch/x86/setup.c @ 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 d1e0d9a8fde0
children f98fa170a9f4 0ef6e8e6e85d
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(&current->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
kaf24@3376 601 /* Initialise the slab allocator. */
kaf24@3376 602 xmem_cache_init();
kaf24@3376 603 xmem_cache_sizes_init(max_page);
kaf24@3376 604
kaf24@3376 605 domain_startofday();
kaf24@3376 606
kaf24@3376 607 start_of_day();
kaf24@3376 608
kaf24@3376 609 grant_table_init();
kaf24@3376 610
kaf24@3376 611 shadow_mode_init();
kaf24@3376 612
kaf24@3376 613 /* Create initial domain 0. */
kaf24@3376 614 dom0 = do_createdomain(0, 0);
kaf24@3376 615 if ( dom0 == NULL )
kaf24@3376 616 panic("Error creating domain 0\n");
kaf24@3376 617
kaf24@3378 618 set_bit(DF_PRIVILEGED, &dom0->d_flags);
kaf24@3376 619
kaf24@3376 620 /* Grab the DOM0 command line. Skip past the image name. */
kaf24@3376 621 cmdline = (unsigned char *)(mod[0].string ? __va(mod[0].string) : NULL);
kaf24@3376 622 if ( cmdline != NULL )
kaf24@3376 623 {
kaf24@3376 624 while ( *cmdline == ' ' ) cmdline++;
kaf24@3376 625 if ( (cmdline = strchr(cmdline, ' ')) != NULL )
kaf24@3376 626 while ( *cmdline == ' ' ) cmdline++;
kaf24@3376 627 }
kaf24@3376 628
kaf24@3376 629 /*
kaf24@3376 630 * We're going to setup domain0 using the module(s) that we stashed safely
kaf24@3376 631 * above our heap. The second module, if present, is an initrd ramdisk.
kaf24@3376 632 */
kaf24@3376 633 if ( construct_dom0(dom0, dom0_memory_start, dom0_memory_end,
kaf24@3376 634 (char *)initial_images_start,
kaf24@3376 635 mod[0].mod_end-mod[0].mod_start,
kaf24@3376 636 (mbi->mods_count == 1) ? 0 :
kaf24@3376 637 (char *)initial_images_start +
kaf24@3376 638 (mod[1].mod_start-mod[0].mod_start),
kaf24@3376 639 (mbi->mods_count == 1) ? 0 :
kaf24@3376 640 mod[mbi->mods_count-1].mod_end - mod[1].mod_start,
kaf24@3376 641 cmdline) != 0)
kaf24@3376 642 panic("Could not set up DOM0 guest OS\n");
kaf24@3376 643
kaf24@3376 644 /* The stash space for the initial kernel image can now be freed up. */
kaf24@3392 645 init_domheap_pages(initial_images_start, initial_images_end);
kaf24@3376 646
kaf24@3376 647 scrub_heap_pages();
kaf24@3376 648
kaf24@3376 649 init_trace_bufs();
kaf24@3376 650
kaf24@3376 651 /* Give up the VGA console if DOM0 is configured to grab it. */
kaf24@3376 652 console_endboot(cmdline && strstr(cmdline, "tty0"));
kaf24@3376 653
kaf24@3378 654 domain_unpause_by_systemcontroller(current->domain);
kaf24@3376 655 domain_unpause_by_systemcontroller(dom0);
kaf24@3376 656 startup_cpu_idle_loop();
kaf24@3376 657 }