diff options
Diffstat (limited to 'arch/sparc/kernel/sun4d_smp.c')
-rw-r--r-- | arch/sparc/kernel/sun4d_smp.c | 103 |
1 files changed, 32 insertions, 71 deletions
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; |