aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/sparc/kernel/entry.S29
-rw-r--r--arch/sparc/kernel/smp_32.c5
-rw-r--r--arch/sparc/kernel/sun4m_smp.c29
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 */
273maybe_smp4m_msg: 275maybe_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
297maybe_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
304maybe_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
310maybe_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
316maybe_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
270void smp_reschedule_irq(void)
271{
272 set_need_resched();
273}
274
275void smp_flush_page_to_ram(unsigned long page) 270void 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
20static inline unsigned long 23static 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
32static void smp4m_ipi_init(void);
29static void smp_setup_percpu_timer(void); 33static void smp_setup_percpu_timer(void);
30 34
31void __cpuinit smp4m_callin(void) 35void __cpuinit smp4m_callin(void)
@@ -81,6 +85,7 @@ void __cpuinit smp4m_callin(void)
81 */ 85 */
82void __init smp4m_boot_cpus(void) 86void __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 */
158static void __init smp4m_ipi_init(void)
159{
160}
161
162static void smp4m_ipi_resched(int cpu)
163{
164 set_cpu_int(cpu, IRQ_IPI_RESCHED);
165}
166
167static void smp4m_ipi_single(int cpu)
168{
169 set_cpu_int(cpu, IRQ_IPI_SINGLE);
170}
171
172static void smp4m_ipi_mask_one(int cpu)
173{
174 set_cpu_int(cpu, IRQ_IPI_MASK);
175}
176
151static struct smp_funcall { 177static 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}