diff options
Diffstat (limited to 'arch/i386/kernel/setup.c')
-rw-r--r-- | arch/i386/kernel/setup.c | 367 |
1 files changed, 128 insertions, 239 deletions
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 16d99444cf66..76a524b4c90f 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c | |||
@@ -90,18 +90,6 @@ EXPORT_SYMBOL(boot_cpu_data); | |||
90 | 90 | ||
91 | unsigned long mmu_cr4_features; | 91 | unsigned long mmu_cr4_features; |
92 | 92 | ||
93 | #ifdef CONFIG_ACPI | ||
94 | int acpi_disabled = 0; | ||
95 | #else | ||
96 | int acpi_disabled = 1; | ||
97 | #endif | ||
98 | EXPORT_SYMBOL(acpi_disabled); | ||
99 | |||
100 | #ifdef CONFIG_ACPI | ||
101 | int __initdata acpi_force = 0; | ||
102 | extern acpi_interrupt_flags acpi_sci_flags; | ||
103 | #endif | ||
104 | |||
105 | /* for MCA, but anyone else can use it if they want */ | 93 | /* for MCA, but anyone else can use it if they want */ |
106 | unsigned int machine_id; | 94 | unsigned int machine_id; |
107 | #ifdef CONFIG_MCA | 95 | #ifdef CONFIG_MCA |
@@ -149,7 +137,6 @@ EXPORT_SYMBOL(ist_info); | |||
149 | struct e820map e820; | 137 | struct e820map e820; |
150 | 138 | ||
151 | extern void early_cpu_init(void); | 139 | extern void early_cpu_init(void); |
152 | extern void generic_apic_probe(char *); | ||
153 | extern int root_mountflags; | 140 | extern int root_mountflags; |
154 | 141 | ||
155 | unsigned long saved_videomode; | 142 | unsigned long saved_videomode; |
@@ -701,238 +688,132 @@ static inline void copy_edd(void) | |||
701 | } | 688 | } |
702 | #endif | 689 | #endif |
703 | 690 | ||
704 | static void __init parse_cmdline_early (char ** cmdline_p) | 691 | static int __initdata user_defined_memmap = 0; |
705 | { | ||
706 | char c = ' ', *to = command_line, *from = saved_command_line; | ||
707 | int len = 0; | ||
708 | int userdef = 0; | ||
709 | 692 | ||
710 | /* Save unparsed command line copy for /proc/cmdline */ | 693 | /* |
711 | saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; | 694 | * "mem=nopentium" disables the 4MB page tables. |
695 | * "mem=XXX[kKmM]" defines a memory region from HIGH_MEM | ||
696 | * to <mem>, overriding the bios size. | ||
697 | * "memmap=XXX[KkmM]@XXX[KkmM]" defines a memory region from | ||
698 | * <start> to <start>+<mem>, overriding the bios size. | ||
699 | * | ||
700 | * HPA tells me bootloaders need to parse mem=, so no new | ||
701 | * option should be mem= [also see Documentation/i386/boot.txt] | ||
702 | */ | ||
703 | static int __init parse_mem(char *arg) | ||
704 | { | ||
705 | if (!arg) | ||
706 | return -EINVAL; | ||
712 | 707 | ||
713 | for (;;) { | 708 | if (strcmp(arg, "nopentium") == 0) { |
714 | if (c != ' ') | 709 | clear_bit(X86_FEATURE_PSE, boot_cpu_data.x86_capability); |
715 | goto next_char; | 710 | disable_pse = 1; |
716 | /* | 711 | } else { |
717 | * "mem=nopentium" disables the 4MB page tables. | 712 | /* If the user specifies memory size, we |
718 | * "mem=XXX[kKmM]" defines a memory region from HIGH_MEM | 713 | * limit the BIOS-provided memory map to |
719 | * to <mem>, overriding the bios size. | 714 | * that size. exactmap can be used to specify |
720 | * "memmap=XXX[KkmM]@XXX[KkmM]" defines a memory region from | 715 | * the exact map. mem=number can be used to |
721 | * <start> to <start>+<mem>, overriding the bios size. | 716 | * trim the existing memory map. |
722 | * | ||
723 | * HPA tells me bootloaders need to parse mem=, so no new | ||
724 | * option should be mem= [also see Documentation/i386/boot.txt] | ||
725 | */ | 717 | */ |
726 | if (!memcmp(from, "mem=", 4)) { | 718 | unsigned long long mem_size; |
727 | if (to != command_line) | ||
728 | to--; | ||
729 | if (!memcmp(from+4, "nopentium", 9)) { | ||
730 | from += 9+4; | ||
731 | clear_bit(X86_FEATURE_PSE, boot_cpu_data.x86_capability); | ||
732 | disable_pse = 1; | ||
733 | } else { | ||
734 | /* If the user specifies memory size, we | ||
735 | * limit the BIOS-provided memory map to | ||
736 | * that size. exactmap can be used to specify | ||
737 | * the exact map. mem=number can be used to | ||
738 | * trim the existing memory map. | ||
739 | */ | ||
740 | unsigned long long mem_size; | ||
741 | 719 | ||
742 | mem_size = memparse(from+4, &from); | 720 | mem_size = memparse(arg, &arg); |
743 | limit_regions(mem_size); | 721 | limit_regions(mem_size); |
744 | userdef=1; | 722 | user_defined_memmap = 1; |
745 | } | 723 | } |
746 | } | 724 | return 0; |
747 | 725 | } | |
748 | else if (!memcmp(from, "memmap=", 7)) { | 726 | early_param("mem", parse_mem); |
749 | if (to != command_line) | ||
750 | to--; | ||
751 | if (!memcmp(from+7, "exactmap", 8)) { | ||
752 | #ifdef CONFIG_CRASH_DUMP | ||
753 | /* If we are doing a crash dump, we | ||
754 | * still need to know the real mem | ||
755 | * size before original memory map is | ||
756 | * reset. | ||
757 | */ | ||
758 | find_max_pfn(); | ||
759 | saved_max_pfn = max_pfn; | ||
760 | #endif | ||
761 | from += 8+7; | ||
762 | e820.nr_map = 0; | ||
763 | userdef = 1; | ||
764 | } else { | ||
765 | /* If the user specifies memory size, we | ||
766 | * limit the BIOS-provided memory map to | ||
767 | * that size. exactmap can be used to specify | ||
768 | * the exact map. mem=number can be used to | ||
769 | * trim the existing memory map. | ||
770 | */ | ||
771 | unsigned long long start_at, mem_size; | ||
772 | |||
773 | mem_size = memparse(from+7, &from); | ||
774 | if (*from == '@') { | ||
775 | start_at = memparse(from+1, &from); | ||
776 | add_memory_region(start_at, mem_size, E820_RAM); | ||
777 | } else if (*from == '#') { | ||
778 | start_at = memparse(from+1, &from); | ||
779 | add_memory_region(start_at, mem_size, E820_ACPI); | ||
780 | } else if (*from == '$') { | ||
781 | start_at = memparse(from+1, &from); | ||
782 | add_memory_region(start_at, mem_size, E820_RESERVED); | ||
783 | } else { | ||
784 | limit_regions(mem_size); | ||
785 | userdef=1; | ||
786 | } | ||
787 | } | ||
788 | } | ||
789 | |||
790 | else if (!memcmp(from, "noexec=", 7)) | ||
791 | noexec_setup(from + 7); | ||
792 | 727 | ||
728 | static int __init parse_memmap(char *arg) | ||
729 | { | ||
730 | if (!arg) | ||
731 | return -EINVAL; | ||
793 | 732 | ||
794 | #ifdef CONFIG_X86_SMP | 733 | if (strcmp(arg, "exactmap") == 0) { |
795 | /* | 734 | #ifdef CONFIG_CRASH_DUMP |
796 | * If the BIOS enumerates physical processors before logical, | 735 | /* If we are doing a crash dump, we |
797 | * maxcpus=N at enumeration-time can be used to disable HT. | 736 | * still need to know the real mem |
737 | * size before original memory map is | ||
738 | * reset. | ||
798 | */ | 739 | */ |
799 | else if (!memcmp(from, "maxcpus=", 8)) { | 740 | find_max_pfn(); |
800 | extern unsigned int maxcpus; | 741 | saved_max_pfn = max_pfn; |
801 | |||
802 | maxcpus = simple_strtoul(from + 8, NULL, 0); | ||
803 | } | ||
804 | #endif | 742 | #endif |
805 | 743 | e820.nr_map = 0; | |
806 | #ifdef CONFIG_ACPI | 744 | user_defined_memmap = 1; |
807 | /* "acpi=off" disables both ACPI table parsing and interpreter */ | 745 | } else { |
808 | else if (!memcmp(from, "acpi=off", 8)) { | 746 | /* If the user specifies memory size, we |
809 | disable_acpi(); | 747 | * limit the BIOS-provided memory map to |
810 | } | 748 | * that size. exactmap can be used to specify |
811 | 749 | * the exact map. mem=number can be used to | |
812 | /* acpi=force to over-ride black-list */ | 750 | * trim the existing memory map. |
813 | else if (!memcmp(from, "acpi=force", 10)) { | 751 | */ |
814 | acpi_force = 1; | 752 | unsigned long long start_at, mem_size; |
815 | acpi_ht = 1; | 753 | |
816 | acpi_disabled = 0; | 754 | mem_size = memparse(arg, &arg); |
817 | } | 755 | if (*arg == '@') { |
818 | 756 | start_at = memparse(arg+1, &arg); | |
819 | /* acpi=strict disables out-of-spec workarounds */ | 757 | add_memory_region(start_at, mem_size, E820_RAM); |
820 | else if (!memcmp(from, "acpi=strict", 11)) { | 758 | } else if (*arg == '#') { |
821 | acpi_strict = 1; | 759 | start_at = memparse(arg+1, &arg); |
822 | } | 760 | add_memory_region(start_at, mem_size, E820_ACPI); |
823 | 761 | } else if (*arg == '$') { | |
824 | /* Limit ACPI just to boot-time to enable HT */ | 762 | start_at = memparse(arg+1, &arg); |
825 | else if (!memcmp(from, "acpi=ht", 7)) { | 763 | add_memory_region(start_at, mem_size, E820_RESERVED); |
826 | if (!acpi_force) | 764 | } else { |
827 | disable_acpi(); | 765 | limit_regions(mem_size); |
828 | acpi_ht = 1; | 766 | user_defined_memmap = 1; |
829 | } | ||
830 | |||
831 | /* "pci=noacpi" disable ACPI IRQ routing and PCI scan */ | ||
832 | else if (!memcmp(from, "pci=noacpi", 10)) { | ||
833 | acpi_disable_pci(); | ||
834 | } | ||
835 | /* "acpi=noirq" disables ACPI interrupt routing */ | ||
836 | else if (!memcmp(from, "acpi=noirq", 10)) { | ||
837 | acpi_noirq_set(); | ||
838 | } | 767 | } |
768 | } | ||
769 | return 0; | ||
770 | } | ||
771 | early_param("memmap", parse_memmap); | ||
839 | 772 | ||
840 | else if (!memcmp(from, "acpi_sci=edge", 13)) | 773 | #ifdef CONFIG_PROC_VMCORE |
841 | acpi_sci_flags.trigger = 1; | 774 | /* elfcorehdr= specifies the location of elf core header |
842 | 775 | * stored by the crashed kernel. | |
843 | else if (!memcmp(from, "acpi_sci=level", 14)) | 776 | */ |
844 | acpi_sci_flags.trigger = 3; | 777 | static int __init parse_elfcorehdr(char *arg) |
845 | 778 | { | |
846 | else if (!memcmp(from, "acpi_sci=high", 13)) | 779 | if (!arg) |
847 | acpi_sci_flags.polarity = 1; | 780 | return -EINVAL; |
848 | |||
849 | else if (!memcmp(from, "acpi_sci=low", 12)) | ||
850 | acpi_sci_flags.polarity = 3; | ||
851 | |||
852 | #ifdef CONFIG_X86_IO_APIC | ||
853 | else if (!memcmp(from, "acpi_skip_timer_override", 24)) | ||
854 | acpi_skip_timer_override = 1; | ||
855 | |||
856 | if (!memcmp(from, "disable_timer_pin_1", 19)) | ||
857 | disable_timer_pin_1 = 1; | ||
858 | if (!memcmp(from, "enable_timer_pin_1", 18)) | ||
859 | disable_timer_pin_1 = -1; | ||
860 | 781 | ||
861 | /* disable IO-APIC */ | 782 | elfcorehdr_addr = memparse(arg, &arg); |
862 | else if (!memcmp(from, "noapic", 6)) | 783 | return 0; |
863 | disable_ioapic_setup(); | 784 | } |
864 | #endif /* CONFIG_X86_IO_APIC */ | 785 | early_param("elfcorehdr", parse_elfcorehdr); |
865 | #endif /* CONFIG_ACPI */ | 786 | #endif /* CONFIG_PROC_VMCORE */ |
866 | 787 | ||
867 | #ifdef CONFIG_X86_LOCAL_APIC | 788 | /* |
868 | /* enable local APIC */ | 789 | * highmem=size forces highmem to be exactly 'size' bytes. |
869 | else if (!memcmp(from, "lapic", 5)) | 790 | * This works even on boxes that have no highmem otherwise. |
870 | lapic_enable(); | 791 | * This also works to reduce highmem size on bigger boxes. |
792 | */ | ||
793 | static int __init parse_highmem(char *arg) | ||
794 | { | ||
795 | if (!arg) | ||
796 | return -EINVAL; | ||
871 | 797 | ||
872 | /* disable local APIC */ | 798 | highmem_pages = memparse(arg, &arg) >> PAGE_SHIFT; |
873 | else if (!memcmp(from, "nolapic", 6)) | 799 | return 0; |
874 | lapic_disable(); | 800 | } |
875 | #endif /* CONFIG_X86_LOCAL_APIC */ | 801 | early_param("highmem", parse_highmem); |
876 | 802 | ||
877 | #ifdef CONFIG_KEXEC | 803 | /* |
878 | /* crashkernel=size@addr specifies the location to reserve for | 804 | * vmalloc=size forces the vmalloc area to be exactly 'size' |
879 | * a crash kernel. By reserving this memory we guarantee | 805 | * bytes. This can be used to increase (or decrease) the |
880 | * that linux never set's it up as a DMA target. | 806 | * vmalloc area - the default is 128m. |
881 | * Useful for holding code to do something appropriate | 807 | */ |
882 | * after a kernel panic. | 808 | static int __init parse_vmalloc(char *arg) |
883 | */ | 809 | { |
884 | else if (!memcmp(from, "crashkernel=", 12)) { | 810 | if (!arg) |
885 | unsigned long size, base; | 811 | return -EINVAL; |
886 | size = memparse(from+12, &from); | ||
887 | if (*from == '@') { | ||
888 | base = memparse(from+1, &from); | ||
889 | /* FIXME: Do I want a sanity check | ||
890 | * to validate the memory range? | ||
891 | */ | ||
892 | crashk_res.start = base; | ||
893 | crashk_res.end = base + size - 1; | ||
894 | } | ||
895 | } | ||
896 | #endif | ||
897 | #ifdef CONFIG_PROC_VMCORE | ||
898 | /* elfcorehdr= specifies the location of elf core header | ||
899 | * stored by the crashed kernel. | ||
900 | */ | ||
901 | else if (!memcmp(from, "elfcorehdr=", 11)) | ||
902 | elfcorehdr_addr = memparse(from+11, &from); | ||
903 | #endif | ||
904 | 812 | ||
905 | /* | 813 | __VMALLOC_RESERVE = memparse(arg, &arg); |
906 | * highmem=size forces highmem to be exactly 'size' bytes. | 814 | return 0; |
907 | * This works even on boxes that have no highmem otherwise. | ||
908 | * This also works to reduce highmem size on bigger boxes. | ||
909 | */ | ||
910 | else if (!memcmp(from, "highmem=", 8)) | ||
911 | highmem_pages = memparse(from+8, &from) >> PAGE_SHIFT; | ||
912 | |||
913 | /* | ||
914 | * vmalloc=size forces the vmalloc area to be exactly 'size' | ||
915 | * bytes. This can be used to increase (or decrease) the | ||
916 | * vmalloc area - the default is 128m. | ||
917 | */ | ||
918 | else if (!memcmp(from, "vmalloc=", 8)) | ||
919 | __VMALLOC_RESERVE = memparse(from+8, &from); | ||
920 | |||
921 | next_char: | ||
922 | c = *(from++); | ||
923 | if (!c) | ||
924 | break; | ||
925 | if (COMMAND_LINE_SIZE <= ++len) | ||
926 | break; | ||
927 | *(to++) = c; | ||
928 | } | ||
929 | *to = '\0'; | ||
930 | *cmdline_p = command_line; | ||
931 | if (userdef) { | ||
932 | printk(KERN_INFO "user-defined physical RAM map:\n"); | ||
933 | print_memory_map("user"); | ||
934 | } | ||
935 | } | 815 | } |
816 | early_param("vmalloc", parse_vmalloc); | ||
936 | 817 | ||
937 | /* | 818 | /* |
938 | * reservetop=size reserves a hole at the top of the kernel address space which | 819 | * reservetop=size reserves a hole at the top of the kernel address space which |
@@ -1189,6 +1070,14 @@ static unsigned long __init setup_memory(void) | |||
1189 | } | 1070 | } |
1190 | printk(KERN_NOTICE "%ldMB HIGHMEM available.\n", | 1071 | printk(KERN_NOTICE "%ldMB HIGHMEM available.\n", |
1191 | pages_to_mb(highend_pfn - highstart_pfn)); | 1072 | pages_to_mb(highend_pfn - highstart_pfn)); |
1073 | num_physpages = highend_pfn; | ||
1074 | high_memory = (void *) __va(highstart_pfn * PAGE_SIZE - 1) + 1; | ||
1075 | #else | ||
1076 | num_physpages = max_low_pfn; | ||
1077 | high_memory = (void *) __va(max_low_pfn * PAGE_SIZE - 1) + 1; | ||
1078 | #endif | ||
1079 | #ifdef CONFIG_FLATMEM | ||
1080 | max_mapnr = num_physpages; | ||
1192 | #endif | 1081 | #endif |
1193 | printk(KERN_NOTICE "%ldMB LOWMEM available.\n", | 1082 | printk(KERN_NOTICE "%ldMB LOWMEM available.\n", |
1194 | pages_to_mb(max_low_pfn)); | 1083 | pages_to_mb(max_low_pfn)); |
@@ -1518,17 +1407,15 @@ void __init setup_arch(char **cmdline_p) | |||
1518 | data_resource.start = virt_to_phys(_etext); | 1407 | data_resource.start = virt_to_phys(_etext); |
1519 | data_resource.end = virt_to_phys(_edata)-1; | 1408 | data_resource.end = virt_to_phys(_edata)-1; |
1520 | 1409 | ||
1521 | parse_cmdline_early(cmdline_p); | 1410 | parse_early_param(); |
1522 | 1411 | ||
1523 | #ifdef CONFIG_EARLY_PRINTK | 1412 | if (user_defined_memmap) { |
1524 | { | 1413 | printk(KERN_INFO "user-defined physical RAM map:\n"); |
1525 | char *s = strstr(*cmdline_p, "earlyprintk="); | 1414 | print_memory_map("user"); |
1526 | if (s) { | ||
1527 | setup_early_printk(strchr(s, '=') + 1); | ||
1528 | printk("early console enabled\n"); | ||
1529 | } | ||
1530 | } | 1415 | } |
1531 | #endif | 1416 | |
1417 | strlcpy(command_line, saved_command_line, COMMAND_LINE_SIZE); | ||
1418 | *cmdline_p = command_line; | ||
1532 | 1419 | ||
1533 | max_low_pfn = setup_memory(); | 1420 | max_low_pfn = setup_memory(); |
1534 | 1421 | ||
@@ -1557,7 +1444,7 @@ void __init setup_arch(char **cmdline_p) | |||
1557 | dmi_scan_machine(); | 1444 | dmi_scan_machine(); |
1558 | 1445 | ||
1559 | #ifdef CONFIG_X86_GENERICARCH | 1446 | #ifdef CONFIG_X86_GENERICARCH |
1560 | generic_apic_probe(*cmdline_p); | 1447 | generic_apic_probe(); |
1561 | #endif | 1448 | #endif |
1562 | if (efi_enabled) | 1449 | if (efi_enabled) |
1563 | efi_map_memmap(); | 1450 | efi_map_memmap(); |
@@ -1569,9 +1456,11 @@ void __init setup_arch(char **cmdline_p) | |||
1569 | acpi_boot_table_init(); | 1456 | acpi_boot_table_init(); |
1570 | #endif | 1457 | #endif |
1571 | 1458 | ||
1459 | #ifdef CONFIG_PCI | ||
1572 | #ifdef CONFIG_X86_IO_APIC | 1460 | #ifdef CONFIG_X86_IO_APIC |
1573 | check_acpi_pci(); /* Checks more than just ACPI actually */ | 1461 | check_acpi_pci(); /* Checks more than just ACPI actually */ |
1574 | #endif | 1462 | #endif |
1463 | #endif | ||
1575 | 1464 | ||
1576 | #ifdef CONFIG_ACPI | 1465 | #ifdef CONFIG_ACPI |
1577 | acpi_boot_init(); | 1466 | acpi_boot_init(); |