diff options
author | Marcin Bukat <marcin.bukat@gmail.com> | 2012-01-25 09:57:59 +0100 |
---|---|---|
committer | Marcin Bukat <marcin.bukat@gmail.com> | 2012-02-22 08:33:26 +0100 |
commit | b4eab599513324dcaffa4c5693345ae11f3f9725 (patch) | |
tree | 58d66298269d2cec58102724565b573f250b5153 /firmware/panic.c | |
parent | 680c6fcde1eabb45dd12c59718d708b2cda61f6a (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.c | 32 |
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 |