summaryrefslogtreecommitdiff
path: root/firmware/panic.c
diff options
context:
space:
mode:
authorMarcin Bukat <marcin.bukat@gmail.com>2012-01-25 09:57:59 +0100
committerMarcin Bukat <marcin.bukat@gmail.com>2012-02-22 08:33:26 +0100
commitb4eab599513324dcaffa4c5693345ae11f3f9725 (patch)
tree58d66298269d2cec58102724565b573f250b5153 /firmware/panic.c
parent680c6fcde1eabb45dd12c59718d708b2cda61f6a (diff)
Arm stack unwinder
Simplified stack unwinder for ARM. This is port of http://www.mcternan.me.uk/ArmStackUnwinding/ backtrace() is called from UIE() on native targets and from panicf() on both native and ARM RaaA. Change-Id: I8e4b3c02490dd60b30aa372fe842d193b8929ce0
Diffstat (limited to 'firmware/panic.c')
-rw-r--r--firmware/panic.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/firmware/panic.c b/firmware/panic.c
index bd2c719607..cdefc5a0b8 100644
--- a/firmware/panic.c
+++ b/firmware/panic.c
@@ -31,14 +31,42 @@
#include "power.h"
#include "system.h"
+#if defined(CPU_ARM)
+#include "gcc_extensions.h"
+#include <backtrace.h>
+#endif
+
static char panic_buf[128];
#define LINECHARS (LCD_WIDTH/SYSFONT_WIDTH) - 2
+#if defined(CPU_ARM)
+void panicf_f( const char *fmt, ...);
+
+/* we wrap panicf() here with naked function to catch SP value */
+void panicf( const char *fmt, ...)
+{
+ (void)fmt;
+ asm volatile ("mov r4, sp \n"
+ "b panicf_f \n"
+ );
+}
+
/*
* "Dude. This is pretty fucked-up, right here."
*/
+void panicf_f( const char *fmt, ...)
+{
+ int sp;
+
+ asm volatile ("mov %[SP],r4 \n"
+ : [SP] "=r" (sp)
+ );
+
+ int pc = (int)__builtin_return_address(0);
+#else
void panicf( const char *fmt, ...)
{
+#endif
va_list ap;
#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
@@ -82,6 +110,10 @@ void panicf( const char *fmt, ...)
panic_buf[i+LINECHARS] = c;
}
}
+
+#if defined(CPU_ARM)
+ backtrace(pc, sp, &y);
+#endif
#else
/* no LCD */
#endif