summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/SOURCES2
-rw-r--r--firmware/export/panic.h6
-rw-r--r--firmware/panic.c32
-rw-r--r--firmware/target/arm/system-arm.c19
-rw-r--r--firmware/target/hosted/ypr0/ypr0.make2
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%) \