Implemented support for multiple sandboxes.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@12977 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
Giovanni Di Sirio 2019-09-07 14:35:52 +00:00
parent 7e335f49a9
commit 7040887600
4 changed files with 166 additions and 23 deletions

View File

@ -756,6 +756,9 @@
/* Port-specific settings (override port settings defaulted in chcore.h). */
/*===========================================================================*/
#define PORT_USE_SYSCALL TRUE
#define PORT_SWITCHED_REGIONS_NUMBER 0
#endif /* CHCONF_H */
/** @} */

View File

@ -122,13 +122,13 @@ void port_unprivileged_jump(regarm_t pc, regarm_t psp) {
/*lint -save -e9075 [8.4] All symbols are invoked from asm context.*/
void SVC_Handler(void) {
/*lint -restore*/
uint32_t control;
uint32_t psp = __get_PSP();
chDbgAssert(((uint32_t)__builtin_return_address(0) & 4U) == 0U,
"not process");
#if PORT_USE_SYSCALL == TRUE
uint32_t control;
/* Caller context.*/
struct port_extctx *ectxp = (struct port_extctx *)psp;

View File

@ -74,7 +74,18 @@
* @brief Implements a syscall interface on SVC.
*/
#if !defined(PORT_USE_SYSCALL) || defined(__DOXYGEN__)
#define PORT_USE_SYSCALL TRUE
#define PORT_USE_SYSCALL FALSE
#endif
/**
* @brief Number of MPU regions to be saved/restored during context switch.
* @note The first region is always region zero.
* @note The use of this option has an overhead of 8 bytes for each
* region for each thread.
* @note Allowed values are 0..4, zero means none.
*/
#if !defined(PORT_SWITCHED_REGIONS_NUMBER) || defined(__DOXYGEN__)
#define PORT_SWITCHED_REGIONS_NUMBER 0
#endif
/**
@ -90,9 +101,11 @@
/**
* @brief MPU region to be used to stack guards.
* @note Make sure this region is not included in the
* @p PORT_SWITCHED_REGIONS_NUMBER regions range.
*/
#if !defined(PORT_USE_MPU_REGION) || defined(__DOXYGEN__)
#define PORT_USE_MPU_REGION MPU_REGION_7
#if !defined(PORT_USE_GUARD_MPU_REGION) || defined(__DOXYGEN__)
#define PORT_USE_GUARD_MPU_REGION MPU_REGION_7
#endif
/**
@ -177,6 +190,10 @@
/* Derived constants and error checks. */
/*===========================================================================*/
#if (PORT_SWITCHED_REGIONS_NUMBER < 0) || (PORT_SWITCHED_REGIONS_NUMBER > 4)
#error "invalid PORT_SWITCHED_REGIONS_NUMBER value"
#endif
#if !defined(_FROM_ASM_)
/**
* @brief MPU guard page size.
@ -370,6 +387,12 @@ struct port_linkctx {
#endif
struct port_intctx {
#if (PORT_SWITCHED_REGIONS_NUMBER > 0) || defined(__DOXYGEN__)
struct {
uint32_t rbar;
uint32_t rasr;
} regions[PORT_SWITCHED_REGIONS_NUMBER];
#endif
#if CORTEX_USE_FPU
regarm_t s16;
regarm_t s17;
@ -404,7 +427,7 @@ struct port_context {
#if (PORT_USE_SYSCALL == TRUE) || defined(__DOXYGEN__)
struct {
regarm_t psp;
const void *regions;
const void *p;
} syscall;
#endif
};
@ -414,14 +437,49 @@ struct port_context {
/* Module macros. */
/*===========================================================================*/
/* By default threads have no syscall context information.*/
#if (PORT_USE_SYSCALL == TRUE) || defined(__DOXYGEN__)
#define __PORT_SETUP_CONTEXT_SYSCALL(tp, wtop) \
(tp)->ctx.syscall.psp = (regarm_t)(wtop); \
(tp)->ctx.syscall.regions = NULL;
(tp)->ctx.syscall.p = NULL;
#else
#define __PORT_SETUP_CONTEXT_SYSCALL(tp, wtop)
#endif
/* By default threads have all regions disabled.*/
#if (PORT_SWITCHED_REGIONS_NUMBER == 0) || defined(__DOXYGEN__)
#define __PORT_SETUP_CONTEXT_MPU(tp)
#elif (PORT_SWITCHED_REGIONS_NUMBER == 1) || defined(__DOXYGEN__)
#define __PORT_SETUP_CONTEXT_MPU(tp) \
(tp)->ctx.sp->regions[0].rbar = 0U; \
(tp)->ctx.sp->regions[0].rasr = 0U
#elif (PORT_SWITCHED_REGIONS_NUMBER == 2) || defined(__DOXYGEN__)
#define __PORT_SETUP_CONTEXT_MPU(tp) \
(tp)->ctx.sp->regions[0].rbar = 0U; \
(tp)->ctx.sp->regions[0].rasr = 0U; \
(tp)->ctx.sp->regions[1].rbar = 0U; \
(tp)->ctx.sp->regions[1].rasr = 0U
#elif (PORT_SWITCHED_REGIONS_NUMBER == 3) || defined(__DOXYGEN__)
#define __PORT_SETUP_CONTEXT_MPU(tp) \
(tp)->ctx.sp->regions[0].rbar = 0U; \
(tp)->ctx.sp->regions[0].rasr = 0U; \
(tp)->ctx.sp->regions[1].rbar = 0U; \
(tp)->ctx.sp->regions[1].rasr = 0U; \
(tp)->ctx.sp->regions[2].rbar = 0U; \
(tp)->ctx.sp->regions[2].rasr = 0U
#elif (PORT_SWITCHED_REGIONS_NUMBER == 4) || defined(__DOXYGEN__)
#define __PORT_SETUP_CONTEXT_MPU(tp) \
(tp)->ctx.sp->regions[0].rbar = 0U; \
(tp)->ctx.sp->regions[0].rasr = 0U; \
(tp)->ctx.sp->regions[1].rbar = 0U; \
(tp)->ctx.sp->regions[1].rasr = 0U; \
(tp)->ctx.sp->regions[2].rbar = 0U; \
(tp)->ctx.sp->regions[2].rasr = 0U; \
(tp)->ctx.sp->regions[3].rbar = 0U; \
(tp)->ctx.sp->regions[3].rasr = 0U
#else
#endif
/**
* @brief Platform dependent part of the @p chThdCreateI() API.
* @details This code usually setup the context switching frame represented
@ -433,9 +491,12 @@ struct port_context {
(tp)->ctx.sp->r4 = (regarm_t)(pf); \
(tp)->ctx.sp->r5 = (regarm_t)(arg); \
(tp)->ctx.sp->lr = (regarm_t)_port_thread_start; \
__PORT_SETUP_CONTEXT_SYSCALL(tp, wtop) \
__PORT_SETUP_CONTEXT_MPU(tp); \
__PORT_SETUP_CONTEXT_SYSCALL(tp, wtop); \
}
// __PORT_SETUP_CONTEXT_MPU(tp)
/**
* @brief Computes the thread working area global size.
* @note There is no need to perform alignments in this macro.
@ -524,8 +585,8 @@ struct port_context {
_port_switch(ntp, otp); \
\
/* Setting up the guard page for the switched-in thread.*/ \
mpuSetRegionAddress(PORT_USE_MPU_REGION, \
chThdGetSelfX()->wabase); \
mpuSetRegionAddress(PORT_USE_GUARD_MPU_REGION, \
chThdGetSelfX()->wabase); \
}
#endif
#endif
@ -559,7 +620,7 @@ extern "C" {
*
* @return The interrupts status.
*/
static inline syssts_t port_get_irq_status(void) {
__STATIC_FORCEINLINE syssts_t port_get_irq_status(void) {
syssts_t sts;
#if CORTEX_SIMPLIFIED_PRIORITY == FALSE
@ -579,7 +640,7 @@ static inline syssts_t port_get_irq_status(void) {
* @retval false the word specified a disabled interrupts status.
* @retval true the word specified an enabled interrupts status.
*/
static inline bool port_irq_enabled(syssts_t sts) {
__STATIC_FORCEINLINE bool port_irq_enabled(syssts_t sts) {
#if CORTEX_SIMPLIFIED_PRIORITY == FALSE
return sts == (syssts_t)CORTEX_BASEPRI_DISABLED;
@ -595,7 +656,7 @@ static inline bool port_irq_enabled(syssts_t sts) {
* @retval false not running in ISR mode.
* @retval true running in ISR mode.
*/
static inline bool port_is_isr_context(void) {
__STATIC_FORCEINLINE bool port_is_isr_context(void) {
return (bool)((__get_IPSR() & 0x1FFU) != 0U);
}
@ -605,7 +666,7 @@ static inline bool port_is_isr_context(void) {
* @details In this port this function raises the base priority to kernel
* level.
*/
static inline void port_lock(void) {
__STATIC_FORCEINLINE void port_lock(void) {
#if CORTEX_SIMPLIFIED_PRIORITY == FALSE
#if defined(__CM7_REV)
@ -629,7 +690,7 @@ static inline void port_lock(void) {
* @details In this port this function lowers the base priority to user
* level.
*/
static inline void port_unlock(void) {
__STATIC_FORCEINLINE void port_unlock(void) {
#if CORTEX_SIMPLIFIED_PRIORITY == FALSE
__set_BASEPRI(CORTEX_BASEPRI_DISABLED);
@ -644,7 +705,7 @@ static inline void port_unlock(void) {
* level.
* @note Same as @p port_lock() in this port.
*/
static inline void port_lock_from_isr(void) {
__STATIC_FORCEINLINE void port_lock_from_isr(void) {
port_lock();
}
@ -655,7 +716,7 @@ static inline void port_lock_from_isr(void) {
* level.
* @note Same as @p port_unlock() in this port.
*/
static inline void port_unlock_from_isr(void) {
__STATIC_FORCEINLINE void port_unlock_from_isr(void) {
port_unlock();
}
@ -665,7 +726,7 @@ static inline void port_unlock_from_isr(void) {
* @note In this port it disables all the interrupt sources by raising
* the priority mask to level 0.
*/
static inline void port_disable(void) {
__STATIC_FORCEINLINE void port_disable(void) {
__disable_irq();
}
@ -675,7 +736,7 @@ static inline void port_disable(void) {
* @note Interrupt sources above kernel level remains enabled.
* @note In this port it raises/lowers the base priority to kernel level.
*/
static inline void port_suspend(void) {
__STATIC_FORCEINLINE void port_suspend(void) {
#if (CORTEX_SIMPLIFIED_PRIORITY == FALSE) || defined(__DOXYGEN__)
__set_BASEPRI(CORTEX_BASEPRI_KERNEL);
@ -689,7 +750,7 @@ static inline void port_suspend(void) {
* @brief Enables all the interrupt sources.
* @note In this port it lowers the base priority to user level.
*/
static inline void port_enable(void) {
__STATIC_FORCEINLINE void port_enable(void) {
#if (CORTEX_SIMPLIFIED_PRIORITY == FALSE) || defined(__DOXYGEN__)
__set_BASEPRI(CORTEX_BASEPRI_DISABLED);
@ -705,7 +766,7 @@ static inline void port_enable(void) {
* modes.
* @note Implemented as an inlined @p WFI instruction.
*/
static inline void port_wait_for_interrupt(void) {
__STATIC_FORCEINLINE void port_wait_for_interrupt(void) {
#if CORTEX_ENABLE_WFI_IDLE == TRUE
__WFI();
@ -717,7 +778,7 @@ static inline void port_wait_for_interrupt(void) {
*
* @return The realtime counter value.
*/
static inline rtcnt_t port_rt_get_counter_value(void) {
__STATIC_FORCEINLINE rtcnt_t port_rt_get_counter_value(void) {
return DWT->CYCCNT;
}

View File

@ -51,8 +51,12 @@
#error "invalid chconf.h"
#endif
.set SCB_ICSR, 0xE000ED04
.set ICSR_PENDSVSET, 0x10000000
/* MPU-related constants.*/
#define MPU_RBAR 0xE000ED9C
/* Other constants.*/
#define SCB_ICSR 0xE000ED04
#define ICSR_PENDSVSET 0x10000000
.syntax unified
.cpu cortex-m4
@ -73,9 +77,47 @@
_port_switch:
push {r4, r5, r6, r7, r8, r9, r10, r11, lr}
#if CORTEX_USE_FPU
/* Saving FPU context.*/
vpush {s16-s31}
#endif
#if PORT_SWITCHED_REGIONS_NUMBER > 0
/* Saving MPU context.*/
ldr r2, =MPU_RBAR
#if PORT_SWITCHED_REGIONS_NUMBER >= 1
mov r3, #0
str r3, [r2, #-4] /* RNR */
ldm r2, {r4, r5} /* RBAR, RASR */
#endif
#if PORT_SWITCHED_REGIONS_NUMBER >= 2
add r3, #1
str r4, [r2, #-4] /* RNR */
ldm r2, {r6, r7} /* RBAR, RASR */
#endif
#if PORT_SWITCHED_REGIONS_NUMBER >= 3
add r3, #1
str r4, [r2, #-4] /* RNR */
ldm r2, {r8, r9} /* RBAR, RASR */
#endif
#if PORT_SWITCHED_REGIONS_NUMBER >= 4
add r3, #1
str r4, [r2, #-4] /* RNR */
ldm r2, {r10, r11} /* RBAR, RASR */
#endif
#if PORT_SWITCHED_REGIONS_NUMBER == 1
push {r4, r5}
#endif
#if PORT_SWITCHED_REGIONS_NUMBER == 2
push {r4, r5, r6, r7}
#endif
#if PORT_SWITCHED_REGIONS_NUMBER == 3
push {r4, r5, r6, r7, r8, r9}
#endif
#if PORT_SWITCHED_REGIONS_NUMBER == 4
push {r4, r5, r6, r7, r8, r9, r10, r11}
#endif
#endif
str sp, [r1, #CONTEXT_OFFSET]
#if (CORTEX_SIMPLIFIED_PRIORITY == FALSE) && \
((CORTEX_MODEL == 3) || (CORTEX_MODEL == 4))
@ -87,7 +129,44 @@ _port_switch:
ldr sp, [r0, #CONTEXT_OFFSET]
#endif
#if PORT_SWITCHED_REGIONS_NUMBER > 0
/* Restoring MPU context.*/
#if PORT_SWITCHED_REGIONS_NUMBER == 1
pop {r4, r5}
#endif
#if PORT_SWITCHED_REGIONS_NUMBER == 2
pop {r4, r5, r6, r7}
#endif
#if PORT_SWITCHED_REGIONS_NUMBER == 3
pop {r4, r5, r6, r7, r8, r9}
#endif
#if PORT_SWITCHED_REGIONS_NUMBER == 4
pop {r4, r5, r6, r7, r8, r9, r10, r11}
#endif
#if PORT_SWITCHED_REGIONS_NUMBER >= 1
mov r3, #0
str r3, [r2, #-4] /* RNR */
stm r2, {r4, r5} /* RBAR, RASR */
#endif
#if PORT_SWITCHED_REGIONS_NUMBER >= 2
add r3, #1
str r3, [r2, #-4] /* RNR */
stm r2, {r6, r7} /* RBAR, RASR */
#endif
#if PORT_SWITCHED_REGIONS_NUMBER >= 3
add r3, #1
str r3, [r2, #-4] /* RNR */
stm r2, {r8, r9} /* RBAR, RASR */
#endif
#if PORT_SWITCHED_REGIONS_NUMBER >= 4
add r3, #1
str r3, [r2, #-4] /* RNR */
stm r2, {r10, r11} /* RBAR, RASR */
#endif
#endif
#if CORTEX_USE_FPU
/* Restoring FPU context.*/
vpop {s16-s31}
#endif
pop {r4, r5, r6, r7, r8, r9, r10, r11, pc}