📄 vectors.s
字号:
#ifdef CYG_HAL_ROM_MONITOR # K1 contains original SP sw k1,(mipsreg_regs+29*4)(sp) # store in reg dump #else # synthesize original SP value move a2,sp # a2 = sp addi a2,a2,mips_exception_decrement # a2 = original sp sw a2,(mipsreg_regs+29*4)(sp) # store in reg dump #endif # save remaining machine state registers mfc0 t0,cause mfc0 t1,sr# mfc0 t2,cache mfc0 t3,badvr mfc0 t4,config mfc0 t5,prid mfc0 t6,epc#ifndef CYG_HAL_MIPS_SIM mfc0 t2,cache#endif sw t0,mipsreg_cause(sp) sw t1,mipsreg_sr(sp) sw t2,mipsreg_cache(sp) sw t3,mipsreg_badvr(sp) sw t4,mipsreg_config(sp) sw t5,mipsreg_prid(sp) sw t6,mipsreg_pc(sp) # The machine state is now all saved on the stack. # Load Global Pointer register. la gp,_gp move s0,sp # save pointer to saved state addi sp,sp,-mips_stack_frame_size # make a null frame # Need to set up back pointers etc. ??? la ra,restore_state # load return address .extern exception_handler j exception_handler # call C code move a0,s0 # arg0 = register dump (delay slot) # When the exception handler returns, it will # go back to restore_state, below. .end __default_exception_vsr ##------------------------------------------------------------------------------## Default interrupt VSR.## Saves machine state and calls appropriate ISR. When done, calls## interrupt_end() to finish up and possibly reschedule. .globl __default_interrupt_vsr .ent __default_interrupt_vsr__default_interrupt_vsr: # We enter here with all of the CPU state still # in its registers except: # K0 = vector index # K1 = address of this function addi sp,sp,-mips_exception_decrement # space for registers + safety margin sw k0,mipsreg_vector(sp) # store vector # store GPRs sw $0,(mipsreg_regs+0*4)(sp) sw $1,(mipsreg_regs+1*4)(sp) sw $2,(mipsreg_regs+2*4)(sp) sw $3,(mipsreg_regs+3*4)(sp) sw $4,(mipsreg_regs+4*4)(sp) sw $5,(mipsreg_regs+5*4)(sp) sw $6,(mipsreg_regs+6*4)(sp) sw $7,(mipsreg_regs+7*4)(sp) sw $8,(mipsreg_regs+8*4)(sp) sw $9,(mipsreg_regs+9*4)(sp) sw $10,(mipsreg_regs+10*4)(sp) sw $11,(mipsreg_regs+11*4)(sp) sw $12,(mipsreg_regs+12*4)(sp) sw $13,(mipsreg_regs+13*4)(sp) sw $14,(mipsreg_regs+14*4)(sp) sw $15,(mipsreg_regs+15*4)(sp) sw $16,(mipsreg_regs+16*4)(sp) sw $17,(mipsreg_regs+17*4)(sp) sw $18,(mipsreg_regs+18*4)(sp) sw $19,(mipsreg_regs+19*4)(sp) sw $20,(mipsreg_regs+20*4)(sp) sw $21,(mipsreg_regs+21*4)(sp) sw $22,(mipsreg_regs+22*4)(sp) sw $23,(mipsreg_regs+23*4)(sp) sw $24,(mipsreg_regs+24*4)(sp) sw $25,(mipsreg_regs+25*4)(sp)# sw $26,(mipsreg_regs+26*4)(sp) # == K0# sw $27,(mipsreg_regs+27*4)(sp) # == K1 sw $28,(mipsreg_regs+28*4)(sp) # == GP# sw $29,(mipsreg_regs+29*4)(sp) # == SP sw $30,(mipsreg_regs+30*4)(sp) # == FP sw $31,(mipsreg_regs+31*4)(sp) # == RA mfhi a0 mflo a1 sw a0,mipsreg_hi(sp) sw a1,mipsreg_lo(sp) # synthesize original SP value move a2,sp # a2 = sp addi a2,a2,mips_exception_decrement # a2 = original sp sw a2,(mipsreg_regs+29*4)(sp) # store in reg dump mfc0 t1,sr mfc0 t3,epc #ifndef CYG_HAL_MIPS_SIM mfc0 t2,cache#endif sw t1,mipsreg_sr(sp) sw t2,mipsreg_cache(sp) sw t3,mipsreg_pc(sp) # The machine state is now all saved on the stack. # Load Global Pointer register. la gp,_gp #ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT .extern cyg_scheduler_sched_lock la v0,cyg_scheduler_sched_lock lw a0,0(v0) addi a0,a0,1 sw a0,0(v0)#endif move s0,sp # save pointer to saved state #ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK la a0,__interrupt_stack # a0 = stack top la a1,__interrupt_stack_base # a1 = stack base sub a3,sp,a1 # a3 = sp - base bltz a3,1f # if < 0 - not on istack nop # delay slot sub t0,a0,sp # t0 = top - sp bgtz t0,8f # if > 0 - already on istack nop # delay slot1: move sp,a0 # switch to istack8: addi sp,sp,-4 # space for old SP sw s0,0(sp) # save old SP on stack #endif subu sp,sp,mips_stack_frame_size # make a null frame # Need to set up back pointers etc. ??? # Decode external interrupt via interrupt controller mfc0 a1,cause # get cause register nop srl a1,a1,10 # shift IP bits to ls bits andi a1,a1,0x7F # isolate IP bits la t0,interrupt_translation_table # address of translation table add t0,t0,a1 # offset of index byte lb s2,0(t0) # load it#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN move s1,zero # Just vector zero is supported#else move s1,s2 # Vector == interrupt number#endif # Here s1 is the number of the vector to be called and s2 is # the number of the interrupt being serviced. #if defined(CYGPKG_KERNEL_INSTRUMENT) && defined(CYGDBG_KERNEL_INSTRUMENT_INTR) # Call cyg_instrument to record that this interrupt is being raised. li a0,0x0301 # a0 = type = INTR,RAISE move a1,s1 # a1 = vector number jal cyg_instrument # call instrument function xor a2,a2,a2 # arg2 = 0 (delay slot)#endif sll s1,s1,2 # s1 = byte offset of vector la t2,hal_interrupt_handlers # handler table add t2,t2,s1 # address of ISR ptr lw t2,0(t2) # ISR pointer la a1,hal_interrupt_data # data table add a1,a1,s1 # address of data ptr lw a1,0(a1) # Data pointer move a0,s2 # pass interrupt number move a2,s0 # arg3 = saved register dump jalr t2 # call ISR via t2 nop # (delay slot)#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK # If we are returning from the last nested interrupt, move back # to the thread stack. interrupt_end() must be called on the # thread stack since it potentially causes a context switch. # Since we have arranged for the top of stack location to # contain the sp we need to go back to here, just pop it off # and put it in SP. lw sp,mips_stack_frame_size(sp) # sp = *sp subu sp,sp,mips_stack_frame_size # make a null frame #endif #ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT # We only need to call _interrupt_end() when there is a kernel # present to do any tidying up. # On return v0 bit 1 will indicate whether a DSR is # to be posted. Pass this together with a pointer to # the interrupt object we have just used to the # interrupt tidy up routine. # Note that s0, s1 and s2 are defined to be preserved across # calls by the calling convention, so they still contain # the register dump, the vector offset and the interrupt number # respectively. move a0,v0 # put ISR result in arg0 la a1,hal_interrupt_objects # interrupt object table add a1,a1,s1 # address of object ptr lw a1,0(a1) # a1 = object ptr move a2,s0 # arg3 = saved register dump # interrupt_end() must be called with interrupts enabled. rfe # restore previous status bits # this may enable interrupts .extern interrupt_end jal interrupt_end # call into C to finish off nop # (delay slot)#endif restore_state: # All done, restore CPU state and continue addi sp,sp,mips_stack_frame_size # retrieve CPU state ptr # Load status register and cache control register. # This will put the interrupt, mode and cache control # bits back to their post-exception values, so we will # need to do another RFE before we finish. lw t1,mipsreg_sr(sp) lw t2,mipsreg_cache(sp) mtc0 t1,sr#ifndef CYG_HAL_MIPS_SIM mtc0 t2,cache#endif lw a0,mipsreg_hi(sp) lw a1,mipsreg_lo(sp) mthi a0 mtlo a1 # load GPRs# lw $0,(mipsreg_regs+0*4)(sp) lw $1,(mipsreg_regs+1*4)(sp) lw $2,(mipsreg_regs+2*4)(sp) lw $3,(mipsreg_regs+3*4)(sp) lw $4,(mipsreg_regs+4*4)(sp) lw $5,(mipsreg_regs+5*4)(sp) lw $6,(mipsreg_regs+6*4)(sp) lw $7,(mipsreg_regs+7*4)(sp) lw $8,(mipsreg_regs+8*4)(sp) lw $9,(mipsreg_regs+9*4)(sp) lw $10,(mipsreg_regs+10*4)(sp) lw $11,(mipsreg_regs+11*4)(sp) lw $12,(mipsreg_regs+12*4)(sp) lw $13,(mipsreg_regs+13*4)(sp) lw $14,(mipsreg_regs+14*4)(sp) lw $15,(mipsreg_regs+15*4)(sp) lw $16,(mipsreg_regs+16*4)(sp) lw $17,(mipsreg_regs+17*4)(sp) lw $18,(mipsreg_regs+18*4)(sp) lw $19,(mipsreg_regs+19*4)(sp) lw $20,(mipsreg_regs+20*4)(sp) lw $21,(mipsreg_regs+21*4)(sp) lw $22,(mipsreg_regs+22*4)(sp) lw $23,(mipsreg_regs+23*4)(sp) lw $24,(mipsreg_regs+24*4)(sp) lw $25,(mipsreg_regs+25*4)(sp)# lw $26,(mipsreg_regs+26*4)(sp) # == K0# lw $27,(mipsreg_regs+27*4)(sp) # == K1 lw $28,(mipsreg_regs+28*4)(sp) # == GP# lw $29,(mipsreg_regs+29*4)(sp) # == SP lw $30,(mipsreg_regs+30*4)(sp) # == FP lw $31,(mipsreg_regs+31*4)(sp) # == RA lw k0,mipsreg_pc(sp) # K0 = return PC lw sp,(mipsreg_regs+29*4)(sp) # load SP sync jr k0 # jump back to interrupted code rfe # restore state (delay slot) .end __default_interrupt_vsr# This table translates from the 6 bit value supplied in the IP bits# of the cause register into a 0..16 offset into the ISR tables.interrupt_translation_table: .byte 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 .byte 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 .byte 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16 .byte 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16 ##-----------------------------------------------------------------------------## Interrupt Stack.## Used during intialization and for executing ISRs. .bss .balign 16__interrupt_stack_base: .rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE .byte 0 .endr .balign 16__interrupt_stack: .long 0,0,0,0,0,0,0,0 ##-----------------------------------------------------------------------------## VSR table.## The main interrupt code indirects through here to find the VSR## to execute for each architecture defined interrupt.## This is only used for simulated targets, on real targets a fixed location VSR## table is now allocated at 0x80000100.#if defined(CYG_HAL_MIPS_SIM) || \ ( defined(CYG_HAL_MIPS_TX3904) && \ defined(CYG_HAL_STARTUP_RAM) && \ !defined(CYG_HAL_USE_ROM_MONITOR) \ ) .section ".vsr_table","a" .globl hal_vsr_tablehal_vsr_table: .long __default_interrupt_vsr .rept 63 .long __default_exception_vsr .endr#endif #------------------------------------------------------------------------------# Interrupt vector tables.# These tables contain the isr, data and object pointers used to deliver# interrupts to user code.# hal_interrupt_level contains the interrupt level set by # HAL_INTERRUPT_CONFIGURE(). .extern hal_default_isr .data .globl hal_interrupt_handlershal_interrupt_handlers: .long hal_default_isr .long hal_default_isr .long hal_default_isr .long hal_default_isr .long hal_default_isr .long hal_default_isr .long hal_default_isr .long hal_default_isr .long hal_default_isr .long hal_default_isr .long hal_default_isr .long hal_default_isr .long hal_default_isr .long hal_default_isr .long hal_default_isr .long hal_default_isr .long hal_default_isr .globl hal_interrupt_datahal_interrupt_data: .rept 17 .long 0 .endr .globl hal_interrupt_objectshal_interrupt_objects: .rept 17 .long 0 .endr .globl hal_interrupt_levelhal_interrupt_level: .rept 17 .byte 7 .endr##-----------------------------------------------------------------------------## end of vectors.S
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -