vectors.s

来自「eCos操作系统源码」· S 代码 · 共 933 行 · 第 1/3 页

S
933
字号
        # set up stack        lwi     sp,__interrupt_stack        mtspr   SPRG0,sp        # save in sprg0 for later use        # Set up exception handlers and VSR table, taking care not to        # step on any ROM monitor''s toes.        hal_mon_init        #if defined(CYG_HAL_STARTUP_ROM)        # Copy data from ROM to ram        lwi     r3,__rom_data_start     # r3 = rom start        lwi     r4,__ram_data_start     # r4 = ram start        lwi     r5,__ram_data_end       # r5 = ram end        cmplw   r4,r5                   # skip if no data        beq     2f        1:        lwz     r0,0(r3)                # get word from ROM        stw     r0,0(r4)                # store in RAM        addi    r3,r3,4                 # increment by 1 word        addi    r4,r4,4                 # increment by 1 word        cmplw   r4,r5                   # compare        blt     1b                      # loop if not yet done2:#endif        # clear BSS        lwi     r3,__bss_start  # r3 = start        lwi     r4,__bss_end    # r4 = end        li      r0,0            # r0 = 0        cmplw   r3,r4           # skip if no bss        beq     2f        1:      stw     r0,0(r3)        # store zero        addi    r3,r3,4         # increment by 1 word        cmplw   r3,r4           # compare        blt     1b              # loop if not yet done2:        # clear SBSS        lwi     r3,__sbss_start # r3 = start        lwi     r4,__sbss_end   # r4 = end        cmplw   r3,r4           # skip if no sbss        beq     2f        1:      stw     r0,0(r3)        # store zero        addi    r3,r3,4         # increment by 1 word        cmplw   r3,r4           # compare        blt     1b              # loop if not yet done2:        # It is now safe to call C functions which may rely on initialized        # data.                # Set up stack for calls to C code.        subi    sp,sp,12                        # make space on stack        li      r0,0        stw     r0,0(sp)                        # clear back chain        stw     r0,8(sp)                        # zero return pc        stwu    sp,-CYGARC_PPC_STACK_FRAME_SIZE(sp) # create new stack frame        # Variant HALs may need to do something special before we continue        bl      hal_variant_init        # Platform initialization        bl      hal_platform_init                # MMU and cache are controlled by the same option since caching        # on the PPC [typically] does not make sense without the MMU to mark         # regions which should not be cached.#ifdef CYGHWR_HAL_POWERPC_ENABLE_MMU        # Initialize MMU.        bl      hal_MMU_init        # Enable MMU (if desired) so we can safely enable caches.        lwi     r3,CYG_MSR              # interrupts enabled later        sync        mtmsr   r3        sync	        # Enable caches        bl      hal_enable_caches#endif // CYGHWR_HAL_POWERPC_ENABLE_MMU        # set up platform specific interrupt environment        bl      hal_IRQ_init        # call c++ constructors        bl      cyg_hal_invoke_constructors#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS        bl      initialize_stub#endif#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \    || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)        .extern hal_ctrlc_isr_init        bl     hal_ctrlc_isr_init#endif                bl      cyg_start                       # call cyg_start9:              b       9b              # if we return, loop#---------------------------------------------------------------------------# This code handles the common part of all exception handlers.# It saves the machine state onto the stack  and then calls# a "C" routine to do the rest of the work. This work may result# in thread switches, and changes to the saved state. When we return# here the saved state is restored and execution is continued.                .text        .globl cyg_hal_default_exception_vsrcyg_hal_default_exception_vsr:                # We come here with all register containing their        # pre-exception values except:        # R3    = ls 16 bits of vector address        # R4    = saved CR        # R5    = saved LR        # LR    = VSR address        # SPRG1 = old R3        # SPRG2 = old R4        # SPRG3 = old R5        # SRR0  = old PC        # SRR1  = old MSR and the exception cause (the POW state is lost!)        subi    sp,sp,CYGARC_PPC_EXCEPTION_DECREMENT                                        # leave space for registers and                                        # a safety margin#ifdef CYGPKG_HAL_POWERPC_PPC40x// The caches on this processor are always enabled when the MMU is on// (and disabled when off).  Thus we need to be careful about cache// polution and staleness when changing the MMU state.// At this point, the MMU is off due to the exception.  We need to// flush the part of the cache which may be touched before the MMU// is reenabled so that memory will be consistent when that happens.// Of course, this is complicated by the fact that there are no "free"// registers at this point in the code.        dcbf    0,sp                    // Flushes first line        stw     r3,0(sp)                // This is now safe        li      r3,CYGARC_PPCREG_VECTOR // Flush lines which will be changed        dcbf    r3,sp                           li      r3,CYGARC_PPCREG_CR        dcbf    r3,sp                           li      r3,CYGARC_PPCREG_LR        dcbf    r3,sp                      lwz     r3,0(sp)                // Restore register#endif                # First, save away some registers        stw     r3,CYGARC_PPCREG_VECTOR(sp)    # stash vector        stw     r4,CYGARC_PPCREG_CR(sp)        # stash CR        stw     r5,CYGARC_PPCREG_LR(sp)        # stash LR#ifdef CYGDBG_HAL_POWERPC_FRAME_WALLS        # Mark this fram as an Exception frame        lwi     r3,0xDDDDDDE0        stw     r3,CYGARC_PPCREG_WALL_HEAD(sp)        lwi     r3,0xDDDDDDE1        stw     r3,CYGARC_PPCREG_WALL_TAIL(sp)#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,        # call into C to do something with it.        mr      r3,sp                           # R3 = register dump                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        lwi     r5,restore_state                # get return link        mtlr    r5                              # to link register        .extern cyg_hal_exception_handler        b       cyg_hal_exception_handler       # call C code, r3 = registers        # When the call returns it will go to restore_state below.##--------------------------------------------------------------------------## The following macros are defined depending on whether the Interrupt## system is using isr tables or chaining, and depending on the interrupt## controller in the system.#ifndef CYGPKG_HAL_POWERPC_INTC_DEFINED## This is the simple version. No interrupt controller, CYGARC_PPCREG_VECTOR ## is updated with the decoded interrupt vector. Isr tables/chaining## use same interrupt decoder.## Bit 21 biffers between decrementer (0) and external (1).        # decode the interrupt	.macro  hal_intc_decode dreg,state        lwz     \dreg,CYGARC_PPCREG_VECTOR(\state) # retrieve vector number,        rlwinm  \dreg,\dreg,22,31,31               # isolate bit 21 and update        stw     \dreg,CYGARC_PPCREG_VECTOR(\state) # vector in state frame.        slwi    \dreg,\dreg,2                      # convert to word offset.        .endm                              #endif // CYGPKG_HAL_POWERPC_INTC_DEFINED#---------------------------------------------------------------------------# Common interrupt handling code.        .globl cyg_hal_default_interrupt_vsrcyg_hal_default_interrupt_vsr:        # We come here with all register containing their        # pre-exception values except:        # R3    = ls 16 bits of vector address        # R4    = saved CR        # R5    = saved LR        # LR    = VSR address        # SPRG1 = old R3        # SPRG2 = old R4        # SPRG3 = old R5        # SRR0  = old PC        # SRR1  = old MSR        subi    sp,sp,CYGARC_PPC_EXCEPTION_DECREMENT                                        # leave space for registers and                                        # a safety margin#ifdef CYGPKG_HAL_POWERPC_PPC40x// The caches on this processor are always enabled when the MMU is on// (and disabled when off).  Thus we need to be careful about cache// polution and staleness when changing the MMU state.// At this point, the MMU is off due to the exception.  We need to// flush the part of the cache which may be touched before the MMU// is reenabled so that memory will be consistent when that happens.// Of course, this is complicated by the fact that there are no "free"// registers at this point in the code.        dcbf    0,sp                    // Flushes first line        stw     r3,0(sp)                // This is now safe        li      r3,CYGARC_PPCREG_VECTOR // Flush lines which will be changed        dcbf    r3,sp                           li      r3,CYGARC_PPCREG_CR        dcbf    r3,sp                           li      r3,CYGARC_PPCREG_LR        dcbf    r3,sp                      lwz     r3,0(sp)                // Restore register#endif                              stw     r3,CYGARC_PPCREG_VECTOR(sp)    # stash vector        stw     r4,CYGARC_PPCREG_CR(sp)        # stash CR        stw     r5,CYGARC_PPCREG_LR(sp)        # stash LR#ifdef CYGDBG_HAL_POWERPC_FRAME_WALLS        # Mark this fram as an 1nterrupt frame        lwi     r3,0xDDDDDD10        stw     r3,CYGARC_PPCREG_WALL_HEAD(sp)        lwi     r3,0xDDDDDD11        stw     r3,CYGARC_PPCREG_WALL_TAIL(sp)#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?