aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorYinghai Lu <yhlu.kernel@gmail.com>2008-08-24 05:01:51 -0400
committerIngo Molnar <mingo@elte.hu>2008-10-16 10:53:02 -0400
commitbe7a656fe131cba088912bcafb079b029320504d (patch)
treea13176640fb1617258a9fadb43890de55eaa4c21 /arch
parentfa2bd35a8d5c88c03b638c72daf7f38a132d0e8c (diff)
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>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/apic_32.c20
-rw-r--r--arch/x86/kernel/apic_64.c82
2 files changed, 101 insertions, 1 deletions
diff --git a/arch/x86/kernel/apic_32.c b/arch/x86/kernel/apic_32.c
index 8f8b0e1f3eb3..1103e05aa1ba 100644
--- a/arch/x86/kernel/apic_32.c
+++ b/arch/x86/kernel/apic_32.c
@@ -1214,6 +1214,25 @@ void __cpuinit end_local_APIC_setup(void)
1214 apic_pm_activate(); 1214 apic_pm_activate();
1215} 1215}
1216 1216
1217#ifdef CONFIG_X86_64
1218/*
1219 * Detect and enable local APICs on non-SMP boards.
1220 * Original code written by Keir Fraser.
1221 * On AMD64 we trust the BIOS - if it says no APIC it is likely
1222 * not correctly set up (usually the APIC timer won't work etc.)
1223 */
1224static int __init detect_init_APIC(void)
1225{
1226 if (!cpu_has_apic) {
1227 printk(KERN_INFO "No local APIC present\n");
1228 return -1;
1229 }
1230
1231 mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
1232 boot_cpu_physical_apicid = 0;
1233 return 0;
1234}
1235#else
1217/* 1236/*
1218 * Detect and initialize APIC 1237 * Detect and initialize APIC
1219 */ 1238 */
@@ -1292,6 +1311,7 @@ no_apic:
1292 printk(KERN_INFO "No local APIC present or hardware disabled\n"); 1311 printk(KERN_INFO "No local APIC present or hardware disabled\n");
1293 return -1; 1312 return -1;
1294} 1313}
1314#endif
1295 1315
1296#ifdef CONFIG_X86_64 1316#ifdef CONFIG_X86_64
1297void __init early_init_lapic_mapping(void) 1317void __init early_init_lapic_mapping(void)
diff --git a/arch/x86/kernel/apic_64.c b/arch/x86/kernel/apic_64.c
index 16a30c22b07c..b7268f5c8b18 100644
--- a/arch/x86/kernel/apic_64.c
+++ b/arch/x86/kernel/apic_64.c
@@ -684,7 +684,6 @@ int setup_profiling_timer(unsigned int multiplier)
684 return -EINVAL; 684 return -EINVAL;
685} 685}
686 686
687
688/* 687/*
689 * Local APIC start and shutdown 688 * Local APIC start and shutdown
690 */ 689 */
@@ -1264,6 +1263,7 @@ end:
1264} 1263}
1265#endif /* HAVE_X2APIC */ 1264#endif /* HAVE_X2APIC */
1266 1265
1266#ifdef CONFIG_X86_64
1267/* 1267/*
1268 * Detect and enable local APICs on non-SMP boards. 1268 * Detect and enable local APICs on non-SMP boards.
1269 * Original code written by Keir Fraser. 1269 * Original code written by Keir Fraser.
@@ -1281,6 +1281,86 @@ static int __init detect_init_APIC(void)
1281 boot_cpu_physical_apicid = 0; 1281 boot_cpu_physical_apicid = 0;
1282 return 0; 1282 return 0;
1283} 1283}
1284#else
1285/*
1286 * Detect and initialize APIC
1287 */
1288static int __init detect_init_APIC(void)
1289{
1290 u32 h, l, features;
1291
1292 /* Disabled by kernel option? */
1293 if (disable_apic)
1294 return -1;
1295
1296 switch (boot_cpu_data.x86_vendor) {
1297 case X86_VENDOR_AMD:
1298 if ((boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model > 1) ||
1299 (boot_cpu_data.x86 == 15))
1300 break;
1301 goto no_apic;
1302 case X86_VENDOR_INTEL:
1303 if (boot_cpu_data.x86 == 6 || boot_cpu_data.x86 == 15 ||
1304 (boot_cpu_data.x86 == 5 && cpu_has_apic))
1305 break;
1306 goto no_apic;
1307 default:
1308 goto no_apic;
1309 }
1310
1311 if (!cpu_has_apic) {
1312 /*
1313 * Over-ride BIOS and try to enable the local APIC only if
1314 * "lapic" specified.
1315 */
1316 if (!force_enable_local_apic) {
1317 printk(KERN_INFO "Local APIC disabled by BIOS -- "
1318 "you can enable it with \"lapic\"\n");
1319 return -1;
1320 }
1321 /*
1322 * Some BIOSes disable the local APIC in the APIC_BASE
1323 * MSR. This can only be done in software for Intel P6 or later
1324 * and AMD K7 (Model > 1) or later.
1325 */
1326 rdmsr(MSR_IA32_APICBASE, l, h);
1327 if (!(l & MSR_IA32_APICBASE_ENABLE)) {
1328 printk(KERN_INFO
1329 "Local APIC disabled by BIOS -- reenabling.\n");
1330 l &= ~MSR_IA32_APICBASE_BASE;
1331 l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE;
1332 wrmsr(MSR_IA32_APICBASE, l, h);
1333 enabled_via_apicbase = 1;
1334 }
1335 }
1336 /*
1337 * The APIC feature bit should now be enabled
1338 * in `cpuid'
1339 */
1340 features = cpuid_edx(1);
1341 if (!(features & (1 << X86_FEATURE_APIC))) {
1342 printk(KERN_WARNING "Could not enable APIC!\n");
1343 return -1;
1344 }
1345 set_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC);
1346 mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
1347
1348 /* The BIOS may have set up the APIC at some other address */
1349 rdmsr(MSR_IA32_APICBASE, l, h);
1350 if (l & MSR_IA32_APICBASE_ENABLE)
1351 mp_lapic_addr = l & MSR_IA32_APICBASE_BASE;
1352
1353 printk(KERN_INFO "Found and enabled local APIC!\n");
1354
1355 apic_pm_activate();
1356
1357 return 0;
1358
1359no_apic:
1360 printk(KERN_INFO "No local APIC present or hardware disabled\n");
1361 return -1;
1362}
1363#endif
1284 1364
1285#ifdef CONFIG_X86_64 1365#ifdef CONFIG_X86_64
1286void __init early_init_lapic_mapping(void) 1366void __init early_init_lapic_mapping(void)