diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/sparc/kernel/entry.S | 29 | ||||
-rw-r--r-- | arch/sparc/kernel/smp_32.c | 5 | ||||
-rw-r--r-- | arch/sparc/kernel/sun4m_smp.c | 29 |
3 files changed, 54 insertions, 9 deletions
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index d759cf31c8ee..8341963f4c84 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S | |||
@@ -269,19 +269,22 @@ smp4m_ticker: | |||
269 | /* Here is where we check for possible SMP IPI passed to us | 269 | /* Here is where we check for possible SMP IPI passed to us |
270 | * on some level other than 15 which is the NMI and only used | 270 | * on some level other than 15 which is the NMI and only used |
271 | * for cross calls. That has a separate entry point below. | 271 | * for cross calls. That has a separate entry point below. |
272 | * | ||
273 | * IPIs are sent on Level 12, 13 and 14. See IRQ_IPI_*. | ||
272 | */ | 274 | */ |
273 | maybe_smp4m_msg: | 275 | maybe_smp4m_msg: |
274 | GET_PROCESSOR4M_ID(o3) | 276 | GET_PROCESSOR4M_ID(o3) |
275 | sethi %hi(sun4m_irq_percpu), %l5 | 277 | sethi %hi(sun4m_irq_percpu), %l5 |
276 | sll %o3, 2, %o3 | 278 | sll %o3, 2, %o3 |
277 | or %l5, %lo(sun4m_irq_percpu), %o5 | 279 | or %l5, %lo(sun4m_irq_percpu), %o5 |
278 | sethi %hi(0x40000000), %o2 | 280 | sethi %hi(0x70000000), %o2 ! Check all soft-IRQs |
279 | ld [%o5 + %o3], %o1 | 281 | ld [%o5 + %o3], %o1 |
280 | ld [%o1 + 0x00], %o3 ! sun4m_irq_percpu[cpu]->pending | 282 | ld [%o1 + 0x00], %o3 ! sun4m_irq_percpu[cpu]->pending |
281 | andcc %o3, %o2, %g0 | 283 | andcc %o3, %o2, %g0 |
282 | be,a smp4m_ticker | 284 | be,a smp4m_ticker |
283 | cmp %l7, 14 | 285 | cmp %l7, 14 |
284 | st %o2, [%o1 + 0x04] ! sun4m_irq_percpu[cpu]->clear=0x40000000 | 286 | /* Soft-IRQ IPI */ |
287 | st %o2, [%o1 + 0x04] ! sun4m_irq_percpu[cpu]->clear=0x70000000 | ||
285 | WRITE_PAUSE | 288 | WRITE_PAUSE |
286 | ld [%o1 + 0x00], %g0 ! sun4m_irq_percpu[cpu]->pending | 289 | ld [%o1 + 0x00], %g0 ! sun4m_irq_percpu[cpu]->pending |
287 | WRITE_PAUSE | 290 | WRITE_PAUSE |
@@ -290,9 +293,27 @@ maybe_smp4m_msg: | |||
290 | WRITE_PAUSE | 293 | WRITE_PAUSE |
291 | wr %l4, PSR_ET, %psr | 294 | wr %l4, PSR_ET, %psr |
292 | WRITE_PAUSE | 295 | WRITE_PAUSE |
293 | call smp_reschedule_irq | 296 | sll %o2, 28, %o2 ! shift for simpler checks below |
297 | maybe_smp4m_msg_check_single: | ||
298 | andcc %o2, 0x1, %g0 | ||
299 | beq,a maybe_smp4m_msg_check_mask | ||
300 | andcc %o2, 0x2, %g0 | ||
301 | call smp_call_function_single_interrupt | ||
294 | nop | 302 | nop |
295 | 303 | andcc %o2, 0x2, %g0 | |
304 | maybe_smp4m_msg_check_mask: | ||
305 | beq,a maybe_smp4m_msg_check_resched | ||
306 | andcc %o2, 0x4, %g0 | ||
307 | call smp_call_function_interrupt | ||
308 | nop | ||
309 | andcc %o2, 0x4, %g0 | ||
310 | maybe_smp4m_msg_check_resched: | ||
311 | /* rescheduling is done in RESTORE_ALL regardless, but incr stats */ | ||
312 | beq,a maybe_smp4m_msg_out | ||
313 | nop | ||
314 | call smp_resched_interrupt | ||
315 | nop | ||
316 | maybe_smp4m_msg_out: | ||
296 | RESTORE_ALL | 317 | RESTORE_ALL |
297 | 318 | ||
298 | .align 4 | 319 | .align 4 |
diff --git a/arch/sparc/kernel/smp_32.c b/arch/sparc/kernel/smp_32.c index 2710602281de..705a94e1b8a5 100644 --- a/arch/sparc/kernel/smp_32.c +++ b/arch/sparc/kernel/smp_32.c | |||
@@ -267,11 +267,6 @@ void smp_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) | |||
267 | } | 267 | } |
268 | } | 268 | } |
269 | 269 | ||
270 | void smp_reschedule_irq(void) | ||
271 | { | ||
272 | set_need_resched(); | ||
273 | } | ||
274 | |||
275 | void smp_flush_page_to_ram(unsigned long page) | 270 | void smp_flush_page_to_ram(unsigned long page) |
276 | { | 271 | { |
277 | /* Current theory is that those who call this are the one's | 272 | /* Current theory is that those who call this are the one's |
diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c index 5545d10d50cd..e2e687312e2e 100644 --- a/arch/sparc/kernel/sun4m_smp.c +++ b/arch/sparc/kernel/sun4m_smp.c | |||
@@ -15,6 +15,9 @@ | |||
15 | #include "irq.h" | 15 | #include "irq.h" |
16 | #include "kernel.h" | 16 | #include "kernel.h" |
17 | 17 | ||
18 | #define IRQ_IPI_SINGLE 12 | ||
19 | #define IRQ_IPI_MASK 13 | ||
20 | #define IRQ_IPI_RESCHED 14 | ||
18 | #define IRQ_CROSS_CALL 15 | 21 | #define IRQ_CROSS_CALL 15 |
19 | 22 | ||
20 | static inline unsigned long | 23 | static inline unsigned long |
@@ -26,6 +29,7 @@ swap_ulong(volatile unsigned long *ptr, unsigned long val) | |||
26 | return val; | 29 | return val; |
27 | } | 30 | } |
28 | 31 | ||
32 | static void smp4m_ipi_init(void); | ||
29 | static void smp_setup_percpu_timer(void); | 33 | static void smp_setup_percpu_timer(void); |
30 | 34 | ||
31 | void __cpuinit smp4m_callin(void) | 35 | void __cpuinit smp4m_callin(void) |
@@ -81,6 +85,7 @@ void __cpuinit smp4m_callin(void) | |||
81 | */ | 85 | */ |
82 | void __init smp4m_boot_cpus(void) | 86 | void __init smp4m_boot_cpus(void) |
83 | { | 87 | { |
88 | smp4m_ipi_init(); | ||
84 | smp_setup_percpu_timer(); | 89 | smp_setup_percpu_timer(); |
85 | local_flush_cache_all(); | 90 | local_flush_cache_all(); |
86 | } | 91 | } |
@@ -148,6 +153,27 @@ void __init smp4m_smp_done(void) | |||
148 | /* Ok, they are spinning and ready to go. */ | 153 | /* Ok, they are spinning and ready to go. */ |
149 | } | 154 | } |
150 | 155 | ||
156 | |||
157 | /* Initialize IPIs on the SUN4M SMP machine */ | ||
158 | static void __init smp4m_ipi_init(void) | ||
159 | { | ||
160 | } | ||
161 | |||
162 | static void smp4m_ipi_resched(int cpu) | ||
163 | { | ||
164 | set_cpu_int(cpu, IRQ_IPI_RESCHED); | ||
165 | } | ||
166 | |||
167 | static void smp4m_ipi_single(int cpu) | ||
168 | { | ||
169 | set_cpu_int(cpu, IRQ_IPI_SINGLE); | ||
170 | } | ||
171 | |||
172 | static void smp4m_ipi_mask_one(int cpu) | ||
173 | { | ||
174 | set_cpu_int(cpu, IRQ_IPI_MASK); | ||
175 | } | ||
176 | |||
151 | static struct smp_funcall { | 177 | static struct smp_funcall { |
152 | smpfunc_t func; | 178 | smpfunc_t func; |
153 | unsigned long arg1; | 179 | unsigned long arg1; |
@@ -290,4 +316,7 @@ void __init sun4m_init_smp(void) | |||
290 | BTFIXUPSET_BLACKBOX(load_current, smp4m_blackbox_current); | 316 | BTFIXUPSET_BLACKBOX(load_current, smp4m_blackbox_current); |
291 | BTFIXUPSET_CALL(smp_cross_call, smp4m_cross_call, BTFIXUPCALL_NORM); | 317 | BTFIXUPSET_CALL(smp_cross_call, smp4m_cross_call, BTFIXUPCALL_NORM); |
292 | BTFIXUPSET_CALL(__hard_smp_processor_id, __smp4m_processor_id, BTFIXUPCALL_NORM); | 318 | BTFIXUPSET_CALL(__hard_smp_processor_id, __smp4m_processor_id, BTFIXUPCALL_NORM); |
319 | BTFIXUPSET_CALL(smp_ipi_resched, smp4m_ipi_resched, BTFIXUPCALL_NORM); | ||
320 | BTFIXUPSET_CALL(smp_ipi_single, smp4m_ipi_single, BTFIXUPCALL_NORM); | ||
321 | BTFIXUPSET_CALL(smp_ipi_mask_one, smp4m_ipi_mask_one, BTFIXUPCALL_NORM); | ||
293 | } | 322 | } |