diff options
author | Mike Frysinger <michael.frysinger@analog.com> | 2007-08-05 05:14:04 -0400 |
---|---|---|
committer | Bryan Wu <bryan.wu@analog.com> | 2007-08-05 05:14:04 -0400 |
commit | 1ffe6646babf8471714e649849ec2c9662bf410c (patch) | |
tree | cc10996b2dd08ac783a4621fffb650e23b66bb2e | |
parent | dbcc78bebe9daed8998d9f7c4e30bd3b73a4a169 (diff) |
Blackfin arch: add an exception request/free api
add an exception request/free api similar to the interrupt request/fre
api so people can utilize the free software based exceptions for their
own purposes
Signed-off-by: Mike Frysinger <michael.frysinger@analog.com>
Signed-off-by: Bryan Wu <bryan.wu@analog.com>
-rw-r--r-- | arch/blackfin/kernel/traps.c | 38 | ||||
-rw-r--r-- | arch/blackfin/mach-common/entry.S | 42 | ||||
-rw-r--r-- | include/asm-blackfin/irq_handler.h | 8 |
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 | ||
54 | asmlinkage void trap_c(struct pt_regs *fp); | ||
55 | |||
56 | int kstack_depth_to_print = 48; | 54 | int 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 | ||
694 | int 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 | } | ||
710 | EXPORT_SYMBOL(bfin_request_exception); | ||
711 | |||
712 | int 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 | } | ||
728 | EXPORT_SYMBOL(bfin_free_exception); | ||
729 | |||
696 | void panic_cplb_error(int cplb_panic, struct pt_regs *fp) | 730 | void 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: | 146 | ENTRY(_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 | ||
174 | ENTRY(_ex_replaceable) | ||
175 | nop; | ||
176 | |||
174 | ENTRY(_ex_trap_c) | 177 | ENTRY(_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 |
821 | ALIGN | 824 | ENTRY(_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 */ |
898 | END(_ex_table) | ||
896 | 899 | ||
897 | ALIGN | ||
898 | ENTRY(_sys_call_table) | 900 | ENTRY(_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); | |||
20 | asmlinkage void evt_soft_int1(void); | 20 | asmlinkage void evt_soft_int1(void); |
21 | asmlinkage void evt_system_call(void); | 21 | asmlinkage void evt_system_call(void); |
22 | asmlinkage void init_exception_buff(void); | 22 | asmlinkage void init_exception_buff(void); |
23 | asmlinkage void trap_c(struct pt_regs *fp); | ||
24 | asmlinkage void ex_replaceable(void); | ||
25 | |||
26 | extern void *ex_table[]; | ||
27 | extern void return_from_exception(void); | ||
28 | |||
29 | extern int bfin_request_exception(unsigned int exception, void (*handler)(void)); | ||
30 | extern int bfin_free_exception(unsigned int exception, void (*handler)(void)); | ||
23 | 31 | ||
24 | #endif | 32 | #endif |