diff options
Diffstat (limited to 'firmware')
-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 1e07e0c029..54432c9731 100644 --- a/firmware/crt0.S +++ b/firmware/crt0.S | |||
@@ -249,6 +249,9 @@ boot_table: | |||
249 | /* Set up stack for IRQ mode */ | 249 | /* Set up stack for IRQ mode */ |
250 | msr cpsr_c, #0xd2 | 250 | msr cpsr_c, #0xd2 |
251 | ldr sp, =irq_stack | 251 | ldr sp, =irq_stack |
252 | /* Let abort mode use IRQ stack */ | ||
253 | msr cpsr_c, #0xd7 | ||
254 | ldr sp, =irq_stack | ||
252 | /* Switch to supervisor mode */ | 255 | /* Switch to supervisor mode */ |
253 | msr cpsr_c, #0xd3 | 256 | msr cpsr_c, #0xd3 |
254 | ldr sp, =stackend | 257 | ldr sp, =stackend |
@@ -278,18 +281,37 @@ ecode: | |||
278 | ecodeend: | 281 | ecodeend: |
279 | 282 | ||
280 | .global irq | 283 | .global irq |
284 | .global UIE | ||
281 | 285 | ||
286 | /* All illegal exceptions call into UIE with exception address as first | ||
287 | parameter. This is calculated differently depending on which exception | ||
288 | we're in. Second parameter is exception number, used for a string lookup | ||
289 | in UIE. | ||
290 | */ | ||
282 | undef_instr_handler: | 291 | undef_instr_handler: |
292 | mov r0, lr | ||
293 | mov r1, #0 | ||
294 | b UIE | ||
295 | |||
296 | /* We run supervisor mode most of the time, and should never see a software | ||
297 | exception being thrown. Perhaps make it illegal and call UIE? | ||
298 | */ | ||
283 | software_int_handler: | 299 | software_int_handler: |
284 | reserved_handler: | 300 | reserved_handler: |
285 | movs pc, lr | 301 | movs pc, lr |
286 | 302 | ||
287 | prefetch_abort_handler: | 303 | prefetch_abort_handler: |
304 | sub r0, lr, #4 | ||
305 | mov r1, #1 | ||
306 | b UIE | ||
307 | |||
288 | fiq_handler: | 308 | fiq_handler: |
289 | subs pc, lr, #4 | 309 | subs pc, lr, #4 |
290 | 310 | ||
291 | data_abort_handler: | 311 | data_abort_handler: |
292 | subs pc, lr, #8 | 312 | sub r0, lr, #8 |
313 | mov r1, #2 | ||
314 | b UIE | ||
293 | 315 | ||
294 | irq_handler: | 316 | irq_handler: |
295 | stmfd sp!, {r0-r3, r12, lr} | 317 | stmfd sp!, {r0-r3, r12, lr} |
diff --git a/firmware/system.c b/firmware/system.c index da15ee1122..81e6957c2b 100644 --- a/firmware/system.c +++ b/firmware/system.c | |||
@@ -1119,6 +1119,34 @@ void irq(void) | |||
1119 | } | 1119 | } |
1120 | #endif | 1120 | #endif |
1121 | 1121 | ||
1122 | static const char* const uiename[] = { | ||
1123 | "Undefined instruction", "Prefetch abort", "Data abort" | ||
1124 | }; | ||
1125 | |||
1126 | /* Unexpected Interrupt or Exception handler. Currently only deals with | ||
1127 | exceptions, but will deal with interrupts later. | ||
1128 | */ | ||
1129 | void UIE(unsigned int pc, unsigned int num) | ||
1130 | { | ||
1131 | char str[32]; | ||
1132 | |||
1133 | lcd_clear_display(); | ||
1134 | #ifdef HAVE_LCD_BITMAP | ||
1135 | lcd_setfont(FONT_SYSFIXED); | ||
1136 | #endif | ||
1137 | lcd_puts(0, 0, uiename[num]); | ||
1138 | snprintf(str, sizeof(str), "at %08x", pc); | ||
1139 | lcd_puts(0, 1, str); | ||
1140 | lcd_update(); | ||
1141 | |||
1142 | while (1) | ||
1143 | { | ||
1144 | /* TODO: perhaps add button handling in here when we get a polling | ||
1145 | driver some day. | ||
1146 | */ | ||
1147 | } | ||
1148 | } | ||
1149 | |||
1122 | /* TODO: The following two function have been lifted straight from IPL, and | 1150 | /* TODO: The following two function have been lifted straight from IPL, and |
1123 | hence have a lot of numeric addresses used straight. I'd like to use | 1151 | hence have a lot of numeric addresses used straight. I'd like to use |
1124 | #defines for these, but don't know what most of them are for or even what | 1152 | #defines for these, but don't know what most of them are for or even what |