diff options
-rw-r--r-- | arch/x86/Kconfig | 4 | ||||
-rw-r--r-- | arch/x86/include/asm/es7000/apic.h | 76 | ||||
-rw-r--r-- | arch/x86/include/asm/genapic_32.h | 1 | ||||
-rw-r--r-- | arch/x86/kernel/es7000_32.c | 17 | ||||
-rw-r--r-- | arch/x86/mach-generic/es7000.c | 14 |
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 | ||
465 | config ES7000_CLUSTERED_APIC | ||
466 | def_bool y | ||
467 | depends on SMP && X86_ES7000 && MPENTIUMIII | ||
468 | |||
469 | source "arch/x86/Kconfig.cpu" | 465 | source "arch/x86/Kconfig.cpu" |
470 | 466 | ||
471 | config HPET_TIMER | 467 | config 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 | ||
12 | static inline cpumask_t target_cpus(void) | 12 | static 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 | |||
17 | static 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 | ||
35 | static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid) | 34 | static 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 | */ |
59 | static 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 | |||
60 | static inline void init_apic_ldr(void) | 69 | static 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 | ||
71 | extern void enable_apic_mode(void); | ||
72 | #endif | ||
73 | |||
74 | extern int apic_version [MAX_APICS]; | 79 | extern int apic_version [MAX_APICS]; |
75 | static inline void setup_apic_routing(void) | 80 | static 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 | ||
144 | static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask) | 149 | static 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 | |||
182 | static 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 | ||
133 | extern struct genapic *genapic; | 133 | extern struct genapic *genapic; |
134 | extern void es7000_update_genapic_to_cluster(void); | ||
134 | 135 | ||
135 | enum uv_system_type {UV_NONE, UV_LEGACY_APIC, UV_X2APIC, UV_NON_UNIQUE_APIC}; | 136 | enum 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 | ||
167 | static int wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip) | 167 | static 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 | ||
185 | static void noop_wait_for_deassert(atomic_t *deassert_not_used) | ||
186 | { | ||
187 | } | ||
188 | |||
185 | static int __init es7000_update_genapic(void) | 189 | static 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 | ||
193 | void __init | 204 | void __init |
194 | setup_unisys(void) | 205 | setup_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 | |||
21 | void __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 | ||
21 | static int probe_es7000(void) | 33 | static int probe_es7000(void) |
22 | { | 34 | { |