Beispiel #1
0
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);
}
Beispiel #2
0
/* 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
    }
}