/* Switch the context from the source box to the destination one, using the * stack pointers provided as input. */ void context_switch_in(TContextSwitchType context_type, uint8_t dst_id, uint32_t src_sp, uint32_t dst_sp) { uint8_t src_id; /* Source box: Gather information from the current state. */ src_id = g_active_box; /* The source/destination box IDs can be the same (for example, in IRQs). */ if (src_id != dst_id) { /* Update the context pointer to the one of the destination box. */ *(__uvisor_config.uvisor_box_context) = (uint32_t *) g_context_current_states[dst_id].bss; /* Update the ID of the currently active box. */ g_active_box = dst_id; UvisorBoxIndex * index = (UvisorBoxIndex *) *(__uvisor_config.uvisor_box_context); index->box_id_self = dst_id; /* Switch MPU configurations. */ /* This function halts if it finds an error. */ vmpu_switch(src_id, dst_id); } /* Push the state of the source box and set the stack pointer for the * destination box. * This is only needed if the context switch is tied to a function. Unbound * context switches require the host OS to set the correct stack pointer * before handling execution to the unprivileged code, and for the same * reason do not require state-keeping. */ /* This function halts if it finds an error. */ if (context_type == CONTEXT_SWITCH_FUNCTION_GATEWAY || context_type == CONTEXT_SWITCH_FUNCTION_ISR || context_type == CONTEXT_SWITCH_FUNCTION_DEBUG) { context_state_push(context_type, src_id, src_sp); __set_PSP(dst_sp); } }
/* Switch the context from the source box to the destination one, using the * stack pointers provided as input. */ void context_switch_in(TContextSwitchType context_type, uint8_t dst_id, uint32_t src_sp, uint32_t dst_sp) { /* The source box is the currently active box. */ uint8_t src_id = g_active_box; if (!vmpu_is_box_id_valid(src_id)) { /* Note: We accept that the source box ID is invalid if this is the very * first context switch. */ if (context_type == CONTEXT_SWITCH_UNBOUND_FIRST) { src_id = dst_id; } else { HALT_ERROR(SANITY_CHECK_FAILED, "Context switch: The source box ID is out of range (%u).\r\n", src_id); } } if (!vmpu_is_box_id_valid(dst_id)) { HALT_ERROR(SANITY_CHECK_FAILED, "Context switch: The destination box ID is out of range (%u).\r\n", dst_id); } /* The source/destination box IDs can be the same (for example, in IRQs). */ if (src_id != dst_id || context_type == CONTEXT_SWITCH_UNBOUND_FIRST) { /* Store outgoing newlib reent pointer. */ UvisorBoxIndex * index = (UvisorBoxIndex *) g_context_current_states[src_id].bss; index->bss.address_of.newlib_reent = (uint32_t) *(__uvisor_config.newlib_impure_ptr); /* Update the context pointer to the one of the destination box. */ index = (UvisorBoxIndex *) g_context_current_states[dst_id].bss; *(__uvisor_config.uvisor_box_context) = (uint32_t *) index; /* Update the ID of the currently active box. */ g_active_box = dst_id; index->box_id_self = dst_id; #if defined(ARCH_CORE_ARMv8M) /* Switch vIRQ configurations. */ virq_switch(src_id, dst_id); #endif /* defined(ARCH_CORE_ARMv8M) */ /* Switch MPU configurations. */ /* This function halts if it finds an error. */ vmpu_switch(src_id, dst_id); /* Restore incoming newlib reent pointer. */ *(__uvisor_config.newlib_impure_ptr) = (uint32_t *) index->bss.address_of.newlib_reent; } /* Push the state of the source box and set the stack pointer for the * destination box. * This is only needed if the context switch is tied to a function. Unbound * context switches require the host OS to set the correct stack pointer * before handling execution to the unprivileged code, and for the same * reason do not require state-keeping. */ /* This function halts if it finds an error. */ if (context_type == CONTEXT_SWITCH_FUNCTION_GATEWAY || context_type == CONTEXT_SWITCH_FUNCTION_ISR || context_type == CONTEXT_SWITCH_FUNCTION_DEBUG) { context_state_push(context_type, src_id, src_sp); #if defined(ARCH_CORE_ARMv8M) /* FIXME: Set the right LR value depending on which NS SP is actually used. */ __TZ_set_MSP_NS(dst_sp); __TZ_set_PSP_NS(dst_sp); #else __set_PSP(dst_sp); #endif } }