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;
}