📄 vectors.s
字号:
add \dreg,\dreg1 # dreg1 = word index of isr mov (0,a2),\dreg # dreg = vector priority mov \dreg1,(0,a2) # store real vector in saved state asl 2,\dreg # dreg = byte index of isr .endm #elif defined(CYG_HAL_MN10300_MN103002) #define CYG_ISR_TABLE_SIZE 10 # decode the interrupt .macro decode_interrupt dreg,areg,dreg1 mov _mn10300_interrupt_control,\areg movhu (0x100,\areg),\dreg1 # dreg1 = IAGR mov (0,a2),\dreg # dreg = vector priority mov \dreg1,(0,a2) # store real vector in saved state asl 2,\dreg # dreg = byte index of isr add 12,\dreg # skip NMI vectors .endm #endif#else#if defined(CYG_HAL_MN10300_MN103000)#define CYG_ISR_TABLE_SIZE 100 # decode the interrupt .macro decode_interrupt dreg,areg,dreg1 mov _mn10300_interrupt_control,\areg movhu (0x100,\areg),\dreg # dreg = IAGR movhu (\dreg,\areg),\dreg1 # dreg1 = IGR[dreg] and 0xf,\dreg1 # dreg1 = ID0..3 mov hal_lsbit_table,\areg # areg = ls bit table movbu (\dreg1,\areg),\dreg1 # dreg1 = ls bit index add \dreg1,\dreg # dreg = word index of isr mov \dreg,(0,a2) # store real vector in saved state asl 2,\dreg # dreg = byte index of isr .endm #elif defined(CYG_HAL_MN10300_MN103002) #define CYG_ISR_TABLE_SIZE 34 # decode the interrupt .macro decode_interrupt dreg,areg,dreg1 mov _mn10300_interrupt_control,\areg movhu (0x100,\areg),\dreg # dreg = IAGR mov \dreg,(0,a2) # store real vector in saved state add 12,\dreg # skip NMI vectors .endm #endif #endif ##-----------------------------------------------------------------------------## Default interrupt VSR .text .globl __default_interrupt_vsr__default_interrupt_vsr: # We come here with all the registers pushed # onto the stack. increment_sched_lock #ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK # Increment interrupt nesting counter mov __interrupt_stack,a0 # A0 = interrupt stack top mov sp,a2 # A2 = SP cmp __interrupt_stack_base,a2 # compare with base of stack blt 1f # if lt switch to int stack cmp a0,a2 # compare sp with stack top ble 8f # if le already on istack1: mov a0,sp # switch to new SP8: movm [a2],(sp) # save old SP#else mov sp,a2 # A2 = saved thread state#endif # Here A2 -> saved thread state on the threads own # stack. We will be executing either on the same stack # or on the interrupt stack, depending on config options. decode_interrupt d3,a3,d0 # Here D3 contains the table byte offset of the vector to # call. On the MN103000 this needs to be shifted right by # two to derive the vector. On the MN103002 this correponds # exactly to the vector used to attach it.#if defined(CYGPKG_KERNEL_INSTRUMENT) && defined(CYGDBG_KERNEL_INSTRUMENT_INTR) # Call cyg_instrument to record that this interrupt is being raised. add -16,sp # make space for return link + args mov 0x0301,d0 # d0 = type = INTR,RAISE mov (0,a2),d1 # d1 = arg1 = vector mov d3,(12,sp) # (12,sp) = arg2 = table offset calls _cyg_instrument # call instrumentation add 16,sp # pop space #endif #ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT .extern _cyg_hal_gdb_isr add -16,sp # make space for return link + args mov (0,a2),d0 # d0 = vector mov (56,a2),d1 # d1 = pc calls _cyg_hal_gdb_isr # call GDB isr function cmp 0x00,d0 # Call ISR proper? beq 2f # (d0 is 0 when skipping # to avoid DSR call) add 16,sp # pop space#endif #ifdef CYGSEM_HAL_COMMON_INTERRUPTS_ALLOW_NESTING # To allow nested interrupts, we set the IE bit. We do # not touch the IPL bits, so only higher priority interrupts # will be nested on top of us. Also, new interrupts will not # be delivered until the ISR calls # Cyg_Interrupt::acknowledge_interrupt(). At some future point # we may want to do the ack stuff here to allow immediate nesting. or 0x0800,psw #endif mov _hal_interrupt_handlers,a0 # a0 = isr table mov (d3,a0),a0 # a0 = isr mov _hal_interrupt_data,a1 # a1 = data table mov (d3,a1),d1 # d1 = isr data mov (0,a2),d0 # d0 = vector. (d3 is... # ...adjusted for table reads)#if defined(CYG_HAL_MN10300_MN103000) lsr 2,d0 # d0 = vector number#endif add -16,sp # make space for return link calls (a0) # call isr # on return d0 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. # D3 is defined to be saved across procedure calls, and # should still contain the vector byte index. Similarly, # A2 should still point to the saved machine state.#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. add 16,sp # pop call frame from int stack movm (sp),[a3] # pop old sp mov a3,sp # put in SP add -16,sp # make call frame for call#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. # Using the vector offset in D3, get the interrupt object pointer # into D1. mov _hal_interrupt_objects,a0 # a0 = object table mov (d3,a0),d1 # d1 = object # Even when this is not the last nested interrupt, we must call # _interrupt_end() to post the DSR and decrement the scheduler # lock. # interrupt_end must be called with interrupts enabled. # At this point we restore the PSW of the code we interrupted # to get the IPL bits back. By definition this PSW must have # interrupts enabled. mov (52,a2),d2 mov d2,psw mov a2,(12,sp) # arg3 = saved state. calls _interrupt_end # call interrupt end fn #endif add 16,sp # pop return link show_interrupts movm (sp),[d2,d3,a2,a3,other] # pop regs add 4,sp rti # and returnhal_lsbit_table: .byte 0, 0, 1, 0 .byte 2, 0, 1, 0 .byte 3, 0, 1, 0 .byte 2, 0, 1, 0##-----------------------------------------------------------------------------## Default NMI VSR#define NMICR 0x34000100#define DCR 0x20000030#define ISR 0x20000034 .globl _cyg_hal_exception_handler .text .globl __default_nmi_vsr__default_nmi_vsr: # We come here with all the registers saved # on the stack. # Decode the cause of the NMI and cancel all the bits in all # the registers. We need to clear any bits set in the ISR and # then clear any bits set in the NMICR. Note that we can only # access the ISR if the DCR:DE bit is set. movhu (NMICR),d0 # D0 = NMI Control register movhu (DCR),d1 # D1 = Debug Control Register mov d1,d2 # D2 = copy of DCR movhu (ISR),d3 # D3 = Interrupt Status Register or 0x0010,d1 # Set DE bit movhu d1,(DCR) movhu d3,(ISR) # clear ISR bits movhu d2,(DCR) # restore DCR to original value movhu d0,(NMICR) # clear NMI bits and 0x7,d0 # LS 3 bits only mov hal_lsbit_table,a0 movbu (d0,a0),d1 # D1 = NMI code ## 0 = NMI ## 1 = Watchdog ## 2 = System Error # It appears that there is an undocumented extra bit # in the PSW that masks the delivery of NMIs. It is in # the upper 16 bits of the register that we cannot access # directly. So, to clear it, we must set up a fake interrupt # state and do an RTI to load the PSW. We need to do this if # we are going to be able to set breakpoints in NMI handlers. # Note that the AM33 has a documented NMID at bit 17 of the # extended PSW (along with instructions to access it). mov PSW,d3 # D3 = PSW and 0xFFFF,d3 mov 1f,d2 # D2 = Next PC movm [d2,d3],(sp) # Push rti # and load into CPU1: mov sp,a1 # a1 = saved state mov a1,d0 # d0 = arg1 = saved state add -16,sp # return link + args mov d1,(16,sp) # save in spare save slot calls _cyg_hal_exception_handler # call C code add 16,sp # pop args movm (sp),[d2,d3,a2,a3,other] # pop all registers add 4,sp rti##-----------------------------------------------------------------------------## Default TRAP VSR .text .globl __default_trap_vsr__default_trap_vsr: # We come here with all the registers saved # on the stack. add -8,sp # return link + arg mov 3,d1 # 3 == TRAP trap mov d1,(0,sp) # save in spare save slot calls _cyg_hal_exception_handler # call C code add 8,sp # pop args movm (sp),[d2,d3,a2,a3,other] # pop all registers add 4,sp rets ##-----------------------------------------------------------------------------## VSR table. The VSRs pointed to by this table are called from the stubs## connected to the hardware.#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_MN10300_SIM) .data .globl _hal_vsr_table_hal_vsr_table: .long __default_interrupt_vsr .long __default_interrupt_vsr .long __default_interrupt_vsr .long __default_interrupt_vsr .long __default_interrupt_vsr .long __default_interrupt_vsr .long __default_interrupt_vsr .long __default_nmi_vsr .long __default_trap_vsr#endif ##-----------------------------------------------------------------------------## Interrupt tables .section ".bss" .globl _hal_interrupt_handlers_hal_interrupt_handlers: .rept CYG_ISR_TABLE_SIZE .long 0 .endr .globl _hal_interrupt_data_hal_interrupt_data: .rept CYG_ISR_TABLE_SIZE .long 0 .endr .globl _hal_interrupt_objects_hal_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 ##----------------------------------------------------------------------------- #ifdef CYG_HAL_MN10300_STDEVAL1 .data## Keep alignment to work around compiler/linker bugled_count: .long 0led_value: .byte 0x40led_foo1: .byte 0x00led_foo2: .byte 0x00led_foo3: .byte 0x00#endif##-----------------------------------------------------------------------------## end of vectors.S
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -