;
; CAREFUL! The stack frame is being altered here. It's ok since
; the only routine relying on this was the Interlock Check. Note that
; we re-push LR onto the stack so that the incoming argument area to
; OEMInterruptHandler will be correct.
;
mrs r1, spsr ; (r1) = saved status reg
stmfd sp!, {r1} ; save SPSR onto the IRQ stack
mov r0,lr ; parAMEter to OEMInterruptHandler
msr cpsr_c, #SVC_MODE:OR:0x80 ; switch to supervisor mode w/IRQs disabled
stmfd sp!, {lr} ; save LR onto the SVC stack
stmfd sp!, {r0} ; save IRQ LR (in R0) onto the SVC stack (param)
;
; Now we call the OEM's interrupt handler code. It is up to them to
; enable interrupts if they so desire. We can't do it for them since
; there's only on interrupt and they haven't yet defined their nesting.
;
CALL OEMInterruptHandler
ldmfd sp!, {r1} ; dummy pop (parameter)
ldmfd sp!, {lr} ; restore SVC LR from the SVC stack
msr cpsr_c, #IRQ_MODE:OR:0x80 ; switch back to IRQ mode w/IRQs disabled
; Restore the saved program status register from the stack.
;
ldmfd sp!, {r1} ; restore IRQ SPSR from the IRQ stack
msr spsr, r1 ; (r1) = saved status reg
ldr lr, =KData ; (lr) = ptr to KDataStruct
cmp r0, #SYSINTR_RESCHED ;->時間片已到,進(jìn)行調(diào)度
beq
%B20
; interrupted, reschedule again
msr spsr, r2
ldr lr, [r0, #TcxPc-TcxR3]
ldmdb r0,
movs pc,
lr
; return to user or system mode
HandleException是實際進(jìn)行異常處理的函數(shù),針對上面沒有處理完的異常進(jìn)一步分析并進(jìn)行處理。這個函數(shù)是沒有公開代碼的,所以沒有辦法進(jìn)一步深入下去。由于處理的異常類型比較多所以這個異常處理函數(shù)的代碼量是相當(dāng)大的,因此會耗費相對比較多的時鐘周期,在之前的代碼中我們都是在關(guān)閉中斷的情況下進(jìn)行異常處理,如果在這里還不打開中斷的話整個異常處理過程會相當(dāng)?shù)拈L,這樣會很大程度上影響系統(tǒng)的實時性,所以在這里調(diào)用HandleException之前是將中斷重新打開的,待到處理完成再將中斷關(guān)閉。對于這些異常,如果不能處理就只有兩種情況:1.結(jié)束該進(jìn)程/線程。2.掛起系統(tǒng)。第二種情況下掛起系統(tǒng)HandleException是不會返回的。因此,只有異常處理正常流程和結(jié)束線程的可能。對于返回的情況,這個時候如果返回觸發(fā)異常的地址繼續(xù)運行的話,仍然會導(dǎo)致異常,所以結(jié)束進(jìn)程/線程都需要重新調(diào)度才能完成了。對于異常處理成功的情形,就不必調(diào)度了,直接就可以返回產(chǎn)生異常的地方繼續(xù)執(zhí)行。在這里還要考慮套嵌(這里僅僅是指系統(tǒng)模式和兼管模式的異常套嵌)的情形,也就是中斷/異常已經(jīng)進(jìn)入調(diào)度狀態(tài)又再次產(chǎn)生中斷/異常,這個時候就強(qiáng)行取消上一次調(diào)度,進(jìn)而重新調(diào)度。這用于調(diào)度過程中遇到異?;謴?fù)和剝奪的情況,如果不屬于這種情況的話就直接恢復(fù)寄存器狀態(tài)并且返回中斷點繼續(xù)執(zhí)行。
; Return to a non-preemptible privileged mode.
;
; (r0) = ptr to THREAD structure
; (r2) = target mode
30 msr cpsr,
r2
; switch to target mode
add r0, r0, #TcxR0
ldmia r0,
; reload all registers & return
通過HandleException處理以后,已經(jīng)完成了所有異常的處理,所以這里只是考慮反回的情況,由于這里不包含用戶模式下的處理,所以這里處理的都是特權(quán)模式,完全可以訪問kdata區(qū)域,這里就直接利用Kdata區(qū)域中的線程備份來完成恢復(fù)寄存器和返回。
評論
查看更多