⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vectors.s

📁 开放源码实时操作系统源码.
💻 S
📖 第 1 页 / 共 3 页
字号:
#endif

        # Enable MMU & interrupt/FPU environment as configured
        lwi     r3,CYG_MSR
        sync
        mtmsr   r3
        sync

        mfspr   r3,SPRG1                # save original R3
        stw     r3,CYGARC_PPCREG_REGS+3*4(sp)
        mfspr   r4,SPRG2                # save original R4
        stw     r4,CYGARC_PPCREG_REGS+4*4(sp)
        mfspr   r5,SPRG3                # save original R5
        stw     r5,CYGARC_PPCREG_REGS+5*4(sp)

        stw     r0,CYGARC_PPCREG_REGS+0*4(sp)  # save R0
        stw     r2,CYGARC_PPCREG_REGS+2*4(sp)  # save R2

        mr      r3,sp                   # recreate original SP
        addi    r3,r3,CYGARC_PPC_EXCEPTION_DECREMENT
        stw     r3,CYGARC_PPCREG_REGS+1*4(sp)  # and save it in state
        
        # Save registers r6..r12/r31
        .set    _reg,6
        .rept   MAX_SAVE_REG+1-6
        stw     _reg,(CYGARC_PPCREG_REGS+_reg*4)(sp)
        .set    _reg,_reg+1
        .endr

        # 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 istack

1:      mr      sp,r3                           # switch to istack

2:      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

#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \
    || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)
	# If we are supporting Ctrl-C interrupts from GDB, we must squirrel
	# away a pointer to the save interrupt state here so that we can
	# plant a breakpoint at some later time.
	
	.extern	hal_saved_interrupt_state
	lwi	r3,hal_saved_interrupt_state
	stw	r14,0(r3)
	
#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
        mr      r5,r14                          # R5 = saved registers        
        
        mtctr   r6                              # put isr address in ctr

        bctrl                                   # branch to ctr reg and link

#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  

        # 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 

restore_state:  
        # All done, restore CPU state and continue

        # retrieve CPU state pointer
        addi    sp,sp,CYGARC_PPC_STACK_FRAME_SIZE*2

        # Restore FPU registers
        hal_fpu_load sp

        # Restore variant registers
        hal_variant_load sp

        # 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_DSRs

FUNC_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_base
cyg_interrupt_stack_base:
__interrupt_stack_base:
	.rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE
	.byte 0
	.endr
	.balign 16
	.global cyg_interrupt_stack
cyg_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 + -