git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@13520 27425a3e-05d8-49a3-a47f-9c15f0e5edd8

This commit is contained in:
Giovanni Di Sirio 2020-04-09 11:36:06 +00:00
parent aafcac7b9d
commit bf0b761497
4 changed files with 203 additions and 56 deletions

View File

@ -74,6 +74,7 @@ thread_t *port_schedule_next(void) {
*/ */
void port_init(void) { void port_init(void) {
/* Starting in a known IRQ configuration.*/
port_suspend(); port_suspend();
/* Initializing priority grouping.*/ /* Initializing priority grouping.*/

View File

@ -72,7 +72,6 @@
#endif /* !defined(_FROM_ASM_) */ #endif /* !defined(_FROM_ASM_) */
/** @} */ /** @} */
/** /**
* @name Port Capabilities and Constants * @name Port Capabilities and Constants
* @{ * @{
@ -104,10 +103,43 @@
/* Inclusion of the Cortex-Mx implementation specific parameters.*/ /* Inclusion of the Cortex-Mx implementation specific parameters.*/
#include "cmparams.h" #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. */ /* 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. * @brief Number of MPU regions to be saved/restored during context switch.
* @note The first region is always region zero. * @note The first region is always region zero.
@ -184,8 +216,20 @@
/* Derived constants and error checks. */ /* Derived constants and error checks. */
/*===========================================================================*/ /*===========================================================================*/
#if (PORT_SWITCHED_REGIONS_NUMBER < 0) || (PORT_SWITCHED_REGIONS_NUMBER > 4) #if PORT_KERNEL_MODE == PORT_KERNEL_MODE_NORMAL
#error "invalid PORT_SWITCHED_REGIONS_NUMBER value" #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 #endif
/** /**
@ -308,6 +352,9 @@ struct port_intctx {
*/ */
struct port_context { struct port_context {
struct port_intctx *sp; struct port_intctx *sp;
#if (PORT_STORE_BASEPRI_NS == TRUE) || defined(__DOXYGEN__)
uint32_t basepri_ns;
#endif
uint32_t basepri; uint32_t basepri;
uint32_t r4; uint32_t r4;
uint32_t r5; uint32_t r5;
@ -438,6 +485,20 @@ struct port_context {
#define PORT_SETUP_CONTEXT_MPU(tp) #define PORT_SETUP_CONTEXT_MPU(tp)
#endif #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. * @brief Platform dependent part of the @p chThdCreateI() API.
* @details This code usually setup the context switching frame represented * @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 { \ #define PORT_SETUP_CONTEXT(tp, wbase, wtop, pf, arg) do { \
(tp)->ctx.sp = (struct port_intctx *)((uint8_t *)(wtop) - \ (tp)->ctx.sp = (struct port_intctx *)((uint8_t *)(wtop) - \
sizeof (struct port_intctx)); \ sizeof (struct port_intctx)); \
PORT_SETUP_CONTEXT_BASEPRI_NS(tp); \
(tp)->ctx.basepri = CORTEX_BASEPRI_KERNEL; \ (tp)->ctx.basepri = CORTEX_BASEPRI_KERNEL; \
(tp)->ctx.r5 = (uint32_t)(arg); \ (tp)->ctx.r5 = (uint32_t)(arg); \
(tp)->ctx.r4 = (uint32_t)(pf); \ (tp)->ctx.r4 = (uint32_t)(pf); \
PORT_SETUP_CONTEXT_SPLIM(tp, wbase); \ 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->pc = (uint32_t)__port_thread_start; \
(tp)->ctx.sp->xpsr = (uint32_t)0x01000000; \ (tp)->ctx.sp->xpsr = (uint32_t)0x01000000; \
PORT_SETUP_CONTEXT_FPU(tp); \ PORT_SETUP_CONTEXT_FPU(tp); \

View File

@ -68,7 +68,7 @@
#define ICSR_PENDSVSET 0x10000000 #define ICSR_PENDSVSET 0x10000000
.syntax unified .syntax unified
.cpu cortex-m4 .cpu cortex-m33
#if CORTEX_USE_FPU #if CORTEX_USE_FPU
.fpu fpv4-sp-d16 .fpu fpv4-sp-d16
#else #else
@ -79,39 +79,135 @@
.text .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 .thumb_func
.globl SVC_Handler .globl SVC_Handler
SVC_Handler: SVC_Handler:
/* Saving callee context of thread being swapped out.*/ /* Saving callee context of thread being swapped out.*/
adds r1, #CONTEXT_OFFSET adds r1, #CONTEXT_OFFSET
mrs r2, PSP
mrs r3, BASEPRI /* Storing integer and control context through R1.*/
// movs r3, #(2 << 5) PORT_STORE_INTEGER_CONTEXT_R1
#if CH_DBG_ENABLE_STACK_CHECK
mrs r12, PSPLIM /* Storing float context through R1.*/
stmia r1!, {r2-r12,lr} PORT_STORE_FLOAT_CONTEXT_R1
#else
stmia r1!, {r2-r11,lr}
#endif
#if CORTEX_USE_FPU
vstmia r1, {s16-s31}
#endif
/* Restoring calle context of thread being swapped in.*/ /* Restoring calle context of thread being swapped in.*/
adds r0, #CONTEXT_OFFSET adds r0, #CONTEXT_OFFSET
#if CH_DBG_ENABLE_STACK_CHECK
ldmia r0!, {r2-r12, lr} /* Restoring integer and control context through R0.*/
msr PSPLIM, r12 PORT_RESTORE_INTEGER_CONTEXT_R0
#else
ldmia r0!, {r2-r11, lr} /* Restoring float context through R0.*/
#endif PORT_RESTORE_FLOAT_CONTEXT_R0
msr BASEPRI, r3
msr PSP, r2
#if CORTEX_USE_FPU
vldmia r0, {s16-s31}
#endif
bx lr bx lr
/*--------------------------------------------------------------------------* /*--------------------------------------------------------------------------*
@ -128,34 +224,25 @@ PendSV_Handler:
/* Saving callee context of thread being swapped out.*/ /* Saving callee context of thread being swapped out.*/
adds r1, #CONTEXT_OFFSET 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 bl port_schedule_next
/* Restoring calle context of thread being swapped in.*/ /* Restoring calle context of thread being swapped in.*/
adds r0, #CONTEXT_OFFSET adds r0, #CONTEXT_OFFSET
#if CH_DBG_ENABLE_STACK_CHECK
ldmia r0!, {r2-r12, lr} /* Restoring integer and control context through R0.*/
msr PSPLIM, r12 PORT_RESTORE_INTEGER_CONTEXT_R0
#else
ldmia r0!, {r2-r11, lr} /* Restoring float context through R0.*/
#endif PORT_RESTORE_FLOAT_CONTEXT_R0
msr BASEPRI, r3
msr PSP, r2
#if CORTEX_USE_FPU
vldmia r0, {s16-s31}
#endif
bx lr bx lr
/*--------------------------------------------------------------------------* /*--------------------------------------------------------------------------*
@ -169,9 +256,6 @@ PendSV_Handler:
.thumb_func .thumb_func
.globl __port_thread_start .globl __port_thread_start
__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 #if CH_DBG_STATISTICS
bl _stats_stop_measure_crit_thd bl _stats_stop_measure_crit_thd
#endif #endif