aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/Kconfig4
-rw-r--r--arch/x86/include/asm/es7000/apic.h76
-rw-r--r--arch/x86/include/asm/genapic_32.h1
-rw-r--r--arch/x86/kernel/es7000_32.c17
-rw-r--r--arch/x86/mach-generic/es7000.c14
5 files changed, 80 insertions, 32 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 93224b569187..7d0ab8942cfb 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -462,10 +462,6 @@ config X86_CYCLONE_TIMER
462 def_bool y 462 def_bool y
463 depends on X86_GENERICARCH 463 depends on X86_GENERICARCH
464 464
465config ES7000_CLUSTERED_APIC
466 def_bool y
467 depends on SMP && X86_ES7000 && MPENTIUMIII
468
469source "arch/x86/Kconfig.cpu" 465source "arch/x86/Kconfig.cpu"
470 466
471config HPET_TIMER 467config HPET_TIMER
diff --git a/arch/x86/include/asm/es7000/apic.h b/arch/x86/include/asm/es7000/apic.h
index 9d8cf776c285..e24ef876915f 100644
--- a/arch/x86/include/asm/es7000/apic.h
+++ b/arch/x86/include/asm/es7000/apic.h
@@ -9,28 +9,27 @@ static inline int apic_id_registered(void)
9 return (1); 9 return (1);
10} 10}
11 11
12static inline cpumask_t target_cpus(void) 12static inline cpumask_t target_cpus_cluster(void)
13{ 13{
14#if defined CONFIG_ES7000_CLUSTERED_APIC
15 return CPU_MASK_ALL; 14 return CPU_MASK_ALL;
16#else 15}
16
17static inline cpumask_t target_cpus(void)
18{
17 return cpumask_of_cpu(smp_processor_id()); 19 return cpumask_of_cpu(smp_processor_id());
18#endif
19} 20}
20 21
21#if defined CONFIG_ES7000_CLUSTERED_APIC 22#define APIC_DFR_VALUE_CLUSTER (APIC_DFR_CLUSTER)
22#define APIC_DFR_VALUE (APIC_DFR_CLUSTER) 23#define INT_DELIVERY_MODE_CLUSTER (dest_LowestPrio)
23#define INT_DELIVERY_MODE (dest_LowestPrio) 24#define INT_DEST_MODE_CLUSTER (1) /* logical delivery broadcast to all procs */
24#define INT_DEST_MODE (1) /* logical delivery broadcast to all procs */ 25#define NO_BALANCE_IRQ_CLUSTER (1)
25#define NO_BALANCE_IRQ (1) 26
26#else
27#define APIC_DFR_VALUE (APIC_DFR_FLAT) 27#define APIC_DFR_VALUE (APIC_DFR_FLAT)
28#define INT_DELIVERY_MODE (dest_Fixed) 28#define INT_DELIVERY_MODE (dest_Fixed)
29#define INT_DEST_MODE (0) /* phys delivery to target procs */ 29#define INT_DEST_MODE (0) /* phys delivery to target procs */
30#define NO_BALANCE_IRQ (0) 30#define NO_BALANCE_IRQ (0)
31#undef APIC_DEST_LOGICAL 31#undef APIC_DEST_LOGICAL
32#define APIC_DEST_LOGICAL 0x0 32#define APIC_DEST_LOGICAL 0x0
33#endif
34 33
35static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid) 34static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid)
36{ 35{
@@ -57,6 +56,16 @@ static inline unsigned long calculate_ldr(int cpu)
57 * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel 56 * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel
58 * document number 292116). So here it goes... 57 * document number 292116). So here it goes...
59 */ 58 */
59static inline void init_apic_ldr_cluster(void)
60{
61 unsigned long val;
62 int cpu = smp_processor_id();
63
64 apic_write(APIC_DFR, APIC_DFR_VALUE_CLUSTER);
65 val = calculate_ldr(cpu);
66 apic_write(APIC_LDR, val);
67}
68
60static inline void init_apic_ldr(void) 69static inline void init_apic_ldr(void)
61{ 70{
62 unsigned long val; 71 unsigned long val;
@@ -67,10 +76,6 @@ static inline void init_apic_ldr(void)
67 apic_write(APIC_LDR, val); 76 apic_write(APIC_LDR, val);
68} 77}
69 78
70#ifndef CONFIG_X86_GENERICARCH
71extern void enable_apic_mode(void);
72#endif
73
74extern int apic_version [MAX_APICS]; 79extern int apic_version [MAX_APICS];
75static inline void setup_apic_routing(void) 80static inline void setup_apic_routing(void)
76{ 81{
@@ -141,7 +146,7 @@ static inline int check_phys_apicid_present(int cpu_physical_apicid)
141 return (1); 146 return (1);
142} 147}
143 148
144static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask) 149static inline unsigned int cpu_mask_to_apicid_cluster(cpumask_t cpumask)
145{ 150{
146 int num_bits_set; 151 int num_bits_set;
147 int cpus_found = 0; 152 int cpus_found = 0;
@@ -151,11 +156,7 @@ static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask)
151 num_bits_set = cpus_weight(cpumask); 156 num_bits_set = cpus_weight(cpumask);
152 /* Return id to all */ 157 /* Return id to all */
153 if (num_bits_set == NR_CPUS) 158 if (num_bits_set == NR_CPUS)
154#if defined CONFIG_ES7000_CLUSTERED_APIC
155 return 0xFF; 159 return 0xFF;
156#else
157 return cpu_to_logical_apicid(0);
158#endif
159 /* 160 /*
160 * The cpus in the mask must all be on the apic cluster. If are not 161 * The cpus in the mask must all be on the apic cluster. If are not
161 * on the same apicid cluster return default value of TARGET_CPUS. 162 * on the same apicid cluster return default value of TARGET_CPUS.
@@ -168,11 +169,40 @@ static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask)
168 if (apicid_cluster(apicid) != 169 if (apicid_cluster(apicid) !=
169 apicid_cluster(new_apicid)){ 170 apicid_cluster(new_apicid)){
170 printk ("%s: Not a valid mask!\n", __func__); 171 printk ("%s: Not a valid mask!\n", __func__);
171#if defined CONFIG_ES7000_CLUSTERED_APIC
172 return 0xFF; 172 return 0xFF;
173#else 173 }
174 apicid = new_apicid;
175 cpus_found++;
176 }
177 cpu++;
178 }
179 return apicid;
180}
181
182static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask)
183{
184 int num_bits_set;
185 int cpus_found = 0;
186 int cpu;
187 int apicid;
188
189 num_bits_set = cpus_weight(cpumask);
190 /* Return id to all */
191 if (num_bits_set == NR_CPUS)
192 return cpu_to_logical_apicid(0);
193 /*
194 * The cpus in the mask must all be on the apic cluster. If are not
195 * on the same apicid cluster return default value of TARGET_CPUS.
196 */
197 cpu = first_cpu(cpumask);
198 apicid = cpu_to_logical_apicid(cpu);
199 while (cpus_found < num_bits_set) {
200 if (cpu_isset(cpu, cpumask)) {
201 int new_apicid = cpu_to_logical_apicid(cpu);
202 if (apicid_cluster(apicid) !=
203 apicid_cluster(new_apicid)){
204 printk ("%s: Not a valid mask!\n", __func__);
174 return cpu_to_logical_apicid(0); 205 return cpu_to_logical_apicid(0);
175#endif
176 } 206 }
177 apicid = new_apicid; 207 apicid = new_apicid;
178 cpus_found++; 208 cpus_found++;
diff --git a/arch/x86/include/asm/genapic_32.h b/arch/x86/include/asm/genapic_32.h
index 455d6c27a98b..0ac17d33a8c7 100644
--- a/arch/x86/include/asm/genapic_32.h
+++ b/arch/x86/include/asm/genapic_32.h
@@ -131,6 +131,7 @@ struct genapic {
131} 131}
132 132
133extern struct genapic *genapic; 133extern struct genapic *genapic;
134extern void es7000_update_genapic_to_cluster(void);
134 135
135enum uv_system_type {UV_NONE, UV_LEGACY_APIC, UV_X2APIC, UV_NON_UNIQUE_APIC}; 136enum uv_system_type {UV_NONE, UV_LEGACY_APIC, UV_X2APIC, UV_NON_UNIQUE_APIC};
136#define get_uv_system_type() UV_NONE 137#define get_uv_system_type() UV_NONE
diff --git a/arch/x86/kernel/es7000_32.c b/arch/x86/kernel/es7000_32.c
index fb3bfe66fbe2..71d7be624d46 100644
--- a/arch/x86/kernel/es7000_32.c
+++ b/arch/x86/kernel/es7000_32.c
@@ -38,6 +38,7 @@
38#include <asm/io.h> 38#include <asm/io.h>
39#include <asm/nmi.h> 39#include <asm/nmi.h>
40#include <asm/smp.h> 40#include <asm/smp.h>
41#include <asm/atomic.h>
41#include <asm/apicdef.h> 42#include <asm/apicdef.h>
42#include <mach_mpparse.h> 43#include <mach_mpparse.h>
43#include <asm/genapic.h> 44#include <asm/genapic.h>
@@ -163,7 +164,6 @@ es7000_rename_gsi(int ioapic, int gsi)
163 return gsi; 164 return gsi;
164} 165}
165 166
166#ifdef CONFIG_ES7000_CLUSTERED_APIC
167static int wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip) 167static int wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip)
168{ 168{
169 unsigned long vect = 0, psaival = 0; 169 unsigned long vect = 0, psaival = 0;
@@ -182,13 +182,24 @@ static int wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip)
182 return 0; 182 return 0;
183} 183}
184 184
185static void noop_wait_for_deassert(atomic_t *deassert_not_used)
186{
187}
188
185static int __init es7000_update_genapic(void) 189static int __init es7000_update_genapic(void)
186{ 190{
187 genapic->wakeup_cpu = wakeup_secondary_cpu_via_mip; 191 genapic->wakeup_cpu = wakeup_secondary_cpu_via_mip;
188 192
193 /* MPENTIUMIII */
194 if (boot_cpu_data.x86 == 6 &&
195 (boot_cpu_data.x86_model >= 7 || boot_cpu_data.x86_model <= 11)) {
196 es7000_update_genapic_to_cluster();
197 genapic->wait_for_init_deassert = noop_wait_for_deassert;
198 genapic->wakeup_cpu = wakeup_secondary_cpu_via_mip;
199 }
200
189 return 0; 201 return 0;
190} 202}
191#endif
192 203
193void __init 204void __init
194setup_unisys(void) 205setup_unisys(void)
@@ -206,9 +217,7 @@ setup_unisys(void)
206 es7000_plat = ES7000_CLASSIC; 217 es7000_plat = ES7000_CLASSIC;
207 ioapic_renumber_irq = es7000_rename_gsi; 218 ioapic_renumber_irq = es7000_rename_gsi;
208 219
209#ifdef CONFIG_ES7000_CLUSTERED_APIC
210 x86_quirks->update_genapic = es7000_update_genapic; 220 x86_quirks->update_genapic = es7000_update_genapic;
211#endif
212} 221}
213 222
214/* 223/*
diff --git a/arch/x86/mach-generic/es7000.c b/arch/x86/mach-generic/es7000.c
index 28459cab3ddb..7b4e6d0d1690 100644
--- a/arch/x86/mach-generic/es7000.c
+++ b/arch/x86/mach-generic/es7000.c
@@ -16,7 +16,19 @@
16#include <asm/es7000/apic.h> 16#include <asm/es7000/apic.h>
17#include <asm/es7000/ipi.h> 17#include <asm/es7000/ipi.h>
18#include <asm/es7000/mpparse.h> 18#include <asm/es7000/mpparse.h>
19#include <asm/es7000/wakecpu.h> 19#include <asm/mach-default/mach_wakecpu.h>
20
21void __init es7000_update_genapic_to_cluster(void)
22{
23 genapic->target_cpus = target_cpus_cluster;
24 genapic->int_delivery_mode = INT_DELIVERY_MODE_CLUSTER;
25 genapic->int_dest_mode = INT_DEST_MODE_CLUSTER;
26 genapic->no_balance_irq = NO_BALANCE_IRQ_CLUSTER;
27
28 genapic->init_apic_ldr = init_apic_ldr_cluster;
29
30 genapic->cpu_mask_to_apicid = cpu_mask_to_apicid_cluster;
31}
20 32
21static int probe_es7000(void) 33static int probe_es7000(void)
22{ 34{