diff options
Diffstat (limited to 'arch/x86/kernel/setup_32.c')
-rw-r--r-- | arch/x86/kernel/setup_32.c | 556 |
1 files changed, 328 insertions, 228 deletions
diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 5a2f8e063887..7e06ecd83174 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c | |||
@@ -59,6 +59,7 @@ | |||
59 | #include <asm/setup.h> | 59 | #include <asm/setup.h> |
60 | #include <asm/arch_hooks.h> | 60 | #include <asm/arch_hooks.h> |
61 | #include <asm/sections.h> | 61 | #include <asm/sections.h> |
62 | #include <asm/dmi.h> | ||
62 | #include <asm/io_apic.h> | 63 | #include <asm/io_apic.h> |
63 | #include <asm/ist.h> | 64 | #include <asm/ist.h> |
64 | #include <asm/io.h> | 65 | #include <asm/io.h> |
@@ -67,10 +68,13 @@ | |||
67 | #include <asm/bios_ebda.h> | 68 | #include <asm/bios_ebda.h> |
68 | #include <asm/cacheflush.h> | 69 | #include <asm/cacheflush.h> |
69 | #include <asm/processor.h> | 70 | #include <asm/processor.h> |
71 | #include <asm/efi.h> | ||
72 | #include <asm/bugs.h> | ||
70 | 73 | ||
71 | /* This value is set up by the early boot code to point to the value | 74 | /* This value is set up by the early boot code to point to the value |
72 | immediately after the boot time page tables. It contains a *physical* | 75 | immediately after the boot time page tables. It contains a *physical* |
73 | address, and must not be in the .bss segment! */ | 76 | address, and must not be in the .bss segment! */ |
77 | unsigned long init_pg_tables_start __initdata = ~0UL; | ||
74 | unsigned long init_pg_tables_end __initdata = ~0UL; | 78 | unsigned long init_pg_tables_end __initdata = ~0UL; |
75 | 79 | ||
76 | /* | 80 | /* |
@@ -182,6 +186,12 @@ int bootloader_type; | |||
182 | static unsigned int highmem_pages = -1; | 186 | static unsigned int highmem_pages = -1; |
183 | 187 | ||
184 | /* | 188 | /* |
189 | * Early DMI memory | ||
190 | */ | ||
191 | int dmi_alloc_index; | ||
192 | char dmi_alloc_data[DMI_MAX_DATA]; | ||
193 | |||
194 | /* | ||
185 | * Setup options | 195 | * Setup options |
186 | */ | 196 | */ |
187 | struct screen_info screen_info; | 197 | struct screen_info screen_info; |
@@ -237,42 +247,6 @@ static inline void copy_edd(void) | |||
237 | } | 247 | } |
238 | #endif | 248 | #endif |
239 | 249 | ||
240 | int __initdata user_defined_memmap; | ||
241 | |||
242 | /* | ||
243 | * "mem=nopentium" disables the 4MB page tables. | ||
244 | * "mem=XXX[kKmM]" defines a memory region from HIGH_MEM | ||
245 | * to <mem>, overriding the bios size. | ||
246 | * "memmap=XXX[KkmM]@XXX[KkmM]" defines a memory region from | ||
247 | * <start> to <start>+<mem>, overriding the bios size. | ||
248 | * | ||
249 | * HPA tells me bootloaders need to parse mem=, so no new | ||
250 | * option should be mem= [also see Documentation/i386/boot.txt] | ||
251 | */ | ||
252 | static int __init parse_mem(char *arg) | ||
253 | { | ||
254 | if (!arg) | ||
255 | return -EINVAL; | ||
256 | |||
257 | if (strcmp(arg, "nopentium") == 0) { | ||
258 | setup_clear_cpu_cap(X86_FEATURE_PSE); | ||
259 | } else { | ||
260 | /* If the user specifies memory size, we | ||
261 | * limit the BIOS-provided memory map to | ||
262 | * that size. exactmap can be used to specify | ||
263 | * the exact map. mem=number can be used to | ||
264 | * trim the existing memory map. | ||
265 | */ | ||
266 | unsigned long long mem_size; | ||
267 | |||
268 | mem_size = memparse(arg, &arg); | ||
269 | limit_regions(mem_size); | ||
270 | user_defined_memmap = 1; | ||
271 | } | ||
272 | return 0; | ||
273 | } | ||
274 | early_param("mem", parse_mem); | ||
275 | |||
276 | #ifdef CONFIG_PROC_VMCORE | 250 | #ifdef CONFIG_PROC_VMCORE |
277 | /* elfcorehdr= specifies the location of elf core header | 251 | /* elfcorehdr= specifies the location of elf core header |
278 | * stored by the crashed kernel. | 252 | * stored by the crashed kernel. |
@@ -395,56 +369,6 @@ unsigned long __init find_max_low_pfn(void) | |||
395 | return max_low_pfn; | 369 | return max_low_pfn; |
396 | } | 370 | } |
397 | 371 | ||
398 | #define BIOS_LOWMEM_KILOBYTES 0x413 | ||
399 | |||
400 | /* | ||
401 | * The BIOS places the EBDA/XBDA at the top of conventional | ||
402 | * memory, and usually decreases the reported amount of | ||
403 | * conventional memory (int 0x12) too. This also contains a | ||
404 | * workaround for Dell systems that neglect to reserve EBDA. | ||
405 | * The same workaround also avoids a problem with the AMD768MPX | ||
406 | * chipset: reserve a page before VGA to prevent PCI prefetch | ||
407 | * into it (errata #56). Usually the page is reserved anyways, | ||
408 | * unless you have no PS/2 mouse plugged in. | ||
409 | */ | ||
410 | static void __init reserve_ebda_region(void) | ||
411 | { | ||
412 | unsigned int lowmem, ebda_addr; | ||
413 | |||
414 | /* To determine the position of the EBDA and the */ | ||
415 | /* end of conventional memory, we need to look at */ | ||
416 | /* the BIOS data area. In a paravirtual environment */ | ||
417 | /* that area is absent. We'll just have to assume */ | ||
418 | /* that the paravirt case can handle memory setup */ | ||
419 | /* correctly, without our help. */ | ||
420 | if (paravirt_enabled()) | ||
421 | return; | ||
422 | |||
423 | /* end of low (conventional) memory */ | ||
424 | lowmem = *(unsigned short *)__va(BIOS_LOWMEM_KILOBYTES); | ||
425 | lowmem <<= 10; | ||
426 | |||
427 | /* start of EBDA area */ | ||
428 | ebda_addr = get_bios_ebda(); | ||
429 | |||
430 | /* Fixup: bios puts an EBDA in the top 64K segment */ | ||
431 | /* of conventional memory, but does not adjust lowmem. */ | ||
432 | if ((lowmem - ebda_addr) <= 0x10000) | ||
433 | lowmem = ebda_addr; | ||
434 | |||
435 | /* Fixup: bios does not report an EBDA at all. */ | ||
436 | /* Some old Dells seem to need 4k anyhow (bugzilla 2990) */ | ||
437 | if ((ebda_addr == 0) && (lowmem >= 0x9f000)) | ||
438 | lowmem = 0x9f000; | ||
439 | |||
440 | /* Paranoia: should never happen, but... */ | ||
441 | if ((lowmem == 0) || (lowmem >= 0x100000)) | ||
442 | lowmem = 0x9f000; | ||
443 | |||
444 | /* reserve all memory between lowmem and the 1MB mark */ | ||
445 | reserve_bootmem(lowmem, 0x100000 - lowmem, BOOTMEM_DEFAULT); | ||
446 | } | ||
447 | |||
448 | #ifndef CONFIG_NEED_MULTIPLE_NODES | 372 | #ifndef CONFIG_NEED_MULTIPLE_NODES |
449 | static void __init setup_bootmem_allocator(void); | 373 | static void __init setup_bootmem_allocator(void); |
450 | static unsigned long __init setup_memory(void) | 374 | static unsigned long __init setup_memory(void) |
@@ -462,11 +386,13 @@ static unsigned long __init setup_memory(void) | |||
462 | if (max_pfn > max_low_pfn) { | 386 | if (max_pfn > max_low_pfn) { |
463 | highstart_pfn = max_low_pfn; | 387 | highstart_pfn = max_low_pfn; |
464 | } | 388 | } |
389 | memory_present(0, 0, highend_pfn); | ||
465 | printk(KERN_NOTICE "%ldMB HIGHMEM available.\n", | 390 | printk(KERN_NOTICE "%ldMB HIGHMEM available.\n", |
466 | pages_to_mb(highend_pfn - highstart_pfn)); | 391 | pages_to_mb(highend_pfn - highstart_pfn)); |
467 | num_physpages = highend_pfn; | 392 | num_physpages = highend_pfn; |
468 | high_memory = (void *) __va(highstart_pfn * PAGE_SIZE - 1) + 1; | 393 | high_memory = (void *) __va(highstart_pfn * PAGE_SIZE - 1) + 1; |
469 | #else | 394 | #else |
395 | memory_present(0, 0, max_low_pfn); | ||
470 | num_physpages = max_low_pfn; | 396 | num_physpages = max_low_pfn; |
471 | high_memory = (void *) __va(max_low_pfn * PAGE_SIZE - 1) + 1; | 397 | high_memory = (void *) __va(max_low_pfn * PAGE_SIZE - 1) + 1; |
472 | #endif | 398 | #endif |
@@ -488,11 +414,12 @@ static void __init zone_sizes_init(void) | |||
488 | max_zone_pfns[ZONE_DMA] = | 414 | max_zone_pfns[ZONE_DMA] = |
489 | virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; | 415 | virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; |
490 | max_zone_pfns[ZONE_NORMAL] = max_low_pfn; | 416 | max_zone_pfns[ZONE_NORMAL] = max_low_pfn; |
417 | remove_all_active_ranges(); | ||
491 | #ifdef CONFIG_HIGHMEM | 418 | #ifdef CONFIG_HIGHMEM |
492 | max_zone_pfns[ZONE_HIGHMEM] = highend_pfn; | 419 | max_zone_pfns[ZONE_HIGHMEM] = highend_pfn; |
493 | add_active_range(0, 0, highend_pfn); | 420 | e820_register_active_regions(0, 0, highend_pfn); |
494 | #else | 421 | #else |
495 | add_active_range(0, 0, max_low_pfn); | 422 | e820_register_active_regions(0, 0, max_low_pfn); |
496 | #endif | 423 | #endif |
497 | 424 | ||
498 | free_area_init_nodes(max_zone_pfns); | 425 | free_area_init_nodes(max_zone_pfns); |
@@ -526,25 +453,28 @@ static void __init reserve_crashkernel(void) | |||
526 | ret = parse_crashkernel(boot_command_line, total_mem, | 453 | ret = parse_crashkernel(boot_command_line, total_mem, |
527 | &crash_size, &crash_base); | 454 | &crash_size, &crash_base); |
528 | if (ret == 0 && crash_size > 0) { | 455 | if (ret == 0 && crash_size > 0) { |
529 | if (crash_base > 0) { | 456 | if (crash_base <= 0) { |
530 | printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " | ||
531 | "for crashkernel (System RAM: %ldMB)\n", | ||
532 | (unsigned long)(crash_size >> 20), | ||
533 | (unsigned long)(crash_base >> 20), | ||
534 | (unsigned long)(total_mem >> 20)); | ||
535 | |||
536 | if (reserve_bootmem(crash_base, crash_size, | ||
537 | BOOTMEM_EXCLUSIVE) < 0) { | ||
538 | printk(KERN_INFO "crashkernel reservation " | ||
539 | "failed - memory is in use\n"); | ||
540 | return; | ||
541 | } | ||
542 | |||
543 | crashk_res.start = crash_base; | ||
544 | crashk_res.end = crash_base + crash_size - 1; | ||
545 | } else | ||
546 | printk(KERN_INFO "crashkernel reservation failed - " | 457 | printk(KERN_INFO "crashkernel reservation failed - " |
547 | "you have to specify a base address\n"); | 458 | "you have to specify a base address\n"); |
459 | return; | ||
460 | } | ||
461 | |||
462 | if (reserve_bootmem_generic(crash_base, crash_size, | ||
463 | BOOTMEM_EXCLUSIVE) < 0) { | ||
464 | printk(KERN_INFO "crashkernel reservation failed - " | ||
465 | "memory is in use\n"); | ||
466 | return; | ||
467 | } | ||
468 | |||
469 | printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " | ||
470 | "for crashkernel (System RAM: %ldMB)\n", | ||
471 | (unsigned long)(crash_size >> 20), | ||
472 | (unsigned long)(crash_base >> 20), | ||
473 | (unsigned long)(total_mem >> 20)); | ||
474 | |||
475 | crashk_res.start = crash_base; | ||
476 | crashk_res.end = crash_base + crash_size - 1; | ||
477 | insert_resource(&iomem_resource, &crashk_res); | ||
548 | } | 478 | } |
549 | } | 479 | } |
550 | #else | 480 | #else |
@@ -558,44 +488,57 @@ static bool do_relocate_initrd = false; | |||
558 | 488 | ||
559 | static void __init reserve_initrd(void) | 489 | static void __init reserve_initrd(void) |
560 | { | 490 | { |
561 | unsigned long ramdisk_image = boot_params.hdr.ramdisk_image; | 491 | u64 ramdisk_image = boot_params.hdr.ramdisk_image; |
562 | unsigned long ramdisk_size = boot_params.hdr.ramdisk_size; | 492 | u64 ramdisk_size = boot_params.hdr.ramdisk_size; |
563 | unsigned long ramdisk_end = ramdisk_image + ramdisk_size; | 493 | u64 ramdisk_end = ramdisk_image + ramdisk_size; |
564 | unsigned long end_of_lowmem = max_low_pfn << PAGE_SHIFT; | 494 | u64 end_of_lowmem = max_low_pfn << PAGE_SHIFT; |
565 | unsigned long ramdisk_here; | 495 | u64 ramdisk_here; |
566 | |||
567 | initrd_start = 0; | ||
568 | 496 | ||
569 | if (!boot_params.hdr.type_of_loader || | 497 | if (!boot_params.hdr.type_of_loader || |
570 | !ramdisk_image || !ramdisk_size) | 498 | !ramdisk_image || !ramdisk_size) |
571 | return; /* No initrd provided by bootloader */ | 499 | return; /* No initrd provided by bootloader */ |
572 | 500 | ||
573 | if (ramdisk_end < ramdisk_image) { | 501 | initrd_start = 0; |
574 | printk(KERN_ERR "initrd wraps around end of memory, " | 502 | |
575 | "disabling initrd\n"); | ||
576 | return; | ||
577 | } | ||
578 | if (ramdisk_size >= end_of_lowmem/2) { | 503 | if (ramdisk_size >= end_of_lowmem/2) { |
504 | free_early(ramdisk_image, ramdisk_end); | ||
579 | printk(KERN_ERR "initrd too large to handle, " | 505 | printk(KERN_ERR "initrd too large to handle, " |
580 | "disabling initrd\n"); | 506 | "disabling initrd\n"); |
581 | return; | 507 | return; |
582 | } | 508 | } |
509 | |||
510 | printk(KERN_INFO "old RAMDISK: %08llx - %08llx\n", ramdisk_image, | ||
511 | ramdisk_end); | ||
512 | |||
513 | |||
583 | if (ramdisk_end <= end_of_lowmem) { | 514 | if (ramdisk_end <= end_of_lowmem) { |
584 | /* All in lowmem, easy case */ | 515 | /* All in lowmem, easy case */ |
585 | reserve_bootmem(ramdisk_image, ramdisk_size, BOOTMEM_DEFAULT); | 516 | /* |
517 | * don't need to reserve again, already reserved early | ||
518 | * in i386_start_kernel | ||
519 | */ | ||
586 | initrd_start = ramdisk_image + PAGE_OFFSET; | 520 | initrd_start = ramdisk_image + PAGE_OFFSET; |
587 | initrd_end = initrd_start+ramdisk_size; | 521 | initrd_end = initrd_start+ramdisk_size; |
588 | return; | 522 | return; |
589 | } | 523 | } |
590 | 524 | ||
591 | /* We need to move the initrd down into lowmem */ | 525 | /* We need to move the initrd down into lowmem */ |
592 | ramdisk_here = (end_of_lowmem - ramdisk_size) & PAGE_MASK; | 526 | ramdisk_here = find_e820_area(min_low_pfn<<PAGE_SHIFT, |
527 | end_of_lowmem, ramdisk_size, | ||
528 | PAGE_SIZE); | ||
529 | |||
530 | if (ramdisk_here == -1ULL) | ||
531 | panic("Cannot find place for new RAMDISK of size %lld\n", | ||
532 | ramdisk_size); | ||
593 | 533 | ||
594 | /* Note: this includes all the lowmem currently occupied by | 534 | /* Note: this includes all the lowmem currently occupied by |
595 | the initrd, we rely on that fact to keep the data intact. */ | 535 | the initrd, we rely on that fact to keep the data intact. */ |
596 | reserve_bootmem(ramdisk_here, ramdisk_size, BOOTMEM_DEFAULT); | 536 | reserve_early(ramdisk_here, ramdisk_here + ramdisk_size, |
537 | "NEW RAMDISK"); | ||
597 | initrd_start = ramdisk_here + PAGE_OFFSET; | 538 | initrd_start = ramdisk_here + PAGE_OFFSET; |
598 | initrd_end = initrd_start + ramdisk_size; | 539 | initrd_end = initrd_start + ramdisk_size; |
540 | printk(KERN_INFO "Allocated new RAMDISK: %08llx - %08llx\n", | ||
541 | ramdisk_here, ramdisk_here + ramdisk_size); | ||
599 | 542 | ||
600 | do_relocate_initrd = true; | 543 | do_relocate_initrd = true; |
601 | } | 544 | } |
@@ -604,10 +547,10 @@ static void __init reserve_initrd(void) | |||
604 | 547 | ||
605 | static void __init relocate_initrd(void) | 548 | static void __init relocate_initrd(void) |
606 | { | 549 | { |
607 | unsigned long ramdisk_image = boot_params.hdr.ramdisk_image; | 550 | u64 ramdisk_image = boot_params.hdr.ramdisk_image; |
608 | unsigned long ramdisk_size = boot_params.hdr.ramdisk_size; | 551 | u64 ramdisk_size = boot_params.hdr.ramdisk_size; |
609 | unsigned long end_of_lowmem = max_low_pfn << PAGE_SHIFT; | 552 | u64 end_of_lowmem = max_low_pfn << PAGE_SHIFT; |
610 | unsigned long ramdisk_here; | 553 | u64 ramdisk_here; |
611 | unsigned long slop, clen, mapaddr; | 554 | unsigned long slop, clen, mapaddr; |
612 | char *p, *q; | 555 | char *p, *q; |
613 | 556 | ||
@@ -624,6 +567,10 @@ static void __init relocate_initrd(void) | |||
624 | p = (char *)__va(ramdisk_image); | 567 | p = (char *)__va(ramdisk_image); |
625 | memcpy(q, p, clen); | 568 | memcpy(q, p, clen); |
626 | q += clen; | 569 | q += clen; |
570 | /* need to free these low pages...*/ | ||
571 | printk(KERN_INFO "Freeing old partial RAMDISK %08llx-%08llx\n", | ||
572 | ramdisk_image, ramdisk_image + clen - 1); | ||
573 | free_bootmem(ramdisk_image, clen); | ||
627 | ramdisk_image += clen; | 574 | ramdisk_image += clen; |
628 | ramdisk_size -= clen; | 575 | ramdisk_size -= clen; |
629 | } | 576 | } |
@@ -642,66 +589,47 @@ static void __init relocate_initrd(void) | |||
642 | ramdisk_image += clen; | 589 | ramdisk_image += clen; |
643 | ramdisk_size -= clen; | 590 | ramdisk_size -= clen; |
644 | } | 591 | } |
592 | /* high pages is not converted by early_res_to_bootmem */ | ||
593 | ramdisk_image = boot_params.hdr.ramdisk_image; | ||
594 | ramdisk_size = boot_params.hdr.ramdisk_size; | ||
595 | printk(KERN_INFO "Copied RAMDISK from %016llx - %016llx to %08llx - %08llx\n", | ||
596 | ramdisk_image, ramdisk_image + ramdisk_size - 1, | ||
597 | ramdisk_here, ramdisk_here + ramdisk_size - 1); | ||
598 | |||
599 | /* need to free that, otherwise init highmem will reserve it again */ | ||
600 | free_early(ramdisk_image, ramdisk_image+ramdisk_size); | ||
645 | } | 601 | } |
646 | 602 | ||
647 | #endif /* CONFIG_BLK_DEV_INITRD */ | 603 | #endif /* CONFIG_BLK_DEV_INITRD */ |
648 | 604 | ||
649 | void __init setup_bootmem_allocator(void) | 605 | void __init setup_bootmem_allocator(void) |
650 | { | 606 | { |
651 | unsigned long bootmap_size; | 607 | int i; |
608 | unsigned long bootmap_size, bootmap; | ||
652 | /* | 609 | /* |
653 | * Initialize the boot-time allocator (with low memory only): | 610 | * Initialize the boot-time allocator (with low memory only): |
654 | */ | 611 | */ |
655 | bootmap_size = init_bootmem(min_low_pfn, max_low_pfn); | 612 | bootmap_size = bootmem_bootmap_pages(max_low_pfn)<<PAGE_SHIFT; |
656 | 613 | bootmap = find_e820_area(min_low_pfn<<PAGE_SHIFT, | |
657 | register_bootmem_low_pages(max_low_pfn); | 614 | max_pfn_mapped<<PAGE_SHIFT, bootmap_size, |
658 | 615 | PAGE_SIZE); | |
659 | /* | 616 | if (bootmap == -1L) |
660 | * Reserve the bootmem bitmap itself as well. We do this in two | 617 | panic("Cannot find bootmem map of size %ld\n", bootmap_size); |
661 | * steps (first step was init_bootmem()) because this catches | 618 | reserve_early(bootmap, bootmap + bootmap_size, "BOOTMAP"); |
662 | * the (very unlikely) case of us accidentally initializing the | ||
663 | * bootmem allocator with an invalid RAM area. | ||
664 | */ | ||
665 | reserve_bootmem(__pa_symbol(_text), (PFN_PHYS(min_low_pfn) + | ||
666 | bootmap_size + PAGE_SIZE-1) - __pa_symbol(_text), | ||
667 | BOOTMEM_DEFAULT); | ||
668 | |||
669 | /* | ||
670 | * reserve physical page 0 - it's a special BIOS page on many boxes, | ||
671 | * enabling clean reboots, SMP operation, laptop functions. | ||
672 | */ | ||
673 | reserve_bootmem(0, PAGE_SIZE, BOOTMEM_DEFAULT); | ||
674 | |||
675 | /* reserve EBDA region */ | ||
676 | reserve_ebda_region(); | ||
677 | |||
678 | #ifdef CONFIG_SMP | ||
679 | /* | ||
680 | * But first pinch a few for the stack/trampoline stuff | ||
681 | * FIXME: Don't need the extra page at 4K, but need to fix | ||
682 | * trampoline before removing it. (see the GDT stuff) | ||
683 | */ | ||
684 | reserve_bootmem(PAGE_SIZE, PAGE_SIZE, BOOTMEM_DEFAULT); | ||
685 | #endif | ||
686 | #ifdef CONFIG_ACPI_SLEEP | ||
687 | /* | ||
688 | * Reserve low memory region for sleep support. | ||
689 | */ | ||
690 | acpi_reserve_bootmem(); | ||
691 | #endif | ||
692 | #ifdef CONFIG_X86_FIND_SMP_CONFIG | ||
693 | /* | ||
694 | * Find and reserve possible boot-time SMP configuration: | ||
695 | */ | ||
696 | find_smp_config(); | ||
697 | #endif | ||
698 | #ifdef CONFIG_BLK_DEV_INITRD | 619 | #ifdef CONFIG_BLK_DEV_INITRD |
699 | reserve_initrd(); | 620 | reserve_initrd(); |
700 | #endif | 621 | #endif |
701 | numa_kva_reserve(); | 622 | bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, max_low_pfn); |
702 | reserve_crashkernel(); | 623 | printk(KERN_INFO " mapped low ram: 0 - %08lx\n", |
624 | max_pfn_mapped<<PAGE_SHIFT); | ||
625 | printk(KERN_INFO " low ram: %08lx - %08lx\n", | ||
626 | min_low_pfn<<PAGE_SHIFT, max_low_pfn<<PAGE_SHIFT); | ||
627 | printk(KERN_INFO " bootmap %08lx - %08lx\n", | ||
628 | bootmap, bootmap + bootmap_size); | ||
629 | for_each_online_node(i) | ||
630 | free_bootmem_with_active_regions(i, max_low_pfn); | ||
631 | early_res_to_bootmem(0, max_low_pfn<<PAGE_SHIFT); | ||
703 | 632 | ||
704 | reserve_ibft_region(); | ||
705 | } | 633 | } |
706 | 634 | ||
707 | /* | 635 | /* |
@@ -731,12 +659,6 @@ static void set_mca_bus(int x) | |||
731 | static void set_mca_bus(int x) { } | 659 | static void set_mca_bus(int x) { } |
732 | #endif | 660 | #endif |
733 | 661 | ||
734 | /* Overridden in paravirt.c if CONFIG_PARAVIRT */ | ||
735 | char * __init __attribute__((weak)) memory_setup(void) | ||
736 | { | ||
737 | return machine_specific_memory_setup(); | ||
738 | } | ||
739 | |||
740 | #ifdef CONFIG_NUMA | 662 | #ifdef CONFIG_NUMA |
741 | /* | 663 | /* |
742 | * In the golden day, when everything among i386 and x86_64 will be | 664 | * In the golden day, when everything among i386 and x86_64 will be |
@@ -749,6 +671,8 @@ int x86_cpu_to_node_map_init[NR_CPUS] = { | |||
749 | DEFINE_PER_CPU(int, x86_cpu_to_node_map) = NUMA_NO_NODE; | 671 | DEFINE_PER_CPU(int, x86_cpu_to_node_map) = NUMA_NO_NODE; |
750 | #endif | 672 | #endif |
751 | 673 | ||
674 | static void probe_roms(void); | ||
675 | |||
752 | /* | 676 | /* |
753 | * Determine if we were loaded by an EFI loader. If so, then we have also been | 677 | * Determine if we were loaded by an EFI loader. If so, then we have also been |
754 | * passed the efi memmap, systab, etc., so we should use these data structures | 678 | * passed the efi memmap, systab, etc., so we should use these data structures |
@@ -758,17 +682,21 @@ DEFINE_PER_CPU(int, x86_cpu_to_node_map) = NUMA_NO_NODE; | |||
758 | */ | 682 | */ |
759 | void __init setup_arch(char **cmdline_p) | 683 | void __init setup_arch(char **cmdline_p) |
760 | { | 684 | { |
685 | int i; | ||
761 | unsigned long max_low_pfn; | 686 | unsigned long max_low_pfn; |
762 | 687 | ||
763 | memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); | 688 | memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); |
764 | pre_setup_arch_hook(); | 689 | pre_setup_arch_hook(); |
765 | early_cpu_init(); | 690 | early_cpu_init(); |
766 | early_ioremap_init(); | 691 | early_ioremap_init(); |
692 | reserve_setup_data(); | ||
767 | 693 | ||
768 | #ifdef CONFIG_EFI | 694 | #ifdef CONFIG_EFI |
769 | if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature, | 695 | if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature, |
770 | "EL32", 4)) | 696 | "EL32", 4)) { |
771 | efi_enabled = 1; | 697 | efi_enabled = 1; |
698 | efi_reserve_early(); | ||
699 | } | ||
772 | #endif | 700 | #endif |
773 | 701 | ||
774 | ROOT_DEV = old_decode_dev(boot_params.hdr.root_dev); | 702 | ROOT_DEV = old_decode_dev(boot_params.hdr.root_dev); |
@@ -792,8 +720,7 @@ void __init setup_arch(char **cmdline_p) | |||
792 | #endif | 720 | #endif |
793 | ARCH_SETUP | 721 | ARCH_SETUP |
794 | 722 | ||
795 | printk(KERN_INFO "BIOS-provided physical RAM map:\n"); | 723 | setup_memory_map(); |
796 | print_memory_map(memory_setup()); | ||
797 | 724 | ||
798 | copy_edd(); | 725 | copy_edd(); |
799 | 726 | ||
@@ -811,12 +738,18 @@ void __init setup_arch(char **cmdline_p) | |||
811 | bss_resource.start = virt_to_phys(&__bss_start); | 738 | bss_resource.start = virt_to_phys(&__bss_start); |
812 | bss_resource.end = virt_to_phys(&__bss_stop)-1; | 739 | bss_resource.end = virt_to_phys(&__bss_stop)-1; |
813 | 740 | ||
741 | parse_setup_data(); | ||
742 | |||
814 | parse_early_param(); | 743 | parse_early_param(); |
815 | 744 | ||
816 | if (user_defined_memmap) { | 745 | finish_e820_parsing(); |
817 | printk(KERN_INFO "user-defined physical RAM map:\n"); | 746 | |
818 | print_memory_map("user"); | 747 | probe_roms(); |
819 | } | 748 | |
749 | /* after parse_early_param, so could debug it */ | ||
750 | insert_resource(&iomem_resource, &code_resource); | ||
751 | insert_resource(&iomem_resource, &data_resource); | ||
752 | insert_resource(&iomem_resource, &bss_resource); | ||
820 | 753 | ||
821 | strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); | 754 | strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); |
822 | *cmdline_p = command_line; | 755 | *cmdline_p = command_line; |
@@ -824,14 +757,67 @@ void __init setup_arch(char **cmdline_p) | |||
824 | if (efi_enabled) | 757 | if (efi_enabled) |
825 | efi_init(); | 758 | efi_init(); |
826 | 759 | ||
760 | if (ppro_with_ram_bug()) { | ||
761 | e820_update_range(0x70000000ULL, 0x40000ULL, E820_RAM, | ||
762 | E820_RESERVED); | ||
763 | sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map); | ||
764 | printk(KERN_INFO "fixed physical RAM map:\n"); | ||
765 | e820_print_map("bad_ppro"); | ||
766 | } | ||
767 | |||
768 | e820_register_active_regions(0, 0, -1UL); | ||
769 | /* | ||
770 | * partially used pages are not usable - thus | ||
771 | * we are rounding upwards: | ||
772 | */ | ||
773 | max_pfn = e820_end_of_ram(); | ||
774 | |||
775 | /* preallocate 4k for mptable mpc */ | ||
776 | early_reserve_e820_mpc_new(); | ||
827 | /* update e820 for memory not covered by WB MTRRs */ | 777 | /* update e820 for memory not covered by WB MTRRs */ |
828 | propagate_e820_map(); | ||
829 | mtrr_bp_init(); | 778 | mtrr_bp_init(); |
830 | if (mtrr_trim_uncached_memory(max_pfn)) | 779 | if (mtrr_trim_uncached_memory(max_pfn)) { |
831 | propagate_e820_map(); | 780 | remove_all_active_ranges(); |
781 | e820_register_active_regions(0, 0, -1UL); | ||
782 | max_pfn = e820_end_of_ram(); | ||
783 | } | ||
784 | |||
785 | dmi_scan_machine(); | ||
786 | |||
787 | io_delay_init(); | ||
788 | |||
789 | #ifdef CONFIG_ACPI | ||
790 | /* | ||
791 | * Parse the ACPI tables for possible boot-time SMP configuration. | ||
792 | */ | ||
793 | acpi_boot_table_init(); | ||
794 | #endif | ||
795 | |||
796 | #ifdef CONFIG_ACPI_NUMA | ||
797 | /* | ||
798 | * Parse SRAT to discover nodes. | ||
799 | */ | ||
800 | acpi_numa_init(); | ||
801 | #endif | ||
832 | 802 | ||
833 | max_low_pfn = setup_memory(); | 803 | max_low_pfn = setup_memory(); |
834 | 804 | ||
805 | #ifdef CONFIG_ACPI_SLEEP | ||
806 | /* | ||
807 | * Reserve low memory region for sleep support. | ||
808 | */ | ||
809 | acpi_reserve_bootmem(); | ||
810 | #endif | ||
811 | #ifdef CONFIG_X86_FIND_SMP_CONFIG | ||
812 | /* | ||
813 | * Find and reserve possible boot-time SMP configuration: | ||
814 | */ | ||
815 | find_smp_config(); | ||
816 | #endif | ||
817 | reserve_crashkernel(); | ||
818 | |||
819 | reserve_ibft_region(); | ||
820 | |||
835 | #ifdef CONFIG_KVM_CLOCK | 821 | #ifdef CONFIG_KVM_CLOCK |
836 | kvmclock_init(); | 822 | kvmclock_init(); |
837 | #endif | 823 | #endif |
@@ -855,9 +841,6 @@ void __init setup_arch(char **cmdline_p) | |||
855 | * not to exceed the 8Mb limit. | 841 | * not to exceed the 8Mb limit. |
856 | */ | 842 | */ |
857 | 843 | ||
858 | #ifdef CONFIG_SMP | ||
859 | smp_alloc_memory(); /* AP processor realmode stacks in low memory*/ | ||
860 | #endif | ||
861 | paging_init(); | 844 | paging_init(); |
862 | 845 | ||
863 | /* | 846 | /* |
@@ -869,10 +852,6 @@ void __init setup_arch(char **cmdline_p) | |||
869 | init_ohci1394_dma_on_all_controllers(); | 852 | init_ohci1394_dma_on_all_controllers(); |
870 | #endif | 853 | #endif |
871 | 854 | ||
872 | remapped_pgdat_init(); | ||
873 | sparse_init(); | ||
874 | zone_sizes_init(); | ||
875 | |||
876 | /* | 855 | /* |
877 | * NOTE: at this point the bootmem allocator is fully available. | 856 | * NOTE: at this point the bootmem allocator is fully available. |
878 | */ | 857 | */ |
@@ -881,11 +860,11 @@ void __init setup_arch(char **cmdline_p) | |||
881 | relocate_initrd(); | 860 | relocate_initrd(); |
882 | #endif | 861 | #endif |
883 | 862 | ||
884 | paravirt_post_allocator_init(); | 863 | remapped_pgdat_init(); |
885 | 864 | sparse_init(); | |
886 | dmi_scan_machine(); | 865 | zone_sizes_init(); |
887 | 866 | ||
888 | io_delay_init(); | 867 | paravirt_post_allocator_init(); |
889 | 868 | ||
890 | #ifdef CONFIG_X86_SMP | 869 | #ifdef CONFIG_X86_SMP |
891 | /* | 870 | /* |
@@ -903,32 +882,31 @@ void __init setup_arch(char **cmdline_p) | |||
903 | generic_apic_probe(); | 882 | generic_apic_probe(); |
904 | #endif | 883 | #endif |
905 | 884 | ||
906 | #ifdef CONFIG_ACPI | ||
907 | /* | ||
908 | * Parse the ACPI tables for possible boot-time SMP configuration. | ||
909 | */ | ||
910 | acpi_boot_table_init(); | ||
911 | #endif | ||
912 | |||
913 | early_quirks(); | 885 | early_quirks(); |
914 | 886 | ||
915 | #ifdef CONFIG_ACPI | 887 | #ifdef CONFIG_ACPI |
916 | acpi_boot_init(); | 888 | acpi_boot_init(); |
917 | 889 | #endif | |
890 | #if defined(CONFIG_X86_MPPARSE) || defined(CONFIG_X86_VISWS) | ||
891 | if (smp_found_config) | ||
892 | get_smp_config(); | ||
893 | #endif | ||
918 | #if defined(CONFIG_SMP) && defined(CONFIG_X86_PC) | 894 | #if defined(CONFIG_SMP) && defined(CONFIG_X86_PC) |
919 | if (def_to_bigsmp) | 895 | if (def_to_bigsmp) |
920 | printk(KERN_WARNING "More than 8 CPUs detected and " | 896 | printk(KERN_WARNING "More than 8 CPUs detected and " |
921 | "CONFIG_X86_PC cannot handle it.\nUse " | 897 | "CONFIG_X86_PC cannot handle it.\nUse " |
922 | "CONFIG_X86_GENERICARCH or CONFIG_X86_BIGSMP.\n"); | 898 | "CONFIG_X86_GENERICARCH or CONFIG_X86_BIGSMP.\n"); |
923 | #endif | 899 | #endif |
924 | #endif | ||
925 | #ifdef CONFIG_X86_LOCAL_APIC | ||
926 | if (smp_found_config) | ||
927 | get_smp_config(); | ||
928 | #endif | ||
929 | 900 | ||
930 | e820_register_memory(); | 901 | e820_reserve_resources(); |
931 | e820_mark_nosave_regions(); | 902 | e820_mark_nosave_regions(max_low_pfn); |
903 | |||
904 | request_resource(&iomem_resource, &video_ram_resource); | ||
905 | /* request I/O space for devices used on all i[345]86 PCs */ | ||
906 | for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++) | ||
907 | request_resource(&ioport_resource, &standard_io_resources[i]); | ||
908 | |||
909 | e820_setup_gap(); | ||
932 | 910 | ||
933 | #ifdef CONFIG_VT | 911 | #ifdef CONFIG_VT |
934 | #if defined(CONFIG_VGA_CONSOLE) | 912 | #if defined(CONFIG_VGA_CONSOLE) |
@@ -940,25 +918,147 @@ void __init setup_arch(char **cmdline_p) | |||
940 | #endif | 918 | #endif |
941 | } | 919 | } |
942 | 920 | ||
943 | /* | 921 | static struct resource system_rom_resource = { |
944 | * Request address space for all standard resources | 922 | .name = "System ROM", |
945 | * | 923 | .start = 0xf0000, |
946 | * This is called just before pcibios_init(), which is also a | 924 | .end = 0xfffff, |
947 | * subsys_initcall, but is linked in later (in arch/i386/pci/common.c). | 925 | .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM |
948 | */ | 926 | }; |
949 | static int __init request_standard_resources(void) | 927 | |
928 | static struct resource extension_rom_resource = { | ||
929 | .name = "Extension ROM", | ||
930 | .start = 0xe0000, | ||
931 | .end = 0xeffff, | ||
932 | .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM | ||
933 | }; | ||
934 | |||
935 | static struct resource adapter_rom_resources[] = { { | ||
936 | .name = "Adapter ROM", | ||
937 | .start = 0xc8000, | ||
938 | .end = 0, | ||
939 | .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM | ||
940 | }, { | ||
941 | .name = "Adapter ROM", | ||
942 | .start = 0, | ||
943 | .end = 0, | ||
944 | .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM | ||
945 | }, { | ||
946 | .name = "Adapter ROM", | ||
947 | .start = 0, | ||
948 | .end = 0, | ||
949 | .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM | ||
950 | }, { | ||
951 | .name = "Adapter ROM", | ||
952 | .start = 0, | ||
953 | .end = 0, | ||
954 | .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM | ||
955 | }, { | ||
956 | .name = "Adapter ROM", | ||
957 | .start = 0, | ||
958 | .end = 0, | ||
959 | .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM | ||
960 | }, { | ||
961 | .name = "Adapter ROM", | ||
962 | .start = 0, | ||
963 | .end = 0, | ||
964 | .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM | ||
965 | } }; | ||
966 | |||
967 | static struct resource video_rom_resource = { | ||
968 | .name = "Video ROM", | ||
969 | .start = 0xc0000, | ||
970 | .end = 0xc7fff, | ||
971 | .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM | ||
972 | }; | ||
973 | |||
974 | #define ROMSIGNATURE 0xaa55 | ||
975 | |||
976 | static int __init romsignature(const unsigned char *rom) | ||
950 | { | 977 | { |
978 | const unsigned short * const ptr = (const unsigned short *)rom; | ||
979 | unsigned short sig; | ||
980 | |||
981 | return probe_kernel_address(ptr, sig) == 0 && sig == ROMSIGNATURE; | ||
982 | } | ||
983 | |||
984 | static int __init romchecksum(const unsigned char *rom, unsigned long length) | ||
985 | { | ||
986 | unsigned char sum, c; | ||
987 | |||
988 | for (sum = 0; length && probe_kernel_address(rom++, c) == 0; length--) | ||
989 | sum += c; | ||
990 | return !length && !sum; | ||
991 | } | ||
992 | |||
993 | static void __init probe_roms(void) | ||
994 | { | ||
995 | const unsigned char *rom; | ||
996 | unsigned long start, length, upper; | ||
997 | unsigned char c; | ||
951 | int i; | 998 | int i; |
952 | 999 | ||
953 | printk(KERN_INFO "Setting up standard PCI resources\n"); | 1000 | /* video rom */ |
954 | init_iomem_resources(&code_resource, &data_resource, &bss_resource); | 1001 | upper = adapter_rom_resources[0].start; |
1002 | for (start = video_rom_resource.start; start < upper; start += 2048) { | ||
1003 | rom = isa_bus_to_virt(start); | ||
1004 | if (!romsignature(rom)) | ||
1005 | continue; | ||
955 | 1006 | ||
956 | request_resource(&iomem_resource, &video_ram_resource); | 1007 | video_rom_resource.start = start; |
957 | 1008 | ||
958 | /* request I/O space for devices used on all i[345]86 PCs */ | 1009 | if (probe_kernel_address(rom + 2, c) != 0) |
959 | for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++) | 1010 | continue; |
960 | request_resource(&ioport_resource, &standard_io_resources[i]); | 1011 | |
961 | return 0; | 1012 | /* 0 < length <= 0x7f * 512, historically */ |
1013 | length = c * 512; | ||
1014 | |||
1015 | /* if checksum okay, trust length byte */ | ||
1016 | if (length && romchecksum(rom, length)) | ||
1017 | video_rom_resource.end = start + length - 1; | ||
1018 | |||
1019 | request_resource(&iomem_resource, &video_rom_resource); | ||
1020 | break; | ||
1021 | } | ||
1022 | |||
1023 | start = (video_rom_resource.end + 1 + 2047) & ~2047UL; | ||
1024 | if (start < upper) | ||
1025 | start = upper; | ||
1026 | |||
1027 | /* system rom */ | ||
1028 | request_resource(&iomem_resource, &system_rom_resource); | ||
1029 | upper = system_rom_resource.start; | ||
1030 | |||
1031 | /* check for extension rom (ignore length byte!) */ | ||
1032 | rom = isa_bus_to_virt(extension_rom_resource.start); | ||
1033 | if (romsignature(rom)) { | ||
1034 | length = extension_rom_resource.end - extension_rom_resource.start + 1; | ||
1035 | if (romchecksum(rom, length)) { | ||
1036 | request_resource(&iomem_resource, &extension_rom_resource); | ||
1037 | upper = extension_rom_resource.start; | ||
1038 | } | ||
1039 | } | ||
1040 | |||
1041 | /* check for adapter roms on 2k boundaries */ | ||
1042 | for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper; start += 2048) { | ||
1043 | rom = isa_bus_to_virt(start); | ||
1044 | if (!romsignature(rom)) | ||
1045 | continue; | ||
1046 | |||
1047 | if (probe_kernel_address(rom + 2, c) != 0) | ||
1048 | continue; | ||
1049 | |||
1050 | /* 0 < length <= 0x7f * 512, historically */ | ||
1051 | length = c * 512; | ||
1052 | |||
1053 | /* but accept any length that fits if checksum okay */ | ||
1054 | if (!length || start + length > upper || !romchecksum(rom, length)) | ||
1055 | continue; | ||
1056 | |||
1057 | adapter_rom_resources[i].start = start; | ||
1058 | adapter_rom_resources[i].end = start + length - 1; | ||
1059 | request_resource(&iomem_resource, &adapter_rom_resources[i]); | ||
1060 | |||
1061 | start = adapter_rom_resources[i++].end & ~2047UL; | ||
1062 | } | ||
962 | } | 1063 | } |
963 | 1064 | ||
964 | subsys_initcall(request_standard_resources); | ||