From 4ed78f5c72649002d78d48d9a117826a5d9c36f9 Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Thu, 8 Jan 2009 10:15:32 +0000 Subject: Clean up panicf and introduce system_exception_wait to do further target tasks and wait for a button when an unrecoverable error has occurred (panic, UIE, etc.). Returning from that function should reboot or don't return from it. Move UIE and __div0 for ARM to its own file. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19716 a1c6a512-1295-4272-9138-f99709370657 --- firmware/SOURCES | 1 + firmware/export/system.h | 3 + firmware/panic.c | 72 ++++----------------- firmware/system.c | 58 +---------------- firmware/target/arm/as3525/system-as3525.c | 5 ++ .../target/arm/imx31/gigabeat-s/system-imx31.c | 10 +++ firmware/target/arm/pnx0101/system-pnx0101.c | 5 ++ .../target/arm/s3c2440/gigabeat-fx/system-meg-fx.c | 6 ++ firmware/target/arm/s5l8700/system-s5l8700.c | 5 ++ firmware/target/arm/system-arm.c | 66 +++++++++++++++++++ firmware/target/arm/system-pp5002.c | 12 ++++ firmware/target/arm/system-pp502x.c | 11 ++++ firmware/target/arm/tcc77x/system-tcc77x.c | 5 ++ firmware/target/arm/tcc780x/system-tcc780x.c | 5 ++ firmware/target/coldfire/system-coldfire.c | 21 +++--- .../target/mips/ingenic_jz47xx/system-jz4740.c | 10 +++ firmware/target/sh/system-sh.c | 74 ++++++++++++---------- uisimulator/common/stubs.c | 10 +++ 18 files changed, 220 insertions(+), 159 deletions(-) create mode 100644 firmware/target/arm/system-arm.c diff --git a/firmware/SOURCES b/firmware/SOURCES index c8f824a849..f4d86bc2cd 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -326,6 +326,7 @@ target/arm/memset16-arm.S #ifdef HAVE_PRIORITY_SCHEDULING target/arm/ffs-arm.S #endif +target/arm/system-arm.c #if CONFIG_I2C == I2C_PP5024 || CONFIG_I2C == I2C_PP5020 || CONFIG_I2C == I2C_PP5002 target/arm/i2c-pp.c #elif CONFIG_I2C == I2C_PNX0101 diff --git a/firmware/export/system.h b/firmware/export/system.h index b82e2b1ad0..8ebd30ac4e 100644 --- a/firmware/export/system.h +++ b/firmware/export/system.h @@ -27,6 +27,9 @@ #include "kernel.h" extern void system_reboot (void); +/* Called from any UIE handler and panicf - wait for a key and return + * to reboot system. */ +extern void system_exception_wait(void); extern void system_init(void); extern long cpu_frequency; diff --git a/firmware/panic.c b/firmware/panic.c index 8fcdd24188..0223dc1494 100644 --- a/firmware/panic.c +++ b/firmware/panic.c @@ -32,6 +32,7 @@ #include "system.h" static char panic_buf[128]; +#define LINECHARS (LCD_WIDTH/SYSFONT_WIDTH) /* * "Dude. This is pretty fucked-up, right here." @@ -41,17 +42,12 @@ void panicf( const char *fmt, ...) va_list ap; #ifndef SIMULATOR -#if (CONFIG_LED == LED_REAL) - bool state = false; - int i = 0; -#endif - /* Disable interrupts */ #ifdef CPU_ARM - disable_fiq(); -#endif - + disable_interrupt(IRQ_FIQ_STATUS); +#else set_irq_level(DISABLE_INTERRUPTS); +#endif #endif /* SIMULATOR */ va_start( ap, fmt ); @@ -69,12 +65,11 @@ void panicf( const char *fmt, ...) { /* wrap panic line */ int i, y=1, len = strlen(panic_buf); -#define STEP (LCD_WIDTH/SYSFONT_WIDTH) - for (i=0; i #include "config.h" -#include -#include "lcd.h" -#include "font.h" #include "system.h" +#include #include "kernel.h" #include "thread.h" -#include "timer.h" -#include "inttypes.h" #include "string.h" #ifndef SIMULATOR @@ -226,54 +221,3 @@ bool detect_original_firmware(void) return !(detect_flashed_ramimage() || detect_flashed_romimage()); } -#if defined(CPU_ARM) - -static const char* const uiename[] = { - "Undefined instruction", - "Prefetch abort", - "Data abort", - "Divide by zero" -}; - -/* Unexpected Interrupt or Exception handler. Currently only deals with - exceptions, but will deal with interrupts later. - */ -void UIE(unsigned int pc, unsigned int num) __attribute__((noreturn)); -void UIE(unsigned int pc, unsigned int num) -{ - char str[32]; - - lcd_clear_display(); -#ifdef HAVE_LCD_BITMAP - lcd_setfont(FONT_SYSFIXED); -#endif - lcd_puts(0, 0, uiename[num]); - snprintf(str, sizeof(str), "at %08x" IF_COP(" (%d)"), pc - IF_COP(, CURRENT_CORE)); - lcd_puts(0, 1, str); - lcd_update(); - - while (1) - { - /* TODO: perhaps add button handling in here when we get a polling - driver some day. - */ - core_idle(); - } -} - -#ifndef STUB -/* Needs to be here or gcc won't find it */ -void __div0(void) __attribute__((naked)); -void __div0(void) -{ - asm volatile ( - "ldr r0, [sp] \r\n" - "mov r1, #3 \r\n" - "b UIE \r\n" - ); -} -#endif - -#endif /* CPU_ARM */ - diff --git a/firmware/target/arm/as3525/system-as3525.c b/firmware/target/arm/as3525/system-as3525.c index b502b22425..c8366fe2bf 100644 --- a/firmware/target/arm/as3525/system-as3525.c +++ b/firmware/target/arm/as3525/system-as3525.c @@ -279,6 +279,11 @@ void system_reboot(void) while(1); } +void system_exception_wait(void) +{ + while (1); +} + int system_memory_guard(int newmode) { (void)newmode; diff --git a/firmware/target/arm/imx31/gigabeat-s/system-imx31.c b/firmware/target/arm/imx31/gigabeat-s/system-imx31.c index 1e084485ac..c339f4fe7c 100644 --- a/firmware/target/arm/imx31/gigabeat-s/system-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/system-imx31.c @@ -65,6 +65,16 @@ int system_memory_guard(int newmode) void system_reboot(void) { + /* Multi-context so no SPI available (WDT?) */ + while (1); +} + +void system_exception_wait(void) +{ + /* Called in many contexts so button reading may be a chore */ + avic_disable_int(ALL); + core_idle(); + while (1); } void system_init(void) diff --git a/firmware/target/arm/pnx0101/system-pnx0101.c b/firmware/target/arm/pnx0101/system-pnx0101.c index f447f5f044..63720d11be 100644 --- a/firmware/target/arm/pnx0101/system-pnx0101.c +++ b/firmware/target/arm/pnx0101/system-pnx0101.c @@ -305,6 +305,11 @@ void system_reboot(void) while (1); } +void system_exception_wait(void) +{ + while (1); +} + int system_memory_guard(int newmode) { (void)newmode; diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/system-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/system-meg-fx.c index 43e2c408a2..61b4653726 100644 --- a/firmware/target/arm/s3c2440/gigabeat-fx/system-meg-fx.c +++ b/firmware/target/arm/s3c2440/gigabeat-fx/system-meg-fx.c @@ -111,6 +111,12 @@ void system_reboot(void) ; } +void system_exception_wait(void) +{ + INTMSK = 0xFFFFFFFF; + while (GPGDAT & (1 << 0)) == 0); /* Wait for power button */ +} + static void set_page_tables(void) { map_section(0, 0, 0x1000, CACHE_NONE); /* map every memory region to itself */ diff --git a/firmware/target/arm/s5l8700/system-s5l8700.c b/firmware/target/arm/s5l8700/system-s5l8700.c index 1370db40d7..c535a0d955 100644 --- a/firmware/target/arm/s5l8700/system-s5l8700.c +++ b/firmware/target/arm/s5l8700/system-s5l8700.c @@ -132,6 +132,11 @@ void system_reboot(void) { } +void system_exception_wait(void) +{ + while (1); +} + int system_memory_guard(int newmode) { (void)newmode; diff --git a/firmware/target/arm/system-arm.c b/firmware/target/arm/system-arm.c new file mode 100644 index 0000000000..5c5a18c867 --- /dev/null +++ b/firmware/target/arm/system-arm.c @@ -0,0 +1,66 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2006 by Thom Johansen + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "config.h" +#include "system.h" +#include +#include "lcd.h" +#include "font.h" + +static const char* const uiename[] = { + "Undefined instruction", + "Prefetch abort", + "Data abort", + "Divide by zero" +}; + +/* Unexpected Interrupt or Exception handler. Currently only deals with + exceptions, but will deal with interrupts later. + */ +void __attribute__((noreturn)) UIE(unsigned int pc, unsigned int num) +{ + char str[32]; + + lcd_clear_display(); +#ifdef HAVE_LCD_BITMAP + lcd_setfont(FONT_SYSFIXED); +#endif + lcd_puts(0, 0, uiename[num]); + snprintf(str, sizeof(str), "at %08x" IF_COP(" (%d)"), pc + IF_COP(, CURRENT_CORE)); + lcd_puts(0, 1, str); + lcd_update(); + + disable_interrupt(IRQ_FIQ_STATUS); + + system_exception_wait(); /* If this returns, try to reboot */ + system_reboot(); + while (1); /* halt */ +} + +/* Needs to be here or gcc won't find it */ +void __attribute__((naked)) __div0(void) +{ + asm volatile ( + "ldr r0, [sp] \r\n" + "mov r1, #3 \r\n" + "b UIE \r\n" + ); +} diff --git a/firmware/target/arm/system-pp5002.c b/firmware/target/arm/system-pp5002.c index b9a937c6e8..1b37d3303f 100644 --- a/firmware/target/arm/system-pp5002.c +++ b/firmware/target/arm/system-pp5002.c @@ -203,6 +203,18 @@ void system_init(void) void system_reboot(void) { DEV_RS |= 4; + while (1); +} + +void system_exception_wait(void) +{ + /* FIXME: we just need the right buttons */ + CPU_INT_DIS = -1; + COP_INT_DIS = -1; + + /* Halt */ + sleep_core(CURRENT_CORE); + while (1); } int system_memory_guard(int newmode) diff --git a/firmware/target/arm/system-pp502x.c b/firmware/target/arm/system-pp502x.c index b1f178c8d5..277b1e9a0b 100644 --- a/firmware/target/arm/system-pp502x.c +++ b/firmware/target/arm/system-pp502x.c @@ -455,6 +455,17 @@ void system_reboot(void) while (1); } +void system_exception_wait(void) +{ + /* FIXME: we just need the right buttons */ + CPU_INT_DIS = -1; + COP_INT_DIS = -1; + + /* Halt */ + PROC_CTL(CURRENT_CORE) = 0x40000000; + while (1); +} + int system_memory_guard(int newmode) { (void)newmode; diff --git a/firmware/target/arm/tcc77x/system-tcc77x.c b/firmware/target/arm/tcc77x/system-tcc77x.c index 0896026b55..90e53afb14 100644 --- a/firmware/target/arm/tcc77x/system-tcc77x.c +++ b/firmware/target/arm/tcc77x/system-tcc77x.c @@ -58,6 +58,11 @@ void system_reboot(void) { } +void system_exception_wait(void) +{ + while (1); +} + /* TODO - these should live in the target-specific directories and once we understand what all the GPIO pins do, move the init to the specific driver for that hardware. For now, we just perform the diff --git a/firmware/target/arm/tcc780x/system-tcc780x.c b/firmware/target/arm/tcc780x/system-tcc780x.c index 5ecbbdac7c..bf3c64cd7a 100644 --- a/firmware/target/arm/tcc780x/system-tcc780x.c +++ b/firmware/target/arm/tcc780x/system-tcc780x.c @@ -287,6 +287,11 @@ void system_reboot(void) while (1); } +void system_exception_wait(void) +{ + while ((GPIOA & 0x10) == 0); /* check for power button */ +} + int system_memory_guard(int newmode) { (void)newmode; diff --git a/firmware/target/coldfire/system-coldfire.c b/firmware/target/coldfire/system-coldfire.c index e04255746f..c4651a3c80 100644 --- a/firmware/target/coldfire/system-coldfire.c +++ b/firmware/target/coldfire/system-coldfire.c @@ -177,16 +177,11 @@ static void system_display_exception_info(unsigned long format, lcd_puts(0, 1, str); lcd_update(); - /* set cpu frequency to 11mhz (to prevent overheating) */ - DCR = (DCR & ~0x01ff) | 1; - PLLCR = EXCP_PLLCR; + system_exception_wait(); - while (1) - { - if ((EXCP_BUTTON_GPIO_READ & EXCP_BUTTON_MASK) == EXCP_BUTTON_VALUE) - SYPCR = 0xc0; - /* Start watchdog timer with 512 cycles timeout. Don't service it. */ - } + /* Start watchdog timer with 512 cycles timeout. Don't service it. */ + SYPCR = 0xc0; + while (1); /* We need a reset method that works in all cases. Calling system_reboot() doesn't work when we're called from the debug interrupt, because then @@ -294,6 +289,14 @@ void system_reboot (void) asm(" jmp (%a0)"); } +void system_exception_wait(void) +{ + /* set cpu frequency to 11mhz (to prevent overheating) */ + DCR = (DCR & ~0x01ff) | 1; + PLLCR = EXCP_PLLCR; + while ((EXCP_BUTTON_GPIO_READ & EXCP_BUTTON_MASK) != EXCP_BUTTON_VALUE); +} + /* Utilise the breakpoint hardware to catch invalid memory accesses. */ int system_memory_guard(int newmode) { diff --git a/firmware/target/mips/ingenic_jz47xx/system-jz4740.c b/firmware/target/mips/ingenic_jz47xx/system-jz4740.c index c741d9f311..033b42214b 100644 --- a/firmware/target/mips/ingenic_jz47xx/system-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/system-jz4740.c @@ -887,6 +887,16 @@ void system_reboot(void) while (1); } +void system_exception_wait(void) +{ + /* check for power button without including any .h file */ + while (1) + { + if( (~(*(volatile unsigned int *)(0xB0010300))) & (1 << 29) ) + break; + } +} + void power_off(void) { /* Put system into hibernate mode */ diff --git a/firmware/target/sh/system-sh.c b/firmware/target/sh/system-sh.c index 63703ab786..02af40282f 100644 --- a/firmware/target/sh/system-sh.c +++ b/firmware/target/sh/system-sh.c @@ -283,10 +283,6 @@ extern void UIE4(void); /* needed for calculating the UIE number */ void UIE (unsigned int pc) __attribute__((section(".text"))); void UIE (unsigned int pc) /* Unexpected Interrupt or Exception */ { -#if CONFIG_LED == LED_REAL - bool state = false; - int i = 0; -#endif unsigned int n; char str[32]; @@ -305,35 +301,13 @@ void UIE (unsigned int pc) /* Unexpected Interrupt or Exception */ lcd_puts(0,1,str); lcd_update (); - while (1) - { -#if CONFIG_LED == LED_REAL - if (--i <= 0) - { - state = !state; - led(state); - i = 240000; - } -#endif + /* try to restart firmware if ON is pressed */ + system_exception_wait(); - /* try to restart firmware if ON is pressed */ -#if CONFIG_KEYPAD == PLAYER_PAD - if (!(PADRL & 0x20)) -#elif CONFIG_KEYPAD == RECORDER_PAD -#ifdef HAVE_FMADC - if (!(PCDR & 0x0008)) -#else - if (!(PBDRH & 0x01)) -#endif -#elif CONFIG_KEYPAD == ONDIO_PAD - if (!(PCDR & 0x0008)) -#endif - { - /* enable the watchguard timer, but don't service it */ - RSTCSR_W = 0x5a40; /* Reset enabled, power-on reset */ - TCSR_W = 0xa560; /* Watchdog timer mode, timer enabled, sysclk/2 */ - } - } + /* enable the watchguard timer, but don't service it */ + RSTCSR_W = 0x5a40; /* Reset enabled, power-on reset */ + TCSR_W = 0xa560; /* Watchdog timer mode, timer enabled, sysclk/2 */ + while (1); } void system_init(void) @@ -378,6 +352,42 @@ void system_reboot (void) "r"(*(int*)0),"r"(4)); } +void system_exception_wait(void) +{ +#if (CONFIG_LED == LED_REAL) + bool state = false; + int i = 0; +#endif + + while (1) + { +#if (CONFIG_LED == LED_REAL) + if (--i <= 0) + { + state = !state; + led(state); + i = 240000; + } +#endif + +#if CONFIG_KEYPAD == PLAYER_PAD + /* Player */ + if (!(PADRL & 0x20)) +#elif CONFIG_KEYPAD == RECORDER_PAD + /* Recorder */ +#ifdef HAVE_FMADC + if (!(PCDR & 0x0008)) +#else + if (!(PBDRH & 0x01)) +#endif +#elif CONFIG_KEYPAD == ONDIO_PAD + /* Ondio */ + if (!(PCDR & 0x0008)) +#endif /* CONFIG_KEYPAD */ + return; + } +} + /* Utilise the user break controller to catch invalid memory accesses. */ int system_memory_guard(int newmode) { diff --git a/uisimulator/common/stubs.c b/uisimulator/common/stubs.c index f50425b494..12b6f293a4 100644 --- a/uisimulator/common/stubs.c +++ b/uisimulator/common/stubs.c @@ -340,6 +340,16 @@ void touchpad_set_sensitivity(int level) } #endif +void system_exception_wait(void) +{ + while(1); +} + +void system_reboot(void) +{ + while(1); +} + /* assure an unused place to direct virtual pointers to */ #define VIRT_SIZE 0xFFFF /* more than enough for our string ID range */ unsigned char vp_dummy[VIRT_SIZE]; -- cgit v1.2.3