1
0
Fork 0
forked from len0rd/rockbox

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
This commit is contained in:
Michael Sevakis 2009-01-08 10:15:32 +00:00
parent 32d9752dcc
commit 4ed78f5c72
18 changed files with 220 additions and 159 deletions

View file

@ -326,6 +326,7 @@ target/arm/memset16-arm.S
#ifdef HAVE_PRIORITY_SCHEDULING #ifdef HAVE_PRIORITY_SCHEDULING
target/arm/ffs-arm.S target/arm/ffs-arm.S
#endif #endif
target/arm/system-arm.c
#if CONFIG_I2C == I2C_PP5024 || CONFIG_I2C == I2C_PP5020 || CONFIG_I2C == I2C_PP5002 #if CONFIG_I2C == I2C_PP5024 || CONFIG_I2C == I2C_PP5020 || CONFIG_I2C == I2C_PP5002
target/arm/i2c-pp.c target/arm/i2c-pp.c
#elif CONFIG_I2C == I2C_PNX0101 #elif CONFIG_I2C == I2C_PNX0101

View file

@ -27,6 +27,9 @@
#include "kernel.h" #include "kernel.h"
extern void system_reboot (void); 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 void system_init(void);
extern long cpu_frequency; extern long cpu_frequency;

View file

@ -32,6 +32,7 @@
#include "system.h" #include "system.h"
static char panic_buf[128]; static char panic_buf[128];
#define LINECHARS (LCD_WIDTH/SYSFONT_WIDTH)
/* /*
* "Dude. This is pretty fucked-up, right here." * "Dude. This is pretty fucked-up, right here."
@ -41,17 +42,12 @@ void panicf( const char *fmt, ...)
va_list ap; va_list ap;
#ifndef SIMULATOR #ifndef SIMULATOR
#if (CONFIG_LED == LED_REAL)
bool state = false;
int i = 0;
#endif
/* Disable interrupts */ /* Disable interrupts */
#ifdef CPU_ARM #ifdef CPU_ARM
disable_fiq(); disable_interrupt(IRQ_FIQ_STATUS);
#endif #else
set_irq_level(DISABLE_INTERRUPTS); set_irq_level(DISABLE_INTERRUPTS);
#endif
#endif /* SIMULATOR */ #endif /* SIMULATOR */
va_start( ap, fmt ); va_start( ap, fmt );
@ -69,12 +65,11 @@ void panicf( const char *fmt, ...)
{ {
/* wrap panic line */ /* wrap panic line */
int i, y=1, len = strlen(panic_buf); int i, y=1, len = strlen(panic_buf);
#define STEP (LCD_WIDTH/SYSFONT_WIDTH) for (i=0; i<len; i+=LINECHARS) {
for (i=0; i<len; i+=STEP) { unsigned char c = panic_buf[i+LINECHARS];
unsigned char c = panic_buf[i+STEP]; panic_buf[i+LINECHARS] = 0;
panic_buf[i+STEP] = 0;
lcd_puts(0, y++, (unsigned char *)panic_buf+i); lcd_puts(0, y++, (unsigned char *)panic_buf+i);
panic_buf[i+STEP] = c; panic_buf[i+LINECHARS] = c;
} }
} }
#else #else
@ -89,52 +84,7 @@ void panicf( const char *fmt, ...)
ide_power_enable(false); ide_power_enable(false);
#endif #endif
while (1) system_exception_wait(); /* if this returns, try to reboot */
{
#ifndef SIMULATOR
#if (CONFIG_LED == LED_REAL)
if (--i <= 0)
{
state = !state;
led(state);
i = 240000;
}
#endif
/* try to restart firmware if ON is pressed */
#if defined (CPU_PP)
/* For now, just sleep the core */
sleep_core(CURRENT_CORE);
#define system_reboot() nop
#elif defined (TOSHIBA_GIGABEAT_F)
if ((GPGDAT & (1 << 0)) != 0)
#elif defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
if ((GPIO1_READ & 0x22) == 0) /* check for ON button and !hold */
#elif defined(IAUDIO_X5) || defined(IAUDIO_M5)
if ((GPIO_READ & 0x0c000000) == 0x08000000) /* check for ON button and !hold */
#elif defined(IAUDIO_M3)
if ((GPIO1_READ & 0x202) == 0x200) /* check for ON button and !hold */
#elif defined(COWON_D2)
if (GPIOA & 0x10) /* check for power button */
#elif CONFIG_CPU == SH7034
#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 /* CONFIG_KEYPAD */
#elif defined(CREATIVE_ZVx)
if(false)
#elif defined(ONDA_VX747)
/* check for power button without including any .h file */
if( (~(*(volatile unsigned int *)(0xB0010300))) & (1 << 29) )
#endif /* CPU */
system_reboot(); system_reboot();
#endif /* !SIMULATOR */ while (1); /* halt */
}
} }

View file

@ -18,16 +18,11 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
****************************************************************************/ ****************************************************************************/
#include <stdio.h>
#include "config.h" #include "config.h"
#include <stdbool.h>
#include "lcd.h"
#include "font.h"
#include "system.h" #include "system.h"
#include <stdio.h>
#include "kernel.h" #include "kernel.h"
#include "thread.h" #include "thread.h"
#include "timer.h"
#include "inttypes.h"
#include "string.h" #include "string.h"
#ifndef SIMULATOR #ifndef SIMULATOR
@ -226,54 +221,3 @@ bool detect_original_firmware(void)
return !(detect_flashed_ramimage() || detect_flashed_romimage()); 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 */

View file

@ -279,6 +279,11 @@ void system_reboot(void)
while(1); while(1);
} }
void system_exception_wait(void)
{
while (1);
}
int system_memory_guard(int newmode) int system_memory_guard(int newmode)
{ {
(void)newmode; (void)newmode;

View file

@ -65,6 +65,16 @@ int system_memory_guard(int newmode)
void system_reboot(void) 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) void system_init(void)

View file

@ -305,6 +305,11 @@ void system_reboot(void)
while (1); while (1);
} }
void system_exception_wait(void)
{
while (1);
}
int system_memory_guard(int newmode) int system_memory_guard(int newmode)
{ {
(void)newmode; (void)newmode;

View file

@ -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) static void set_page_tables(void)
{ {
map_section(0, 0, 0x1000, CACHE_NONE); /* map every memory region to itself */ map_section(0, 0, 0x1000, CACHE_NONE); /* map every memory region to itself */

View file

@ -132,6 +132,11 @@ void system_reboot(void)
{ {
} }
void system_exception_wait(void)
{
while (1);
}
int system_memory_guard(int newmode) int system_memory_guard(int newmode)
{ {
(void)newmode; (void)newmode;

View file

@ -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 <stdio.h>
#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"
);
}

View file

@ -203,6 +203,18 @@ void system_init(void)
void system_reboot(void) void system_reboot(void)
{ {
DEV_RS |= 4; 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) int system_memory_guard(int newmode)

View file

@ -455,6 +455,17 @@ void system_reboot(void)
while (1); 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) int system_memory_guard(int newmode)
{ {
(void)newmode; (void)newmode;

View file

@ -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 /* TODO - these should live in the target-specific directories and
once we understand what all the GPIO pins do, move the init to the 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 specific driver for that hardware. For now, we just perform the

View file

@ -287,6 +287,11 @@ void system_reboot(void)
while (1); while (1);
} }
void system_exception_wait(void)
{
while ((GPIOA & 0x10) == 0); /* check for power button */
}
int system_memory_guard(int newmode) int system_memory_guard(int newmode)
{ {
(void)newmode; (void)newmode;

View file

@ -177,16 +177,11 @@ static void system_display_exception_info(unsigned long format,
lcd_puts(0, 1, str); lcd_puts(0, 1, str);
lcd_update(); lcd_update();
/* set cpu frequency to 11mhz (to prevent overheating) */ system_exception_wait();
DCR = (DCR & ~0x01ff) | 1;
PLLCR = EXCP_PLLCR;
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() /* 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 doesn't work when we're called from the debug interrupt, because then
@ -294,6 +289,14 @@ void system_reboot (void)
asm(" jmp (%a0)"); 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. */ /* Utilise the breakpoint hardware to catch invalid memory accesses. */
int system_memory_guard(int newmode) int system_memory_guard(int newmode)
{ {

View file

@ -887,6 +887,16 @@ void system_reboot(void)
while (1); 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) void power_off(void)
{ {
/* Put system into hibernate mode */ /* Put system into hibernate mode */

View file

@ -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) __attribute__((section(".text")));
void UIE (unsigned int pc) /* Unexpected Interrupt or Exception */ void UIE (unsigned int pc) /* Unexpected Interrupt or Exception */
{ {
#if CONFIG_LED == LED_REAL
bool state = false;
int i = 0;
#endif
unsigned int n; unsigned int n;
char str[32]; char str[32];
@ -305,35 +301,13 @@ void UIE (unsigned int pc) /* Unexpected Interrupt or Exception */
lcd_puts(0,1,str); lcd_puts(0,1,str);
lcd_update (); 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 */ /* try to restart firmware if ON is pressed */
#if CONFIG_KEYPAD == PLAYER_PAD system_exception_wait();
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 */ /* enable the watchguard timer, but don't service it */
RSTCSR_W = 0x5a40; /* Reset enabled, power-on reset */ RSTCSR_W = 0x5a40; /* Reset enabled, power-on reset */
TCSR_W = 0xa560; /* Watchdog timer mode, timer enabled, sysclk/2 */ TCSR_W = 0xa560; /* Watchdog timer mode, timer enabled, sysclk/2 */
} while (1);
}
} }
void system_init(void) void system_init(void)
@ -378,6 +352,42 @@ void system_reboot (void)
"r"(*(int*)0),"r"(4)); "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. */ /* Utilise the user break controller to catch invalid memory accesses. */
int system_memory_guard(int newmode) int system_memory_guard(int newmode)
{ {

View file

@ -340,6 +340,16 @@ void touchpad_set_sensitivity(int level)
} }
#endif #endif
void system_exception_wait(void)
{
while(1);
}
void system_reboot(void)
{
while(1);
}
/* assure an unused place to direct virtual pointers to */ /* assure an unused place to direct virtual pointers to */
#define VIRT_SIZE 0xFFFF /* more than enough for our string ID range */ #define VIRT_SIZE 0xFFFF /* more than enough for our string ID range */
unsigned char vp_dummy[VIRT_SIZE]; unsigned char vp_dummy[VIRT_SIZE];