diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-11 19:11:51 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-11 19:11:51 -0700 |
commit | 1ef3e36251e4edc77a48967d015a87ca3c4283ea (patch) | |
tree | 2ee6c869d752c13a56ee2259d115210135f5d5de /arch/blackfin/kernel/traps.c | |
parent | c634920abaf9c0a93266a57beff6fce9d3852cb2 (diff) | |
parent | bbf275f092b1b2a9bc8a504500ec387f9ddff859 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/blackfin-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/blackfin-2.6: (74 commits)
Blackfin serial driver: pending a unique anomaly id, tie the break flood issue to ANOMALY_05000230
blackfin enable arbitary speed serial setting
Blackfin arch: Remove cruft - CONFIG_DEBUG_SERIAL_EARLY_INIT and DEBUG_KERNEL_START
Blackfin arch: fix typo in register name
Blackfin arch: trim the Blackfin arch MAINTAINERS list
Blackfin arch: fix bug libstdc++ calling writev with an iovec containing { NULL, 0 } fails on Blackfin
Blackfin arch: Export strcpy - occasionally get module link failures otherwise
Blackfin arch: the load address is not safe to point to as a workaround for ANOMALY 05000281
Blackfin arch: show_mem can not be marked as init, since it is called during OOM condition
Blackfin arch: flush/inv the correct range when using write back cache and fix bugs find by dmacopy
Blackfin arch: update kgdb patch
Blackfin arch: Comply with revised Anomaly Workarounds for BF533 05000311 and BF561 05000323
Blackfin arch: Print out debug info, as early as possible
Blackfin arch: Enable earlyprintk earlier - so any error after our interrupt tables are set up will print out
Blackfin arch: fix endless loop bug when a double fault happens
Blackfin arch: Initial patch to add earlyprintk support
Blackfin arch: add TWIx_REGBASE and SPIx_REGBASE to specific CPU header files, use the new REGBASE for board platform resources
Blackfin arch: modify the insX/outsX and dma_insX/dma_outsX to be compatible with other archs
Blackfin arch: add more common defines for output sections
Blackfin arch: cleanup IO and DMA_IO API function definitions according to other arches
...
Diffstat (limited to 'arch/blackfin/kernel/traps.c')
-rw-r--r-- | arch/blackfin/kernel/traps.c | 110 |
1 files changed, 95 insertions, 15 deletions
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index 792a8416fe10..8823e9ade584 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c @@ -51,10 +51,9 @@ void __init trap_init(void) CSYNC(); } -asmlinkage void trap_c(struct pt_regs *fp); - int kstack_depth_to_print = 48; +#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON static int printk_address(unsigned long address) { struct vm_list_struct *vml; @@ -131,10 +130,22 @@ static int printk_address(unsigned long address) /* we were unable to find this address anywhere */ return printk("[<0x%p>]", (void *)address); } +#endif + +asmlinkage void double_fault_c(struct pt_regs *fp) +{ + printk(KERN_EMERG "\n" KERN_EMERG "Double Fault\n"); + dump_bfin_regs(fp, (void *)fp->retx); + panic("Double Fault - unrecoverable event\n"); + +} asmlinkage void trap_c(struct pt_regs *fp) { - int j, sig = 0; +#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON + int j; +#endif + int sig = 0; siginfo_t info; unsigned long trapnr = fp->seqstat & SEQSTAT_EXCAUSE; @@ -391,10 +402,6 @@ asmlinkage void trap_c(struct pt_regs *fp) break; } - info.si_signo = sig; - info.si_errno = 0; - info.si_addr = (void *)fp->pc; - force_sig_info(sig, &info, current); if (sig != 0 && sig != SIGTRAP) { unsigned long stack; dump_bfin_regs(fp, (void *)fp->retx); @@ -403,6 +410,10 @@ asmlinkage void trap_c(struct pt_regs *fp) if (current->mm == NULL) panic("Kernel exception"); } + info.si_signo = sig; + info.si_errno = 0; + info.si_addr = (void *)fp->pc; + force_sig_info(sig, &info, current); /* if the address that we are about to return to is not valid, set it * to a valid address, if we have a current application or panic @@ -429,24 +440,56 @@ asmlinkage void trap_c(struct pt_regs *fp) /* Typical exception handling routines */ +#define EXPAND_LEN ((1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 256 - 1) + void dump_bfin_trace_buffer(void) { - int tflags; +#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON + int tflags, i = 0; +#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND + int j, index; +#endif + trace_buffer_save(tflags); + printk(KERN_EMERG "Hardware Trace:\n"); + if (likely(bfin_read_TBUFSTAT() & TBUFCNT)) { - int i; - printk(KERN_EMERG "Hardware Trace:\n"); - for (i = 0; bfin_read_TBUFSTAT() & TBUFCNT; i++) { - printk(KERN_EMERG "%2i Target : ", i); + for (; bfin_read_TBUFSTAT() & TBUFCNT; i++) { + printk(KERN_EMERG "%4i Target : ", i); printk_address((unsigned long)bfin_read_TBUF()); - printk("\n" KERN_EMERG " Source : "); + printk("\n" KERN_EMERG " Source : "); printk_address((unsigned long)bfin_read_TBUF()); printk("\n"); } } +#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND + if (trace_buff_offset) + index = trace_buff_offset/4 - 1; + else + index = EXPAND_LEN; + + j = (1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 128; + while (j) { + printk(KERN_EMERG "%4i Target : ", i); + printk_address(software_trace_buff[index]); + index -= 1; + if (index < 0 ) + index = EXPAND_LEN; + printk("\n" KERN_EMERG " Source : "); + printk_address(software_trace_buff[index]); + index -= 1; + if (index < 0) + index = EXPAND_LEN; + printk("\n"); + j--; + i++; + } +#endif + trace_buffer_restore(tflags); +#endif } EXPORT_SYMBOL(dump_bfin_trace_buffer); @@ -510,7 +553,9 @@ void show_stack(struct task_struct *task, unsigned long *stack) void dump_stack(void) { unsigned long stack; +#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON int tflags; +#endif trace_buffer_save(tflags); dump_bfin_trace_buffer(); show_stack(current, &stack); @@ -559,8 +604,7 @@ void dump_bfin_regs(struct pt_regs *fp, void *retaddr) unsigned short x = 0; for (; i < ((unsigned int)retaddr & 0xFFFFFFF0) + 32; i += 2) { if (!(i & 0xF)) - printk(KERN_EMERG "\n" KERN_EMERG - "0x%08x: ", i); + printk("\n" KERN_EMERG "0x%08x: ", i); if (get_user(x, (unsigned short *)i)) break; @@ -655,6 +699,42 @@ asmlinkage int sys_bfin_spinlock(int *spinlock) return ret; } +int bfin_request_exception(unsigned int exception, void (*handler)(void)) +{ + void (*curr_handler)(void); + + if (exception > 0x3F) + return -EINVAL; + + curr_handler = ex_table[exception]; + + if (curr_handler != ex_replaceable) + return -EBUSY; + + ex_table[exception] = handler; + + return 0; +} +EXPORT_SYMBOL(bfin_request_exception); + +int bfin_free_exception(unsigned int exception, void (*handler)(void)) +{ + void (*curr_handler)(void); + + if (exception > 0x3F) + return -EINVAL; + + curr_handler = ex_table[exception]; + + if (curr_handler != handler) + return -EBUSY; + + ex_table[exception] = ex_replaceable; + + return 0; +} +EXPORT_SYMBOL(bfin_free_exception); + void panic_cplb_error(int cplb_panic, struct pt_regs *fp) { switch (cplb_panic) { |