Mercurial > flash_v2
diff packages/hal/mn10300/arch/current/src/vectors.S @ 0:3111d98ba7b3 ecos-v1_1-release
Initial commit of eCos version 1.1
| author | jlarmour |
|---|---|
| date | Tue, 11 May 1999 11:16:07 +0000 |
| parents | |
| children | 443894e2e912 |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/packages/hal/mn10300/arch/current/src/vectors.S @@ -0,0 +1,698 @@ +##============================================================================= +## +## vectors.S +## +## MN10300 exception vectors +## +##============================================================================= +#####COPYRIGHTBEGIN#### +# +# ------------------------------------------- +# The contents of this file are subject to the Cygnus eCos Public License +# Version 1.0 (the "License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://sourceware.cygnus.com/ecos +# +# 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 Cygnus Operating System, released +# September 30, 1998. +# +# The Initial Developer of the Original Code is Cygnus. Portions created +# by Cygnus are Copyright (C) 1998 Cygnus Solutions. All Rights Reserved. +# ------------------------------------------- +# +#####COPYRIGHTEND#### +##============================================================================= +#######DESCRIPTIONBEGIN#### +## +## Author(s): nickg +## Contributors: nickg +## Date: 1997-10-16 +## Purpose: MN10300 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> + +#ifdef CYGPKG_KERNEL + +#include <pkgconf/kernel.h> + +#endif + + .extern _cyg_instrument + + +##----------------------------------------------------------------------------- +## Register addresses and initialization values + + .equ IOBCTR ,0x32000010 + .equ MEMCTR0 ,0x32000020 + .equ MEMCTR1 ,0x32000022 + .equ MEMCTR2 ,0x32000024 + .equ MEMCTR3 ,0x32000026 + .equ MEMCTR4 ,0x32000028 + .equ MEMCTR5 ,0x3200002a + .equ MEMCTR6 ,0x3200002c + .equ MEMCTR7 ,0x3200002e + .equ DRAMCTR ,0x32000040 + .equ REFCNT ,0x32000042 + +#ifdef CYG_HAL_MN10300_STDEVAL1 + .equ INIT_MEMCTR0,0x1200 # 2wait + .equ INIT_MEMCTR1,0x0120 # 1wait-32bit- + .equ INIT_MEMCTR2,0x0065 + .equ INIT_DRAMCTR,0x0287 + .equ INIT_REFCNT,0x00eb +#endif + + .equ P2OUT ,0x36008004 + .equ P2MD ,0x36008024 + .equ P2SS ,0x36008044 + .equ P2DIR ,0x36008064 + + .equ INIT_P2MD,0xf0 + .equ INIT_P2DIR,0xff + +##----------------------------------------------------------------------------- + + .macro led val + movm [d2],(sp) + mov \val,d2 + asl 4,d2 + movbu d2,(P2OUT) + movm (sp),[d2] + .endm + + +##----------------------------------------------------------------------------- + + .file "vectors.S" + +##----------------------------------------------------------------------------- + + .section ".vectors","ax" + + .globl reset_vector + +reset_vector: + # Reset vector + jmp _start + + .p2align 3 + + # NMI vector + jmp __nmi + + .p2align 3 + + # Trap vector + jmp __trap + +##----------------------------------------------------------------------------- +## NMI vector + + .globl __nmi +__nmi: + add -4,sp # space for SP + movm [d2,d3,a2,a3,other],(sp) # push all registers + mov (_hal_vsr_table+28),a0 + jmp (a0) + +##----------------------------------------------------------------------------- +## Trap vector + + .globl __trap +__trap: + add -8,sp # space for SP and PSW + movm [d2,d3,a2,a3,other],(sp) # push all registers + mov (_hal_vsr_table+32),a0 + jmp (a0) + +##----------------------------------------------------------------------------- +## Macro to define a hardware VSR + + .macro hardware_vector name + .globl __hardware_vector_\name +__hardware_vector_\name: + add -4,sp # space for SP + movm [d2,d3,a2,a3,other],(sp) # push all registers + mov \name,d0 # d0 = vector id + mov d0,(0,sp) # save in dummy stack loc + mov _hal_vsr_table,a0 # a0 = vsr table + add \name<<2,a0 # a0 = &required vsr + mov (a0),a0 # a0 = required vsr + jmp (a0) # go there + .endm + +##----------------------------------------------------------------------------- +## Hardware Vectors. These are pointed to by the registers in +## mn10300_interrupt_vectors and must be in the range 0x4000XXXX. + + hardware_vector 0 + hardware_vector 1 + hardware_vector 2 + hardware_vector 3 + hardware_vector 4 + hardware_vector 5 + hardware_vector 6 + +##----------------------------------------------------------------------------- +## Startup code + + .text + + .globl _start +_start: + +#if defined(CYG_HAL_MN10300_STDEVAL1) + mov INIT_MEMCTR0,d2 + movhu d2,(MEMCTR0) + + mov INIT_MEMCTR1,d2 + movhu d2,(MEMCTR1) + + mov INIT_MEMCTR2,d2 + movhu d2,(MEMCTR2) + + mov INIT_REFCNT,d2 + movhu d2,(REFCNT) + + mov INIT_DRAMCTR,d2 + movhu d2,(DRAMCTR) + + # Set up LED + + mov INIT_P2MD,d2 + movbu d2,(P2MD) + + mov INIT_P2DIR,d2 + movbu d2,(P2DIR) + + +#endif + + # Set up the PSW + + mov 0x0700,d0 + mov d0,psw + + # set up stack + + mov __interrupt_stack,a0 + sub 8,a0 + mov a0,sp + +#ifdef CYG_HAL_STARTUP_ROM + + # Copy data from ROM to RAM + + mov __rom_data_start,a0 + mov __ram_data_end,a1 + mov __ram_data_start,a2 + + cmp a2,a1 + beq 8f +1: + movbu (a0),d0 + movbu d0,(a2) + inc a0 + inc a2 + cmp a2,a1 + bne 1b +8: + +#endif + + # Clear BSS + mov __bss_start,a0 + mov _end,a1 + + cmp a0,a1 + beq 8f + clr d0 +1: + movbu d0,(a0) + inc a0 + cmp a0,a1 + bne 1b +8: + # Install interrupt vectors + +#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_MN10300_SIM) + mov _mn10300_interrupt_vectors,a0 + mov __hardware_vector_0,d0 + movhu d0,(0,a0) + mov __hardware_vector_1,d0 + movhu d0,(4,a0) + mov __hardware_vector_2,d0 + movhu d0,(8,a0) + mov __hardware_vector_3,d0 + movhu d0,(12,a0) + mov __hardware_vector_4,d0 + movhu d0,(16,a0) + mov __hardware_vector_5,d0 + movhu d0,(20,a0) + mov __hardware_vector_6,d0 + movhu d0,(24,a0) +#endif +#if defined(CYG_HAL_STARTUP_RAM) && !defined(CYG_HAL_MN10300_SIM) + + # init vsr table in SRAM where the ROM + # vectors the interrupts. + + mov _hal_vsr_table,a0 + mov __default_interrupt_vsr,d0 + mov d0,(0,a0) + mov d0,(4,a0) + mov d0,(8,a0) +#ifndef CYG_HAL_USE_ROM_MONITOR_CYGMON + # When using Cygmon, leave level 3 for GDB + # Ctrl-C interrupts. + mov d0,(12,a0) +#endif + mov d0,(16,a0) + mov d0,(20,a0) + mov d0,(24,a0) + mov __default_nmi_vsr,d0 + mov d0,(28,a0) + mov __default_trap_vsr,d0 + mov d0,(32,a0) +#endif + + # Call constructors + + .extern _cyg_hal_invoke_constructors + call _cyg_hal_invoke_constructors,[],0 + + # Call cyg_start + clr d0 + mov d0,(4,sp) + + .extern _cyg_start + call _cyg_start,[],0 + +9: + bra 9b # Loop if we return + +##----------------------------------------------------------------------------- +## Debug code to count interrupts on the led. + +#ifdef CYG_HAL_MN10300_STDEVAL1 + + .macro show_interrupts + mov (led_count),d1 + inc d1 +# cmp 20000,d1 +# ble 2f + mov 0,d1 + movbu (led_value),d0 + movbu d0,(P2OUT) + add 16,d0 + cmp 0x90,d0 + bne 1f + mov 0,d0 +1: + movbu d0,(led_value) +2: + mov d1,(led_count) + .endm + +#else + + .macro show_interrupts + .endm + +#endif + +##----------------------------------------------------------------------------- +## The following macros are defined depending on whether the HAL is configured +## to support the kernel or not. + +#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT + + .extern __18Cyg_Scheduler_Base.sched_lock + + # Increment the scheduler lock + + .macro increment_sched_lock reg=d0 + mov (__18Cyg_Scheduler_Base.sched_lock),\reg + inc \reg + mov \reg,(__18Cyg_Scheduler_Base.sched_lock) + .endm + +#else + + .macro increment_sched_lock reg=d0 + .endm + +#endif + +##----------------------------------------------------------------------------- +## The following macros are defined depending on whether the Interrupt +## system is using isr tables or chaining. + +#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN + +#define CYG_ISR_TABLE_SIZE 7 + +#if defined(CYG_HAL_MN10300_MN103000) + + # decode the interrupt + .macro decode_interrupt dreg,areg,dreg1 + mov _mn10300_interrupt_control,\areg + movhu (0x100,\areg),\dreg # dreg = IAGR + movhu (\dreg,\areg),\dreg1 # dreg1 = IGR[dreg] + and 0xf,\dreg1 # dreg1 = ID0..3 + mov hal_lsbit_table,\areg # areg = ls bit table + movbu (\dreg1,\areg),\dreg1 # dreg1 = ls bit index + add \dreg,\dreg1 # dreg1 = word index of isr + mov (0,a2),\dreg # dreg = vector priority + mov \dreg1,(0,a2) # store real vector in saved state + asl 2,\dreg # dreg = byte index of isr + .endm + +#elif defined(CYG_HAL_MN10300_MN103002) + + # decode the interrupt + .macro decode_interrupt dreg,areg,dreg1 + mov _mn10300_interrupt_control,\areg + movhu (0x100,\areg),\dreg1 # dreg1 = IAGR + mov (0,a2),\dreg # dreg = vector priority + mov \dreg1,(0,a2) # store real vector in saved state + asl 2,\dreg # dreg = byte index of isr + .endm + +#endif + +#else + +#if defined(CYG_HAL_MN10300_MN103000) + +#define CYG_ISR_TABLE_SIZE 100 + + # decode the interrupt + .macro decode_interrupt dreg,areg,dreg1 + mov _mn10300_interrupt_control,\areg + movhu (0x100,\areg),\dreg # dreg = IAGR + movhu (\dreg,\areg),\dreg1 # dreg1 = IGR[dreg] + and 0xf,\dreg1 # dreg1 = ID0..3 + mov hal_lsbit_table,\areg # areg = ls bit table + movbu (\dreg1,\areg),\dreg1 # dreg1 = ls bit index + add \dreg1,\dreg # dreg = word index of isr + mov \dreg,(0,a2) # store real vector in saved state + asl 2,\dreg # dreg = byte index of isr + .endm + + +#elif defined(CYG_HAL_MN10300_MN103002) + +#define CYG_ISR_TABLE_SIZE 34 + + # decode the interrupt + .macro decode_interrupt dreg,areg,dreg1 + mov _mn10300_interrupt_control,\areg + movhu (0x100,\areg),\dreg # dreg = IAGR + mov \dreg,(0,a2) # store real vector in saved state + add 12,\dreg # skip NMI vectors + .endm + +#endif + +#endif + +##----------------------------------------------------------------------------- +## Default interrupt VSR + + .text + .globl __default_interrupt_vsr +__default_interrupt_vsr: + + # We come here with all the registers pushed + # onto the stack. + + increment_sched_lock + +#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK + # Increment interrupt nesting counter + mov __interrupt_stack,a0 # A0 = interrupt stack top + mov sp,a2 # A2 = SP + cmp __interrupt_stack_base,a2 # compare with base of stack + blt 1f # if lt switch to int stack + cmp a0,a2 # compare sp with stack top + ble 8f # if le already on istack +1: + mov a0,sp # switch to new SP +8: + movm [a2],(sp) # save old SP + +#else + mov sp,a2 # A2 = saved thread state +#endif + + # Here A2 -> saved thread state on the threads own + # stack. We will be executing either on the same stack + # or on the interrupt stack, depending on config options. + + decode_interrupt d3,a3,d0 + + # Here D3 contains the table byte offset of the vector to + # call. On the MN103000 this needs to be shifted right by + # two to derive the vector. On the MN103002 this correponds + # exactly to the vector used to attach it. + +#if defined(CYGPKG_KERNEL_INSTRUMENT) && defined(CYGDBG_KERNEL_INSTRUMENT_INTR) + + # Call cyg_instrument to record that this interrupt is being raised. + + add -16,sp # make space for return link + args + mov 0x0301,d0 # d0 = type = INTR,RAISE + mov (0,a2),d1 # d1 = arg1 = vector + mov d3,(12,sp) # (12,sp) = arg2 = table offset + calls _cyg_instrument # call instrumentation + add 16,sp # pop space + +#endif + +#ifdef CYGSEM_HAL_COMMON_INTERRUPTS_ALLOW_NESTING + + # To allow nested interrupts, we set the IE bit. We do + # not touch the IPL bits, so only higher priority interrupts + # will be nested on top of us. Also, new interrupts will not + # be delivered until the ISR calls + # Cyg_Interrupt::acknowledge_interrupt(). At some future point + # we may want to do the ack stuff here to allow immediate nesting. + + or 0x0800,psw + +#endif + mov _hal_interrupt_handlers,a0 # a0 = isr table + mov (d3,a0),a0 # a0 = isr + + mov _hal_interrupt_data,a1 # a1 = data table + mov (d3,a1),d1 # d1 = isr data + + mov (0,a2),d0 # d0 = vector. (d3 is... + # ...adjusted for table reads) +#if defined(CYG_HAL_MN10300_MN103000) + lsr 2,d0 # d0 = vector number +#endif + add -16,sp # make space for return link + + calls (a0) # call isr + + # on return d0 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. + + # D3 is defined to be saved across procedure calls, and + # should still contain the vector byte index. Similarly, + # A2 should still point to the saved machine state. + +#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. + + add 16,sp # pop call frame from int stack + movm (sp),[a3] # pop old sp + mov a3,sp # put in SP + + add -16,sp # make call frame for call + +#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. + + # Using the vector offset in D3, get the interrupt object pointer + # into D1. + mov _hal_interrupt_objects,a0 # a0 = object table + mov (d3,a0),d1 # d1 = object + + # Even when this is not the last nested interrupt, we must call + # _interrupt_end() to post the DSR and decrement the scheduler + # lock. + + # interrupt_end must be called with interrupts enabled. + # At this point we restore the PSW of the code we interrupted + # to get the IPL bits back. By definition this PSW must have + # interrupts enabled. + mov (52,a2),d2 + + mov d2,psw + + mov a2,(12,sp) # arg3 = saved state. + + calls _interrupt_end # call interrupt end fn +#endif + + add 16,sp # pop return link + + show_interrupts + + movm (sp),[d2,d3,a2,a3,other] # pop regs + add 4,sp + rti # and return + +hal_lsbit_table: + .byte 0, 0, 1, 0 + .byte 2, 0, 1, 0 + .byte 3, 0, 1, 0 + .byte 2, 0, 1, 0 + + +##----------------------------------------------------------------------------- +## Default NMI VSR + + .globl _exception_handler + + .text + .globl __default_nmi_vsr +__default_nmi_vsr: + + # We come here with all the registers saved + # on the stack. + + mov sp,a1 # a1 = saved state + mov a1,d0 # d0 = arg1 = saved state + + add -16,sp # return link + args + mov 0,d1 # 0 == NMI trap + mov d1,(16,sp) # save in spare save slot + + calls _exception_handler # call C code + add 16,sp # pop args + movm (sp),[d2,d3,a2,a3,other] # pop all registers + add 4,sp + rti + +##----------------------------------------------------------------------------- +## Default TRAP VSR + + .text + .globl __default_trap_vsr +__default_trap_vsr: + + # We come here with all the registers saved + # on the stack. + + add -8,sp # return link + arg + mov 3,d1 # 3 == TRAP trap + mov d1,(0,sp) # save in spare save slot + calls _exception_handler # call C code + add 8,sp # pop args + movm (sp),[d2,d3,a2,a3,other] # pop all registers + add 4,sp + rets + +##----------------------------------------------------------------------------- +## VSR table. The VSRs pointed to by this table are called from the stubs +## connected to the hardware. + +#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_MN10300_SIM) + + .data + + .globl _hal_vsr_table +_hal_vsr_table: + .long __default_interrupt_vsr + .long __default_interrupt_vsr + .long __default_interrupt_vsr + .long __default_interrupt_vsr + .long __default_interrupt_vsr + .long __default_interrupt_vsr + .long __default_interrupt_vsr + .long __default_nmi_vsr + .long __default_trap_vsr + +#endif + +##----------------------------------------------------------------------------- +## Interrupt tables + + .section ".bss" + + .globl _hal_interrupt_handlers +_hal_interrupt_handlers: + .rept CYG_ISR_TABLE_SIZE + .long 0 + .endr + + .globl _hal_interrupt_data +_hal_interrupt_data: + .rept CYG_ISR_TABLE_SIZE + .long 0 + .endr + + .globl _hal_interrupt_objects +_hal_interrupt_objects: + .rept CYG_ISR_TABLE_SIZE + .long 0 + .endr + + +##----------------------------------------------------------------------------- +## Temporary interrupt stack + + .section ".bss" + + .balign 16 +__interrupt_stack_base: + .rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE + .byte 0 + .endr + .balign 16 +__interrupt_stack: + + .long 0,0,0,0,0,0,0,0 + +##----------------------------------------------------------------------------- + +#ifdef CYG_HAL_MN10300_STDEVAL1 + .data +## Keep alignment to work around compiler/linker bug +led_count: .long 0 +led_value: .byte 0x40 +led_foo1: .byte 0x00 +led_foo2: .byte 0x00 +led_foo3: .byte 0x00 +#endif + +##----------------------------------------------------------------------------- +## end of vectors.S +
