]> err.no Git - linux-2.6/commitdiff
Blackfin arch: allow people to select the feature that is unavailable to the kernel
authorMike Frysinger <michael.frysinger@analog.com>
Sun, 5 Aug 2007 09:03:59 +0000 (17:03 +0800)
committerBryan Wu <bryan.wu@analog.com>
Sun, 5 Aug 2007 09:03:59 +0000 (17:03 +0800)
 - allow people to select the feature that is unavailable to the kernel: NMI, JTAG, or CYCLES.
 - change default NMI handler to simply dump hardware trace buffer.
 - remove default NMI handler completely as calling into kernel code is not safe
   move example handler to wiki so people dont haphazardly copy and paste this stuff thinking its safe

Signed-off-by: Mike Frysinger <michael.frysinger@analog.com>
Signed-off-by: Bryan Wu <bryan.wu@analog.com>
arch/blackfin/Kconfig
arch/blackfin/kernel/irqchip.c
arch/blackfin/mach-bf533/head.S
arch/blackfin/mach-bf537/head.S
arch/blackfin/mach-bf548/head.S
arch/blackfin/mach-bf561/head.S
arch/blackfin/mach-common/entry.S
arch/blackfin/mach-common/interrupt.S
arch/blackfin/mach-common/ints-priority-dc.c
arch/blackfin/mach-common/ints-priority-sc.c
include/asm-blackfin/irq_handler.h

index cdce8cc5b7b32bd3bc15e3b09b59fb0c7a879b65..26ebb0e8c43165c503eb96191544bdd37bee3a63 100644 (file)
@@ -521,6 +521,52 @@ config BFIN_IDLE_LED_NUM
        help
          Select the LED (marked on the board) for you to blink.
 
+choice
+       prompt "Blackfin Exception Scratch Register"
+       default BFIN_SCRATCH_REG_RETN
+       help
+         Select the resource to reserve for the Exception handler:
+           - RETN: Non-Maskable Interrupt (NMI)
+           - RETE: Exception Return (JTAG/ICE)
+           - CYCLES: Performance counter
+
+         If you are unsure, please select "RETN".
+
+config BFIN_SCRATCH_REG_RETN
+       bool "RETN"
+       help
+         Use the RETN register in the Blackfin exception handler
+         as a stack scratch register.  This means you cannot
+         safely use NMI on the Blackfin while running Linux, but
+         you can debug the system with a JTAG ICE and use the
+         CYCLES performance registers.
+
+         If you are unsure, please select "RETN".
+
+config BFIN_SCRATCH_REG_RETE
+       bool "RETE"
+       help
+         Use the RETE register in the Blackfin exception handler
+         as a stack scratch register.  This means you cannot
+         safely use a JTAG ICE while debugging a Blackfin board,
+         but you can safely use the CYCLES performance registers
+         and the NMI.
+
+         If you are unsure, please select "RETN".
+
+config BFIN_SCRATCH_REG_CYCLES
+       bool "CYCLES"
+       help
+         Use the CYCLES register in the Blackfin exception handler
+         as a stack scratch register.  This means you cannot
+         safely use the CYCLES performance registers on a Blackfin
+         board at anytime, but you can debug the system with a JTAG
+         ICE and use the NMI.
+
+         If you are unsure, please select "RETN".
+
+endchoice
+
 #
 # Sorry - but you need to put the hex address here -
 #
index 462ae41144c7deec2aaa946489acde62e4117b18..73647c158774e0acd31efcf3e7385dd2b104365a 100644 (file)
@@ -98,9 +98,8 @@ int show_interrupts(struct seq_file *p, void *v)
  */
 
 #ifdef CONFIG_DO_IRQ_L1
-asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)__attribute__((l1_text));
+__attribute__((l1_text))
 #endif
-
 asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
 {
        struct pt_regs *old_regs;
index 1d5b9dbbbaa741f0000e0378755c1b0152943020..3be6feefa8a9eca9c61486dfff7a156edc6c8430 100644 (file)
@@ -53,10 +53,12 @@ __INIT
 ENTRY(__start)
        /* R0: argument of command line string, passed from uboot, save it */
        R7 = R0;
-       /* Set the SYSCFG register:
-        * Enable Cycle Counter and Nesting Of Interrupts (3rd Bit)
-        */
-       R0 = 0x36;
+       /* Enable Cycle Counter and Nesting Of Interrupts */
+#ifdef CONFIG_BFIN_SCRATCH_REG_CYCLES
+       R0 = SYSCFG_SNEN;
+#else
+       R0 = SYSCFG_SNEN | SYSCFG_CCEN;
+#endif
        SYSCFG = R0;
        R0 = 0;
 
index 6dbcb77c8d365fe7429b8817ec1f13f67f30d3cc..0836bfdcc6c5cd8dc5dc6b430159fbfd071b1a3d 100644 (file)
@@ -51,10 +51,12 @@ __INIT
 ENTRY(__start)
        /* R0: argument of command line string, passed from uboot, save it */
        R7 = R0;
-       /* Set the SYSCFG register:
-        * Enable Cycle Counter and Nesting Of Interrupts (3rd Bit)
-        */
-       R0 = 0x36;
+       /* Enable Cycle Counter and Nesting Of Interrupts */
+#ifdef CONFIG_BFIN_SCRATCH_REG_CYCLES
+       R0 = SYSCFG_SNEN;
+#else
+       R0 = SYSCFG_SNEN | SYSCFG_CCEN;
+#endif
        SYSCFG = R0;
        R0 = 0;
 
index 4c7d49f4118768b8eb86fbcc1fec87cf612412ec..937fbef26a5178a348ffba019c61ff8ba6f3c9ee 100644 (file)
@@ -50,9 +50,13 @@ ENTRY(__start)
 ENTRY(__stext)
        /* R0: argument of command line string, passed from uboot, save it */
        R7 = R0;
-       /* Set the SYSCFG register */
-       R0 = 0x36;
-       SYSCFG = R0;   /*Enable Cycle Counter and Nesting Of Interrupts(3rd Bit)*/
+       /* Enable Cycle Counter and Nesting Of Interrupts */
+#ifdef CONFIG_BFIN_SCRATCH_REG_CYCLES
+       R0 = SYSCFG_SNEN;
+#else
+       R0 = SYSCFG_SNEN | SYSCFG_CCEN;
+#endif
+       SYSCFG = R0;
        R0 = 0;
 
        /* Clear Out All the data and pointer  Registers*/
index 8c9f73b8e579dc22071cb9546e3a97d64fbd209a..139f4cff801ba3c1ffea2eb411afc71e9521d254 100644 (file)
@@ -51,10 +51,12 @@ __INIT
 ENTRY(__start)
        /* R0: argument of command line string, passed from uboot, save it */
        R7 = R0;
-       /* Set the SYSCFG register:
-        * Enable Cycle Counter and Nesting Of Interrupts (3rd Bit)
-        */
-       R0 = 0x36;
+       /* Enable Cycle Counter and Nesting Of Interrupts */
+#ifdef CONFIG_BFIN_SCRATCH_REG_CYCLES
+       R0 = SYSCFG_SNEN;
+#else
+       R0 = SYSCFG_SNEN | SYSCFG_CCEN;
+#endif
        SYSCFG = R0;
        R0 = 0;
 
index ab278a72f282aae4df5a004e8c84be78f5145f18..2188f81c645677a107392c225c5bbc348608c752 100644 (file)
 
 #include <asm/mach-common/context.S>
 
+#if defined(CONFIG_BFIN_SCRATCH_REG_RETN)
+# define EX_SCRATCH_REG RETN
+#elif defined(CONFIG_BFIN_SCRATCH_REG_RETE)
+# define EX_SCRATCH_REG RETE
+#else
+# define EX_SCRATCH_REG CYCLES
+#endif
+
 #ifdef CONFIG_EXCPT_IRQ_SYSC_L1
 .section .l1.text
 #else
@@ -93,7 +101,7 @@ ENTRY(_ex_icplb)
        call __cplb_hdr;
        DEBUG_START_HWTRACE(p5, r7)
        RESTORE_ALL_SYS
-       SP = RETN;
+       SP = EX_SCRATCH_REG;
        rtx;
 ENDPROC(_ex_icplb)
 
@@ -102,7 +110,7 @@ ENTRY(_ex_syscall)
        (R7:6,P5:4) = [sp++];
        ASTAT = [sp++];
        raise 15;               /* invoked by TRAP #0, for sys call */
-       sp = retn;
+       sp = EX_SCRATCH_REG;
        rtx
 ENDPROC(_ex_syscall)
 
@@ -145,7 +153,7 @@ _return_from_exception:
 #endif
        (R7:6,P5:4) = [sp++];
        ASTAT = [sp++];
-       sp = retn;
+       sp = EX_SCRATCH_REG;
        rtx;
 ENDPROC(_ex_soft_bp)
 
@@ -204,7 +212,7 @@ ENTRY(_ex_trap_c)
        DEBUG_START_HWTRACE(p5, r7)
        (R7:6,P5:4) = [sp++];
        ASTAT = [sp++];
-       SP = RETN;
+       SP = EX_SCRATCH_REG;
        raise 5;
        rtx;
 ENDPROC(_ex_trap_c)
@@ -279,7 +287,7 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/
         * covered by a CPLB.  Switch to an exception stack; use RETN as a
         * scratch register (for want of a better option).
         */
-       retn = sp;
+       EX_SCRATCH_REG = sp;
        sp.l = _exception_stack_top;
        sp.h = _exception_stack_top;
        /* Try to deal with syscalls quickly.  */
index 1d5ba5e3d91c5b9dc5481f5f81d95d63fcaf28ea..c6b32fe0f6e9f0b2cc12ebcaa3fd28e4e6ed89ef 100644 (file)
@@ -177,27 +177,15 @@ ENTRY(_evt_ivhw)
        jump .Lcommon_restore_context;
 #endif
 
-/* interrupt routine for evt2 - 2.  This is NMI.  */
-ENTRY(_evt_evt2)
-       SAVE_CONTEXT
-#ifdef CONFIG_FRAME_POINTER
-       fp = 0;
-#endif
-#if ANOMALY_05000283
-       cc = r7 == r7;
-       p5.h = 0xffc0;
-       p5.l = 0x0014;
-       if cc jump 1f;
-       r7.l = W[p5];
-1:
-#endif
-       r0 = IRQ_NMI;
-       r1 =  sp;
-       SP += -12;
-       call _asm_do_IRQ;
-       SP += 12;
-       RESTORE_CONTEXT
+/* Interrupt routine for evt2 (NMI).
+ * We don't actually use this, so just return.
+ * For inner circle type details, please see:
+ * http://docs.blackfin.uclinux.org/doku.php?id=linux:nmi
+ */
+ENTRY(_evt_nmi)
+.weak _evt_nmi
        rtn;
+ENDPROC(_evt_nmi)
 
 /* interrupt routine for core timer - 6 */
 ENTRY(_evt_timer)
index 684d306ab6bb0089a7a94f856b1c0550a74d952e..2db3546fc874f73804cd360c6d46c16c99262b5a 100644 (file)
@@ -362,7 +362,11 @@ void __init init_exception_vectors(void)
 {
        SSYNC();
 
-       bfin_write_EVT2(evt_evt2);
+       /* cannot program in software:
+        * evt0 - emulation (jtag)
+        * evt1 - reset
+        */
+       bfin_write_EVT2(evt_nmi);
        bfin_write_EVT3(trap);
        bfin_write_EVT5(evt_ivhw);
        bfin_write_EVT6(evt_timer);
index a2016af65eb0fe56c3420acdda5c0e554b7fef79..d3b7672b2b94ce91dd970c9ce30490cdf4362bae 100644 (file)
@@ -721,7 +721,11 @@ void __init init_exception_vectors(void)
 {
        SSYNC();
 
-       bfin_write_EVT2(evt_evt2);
+       /* cannot program in software:
+        * evt0 - emulation (jtag)
+        * evt1 - reset
+        */
+       bfin_write_EVT2(evt_nmi);
        bfin_write_EVT3(trap);
        bfin_write_EVT5(evt_ivhw);
        bfin_write_EVT6(evt_timer);
index 6a768315bbf7959b6c960942756e61ae26790adc..f13cd73b0966229b444901ad2f9d04ec1e0529f1 100644 (file)
@@ -1,12 +1,15 @@
 #ifndef _IRQ_HANDLER_H
 #define _IRQ_HANDLER_H
 
+#include <linux/types.h>
+#include <linux/linkage.h>
+
 /* BASE LEVEL interrupt handler routines */
 asmlinkage void evt_exception(void);
 asmlinkage void trap(void);
 asmlinkage void evt_ivhw(void);
 asmlinkage void evt_timer(void);
-asmlinkage void evt_evt2(void);
+asmlinkage void evt_nmi(void);
 asmlinkage void evt_evt7(void);
 asmlinkage void evt_evt8(void);
 asmlinkage void evt_evt9(void);