Merge branch 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: x86: Fix APIC ID sizing bug on larger systems, clean up MAX_APICS confusion x86, acpi: Parse all SRAT cpu entries even above the cpu number limitation x86, acpi: Add MAX_LOCAL_APIC for 32bit x86: io_apic: Split setup_ioapic_ids_from_mpc() x86: io_apic: Fix CONFIG_X86_IO_APIC=n breakage x86: apic: Move probe_nr_irqs_gsi() into ioapic_init_mappings() x86: Allow platforms to force enable apic
This commit is contained in:
@@ -1532,13 +1532,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;
|
||||
@@ -1568,38 +1615,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();
|
||||
|
||||
@@ -1687,7 +1708,7 @@ void __init init_apic_mappings(void)
|
||||
* This initializes the IO-APIC and APIC hardware if this is
|
||||
* a UP kernel.
|
||||
*/
|
||||
int apic_version[MAX_APICS];
|
||||
int apic_version[MAX_LOCAL_APIC];
|
||||
|
||||
int __init APIC_init_uniprocessor(void)
|
||||
{
|
||||
|
Reference in New Issue
Block a user