📄 vectors.s
字号:
# Save registers used in vsr (r14+r15) stw r14,CYGARC_PPCREG_REGS+14*4(sp) stw r15,CYGARC_PPCREG_REGS+15*4(sp) # get remaining family CPU registers mfxer r3 mfctr r4 mfsrr0 r5 mfsrr1 r6 # and store them stw r3,CYGARC_PPCREG_XER(sp) stw r4,CYGARC_PPCREG_CTR(sp) stw r5,CYGARC_PPCREG_PC(sp) stw r6,CYGARC_PPCREG_MSR(sp) # Save variant registers hal_variant_save sp # Save FPU registers hal_fpu_save sp # The entire CPU state is now stashed on the stack, # increment the scheduler lock and call the ISR # for this vector.#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT .extern cyg_scheduler_sched_lock lwi r3,cyg_scheduler_sched_lock lwz r4,0(r3) addi r4,r4,1 stw r4,0(r3)#endif mr r14,sp # r14 = register dump #ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK lwi r3,__interrupt_stack # stack top lwi r4,__interrupt_stack_base # stack base sub. r5,sp,r4 # sp - base blt 1f # if < 0 - not on istack sub. r5,r3,sp # top - sp bgt 2f # if > 0 - already on istack1: mr sp,r3 # switch to istack2: stwu r14,-4(sp) # save old SP on stack#endif subi sp,sp,CYGARC_PPC_STACK_FRAME_SIZE # make a null frame li r0,0 # R0 = 0 stw r0,0(sp) # backchain = 0 stw r0,8(sp) # return pc = 0 stwu sp,-CYGARC_PPC_STACK_FRAME_SIZE(sp) # create new stack frame # where C code can save LR #if defined(CYGPKG_KERNEL_INSTRUMENT) && defined(CYGDBG_KERNEL_INSTRUMENT_INTR) lwi r3,0x0301 # r3 = type = INTR,RAISE lwz r4,CYGARC_PPCREG_VECTOR(r14) # arg1 = vector address srwi r4,r4,8 # arg1 = vector number xor r5,r5,r5 # arg2 = 0 bl cyg_instrument # call instrument function #endif hal_intc_decode r15,r14 # get table index#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT .extern cyg_hal_gdb_isr lwz r3,CYGARC_PPCREG_PC(r14) # for serial receive irq. bl cyg_hal_gdb_isr # (arg1 is PC) cmpwi r3,0x0000 # Call ISR proper? beq 2f # (r3 is 0 when skipping # to avoid DSR call)1:#endif#ifdef CYGSEM_HAL_COMMON_INTERRUPTS_ALLOW_NESTING#ifdef CYGPKG_HAL_POWERPC_MPC8xx # The CPM controller allows nested interrupts. However, # it sits on the back of the SIU controller which has no # HW support for this. In effect, SW masking of lower # priority IRQs in the SIU would be required for this to work.#endif#endif lwz r3,CYGARC_PPCREG_VECTOR(r14) # retrieve decoded vector # lwi r6,hal_interrupt_handlers # get interrupt handler table lwzx r6,r6,r15 # load routine pointer lwi r4,hal_interrupt_data # get interrupt data table lwzx r4,r4,r15 # load data pointer # R4 = data argument mtctr r6 # put isr address in ctr bctrl # branch to ctr reg and link#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT # If interrupt was caused by GDB, the ISR call above # is skipped by jumping here.2:#endif #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. lwz sp,CYGARC_PPC_STACK_FRAME_SIZE*2(sp) # sp = *sp subi sp,sp,CYGARC_PPC_STACK_FRAME_SIZE # make a null frame li r0,0 # R0 = 0 stw r0,0(sp) # backchain = 0 stw r0,8(sp) # return pc = 0 stwu sp,-CYGARC_PPC_STACK_FRAME_SIZE(sp) # create new stack frame # where C code can save LR#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 r3 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 r14 and r15 are defined to be preserved across # calls by the calling convention, so they still contain # the register dump and the vector number respectively. lwi r4,hal_interrupt_objects # get interrupt object table lwzx r4,r4,r15 # load object pointer mr r5,r14 # arg3 = saved register dump .extern interrupt_end bl interrupt_end # call into C to finish off #endifrestore_state: # All done, restore CPU state and continue addi sp,sp,CYGARC_PPC_STACK_FRAME_SIZE*2 # retrieve CPU state pointer # get sprs we want to restore # stuff some of them into the CPU lwz r3,CYGARC_PPCREG_XER(sp) lwz r4,CYGARC_PPCREG_LR(sp) lwz r5,CYGARC_PPCREG_CTR(sp) mtxer r3 mtlr r4 mtctr r5 # Restore registers used in vsr (r14+r15) lwz r14,CYGARC_PPCREG_REGS+14*4(r1) lwz r15,CYGARC_PPCREG_REGS+15*4(r1) # restore registers r6..r12/r31 .set _reg,6 .rept MAX_SAVE_REG+1-6 lwz _reg,(CYGARC_PPCREG_REGS+_reg*4)(sp) .set _reg,_reg+1 .endr hal_cpu_int_disable # restore R0 and R2 lwz r0,CYGARC_PPCREG_REGS+0*4(sp) lwz r2,CYGARC_PPCREG_REGS+2*4(sp) # Here all the registers are loaded except # sp = HAL_SavedRegisters # r3 = ccr # r4 = srr0 = pc # r5 = srr1 = msr # # We have to disable interrupts while srr0 and # srr1 are loaded, since another interrupt will # destroy them. lwz r3,CYGARC_PPCREG_CR(sp) lwz r4,CYGARC_PPCREG_PC(sp) lwz r5,CYGARC_PPCREG_MSR(sp) mtcr r3 # set ccr mtsrr0 r4 # load old pc mtsrr1 r5 # load old msr #ifdef CYGDBG_HAL_POWERPC_FRAME_WALLS # Mark this frame as (almost) dead. lwi r3,0xDDDDDDD0 stw r3,CYGARC_PPCREG_WALL_HEAD(sp) lwi r3,0xDDDDDDD1 stw r3,CYGARC_PPCREG_WALL_TAIL(sp)#endif lwz r3,CYGARC_PPCREG_REGS+3*4(sp) # load r3 value lwz r4,CYGARC_PPCREG_REGS+4*4(sp) # load r4 value lwz r5,CYGARC_PPCREG_REGS+5*4(sp) # load r5 value lwz sp,CYGARC_PPCREG_REGS+1*4(sp) # restore sp sync # settle things down isync rfi # and return##-----------------------------------------------------------------------------## Execute pending DSRs on the interrupt stack with interrupts enabled.## Note: this can only be called from code running on a thread stack#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK .extern cyg_interrupt_call_pending_DSRsFUNC_START(hal_interrupt_stack_call_pending_DSRs) # Change to interrupt stack, save state and set up stack for # calls to C code. mr r3,sp lwi r4,__interrupt_stack subi r4,r4,24 # make space on stack mr sp,r4 stw r3,12(sp) # save old sp mfmsr r3 stw r3,16(sp) # save old MSR mflr r3 stw r3,20(sp) # save old LR li r0,0 stw r0,0(sp) # clear back chain stw r0,8(sp) # zero return pc hal_cpu_int_enable # Call into kernel which will execute DSRs stwu sp,-CYGARC_PPC_STACK_FRAME_SIZE(sp) bl cyg_interrupt_call_pending_DSRs addi sp,sp,CYGARC_PPC_STACK_FRAME_SIZE lwz r3,20(sp) # restore LR mtlr r3 lwz r5,12(sp) # get SP from saved state lwz r3,16(sp) # restore interrupt setting hal_cpu_int_merge r3 mr sp,r5 # restore stack pointer blr # and return to caller#endif #---------------------------------------------------------------------------## Temporary interrupt stack .section ".bss" .balign 16 .global cyg_interrupt_stack_basecyg_interrupt_stack_base:__interrupt_stack_base: .rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE .byte 0 .endr .balign 16 .global cyg_interrupt_stackcyg_interrupt_stack:__interrupt_stack: .long 0,0,0,0,0,0,0,0 #---------------------------------------------------------------------------# end of vectors.S
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -