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); |