diff options
Diffstat (limited to 'firmware')
| -rw-r--r-- | firmware/SOURCES | 2 | ||||
| -rw-r--r-- | firmware/export/panic.h | 6 | ||||
| -rw-r--r-- | firmware/panic.c | 32 | ||||
| -rw-r--r-- | firmware/target/arm/system-arm.c | 19 | ||||
| -rw-r--r-- | firmware/target/hosted/ypr0/ypr0.make | 2 |
5 files changed, 55 insertions, 6 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES index e5df779..85705cb 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -433,7 +433,7 @@ target/coldfire/i2c-coldfire.c target/coldfire/ata-as-coldfire.S #endif -#elif defined(CPU_PP) || (defined(CPU_ARM) && CONFIG_PLATFORM & PLATFORM_NATIVE) +#elif defined(CPU_PP) || (defined(CPU_ARM) && (CONFIG_PLATFORM & PLATFORM_NATIVE)) /* CPU_PP => CPU_ARM, CPU_ARM !=> CPU_PP */ # if ARM_ARCH < 6 diff --git a/firmware/export/panic.h b/firmware/export/panic.h index b0325aa..7767c67 100644 --- a/firmware/export/panic.h +++ b/firmware/export/panic.h @@ -22,8 +22,12 @@ #ifndef __PANIC_H__ #define __PANIC_H__ +#include "config.h" #include "gcc_extensions.h" +#if defined(CPU_ARM) +void panicf( const char *fmt, ... ) __attribute__ ((naked)) ATTRIBUTE_PRINTF(1, 2); +#else void panicf( const char *fmt, ... ) ATTRIBUTE_PRINTF(1, 2); - +#endif #endif /* __PANIC_H__ */ diff --git a/firmware/panic.c b/firmware/panic.c index bd2c719..cdefc5a 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 diff --git a/firmware/target/arm/system-arm.c b/firmware/target/arm/system-arm.c index 23ccfd1..c4692bb 100644 --- a/firmware/target/arm/system-arm.c +++ b/firmware/target/arm/system-arm.c @@ -25,6 +25,9 @@ #include "font.h" #include "gcc_extensions.h" +#include <get_sp.h> +#include <backtrace.h> + static const char* const uiename[] = { "Undefined instruction", "Prefetch abort", @@ -38,6 +41,12 @@ static const char* const uiename[] = { */ void NORETURN_ATTR UIE(unsigned int pc, unsigned int num) { + /* safe guard variable - we call backtrace() only on first + * UIE call. This prevent endless loop if backtrace() touches + * memory regions which cause abort + */ + static bool triggered = false; + #if LCD_DEPTH > 1 lcd_set_backdrop(NULL); lcd_set_drawmode(DRMODE_SOLID); @@ -49,9 +58,7 @@ void NORETURN_ATTR UIE(unsigned int pc, unsigned int num) lcd_setfont(FONT_SYSFIXED); lcd_set_viewport(NULL); lcd_clear_display(); - lcd_puts(0, line++, uiename[num]); - lcd_putsf(0, line++, "at %08x" IF_COP(" (%d)"), pc - IF_COP(, CURRENT_CORE)); + lcd_putsf(0, line++, "%s at %08x" IF_COP(" (%d)"), uiename[num], pc IF_COP(, CURRENT_CORE)); #if !defined(CPU_ARM7TDMI) && (CONFIG_CPU != RK27XX) /* arm7tdmi has no MPU/MMU */ if(num == 1 || num == 2) /* prefetch / data abort */ @@ -88,6 +95,12 @@ void NORETURN_ATTR UIE(unsigned int pc, unsigned int num) } /* num == 1 || num == 2 // prefetch/data abort */ #endif /* !defined(CPU_ARM7TDMI */ + if (!triggered) + { + triggered = true; + backtrace(pc, __get_sp(), &line); + } + lcd_update(); disable_interrupt(IRQ_FIQ_STATUS); diff --git a/firmware/target/hosted/ypr0/ypr0.make b/firmware/target/hosted/ypr0/ypr0.make index c211487..1b67054 100644 --- a/firmware/target/hosted/ypr0/ypr0.make +++ b/firmware/target/hosted/ypr0/ypr0.make @@ -14,7 +14,7 @@ SIMFLAGS += $(INCLUDES) $(DEFINES) -DHAVE_CONFIG_H $(GCCOPTS) .SECONDEXPANSION: # $$(OBJ) is not populated until after this -$(BUILDDIR)/rockbox.elf : $$(OBJ) $$(FIRMLIB) $$(VOICESPEEXLIB) $$(SKINLIB) +$(BUILDDIR)/rockbox.elf : $$(OBJ) $$(FIRMLIB) $$(VOICESPEEXLIB) $$(SKINLIB) $$(UNWARMINDER) $(call PRINTS,LD $(@F))$(CC) $(GCCOPTS) -Os -o $@ $(OBJ) \ -L$(BUILDDIR)/firmware -lfirmware \ -L$(BUILDDIR)/apps/codecs $(VOICESPEEXLIB:lib%.a=-l%) \ |