Merge branch 'preempt' into release
[sfrench/cifs-2.6.git] / arch / blackfin / kernel / traps.c
index bf2b2d1f8ae5f35ecd64b68abbbc324f444fa421..56464cb8edf3105e9a105a9e823eb22b3fead290 100644 (file)
@@ -100,7 +100,11 @@ static void decode_address(char *buf, unsigned long address)
        char *modname;
        char *delim = ":";
        char namebuf[128];
+#endif
+
+       buf += sprintf(buf, "<0x%08lx> ", address);
 
+#ifdef CONFIG_KALLSYMS
        /* look up the address and see if we are in kernel space */
        symname = kallsyms_lookup(address, &symsize, &offset, &modname, namebuf);
 
@@ -108,23 +112,33 @@ static void decode_address(char *buf, unsigned long address)
                /* yeah! kernel space! */
                if (!modname)
                        modname = delim = "";
-               sprintf(buf, "<0x%p> { %s%s%s%s + 0x%lx }",
-                             (void *)address, delim, modname, delim, symname,
-                             (unsigned long)offset);
+               sprintf(buf, "{ %s%s%s%s + 0x%lx }",
+                       delim, modname, delim, symname,
+                       (unsigned long)offset);
                return;
-
        }
 #endif
 
-       /* Problem in fixed code section? */
        if (address >= FIXED_CODE_START && address < FIXED_CODE_END) {
-               sprintf(buf, "<0x%p> /* Maybe fixed code section */", (void *)address);
+               /* Problem in fixed code section? */
+               strcat(buf, "/* Maybe fixed code section */");
+               return;
+
+       } else if (address < CONFIG_BOOT_LOAD) {
+               /* Problem somewhere before the kernel start address */
+               strcat(buf, "/* Maybe null pointer? */");
+               return;
+
+       } else if (address >= COREMMR_BASE) {
+               strcat(buf, "/* core mmrs */");
                return;
-       }
 
-       /* Problem somewhere before the kernel start address */
-       if (address < CONFIG_BOOT_LOAD) {
-               sprintf(buf, "<0x%p> /* Maybe null pointer? */", (void *)address);
+       } else if (address >= SYSMMR_BASE) {
+               strcat(buf, "/* system mmrs */");
+               return;
+
+       } else if (address >= L1_ROM_START && address < L1_ROM_START + L1_ROM_LENGTH) {
+               strcat(buf, "/* on-chip L1 ROM */");
                return;
        }
 
@@ -172,18 +186,16 @@ static void decode_address(char *buf, unsigned long address)
                                                offset = (address - vma->vm_start) +
                                                         (vma->vm_pgoff << PAGE_SHIFT);
 
-                                       sprintf(buf, "<0x%p> [ %s + 0x%lx ]",
-                                               (void *)address, name, offset);
+                                       sprintf(buf, "[ %s + 0x%lx ]", name, offset);
                                } else
-                                       sprintf(buf, "<0x%p> [ %s vma:0x%lx-0x%lx]",
-                                               (void *)address, name,
-                                               vma->vm_start, vma->vm_end);
+                                       sprintf(buf, "[ %s vma:0x%lx-0x%lx]",
+                                               name, vma->vm_start, vma->vm_end);
 
                                if (!in_atomic)
                                        mmput(mm);
 
-                               if (!strlen(buf))
-                                       sprintf(buf, "<0x%p> [ %s ] dynamic memory", (void *)address, name);
+                               if (buf[0] == '\0')
+                                       sprintf(buf, "[ %s ] dynamic memory", name);
 
                                goto done;
                        }
@@ -193,7 +205,7 @@ static void decode_address(char *buf, unsigned long address)
        }
 
        /* we were unable to find this address anywhere */
-       sprintf(buf, "<0x%p> /* kernel dynamic memory */", (void *)address);
+       sprintf(buf, "/* kernel dynamic memory */");
 
 done:
        write_unlock_irqrestore(&tasklist_lock, flags);
@@ -215,14 +227,14 @@ asmlinkage void double_fault_c(struct pt_regs *fp)
        printk(KERN_EMERG "Double Fault\n");
 #ifdef CONFIG_DEBUG_DOUBLEFAULT_PRINT
        if (((long)fp->seqstat &  SEQSTAT_EXCAUSE) == VEC_UNCOV) {
-               unsigned int cpu = smp_processor_id();
+               unsigned int cpu = raw_smp_processor_id();
                char buf[150];
-               decode_address(buf, cpu_pda[cpu].retx);
+               decode_address(buf, cpu_pda[cpu].retx_doublefault);
                printk(KERN_EMERG "While handling exception (EXCAUSE = 0x%x) at %s:\n",
-                       (unsigned int)cpu_pda[cpu].seqstat & SEQSTAT_EXCAUSE, buf);
-               decode_address(buf, cpu_pda[cpu].dcplb_fault_addr);
+                       (unsigned int)cpu_pda[cpu].seqstat_doublefault & SEQSTAT_EXCAUSE, buf);
+               decode_address(buf, cpu_pda[cpu].dcplb_doublefault_addr);
                printk(KERN_NOTICE "   DCPLB_FAULT_ADDR: %s\n", buf);
-               decode_address(buf, cpu_pda[cpu].icplb_fault_addr);
+               decode_address(buf, cpu_pda[cpu].icplb_doublefault_addr);
                printk(KERN_NOTICE "   ICPLB_FAULT_ADDR: %s\n", buf);
 
                decode_address(buf, fp->retx);
@@ -245,13 +257,13 @@ static int kernel_mode_regs(struct pt_regs *regs)
        return regs->ipend & 0xffc0;
 }
 
-asmlinkage void trap_c(struct pt_regs *fp)
+asmlinkage notrace void trap_c(struct pt_regs *fp)
 {
 #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON
        int j;
 #endif
 #ifdef CONFIG_DEBUG_HUNT_FOR_ZERO
-       unsigned int cpu = smp_processor_id();
+       unsigned int cpu = raw_smp_processor_id();
 #endif
        const char *strerror = NULL;
        int sig = 0;
@@ -267,11 +279,6 @@ asmlinkage void trap_c(struct pt_regs *fp)
         * double faults if the stack has become corrupt
         */
 
-#ifndef CONFIG_KGDB
-       /* IPEND is skipped if KGDB isn't enabled (see entry code) */
-       fp->ipend = bfin_read_IPEND();
-#endif
-
        /* trap_c() will be called for exceptions. During exceptions
         * processing, the pc value should be set with retx value.
         * With this change we can cleanup some code in signal.c- TODO
@@ -404,7 +411,7 @@ asmlinkage void trap_c(struct pt_regs *fp)
        /* 0x23 - Data CPLB protection violation, handled here */
        case VEC_CPLB_VL:
                info.si_code = ILL_CPLB_VI;
-               sig = SIGBUS;
+               sig = SIGSEGV;
                strerror = KERN_NOTICE EXC_0x23(KERN_NOTICE);
                CHK_DEBUGGER_TRAP_MAYBE();
                break;
@@ -904,7 +911,7 @@ void show_stack(struct task_struct *task, unsigned long *stack)
                frame_no = 0;
 
                for (addr = (unsigned int *)((unsigned int)stack & ~0xF), i = 0;
-                    addr <= endstack; addr++, i++) {
+                    addr < endstack; addr++, i++) {
 
                        ret_addr = 0;
                        if (!j && i % 8 == 0)
@@ -949,6 +956,7 @@ void show_stack(struct task_struct *task, unsigned long *stack)
        }
 #endif
 }
+EXPORT_SYMBOL(show_stack);
 
 void dump_stack(void)
 {
@@ -1090,7 +1098,7 @@ void show_regs(struct pt_regs *fp)
        struct irqaction *action;
        unsigned int i;
        unsigned long flags = 0;
-       unsigned int cpu = smp_processor_id();
+       unsigned int cpu = raw_smp_processor_id();
        unsigned char in_atomic = (bfin_read_IPEND() & 0x10) || in_atomic();
 
        verbose_printk(KERN_NOTICE "\n");
@@ -1116,10 +1124,16 @@ void show_regs(struct pt_regs *fp)
 
        verbose_printk(KERN_NOTICE "%s", linux_banner);
 
-       verbose_printk(KERN_NOTICE "\nSEQUENCER STATUS:\t\t%s\n",
-                      print_tainted());
-       verbose_printk(KERN_NOTICE " SEQSTAT: %08lx  IPEND: %04lx  SYSCFG: %04lx\n",
-                      (long)fp->seqstat, fp->ipend, fp->syscfg);
+       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",
+               (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");
+       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");
+       if (!(cpu_pda[raw_smp_processor_id()].ex_imask & (EVT_IVG15 | EVT_IVG14)))
+               verbose_printk(KERN_NOTICE "  Kernel interrupts masked off\n");
        if ((fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR) {
                verbose_printk(KERN_NOTICE "  HWERRCAUSE: 0x%lx\n",
                        (fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14);