From 2a12c4632db1c0c548a7023e63869b27c7789a92 Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Thu, 11 Mar 2010 16:24:18 +0000 Subject: Blackfin: split kernel/traps.c The current kernel/traps.c file has grown a bit unwieldy as more debugging functionality has been added over time, so split it up into more logical files. There should be no functional changes here, just minor whitespace tweaking. This should make future extensions easier to manage. Signed-off-by: Robin Getz Signed-off-by: Mike Frysinger --- arch/blackfin/kernel/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch/blackfin/kernel/Makefile') diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile index 346a421f156..b32a04a95d9 100644 --- a/arch/blackfin/kernel/Makefile +++ b/arch/blackfin/kernel/Makefile @@ -7,7 +7,8 @@ extra-y := init_task.o vmlinux.lds obj-y := \ entry.o process.o bfin_ksyms.o ptrace.o setup.o signal.o \ sys_bfin.o traps.o irqchip.o dma-mapping.o flat.o \ - fixed_code.o reboot.o bfin_gpio.o bfin_dma_5xx.o + fixed_code.o reboot.o bfin_gpio.o bfin_dma_5xx.o \ + trace.o exception.o dumpstack.o ifeq ($(CONFIG_GENERIC_CLOCKEVENTS),y) obj-y += time-ts.o -- cgit v1.2.3-70-g09d2 From d28cff4b615c2da274922311cef024d52c839870 Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Thu, 11 Mar 2010 19:26:38 +0000 Subject: Blackfin: remove CONFIG_DEBUG_VERBOSE from trace.c Now that the split traps code has moved all the verbose output to the trace.c file, we can unify all the CONFIG_DEBUG_VERBOSE handling. This gets rid of much of the crappy ifdef forest and enables usage of normal pr_xxx functions so checkpatch stops complaining. Signed-off-by: Robin Getz Signed-off-by: Mike Frysinger --- arch/blackfin/include/asm/bfin-global.h | 6 + arch/blackfin/include/asm/trace.h | 5 + arch/blackfin/kernel/Makefile | 3 +- arch/blackfin/kernel/trace.c | 221 ++++++++++++++------------------ arch/blackfin/kernel/traps.c | 8 ++ 5 files changed, 120 insertions(+), 123 deletions(-) (limited to 'arch/blackfin/kernel/Makefile') diff --git a/arch/blackfin/include/asm/bfin-global.h b/arch/blackfin/include/asm/bfin-global.h index e6485c305ea..121cc04d877 100644 --- a/arch/blackfin/include/asm/bfin-global.h +++ b/arch/blackfin/include/asm/bfin-global.h @@ -39,9 +39,15 @@ extern unsigned long sclk_to_usecs(unsigned long sclk); extern unsigned long usecs_to_sclk(unsigned long usecs); struct pt_regs; +#if defined(CONFIG_DEBUG_VERBOSE) extern void dump_bfin_process(struct pt_regs *regs); extern void dump_bfin_mem(struct pt_regs *regs); extern void dump_bfin_trace_buffer(void); +#else +#define dump_bfin_process(regs) +#define dump_bfin_mem(regs) +#define dump_bfin_trace_buffer() +#endif /* init functions only */ extern int init_arch_irq(void); diff --git a/arch/blackfin/include/asm/trace.h b/arch/blackfin/include/asm/trace.h index 395decd8bc3..91179395baa 100644 --- a/arch/blackfin/include/asm/trace.h +++ b/arch/blackfin/include/asm/trace.h @@ -23,8 +23,13 @@ #ifndef __ASSEMBLY__ extern unsigned long trace_buff_offset; extern unsigned long software_trace_buff[]; +#if defined(CONFIG_DEBUG_VERBOSE) extern void decode_address(char *buf, unsigned long address); extern bool get_instruction(unsigned short *val, unsigned short *address); +#else +#define decode_address(buf, address) +#define get_instruction(val, address) 0 +#endif /* Trace Macros for C files */ diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile index b32a04a95d9..2fc7f32ae32 100644 --- a/arch/blackfin/kernel/Makefile +++ b/arch/blackfin/kernel/Makefile @@ -8,7 +8,7 @@ obj-y := \ entry.o process.o bfin_ksyms.o ptrace.o setup.o signal.o \ sys_bfin.o traps.o irqchip.o dma-mapping.o flat.o \ fixed_code.o reboot.o bfin_gpio.o bfin_dma_5xx.o \ - trace.o exception.o dumpstack.o + exception.o dumpstack.o ifeq ($(CONFIG_GENERIC_CLOCKEVENTS),y) obj-y += time-ts.o @@ -30,6 +30,7 @@ obj-$(CONFIG_NMI_WATCHDOG) += nmi.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_EARLY_PRINTK) += shadow_console.o obj-$(CONFIG_STACKTRACE) += stacktrace.o +obj-$(CONFIG_DEBUG_VERBOSE) += trace.o # the kgdb test puts code into L2 and without linker # relaxation, we need to force long calls to/from it diff --git a/arch/blackfin/kernel/trace.c b/arch/blackfin/kernel/trace.c index 3a268c3ed47..6e37a8765bc 100644 --- a/arch/blackfin/kernel/trace.c +++ b/arch/blackfin/kernel/trace.c @@ -20,18 +20,8 @@ #include #include -#ifdef CONFIG_DEBUG_VERBOSE -#define verbose_printk(fmt, arg...) \ - printk(fmt, ##arg) -#else -#define verbose_printk(fmt, arg...) \ - ({ if (0) printk(fmt, ##arg); 0; }) -#endif - - void decode_address(char *buf, unsigned long address) { -#ifdef CONFIG_DEBUG_VERBOSE struct task_struct *p; struct mm_struct *mm; unsigned long flags, offset; @@ -174,9 +164,6 @@ void decode_address(char *buf, unsigned long address) done: write_unlock_irqrestore(&tasklist_lock, flags); -#else - sprintf(buf, " "); -#endif } #define EXPAND_LEN ((1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 256 - 1) @@ -219,52 +206,52 @@ bool get_instruction(unsigned short *val, unsigned short *address) * These are the normal instructions which cause change of flow, which * would be at the source of the trace buffer */ -#if defined(CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_BFIN_HWTRACE_ON) +#if defined(CONFIG_DEBUG_BFIN_HWTRACE_ON) static void decode_instruction(unsigned short *address) { unsigned short opcode; if (get_instruction(&opcode, address)) { if (opcode == 0x0010) - verbose_printk("RTS"); + pr_cont("RTS"); else if (opcode == 0x0011) - verbose_printk("RTI"); + pr_cont("RTI"); else if (opcode == 0x0012) - verbose_printk("RTX"); + pr_cont("RTX"); else if (opcode == 0x0013) - verbose_printk("RTN"); + pr_cont("RTN"); else if (opcode == 0x0014) - verbose_printk("RTE"); + pr_cont("RTE"); else if (opcode == 0x0025) - verbose_printk("EMUEXCPT"); + pr_cont("EMUEXCPT"); else if (opcode >= 0x0040 && opcode <= 0x0047) - verbose_printk("STI R%i", opcode & 7); + pr_cont("STI R%i", opcode & 7); else if (opcode >= 0x0050 && opcode <= 0x0057) - verbose_printk("JUMP (P%i)", opcode & 7); + pr_cont("JUMP (P%i)", opcode & 7); else if (opcode >= 0x0060 && opcode <= 0x0067) - verbose_printk("CALL (P%i)", opcode & 7); + pr_cont("CALL (P%i)", opcode & 7); else if (opcode >= 0x0070 && opcode <= 0x0077) - verbose_printk("CALL (PC+P%i)", opcode & 7); + pr_cont("CALL (PC+P%i)", opcode & 7); else if (opcode >= 0x0080 && opcode <= 0x0087) - verbose_printk("JUMP (PC+P%i)", opcode & 7); + pr_cont("JUMP (PC+P%i)", opcode & 7); else if (opcode >= 0x0090 && opcode <= 0x009F) - verbose_printk("RAISE 0x%x", opcode & 0xF); + pr_cont("RAISE 0x%x", opcode & 0xF); else if (opcode >= 0x00A0 && opcode <= 0x00AF) - verbose_printk("EXCPT 0x%x", opcode & 0xF); + pr_cont("EXCPT 0x%x", opcode & 0xF); else if ((opcode >= 0x1000 && opcode <= 0x13FF) || (opcode >= 0x1800 && opcode <= 0x1BFF)) - verbose_printk("IF !CC JUMP"); + pr_cont("IF !CC JUMP"); else if ((opcode >= 0x1400 && opcode <= 0x17ff) || (opcode >= 0x1c00 && opcode <= 0x1fff)) - verbose_printk("IF CC JUMP"); + pr_cont("IF CC JUMP"); else if (opcode >= 0x2000 && opcode <= 0x2fff) - verbose_printk("JUMP.S"); + pr_cont("JUMP.S"); else if (opcode >= 0xe080 && opcode <= 0xe0ff) - verbose_printk("LSETUP"); + pr_cont("LSETUP"); else if (opcode >= 0xe200 && opcode <= 0xe2ff) - verbose_printk("JUMP.L"); + pr_cont("JUMP.L"); else if (opcode >= 0xe300 && opcode <= 0xe3ff) - verbose_printk("CALL pcrel"); + pr_cont("CALL pcrel"); else - verbose_printk("0x%04x", opcode); + pr_cont("0x%04x", opcode); } } @@ -272,7 +259,6 @@ static void decode_instruction(unsigned short *address) void dump_bfin_trace_buffer(void) { -#ifdef CONFIG_DEBUG_VERBOSE #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON int tflags, i = 0; char buf[150]; @@ -283,21 +269,21 @@ void dump_bfin_trace_buffer(void) trace_buffer_save(tflags); - printk(KERN_NOTICE "Hardware Trace:\n"); + pr_notice("Hardware Trace:\n"); #ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND - printk(KERN_NOTICE "WARNING: Expanded trace turned on - can not trace exceptions\n"); + pr_notice("WARNING: Expanded trace turned on - can not trace exceptions\n"); #endif if (likely(bfin_read_TBUFSTAT() & TBUFCNT)) { for (; bfin_read_TBUFSTAT() & TBUFCNT; i++) { decode_address(buf, (unsigned long)bfin_read_TBUF()); - printk(KERN_NOTICE "%4i Target : %s\n", i, buf); + pr_notice("%4i Target : %s\n", i, buf); addr = (unsigned short *)bfin_read_TBUF(); decode_address(buf, (unsigned long)addr); - printk(KERN_NOTICE " Source : %s ", buf); + pr_notice(" Source : %s ", buf); decode_instruction(addr); - printk("\n"); + pr_cont("\n"); } } @@ -310,14 +296,14 @@ void dump_bfin_trace_buffer(void) j = (1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 128; while (j) { decode_address(buf, software_trace_buff[index]); - printk(KERN_NOTICE "%4i Target : %s\n", i, buf); + pr_notice("%4i Target : %s\n", i, buf); index -= 1; if (index < 0) index = EXPAND_LEN; decode_address(buf, software_trace_buff[index]); - printk(KERN_NOTICE " Source : %s ", buf); + pr_notice(" Source : %s ", buf); decode_instruction((unsigned short *)software_trace_buff[index]); - printk("\n"); + pr_cont("\n"); index -= 1; if (index < 0) index = EXPAND_LEN; @@ -328,78 +314,73 @@ void dump_bfin_trace_buffer(void) trace_buffer_restore(tflags); #endif -#endif } EXPORT_SYMBOL(dump_bfin_trace_buffer); void dump_bfin_process(struct pt_regs *fp) { -#ifdef CONFIG_DEBUG_VERBOSE /* We should be able to look at fp->ipend, but we don't push it on the * stack all the time, so do this until we fix that */ unsigned int context = bfin_read_IPEND(); if (oops_in_progress) - verbose_printk(KERN_EMERG "Kernel OOPS in progress\n"); + pr_emerg("Kernel OOPS in progress\n"); if (context & 0x0020 && (fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR) - verbose_printk(KERN_NOTICE "HW Error context\n"); + pr_notice("HW Error context\n"); else if (context & 0x0020) - verbose_printk(KERN_NOTICE "Deferred Exception context\n"); + pr_notice("Deferred Exception context\n"); else if (context & 0x3FC0) - verbose_printk(KERN_NOTICE "Interrupt context\n"); + pr_notice("Interrupt context\n"); else if (context & 0x4000) - verbose_printk(KERN_NOTICE "Deferred Interrupt context\n"); + pr_notice("Deferred Interrupt context\n"); else if (context & 0x8000) - verbose_printk(KERN_NOTICE "Kernel process context\n"); + pr_notice("Kernel process context\n"); /* Because we are crashing, and pointers could be bad, we check things * pretty closely before we use them */ if ((unsigned long)current >= FIXED_CODE_START && !((unsigned long)current & 0x3) && current->pid) { - verbose_printk(KERN_NOTICE "CURRENT PROCESS:\n"); + pr_notice("CURRENT PROCESS:\n"); if (current->comm >= (char *)FIXED_CODE_START) - verbose_printk(KERN_NOTICE "COMM=%s PID=%d", + pr_notice("COMM=%s PID=%d", current->comm, current->pid); else - verbose_printk(KERN_NOTICE "COMM= invalid"); + pr_notice("COMM= invalid"); - printk(KERN_CONT " CPU=%d\n", current_thread_info()->cpu); - if (!((unsigned long)current->mm & 0x3) && (unsigned long)current->mm >= FIXED_CODE_START) - verbose_printk(KERN_NOTICE - "TEXT = 0x%p-0x%p DATA = 0x%p-0x%p\n" - " BSS = 0x%p-0x%p USER-STACK = 0x%p\n\n", + pr_cont(" CPU=%d\n", current_thread_info()->cpu); + if (!((unsigned long)current->mm & 0x3) && + (unsigned long)current->mm >= FIXED_CODE_START) { + pr_notice("TEXT = 0x%p-0x%p DATA = 0x%p-0x%p\n", (void *)current->mm->start_code, (void *)current->mm->end_code, (void *)current->mm->start_data, - (void *)current->mm->end_data, + (void *)current->mm->end_data); + pr_notice(" BSS = 0x%p-0x%p USER-STACK = 0x%p\n\n", (void *)current->mm->end_data, (void *)current->mm->brk, (void *)current->mm->start_stack); - else - verbose_printk(KERN_NOTICE "invalid mm\n"); + } else + pr_notice("invalid mm\n"); } else - verbose_printk(KERN_NOTICE - "No Valid process in current context\n"); -#endif + pr_notice("No Valid process in current context\n"); } void dump_bfin_mem(struct pt_regs *fp) { -#ifdef CONFIG_DEBUG_VERBOSE unsigned short *addr, *erraddr, val = 0, err = 0; char sti = 0, buf[6]; erraddr = (void *)fp->pc; - verbose_printk(KERN_NOTICE "return address: [0x%p]; contents of:", erraddr); + pr_notice("return address: [0x%p]; contents of:", erraddr); for (addr = (unsigned short *)((unsigned long)erraddr & ~0xF) - 0x10; addr < (unsigned short *)((unsigned long)erraddr & ~0xF) + 0x10; addr++) { if (!((unsigned long)addr & 0xF)) - verbose_printk(KERN_NOTICE "0x%p: ", addr); + pr_notice("0x%p: ", addr); if (!get_instruction(&val, addr)) { val = 0; @@ -408,10 +389,10 @@ void dump_bfin_mem(struct pt_regs *fp) sprintf(buf, "%04x", val); if (addr == erraddr) { - verbose_printk("[%s]", buf); + pr_cont("[%s]", buf); err = val; } else - verbose_printk(" %s ", buf); + pr_cont(" %s ", buf); /* Do any previous instructions turn on interrupts? */ if (addr <= erraddr && /* in the past */ @@ -420,16 +401,15 @@ void dump_bfin_mem(struct pt_regs *fp) sti = 1; } - verbose_printk("\n"); + pr_cont("\n"); /* Hardware error interrupts can be deferred */ if (unlikely(sti && (fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR && oops_in_progress)){ - verbose_printk(KERN_NOTICE "Looks like this was a deferred error - sorry\n"); + pr_notice("Looks like this was a deferred error - sorry\n"); #ifndef CONFIG_DEBUG_HWERR - verbose_printk(KERN_NOTICE -"The remaining message may be meaningless\n" -"You should enable CONFIG_DEBUG_HWERR to get a better idea where it came from\n"); + pr_notice("The remaining message may be meaningless\n"); + pr_notice("You should enable CONFIG_DEBUG_HWERR to get a better idea where it came from\n"); #else /* If we are handling only one peripheral interrupt * and current mm and pid are valid, and the last error @@ -441,20 +421,18 @@ void dump_bfin_mem(struct pt_regs *fp) /* And the last RETI points to the current userspace context */ if ((fp + 1)->pc >= current->mm->start_code && (fp + 1)->pc <= current->mm->end_code) { - verbose_printk(KERN_NOTICE "It might be better to look around here :\n"); - verbose_printk(KERN_NOTICE "-------------------------------------------\n"); + pr_notice("It might be better to look around here :\n"); + pr_notice("-------------------------------------------\n"); show_regs(fp + 1); - verbose_printk(KERN_NOTICE "-------------------------------------------\n"); + pr_notice("-------------------------------------------\n"); } } #endif } -#endif } void show_regs(struct pt_regs *fp) { -#ifdef CONFIG_DEBUG_VERBOSE char buf[150]; struct irqaction *action; unsigned int i; @@ -462,19 +440,19 @@ void show_regs(struct pt_regs *fp) unsigned int cpu = raw_smp_processor_id(); unsigned char in_atomic = (bfin_read_IPEND() & 0x10) || in_atomic(); - verbose_printk(KERN_NOTICE "\n"); + pr_notice("\n"); if (CPUID != bfin_cpuid()) - verbose_printk(KERN_NOTICE "Compiled for cpu family 0x%04x (Rev %d), " + pr_notice("Compiled for cpu family 0x%04x (Rev %d), " "but running on:0x%04x (Rev %d)\n", CPUID, bfin_compiled_revid(), bfin_cpuid(), bfin_revid()); - verbose_printk(KERN_NOTICE "ADSP-%s-0.%d", + pr_notice("ADSP-%s-0.%d", CPU, bfin_compiled_revid()); if (bfin_compiled_revid() != bfin_revid()) - verbose_printk("(Detected 0.%d)", bfin_revid()); + pr_cont("(Detected 0.%d)", bfin_revid()); - verbose_printk(" %lu(MHz CCLK) %lu(MHz SCLK) (%s)\n", + pr_cont(" %lu(MHz CCLK) %lu(MHz SCLK) (%s)\n", get_cclk()/1000000, get_sclk()/1000000, #ifdef CONFIG_MPU "mpu on" @@ -483,40 +461,40 @@ void show_regs(struct pt_regs *fp) #endif ); - verbose_printk(KERN_NOTICE "%s", linux_banner); + pr_notice("%s", linux_banner); - verbose_printk(KERN_NOTICE "\nSEQUENCER STATUS:\t\t%s\n", print_tainted()); - verbose_printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx IMASK: %04lx SYSCFG: %04lx\n", + pr_notice("\nSEQUENCER STATUS:\t\t%s\n", print_tainted()); + pr_notice(" SEQSTAT: %08lx IPEND: %04lx IMASK: %04lx SYSCFG: %04lx\n", (long)fp->seqstat, fp->ipend, cpu_pda[raw_smp_processor_id()].ex_imask, fp->syscfg); if (fp->ipend & EVT_IRPTEN) - verbose_printk(KERN_NOTICE " Global Interrupts Disabled (IPEND[4])\n"); + pr_notice(" Global Interrupts Disabled (IPEND[4])\n"); if (!(cpu_pda[raw_smp_processor_id()].ex_imask & (EVT_IVG13 | EVT_IVG12 | EVT_IVG11 | EVT_IVG10 | EVT_IVG9 | EVT_IVG8 | EVT_IVG7 | EVT_IVTMR))) - verbose_printk(KERN_NOTICE " Peripheral interrupts masked off\n"); + pr_notice(" Peripheral interrupts masked off\n"); if (!(cpu_pda[raw_smp_processor_id()].ex_imask & (EVT_IVG15 | EVT_IVG14))) - verbose_printk(KERN_NOTICE " Kernel interrupts masked off\n"); + pr_notice(" Kernel interrupts masked off\n"); if ((fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR) { - verbose_printk(KERN_NOTICE " HWERRCAUSE: 0x%lx\n", + pr_notice(" HWERRCAUSE: 0x%lx\n", (fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14); #ifdef EBIU_ERRMST /* If the error was from the EBIU, print it out */ if (bfin_read_EBIU_ERRMST() & CORE_ERROR) { - verbose_printk(KERN_NOTICE " EBIU Error Reason : 0x%04x\n", + pr_notice(" EBIU Error Reason : 0x%04x\n", bfin_read_EBIU_ERRMST()); - verbose_printk(KERN_NOTICE " EBIU Error Address : 0x%08x\n", + pr_notice(" EBIU Error Address : 0x%08x\n", bfin_read_EBIU_ERRADD()); } #endif } - verbose_printk(KERN_NOTICE " EXCAUSE : 0x%lx\n", + pr_notice(" EXCAUSE : 0x%lx\n", fp->seqstat & SEQSTAT_EXCAUSE); for (i = 2; i <= 15 ; i++) { if (fp->ipend & (1 << i)) { if (i != 4) { decode_address(buf, bfin_read32(EVT0 + 4*i)); - verbose_printk(KERN_NOTICE " physical IVG%i asserted : %s\n", i, buf); + pr_notice(" physical IVG%i asserted : %s\n", i, buf); } else - verbose_printk(KERN_NOTICE " interrupts disabled\n"); + pr_notice(" interrupts disabled\n"); } } @@ -531,12 +509,12 @@ void show_regs(struct pt_regs *fp) goto unlock; decode_address(buf, (unsigned int)action->handler); - verbose_printk(KERN_NOTICE " logical irq %3d mapped : %s", i, buf); + pr_notice(" logical irq %3d mapped : %s", i, buf); for (action = action->next; action; action = action->next) { decode_address(buf, (unsigned int)action->handler); - verbose_printk(", %s", buf); + pr_cont(", %s", buf); } - verbose_printk("\n"); + pr_cont("\n"); unlock: if (!in_atomic) raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); @@ -544,51 +522,50 @@ unlock: } decode_address(buf, fp->rete); - verbose_printk(KERN_NOTICE " RETE: %s\n", buf); + pr_notice(" RETE: %s\n", buf); decode_address(buf, fp->retn); - verbose_printk(KERN_NOTICE " RETN: %s\n", buf); + pr_notice(" RETN: %s\n", buf); decode_address(buf, fp->retx); - verbose_printk(KERN_NOTICE " RETX: %s\n", buf); + pr_notice(" RETX: %s\n", buf); decode_address(buf, fp->rets); - verbose_printk(KERN_NOTICE " RETS: %s\n", buf); + pr_notice(" RETS: %s\n", buf); decode_address(buf, fp->pc); - verbose_printk(KERN_NOTICE " PC : %s\n", buf); + pr_notice(" PC : %s\n", buf); if (((long)fp->seqstat & SEQSTAT_EXCAUSE) && (((long)fp->seqstat & SEQSTAT_EXCAUSE) != VEC_HWERR)) { decode_address(buf, cpu_pda[cpu].dcplb_fault_addr); - verbose_printk(KERN_NOTICE "DCPLB_FAULT_ADDR: %s\n", buf); + pr_notice("DCPLB_FAULT_ADDR: %s\n", buf); decode_address(buf, cpu_pda[cpu].icplb_fault_addr); - verbose_printk(KERN_NOTICE "ICPLB_FAULT_ADDR: %s\n", buf); + pr_notice("ICPLB_FAULT_ADDR: %s\n", buf); } - verbose_printk(KERN_NOTICE "PROCESSOR STATE:\n"); - verbose_printk(KERN_NOTICE " R0 : %08lx R1 : %08lx R2 : %08lx R3 : %08lx\n", + pr_notice("PROCESSOR STATE:\n"); + pr_notice(" R0 : %08lx R1 : %08lx R2 : %08lx R3 : %08lx\n", fp->r0, fp->r1, fp->r2, fp->r3); - verbose_printk(KERN_NOTICE " R4 : %08lx R5 : %08lx R6 : %08lx R7 : %08lx\n", + pr_notice(" R4 : %08lx R5 : %08lx R6 : %08lx R7 : %08lx\n", fp->r4, fp->r5, fp->r6, fp->r7); - verbose_printk(KERN_NOTICE " P0 : %08lx P1 : %08lx P2 : %08lx P3 : %08lx\n", + pr_notice(" P0 : %08lx P1 : %08lx P2 : %08lx P3 : %08lx\n", fp->p0, fp->p1, fp->p2, fp->p3); - verbose_printk(KERN_NOTICE " P4 : %08lx P5 : %08lx FP : %08lx SP : %08lx\n", + pr_notice(" P4 : %08lx P5 : %08lx FP : %08lx SP : %08lx\n", fp->p4, fp->p5, fp->fp, (long)fp); - verbose_printk(KERN_NOTICE " LB0: %08lx LT0: %08lx LC0: %08lx\n", + pr_notice(" LB0: %08lx LT0: %08lx LC0: %08lx\n", fp->lb0, fp->lt0, fp->lc0); - verbose_printk(KERN_NOTICE " LB1: %08lx LT1: %08lx LC1: %08lx\n", + pr_notice(" LB1: %08lx LT1: %08lx LC1: %08lx\n", fp->lb1, fp->lt1, fp->lc1); - verbose_printk(KERN_NOTICE " B0 : %08lx L0 : %08lx M0 : %08lx I0 : %08lx\n", + pr_notice(" B0 : %08lx L0 : %08lx M0 : %08lx I0 : %08lx\n", fp->b0, fp->l0, fp->m0, fp->i0); - verbose_printk(KERN_NOTICE " B1 : %08lx L1 : %08lx M1 : %08lx I1 : %08lx\n", + pr_notice(" B1 : %08lx L1 : %08lx M1 : %08lx I1 : %08lx\n", fp->b1, fp->l1, fp->m1, fp->i1); - verbose_printk(KERN_NOTICE " B2 : %08lx L2 : %08lx M2 : %08lx I2 : %08lx\n", + pr_notice(" B2 : %08lx L2 : %08lx M2 : %08lx I2 : %08lx\n", fp->b2, fp->l2, fp->m2, fp->i2); - verbose_printk(KERN_NOTICE " B3 : %08lx L3 : %08lx M3 : %08lx I3 : %08lx\n", + pr_notice(" B3 : %08lx L3 : %08lx M3 : %08lx I3 : %08lx\n", fp->b3, fp->l3, fp->m3, fp->i3); - verbose_printk(KERN_NOTICE "A0.w: %08lx A0.x: %08lx A1.w: %08lx A1.x: %08lx\n", + pr_notice("A0.w: %08lx A0.x: %08lx A1.w: %08lx A1.x: %08lx\n", fp->a0w, fp->a0x, fp->a1w, fp->a1x); - verbose_printk(KERN_NOTICE "USP : %08lx ASTAT: %08lx\n", + pr_notice("USP : %08lx ASTAT: %08lx\n", rdusp(), fp->astat); - verbose_printk(KERN_NOTICE "\n"); -#endif + pr_notice("\n"); } diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index 891cc39f7ee..7c31a3d7af2 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c @@ -554,3 +554,11 @@ int is_valid_bugaddr(unsigned long addr) return opcode == BFIN_BUG_OPCODE; } #endif + +/* stub this out */ +#ifndef CONFIG_DEBUG_VERBOSE +void show_regs(struct pt_regs *fp) +{ + +} +#endif -- cgit v1.2.3-70-g09d2 From 6ce3e9c2a2cfb8849dd471349fe5e6bc37c0f13f Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Tue, 16 Mar 2010 14:40:17 +0000 Subject: Blackfin: add support for the DBGA (debug assert) pseudo insn A few pseudo debug insns exist to make testing of simulators easier. Since these don't actually exist in the hardware, we have to have the exception handler take care of emulating these. This allows sim test cases to be executed unmodified under Linux and thus simplify debugging greatly. Signed-off-by: Robin Getz Signed-off-by: Mike Frysinger --- arch/blackfin/Kconfig.debug | 9 +++ arch/blackfin/include/asm/pseudo_instructions.h | 17 ++++++ arch/blackfin/kernel/Makefile | 1 + arch/blackfin/kernel/pseudodbg.c | 73 +++++++++++++++++++++++++ arch/blackfin/kernel/traps.c | 15 +++++ 5 files changed, 115 insertions(+) create mode 100644 arch/blackfin/include/asm/pseudo_instructions.h create mode 100644 arch/blackfin/kernel/pseudodbg.c (limited to 'arch/blackfin/kernel/Makefile') diff --git a/arch/blackfin/Kconfig.debug b/arch/blackfin/Kconfig.debug index aec89a5280b..3c49f76b37b 100644 --- a/arch/blackfin/Kconfig.debug +++ b/arch/blackfin/Kconfig.debug @@ -264,4 +264,13 @@ config BFIN_ISRAM_SELF_TEST help Run some self tests of the isram driver code at boot. +config BFIN_PSEUDODBG_INSNS + bool "Support pseudo debug instructions" + default n + help + This option allows the kernel to emulate some pseudo instructions which + allow simulator test cases to be run under Linux with no changes. + + Most people should say N here. + endmenu diff --git a/arch/blackfin/include/asm/pseudo_instructions.h b/arch/blackfin/include/asm/pseudo_instructions.h new file mode 100644 index 00000000000..7173719fb53 --- /dev/null +++ b/arch/blackfin/include/asm/pseudo_instructions.h @@ -0,0 +1,17 @@ +/* + * header file for pseudo instructions + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#ifndef _BLACKFIN_PSEUDO_ +#define _BLACKFIN_PSEUDO_ + +#include +#include + +extern bool execute_pseudodbg_assert(struct pt_regs *fp, unsigned int opcode); + +#endif diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile index 2fc7f32ae32..30d0d1f01dc 100644 --- a/arch/blackfin/kernel/Makefile +++ b/arch/blackfin/kernel/Makefile @@ -31,6 +31,7 @@ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_EARLY_PRINTK) += shadow_console.o obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_DEBUG_VERBOSE) += trace.o +obj-$(CONFIG_BFIN_PSEUDODBG_INSNS) += pseudodbg.o # the kgdb test puts code into L2 and without linker # relaxation, we need to force long calls to/from it diff --git a/arch/blackfin/kernel/pseudodbg.c b/arch/blackfin/kernel/pseudodbg.c new file mode 100644 index 00000000000..4474b8db350 --- /dev/null +++ b/arch/blackfin/kernel/pseudodbg.c @@ -0,0 +1,73 @@ +/* The fake debug assert instructions + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later + */ + +#include +#include +#include + +#define PseudoDbg_Assert_opcode 0xf0000000 +#define PseudoDbg_Assert_expected_bits 0 +#define PseudoDbg_Assert_expected_mask 0xffff +#define PseudoDbg_Assert_regtest_bits 16 +#define PseudoDbg_Assert_regtest_mask 0x7 +#define PseudoDbg_Assert_grp_bits 19 +#define PseudoDbg_Assert_grp_mask 0x7 +#define PseudoDbg_Assert_dbgop_bits 22 +#define PseudoDbg_Assert_dbgop_mask 0x3 +#define PseudoDbg_Assert_dontcare_bits 24 +#define PseudoDbg_Assert_dontcare_mask 0x7 +#define PseudoDbg_Assert_code_bits 27 +#define PseudoDbg_Assert_code_mask 0x1f + +bool execute_pseudodbg_assert(struct pt_regs *fp, unsigned int opcode) +{ + int expected = ((opcode >> PseudoDbg_Assert_expected_bits) & PseudoDbg_Assert_expected_mask); + int dbgop = ((opcode >> (PseudoDbg_Assert_dbgop_bits)) & PseudoDbg_Assert_dbgop_mask); + int grp = ((opcode >> (PseudoDbg_Assert_grp_bits)) & PseudoDbg_Assert_grp_mask); + int regtest = ((opcode >> (PseudoDbg_Assert_regtest_bits)) & PseudoDbg_Assert_regtest_mask); + long *value = &fp->r0; + + if ((opcode & 0xFF000000) != PseudoDbg_Assert_opcode) + return false; + + /* Only do Dregs and Pregs for now */ + if (grp > 1) + return false; + + /* + * Unfortunately, the pt_regs structure is not laid out the same way as the + * hardware register file, so we need to do some fix ups. + */ + if (grp == 0 || (grp == 1 && regtest < 6)) + value -= (regtest + 8 * grp); + else if (grp == 1 && regtest == 6) + value = &fp->usp; + else if (grp == 1 && regtest == 7) + value = &fp->fp; + + if (dbgop == 0 || dbgop == 2) { + /* DBGA ( regs_lo , uimm16 ) */ + /* DBGAL ( regs , uimm16 ) */ + if (expected != (*value & 0xFFFF)) { + pr_notice("DBGA (%s%i.L,0x%x) failure, got 0x%x\n", grp ? "P" : "R", + regtest, expected, (unsigned int)(*value & 0xFFFF)); + return false; + } + + } else if (dbgop == 1 || dbgop == 3) { + /* DBGA ( regs_hi , uimm16 ) */ + /* DBGAH ( regs , uimm16 ) */ + if (expected != ((*value >> 16) & 0xFFFF)) { + pr_notice("DBGA (%s%i.H,0x%x) failure, got 0x%x\n", grp ? "P" : "R", + regtest, expected, (unsigned int)((*value >> 16) & 0xFFFF)); + return false; + } + } + + fp->pc += 4; + return true; +} diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index fffcf8a516b..9369836365b 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c @@ -16,6 +16,7 @@ #include #include #include +#include #ifdef CONFIG_KGDB # include @@ -67,6 +68,9 @@ asmlinkage notrace void trap_c(struct pt_regs *fp) { #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON int j; +#endif +#ifdef CONFIG_BFIN_PSEUDODBG_INSNS + int opcode; #endif unsigned int cpu = raw_smp_processor_id(); const char *strerror = NULL; @@ -199,6 +203,17 @@ asmlinkage notrace void trap_c(struct pt_regs *fp) panic("BUG()"); } } +#endif +#ifdef CONFIG_BFIN_PSEUDODBG_INSNS + /* + * Support for the fake instructions, if the instruction fails, + * then just execute a illegal opcode failure (like normal). + * Don't support these instructions inside the kernel + */ + if (!kernel_mode_regs(fp) && get_instruction(&opcode, (unsigned short *)fp->pc)) { + if (execute_pseudodbg_assert(fp, opcode)) + goto traps_done; + } #endif info.si_code = ILL_ILLOPC; sig = SIGILL; -- cgit v1.2.3-70-g09d2