aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc')
-rw-r--r--arch/sparc/kernel/smp.c96
-rw-r--r--arch/sparc/kernel/sun4d_smp.c103
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)
87void __init smp_cpus_done(unsigned int max_cpus) 87void __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
107void cpu_panic(void) 134void cpu_panic(void)
@@ -267,9 +294,9 @@ int setup_profiling_timer(unsigned int multiplier)
267void __init smp_prepare_cpus(unsigned int max_cpus) 294void __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)
323int __cpuinit __cpu_up(unsigned int cpu) 377int __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;
43extern void calibrate_delay(void); 43extern void calibrate_delay(void);
44 44
45extern volatile int smp_processors_ready; 45extern volatile int smp_processors_ready;
46extern int smp_num_cpus;
47static int smp_highest_cpu; 46static int smp_highest_cpu;
48extern volatile unsigned long cpu_callin_map[NR_CPUS]; 47extern volatile unsigned long cpu_callin_map[NR_CPUS];
49extern cpuinfo_sparc cpu_data[NR_CPUS]; 48extern cpuinfo_sparc cpu_data[NR_CPUS];
50extern unsigned char boot_cpu_id; 49extern unsigned char boot_cpu_id;
51extern int smp_activated;
52extern volatile int __cpu_number_map[NR_CPUS];
53extern volatile int __cpu_logical_map[NR_CPUS];
54extern volatile unsigned long ipi_count;
55extern volatile int smp_process_available; 50extern volatile int smp_process_available;
56 51
57extern cpumask_t smp_commenced_mask; 52extern 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
149extern void init_IRQ(void); 146extern void init_IRQ(void);
@@ -160,51 +157,24 @@ extern unsigned long trapbase_cpu3[];
160 157
161void __init smp4d_boot_cpus(void) 158void __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")); 166int 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 { 212void __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;