From bf0b761497c67f00d8df2a92c0339a8cc11a6d2a Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Thu, 9 Apr 2020 11:36:06 +0000 Subject: [PATCH] git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@13520 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- ...(ST-Link GDB Server, Flash and Run).launch | 2 +- os/common/ports/ARMv8-M-ML/chcore.c | 1 + os/common/ports/ARMv8-M-ML/chcore.h | 70 ++++++- .../ARMv8-M-ML/compilers/GCC/chcoreasm.S | 186 +++++++++++++----- 4 files changed, 203 insertions(+), 56 deletions(-) diff --git a/demos/various/RT-TEST-Latency/debug/RT-TEST-Latency (ST-Link GDB Server, Flash and Run).launch b/demos/various/RT-TEST-Latency/debug/RT-TEST-Latency (ST-Link GDB Server, Flash and Run).launch index f86b69e08..496fef86c 100644 --- a/demos/various/RT-TEST-Latency/debug/RT-TEST-Latency (ST-Link GDB Server, Flash and Run).launch +++ b/demos/various/RT-TEST-Latency/debug/RT-TEST-Latency (ST-Link GDB Server, Flash and Run).launch @@ -33,7 +33,7 @@ - + diff --git a/os/common/ports/ARMv8-M-ML/chcore.c b/os/common/ports/ARMv8-M-ML/chcore.c index be365dddf..01a126fa0 100644 --- a/os/common/ports/ARMv8-M-ML/chcore.c +++ b/os/common/ports/ARMv8-M-ML/chcore.c @@ -74,6 +74,7 @@ thread_t *port_schedule_next(void) { */ void port_init(void) { + /* Starting in a known IRQ configuration.*/ port_suspend(); /* Initializing priority grouping.*/ diff --git a/os/common/ports/ARMv8-M-ML/chcore.h b/os/common/ports/ARMv8-M-ML/chcore.h index 028bf6fba..b2f4b83bf 100644 --- a/os/common/ports/ARMv8-M-ML/chcore.h +++ b/os/common/ports/ARMv8-M-ML/chcore.h @@ -72,7 +72,6 @@ #endif /* !defined(_FROM_ASM_) */ /** @} */ - /** * @name Port Capabilities and Constants * @{ @@ -104,10 +103,43 @@ /* Inclusion of the Cortex-Mx implementation specific parameters.*/ #include "cmparams.h" + +/** + * @name Kernel modes + * @{ + */ +/** + * @brief Standard mode. + * @details The RTOS is running in secure state with no switch in non-secure + * state ever performed. This is also used on devices with no + * TrustZone support at all. + */ +#define PORT_KERNEL_MODE_NORMAL 0U +/** + * @brief Kernel running in secure state. + * @details The RTOS is running in secure state with support for one thread + * running in non-secure state. + */ +#define PORT_KERNEL_MODE_HOST 1U +/** + * @brief Kernel running in non-secure state. + * @details The RTOS is running in non-secure state with no access to secure + * resources. + */ +#define PORT_KERNEL_MODE_GUEST 2U +/** @} */ + /*===========================================================================*/ /* Module pre-compile time settings. */ /*===========================================================================*/ +/** + * @brief Kernel mode selection. + */ +#if !defined(PORT_KERNEL_MODE) || defined(__DOXYGEN__) +#define PORT_KERNEL_MODE PORT_KERNEL_MODE_NORMAL +#endif + /** * @brief Number of MPU regions to be saved/restored during context switch. * @note The first region is always region zero. @@ -184,8 +216,20 @@ /* Derived constants and error checks. */ /*===========================================================================*/ -#if (PORT_SWITCHED_REGIONS_NUMBER < 0) || (PORT_SWITCHED_REGIONS_NUMBER > 4) -#error "invalid PORT_SWITCHED_REGIONS_NUMBER value" +#if PORT_KERNEL_MODE == PORT_KERNEL_MODE_NORMAL +#define PORT_EXC_RETURN 0xFFFFFFFD +#define PORT_STORE_BASEPRI_NS FALSE + +#elif PORT_KERNEL_MODE == PORT_KERNEL_MODE_HOST +#define PORT_EXC_RETURN 0xFFFFFFFD +#define PORT_STORE_BASEPRI_NS TRUE + +#elif PORT_KERNEL_MODE == PORT_KERNEL_MODE_GUEST +#define PORT_EXC_RETURN 0xFFFFFFBC +#define PORT_STORE_BASEPRI_NS FALSE + +#else +#error "invalid kernel security mode" #endif /** @@ -308,6 +352,9 @@ struct port_intctx { */ struct port_context { struct port_intctx *sp; +#if (PORT_STORE_BASEPRI_NS == TRUE) || defined(__DOXYGEN__) + uint32_t basepri_ns; +#endif uint32_t basepri; uint32_t r4; uint32_t r5; @@ -438,6 +485,20 @@ struct port_context { #define PORT_SETUP_CONTEXT_MPU(tp) #endif +/** + * @brief Initialization of BASEPRI_NS part of thread context. + * @note All secure threads have BASEPRI_NS set to mask PendSV, this + * way a guest RTOS cannot reschedule while a secure thread + * is running, reschedule is delayed to when the non-secure + * thread running the guest is activated again. + */ +#if (PORT_STORE_BASEPRI_NS == TRUE) || defined(__DOXYGEN__) +#define PORT_SETUP_CONTEXT_BASEPRI_NS(tp) \ + (tp)->ctx.basepri_ns = (uint32_t)CORTEX_PRIO_MASK(CORTEX_PRIORITY_PENDSV) +#else +#define PORT_SETUP_CONTEXT_BASEPRI_NS(tp) +#endif + /** * @brief Platform dependent part of the @p chThdCreateI() API. * @details This code usually setup the context switching frame represented @@ -446,11 +507,12 @@ struct port_context { #define PORT_SETUP_CONTEXT(tp, wbase, wtop, pf, arg) do { \ (tp)->ctx.sp = (struct port_intctx *)((uint8_t *)(wtop) - \ sizeof (struct port_intctx)); \ + PORT_SETUP_CONTEXT_BASEPRI_NS(tp); \ (tp)->ctx.basepri = CORTEX_BASEPRI_KERNEL; \ (tp)->ctx.r5 = (uint32_t)(arg); \ (tp)->ctx.r4 = (uint32_t)(pf); \ PORT_SETUP_CONTEXT_SPLIM(tp, wbase); \ - (tp)->ctx.lr_exc = (uint32_t)0xFFFFFFFD; \ + (tp)->ctx.lr_exc = (uint32_t)PORT_EXC_RETURN; \ (tp)->ctx.sp->pc = (uint32_t)__port_thread_start; \ (tp)->ctx.sp->xpsr = (uint32_t)0x01000000; \ PORT_SETUP_CONTEXT_FPU(tp); \ diff --git a/os/common/ports/ARMv8-M-ML/compilers/GCC/chcoreasm.S b/os/common/ports/ARMv8-M-ML/compilers/GCC/chcoreasm.S index 6e85b0a21..e0d4ca572 100644 --- a/os/common/ports/ARMv8-M-ML/compilers/GCC/chcoreasm.S +++ b/os/common/ports/ARMv8-M-ML/compilers/GCC/chcoreasm.S @@ -68,7 +68,7 @@ #define ICSR_PENDSVSET 0x10000000 .syntax unified - .cpu cortex-m4 + .cpu cortex-m33 #if CORTEX_USE_FPU .fpu fpv4-sp-d16 #else @@ -79,39 +79,135 @@ .text /*--------------------------------------------------------------------------* - * Performs a context switch between two threads. + * Context switch macros depending on various options. + *--------------------------------------------------------------------------*/ + +#if !PORT_STORE_BASEPRI_NS + +#if !CH_DBG_ENABLE_STACK_CHECK + .macro PORT_STORE_INTEGER_CONTEXT_R1 + mrs r2, PSP + mrs r3, BASEPRI + stmia r1!, {r2-r11,lr} + .endm + + .macro PORT_RESTORE_INTEGER_CONTEXT_R0 + ldmia r0!, {r2-r11, lr} + msr PSP, r2 + msr BASEPRI, r3 + .endm +#else /* CH_DBG_ENABLE_STACK_CHECK */ + .macro PORT_STORE_INTEGER_CONTEXT_R1 + mrs r2, PSP + mrs r3, BASEPRI + mrs r12, PSPLIM + stmia r1!, {r2-r12,lr} + .endm + + .macro PORT_RESTORE_INTEGER_CONTEXT_R0 + ldmia r0!, {r2-r12, lr} + /* Note the following is not required because this sentence + in the ARMv8-M architecture manual: + Updates to the stack pointer by the MSR instruction + targeting SP_NS are subject to stack limit checking. + Updates to the stack pointer and stack pointer limit + by any other MSR instruction are not subject to + stack limit checking.*/ +// movs r1, #0 +// msr PSPLIM, r1 /* Temporarily disabling stack check.*/ + msr PSP, r2 + msr BASEPRI, r3 + msr PSPLIM, r12 + .endm +#endif + +#else /* PORT_STORE_BASEPRI_NS */ + +#if !CH_DBG_ENABLE_STACK_CHECK + .macro PORT_STORE_INTEGER_CONTEXT_R1 + mrs r2, BASEPRI_NS + stmia r1!, {r2} + mrs r2, PSP + mrs r3, BASEPRI + stmia r1!, {r2-r11,lr} + .endm + + .macro PORT_RESTORE_INTEGER_CONTEXT_R0 + ldmia r0!, {r1-r11, lr} + msr BASEPRI_NS, r1 + msr PSP, r2 + msr BASEPRI, r3 + .endm +#else /* CH_DBG_ENABLE_STACK_CHECK */ + .macro PORT_STORE_INTEGER_CONTEXT_R1 + mrs r2, BASEPRI_NS + stmia r1!, {r2} + mrs r2, PSP + mrs r3, BASEPRI + mrs r12, PSPLIM + stmia r1!, {r2-r12,lr} + .endm + + .macro PORT_RESTORE_INTEGER_CONTEXT_R0 + ldmia r0!, {r1-r12, lr} + msr BASEPRI_NS, r1 + /* Note the following is not required because this sentence + in the ARMv8-M architecture manual: + Updates to the stack pointer by the MSR instruction + targeting SP_NS are subject to stack limit checking. + Updates to the stack pointer and stack pointer limit + by any other MSR instruction are not subject to + stack limit checking.*/ +// movs r1, #0 +// msr PSPLIM, r1 /* Temporarily disabling stack check.*/ + msr PSP, r2 + msr BASEPRI, r3 + msr PSPLIM, r12 + .endm +#endif + +#endif /* PORT_STORE_BASEPRI_NS */ + +#if CORTEX_USE_FPU + .macro PORT_STORE_FLOAT_CONTEXT_R1 + vstmia r1!, {s16-s31} + .endm + + .macro PORT_RESTORE_FLOAT_CONTEXT_R0 + vldmia r0!, {s16-s31} + .endm +#else + .macro PORT_STORE_FLOAT_CONTEXT_R1 + .endm + + .macro PORT_RESTORE_FLOAT_CONTEXT_R0 + .endm +#endif + +/*--------------------------------------------------------------------------* + * Performs a context switch between two threads using SVC. *--------------------------------------------------------------------------*/ .thumb_func .globl SVC_Handler SVC_Handler: /* Saving callee context of thread being swapped out.*/ adds r1, #CONTEXT_OFFSET - mrs r2, PSP - mrs r3, BASEPRI -// movs r3, #(2 << 5) -#if CH_DBG_ENABLE_STACK_CHECK - mrs r12, PSPLIM - stmia r1!, {r2-r12,lr} -#else - stmia r1!, {r2-r11,lr} -#endif -#if CORTEX_USE_FPU - vstmia r1, {s16-s31} -#endif + + /* Storing integer and control context through R1.*/ + PORT_STORE_INTEGER_CONTEXT_R1 + + /* Storing float context through R1.*/ + PORT_STORE_FLOAT_CONTEXT_R1 /* Restoring calle context of thread being swapped in.*/ adds r0, #CONTEXT_OFFSET -#if CH_DBG_ENABLE_STACK_CHECK - ldmia r0!, {r2-r12, lr} - msr PSPLIM, r12 -#else - ldmia r0!, {r2-r11, lr} -#endif - msr BASEPRI, r3 - msr PSP, r2 -#if CORTEX_USE_FPU - vldmia r0, {s16-s31} -#endif + + /* Restoring integer and control context through R0.*/ + PORT_RESTORE_INTEGER_CONTEXT_R0 + + /* Restoring float context through R0.*/ + PORT_RESTORE_FLOAT_CONTEXT_R0 + bx lr /*--------------------------------------------------------------------------* @@ -128,34 +224,25 @@ PendSV_Handler: /* Saving callee context of thread being swapped out.*/ adds r1, #CONTEXT_OFFSET - mrs r2, PSP - mrs r3, BASEPRI -#if CH_DBG_ENABLE_STACK_CHECK - mrs r12, PSPLIM - stmia r1!, {r2-r12,lr} -#else - stmia r1!, {r2-r11,lr} -#endif -#if CORTEX_USE_FPU - vstmia r1, {s16-s31} -#endif - /* Selecting the thread to be swapped in.*/ + /* Storing integer and control context through R1.*/ + PORT_STORE_INTEGER_CONTEXT_R1 + + /* Storing float context through R1.*/ + PORT_STORE_FLOAT_CONTEXT_R1 + + /* Selecting the thread to be swapped in, R0 points to it.*/ bl port_schedule_next /* Restoring calle context of thread being swapped in.*/ adds r0, #CONTEXT_OFFSET -#if CH_DBG_ENABLE_STACK_CHECK - ldmia r0!, {r2-r12, lr} - msr PSPLIM, r12 -#else - ldmia r0!, {r2-r11, lr} -#endif - msr BASEPRI, r3 - msr PSP, r2 -#if CORTEX_USE_FPU - vldmia r0, {s16-s31} -#endif + + /* Restoring integer and control context through R0.*/ + PORT_RESTORE_INTEGER_CONTEXT_R0 + + /* Restoring float context through R0.*/ + PORT_RESTORE_FLOAT_CONTEXT_R0 + bx lr /*--------------------------------------------------------------------------* @@ -169,9 +256,6 @@ PendSV_Handler: .thumb_func .globl __port_thread_start __port_thread_start: -#if CH_DBG_ENABLE_STACK_CHECK && PORT_ENABLE_GUARD_PAGES - bl _port_set_region -#endif #if CH_DBG_STATISTICS bl _stats_stop_measure_crit_thd #endif