📄 vectors.s
字号:
##==========================================================================#### vectors.S#### SH exception vectors####==========================================================================#####COPYRIGHTBEGIN##### # ------------------------------------------- # The contents of this file are subject to the Red Hat eCos Public License # Version 1.1 (the "License"); you may not use this file except in # compliance with the License. You may obtain a copy of the License at # http://www.redhat.com/ # # Software distributed under the License is distributed on an "AS IS" # basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the # License for the specific language governing rights and limitations under # the License. # # The Original Code is eCos - Embedded Configurable Operating System, # released September 30, 1998. # # The Initial Developer of the Original Code is Red Hat. # Portions created by Red Hat are # Copyright (C) 1998, 1999, 2000 Red Hat, Inc. # All Rights Reserved. # ------------------------------------------- # #####COPYRIGHTEND######==========================================================================#######DESCRIPTIONBEGIN######## Author(s): jskov## Contributors: jskov## 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 <cyg/hal/arch.inc>#include <cyg/hal/sh_regs.h>#include <cyg/hal/sh_offsets.inc>#include <cyg/hal/hal_intr.h>#=========================================================================== .file "vectors.S"#undef __DEBUG #===========================================================================# SR initialization value# zero all bits except:# MD = Processor operation mode field (privileged mode)# I0-3 = Mask out all interrupts but NMI.## When saving or restoring the state of an exception or interrupt, the bit# CYGARC_REG_SR_RB is also set, switching the register bank. When this bit# is set, interrupts must be disabled.## Note: We could also use the BL bit to prevent interrupts, but that would# also prevent the use of breakpoints.#define CYG_SR (CYGARC_REG_SR_MD|CYGARC_REG_SR_IMASK)#define CYG_SR_BANK1 (CYGARC_REG_SR_MD|CYGARC_REG_SR_IMASK|CYGARC_REG_SR_RB)#===========================================================================# Start by defining the exceptions vectors. .section ".vectors","ax"rom_vectors: # reset 0xa0000000# other exceptions VBR+0x100# tlb miss VBR+0x400# interrupts VBR+0x600 .globl __reset;__reset: # Put CPU in a well-known state, disable interrupts. mov.l $nCYG_SR,r1 ldc r1,sr # Initialize VBR if necessary#if defined(CYG_HAL_STARTUP_ROM) || \ ( defined(CYG_HAL_STARTUP_RAM) && \ !defined(CYGSEM_HAL_USE_ROM_MONITOR)) mov.l $__reset,r1 ! Set VBR ldc r1,vbr#endif#ifdef CYG_HAL_STARTUP_ROM # This code will be executed from address 0 if started from ROM. # We do not need it when starting from RAM. mov.l $_start,r0 jmp @r0 nop .align 2$_start: .long _start#endif#===========================================================================# Real startup code. .globl _start_start: # Initialize CPU mov #0,r0 mov #CYGARC_REG_CCR,r1 ! Disable cache mov.l r0,@r1 mov #CYGARC_REG_MMUCR,r1 ! Disable MMU mov.l r0,@r1 mov #CYGARC_REG_BBRA,r1 ! Disable UBC Channel A mov.w r0,@r1 mov #CYGARC_REG_BBRB,r1 ! Disable UBC Channel B mov.w r0,@r1 mov #CYGARC_REG_BRCR,r1 ! Reset UBC common register mov.w r0,@r1 mov.l $CYGARC_REG_TSTR,r1 ! Disable timers mov.b r0,@r1 mov.l $CYGARC_REG_IPRA,r1 ! Disable interrupt request sources mov.w r0,@r1 mov.l $CYGARC_REG_IPRB,r1 mov.w r0,@r1 #ifdef __DEBUG mov #0,r0 mov #1,r1 mov #2,r2 mov #3,r3 mov #4,r4 mov #5,r5 mov #6,r6 mov #7,r7 mov #8,r8 mov #9,r9 mov #10,r10 mov #11,r11 mov #12,r12 mov #13,r13 mov #14,r14#endif # Call platform specific hardware initialization # This may include memory controller initialization. It is not # safe to access RAM until after this point. mov.l $_hal_hardware_init,r0 jsr @r0 nop # Set up monitor related stuff (vectors primarily) hal_mon_init # set up stack mov.l $__startup_stack,r15#if defined(CYG_HAL_STARTUP_ROM) # Copy data from ROM to ram mov.l $__rom_data_start,r3 ! r3 = rom start mov.l $__ram_data_start,r4 ! r4 = ram start mov.l $__ram_data_end,r5 ! r5 = ram end cmp/eq r4,r5 ! skip if no data bt 2f1: mov.l @r3+,r0 ! get word from ROM mov.l r0,@r4 ! store in RAM add #4,r4 cmp/eq r4,r5 ! compare bf 1b ! loop if not yet done2:#endif # clear BSS mov.l $__bss_start,r3 ! r3 = start mov.l $__bss_end,r4 ! r4 = end mov #0,r0 ! r0 = 01: cmp/eq r3,r4 ! skip if no bss bt 2f mov.l r0,@r3 ! store zero add #4,r3 bra 1b ! loop nop2: # It is now safe to call C functions which may rely on initialized # data. # # Initialize MMU.# .extern hal_MMU_init# jsr hal_MMU_init# nop # Enable caches mov.l $_cyg_hal_enable_caches,r1 jsr @r1 nop # call c++ constructors mov.l $_cyg_hal_invoke_constructors,r1 jsr @r1 nop#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS mov.l $_initialize_stub,r1 jsr @r1 nop#endif mov.l $_cyg_start,r1 jsr @r1 nop9: bra 9b ! if we return, loop nop .align 2$nCYG_SR: .long CYG_SR$__startup_stack: .long __startup_stack$__reset: .long __reset$CYGARC_REG_TSTR: .long CYGARC_REG_TSTR$CYGARC_REG_IPRA: .long CYGARC_REG_IPRA$CYGARC_REG_IPRB: .long CYGARC_REG_IPRB .extern _hal_hardware_init .extern __bss_start .extern __bss_end .extern _cyg_hal_invoke_constructors .extern _cyg_start .extern __rom_data_start .extern __ram_data_start .extern __ram_data_end$_hal_hardware_init: .long _hal_hardware_init$__bss_start: .long __bss_start$__bss_end: .long __bss_end$_cyg_hal_invoke_constructors: .long _cyg_hal_invoke_constructors$_cyg_hal_enable_caches: .long _cyg_hal_enable_caches$_cyg_start: .long _cyg_start$__rom_data_start: .long __rom_data_start$__ram_data_start: .long __ram_data_start$__ram_data_end: .long __ram_data_end#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS .extern _initialize_stub$_initialize_stub: .long _initialize_stub#endif .org 0x100__exception:#if defined(CYGPKG_KERNEL_INSTRUMENT) && defined(CYGDBG_KERNEL_INSTRUMENT_INTR) mov #1,r7#endif#ifdef __DEBUG mov #CYGARC_REG_EXCEVT,r1 mov.l @r1,r1 mov.l $trapval,r0 cmp/eq r0,r1 bt 1f mov.l $safe_excevt,r0 mov.l r1,@r01: #endif mov #CYGARC_REG_EXCEVT,r1 mov.l @r1,r1 shlr2 r1 shlr r1 ! divide cause by 0x08 mov.l $_hal_vsr_table,r0 mov.l @(r0,r1),r1 jmp @r1 nop .align 2$_hal_vsr_table: .long _hal_vsr_table#ifdef __DEBUG$safe_excevt: .long 0x080d0200$trapval: .long 0x00000160#endif#---------------------------------------------------------------------------# 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. .globl _cyg_hal_default_exception_vsr_cyg_hal_default_exception_vsr: # We come here with all register containing their # pre-exception values except: # r0_b-r7_b = saved r0-r7 # r7 = vector # # spc = saved pc # ssr = saved sr # Save away some registers mov r15,r1 ! entry sp#ifdef __DEBUG mov.l $exc_state_marker,r0 mov.l r0,@-r15 mov #CYGARC_REG_EXCEVT,r0 mov.l @r0,r0 mov.l r0,@-r15#endif#ifdef CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT add #-12,r15 ! Space for cause, gbr, and vbr#else add #-4,r15 ! Space for cause stc gbr,r0 ! GBR mov.l r0,@-r15 stc vbr,r0 ! VBR mov.l r0,@-r15#endif stc spc,r0 mov.l r0,@-r15 ! PC stc ssr,r0 mov.l r0,@-r15 ! SR sts.l pr,@-r15 ! PR sts.l mach,@-r15 ! mach sts.l macl,@-r15 ! macl mov.l r1,@-r15 ! entry sp mov.l r14,@-r15 ! r14-r0 mov.l r13,@-r15 mov.l r12,@-r15 mov.l r11,@-r15 mov.l r10,@-r15 mov.l r9,@-r15 mov.l r8,@-r15 stc.l r7_bank,@-r15 stc.l r6_bank,@-r15 stc.l r5_bank,@-r15 stc.l r4_bank,@-r15 stc.l r3_bank,@-r15 stc.l r2_bank,@-r15 stc.l r1_bank,@-r15 stc.l r0_bank,@-r15 # After setting the SR it will be possible to use breakpoints. mov.l $nCYG_SR1,r1 ldc r1,sr # ------------------------------------------------------------ # Register bank has changed now. #ifdef __DEBUG # 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 mov #CYGARC_REG_EXCEVT,r0 mov.l @r0,r4 mov #-5,r0 ! divide cause by 0x20 shld r0,r4 mov #CYGARC_SHREG_EVENT,r0 mov.l r4,@(r0,r15) ! store decoded vector number back # The entire CPU state is now stashed on the stack, # call into C to do something with it. mov r15,r4 ! R4 = register dump mov.l $restore_state,r0 ! get return link lds r0,pr ! to procedure register mov.l $_cyg_hal_exception_handler,r0 jmp @r0 ! call C code, r4 = registers nop .align 2$restore_state: .long restore_state$nCYG_SR1: .long CYG_SR#ifdef __DEBUG$exc_state_marker: .long 0x77777770#endif .extern _cyg_hal_exception_handler$_cyg_hal_exception_handler: .long _cyg_hal_exception_handler ! When the call returns it will go to restore_state. .org 0x400__tlb_miss:#if defined(CYGPKG_KERNEL_INSTRUMENT) && defined(CYGDBG_KERNEL_INSTRUMENT_INTR) mov #2,r7#endif#ifdef __DEBUG mov #CYGARC_REG_EXCEVT,r1 mov.l @r1,r1 mov.l $safe_excevt2,r0 mov.l r1,@r0#endif mov #CYGARC_REG_EXCEVT,r1 mov.l @r1,r1 shlr2 r1 shlr r1 ! divide cause by 0x08 mov.l $_hal_vsr_table2,r0 mov.l @(r0,r1),r1 jmp @r1 nop .align 2$_hal_vsr_table2: .long _hal_vsr_table#ifdef __DEBUG$safe_excevt2: .long 0x080d0200#endif .org 0x600__interrupt: #ifdef CYGHWR_HAL_SH_HANDLE_SPURIOUS_INTERRUPTS # A spurious interrupt with INTEVT=0 may be caused by # clearing of BL. Those interrupts need to be ignored. mov #CYGARC_REG_INTEVT,r0 mov.l @r0,r0 cmp/eq #0,r0 bf 1f rte nop1: #endif #if defined(CYGPKG_KERNEL_INSTRUMENT) && defined(CYGDBG_KERNEL_INSTRUMENT_INTR) mov #3,r7#endif#ifdef __DEBUG mov #CYGARC_REG_INTEVT,r1 mov.l @r1,r1 mov.l $safe_intevt,r0 mov.l r1,@r0#endif mov.l $_hal_vsr_table_int,r1 mov.l @r1,r1 jmp @r1 nop .align 2$_hal_vsr_table_int: .long _hal_vsr_table+CYGNUM_HAL_VECTOR_INTERRUPT*4#ifdef __DEBUG$safe_intevt: .long 0x080d0204#endifrom_vectors_end: #---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -