diff options
author | Mike Frysinger <michael.frysinger@analog.com> | 2007-08-05 05:03:59 -0400 |
---|---|---|
committer | Bryan Wu <bryan.wu@analog.com> | 2007-08-05 05:03:59 -0400 |
commit | f0b5d12f2b3226c85258519d7725e63d9daf5e90 (patch) | |
tree | d64fdcf65cb5f647b544ece5f1727af5153c0a3d /arch/blackfin | |
parent | 0174dd59bb5f343e8981b5ea7a3dc782fad5b644 (diff) |
Blackfin arch: allow people to select the feature that is unavailable to the kernel
- 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>
Diffstat (limited to 'arch/blackfin')
-rw-r--r-- | arch/blackfin/Kconfig | 46 | ||||
-rw-r--r-- | arch/blackfin/kernel/irqchip.c | 3 | ||||
-rw-r--r-- | arch/blackfin/mach-bf533/head.S | 10 | ||||
-rw-r--r-- | arch/blackfin/mach-bf537/head.S | 10 | ||||
-rw-r--r-- | arch/blackfin/mach-bf548/head.S | 10 | ||||
-rw-r--r-- | arch/blackfin/mach-bf561/head.S | 10 | ||||
-rw-r--r-- | arch/blackfin/mach-common/entry.S | 18 | ||||
-rw-r--r-- | arch/blackfin/mach-common/interrupt.S | 28 | ||||
-rw-r--r-- | arch/blackfin/mach-common/ints-priority-dc.c | 6 | ||||
-rw-r--r-- | arch/blackfin/mach-common/ints-priority-sc.c | 6 |
10 files changed, 103 insertions, 44 deletions
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index cdce8cc5b7b..26ebb0e8c43 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig | |||
@@ -521,6 +521,52 @@ config BFIN_IDLE_LED_NUM | |||
521 | help | 521 | help |
522 | Select the LED (marked on the board) for you to blink. | 522 | Select the LED (marked on the board) for you to blink. |
523 | 523 | ||
524 | choice | ||
525 | prompt "Blackfin Exception Scratch Register" | ||
526 | default BFIN_SCRATCH_REG_RETN | ||
527 | help | ||
528 | Select the resource to reserve for the Exception handler: | ||
529 | - RETN: Non-Maskable Interrupt (NMI) | ||
530 | - RETE: Exception Return (JTAG/ICE) | ||
531 | - CYCLES: Performance counter | ||
532 | |||
533 | If you are unsure, please select "RETN". | ||
534 | |||
535 | config BFIN_SCRATCH_REG_RETN | ||
536 | bool "RETN" | ||
537 | help | ||
538 | Use the RETN register in the Blackfin exception handler | ||
539 | as a stack scratch register. This means you cannot | ||
540 | safely use NMI on the Blackfin while running Linux, but | ||
541 | you can debug the system with a JTAG ICE and use the | ||
542 | CYCLES performance registers. | ||
543 | |||
544 | If you are unsure, please select "RETN". | ||
545 | |||
546 | config BFIN_SCRATCH_REG_RETE | ||
547 | bool "RETE" | ||
548 | help | ||
549 | Use the RETE register in the Blackfin exception handler | ||
550 | as a stack scratch register. This means you cannot | ||
551 | safely use a JTAG ICE while debugging a Blackfin board, | ||
552 | but you can safely use the CYCLES performance registers | ||
553 | and the NMI. | ||
554 | |||
555 | If you are unsure, please select "RETN". | ||
556 | |||
557 | config BFIN_SCRATCH_REG_CYCLES | ||
558 | bool "CYCLES" | ||
559 | help | ||
560 | Use the CYCLES register in the Blackfin exception handler | ||
561 | as a stack scratch register. This means you cannot | ||
562 | safely use the CYCLES performance registers on a Blackfin | ||
563 | board at anytime, but you can debug the system with a JTAG | ||
564 | ICE and use the NMI. | ||
565 | |||
566 | If you are unsure, please select "RETN". | ||
567 | |||
568 | endchoice | ||
569 | |||
524 | # | 570 | # |
525 | # Sorry - but you need to put the hex address here - | 571 | # Sorry - but you need to put the hex address here - |
526 | # | 572 | # |
diff --git a/arch/blackfin/kernel/irqchip.c b/arch/blackfin/kernel/irqchip.c index 462ae41144c..73647c15877 100644 --- a/arch/blackfin/kernel/irqchip.c +++ b/arch/blackfin/kernel/irqchip.c | |||
@@ -98,9 +98,8 @@ int show_interrupts(struct seq_file *p, void *v) | |||
98 | */ | 98 | */ |
99 | 99 | ||
100 | #ifdef CONFIG_DO_IRQ_L1 | 100 | #ifdef CONFIG_DO_IRQ_L1 |
101 | asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)__attribute__((l1_text)); | 101 | __attribute__((l1_text)) |
102 | #endif | 102 | #endif |
103 | |||
104 | asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs) | 103 | asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs) |
105 | { | 104 | { |
106 | struct pt_regs *old_regs; | 105 | struct pt_regs *old_regs; |
diff --git a/arch/blackfin/mach-bf533/head.S b/arch/blackfin/mach-bf533/head.S index 1d5b9dbbbaa..3be6feefa8a 100644 --- a/arch/blackfin/mach-bf533/head.S +++ b/arch/blackfin/mach-bf533/head.S | |||
@@ -53,10 +53,12 @@ __INIT | |||
53 | ENTRY(__start) | 53 | ENTRY(__start) |
54 | /* R0: argument of command line string, passed from uboot, save it */ | 54 | /* R0: argument of command line string, passed from uboot, save it */ |
55 | R7 = R0; | 55 | R7 = R0; |
56 | /* Set the SYSCFG register: | 56 | /* Enable Cycle Counter and Nesting Of Interrupts */ |
57 | * Enable Cycle Counter and Nesting Of Interrupts (3rd Bit) | 57 | #ifdef CONFIG_BFIN_SCRATCH_REG_CYCLES |
58 | */ | 58 | R0 = SYSCFG_SNEN; |
59 | R0 = 0x36; | 59 | #else |
60 | R0 = SYSCFG_SNEN | SYSCFG_CCEN; | ||
61 | #endif | ||
60 | SYSCFG = R0; | 62 | SYSCFG = R0; |
61 | R0 = 0; | 63 | R0 = 0; |
62 | 64 | ||
diff --git a/arch/blackfin/mach-bf537/head.S b/arch/blackfin/mach-bf537/head.S index 6dbcb77c8d3..0836bfdcc6c 100644 --- a/arch/blackfin/mach-bf537/head.S +++ b/arch/blackfin/mach-bf537/head.S | |||
@@ -51,10 +51,12 @@ __INIT | |||
51 | ENTRY(__start) | 51 | ENTRY(__start) |
52 | /* R0: argument of command line string, passed from uboot, save it */ | 52 | /* R0: argument of command line string, passed from uboot, save it */ |
53 | R7 = R0; | 53 | R7 = R0; |
54 | /* Set the SYSCFG register: | 54 | /* Enable Cycle Counter and Nesting Of Interrupts */ |
55 | * Enable Cycle Counter and Nesting Of Interrupts (3rd Bit) | 55 | #ifdef CONFIG_BFIN_SCRATCH_REG_CYCLES |
56 | */ | 56 | R0 = SYSCFG_SNEN; |
57 | R0 = 0x36; | 57 | #else |
58 | R0 = SYSCFG_SNEN | SYSCFG_CCEN; | ||
59 | #endif | ||
58 | SYSCFG = R0; | 60 | SYSCFG = R0; |
59 | R0 = 0; | 61 | R0 = 0; |
60 | 62 | ||
diff --git a/arch/blackfin/mach-bf548/head.S b/arch/blackfin/mach-bf548/head.S index 4c7d49f4118..937fbef26a5 100644 --- a/arch/blackfin/mach-bf548/head.S +++ b/arch/blackfin/mach-bf548/head.S | |||
@@ -50,9 +50,13 @@ ENTRY(__start) | |||
50 | ENTRY(__stext) | 50 | ENTRY(__stext) |
51 | /* R0: argument of command line string, passed from uboot, save it */ | 51 | /* R0: argument of command line string, passed from uboot, save it */ |
52 | R7 = R0; | 52 | R7 = R0; |
53 | /* Set the SYSCFG register */ | 53 | /* Enable Cycle Counter and Nesting Of Interrupts */ |
54 | R0 = 0x36; | 54 | #ifdef CONFIG_BFIN_SCRATCH_REG_CYCLES |
55 | SYSCFG = R0; /*Enable Cycle Counter and Nesting Of Interrupts(3rd Bit)*/ | 55 | R0 = SYSCFG_SNEN; |
56 | #else | ||
57 | R0 = SYSCFG_SNEN | SYSCFG_CCEN; | ||
58 | #endif | ||
59 | SYSCFG = R0; | ||
56 | R0 = 0; | 60 | R0 = 0; |
57 | 61 | ||
58 | /* Clear Out All the data and pointer Registers*/ | 62 | /* Clear Out All the data and pointer Registers*/ |
diff --git a/arch/blackfin/mach-bf561/head.S b/arch/blackfin/mach-bf561/head.S index 8c9f73b8e57..139f4cff801 100644 --- a/arch/blackfin/mach-bf561/head.S +++ b/arch/blackfin/mach-bf561/head.S | |||
@@ -51,10 +51,12 @@ __INIT | |||
51 | ENTRY(__start) | 51 | ENTRY(__start) |
52 | /* R0: argument of command line string, passed from uboot, save it */ | 52 | /* R0: argument of command line string, passed from uboot, save it */ |
53 | R7 = R0; | 53 | R7 = R0; |
54 | /* Set the SYSCFG register: | 54 | /* Enable Cycle Counter and Nesting Of Interrupts */ |
55 | * Enable Cycle Counter and Nesting Of Interrupts (3rd Bit) | 55 | #ifdef CONFIG_BFIN_SCRATCH_REG_CYCLES |
56 | */ | 56 | R0 = SYSCFG_SNEN; |
57 | R0 = 0x36; | 57 | #else |
58 | R0 = SYSCFG_SNEN | SYSCFG_CCEN; | ||
59 | #endif | ||
58 | SYSCFG = R0; | 60 | SYSCFG = R0; |
59 | R0 = 0; | 61 | R0 = 0; |
60 | 62 | ||
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index ab278a72f28..2188f81c645 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S | |||
@@ -58,6 +58,14 @@ | |||
58 | 58 | ||
59 | #include <asm/mach-common/context.S> | 59 | #include <asm/mach-common/context.S> |
60 | 60 | ||
61 | #if defined(CONFIG_BFIN_SCRATCH_REG_RETN) | ||
62 | # define EX_SCRATCH_REG RETN | ||
63 | #elif defined(CONFIG_BFIN_SCRATCH_REG_RETE) | ||
64 | # define EX_SCRATCH_REG RETE | ||
65 | #else | ||
66 | # define EX_SCRATCH_REG CYCLES | ||
67 | #endif | ||
68 | |||
61 | #ifdef CONFIG_EXCPT_IRQ_SYSC_L1 | 69 | #ifdef CONFIG_EXCPT_IRQ_SYSC_L1 |
62 | .section .l1.text | 70 | .section .l1.text |
63 | #else | 71 | #else |
@@ -93,7 +101,7 @@ ENTRY(_ex_icplb) | |||
93 | call __cplb_hdr; | 101 | call __cplb_hdr; |
94 | DEBUG_START_HWTRACE(p5, r7) | 102 | DEBUG_START_HWTRACE(p5, r7) |
95 | RESTORE_ALL_SYS | 103 | RESTORE_ALL_SYS |
96 | SP = RETN; | 104 | SP = EX_SCRATCH_REG; |
97 | rtx; | 105 | rtx; |
98 | ENDPROC(_ex_icplb) | 106 | ENDPROC(_ex_icplb) |
99 | 107 | ||
@@ -102,7 +110,7 @@ ENTRY(_ex_syscall) | |||
102 | (R7:6,P5:4) = [sp++]; | 110 | (R7:6,P5:4) = [sp++]; |
103 | ASTAT = [sp++]; | 111 | ASTAT = [sp++]; |
104 | raise 15; /* invoked by TRAP #0, for sys call */ | 112 | raise 15; /* invoked by TRAP #0, for sys call */ |
105 | sp = retn; | 113 | sp = EX_SCRATCH_REG; |
106 | rtx | 114 | rtx |
107 | ENDPROC(_ex_syscall) | 115 | ENDPROC(_ex_syscall) |
108 | 116 | ||
@@ -145,7 +153,7 @@ _return_from_exception: | |||
145 | #endif | 153 | #endif |
146 | (R7:6,P5:4) = [sp++]; | 154 | (R7:6,P5:4) = [sp++]; |
147 | ASTAT = [sp++]; | 155 | ASTAT = [sp++]; |
148 | sp = retn; | 156 | sp = EX_SCRATCH_REG; |
149 | rtx; | 157 | rtx; |
150 | ENDPROC(_ex_soft_bp) | 158 | ENDPROC(_ex_soft_bp) |
151 | 159 | ||
@@ -204,7 +212,7 @@ ENTRY(_ex_trap_c) | |||
204 | DEBUG_START_HWTRACE(p5, r7) | 212 | DEBUG_START_HWTRACE(p5, r7) |
205 | (R7:6,P5:4) = [sp++]; | 213 | (R7:6,P5:4) = [sp++]; |
206 | ASTAT = [sp++]; | 214 | ASTAT = [sp++]; |
207 | SP = RETN; | 215 | SP = EX_SCRATCH_REG; |
208 | raise 5; | 216 | raise 5; |
209 | rtx; | 217 | rtx; |
210 | ENDPROC(_ex_trap_c) | 218 | ENDPROC(_ex_trap_c) |
@@ -279,7 +287,7 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/ | |||
279 | * covered by a CPLB. Switch to an exception stack; use RETN as a | 287 | * covered by a CPLB. Switch to an exception stack; use RETN as a |
280 | * scratch register (for want of a better option). | 288 | * scratch register (for want of a better option). |
281 | */ | 289 | */ |
282 | retn = sp; | 290 | EX_SCRATCH_REG = sp; |
283 | sp.l = _exception_stack_top; | 291 | sp.l = _exception_stack_top; |
284 | sp.h = _exception_stack_top; | 292 | sp.h = _exception_stack_top; |
285 | /* Try to deal with syscalls quickly. */ | 293 | /* Try to deal with syscalls quickly. */ |
diff --git a/arch/blackfin/mach-common/interrupt.S b/arch/blackfin/mach-common/interrupt.S index 1d5ba5e3d91..c6b32fe0f6e 100644 --- a/arch/blackfin/mach-common/interrupt.S +++ b/arch/blackfin/mach-common/interrupt.S | |||
@@ -177,27 +177,15 @@ ENTRY(_evt_ivhw) | |||
177 | jump .Lcommon_restore_context; | 177 | jump .Lcommon_restore_context; |
178 | #endif | 178 | #endif |
179 | 179 | ||
180 | /* interrupt routine for evt2 - 2. This is NMI. */ | 180 | /* Interrupt routine for evt2 (NMI). |
181 | ENTRY(_evt_evt2) | 181 | * We don't actually use this, so just return. |
182 | SAVE_CONTEXT | 182 | * For inner circle type details, please see: |
183 | #ifdef CONFIG_FRAME_POINTER | 183 | * http://docs.blackfin.uclinux.org/doku.php?id=linux:nmi |
184 | fp = 0; | 184 | */ |
185 | #endif | 185 | ENTRY(_evt_nmi) |
186 | #if ANOMALY_05000283 | 186 | .weak _evt_nmi |
187 | cc = r7 == r7; | ||
188 | p5.h = 0xffc0; | ||
189 | p5.l = 0x0014; | ||
190 | if cc jump 1f; | ||
191 | r7.l = W[p5]; | ||
192 | 1: | ||
193 | #endif | ||
194 | r0 = IRQ_NMI; | ||
195 | r1 = sp; | ||
196 | SP += -12; | ||
197 | call _asm_do_IRQ; | ||
198 | SP += 12; | ||
199 | RESTORE_CONTEXT | ||
200 | rtn; | 187 | rtn; |
188 | ENDPROC(_evt_nmi) | ||
201 | 189 | ||
202 | /* interrupt routine for core timer - 6 */ | 190 | /* interrupt routine for core timer - 6 */ |
203 | ENTRY(_evt_timer) | 191 | ENTRY(_evt_timer) |
diff --git a/arch/blackfin/mach-common/ints-priority-dc.c b/arch/blackfin/mach-common/ints-priority-dc.c index 684d306ab6b..2db3546fc87 100644 --- a/arch/blackfin/mach-common/ints-priority-dc.c +++ b/arch/blackfin/mach-common/ints-priority-dc.c | |||
@@ -362,7 +362,11 @@ void __init init_exception_vectors(void) | |||
362 | { | 362 | { |
363 | SSYNC(); | 363 | SSYNC(); |
364 | 364 | ||
365 | bfin_write_EVT2(evt_evt2); | 365 | /* cannot program in software: |
366 | * evt0 - emulation (jtag) | ||
367 | * evt1 - reset | ||
368 | */ | ||
369 | bfin_write_EVT2(evt_nmi); | ||
366 | bfin_write_EVT3(trap); | 370 | bfin_write_EVT3(trap); |
367 | bfin_write_EVT5(evt_ivhw); | 371 | bfin_write_EVT5(evt_ivhw); |
368 | bfin_write_EVT6(evt_timer); | 372 | bfin_write_EVT6(evt_timer); |
diff --git a/arch/blackfin/mach-common/ints-priority-sc.c b/arch/blackfin/mach-common/ints-priority-sc.c index a2016af65eb..d3b7672b2b9 100644 --- a/arch/blackfin/mach-common/ints-priority-sc.c +++ b/arch/blackfin/mach-common/ints-priority-sc.c | |||
@@ -721,7 +721,11 @@ void __init init_exception_vectors(void) | |||
721 | { | 721 | { |
722 | SSYNC(); | 722 | SSYNC(); |
723 | 723 | ||
724 | bfin_write_EVT2(evt_evt2); | 724 | /* cannot program in software: |
725 | * evt0 - emulation (jtag) | ||
726 | * evt1 - reset | ||
727 | */ | ||
728 | bfin_write_EVT2(evt_nmi); | ||
725 | bfin_write_EVT3(trap); | 729 | bfin_write_EVT3(trap); |
726 | bfin_write_EVT5(evt_ivhw); | 730 | bfin_write_EVT5(evt_ivhw); |
727 | bfin_write_EVT6(evt_timer); | 731 | bfin_write_EVT6(evt_timer); |