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

📄 vectors.s

📁 开放源码实时操作系统源码.
💻 S
📖 第 1 页 / 共 3 页
字号:
        # 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
        sub     r5,r5,r4                # compute number of words to copy
        srwi    r5,r5,2
        mtctr   r5
        subi    r3,r3,4
        subi    r4,r4,4
1:      lwzu    r0,4(r3)                # get word from ROM
        stwu    r0,4(r4)                # store in RAM
        bdnz    1b
2:
#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
        sub     r4,r4,r3        # compute number of words to clear
        srwi    r4,r4,2
        mtctr   r4
        subi    r3,r3,4
        
1:      stwu    r0,4(r3)        # store zero & increment pointer
        bdnz    1b
2:

        # clear SBSS
        lwi     r3,__sbss_start # r3 = start
        lwi     r4,__sbss_end   # r4 = end
        cmplw   r3,r4           # skip if no sbss
        beq     2f
        sub     r4,r4,r3        # compute number of words to clear
        srwi    r4,r4,2
        mtctr   r4
        subi    r3,r3,4
        
1:      stwu    r0,4(r3)        # store zero & increment pointer
        bdnz    1b
2:

        # 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_start
9:      
        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_vsr
cyg_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_vsr
cyg_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)

⌨️ 快捷键说明

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