📄 vectors.s
字号:
1: mr sp,r3 # switch to istack2: stwu r14,-4(sp) # save old SP on stack#endif 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 #if defined(CYGPKG_KERNEL_INSTRUMENT) && defined(CYGDBG_KERNEL_INSTRUMENT_INTR) lwi r3,0x0301 # r3 = type = INTR,RAISE lwz r4,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 decode_interrupt r15,r14 # get table index#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT .extern cyg_hal_gdb_isr lwz r3,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 CYG_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,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,ppc_stack_frame_size*2(sp) # sp = *sp 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#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. # Note: The instructions restoring the msr mask out the POW bit. # When eCos gets power management aware, this bit will have to be # set to the correct state rather than just cleared. lwi r4,hal_interrupt_objects # get interrupt object table lwzx r4,r4,r15 # load object pointer lwz r6,ppcreg_msr(r14) # restore msr, including lis r5,0xfffe # interrupt enable. andc r6,r6,r5 # mask out reserved bits sync # (and POW!) mtmsr r6 sync 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,ppc_stack_frame_size*2 # retrieve CPU state pointer # get sprs we want to restore lwz r3,ppcreg_cr(sp) lwz r4,ppcreg_pc(sp) lwz r5,ppcreg_msr(sp) lwz r6,ppcreg_xer(sp) lwz r7,ppcreg_lr(sp) lwz r8,ppcreg_ctr(sp) # stuff some of them into the CPU mtxer r6 mtlr r7 mtctr r8 # restore R0 and R2 lwz r0,ppcreg_regs(sp) lwz r2,ppcreg_regs+2*4(sp) # Restore registers used in vsr (r14+r15) lwz r14,(ppcreg_regs+14*4)(r1) lwz r15,(ppcreg_regs+15*4)(r1) # restore registers r6..r12/r31 .set _reg,6 .rept MAX_SAVE_REG+1-6 lwz _reg,(ppcreg_regs+_reg*4)(r1) .set _reg,_reg+1 .endr # Here all the registers are loaded except # r1 = ppcregs # 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. mtcr r3 # set ccr lwi r3,CYG_MSR # do rest with ints disabled sync mtmsr r3 sync mtsrr0 r4 # load old pc mtsrr1 r5 # load old msr lwz r3,ppcreg_regs+3*4(r1) # load r3 value lwz r4,ppcreg_regs+4*4(r1) # load r4 value lwz r5,ppcreg_regs+5*4(r1) # load r5 value lwz r1,ppcreg_regs+1*4(r1) # restore r1 sync # settle things down isync rfi # and return#---------------------------------------------------------------------------# Code for putting the CPU in a post-reset state; disabling MMU and caches._init_CPU:#ifdef CYG_HAL_POWERPC_MPC8xx lwi r3,CYGARC_REG_DC_CMD_CD sync mtspr CYGARC_REG_DC_CST,r3 lwi r3,CYGARC_REG_IC_CMD_CD isync mtspr CYGARC_REG_IC_CST,r3 isync#endif # Set up MSR (disable MMU for now) lwi r3,(CYG_MSR & ~(MSR_IR | MSR_DR)) sync mtmsr r3 sync blr#---------------------------------------------------------------------------# This table contains a VSR pointer for each defined exception.# All of these except 5 and 9 point to the __default_exception_vsr# above, 5 and 9 point to the __default_interrupt_vsr. Entries in# this table may be changed using Cyg_Interrupt::set_vsr(). .data .globl hal_vsr_tablehal_vsr_table: # Architecture defined vectors .long __default_exception_vsr # reserved .long __default_exception_vsr # system reset .long __default_exception_vsr # machine check .long __default_exception_vsr # data storage .long __default_exception_vsr # instruction storage .long __default_interrupt_vsr # external interrupt .long __default_exception_vsr # alignment .long __default_exception_vsr # program .long __default_exception_vsr # floating point unavailable .long __default_interrupt_vsr # decrementer .long __default_exception_vsr # reserved 0x0a00 .long __default_exception_vsr # reserved 0x0b00 .long __default_exception_vsr # system call .long __default_exception_vsr # trace .long __default_exception_vsr # floating point assist .long __default_exception_vsr # reserved 0x0f00#ifdef CYG_HAL_POWERPC_MPC8xx # Implementation defined vectors .long __default_exception_vsr # software emulation .long __default_exception_vsr # instruction TLB miss .long __default_exception_vsr # data TLB miss .long __default_exception_vsr # instruction TLB error .long __default_exception_vsr # data TLB error .long __default_exception_vsr # reserved 0x1500 .long __default_exception_vsr # reserved 0x1600 .long __default_exception_vsr # reserved 0x1700 .long __default_exception_vsr # reserved 0x1800 .long __default_exception_vsr # reserved 0x1900 .long __default_exception_vsr # reserved 0x1a00 .long __default_exception_vsr # reserved 0x1b00 .long __default_exception_vsr # data breakpoint .long __default_exception_vsr # instruction breakpoint .long __default_exception_vsr # peripheral breakpoint .long __default_exception_vsr # non maskable development port#endif#---------------------------------------------------------------------------# Interrupt vector tables.# These tables contain the isr, data and object pointers used to deliver# interrupts to user code.#if (CYG_ISR_TABLE_SIZE > 2) .data#else .section ".sdata","aw"#endif .extern hal_default_isr .globl hal_interrupt_handlershal_interrupt_handlers: .rept CYG_ISR_TABLE_SIZE .long hal_default_isr .endr .globl hal_interrupt_datahal_interrupt_data: .rept CYG_ISR_TABLE_SIZE .long 0 .endr .globl hal_interrupt_objectshal_interrupt_objects: .rept CYG_ISR_TABLE_SIZE .long 0 .endr#---------------------------------------------------------------------------## Temporary interrupt stack .section ".bss" .balign 16__interrupt_stack_base: .rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE .byte 0 .endr .balign 16__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 + -