ia64/xen-unstable

annotate xen/arch/x86/setup.c @ 8402:47d947e07205

Work around a nasty BIOS/GRUB bug which causes fields in
the e820 map to not be initialized to zero when they should be.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Fri Dec 16 04:11:41 2005 +0100 (2005-12-16)
parents 379921f2259d
children 3dc1c23dd508
rev   line source
kaf24@1452 1
kaf24@1452 2 #include <xen/config.h>
kaf24@1452 3 #include <xen/init.h>
kaf24@1452 4 #include <xen/lib.h>
kaf24@1452 5 #include <xen/sched.h>
cl349@5247 6 #include <xen/domain.h>
kaf24@1452 7 #include <xen/serial.h>
kaf24@1506 8 #include <xen/softirq.h>
kaf24@1452 9 #include <xen/acpi.h>
kaf24@3338 10 #include <xen/console.h>
iap10@4287 11 #include <xen/serial.h>
kaf24@3338 12 #include <xen/trace.h>
kaf24@3338 13 #include <xen/multiboot.h>
kaf24@5356 14 #include <xen/domain_page.h>
iap10@6721 15 #include <xen/compile.h>
iap10@6721 16 #include <public/version.h>
kaf24@1452 17 #include <asm/bitops.h>
kaf24@1452 18 #include <asm/smp.h>
kaf24@1452 19 #include <asm/processor.h>
kaf24@1452 20 #include <asm/mpspec.h>
kaf24@1452 21 #include <asm/apic.h>
kaf24@1452 22 #include <asm/desc.h>
kaf24@3338 23 #include <asm/shadow.h>
kaf24@3344 24 #include <asm/e820.h>
kaf24@5536 25 #include <acm/acm_hooks.h>
kaf24@3338 26
kaf24@5157 27 extern void dmi_scan_machine(void);
kaf24@5211 28 extern void generic_apic_probe(void);
kaf24@5157 29
kaf24@3338 30 /*
kaf24@3338 31 * opt_xenheap_megabytes: Size of Xen heap in megabytes, excluding the
kaf24@3338 32 * pfn_info table and allocation bitmap.
kaf24@3338 33 */
kaf24@3338 34 static unsigned int opt_xenheap_megabytes = XENHEAP_DEFAULT_MB;
kaf24@4950 35 #if defined(CONFIG_X86_64)
kaf24@3338 36 integer_param("xenheap_megabytes", opt_xenheap_megabytes);
kaf24@3354 37 #endif
kaf24@1452 38
kaf24@5146 39 /* opt_nosmp: If true, secondary processors are ignored. */
kaf24@5900 40 static int opt_nosmp = 0;
kaf24@5146 41 boolean_param("nosmp", opt_nosmp);
kaf24@5146 42
kaf24@5146 43 /* maxcpus: maximum number of CPUs to activate. */
kaf24@5146 44 static unsigned int max_cpus = NR_CPUS;
kaf24@5146 45 integer_param("maxcpus", max_cpus);
kaf24@5146 46
kaf24@3334 47 /* opt_watchdog: If true, run a watchdog NMI on each processor. */
kaf24@3334 48 static int opt_watchdog = 0;
kaf24@3334 49 boolean_param("watchdog", opt_watchdog);
kaf24@3334 50
kaf24@4850 51 /* **** Linux config option: propagated to domain0. */
kaf24@4850 52 /* "acpi=off": Sisables both ACPI table parsing and interpreter. */
kaf24@4850 53 /* "acpi=force": Override the disable blacklist. */
kaf24@4850 54 /* "acpi=strict": Disables out-of-spec workarounds. */
kaf24@4850 55 /* "acpi=ht": Limit ACPI just to boot-time to enable HT. */
kaf24@4850 56 /* "acpi=noirq": Disables ACPI interrupt routing. */
kaf24@4850 57 static void parse_acpi_param(char *s);
kaf24@4850 58 custom_param("acpi", parse_acpi_param);
kaf24@4850 59
kaf24@4850 60 /* **** Linux config option: propagated to domain0. */
kaf24@4850 61 /* acpi_skip_timer_override: Skip IRQ0 overrides. */
kaf24@4850 62 extern int acpi_skip_timer_override;
kaf24@4850 63 boolean_param("acpi_skip_timer_override", acpi_skip_timer_override);
kaf24@4850 64
kaf24@4850 65 /* **** Linux config option: propagated to domain0. */
kaf24@4850 66 /* noapic: Disable IOAPIC setup. */
kaf24@4850 67 extern int skip_ioapic_setup;
kaf24@4850 68 boolean_param("noapic", skip_ioapic_setup);
kaf24@4850 69
kaf24@3594 70 int early_boot = 1;
kaf24@3594 71
kaf24@5146 72 cpumask_t cpu_present_map;
kaf24@5146 73
kaf24@5003 74 /* Limits of Xen heap, used to initialise the allocator. */
kaf24@5003 75 unsigned long xenheap_phys_start, xenheap_phys_end;
kaf24@3338 76
kaf24@2298 77 extern void arch_init_memory(void);
kaf24@1589 78 extern void init_IRQ(void);
kaf24@1589 79 extern void trap_init(void);
kaf24@5604 80 extern void early_time_init(void);
kaf24@5167 81 extern void initialize_keytable(void);
kaf24@5167 82 extern void early_cpu_init(void);
kaf24@1589 83
kaf24@5011 84 extern unsigned long cpu0_stack[];
kaf24@5011 85
kaf24@5214 86 struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
kaf24@1452 87
kaf24@5237 88 #if CONFIG_PAGING_LEVELS > 2
kaf24@1670 89 unsigned long mmu_cr4_features = X86_CR4_PSE | X86_CR4_PGE | X86_CR4_PAE;
kaf24@1670 90 #else
kaf24@5593 91 unsigned long mmu_cr4_features = X86_CR4_PSE;
kaf24@1670 92 #endif
kaf24@1452 93 EXPORT_SYMBOL(mmu_cr4_features);
kaf24@1452 94
kaf24@5289 95 struct vcpu *idle_task[NR_CPUS] = { &idle0_vcpu };
kaf24@1452 96
kaf24@4818 97 int acpi_disabled;
kaf24@1452 98
kaf24@4850 99 int acpi_force;
kaf24@4850 100 char acpi_param[10] = "";
kaf24@4850 101 static void parse_acpi_param(char *s)
kaf24@4850 102 {
kaf24@4850 103 /* Save the parameter so it can be propagated to domain0. */
kaf24@4850 104 strncpy(acpi_param, s, sizeof(acpi_param));
kaf24@4850 105 acpi_param[sizeof(acpi_param)-1] = '\0';
kaf24@4850 106
kaf24@4850 107 /* Interpret the parameter for use within Xen. */
kaf24@4850 108 if ( !strcmp(s, "off") )
kaf24@4850 109 {
kaf24@4850 110 disable_acpi();
kaf24@4850 111 }
kaf24@4850 112 else if ( !strcmp(s, "force") )
kaf24@4850 113 {
kaf24@4850 114 acpi_force = 1;
kaf24@4850 115 acpi_ht = 1;
kaf24@4850 116 acpi_disabled = 0;
kaf24@4850 117 }
kaf24@4850 118 else if ( !strcmp(s, "strict") )
kaf24@4850 119 {
kaf24@4850 120 acpi_strict = 1;
kaf24@4850 121 }
kaf24@4850 122 else if ( !strcmp(s, "ht") )
kaf24@4850 123 {
kaf24@4850 124 if ( !acpi_force )
kaf24@4850 125 disable_acpi();
kaf24@4850 126 acpi_ht = 1;
kaf24@4850 127 }
kaf24@4850 128 else if ( !strcmp(s, "noirq") )
kaf24@4850 129 {
kaf24@4850 130 acpi_noirq_set();
kaf24@4850 131 }
kaf24@4850 132 }
kaf24@4850 133
kaf24@1452 134 static void __init do_initcalls(void)
kaf24@1452 135 {
kaf24@1452 136 initcall_t *call;
kaf24@1452 137 for ( call = &__initcall_start; call < &__initcall_end; call++ )
kaf24@1452 138 (*call)();
kaf24@1452 139 }
kaf24@1452 140
kaf24@3338 141 static void __init start_of_day(void)
kaf24@1452 142 {
kaf24@5146 143 int i;
kaf24@7462 144 unsigned long vgdt, gdt_pfn;
kaf24@5146 145
kaf24@5214 146 early_cpu_init();
kaf24@5214 147
kaf24@5298 148 paging_init();
kaf24@5298 149
kaf24@1452 150 /* Unmap the first page of CPU0's stack. */
kaf24@3686 151 memguard_guard_stack(cpu0_stack);
kaf24@1452 152
kaf24@1505 153 open_softirq(NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ, new_tlbflush_clock_period);
kaf24@1452 154
kaf24@1452 155 if ( opt_watchdog )
kaf24@1452 156 nmi_watchdog = NMI_LOCAL_APIC;
kaf24@1452 157
kaf24@3120 158 sort_exception_tables();
kaf24@3120 159
kaf24@3272 160 arch_do_createdomain(current);
kaf24@4972 161
kaf24@7450 162 /*
kaf24@7450 163 * Map default GDT into its final positions in the idle page table. As
kaf24@7450 164 * noted in arch_do_createdomain(), we must map for every possible VCPU#.
kaf24@7450 165 */
kaf24@7450 166 vgdt = GDT_VIRT_START(current) + FIRST_RESERVED_GDT_BYTE;
kaf24@7462 167 gdt_pfn = virt_to_phys(gdt_table) >> PAGE_SHIFT;
kaf24@7450 168 for ( i = 0; i < MAX_VIRT_CPUS; i++ )
kaf24@7450 169 {
kaf24@7462 170 map_pages_to_xen(vgdt, gdt_pfn, 1, PAGE_HYPERVISOR);
kaf24@7450 171 vgdt += 1 << PDPT_VCPU_VA_SHIFT;
kaf24@7450 172 }
kaf24@3272 173
kaf24@4850 174 find_smp_config();
kaf24@4850 175
kaf24@4850 176 smp_alloc_memory();
kaf24@4850 177
kaf24@5157 178 dmi_scan_machine();
kaf24@5157 179
kaf24@5211 180 generic_apic_probe();
kaf24@5157 181
kaf24@4850 182 acpi_boot_table_init();
kaf24@4850 183 acpi_boot_init();
kaf24@4850 184
kaf24@1452 185 if ( smp_found_config )
kaf24@1452 186 get_smp_config();
kaf24@4850 187
kaf24@4850 188 init_apic_mappings();
kaf24@4850 189
kaf24@4850 190 init_IRQ();
kaf24@4850 191
kaf24@1452 192 trap_init();
kaf24@4850 193
kaf24@5174 194 ac_timer_init();
kaf24@5174 195
kaf24@5604 196 early_time_init();
kaf24@1452 197
kaf24@2298 198 arch_init_memory();
kaf24@2298 199
kaf24@5536 200 scheduler_init();
kaf24@1452 201
kaf24@5214 202 identify_cpu(&boot_cpu_data);
kaf24@5214 203 if ( cpu_has_fxsr )
kaf24@5214 204 set_in_cr4(X86_CR4_OSFXSR);
kaf24@5214 205 if ( cpu_has_xmm )
kaf24@5214 206 set_in_cr4(X86_CR4_OSXMMEXCPT);
kaf24@5214 207
kaf24@5146 208 if ( opt_nosmp )
kaf24@5900 209 {
kaf24@5146 210 max_cpus = 0;
kaf24@5900 211 smp_num_siblings = 1;
kaf24@5900 212 boot_cpu_data.x86_num_cores = 1;
kaf24@5900 213 }
kaf24@5900 214
kaf24@5146 215 smp_prepare_cpus(max_cpus);
kaf24@5146 216
kaf24@5146 217 /* We aren't hotplug-capable yet. */
kaf24@5146 218 BUG_ON(!cpus_empty(cpu_present_map));
kaf24@5146 219 for_each_cpu ( i )
kaf24@5146 220 cpu_set(i, cpu_present_map);
kaf24@1452 221
kaf24@5604 222 /*
kaf24@5604 223 * Initialise higher-level timer functions. We do this fairly late
kaf24@5604 224 * (post-SMP) because the time bases and scale factors need to be updated
kaf24@5604 225 * regularly, and SMP initialisation can cause a long delay with
kaf24@5604 226 * interrupts not yet enabled.
kaf24@5604 227 */
kaf24@5604 228 init_xen_time();
kaf24@5177 229
kaf24@4850 230 initialize_keytable();
kaf24@1452 231
kaf24@5195 232 serial_init_postirq();
kaf24@1452 233
kaf24@5604 234 BUG_ON(!local_irq_is_enabled());
kaf24@5146 235
kaf24@5146 236 for_each_present_cpu ( i )
kaf24@1452 237 {
kaf24@5146 238 if ( num_online_cpus() >= max_cpus )
kaf24@5146 239 break;
kaf24@5146 240 if ( !cpu_online(i) )
kaf24@5146 241 __cpu_up(i);
kaf24@1452 242 }
kaf24@1452 243
kaf24@5146 244 printk("Brought up %ld CPUs\n", (long)num_online_cpus());
kaf24@5146 245 smp_cpus_done(max_cpus);
kaf24@1452 246
kaf24@1452 247 do_initcalls();
kaf24@1452 248
kaf24@5146 249 schedulers_start();
kaf24@1452 250
kaf24@4926 251 watchdog_enable();
kaf24@1452 252 }
kaf24@3338 253
kaf24@5011 254 #define EARLY_FAIL() for ( ; ; ) __asm__ __volatile__ ( "hlt" )
kaf24@5011 255
iap10@6238 256 static struct e820entry e820_raw[E820MAX];
iap10@6238 257
kaf24@3338 258 void __init __start_xen(multiboot_info_t *mbi)
kaf24@3338 259 {
riel@3992 260 char *cmdline;
kaf24@3338 261 module_t *mod = (module_t *)__va(mbi->mods_addr);
kaf24@6111 262 unsigned long nr_pages, modules_length;
kaf24@3338 263 unsigned long initial_images_start, initial_images_end;
kaf24@5859 264 unsigned long _initrd_start = 0, _initrd_len = 0;
kaf24@5859 265 unsigned int initrdidx = 1;
kaf24@6111 266 physaddr_t s, e;
kaf24@8402 267 int i, e820_warn = 0, e820_raw_nr = 0, bytes = 0;
kaf24@5776 268 struct ns16550_defaults ns16550 = {
kaf24@5776 269 .data_bits = 8,
kaf24@5776 270 .parity = 'n',
kaf24@5776 271 .stop_bits = 1
kaf24@5776 272 };
kaf24@3338 273
kaf24@3338 274 /* Parse the command-line options. */
kaf24@3344 275 if ( (mbi->flags & MBI_CMDLINE) && (mbi->cmdline != 0) )
kaf24@5211 276 cmdline_parse(__va(mbi->cmdline));
kaf24@3338 277
kaf24@3338 278 /* Must do this early -- e.g., spinlocks rely on get_current(). */
kaf24@5289 279 set_current(&idle0_vcpu);
kaf24@4986 280 set_processor_id(0);
kaf24@3338 281
kaf24@5146 282 smp_prepare_boot_cpu();
kaf24@5146 283
kaf24@3338 284 /* We initialise the serial devices very early so we can get debugging. */
kaf24@5776 285 ns16550.io_base = 0x3f8;
kaf24@5776 286 ns16550.irq = 4;
kaf24@5776 287 ns16550_init(0, &ns16550);
kaf24@5776 288 ns16550.io_base = 0x2f8;
kaf24@5776 289 ns16550.irq = 3;
kaf24@5776 290 ns16550_init(1, &ns16550);
kaf24@5195 291 serial_init_preirq();
kaf24@3338 292
kaf24@3338 293 init_console();
kaf24@3338 294
kaf24@3344 295 /* Check that we have at least one Multiboot module. */
kaf24@3344 296 if ( !(mbi->flags & MBI_MODULES) || (mbi->mods_count == 0) )
kaf24@3338 297 {
kaf24@5542 298 printk("FATAL ERROR: dom0 kernel not specified."
kaf24@5542 299 " Check bootloader configuration.\n");
kaf24@5011 300 EARLY_FAIL();
kaf24@5011 301 }
kaf24@5011 302
kaf24@5011 303 if ( ((unsigned long)cpu0_stack & (STACK_SIZE-1)) != 0 )
kaf24@5011 304 {
kaf24@5011 305 printk("FATAL ERROR: Misaligned CPU0 stack.\n");
kaf24@5011 306 EARLY_FAIL();
kaf24@3338 307 }
kaf24@3338 308
kaf24@3338 309 xenheap_phys_end = opt_xenheap_megabytes << 20;
kaf24@3338 310
kaf24@3344 311 if ( mbi->flags & MBI_MEMMAP )
kaf24@3344 312 {
kaf24@3344 313 while ( bytes < mbi->mmap_length )
kaf24@3344 314 {
kaf24@3344 315 memory_map_t *map = __va(mbi->mmap_addr + bytes);
kaf24@8402 316
kaf24@8402 317 /*
kaf24@8402 318 * This is a gross workaround for a BIOS/GRUB bug. GRUB does
kaf24@8402 319 * not write e820 map entries into pre-zeroed memory. This is
kaf24@8402 320 * okay if the BIOS fills in all fields of the map entry, but
kaf24@8402 321 * some broken BIOSes do not bother to write the high word of
kaf24@8402 322 * the length field if the length is smaller than 4GB. We
kaf24@8402 323 * detect and fix this by flagging sections below 4GB that
kaf24@8402 324 * appear to be larger than 4GB in size. We disable this check
kaf24@8402 325 * for mbootpack and syslinux (which we can detect because they
kaf24@8402 326 * place the mmap_addr list above 1MB in memory).
kaf24@8402 327 */
kaf24@8402 328 if ( (mbi->mmap_addr < 0x100000) &&
kaf24@8402 329 (map->base_addr_high == 0) &&
kaf24@8402 330 (map->length_high != 0) )
kaf24@8402 331 {
kaf24@8402 332 e820_warn = 1;
kaf24@8402 333 map->length_high = 0;
kaf24@8402 334 }
kaf24@8402 335
kaf24@3344 336 e820_raw[e820_raw_nr].addr =
kaf24@3344 337 ((u64)map->base_addr_high << 32) | (u64)map->base_addr_low;
kaf24@3344 338 e820_raw[e820_raw_nr].size =
kaf24@3344 339 ((u64)map->length_high << 32) | (u64)map->length_low;
kaf24@3344 340 e820_raw[e820_raw_nr].type =
kaf24@3346 341 (map->type > E820_SHARED_PAGE) ? E820_RESERVED : map->type;
kaf24@3344 342 e820_raw_nr++;
kaf24@8402 343
kaf24@3344 344 bytes += map->size + 4;
kaf24@3344 345 }
kaf24@3344 346 }
kaf24@3344 347 else if ( mbi->flags & MBI_MEMLIMITS )
kaf24@3344 348 {
kaf24@3344 349 e820_raw[0].addr = 0;
kaf24@3344 350 e820_raw[0].size = mbi->mem_lower << 10;
kaf24@3344 351 e820_raw[0].type = E820_RAM;
kaf24@3354 352 e820_raw[1].addr = 0x100000;
kaf24@3354 353 e820_raw[1].size = mbi->mem_upper << 10;
kaf24@3354 354 e820_raw[1].type = E820_RAM;
kaf24@3344 355 e820_raw_nr = 2;
kaf24@3344 356 }
kaf24@3344 357 else
kaf24@3344 358 {
kaf24@3344 359 printk("FATAL ERROR: Bootloader provided no memory information.\n");
kaf24@3344 360 for ( ; ; ) ;
kaf24@3344 361 }
kaf24@3344 362
kaf24@8402 363 if ( e820_warn )
kaf24@8402 364 printk("WARNING: Buggy e820 map detected and fixed "
kaf24@8402 365 "(truncated length fields).\n");
kaf24@8402 366
kaf24@4950 367 max_page = init_e820(e820_raw, &e820_raw_nr);
kaf24@3338 368
kaf24@6111 369 modules_length = mod[mbi->mods_count-1].mod_end - mod[0].mod_start;
kaf24@3338 370
kaf24@6111 371 /* Find a large enough RAM extent to stash the DOM0 modules. */
kaf24@6111 372 for ( i = 0; ; i++ )
kaf24@3338 373 {
kaf24@6111 374 if ( i == e820.nr_map )
kaf24@6111 375 {
kaf24@6111 376 printk("Not enough memory to stash the DOM0 kernel image.\n");
kaf24@6111 377 for ( ; ; ) ;
kaf24@6111 378 }
kaf24@6134 379
kaf24@6134 380 if ( (e820.map[i].type == E820_RAM) &&
kaf24@6134 381 (e820.map[i].size >= modules_length) &&
kaf24@6134 382 ((e820.map[i].addr + e820.map[i].size) >=
kaf24@6134 383 (xenheap_phys_end + modules_length)) )
kaf24@6134 384 break;
kaf24@3338 385 }
kaf24@6111 386
kaf24@6134 387 /* Stash as near as possible to the beginning of the RAM extent. */
kaf24@6134 388 initial_images_start = e820.map[i].addr;
kaf24@6134 389 if ( initial_images_start < xenheap_phys_end )
kaf24@6134 390 initial_images_start = xenheap_phys_end;
kaf24@6134 391 initial_images_end = initial_images_start + modules_length;
kaf24@6134 392
kaf24@4950 393 #if defined(CONFIG_X86_32)
kaf24@3338 394 memmove((void *)initial_images_start, /* use low mapping */
kaf24@3338 395 (void *)mod[0].mod_start, /* use low mapping */
kaf24@3338 396 mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
kaf24@4950 397 #elif defined(CONFIG_X86_64)
kaf24@3338 398 memmove(__va(initial_images_start),
kaf24@3338 399 __va(mod[0].mod_start),
kaf24@3338 400 mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
kaf24@3338 401 #endif
kaf24@3338 402
kaf24@3354 403 /* Initialise boot-time allocator with all RAM situated after modules. */
kaf24@5003 404 xenheap_phys_start = init_boot_allocator(__pa(&_end));
kaf24@6111 405 nr_pages = 0;
kaf24@3354 406 for ( i = 0; i < e820.nr_map; i++ )
kaf24@3354 407 {
kaf24@3354 408 if ( e820.map[i].type != E820_RAM )
kaf24@3354 409 continue;
kaf24@6111 410
kaf24@3354 411 nr_pages += e820.map[i].size >> PAGE_SHIFT;
kaf24@6111 412
kaf24@6111 413 /* Initialise boot heap, skipping Xen heap and dom0 modules. */
kaf24@6111 414 s = e820.map[i].addr;
kaf24@6111 415 e = s + e820.map[i].size;
kaf24@6111 416 if ( s < xenheap_phys_end )
kaf24@6111 417 s = xenheap_phys_end;
kaf24@6111 418 if ( (s < initial_images_end) && (e > initial_images_start) )
kaf24@6111 419 s = initial_images_end;
kaf24@6111 420 init_boot_pages(s, e);
kaf24@6111 421
kaf24@5003 422 #if defined (CONFIG_X86_64)
kaf24@5003 423 /*
kaf24@5003 424 * x86/64 maps all registered RAM. Points to note:
kaf24@5003 425 * 1. The initial pagetable already maps low 64MB, so skip that.
kaf24@5003 426 * 2. We must map *only* RAM areas, taking care to avoid I/O holes.
kaf24@5003 427 * Failure to do this can cause coherency problems and deadlocks
kaf24@5003 428 * due to cache-attribute mismatches (e.g., AMD/AGP Linux bug).
kaf24@5003 429 */
kaf24@5003 430 {
kaf24@5004 431 /* Calculate page-frame range, discarding partial frames. */
kaf24@5004 432 unsigned long start, end;
kaf24@5005 433 start = PFN_UP(e820.map[i].addr);
kaf24@5005 434 end = PFN_DOWN(e820.map[i].addr + e820.map[i].size);
kaf24@5004 435 /* Clip the range to above 64MB. */
kaf24@5004 436 if ( end < (64UL << (20-PAGE_SHIFT)) )
kaf24@5004 437 continue;
kaf24@5004 438 if ( start < (64UL << (20-PAGE_SHIFT)) )
kaf24@5004 439 start = 64UL << (20-PAGE_SHIFT);
kaf24@5004 440 /* Request the mapping. */
kaf24@5003 441 map_pages_to_xen(
kaf24@5004 442 PAGE_OFFSET + (start << PAGE_SHIFT),
kaf24@5004 443 start, end-start, PAGE_HYPERVISOR);
kaf24@5003 444 }
kaf24@5003 445 #endif
kaf24@3354 446 }
kaf24@3354 447
kaf24@5003 448 memguard_init();
kaf24@4950 449
kaf24@3354 450 printk("System RAM: %luMB (%lukB)\n",
kaf24@3354 451 nr_pages >> (20 - PAGE_SHIFT),
kaf24@3354 452 nr_pages << (PAGE_SHIFT - 10));
kaf24@7220 453 total_pages = nr_pages;
kaf24@3354 454
kaf24@7388 455 /* Sanity check for unwanted bloat of dom0_op_t structure. */
kaf24@7388 456 BUG_ON(sizeof(((dom0_op_t *)0)->u) != sizeof(((dom0_op_t *)0)->u.pad));
kaf24@7388 457
kaf24@7744 458 BUG_ON(sizeof(start_info_t) > PAGE_SIZE);
kaf24@7744 459 BUG_ON(sizeof(shared_info_t) > PAGE_SIZE);
kaf24@8108 460 BUG_ON(sizeof(vcpu_info_t) != 64);
kaf24@7744 461
kaf24@3354 462 init_frametable();
kaf24@3338 463
kaf24@3354 464 end_boot_allocator();
kaf24@3354 465
kaf24@6111 466 /* Initialise the Xen heap, skipping RAM holes. */
kaf24@6111 467 nr_pages = 0;
kaf24@6111 468 for ( i = 0; i < e820.nr_map; i++ )
kaf24@6111 469 {
kaf24@6111 470 if ( e820.map[i].type != E820_RAM )
kaf24@6111 471 continue;
kaf24@6111 472
kaf24@6111 473 s = e820.map[i].addr;
kaf24@6111 474 e = s + e820.map[i].size;
kaf24@6111 475 if ( s < xenheap_phys_start )
kaf24@6111 476 s = xenheap_phys_start;
kaf24@6111 477 if ( e > xenheap_phys_end )
kaf24@6111 478 e = xenheap_phys_end;
kaf24@6111 479
kaf24@6111 480 if ( s < e )
kaf24@6111 481 {
kaf24@6111 482 nr_pages += (e - s) >> PAGE_SHIFT;
kaf24@6111 483 init_xenheap_pages(s, e);
kaf24@6111 484 }
kaf24@6111 485 }
kaf24@6111 486
kaf24@6111 487 printk("Xen heap: %luMB (%lukB)\n",
kaf24@6111 488 nr_pages >> (20 - PAGE_SHIFT),
kaf24@6111 489 nr_pages << (PAGE_SHIFT - 10));
kaf24@3338 490
kaf24@3594 491 early_boot = 0;
kaf24@3338 492
kaf24@3338 493 start_of_day();
kaf24@3338 494
kaf24@3338 495 grant_table_init();
kaf24@3338 496
kaf24@3338 497 shadow_mode_init();
kaf24@3338 498
smh22@5514 499 /* initialize access control security module */
kaf24@5859 500 acm_init(&initrdidx, mbi, initial_images_start);
smh22@5514 501
kaf24@3338 502 /* Create initial domain 0. */
kaf24@3338 503 dom0 = do_createdomain(0, 0);
kaf24@3338 504 if ( dom0 == NULL )
kaf24@3338 505 panic("Error creating domain 0\n");
kaf24@3338 506
kaf24@4877 507 set_bit(_DOMF_privileged, &dom0->domain_flags);
smh22@5514 508 /* post-create hooks sets security label */
smh22@5514 509 acm_post_domain0_create(dom0->domain_id);
kaf24@3338 510
kaf24@4850 511 /* Grab the DOM0 command line. */
riel@3992 512 cmdline = (char *)(mod[0].string ? __va(mod[0].string) : NULL);
kaf24@3338 513 if ( cmdline != NULL )
kaf24@3338 514 {
kaf24@5366 515 static char dom0_cmdline[MAX_GUEST_CMDLINE];
kaf24@4850 516
kaf24@7221 517 /* Skip past the image name and copy to a local buffer. */
kaf24@3338 518 while ( *cmdline == ' ' ) cmdline++;
kaf24@3338 519 if ( (cmdline = strchr(cmdline, ' ')) != NULL )
kaf24@7221 520 {
kaf24@3338 521 while ( *cmdline == ' ' ) cmdline++;
kaf24@7221 522 strcpy(dom0_cmdline, cmdline);
kaf24@7221 523 }
kaf24@4850 524
kaf24@4850 525 cmdline = dom0_cmdline;
kaf24@4850 526
kaf24@4850 527 /* Append any extra parameters. */
kaf24@4850 528 if ( skip_ioapic_setup && !strstr(cmdline, "noapic") )
kaf24@4850 529 strcat(cmdline, " noapic");
kaf24@4850 530 if ( acpi_skip_timer_override &&
kaf24@4850 531 !strstr(cmdline, "acpi_skip_timer_override") )
kaf24@4850 532 strcat(cmdline, " acpi_skip_timer_override");
kaf24@4850 533 if ( (strlen(acpi_param) != 0) && !strstr(cmdline, "acpi=") )
kaf24@4850 534 {
kaf24@4850 535 strcat(cmdline, " acpi=");
kaf24@4850 536 strcat(cmdline, acpi_param);
kaf24@4850 537 }
kaf24@3338 538 }
kaf24@3338 539
kaf24@5859 540 if ( (initrdidx > 0) && (initrdidx < mbi->mods_count) )
kaf24@5859 541 {
kaf24@5859 542 _initrd_start = initial_images_start +
kaf24@5859 543 (mod[initrdidx].mod_start - mod[0].mod_start);
kaf24@5859 544 _initrd_len = mod[initrdidx].mod_end - mod[initrdidx].mod_start;
kaf24@5859 545 }
kaf24@5859 546
kaf24@3338 547 /*
kaf24@3338 548 * We're going to setup domain0 using the module(s) that we stashed safely
kaf24@3338 549 * above our heap. The second module, if present, is an initrd ramdisk.
kaf24@3338 550 */
kaf24@3935 551 if ( construct_dom0(dom0,
kaf24@3635 552 initial_images_start,
kaf24@3338 553 mod[0].mod_end-mod[0].mod_start,
kaf24@5859 554 _initrd_start,
kaf24@5859 555 _initrd_len,
kaf24@3338 556 cmdline) != 0)
kaf24@3338 557 panic("Could not set up DOM0 guest OS\n");
kaf24@3338 558
kaf24@3935 559 /* Scrub RAM that is still free and so may go to an unprivileged domain. */
kaf24@3338 560 scrub_heap_pages();
kaf24@3338 561
kaf24@3338 562 init_trace_bufs();
kaf24@3338 563
kaf24@3338 564 /* Give up the VGA console if DOM0 is configured to grab it. */
kaf24@3338 565 console_endboot(cmdline && strstr(cmdline, "tty0"));
kaf24@3338 566
iap10@4287 567 /* Hide UART from DOM0 if we're using it */
iap10@4287 568 serial_endboot();
iap10@4287 569
kaf24@3338 570 domain_unpause_by_systemcontroller(dom0);
kaf24@5146 571
kaf24@3338 572 startup_cpu_idle_loop();
kaf24@3338 573 }
kaf24@3914 574
kaf24@6725 575 void arch_get_xen_caps(xen_capabilities_info_t info)
iap10@6721 576 {
kaf24@6725 577 char *p = info;
iap10@6721 578
kaf24@6725 579 #if defined(CONFIG_X86_32) && !defined(CONFIG_X86_PAE)
kaf24@6725 580
smh22@7709 581 p += sprintf(p, "xen-%d.%d-x86_32 ", XEN_VERSION, XEN_SUBVERSION);
kaf24@6725 582 if ( hvm_enabled )
smh22@7709 583 p += sprintf(p, "hvm-%d.%d-x86_32 ", XEN_VERSION, XEN_SUBVERSION);
kaf24@6725 584
kaf24@6725 585 #elif defined(CONFIG_X86_32) && defined(CONFIG_X86_PAE)
kaf24@6725 586
smh22@7709 587 p += sprintf(p, "xen-%d.%d-x86_32p ", XEN_VERSION, XEN_SUBVERSION);
kaf24@6725 588 if ( hvm_enabled )
iap10@6721 589 {
smh22@7709 590 //p += sprintf(p, "hvm-%d.%d-x86_32 ", XEN_VERSION, XEN_SUBVERSION);
smh22@7709 591 //p += sprintf(p, "hvm-%d.%d-x86_32p ", XEN_VERSION, XEN_SUBVERSION);
iap10@6721 592 }
iap10@6721 593
kaf24@6725 594 #elif defined(CONFIG_X86_64)
iap10@6721 595
smh22@7709 596 p += sprintf(p, "xen-%d.%d-x86_64 ", XEN_VERSION, XEN_SUBVERSION);
kaf24@6725 597 if ( hvm_enabled )
iap10@6721 598 {
kaf24@8246 599 p += sprintf(p, "hvm-%d.%d-x86_32 ", XEN_VERSION, XEN_SUBVERSION);
smh22@7709 600 //p += sprintf(p, "hvm-%d.%d-x86_32p ", XEN_VERSION, XEN_SUBVERSION);
smh22@7709 601 p += sprintf(p, "hvm-%d.%d-x86_64 ", XEN_VERSION, XEN_SUBVERSION);
iap10@6721 602 }
kaf24@6725 603
kaf24@6725 604 #else
kaf24@6725 605
kaf24@6725 606 p++;
kaf24@6725 607
iap10@6721 608 #endif
kaf24@8246 609
kaf24@6725 610 *(p-1) = 0;
iap10@6721 611
shand@6734 612 BUG_ON((p - info) > sizeof(xen_capabilities_info_t));
iap10@6721 613 }
iap10@6721 614
kaf24@3914 615 /*
kaf24@3914 616 * Local variables:
kaf24@3914 617 * mode: C
kaf24@3914 618 * c-set-style: "BSD"
kaf24@3914 619 * c-basic-offset: 4
kaf24@3914 620 * tab-width: 4
kaf24@3914 621 * indent-tabs-mode: nil
kaf24@3988 622 * End:
kaf24@3914 623 */