aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2006-09-26 04:52:32 -0400
committerAndi Kleen <andi@basil.nowhere.org>2006-09-26 04:52:32 -0400
commit1a3f239ddf9208f2e52d36fef1c1c4518cbbbabe (patch)
treef2ad21f766102540e15ea61145e94be65901e272 /arch/i386/kernel
parent33df0d19ea425d28bd5afb48898af32237fe81af (diff)
[PATCH] i386: Replace i386 open-coded cmdline parsing with
This patch replaces the open-coded early commandline parsing throughout the i386 boot code with the generic mechanism (already used by ppc, powerpc, ia64 and s390). The code was inconsistent with whether it deletes the option from the cmdline or not, meaning some of these will get passed through the environment into init. This transformation is mainly mechanical, but there are some notable parts: 1) Grammar: s/linux never set's it up/linux never sets it up/ 2) Remove hacked-in earlyprintk= option scanning. When someone actually implements CONFIG_EARLY_PRINTK, then they can use early_param(). [AK: actually it is implemented, but I'm adding the early_param it in the next x86-64 patch] 3) Move declaration of generic_apic_probe() from setup.c into asm/apic.h 4) Various parameters now moved into their appropriate files (thanks Andi). 5) All parse functions which examine arg need to check for NULL, except one where it has subtle humor value. AK: readded acpi_sci handling which was completely dropped AK: moved some more variables into acpi/boot.c Cc: len.brown@intel.com Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Signed-off-by: Andi Kleen <ak@suse.de>
Diffstat (limited to 'arch/i386/kernel')
-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
6 files changed, 266 insertions, 235 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);