📄 vectors.s
字号:
##==========================================================================
##
## Vectors.S
##
## OpenRISC exception vectors, interrupt-handling, reset and
## platform-indepent initialization
##
##==========================================================================
#####ECOSGPLCOPYRIGHTBEGIN####
## -------------------------------------------
## This file is part of eCos, the Embedded Configurable Operating System.
## Copyright (C) 2002 Red Hat, Inc.
##
## 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): sfurman
## Contributors:
## Date: 2003-01-20
## Purpose: OpenRISC interrupts, exception vectors and reset
## 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>
#ifdef CYGPKG_KERNEL
#include <pkgconf/kernel.h> // CYGPKG_KERNEL_INSTRUMENT
#endif
#include <cyg/hal/hal_intr.h>
#include <cyg/hal/hal_cache.h>
#===========================================================================
.extern _hal_vsr_table
.extern _cyg_hal_invoke_constructors
.extern _cyg_instrument
.extern _cyg_start
.extern _hal_IRQ_init
.extern _hal_platform_init
.extern _initialize_stub
.extern __bss_start
.extern __bss_end
.extern __sbss_start
.extern __sbss_end
# Include variant macros after MSR definition.
#include <cyg/hal/arch.inc>
#include <cyg/hal/openrisc.inc>
#===========================================================================
# Start by defining the exceptions vectors that must be placed in low
# memory, starting at location 0x100.
.section ".vectors","ax"
#---------------------------------------------------------------------------
# Macros for generating an exception vector service routine
# Reset vector macro
.macro reset_vector name org
.p2align 8
.globl __exception_\name
__exception_\name:
load32i r3,_start
l.jr r3
l.nop # delay slot
.endm
# Generic vector macro
.macro exception_vector name org
.p2align 8
.globl __exception_\name
__exception_\name:
l.addi sp,sp,-SIZEOF_OR1KREGS # space for registers
# Store General Purpose Registers (GPRs).
l.sw 3 * OR1K_GPRSIZE(sp), r3
l.sw 4 * OR1K_GPRSIZE(sp), r4
l.sw 5 * OR1K_GPRSIZE(sp), r5
l.sw 6 * OR1K_GPRSIZE(sp), r6
l.sw 7 * OR1K_GPRSIZE(sp), r7
l.sw 8 * OR1K_GPRSIZE(sp), r8
l.sw 9 * OR1K_GPRSIZE(sp), r9
l.sw 11 * OR1K_GPRSIZE(sp), r11
l.sw 13 * OR1K_GPRSIZE(sp), r13
l.sw 15 * OR1K_GPRSIZE(sp), r15
l.sw 17 * OR1K_GPRSIZE(sp), r17
l.sw 19 * OR1K_GPRSIZE(sp), r19
l.sw 21 * OR1K_GPRSIZE(sp), r21
l.sw 23 * OR1K_GPRSIZE(sp), r23
l.sw 25 * OR1K_GPRSIZE(sp), r25
l.sw 27 * OR1K_GPRSIZE(sp), r27
l.sw 29 * OR1K_GPRSIZE(sp), r29
l.sw 31 * OR1K_GPRSIZE(sp), r31
#ifndef CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT
# R0 is not typically stored because it is always zero-valued,
# but we store it here for consistency when examining registers
# in the debugger.
l.sw 0 * OR1K_GPRSIZE(sp), r0
# Callee-saved regs don't need to be preserved across a call into
# an ISR, but we can do so to make debugging easier.
l.sw 2 * OR1K_GPRSIZE(sp), r2
l.sw 10 * OR1K_GPRSIZE(sp), r10
l.sw 12 * OR1K_GPRSIZE(sp), r12
l.sw 14 * OR1K_GPRSIZE(sp), r14
l.sw 16 * OR1K_GPRSIZE(sp), r16
l.sw 18 * OR1K_GPRSIZE(sp), r18
l.sw 20 * OR1K_GPRSIZE(sp), r20
l.sw 22 * OR1K_GPRSIZE(sp), r22
l.sw 24 * OR1K_GPRSIZE(sp), r24
l.sw 26 * OR1K_GPRSIZE(sp), r26
l.sw 28 * OR1K_GPRSIZE(sp), r28
l.sw 30 * OR1K_GPRSIZE(sp), r30
# save MAC LO and HI regs
l.mfspr r5,r0,SPR_MACLO
l.sw OR1KREG_MACLO(sp),r5
l.mfspr r5,r0,SPR_MACHI
l.sw OR1KREG_MACHI(sp),r5
#endif
# Save SP of interruptee in reg dump
l.addi r5,sp,SIZEOF_OR1KREGS
l.sw 1 * OR1K_GPRSIZE(sp),r5
# ...and the PC
l.mfspr r5,r0,SPR_EPCR_BASE
l.sw OR1KREG_PC(sp),r5
# ... and the Supervisor Register
l.mfspr r5,r0,SPR_ESR_BASE
l.sw OR1KREG_SR(sp),r5
# ... and the exception's effective address, if there is one.
# FIXME - don't need to do this for some exceptions
l.mfspr r5,r0,SPR_EEAR_BASE
l.sw OR1KREG_EEAR(sp),r5
# Second arg to VSR is exception number
# First vector is located at 0x100, second at 0x200, etc.
# Shift right to get vector number for address lookup.
l.ori r4,r0,(\org>>8)
l.sw OR1KREG_VECTOR(sp),r4
# Lookup address of VSR in table and jump to it
# Arg 0: Pointer to HAL_SavedRegisters struct
# Arg 1: Vector #
load32i r5,_hal_vsr_table+(\org>>6)
l.lwz r5,0(r5)
l.jr r5 # To the VSR, Batman
# First arg to VSR is SP
l.or r3,r0,sp # Delay slot
.endm
#---------------------------------------------------------------------------
# Define the exception vectors.
rom_vectors:
# These are the architecture-defined vectors that
# are always present.
reset_vector reset 0x100
exception_vector bus_error 0x200
exception_vector data_page_fault 0x300
exception_vector instruction_page_fault 0x400
exception_vector tick_timer 0x500
exception_vector unaligned_access 0x600
exception_vector illegal_instruction 0x700
exception_vector external_interrupt 0x800
exception_vector dtlb_miss 0x900
exception_vector itlb_miss 0xa00
exception_vector range 0xb00
exception_vector syscall 0xc00
exception_vector reserved 0xd00
exception_vector trap 0xe00
rom_vectors_end:
#if defined(CYG_HAL_STARTUP_ROM) || \
( defined(CYG_HAL_STARTUP_RAM) && \
!defined(CYGSEM_HAL_USE_ROM_MONITOR))
.macro hal_vsr_table_init
# Next initialize the VSR table. This happens whether the
# vectors were copied to RAM or not.
# First fill with exception handlers
load32i r3,_cyg_hal_default_exception_vsr
load32i r4,_hal_vsr_table+4 # First entry in table is unused
l.ori r5,r0,CYGNUM_HAL_VSR_COUNT
1: l.sw 0(r4),r3
l.addi r5,r5,-1
l.sfgtsi r5,0
l.bf 1b
l.addi r4,r4,4 # delay slot
# Then fill in the interrupt handlers
load32i r4,_hal_vsr_table
load32i r3,_cyg_hal_default_interrupt_vsr
l.sw CYGNUM_HAL_VECTOR_INTERRUPT*4(r4),r3
l.sw CYGNUM_HAL_VECTOR_TICK_TIMER*4(r4),r3
.endm
#elif defined(CYG_HAL_STARTUP_RAM) && defined(CYGSEM_HAL_USE_ROM_MONITOR)
# Initialize the VSR table entries
# We only take control of the interrupt vectors,
# the rest are left to the ROM for now...
.macro hal_vsr_table_init
load32i r4,_hal_vsr_table
load32i r3,_cyg_hal_default_interrupt_vsr
l.sw CYGNUM_HAL_VECTOR_INTERRUPT*4(r4),r3
l.sw CYGNUM_HAL_VECTOR_TICK_TIMER*4(r4),r3
.endm
#else
#error "Need to define hal_vsr_table_init"
#endif
# I-Cache initialization macro
.macro hal_icache_init
/* Disable I-Cache */
l.mfspr r13,r0,SPR_SR
l.addi r11,r0,-1
l.xori r11,r11,SPR_SR_ICE
l.and r11,r13,r11
l.mtspr r0,r11,SPR_SR
/* Invalidate I-Cache */
l.addi r13,r0,0
l.addi r11,r0,HAL_ICACHE_SIZE
1:
l.mtspr r0,r13,SPR_ICBIR
l.sfne r13,r11
l.bf 1b
l.addi r13,r13,HAL_ICACHE_LINE_SIZE
/* Enable I-Cache */
l.mfspr r13,r0,SPR_SR
l.ori r13,r13,SPR_SR_ICE
l.mtspr r0,r13,SPR_SR
/* Flush instructions out of instruction buffer */
l.nop
l.nop
l.nop
l.nop
l.nop
.endm
# D-Cache initialization macro
.macro hal_dcache_init
/* Flush DC */
l.addi r10,r0,0
l.addi r11,r0,HAL_DCACHE_SIZE
1:
l.mtspr r0,r10,SPR_DCBIR
l.sfne r10,r11
l.bf 1b
l.addi r10,r10,HAL_DCACHE_LINE_SIZE
/* Enable DC */
l.mfspr r10,r0,SPR_SR
l.ori r10,r10,SPR_SR_DCE
l.mtspr r0,r10,SPR_SR
.endm
#===========================================================================
# Startup code: We jump here from the reset vector to set up the world.
.text
FUNC_START(start)
# Initialize Supervision Register:
# Supervisor mode on, all interrupts off, caches off
#
# (If we've entered here from a hardware reset, then the SR is already
# set to this value, but we may have jumped here as part of a soft
# system reset.)
l.ori r3,r0,SPR_SR_SM
l.mtspr r0,r3,SPR_SR
# Run platform-specific hardware initialization code.
# This may include memory controller initialization.
# Hence, it is not safe to access RAM until after this point.
hal_hardware_init
#ifdef CYGSEM_HAL_ENABLE_ICACHE_ON_STARTUP
# Enable I-Cache
hal_icache_init
#endif
#ifdef CYGSEM_HAL_ENABLE_DCACHE_ON_STARTUP
# Enable D-Cache
hal_dcache_init
#endif
# Start the tick timer, in case timer polling routine hal_delay_us() is called.
# Initially, no interrupts are generated by the tick timer. Later on, that
# may change when the kernel is initialized.
l.movhi r3, hi(0x40000000|CYGNUM_HAL_RTC_PERIOD)
l.mtspr r0,r3, SPR_TTMR
.globl _hal_hardware_init_done
_hal_hardware_init_done:
# set up stack
load32i sp,__interrupt_stack
# Make a dummy frame on the stack, so that stack backtraces are sane
# for debugging. On return from that function, the restore_state()
# function is called to resume the interrupted thread.
l.addi sp,sp,-8
l.sw 4(sp),r0 # Dummy saved FP
l.sw 0(sp),r0 # Dummy saved LR
# Set up exception handlers and VSR table, taking care not to
# step on any ROM monitor VSRs.
hal_vsr_table_init
#if defined(CYG_HAL_STARTUP_ROM)
# Copy exception/interrupt vectors from ROM to address 0x100
load32i r4,0x100
load32i r3,rom_vectors
load32i r5,rom_vectors_end
1: l.sfeq r3,r5
l.bf 2f
l.lwz r6,0(r3)
l.sw 0(r4),r6
l.addi r3,r3,4
l.j 1b
l.addi r4,r4,4 # delay slot
2:
# Copy .data section into RAM
load32i r3,__rom_data_start
load32i r4,__ram_data_start
load32i r5,__ram_data_end
1: l.sfeq r4,r5
l.bf 2f
l.lwz r6,0(r3)
l.sw 0(r4),r6
l.addi r3,r3,4
l.j 1b
l.addi r4,r4,4 # delay slot
2:
#endif
# clear BSS
load32i r4,__bss_start
load32i r5,__bss_end
1: l.sfeq r4,r5
l.bf 2f
l.nop
l.sw 0(r4),r0
l.j 1b
l.addi r4,r4,4
2:
# Note: no SBSS section to clear with OpenRISC target
# Platform-specific initialization
l.jal _hal_platform_init
l.nop # delay slot
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -