diff --git a/firmware/target/arm/rk27xx/app.lds b/firmware/target/arm/rk27xx/app.lds
index 080c74f..a282a4d 100644
--- a/firmware/target/arm/rk27xx/app.lds
+++ b/firmware/target/arm/rk27xx/app.lds
@@ -89,6 +89,9 @@ SECTIONS
_fiqstackbegin = .;
. += 0x400;
_fiqstackend = .;
+ _svcabtundfstackbegin = .;
+ . += 0x100;
+ _svcabtundfstackend = .;
} > DRAM
.bss (NOLOAD) : {
diff --git a/firmware/target/arm/rk27xx/crt0.S b/firmware/target/arm/rk27xx/crt0.S
index 4ddae01..c29657f 100644
--- a/firmware/target/arm/rk27xx/crt0.S
+++ b/firmware/target/arm/rk27xx/crt0.S
@@ -156,15 +156,6 @@ newstart2:
bhi 1b
#endif
- /* Set up some stack and munge it with 0xdeadbeef */
- ldr sp, =stackend
- ldr r2, =stackbegin
- ldr r3, =0xdeadbeef
-1:
- cmp sp, r2
- strhi r3, [r2], #4
- bhi 1b
-
/* Set up stack for IRQ mode */
msr cpsr_c, #0xd2
ldr sp, =_irqstackend
@@ -173,14 +164,25 @@ newstart2:
msr cpsr_c, #0xd1
ldr sp, =_fiqstackend
- /* Let abort and undefined modes use IRQ stack */
+ /* Let svc, abort and undefined modes use separate stack */
+ ldr sp, =_svcabtundfstackend
msr cpsr_c, #0xd7
- ldr sp, =_irqstackend
+ ldr sp, =_svcabtundfstackend
msr cpsr_c, #0xdb
- ldr sp, =_irqstackend
+ ldr sp, =_svcabtundfstackend
+
+ /* Switch to sys mode */
+ msr cpsr_c, #0xdf
+
+ /* Set up some stack and munge it with 0xdeadbeef */
+ ldr sp, =stackend
+ ldr r2, =stackbegin
+ ldr r3, =0xdeadbeef
+1:
+ cmp sp, r2
+ strhi r3, [r2], #4
+ bhi 1b
- /* Switch back to supervisor mode */
- msr cpsr_c, #0xd3
bl main
@@ -196,12 +198,6 @@ undef_instr_handler:
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
@@ -211,3 +207,11 @@ data_abort_handler:
sub r0, lr, #8
mov r1, #2
b UIE
+
+/* We run sys mode most of the time, and should never see a software
+ * exception being thrown. Make it illegal and call UIE */
+software_int_handler:
+reserved_handler:
+ sub r0, lr, #4
+ mov r1, #5
+ b UIE
diff --git a/firmware/target/arm/system-arm.c b/firmware/target/arm/system-arm.c
index 59eaa90..23ccfd1 100644
--- a/firmware/target/arm/system-arm.c
+++ b/firmware/target/arm/system-arm.c
@@ -29,7 +29,8 @@ static const char* const uiename[] = {
"Undefined instruction",
"Prefetch abort",
"Data abort",
- "Divide by zero"
+ "Divide by zero",
+ "SWI"
};
/* Unexpected Interrupt or Exception handler. Currently only deals with