diff options
Diffstat (limited to 'arch/x86_64/kernel/setup.c')
-rw-r--r-- | arch/x86_64/kernel/setup.c | 248 |
1 files changed, 48 insertions, 200 deletions
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index 4b39f0da17f3..0b00bb2ea576 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c | |||
@@ -74,16 +74,6 @@ EXPORT_SYMBOL(boot_cpu_data); | |||
74 | 74 | ||
75 | unsigned long mmu_cr4_features; | 75 | unsigned long mmu_cr4_features; |
76 | 76 | ||
77 | int acpi_disabled; | ||
78 | EXPORT_SYMBOL(acpi_disabled); | ||
79 | #ifdef CONFIG_ACPI | ||
80 | extern int __initdata acpi_ht; | ||
81 | extern acpi_interrupt_flags acpi_sci_flags; | ||
82 | int __initdata acpi_force = 0; | ||
83 | #endif | ||
84 | |||
85 | int acpi_numa __initdata; | ||
86 | |||
87 | /* Boot loader ID as an integer, for the benefit of proc_dointvec */ | 77 | /* Boot loader ID as an integer, for the benefit of proc_dointvec */ |
88 | int bootloader_type; | 78 | int bootloader_type; |
89 | 79 | ||
@@ -107,7 +97,6 @@ struct sys_desc_table_struct { | |||
107 | 97 | ||
108 | struct edid_info edid_info; | 98 | struct edid_info edid_info; |
109 | EXPORT_SYMBOL_GPL(edid_info); | 99 | EXPORT_SYMBOL_GPL(edid_info); |
110 | struct e820map e820; | ||
111 | 100 | ||
112 | extern int root_mountflags; | 101 | extern int root_mountflags; |
113 | 102 | ||
@@ -276,185 +265,22 @@ static void __init probe_roms(void) | |||
276 | } | 265 | } |
277 | } | 266 | } |
278 | 267 | ||
279 | /* Check for full argument with no trailing characters */ | 268 | #ifdef CONFIG_PROC_VMCORE |
280 | static int fullarg(char *p, char *arg) | 269 | /* elfcorehdr= specifies the location of elf core header |
270 | * stored by the crashed kernel. This option will be passed | ||
271 | * by kexec loader to the capture kernel. | ||
272 | */ | ||
273 | static int __init setup_elfcorehdr(char *arg) | ||
281 | { | 274 | { |
282 | int l = strlen(arg); | 275 | char *end; |
283 | return !memcmp(p, arg, l) && (p[l] == 0 || isspace(p[l])); | 276 | if (!arg) |
277 | return -EINVAL; | ||
278 | elfcorehdr_addr = memparse(arg, &end); | ||
279 | return end > arg ? 0 : -EINVAL; | ||
284 | } | 280 | } |
285 | 281 | early_param("elfcorehdr", setup_elfcorehdr); | |
286 | static __init void parse_cmdline_early (char ** cmdline_p) | ||
287 | { | ||
288 | char c = ' ', *to = command_line, *from = COMMAND_LINE; | ||
289 | int len = 0; | ||
290 | int userdef = 0; | ||
291 | |||
292 | for (;;) { | ||
293 | if (c != ' ') | ||
294 | goto next_char; | ||
295 | |||
296 | #ifdef CONFIG_SMP | ||
297 | /* | ||
298 | * If the BIOS enumerates physical processors before logical, | ||
299 | * maxcpus=N at enumeration-time can be used to disable HT. | ||
300 | */ | ||
301 | else if (!memcmp(from, "maxcpus=", 8)) { | ||
302 | extern unsigned int maxcpus; | ||
303 | |||
304 | maxcpus = simple_strtoul(from + 8, NULL, 0); | ||
305 | } | ||
306 | #endif | ||
307 | #ifdef CONFIG_ACPI | ||
308 | /* "acpi=off" disables both ACPI table parsing and interpreter init */ | ||
309 | if (fullarg(from,"acpi=off")) | ||
310 | disable_acpi(); | ||
311 | |||
312 | if (fullarg(from, "acpi=force")) { | ||
313 | /* add later when we do DMI horrors: */ | ||
314 | acpi_force = 1; | ||
315 | acpi_disabled = 0; | ||
316 | } | ||
317 | |||
318 | /* acpi=ht just means: do ACPI MADT parsing | ||
319 | at bootup, but don't enable the full ACPI interpreter */ | ||
320 | if (fullarg(from, "acpi=ht")) { | ||
321 | if (!acpi_force) | ||
322 | disable_acpi(); | ||
323 | acpi_ht = 1; | ||
324 | } | ||
325 | else if (fullarg(from, "pci=noacpi")) | ||
326 | acpi_disable_pci(); | ||
327 | else if (fullarg(from, "acpi=noirq")) | ||
328 | acpi_noirq_set(); | ||
329 | |||
330 | else if (fullarg(from, "acpi_sci=edge")) | ||
331 | acpi_sci_flags.trigger = 1; | ||
332 | else if (fullarg(from, "acpi_sci=level")) | ||
333 | acpi_sci_flags.trigger = 3; | ||
334 | else if (fullarg(from, "acpi_sci=high")) | ||
335 | acpi_sci_flags.polarity = 1; | ||
336 | else if (fullarg(from, "acpi_sci=low")) | ||
337 | acpi_sci_flags.polarity = 3; | ||
338 | |||
339 | /* acpi=strict disables out-of-spec workarounds */ | ||
340 | else if (fullarg(from, "acpi=strict")) { | ||
341 | acpi_strict = 1; | ||
342 | } | ||
343 | #ifdef CONFIG_X86_IO_APIC | ||
344 | else if (fullarg(from, "acpi_skip_timer_override")) | ||
345 | acpi_skip_timer_override = 1; | ||
346 | #endif | ||
347 | #endif | ||
348 | |||
349 | if (fullarg(from, "disable_timer_pin_1")) | ||
350 | disable_timer_pin_1 = 1; | ||
351 | if (fullarg(from, "enable_timer_pin_1")) | ||
352 | disable_timer_pin_1 = -1; | ||
353 | |||
354 | if (fullarg(from, "nolapic") || fullarg(from, "disableapic")) { | ||
355 | clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); | ||
356 | disable_apic = 1; | ||
357 | } | ||
358 | |||
359 | if (fullarg(from, "noapic")) | ||
360 | skip_ioapic_setup = 1; | ||
361 | |||
362 | if (fullarg(from,"apic")) { | ||
363 | skip_ioapic_setup = 0; | ||
364 | ioapic_force = 1; | ||
365 | } | ||
366 | |||
367 | if (!memcmp(from, "mem=", 4)) | ||
368 | parse_memopt(from+4, &from); | ||
369 | |||
370 | if (!memcmp(from, "memmap=", 7)) { | ||
371 | /* exactmap option is for used defined memory */ | ||
372 | if (!memcmp(from+7, "exactmap", 8)) { | ||
373 | #ifdef CONFIG_CRASH_DUMP | ||
374 | /* If we are doing a crash dump, we | ||
375 | * still need to know the real mem | ||
376 | * size before original memory map is | ||
377 | * reset. | ||
378 | */ | ||
379 | saved_max_pfn = e820_end_of_ram(); | ||
380 | #endif | ||
381 | from += 8+7; | ||
382 | end_pfn_map = 0; | ||
383 | e820.nr_map = 0; | ||
384 | userdef = 1; | ||
385 | } | ||
386 | else { | ||
387 | parse_memmapopt(from+7, &from); | ||
388 | userdef = 1; | ||
389 | } | ||
390 | } | ||
391 | |||
392 | #ifdef CONFIG_NUMA | ||
393 | if (!memcmp(from, "numa=", 5)) | ||
394 | numa_setup(from+5); | ||
395 | #endif | 282 | #endif |
396 | 283 | ||
397 | if (!memcmp(from,"iommu=",6)) { | ||
398 | iommu_setup(from+6); | ||
399 | } | ||
400 | |||
401 | if (fullarg(from,"oops=panic")) | ||
402 | panic_on_oops = 1; | ||
403 | |||
404 | if (!memcmp(from, "noexec=", 7)) | ||
405 | nonx_setup(from + 7); | ||
406 | |||
407 | #ifdef CONFIG_KEXEC | ||
408 | /* crashkernel=size@addr specifies the location to reserve for | ||
409 | * a crash kernel. By reserving this memory we guarantee | ||
410 | * that linux never set's it up as a DMA target. | ||
411 | * Useful for holding code to do something appropriate | ||
412 | * after a kernel panic. | ||
413 | */ | ||
414 | else if (!memcmp(from, "crashkernel=", 12)) { | ||
415 | unsigned long size, base; | ||
416 | size = memparse(from+12, &from); | ||
417 | if (*from == '@') { | ||
418 | base = memparse(from+1, &from); | ||
419 | /* FIXME: Do I want a sanity check | ||
420 | * to validate the memory range? | ||
421 | */ | ||
422 | crashk_res.start = base; | ||
423 | crashk_res.end = base + size - 1; | ||
424 | } | ||
425 | } | ||
426 | #endif | ||
427 | |||
428 | #ifdef CONFIG_PROC_VMCORE | ||
429 | /* elfcorehdr= specifies the location of elf core header | ||
430 | * stored by the crashed kernel. This option will be passed | ||
431 | * by kexec loader to the capture kernel. | ||
432 | */ | ||
433 | else if(!memcmp(from, "elfcorehdr=", 11)) | ||
434 | elfcorehdr_addr = memparse(from+11, &from); | ||
435 | #endif | ||
436 | |||
437 | #ifdef CONFIG_HOTPLUG_CPU | ||
438 | else if (!memcmp(from, "additional_cpus=", 16)) | ||
439 | setup_additional_cpus(from+16); | ||
440 | #endif | ||
441 | |||
442 | next_char: | ||
443 | c = *(from++); | ||
444 | if (!c) | ||
445 | break; | ||
446 | if (COMMAND_LINE_SIZE <= ++len) | ||
447 | break; | ||
448 | *(to++) = c; | ||
449 | } | ||
450 | if (userdef) { | ||
451 | printk(KERN_INFO "user-defined physical RAM map:\n"); | ||
452 | e820_print_map("user"); | ||
453 | } | ||
454 | *to = '\0'; | ||
455 | *cmdline_p = command_line; | ||
456 | } | ||
457 | |||
458 | #ifndef CONFIG_NUMA | 284 | #ifndef CONFIG_NUMA |
459 | static void __init | 285 | static void __init |
460 | contig_initmem_init(unsigned long start_pfn, unsigned long end_pfn) | 286 | contig_initmem_init(unsigned long start_pfn, unsigned long end_pfn) |
@@ -466,7 +292,8 @@ contig_initmem_init(unsigned long start_pfn, unsigned long end_pfn) | |||
466 | if (bootmap == -1L) | 292 | if (bootmap == -1L) |
467 | panic("Cannot find bootmem map of size %ld\n",bootmap_size); | 293 | panic("Cannot find bootmem map of size %ld\n",bootmap_size); |
468 | bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn); | 294 | bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn); |
469 | e820_bootmem_free(NODE_DATA(0), 0, end_pfn << PAGE_SHIFT); | 295 | e820_register_active_regions(0, start_pfn, end_pfn); |
296 | free_bootmem_with_active_regions(0, end_pfn); | ||
470 | reserve_bootmem(bootmap, bootmap_size); | 297 | reserve_bootmem(bootmap, bootmap_size); |
471 | } | 298 | } |
472 | #endif | 299 | #endif |
@@ -521,6 +348,8 @@ static void discover_ebda(void) | |||
521 | 348 | ||
522 | void __init setup_arch(char **cmdline_p) | 349 | void __init setup_arch(char **cmdline_p) |
523 | { | 350 | { |
351 | printk(KERN_INFO "Command line: %s\n", saved_command_line); | ||
352 | |||
524 | ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); | 353 | ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); |
525 | screen_info = SCREEN_INFO; | 354 | screen_info = SCREEN_INFO; |
526 | edid_info = EDID_INFO; | 355 | edid_info = EDID_INFO; |
@@ -547,16 +376,22 @@ void __init setup_arch(char **cmdline_p) | |||
547 | data_resource.start = virt_to_phys(&_etext); | 376 | data_resource.start = virt_to_phys(&_etext); |
548 | data_resource.end = virt_to_phys(&_edata)-1; | 377 | data_resource.end = virt_to_phys(&_edata)-1; |
549 | 378 | ||
550 | parse_cmdline_early(cmdline_p); | ||
551 | |||
552 | early_identify_cpu(&boot_cpu_data); | 379 | early_identify_cpu(&boot_cpu_data); |
553 | 380 | ||
381 | strlcpy(command_line, saved_command_line, COMMAND_LINE_SIZE); | ||
382 | *cmdline_p = command_line; | ||
383 | |||
384 | parse_early_param(); | ||
385 | |||
386 | finish_e820_parsing(); | ||
387 | |||
388 | e820_register_active_regions(0, 0, -1UL); | ||
554 | /* | 389 | /* |
555 | * partially used pages are not usable - thus | 390 | * partially used pages are not usable - thus |
556 | * we are rounding upwards: | 391 | * we are rounding upwards: |
557 | */ | 392 | */ |
558 | end_pfn = e820_end_of_ram(); | 393 | end_pfn = e820_end_of_ram(); |
559 | num_physpages = end_pfn; /* for pfn_valid */ | 394 | num_physpages = end_pfn; |
560 | 395 | ||
561 | check_efer(); | 396 | check_efer(); |
562 | 397 | ||
@@ -576,6 +411,14 @@ void __init setup_arch(char **cmdline_p) | |||
576 | acpi_boot_table_init(); | 411 | acpi_boot_table_init(); |
577 | #endif | 412 | #endif |
578 | 413 | ||
414 | /* How many end-of-memory variables you have, grandma! */ | ||
415 | max_low_pfn = end_pfn; | ||
416 | max_pfn = end_pfn; | ||
417 | high_memory = (void *)__va(end_pfn * PAGE_SIZE - 1) + 1; | ||
418 | |||
419 | /* Remove active ranges so rediscovery with NUMA-awareness happens */ | ||
420 | remove_all_active_ranges(); | ||
421 | |||
579 | #ifdef CONFIG_ACPI_NUMA | 422 | #ifdef CONFIG_ACPI_NUMA |
580 | /* | 423 | /* |
581 | * Parse SRAT to discover nodes. | 424 | * Parse SRAT to discover nodes. |
@@ -625,12 +468,10 @@ void __init setup_arch(char **cmdline_p) | |||
625 | */ | 468 | */ |
626 | acpi_reserve_bootmem(); | 469 | acpi_reserve_bootmem(); |
627 | #endif | 470 | #endif |
628 | #ifdef CONFIG_X86_LOCAL_APIC | ||
629 | /* | 471 | /* |
630 | * Find and reserve possible boot-time SMP configuration: | 472 | * Find and reserve possible boot-time SMP configuration: |
631 | */ | 473 | */ |
632 | find_smp_config(); | 474 | find_smp_config(); |
633 | #endif | ||
634 | #ifdef CONFIG_BLK_DEV_INITRD | 475 | #ifdef CONFIG_BLK_DEV_INITRD |
635 | if (LOADER_TYPE && INITRD_START) { | 476 | if (LOADER_TYPE && INITRD_START) { |
636 | if (INITRD_START + INITRD_SIZE <= (end_pfn << PAGE_SHIFT)) { | 477 | if (INITRD_START + INITRD_SIZE <= (end_pfn << PAGE_SHIFT)) { |
@@ -657,7 +498,9 @@ void __init setup_arch(char **cmdline_p) | |||
657 | 498 | ||
658 | paging_init(); | 499 | paging_init(); |
659 | 500 | ||
660 | check_ioapic(); | 501 | #ifdef CONFIG_PCI |
502 | early_quirks(); | ||
503 | #endif | ||
661 | 504 | ||
662 | /* | 505 | /* |
663 | * set this early, so we dont allocate cpu0 | 506 | * set this early, so we dont allocate cpu0 |
@@ -674,14 +517,12 @@ void __init setup_arch(char **cmdline_p) | |||
674 | 517 | ||
675 | init_cpu_to_node(); | 518 | init_cpu_to_node(); |
676 | 519 | ||
677 | #ifdef CONFIG_X86_LOCAL_APIC | ||
678 | /* | 520 | /* |
679 | * get boot-time SMP configuration: | 521 | * get boot-time SMP configuration: |
680 | */ | 522 | */ |
681 | if (smp_found_config) | 523 | if (smp_found_config) |
682 | get_smp_config(); | 524 | get_smp_config(); |
683 | init_apic_mappings(); | 525 | init_apic_mappings(); |
684 | #endif | ||
685 | 526 | ||
686 | /* | 527 | /* |
687 | * Request address space for all standard RAM and ROM resources | 528 | * Request address space for all standard RAM and ROM resources |
@@ -839,7 +680,7 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c) | |||
839 | #endif | 680 | #endif |
840 | } | 681 | } |
841 | 682 | ||
842 | static void __init init_amd(struct cpuinfo_x86 *c) | 683 | static void __cpuinit init_amd(struct cpuinfo_x86 *c) |
843 | { | 684 | { |
844 | unsigned level; | 685 | unsigned level; |
845 | 686 | ||
@@ -895,6 +736,12 @@ static void __init init_amd(struct cpuinfo_x86 *c) | |||
895 | 736 | ||
896 | /* Fix cpuid4 emulation for more */ | 737 | /* Fix cpuid4 emulation for more */ |
897 | num_cache_leaves = 3; | 738 | num_cache_leaves = 3; |
739 | |||
740 | /* When there is only one core no need to synchronize RDTSC */ | ||
741 | if (num_possible_cpus() == 1) | ||
742 | set_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); | ||
743 | else | ||
744 | clear_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); | ||
898 | } | 745 | } |
899 | 746 | ||
900 | static void __cpuinit detect_ht(struct cpuinfo_x86 *c) | 747 | static void __cpuinit detect_ht(struct cpuinfo_x86 *c) |
@@ -976,8 +823,7 @@ static void srat_detect_node(void) | |||
976 | node = first_node(node_online_map); | 823 | node = first_node(node_online_map); |
977 | numa_set_node(cpu, node); | 824 | numa_set_node(cpu, node); |
978 | 825 | ||
979 | if (acpi_numa > 0) | 826 | printk(KERN_INFO "CPU %d/%x -> Node %d\n", cpu, apicid, node); |
980 | printk(KERN_INFO "CPU %d/%x -> Node %d\n", cpu, apicid, node); | ||
981 | #endif | 827 | #endif |
982 | } | 828 | } |
983 | 829 | ||
@@ -1011,6 +857,8 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) | |||
1011 | if ((c->x86 == 0xf && c->x86_model >= 0x03) || | 857 | if ((c->x86 == 0xf && c->x86_model >= 0x03) || |
1012 | (c->x86 == 0x6 && c->x86_model >= 0x0e)) | 858 | (c->x86 == 0x6 && c->x86_model >= 0x0e)) |
1013 | set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability); | 859 | set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability); |
860 | if (c->x86 == 6) | ||
861 | set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability); | ||
1014 | set_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); | 862 | set_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); |
1015 | c->x86_max_cores = intel_num_cpu_cores(c); | 863 | c->x86_max_cores = intel_num_cpu_cores(c); |
1016 | 864 | ||
@@ -1229,8 +1077,8 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
1229 | 1077 | ||
1230 | /* Intel-defined (#2) */ | 1078 | /* Intel-defined (#2) */ |
1231 | "pni", NULL, NULL, "monitor", "ds_cpl", "vmx", "smx", "est", | 1079 | "pni", NULL, NULL, "monitor", "ds_cpl", "vmx", "smx", "est", |
1232 | "tm2", NULL, "cid", NULL, NULL, "cx16", "xtpr", NULL, | 1080 | "tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL, |
1233 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 1081 | NULL, NULL, "dca", NULL, NULL, NULL, NULL, NULL, |
1234 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 1082 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
1235 | 1083 | ||
1236 | /* VIA/Cyrix/Centaur-defined */ | 1084 | /* VIA/Cyrix/Centaur-defined */ |