summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafaël Carré <rafael.carre@gmail.com>2010-03-09 16:19:50 +0000
committerRafaël Carré <rafael.carre@gmail.com>2010-03-09 16:19:50 +0000
commit8d720f4d4e956a0c97466def1f3600ae5c10f268 (patch)
treefa2c5f58cfaf2cd4549f0c951b2fb21861060afe
parent226cd04f742f36e72b110848694a5d80233a0b78 (diff)
downloadrockbox-8d720f4d4e956a0c97466def1f3600ae5c10f268.zip
rockbox-8d720f4d4e956a0c97466def1f3600ae5c10f268.tar.gz
rockbox-8d720f4d4e956a0c97466def1f3600ae5c10f268.tar.bz2
rockbox-8d720f4d4e956a0c97466def1f3600ae5c10f268.tar.xz
Display Fault status address register on data/prefetch aborts
Display Address status address register on data aborts Work on all ARM cpus but arm7tdmi (no MMU/MPU there) FlySpray: FS#10296 Author: myself with help of Torne Wuff git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25087 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/target/arm/system-arm.c42
1 files changed, 40 insertions, 2 deletions
diff --git a/firmware/target/arm/system-arm.c b/firmware/target/arm/system-arm.c
index 60e57cf..e83b7c5 100644
--- a/firmware/target/arm/system-arm.c
+++ b/firmware/target/arm/system-arm.c
@@ -42,12 +42,50 @@ void __attribute__((noreturn)) UIE(unsigned int pc, unsigned int num)
lcd_set_foreground(LCD_BLACK);
lcd_set_background(LCD_WHITE);
#endif
+ unsigned line = 0;
+
lcd_setfont(FONT_SYSFIXED);
lcd_set_viewport(NULL);
lcd_clear_display();
- lcd_puts(0, 0, uiename[num]);
- lcd_putsf(0, 1, "at %08x" IF_COP(" (%d)"), pc
+ lcd_puts(0, line++, uiename[num]);
+ lcd_putsf(0, line++, "at %08x" IF_COP(" (%d)"), pc
IF_COP(, CURRENT_CORE));
+
+#if !defined(CPU_ARM7TDMI) /* arm7tdmi has no MPU/MMU */
+ if(num == 1 || num == 2) /* prefetch / data abort */
+ {
+ register unsigned status;
+
+#if ARM_ARCH >= 6
+ /* ARMv6 has 2 different registers for prefetch & data aborts */
+ if(num == 1) /* instruction prefetch abort */
+ asm volatile( "mrc p15, 0, %0, c5, c0, 1\n" : "=r"(status));
+ else
+#endif
+ asm volatile( "mrc p15, 0, %0, c5, c0, 0\n" : "=r"(status));
+
+ lcd_putsf(0, line++, "FSR 0x%x", status);
+
+ unsigned int domain = (status >> 4) & 0xf;
+ unsigned int fault = status & 0xf;
+#if ARM_ARCH >= 6
+ fault |= (status & (1<<10)) >> 6; /* fault is 5 bits on armv6 */
+#endif
+ lcd_putsf(0, line++, "(domain %d, fault %d)", domain, fault);
+
+ if(num == 2) /* data abort */
+ {
+ register unsigned address;
+ /* read FAR (fault address register) */
+ asm volatile( "mrc p15, 0, %0, c6, c0\n" : "=r"(address));
+ lcd_putsf(0, line++, "address 0x%8x", address);
+#if ARM_ARCH >= 6
+ lcd_putsf(0, line++, (status & (1<<11)) ? "(write)" : "(read)");
+#endif
+ }
+ } /* num == 1 || num == 2 // prefetch/data abort */
+#endif /* !defined(CPU_ARM7TDMI */
+
lcd_update();
disable_interrupt(IRQ_FIQ_STATUS);