aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386')
-rw-r--r--arch/i386/kernel/acpi/boot.c76
-rw-r--r--arch/i386/kernel/apic.c15
-rw-r--r--arch/i386/kernel/io_apic.c24
-rw-r--r--arch/i386/kernel/machine_kexec.c23
-rw-r--r--arch/i386/kernel/setup.c350
-rw-r--r--arch/i386/kernel/smpboot.c13
-rw-r--r--arch/i386/mach-generic/probe.c58
-rw-r--r--arch/i386/mm/init.c18
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
39int __initdata acpi_force = 0;
40
39#ifdef CONFIG_X86_64 41#ifdef CONFIG_X86_64
40 42
41extern void __init clustered_apic_check(void); 43extern 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
863extern int acpi_force;
864
865#ifdef __i386__ 865#ifdef __i386__
866 866
867static int __init disable_acpi_irq(struct dmi_system_id *d) 867static 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
1167static 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}
1201early_param("acpi", parse_acpi);
1202
1203/* FIXME: Using pci= for an ACPI parameter is a travesty. */
1204static int __init parse_pci(char *arg)
1205{
1206 if (arg && strcmp(arg, "noacpi") == 0)
1207 acpi_disable_pci();
1208 return 0;
1209}
1210early_param("pci", parse_pci);
1211
1212#ifdef CONFIG_X86_IO_APIC
1213static int __init parse_acpi_skip_timer_override(char *arg)
1214{
1215 acpi_skip_timer_override = 1;
1216 return 0;
1217}
1218early_param("acpi_skip_timer_override", parse_acpi_skip_timer_override);
1219#endif /* CONFIG_X86_IO_APIC */
1220
1221static 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}
1237early_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
1376static int __init parse_lapic(char *arg)
1377{
1378 lapic_enable();
1379 return 0;
1380}
1381early_param("lapic", parse_lapic);
1382
1383static int __init parse_nolapic(char *arg)
1384{
1385 lapic_disable();
1386 return 0;
1387}
1388early_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 */
67int nr_ioapic_registers[MAX_IO_APICS]; 67int nr_ioapic_registers[MAX_IO_APICS];
68 68
69int disable_timer_pin_1 __initdata; 69static 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
2695static int __init parse_disable_timer_pin_1(char *arg)
2696{
2697 disable_timer_pin_1 = 1;
2698 return 0;
2699}
2700early_param("disable_timer_pin_1", parse_disable_timer_pin_1);
2701
2702static int __init parse_enable_timer_pin_1(char *arg)
2703{
2704 disable_timer_pin_1 = -1;
2705 return 0;
2706}
2707early_param("enable_timer_pin_1", parse_enable_timer_pin_1);
2708
2709static int __init parse_noapic(char *arg)
2710{
2711 /* disable IO-APIC */
2712 disable_ioapic_setup();
2713 return 0;
2714}
2715early_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 */
220static 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}
234early_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
97EXPORT_SYMBOL(acpi_disabled); 97EXPORT_SYMBOL(acpi_disabled);
98 98
99#ifdef CONFIG_ACPI
100int __initdata acpi_force = 0;
101extern 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 */
105unsigned int machine_id; 100unsigned int machine_id;
106#ifdef CONFIG_MCA 101#ifdef CONFIG_MCA
@@ -148,7 +143,6 @@ EXPORT_SYMBOL(ist_info);
148struct e820map e820; 143struct e820map e820;
149 144
150extern void early_cpu_init(void); 145extern void early_cpu_init(void);
151extern void generic_apic_probe(char *);
152extern int root_mountflags; 146extern int root_mountflags;
153 147
154unsigned long saved_videomode; 148unsigned long saved_videomode;
@@ -700,238 +694,132 @@ static inline void copy_edd(void)
700} 694}
701#endif 695#endif
702 696
703static void __init parse_cmdline_early (char ** cmdline_p) 697static 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 */
709static 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)) { 732early_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
734static 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}
777early_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; 783static 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 */ 791early_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 */
799static 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 */ 807early_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. 814static 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}
822early_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 */
1499static int __init parse_maxcpus(char *arg)
1500{
1501 extern unsigned int maxcpus;
1502
1503 maxcpus = simple_strtoul(arg, NULL, 0);
1504 return 0;
1505}
1506early_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
32static int cmdline_apic; 33static int cmdline_apic __initdata;
34static 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}
50early_param("apic", parse_apic);
33 51
34void __init generic_bigsmp_probe(void) 52void __init generic_bigsmp_probe(void)
35{ 53{
@@ -48,40 +66,20 @@ void __init generic_bigsmp_probe(void)
48 } 66 }
49} 67}
50 68
51void __init generic_apic_probe(char *command_line) 69void __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 */
438void __init noexec_setup(const char *str) 438static 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}
453early_param("noexec", noexec_setup);
448 454
449int nx_enabled = 0; 455int nx_enabled = 0;
450#ifdef CONFIG_X86_PAE 456#ifdef CONFIG_X86_PAE