x86: copy detect_init_APIC to the other

Signed-off-by: Yinghai Lu <yhlu.kernel@mgail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
Yinghai Lu 2008-08-24 02:01:51 -07:00 committed by Ingo Molnar
parent fa2bd35a8d
commit be7a656fe1
2 changed files with 101 additions and 1 deletions

View File

@ -1214,6 +1214,25 @@ void __cpuinit end_local_APIC_setup(void)
apic_pm_activate();
}
#ifdef CONFIG_X86_64
/*
* Detect and enable local APICs on non-SMP boards.
* Original code written by Keir Fraser.
* On AMD64 we trust the BIOS - if it says no APIC it is likely
* not correctly set up (usually the APIC timer won't work etc.)
*/
static int __init detect_init_APIC(void)
{
if (!cpu_has_apic) {
printk(KERN_INFO "No local APIC present\n");
return -1;
}
mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
boot_cpu_physical_apicid = 0;
return 0;
}
#else
/*
* Detect and initialize APIC
*/
@ -1292,6 +1311,7 @@ no_apic:
printk(KERN_INFO "No local APIC present or hardware disabled\n");
return -1;
}
#endif
#ifdef CONFIG_X86_64
void __init early_init_lapic_mapping(void)

View File

@ -684,7 +684,6 @@ int setup_profiling_timer(unsigned int multiplier)
return -EINVAL;
}
/*
* Local APIC start and shutdown
*/
@ -1264,6 +1263,7 @@ end:
}
#endif /* HAVE_X2APIC */
#ifdef CONFIG_X86_64
/*
* Detect and enable local APICs on non-SMP boards.
* Original code written by Keir Fraser.
@ -1281,6 +1281,86 @@ static int __init detect_init_APIC(void)
boot_cpu_physical_apicid = 0;
return 0;
}
#else
/*
* Detect and initialize APIC
*/
static int __init detect_init_APIC(void)
{
u32 h, l, features;
/* Disabled by kernel option? */
if (disable_apic)
return -1;
switch (boot_cpu_data.x86_vendor) {
case X86_VENDOR_AMD:
if ((boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model > 1) ||
(boot_cpu_data.x86 == 15))
break;
goto no_apic;
case X86_VENDOR_INTEL:
if (boot_cpu_data.x86 == 6 || boot_cpu_data.x86 == 15 ||
(boot_cpu_data.x86 == 5 && cpu_has_apic))
break;
goto no_apic;
default:
goto no_apic;
}
if (!cpu_has_apic) {
/*
* Over-ride BIOS and try to enable the local APIC only if
* "lapic" specified.
*/
if (!force_enable_local_apic) {
printk(KERN_INFO "Local APIC disabled by BIOS -- "
"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)) {
printk(KERN_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))) {
printk(KERN_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;
printk(KERN_INFO "Found and enabled local APIC!\n");
apic_pm_activate();
return 0;
no_apic:
printk(KERN_INFO "No local APIC present or hardware disabled\n");
return -1;
}
#endif
#ifdef CONFIG_X86_64
void __init early_init_lapic_mapping(void)