diff options
author | Yinghai Lu <yhlu.kernel@gmail.com> | 2008-08-24 05:01:49 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-10-16 10:53:02 -0400 |
commit | f28c0ae21d80ffd6eb0987901c5273843387e341 (patch) | |
tree | 30e5d497a5deefdcfaf862f9c5c7a78dfc825cec /arch | |
parent | 3491998dd54f6d4ef7344518fe5463b299fdf537 (diff) |
x86: make apic_32/64.c more like
except x2apic, detec_init_APIC, and calibrating_APIC_clock
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kernel/apic_32.c | 125 | ||||
-rw-r--r-- | arch/x86/kernel/apic_64.c | 10 |
2 files changed, 122 insertions, 13 deletions
diff --git a/arch/x86/kernel/apic_32.c b/arch/x86/kernel/apic_32.c index 93718ffb9b9c..bfac26a16099 100644 --- a/arch/x86/kernel/apic_32.c +++ b/arch/x86/kernel/apic_32.c | |||
@@ -66,6 +66,9 @@ static int __init parse_lapic(char *arg) | |||
66 | return 0; | 66 | return 0; |
67 | } | 67 | } |
68 | early_param("lapic", parse_lapic); | 68 | early_param("lapic", parse_lapic); |
69 | /* Local APIC was disabled by the BIOS and enabled by the kernel */ | ||
70 | static int enabled_via_apicbase; | ||
71 | |||
69 | #endif | 72 | #endif |
70 | 73 | ||
71 | #ifdef CONFIG_X86_64 | 74 | #ifdef CONFIG_X86_64 |
@@ -131,9 +134,6 @@ static struct clock_event_device lapic_clockevent = { | |||
131 | }; | 134 | }; |
132 | static DEFINE_PER_CPU(struct clock_event_device, lapic_events); | 135 | static DEFINE_PER_CPU(struct clock_event_device, lapic_events); |
133 | 136 | ||
134 | /* Local APIC was disabled by the BIOS and enabled by the kernel */ | ||
135 | static int enabled_via_apicbase; | ||
136 | |||
137 | static unsigned long apic_phys; | 137 | static unsigned long apic_phys; |
138 | 138 | ||
139 | /* | 139 | /* |
@@ -240,6 +240,7 @@ void __cpuinit enable_NMI_through_LVT0(void) | |||
240 | apic_write(APIC_LVT0, v); | 240 | apic_write(APIC_LVT0, v); |
241 | } | 241 | } |
242 | 242 | ||
243 | #ifdef CONFIG_X86_32 | ||
243 | /** | 244 | /** |
244 | * get_physical_broadcast - Get number of physical broadcast IDs | 245 | * get_physical_broadcast - Get number of physical broadcast IDs |
245 | */ | 246 | */ |
@@ -247,6 +248,7 @@ int get_physical_broadcast(void) | |||
247 | { | 248 | { |
248 | return modern_apic() ? 0xff : 0xf; | 249 | return modern_apic() ? 0xff : 0xf; |
249 | } | 250 | } |
251 | #endif | ||
250 | 252 | ||
251 | /** | 253 | /** |
252 | * lapic_get_maxlvt - get the maximum number of local vector table entries | 254 | * lapic_get_maxlvt - get the maximum number of local vector table entries |
@@ -1291,6 +1293,32 @@ no_apic: | |||
1291 | return -1; | 1293 | return -1; |
1292 | } | 1294 | } |
1293 | 1295 | ||
1296 | #ifdef CONFIG_X86_64 | ||
1297 | void __init early_init_lapic_mapping(void) | ||
1298 | { | ||
1299 | unsigned long phys_addr; | ||
1300 | |||
1301 | /* | ||
1302 | * If no local APIC can be found then go out | ||
1303 | * : it means there is no mpatable and MADT | ||
1304 | */ | ||
1305 | if (!smp_found_config) | ||
1306 | return; | ||
1307 | |||
1308 | phys_addr = mp_lapic_addr; | ||
1309 | |||
1310 | set_fixmap_nocache(FIX_APIC_BASE, phys_addr); | ||
1311 | apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n", | ||
1312 | APIC_BASE, phys_addr); | ||
1313 | |||
1314 | /* | ||
1315 | * Fetch the APIC ID of the BSP in case we have a | ||
1316 | * default configuration (or the MP table is broken). | ||
1317 | */ | ||
1318 | boot_cpu_physical_apicid = read_apic_id(); | ||
1319 | } | ||
1320 | #endif | ||
1321 | |||
1294 | /** | 1322 | /** |
1295 | * init_apic_mappings - initialize APIC mappings | 1323 | * init_apic_mappings - initialize APIC mappings |
1296 | */ | 1324 | */ |
@@ -1308,8 +1336,8 @@ void __init init_apic_mappings(void) | |||
1308 | apic_phys = mp_lapic_addr; | 1336 | apic_phys = mp_lapic_addr; |
1309 | 1337 | ||
1310 | set_fixmap_nocache(FIX_APIC_BASE, apic_phys); | 1338 | set_fixmap_nocache(FIX_APIC_BASE, apic_phys); |
1311 | printk(KERN_DEBUG "mapped APIC to %08lx (%08lx)\n", APIC_BASE, | 1339 | apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n", |
1312 | apic_phys); | 1340 | APIC_BASE, apic_phys); |
1313 | 1341 | ||
1314 | /* | 1342 | /* |
1315 | * Fetch the APIC ID of the BSP in case we have a | 1343 | * Fetch the APIC ID of the BSP in case we have a |
@@ -1317,14 +1345,12 @@ void __init init_apic_mappings(void) | |||
1317 | */ | 1345 | */ |
1318 | if (boot_cpu_physical_apicid == -1U) | 1346 | if (boot_cpu_physical_apicid == -1U) |
1319 | boot_cpu_physical_apicid = read_apic_id(); | 1347 | boot_cpu_physical_apicid = read_apic_id(); |
1320 | |||
1321 | } | 1348 | } |
1322 | 1349 | ||
1323 | /* | 1350 | /* |
1324 | * This initializes the IO-APIC and APIC hardware if this is | 1351 | * This initializes the IO-APIC and APIC hardware if this is |
1325 | * a UP kernel. | 1352 | * a UP kernel. |
1326 | */ | 1353 | */ |
1327 | |||
1328 | int apic_version[MAX_APICS]; | 1354 | int apic_version[MAX_APICS]; |
1329 | 1355 | ||
1330 | int __init APIC_init_uniprocessor(void) | 1356 | int __init APIC_init_uniprocessor(void) |
@@ -1682,11 +1708,6 @@ static int lapic_resume(struct sys_device *dev) | |||
1682 | 1708 | ||
1683 | local_irq_save(flags); | 1709 | local_irq_save(flags); |
1684 | 1710 | ||
1685 | #ifdef CONFIG_X86_64 | ||
1686 | if (x2apic) | ||
1687 | enable_x2apic(); | ||
1688 | else | ||
1689 | #endif | ||
1690 | { | 1711 | { |
1691 | /* | 1712 | /* |
1692 | * Make sure the APICBASE points to the right address | 1713 | * Make sure the APICBASE points to the right address |
@@ -1770,7 +1791,87 @@ static void apic_pm_activate(void) { } | |||
1770 | 1791 | ||
1771 | #endif /* CONFIG_PM */ | 1792 | #endif /* CONFIG_PM */ |
1772 | 1793 | ||
1794 | #ifdef CONFIG_X86_64 | ||
1795 | /* | ||
1796 | * apic_is_clustered_box() -- Check if we can expect good TSC | ||
1797 | * | ||
1798 | * Thus far, the major user of this is IBM's Summit2 series: | ||
1799 | * | ||
1800 | * Clustered boxes may have unsynced TSC problems if they are | ||
1801 | * multi-chassis. Use available data to take a good guess. | ||
1802 | * If in doubt, go HPET. | ||
1803 | */ | ||
1804 | __cpuinit int apic_is_clustered_box(void) | ||
1805 | { | ||
1806 | int i, clusters, zeros; | ||
1807 | unsigned id; | ||
1808 | u16 *bios_cpu_apicid; | ||
1809 | DECLARE_BITMAP(clustermap, NUM_APIC_CLUSTERS); | ||
1810 | |||
1811 | /* | ||
1812 | * there is not this kind of box with AMD CPU yet. | ||
1813 | * Some AMD box with quadcore cpu and 8 sockets apicid | ||
1814 | * will be [4, 0x23] or [8, 0x27] could be thought to | ||
1815 | * vsmp box still need checking... | ||
1816 | */ | ||
1817 | if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && !is_vsmp_box()) | ||
1818 | return 0; | ||
1819 | |||
1820 | bios_cpu_apicid = early_per_cpu_ptr(x86_bios_cpu_apicid); | ||
1821 | bitmap_zero(clustermap, NUM_APIC_CLUSTERS); | ||
1822 | |||
1823 | for (i = 0; i < NR_CPUS; i++) { | ||
1824 | /* are we being called early in kernel startup? */ | ||
1825 | if (bios_cpu_apicid) { | ||
1826 | id = bios_cpu_apicid[i]; | ||
1827 | } | ||
1828 | else if (i < nr_cpu_ids) { | ||
1829 | if (cpu_present(i)) | ||
1830 | id = per_cpu(x86_bios_cpu_apicid, i); | ||
1831 | else | ||
1832 | continue; | ||
1833 | } | ||
1834 | else | ||
1835 | break; | ||
1773 | 1836 | ||
1837 | if (id != BAD_APICID) | ||
1838 | __set_bit(APIC_CLUSTERID(id), clustermap); | ||
1839 | } | ||
1840 | |||
1841 | /* Problem: Partially populated chassis may not have CPUs in some of | ||
1842 | * the APIC clusters they have been allocated. Only present CPUs have | ||
1843 | * x86_bios_cpu_apicid entries, thus causing zeroes in the bitmap. | ||
1844 | * Since clusters are allocated sequentially, count zeros only if | ||
1845 | * they are bounded by ones. | ||
1846 | */ | ||
1847 | clusters = 0; | ||
1848 | zeros = 0; | ||
1849 | for (i = 0; i < NUM_APIC_CLUSTERS; i++) { | ||
1850 | if (test_bit(i, clustermap)) { | ||
1851 | clusters += 1 + zeros; | ||
1852 | zeros = 0; | ||
1853 | } else | ||
1854 | ++zeros; | ||
1855 | } | ||
1856 | |||
1857 | /* ScaleMP vSMPowered boxes have one cluster per board and TSCs are | ||
1858 | * not guaranteed to be synced between boards | ||
1859 | */ | ||
1860 | if (is_vsmp_box() && clusters > 1) | ||
1861 | return 1; | ||
1862 | |||
1863 | /* | ||
1864 | * If clusters > 2, then should be multi-chassis. | ||
1865 | * May have to revisit this when multi-core + hyperthreaded CPUs come | ||
1866 | * out, but AFAIK this will work even for them. | ||
1867 | */ | ||
1868 | return (clusters > 2); | ||
1869 | } | ||
1870 | #endif | ||
1871 | |||
1872 | /* | ||
1873 | * APIC command line parameters | ||
1874 | */ | ||
1774 | static int __init setup_disableapic(char *arg) | 1875 | static int __init setup_disableapic(char *arg) |
1775 | { | 1876 | { |
1776 | disable_apic = 1; | 1877 | disable_apic = 1; |
diff --git a/arch/x86/kernel/apic_64.c b/arch/x86/kernel/apic_64.c index eeb69838c2f8..dca6c246e731 100644 --- a/arch/x86/kernel/apic_64.c +++ b/arch/x86/kernel/apic_64.c | |||
@@ -69,6 +69,9 @@ static int __init parse_lapic(char *arg) | |||
69 | return 0; | 69 | return 0; |
70 | } | 70 | } |
71 | early_param("lapic", parse_lapic); | 71 | early_param("lapic", parse_lapic); |
72 | /* Local APIC was disabled by the BIOS and enabled by the kernel */ | ||
73 | static int enabled_via_apicbase; | ||
74 | |||
72 | #endif | 75 | #endif |
73 | 76 | ||
74 | #ifdef CONFIG_X86_64 | 77 | #ifdef CONFIG_X86_64 |
@@ -1279,6 +1282,7 @@ static int __init detect_init_APIC(void) | |||
1279 | return 0; | 1282 | return 0; |
1280 | } | 1283 | } |
1281 | 1284 | ||
1285 | #ifdef CONFIG_X86_64 | ||
1282 | void __init early_init_lapic_mapping(void) | 1286 | void __init early_init_lapic_mapping(void) |
1283 | { | 1287 | { |
1284 | unsigned long phys_addr; | 1288 | unsigned long phys_addr; |
@@ -1302,6 +1306,7 @@ void __init early_init_lapic_mapping(void) | |||
1302 | */ | 1306 | */ |
1303 | boot_cpu_physical_apicid = read_apic_id(); | 1307 | boot_cpu_physical_apicid = read_apic_id(); |
1304 | } | 1308 | } |
1309 | #endif | ||
1305 | 1310 | ||
1306 | /** | 1311 | /** |
1307 | * init_apic_mappings - initialize APIC mappings | 1312 | * init_apic_mappings - initialize APIC mappings |
@@ -1334,7 +1339,8 @@ void __init init_apic_mappings(void) | |||
1334 | * Fetch the APIC ID of the BSP in case we have a | 1339 | * Fetch the APIC ID of the BSP in case we have a |
1335 | * default configuration (or the MP table is broken). | 1340 | * default configuration (or the MP table is broken). |
1336 | */ | 1341 | */ |
1337 | boot_cpu_physical_apicid = read_apic_id(); | 1342 | if (boot_cpu_physical_apicid == -1U) |
1343 | boot_cpu_physical_apicid = read_apic_id(); | ||
1338 | } | 1344 | } |
1339 | 1345 | ||
1340 | /* | 1346 | /* |
@@ -1782,6 +1788,7 @@ static void apic_pm_activate(void) { } | |||
1782 | 1788 | ||
1783 | #endif /* CONFIG_PM */ | 1789 | #endif /* CONFIG_PM */ |
1784 | 1790 | ||
1791 | #ifdef CONFIG_X86_64 | ||
1785 | /* | 1792 | /* |
1786 | * apic_is_clustered_box() -- Check if we can expect good TSC | 1793 | * apic_is_clustered_box() -- Check if we can expect good TSC |
1787 | * | 1794 | * |
@@ -1857,6 +1864,7 @@ __cpuinit int apic_is_clustered_box(void) | |||
1857 | */ | 1864 | */ |
1858 | return (clusters > 2); | 1865 | return (clusters > 2); |
1859 | } | 1866 | } |
1867 | #endif | ||
1860 | 1868 | ||
1861 | /* | 1869 | /* |
1862 | * APIC command line parameters | 1870 | * APIC command line parameters |