diff options
Diffstat (limited to 'arch/sparc/kernel/entry.S')
-rw-r--r-- | arch/sparc/kernel/entry.S | 29 |
1 files changed, 25 insertions, 4 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 |