diff options
Diffstat (limited to 'arch/blackfin/kernel/traps.c')
| -rw-r--r-- | arch/blackfin/kernel/traps.c | 88 |
1 files changed, 51 insertions, 37 deletions
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index bf2b2d1f8ae5..56464cb8edf3 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c | |||
| @@ -100,7 +100,11 @@ static void decode_address(char *buf, unsigned long address) | |||
| 100 | char *modname; | 100 | char *modname; |
| 101 | char *delim = ":"; | 101 | char *delim = ":"; |
| 102 | char namebuf[128]; | 102 | char namebuf[128]; |
| 103 | #endif | ||
| 104 | |||
| 105 | buf += sprintf(buf, "<0x%08lx> ", address); | ||
| 103 | 106 | ||
| 107 | #ifdef CONFIG_KALLSYMS | ||
| 104 | /* look up the address and see if we are in kernel space */ | 108 | /* look up the address and see if we are in kernel space */ |
| 105 | symname = kallsyms_lookup(address, &symsize, &offset, &modname, namebuf); | 109 | symname = kallsyms_lookup(address, &symsize, &offset, &modname, namebuf); |
| 106 | 110 | ||
| @@ -108,23 +112,33 @@ static void decode_address(char *buf, unsigned long address) | |||
| 108 | /* yeah! kernel space! */ | 112 | /* yeah! kernel space! */ |
| 109 | if (!modname) | 113 | if (!modname) |
| 110 | modname = delim = ""; | 114 | modname = delim = ""; |
| 111 | sprintf(buf, "<0x%p> { %s%s%s%s + 0x%lx }", | 115 | sprintf(buf, "{ %s%s%s%s + 0x%lx }", |
| 112 | (void *)address, delim, modname, delim, symname, | 116 | delim, modname, delim, symname, |
| 113 | (unsigned long)offset); | 117 | (unsigned long)offset); |
| 114 | return; | 118 | return; |
| 115 | |||
| 116 | } | 119 | } |
| 117 | #endif | 120 | #endif |
| 118 | 121 | ||
| 119 | /* Problem in fixed code section? */ | ||
| 120 | if (address >= FIXED_CODE_START && address < FIXED_CODE_END) { | 122 | if (address >= FIXED_CODE_START && address < FIXED_CODE_END) { |
| 121 | sprintf(buf, "<0x%p> /* Maybe fixed code section */", (void *)address); | 123 | /* Problem in fixed code section? */ |
| 124 | strcat(buf, "/* Maybe fixed code section */"); | ||
| 125 | return; | ||
| 126 | |||
| 127 | } else if (address < CONFIG_BOOT_LOAD) { | ||
| 128 | /* Problem somewhere before the kernel start address */ | ||
| 129 | strcat(buf, "/* Maybe null pointer? */"); | ||
| 130 | return; | ||
| 131 | |||
| 132 | } else if (address >= COREMMR_BASE) { | ||
| 133 | strcat(buf, "/* core mmrs */"); | ||
| 122 | return; | 134 | return; |
| 123 | } | ||
| 124 | 135 | ||
| 125 | /* Problem somewhere before the kernel start address */ | 136 | } else if (address >= SYSMMR_BASE) { |
| 126 | if (address < CONFIG_BOOT_LOAD) { | 137 | strcat(buf, "/* system mmrs */"); |
| 127 | sprintf(buf, "<0x%p> /* Maybe null pointer? */", (void *)address); | 138 | return; |
| 139 | |||
| 140 | } else if (address >= L1_ROM_START && address < L1_ROM_START + L1_ROM_LENGTH) { | ||
| 141 | strcat(buf, "/* on-chip L1 ROM */"); | ||
| 128 | return; | 142 | return; |
| 129 | } | 143 | } |
| 130 | 144 | ||
| @@ -172,18 +186,16 @@ static void decode_address(char *buf, unsigned long address) | |||
| 172 | offset = (address - vma->vm_start) + | 186 | offset = (address - vma->vm_start) + |
| 173 | (vma->vm_pgoff << PAGE_SHIFT); | 187 | (vma->vm_pgoff << PAGE_SHIFT); |
| 174 | 188 | ||
| 175 | sprintf(buf, "<0x%p> [ %s + 0x%lx ]", | 189 | sprintf(buf, "[ %s + 0x%lx ]", name, offset); |
| 176 | (void *)address, name, offset); | ||
| 177 | } else | 190 | } else |
| 178 | sprintf(buf, "<0x%p> [ %s vma:0x%lx-0x%lx]", | 191 | sprintf(buf, "[ %s vma:0x%lx-0x%lx]", |
| 179 | (void *)address, name, | 192 | name, vma->vm_start, vma->vm_end); |
| 180 | vma->vm_start, vma->vm_end); | ||
| 181 | 193 | ||
| 182 | if (!in_atomic) | 194 | if (!in_atomic) |
| 183 | mmput(mm); | 195 | mmput(mm); |
| 184 | 196 | ||
| 185 | if (!strlen(buf)) | 197 | if (buf[0] == '\0') |
| 186 | sprintf(buf, "<0x%p> [ %s ] dynamic memory", (void *)address, name); | 198 | sprintf(buf, "[ %s ] dynamic memory", name); |
| 187 | 199 | ||
| 188 | goto done; | 200 | goto done; |
| 189 | } | 201 | } |
| @@ -193,7 +205,7 @@ static void decode_address(char *buf, unsigned long address) | |||
| 193 | } | 205 | } |
| 194 | 206 | ||
| 195 | /* we were unable to find this address anywhere */ | 207 | /* we were unable to find this address anywhere */ |
| 196 | sprintf(buf, "<0x%p> /* kernel dynamic memory */", (void *)address); | 208 | sprintf(buf, "/* kernel dynamic memory */"); |
| 197 | 209 | ||
| 198 | done: | 210 | done: |
| 199 | write_unlock_irqrestore(&tasklist_lock, flags); | 211 | write_unlock_irqrestore(&tasklist_lock, flags); |
| @@ -215,14 +227,14 @@ asmlinkage void double_fault_c(struct pt_regs *fp) | |||
| 215 | printk(KERN_EMERG "Double Fault\n"); | 227 | printk(KERN_EMERG "Double Fault\n"); |
| 216 | #ifdef CONFIG_DEBUG_DOUBLEFAULT_PRINT | 228 | #ifdef CONFIG_DEBUG_DOUBLEFAULT_PRINT |
| 217 | if (((long)fp->seqstat & SEQSTAT_EXCAUSE) == VEC_UNCOV) { | 229 | if (((long)fp->seqstat & SEQSTAT_EXCAUSE) == VEC_UNCOV) { |
| 218 | unsigned int cpu = smp_processor_id(); | 230 | unsigned int cpu = raw_smp_processor_id(); |
| 219 | char buf[150]; | 231 | char buf[150]; |
| 220 | decode_address(buf, cpu_pda[cpu].retx); | 232 | decode_address(buf, cpu_pda[cpu].retx_doublefault); |
| 221 | printk(KERN_EMERG "While handling exception (EXCAUSE = 0x%x) at %s:\n", | 233 | printk(KERN_EMERG "While handling exception (EXCAUSE = 0x%x) at %s:\n", |
| 222 | (unsigned int)cpu_pda[cpu].seqstat & SEQSTAT_EXCAUSE, buf); | 234 | (unsigned int)cpu_pda[cpu].seqstat_doublefault & SEQSTAT_EXCAUSE, buf); |
| 223 | decode_address(buf, cpu_pda[cpu].dcplb_fault_addr); | 235 | decode_address(buf, cpu_pda[cpu].dcplb_doublefault_addr); |
| 224 | printk(KERN_NOTICE " DCPLB_FAULT_ADDR: %s\n", buf); | 236 | printk(KERN_NOTICE " DCPLB_FAULT_ADDR: %s\n", buf); |
| 225 | decode_address(buf, cpu_pda[cpu].icplb_fault_addr); | 237 | decode_address(buf, cpu_pda[cpu].icplb_doublefault_addr); |
| 226 | printk(KERN_NOTICE " ICPLB_FAULT_ADDR: %s\n", buf); | 238 | printk(KERN_NOTICE " ICPLB_FAULT_ADDR: %s\n", buf); |
| 227 | 239 | ||
| 228 | decode_address(buf, fp->retx); | 240 | decode_address(buf, fp->retx); |
| @@ -245,13 +257,13 @@ static int kernel_mode_regs(struct pt_regs *regs) | |||
| 245 | return regs->ipend & 0xffc0; | 257 | return regs->ipend & 0xffc0; |
| 246 | } | 258 | } |
| 247 | 259 | ||
| 248 | asmlinkage void trap_c(struct pt_regs *fp) | 260 | asmlinkage notrace void trap_c(struct pt_regs *fp) |
| 249 | { | 261 | { |
| 250 | #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON | 262 | #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON |
| 251 | int j; | 263 | int j; |
| 252 | #endif | 264 | #endif |
| 253 | #ifdef CONFIG_DEBUG_HUNT_FOR_ZERO | 265 | #ifdef CONFIG_DEBUG_HUNT_FOR_ZERO |
| 254 | unsigned int cpu = smp_processor_id(); | 266 | unsigned int cpu = raw_smp_processor_id(); |
| 255 | #endif | 267 | #endif |
| 256 | const char *strerror = NULL; | 268 | const char *strerror = NULL; |
| 257 | int sig = 0; | 269 | int sig = 0; |
| @@ -267,11 +279,6 @@ asmlinkage void trap_c(struct pt_regs *fp) | |||
| 267 | * double faults if the stack has become corrupt | 279 | * double faults if the stack has become corrupt |
| 268 | */ | 280 | */ |
| 269 | 281 | ||
| 270 | #ifndef CONFIG_KGDB | ||
| 271 | /* IPEND is skipped if KGDB isn't enabled (see entry code) */ | ||
| 272 | fp->ipend = bfin_read_IPEND(); | ||
| 273 | #endif | ||
| 274 | |||
| 275 | /* trap_c() will be called for exceptions. During exceptions | 282 | /* trap_c() will be called for exceptions. During exceptions |
| 276 | * processing, the pc value should be set with retx value. | 283 | * processing, the pc value should be set with retx value. |
| 277 | * With this change we can cleanup some code in signal.c- TODO | 284 | * With this change we can cleanup some code in signal.c- TODO |
| @@ -404,7 +411,7 @@ asmlinkage void trap_c(struct pt_regs *fp) | |||
| 404 | /* 0x23 - Data CPLB protection violation, handled here */ | 411 | /* 0x23 - Data CPLB protection violation, handled here */ |
| 405 | case VEC_CPLB_VL: | 412 | case VEC_CPLB_VL: |
| 406 | info.si_code = ILL_CPLB_VI; | 413 | info.si_code = ILL_CPLB_VI; |
| 407 | sig = SIGBUS; | 414 | sig = SIGSEGV; |
| 408 | strerror = KERN_NOTICE EXC_0x23(KERN_NOTICE); | 415 | strerror = KERN_NOTICE EXC_0x23(KERN_NOTICE); |
| 409 | CHK_DEBUGGER_TRAP_MAYBE(); | 416 | CHK_DEBUGGER_TRAP_MAYBE(); |
| 410 | break; | 417 | break; |
| @@ -904,7 +911,7 @@ void show_stack(struct task_struct *task, unsigned long *stack) | |||
| 904 | frame_no = 0; | 911 | frame_no = 0; |
| 905 | 912 | ||
| 906 | for (addr = (unsigned int *)((unsigned int)stack & ~0xF), i = 0; | 913 | for (addr = (unsigned int *)((unsigned int)stack & ~0xF), i = 0; |
| 907 | addr <= endstack; addr++, i++) { | 914 | addr < endstack; addr++, i++) { |
| 908 | 915 | ||
| 909 | ret_addr = 0; | 916 | ret_addr = 0; |
| 910 | if (!j && i % 8 == 0) | 917 | if (!j && i % 8 == 0) |
| @@ -949,6 +956,7 @@ void show_stack(struct task_struct *task, unsigned long *stack) | |||
| 949 | } | 956 | } |
| 950 | #endif | 957 | #endif |
| 951 | } | 958 | } |
| 959 | EXPORT_SYMBOL(show_stack); | ||
| 952 | 960 | ||
| 953 | void dump_stack(void) | 961 | void dump_stack(void) |
| 954 | { | 962 | { |
| @@ -1090,7 +1098,7 @@ void show_regs(struct pt_regs *fp) | |||
| 1090 | struct irqaction *action; | 1098 | struct irqaction *action; |
| 1091 | unsigned int i; | 1099 | unsigned int i; |
| 1092 | unsigned long flags = 0; | 1100 | unsigned long flags = 0; |
| 1093 | unsigned int cpu = smp_processor_id(); | 1101 | unsigned int cpu = raw_smp_processor_id(); |
| 1094 | unsigned char in_atomic = (bfin_read_IPEND() & 0x10) || in_atomic(); | 1102 | unsigned char in_atomic = (bfin_read_IPEND() & 0x10) || in_atomic(); |
| 1095 | 1103 | ||
| 1096 | verbose_printk(KERN_NOTICE "\n"); | 1104 | verbose_printk(KERN_NOTICE "\n"); |
| @@ -1116,10 +1124,16 @@ void show_regs(struct pt_regs *fp) | |||
| 1116 | 1124 | ||
| 1117 | verbose_printk(KERN_NOTICE "%s", linux_banner); | 1125 | verbose_printk(KERN_NOTICE "%s", linux_banner); |
| 1118 | 1126 | ||
| 1119 | verbose_printk(KERN_NOTICE "\nSEQUENCER STATUS:\t\t%s\n", | 1127 | verbose_printk(KERN_NOTICE "\nSEQUENCER STATUS:\t\t%s\n", print_tainted()); |
| 1120 | print_tainted()); | 1128 | verbose_printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx IMASK: %04lx SYSCFG: %04lx\n", |
| 1121 | verbose_printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx SYSCFG: %04lx\n", | 1129 | (long)fp->seqstat, fp->ipend, cpu_pda[raw_smp_processor_id()].ex_imask, fp->syscfg); |
| 1122 | (long)fp->seqstat, fp->ipend, fp->syscfg); | 1130 | if (fp->ipend & EVT_IRPTEN) |
| 1131 | verbose_printk(KERN_NOTICE " Global Interrupts Disabled (IPEND[4])\n"); | ||
| 1132 | if (!(cpu_pda[raw_smp_processor_id()].ex_imask & (EVT_IVG13 | EVT_IVG12 | EVT_IVG11 | | ||
| 1133 | EVT_IVG10 | EVT_IVG9 | EVT_IVG8 | EVT_IVG7 | EVT_IVTMR))) | ||
| 1134 | verbose_printk(KERN_NOTICE " Peripheral interrupts masked off\n"); | ||
| 1135 | if (!(cpu_pda[raw_smp_processor_id()].ex_imask & (EVT_IVG15 | EVT_IVG14))) | ||
| 1136 | verbose_printk(KERN_NOTICE " Kernel interrupts masked off\n"); | ||
| 1123 | if ((fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR) { | 1137 | if ((fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR) { |
| 1124 | verbose_printk(KERN_NOTICE " HWERRCAUSE: 0x%lx\n", | 1138 | verbose_printk(KERN_NOTICE " HWERRCAUSE: 0x%lx\n", |
| 1125 | (fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14); | 1139 | (fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14); |
