aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/apic_64.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/apic_64.c')
-rw-r--r--arch/x86/kernel/apic_64.c251
1 files changed, 237 insertions, 14 deletions
diff --git a/arch/x86/kernel/apic_64.c b/arch/x86/kernel/apic_64.c
index 446c062e831c..1a6011855af3 100644
--- a/arch/x86/kernel/apic_64.c
+++ b/arch/x86/kernel/apic_64.c
@@ -27,6 +27,7 @@
27#include <linux/clockchips.h> 27#include <linux/clockchips.h>
28#include <linux/acpi_pmtmr.h> 28#include <linux/acpi_pmtmr.h>
29#include <linux/module.h> 29#include <linux/module.h>
30#include <linux/dmar.h>
30 31
31#include <asm/atomic.h> 32#include <asm/atomic.h>
32#include <asm/smp.h> 33#include <asm/smp.h>
@@ -39,6 +40,7 @@
39#include <asm/proto.h> 40#include <asm/proto.h>
40#include <asm/timex.h> 41#include <asm/timex.h>
41#include <asm/apic.h> 42#include <asm/apic.h>
43#include <asm/i8259.h>
42 44
43#include <mach_ipi.h> 45#include <mach_ipi.h>
44#include <mach_apic.h> 46#include <mach_apic.h>
@@ -46,6 +48,11 @@
46static int disable_apic_timer __cpuinitdata; 48static int disable_apic_timer __cpuinitdata;
47static int apic_calibrate_pmtmr __initdata; 49static int apic_calibrate_pmtmr __initdata;
48int disable_apic; 50int disable_apic;
51int disable_x2apic;
52int x2apic;
53
54/* x2apic enabled before OS handover */
55int x2apic_preenabled;
49 56
50/* Local APIC timer works in C2 */ 57/* Local APIC timer works in C2 */
51int local_apic_timer_c2_ok; 58int local_apic_timer_c2_ok;
@@ -118,13 +125,13 @@ static int modern_apic(void)
118 return lapic_get_version() >= 0x14; 125 return lapic_get_version() >= 0x14;
119} 126}
120 127
121void apic_wait_icr_idle(void) 128void xapic_wait_icr_idle(void)
122{ 129{
123 while (apic_read(APIC_ICR) & APIC_ICR_BUSY) 130 while (apic_read(APIC_ICR) & APIC_ICR_BUSY)
124 cpu_relax(); 131 cpu_relax();
125} 132}
126 133
127u32 safe_apic_wait_icr_idle(void) 134u32 safe_xapic_wait_icr_idle(void)
128{ 135{
129 u32 send_status; 136 u32 send_status;
130 int timeout; 137 int timeout;
@@ -140,6 +147,69 @@ u32 safe_apic_wait_icr_idle(void)
140 return send_status; 147 return send_status;
141} 148}
142 149
150void xapic_icr_write(u32 low, u32 id)
151{
152 apic_write(APIC_ICR2, id << 24);
153 apic_write(APIC_ICR, low);
154}
155
156u64 xapic_icr_read(void)
157{
158 u32 icr1, icr2;
159
160 icr2 = apic_read(APIC_ICR2);
161 icr1 = apic_read(APIC_ICR);
162
163 return (icr1 | ((u64)icr2 << 32));
164}
165
166static struct apic_ops xapic_ops = {
167 .read = native_apic_mem_read,
168 .write = native_apic_mem_write,
169 .icr_read = xapic_icr_read,
170 .icr_write = xapic_icr_write,
171 .wait_icr_idle = xapic_wait_icr_idle,
172 .safe_wait_icr_idle = safe_xapic_wait_icr_idle,
173};
174
175struct apic_ops __read_mostly *apic_ops = &xapic_ops;
176
177EXPORT_SYMBOL_GPL(apic_ops);
178
179static void x2apic_wait_icr_idle(void)
180{
181 /* no need to wait for icr idle in x2apic */
182 return;
183}
184
185static u32 safe_x2apic_wait_icr_idle(void)
186{
187 /* no need to wait for icr idle in x2apic */
188 return 0;
189}
190
191void x2apic_icr_write(u32 low, u32 id)
192{
193 wrmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), ((__u64) id) << 32 | low);
194}
195
196u64 x2apic_icr_read(void)
197{
198 unsigned long val;
199
200 rdmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), val);
201 return val;
202}
203
204static struct apic_ops x2apic_ops = {
205 .read = native_apic_msr_read,
206 .write = native_apic_msr_write,
207 .icr_read = x2apic_icr_read,
208 .icr_write = x2apic_icr_write,
209 .wait_icr_idle = x2apic_wait_icr_idle,
210 .safe_wait_icr_idle = safe_x2apic_wait_icr_idle,
211};
212
143/** 213/**
144 * enable_NMI_through_LVT0 - enable NMI through local vector table 0 214 * enable_NMI_through_LVT0 - enable NMI through local vector table 0
145 */ 215 */
@@ -149,6 +219,11 @@ void __cpuinit enable_NMI_through_LVT0(void)
149 219
150 /* unmask and set to NMI */ 220 /* unmask and set to NMI */
151 v = APIC_DM_NMI; 221 v = APIC_DM_NMI;
222
223 /* Level triggered for 82489DX (32bit mode) */
224 if (!lapic_is_integrated())
225 v |= APIC_LVT_LEVEL_TRIGGER;
226
152 apic_write(APIC_LVT0, v); 227 apic_write(APIC_LVT0, v);
153} 228}
154 229
@@ -157,11 +232,14 @@ void __cpuinit enable_NMI_through_LVT0(void)
157 */ 232 */
158int lapic_get_maxlvt(void) 233int lapic_get_maxlvt(void)
159{ 234{
160 unsigned int v, maxlvt; 235 unsigned int v;
161 236
162 v = apic_read(APIC_LVR); 237 v = apic_read(APIC_LVR);
163 maxlvt = GET_APIC_MAXLVT(v); 238 /*
164 return maxlvt; 239 * - we always have APIC integrated on 64bit mode
240 * - 82489DXs do not report # of LVT entries
241 */
242 return APIC_INTEGRATED(GET_APIC_VERSION(v)) ? GET_APIC_MAXLVT(v) : 2;
165} 243}
166 244
167/* 245/*
@@ -629,10 +707,10 @@ int __init verify_local_APIC(void)
629 /* 707 /*
630 * The ID register is read/write in a real APIC. 708 * The ID register is read/write in a real APIC.
631 */ 709 */
632 reg0 = read_apic_id(); 710 reg0 = apic_read(APIC_ID);
633 apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg0); 711 apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg0);
634 apic_write(APIC_ID, reg0 ^ APIC_ID_MASK); 712 apic_write(APIC_ID, reg0 ^ APIC_ID_MASK);
635 reg1 = read_apic_id(); 713 reg1 = apic_read(APIC_ID);
636 apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg1); 714 apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg1);
637 apic_write(APIC_ID, reg0); 715 apic_write(APIC_ID, reg0);
638 if (reg1 != (reg0 ^ APIC_ID_MASK)) 716 if (reg1 != (reg0 ^ APIC_ID_MASK))
@@ -833,6 +911,125 @@ void __cpuinit end_local_APIC_setup(void)
833 apic_pm_activate(); 911 apic_pm_activate();
834} 912}
835 913
914void check_x2apic(void)
915{
916 int msr, msr2;
917
918 rdmsr(MSR_IA32_APICBASE, msr, msr2);
919
920 if (msr & X2APIC_ENABLE) {
921 printk("x2apic enabled by BIOS, switching to x2apic ops\n");
922 x2apic_preenabled = x2apic = 1;
923 apic_ops = &x2apic_ops;
924 }
925}
926
927void enable_x2apic(void)
928{
929 int msr, msr2;
930
931 rdmsr(MSR_IA32_APICBASE, msr, msr2);
932 if (!(msr & X2APIC_ENABLE)) {
933 printk("Enabling x2apic\n");
934 wrmsr(MSR_IA32_APICBASE, msr | X2APIC_ENABLE, 0);
935 }
936}
937
938void enable_IR_x2apic(void)
939{
940#ifdef CONFIG_INTR_REMAP
941 int ret;
942 unsigned long flags;
943
944 if (!cpu_has_x2apic)
945 return;
946
947 if (!x2apic_preenabled && disable_x2apic) {
948 printk(KERN_INFO
949 "Skipped enabling x2apic and Interrupt-remapping "
950 "because of nox2apic\n");
951 return;
952 }
953
954 if (x2apic_preenabled && disable_x2apic)
955 panic("Bios already enabled x2apic, can't enforce nox2apic");
956
957 if (!x2apic_preenabled && skip_ioapic_setup) {
958 printk(KERN_INFO
959 "Skipped enabling x2apic and Interrupt-remapping "
960 "because of skipping io-apic setup\n");
961 return;
962 }
963
964 ret = dmar_table_init();
965 if (ret) {
966 printk(KERN_INFO
967 "dmar_table_init() failed with %d:\n", ret);
968
969 if (x2apic_preenabled)
970 panic("x2apic enabled by bios. But IR enabling failed");
971 else
972 printk(KERN_INFO
973 "Not enabling x2apic,Intr-remapping\n");
974 return;
975 }
976
977 local_irq_save(flags);
978 mask_8259A();
979 save_mask_IO_APIC_setup();
980
981 ret = enable_intr_remapping(1);
982
983 if (ret && x2apic_preenabled) {
984 local_irq_restore(flags);
985 panic("x2apic enabled by bios. But IR enabling failed");
986 }
987
988 if (ret)
989 goto end;
990
991 if (!x2apic) {
992 x2apic = 1;
993 apic_ops = &x2apic_ops;
994 enable_x2apic();
995 }
996end:
997 if (ret)
998 /*
999 * IR enabling failed
1000 */
1001 restore_IO_APIC_setup();
1002 else
1003 reinit_intr_remapped_IO_APIC(x2apic_preenabled);
1004
1005 unmask_8259A();
1006 local_irq_restore(flags);
1007
1008 if (!ret) {
1009 if (!x2apic_preenabled)
1010 printk(KERN_INFO
1011 "Enabled x2apic and interrupt-remapping\n");
1012 else
1013 printk(KERN_INFO
1014 "Enabled Interrupt-remapping\n");
1015 } else
1016 printk(KERN_ERR
1017 "Failed to enable Interrupt-remapping and x2apic\n");
1018#else
1019 if (!cpu_has_x2apic)
1020 return;
1021
1022 if (x2apic_preenabled)
1023 panic("x2apic enabled prior OS handover,"
1024 " enable CONFIG_INTR_REMAP");
1025
1026 printk(KERN_INFO "Enable CONFIG_INTR_REMAP for enabling intr-remapping "
1027 " and x2apic\n");
1028#endif
1029
1030 return;
1031}
1032
836/* 1033/*
837 * Detect and enable local APICs on non-SMP boards. 1034 * Detect and enable local APICs on non-SMP boards.
838 * Original code written by Keir Fraser. 1035 * Original code written by Keir Fraser.
@@ -872,7 +1069,7 @@ void __init early_init_lapic_mapping(void)
872 * Fetch the APIC ID of the BSP in case we have a 1069 * Fetch the APIC ID of the BSP in case we have a
873 * default configuration (or the MP table is broken). 1070 * default configuration (or the MP table is broken).
874 */ 1071 */
875 boot_cpu_physical_apicid = GET_APIC_ID(read_apic_id()); 1072 boot_cpu_physical_apicid = read_apic_id();
876} 1073}
877 1074
878/** 1075/**
@@ -880,6 +1077,11 @@ void __init early_init_lapic_mapping(void)
880 */ 1077 */
881void __init init_apic_mappings(void) 1078void __init init_apic_mappings(void)
882{ 1079{
1080 if (x2apic) {
1081 boot_cpu_physical_apicid = read_apic_id();
1082 return;
1083 }
1084
883 /* 1085 /*
884 * If no local APIC can be found then set up a fake all 1086 * If no local APIC can be found then set up a fake all
885 * zeroes page to simulate the local APIC and another 1087 * zeroes page to simulate the local APIC and another
@@ -899,7 +1101,7 @@ void __init init_apic_mappings(void)
899 * Fetch the APIC ID of the BSP in case we have a 1101 * Fetch the APIC ID of the BSP in case we have a
900 * default configuration (or the MP table is broken). 1102 * default configuration (or the MP table is broken).
901 */ 1103 */
902 boot_cpu_physical_apicid = GET_APIC_ID(read_apic_id()); 1104 boot_cpu_physical_apicid = read_apic_id();
903} 1105}
904 1106
905/* 1107/*
@@ -918,6 +1120,9 @@ int __init APIC_init_uniprocessor(void)
918 return -1; 1120 return -1;
919 } 1121 }
920 1122
1123 enable_IR_x2apic();
1124 setup_apic_routing();
1125
921 verify_local_APIC(); 1126 verify_local_APIC();
922 1127
923 connect_bsp_APIC(); 1128 connect_bsp_APIC();
@@ -1093,6 +1298,11 @@ void __cpuinit generic_processor_info(int apicid, int version)
1093 cpu_set(cpu, cpu_present_map); 1298 cpu_set(cpu, cpu_present_map);
1094} 1299}
1095 1300
1301int hard_smp_processor_id(void)
1302{
1303 return read_apic_id();
1304}
1305
1096/* 1306/*
1097 * Power management 1307 * Power management
1098 */ 1308 */
@@ -1129,7 +1339,7 @@ static int lapic_suspend(struct sys_device *dev, pm_message_t state)
1129 1339
1130 maxlvt = lapic_get_maxlvt(); 1340 maxlvt = lapic_get_maxlvt();
1131 1341
1132 apic_pm_state.apic_id = read_apic_id(); 1342 apic_pm_state.apic_id = apic_read(APIC_ID);
1133 apic_pm_state.apic_taskpri = apic_read(APIC_TASKPRI); 1343 apic_pm_state.apic_taskpri = apic_read(APIC_TASKPRI);
1134 apic_pm_state.apic_ldr = apic_read(APIC_LDR); 1344 apic_pm_state.apic_ldr = apic_read(APIC_LDR);
1135 apic_pm_state.apic_dfr = apic_read(APIC_DFR); 1345 apic_pm_state.apic_dfr = apic_read(APIC_DFR);
@@ -1164,10 +1374,14 @@ static int lapic_resume(struct sys_device *dev)
1164 maxlvt = lapic_get_maxlvt(); 1374 maxlvt = lapic_get_maxlvt();
1165 1375
1166 local_irq_save(flags); 1376 local_irq_save(flags);
1167 rdmsr(MSR_IA32_APICBASE, l, h); 1377 if (!x2apic) {
1168 l &= ~MSR_IA32_APICBASE_BASE; 1378 rdmsr(MSR_IA32_APICBASE, l, h);
1169 l |= MSR_IA32_APICBASE_ENABLE | mp_lapic_addr; 1379 l &= ~MSR_IA32_APICBASE_BASE;
1170 wrmsr(MSR_IA32_APICBASE, l, h); 1380 l |= MSR_IA32_APICBASE_ENABLE | mp_lapic_addr;
1381 wrmsr(MSR_IA32_APICBASE, l, h);
1382 } else
1383 enable_x2apic();
1384
1171 apic_write(APIC_LVTERR, ERROR_APIC_VECTOR | APIC_LVT_MASKED); 1385 apic_write(APIC_LVTERR, ERROR_APIC_VECTOR | APIC_LVT_MASKED);
1172 apic_write(APIC_ID, apic_pm_state.apic_id); 1386 apic_write(APIC_ID, apic_pm_state.apic_id);
1173 apic_write(APIC_DFR, apic_pm_state.apic_dfr); 1387 apic_write(APIC_DFR, apic_pm_state.apic_dfr);
@@ -1307,6 +1521,15 @@ __cpuinit int apic_is_clustered_box(void)
1307 return (clusters > 2); 1521 return (clusters > 2);
1308} 1522}
1309 1523
1524static __init int setup_nox2apic(char *str)
1525{
1526 disable_x2apic = 1;
1527 clear_cpu_cap(&boot_cpu_data, X86_FEATURE_X2APIC);
1528 return 0;
1529}
1530early_param("nox2apic", setup_nox2apic);
1531
1532
1310/* 1533/*
1311 * APIC command line parameters 1534 * APIC command line parameters
1312 */ 1535 */