trap_irq - wlshiu/my_note GitHub Wiki




static uintptr_t    g_org_sp = 0;
static uintptr_t    __fence__ = ??;

/**
 *  memory area: __Sys_Intc_Stack ~ __fence__  is the specific stack of nesting ISR
 */

frame_save()
{
    g_org_sp = reg_sp;
}

frame_restore()
{
    reg_sp = g_org_sp;
}

hsp_update()
{
    reg_SP_BOUND = __fence__;
}

tcb_hsp_update(uintptr_t* reg_r0, uintptr_t* reg_r1)
{
    reg_SP_BOUND = pxCurrentTCB->stack_top + M_SP_TOP_OFFSET;

    *reg_r0 = reg_SP_BOUND;
    *reg_r1 = pxCurrentTCB->stack_top;
}

OS_Trap_Intc()
{
    caller_save();  // push all registers to stack, reg_sp += N

    intc_lv_switch(0);

    if( gOsFromISR == 0 ) {
        frame_save();
    #if (CONFIG_ENABLE_HSP)
        hsp_update();
        reg_sp = __Sys_Intc_Stack;
    #endif
    }

    gOsFromISR++;

    {
        uint32_t    itype = __nds32_get_itype();

        itype &= 0x0FE0;
        itype >>= 5;
        itype  -= 9;
    }

    void (*pf_isr)(void);

    pf_isr = OS_CPU_Vector_Table[IRQ_index];

    // nesting

    #if (CONFIG_ENABLE_ISR_MEASURE)
    Sys_isr_start_time();  // record start time
    #endif

    __nds32_enable_gie();
    __nds32_dsb();

    pf_isr();

    __nds32_disable_gie();
    __nds32_dsb();

    #if (CONFIG_ENABLE_ISR_MEASURE)
    Sys_isr_end_time(); // calculate elapsed time
    #endif

    gOsFromISR--;

    if( gOsFromISR == 0 ) {
        tcb_hsp_update();
        frame_restore();
    }

    caller_restore(); // pop to registers from stack

    return;
}