vectors.s
来自「eCos操作系统源码」· S 代码 · 共 643 行 · 第 1/2 页
S
643 行
##==========================================================================#### vectors.S#### SH exception vectors####==========================================================================#####ECOSGPLCOPYRIGHTBEGIN###### -------------------------------------------## This file is part of eCos, the Embedded Configurable Operating System.## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.## Copyright (C) 2003 Nick Garnett #### eCos is free software; you can redistribute it and/or modify it under## the terms of the GNU General Public License as published by the Free## Software Foundation; either version 2 or (at your option) any later version.#### eCos is distributed in the hope that it will be useful, but WITHOUT ANY## WARRANTY; without even the implied warranty of MERCHANTABILITY or## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License## for more details.#### You should have received a copy of the GNU General Public License along## with eCos; if not, write to the Free Software Foundation, Inc.,## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.#### As a special exception, if other files instantiate templates or use macros## or inline functions from this file, or you compile this file and link it## with other works to produce a work based on this file, this file does not## by itself cause the resulting work to be covered by the GNU General Public## License. However the source code for this file must still be made available## in accordance with section (3) of the GNU General Public License.#### This exception does not invalidate any other reasons why a work based on## this file might be covered by the GNU General Public License.#### Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.## at http://sources.redhat.com/ecos/ecos-license/## -------------------------------------------#####ECOSGPLCOPYRIGHTEND######==========================================================================#######DESCRIPTIONBEGIN######## Author(s): jskov## Contributors: jskov, gthomas, nickg## Date: 1999-05-01## Purpose: SH exception vectors## Description: This file defines the code placed into the exception## vectors. It also contains the first level default VSRs## that save and restore state for both exceptions and## interrupts.########DESCRIPTIONEND########==========================================================================#include <pkgconf/hal.h>#include <pkgconf/hal_sh.h>#ifdef CYGPKG_KERNEL#include <pkgconf/kernel.h> // CYGPKG_KERNEL_INSTRUMENT#endif#include CYGHWR_MEMORY_LAYOUT_H #include <cyg/hal/arch.inc>#include <cyg/hal/variant.inc>#include <cyg/hal/sh_regs.h>#include <cyg/hal/sh_offsets.inc>#===========================================================================// .file "vectors.S"#define n__DEBUG #===========================================================================# Start by defining the exceptions vectors. .section ".vectors","ax"# Include exception entry code since it exists in two variants,# depending on the CPU model. This file also defines macros used# for exception return.FUNC_START(_vector_code_vma)#include CYGBLD_HAL_VAR_EXCEPTION_MODEL_INC#---------------------------------------------------------------------------# 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.FUNC_START(cyg_hal_default_exception_vsr) hal_cpu_save_regs hal_exception_entry_extras#ifdef __DEBUG mov.l 1f,r0 mov.l r0,@-r15 bra 2f nop .align 21: .long 0x777777702: # It is safe to use breakpoints below this point. .globl _cyg_hal_default_exception_vsr_bp_safe_cyg_hal_default_exception_vsr_bp_safe:#endif # Make sure the saved registers structure contain # the decoded exception number hal_exception_translate mov r15,r4 ! R4 = register dump #if (defined(CYGSEM_HAL_ROM_MONITOR) || defined(CYGPKG_REDBOOT)) && \ defined(CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK) mov.l $cyg_interrupt_stack_base,r0 mov.l $cyg_interrupt_stack,r1 cmp/hi r15,r0 ! if r0 > r15 or bt 2f cmp/hi r1,r15 ! if r15 > r1 bf 1f2: mov r1,r15 ! change to supervisor stack1: mov.l r4,@-r15 ! save old stack pointer#endif # The entire CPU state is now stashed on the stack, # call into C to do something with it. mov.l $cyg_hal_exception_handler,r0 jsr @r0 ! call C code, r4 = registers nop#if (defined(CYGSEM_HAL_ROM_MONITOR) || defined(CYGPKG_REDBOOT)) && \ defined(CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK) # If we are returning from the last nested exception, move back # to the thread stack. # 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. mov.l @r15,r15#endif bra restore_state nop .align 2 SYM_PTR_REF(cyg_hal_exception_handler)#---------------------------------------------------------------------------# Common interrupt handling code.FUNC_START(cyg_hal_default_interrupt_vsr) hal_cpu_save_regs hal_interrupt_entry_extras #ifdef __DEBUG mov.l 1f,r0 mov.l r0,@-r15 bra 2f nop .align 21: .long 0x777777712: # It is safe to use breakpoints below this point. .globl _cyg_hal_default_interrupt_vsr_bp_safe_cyg_hal_default_interrupt_vsr_bp_safe:#endif # 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 mov.l $cyg_scheduler_sched_lock,r0 mov.l @r0,r1 add #1,r1 mov.l r1,@r0#endif mov r15,r8 ! R8 = register dump#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK mov.l $cyg_interrupt_stack_base,r0 mov.l $cyg_interrupt_stack,r1 cmp/hi r15,r0 ! if r0 > r15 or bt 2f cmp/hi r1,r15 ! if r15 > r1 bf 1f2: mov r1,r15 ! change to supervisor stack1: mov.l r8,@-r15 ! save old stack pointer#endif#if defined(CYGPKG_KERNEL_INSTRUMENT) && defined(CYGDBG_KERNEL_INSTRUMENT_INTR) mov.l $n0301,r4 ! arg0 = type = INTR,RAISE mov r7,r5 ! arg1 = vector number mov.l $cyg_instrument,r0 mov #0,r6 ! arg2 = 0 jsr @r0 ! call instrument function nop bra 1f nop .align 2$n0301: .long 0x0301 SYM_PTR_REF(cyg_instrument)1:#endif # Decode the interrupt vector, and find ISR index mov #CYGARC_SHREG_EVENT,r0 mov.l @(r0,r8),r4 ! load existing vector number hal_intc_decode r1,r4 mov.l r4,@(r0,r8) ! store decoded vector number back ! to saved state. hal_intc_translate r4,r9#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. mov.l $hal_saved_interrupt_state,r1 mov.l r8,@r1#endif#ifdef CYGSEM_HAL_COMMON_INTERRUPTS_ALLOW_NESTING#if defined(CYGARC_SH_SOFTWARE_IP_UPDATE) # The interrupt mask bits in the SR are not updated by the # CPU. Proper nested operation requires the level to be # found and put in the SR. # R4 contains the vector number: # CYGNUM_HAL_INTERRUPT_NMI: # Ix = 15 # CYGNUM_HAL_INTERRUPT_LVL0-CYGNUM_HAL_INTERRUPT_LVL14: # Ix = 15-(CYGNUM_HAL_INTERRUPT_LVL0-R4) # IRA sources: # Get level from IRA # IRB sources: # Get level from IRB # However, doing mutiple checks and branches here is not smart. # Instead rely on alternative implementation where all programmed # priorities are also kept in a table. mov.l $cyg_hal_ILVL_table,r0 mov.b @(r0,r4),r0 shll2 r0 shll2 r0 mov.l $unmasked_SR,r1 or r0,r1 ldc r1,sr#endif#endif mov r9,r0 mov.l $hal_interrupt_handlers,r1 ! get interrupt handler mov.l @(r0,r1),r1 mov.l $hal_interrupt_data,r5 ! get interrupt data mov.l @(r0,r5),r5 jsr @r1 ! r4=vector, r5=data nop#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. mov.l @r15,r15#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 r0 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. mov r0,r4 ! arg1 = isr_ret # Note that r8 and r9 are defined to be preserved across # calls by the calling convention, so they still contain # the register dump and the vector table index respectively. mov.l $hal_interrupt_objects,r0 ! get interrupt object table mov.l @(r0,r9),r5 ! arg2 = interrupt object mov.l $interrupt_end,r0 mov r8,r6 ! arg3 = saved register dump jsr @r0 ! call into C to finish off nop#endifrestore_state: # All done, restore CPU state and continue#ifdef __DEBUG # skip past debug marker add #4,sp#endif hal_cpu_restore_regs_return
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?