aboutsummaryrefslogtreecommitdiffstats
path: root/os
diff options
context:
space:
mode:
authorisiora <none@example.com>2017-07-07 16:01:52 +0000
committerisiora <none@example.com>2017-07-07 16:01:52 +0000
commit2fc72ef5f81f3fa4eb0cb908a7138b43b1478ff4 (patch)
tree184c764ed85489cbabd1dad33d661ae02c8807bc /os
parentdd85bcdf688ac779f157f35f0e23f489d0d466c1 (diff)
downloadChibiOS-2fc72ef5f81f3fa4eb0cb908a7138b43b1478ff4.tar.gz
ChibiOS-2fc72ef5f81f3fa4eb0cb908a7138b43b1478ff4.tar.bz2
ChibiOS-2fc72ef5f81f3fa4eb0cb908a7138b43b1478ff4.zip
Added monitor code to route IRQ to non-secure world.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10303 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os')
-rw-r--r--os/common/ports/ARMCMAx-TZ/compilers/GCC/chcoreasm.S71
1 files changed, 56 insertions, 15 deletions
diff --git a/os/common/ports/ARMCMAx-TZ/compilers/GCC/chcoreasm.S b/os/common/ports/ARMCMAx-TZ/compilers/GCC/chcoreasm.S
index e3c15866a..41e0238ad 100644
--- a/os/common/ports/ARMCMAx-TZ/compilers/GCC/chcoreasm.S
+++ b/os/common/ports/ARMCMAx-TZ/compilers/GCC/chcoreasm.S
@@ -111,23 +111,64 @@ _port_switch_arm:
*/
/*
- * We are on an architecures with security extension exploited.
- * The following execution path is taken by the execution units running in
- * non-secure state when a fiq interrupt is fired.
- * It originates by the monitor fiq vector and runs in monitor mode,
+ * We are facing an architecure with security extension exploited.
+ * The following two monitor execution paths are taken by the execution units
+ * running in secure state when an irq is fired (Mon_Irq_Handler), and in non-secure
+ * state when a fiq interrupt is fired (Mon_Fiq_Handler).
+ * They originate by the monitor irq/fiq vector and run in monitor mode,
* ie in secure state.
* It assumes the following, set at boot time, or wherever it needs:
* SCR.FW == 0 and SCR.FIQ == 1 and SCR.IRQ == 0 in non-secure state,
* ie FIQs are taken to monitor mode, IRQ locally
- * SCR.FIQ == 0 and SCR.IRQ == 1 and CPSR.I == 1 in secure state,
- * ie the secure code takes fiq locally and runs always with IRQ disabled(?)
+ * SCR.FW == 0 and SCR.FIQ == 0 and SCR.IRQ == 1 in secure state,
+ * ie the secure code takes fiq locally and the non-secure code takes irq locally
+ * ie the secure code takes irq to monitor and the non-secure code takes fiq to monitor
* MVBAR holds the address of the monitor vectors base.
- * The code and the stacks memory reside in secure memory.
+ * The code and the stacks memory reside both in secure memory.
*/
.balign 16
.code 32
.global Mon_Fiq_Handler
+ .global Mon_Irq_Handler
.global Fiq_Handler
+Mon_Irq_Handler:
+ // here the irq is taken from secure state
+ // current mode is monitor (so current state is secure)
+ //
+ // This procedure is challenging, because the irq must be
+ // executed in the context of the NT thread.
+ // So we shall switch to a NT thread and return into non-secure
+ // world where the IRQ will be served.
+
+ // The frame is created in the system stack,
+ // current state is secure.
+ msr CPSR_c, #MODE_SYS | I_BIT | F_BIT
+ stmfd sp!, {r0-r3, r12, lr}
+ msr CPSR_c, #MODE_MON | I_BIT | F_BIT
+ mrs r0, SPSR
+ mov r1, lr
+ msr CPSR_c, #MODE_SYS | I_BIT | F_BIT
+ stmfd sp!, {r0, r1} // Push R0=SPSR, R1=LR_IRQ.
+
+ /* bl chSchDoNTReschedule */
+
+ // Re-establish the original conditions
+ ldmfd sp!, {r0, r1} // Pop R0=SPSR, R1=LR_IRQ.
+ msr CPSR_c, #MODE_MON | I_BIT | F_BIT
+ msr SPSR_fsxc, r0
+ mov lr, r1
+ msr CPSR_c, #MODE_SYS | I_BIT | F_BIT
+ ldmfd sp!, {r0-r3, r12, lr}
+ msr CPSR_c, #MODE_MON | I_BIT | F_BIT
+ stmfd sp!, {lr} // save lr into monitor stack
+ ldr lr, =#MON_NS_SCR // set non-secure SCR before return
+ mrc p15, 0, lr, c1, c1, 0
+ ldmfd sp!, {lr}
+ subs pc, lr, #4 // return into non-secure world
+ // and serve the IRQ
+/*
+ *
+ */
Mon_Fiq_Handler:
// here the fiq is taken from non-secure state
// current mode is monitor (so current state is secure)
@@ -135,7 +176,7 @@ Mon_Fiq_Handler:
ldr lr, =#MON_S_SCR // set secure SCR before to switch to FIQ mode
mrc p15, 0, lr, c1, c1, 0
cpsid if, #MODE_FIQ // secure FIQ mode
- stmfd sp!, {r0-r3, r12} // IRQ frame
+ stmfd sp!, {r0-r3, r12} // IRQ frame, save scratch registers
ldr r0, =ARM_IRQ_VECTOR_REG
ldr r0, [r0]
ldr lr, =_mon_fiq_ret_arm // ISR return point.
@@ -187,7 +228,7 @@ _mon_fiq_ret_arm:
Fiq_Handler:
// the fiq is taken locally from secure state
// current mode is fiq
- stmfd sp!, {r0-r3, r12, lr}
+ stmfd sp!, {r0-r3, r12, lr} // save scratch registers and lr
ldr r0, =ARM_IRQ_VECTOR_REG
ldr r0, [r0]
ldr lr, =_fiq_ret_arm // ISR return point.
@@ -199,12 +240,12 @@ _fiq_ret_arm:
// Now the frame is created in the system stack, the IRQ
// stack is empty.
- msr CPSR_c, #MODE_SYS | I_BIT
+ msr CPSR_c, #MODE_SYS | I_BIT | F_BIT
stmfd sp!, {r0-r3, r12, lr}
- msr CPSR_c, #MODE_FIQ | I_BIT
+ msr CPSR_c, #MODE_FIQ | I_BIT | F_BIT
mrs r0, SPSR
mov r1, lr
- msr CPSR_c, #MODE_SYS | I_BIT
+ msr CPSR_c, #MODE_SYS | I_BIT | F_BIT
stmfd sp!, {r0, r1} // Push R0=SPSR, R1=LR_IRQ.
// Context switch.
@@ -218,12 +259,12 @@ _fiq_ret_arm:
// Re-establish the IRQ conditions again.
ldmfd sp!, {r0, r1} // Pop R0=SPSR, R1=LR_IRQ.
- msr CPSR_c, #MODE_FIQ | I_BIT
+ msr CPSR_c, #MODE_FIQ | I_BIT | F_BIT
msr SPSR_fsxc, r0
mov lr, r1
- msr CPSR_c, #MODE_SYS | I_BIT
+ msr CPSR_c, #MODE_SYS | I_BIT | F_BIT
ldmfd sp!, {r0-r3, r12, lr}
- msr CPSR_c, #MODE_FIQ | I_BIT
+ msr CPSR_c, #MODE_FIQ | I_BIT | F_BIT
subs pc, lr, #4
/*