More VRQ code.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15623 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
parent
a3d8eb7e71
commit
3fcb8c47c3
|
@ -723,7 +723,7 @@ struct port_context {
|
||||||
* @param[in] tp pointer to the thread
|
* @param[in] tp pointer to the thread
|
||||||
* @param[in] addr new address
|
* @param[in] addr new address
|
||||||
*/
|
*/
|
||||||
#define __port_syscall_set_u_psp(tp, addr) (tp)->ctx.syscall.u_psp = (addr)
|
#define __port_syscall_set_u_psp(tp, addr) (tp)->ctx.syscall.u_psp = (uint32_t)(addr)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Updates the stored system PSP address.
|
* @brief Updates the stored system PSP address.
|
||||||
|
@ -731,7 +731,7 @@ struct port_context {
|
||||||
* @param[in] tp pointer to the thread
|
* @param[in] tp pointer to the thread
|
||||||
* @param[in] addr new address
|
* @param[in] addr new address
|
||||||
*/
|
*/
|
||||||
#define __port_syscall_set_s_psp(tp, addr) (tp)->ctx.syscall.u_ssp = (addr)
|
#define __port_syscall_set_s_psp(tp, addr) (tp)->ctx.syscall.s_psp = (uint32_t)(addr)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the user PSP address.
|
* @brief Returns the user PSP address.
|
||||||
|
|
|
@ -52,20 +52,29 @@
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
__STATIC_FORCEINLINE void vfq_makectx(sb_class_t *sbp,
|
__STATIC_FORCEINLINE void vfq_makectx(sb_class_t *sbp,
|
||||||
struct port_extctx *ectxp,
|
struct port_extctx *newctxp,
|
||||||
uint32_t active_mask) {
|
uint32_t active_mask) {
|
||||||
uint32_t irqn = __CLZ(active_mask);
|
uint32_t irqn = __CLZ(active_mask);
|
||||||
sbp->vrq_wtmask &= ~(1U << irqn);
|
sbp->vrq_wtmask &= ~(1U << irqn);
|
||||||
|
|
||||||
/* Building the return context.*/
|
/* Building the return context.*/
|
||||||
ectxp->r0 = irqn;
|
newctxp->r0 = irqn;
|
||||||
ectxp->pc = sbp->sbhp->hdr_vfq; /* TODO validate or let it eventually crash? */
|
newctxp->pc = sbp->sbhp->hdr_vfq; /* TODO validate or let it eventually crash? */
|
||||||
ectxp->xpsr = 0x01000000U;
|
newctxp->xpsr = 0x01000000U;
|
||||||
#if CORTEX_USE_FPU == TRUE
|
#if CORTEX_USE_FPU == TRUE
|
||||||
ectxp->fpscr = FPU->FPDSCR;
|
newctxp->fpscr = FPU->FPDSCR;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Used as a known privileged address.
|
||||||
|
*/
|
||||||
|
static void vfq_privileged_code(void) {
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Module exported functions. */
|
/* Module exported functions. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -77,14 +86,10 @@ __STATIC_FORCEINLINE void vfq_makectx(sb_class_t *sbp,
|
||||||
*
|
*
|
||||||
* @param[in] sbp pointer to a @p sb_class_t structure
|
* @param[in] sbp pointer to a @p sb_class_t structure
|
||||||
* @param[in] vmask mask of VRQs to be activated
|
* @param[in] vmask mask of VRQs to be activated
|
||||||
* @return The operation status.
|
|
||||||
* @retval false if the activation has succeeded.
|
|
||||||
* @retval true in case of sandbox stack overflow.
|
|
||||||
*
|
*
|
||||||
* @special
|
* @special
|
||||||
*/
|
*/
|
||||||
bool sbVRQTriggerFromISR(sb_class_t *sbp, sb_vrqmask_t vmask) {
|
void sbVRQTriggerFromISR(sb_class_t *sbp, sb_vrqmask_t vmask) {
|
||||||
struct port_extctx *ectxp;
|
|
||||||
|
|
||||||
chSysLockFromISR();
|
chSysLockFromISR();
|
||||||
|
|
||||||
|
@ -96,47 +101,57 @@ bool sbVRQTriggerFromISR(sb_class_t *sbp, sb_vrqmask_t vmask) {
|
||||||
sb_vrqmask_t active_mask = sbp->vrq_wtmask & sbp->vrq_enmask;
|
sb_vrqmask_t active_mask = sbp->vrq_wtmask & sbp->vrq_enmask;
|
||||||
|
|
||||||
if (active_mask != 0U) {
|
if (active_mask != 0U) {
|
||||||
|
struct port_extctx *ectxp, *newctxp;
|
||||||
|
|
||||||
/* This IRQ could have preempted the sandbox itself or some other thread,
|
/* This IRQ could have preempted the sandbox itself or some other thread,
|
||||||
handling is different.*/
|
handling is different.*/
|
||||||
if (sbp->tp->state == CH_STATE_CURRENT) {
|
if (sbp->tp->state == CH_STATE_CURRENT) {
|
||||||
/* Sandbox case, getting the current exception frame.*/
|
/* Sandbox case, getting the current exception frame.*/
|
||||||
ectxp = (struct port_extctx *)__get_PSP() - 1;
|
ectxp = (struct port_extctx *)__get_PSP();
|
||||||
|
newctxp = ectxp - 1;
|
||||||
|
|
||||||
/* Checking if the new frame is within the sandbox else failure.*/
|
/* Checking if the new frame is within the sandbox else failure.*/
|
||||||
if (!sb_is_valid_write_range(sbp,
|
if (!sb_is_valid_write_range(sbp,
|
||||||
(void *)ectxp,
|
(void *)newctxp,
|
||||||
sizeof (struct port_extctx))) {
|
sizeof (struct port_extctx))) {
|
||||||
|
/* Making the sandbox return on a privileged address, this
|
||||||
|
will cause a fault and sandbox termination.*/
|
||||||
chSysUnlockFromISR();
|
chSysUnlockFromISR();
|
||||||
|
ectxp->pc = (uint32_t)vfq_privileged_code;
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ectxp = sbp->tp->ctx.sp - 1;
|
/* Other thread case, getting the pointer from the context switch
|
||||||
|
structure.*/
|
||||||
|
ectxp = sbp->tp->ctx.sp;
|
||||||
|
newctxp = ectxp - 1;
|
||||||
|
|
||||||
/* Checking if the new frame is within the sandbox else failure.*/
|
/* Checking if the new frame is within the sandbox else failure.*/
|
||||||
if (!sb_is_valid_write_range(sbp,
|
if (!sb_is_valid_write_range(sbp,
|
||||||
(void *)ectxp,
|
(void *)newctxp,
|
||||||
sizeof (struct port_extctx))) {
|
sizeof (struct port_extctx))) {
|
||||||
|
/* Making the sandbox return on a privileged address, this
|
||||||
|
will cause a fault and sandbox termination.*/
|
||||||
chSysUnlockFromISR();
|
chSysUnlockFromISR();
|
||||||
|
ectxp->pc = (uint32_t)vfq_privileged_code;
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Preventing leakage of information, clearing all register values, those
|
/* Preventing leakage of information, clearing all register values, those
|
||||||
would come from outside the sandbox.*/
|
would come from outside the sandbox.*/
|
||||||
memset((void *)ectxp, 0, sizeof (struct port_extctx));
|
memset((void *)newctxp, 0, sizeof (struct port_extctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Building the return context.*/
|
/* Building the return context.*/
|
||||||
vfq_makectx(sbp, ectxp, active_mask);
|
vfq_makectx(sbp, newctxp, active_mask);
|
||||||
|
__port_syscall_set_u_psp(sbp->tp, newctxp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
chSysUnlockFromISR();
|
chSysUnlockFromISR();
|
||||||
|
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sb_vrq_disable(struct port_extctx *ectxp) {
|
void sb_vrq_disable(struct port_extctx *ectxp) {
|
||||||
|
@ -169,6 +184,7 @@ void sb_vrq_enable(struct port_extctx *ectxp) {
|
||||||
|
|
||||||
/* Building the return context.*/
|
/* Building the return context.*/
|
||||||
vfq_makectx(sbp, ectxp, active_mask);
|
vfq_makectx(sbp, ectxp, active_mask);
|
||||||
|
__port_syscall_set_u_psp(sbp->tp, ectxp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -202,6 +218,8 @@ void sb_vrq_return(struct port_extctx *ectxp) {
|
||||||
/* Discarding the return current context, returning on the previous one.*/
|
/* Discarding the return current context, returning on the previous one.*/
|
||||||
ectxp++;
|
ectxp++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__port_syscall_set_u_psp(sbp->tp, ectxp);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* SB_CFG_ENABLE_VRQ == TRUE */
|
#endif /* SB_CFG_ENABLE_VRQ == TRUE */
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
bool sbVRQTriggerFromISR(sb_class_t *sbp, sb_vrqmask_t vmask);
|
void sbVRQTriggerFromISR(sb_class_t *sbp, sb_vrqmask_t vmask);
|
||||||
void sb_vrq_disable(struct port_extctx *ectxp);
|
void sb_vrq_disable(struct port_extctx *ectxp);
|
||||||
void sb_vrq_enable(struct port_extctx *ectxp);
|
void sb_vrq_enable(struct port_extctx *ectxp);
|
||||||
void sb_vrq_getisr(struct port_extctx *ectxp);
|
void sb_vrq_getisr(struct port_extctx *ectxp);
|
||||||
|
|
Loading…
Reference in New Issue