aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/apic/apic.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2010-10-19 13:46:28 -0400
committerThomas Gleixner <tglx@linutronix.de>2010-10-23 11:27:43 -0400
commit5a7ae78fd478624df3059cb6f55056b85d074acc (patch)
treebd5adc0bde70bc8e93e9ef1d1f124ecdff4538be /arch/x86/kernel/apic/apic.c
parentd4429f608abde89e8bc1e24b43cd503feb95c496 (diff)
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>
Diffstat (limited to 'arch/x86/kernel/apic/apic.c')
-rw-r--r--arch/x86/kernel/apic/apic.c87
1 files changed, 54 insertions, 33 deletions
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 850657d1b0ed..463839645f9b 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -1531,13 +1531,60 @@ static int __init detect_init_APIC(void)
1531 return 0; 1531 return 0;
1532} 1532}
1533#else 1533#else
1534
1535static int apic_verify(void)
1536{
1537 u32 features, h, l;
1538
1539 /*
1540 * The APIC feature bit should now be enabled
1541 * in `cpuid'
1542 */
1543 features = cpuid_edx(1);
1544 if (!(features & (1 << X86_FEATURE_APIC))) {
1545 pr_warning("Could not enable APIC!\n");
1546 return -1;
1547 }
1548 set_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC);
1549 mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
1550
1551 /* The BIOS may have set up the APIC at some other address */
1552 rdmsr(MSR_IA32_APICBASE, l, h);
1553 if (l & MSR_IA32_APICBASE_ENABLE)
1554 mp_lapic_addr = l & MSR_IA32_APICBASE_BASE;
1555
1556 pr_info("Found and enabled local APIC!\n");
1557 return 0;
1558}
1559
1560int apic_force_enable(void)
1561{
1562 u32 h, l;
1563
1564 if (disable_apic)
1565 return -1;
1566
1567 /*
1568 * Some BIOSes disable the local APIC in the APIC_BASE
1569 * MSR. This can only be done in software for Intel P6 or later
1570 * and AMD K7 (Model > 1) or later.
1571 */
1572 rdmsr(MSR_IA32_APICBASE, l, h);
1573 if (!(l & MSR_IA32_APICBASE_ENABLE)) {
1574 pr_info("Local APIC disabled by BIOS -- reenabling.\n");
1575 l &= ~MSR_IA32_APICBASE_BASE;
1576 l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE;
1577 wrmsr(MSR_IA32_APICBASE, l, h);
1578 enabled_via_apicbase = 1;
1579 }
1580 return apic_verify();
1581}
1582
1534/* 1583/*
1535 * Detect and initialize APIC 1584 * Detect and initialize APIC
1536 */ 1585 */
1537static int __init detect_init_APIC(void) 1586static int __init detect_init_APIC(void)
1538{ 1587{
1539 u32 h, l, features;
1540
1541 /* Disabled by kernel option? */ 1588 /* Disabled by kernel option? */
1542 if (disable_apic) 1589 if (disable_apic)
1543 return -1; 1590 return -1;
@@ -1567,38 +1614,12 @@ static int __init detect_init_APIC(void)
1567 "you can enable it with \"lapic\"\n"); 1614 "you can enable it with \"lapic\"\n");
1568 return -1; 1615 return -1;
1569 } 1616 }
1570 /* 1617 if (apic_force_enable())
1571 * Some BIOSes disable the local APIC in the APIC_BASE 1618 return -1;
1572 * MSR. This can only be done in software for Intel P6 or later 1619 } else {
1573 * and AMD K7 (Model > 1) or later. 1620 if (apic_verify())
1574 */ 1621 return -1;
1575 rdmsr(MSR_IA32_APICBASE, l, h);
1576 if (!(l & MSR_IA32_APICBASE_ENABLE)) {
1577 pr_info("Local APIC disabled by BIOS -- reenabling.\n");
1578 l &= ~MSR_IA32_APICBASE_BASE;
1579 l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE;
1580 wrmsr(MSR_IA32_APICBASE, l, h);
1581 enabled_via_apicbase = 1;
1582 }
1583 }
1584 /*
1585 * The APIC feature bit should now be enabled
1586 * in `cpuid'
1587 */
1588 features = cpuid_edx(1);
1589 if (!(features & (1 << X86_FEATURE_APIC))) {
1590 pr_warning("Could not enable APIC!\n");
1591 return -1;
1592 } 1622 }
1593 set_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC);
1594 mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
1595
1596 /* The BIOS may have set up the APIC at some other address */
1597 rdmsr(MSR_IA32_APICBASE, l, h);
1598 if (l & MSR_IA32_APICBASE_ENABLE)
1599 mp_lapic_addr = l & MSR_IA32_APICBASE_BASE;
1600
1601 pr_info("Found and enabled local APIC!\n");
1602 1623
1603 apic_pm_activate(); 1624 apic_pm_activate();
1604 1625