1a3f239ddf
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>
126 lines
2.8 KiB
C
126 lines
2.8 KiB
C
/* Copyright 2003 Andi Kleen, SuSE Labs.
|
|
* Subject to the GNU Public License, v.2
|
|
*
|
|
* Generic x86 APIC driver probe layer.
|
|
*/
|
|
#include <linux/threads.h>
|
|
#include <linux/cpumask.h>
|
|
#include <linux/string.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/ctype.h>
|
|
#include <linux/init.h>
|
|
#include <linux/errno.h>
|
|
#include <asm/fixmap.h>
|
|
#include <asm/mpspec.h>
|
|
#include <asm/apicdef.h>
|
|
#include <asm/genapic.h>
|
|
|
|
extern struct genapic apic_summit;
|
|
extern struct genapic apic_bigsmp;
|
|
extern struct genapic apic_es7000;
|
|
extern struct genapic apic_default;
|
|
|
|
struct genapic *genapic = &apic_default;
|
|
|
|
struct genapic *apic_probe[] __initdata = {
|
|
&apic_summit,
|
|
&apic_bigsmp,
|
|
&apic_es7000,
|
|
&apic_default, /* must be last */
|
|
NULL,
|
|
};
|
|
|
|
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)
|
|
{
|
|
/*
|
|
* This routine is used to switch to bigsmp mode when
|
|
* - There is no apic= option specified by the user
|
|
* - generic_apic_probe() has choosen apic_default as the sub_arch
|
|
* - we find more than 8 CPUs in acpi LAPIC listing with xAPIC support
|
|
*/
|
|
|
|
if (!cmdline_apic && genapic == &apic_default)
|
|
if (apic_bigsmp.probe()) {
|
|
genapic = &apic_bigsmp;
|
|
printk(KERN_INFO "Overriding APIC driver with %s\n",
|
|
genapic->name);
|
|
}
|
|
}
|
|
|
|
void __init generic_apic_probe(void)
|
|
{
|
|
if (!cmdline_apic) {
|
|
int i;
|
|
for (i = 0; apic_probe[i]; i++) {
|
|
if (apic_probe[i]->probe()) {
|
|
genapic = apic_probe[i];
|
|
break;
|
|
}
|
|
}
|
|
/* Not visible without early console */
|
|
if (!apic_probe[i])
|
|
panic("Didn't find an APIC driver");
|
|
}
|
|
printk(KERN_INFO "Using APIC driver %s\n", genapic->name);
|
|
}
|
|
|
|
/* These functions can switch the APIC even after the initial ->probe() */
|
|
|
|
int __init mps_oem_check(struct mp_config_table *mpc, char *oem, char *productid)
|
|
{
|
|
int i;
|
|
for (i = 0; apic_probe[i]; ++i) {
|
|
if (apic_probe[i]->mps_oem_check(mpc,oem,productid)) {
|
|
if (!cmdline_apic) {
|
|
genapic = apic_probe[i];
|
|
printk(KERN_INFO "Switched to APIC driver `%s'.\n",
|
|
genapic->name);
|
|
}
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id)
|
|
{
|
|
int i;
|
|
for (i = 0; apic_probe[i]; ++i) {
|
|
if (apic_probe[i]->acpi_madt_oem_check(oem_id, oem_table_id)) {
|
|
if (!cmdline_apic) {
|
|
genapic = apic_probe[i];
|
|
printk(KERN_INFO "Switched to APIC driver `%s'.\n",
|
|
genapic->name);
|
|
}
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
#ifdef CONFIG_SMP
|
|
int hard_smp_processor_id(void)
|
|
{
|
|
return genapic->get_apic_id(*(unsigned long *)(APIC_BASE+APIC_ID));
|
|
}
|
|
#endif
|