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.c177
1 files changed, 114 insertions, 63 deletions
diff --git a/arch/x86/kernel/apic.c b/arch/x86/kernel/apic.c
index abfa0b641aea..c9aed4510585 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,52 +14,72 @@
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/perf_counter.h> 37#include <asm/perf_counter.h>
39#include <asm/atomic.h>
40#include <asm/mtrr.h>
41#include <asm/mpspec.h>
42#include <asm/desc.h>
43#include <asm/arch_hooks.h> 38#include <asm/arch_hooks.h>
44#include <asm/hpet.h>
45#include <asm/pgalloc.h> 39#include <asm/pgalloc.h>
40#include <asm/genapic.h>
41#include <asm/atomic.h>
42#include <asm/mpspec.h>
46#include <asm/i8253.h> 43#include <asm/i8253.h>
47#include <asm/idle.h> 44#include <asm/i8259.h>
48#include <asm/proto.h> 45#include <asm/proto.h>
49#include <asm/apic.h> 46#include <asm/apic.h>
50#include <asm/i8259.h> 47#include <asm/desc.h>
48#include <asm/hpet.h>
49#include <asm/idle.h>
50#include <asm/mtrr.h>
51#include <asm/smp.h> 51#include <asm/smp.h>
52 52
53#include <mach_apic.h> 53unsigned int num_processors;
54#include <mach_apicdef.h> 54
55#include <mach_ipi.h> 55unsigned disabled_cpus __cpuinitdata;
56
57/* Processor that is doing the boot up */
58unsigned int boot_cpu_physical_apicid = -1U;
56 59
57/* 60/*
58 * Sanity check 61 * The highest APIC ID seen during enumeration.
62 *
63 * This determines the messaging protocol we can use: if all APIC IDs
64 * are in the 0 ... 7 range, then we can use logical addressing which
65 * has some performance advantages (better broadcasting).
66 *
67 * If there's an APIC ID above 8, we use physical addressing.
59 */ 68 */
60#if ((SPURIOUS_APIC_VECTOR & 0x0F) != 0x0F) 69unsigned int max_physical_apicid;
61# error SPURIOUS_APIC_VECTOR definition error 70
62#endif 71/*
72 * Bitmask of physically existing CPUs:
73 */
74physid_mask_t phys_cpu_present_map;
75
76/*
77 * Map cpu index to physical APIC ID
78 */
79DEFINE_EARLY_PER_CPU(u16, x86_cpu_to_apicid, BAD_APICID);
80DEFINE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid, BAD_APICID);
81EXPORT_EARLY_PER_CPU_SYMBOL(x86_cpu_to_apicid);
82EXPORT_EARLY_PER_CPU_SYMBOL(x86_bios_cpu_apicid);
63 83
64#ifdef CONFIG_X86_32 84#ifdef CONFIG_X86_32
65/* 85/*
@@ -458,7 +478,7 @@ static void lapic_timer_setup(enum clock_event_mode mode,
458static void lapic_timer_broadcast(const struct cpumask *mask) 478static void lapic_timer_broadcast(const struct cpumask *mask)
459{ 479{
460#ifdef CONFIG_SMP 480#ifdef CONFIG_SMP
461 send_IPI_mask(mask, LOCAL_TIMER_VECTOR); 481 apic->send_IPI_mask(mask, LOCAL_TIMER_VECTOR);
462#endif 482#endif
463} 483}
464 484
@@ -536,7 +556,8 @@ static void __init lapic_cal_handler(struct clock_event_device *dev)
536 } 556 }
537} 557}
538 558
539static int __init calibrate_by_pmtimer(long deltapm, long *delta) 559static int __init
560calibrate_by_pmtimer(long deltapm, long *delta, long *deltatsc)
540{ 561{
541 const long pm_100ms = PMTMR_TICKS_PER_SEC / 10; 562 const long pm_100ms = PMTMR_TICKS_PER_SEC / 10;
542 const long pm_thresh = pm_100ms / 100; 563 const long pm_thresh = pm_100ms / 100;
@@ -547,7 +568,7 @@ static int __init calibrate_by_pmtimer(long deltapm, long *delta)
547 return -1; 568 return -1;
548#endif 569#endif
549 570
550 apic_printk(APIC_VERBOSE, "... PM timer delta = %ld\n", deltapm); 571 apic_printk(APIC_VERBOSE, "... PM-Timer delta = %ld\n", deltapm);
551 572
552 /* Check, if the PM timer is available */ 573 /* Check, if the PM timer is available */
553 if (!deltapm) 574 if (!deltapm)
@@ -557,19 +578,30 @@ static int __init calibrate_by_pmtimer(long deltapm, long *delta)
557 578
558 if (deltapm > (pm_100ms - pm_thresh) && 579 if (deltapm > (pm_100ms - pm_thresh) &&
559 deltapm < (pm_100ms + pm_thresh)) { 580 deltapm < (pm_100ms + pm_thresh)) {
560 apic_printk(APIC_VERBOSE, "... PM timer result ok\n"); 581 apic_printk(APIC_VERBOSE, "... PM-Timer result ok\n");
561 } else { 582 return 0;
562 res = (((u64)deltapm) * mult) >> 22; 583 }
563 do_div(res, 1000000); 584
564 pr_warning("APIC calibration not consistent " 585 res = (((u64)deltapm) * mult) >> 22;
565 "with PM Timer: %ldms instead of 100ms\n", 586 do_div(res, 1000000);
566 (long)res); 587 pr_warning("APIC calibration not consistent "
567 /* Correct the lapic counter value */ 588 "with PM-Timer: %ldms instead of 100ms\n",(long)res);
568 res = (((u64)(*delta)) * pm_100ms); 589
590 /* Correct the lapic counter value */
591 res = (((u64)(*delta)) * pm_100ms);
592 do_div(res, deltapm);
593 pr_info("APIC delta adjusted to PM-Timer: "
594 "%lu (%ld)\n", (unsigned long)res, *delta);
595 *delta = (long)res;
596
597 /* Correct the tsc counter value */
598 if (cpu_has_tsc) {
599 res = (((u64)(*deltatsc)) * pm_100ms);
569 do_div(res, deltapm); 600 do_div(res, deltapm);
570 pr_info("APIC delta adjusted to PM-Timer: " 601 apic_printk(APIC_VERBOSE, "TSC delta adjusted to "
571 "%lu (%ld)\n", (unsigned long)res, *delta); 602 "PM-Timer: %lu (%ld) \n",
572 *delta = (long)res; 603 (unsigned long)res, *deltatsc);
604 *deltatsc = (long)res;
573 } 605 }
574 606
575 return 0; 607 return 0;
@@ -580,7 +612,7 @@ static int __init calibrate_APIC_clock(void)
580 struct clock_event_device *levt = &__get_cpu_var(lapic_events); 612 struct clock_event_device *levt = &__get_cpu_var(lapic_events);
581 void (*real_handler)(struct clock_event_device *dev); 613 void (*real_handler)(struct clock_event_device *dev);
582 unsigned long deltaj; 614 unsigned long deltaj;
583 long delta; 615 long delta, deltatsc;
584 int pm_referenced = 0; 616 int pm_referenced = 0;
585 617
586 local_irq_disable(); 618 local_irq_disable();
@@ -610,9 +642,11 @@ static int __init calibrate_APIC_clock(void)
610 delta = lapic_cal_t1 - lapic_cal_t2; 642 delta = lapic_cal_t1 - lapic_cal_t2;
611 apic_printk(APIC_VERBOSE, "... lapic delta = %ld\n", delta); 643 apic_printk(APIC_VERBOSE, "... lapic delta = %ld\n", delta);
612 644
645 deltatsc = (long)(lapic_cal_tsc2 - lapic_cal_tsc1);
646
613 /* we trust the PM based calibration if possible */ 647 /* we trust the PM based calibration if possible */
614 pm_referenced = !calibrate_by_pmtimer(lapic_cal_pm2 - lapic_cal_pm1, 648 pm_referenced = !calibrate_by_pmtimer(lapic_cal_pm2 - lapic_cal_pm1,
615 &delta); 649 &delta, &deltatsc);
616 650
617 /* Calculate the scaled math multiplication factor */ 651 /* Calculate the scaled math multiplication factor */
618 lapic_clockevent.mult = div_sc(delta, TICK_NSEC * LAPIC_CAL_LOOPS, 652 lapic_clockevent.mult = div_sc(delta, TICK_NSEC * LAPIC_CAL_LOOPS,
@@ -630,11 +664,10 @@ static int __init calibrate_APIC_clock(void)
630 calibration_result); 664 calibration_result);
631 665
632 if (cpu_has_tsc) { 666 if (cpu_has_tsc) {
633 delta = (long)(lapic_cal_tsc2 - lapic_cal_tsc1);
634 apic_printk(APIC_VERBOSE, "..... CPU clock speed is " 667 apic_printk(APIC_VERBOSE, "..... CPU clock speed is "
635 "%ld.%04ld MHz.\n", 668 "%ld.%04ld MHz.\n",
636 (delta / LAPIC_CAL_LOOPS) / (1000000 / HZ), 669 (deltatsc / LAPIC_CAL_LOOPS) / (1000000 / HZ),
637 (delta / LAPIC_CAL_LOOPS) % (1000000 / HZ)); 670 (deltatsc / LAPIC_CAL_LOOPS) % (1000000 / HZ));
638 } 671 }
639 672
640 apic_printk(APIC_VERBOSE, "..... host bus clock speed is " 673 apic_printk(APIC_VERBOSE, "..... host bus clock speed is "
@@ -994,11 +1027,11 @@ int __init verify_local_APIC(void)
994 */ 1027 */
995 reg0 = apic_read(APIC_ID); 1028 reg0 = apic_read(APIC_ID);
996 apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg0); 1029 apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg0);
997 apic_write(APIC_ID, reg0 ^ APIC_ID_MASK); 1030 apic_write(APIC_ID, reg0 ^ apic->apic_id_mask);
998 reg1 = apic_read(APIC_ID); 1031 reg1 = apic_read(APIC_ID);
999 apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg1); 1032 apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg1);
1000 apic_write(APIC_ID, reg0); 1033 apic_write(APIC_ID, reg0);
1001 if (reg1 != (reg0 ^ APIC_ID_MASK)) 1034 if (reg1 != (reg0 ^ apic->apic_id_mask))
1002 return 0; 1035 return 0;
1003 1036
1004 /* 1037 /*
@@ -1092,7 +1125,7 @@ static void __cpuinit lapic_setup_esr(void)
1092 return; 1125 return;
1093 } 1126 }
1094 1127
1095 if (esr_disable) { 1128 if (apic->disable_esr) {
1096 /* 1129 /*
1097 * Something untraceable is creating bad interrupts on 1130 * Something untraceable is creating bad interrupts on
1098 * secondary quads ... for the moment, just leave the 1131 * secondary quads ... for the moment, just leave the
@@ -1134,15 +1167,13 @@ void __cpuinit setup_local_APIC(void)
1134 int i, j; 1167 int i, j;
1135 1168
1136 if (disable_apic) { 1169 if (disable_apic) {
1137#ifdef CONFIG_X86_IO_APIC 1170 arch_disable_smp_support();
1138 disable_ioapic_setup();
1139#endif
1140 return; 1171 return;
1141 } 1172 }
1142 1173
1143#ifdef CONFIG_X86_32 1174#ifdef CONFIG_X86_32
1144 /* Pound the ESR really hard over the head with a big hammer - mbligh */ 1175 /* Pound the ESR really hard over the head with a big hammer - mbligh */
1145 if (lapic_is_integrated() && esr_disable) { 1176 if (lapic_is_integrated() && apic->disable_esr) {
1146 apic_write(APIC_ESR, 0); 1177 apic_write(APIC_ESR, 0);
1147 apic_write(APIC_ESR, 0); 1178 apic_write(APIC_ESR, 0);
1148 apic_write(APIC_ESR, 0); 1179 apic_write(APIC_ESR, 0);
@@ -1157,7 +1188,7 @@ void __cpuinit setup_local_APIC(void)
1157 * Double-check whether this APIC is really registered. 1188 * Double-check whether this APIC is really registered.
1158 * This is meaningless in clustered apic mode, so we skip it. 1189 * This is meaningless in clustered apic mode, so we skip it.
1159 */ 1190 */
1160 if (!apic_id_registered()) 1191 if (!apic->apic_id_registered())
1161 BUG(); 1192 BUG();
1162 1193
1163 /* 1194 /*
@@ -1165,7 +1196,7 @@ void __cpuinit setup_local_APIC(void)
1165 * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel 1196 * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel
1166 * document number 292116). So here it goes... 1197 * document number 292116). So here it goes...
1167 */ 1198 */
1168 init_apic_ldr(); 1199 apic->init_apic_ldr();
1169 1200
1170 /* 1201 /*
1171 * Set Task Priority to 'accept all'. We never change this 1202 * Set Task Priority to 'accept all'. We never change this
@@ -1611,7 +1642,7 @@ int __init APIC_init_uniprocessor(void)
1611 enable_IR_x2apic(); 1642 enable_IR_x2apic();
1612#endif 1643#endif
1613#ifdef CONFIG_X86_64 1644#ifdef CONFIG_X86_64
1614 setup_apic_routing(); 1645 default_setup_apic_routing();
1615#endif 1646#endif
1616 1647
1617 verify_local_APIC(); 1648 verify_local_APIC();
@@ -1749,7 +1780,8 @@ void __init connect_bsp_APIC(void)
1749 outb(0x01, 0x23); 1780 outb(0x01, 0x23);
1750 } 1781 }
1751#endif 1782#endif
1752 enable_apic_mode(); 1783 if (apic->enable_apic_mode)
1784 apic->enable_apic_mode();
1753} 1785}
1754 1786
1755/** 1787/**
@@ -1887,7 +1919,7 @@ void __cpuinit generic_processor_info(int apicid, int version)
1887 } 1919 }
1888#endif 1920#endif
1889 1921
1890#if defined(CONFIG_X86_SMP) || defined(CONFIG_X86_64) 1922#if defined(CONFIG_SMP) || defined(CONFIG_X86_64)
1891 early_per_cpu(x86_cpu_to_apicid, cpu) = apicid; 1923 early_per_cpu(x86_cpu_to_apicid, cpu) = apicid;
1892 early_per_cpu(x86_bios_cpu_apicid, cpu) = apicid; 1924 early_per_cpu(x86_bios_cpu_apicid, cpu) = apicid;
1893#endif 1925#endif
@@ -1896,11 +1928,30 @@ void __cpuinit generic_processor_info(int apicid, int version)
1896 set_cpu_present(cpu, true); 1928 set_cpu_present(cpu, true);
1897} 1929}
1898 1930
1899#ifdef CONFIG_X86_64
1900int hard_smp_processor_id(void) 1931int hard_smp_processor_id(void)
1901{ 1932{
1902 return read_apic_id(); 1933 return read_apic_id();
1903} 1934}
1935
1936void default_init_apic_ldr(void)
1937{
1938 unsigned long val;
1939
1940 apic_write(APIC_DFR, APIC_DFR_VALUE);
1941 val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
1942 val |= SET_APIC_LOGICAL_ID(1UL << smp_processor_id());
1943 apic_write(APIC_LDR, val);
1944}
1945
1946#ifdef CONFIG_X86_32
1947int default_apicid_to_node(int logical_apicid)
1948{
1949#ifdef CONFIG_SMP
1950 return apicid_2_node[hard_smp_processor_id()];
1951#else
1952 return 0;
1953#endif
1954}
1904#endif 1955#endif
1905 1956
1906/* 1957/*