Commit 5a7ae78f authored by Thomas Gleixner's avatar Thomas Gleixner

x86: Allow platforms to force enable apic

Some embedded x86 platforms don't setup the APIC in the
BIOS/bootloader and would be forced to add "lapic" on the kernel
command line. That's a bit akward.

Split out the force enable code from detect_init_APIC() and allow
platform code to call it from the platform setup. That avoids the
command line parameter and possible replication of the MSR dance in
the force enable code.
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
LKML-Reference: <1287510389-8388-1-git-send-email-dirk.brandewie@gmail.com>
Signed-off-by: default avatarDirk Brandewie <dirk.j.brandewie@intel.com>
parent d4429f60
...@@ -238,6 +238,7 @@ extern void setup_boot_APIC_clock(void); ...@@ -238,6 +238,7 @@ extern void setup_boot_APIC_clock(void);
extern void setup_secondary_APIC_clock(void); extern void setup_secondary_APIC_clock(void);
extern int APIC_init_uniprocessor(void); extern int APIC_init_uniprocessor(void);
extern void enable_NMI_through_LVT0(void); extern void enable_NMI_through_LVT0(void);
extern int apic_force_enable(void);
/* /*
* On 32bit this is mach-xxx local * On 32bit this is mach-xxx local
......
...@@ -1531,13 +1531,60 @@ static int __init detect_init_APIC(void) ...@@ -1531,13 +1531,60 @@ static int __init detect_init_APIC(void)
return 0; return 0;
} }
#else #else
static int apic_verify(void)
{
u32 features, h, l;
/*
* The APIC feature bit should now be enabled
* in `cpuid'
*/
features = cpuid_edx(1);
if (!(features & (1 << X86_FEATURE_APIC))) {
pr_warning("Could not enable APIC!\n");
return -1;
}
set_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC);
mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
/* The BIOS may have set up the APIC at some other address */
rdmsr(MSR_IA32_APICBASE, l, h);
if (l & MSR_IA32_APICBASE_ENABLE)
mp_lapic_addr = l & MSR_IA32_APICBASE_BASE;
pr_info("Found and enabled local APIC!\n");
return 0;
}
int apic_force_enable(void)
{
u32 h, l;
if (disable_apic)
return -1;
/*
* Some BIOSes disable the local APIC in the APIC_BASE
* MSR. This can only be done in software for Intel P6 or later
* and AMD K7 (Model > 1) or later.
*/
rdmsr(MSR_IA32_APICBASE, l, h);
if (!(l & MSR_IA32_APICBASE_ENABLE)) {
pr_info("Local APIC disabled by BIOS -- reenabling.\n");
l &= ~MSR_IA32_APICBASE_BASE;
l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE;
wrmsr(MSR_IA32_APICBASE, l, h);
enabled_via_apicbase = 1;
}
return apic_verify();
}
/* /*
* Detect and initialize APIC * Detect and initialize APIC
*/ */
static int __init detect_init_APIC(void) static int __init detect_init_APIC(void)
{ {
u32 h, l, features;
/* Disabled by kernel option? */ /* Disabled by kernel option? */
if (disable_apic) if (disable_apic)
return -1; return -1;
...@@ -1567,38 +1614,12 @@ static int __init detect_init_APIC(void) ...@@ -1567,38 +1614,12 @@ static int __init detect_init_APIC(void)
"you can enable it with \"lapic\"\n"); "you can enable it with \"lapic\"\n");
return -1; return -1;
} }
/* if (apic_force_enable())
* Some BIOSes disable the local APIC in the APIC_BASE return -1;
* MSR. This can only be done in software for Intel P6 or later } else {
* and AMD K7 (Model > 1) or later. if (apic_verify())
*/ return -1;
rdmsr(MSR_IA32_APICBASE, l, h);
if (!(l & MSR_IA32_APICBASE_ENABLE)) {
pr_info("Local APIC disabled by BIOS -- reenabling.\n");
l &= ~MSR_IA32_APICBASE_BASE;
l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE;
wrmsr(MSR_IA32_APICBASE, l, h);
enabled_via_apicbase = 1;
}
}
/*
* The APIC feature bit should now be enabled
* in `cpuid'
*/
features = cpuid_edx(1);
if (!(features & (1 << X86_FEATURE_APIC))) {
pr_warning("Could not enable APIC!\n");
return -1;
} }
set_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC);
mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
/* The BIOS may have set up the APIC at some other address */
rdmsr(MSR_IA32_APICBASE, l, h);
if (l & MSR_IA32_APICBASE_ENABLE)
mp_lapic_addr = l & MSR_IA32_APICBASE_BASE;
pr_info("Found and enabled local APIC!\n");
apic_pm_activate(); apic_pm_activate();
......
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