aboutsummaryrefslogtreecommitdiffstats
path: root/os/common
diff options
context:
space:
mode:
authorisiora <none@example.com>2018-01-20 22:39:43 +0000
committerisiora <none@example.com>2018-01-20 22:39:43 +0000
commit837c6f9717e6d2102e4a76bb502ca84799b0cbc9 (patch)
tree9070ebade0eb408a8f26efc86cd7fcf17127c9c5 /os/common
parent282bc3a8f0c8357737dda060c24abb439763ffd6 (diff)
downloadChibiOS-837c6f9717e6d2102e4a76bb502ca84799b0cbc9.tar.gz
ChibiOS-837c6f9717e6d2102e4a76bb502ca84799b0cbc9.tar.bz2
ChibiOS-837c6f9717e6d2102e4a76bb502ca84799b0cbc9.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@11378 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/common')
-rw-r--r--os/common/ports/ARMCAx-TZ/compilers/GCC/monitor.S388
1 files changed, 193 insertions, 195 deletions
diff --git a/os/common/ports/ARMCAx-TZ/compilers/GCC/monitor.S b/os/common/ports/ARMCAx-TZ/compilers/GCC/monitor.S
index 82c84ad66..63acd6e34 100644
--- a/os/common/ports/ARMCAx-TZ/compilers/GCC/monitor.S
+++ b/os/common/ports/ARMCAx-TZ/compilers/GCC/monitor.S
@@ -1,195 +1,193 @@
-/*
- ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-/**
- * @file ARMCAx-TZ/compilers/GCC/monitor.S
- * @brief ARMCAx-TZ monitor code
- *
- * @addtogroup ARM_CORE
- * @{
- */
-#define TRUE 1
-#define FALSE 0
-
-#define _FROM_ASM_
-#include "chlicense.h"
-#include "chconf.h"
-#include "armparams.h"
-
-/*
- * We are facing an architecure with security extension exploited.
- * The following execution paths are taken by the execution units
- * running in secure state when an irq is fired (sm_irq), and in non-secure
- * state when a fiq interrupt is fired (sm_fiq).
- * They originate by the monitor irq/fiq vector and run in monitor mode,
- * ie in secure state.
- * It assumes the following, intially 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, IRQs are taken locally
- * SCR.FW == 0 and SCR.FIQ == 0 and SCR.IRQ == 1 in secure state,
- * ie FIQs are taken locally, IRQs are taken to monitor mode
- * MVBAR holds the address of the monitor vectors base.
- * The code and the stacks memory reside both in secure memory.
- */
-
-#if !defined(__DOXYGEN__)
-
- .set MODE_USR, 0x10
- .set MODE_FIQ, 0x11
- .set MODE_IRQ, 0x12
- .set MODE_SVC, 0x13
- .set MODE_MON, 0x16
- .set MODE_ABT, 0x17
- .set MODE_UND, 0x1B
- .set MODE_SYS, 0x1F
-
- .set I_BIT, 0x80
- .set F_BIT, 0x40
-
- .set SCR_NS, 0x01
- .set SCR_IRQ, 0x02
- .set SCR_FIQ, 0x04
- .set SCR_EA, 0x08
- .set SCR_FW, 0x10
- .set SCR_AW, 0x20
-
- .set MON_S_SCR, (SCR_IRQ) // (SCR_EA|SCR_IRQ)
- .set MON_NS_SCR, (SCR_FIQ|SCR_NS)
-
- .set MSG_OK, 0
- .set MSG_TIMEOUT, -1
- .set MSG_RESET, -2
- .section .data
- .balign 4
- _ns_thread: .zero 4
-
- .section .text
- .code 32
- .balign 4
-/*
- * Monitor vectors
- */
- .global _monitor_vectors
-_monitor_vectors:
- b . // Reset vector, not used
- b . // Undefined instruction, not used
- b sm_call // Secure monitor call
- b . // Prefetch abort, not taken to Monitor mode
- b . // Data abort, not taken to Monitor mode
- b . // Reserved
- b sm_irq // IRQ
- b sm_fiq // FIQ
-/*
- * SMC entry
- */
-sm_call:
- ldr r12, =MON_S_SCR // enter in the secure world
- mcr p15, 0, r12, c1, c1, 0
- ands r0, r0 // OS special service,
- // 0 == jump trampoline to non secure world
- // r1 contains the address where it jumps
- beq 1f
- msr CPSR_c, #MODE_SYS | I_BIT // switch to sys mode, foreign int disabled
- stmfd sp!, {lr} // save lr
- bl smcEntry // call the C smc handler
- ldmfd sp!, {lr} // restore lr
- msr CPSR_c, #MODE_MON | I_BIT | F_BIT // switch to monitor mode
- ldr r12, =MON_NS_SCR // enter in the non-secure world
- mcr p15, 0, r12, c1, c1, 0
- subs pc, lr, #0 // return from smc
-1:
- mov lr, r1 // use the address in r1 as return address
- // in the non secure world
- ldr r12, =MON_NS_SCR // enter in the non-secure world
- mcr p15, 0, r12, c1, c1, 0
- subs pc, lr, #0 // return from smc
-
-/*
- * FIQ entry
- *
- * Here the fiq is taken from non-secure state, via the FIQ vector
- * that is in the monitor vector table.
- * Current mode is monitor (so current state is secure).
- * We switch immediately to system mode, enabling FIQ.
- * The FIQ is then served while the ns_thread is running.
- * Because the ns_thread has the highest priority, the handler returns here
- * without scheduling.
- */
-sm_fiq:
- // check point: SCR.NS == 1
- stmfd sp!, {r0}
- ldr r0, =MON_S_SCR // enter in the secure world
- mcr p15, 0, r0, c1, c1, 0
- msr CPSR_c, #MODE_SYS | I_BIT // FIQ enabled, served via base table
- msr CPSR_c, #MODE_MON | I_BIT | F_BIT // the handler returns here. Switch to monitor mode
- ldr r0, =MON_NS_SCR // set non-secure SCR before return
- mcr p15, 0, r0, c1, c1, 0
- ldmfd sp!, {r0}
- subs pc, lr, #4 // return into non-secure world
-/*
- * IRQ entry
- *
- * Here the IRQ is taken from secure state.
- * Current mode is monitor (so current state is secure),
- * the previous mode and status is in mon.spsr and
- * the return address+4 is in mon.lr.
- * Because we are running in secure state, we are sure that
- * the main thread is suspended in the smc handler.
- * The main thread is then resumed with MSG_TIMEOUT
- * The non secure IRQ handler has then the responsibility to return into
- * secure state via a smc.
- *
- */
- sm_irq:
- // check point: SCR.NS == 0
- msr CPSR_c, #MODE_SYS | I_BIT | F_BIT
- stmfd sp!, {r0-r3, r12, lr} // save scratch registers and 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_MON.
- // check point: ns_tread != 0
- ldr r0, =_ns_thread
- mov r1, #MSG_TIMEOUT
-#if (CH_DBG_SYSTEM_STATE_CHECK == TRUE)
- bl _dbg_check_lock
-#endif
- bl chThdResumeS // resume the ns_thread and serve the IRQ
- // into non-secure world
-#if (CH_DBG_SYSTEM_STATE_CHECK == TRUE)
- bl _dbg_check_unlock
-#endif
- // The ns_thread reentered smc, that set SRC.NS to 0
- // re-establish the original conditions
- ldmfd sp!, {r0, r1} // pop R0=SPSR, R1=LR_MON.
- 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
- subs pc, lr, #4 // return into secure world
-
- .global _ns_trampoline
-_ns_trampoline:
- mov r1, r0
- ldr r0, =#0
- smc #0
-
-#endif /* !defined(__DOXYGEN__) */
-
-/** @} */
+/*
+ ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file ARMCAx-TZ/compilers/GCC/monitor.S
+ * @brief ARMCAx-TZ monitor code
+ *
+ * @addtogroup ARM_CORE
+ * @{
+ */
+#define TRUE 1
+#define FALSE 0
+
+#define _FROM_ASM_
+#include "chlicense.h"
+#include "chconf.h"
+#include "armparams.h"
+
+/*
+ * We are facing an architecure with security extension exploited.
+ * The following execution paths are taken by the execution units
+ * running in secure state when an irq is fired (sm_irq), and in non-secure
+ * state when a fiq interrupt is fired (sm_fiq).
+ * They originate by the monitor irq/fiq vector and run in monitor mode,
+ * ie in secure state.
+ * It assumes the following, intially 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, IRQs are taken locally
+ * SCR.FW == 0 and SCR.FIQ == 0 and SCR.IRQ == 1 in secure state,
+ * ie FIQs are taken locally, IRQs are taken to monitor mode
+ * MVBAR holds the address of the monitor vectors base.
+ * The code and the stacks memory reside both in secure memory.
+ */
+
+#if !defined(__DOXYGEN__)
+
+ .set MODE_USR, 0x10
+ .set MODE_FIQ, 0x11
+ .set MODE_IRQ, 0x12
+ .set MODE_SVC, 0x13
+ .set MODE_MON, 0x16
+ .set MODE_ABT, 0x17
+ .set MODE_UND, 0x1B
+ .set MODE_SYS, 0x1F
+
+ .set I_BIT, 0x80
+ .set F_BIT, 0x40
+
+ .set SCR_NS, 0x01
+ .set SCR_IRQ, 0x02
+ .set SCR_FIQ, 0x04
+ .set SCR_EA, 0x08
+ .set SCR_FW, 0x10
+ .set SCR_AW, 0x20
+
+ .set MON_S_SCR, (SCR_IRQ) // (SCR_EA|SCR_IRQ)
+ .set MON_NS_SCR, (SCR_FIQ|SCR_NS)
+
+ .set MSG_OK, 0
+ .set MSG_TIMEOUT, -1
+ .set MSG_RESET, -2
+
+ .global _ns_thread
+ .section .text
+ .code 32
+ .balign 4
+/*
+ * Monitor vectors
+ */
+ .global _monitor_vectors
+_monitor_vectors:
+ b . // Reset vector, not used
+ b . // Undefined instruction, not used
+ b sm_call // Secure monitor call
+ b . // Prefetch abort, not taken to Monitor mode
+ b . // Data abort, not taken to Monitor mode
+ b . // Reserved
+ b sm_irq // IRQ
+ b sm_fiq // FIQ
+/*
+ * SMC entry
+ */
+sm_call:
+ ldr r12, =MON_S_SCR // enter in the secure world
+ mcr p15, 0, r12, c1, c1, 0
+ ands r0, r0 // OS special service,
+ // 0 == jump trampoline to non secure world
+ // r1 contains the address where it jumps
+ beq 1f
+ msr CPSR_c, #MODE_SYS | I_BIT // switch to sys mode, foreign int disabled
+ stmfd sp!, {lr} // save lr
+ bl smcEntry // call the C smc handler
+ ldmfd sp!, {lr} // restore lr
+ msr CPSR_c, #MODE_MON | I_BIT | F_BIT // switch to monitor mode
+ ldr r12, =MON_NS_SCR // enter in the non-secure world
+ mcr p15, 0, r12, c1, c1, 0
+ subs pc, lr, #0 // return from smc
+1:
+ mov lr, r1 // use the address in r1 as return address
+ // in the non secure world
+ ldr r12, =MON_NS_SCR // enter in the non-secure world
+ mcr p15, 0, r12, c1, c1, 0
+ subs pc, lr, #0 // return from smc
+
+/*
+ * FIQ entry
+ *
+ * Here the fiq is taken from non-secure state, via the FIQ vector
+ * that is in the monitor vector table.
+ * Current mode is monitor (so current state is secure).
+ * We switch immediately to system mode, enabling FIQ.
+ * The FIQ is then served while the ns_thread is running.
+ * Because the ns_thread has the highest priority, the handler returns here
+ * without scheduling.
+ */
+sm_fiq:
+ // check point: SCR.NS == 1
+ stmfd sp!, {r0}
+ ldr r0, =MON_S_SCR // enter in the secure world
+ mcr p15, 0, r0, c1, c1, 0
+ msr CPSR_c, #MODE_SYS | I_BIT // FIQ enabled, served via base table
+ msr CPSR_c, #MODE_MON | I_BIT | F_BIT // the handler returns here. Switch to monitor mode
+ ldr r0, =MON_NS_SCR // set non-secure SCR before return
+ mcr p15, 0, r0, c1, c1, 0
+ ldmfd sp!, {r0}
+ subs pc, lr, #4 // return into non-secure world
+/*
+ * IRQ entry
+ *
+ * Here the IRQ is taken from secure state.
+ * Current mode is monitor (so current state is secure),
+ * the previous mode and status is in mon.spsr and
+ * the return address+4 is in mon.lr.
+ * Because we are running in secure state, we are sure that
+ * the main thread is suspended in the smc handler.
+ * The main thread is then resumed with MSG_TIMEOUT
+ * The non secure IRQ handler has then the responsibility to return into
+ * secure state via a smc.
+ *
+ */
+ sm_irq:
+ // check point: SCR.NS == 0
+ msr CPSR_c, #MODE_SYS | I_BIT | F_BIT
+ stmfd sp!, {r0-r3, r12, lr} // save scratch registers and 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_MON.
+ // check point: ns_tread != 0
+ ldr r0, =_ns_thread
+ mov r1, #MSG_TIMEOUT
+#if (CH_DBG_SYSTEM_STATE_CHECK == TRUE)
+ bl _dbg_check_lock
+#endif
+ bl chThdResumeS // resume the ns_thread and serve the IRQ
+ // into non-secure world
+#if (CH_DBG_SYSTEM_STATE_CHECK == TRUE)
+ bl _dbg_check_unlock
+#endif
+ // The ns_thread reentered smc, that set SRC.NS to 0
+ // re-establish the original conditions
+ ldmfd sp!, {r0, r1} // pop R0=SPSR, R1=LR_MON.
+ 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
+ subs pc, lr, #4 // return into secure world
+
+ .global _ns_trampoline
+_ns_trampoline:
+ mov r1, r0
+ ldr r0, =#0
+ smc #0
+
+#endif /* !defined(__DOXYGEN__) */
+
+/** @} */