Mercurial > hg > Members > menikon > CbC_xv6
diff src/trap_asm.S @ 0:83c23a36980d
Init
author | Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 26 May 2017 23:11:05 +0900 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/trap_asm.S Fri May 26 23:11:05 2017 +0900 @@ -0,0 +1,165 @@ +//low-level trap handler glue code +#include "arm.h" + +.text +.code 32 + +.global trap_swi +.global trap_irq +.global trap_reset +.global trap_und +.global trap_iabort +.global trap_dabort +.global trap_na +.global trap_fiq +.global trapret + + +# handle SWI, we allow nested SWI +trap_swi: + # build trapframe on the stack + STMFD sp!, {r0-r12, r14} // save context + MRS r2, spsr // copy spsr to r2 + STMFD r13!, {r2} // save r2(spsr) to the stack + STMFD r13!, {r14} // save r14 again to have one uniform trapframe + STMFD r13, {sp, lr}^ // save user mode sp and lr + SUB r13, r13, #8 + + # call traps (trapframe *fp) + MOV r0, r13 // copy r13_svc to r0 + BL swi_handler // branch to the isr_swi + + # restore states +trapret: + LDMFD r13, {sp, lr}^ // restore user mode sp and lr + ADD r13, r13, #8 + LDMFD r13!, {r14} // restore r14 + LDMFD r13!, {r2} // restore spsr + MSR spsr_cxsf, r2 + LDMFD r13!,{r0-r12, pc}^ // restore context and return + + +# handle IRQ, we allow nested IRQs +trap_irq: + # save a few registers to the irq stack to provide scratch regs. + # r14 (lr_irq) contains the instruction (pc) to return to, need to + # save it on the stack as r14 is banked + SUB r14, r14, #4 // r14 (lr) contains the interrupted PC + STMFD r13!, {r0-r2, r14} // + MRS r1, spsr // save spsr_irq + MOV r0, r13 // save stack stop (r13_irq) + ADD r13, r13, #16 // reset the IRQ stack + + # switch to the SVC mode + MRS r2, cpsr + BIC r2, r2, #MODE_MASK + ORR r2, r2, #SVC_MODE + MSR cpsr_cxsf, r2 + + # now, in SVC mode, sp, lr, pc (r13, r14, r15) are all banked + # build the trap frame + LDR r2, [r0, #12] // read the r14_irq, then save it + STMFD r13!, {r2} + STMFD r13!, {r3-r12} // r4-r12 are preserved (non-banked) + LDMFD r0, {r3-r5} // copy r0-r2 over from irq stack + STMFD r13!, {r3-r5} + STMFD r13!, {r1} // save spsr + STMFD r13!, {lr} // save r14_svc + + STMFD r13, {sp, lr}^ // save user mode sp and lr + SUB r13, r13, #8 + + # get the parameters, then call the handler + MOV r0, r13 // points to + BL irq_handler + + # restore the previous status + B trapret + +# handle reset/undefine instruction/abort/not-assigned/fiq +# these handler does not allow nested handling +trap_reset: + MOV r14, #0 // lr: not defined on reset + STMFD r13!, {r0-r12, r14} + MRS r2, spsr // copy spsr to r2 + STMFD r13!, {r2} // save r2(spsr) to the stack + STMFD r13!, {r14} // save r14 again (it is not really correct) + STMFD r13, {sp, lr}^ // save user mode sp and lr + SUB r13, r13, #8 + + # call traps (trapframe *fp) + MOV r0, r13 // copy r13_svc to r0 + BL reset_handler + B . + +trap_und: + STMFD r13!, {r0-r12, r14} // lr: instruction after the undefined + MRS r2, spsr // copy spsr to r2 + STMFD r13!, {r2} // save r2(spsr) to the stack + STMFD r13!, {r14} // save r14 again (it is not really correct) + STMFD r13, {sp, lr}^ // save user mode sp and lr + SUB r13, r13, #8 + + # call traps (trapframe *fp) + MOV r0, r13 // save trapframe as the first parameter + BL und_handler + B . + +trap_iabort: + SUB r14, r14, #4 // lr: instruction causing the abort + STMFD r13!, {r0-r12, r14} + MRS r2, spsr // copy spsr to r2 + STMFD r13!, {r2} // save r2(spsr) to the stack + STMFD r13!, {r14} // save r14 again (it is not really correct) + STMFD r13, {sp, lr}^ // save user mode sp and lr + SUB r13, r13, #8 + + # call traps (trapframe *fp) + MOV r0, r13 // save trapframe as the first parameter + BL iabort_handler + B . + +trap_dabort: + SUB r14, r14, #8 // lr: instruction causing the abort + STMFD r13!, {r0-r12, r14} + MRS r2, spsr // copy spsr to r2 + STMFD r13!, {r2} // save r2(spsr) to the stack + STMFD r13!, {r14} // save r14 again (it is not really correct) + STMFD r13, {sp, lr}^ // save user mode sp and lr + SUB r13, r13, #8 + + # call traps (trapframe *fp) + MOV r0, r13 // save trapframe as the first parameter + BL dabort_handler + MOV r0, #2 // #SYS_exit + SWI 0x00 + B exit + #B . // trapret + +trap_na: + STMFD r13!, {r0-r12, r14} // should never happen, hardware error + MRS r2, spsr // copy spsr to r2 + STMFD r13!, {r2} // save r2(spsr) to the stack + STMFD r13!, {r14} // save r14 again (it is not really correct) + STMFD r13, {sp, lr}^ // save user mode sp and lr + SUB r13, r13, #8 + + # call traps (trapframe *fp) + MOV r0, r13 // save trapframe as the first parameter + BL na_handler + B . + +trap_fiq: + SUB r14, r14, #4 // lr: return address after the fiq handler + STMFD r13!, {r0-r12, r14} + MRS r2, spsr // copy spsr to r2 + STMFD r13!, {r2} // save r2(spsr) to the stack + STMFD r13!, {r14} // save r14 again (it is not really correct) + STMFD r13, {sp, lr}^ // save user mode sp and lr + SUB r13, r13, #8 + + # call traps (trapframe *fp) + MOV r0, r13 // save trapframe as the first parameter + BL fiq_handler + B . +