aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/apic.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/apic.c')
-rw-r--r--arch/x86/kernel/apic.c213
1 files changed, 129 insertions, 84 deletions
diff --git a/arch/x86/kernel/apic.c b/arch/x86/kernel/apic.c
index 115449f869ee..a894eea9d51a 100644
--- a/arch/x86/kernel/apic.c
+++ b/arch/x86/kernel/apic.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Local APIC handling, local APIC timers 2 * Local APIC handling, local APIC timers
3 * 3 *
4 * (c) 1999, 2000 Ingo Molnar <mingo@redhat.com> 4 * (c) 1999, 2000, 2009 Ingo Molnar <mingo@redhat.com>
5 * 5 *
6 * Fixes 6 * Fixes
7 * Maciej W. Rozycki : Bits for genuine 82489DX APICs; 7 * Maciej W. Rozycki : Bits for genuine 82489DX APICs;
@@ -14,51 +14,71 @@
14 * Mikael Pettersson : PM converted to driver model. 14 * Mikael Pettersson : PM converted to driver model.
15 */ 15 */
16 16
17#include <linux/init.h>
18
19#include <linux/mm.h>
20#include <linux/delay.h>
21#include <linux/bootmem.h>
22#include <linux/interrupt.h>
23#include <linux/mc146818rtc.h>
24#include <linux/kernel_stat.h> 17#include <linux/kernel_stat.h>
25#include <linux/sysdev.h> 18#include <linux/mc146818rtc.h>
26#include <linux/ioport.h>
27#include <linux/cpu.h>
28#include <linux/clockchips.h>
29#include <linux/acpi_pmtmr.h> 19#include <linux/acpi_pmtmr.h>
20#include <linux/clockchips.h>
21#include <linux/interrupt.h>
22#include <linux/bootmem.h>
23#include <linux/ftrace.h>
24#include <linux/ioport.h>
30#include <linux/module.h> 25#include <linux/module.h>
31#include <linux/dmi.h> 26#include <linux/sysdev.h>
27#include <linux/delay.h>
28#include <linux/timex.h>
32#include <linux/dmar.h> 29#include <linux/dmar.h>
33#include <linux/ftrace.h> 30#include <linux/init.h>
34#include <linux/smp.h> 31#include <linux/cpu.h>
32#include <linux/dmi.h>
35#include <linux/nmi.h> 33#include <linux/nmi.h>
36#include <linux/timex.h> 34#include <linux/smp.h>
35#include <linux/mm.h>
37 36
38#include <asm/atomic.h>
39#include <asm/mtrr.h>
40#include <asm/mpspec.h>
41#include <asm/desc.h>
42#include <asm/arch_hooks.h> 37#include <asm/arch_hooks.h>
43#include <asm/hpet.h>
44#include <asm/pgalloc.h> 38#include <asm/pgalloc.h>
39#include <asm/genapic.h>
40#include <asm/atomic.h>
41#include <asm/mpspec.h>
45#include <asm/i8253.h> 42#include <asm/i8253.h>
46#include <asm/idle.h> 43#include <asm/i8259.h>
47#include <asm/proto.h> 44#include <asm/proto.h>
48#include <asm/apic.h> 45#include <asm/apic.h>
49#include <asm/i8259.h> 46#include <asm/desc.h>
47#include <asm/hpet.h>
48#include <asm/idle.h>
49#include <asm/mtrr.h>
50#include <asm/smp.h> 50#include <asm/smp.h>
51 51
52#include <mach_apic.h> 52unsigned int num_processors;
53#include <mach_apicdef.h> 53
54#include <mach_ipi.h> 54unsigned disabled_cpus __cpuinitdata;
55
56/* Processor that is doing the boot up */
57unsigned int boot_cpu_physical_apicid = -1U;
55 58
56/* 59/*
57 * Sanity check 60 * The highest APIC ID seen during enumeration.
61 *
62 * This determines the messaging protocol we can use: if all APIC IDs
63 * are in the 0 ... 7 range, then we can use logical addressing which
64 * has some performance advantages (better broadcasting).
65 *
66 * If there's an APIC ID above 8, we use physical addressing.
58 */ 67 */
59#if ((SPURIOUS_APIC_VECTOR & 0x0F) != 0x0F) 68unsigned int max_physical_apicid;
60# error SPURIOUS_APIC_VECTOR definition error 69
61#endif 70/*
71 * Bitmask of physically existing CPUs:
72 */
73physid_mask_t phys_cpu_present_map;
74
75/*
76 * Map cpu index to physical APIC ID
77 */
78DEFINE_EARLY_PER_CPU(u16, x86_cpu_to_apicid, BAD_APICID);
79DEFINE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid, BAD_APICID);
80EXPORT_EARLY_PER_CPU_SYMBOL(x86_cpu_to_apicid);
81EXPORT_EARLY_PER_CPU_SYMBOL(x86_bios_cpu_apicid);
62 82
63#ifdef CONFIG_X86_32 83#ifdef CONFIG_X86_32
64/* 84/*
@@ -457,7 +477,7 @@ static void lapic_timer_setup(enum clock_event_mode mode,
457static void lapic_timer_broadcast(const struct cpumask *mask) 477static void lapic_timer_broadcast(const struct cpumask *mask)
458{ 478{
459#ifdef CONFIG_SMP 479#ifdef CONFIG_SMP
460 send_IPI_mask(mask, LOCAL_TIMER_VECTOR); 480 apic->send_IPI_mask(mask, LOCAL_TIMER_VECTOR);
461#endif 481#endif
462} 482}
463 483
@@ -535,7 +555,8 @@ static void __init lapic_cal_handler(struct clock_event_device *dev)
535 } 555 }
536} 556}
537 557
538static int __init calibrate_by_pmtimer(long deltapm, long *delta) 558static int __init
559calibrate_by_pmtimer(long deltapm, long *delta, long *deltatsc)
539{ 560{
540 const long pm_100ms = PMTMR_TICKS_PER_SEC / 10; 561 const long pm_100ms = PMTMR_TICKS_PER_SEC / 10;
541 const long pm_thresh = pm_100ms / 100; 562 const long pm_thresh = pm_100ms / 100;
@@ -546,7 +567,7 @@ static int __init calibrate_by_pmtimer(long deltapm, long *delta)
546 return -1; 567 return -1;
547#endif 568#endif
548 569
549 apic_printk(APIC_VERBOSE, "... PM timer delta = %ld\n", deltapm); 570 apic_printk(APIC_VERBOSE, "... PM-Timer delta = %ld\n", deltapm);
550 571
551 /* Check, if the PM timer is available */ 572 /* Check, if the PM timer is available */
552 if (!deltapm) 573 if (!deltapm)
@@ -556,19 +577,30 @@ static int __init calibrate_by_pmtimer(long deltapm, long *delta)
556 577
557 if (deltapm > (pm_100ms - pm_thresh) && 578 if (deltapm > (pm_100ms - pm_thresh) &&
558 deltapm < (pm_100ms + pm_thresh)) { 579 deltapm < (pm_100ms + pm_thresh)) {
559 apic_printk(APIC_VERBOSE, "... PM timer result ok\n"); 580 apic_printk(APIC_VERBOSE, "... PM-Timer result ok\n");
560 } else { 581 return 0;
561 res = (((u64)deltapm) * mult) >> 22; 582 }
562 do_div(res, 1000000); 583
563 pr_warning("APIC calibration not consistent " 584 res = (((u64)deltapm) * mult) >> 22;
564 "with PM Timer: %ldms instead of 100ms\n", 585 do_div(res, 1000000);
565 (long)res); 586 pr_warning("APIC calibration not consistent "
566 /* Correct the lapic counter value */ 587 "with PM-Timer: %ldms instead of 100ms\n",(long)res);
567 res = (((u64)(*delta)) * pm_100ms); 588
589 /* Correct the lapic counter value */
590 res = (((u64)(*delta)) * pm_100ms);
591 do_div(res, deltapm);
592 pr_info("APIC delta adjusted to PM-Timer: "
593 "%lu (%ld)\n", (unsigned long)res, *delta);
594 *delta = (long)res;
595
596 /* Correct the tsc counter value */
597 if (cpu_has_tsc) {
598 res = (((u64)(*deltatsc)) * pm_100ms);
568 do_div(res, deltapm); 599 do_div(res, deltapm);
569 pr_info("APIC delta adjusted to PM-Timer: " 600 apic_printk(APIC_VERBOSE, "TSC delta adjusted to "
570 "%lu (%ld)\n", (unsigned long)res, *delta); 601 "PM-Timer: %lu (%ld) \n",
571 *delta = (long)res; 602 (unsigned long)res, *deltatsc);
603 *deltatsc = (long)res;
572 } 604 }
573 605
574 return 0; 606 return 0;
@@ -579,7 +611,7 @@ static int __init calibrate_APIC_clock(void)
579 struct clock_event_device *levt = &__get_cpu_var(lapic_events); 611 struct clock_event_device *levt = &__get_cpu_var(lapic_events);
580 void (*real_handler)(struct clock_event_device *dev); 612 void (*real_handler)(struct clock_event_device *dev);
581 unsigned long deltaj; 613 unsigned long deltaj;
582 long delta; 614 long delta, deltatsc;
583 int pm_referenced = 0; 615 int pm_referenced = 0;
584 616
585 local_irq_disable(); 617 local_irq_disable();
@@ -609,9 +641,11 @@ static int __init calibrate_APIC_clock(void)
609 delta = lapic_cal_t1 - lapic_cal_t2; 641 delta = lapic_cal_t1 - lapic_cal_t2;
610 apic_printk(APIC_VERBOSE, "... lapic delta = %ld\n", delta); 642 apic_printk(APIC_VERBOSE, "... lapic delta = %ld\n", delta);
611 643
644 deltatsc = (long)(lapic_cal_tsc2 - lapic_cal_tsc1);
645
612 /* we trust the PM based calibration if possible */ 646 /* we trust the PM based calibration if possible */
613 pm_referenced = !calibrate_by_pmtimer(lapic_cal_pm2 - lapic_cal_pm1, 647 pm_referenced = !calibrate_by_pmtimer(lapic_cal_pm2 - lapic_cal_pm1,
614 &delta); 648 &delta, &deltatsc);
615 649
616 /* Calculate the scaled math multiplication factor */ 650 /* Calculate the scaled math multiplication factor */
617 lapic_clockevent.mult = div_sc(delta, TICK_NSEC * LAPIC_CAL_LOOPS, 651 lapic_clockevent.mult = div_sc(delta, TICK_NSEC * LAPIC_CAL_LOOPS,
@@ -629,11 +663,10 @@ static int __init calibrate_APIC_clock(void)
629 calibration_result); 663 calibration_result);
630 664
631 if (cpu_has_tsc) { 665 if (cpu_has_tsc) {
632 delta = (long)(lapic_cal_tsc2 - lapic_cal_tsc1);
633 apic_printk(APIC_VERBOSE, "..... CPU clock speed is " 666 apic_printk(APIC_VERBOSE, "..... CPU clock speed is "
634 "%ld.%04ld MHz.\n", 667 "%ld.%04ld MHz.\n",
635 (delta / LAPIC_CAL_LOOPS) / (1000000 / HZ), 668 (deltatsc / LAPIC_CAL_LOOPS) / (1000000 / HZ),
636 (delta / LAPIC_CAL_LOOPS) % (1000000 / HZ)); 669 (deltatsc / LAPIC_CAL_LOOPS) % (1000000 / HZ));
637 } 670 }
638 671
639 apic_printk(APIC_VERBOSE, "..... host bus clock speed is " 672 apic_printk(APIC_VERBOSE, "..... host bus clock speed is "
@@ -991,11 +1024,11 @@ int __init verify_local_APIC(void)
991 */ 1024 */
992 reg0 = apic_read(APIC_ID); 1025 reg0 = apic_read(APIC_ID);
993 apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg0); 1026 apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg0);
994 apic_write(APIC_ID, reg0 ^ APIC_ID_MASK); 1027 apic_write(APIC_ID, reg0 ^ apic->apic_id_mask);
995 reg1 = apic_read(APIC_ID); 1028 reg1 = apic_read(APIC_ID);
996 apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg1); 1029 apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg1);
997 apic_write(APIC_ID, reg0); 1030 apic_write(APIC_ID, reg0);
998 if (reg1 != (reg0 ^ APIC_ID_MASK)) 1031 if (reg1 != (reg0 ^ apic->apic_id_mask))
999 return 0; 1032 return 0;
1000 1033
1001 /* 1034 /*
@@ -1089,7 +1122,7 @@ static void __cpuinit lapic_setup_esr(void)
1089 return; 1122 return;
1090 } 1123 }
1091 1124
1092 if (esr_disable) { 1125 if (apic->disable_esr) {
1093 /* 1126 /*
1094 * Something untraceable is creating bad interrupts on 1127 * Something untraceable is creating bad interrupts on
1095 * secondary quads ... for the moment, just leave the 1128 * secondary quads ... for the moment, just leave the
@@ -1130,9 +1163,14 @@ void __cpuinit setup_local_APIC(void)
1130 unsigned int value; 1163 unsigned int value;
1131 int i, j; 1164 int i, j;
1132 1165
1166 if (disable_apic) {
1167 arch_disable_smp_support();
1168 return;
1169 }
1170
1133#ifdef CONFIG_X86_32 1171#ifdef CONFIG_X86_32
1134 /* Pound the ESR really hard over the head with a big hammer - mbligh */ 1172 /* Pound the ESR really hard over the head with a big hammer - mbligh */
1135 if (lapic_is_integrated() && esr_disable) { 1173 if (lapic_is_integrated() && apic->disable_esr) {
1136 apic_write(APIC_ESR, 0); 1174 apic_write(APIC_ESR, 0);
1137 apic_write(APIC_ESR, 0); 1175 apic_write(APIC_ESR, 0);
1138 apic_write(APIC_ESR, 0); 1176 apic_write(APIC_ESR, 0);
@@ -1146,7 +1184,7 @@ void __cpuinit setup_local_APIC(void)
1146 * Double-check whether this APIC is really registered. 1184 * Double-check whether this APIC is really registered.
1147 * This is meaningless in clustered apic mode, so we skip it. 1185 * This is meaningless in clustered apic mode, so we skip it.
1148 */ 1186 */
1149 if (!apic_id_registered()) 1187 if (!apic->apic_id_registered())
1150 BUG(); 1188 BUG();
1151 1189
1152 /* 1190 /*
@@ -1154,7 +1192,7 @@ void __cpuinit setup_local_APIC(void)
1154 * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel 1192 * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel
1155 * document number 292116). So here it goes... 1193 * document number 292116). So here it goes...
1156 */ 1194 */
1157 init_apic_ldr(); 1195 apic->init_apic_ldr();
1158 1196
1159 /* 1197 /*
1160 * Set Task Priority to 'accept all'. We never change this 1198 * Set Task Priority to 'accept all'. We never change this
@@ -1570,11 +1608,11 @@ int apic_version[MAX_APICS];
1570 1608
1571int __init APIC_init_uniprocessor(void) 1609int __init APIC_init_uniprocessor(void)
1572{ 1610{
1573#ifdef CONFIG_X86_64
1574 if (disable_apic) { 1611 if (disable_apic) {
1575 pr_info("Apic disabled\n"); 1612 pr_info("Apic disabled\n");
1576 return -1; 1613 return -1;
1577 } 1614 }
1615#ifdef CONFIG_X86_64
1578 if (!cpu_has_apic) { 1616 if (!cpu_has_apic) {
1579 disable_apic = 1; 1617 disable_apic = 1;
1580 pr_info("Apic disabled by BIOS\n"); 1618 pr_info("Apic disabled by BIOS\n");
@@ -1600,7 +1638,7 @@ int __init APIC_init_uniprocessor(void)
1600 enable_IR_x2apic(); 1638 enable_IR_x2apic();
1601#endif 1639#endif
1602#ifdef CONFIG_X86_64 1640#ifdef CONFIG_X86_64
1603 setup_apic_routing(); 1641 default_setup_apic_routing();
1604#endif 1642#endif
1605 1643
1606 verify_local_APIC(); 1644 verify_local_APIC();
@@ -1621,35 +1659,31 @@ int __init APIC_init_uniprocessor(void)
1621 physid_set_mask_of_physid(boot_cpu_physical_apicid, &phys_cpu_present_map); 1659 physid_set_mask_of_physid(boot_cpu_physical_apicid, &phys_cpu_present_map);
1622 setup_local_APIC(); 1660 setup_local_APIC();
1623 1661
1624#ifdef CONFIG_X86_64 1662#ifdef CONFIG_X86_IO_APIC
1625 /* 1663 /*
1626 * Now enable IO-APICs, actually call clear_IO_APIC 1664 * Now enable IO-APICs, actually call clear_IO_APIC
1627 * We need clear_IO_APIC before enabling vector on BP 1665 * We need clear_IO_APIC before enabling error vector
1628 */ 1666 */
1629 if (!skip_ioapic_setup && nr_ioapics) 1667 if (!skip_ioapic_setup && nr_ioapics)
1630 enable_IO_APIC(); 1668 enable_IO_APIC();
1631#endif 1669#endif
1632 1670
1633#ifdef CONFIG_X86_IO_APIC
1634 if (!smp_found_config || skip_ioapic_setup || !nr_ioapics)
1635#endif
1636 localise_nmi_watchdog();
1637 end_local_APIC_setup(); 1671 end_local_APIC_setup();
1638 1672
1639#ifdef CONFIG_X86_IO_APIC 1673#ifdef CONFIG_X86_IO_APIC
1640 if (smp_found_config && !skip_ioapic_setup && nr_ioapics) 1674 if (smp_found_config && !skip_ioapic_setup && nr_ioapics)
1641 setup_IO_APIC(); 1675 setup_IO_APIC();
1642# ifdef CONFIG_X86_64 1676 else {
1643 else
1644 nr_ioapics = 0; 1677 nr_ioapics = 0;
1645# endif 1678 localise_nmi_watchdog();
1679 }
1680#else
1681 localise_nmi_watchdog();
1646#endif 1682#endif
1647 1683
1684 setup_boot_clock();
1648#ifdef CONFIG_X86_64 1685#ifdef CONFIG_X86_64
1649 setup_boot_APIC_clock();
1650 check_nmi_watchdog(); 1686 check_nmi_watchdog();
1651#else
1652 setup_boot_clock();
1653#endif 1687#endif
1654 1688
1655 return 0; 1689 return 0;
@@ -1738,7 +1772,8 @@ void __init connect_bsp_APIC(void)
1738 outb(0x01, 0x23); 1772 outb(0x01, 0x23);
1739 } 1773 }
1740#endif 1774#endif
1741 enable_apic_mode(); 1775 if (apic->enable_apic_mode)
1776 apic->enable_apic_mode();
1742} 1777}
1743 1778
1744/** 1779/**
@@ -1876,29 +1911,39 @@ void __cpuinit generic_processor_info(int apicid, int version)
1876 } 1911 }
1877#endif 1912#endif
1878 1913
1879#if defined(CONFIG_X86_SMP) || defined(CONFIG_X86_64) 1914#if defined(CONFIG_SMP) || defined(CONFIG_X86_64)
1880 /* are we being called early in kernel startup? */ 1915 early_per_cpu(x86_cpu_to_apicid, cpu) = apicid;
1881 if (early_per_cpu_ptr(x86_cpu_to_apicid)) { 1916 early_per_cpu(x86_bios_cpu_apicid, cpu) = apicid;
1882 u16 *cpu_to_apicid = early_per_cpu_ptr(x86_cpu_to_apicid);
1883 u16 *bios_cpu_apicid = early_per_cpu_ptr(x86_bios_cpu_apicid);
1884
1885 cpu_to_apicid[cpu] = apicid;
1886 bios_cpu_apicid[cpu] = apicid;
1887 } else {
1888 per_cpu(x86_cpu_to_apicid, cpu) = apicid;
1889 per_cpu(x86_bios_cpu_apicid, cpu) = apicid;
1890 }
1891#endif 1917#endif
1892 1918
1893 set_cpu_possible(cpu, true); 1919 set_cpu_possible(cpu, true);
1894 set_cpu_present(cpu, true); 1920 set_cpu_present(cpu, true);
1895} 1921}
1896 1922
1897#ifdef CONFIG_X86_64
1898int hard_smp_processor_id(void) 1923int hard_smp_processor_id(void)
1899{ 1924{
1900 return read_apic_id(); 1925 return read_apic_id();
1901} 1926}
1927
1928void default_init_apic_ldr(void)
1929{
1930 unsigned long val;
1931
1932 apic_write(APIC_DFR, APIC_DFR_VALUE);
1933 val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
1934 val |= SET_APIC_LOGICAL_ID(1UL << smp_processor_id());
1935 apic_write(APIC_LDR, val);
1936}
1937
1938#ifdef CONFIG_X86_32
1939int default_apicid_to_node(int logical_apicid)
1940{
1941#ifdef CONFIG_SMP
1942 return apicid_2_node[hard_smp_processor_id()];
1943#else
1944 return 0;
1945#endif
1946}
1902#endif 1947#endif
1903 1948
1904/* 1949/*