URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [hal/] [fr30/] [arch/] [current/] [src/] [vectors.S] - Rev 868
Go to most recent revision | Compare with Previous | Blame | View Log
##=============================================================================
##
## vectors.S
##
## fr30 startup code and exception and interrupt vectors
##
##=============================================================================
## ####ECOSGPLCOPYRIGHTBEGIN####
## -------------------------------------------
## This file is part of eCos, the Embedded Configurable Operating System.
## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2007 Free Software Foundation, 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.,
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 v2.
##
## This exception does not invalidate any other reasons why a work based
## on this file might be covered by the GNU General Public License.
## -------------------------------------------
## ####ECOSGPLCOPYRIGHTEND####
##=============================================================================
#######DESCRIPTIONBEGIN####
##
## Author(s): larsi
## Contributors:larsi
## Date: 2006-06-26
## Purpose: fr30 exception vectors
## Description: This file defines the code placed into the exception
## vectors. It also contains the startup code and first
## level default VSRs that save and restore state for
## both exceptions and interrupts.
##
######DESCRIPTIONEND####
##
##=============================================================================
#include <pkgconf/system.h>
#include <pkgconf/hal.h>
#include CYGBLD_HAL_PLATFORM_H
#ifdef CYGPKG_KERNEL
#include <pkgconf/kernel.h>
#endif /* CYGPKG_KERNEL */
#include <cyg/hal/arch.inc>
#==============================================================================
.file "vectors.S"
#==============================================================================
# Real startup code. We jump here from the various reset vectors to set up the
# world.
.text
.globl _start
_start:
# disable interrupts and set priority to lowest (=disable)
andccr #0xef
stilm #0x0
hal_diag_init_led
#ifdef CYGPKG_HAL_FR30_FLASH_INIT_DEFINED
hal_flash_init
#endif
hal_cpu_init
#ifdef CYGPKG_HAL_FR30_MEMC_INIT_DEFINED
hal_memc_init
#endif
hal_intc_init
hal_cache_init
hal_timer_init
# Zero the BSS. If the BSS is not a whole number of words
# long we will write up to 3 extra bytes at the end.
# (This should not be a problem usually).
ldi:32 #__bss_end - 8, r12
ldi:32 #__bss_start - 4, r13
eor r0, r0 ; zero r0
2:
add #0x4, r13
cmp r12, r13
ble:d 2b
st r0, @r13
#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM)
# In a ROM booted system, we also need to copy the data section
# out to the RAM.
ldi:32 #__rom_data_start - 4 + CYGPKG_HAL_FR30_LMA_OFFSET, r11
ldi:32 #__ram_data_start - 4, r9
ldi:32 #__ram_data_end - 8, r10
3:
add #0x4, r11
add #0x4, r9
ld @r11, r0
cmp r10, r9
ble:d 3b
st r0, @r9
#endif
# Set up the stacks
# Begin with interrupt (system) stack
ldi:32 #__interrupt_stack, r11
mov r11, ssp
# and now continue with user stack
orccr #0x20
ldi:32 #__user_stack, r11
mov r11, usp
#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM)
# If we are here, initialize the hal_vsr_table. RAM startup
# configurations can assume that Redboot has already set it up.
.extern hal_mon_init
ldi:32 #hal_mon_init, r11
call @r11
#endif
.extern hal_variant_init
ldi:32 #hal_variant_init, r11
call @r11
.extern hal_platform_init
ldi:32 #hal_platform_init, r11
call @r11
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
// This is here so we can debug the constructors.
.extern initialize_stub
ldi:32 #initialize_stub, r11
call @r11
#endif
.extern cyg_hal_invoke_constructors
ldi:32 #cyg_hal_invoke_constructors, r11
call @r11
# TODO integrate into hal_intr.h
# set irq 25 priority (for reload timer 1)
ldi:20 #0x449, r4
ldi:8 #0x10, r5
stb r5, @r4
#ifdef CYGDBG_HAL_DEBUG_GDB_INITIAL_BREAK
.extern breakpoint
call breakpoint
#endif
.extern cyg_start
ldi:32 #cyg_start, r11
call @r11
# Hmm. Not expecting to return from cyg_start, endless nop loop
1: nop
call 1b
#==============================================================================
# Default exception VSR
.align 2, 0xcc
.globl __default_exception_vsr
__default_exception_vsr:
## We enter here with the CPU state still in the registers and:
## @(ssp,8) PS pushed by hardware
## @(ssp,4) PC pushed by hardware
## @(ssp) old register r0 content pushed by trampoline
## r0 now contains the vector number
# at first switch to USP (set bit 5 in CCR in PS)
orccr #0x20
st r0, @-r15
st mdl, @-r15
st mdh, @-r15
mov r0, mdh ; save exception/interrupt number
mov r15, r0
addn #+12, r0
mov r0, mdl ; save r15 also in mdl
st r0, @-r15 ; store usp
mov ssp, r0
st r0, @-r15 ; store ssp (TODO maybe have to sub 12 before)
st rp, @-r15
st tbr, @-r15
addsp #-8 ; skip 2 positions for PS and PC
mov r15, r0 ; save stack position to later store PS and PC
st mdl, @-r15 ; store original r15 here
stm1 (r8, r9, r10, r11, r12, r13, r14)
stm0 (r1, r2, r3, r4, r5, r6, r7)
mov ssp, r14
ld @r14, r1 ; get original r0 content
st r1, @-r15 ; and store it
ld @(r14,4), r2 ; get hardware pushed PC
st r2, @r0 ; and store it
ld @(r14,8), r3 ; get hardware pushed PS
addn #4, r0 ; and
st r3, @r0 ; store it
# we should be finished saving context here
# Call exception handler
.extern hal_default_exception_handler
ldi:32 #hal_default_exception_handler, r11
mov r15, r5 ; pointer to saved state as second argument
call:d @r11
mov mdh, r4 ; exception number as first argument
__default_exception_vsr_return:
## At this point, the user stack (USP) contains:
## @(usp,0x60) trap number
## @(usp,0x5c) mdl
## @(usp,0x58) mdh
## @(usp,0x54) usp
## @(usp,0x50) ssp
## @(usp,0x4c) rp
## @(usp,0x48) tbr
## @(usp,0x44) ps
## @(usp,0x40) pc
## @(usp,0x3c) r15
## @(usp,0x38) r14
## @(usp,0x34) r13
## @(usp,0x30) r12
## @(usp,0x2c) r11
## @(usp,0x28) r10
## @(usp,0x24) r9
## @(usp,0x20) r8
## @(usp,0x1c) r7
## @(usp,0x18) r6
## @(usp,0x14) r5
## @(usp,0x10) r4
## @(usp,0xc) r3
## @(usp,8) r2
## @(usp,4) r1
## @(usp) r0
##
## and system stack (SSP) contains:
## @(ssp,8) PS
## @(ssp,4) PC
## @(ssp) old r0 content
# we can reuse the code from __default_interrupt_vsr
ldi:32 #hal_exception_return, r0
jmp @r0
#==============================================================================
# Default interrupt VSR
#
#
.align 2, 0xcc
.globl __default_interrupt_vsr
__default_interrupt_vsr:
## We enter here with the CPU state still in the registers and:
## r0 vector number
## @(ssp) old register r0 content pushed by trampoline
## @(ssp,4) PS pushed by hardware
## @(ssp,8) PC pushed by hardware
# begin to save registers (to USP)
orccr #0x20
st mdl, @-r15
st mdh, @-r15
st rp, @-r15
stm1 (r8, r9, r10, r11, r12, r13)
stm0 (r1, r2, r3 , r4 , r5 , r6, r7)
andccr #0xdf
ld @r15+, r8 ; read old r0 content from SSP
ld @r15+, r9 ; read pc pushed by hardware
ld @r15+, r10 ; read ps pushed by hardware
orccr #0x20
st r8, @-r15 ; push old r0 content to USP
# we should be finished saving irq context here
#if defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT)
# Increment scheduler lock
.extern cyg_scheduler_sched_lock
ldi:32 #cyg_scheduler_sched_lock, r1
ld @r1, r2
addn #1, r2
st r2, @r1
#endif
# Call hal_interrupt_handlers[vector](vector, cyg_hal_interrupt_data[vector])
mov r0, r8 ; copy the vector
lsl #2, r8 ; multiply vector by 4
ldi:32 #hal_interrupt_handlers, r13 ; load handlers table
ld @(r13, r8), r1 ; current handler
ldi:32 #hal_interrupt_data, r13 ; load data table
ld @(r13, r8), r5 ; current data, second argument
call:d @r1
mov r0, r4 ; exception number as argument
# At this point:
# r15 = stack pointer /*(should be usable as pointer to HAL_SavedRegisters)*/
# r4 = ISR return code (returned by call)
# r8 = ISR table offset (saved across call)
# r0 = vector number (NOT saved across call, but we don't need it)
/*
# 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.
hal_from_intstack
*/
#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT
# Call interrupt_end(return_value, hal_interrupt_objects[vector], regs)
# - r4 is the return value from the ISR
# - regs points to saved CPU context
ldi:32 #hal_interrupt_objects, r13 ; load objects table
ld @(r13, r8), r5 ; current object, second argument
ldi:32 #interrupt_end, r12
call:d @r12
mov r15, r6 ; third argument TODO is not in
; HAL_Saved_Registers format
#endif
##.globl hal_exception_return
hal_exception_return:
# Now pull saved state from stack and return to
# what thread was originally doing.
# at first store return values to SSP
andccr #0xdf
st r10, @-r15 ; store ps
st r9, @-r15 ; store pc
orccr #0x20
# and then restore normal registers from USP
ldm0 (r0, r1, r2 , r3 , r4 , r5, r6, r7)
ldm1 (r8, r9, r10, r11, r12, r13)
ld @r15+, rp
ld @r15+, mdh
ld @r15+, mdl
andccr #0xdf
reti
#==============================================================================
# Exception trampolines
# TBR table points to these short code sequences here that push the vector
# number on to the stack and then indirect via the VSR table to a handler.
# (__default_interrupt_vsr)
.text
# macro to create exception handler (no error code)
.macro hal_fr30_exception_noerr idx
.globl hal_fr30_exception_noerr_\idx
hal_fr30_exception_noerr_\idx:
st r0, @-r15
ldi:32 #hal_vsr_table + \idx * 4, r0
ld @r0, r0
jmp:d @r0
ldi:8 #\idx, r0
.endm
# Now generate all the default exception VSR trampolines.
# hal_fr30_exception_noerr 1 no trampoline needed for reset and mode vector
hal_fr30_exception_noerr 2
hal_fr30_exception_noerr 3
hal_fr30_exception_noerr 4
hal_fr30_exception_noerr 5
hal_fr30_exception_noerr 6
hal_fr30_exception_noerr 7
hal_fr30_exception_noerr 8
hal_fr30_exception_noerr 9
hal_fr30_exception_noerr 10
hal_fr30_exception_noerr 11
hal_fr30_exception_noerr 12
hal_fr30_exception_noerr 13
hal_fr30_exception_noerr 14
#==============================================================================
# IRQ handler trampolines
# macro to create exception handler (no error code)
.macro hal_fr30_irq_handler idx
.globl hal_fr30_irq_\idx
hal_fr30_irq_\idx:
st r0, @-r15
ldi:32 #hal_vsr_table + \idx * 4, r0
ld @r0, r0
jmp:d @r0
ldi:8 #\idx, r0
.endm
hal_fr30_irq_handler 15
hal_fr30_irq_handler 16
hal_fr30_irq_handler 17
hal_fr30_irq_handler 18
hal_fr30_irq_handler 19
hal_fr30_irq_handler 20
hal_fr30_irq_handler 21
hal_fr30_irq_handler 22
hal_fr30_irq_handler 23
hal_fr30_irq_handler 24
hal_fr30_irq_handler 25
hal_fr30_irq_handler 26
hal_fr30_irq_handler 27
hal_fr30_irq_handler 28
hal_fr30_irq_handler 29
hal_fr30_irq_handler 30
hal_fr30_irq_handler 31
hal_fr30_irq_handler 32
hal_fr30_irq_handler 33
hal_fr30_irq_handler 34
hal_fr30_irq_handler 35
hal_fr30_irq_handler 36
hal_fr30_irq_handler 37
hal_fr30_irq_handler 38
hal_fr30_irq_handler 39
hal_fr30_irq_handler 40
hal_fr30_irq_handler 41
hal_fr30_irq_handler 42
hal_fr30_irq_handler 43
hal_fr30_irq_handler 44
hal_fr30_irq_handler 45
hal_fr30_irq_handler 46
hal_fr30_irq_handler 47
hal_fr30_irq_handler 48
hal_fr30_irq_handler 49
hal_fr30_irq_handler 50
hal_fr30_irq_handler 51
hal_fr30_irq_handler 52
hal_fr30_irq_handler 53
hal_fr30_irq_handler 54
hal_fr30_irq_handler 55
hal_fr30_irq_handler 56
hal_fr30_irq_handler 57
hal_fr30_irq_handler 58
hal_fr30_irq_handler 59
hal_fr30_irq_handler 60
hal_fr30_irq_handler 61
hal_fr30_irq_handler 62
hal_fr30_irq_handler 63
.data
//
// "Vectors" - fixed location data items
// This section contains any data which might be shared between
// an eCos application and any other environment, e.g. the debug
// ROM.
//
.section ".fixed_vectors"
// Space for the virtual vectors
.balign 4
// Vectors used to communicate between eCos and ROM environments
.globl hal_virtual_vector_table
hal_virtual_vector_table:
.rept 64 // CYGNUM_CALL_IF_TABLE_SIZE
.long 0
.endr
.globl hal_vsr_table
hal_vsr_table:
.rept CYGNUM_HAL_VSR_COUNT // exceptions & interrupts
.long 0
.endr
#==============================================================================
# Initial and interrupt stack
.section ".bss"
.balign 4
.global cyg_interrupt_stack_base
cyg_interrupt_stack_base:
__interrupt_stack_base:
.rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE
.byte 0
.endr
.balign 4
.global cyg_interrupt_stack
cyg_interrupt_stack:
__interrupt_stack:
.long 0,0,0,0,0,0,0,0
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
.global __stub_stack_base
__stub_stack_base:
.rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE
.byte 0
.endr
.balign 4
.global __stub_stack
__stub_stack:
.long 0,0,0,0,0,0,0,0
#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
.balign 4
__user_stack_base:
// FIXME TODO import symbolic constant from C-code
.rept 4532
.byte 0
.endr
.balign 4
__user_stack:
.long 0
#------------------------------------------------------------------------------
# end of vectors.S
Go to most recent revision | Compare with Previous | Blame | View Log