예제 #1
0
파일: virq.c 프로젝트: ccli8/uvisor
void virq_init(uint32_t const * const user_vtor)
{
    /* Detect the number of implemented priority bits.
     * The architecture specifies that unused/not implemented bits in the
     * NVIC IP registers read back as 0. */
    __disable_irq();
    uint8_t volatile * prio = (uint8_t volatile *) &(NVIC->IPR[0]);
    uint8_t prio_bits = *prio;
    *prio = 0xFFU;
    g_virq_prio_bits = (uint8_t) __builtin_popcount(*prio);
    *prio = prio_bits;
    __enable_irq();

    /* Verify that the priority bits read at runtime are realistic. */
    assert(g_virq_prio_bits > 0 && g_virq_prio_bits <= 8);

    /* Set the minimum IRQ priority. */
    g_virq_min_priority = (uint8_t) ((1 << g_virq_prio_bits) - 1);

    /* At the beginning, all IRQs are dis-owned. */
    for (size_t irqn = 0; irqn < NVIC_VECTORS; ++irqn) {
        g_virq_states[irqn].box_id = UVISOR_BOX_ID_INVALID;
        NVIC_ClearTargetState(irqn);
    }
}
예제 #2
0
파일: target_cfg.c 프로젝트: toyowata/mbed
/*----------------- NVIC interrupt target state to NS configuration ----------*/
void nvic_interrupt_target_state_cfg()
{
    /* Target every interrupt to NS; unimplemented interrupts will be WI */
    for (uint8_t i=0; i<sizeof(NVIC->ITNS)/sizeof(NVIC->ITNS[0]); i++) {
        NVIC->ITNS[i] = 0xFFFFFFFF;
    }

    /* Make sure that MPC and PPC are targeted to S state */
    NVIC_ClearTargetState(SEC_VIO_IRQn);
}
예제 #3
0
파일: virq.c 프로젝트: ccli8/uvisor
void virq_switch(uint8_t src_id, uint8_t dst_id)
{
    bool src_box_in_active_irq = false;

    for (uint32_t irqn = 0; irqn < NVIC_VECTORS; ++irqn) {
        TVirqState * irq = &g_virq_states[irqn];

        /* Put all the source box IRQs on hold.
         * Putting an IRQ on hold means:
         *   - Promote it to secure state, so that NS code cannot modify it.
         *   - De-prioritize it, so that the destination box can be pre-empted.
         */
        if (irq->box_id == src_id) {
            irq->enabled = TZ_NVIC_GetEnableIRQ_NS(irqn);
            irq->priority = TZ_NVIC_GetPriority_NS(irqn);
            if (TZ_NVIC_GetActive_NS(irqn)) {
                src_box_in_active_irq = true;
            }
            assert(irq->priority < g_virq_min_priority);
            TZ_NVIC_SetPriority_NS(irqn, g_virq_min_priority);
            TZ_NVIC_DisableIRQ_NS(irqn);
            NVIC_ClearTargetState(irqn);
        }

        /* Re-enable all the destination box IRQs. */
        if (irq->box_id == dst_id) {
            NVIC_SetTargetState(irqn);
            if (irq->enabled) {
                TZ_NVIC_EnableIRQ_NS(irqn);
            }
            TZ_NVIC_SetPriority_NS(irqn, irq->priority);
        }
    }

    /* System exceptions
     * These exceptions are banked between secure states, and hence need to be
     * saved and restored at every context switch. */
    /* Note: The very first time that an exception state is saved or restored,
     *       the box has actually never run. The code below assumes that all the
     *       save/restore functions use a sensible default state, i.e., an
     *       inactive, not pending, not enabled exception state. */

    /* SysTick */
    src_box_in_active_irq |= virq_copy_systick_ns(src_id);
    virq_load_systick_ns(dst_id);

    /* SVCall */
    src_box_in_active_irq |= virq_copy_svcall_ns(src_id);
    virq_load_svcall_ns(dst_id);

    /* Save the active state for the source box. */
    g_virq_box_in_active_irq[src_id] = src_box_in_active_irq;
}
예제 #4
0
/**
 *
 * @brief Set the target security state for the given IRQ
 *
 * Function sets the security state (Secure or Non-Secure) targeted
 * by the given irq. It requires ARMv8-M MCU.
 * It is only compiled if ARM_SECURE_FIRMWARE is defined.
 * It should only be called while in Secure state, otherwise, a write attempt
 * to NVIC.ITNS register is write-ignored(WI), as the ITNS register is not
 * banked between security states and, therefore, has no Non-Secure instance.
 *
 * It shall assert if the operation is not performed successfully.
 *
 * @param irq IRQ line
 * @param secure_state 1 if target state is Secure, 0 otherwise.
 *
 * @return N/A
 */
void irq_target_state_set(unsigned int irq, int secure_state)
{
	if (secure_state) {
		/* Set target to Secure */
		if (NVIC_ClearTargetState(irq) != 0) {
			__ASSERT(0, "NVIC SetTargetState error");
		}
	} else {
		/* Set target state to Non-Secure */
		if (NVIC_SetTargetState(irq) != 1) {
			__ASSERT(0, "NVIC SetTargetState error");
		}
	}
}