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) {
/* Starting in a known IRQ configuration.*/
port_suspend();
/* Initializing priority grouping.*/

View File

@ -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); \

View File

@ -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