硬體中斷有數量限制, 如果改成軟體中斷,就可以將發生過的中斷全部存起來。
以下用demo-int做為說明的example。 在demo-int中,當HW1 interrupt發生時,進入的SAVE_ALL_HW macro, 會將interrupt等資訊存起來。
common_ISR_wrapper: SAVE_ALL_HW la $r1, ISR_TABLE lw $r1, [$r1+$r0<<2] jral $r1 RESTORE_ALL_HW iret
OS_Trap_Interrupt_HW1: push $r0 li $r0, 0x01 b common_ISR_wrapper
以下為SAVE_ALL_HW的macro。(在interrupt.h裏) ir0的bit 1 和2為interrupt level,下面我紅色標示的地方, 為將interrupt level下降1。 粉紅色字體的部份為將interrupt status存入stack
.macro SAVE_ALL_HW !should not touch $r0 /* push caller-saved gpr */ pushm $r1, $r5 pushm $r15, $r30 push_d0d1 #if !(defined(NDS32_BASELINE_V3M) || defined(NDS32_BASELINE_V3)) /* push $INT_MASK */ mfsr $r1, $INT_MASK push $r1 !push $INT_MASK
/* disable low priority and * enable high priority interrupt */ ori $r1, $r1, 0x3f ! r1= {mask[31:6],000000} li $r2, 1 sll $r2, $r2, $r0 ! 1<<r0 subri $r2, $r2, 64 ! 64 - (1 << r0) sub $r1, $r1, $r2 ! {mask[31:6],000000} - (64- (1<<r0)) mtsr $r1, $INT_MASK
#endif /* push $PSW, $IPC, $IPSW */ mfsr $r1, $PSW mfsr $r2, $IPC mfsr $r3, $IPSW pushm $r1, $r3 /* You can use -1 if you want to * descend interrupt level and enable gie or * you can enable gie when you finish your top * half isr. */ /* Descend interrupt level */ addi $r1, $r1, #-2 mtsr $r1, $PSW /* align $sp to 8B boundary */ move $r2, $sp !keep original $sp to be pushed #if !(defined(NDS32_BASELINE_V3M) || defined(NDS32_BASELINE_V3)) andi $r3, $sp, #4 subri $r3, $r3, #4 ! bit2==0? 4 : 0 sub $sp, $sp, $r3 ! bit2==0? (sp-=4) : (sp-=0) #endif push $r2 push_fpu .endm
|