Commit 2c8c0e6b authored by Andi Kleen's avatar Andi Kleen Committed by Andi Kleen
Browse files

[PATCH] Convert x86-64 to early param



Instead of hackish manual parsing

Requires earlier i386 patchkit, but also fixes i386 early_printk again.

I removed some obsolete really early parameters which didn't do anything useful.
Also made a few parameters that needed it early (mostly oops printing setup)

Also removed one panic check that wasn't visible without
early console anyways (the early console is now initialized after that
panic)

This cleans up a lot of code.
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
parent 1a3f239d
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <asm/idle.h> #include <asm/idle.h>
#include <asm/proto.h> #include <asm/proto.h>
#include <asm/timex.h> #include <asm/timex.h>
#include <asm/apic.h>
int apic_verbosity; int apic_verbosity;
int apic_runs_main_timer; int apic_runs_main_timer;
...@@ -546,18 +547,24 @@ static void apic_pm_activate(void) { } ...@@ -546,18 +547,24 @@ static void apic_pm_activate(void) { }
static int __init apic_set_verbosity(char *str) static int __init apic_set_verbosity(char *str)
{ {
if (str == NULL) {
skip_ioapic_setup = 0;
ioapic_force = 1;
return 0;
}
if (strcmp("debug", str) == 0) if (strcmp("debug", str) == 0)
apic_verbosity = APIC_DEBUG; apic_verbosity = APIC_DEBUG;
else if (strcmp("verbose", str) == 0) else if (strcmp("verbose", str) == 0)
apic_verbosity = APIC_VERBOSE; apic_verbosity = APIC_VERBOSE;
else else {
printk(KERN_WARNING "APIC Verbosity level %s not recognised" printk(KERN_WARNING "APIC Verbosity level %s not recognised"
" use apic=verbose or apic=debug", str); " use apic=verbose or apic=debug\n", str);
return -EINVAL;
}
return 1; return 0;
} }
early_param("apic", apic_set_verbosity);
__setup("apic=", apic_set_verbosity);
/* /*
* Detect and enable local APICs on non-SMP boards. * Detect and enable local APICs on non-SMP boards.
...@@ -1078,14 +1085,17 @@ int __init APIC_init_uniprocessor (void) ...@@ -1078,14 +1085,17 @@ int __init APIC_init_uniprocessor (void)
static __init int setup_disableapic(char *str) static __init int setup_disableapic(char *str)
{ {
disable_apic = 1; disable_apic = 1;
return 1; clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
} return 0;
}
early_param("disableapic", setup_disableapic);
/* same as disableapic, for compatibility */
static __init int setup_nolapic(char *str) static __init int setup_nolapic(char *str)
{ {
disable_apic = 1; return setup_disableapic(str);
return 1;
} }
early_param("nolapic", setup_nolapic);
static __init int setup_noapictimer(char *str) static __init int setup_noapictimer(char *str)
{ {
...@@ -1118,11 +1128,5 @@ static __init int setup_apicpmtimer(char *s) ...@@ -1118,11 +1128,5 @@ static __init int setup_apicpmtimer(char *s)
} }
__setup("apicpmtimer", setup_apicpmtimer); __setup("apicpmtimer", setup_apicpmtimer);
/* dummy parsing: see setup.c */
__setup("disableapic", setup_disableapic);
__setup("nolapic", setup_nolapic); /* same as disableapic, for compatibility */
__setup("noapictimer", setup_noapictimer); __setup("noapictimer", setup_noapictimer);
/* no "lapic" flag - we only use the lapic when the BIOS tells us so. */
...@@ -596,31 +596,64 @@ void __init setup_memory_region(void) ...@@ -596,31 +596,64 @@ void __init setup_memory_region(void)
e820_print_map(who); e820_print_map(who);
} }
void __init parse_memopt(char *p, char **from) static int __init parse_memopt(char *p)
{ {
end_user_pfn = memparse(p, from); if (!p)
return -EINVAL;
end_user_pfn = memparse(p, &p);
end_user_pfn >>= PAGE_SHIFT; end_user_pfn >>= PAGE_SHIFT;
return 0;
} }
early_param("mem", parse_memopt);
static int userdef __initdata;
void __init parse_memmapopt(char *p, char **from) static int __init parse_memmap_opt(char *p)
{ {
char *oldp;
unsigned long long start_at, mem_size; unsigned long long start_at, mem_size;
mem_size = memparse(p, from); if (!strcmp(p, "exactmap")) {
p = *from; #ifdef CONFIG_CRASH_DUMP
/* If we are doing a crash dump, we
* still need to know the real mem
* size before original memory map is
* reset.
*/
saved_max_pfn = e820_end_of_ram();
#endif
end_pfn_map = 0;
e820.nr_map = 0;
userdef = 1;
return 0;
}
oldp = p;
mem_size = memparse(p, &p);
if (p == oldp)
return -EINVAL;
if (*p == '@') { if (*p == '@') {
start_at = memparse(p+1, from); start_at = memparse(p+1, &p);
add_memory_region(start_at, mem_size, E820_RAM); add_memory_region(start_at, mem_size, E820_RAM);
} else if (*p == '#') { } else if (*p == '#') {
start_at = memparse(p+1, from); start_at = memparse(p+1, &p);
add_memory_region(start_at, mem_size, E820_ACPI); add_memory_region(start_at, mem_size, E820_ACPI);
} else if (*p == '$') { } else if (*p == '$') {
start_at = memparse(p+1, from); start_at = memparse(p+1, &p);
add_memory_region(start_at, mem_size, E820_RESERVED); add_memory_region(start_at, mem_size, E820_RESERVED);
} else { } else {
end_user_pfn = (mem_size >> PAGE_SHIFT); end_user_pfn = (mem_size >> PAGE_SHIFT);
} }
p = *from; return *p == '\0' ? 0 : -EINVAL;
}
early_param("memmap", parse_memmap_opt);
void finish_e820_parsing(void)
{
if (userdef) {
printk(KERN_INFO "user-defined physical RAM map:\n");
e820_print_map("user");
}
} }
unsigned long pci_mem_start = 0xaeedbabe; unsigned long pci_mem_start = 0xaeedbabe;
......
...@@ -215,20 +215,16 @@ void early_printk(const char *fmt, ...) ...@@ -215,20 +215,16 @@ void early_printk(const char *fmt, ...)
static int __initdata keep_early; static int __initdata keep_early;
int __init setup_early_printk(char *opt) static int __init setup_early_printk(char *buf)
{ {
char *space; if (!buf)
char buf[256]; return 0;
if (early_console_initialized) if (early_console_initialized)
return 1; return 0;
early_console_initialized = 1;
strlcpy(buf,opt,sizeof(buf));
space = strchr(buf, ' ');
if (space)
*space = 0;
if (strstr(buf,"keep")) if (!strcmp(buf,"keep"))
keep_early = 1; keep_early = 1;
if (!strncmp(buf, "serial", 6)) { if (!strncmp(buf, "serial", 6)) {
...@@ -248,11 +244,12 @@ int __init setup_early_printk(char *opt) ...@@ -248,11 +244,12 @@ int __init setup_early_printk(char *opt)
early_console = &simnow_console; early_console = &simnow_console;
keep_early = 1; keep_early = 1;
} }
early_console_initialized = 1;
register_console(early_console); register_console(early_console);
return 0; return 0;
} }
early_param("earlyprintk", setup_early_printk);
void __init disable_early_printk(void) void __init disable_early_printk(void)
{ {
if (!early_console_initialized || !early_console) if (!early_console_initialized || !early_console)
...@@ -266,4 +263,3 @@ void __init disable_early_printk(void) ...@@ -266,4 +263,3 @@ void __init disable_early_printk(void)
} }
} }
__setup("earlyprintk=", setup_early_printk);
...@@ -58,7 +58,6 @@ static void __init copy_bootdata(char *real_mode_data) ...@@ -58,7 +58,6 @@ static void __init copy_bootdata(char *real_mode_data)
void __init x86_64_start_kernel(char * real_mode_data) void __init x86_64_start_kernel(char * real_mode_data)
{ {
char *s;
int i; int i;
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
...@@ -85,19 +84,5 @@ void __init x86_64_start_kernel(char * real_mode_data) ...@@ -85,19 +84,5 @@ void __init x86_64_start_kernel(char * real_mode_data)
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
cpu_set(0, cpu_online_map); cpu_set(0, cpu_online_map);
#endif #endif
s = strstr(saved_command_line, "earlyprintk=");
if (s != NULL)
setup_early_printk(strchr(s, '=') + 1);
#ifdef CONFIG_NUMA
s = strstr(saved_command_line, "numa=");
if (s != NULL)
numa_setup(s+5);
#endif
if (strstr(saved_command_line, "disableapic"))
disable_apic = 1;
/* You need early console to see that */
if (__pa_symbol(&_end) >= KERNEL_TEXT_SIZE)
panic("Kernel too big for kernel mapping\n");
start_kernel(); start_kernel();
} }
...@@ -48,7 +48,7 @@ int sis_apic_bug; /* not actually supported, dummy for compile */ ...@@ -48,7 +48,7 @@ int sis_apic_bug; /* not actually supported, dummy for compile */
static int no_timer_check; static int no_timer_check;
int disable_timer_pin_1 __initdata; static int disable_timer_pin_1 __initdata;
int timer_over_8254 __initdata = 0; int timer_over_8254 __initdata = 0;
...@@ -253,18 +253,17 @@ int ioapic_force; ...@@ -253,18 +253,17 @@ int ioapic_force;
static int __init disable_ioapic_setup(char *str) static int __init disable_ioapic_setup(char *str)
{ {
skip_ioapic_setup = 1; skip_ioapic_setup = 1;
return 1; return 0;
} }
early_param("noapic", disable_ioapic_setup);
static int __init enable_ioapic_setup(char *str) /* Actually the next is obsolete, but keep it for paranoid reasons -AK */
static int __init disable_timer_pin_setup(char *arg)
{ {
ioapic_force = 1; disable_timer_pin_1 = 1;
skip_ioapic_setup = 0;
return 1; return 1;
} }
__setup("disable_timer_pin_1", disable_timer_pin_setup);
__setup("noapic", disable_ioapic_setup);
__setup("apic", enable_ioapic_setup);
static int __init setup_disable_8254_timer(char *s) static int __init setup_disable_8254_timer(char *s)
{ {
......
...@@ -226,3 +226,31 @@ NORET_TYPE void machine_kexec(struct kimage *image) ...@@ -226,3 +226,31 @@ NORET_TYPE void machine_kexec(struct kimage *image)
rnk = (relocate_new_kernel_t) control_code_buffer; rnk = (relocate_new_kernel_t) control_code_buffer;
(*rnk)(page_list, control_code_buffer, image->start, start_pgtable); (*rnk)(page_list, control_code_buffer, image->start, start_pgtable);
} }
/* crashkernel=size@addr specifies the location to reserve for
* a crash kernel. By reserving this memory we guarantee
* that linux never set's it up as a DMA target.
* Useful for holding code to do something appropriate
* after a kernel panic.
*/
static int __init setup_crashkernel(char *arg)
{
unsigned long size, base;
char *p;
if (!arg)
return -EINVAL;
size = memparse(arg, &p);
if (arg == p)
return -EINVAL;
if (*p == '@') {
base = memparse(p+1, &p);
/* FIXME: Do I want a sanity check to validate the
* memory range? Yes you do, but it's too early for
* e820 -AK */
crashk_res.start = base;
crashk_res.end = base + size - 1;
}
return 0;
}
early_param("crashkernel", setup_crashkernel);
...@@ -236,6 +236,9 @@ __init int iommu_setup(char *p) ...@@ -236,6 +236,9 @@ __init int iommu_setup(char *p)
{ {
iommu_merge = 1; iommu_merge = 1;
if (!p)
return -EINVAL;
while (*p) { while (*p) {
if (!strncmp(p,"off",3)) if (!strncmp(p,"off",3))
no_iommu = 1; no_iommu = 1;
...@@ -278,9 +281,9 @@ __init int iommu_setup(char *p) ...@@ -278,9 +281,9 @@ __init int iommu_setup(char *p)
if (*p == ',') if (*p == ',')
++p; ++p;
} }
return 1; return 0;
} }
__setup("iommu=", iommu_setup); early_param("iommu", iommu_setup);
void __init pci_iommu_alloc(void) void __init pci_iommu_alloc(void)
{ {
......
...@@ -76,11 +76,6 @@ unsigned long mmu_cr4_features; ...@@ -76,11 +76,6 @@ unsigned long mmu_cr4_features;
int acpi_disabled; int acpi_disabled;
EXPORT_SYMBOL(acpi_disabled); EXPORT_SYMBOL(acpi_disabled);
#ifdef CONFIG_ACPI
extern int __initdata acpi_ht;
extern acpi_interrupt_flags acpi_sci_flags;
int __initdata acpi_force = 0;
#endif
int acpi_numa __initdata; int acpi_numa __initdata;
...@@ -276,183 +271,22 @@ static void __init probe_roms(void) ...@@ -276,183 +271,22 @@ static void __init probe_roms(void)
} }
} }
/* Check for full argument with no trailing characters */ #ifdef CONFIG_PROC_VMCORE
static int fullarg(char *p, char *arg) /* elfcorehdr= specifies the location of elf core header
* stored by the crashed kernel. This option will be passed
* by kexec loader to the capture kernel.
*/
static int __init setup_elfcorehdr(char *arg)
{ {
int l = strlen(arg); char *end;
return !memcmp(p, arg, l) && (p[l] == 0 || isspace(p[l])); if (!arg)
return -EINVAL;
elfcorehdr_addr = memparse(arg, &end);
return end > arg ? 0 : -EINVAL;
} }
early_param("elfcorehdr", setup_elfcorehdr);
static __init void parse_cmdline_early (char ** cmdline_p)
{
char c = ' ', *to = command_line, *from = COMMAND_LINE;
int len = 0;
int userdef = 0;
for (;;) {
if (c != ' ')
goto next_char;
#ifdef CONFIG_SMP
/*
* If the BIOS enumerates physical processors before logical,
* maxcpus=N at enumeration-time can be used to disable HT.
*/
else if (!memcmp(from, "maxcpus=", 8)) {
extern unsigned int maxcpus;
maxcpus = simple_strtoul(from + 8, NULL, 0);
}
#endif
#ifdef CONFIG_ACPI
/* "acpi=off" disables both ACPI table parsing and interpreter init */
if (fullarg(from,"acpi=off"))
disable_acpi();
if (fullarg(from, "acpi=force")) {
/* add later when we do DMI horrors: */
acpi_force = 1;
acpi_disabled = 0;
}
/* acpi=ht just means: do ACPI MADT parsing
at bootup, but don't enable the full ACPI interpreter */
if (fullarg(from, "acpi=ht")) {
if (!acpi_force)
disable_acpi();
acpi_ht = 1;
}
else if (fullarg(from, "pci=noacpi"))
acpi_disable_pci();
else if (fullarg(from, "acpi=noirq"))
acpi_noirq_set();
else if (fullarg(from, "acpi_sci=edge"))
acpi_sci_flags.trigger = 1;
else if (fullarg(from, "acpi_sci=level"))
acpi_sci_flags.trigger = 3;
else if (fullarg(from, "acpi_sci=high"))
acpi_sci_flags.polarity = 1;
else if (fullarg(from, "acpi_sci=low"))
acpi_sci_flags.polarity = 3;
/* acpi=strict disables out-of-spec workarounds */
else if (fullarg(from, "acpi=strict")) {
acpi_strict = 1;
}
else if (fullarg(from, "acpi_skip_timer_override"))
acpi_skip_timer_override = 1;
#endif #endif
if (fullarg(from, "disable_timer_pin_1"))
disable_timer_pin_1 = 1;
if (fullarg(from, "enable_timer_pin_1"))
disable_timer_pin_1 = -1;
if (fullarg(from, "nolapic") || fullarg(from, "disableapic")) {
clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
disable_apic = 1;
}
if (fullarg(from, "noapic"))
skip_ioapic_setup = 1;
if (fullarg(from,"apic")) {
skip_ioapic_setup = 0;
ioapic_force = 1;
}
if (!memcmp(from, "mem=", 4))
parse_memopt(from+4, &from);
if (!memcmp(from, "memmap=", 7)) {
/* exactmap option is for used defined memory */
if (!memcmp(from+7, "exactmap", 8)) {
#ifdef CONFIG_CRASH_DUMP
/* If we are doing a crash dump, we
* still need to know the real mem
* size before original memory map is
* reset.
*/
saved_max_pfn = e820_end_of_ram();
#endif
from += 8+7;
end_pfn_map = 0;
e820.nr_map = 0;
userdef = 1;
}
else {
parse_memmapopt(from+7, &from);
userdef = 1;
}
}
#ifdef CONFIG_NUMA
if (!memcmp(from, "numa=", 5))
numa_setup(from+5);
#endif
if (!memcmp(from,"iommu=",6)) {
iommu_setup(from+6);
}
if (fullarg(from,"oops=panic"))
panic_on_oops = 1;
if (!memcmp(from, "noexec=", 7))
nonx_setup(from + 7);
#ifdef CONFIG_KEXEC
/* crashkernel=size@addr specifies the location to reserve for
* a crash kernel. By reserving this memory we guarantee
* that linux never set's it up as a DMA target.
* Useful for holding code to do something appropriate
* after a kernel panic.
*/
else if (!memcmp(from, "crashkernel=", 12)) {
unsigned long size, base;
size = memparse(from+12, &from);
if (*from == '@') {
base = memparse(from+1, &from);
/* FIXME: Do I want a sanity check
* to validate the memory range?
*/
crashk_res.start = base;
crashk_res.end = base + size - 1;
}
}
#endif
#ifdef CONFIG_PROC_VMCORE
/* elfcorehdr= specifies the location of elf core header
* stored by the crashed kernel. This option will be passed
* by kexec loader to the capture kernel.
*/
else if(!memcmp(from, "elfcorehdr=", 11))
elfcorehdr_addr = memparse(from+11, &from);
#endif
#ifdef CONFIG_HOTPLUG_CPU
else if (!memcmp(from, "additional_cpus=", 16))
setup_additional_cpus(from+16);
#endif
next_char:
c = *(from++);
if (!c)
break;
if (COMMAND_LINE_SIZE <= ++len)
break;
*(to++) = c;
}
if (userdef) {
printk(KERN_INFO "user-defined physical RAM map:\n");
e820_print_map("user");
}
*to = '\0';
*cmdline_p = command_line;
}