From b4f4372f96e0573d752d9e45beda02fabf716cc8 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 23 Nov 2008 21:55:29 -0800 Subject: sparc64: Make %pil level 15 a pseudo-NMI. So that we can profile code even in a local_irq_disable() section, only write 14 (instead of 15) into the %pil register to disable IRQs. This allows PIL level 15 to serve as a pseudo NMI. Signed-off-by: David S. Miller --- arch/sparc/include/asm/irqflags_64.h | 6 ++++-- arch/sparc/include/asm/pil.h | 9 ++++++++- arch/sparc/include/asm/ttable.h | 15 +++++++++++++-- arch/sparc/mm/ultra.S | 4 ++-- 4 files changed, 27 insertions(+), 7 deletions(-) (limited to 'arch/sparc') diff --git a/arch/sparc/include/asm/irqflags_64.h b/arch/sparc/include/asm/irqflags_64.h index bb42e59..8b49bf9 100644 --- a/arch/sparc/include/asm/irqflags_64.h +++ b/arch/sparc/include/asm/irqflags_64.h @@ -10,6 +10,8 @@ #ifndef _ASM_IRQFLAGS_H #define _ASM_IRQFLAGS_H +#include + #ifndef __ASSEMBLY__ static inline unsigned long __raw_local_save_flags(void) @@ -40,9 +42,9 @@ static inline void raw_local_irq_restore(unsigned long flags) static inline void raw_local_irq_disable(void) { __asm__ __volatile__( - "wrpr 15, %%pil" + "wrpr %0, %%pil" : /* no outputs */ - : /* no inputs */ + : "i" (PIL_NORMAL_MAX) : "memory" ); } diff --git a/arch/sparc/include/asm/pil.h b/arch/sparc/include/asm/pil.h index 71819bb..d573820 100644 --- a/arch/sparc/include/asm/pil.h +++ b/arch/sparc/include/asm/pil.h @@ -10,7 +10,12 @@ * * In fact any XCALL which has to etrap/rtrap has a problem because * it is difficult to prevent rtrap from running BH's, and that would - * need to be done if the XCALL arrived while %pil==15. + * need to be done if the XCALL arrived while %pil==PIL_NORMAL_MAX. + * + * Finally, in order to handle profiling events even when a + * local_irq_disable() is in progress, we only disable up to level 14 + * interrupts. Profile counter overflow interrupts arrive at level + * 15. */ #define PIL_SMP_CALL_FUNC 1 #define PIL_SMP_RECEIVE_SIGNAL 2 @@ -18,5 +23,7 @@ #define PIL_SMP_CTX_NEW_VERSION 4 #define PIL_DEVICE_IRQ 5 #define PIL_SMP_CALL_FUNC_SNGL 6 +#define PIL_NORMAL_MAX 14 +#define PIL_NMI 15 #endif /* !(_SPARC64_PIL_H) */ diff --git a/arch/sparc/include/asm/ttable.h b/arch/sparc/include/asm/ttable.h index 5708ba2..bb2c077 100644 --- a/arch/sparc/include/asm/ttable.h +++ b/arch/sparc/include/asm/ttable.h @@ -2,6 +2,7 @@ #define _SPARC64_TTABLE_H #include +#include #ifdef __ASSEMBLY__ #include @@ -123,7 +124,7 @@ #define TRAP_IRQ(routine, level) \ rdpr %pil, %g2; \ - wrpr %g0, 15, %pil; \ + wrpr %g0, PIL_NORMAL_MAX, %pil; \ sethi %hi(1f-4), %g7; \ ba,pt %xcc, etrap_irq; \ or %g7, %lo(1f-4), %g7; \ @@ -143,7 +144,7 @@ #define TRAP_IRQ(routine, level) \ rdpr %pil, %g2; \ - wrpr %g0, 15, %pil; \ + wrpr %g0, PIL_NORMAL_MAX, %pil; \ ba,pt %xcc, etrap_irq; \ rd %pc, %g7; \ mov level, %o0; \ @@ -153,6 +154,16 @@ #endif +#define TRAP_NMI_IRQ(routine, level) \ + rdpr %pil, %g2; \ + wrpr %g0, PIL_NMI, %pil; \ + ba,pt %xcc, etrap_irq; \ + rd %pc, %g7; \ + mov level, %o0; \ + call routine; \ + add %sp, PTREGS_OFF, %o1; \ + ba,a,pt %xcc, rtrap_irq; + #define TRAP_IVEC TRAP_NOSAVE(do_ivec) #define BTRAP(lvl) TRAP_ARG(bad_trap, lvl) diff --git a/arch/sparc/mm/ultra.S b/arch/sparc/mm/ultra.S index e4c146f..80c788e 100644 --- a/arch/sparc/mm/ultra.S +++ b/arch/sparc/mm/ultra.S @@ -466,7 +466,7 @@ xcall_sync_tick: .previous rdpr %pil, %g2 - wrpr %g0, 15, %pil + wrpr %g0, PIL_NORMAL_MAX, %pil sethi %hi(109f), %g7 b,pt %xcc, etrap_irq 109: or %g7, %lo(109b), %g7 @@ -688,7 +688,7 @@ xcall_kgdb_capture: .previous rdpr %pil, %g2 - wrpr %g0, 15, %pil + wrpr %g0, PIL_NORMAL_MAX, %pil sethi %hi(109f), %g7 ba,pt %xcc, etrap_irq 109: or %g7, %lo(109b), %g7 -- cgit v1.1