vectors.s
来自「开放源码实时操作系统源码.」· 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 2
1: .long 0x77777770
2:
# 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 1f
2: mov r1,r15 ! change to supervisor stack
1: 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 2
1: .long 0x77777771
2:
# 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 1f
2: mov r1,r15 ! change to supervisor stack
1: 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
#endif
restore_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 + -
显示快捷键?