diff options
Diffstat (limited to 'arch/x86/kernel/apic/apic.c')
-rw-r--r-- | arch/x86/kernel/apic/apic.c | 455 |
1 files changed, 238 insertions, 217 deletions
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 29b5b18afa27..ad3639ae1b9b 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
@@ -134,9 +134,6 @@ static inline void imcr_apic_to_pic(void) | |||
134 | */ | 134 | */ |
135 | static int force_enable_local_apic __initdata; | 135 | static int force_enable_local_apic __initdata; |
136 | 136 | ||
137 | /* Control whether x2APIC mode is enabled or not */ | ||
138 | static bool nox2apic __initdata; | ||
139 | |||
140 | /* | 137 | /* |
141 | * APIC command line parameters | 138 | * APIC command line parameters |
142 | */ | 139 | */ |
@@ -161,33 +158,6 @@ static __init int setup_apicpmtimer(char *s) | |||
161 | __setup("apicpmtimer", setup_apicpmtimer); | 158 | __setup("apicpmtimer", setup_apicpmtimer); |
162 | #endif | 159 | #endif |
163 | 160 | ||
164 | int x2apic_mode; | ||
165 | #ifdef CONFIG_X86_X2APIC | ||
166 | /* x2apic enabled before OS handover */ | ||
167 | int x2apic_preenabled; | ||
168 | static int x2apic_disabled; | ||
169 | static int __init setup_nox2apic(char *str) | ||
170 | { | ||
171 | if (x2apic_enabled()) { | ||
172 | int apicid = native_apic_msr_read(APIC_ID); | ||
173 | |||
174 | if (apicid >= 255) { | ||
175 | pr_warning("Apicid: %08x, cannot enforce nox2apic\n", | ||
176 | apicid); | ||
177 | return 0; | ||
178 | } | ||
179 | |||
180 | pr_warning("x2apic already enabled. will disable it\n"); | ||
181 | } else | ||
182 | setup_clear_cpu_cap(X86_FEATURE_X2APIC); | ||
183 | |||
184 | nox2apic = true; | ||
185 | |||
186 | return 0; | ||
187 | } | ||
188 | early_param("nox2apic", setup_nox2apic); | ||
189 | #endif | ||
190 | |||
191 | unsigned long mp_lapic_addr; | 161 | unsigned long mp_lapic_addr; |
192 | int disable_apic; | 162 | int disable_apic; |
193 | /* Disable local APIC timer from the kernel commandline or via dmi quirk */ | 163 | /* Disable local APIC timer from the kernel commandline or via dmi quirk */ |
@@ -1475,7 +1445,7 @@ void setup_local_APIC(void) | |||
1475 | #endif | 1445 | #endif |
1476 | } | 1446 | } |
1477 | 1447 | ||
1478 | void end_local_APIC_setup(void) | 1448 | static void end_local_APIC_setup(void) |
1479 | { | 1449 | { |
1480 | lapic_setup_esr(); | 1450 | lapic_setup_esr(); |
1481 | 1451 | ||
@@ -1492,116 +1462,183 @@ void end_local_APIC_setup(void) | |||
1492 | apic_pm_activate(); | 1462 | apic_pm_activate(); |
1493 | } | 1463 | } |
1494 | 1464 | ||
1495 | void __init bsp_end_local_APIC_setup(void) | 1465 | /* |
1466 | * APIC setup function for application processors. Called from smpboot.c | ||
1467 | */ | ||
1468 | void apic_ap_setup(void) | ||
1496 | { | 1469 | { |
1470 | setup_local_APIC(); | ||
1497 | end_local_APIC_setup(); | 1471 | end_local_APIC_setup(); |
1498 | |||
1499 | /* | ||
1500 | * Now that local APIC setup is completed for BP, configure the fault | ||
1501 | * handling for interrupt remapping. | ||
1502 | */ | ||
1503 | irq_remap_enable_fault_handling(); | ||
1504 | |||
1505 | } | 1472 | } |
1506 | 1473 | ||
1507 | #ifdef CONFIG_X86_X2APIC | 1474 | #ifdef CONFIG_X86_X2APIC |
1508 | /* | 1475 | int x2apic_mode; |
1509 | * Need to disable xapic and x2apic at the same time and then enable xapic mode | ||
1510 | */ | ||
1511 | static inline void __disable_x2apic(u64 msr) | ||
1512 | { | ||
1513 | wrmsrl(MSR_IA32_APICBASE, | ||
1514 | msr & ~(X2APIC_ENABLE | XAPIC_ENABLE)); | ||
1515 | wrmsrl(MSR_IA32_APICBASE, msr & ~X2APIC_ENABLE); | ||
1516 | } | ||
1517 | 1476 | ||
1518 | static __init void disable_x2apic(void) | 1477 | enum { |
1478 | X2APIC_OFF, | ||
1479 | X2APIC_ON, | ||
1480 | X2APIC_DISABLED, | ||
1481 | }; | ||
1482 | static int x2apic_state; | ||
1483 | |||
1484 | static inline void __x2apic_disable(void) | ||
1519 | { | 1485 | { |
1520 | u64 msr; | 1486 | u64 msr; |
1521 | 1487 | ||
1522 | if (!cpu_has_x2apic) | 1488 | if (cpu_has_apic) |
1523 | return; | 1489 | return; |
1524 | 1490 | ||
1525 | rdmsrl(MSR_IA32_APICBASE, msr); | 1491 | rdmsrl(MSR_IA32_APICBASE, msr); |
1526 | if (msr & X2APIC_ENABLE) { | 1492 | if (!(msr & X2APIC_ENABLE)) |
1527 | u32 x2apic_id = read_apic_id(); | 1493 | return; |
1528 | 1494 | /* Disable xapic and x2apic first and then reenable xapic mode */ | |
1529 | if (x2apic_id >= 255) | 1495 | wrmsrl(MSR_IA32_APICBASE, msr & ~(X2APIC_ENABLE | XAPIC_ENABLE)); |
1530 | panic("Cannot disable x2apic, id: %08x\n", x2apic_id); | 1496 | wrmsrl(MSR_IA32_APICBASE, msr & ~X2APIC_ENABLE); |
1497 | printk_once(KERN_INFO "x2apic disabled\n"); | ||
1498 | } | ||
1531 | 1499 | ||
1532 | pr_info("Disabling x2apic\n"); | 1500 | static inline void __x2apic_enable(void) |
1533 | __disable_x2apic(msr); | 1501 | { |
1502 | u64 msr; | ||
1534 | 1503 | ||
1535 | if (nox2apic) { | 1504 | rdmsrl(MSR_IA32_APICBASE, msr); |
1536 | clear_cpu_cap(&cpu_data(0), X86_FEATURE_X2APIC); | 1505 | if (msr & X2APIC_ENABLE) |
1537 | setup_clear_cpu_cap(X86_FEATURE_X2APIC); | 1506 | return; |
1538 | } | 1507 | wrmsrl(MSR_IA32_APICBASE, msr | X2APIC_ENABLE); |
1508 | printk_once(KERN_INFO "x2apic enabled\n"); | ||
1509 | } | ||
1539 | 1510 | ||
1540 | x2apic_disabled = 1; | 1511 | static int __init setup_nox2apic(char *str) |
1541 | x2apic_mode = 0; | 1512 | { |
1513 | if (x2apic_enabled()) { | ||
1514 | int apicid = native_apic_msr_read(APIC_ID); | ||
1542 | 1515 | ||
1543 | register_lapic_address(mp_lapic_addr); | 1516 | if (apicid >= 255) { |
1517 | pr_warning("Apicid: %08x, cannot enforce nox2apic\n", | ||
1518 | apicid); | ||
1519 | return 0; | ||
1520 | } | ||
1521 | pr_warning("x2apic already enabled.\n"); | ||
1522 | __x2apic_disable(); | ||
1544 | } | 1523 | } |
1524 | setup_clear_cpu_cap(X86_FEATURE_X2APIC); | ||
1525 | x2apic_state = X2APIC_DISABLED; | ||
1526 | x2apic_mode = 0; | ||
1527 | return 0; | ||
1545 | } | 1528 | } |
1529 | early_param("nox2apic", setup_nox2apic); | ||
1546 | 1530 | ||
1547 | void check_x2apic(void) | 1531 | /* Called from cpu_init() to enable x2apic on (secondary) cpus */ |
1532 | void x2apic_setup(void) | ||
1548 | { | 1533 | { |
1549 | if (x2apic_enabled()) { | 1534 | /* |
1550 | pr_info("x2apic enabled by BIOS, switching to x2apic ops\n"); | 1535 | * If x2apic is not in ON state, disable it if already enabled |
1551 | x2apic_preenabled = x2apic_mode = 1; | 1536 | * from BIOS. |
1537 | */ | ||
1538 | if (x2apic_state != X2APIC_ON) { | ||
1539 | __x2apic_disable(); | ||
1540 | return; | ||
1552 | } | 1541 | } |
1542 | __x2apic_enable(); | ||
1553 | } | 1543 | } |
1554 | 1544 | ||
1555 | void enable_x2apic(void) | 1545 | static __init void x2apic_disable(void) |
1556 | { | 1546 | { |
1557 | u64 msr; | 1547 | u32 x2apic_id; |
1558 | 1548 | ||
1559 | rdmsrl(MSR_IA32_APICBASE, msr); | 1549 | if (x2apic_state != X2APIC_ON) |
1560 | if (x2apic_disabled) { | 1550 | goto out; |
1561 | __disable_x2apic(msr); | 1551 | |
1552 | x2apic_id = read_apic_id(); | ||
1553 | if (x2apic_id >= 255) | ||
1554 | panic("Cannot disable x2apic, id: %08x\n", x2apic_id); | ||
1555 | |||
1556 | __x2apic_disable(); | ||
1557 | register_lapic_address(mp_lapic_addr); | ||
1558 | out: | ||
1559 | x2apic_state = X2APIC_DISABLED; | ||
1560 | x2apic_mode = 0; | ||
1561 | } | ||
1562 | |||
1563 | static __init void x2apic_enable(void) | ||
1564 | { | ||
1565 | if (x2apic_state != X2APIC_OFF) | ||
1562 | return; | 1566 | return; |
1563 | } | ||
1564 | 1567 | ||
1565 | if (!x2apic_mode) | 1568 | x2apic_mode = 1; |
1569 | x2apic_state = X2APIC_ON; | ||
1570 | __x2apic_enable(); | ||
1571 | } | ||
1572 | |||
1573 | static __init void try_to_enable_x2apic(int remap_mode) | ||
1574 | { | ||
1575 | if (x2apic_state == X2APIC_DISABLED) | ||
1566 | return; | 1576 | return; |
1567 | 1577 | ||
1568 | if (!(msr & X2APIC_ENABLE)) { | 1578 | if (remap_mode != IRQ_REMAP_X2APIC_MODE) { |
1569 | printk_once(KERN_INFO "Enabling x2apic\n"); | 1579 | /* IR is required if there is APIC ID > 255 even when running |
1570 | wrmsrl(MSR_IA32_APICBASE, msr | X2APIC_ENABLE); | 1580 | * under KVM |
1581 | */ | ||
1582 | if (max_physical_apicid > 255 || | ||
1583 | !hypervisor_x2apic_available()) { | ||
1584 | pr_info("x2apic: IRQ remapping doesn't support X2APIC mode\n"); | ||
1585 | x2apic_disable(); | ||
1586 | return; | ||
1587 | } | ||
1588 | |||
1589 | /* | ||
1590 | * without IR all CPUs can be addressed by IOAPIC/MSI | ||
1591 | * only in physical mode | ||
1592 | */ | ||
1593 | x2apic_phys = 1; | ||
1571 | } | 1594 | } |
1595 | x2apic_enable(); | ||
1572 | } | 1596 | } |
1573 | #endif /* CONFIG_X86_X2APIC */ | ||
1574 | 1597 | ||
1575 | int __init enable_IR(void) | 1598 | void __init check_x2apic(void) |
1576 | { | 1599 | { |
1577 | #ifdef CONFIG_IRQ_REMAP | 1600 | if (x2apic_enabled()) { |
1578 | if (!irq_remapping_supported()) { | 1601 | pr_info("x2apic: enabled by BIOS, switching to x2apic ops\n"); |
1579 | pr_debug("intr-remapping not supported\n"); | 1602 | x2apic_mode = 1; |
1580 | return -1; | 1603 | x2apic_state = X2APIC_ON; |
1604 | } else if (!cpu_has_x2apic) { | ||
1605 | x2apic_state = X2APIC_DISABLED; | ||
1581 | } | 1606 | } |
1607 | } | ||
1608 | #else /* CONFIG_X86_X2APIC */ | ||
1609 | static int __init validate_x2apic(void) | ||
1610 | { | ||
1611 | if (!apic_is_x2apic_enabled()) | ||
1612 | return 0; | ||
1613 | /* | ||
1614 | * Checkme: Can we simply turn off x2apic here instead of panic? | ||
1615 | */ | ||
1616 | panic("BIOS has enabled x2apic but kernel doesn't support x2apic, please disable x2apic in BIOS.\n"); | ||
1617 | } | ||
1618 | early_initcall(validate_x2apic); | ||
1582 | 1619 | ||
1583 | if (!x2apic_preenabled && skip_ioapic_setup) { | 1620 | static inline void try_to_enable_x2apic(int remap_mode) { } |
1584 | pr_info("Skipped enabling intr-remap because of skipping " | 1621 | static inline void __x2apic_enable(void) { } |
1585 | "io-apic setup\n"); | 1622 | #endif /* !CONFIG_X86_X2APIC */ |
1623 | |||
1624 | static int __init try_to_enable_IR(void) | ||
1625 | { | ||
1626 | #ifdef CONFIG_X86_IO_APIC | ||
1627 | if (!x2apic_enabled() && skip_ioapic_setup) { | ||
1628 | pr_info("Not enabling interrupt remapping due to skipped IO-APIC setup\n"); | ||
1586 | return -1; | 1629 | return -1; |
1587 | } | 1630 | } |
1588 | |||
1589 | return irq_remapping_enable(); | ||
1590 | #endif | 1631 | #endif |
1591 | return -1; | 1632 | return irq_remapping_enable(); |
1592 | } | 1633 | } |
1593 | 1634 | ||
1594 | void __init enable_IR_x2apic(void) | 1635 | void __init enable_IR_x2apic(void) |
1595 | { | 1636 | { |
1596 | unsigned long flags; | 1637 | unsigned long flags; |
1597 | int ret, x2apic_enabled = 0; | 1638 | int ret, ir_stat; |
1598 | int hardware_init_ret; | ||
1599 | |||
1600 | /* Make sure irq_remap_ops are initialized */ | ||
1601 | setup_irq_remapping_ops(); | ||
1602 | 1639 | ||
1603 | hardware_init_ret = irq_remapping_prepare(); | 1640 | ir_stat = irq_remapping_prepare(); |
1604 | if (hardware_init_ret && !x2apic_supported()) | 1641 | if (ir_stat < 0 && !x2apic_supported()) |
1605 | return; | 1642 | return; |
1606 | 1643 | ||
1607 | ret = save_ioapic_entries(); | 1644 | ret = save_ioapic_entries(); |
@@ -1614,49 +1651,13 @@ void __init enable_IR_x2apic(void) | |||
1614 | legacy_pic->mask_all(); | 1651 | legacy_pic->mask_all(); |
1615 | mask_ioapic_entries(); | 1652 | mask_ioapic_entries(); |
1616 | 1653 | ||
1617 | if (x2apic_preenabled && nox2apic) | 1654 | /* If irq_remapping_prepare() succeded, try to enable it */ |
1618 | disable_x2apic(); | 1655 | if (ir_stat >= 0) |
1619 | 1656 | ir_stat = try_to_enable_IR(); | |
1620 | if (hardware_init_ret) | 1657 | /* ir_stat contains the remap mode or an error code */ |
1621 | ret = -1; | 1658 | try_to_enable_x2apic(ir_stat); |
1622 | else | ||
1623 | ret = enable_IR(); | ||
1624 | |||
1625 | if (!x2apic_supported()) | ||
1626 | goto skip_x2apic; | ||
1627 | |||
1628 | if (ret < 0) { | ||
1629 | /* IR is required if there is APIC ID > 255 even when running | ||
1630 | * under KVM | ||
1631 | */ | ||
1632 | if (max_physical_apicid > 255 || | ||
1633 | !hypervisor_x2apic_available()) { | ||
1634 | if (x2apic_preenabled) | ||
1635 | disable_x2apic(); | ||
1636 | goto skip_x2apic; | ||
1637 | } | ||
1638 | /* | ||
1639 | * without IR all CPUs can be addressed by IOAPIC/MSI | ||
1640 | * only in physical mode | ||
1641 | */ | ||
1642 | x2apic_force_phys(); | ||
1643 | } | ||
1644 | 1659 | ||
1645 | if (ret == IRQ_REMAP_XAPIC_MODE) { | 1660 | if (ir_stat < 0) |
1646 | pr_info("x2apic not enabled, IRQ remapping is in xapic mode\n"); | ||
1647 | goto skip_x2apic; | ||
1648 | } | ||
1649 | |||
1650 | x2apic_enabled = 1; | ||
1651 | |||
1652 | if (x2apic_supported() && !x2apic_mode) { | ||
1653 | x2apic_mode = 1; | ||
1654 | enable_x2apic(); | ||
1655 | pr_info("Enabled x2apic\n"); | ||
1656 | } | ||
1657 | |||
1658 | skip_x2apic: | ||
1659 | if (ret < 0) /* IR enabling failed */ | ||
1660 | restore_ioapic_entries(); | 1661 | restore_ioapic_entries(); |
1661 | legacy_pic->restore_mask(); | 1662 | legacy_pic->restore_mask(); |
1662 | local_irq_restore(flags); | 1663 | local_irq_restore(flags); |
@@ -1847,82 +1848,8 @@ void __init register_lapic_address(unsigned long address) | |||
1847 | } | 1848 | } |
1848 | } | 1849 | } |
1849 | 1850 | ||
1850 | /* | ||
1851 | * This initializes the IO-APIC and APIC hardware if this is | ||
1852 | * a UP kernel. | ||
1853 | */ | ||
1854 | int apic_version[MAX_LOCAL_APIC]; | 1851 | int apic_version[MAX_LOCAL_APIC]; |
1855 | 1852 | ||
1856 | int __init APIC_init_uniprocessor(void) | ||
1857 | { | ||
1858 | if (disable_apic) { | ||
1859 | pr_info("Apic disabled\n"); | ||
1860 | return -1; | ||
1861 | } | ||
1862 | #ifdef CONFIG_X86_64 | ||
1863 | if (!cpu_has_apic) { | ||
1864 | disable_apic = 1; | ||
1865 | pr_info("Apic disabled by BIOS\n"); | ||
1866 | return -1; | ||
1867 | } | ||
1868 | #else | ||
1869 | if (!smp_found_config && !cpu_has_apic) | ||
1870 | return -1; | ||
1871 | |||
1872 | /* | ||
1873 | * Complain if the BIOS pretends there is one. | ||
1874 | */ | ||
1875 | if (!cpu_has_apic && | ||
1876 | APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) { | ||
1877 | pr_err("BIOS bug, local APIC 0x%x not detected!...\n", | ||
1878 | boot_cpu_physical_apicid); | ||
1879 | return -1; | ||
1880 | } | ||
1881 | #endif | ||
1882 | |||
1883 | default_setup_apic_routing(); | ||
1884 | |||
1885 | verify_local_APIC(); | ||
1886 | connect_bsp_APIC(); | ||
1887 | |||
1888 | #ifdef CONFIG_X86_64 | ||
1889 | apic_write(APIC_ID, SET_APIC_ID(boot_cpu_physical_apicid)); | ||
1890 | #else | ||
1891 | /* | ||
1892 | * Hack: In case of kdump, after a crash, kernel might be booting | ||
1893 | * on a cpu with non-zero lapic id. But boot_cpu_physical_apicid | ||
1894 | * might be zero if read from MP tables. Get it from LAPIC. | ||
1895 | */ | ||
1896 | # ifdef CONFIG_CRASH_DUMP | ||
1897 | boot_cpu_physical_apicid = read_apic_id(); | ||
1898 | # endif | ||
1899 | #endif | ||
1900 | physid_set_mask_of_physid(boot_cpu_physical_apicid, &phys_cpu_present_map); | ||
1901 | setup_local_APIC(); | ||
1902 | |||
1903 | #ifdef CONFIG_X86_IO_APIC | ||
1904 | /* | ||
1905 | * Now enable IO-APICs, actually call clear_IO_APIC | ||
1906 | * We need clear_IO_APIC before enabling error vector | ||
1907 | */ | ||
1908 | if (!skip_ioapic_setup && nr_ioapics) | ||
1909 | enable_IO_APIC(); | ||
1910 | #endif | ||
1911 | |||
1912 | bsp_end_local_APIC_setup(); | ||
1913 | |||
1914 | #ifdef CONFIG_X86_IO_APIC | ||
1915 | if (smp_found_config && !skip_ioapic_setup && nr_ioapics) | ||
1916 | setup_IO_APIC(); | ||
1917 | else { | ||
1918 | nr_ioapics = 0; | ||
1919 | } | ||
1920 | #endif | ||
1921 | |||
1922 | x86_init.timers.setup_percpu_clockev(); | ||
1923 | return 0; | ||
1924 | } | ||
1925 | |||
1926 | /* | 1853 | /* |
1927 | * Local APIC interrupts | 1854 | * Local APIC interrupts |
1928 | */ | 1855 | */ |
@@ -2027,7 +1954,7 @@ __visible void smp_trace_error_interrupt(struct pt_regs *regs) | |||
2027 | /** | 1954 | /** |
2028 | * connect_bsp_APIC - attach the APIC to the interrupt system | 1955 | * connect_bsp_APIC - attach the APIC to the interrupt system |
2029 | */ | 1956 | */ |
2030 | void __init connect_bsp_APIC(void) | 1957 | static void __init connect_bsp_APIC(void) |
2031 | { | 1958 | { |
2032 | #ifdef CONFIG_X86_32 | 1959 | #ifdef CONFIG_X86_32 |
2033 | if (pic_mode) { | 1960 | if (pic_mode) { |
@@ -2274,6 +2201,100 @@ void __init apic_set_eoi_write(void (*eoi_write)(u32 reg, u32 v)) | |||
2274 | } | 2201 | } |
2275 | } | 2202 | } |
2276 | 2203 | ||
2204 | static void __init apic_bsp_up_setup(void) | ||
2205 | { | ||
2206 | #ifdef CONFIG_X86_64 | ||
2207 | apic_write(APIC_ID, SET_APIC_ID(boot_cpu_physical_apicid)); | ||
2208 | #else | ||
2209 | /* | ||
2210 | * Hack: In case of kdump, after a crash, kernel might be booting | ||
2211 | * on a cpu with non-zero lapic id. But boot_cpu_physical_apicid | ||
2212 | * might be zero if read from MP tables. Get it from LAPIC. | ||
2213 | */ | ||
2214 | # ifdef CONFIG_CRASH_DUMP | ||
2215 | boot_cpu_physical_apicid = read_apic_id(); | ||
2216 | # endif | ||
2217 | #endif | ||
2218 | physid_set_mask_of_physid(boot_cpu_physical_apicid, &phys_cpu_present_map); | ||
2219 | } | ||
2220 | |||
2221 | /** | ||
2222 | * apic_bsp_setup - Setup function for local apic and io-apic | ||
2223 | * @upmode: Force UP mode (for APIC_init_uniprocessor) | ||
2224 | * | ||
2225 | * Returns: | ||
2226 | * apic_id of BSP APIC | ||
2227 | */ | ||
2228 | int __init apic_bsp_setup(bool upmode) | ||
2229 | { | ||
2230 | int id; | ||
2231 | |||
2232 | connect_bsp_APIC(); | ||
2233 | if (upmode) | ||
2234 | apic_bsp_up_setup(); | ||
2235 | setup_local_APIC(); | ||
2236 | |||
2237 | if (x2apic_mode) | ||
2238 | id = apic_read(APIC_LDR); | ||
2239 | else | ||
2240 | id = GET_APIC_LOGICAL_ID(apic_read(APIC_LDR)); | ||
2241 | |||
2242 | enable_IO_APIC(); | ||
2243 | end_local_APIC_setup(); | ||
2244 | irq_remap_enable_fault_handling(); | ||
2245 | setup_IO_APIC(); | ||
2246 | /* Setup local timer */ | ||
2247 | x86_init.timers.setup_percpu_clockev(); | ||
2248 | return id; | ||
2249 | } | ||
2250 | |||
2251 | /* | ||
2252 | * This initializes the IO-APIC and APIC hardware if this is | ||
2253 | * a UP kernel. | ||
2254 | */ | ||
2255 | int __init APIC_init_uniprocessor(void) | ||
2256 | { | ||
2257 | if (disable_apic) { | ||
2258 | pr_info("Apic disabled\n"); | ||
2259 | return -1; | ||
2260 | } | ||
2261 | #ifdef CONFIG_X86_64 | ||
2262 | if (!cpu_has_apic) { | ||
2263 | disable_apic = 1; | ||
2264 | pr_info("Apic disabled by BIOS\n"); | ||
2265 | return -1; | ||
2266 | } | ||
2267 | #else | ||
2268 | if (!smp_found_config && !cpu_has_apic) | ||
2269 | return -1; | ||
2270 | |||
2271 | /* | ||
2272 | * Complain if the BIOS pretends there is one. | ||
2273 | */ | ||
2274 | if (!cpu_has_apic && | ||
2275 | APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) { | ||
2276 | pr_err("BIOS bug, local APIC 0x%x not detected!...\n", | ||
2277 | boot_cpu_physical_apicid); | ||
2278 | return -1; | ||
2279 | } | ||
2280 | #endif | ||
2281 | |||
2282 | if (!smp_found_config) | ||
2283 | disable_ioapic_support(); | ||
2284 | |||
2285 | default_setup_apic_routing(); | ||
2286 | verify_local_APIC(); | ||
2287 | apic_bsp_setup(true); | ||
2288 | return 0; | ||
2289 | } | ||
2290 | |||
2291 | #ifdef CONFIG_UP_LATE_INIT | ||
2292 | void __init up_late_init(void) | ||
2293 | { | ||
2294 | APIC_init_uniprocessor(); | ||
2295 | } | ||
2296 | #endif | ||
2297 | |||
2277 | /* | 2298 | /* |
2278 | * Power management | 2299 | * Power management |
2279 | */ | 2300 | */ |
@@ -2359,9 +2380,9 @@ static void lapic_resume(void) | |||
2359 | mask_ioapic_entries(); | 2380 | mask_ioapic_entries(); |
2360 | legacy_pic->mask_all(); | 2381 | legacy_pic->mask_all(); |
2361 | 2382 | ||
2362 | if (x2apic_mode) | 2383 | if (x2apic_mode) { |
2363 | enable_x2apic(); | 2384 | __x2apic_enable(); |
2364 | else { | 2385 | } else { |
2365 | /* | 2386 | /* |
2366 | * Make sure the APICBASE points to the right address | 2387 | * Make sure the APICBASE points to the right address |
2367 | * | 2388 | * |