diff options
author | Raymond Burns <rayburns@comcast.net> | 2006-07-18 00:57:09 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-07-21 17:18:20 -0400 |
commit | 8b3c848cc89e62904e6d9c8f9fed13d5c225572d (patch) | |
tree | 7549671e3e19f5553e75898d430a298979e05b36 /arch/sparc/kernel | |
parent | 198c167c5424d30d4f6687aed6e54ef71036f8e9 (diff) |
[SPARC]: Get sun4d SMP building again.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc/kernel')
-rw-r--r-- | arch/sparc/kernel/smp.c | 96 | ||||
-rw-r--r-- | arch/sparc/kernel/sun4d_smp.c | 103 |
2 files changed, 121 insertions, 78 deletions
diff --git a/arch/sparc/kernel/smp.c b/arch/sparc/kernel/smp.c index 6135d4faeeeb..e311ade1b490 100644 --- a/arch/sparc/kernel/smp.c +++ b/arch/sparc/kernel/smp.c | |||
@@ -87,6 +87,7 @@ void __cpuinit smp_store_cpu_info(int id) | |||
87 | void __init smp_cpus_done(unsigned int max_cpus) | 87 | void __init smp_cpus_done(unsigned int max_cpus) |
88 | { | 88 | { |
89 | extern void smp4m_smp_done(void); | 89 | extern void smp4m_smp_done(void); |
90 | extern void smp4d_smp_done(void); | ||
90 | unsigned long bogosum = 0; | 91 | unsigned long bogosum = 0; |
91 | int cpu, num; | 92 | int cpu, num; |
92 | 93 | ||
@@ -100,8 +101,34 @@ void __init smp_cpus_done(unsigned int max_cpus) | |||
100 | num, bogosum/(500000/HZ), | 101 | num, bogosum/(500000/HZ), |
101 | (bogosum/(5000/HZ))%100); | 102 | (bogosum/(5000/HZ))%100); |
102 | 103 | ||
103 | BUG_ON(sparc_cpu_model != sun4m); | 104 | switch(sparc_cpu_model) { |
104 | smp4m_smp_done(); | 105 | case sun4: |
106 | printk("SUN4\n"); | ||
107 | BUG(); | ||
108 | break; | ||
109 | case sun4c: | ||
110 | printk("SUN4C\n"); | ||
111 | BUG(); | ||
112 | break; | ||
113 | case sun4m: | ||
114 | smp4m_smp_done(); | ||
115 | break; | ||
116 | case sun4d: | ||
117 | smp4d_smp_done(); | ||
118 | break; | ||
119 | case sun4e: | ||
120 | printk("SUN4E\n"); | ||
121 | BUG(); | ||
122 | break; | ||
123 | case sun4u: | ||
124 | printk("SUN4U\n"); | ||
125 | BUG(); | ||
126 | break; | ||
127 | default: | ||
128 | printk("UNKNOWN!\n"); | ||
129 | BUG(); | ||
130 | break; | ||
131 | }; | ||
105 | } | 132 | } |
106 | 133 | ||
107 | void cpu_panic(void) | 134 | void cpu_panic(void) |
@@ -267,9 +294,9 @@ int setup_profiling_timer(unsigned int multiplier) | |||
267 | void __init smp_prepare_cpus(unsigned int max_cpus) | 294 | void __init smp_prepare_cpus(unsigned int max_cpus) |
268 | { | 295 | { |
269 | extern void smp4m_boot_cpus(void); | 296 | extern void smp4m_boot_cpus(void); |
297 | extern void smp4d_boot_cpus(void); | ||
270 | int i, cpuid, extra; | 298 | int i, cpuid, extra; |
271 | 299 | ||
272 | BUG_ON(sparc_cpu_model != sun4m); | ||
273 | printk("Entering SMP Mode...\n"); | 300 | printk("Entering SMP Mode...\n"); |
274 | 301 | ||
275 | extra = 0; | 302 | extra = 0; |
@@ -283,7 +310,34 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
283 | 310 | ||
284 | smp_store_cpu_info(boot_cpu_id); | 311 | smp_store_cpu_info(boot_cpu_id); |
285 | 312 | ||
286 | smp4m_boot_cpus(); | 313 | switch(sparc_cpu_model) { |
314 | case sun4: | ||
315 | printk("SUN4\n"); | ||
316 | BUG(); | ||
317 | break; | ||
318 | case sun4c: | ||
319 | printk("SUN4C\n"); | ||
320 | BUG(); | ||
321 | break; | ||
322 | case sun4m: | ||
323 | smp4m_boot_cpus(); | ||
324 | break; | ||
325 | case sun4d: | ||
326 | smp4d_boot_cpus(); | ||
327 | break; | ||
328 | case sun4e: | ||
329 | printk("SUN4E\n"); | ||
330 | BUG(); | ||
331 | break; | ||
332 | case sun4u: | ||
333 | printk("SUN4U\n"); | ||
334 | BUG(); | ||
335 | break; | ||
336 | default: | ||
337 | printk("UNKNOWN!\n"); | ||
338 | BUG(); | ||
339 | break; | ||
340 | }; | ||
287 | } | 341 | } |
288 | 342 | ||
289 | /* Set this up early so that things like the scheduler can init | 343 | /* Set this up early so that things like the scheduler can init |
@@ -323,9 +377,37 @@ void __init smp_prepare_boot_cpu(void) | |||
323 | int __cpuinit __cpu_up(unsigned int cpu) | 377 | int __cpuinit __cpu_up(unsigned int cpu) |
324 | { | 378 | { |
325 | extern int smp4m_boot_one_cpu(int); | 379 | extern int smp4m_boot_one_cpu(int); |
326 | int ret; | 380 | extern int smp4d_boot_one_cpu(int); |
327 | 381 | int ret=0; | |
328 | ret = smp4m_boot_one_cpu(cpu); | 382 | |
383 | switch(sparc_cpu_model) { | ||
384 | case sun4: | ||
385 | printk("SUN4\n"); | ||
386 | BUG(); | ||
387 | break; | ||
388 | case sun4c: | ||
389 | printk("SUN4C\n"); | ||
390 | BUG(); | ||
391 | break; | ||
392 | case sun4m: | ||
393 | ret = smp4m_boot_one_cpu(cpu); | ||
394 | break; | ||
395 | case sun4d: | ||
396 | ret = smp4d_boot_one_cpu(cpu); | ||
397 | break; | ||
398 | case sun4e: | ||
399 | printk("SUN4E\n"); | ||
400 | BUG(); | ||
401 | break; | ||
402 | case sun4u: | ||
403 | printk("SUN4U\n"); | ||
404 | BUG(); | ||
405 | break; | ||
406 | default: | ||
407 | printk("UNKNOWN!\n"); | ||
408 | BUG(); | ||
409 | break; | ||
410 | }; | ||
329 | 411 | ||
330 | if (!ret) { | 412 | if (!ret) { |
331 | cpu_set(cpu, smp_commenced_mask); | 413 | cpu_set(cpu, smp_commenced_mask); |
diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c index b141b7ee6717..ba843f6a2832 100644 --- a/arch/sparc/kernel/sun4d_smp.c +++ b/arch/sparc/kernel/sun4d_smp.c | |||
@@ -43,15 +43,10 @@ extern ctxd_t *srmmu_ctx_table_phys; | |||
43 | extern void calibrate_delay(void); | 43 | extern void calibrate_delay(void); |
44 | 44 | ||
45 | extern volatile int smp_processors_ready; | 45 | extern volatile int smp_processors_ready; |
46 | extern int smp_num_cpus; | ||
47 | static int smp_highest_cpu; | 46 | static int smp_highest_cpu; |
48 | extern volatile unsigned long cpu_callin_map[NR_CPUS]; | 47 | extern volatile unsigned long cpu_callin_map[NR_CPUS]; |
49 | extern cpuinfo_sparc cpu_data[NR_CPUS]; | 48 | extern cpuinfo_sparc cpu_data[NR_CPUS]; |
50 | extern unsigned char boot_cpu_id; | 49 | extern unsigned char boot_cpu_id; |
51 | extern int smp_activated; | ||
52 | extern volatile int __cpu_number_map[NR_CPUS]; | ||
53 | extern volatile int __cpu_logical_map[NR_CPUS]; | ||
54 | extern volatile unsigned long ipi_count; | ||
55 | extern volatile int smp_process_available; | 50 | extern volatile int smp_process_available; |
56 | 51 | ||
57 | extern cpumask_t smp_commenced_mask; | 52 | extern cpumask_t smp_commenced_mask; |
@@ -144,6 +139,8 @@ void __init smp4d_callin(void) | |||
144 | spin_lock_irqsave(&sun4d_imsk_lock, flags); | 139 | spin_lock_irqsave(&sun4d_imsk_lock, flags); |
145 | cc_set_imsk(cc_get_imsk() & ~0x4000); /* Allow PIL 14 as well */ | 140 | cc_set_imsk(cc_get_imsk() & ~0x4000); /* Allow PIL 14 as well */ |
146 | spin_unlock_irqrestore(&sun4d_imsk_lock, flags); | 141 | spin_unlock_irqrestore(&sun4d_imsk_lock, flags); |
142 | cpu_set(cpuid, cpu_online_map); | ||
143 | |||
147 | } | 144 | } |
148 | 145 | ||
149 | extern void init_IRQ(void); | 146 | extern void init_IRQ(void); |
@@ -160,51 +157,24 @@ extern unsigned long trapbase_cpu3[]; | |||
160 | 157 | ||
161 | void __init smp4d_boot_cpus(void) | 158 | void __init smp4d_boot_cpus(void) |
162 | { | 159 | { |
163 | int cpucount = 0; | ||
164 | int i, mid; | ||
165 | |||
166 | printk("Entering SMP Mode...\n"); | ||
167 | |||
168 | if (boot_cpu_id) | 160 | if (boot_cpu_id) |
169 | current_set[0] = NULL; | 161 | current_set[0] = NULL; |
170 | |||
171 | local_irq_enable(); | ||
172 | cpus_clear(cpu_present_map); | ||
173 | |||
174 | /* XXX This whole thing has to go. See sparc64. */ | ||
175 | for (i = 0; !cpu_find_by_instance(i, NULL, &mid); i++) | ||
176 | cpu_set(mid, cpu_present_map); | ||
177 | SMP_PRINTK(("cpu_present_map %08lx\n", cpus_addr(cpu_present_map)[0])); | ||
178 | for(i=0; i < NR_CPUS; i++) | ||
179 | __cpu_number_map[i] = -1; | ||
180 | for(i=0; i < NR_CPUS; i++) | ||
181 | __cpu_logical_map[i] = -1; | ||
182 | __cpu_number_map[boot_cpu_id] = 0; | ||
183 | __cpu_logical_map[0] = boot_cpu_id; | ||
184 | current_thread_info()->cpu = boot_cpu_id; | ||
185 | smp_store_cpu_info(boot_cpu_id); | ||
186 | smp_setup_percpu_timer(); | 162 | smp_setup_percpu_timer(); |
187 | local_flush_cache_all(); | 163 | local_flush_cache_all(); |
188 | if (cpu_find_by_instance(1, NULL, NULL)) | 164 | } |
189 | return; /* Not an MP box. */ | 165 | |
190 | SMP_PRINTK(("Iterating over CPUs\n")); | 166 | int smp4d_boot_one_cpu(int i) |
191 | for(i = 0; i < NR_CPUS; i++) { | 167 | { |
192 | if(i == boot_cpu_id) | ||
193 | continue; | ||
194 | |||
195 | if (cpu_isset(i, cpu_present_map)) { | ||
196 | extern unsigned long sun4d_cpu_startup; | 168 | extern unsigned long sun4d_cpu_startup; |
197 | unsigned long *entry = &sun4d_cpu_startup; | 169 | unsigned long *entry = &sun4d_cpu_startup; |
198 | struct task_struct *p; | 170 | struct task_struct *p; |
199 | int timeout; | 171 | int timeout; |
200 | int no; | 172 | int cpu_node; |
201 | 173 | ||
174 | cpu_find_by_instance(i, &cpu_node,NULL); | ||
202 | /* Cook up an idler for this guy. */ | 175 | /* Cook up an idler for this guy. */ |
203 | p = fork_idle(i); | 176 | p = fork_idle(i); |
204 | cpucount++; | ||
205 | current_set[i] = task_thread_info(p); | 177 | current_set[i] = task_thread_info(p); |
206 | for (no = 0; !cpu_find_by_instance(no, NULL, &mid) | ||
207 | && mid != i; no++) ; | ||
208 | 178 | ||
209 | /* | 179 | /* |
210 | * Initialize the contexts table | 180 | * Initialize the contexts table |
@@ -216,9 +186,9 @@ void __init smp4d_boot_cpus(void) | |||
216 | smp_penguin_ctable.reg_size = 0; | 186 | smp_penguin_ctable.reg_size = 0; |
217 | 187 | ||
218 | /* whirrr, whirrr, whirrrrrrrrr... */ | 188 | /* whirrr, whirrr, whirrrrrrrrr... */ |
219 | SMP_PRINTK(("Starting CPU %d at %p task %d node %08x\n", i, entry, cpucount, cpu_data(no).prom_node)); | 189 | SMP_PRINTK(("Starting CPU %d at %p \n", i, entry)); |
220 | local_flush_cache_all(); | 190 | local_flush_cache_all(); |
221 | prom_startcpu(cpu_data(no).prom_node, | 191 | prom_startcpu(cpu_node, |
222 | &smp_penguin_ctable, 0, (char *)entry); | 192 | &smp_penguin_ctable, 0, (char *)entry); |
223 | 193 | ||
224 | SMP_PRINTK(("prom_startcpu returned :)\n")); | 194 | SMP_PRINTK(("prom_startcpu returned :)\n")); |
@@ -230,39 +200,30 @@ void __init smp4d_boot_cpus(void) | |||
230 | udelay(200); | 200 | udelay(200); |
231 | } | 201 | } |
232 | 202 | ||
233 | if(cpu_callin_map[i]) { | 203 | if (!(cpu_callin_map[i])) { |
234 | /* Another "Red Snapper". */ | 204 | printk("Processor %d is stuck.\n", i); |
235 | __cpu_number_map[i] = cpucount; | 205 | return -ENODEV; |
236 | __cpu_logical_map[cpucount] = i; | 206 | |
237 | } else { | ||
238 | cpucount--; | ||
239 | printk("Processor %d is stuck.\n", i); | ||
240 | } | ||
241 | } | ||
242 | if(!(cpu_callin_map[i])) { | ||
243 | cpu_clear(i, cpu_present_map); | ||
244 | __cpu_number_map[i] = -1; | ||
245 | } | ||
246 | } | 207 | } |
247 | local_flush_cache_all(); | 208 | local_flush_cache_all(); |
248 | if(cpucount == 0) { | 209 | return 0; |
249 | printk("Error: only one Processor found.\n"); | 210 | } |
250 | cpu_present_map = cpumask_of_cpu(hard_smp4d_processor_id()); | 211 | |
251 | } else { | 212 | void __init smp4d_smp_done(void) |
252 | unsigned long bogosum = 0; | 213 | { |
253 | 214 | int i, first; | |
254 | for_each_present_cpu(i) { | 215 | int *prev; |
255 | bogosum += cpu_data(i).udelay_val; | 216 | |
256 | smp_highest_cpu = i; | 217 | /* setup cpu list for irq rotation */ |
218 | first = 0; | ||
219 | prev = &first; | ||
220 | for (i = 0; i < NR_CPUS; i++) | ||
221 | if (cpu_online(i)) { | ||
222 | *prev = i; | ||
223 | prev = &cpu_data(i).next; | ||
257 | } | 224 | } |
258 | SMP_PRINTK(("Total of %d Processors activated (%lu.%02lu BogoMIPS).\n", cpucount + 1, bogosum/(500000/HZ), (bogosum/(5000/HZ))%100)); | 225 | *prev = first; |
259 | printk("Total of %d Processors activated (%lu.%02lu BogoMIPS).\n", | 226 | local_flush_cache_all(); |
260 | cpucount + 1, | ||
261 | bogosum/(500000/HZ), | ||
262 | (bogosum/(5000/HZ))%100); | ||
263 | smp_activated = 1; | ||
264 | smp_num_cpus = cpucount + 1; | ||
265 | } | ||
266 | 227 | ||
267 | /* Free unneeded trap tables */ | 228 | /* Free unneeded trap tables */ |
268 | ClearPageReserved(virt_to_page(trapbase_cpu1)); | 229 | ClearPageReserved(virt_to_page(trapbase_cpu1)); |
@@ -334,7 +295,7 @@ void smp4d_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2, | |||
334 | register int i; | 295 | register int i; |
335 | 296 | ||
336 | mask = cpumask_of_cpu(hard_smp4d_processor_id()); | 297 | mask = cpumask_of_cpu(hard_smp4d_processor_id()); |
337 | cpus_andnot(mask, cpu_present_map, mask); | 298 | cpus_andnot(mask, cpu_online_map, mask); |
338 | for(i = 0; i <= high; i++) { | 299 | for(i = 0; i <= high; i++) { |
339 | if (cpu_isset(i, mask)) { | 300 | if (cpu_isset(i, mask)) { |
340 | ccall_info.processors_in[i] = 0; | 301 | ccall_info.processors_in[i] = 0; |