int vmpu_box_namespace_from_id(int box_id, char *box_namespace, size_t length) { const UvisorBoxConfig **box_cfgtbl; box_cfgtbl = (const UvisorBoxConfig**) __uvisor_config.cfgtbl_ptr_start; if (!vmpu_is_box_id_valid(box_id)) { /* The box_id is not valid, so return an error to prevent reading * non-box-configuration data from flash. */ return UVISOR_ERROR_INVALID_BOX_ID; } if (length < UVISOR_MAX_BOX_NAMESPACE_LENGTH) { /* There is not enough room in the supplied buffer for maximum length * namespace. */ return UVISOR_ERROR_BUFFER_TOO_SMALL; } if (box_cfgtbl[box_id]->box_namespace == NULL) { return UVISOR_ERROR_BOX_NAMESPACE_ANONYMOUS; } return copy_box_namespace(box_cfgtbl[box_id]->box_namespace, box_namespace); }
/* 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 } }