aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/blackfin/kernel/traps.c38
-rw-r--r--arch/blackfin/mach-common/entry.S42
-rw-r--r--include/asm-blackfin/irq_handler.h8
3 files changed, 66 insertions, 22 deletions
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c
index 0d2052abe41b..1a8a5f171bc8 100644
--- a/arch/blackfin/kernel/traps.c
+++ b/arch/blackfin/kernel/traps.c
@@ -51,8 +51,6 @@ void __init trap_init(void)
51 CSYNC(); 51 CSYNC();
52} 52}
53 53
54asmlinkage void trap_c(struct pt_regs *fp);
55
56int kstack_depth_to_print = 48; 54int kstack_depth_to_print = 48;
57 55
58#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON 56#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON
@@ -693,6 +691,42 @@ asmlinkage int sys_bfin_spinlock(int *spinlock)
693 return ret; 691 return ret;
694} 692}
695 693
694int bfin_request_exception(unsigned int exception, void (*handler)(void))
695{
696 void (*curr_handler)(void);
697
698 if (exception > 0x3F)
699 return -EINVAL;
700
701 curr_handler = ex_table[exception];
702
703 if (curr_handler != ex_replaceable)
704 return -EBUSY;
705
706 ex_table[exception] = handler;
707
708 return 0;
709}
710EXPORT_SYMBOL(bfin_request_exception);
711
712int bfin_free_exception(unsigned int exception, void (*handler)(void))
713{
714 void (*curr_handler)(void);
715
716 if (exception > 0x3F)
717 return -EINVAL;
718
719 curr_handler = ex_table[exception];
720
721 if (curr_handler != handler)
722 return -EBUSY;
723
724 ex_table[exception] = ex_replaceable;
725
726 return 0;
727}
728EXPORT_SYMBOL(bfin_free_exception);
729
696void panic_cplb_error(int cplb_panic, struct pt_regs *fp) 730void panic_cplb_error(int cplb_panic, struct pt_regs *fp)
697{ 731{
698 switch (cplb_panic) { 732 switch (cplb_panic) {
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
index 2188f81c6456..3feca05694f8 100644
--- a/arch/blackfin/mach-common/entry.S
+++ b/arch/blackfin/mach-common/entry.S
@@ -143,7 +143,7 @@ ENTRY(_ex_single_step)
143 cc = r6 == r7; 143 cc = r6 == r7;
144 if !cc jump _ex_trap_c; 144 if !cc jump _ex_trap_c;
145 145
146_return_from_exception: 146ENTRY(_return_from_exception)
147 DEBUG_START_HWTRACE(p5, r7) 147 DEBUG_START_HWTRACE(p5, r7)
148#if ANOMALY_05000257 148#if ANOMALY_05000257
149 R7=LC0; 149 R7=LC0;
@@ -171,6 +171,9 @@ ENTRY(_handle_bad_cplb)
171 [--sp] = ASTAT; 171 [--sp] = ASTAT;
172 [--sp] = (R7:6, P5:4); 172 [--sp] = (R7:6, P5:4);
173 173
174ENTRY(_ex_replaceable)
175 nop;
176
174ENTRY(_ex_trap_c) 177ENTRY(_ex_trap_c)
175 /* Call C code (trap_c) to handle the exception, which most 178 /* Call C code (trap_c) to handle the exception, which most
176 * likely involves sending a signal to the current process. 179 * likely involves sending a signal to the current process.
@@ -298,8 +301,8 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/
298 r6.l = lo(SEQSTAT_EXCAUSE); 301 r6.l = lo(SEQSTAT_EXCAUSE);
299 r6.h = hi(SEQSTAT_EXCAUSE); 302 r6.h = hi(SEQSTAT_EXCAUSE);
300 r7 = r7 & r6; 303 r7 = r7 & r6;
301 p5.h = _extable; 304 p5.h = _ex_table;
302 p5.l = _extable; 305 p5.l = _ex_table;
303 p4 = r7; 306 p4 = r7;
304 p5 = p5 + (p4 << 2); 307 p5 = p5 + (p4 << 2);
305 p4 = [p5]; 308 p4 = [p5];
@@ -818,28 +821,27 @@ ENTRY(_software_trace_buff)
818#else 821#else
819.data 822.data
820#endif 823#endif
821ALIGN 824ENTRY(_ex_table)
822_extable:
823 /* entry for each EXCAUSE[5:0] 825 /* entry for each EXCAUSE[5:0]
824 * This table must be in sync with the table in ./kernel/traps.c 826 * This table must be in sync with the table in ./kernel/traps.c
825 * EXCPT instruction can provide 4 bits of EXCAUSE, allowing 16 to be user defined 827 * EXCPT instruction can provide 4 bits of EXCAUSE, allowing 16 to be user defined
826 */ 828 */
827 .long _ex_syscall; /* 0x00 - User Defined - Linux Syscall */ 829 .long _ex_syscall /* 0x00 - User Defined - Linux Syscall */
828 .long _ex_soft_bp /* 0x01 - User Defined - Software breakpoint */ 830 .long _ex_soft_bp /* 0x01 - User Defined - Software breakpoint */
829 .long _ex_trap_c /* 0x02 - User Defined */ 831 .long _ex_replaceable /* 0x02 - User Defined */
830 .long _ex_trap_c /* 0x03 - User Defined - userspace stack overflow */ 832 .long _ex_trap_c /* 0x03 - User Defined - userspace stack overflow */
831 .long _ex_trap_c /* 0x04 - User Defined */ 833 .long _ex_replaceable /* 0x04 - User Defined */
832 .long _ex_trap_c /* 0x05 - User Defined */ 834 .long _ex_replaceable /* 0x05 - User Defined */
833 .long _ex_trap_c /* 0x06 - User Defined */ 835 .long _ex_replaceable /* 0x06 - User Defined */
834 .long _ex_trap_c /* 0x07 - User Defined */ 836 .long _ex_replaceable /* 0x07 - User Defined */
835 .long _ex_trap_c /* 0x08 - User Defined */ 837 .long _ex_replaceable /* 0x08 - User Defined */
836 .long _ex_trap_c /* 0x09 - User Defined */ 838 .long _ex_replaceable /* 0x09 - User Defined */
837 .long _ex_trap_c /* 0x0A - User Defined */ 839 .long _ex_replaceable /* 0x0A - User Defined */
838 .long _ex_trap_c /* 0x0B - User Defined */ 840 .long _ex_replaceable /* 0x0B - User Defined */
839 .long _ex_trap_c /* 0x0C - User Defined */ 841 .long _ex_replaceable /* 0x0C - User Defined */
840 .long _ex_trap_c /* 0x0D - User Defined */ 842 .long _ex_replaceable /* 0x0D - User Defined */
841 .long _ex_trap_c /* 0x0E - User Defined */ 843 .long _ex_replaceable /* 0x0E - User Defined */
842 .long _ex_trap_c /* 0x0F - User Defined */ 844 .long _ex_replaceable /* 0x0F - User Defined */
843 .long _ex_single_step /* 0x10 - HW Single step */ 845 .long _ex_single_step /* 0x10 - HW Single step */
844#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND 846#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND
845 .long _ex_trace_buff_full /* 0x11 - Trace Buffer Full */ 847 .long _ex_trace_buff_full /* 0x11 - Trace Buffer Full */
@@ -893,8 +895,8 @@ _extable:
893 .long _ex_trap_c /* 0x3D - Reserved */ 895 .long _ex_trap_c /* 0x3D - Reserved */
894 .long _ex_trap_c /* 0x3E - Reserved */ 896 .long _ex_trap_c /* 0x3E - Reserved */
895 .long _ex_trap_c /* 0x3F - Reserved */ 897 .long _ex_trap_c /* 0x3F - Reserved */
898END(_ex_table)
896 899
897ALIGN
898ENTRY(_sys_call_table) 900ENTRY(_sys_call_table)
899 .long _sys_restart_syscall /* 0 */ 901 .long _sys_restart_syscall /* 0 */
900 .long _sys_exit 902 .long _sys_exit
diff --git a/include/asm-blackfin/irq_handler.h b/include/asm-blackfin/irq_handler.h
index f13cd73b0966..19534c133c93 100644
--- a/include/asm-blackfin/irq_handler.h
+++ b/include/asm-blackfin/irq_handler.h
@@ -20,5 +20,13 @@ asmlinkage void evt_evt13(void);
20asmlinkage void evt_soft_int1(void); 20asmlinkage void evt_soft_int1(void);
21asmlinkage void evt_system_call(void); 21asmlinkage void evt_system_call(void);
22asmlinkage void init_exception_buff(void); 22asmlinkage void init_exception_buff(void);
23asmlinkage void trap_c(struct pt_regs *fp);
24asmlinkage void ex_replaceable(void);
25
26extern void *ex_table[];
27extern void return_from_exception(void);
28
29extern int bfin_request_exception(unsigned int exception, void (*handler)(void));
30extern int bfin_free_exception(unsigned int exception, void (*handler)(void));
23 31
24#endif 32#endif