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

📄 vectors.s

📁 开放源码实时操作系统源码.
💻 S
📖 第 1 页 / 共 2 页
字号:

/*      Before branching  to common  code, load  a value  to translate  the */
/* vector table offset to the ISR  table  offset.   The  ISR  vector  table */
/* contains  the  autovectors  (0-6)  followed  by  the  interrupt  vectors */
/* (7-198).                                                                 */

        .equ      int_pres_regs_sz,((2+3)*4)
        .macro    int_pres_regs
        lea.l     -int_pres_regs_sz(%sp),%sp
        movem.l   %d0-%d2/%a0-%a1,(%sp)
        .endm
        .macro    int_rest_regs
        movem.l   (%sp),%d0-%d2/%a0-%a1
        lea.l     int_pres_regs_sz(%sp),%sp
        .endm

        .text
        .balign 4
hw_vsr_interrupt:

        int_pres_regs                       /*   Preserve   all   registers */
                                            /* that this ISR routine  needs */
                                            /* to  preserve.   The  C  code */
                                            /* will  preserve   all   other */
                                            /* registers.                   */

        move.l #(-64+7)*4,%d0               /*   Adding this  value to  the */
                                            /* vector  table  offset   will */
                                            /* result in the  corresponding */
                                            /* offset into the ISR table.   */

        /*   Fall through to common code.                                   */

hw_vsr_int_common:                          /*   Common code.               */

        /*   d0.l: Contains a value to translate the vector table offset to */
        /* the ISR table offset.                                            */

        move.w  int_pres_regs_sz(%sp),%d1   /*   Calculate    the    vector */
        and.l   #0x000003fc,%d1             /* offset.   The  format/vector */
                                            /* word on  the stack  contains */
                                            /* the vector number.  Mask off */
                                            /* all unused  bits.   The  bit */
                                            /* position   of   the   vector */
                                            /* number   field   makes    it */
                                            /* automatically multiplied  by */
                                            /* four.                        */

        add.l   %d1,%d0                     /*   Calculate  the  ISR  table */
                                            /* offset.   Add   the   vector */
                                            /* table    offset    to    the */
                                            /* translation value.           */

        asr.l   #2,%d1                      /*   Calculate    the    vector */
                                            /* number  using   the   vector */
                                            /* table offset.                */

        /*   d0.l: Contains the offset into the ISR table.                  */

        /*   d1.l: Contains the vector number.                              */

#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT

        .extern cyg_scheduler_sched_lock        /*   Lock the scheduler  if */
        addq.l  #1,cyg_scheduler_sched_lock     /* we are using the kernel. */

#endif /* CYGFUN_HAL_COMMON_KERNEL_SUPPORT */

/*      We need to call the following routines.  The isr address, data, and */
/* intr are all from the  ISR table.  interrupt_end is  a C routine and  is */
/* only called if we are using  the  kernel.   regs  points  to  the  saved */
/* registers on the stack.  isr_ret is the return address from isr.  vector */
/* is the vector number.                                                    */

/*
static cyg_uint32 isr(CYG_ADDRWORD vector,
                      CYG_ADDRWORD data)

externC void interrupt_end(cyg_uint32 isr_ret,
                           Cyg_Interrupt *intr,
                           HAL_SavedRegisters  *regs)
*/

        pea     (%sp)                       /*   Push the regs pointer.     */

        .extern cyg_hal_interrupt_objects       /*   Push the  intr  object */
        lea     cyg_hal_interrupt_objects,%a0   /* pointer from the table.  */
        move.l  (%a0,%d0.l),-(%sp)

        .extern cyg_hal_interrupt_data          /*   Push  the  data  value */
        lea     cyg_hal_interrupt_data,%a0      /* from the table.          */
        move.l  (%a0,%d0.l),-(%sp)

        .extern cyg_hal_interrupt_handlers      /*   Get the address of the */
        lea     cyg_hal_interrupt_handlers,%a0  /* ISR from the table.      */
        move.l  (%a0,%d0.l),%a0

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

        jbsr   (%a0)                        /*   Call the ISR.              */

        addq.l  #4*1,%sp                    /*   Remove     the      vector */
                                            /* parameter from the stack.    */

        move.l  %d0,(%sp)                   /*   d0.l contains  the  return */
                                            /* value    from    the    ISR. */
                                            /* Overwrite the data parameter */
                                            /* with the ISR return value to */
                                            /* pass    as    a    parameter */
                                            /* (isr_ret) to  interrupt_end. */
                                            /* The  intr  object  and  regs */
                                            /* parameters are still on  the */
                                            /* stack.                       */

#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT

        /*   We only need to  call interrupt_end() when  there is a  kernel */
        /* present to do any tidying up.                                    */

        /*   The  interrupt_end  routine  will   call  the   DSRs  and   do */
        /* rescheduling when it  decrements the  scheduler lock  from 1  to */
        /* zero.  In this case, we  do not want  to have interrupts  masked */
        /* while the DSRs run.   Restore the  interrupt mask  to the  value */
        /* prior  to  this  interrupt.    Do  not  completely  unmask   all */
        /* interrupts because this interrupt may be a nested interrupt.  We */
        /* do not want to lower  the interrupt mask  on the lower  priority */
        /* interrupt.                                                       */

        move.w  (4*3)+int_pres_regs_sz+2(%sp),%d2
        move.w  %d2,%sr

        /*   If the interrupt mask was not previously zero, we want to make */
        /* sure that the DSRs to not run and no preemption occurs.  Add the */
        /* value of the previous interrupt mask to the scheduler lock.   If */
        /* the previous mask was  zero, the scheduler  lock will remain  at */
        /* one and the interrupt  end function will  decrement it to  zero. */
        /* Otherwise, we want  to prevent the  interrupt end function  from */
        /* unlocking the scheduler.  We do  this because there is a  chance */
        /* that someone had  interrupts masked with  the scheduler lock  at */
        /* zero.  If a  higher  priority  interrupt  occurs,  we  could  be */
        /* running DSRs and doing preemption with the interrupts masked!    */

        and.l   #0x0700,%d2
        lsr.l   #8,%d2
        add.l   %d2,cyg_scheduler_sched_lock

        .extern interrupt_end               /*   Call the  interrupt_end  C */
        jbsr    interrupt_end               /* routine.  This routine might */
                                            /* preempt    the     currently */
                                            /* running thread.              */

        /*   Now that interrupt end  is  complete,  subtract  the  previous */
        /* interrupt level back out of the scheduler lock.                  */

        sub.l   %d2,cyg_scheduler_sched_lock

#endif

        lea     (4*3)(%sp),%sp              /*   Remove the isr_ret,  intr, */
                                            /* and regs parameters from the */
                                            /* stack.                       */

        int_rest_regs                       /*   Restore   the    preserved */
                                            /* registers  for  the  current */
                                            /* thread.                      */

        rte                                 /*   Restore the SR and PC.     */

/****************************************************************************/
/*      Autovector interrupt vector handler.                                */

/*      Control is transferred here from an interrupt autovector  (#25-31). */

/*      Before branching  to common  code, load  a value  to translate  the */
/* vector table offset to the ISR  table  offset.   The  ISR  vector  table */
/* contains  the  autovectors  (0-6)  followed  by  the  interrupt  vectors */
/* (7-198).                                                                 */

        .text
        .balign 4
hw_vsr_autovec:

        int_pres_regs                       /*   Preserve   all   registers */
                                            /* that this ISR routine  needs */
                                            /* to  preserve.   The  C  code */
                                            /* will  preserve   all   other */
                                            /* registers.                   */

        move.l #(-25+0)*4,%d0               /*   Adding this  value to  the */
                                            /* vector  table  offset   will */
                                            /* result in the  corresponding */
                                            /* offset into the ISR table.   */

        jra     hw_vsr_int_common           /*   Branch into common code.   */

/****************************************************************************/
/*      hw_vsr_reset -- Hardware Reset Vector                               */

/*      We assume that most of the chip selects are configured by the  boot */
/* loader.                                                                  */

        .text
        .balign 4
        .globl  hw_vsr_reset
hw_vsr_reset:

        .globl  __exception_reset           /*   Define the entry point for */
__exception_reset:                          /* the linker.                  */

        move.w  #0x2700,%sr                 /*   Make   sure    that    all */
                                            /* interrupts are masked.       */

        lea     hw_vsr_stack,%sp            /*   Load   the    reset    and */
                                            /* interrupt stack pointer.     */

        lea     0,%fp                       /*   Set up  the initial  frame */
        link    %fp,#0                      /* pointer.                     */

        .extern hal_reset                   /*   Call  the  C  routine   to */
        jbsr    hal_reset                   /* complete the reset process.  */

9:      stop    #0x2000                     /*   If we return, stop.        */
        jra     9b

/****************************************************************************/
/*      Interrupt and reset stack                                           */

/*      WARNING:  Do  not  put  this  in  any  memory  section  that   gets */
/* initialized.  Doing so may cause the C code to initialize its own stack. */

        .section ".uninvar","aw",@nobits

        .balign 16
        .global hw_vsr_stack_bottom
hw_vsr_stack_bottom:
        .skip   0x2000
        .balign 16
        .global hw_vsr_stack
hw_vsr_stack:
        .skip   0x10

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

⌨️ 快捷键说明

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