aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel
diff options
context:
space:
mode:
authorCyrill Gorcunov <gorcunov@gmail.com>2008-08-24 05:01:43 -0400
committerIngo Molnar <mingo@elte.hu>2008-10-16 10:53:01 -0400
commit89c38c2867ebe37c4c5aee23e7fa1bffb025b171 (patch)
treec0f9fbc1b4cf58e3431b0fb5ab26f3cb9b5c7330 /arch/x86/kernel
parent80e5609cabd7e4321769701a70297f819a15b08d (diff)
x86: apic - unify setup_local_APIC
- remove useless read of APIC_LVR - wrap with preempt_disable/enable - check for integrated APIC just in place v2: fix by Yinghai Lu. fix lapic_is_integrated using let 64-bit too have pic_mode Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com> Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r--arch/x86/kernel/apic_32.c21
-rw-r--r--arch/x86/kernel/apic_64.c51
2 files changed, 62 insertions, 10 deletions
diff --git a/arch/x86/kernel/apic_32.c b/arch/x86/kernel/apic_32.c
index df6ed603e547..f8c1251984e2 100644
--- a/arch/x86/kernel/apic_32.c
+++ b/arch/x86/kernel/apic_32.c
@@ -1033,9 +1033,10 @@ static void __cpuinit lapic_setup_esr(void)
1033 */ 1033 */
1034void __cpuinit setup_local_APIC(void) 1034void __cpuinit setup_local_APIC(void)
1035{ 1035{
1036 unsigned long value, integrated; 1036 unsigned int value;
1037 int i, j; 1037 int i, j;
1038 1038
1039#ifdef CONFIG_X86_32
1039 /* Pound the ESR really hard over the head with a big hammer - mbligh */ 1040 /* Pound the ESR really hard over the head with a big hammer - mbligh */
1040 if (esr_disable) { 1041 if (esr_disable) {
1041 apic_write(APIC_ESR, 0); 1042 apic_write(APIC_ESR, 0);
@@ -1043,14 +1044,16 @@ void __cpuinit setup_local_APIC(void)
1043 apic_write(APIC_ESR, 0); 1044 apic_write(APIC_ESR, 0);
1044 apic_write(APIC_ESR, 0); 1045 apic_write(APIC_ESR, 0);
1045 } 1046 }
1047#endif
1046 1048
1047 integrated = lapic_is_integrated(); 1049 preempt_disable();
1048 1050
1049 /* 1051 /*
1050 * Double-check whether this APIC is really registered. 1052 * Double-check whether this APIC is really registered.
1053 * This is meaningless in clustered apic mode, so we skip it.
1051 */ 1054 */
1052 if (!apic_id_registered()) 1055 if (!apic_id_registered())
1053 WARN_ON_ONCE(1); 1056 BUG();
1054 1057
1055 /* 1058 /*
1056 * Intel recommends to set DFR, LDR and TPR before enabling 1059 * Intel recommends to set DFR, LDR and TPR before enabling
@@ -1096,6 +1099,7 @@ void __cpuinit setup_local_APIC(void)
1096 */ 1099 */
1097 value |= APIC_SPIV_APIC_ENABLED; 1100 value |= APIC_SPIV_APIC_ENABLED;
1098 1101
1102#ifdef CONFIG_X86_32
1099 /* 1103 /*
1100 * Some unknown Intel IO/APIC (or APIC) errata is biting us with 1104 * Some unknown Intel IO/APIC (or APIC) errata is biting us with
1101 * certain networking cards. If high frequency interrupts are 1105 * certain networking cards. If high frequency interrupts are
@@ -1116,8 +1120,13 @@ void __cpuinit setup_local_APIC(void)
1116 * See also the comment in end_level_ioapic_irq(). --macro 1120 * See also the comment in end_level_ioapic_irq(). --macro
1117 */ 1121 */
1118 1122
1119 /* Enable focus processor (bit==0) */ 1123 /*
1124 * - enable focus processor (bit==0)
1125 * - 64bit mode always use processor focus
1126 * so no need to set it
1127 */
1120 value &= ~APIC_SPIV_FOCUS_DISABLED; 1128 value &= ~APIC_SPIV_FOCUS_DISABLED;
1129#endif
1121 1130
1122 /* 1131 /*
1123 * Set spurious IRQ vector 1132 * Set spurious IRQ vector
@@ -1154,9 +1163,11 @@ void __cpuinit setup_local_APIC(void)
1154 value = APIC_DM_NMI; 1163 value = APIC_DM_NMI;
1155 else 1164 else
1156 value = APIC_DM_NMI | APIC_LVT_MASKED; 1165 value = APIC_DM_NMI | APIC_LVT_MASKED;
1157 if (!integrated) /* 82489DX */ 1166 if (!lapic_is_integrated()) /* 82489DX */
1158 value |= APIC_LVT_LEVEL_TRIGGER; 1167 value |= APIC_LVT_LEVEL_TRIGGER;
1159 apic_write(APIC_LVT1, value); 1168 apic_write(APIC_LVT1, value);
1169
1170 preempt_enable();
1160} 1171}
1161 1172
1162void __cpuinit end_local_APIC_setup(void) 1173void __cpuinit end_local_APIC_setup(void)
diff --git a/arch/x86/kernel/apic_64.c b/arch/x86/kernel/apic_64.c
index 4587e16f73ec..283968d4e024 100644
--- a/arch/x86/kernel/apic_64.c
+++ b/arch/x86/kernel/apic_64.c
@@ -76,6 +76,8 @@ char system_vectors[NR_VECTORS] = { [0 ... NR_VECTORS-1] = SYS_VECTOR_FREE};
76 */ 76 */
77unsigned int apic_verbosity; 77unsigned int apic_verbosity;
78 78
79int pic_mode;
80
79/* Have we found an MP table */ 81/* Have we found an MP table */
80int smp_found_config; 82int smp_found_config;
81 83
@@ -943,8 +945,17 @@ void __cpuinit setup_local_APIC(void)
943 unsigned int value; 945 unsigned int value;
944 int i, j; 946 int i, j;
945 947
948#ifdef CONFIG_X86_32
949 /* Pound the ESR really hard over the head with a big hammer - mbligh */
950 if (esr_disable) {
951 apic_write(APIC_ESR, 0);
952 apic_write(APIC_ESR, 0);
953 apic_write(APIC_ESR, 0);
954 apic_write(APIC_ESR, 0);
955 }
956#endif
957
946 preempt_disable(); 958 preempt_disable();
947 value = apic_read(APIC_LVR);
948 959
949 /* 960 /*
950 * Double-check whether this APIC is really registered. 961 * Double-check whether this APIC is really registered.
@@ -997,7 +1008,34 @@ void __cpuinit setup_local_APIC(void)
997 */ 1008 */
998 value |= APIC_SPIV_APIC_ENABLED; 1009 value |= APIC_SPIV_APIC_ENABLED;
999 1010
1000 /* We always use processor focus */ 1011#ifdef CONFIG_X86_32
1012 /*
1013 * Some unknown Intel IO/APIC (or APIC) errata is biting us with
1014 * certain networking cards. If high frequency interrupts are
1015 * happening on a particular IOAPIC pin, plus the IOAPIC routing
1016 * entry is masked/unmasked at a high rate as well then sooner or
1017 * later IOAPIC line gets 'stuck', no more interrupts are received
1018 * from the device. If focus CPU is disabled then the hang goes
1019 * away, oh well :-(
1020 *
1021 * [ This bug can be reproduced easily with a level-triggered
1022 * PCI Ne2000 networking cards and PII/PIII processors, dual
1023 * BX chipset. ]
1024 */
1025 /*
1026 * Actually disabling the focus CPU check just makes the hang less
1027 * frequent as it makes the interrupt distributon model be more
1028 * like LRU than MRU (the short-term load is more even across CPUs).
1029 * See also the comment in end_level_ioapic_irq(). --macro
1030 */
1031
1032 /*
1033 * - enable focus processor (bit==0)
1034 * - 64bit mode always use processor focus
1035 * so no need to set it
1036 */
1037 value &= ~APIC_SPIV_FOCUS_DISABLED;
1038#endif
1001 1039
1002 /* 1040 /*
1003 * Set spurious IRQ vector 1041 * Set spurious IRQ vector
@@ -1016,14 +1054,14 @@ void __cpuinit setup_local_APIC(void)
1016 * TODO: set up through-local-APIC from through-I/O-APIC? --macro 1054 * TODO: set up through-local-APIC from through-I/O-APIC? --macro
1017 */ 1055 */
1018 value = apic_read(APIC_LVT0) & APIC_LVT_MASKED; 1056 value = apic_read(APIC_LVT0) & APIC_LVT_MASKED;
1019 if (!smp_processor_id() && !value) { 1057 if (!smp_processor_id() && (pic_mode || !value)) {
1020 value = APIC_DM_EXTINT; 1058 value = APIC_DM_EXTINT;
1021 apic_printk(APIC_VERBOSE, "enabled ExtINT on CPU#%d\n", 1059 apic_printk(APIC_VERBOSE, "enabled ExtINT on CPU#%d\n",
1022 smp_processor_id()); 1060 smp_processor_id());
1023 } else { 1061 } else {
1024 value = APIC_DM_EXTINT | APIC_LVT_MASKED; 1062 value = APIC_DM_EXTINT | APIC_LVT_MASKED;
1025 apic_printk(APIC_VERBOSE, "masked ExtINT on CPU#%d\n", 1063 apic_printk(APIC_VERBOSE, "masked ExtINT on CPU#%d\n",
1026 smp_processor_id()); 1064 smp_processor_id());
1027 } 1065 }
1028 apic_write(APIC_LVT0, value); 1066 apic_write(APIC_LVT0, value);
1029 1067
@@ -1034,7 +1072,10 @@ void __cpuinit setup_local_APIC(void)
1034 value = APIC_DM_NMI; 1072 value = APIC_DM_NMI;
1035 else 1073 else
1036 value = APIC_DM_NMI | APIC_LVT_MASKED; 1074 value = APIC_DM_NMI | APIC_LVT_MASKED;
1075 if (!lapic_is_integrated()) /* 82489DX */
1076 value |= APIC_LVT_LEVEL_TRIGGER;
1037 apic_write(APIC_LVT1, value); 1077 apic_write(APIC_LVT1, value);
1078
1038 preempt_enable(); 1079 preempt_enable();
1039} 1080}
1040 1081