summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThom Johansen <thomj@rockbox.org>2006-01-19 15:03:34 +0000
committerThom Johansen <thomj@rockbox.org>2006-01-19 15:03:34 +0000
commit127c3febc130c4f35ed7e66601a7a59a78fa97a9 (patch)
tree0b91345f83daf94759c642a7978bdd3f347a651a
parent4926682378ea22225675a4155a4fd3e5671f1a1c (diff)
downloadrockbox-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.S24
-rw-r--r--firmware/system.c28
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