📄 vectors.s
字号:
return_from_exception_or_interrupt: // save sp, but remove space for the parameter flush back area // (as per calling conventions) at the same time addi 16,sp,ep sld.w CYGARC_REG_PSW[ep],r7 sld.w CYGARC_REG_R1[ep],r1 sld.w CYGARC_REG_PC[ep],r6 sld.w CYGARC_REG_R2[ep],r2 // disable interrupts while restoring context ld.w CYGARC_REG_VECTOR[ep],r4 stsr PSW,r8 cmp CYGNUM_HAL_VECTOR_TRAP00,r4 bge 10f ori CYGARC_PSW_NP,r8,r8 // returning from NMI ori CYGARC_PSW_ID,r8,r8 // disable interrupt ldsr r8,PSW ldsr r7,FEPSW ldsr r6,FEPC br 30f10: cmp CYGNUM_HAL_ISR_MIN,r4 // exception or interrupt bge 20f ori CYGARC_PSW_EP,r8,r8 // returning from exception20: ori CYGARC_PSW_ID,r8,r8 // disable interrupt ldsr r8,PSW ldsr r7,EIPSW // Avoid pipeline bubbles ldsr r6,EIPC30: sld.w CYGARC_REG_R4[ep],r4 sld.w CYGARC_REG_R5[ep],r5 sld.w CYGARC_REG_R6[ep],r6 sld.w CYGARC_REG_R7[ep],r7 sld.w CYGARC_REG_R8[ep],r8 sld.w CYGARC_REG_R9[ep],r9 sld.w CYGARC_REG_R10[ep],r10 sld.w CYGARC_REG_R11[ep],r11 sld.w CYGARC_REG_R12[ep],r12 sld.w CYGARC_REG_R13[ep],r13 sld.w CYGARC_REG_R14[ep],r14 sld.w CYGARC_REG_R15[ep],r15 sld.w CYGARC_REG_R16[ep],r16 sld.w CYGARC_REG_R17[ep],r17 sld.w CYGARC_REG_R18[ep],r18 sld.w CYGARC_REG_R19[ep],r19 #ifndef CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT sld.w CYGARC_REG_R20[ep],r20 sld.w CYGARC_REG_R21[ep],r21 sld.w CYGARC_REG_R22[ep],r22 sld.w CYGARC_REG_R23[ep],r23 sld.w CYGARC_REG_R24[ep],r24 sld.w CYGARC_REG_R25[ep],r25 sld.w CYGARC_REG_R26[ep],r26 sld.w CYGARC_REG_R27[ep],r27 sld.w CYGARC_REG_R28[ep],r28 #endif sld.w CYGARC_REG_R29[ep],r29 // NB frame pointer sld.w CYGARC_REG_LP[ep],lp sld.w CYGARC_REG_SP[ep],sp sld.w CYGARC_REG_EP[ep],ep reti // Handle interrupt - these are typically vectored into user codedo_interrupt: mov sp,ep // save pointer to regs frame // leave space for the parameter flush back area (as per calling // conventions) addi -16,sp,sp#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK // Switch to interrupt stack lea irq_level,r6 // current number of nested interrupts ld.w 0[r6],r7 addi 1,r7,r8 st.w r8,0[r6] cmp 0,r7 // if was zero, switch stacks bne 10f mov sp,r1 // save old stack pointer lea __interrupt_stack-20,r2 mov r2,sp st.w r1,16[sp] 10:#endif // CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK // The entire CPU state is now stashed on the stack, // increment the scheduler lock and handle the interrupt#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT .extern _cyg_scheduler_sched_lock lea _cyg_scheduler_sched_lock,r7 ld.w 0[r7],r8 addi 1,r8,r8 st.w r8,0[r7]#endif#if defined(CYGPKG_KERNEL_INSTRUMENT) && \ defined(CYGDBG_KERNEL_INSTRUMENT_INTR) lea RAISE_INTR,r6 // arg0 = type = INTR,RAISE ld.w CYGARC_REG_VECTOR[ep],r7 // args = vector mov r0,r8 // arg2 = 0 jarl _cyg_instrument,r31#endif#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 lea _hal_saved_interrupt_state,r8 st.w ep,0[r8]#endif#ifdef CYGIMP_KERNEL_INTERRUPTS_CHAIN mov r0,r8 // vector # (overloaded by kernel)#else ld.w CYGARC_REG_VECTOR[ep],r6 // vector # addi -CYGNUM_HAL_ISR_MIN,r6,r8 shl 2,r8#endif lea _hal_interrupt_objects,r1 add r8,r1 ld.w 0[r1],r29 // save object handle lea _hal_interrupt_data,r1 add r8,r1 ld.w 0[r1],r7 // handler data lea _hal_interrupt_handlers,r1 add r8,r1 mov ep,r8 // pointer to saved registers ld.w 0[r1],r1 // handler routine#ifdef CYGIMP_KERNEL_INTERRUPTS_CHAIN ld.w CYGARC_REG_VECTOR[ep],r6 // vector ##endif jarl call_via_r1,r31 #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. lea irq_level,r6 ld.w 0[r6],r7 addi -1,r7,r8 st.w r8,0[r6] cmp 0,r8 bne 10f ld.w 16[sp],sp // Restore non-interrupt stack at last interrupt // this is offset 16 because of parameter // flush back area10:#endif // CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT // The return value from the handler (in r10) 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. mov r10,r6 // interrupt handler return code mov r29,r7 // object handle mov ep,r8 // register frame jarl _interrupt_end,r31 // post any bottom layer handle #endif br return_from_exception_or_interrupt#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK .globl _hal_interrupt_stack_call_pending_DSRs_hal_interrupt_stack_call_pending_DSRs: stsr PSW,r9 di // disable interrupts while changing stack // Switch to interrupt stack lea irq_level,r6 // current number of nested interrupts mov 1,r7 // note: this can never be non-zero at this point st.w r7,0[r6] mov sp,r1 // save old stack pointer lea __interrupt_stack-32,r8 // 32 for 16-byte parameter flush back // plus 12 bytes for following reg saves // plus 4 bytes to preserve alignment mov r8,sp st.w r1,16[sp] st.w r9,20[sp] st.w lp,24[sp] ei jarl _cyg_interrupt_call_pending_DSRs,lp di ld.w 24[sp],lp // restore state ld.w 20[sp],r6 ld.w 16[sp],sp lea irq_level,r7 st.w r0,0[r7] ldsr r6,PSW jmp [lp]#endif // CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK //// Indirect subroutine call, via R1call_via_r1: jmp [r1] //// Reset the board// .globl _hal_reset_board_hal_reset_board: di // Turn off interrupts // Don't process NMIs lea __allow_nmi,r1 st.w r0,0[r1] jmp [r0] // Restart machine #if !defined(CYGSEM_HAL_NEC_INLINE_INTERRUPT_FUNCTIONS) .globl _hal_disable_interrupts_hal_disable_interrupts: stsr PSW,r10 di jmp [lp] .globl _hal_enable_interrupts_hal_enable_interrupts: stsr PSW,r6 ei jmp [lp] .globl _hal_restore_interrupts_hal_restore_interrupts: ldsr r6,PSW jmp [lp]#endif // ------------------------------------------------------------------------- .section ".ram_vectors","awx",@progbits#if defined(CYG_HAL_STARTUP_ROM)// Trap jump table - used by builtin ROM__vsr_table: .rept CYGNUM_HAL_VSR_COUNT .word 0x00000794,0,0,0 // jr 0x0100xx0, nop, nop, nop .endr__vsr_table_end:#endif#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM) _hal_vsr_table: .rept CYGNUM_HAL_EXCEPTION_COUNT .word do_exception .endr .rept CYGNUM_HAL_ISR_COUNT .word do_interrupt .endr// Flag to indicate whether NMIs are allowed// Without this, if we do a soft reset (using hal_plf_reset_board above)// we may process NMIs like the watchdog timeout before the system can// accept them__allow_nmi: .word 0 .balign 64_hal_virtual_vector_table: .rept CYGNUM_CALL_IF_TABLE_SIZE .word 0 .endr#if CYGINT_HAL_V85X_ICE_DEBUG .globl _hal_v85x_ice_syscall_info_hal_v85x_ice_syscall_info: .rept 48 .long 0 .endr#endif // if CYGINT_HAL_V85X_ICE_DEBUG#endif // if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM) .data// Initial stack .rept 1024 .byte 0 .endr__startup_stack: #ifndef CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE#define CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE 4096#endif#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK .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:irq_level: .long 0#endif // Interrupt vector tables.// These tables contain the isr, data and object pointers used to deliver// interrupts to user code. .extern _hal_default_isr .globl _hal_interrupt_handlers_hal_interrupt_handlers: .rept CYGNUM_HAL_ISR_COUNT .long _hal_default_isr .endr .globl _hal_interrupt_data_hal_interrupt_data: .rept CYGNUM_HAL_ISR_COUNT .long 0 .endr .globl _hal_interrupt_objects_hal_interrupt_objects: .rept CYGNUM_HAL_ISR_COUNT .long 0 .endr// -------------------------------------------------------------------------// EOF vectors.S
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -