⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vectors.s

📁 开放源码实时操作系统源码.
💻 S
📖 第 1 页 / 共 2 页
字号:
|==========================================================================
|
|      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 + -