aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/kernel/smp_32.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc/kernel/smp_32.c')
-rw-r--r--arch/sparc/kernel/smp_32.c103
1 files changed, 73 insertions, 30 deletions
diff --git a/arch/sparc/kernel/smp_32.c b/arch/sparc/kernel/smp_32.c
index 442286d83435..d5b3958be0b4 100644
--- a/arch/sparc/kernel/smp_32.c
+++ b/arch/sparc/kernel/smp_32.c
@@ -37,8 +37,6 @@
37#include "irq.h" 37#include "irq.h"
38 38
39volatile unsigned long cpu_callin_map[NR_CPUS] __cpuinitdata = {0,}; 39volatile unsigned long cpu_callin_map[NR_CPUS] __cpuinitdata = {0,};
40unsigned char boot_cpu_id = 0;
41unsigned char boot_cpu_id4 = 0; /* boot_cpu_id << 2 */
42 40
43cpumask_t smp_commenced_mask = CPU_MASK_NONE; 41cpumask_t smp_commenced_mask = CPU_MASK_NONE;
44 42
@@ -130,14 +128,57 @@ struct linux_prom_registers smp_penguin_ctable __cpuinitdata = { 0 };
130void smp_send_reschedule(int cpu) 128void smp_send_reschedule(int cpu)
131{ 129{
132 /* 130 /*
133 * XXX missing reschedule IPI, see scheduler_ipi() 131 * CPU model dependent way of implementing IPI generation targeting
132 * a single CPU. The trap handler needs only to do trap entry/return
133 * to call schedule.
134 */ 134 */
135 BTFIXUP_CALL(smp_ipi_resched)(cpu);
135} 136}
136 137
137void smp_send_stop(void) 138void smp_send_stop(void)
138{ 139{
139} 140}
140 141
142void arch_send_call_function_single_ipi(int cpu)
143{
144 /* trigger one IPI single call on one CPU */
145 BTFIXUP_CALL(smp_ipi_single)(cpu);
146}
147
148void arch_send_call_function_ipi_mask(const struct cpumask *mask)
149{
150 int cpu;
151
152 /* trigger IPI mask call on each CPU */
153 for_each_cpu(cpu, mask)
154 BTFIXUP_CALL(smp_ipi_mask_one)(cpu);
155}
156
157void smp_resched_interrupt(void)
158{
159 irq_enter();
160 scheduler_ipi();
161 local_cpu_data().irq_resched_count++;
162 irq_exit();
163 /* re-schedule routine called by interrupt return code. */
164}
165
166void smp_call_function_single_interrupt(void)
167{
168 irq_enter();
169 generic_smp_call_function_single_interrupt();
170 local_cpu_data().irq_call_count++;
171 irq_exit();
172}
173
174void smp_call_function_interrupt(void)
175{
176 irq_enter();
177 generic_smp_call_function_interrupt();
178 local_cpu_data().irq_call_count++;
179 irq_exit();
180}
181
141void smp_flush_cache_all(void) 182void smp_flush_cache_all(void)
142{ 183{
143 xc0((smpfunc_t) BTFIXUP_CALL(local_flush_cache_all)); 184 xc0((smpfunc_t) BTFIXUP_CALL(local_flush_cache_all));
@@ -153,9 +194,10 @@ void smp_flush_tlb_all(void)
153void smp_flush_cache_mm(struct mm_struct *mm) 194void smp_flush_cache_mm(struct mm_struct *mm)
154{ 195{
155 if(mm->context != NO_CONTEXT) { 196 if(mm->context != NO_CONTEXT) {
156 cpumask_t cpu_mask = *mm_cpumask(mm); 197 cpumask_t cpu_mask;
157 cpu_clear(smp_processor_id(), cpu_mask); 198 cpumask_copy(&cpu_mask, mm_cpumask(mm));
158 if (!cpus_empty(cpu_mask)) 199 cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
200 if (!cpumask_empty(&cpu_mask))
159 xc1((smpfunc_t) BTFIXUP_CALL(local_flush_cache_mm), (unsigned long) mm); 201 xc1((smpfunc_t) BTFIXUP_CALL(local_flush_cache_mm), (unsigned long) mm);
160 local_flush_cache_mm(mm); 202 local_flush_cache_mm(mm);
161 } 203 }
@@ -164,9 +206,10 @@ void smp_flush_cache_mm(struct mm_struct *mm)
164void smp_flush_tlb_mm(struct mm_struct *mm) 206void smp_flush_tlb_mm(struct mm_struct *mm)
165{ 207{
166 if(mm->context != NO_CONTEXT) { 208 if(mm->context != NO_CONTEXT) {
167 cpumask_t cpu_mask = *mm_cpumask(mm); 209 cpumask_t cpu_mask;
168 cpu_clear(smp_processor_id(), cpu_mask); 210 cpumask_copy(&cpu_mask, mm_cpumask(mm));
169 if (!cpus_empty(cpu_mask)) { 211 cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
212 if (!cpumask_empty(&cpu_mask)) {
170 xc1((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_mm), (unsigned long) mm); 213 xc1((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_mm), (unsigned long) mm);
171 if(atomic_read(&mm->mm_users) == 1 && current->active_mm == mm) 214 if(atomic_read(&mm->mm_users) == 1 && current->active_mm == mm)
172 cpumask_copy(mm_cpumask(mm), 215 cpumask_copy(mm_cpumask(mm),
@@ -182,9 +225,10 @@ void smp_flush_cache_range(struct vm_area_struct *vma, unsigned long start,
182 struct mm_struct *mm = vma->vm_mm; 225 struct mm_struct *mm = vma->vm_mm;
183 226
184 if (mm->context != NO_CONTEXT) { 227 if (mm->context != NO_CONTEXT) {
185 cpumask_t cpu_mask = *mm_cpumask(mm); 228 cpumask_t cpu_mask;
186 cpu_clear(smp_processor_id(), cpu_mask); 229 cpumask_copy(&cpu_mask, mm_cpumask(mm));
187 if (!cpus_empty(cpu_mask)) 230 cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
231 if (!cpumask_empty(&cpu_mask))
188 xc3((smpfunc_t) BTFIXUP_CALL(local_flush_cache_range), (unsigned long) vma, start, end); 232 xc3((smpfunc_t) BTFIXUP_CALL(local_flush_cache_range), (unsigned long) vma, start, end);
189 local_flush_cache_range(vma, start, end); 233 local_flush_cache_range(vma, start, end);
190 } 234 }
@@ -196,9 +240,10 @@ void smp_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
196 struct mm_struct *mm = vma->vm_mm; 240 struct mm_struct *mm = vma->vm_mm;
197 241
198 if (mm->context != NO_CONTEXT) { 242 if (mm->context != NO_CONTEXT) {
199 cpumask_t cpu_mask = *mm_cpumask(mm); 243 cpumask_t cpu_mask;
200 cpu_clear(smp_processor_id(), cpu_mask); 244 cpumask_copy(&cpu_mask, mm_cpumask(mm));
201 if (!cpus_empty(cpu_mask)) 245 cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
246 if (!cpumask_empty(&cpu_mask))
202 xc3((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_range), (unsigned long) vma, start, end); 247 xc3((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_range), (unsigned long) vma, start, end);
203 local_flush_tlb_range(vma, start, end); 248 local_flush_tlb_range(vma, start, end);
204 } 249 }
@@ -209,9 +254,10 @@ void smp_flush_cache_page(struct vm_area_struct *vma, unsigned long page)
209 struct mm_struct *mm = vma->vm_mm; 254 struct mm_struct *mm = vma->vm_mm;
210 255
211 if(mm->context != NO_CONTEXT) { 256 if(mm->context != NO_CONTEXT) {
212 cpumask_t cpu_mask = *mm_cpumask(mm); 257 cpumask_t cpu_mask;
213 cpu_clear(smp_processor_id(), cpu_mask); 258 cpumask_copy(&cpu_mask, mm_cpumask(mm));
214 if (!cpus_empty(cpu_mask)) 259 cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
260 if (!cpumask_empty(&cpu_mask))
215 xc2((smpfunc_t) BTFIXUP_CALL(local_flush_cache_page), (unsigned long) vma, page); 261 xc2((smpfunc_t) BTFIXUP_CALL(local_flush_cache_page), (unsigned long) vma, page);
216 local_flush_cache_page(vma, page); 262 local_flush_cache_page(vma, page);
217 } 263 }
@@ -222,19 +268,15 @@ void smp_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
222 struct mm_struct *mm = vma->vm_mm; 268 struct mm_struct *mm = vma->vm_mm;
223 269
224 if(mm->context != NO_CONTEXT) { 270 if(mm->context != NO_CONTEXT) {
225 cpumask_t cpu_mask = *mm_cpumask(mm); 271 cpumask_t cpu_mask;
226 cpu_clear(smp_processor_id(), cpu_mask); 272 cpumask_copy(&cpu_mask, mm_cpumask(mm));
227 if (!cpus_empty(cpu_mask)) 273 cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
274 if (!cpumask_empty(&cpu_mask))
228 xc2((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_page), (unsigned long) vma, page); 275 xc2((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_page), (unsigned long) vma, page);
229 local_flush_tlb_page(vma, page); 276 local_flush_tlb_page(vma, page);
230 } 277 }
231} 278}
232 279
233void smp_reschedule_irq(void)
234{
235 set_need_resched();
236}
237
238void smp_flush_page_to_ram(unsigned long page) 280void smp_flush_page_to_ram(unsigned long page)
239{ 281{
240 /* Current theory is that those who call this are the one's 282 /* Current theory is that those who call this are the one's
@@ -251,9 +293,10 @@ void smp_flush_page_to_ram(unsigned long page)
251 293
252void smp_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr) 294void smp_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr)
253{ 295{
254 cpumask_t cpu_mask = *mm_cpumask(mm); 296 cpumask_t cpu_mask;
255 cpu_clear(smp_processor_id(), cpu_mask); 297 cpumask_copy(&cpu_mask, mm_cpumask(mm));
256 if (!cpus_empty(cpu_mask)) 298 cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
299 if (!cpumask_empty(&cpu_mask))
257 xc2((smpfunc_t) BTFIXUP_CALL(local_flush_sig_insns), (unsigned long) mm, insn_addr); 300 xc2((smpfunc_t) BTFIXUP_CALL(local_flush_sig_insns), (unsigned long) mm, insn_addr);
258 local_flush_sig_insns(mm, insn_addr); 301 local_flush_sig_insns(mm, insn_addr);
259} 302}
@@ -407,7 +450,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
407 }; 450 };
408 451
409 if (!ret) { 452 if (!ret) {
410 cpu_set(cpu, smp_commenced_mask); 453 cpumask_set_cpu(cpu, &smp_commenced_mask);
411 while (!cpu_online(cpu)) 454 while (!cpu_online(cpu))
412 mb(); 455 mb();
413 } 456 }