diff options
Diffstat (limited to 'arch/blackfin/kernel/early_printk.c')
-rw-r--r-- | arch/blackfin/kernel/early_printk.c | 74 |
1 files changed, 70 insertions, 4 deletions
diff --git a/arch/blackfin/kernel/early_printk.c b/arch/blackfin/kernel/early_printk.c index 2ab56811841..931c78b5ea1 100644 --- a/arch/blackfin/kernel/early_printk.c +++ b/arch/blackfin/kernel/early_printk.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/serial_core.h> | 27 | #include <linux/serial_core.h> |
28 | #include <linux/console.h> | 28 | #include <linux/console.h> |
29 | #include <linux/string.h> | 29 | #include <linux/string.h> |
30 | #include <linux/reboot.h> | ||
30 | #include <asm/blackfin.h> | 31 | #include <asm/blackfin.h> |
31 | #include <asm/irq_handler.h> | 32 | #include <asm/irq_handler.h> |
32 | #include <asm/early_printk.h> | 33 | #include <asm/early_printk.h> |
@@ -181,6 +182,22 @@ asmlinkage void __init init_early_exception_vectors(void) | |||
181 | u32 evt; | 182 | u32 evt; |
182 | SSYNC(); | 183 | SSYNC(); |
183 | 184 | ||
185 | /* | ||
186 | * This starts up the shadow buffer, incase anything crashes before | ||
187 | * setup arch | ||
188 | */ | ||
189 | mark_shadow_error(); | ||
190 | early_shadow_puts(linux_banner); | ||
191 | early_shadow_stamp(); | ||
192 | |||
193 | if (CPUID != bfin_cpuid()) { | ||
194 | early_shadow_puts("Running on wrong machine type, expected"); | ||
195 | early_shadow_reg(CPUID, 16); | ||
196 | early_shadow_puts(", but running on"); | ||
197 | early_shadow_reg(bfin_cpuid(), 16); | ||
198 | early_shadow_puts("\n"); | ||
199 | } | ||
200 | |||
184 | /* cannot program in software: | 201 | /* cannot program in software: |
185 | * evt0 - emulation (jtag) | 202 | * evt0 - emulation (jtag) |
186 | * evt1 - reset | 203 | * evt1 - reset |
@@ -199,6 +216,7 @@ asmlinkage void __init init_early_exception_vectors(void) | |||
199 | 216 | ||
200 | } | 217 | } |
201 | 218 | ||
219 | __attribute__((__noreturn__)) | ||
202 | asmlinkage void __init early_trap_c(struct pt_regs *fp, void *retaddr) | 220 | asmlinkage void __init early_trap_c(struct pt_regs *fp, void *retaddr) |
203 | { | 221 | { |
204 | /* This can happen before the uart is initialized, so initialize | 222 | /* This can happen before the uart is initialized, so initialize |
@@ -210,10 +228,58 @@ asmlinkage void __init early_trap_c(struct pt_regs *fp, void *retaddr) | |||
210 | if (likely(early_console == NULL) && CPUID == bfin_cpuid()) | 228 | if (likely(early_console == NULL) && CPUID == bfin_cpuid()) |
211 | setup_early_printk(DEFAULT_EARLY_PORT); | 229 | setup_early_printk(DEFAULT_EARLY_PORT); |
212 | 230 | ||
213 | printk(KERN_EMERG "Early panic\n"); | 231 | if (!shadow_console_enabled()) { |
214 | dump_bfin_mem(fp); | 232 | /* crap - we crashed before setup_arch() */ |
215 | show_regs(fp); | 233 | early_shadow_puts("panic before setup_arch\n"); |
216 | dump_bfin_trace_buffer(); | 234 | early_shadow_puts("IPEND:"); |
235 | early_shadow_reg(fp->ipend, 16); | ||
236 | if (fp->seqstat & SEQSTAT_EXCAUSE) { | ||
237 | early_shadow_puts("\nEXCAUSE:"); | ||
238 | early_shadow_reg(fp->seqstat & SEQSTAT_EXCAUSE, 8); | ||
239 | } | ||
240 | if (fp->seqstat & SEQSTAT_HWERRCAUSE) { | ||
241 | early_shadow_puts("\nHWERRCAUSE:"); | ||
242 | early_shadow_reg( | ||
243 | (fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14, 8); | ||
244 | } | ||
245 | early_shadow_puts("\nErr @"); | ||
246 | if (fp->ipend & EVT_EVX) | ||
247 | early_shadow_reg(fp->retx, 32); | ||
248 | else | ||
249 | early_shadow_reg(fp->pc, 32); | ||
250 | #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON | ||
251 | early_shadow_puts("\nTrace:"); | ||
252 | if (likely(bfin_read_TBUFSTAT() & TBUFCNT)) { | ||
253 | while (bfin_read_TBUFSTAT() & TBUFCNT) { | ||
254 | early_shadow_puts("\nT :"); | ||
255 | early_shadow_reg(bfin_read_TBUF(), 32); | ||
256 | early_shadow_puts("\n S :"); | ||
257 | early_shadow_reg(bfin_read_TBUF(), 32); | ||
258 | } | ||
259 | } | ||
260 | #endif | ||
261 | early_shadow_puts("\nUse bfin-elf-addr2line to determine " | ||
262 | "function names\n"); | ||
263 | /* | ||
264 | * We should panic(), but we can't - since panic calls printk, | ||
265 | * and printk uses memcpy. | ||
266 | * we want to reboot, but if the machine type is different, | ||
267 | * can't due to machine specific reboot sequences | ||
268 | */ | ||
269 | if (CPUID == bfin_cpuid()) { | ||
270 | early_shadow_puts("Trying to restart\n"); | ||
271 | machine_restart(""); | ||
272 | } | ||
273 | |||
274 | early_shadow_puts("Halting, since it is not safe to restart\n"); | ||
275 | while (1) | ||
276 | asm volatile ("EMUEXCPT; IDLE;\n"); | ||
277 | |||
278 | } else { | ||
279 | printk(KERN_EMERG "Early panic\n"); | ||
280 | show_regs(fp); | ||
281 | dump_bfin_trace_buffer(); | ||
282 | } | ||
217 | 283 | ||
218 | panic("Died early"); | 284 | panic("Died early"); |
219 | } | 285 | } |