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: Thomas Gleixner <tglx@linutronix.de> LKML-Reference: <1287510389-8388-1-git-send-email-dirk.brandewie@gmail.com> Signed-off-by: Dirk Brandewie <dirk.j.brandewie@intel.com>
This commit is contained in:
parent
d4429f608a
commit
5a7ae78fd4
2 changed files with 55 additions and 33 deletions
|
@ -238,6 +238,7 @@ extern void setup_boot_APIC_clock(void);
|
|||
extern void setup_secondary_APIC_clock(void);
|
||||
extern int APIC_init_uniprocessor(void);
|
||||
extern void enable_NMI_through_LVT0(void);
|
||||
extern int apic_force_enable(void);
|
||||
|
||||
/*
|
||||
* On 32bit this is mach-xxx local
|
||||
|
|
|
@ -1531,13 +1531,60 @@ static int __init detect_init_APIC(void)
|
|||
return 0;
|
||||
}
|
||||
#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
|
||||
*/
|
||||
static int __init detect_init_APIC(void)
|
||||
{
|
||||
u32 h, l, features;
|
||||
|
||||
/* Disabled by kernel option? */
|
||||
if (disable_apic)
|
||||
return -1;
|
||||
|
@ -1567,38 +1614,12 @@ static int __init detect_init_APIC(void)
|
|||
"you can enable it with \"lapic\"\n");
|
||||
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;
|
||||
}
|
||||
if (apic_force_enable())
|
||||
return -1;
|
||||
} else {
|
||||
if (apic_verify())
|
||||
return -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();
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue