diff options
| author | Thom Johansen <thomj@rockbox.org> | 2006-01-19 15:03:34 +0000 |
|---|---|---|
| committer | Thom Johansen <thomj@rockbox.org> | 2006-01-19 15:03:34 +0000 |
| commit | 127c3febc130c4f35ed7e66601a7a59a78fa97a9 (patch) | |
| tree | 0b91345f83daf94759c642a7978bdd3f347a651a | |
| parent | 4926682378ea22225675a4155a4fd3e5671f1a1c (diff) | |
| download | rockbox-127c3febc130c4f35ed7e66601a7a59a78fa97a9.zip rockbox-127c3febc130c4f35ed7e66601a7a59a78fa97a9.tar.gz rockbox-127c3febc130c4f35ed7e66601a7a59a78fa97a9.tar.bz2 rockbox-127c3febc130c4f35ed7e66601a7a59a78fa97a9.tar.xz | |
UIE handler for ARM/iPod. Currently does not support interrupts. Will
probably also work for other ARM based targets, like iFP.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8388 a1c6a512-1295-4272-9138-f99709370657
| -rw-r--r-- | firmware/crt0.S | 24 | ||||
| -rw-r--r-- | firmware/system.c | 28 |
2 files changed, 51 insertions, 1 deletions
diff --git a/firmware/crt0.S b/firmware/crt0.S index 1e07e0c..54432c9 100644 --- a/firmware/crt0.S +++ b/firmware/crt0.S @@ -249,6 +249,9 @@ boot_table: /* Set up stack for IRQ mode */ msr cpsr_c, #0xd2 ldr sp, =irq_stack + /* Let abort mode use IRQ stack */ + msr cpsr_c, #0xd7 + ldr sp, =irq_stack /* Switch to supervisor mode */ msr cpsr_c, #0xd3 ldr sp, =stackend @@ -278,18 +281,37 @@ ecode: ecodeend: .global irq + .global UIE +/* All illegal exceptions call into UIE with exception address as first + parameter. This is calculated differently depending on which exception + we're in. Second parameter is exception number, used for a string lookup + in UIE. + */ undef_instr_handler: + mov r0, lr + mov r1, #0 + b UIE + +/* We run supervisor mode most of the time, and should never see a software + exception being thrown. Perhaps make it illegal and call UIE? + */ software_int_handler: reserved_handler: movs pc, lr prefetch_abort_handler: + sub r0, lr, #4 + mov r1, #1 + b UIE + fiq_handler: subs pc, lr, #4 data_abort_handler: - subs pc, lr, #8 + sub r0, lr, #8 + mov r1, #2 + b UIE irq_handler: stmfd sp!, {r0-r3, r12, lr} diff --git a/firmware/system.c b/firmware/system.c index da15ee1..81e6957 100644 --- a/firmware/system.c +++ b/firmware/system.c @@ -1119,6 +1119,34 @@ void irq(void) } #endif +static const char* const uiename[] = { + "Undefined instruction", "Prefetch abort", "Data abort" +}; + +/* Unexpected Interrupt or Exception handler. Currently only deals with + exceptions, but will deal with interrupts later. + */ +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", pc); + lcd_puts(0, 1, str); + lcd_update(); + + while (1) + { + /* TODO: perhaps add button handling in here when we get a polling + driver some day. + */ + } +} + /* TODO: The following two function have been lifted straight from IPL, and hence have a lot of numeric addresses used straight. I'd like to use #defines for these, but don't know what most of them are for or even what |