📄 vectors.s
字号:
|==========================================================================
|
| vectors.S
|
| ColdFire 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) 2006 eCosCentric Ltd.
|
| 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.
| -------------------------------------------
|###ECOSGPLCOPYRIGHTEND####
|=============================================================================
|#####DESCRIPTIONBEGIN####
|
| Author(s): Enrico Piria
| Contributors: Wade Jensen
| Date: 2005-25-06
| Purpose: ColdFire exception vectors
| Description: This file contains the first level default VSRs
| that save and restore state for both exceptions and
| interrupts.
|
|####DESCRIPTIONEND####
|==========================================================================
#include <pkgconf/system.h>
#include <pkgconf/hal.h>
#include <cyg/hal/cf_offsets.inc>
#include <cyg/hal/arch.inc>
#include <cyg/hal/variant.inc>
#ifdef CYGPKG_KERNEL
#include <pkgconf/kernel.h>
#endif
| ----------------------------------------------------------------------------
| Hardware reset vector
.section ".boot","x"
.balign 4
.globl cyg_hal_reset_vsr
cyg_hal_reset_vsr:
| Define the entry point for the linker.
.globl _start
_start:
| Make sure that all interrupts are masked.
hal_cpu_int_disable
| Initial setup. Just do the minimum to be able to perform
| initialization in C.
| Initialize CPU variant
hal_cpu_init
| Platform specific hardware initialization.
| This may include memory controller initialization.
hal_hardware_init
| Setup boot stack
hal_boot_stack_init
| Set up the initial frame pointer.
lea 0,%fp
link %fp,#0
| Call the C routine to complete the reset process.
.extern hal_reset
jsr hal_reset
| If we return, stop.
9:
stop #0x2000
bra 9b
| ----------------------------------------------------------------------------
| Default exception vector handler
|
| The default handler for all machine exceptions. We save the
| machine state and call the default C exception handler. This routine passes a
| pointer to the saved state to the C exception handler. The stack pointer in
| the saved state points to the the sp before the exception.
| The format/vector word in the exception stack contains the vector
| number.
| void hal_exception_handler(CYG_WORD vector, HAL_SavedRegisters *regs);
.text
.balign 4
.globl cyg_hal_default_exception_vsr
cyg_hal_default_exception_vsr:
| Disable all interrupts
hal_cpu_int_disable
| Preserve the entire state.
| Allocate space for all registers (including the stack pointer).
| Write all registers to the stack space.
lea.l -CYGARC_CF_EXCEPTION_DECREMENT(%sp),%sp
movem.l %d0-%d7,CYGARC_CFREG_DREGS(%sp)
movem.l %a0-%a6,CYGARC_CFREG_AREGS(%sp)
#ifdef CYGHWR_HAL_COLDFIRE_MAC
save_mac_registers %d0
#endif
| Write the original stack pointer value to the stack.
| The format/vector word, sr, and pc are already on the stack.
find_original_sp %d0
move.l %d0,CYGARC_CFREG_SP(%sp)
| Calculate the vector number. The format/vector word on the stack
| contains the vector number.
move.w CYGARC_CF_FMTVECWORD(%sp),%d0
and.l #0x000003fc,%d0
lsr.l #2,%d0
| Pass a pointer to the saved state to the exception handler.
pea.l (%sp)
| Push the vector number parameter.
move.l %d0,-(%sp)
| Call the default exception handler. This routine may modify
| the exception context.
.extern hal_exception_handler
jsr hal_exception_handler
| Remove the vector number and the state pointer from the stack.
addq.l #2*4,%sp
| Get a pointer to the location following the exception context.
find_original_sp %d0
| Restore all of the registers that we do not need in the following
| code. We will copy all registers that are not restored here
| to the new stack before restoring them.
#ifdef CYGHWR_HAL_COLDFIRE_MAC
restore_mac_registers %d0
#endif
movem.l CYGARC_CFREG_D2(%sp),%d2-%d7
movem.l CYGARC_CFREG_A1(%sp),%a1-%a6
| Load the address of the new SP.
move.l CYGARC_CFREG_SP(%sp),%d1
| We now have:
| d0.l : original stack pointer
| d1.l : final stack pointer
| ColdFire programmer's manual doesn't tell if rte instruction expects
| the stack frame to be aligned at 32-bit boundaries.
| So, we align the new stack value, and adjust the format field
| accordingly. At the end of rte instruction the stack will thus point
| to the desired location.
| Compare the new stack address to the end of the exception context.
| This will tell us the order that we need to copy the exception
| stack and the remaining registers from the old exception context to
| the new one. The order is important because the stack frames might
| overlap.
cmp.l %d0,%d1
| If the new SP and the old one coincide.
beq 2f
| If the new SP is at a higher address than the old one.
bgt 1f
| The new SP is at a lower address than the old one. Copy from the
| lowest address to the highest address.
| Align stack at longword boundary
move.l %d1,%d0
and.l #0xfffffffc,%d0
move.l %d0,%a0
| Allocate new frame
sub.l #CYGARC_CF_CONTEXT_SIZE,%a0
| Copy D0, D1, A0, FVW, SR, and PC from the old stack to the new stack.
| Note that we copy in ascending order.
| Copy D0, D1, A0
move.l CYGARC_CFREG_D0(%sp),CYGARC_CFREG_D0(%a0)
move.l CYGARC_CFREG_D1(%sp),CYGARC_CFREG_D1(%a0)
move.l CYGARC_CFREG_A0(%sp),CYGARC_CFREG_A0(%a0)
| Based on target SP address, construct new format field
and.l #0x00000003,%d1
or.l #0x4,%d1
lsl.l #8,%d1
lsl.l #4,%d1
| Load old format field
move.w CYGARC_CF_FMTVECWORD(%sp),%d0
| Clear old format field
and.l #0x0fff,%d0
| Write the new one
or.l %d1,%d0
move.w %d0,CYGARC_CF_FMTVECWORD(%a0)
| Copy SR and PC
move.w CYGARC_CF_SR(%sp),CYGARC_CF_SR(%a0)
move.l CYGARC_CFREG_PC(%sp),CYGARC_CFREG_PC(%a0)
| A0 points to the top of the new stack
move.l %a0,%sp
| Restore remaining registers and exit
jmp 2f
1:
| The new SP is at a higher address than the old one. Copy from the
| highest address to the lowest address.
| Align stack at longword boundary
move.l %d1,%d0
and.l #0xfffffffc,%d0
move.l %d0,%a0
| Allocate new frame
sub.l #CYGARC_CF_CONTEXT_SIZE,%a0
| Copy D0, D1, A0, FVW, SR, and PC from the old stack to the new stack.
| Note that we copy in descending order.
| Copy PC and SR
move.l CYGARC_CFREG_PC(%sp),CYGARC_CFREG_PC(%a0)
move.w CYGARC_CF_SR(%sp),CYGARC_CF_SR(%a0)
| Based on target SP address, construct new format field
and.l #0x00000003,%d1
or.l #0x4,%d1
lsl.l #8,%d1
lsl.l #4,%d1
| Load old format field
move.w CYGARC_CF_FMTVECWORD(%sp),%d0
| Clear old format field
and.l #0x0fff,%d0
| Write the new one
or.l %d1,%d0
move.w %d0,CYGARC_CF_FMTVECWORD(%a0)
| Copy A0, D1, D0
move.l CYGARC_CFREG_A0(%sp),CYGARC_CFREG_A0(%a0)
move.l CYGARC_CFREG_D1(%sp),CYGARC_CFREG_D1(%a0)
move.l CYGARC_CFREG_D0(%sp),CYGARC_CFREG_D0(%a0)
| A0 points to the top of the new stack
move.l %a0,%sp
2:
| Restore remaining registers
move.l CYGARC_CFREG_D0(%sp),%d0
move.l CYGARC_CFREG_D1(%sp),%d1
move.l CYGARC_CFREG_A0(%sp),%a0
add.l #CYGARC_CF_EXCEPTION_DECREMENT,%sp
| Return from exception
rte
| ----------------------------------------------------------------------------
| Spurious interrupt vector handler
|
| Used for spurious and uninitialized interrupts.
| It is unknown at which priority spurious interrupts are generated. So, the
| safest thing to do is to disable all interrupts while processing spurious
| ones.
.text
.balign 4
.globl cyg_hal_default_spurious_vsr
cyg_hal_default_spurious_vsr:
#ifndef CYGIMP_HAL_COMMON_INTERRUPTS_IGNORE_SPURIOUS
| Disable all interrupts. On the first instruction, interrupt sampling
| is always disabled.
hal_cpu_int_disable
| Preserve all registers that this handler needs to preserve.
| The C code will preserve all other registers.
int_pres_regs
| Pass a pointer to the saved state to the interrupt handler.
pea.l (%sp)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -