diff options
Diffstat (limited to 'arch/i386')
-rw-r--r-- | arch/i386/kernel/acpi/boot.c | 76 | ||||
-rw-r--r-- | arch/i386/kernel/apic.c | 15 | ||||
-rw-r--r-- | arch/i386/kernel/io_apic.c | 24 | ||||
-rw-r--r-- | arch/i386/kernel/machine_kexec.c | 23 | ||||
-rw-r--r-- | arch/i386/kernel/setup.c | 350 | ||||
-rw-r--r-- | arch/i386/kernel/smpboot.c | 13 | ||||
-rw-r--r-- | arch/i386/mach-generic/probe.c | 58 | ||||
-rw-r--r-- | arch/i386/mm/init.c | 18 |
8 files changed, 306 insertions, 271 deletions
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index ee003bc0e8b1..87e2ab50b694 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c | |||
@@ -36,6 +36,8 @@ | |||
36 | #include <asm/io.h> | 36 | #include <asm/io.h> |
37 | #include <asm/mpspec.h> | 37 | #include <asm/mpspec.h> |
38 | 38 | ||
39 | int __initdata acpi_force = 0; | ||
40 | |||
39 | #ifdef CONFIG_X86_64 | 41 | #ifdef CONFIG_X86_64 |
40 | 42 | ||
41 | extern void __init clustered_apic_check(void); | 43 | extern void __init clustered_apic_check(void); |
@@ -860,8 +862,6 @@ static void __init acpi_process_madt(void) | |||
860 | return; | 862 | return; |
861 | } | 863 | } |
862 | 864 | ||
863 | extern int acpi_force; | ||
864 | |||
865 | #ifdef __i386__ | 865 | #ifdef __i386__ |
866 | 866 | ||
867 | static int __init disable_acpi_irq(struct dmi_system_id *d) | 867 | static int __init disable_acpi_irq(struct dmi_system_id *d) |
@@ -1163,3 +1163,75 @@ int __init acpi_boot_init(void) | |||
1163 | 1163 | ||
1164 | return 0; | 1164 | return 0; |
1165 | } | 1165 | } |
1166 | |||
1167 | static int __init parse_acpi(char *arg) | ||
1168 | { | ||
1169 | if (!arg) | ||
1170 | return -EINVAL; | ||
1171 | |||
1172 | /* "acpi=off" disables both ACPI table parsing and interpreter */ | ||
1173 | if (strcmp(arg, "off") == 0) { | ||
1174 | disable_acpi(); | ||
1175 | } | ||
1176 | /* acpi=force to over-ride black-list */ | ||
1177 | else if (strcmp(arg, "force") == 0) { | ||
1178 | acpi_force = 1; | ||
1179 | acpi_ht = 1; | ||
1180 | acpi_disabled = 0; | ||
1181 | } | ||
1182 | /* acpi=strict disables out-of-spec workarounds */ | ||
1183 | else if (strcmp(arg, "strict") == 0) { | ||
1184 | acpi_strict = 1; | ||
1185 | } | ||
1186 | /* Limit ACPI just to boot-time to enable HT */ | ||
1187 | else if (strcmp(arg, "ht") == 0) { | ||
1188 | if (!acpi_force) | ||
1189 | disable_acpi(); | ||
1190 | acpi_ht = 1; | ||
1191 | } | ||
1192 | /* "acpi=noirq" disables ACPI interrupt routing */ | ||
1193 | else if (strcmp(arg, "noirq") == 0) { | ||
1194 | acpi_noirq_set(); | ||
1195 | } else { | ||
1196 | /* Core will printk when we return error. */ | ||
1197 | return -EINVAL; | ||
1198 | } | ||
1199 | return 0; | ||
1200 | } | ||
1201 | early_param("acpi", parse_acpi); | ||
1202 | |||
1203 | /* FIXME: Using pci= for an ACPI parameter is a travesty. */ | ||
1204 | static int __init parse_pci(char *arg) | ||
1205 | { | ||
1206 | if (arg && strcmp(arg, "noacpi") == 0) | ||
1207 | acpi_disable_pci(); | ||
1208 | return 0; | ||
1209 | } | ||
1210 | early_param("pci", parse_pci); | ||
1211 | |||
1212 | #ifdef CONFIG_X86_IO_APIC | ||
1213 | static int __init parse_acpi_skip_timer_override(char *arg) | ||
1214 | { | ||
1215 | acpi_skip_timer_override = 1; | ||
1216 | return 0; | ||
1217 | } | ||
1218 | early_param("acpi_skip_timer_override", parse_acpi_skip_timer_override); | ||
1219 | #endif /* CONFIG_X86_IO_APIC */ | ||
1220 | |||
1221 | static int __init setup_acpi_sci(char *s) | ||
1222 | { | ||
1223 | if (!s) | ||
1224 | return -EINVAL; | ||
1225 | if (!strcmp(s, "edge")) | ||
1226 | acpi_sci_flags.trigger = 1; | ||
1227 | else if (!strcmp(s, "level")) | ||
1228 | acpi_sci_flags.trigger = 3; | ||
1229 | else if (!strcmp(s, "high")) | ||
1230 | acpi_sci_flags.polarity = 1; | ||
1231 | else if (!strcmp(s, "low")) | ||
1232 | acpi_sci_flags.polarity = 3; | ||
1233 | else | ||
1234 | return -EINVAL; | ||
1235 | return 0; | ||
1236 | } | ||
1237 | early_param("acpi_sci", setup_acpi_sci); | ||
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index 1a34fc57800b..ce75e71b694f 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c | |||
@@ -1372,3 +1372,18 @@ int __init APIC_init_uniprocessor (void) | |||
1372 | 1372 | ||
1373 | return 0; | 1373 | return 0; |
1374 | } | 1374 | } |
1375 | |||
1376 | static int __init parse_lapic(char *arg) | ||
1377 | { | ||
1378 | lapic_enable(); | ||
1379 | return 0; | ||
1380 | } | ||
1381 | early_param("lapic", parse_lapic); | ||
1382 | |||
1383 | static int __init parse_nolapic(char *arg) | ||
1384 | { | ||
1385 | lapic_disable(); | ||
1386 | return 0; | ||
1387 | } | ||
1388 | early_param("nolapic", parse_nolapic); | ||
1389 | |||
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index b713f27d7e86..fd0df75cfbda 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c | |||
@@ -66,7 +66,7 @@ int sis_apic_bug = -1; | |||
66 | */ | 66 | */ |
67 | int nr_ioapic_registers[MAX_IO_APICS]; | 67 | int nr_ioapic_registers[MAX_IO_APICS]; |
68 | 68 | ||
69 | int disable_timer_pin_1 __initdata; | 69 | static int disable_timer_pin_1 __initdata; |
70 | 70 | ||
71 | /* | 71 | /* |
72 | * Rough estimation of how many shared IRQs there are, can | 72 | * Rough estimation of how many shared IRQs there are, can |
@@ -2691,3 +2691,25 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int a | |||
2691 | } | 2691 | } |
2692 | 2692 | ||
2693 | #endif /* CONFIG_ACPI */ | 2693 | #endif /* CONFIG_ACPI */ |
2694 | |||
2695 | static int __init parse_disable_timer_pin_1(char *arg) | ||
2696 | { | ||
2697 | disable_timer_pin_1 = 1; | ||
2698 | return 0; | ||
2699 | } | ||
2700 | early_param("disable_timer_pin_1", parse_disable_timer_pin_1); | ||
2701 | |||
2702 | static int __init parse_enable_timer_pin_1(char *arg) | ||
2703 | { | ||
2704 | disable_timer_pin_1 = -1; | ||
2705 | return 0; | ||
2706 | } | ||
2707 | early_param("enable_timer_pin_1", parse_enable_timer_pin_1); | ||
2708 | |||
2709 | static int __init parse_noapic(char *arg) | ||
2710 | { | ||
2711 | /* disable IO-APIC */ | ||
2712 | disable_ioapic_setup(); | ||
2713 | return 0; | ||
2714 | } | ||
2715 | early_param("noapic", parse_noapic); | ||
diff --git a/arch/i386/kernel/machine_kexec.c b/arch/i386/kernel/machine_kexec.c index 6b1ae6ba76f0..66c3dc99a655 100644 --- a/arch/i386/kernel/machine_kexec.c +++ b/arch/i386/kernel/machine_kexec.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/mm.h> | 9 | #include <linux/mm.h> |
10 | #include <linux/kexec.h> | 10 | #include <linux/kexec.h> |
11 | #include <linux/delay.h> | 11 | #include <linux/delay.h> |
12 | #include <linux/init.h> | ||
12 | #include <asm/pgtable.h> | 13 | #include <asm/pgtable.h> |
13 | #include <asm/pgalloc.h> | 14 | #include <asm/pgalloc.h> |
14 | #include <asm/tlbflush.h> | 15 | #include <asm/tlbflush.h> |
@@ -209,3 +210,25 @@ NORET_TYPE void machine_kexec(struct kimage *image) | |||
209 | rnk = (relocate_new_kernel_t) reboot_code_buffer; | 210 | rnk = (relocate_new_kernel_t) reboot_code_buffer; |
210 | (*rnk)(page_list, reboot_code_buffer, image->start, cpu_has_pae); | 211 | (*rnk)(page_list, reboot_code_buffer, image->start, cpu_has_pae); |
211 | } | 212 | } |
213 | |||
214 | /* crashkernel=size@addr specifies the location to reserve for | ||
215 | * a crash kernel. By reserving this memory we guarantee | ||
216 | * that linux never sets it up as a DMA target. | ||
217 | * Useful for holding code to do something appropriate | ||
218 | * after a kernel panic. | ||
219 | */ | ||
220 | static int __init parse_crashkernel(char *arg) | ||
221 | { | ||
222 | unsigned long size, base; | ||
223 | size = memparse(arg, &arg); | ||
224 | if (*arg == '@') { | ||
225 | base = memparse(arg+1, &arg); | ||
226 | /* FIXME: Do I want a sanity check | ||
227 | * to validate the memory range? | ||
228 | */ | ||
229 | crashk_res.start = base; | ||
230 | crashk_res.end = base + size - 1; | ||
231 | } | ||
232 | return 0; | ||
233 | } | ||
234 | early_param("crashkernel", parse_crashkernel); | ||
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 71a540362b78..c6e31ed386f5 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c | |||
@@ -96,11 +96,6 @@ unsigned long mmu_cr4_features; | |||
96 | #endif | 96 | #endif |
97 | EXPORT_SYMBOL(acpi_disabled); | 97 | EXPORT_SYMBOL(acpi_disabled); |
98 | 98 | ||
99 | #ifdef CONFIG_ACPI | ||
100 | int __initdata acpi_force = 0; | ||
101 | extern acpi_interrupt_flags acpi_sci_flags; | ||
102 | #endif | ||
103 | |||
104 | /* for MCA, but anyone else can use it if they want */ | 99 | /* for MCA, but anyone else can use it if they want */ |
105 | unsigned int machine_id; | 100 | unsigned int machine_id; |
106 | #ifdef CONFIG_MCA | 101 | #ifdef CONFIG_MCA |
@@ -148,7 +143,6 @@ EXPORT_SYMBOL(ist_info); | |||
148 | struct e820map e820; | 143 | struct e820map e820; |
149 | 144 | ||
150 | extern void early_cpu_init(void); | 145 | extern void early_cpu_init(void); |
151 | extern void generic_apic_probe(char *); | ||
152 | extern int root_mountflags; | 146 | extern int root_mountflags; |
153 | 147 | ||
154 | unsigned long saved_videomode; | 148 | unsigned long saved_videomode; |
@@ -700,238 +694,132 @@ static inline void copy_edd(void) | |||
700 | } | 694 | } |
701 | #endif | 695 | #endif |
702 | 696 | ||
703 | static void __init parse_cmdline_early (char ** cmdline_p) | 697 | static int __initdata user_defined_memmap = 0; |
704 | { | ||
705 | char c = ' ', *to = command_line, *from = saved_command_line; | ||
706 | int len = 0; | ||
707 | int userdef = 0; | ||
708 | 698 | ||
709 | /* Save unparsed command line copy for /proc/cmdline */ | 699 | /* |
710 | saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; | 700 | * "mem=nopentium" disables the 4MB page tables. |
701 | * "mem=XXX[kKmM]" defines a memory region from HIGH_MEM | ||
702 | * to <mem>, overriding the bios size. | ||
703 | * "memmap=XXX[KkmM]@XXX[KkmM]" defines a memory region from | ||
704 | * <start> to <start>+<mem>, overriding the bios size. | ||
705 | * | ||
706 | * HPA tells me bootloaders need to parse mem=, so no new | ||
707 | * option should be mem= [also see Documentation/i386/boot.txt] | ||
708 | */ | ||
709 | static int __init parse_mem(char *arg) | ||
710 | { | ||
711 | if (!arg) | ||
712 | return -EINVAL; | ||
711 | 713 | ||
712 | for (;;) { | 714 | if (strcmp(arg, "nopentium") == 0) { |
713 | if (c != ' ') | 715 | clear_bit(X86_FEATURE_PSE, boot_cpu_data.x86_capability); |
714 | goto next_char; | 716 | disable_pse = 1; |
715 | /* | 717 | } else { |
716 | * "mem=nopentium" disables the 4MB page tables. | 718 | /* If the user specifies memory size, we |
717 | * "mem=XXX[kKmM]" defines a memory region from HIGH_MEM | 719 | * limit the BIOS-provided memory map to |
718 | * to <mem>, overriding the bios size. | 720 | * that size. exactmap can be used to specify |
719 | * "memmap=XXX[KkmM]@XXX[KkmM]" defines a memory region from | 721 | * the exact map. mem=number can be used to |
720 | * <start> to <start>+<mem>, overriding the bios size. | 722 | * trim the existing memory map. |
721 | * | ||
722 | * HPA tells me bootloaders need to parse mem=, so no new | ||
723 | * option should be mem= [also see Documentation/i386/boot.txt] | ||
724 | */ | 723 | */ |
725 | if (!memcmp(from, "mem=", 4)) { | 724 | unsigned long long mem_size; |
726 | if (to != command_line) | ||
727 | to--; | ||
728 | if (!memcmp(from+4, "nopentium", 9)) { | ||
729 | from += 9+4; | ||
730 | clear_bit(X86_FEATURE_PSE, boot_cpu_data.x86_capability); | ||
731 | disable_pse = 1; | ||
732 | } else { | ||
733 | /* If the user specifies memory size, we | ||
734 | * limit the BIOS-provided memory map to | ||
735 | * that size. exactmap can be used to specify | ||
736 | * the exact map. mem=number can be used to | ||
737 | * trim the existing memory map. | ||
738 | */ | ||
739 | unsigned long long mem_size; | ||
740 | 725 | ||
741 | mem_size = memparse(from+4, &from); | 726 | mem_size = memparse(arg, &arg); |
742 | limit_regions(mem_size); | 727 | limit_regions(mem_size); |
743 | userdef=1; | 728 | user_defined_memmap = 1; |
744 | } | 729 | } |
745 | } | 730 | return 0; |
746 | 731 | } | |
747 | else if (!memcmp(from, "memmap=", 7)) { | 732 | early_param("mem", parse_mem); |
748 | if (to != command_line) | ||
749 | to--; | ||
750 | if (!memcmp(from+7, "exactmap", 8)) { | ||
751 | #ifdef CONFIG_CRASH_DUMP | ||
752 | /* If we are doing a crash dump, we | ||
753 | * still need to know the real mem | ||
754 | * size before original memory map is | ||
755 | * reset. | ||
756 | */ | ||
757 | find_max_pfn(); | ||
758 | saved_max_pfn = max_pfn; | ||
759 | #endif | ||
760 | from += 8+7; | ||
761 | e820.nr_map = 0; | ||
762 | userdef = 1; | ||
763 | } else { | ||
764 | /* If the user specifies memory size, we | ||
765 | * limit the BIOS-provided memory map to | ||
766 | * that size. exactmap can be used to specify | ||
767 | * the exact map. mem=number can be used to | ||
768 | * trim the existing memory map. | ||
769 | */ | ||
770 | unsigned long long start_at, mem_size; | ||
771 | |||
772 | mem_size = memparse(from+7, &from); | ||
773 | if (*from == '@') { | ||
774 | start_at = memparse(from+1, &from); | ||
775 | add_memory_region(start_at, mem_size, E820_RAM); | ||
776 | } else if (*from == '#') { | ||
777 | start_at = memparse(from+1, &from); | ||
778 | add_memory_region(start_at, mem_size, E820_ACPI); | ||
779 | } else if (*from == '$') { | ||
780 | start_at = memparse(from+1, &from); | ||
781 | add_memory_region(start_at, mem_size, E820_RESERVED); | ||
782 | } else { | ||
783 | limit_regions(mem_size); | ||
784 | userdef=1; | ||
785 | } | ||
786 | } | ||
787 | } | ||
788 | |||
789 | else if (!memcmp(from, "noexec=", 7)) | ||
790 | noexec_setup(from + 7); | ||
791 | 733 | ||
734 | static int __init parse_memmap(char *arg) | ||
735 | { | ||
736 | if (!arg) | ||
737 | return -EINVAL; | ||
792 | 738 | ||
793 | #ifdef CONFIG_X86_SMP | 739 | if (strcmp(arg, "exactmap") == 0) { |
794 | /* | 740 | #ifdef CONFIG_CRASH_DUMP |
795 | * If the BIOS enumerates physical processors before logical, | 741 | /* If we are doing a crash dump, we |
796 | * maxcpus=N at enumeration-time can be used to disable HT. | 742 | * still need to know the real mem |
743 | * size before original memory map is | ||
744 | * reset. | ||
797 | */ | 745 | */ |
798 | else if (!memcmp(from, "maxcpus=", 8)) { | 746 | find_max_pfn(); |
799 | extern unsigned int maxcpus; | 747 | saved_max_pfn = max_pfn; |
800 | |||
801 | maxcpus = simple_strtoul(from + 8, NULL, 0); | ||
802 | } | ||
803 | #endif | 748 | #endif |
804 | 749 | e820.nr_map = 0; | |
805 | #ifdef CONFIG_ACPI | 750 | user_defined_memmap = 1; |
806 | /* "acpi=off" disables both ACPI table parsing and interpreter */ | 751 | } else { |
807 | else if (!memcmp(from, "acpi=off", 8)) { | 752 | /* If the user specifies memory size, we |
808 | disable_acpi(); | 753 | * limit the BIOS-provided memory map to |
809 | } | 754 | * that size. exactmap can be used to specify |
810 | 755 | * the exact map. mem=number can be used to | |
811 | /* acpi=force to over-ride black-list */ | 756 | * trim the existing memory map. |
812 | else if (!memcmp(from, "acpi=force", 10)) { | 757 | */ |
813 | acpi_force = 1; | 758 | unsigned long long start_at, mem_size; |
814 | acpi_ht = 1; | 759 | |
815 | acpi_disabled = 0; | 760 | mem_size = memparse(arg, &arg); |
816 | } | 761 | if (*arg == '@') { |
817 | 762 | start_at = memparse(arg+1, &arg); | |
818 | /* acpi=strict disables out-of-spec workarounds */ | 763 | add_memory_region(start_at, mem_size, E820_RAM); |
819 | else if (!memcmp(from, "acpi=strict", 11)) { | 764 | } else if (*arg == '#') { |
820 | acpi_strict = 1; | 765 | start_at = memparse(arg+1, &arg); |
821 | } | 766 | add_memory_region(start_at, mem_size, E820_ACPI); |
822 | 767 | } else if (*arg == '$') { | |
823 | /* Limit ACPI just to boot-time to enable HT */ | 768 | start_at = memparse(arg+1, &arg); |
824 | else if (!memcmp(from, "acpi=ht", 7)) { | 769 | add_memory_region(start_at, mem_size, E820_RESERVED); |
825 | if (!acpi_force) | 770 | } else { |
826 | disable_acpi(); | 771 | limit_regions(mem_size); |
827 | acpi_ht = 1; | 772 | user_defined_memmap = 1; |
828 | } | ||
829 | |||
830 | /* "pci=noacpi" disable ACPI IRQ routing and PCI scan */ | ||
831 | else if (!memcmp(from, "pci=noacpi", 10)) { | ||
832 | acpi_disable_pci(); | ||
833 | } | ||
834 | /* "acpi=noirq" disables ACPI interrupt routing */ | ||
835 | else if (!memcmp(from, "acpi=noirq", 10)) { | ||
836 | acpi_noirq_set(); | ||
837 | } | 773 | } |
774 | } | ||
775 | return 0; | ||
776 | } | ||
777 | early_param("memmap", parse_memmap); | ||
838 | 778 | ||
839 | else if (!memcmp(from, "acpi_sci=edge", 13)) | 779 | #ifdef CONFIG_PROC_VMCORE |
840 | acpi_sci_flags.trigger = 1; | 780 | /* elfcorehdr= specifies the location of elf core header |
841 | 781 | * stored by the crashed kernel. | |
842 | else if (!memcmp(from, "acpi_sci=level", 14)) | 782 | */ |
843 | acpi_sci_flags.trigger = 3; | 783 | static int __init parse_elfcorehdr(char *arg) |
844 | 784 | { | |
845 | else if (!memcmp(from, "acpi_sci=high", 13)) | 785 | if (!arg) |
846 | acpi_sci_flags.polarity = 1; | 786 | return -EINVAL; |
847 | |||
848 | else if (!memcmp(from, "acpi_sci=low", 12)) | ||
849 | acpi_sci_flags.polarity = 3; | ||
850 | |||
851 | #ifdef CONFIG_X86_IO_APIC | ||
852 | else if (!memcmp(from, "acpi_skip_timer_override", 24)) | ||
853 | acpi_skip_timer_override = 1; | ||
854 | |||
855 | if (!memcmp(from, "disable_timer_pin_1", 19)) | ||
856 | disable_timer_pin_1 = 1; | ||
857 | if (!memcmp(from, "enable_timer_pin_1", 18)) | ||
858 | disable_timer_pin_1 = -1; | ||
859 | 787 | ||
860 | /* disable IO-APIC */ | 788 | elfcorehdr_addr = memparse(arg, &arg); |
861 | else if (!memcmp(from, "noapic", 6)) | 789 | return 0; |
862 | disable_ioapic_setup(); | 790 | } |
863 | #endif /* CONFIG_X86_IO_APIC */ | 791 | early_param("elfcorehdr", parse_elfcorehdr); |
864 | #endif /* CONFIG_ACPI */ | 792 | #endif /* CONFIG_PROC_VMCORE */ |
865 | 793 | ||
866 | #ifdef CONFIG_X86_LOCAL_APIC | 794 | /* |
867 | /* enable local APIC */ | 795 | * highmem=size forces highmem to be exactly 'size' bytes. |
868 | else if (!memcmp(from, "lapic", 5)) | 796 | * This works even on boxes that have no highmem otherwise. |
869 | lapic_enable(); | 797 | * This also works to reduce highmem size on bigger boxes. |
798 | */ | ||
799 | static int __init parse_highmem(char *arg) | ||
800 | { | ||
801 | if (!arg) | ||
802 | return -EINVAL; | ||
870 | 803 | ||
871 | /* disable local APIC */ | 804 | highmem_pages = memparse(arg, &arg) >> PAGE_SHIFT; |
872 | else if (!memcmp(from, "nolapic", 6)) | 805 | return 0; |
873 | lapic_disable(); | 806 | } |
874 | #endif /* CONFIG_X86_LOCAL_APIC */ | 807 | early_param("highmem", parse_highmem); |
875 | 808 | ||
876 | #ifdef CONFIG_KEXEC | 809 | /* |
877 | /* crashkernel=size@addr specifies the location to reserve for | 810 | * vmalloc=size forces the vmalloc area to be exactly 'size' |
878 | * a crash kernel. By reserving this memory we guarantee | 811 | * bytes. This can be used to increase (or decrease) the |
879 | * that linux never set's it up as a DMA target. | 812 | * vmalloc area - the default is 128m. |
880 | * Useful for holding code to do something appropriate | 813 | */ |
881 | * after a kernel panic. | 814 | static int __init parse_vmalloc(char *arg) |
882 | */ | 815 | { |
883 | else if (!memcmp(from, "crashkernel=", 12)) { | 816 | if (!arg) |
884 | unsigned long size, base; | 817 | return -EINVAL; |
885 | size = memparse(from+12, &from); | ||
886 | if (*from == '@') { | ||
887 | base = memparse(from+1, &from); | ||
888 | /* FIXME: Do I want a sanity check | ||
889 | * to validate the memory range? | ||
890 | */ | ||
891 | crashk_res.start = base; | ||
892 | crashk_res.end = base + size - 1; | ||
893 | } | ||
894 | } | ||
895 | #endif | ||
896 | #ifdef CONFIG_PROC_VMCORE | ||
897 | /* elfcorehdr= specifies the location of elf core header | ||
898 | * stored by the crashed kernel. | ||
899 | */ | ||
900 | else if (!memcmp(from, "elfcorehdr=", 11)) | ||
901 | elfcorehdr_addr = memparse(from+11, &from); | ||
902 | #endif | ||
903 | 818 | ||
904 | /* | 819 | __VMALLOC_RESERVE = memparse(arg, &arg); |
905 | * highmem=size forces highmem to be exactly 'size' bytes. | 820 | return 0; |
906 | * This works even on boxes that have no highmem otherwise. | ||
907 | * This also works to reduce highmem size on bigger boxes. | ||
908 | */ | ||
909 | else if (!memcmp(from, "highmem=", 8)) | ||
910 | highmem_pages = memparse(from+8, &from) >> PAGE_SHIFT; | ||
911 | |||
912 | /* | ||
913 | * vmalloc=size forces the vmalloc area to be exactly 'size' | ||
914 | * bytes. This can be used to increase (or decrease) the | ||
915 | * vmalloc area - the default is 128m. | ||
916 | */ | ||
917 | else if (!memcmp(from, "vmalloc=", 8)) | ||
918 | __VMALLOC_RESERVE = memparse(from+8, &from); | ||
919 | |||
920 | next_char: | ||
921 | c = *(from++); | ||
922 | if (!c) | ||
923 | break; | ||
924 | if (COMMAND_LINE_SIZE <= ++len) | ||
925 | break; | ||
926 | *(to++) = c; | ||
927 | } | ||
928 | *to = '\0'; | ||
929 | *cmdline_p = command_line; | ||
930 | if (userdef) { | ||
931 | printk(KERN_INFO "user-defined physical RAM map:\n"); | ||
932 | print_memory_map("user"); | ||
933 | } | ||
934 | } | 821 | } |
822 | early_param("vmalloc", parse_vmalloc); | ||
935 | 823 | ||
936 | /* | 824 | /* |
937 | * Callback for efi_memory_walk. | 825 | * Callback for efi_memory_walk. |
@@ -1507,17 +1395,15 @@ void __init setup_arch(char **cmdline_p) | |||
1507 | data_resource.start = virt_to_phys(_etext); | 1395 | data_resource.start = virt_to_phys(_etext); |
1508 | data_resource.end = virt_to_phys(_edata)-1; | 1396 | data_resource.end = virt_to_phys(_edata)-1; |
1509 | 1397 | ||
1510 | parse_cmdline_early(cmdline_p); | 1398 | parse_early_param(); |
1511 | 1399 | ||
1512 | #ifdef CONFIG_EARLY_PRINTK | 1400 | if (user_defined_memmap) { |
1513 | { | 1401 | printk(KERN_INFO "user-defined physical RAM map:\n"); |
1514 | char *s = strstr(*cmdline_p, "earlyprintk="); | 1402 | print_memory_map("user"); |
1515 | if (s) { | ||
1516 | setup_early_printk(strchr(s, '=') + 1); | ||
1517 | printk("early console enabled\n"); | ||
1518 | } | ||
1519 | } | 1403 | } |
1520 | #endif | 1404 | |
1405 | strlcpy(command_line, saved_command_line, COMMAND_LINE_SIZE); | ||
1406 | *cmdline_p = command_line; | ||
1521 | 1407 | ||
1522 | max_low_pfn = setup_memory(); | 1408 | max_low_pfn = setup_memory(); |
1523 | 1409 | ||
@@ -1546,7 +1432,7 @@ void __init setup_arch(char **cmdline_p) | |||
1546 | dmi_scan_machine(); | 1432 | dmi_scan_machine(); |
1547 | 1433 | ||
1548 | #ifdef CONFIG_X86_GENERICARCH | 1434 | #ifdef CONFIG_X86_GENERICARCH |
1549 | generic_apic_probe(*cmdline_p); | 1435 | generic_apic_probe(); |
1550 | #endif | 1436 | #endif |
1551 | if (efi_enabled) | 1437 | if (efi_enabled) |
1552 | efi_map_memmap(); | 1438 | efi_map_memmap(); |
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 9367af76ce37..517eb3874550 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c | |||
@@ -1491,3 +1491,16 @@ void __init smp_intr_init(void) | |||
1491 | /* IPI for generic function call */ | 1491 | /* IPI for generic function call */ |
1492 | set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt); | 1492 | set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt); |
1493 | } | 1493 | } |
1494 | |||
1495 | /* | ||
1496 | * If the BIOS enumerates physical processors before logical, | ||
1497 | * maxcpus=N at enumeration-time can be used to disable HT. | ||
1498 | */ | ||
1499 | static int __init parse_maxcpus(char *arg) | ||
1500 | { | ||
1501 | extern unsigned int maxcpus; | ||
1502 | |||
1503 | maxcpus = simple_strtoul(arg, NULL, 0); | ||
1504 | return 0; | ||
1505 | } | ||
1506 | early_param("maxcpus", parse_maxcpus); | ||
diff --git a/arch/i386/mach-generic/probe.c b/arch/i386/mach-generic/probe.c index 793d1b473251..94b1fd9cbe3c 100644 --- a/arch/i386/mach-generic/probe.c +++ b/arch/i386/mach-generic/probe.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
10 | #include <linux/ctype.h> | 10 | #include <linux/ctype.h> |
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
12 | #include <linux/errno.h> | ||
12 | #include <asm/fixmap.h> | 13 | #include <asm/fixmap.h> |
13 | #include <asm/mpspec.h> | 14 | #include <asm/mpspec.h> |
14 | #include <asm/apicdef.h> | 15 | #include <asm/apicdef.h> |
@@ -29,7 +30,24 @@ struct genapic *apic_probe[] __initdata = { | |||
29 | NULL, | 30 | NULL, |
30 | }; | 31 | }; |
31 | 32 | ||
32 | static int cmdline_apic; | 33 | static int cmdline_apic __initdata; |
34 | static int __init parse_apic(char *arg) | ||
35 | { | ||
36 | int i; | ||
37 | |||
38 | if (!arg) | ||
39 | return -EINVAL; | ||
40 | |||
41 | for (i = 0; apic_probe[i]; i++) { | ||
42 | if (!strcmp(apic_probe[i]->name, arg)) { | ||
43 | genapic = apic_probe[i]; | ||
44 | cmdline_apic = 1; | ||
45 | return 0; | ||
46 | } | ||
47 | } | ||
48 | return -ENOENT; | ||
49 | } | ||
50 | early_param("apic", parse_apic); | ||
33 | 51 | ||
34 | void __init generic_bigsmp_probe(void) | 52 | void __init generic_bigsmp_probe(void) |
35 | { | 53 | { |
@@ -48,40 +66,20 @@ void __init generic_bigsmp_probe(void) | |||
48 | } | 66 | } |
49 | } | 67 | } |
50 | 68 | ||
51 | void __init generic_apic_probe(char *command_line) | 69 | void __init generic_apic_probe(void) |
52 | { | 70 | { |
53 | char *s; | 71 | if (!cmdline_apic) { |
54 | int i; | 72 | int i; |
55 | int changed = 0; | 73 | for (i = 0; apic_probe[i]; i++) { |
56 | 74 | if (apic_probe[i]->probe()) { | |
57 | s = strstr(command_line, "apic="); | ||
58 | if (s && (s == command_line || isspace(s[-1]))) { | ||
59 | char *p = strchr(s, ' '), old; | ||
60 | if (!p) | ||
61 | p = strchr(s, '\0'); | ||
62 | old = *p; | ||
63 | *p = 0; | ||
64 | for (i = 0; !changed && apic_probe[i]; i++) { | ||
65 | if (!strcmp(apic_probe[i]->name, s+5)) { | ||
66 | changed = 1; | ||
67 | genapic = apic_probe[i]; | 75 | genapic = apic_probe[i]; |
76 | break; | ||
68 | } | 77 | } |
69 | } | 78 | } |
70 | if (!changed) | 79 | /* Not visible without early console */ |
71 | printk(KERN_ERR "Unknown genapic `%s' specified.\n", s); | 80 | if (!apic_probe[i]) |
72 | *p = old; | 81 | panic("Didn't find an APIC driver"); |
73 | cmdline_apic = changed; | ||
74 | } | ||
75 | for (i = 0; !changed && apic_probe[i]; i++) { | ||
76 | if (apic_probe[i]->probe()) { | ||
77 | changed = 1; | ||
78 | genapic = apic_probe[i]; | ||
79 | } | ||
80 | } | 82 | } |
81 | /* Not visible without early console */ | ||
82 | if (!changed) | ||
83 | panic("Didn't find an APIC driver"); | ||
84 | |||
85 | printk(KERN_INFO "Using APIC driver %s\n", genapic->name); | 83 | printk(KERN_INFO "Using APIC driver %s\n", genapic->name); |
86 | } | 84 | } |
87 | 85 | ||
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index d0c2fdf6a4d7..951386606d09 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c | |||
@@ -435,16 +435,22 @@ u64 __supported_pte_mask __read_mostly = ~_PAGE_NX; | |||
435 | * on Enable | 435 | * on Enable |
436 | * off Disable | 436 | * off Disable |
437 | */ | 437 | */ |
438 | void __init noexec_setup(const char *str) | 438 | static int __init noexec_setup(char *str) |
439 | { | 439 | { |
440 | if (!strncmp(str, "on",2) && cpu_has_nx) { | 440 | if (!str || !strcmp(str, "on")) { |
441 | __supported_pte_mask |= _PAGE_NX; | 441 | if (cpu_has_nx) { |
442 | disable_nx = 0; | 442 | __supported_pte_mask |= _PAGE_NX; |
443 | } else if (!strncmp(str,"off",3)) { | 443 | disable_nx = 0; |
444 | } | ||
445 | } else if (!strcmp(str,"off")) { | ||
444 | disable_nx = 1; | 446 | disable_nx = 1; |
445 | __supported_pte_mask &= ~_PAGE_NX; | 447 | __supported_pte_mask &= ~_PAGE_NX; |
446 | } | 448 | } else |
449 | return -EINVAL; | ||
450 | |||
451 | return 0; | ||
447 | } | 452 | } |
453 | early_param("noexec", noexec_setup); | ||
448 | 454 | ||
449 | int nx_enabled = 0; | 455 | int nx_enabled = 0; |
450 | #ifdef CONFIG_X86_PAE | 456 | #ifdef CONFIG_X86_PAE |