📄 vectors.s
字号:
.extern __bss_start .extern __bss_end 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 .extern __sbss_start .extern __sbss_end 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,-ppc_stack_frame_size(sp) # create new stack frame # Initialize MMU. .extern hal_MMU_init bl hal_MMU_init # Enable MMU it so we can safely enable caches. lwi r3,CYG_MSR sync mtmsr r3 sync # Enable caches .extern hal_enable_caches bl hal_enable_caches # call c++ constructors .extern cyg_hal_invoke_constructors bl cyg_hal_invoke_constructors#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS .extern initialize_stub bl initialize_stub#endif .extern cyg_start 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 .extern __default_exception_vsr__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 r1,r1,ppc_exception_decrement # leave space for registers and # a safety margin # First, save away some registers stw r3,ppcreg_vector(r1) # stash vector stw r4,ppcreg_cr(r1) # stash CR stw r5,ppcreg_lr(r1) # stash LR # Enable MMU. lwi r3,CYG_MSR sync mtmsr r3 sync mfspr r3,SPRG1 # save original R3 stw r3,ppcreg_regs+3*4(r1) mfspr r4,SPRG2 # save original R4 stw r4,ppcreg_regs+4*4(r1) mfspr r5,SPRG3 # save original R5 stw r5,ppcreg_regs+5*4(r1) stw r0,ppcreg_regs(r1) # save R0 stw r2,ppcreg_regs+2*4(r1) # save R2 mr r3,r1 # recreate original R1 addi r3,r3,ppc_exception_decrement stw r3,ppcreg_regs+1*4(r1) # and save it in state # Save registers r6..r12/r31 .set _reg,6 .rept MAX_SAVE_REG+1-6 stw _reg,(ppcreg_regs+_reg*4)(r1) .set _reg,_reg+1 .endr # Save registers used in vsr (r14+r15) stw r14,(ppcreg_regs+14*4)(r1) stw r15,(ppcreg_regs+15*4)(r1) # get remaining CPU registers mfxer r3 mfctr r5 mfdar r6 mfdsisr r7 mfpvr r8 mfsrr0 r9 mfsrr1 r10 # and store them stw r3,ppcreg_xer(r1) stw r5,ppcreg_ctr(r1) stw r6,ppcreg_dar(r1) stw r7,ppcreg_dsisr(r1) stw r8,ppcreg_pvr(r1) stw r9,ppcreg_pc(r1) stw r10,ppcreg_msr(r1) # 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,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,-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.## Note: CYG_ISR_TABLE_SIZE must match CYG_ISR_COUNT defined in hal_intr.h.#ifdef CYG_HAL_POWERPC_MPC8xx ## First level decoding of MPC8xx SIU interrupt controller.#define CYG_ISR_TABLE_SIZE 59 # decode the interrupt .macro decode_interrupt dreg,state lwz \dreg,ppcreg_vector(\state) # retrieve vector number, rlwinm. \dreg,\dreg,22,31,31 # isolate bit 21 beq 0f # done if decrementer (vec 0) lwi \dreg,CYGARC_REG_IMM_SIVEC # if external, get SIU lbz \dreg,0(\dreg) # vector. srwi \dreg,\dreg,2 addi \dreg,\dreg,1 # Skip decrementer vector0: stw \dreg,ppcreg_vector(\state) # update vector in state frame. slwi \dreg,\dreg,2 # convert to byte offset. .endm #else## This is the simple version. No interrupt controller, 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).#define CYG_ISR_TABLE_SIZE 2 # decode the interrupt .macro decode_interrupt dreg,state lwz \dreg,ppcreg_vector(\state) # retrieve vector number, rlwinm \dreg,\dreg,22,31,31 # isolate bit 21 and update stw \dreg,ppcreg_vector(\state) # vector in state frame. slwi \dreg,\dreg,2 # convert to word offset. .endm #endif#---------------------------------------------------------------------------# Common interrupt handling code. .extern __default_interrupt_vsr__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 r1,r1,ppc_exception_decrement # leave space for registers and # a safety margin stw r3,ppcreg_vector(r1) # stash vector stw r4,ppcreg_cr(r1) # stash CR stw r5,ppcreg_lr(r1) # stash LR # Enable MMU. lwi r3,CYG_MSR sync mtmsr r3 sync mfspr r3,SPRG1 # save original R3 stw r3,ppcreg_regs+3*4(r1) mfspr r4,SPRG2 # save original R4 stw r4,ppcreg_regs+4*4(r1) mfspr r5,SPRG3 # save original R5 stw r5,ppcreg_regs+5*4(r1) stw r0,ppcreg_regs(r1) # save R0 stw r2,ppcreg_regs+2*4(r1) # save R2 mr r3,r1 # recreate original R1 addi r3,r3,ppc_exception_decrement stw r3,ppcreg_regs+1*4(r1) # and save it in state # Save registers r6..r12/r31 .set _reg,6 .rept MAX_SAVE_REG+1-6 stw _reg,(ppcreg_regs+_reg*4)(r1) .set _reg,_reg+1 .endr # Save registers used in vsr (r14+r15) stw r14,(ppcreg_regs+14*4)(r1) stw r15,(ppcreg_regs+15*4)(r1) # get remaining CPU registers mfxer r3 mfctr r5 mfsrr0 r6 mfsrr1 r7 # and store them stw r3,ppcreg_xer(r1) stw r5,ppcreg_ctr(r1) stw r6,ppcreg_pc(r1) stw r7,ppcreg_msr(r1) # 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -