Commit 1a3f239d authored by Rusty Russell's avatar Rusty Russell Committed by Andi Kleen

[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: default avatarRusty Russell <rusty@rustcorp.com.au>
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
parent 33df0d19
...@@ -36,6 +36,8 @@ ...@@ -36,6 +36,8 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/mpspec.h> #include <asm/mpspec.h>
int __initdata acpi_force = 0;
#ifdef CONFIG_X86_64 #ifdef CONFIG_X86_64
extern void __init clustered_apic_check(void); extern void __init clustered_apic_check(void);
...@@ -860,8 +862,6 @@ static void __init acpi_process_madt(void) ...@@ -860,8 +862,6 @@ static void __init acpi_process_madt(void)
return; return;
} }
extern int acpi_force;
#ifdef __i386__ #ifdef __i386__
static int __init disable_acpi_irq(struct dmi_system_id *d) static int __init disable_acpi_irq(struct dmi_system_id *d)
...@@ -1163,3 +1163,75 @@ int __init acpi_boot_init(void) ...@@ -1163,3 +1163,75 @@ int __init acpi_boot_init(void)
return 0; return 0;
} }
static int __init parse_acpi(char *arg)
{
if (!arg)
return -EINVAL;
/* "acpi=off" disables both ACPI table parsing and interpreter */
if (strcmp(arg, "off") == 0) {
disable_acpi();
}
/* acpi=force to over-ride black-list */
else if (strcmp(arg, "force") == 0) {
acpi_force = 1;
acpi_ht = 1;
acpi_disabled = 0;
}
/* acpi=strict disables out-of-spec workarounds */
else if (strcmp(arg, "strict") == 0) {
acpi_strict = 1;
}
/* Limit ACPI just to boot-time to enable HT */
else if (strcmp(arg, "ht") == 0) {
if (!acpi_force)
disable_acpi();
acpi_ht = 1;
}
/* "acpi=noirq" disables ACPI interrupt routing */
else if (strcmp(arg, "noirq") == 0) {
acpi_noirq_set();
} else {
/* Core will printk when we return error. */
return -EINVAL;
}
return 0;
}
early_param("acpi", parse_acpi);
/* FIXME: Using pci= for an ACPI parameter is a travesty. */
static int __init parse_pci(char *arg)
{
if (arg && strcmp(arg, "noacpi") == 0)
acpi_disable_pci();
return 0;
}
early_param("pci", parse_pci);
#ifdef CONFIG_X86_IO_APIC
static int __init parse_acpi_skip_timer_override(char *arg)
{
acpi_skip_timer_override = 1;
return 0;
}
early_param("acpi_skip_timer_override", parse_acpi_skip_timer_override);
#endif /* CONFIG_X86_IO_APIC */
static int __init setup_acpi_sci(char *s)
{
if (!s)
return -EINVAL;
if (!strcmp(s, "edge"))
acpi_sci_flags.trigger = 1;
else if (!strcmp(s, "level"))
acpi_sci_flags.trigger = 3;
else if (!strcmp(s, "high"))
acpi_sci_flags.polarity = 1;
else if (!strcmp(s, "low"))
acpi_sci_flags.polarity = 3;
else
return -EINVAL;
return 0;
}
early_param("acpi_sci", setup_acpi_sci);
...@@ -1372,3 +1372,18 @@ int __init APIC_init_uniprocessor (void) ...@@ -1372,3 +1372,18 @@ int __init APIC_init_uniprocessor (void)
return 0; return 0;
} }
static int __init parse_lapic(char *arg)
{
lapic_enable();
return 0;
}
early_param("lapic", parse_lapic);
static int __init parse_nolapic(char *arg)
{
lapic_disable();
return 0;
}
early_param("nolapic", parse_nolapic);
...@@ -66,7 +66,7 @@ int sis_apic_bug = -1; ...@@ -66,7 +66,7 @@ int sis_apic_bug = -1;
*/ */
int nr_ioapic_registers[MAX_IO_APICS]; int nr_ioapic_registers[MAX_IO_APICS];
int disable_timer_pin_1 __initdata; static int disable_timer_pin_1 __initdata;
/* /*
* Rough estimation of how many shared IRQs there are, can * 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,3 +2691,25 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int a
} }
#endif /* CONFIG_ACPI */ #endif /* CONFIG_ACPI */
static int __init parse_disable_timer_pin_1(char *arg)
{
disable_timer_pin_1 = 1;
return 0;
}
early_param("disable_timer_pin_1", parse_disable_timer_pin_1);
static int __init parse_enable_timer_pin_1(char *arg)
{
disable_timer_pin_1 = -1;
return 0;
}
early_param("enable_timer_pin_1", parse_enable_timer_pin_1);
static int __init parse_noapic(char *arg)
{
/* disable IO-APIC */
disable_ioapic_setup();
return 0;
}
early_param("noapic", parse_noapic);
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/kexec.h> #include <linux/kexec.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/init.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/pgalloc.h> #include <asm/pgalloc.h>
#include <asm/tlbflush.h> #include <asm/tlbflush.h>
...@@ -209,3 +210,25 @@ NORET_TYPE void machine_kexec(struct kimage *image) ...@@ -209,3 +210,25 @@ NORET_TYPE void machine_kexec(struct kimage *image)
rnk = (relocate_new_kernel_t) reboot_code_buffer; rnk = (relocate_new_kernel_t) reboot_code_buffer;
(*rnk)(page_list, reboot_code_buffer, image->start, cpu_has_pae); (*rnk)(page_list, reboot_code_buffer, image->start, cpu_has_pae);
} }
/* crashkernel=size@addr specifies the location to reserve for
* a crash kernel. By reserving this memory we guarantee
* that linux never sets it up as a DMA target.
* Useful for holding code to do something appropriate
* after a kernel panic.
*/
static int __init parse_crashkernel(char *arg)
{
unsigned long size, base;
size = memparse(arg, &arg);
if (*arg == '@') {
base = memparse(arg+1, &arg);
/* FIXME: Do I want a sanity check
* to validate the memory range?
*/
crashk_res.start = base;
crashk_res.end = base + size - 1;
}
return 0;
}
early_param("crashkernel", parse_crashkernel);
This diff is collapsed.
...@@ -1491,3 +1491,16 @@ void __init smp_intr_init(void) ...@@ -1491,3 +1491,16 @@ void __init smp_intr_init(void)
/* IPI for generic function call */ /* IPI for generic function call */
set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt); set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
} }
/*
* If the BIOS enumerates physical processors before logical,
* maxcpus=N at enumeration-time can be used to disable HT.
*/
static int __init parse_maxcpus(char *arg)
{
extern unsigned int maxcpus;
maxcpus = simple_strtoul(arg, NULL, 0);
return 0;
}
early_param("maxcpus", parse_maxcpus);
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/ctype.h> #include <linux/ctype.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/errno.h>
#include <asm/fixmap.h> #include <asm/fixmap.h>
#include <asm/mpspec.h> #include <asm/mpspec.h>
#include <asm/apicdef.h> #include <asm/apicdef.h>
...@@ -29,7 +30,24 @@ struct genapic *apic_probe[] __initdata = { ...@@ -29,7 +30,24 @@ struct genapic *apic_probe[] __initdata = {
NULL, NULL,
}; };
static int cmdline_apic; static int cmdline_apic __initdata;
static int __init parse_apic(char *arg)
{
int i;
if (!arg)
return -EINVAL;
for (i = 0; apic_probe[i]; i++) {
if (!strcmp(apic_probe[i]->name, arg)) {
genapic = apic_probe[i];
cmdline_apic = 1;
return 0;
}
}
return -ENOENT;
}
early_param("apic", parse_apic);
void __init generic_bigsmp_probe(void) void __init generic_bigsmp_probe(void)
{ {
...@@ -48,40 +66,20 @@ void __init generic_bigsmp_probe(void) ...@@ -48,40 +66,20 @@ void __init generic_bigsmp_probe(void)
} }
} }
void __init generic_apic_probe(char *command_line) void __init generic_apic_probe(void)
{ {
char *s; if (!cmdline_apic) {
int i; int i;
int changed = 0; for (i = 0; apic_probe[i]; i++) {
if (apic_probe[i]->probe()) {
s = strstr(command_line, "apic=");
if (s && (s == command_line || isspace(s[-1]))) {
char *p = strchr(s, ' '), old;
if (!p)
p = strchr(s, '\0');
old = *p;
*p = 0;
for (i = 0; !changed && apic_probe[i]; i++) {
if (!strcmp(apic_probe[i]->name, s+5)) {
changed = 1;
genapic = apic_probe[i]; genapic = apic_probe[i];
break;
} }
} }
if (!changed) /* Not visible without early console */
printk(KERN_ERR "Unknown genapic `%s' specified.\n", s); if (!apic_probe[i])
*p = old; panic("Didn't find an APIC driver");
cmdline_apic = changed;
}
for (i = 0; !changed && apic_probe[i]; i++) {
if (apic_probe[i]->probe()) {
changed = 1;
genapic = apic_probe[i];
}
} }
/* Not visible without early console */
if (!changed)
panic("Didn't find an APIC driver");
printk(KERN_INFO "Using APIC driver %s\n", genapic->name); printk(KERN_INFO "Using APIC driver %s\n", genapic->name);
} }
......
...@@ -435,16 +435,22 @@ u64 __supported_pte_mask __read_mostly = ~_PAGE_NX; ...@@ -435,16 +435,22 @@ u64 __supported_pte_mask __read_mostly = ~_PAGE_NX;
* on Enable * on Enable
* off Disable * off Disable
*/ */
void __init noexec_setup(const char *str) static int __init noexec_setup(char *str)
{ {
if (!strncmp(str, "on",2) && cpu_has_nx) { if (!str || !strcmp(str, "on")) {
__supported_pte_mask |= _PAGE_NX; if (cpu_has_nx) {
disable_nx = 0; __supported_pte_mask |= _PAGE_NX;
} else if (!strncmp(str,"off",3)) { disable_nx = 0;
}
} else if (!strcmp(str,"off")) {
disable_nx = 1; disable_nx = 1;
__supported_pte_mask &= ~_PAGE_NX; __supported_pte_mask &= ~_PAGE_NX;
} } else
return -EINVAL;
return 0;
} }
early_param("noexec", noexec_setup);
int nx_enabled = 0; int nx_enabled = 0;
#ifdef CONFIG_X86_PAE #ifdef CONFIG_X86_PAE
......
...@@ -131,21 +131,7 @@ static inline void disable_acpi(void) ...@@ -131,21 +131,7 @@ static inline void disable_acpi(void)
extern int acpi_gsi_to_irq(u32 gsi, unsigned int *irq); extern int acpi_gsi_to_irq(u32 gsi, unsigned int *irq);
#ifdef CONFIG_X86_IO_APIC #ifdef CONFIG_X86_IO_APIC
extern int skip_ioapic_setup;
extern int acpi_skip_timer_override; extern int acpi_skip_timer_override;
static inline void disable_ioapic_setup(void)
{
skip_ioapic_setup = 1;
}
static inline int ioapic_setup_disabled(void)
{
return skip_ioapic_setup;
}
#else
static inline void disable_ioapic_setup(void) { }
#endif #endif
static inline void acpi_noirq_set(void) { acpi_noirq = 1; } static inline void acpi_noirq_set(void) { acpi_noirq = 1; }
......
...@@ -42,6 +42,8 @@ static inline void lapic_enable(void) ...@@ -42,6 +42,8 @@ static inline void lapic_enable(void)
} while (0) } while (0)
extern void generic_apic_probe(void);
#ifdef CONFIG_X86_LOCAL_APIC #ifdef CONFIG_X86_LOCAL_APIC
/* /*
...@@ -117,8 +119,6 @@ extern void enable_APIC_timer(void); ...@@ -117,8 +119,6 @@ extern void enable_APIC_timer(void);
extern void enable_NMI_through_LVT0 (void * dummy); extern void enable_NMI_through_LVT0 (void * dummy);
extern int disable_timer_pin_1;
void smp_send_timer_broadcast_ipi(struct pt_regs *regs); void smp_send_timer_broadcast_ipi(struct pt_regs *regs);
void switch_APIC_timer_to_ipi(void *cpumask); void switch_APIC_timer_to_ipi(void *cpumask);
void switch_ipi_to_APIC_timer(void *cpumask); void switch_ipi_to_APIC_timer(void *cpumask);
......
...@@ -188,6 +188,16 @@ static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned ...@@ -188,6 +188,16 @@ static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned
/* 1 if "noapic" boot option passed */ /* 1 if "noapic" boot option passed */
extern int skip_ioapic_setup; extern int skip_ioapic_setup;
static inline void disable_ioapic_setup(void)
{
skip_ioapic_setup = 1;
}
static inline int ioapic_setup_disabled(void)
{
return skip_ioapic_setup;
}
/* /*
* If we use the IO-APIC for IRQ routing, disable automatic * If we use the IO-APIC for IRQ routing, disable automatic
* assignment of PCI IRQ's. * assignment of PCI IRQ's.
...@@ -206,6 +216,7 @@ extern int (*ioapic_renumber_irq)(int ioapic, int irq); ...@@ -206,6 +216,7 @@ extern int (*ioapic_renumber_irq)(int ioapic, int irq);
#else /* !CONFIG_X86_IO_APIC */ #else /* !CONFIG_X86_IO_APIC */
#define io_apic_assign_pci_irqs 0 #define io_apic_assign_pci_irqs 0
static inline void disable_ioapic_setup(void) { }
#endif #endif
extern int assign_irq_vector(int irq); extern int assign_irq_vector(int irq);
......
...@@ -391,8 +391,6 @@ extern pte_t *lookup_address(unsigned long address); ...@@ -391,8 +391,6 @@ extern pte_t *lookup_address(unsigned long address);
static inline int set_kernel_exec(unsigned long vaddr, int enable) { return 0;} static inline int set_kernel_exec(unsigned long vaddr, int enable) { return 0;}
#endif #endif
extern void noexec_setup(const char *str);
#if defined(CONFIG_HIGHPTE) #if defined(CONFIG_HIGHPTE)
#define pte_offset_map(dir, address) \ #define pte_offset_map(dir, address) \
((pte_t *)kmap_atomic(pmd_page(*(dir)),KM_PTE0) + pte_index(address)) ((pte_t *)kmap_atomic(pmd_page(*(dir)),KM_PTE0) + pte_index(address))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment