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

📄 vectors.s

📁 开放源码实时操作系统源码.
💻 S
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************
vectors.S -- mcf52xx exception vectors
*****************************************************************************/
#####ECOSGPLCOPYRIGHTBEGIN####
## -------------------------------------------
## This file is part of eCos, the Embedded Configurable Operating System.
## Copyright (C) 1998, 1999, 2000, 2001, 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####
##=============================================================================

#include <pkgconf/system.h>
#include <pkgconf/hal.h>

#ifdef CYGPKG_KERNEL
#include <pkgconf/kernel.h>
#endif /* CYGPKG_KERNEL */

/****************************************************************************/

        .file   "vectors.S"

/****************************************************************************/

/****************************************************************************/

/*      The mcf52xx core allows us to move the VBR to our RAM vector  table */
/* at cyg_hal_vsr_table provided the table is at a 1MB boundary.            */

/****************************************************************************/
/*      ROM vector table                                                    */

/*      Create the ROM vector table.   We  use  this  table  to  initialize */
/* cyg_hal_vsr_table which we point the VBR to.                             */

        .macro  hw_vsr name
        .long   hw_vsr_\name
        .endm

        .section ".romvec","ax"

        .globl  rom_vsr_table
rom_vsr_table:

        /*   0 - Initial SSP                                                */
        hw_vsr  stack

        /*   1 - Initial PC                                                 */
        hw_vsr  reset

        /*   2-24 - Default exception handlers                              */
        .rept   24-2+1
        hw_vsr  default
        .endr

        /*   25-31 - Autovector interrupts 1-7                              */
        .rept   31-25+1
        hw_vsr  autovec
        .endr

        /*   32-63 - Default exception handlers                             */
        .rept   63-32+1
        hw_vsr  default
        .endr

        /*   64-255 - User interrupt vectors                                */
        .rept   255-64+1
        hw_vsr  interrupt
        .endr

        .equ    rom_vsr_table_size, . - rom_vsr_table

/****************************************************************************/
/*      The default excetpion vector handler                                */

/*      The default handler  for  all  machine  exceptions.   We  save  the */
/* machine state and call the default C VSR handler.  This routine passes a */
/* pointer to the saved state to the  C VSR handler.  The stack pointer  in */
/* the saved state  points to the  byte following the  PC on the  exception */
/* stack (the  sp before  the exception).   The format/vector  word in  the */
/* exception stack contains the vector number.                              */

/*
void hal_default_exception_handler(CYG_WORD vector, HAL_SavedRegisters *regs);
*/

        .text
        .balign 4
hw_vsr_default:

        lea.l   -(16*4)(%sp),%sp            /*   Preserve the entire state. */
        movem.l %d0-%d7/%a0-%a6,(%sp)       /* Allocate   space   for   all */
        lea.l   ((16+1+1)*4)(%sp),%a0       /* registers   (including   the */
        move.l  %a0,(15*4)(%sp)             /* stack pointer).   Write  all */
                                            /* registers   to   the   stack */
                                            /* space.  Write  the  original */
                                            /* stack pointer  value to  the */
                                            /* stack.   The   format/vector */
                                            /* word, sr, and pc are already */
                                            /* on the stack.                */

        move.w  (16*4)(%sp),%d0             /*   Calculate    the    vector */
        and.l   #0x000003fc,%d0             /* number.   The  format/vector */
        lsr.l   #2,%d0                      /* word on  the stack  contains */
                                            /* the vector number.           */

        pea.l   (%sp)                       /*   Pass  a  pointer  to   the */
                                            /* saved state to the exception */
                                            /* handler.                     */

        move.l  %d0,-(%sp)                  /*   Push  the  vector   number */
                                            /* parameter.                   */

        .extern hal_default_exception_handler   /*   Call    the    default */
        jbsr    hal_default_exception_handler   /* exception   VSR.    This */
                                                /* routine     may     (and */
                                                /* probably  will)   modify */
                                                /* the exception context.   */

        addq.l  #2*4,%sp                    /*   Remove the  vector  number */
                                            /* and the  state pointer  from */
                                            /* the stack.                   */

                                            /*   Restore the state.   There */
                                            /* is a chance that a  debugger */
                                            /* changed the state (including */
                                            /* the   stack   pointer,   PC, */
                                            /* etc.).   We  must  be   very */
                                            /* careful to  restore the  new */
                                            /* state     without      first */
                                            /* overwriting  the  values  on */
                                            /* the stack.  We must copy the */
                                            /* format/vector word, SR,  and */
                                            /* PC to the new stack, but  we */
                                            /* must make sure that the  new */
                                            /* stack is not  in the  middle */
                                            /* of   our    current    stack */
                                            /* variables that we are using. */

        movem.l (%sp),%d0-%d7/%a0-%a4       /*   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.              */

        move.l  (15*4)(%sp),%a6             /*   Load the  address  of  the */
                                            /* new SP.                      */

        lea.l   (18*4)(%sp),%a5             /*   Get  a   pointer  to   the */
                                            /* location    following    the */
                                            /* exception context.           */

        cmp.l   %a5,%a6                     /*   Compare  the   new   stack */
        jcc     1f   /*jcc=jhs*/            /* 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 */
                                            /* exception context to the new */
                                            /* stack.    The    order    is */
                                            /* important because the  stack */
                                            /* frames might  (and  in  many */
                                            /* cases do) overlap.           */

                                            /*   The new SP  is at a  lower */
                                            /* address than the end of  the */
                                            /* exception   context.    Copy */
                                            /* from the  lowest address  to */
                                            /* the highest address.         */

        lea.l   -5*4(%a6),%a6               /*   Copy A5, A6, FVW, SR,  and */
        move.l  -5*4(%a5),(%a6)             /* PC from the old stack to the */
        move.l  -4*4(%a5),1*4(%a6)          /* new stack.  Note that we  do */
        move.l  -2*4(%a5),3*4(%a6)          /* not copy the SP location but */
        move.l  -1*4(%a5),4*4(%a6)          /* we leave a  space for it  on */
                                            /* the new stack.  If we do not */
                                            /* leave  space  for  the   SP, */
                                            /* there is  a  possibility  of */
                                            /* overwriting  some   of   our */
                                            /* data.  Note that we copy  in */
                                            /* increasing order.            */

        move.l  %a6,%sp                     /*   A6 points to  the  top  of */
        move.l  (%sp)+,%a5                  /* the  new   stack  with   our */
        move.l  (%sp)+,%a6                  /* registers  on  it.   Restore */
        addq.l  #1*4,%sp                    /* the remaining registers  and */
        rte                                 /* use the  exception stack  to */
                                            /* return.  Note  that we  also */
                                            /* remove the unused space left */
                                            /* for the SP.                  */

1:

        move.l  -(%a5),-(%a6)               /*   The new SP is at a  higher */
        move.l  -(%a5),-(%a6)               /* or the same  address as  the */
        subq.l  #4,%a5                      /* end   of    the    exception */
        move.l  -(%a5),-(%a6)               /* context.   Copy   from   the */
        move.l  -(%a5),-(%a6)               /* highest   address   to   the */
                                            /* lowest address.   Note  that */
                                            /* we do  not  copy  the  stack */
                                            /* pointer.   When  copying  in */
                                            /* this direction, there is  no */
                                            /* reason to  leave  space  for */
                                            /* the stack pointer.           */

        move.l  %a6,%sp                     /*   A6 points to  the  top  of */
        move.l  (%sp)+,%a5                  /* the  new   stack  with   our */
        move.l  (%sp)+,%a6                  /* registers  on  it.   Restore */
        rte                                 /* the remaining registers  and */
                                            /* use the  exception stack  to */
                                            /* return.                      */

/****************************************************************************/
/*      User interrupt vector handler                                       */

/*      Control is transferred here from a user interrupt vector (#64-255). */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -