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

📄 mcfv4e_lo.s

📁 motorola 针对coldfire 5275 评估板的Dbug bootloader源程序
💻 S
字号:
/*
 * File:    mcfv4e_lo.s
 * Purpose: Lowest level routines for all CF V4e
 *
 * Notes:   Has support for FPU registers
 *
 */

/*
 * Only need underscore for C functions. The assembly functions will
 * provide both style names.
 */
#ifdef _UNDERSCORE_
#define context                 _context
#define cpu_handler             _cpu_handler
#define isr_execute_handler     _isr_execute_handler
#define mainloop                _mainloop
#define __SP_INIT               ___SP_INIT
#endif

    .extern __SP_INIT
    .extern context
    .extern mainloop
    .extern cpu_handler
    .extern isr_execute_handler

    .extern cpu_cache_flush
    .extern _cpu_cache_flush

    .extern VECTOR_TABLE
    .extern _VECTOR_TABLE

    .global asm_exception_handler
    .global _asm_exception_handler
    .global asm_switch_context
    .global _asm_switch_context
    .global asm_set_ipl
    .global _asm_set_ipl
    .global asm_sc_exit_to_dbug
    .global _asm_sc_exit_to_dbug
    .global asm_isr_handler
    .global _asm_isr_handler
    .global mcf5xxx_wr_cacr
    .global _mcf5xxx_wr_cacr
    .global mcf5xxx_wr_asid
    .global _mcf5xxx_wr_asid
    .global mcf5xxx_wr_acr0
    .global _mcf5xxx_wr_acr0
    .global mcf5xxx_wr_acr1
    .global _mcf5xxx_wr_acr1
    .global mcf5xxx_wr_acr2
    .global _mcf5xxx_wr_acr2
    .global mcf5xxx_wr_acr3
    .global _mcf5xxx_wr_acr3
    .global mcf5xxx_wr_mmubar
    .global _mcf5xxx_wr_mmubar
    .global mcf5xxx_wr_other_a7
    .global _mcf5xxx_wr_other_a7
    .global mcf5xxx_wr_vbr
    .global _mcf5xxx_wr_vbr
    .global mcf5xxx_wr_macsr
    .global _mcf5xxx_wr_macsr
    .global mcf5xxx_wr_mask
    .global _mcf5xxx_wr_mask
    .global mcf5xxx_wr_acc0
    .global _mcf5xxx_wr_acc0
    .global mcf5xxx_wr_accext01
    .global _mcf5xxx_wr_accext01
    .global mcf5xxx_wr_accext23
    .global _mcf5xxx_wr_accext23
    .global mcf5xxx_wr_acc1
    .global _mcf5xxx_wr_acc1
    .global mcf5xxx_wr_acc2
    .global _mcf5xxx_wr_acc2
    .global mcf5xxx_wr_acc3
    .global _mcf5xxx_wr_acc3
    .global mcf5xxx_wr_sr
    .global _mcf5xxx_wr_sr
    .global mcf5xxx_wr_pc
    .global _mcf5xxx_wr_pc
    .global mcf5xxx_wr_rombar0
    .global _mcf5xxx_wr_rombar0
    .global mcf5xxx_wr_rombar1
    .global _mcf5xxx_wr_rombar1
    .global mcf5xxx_wr_rambar0
    .global _mcf5xxx_wr_rambar0
    .global mcf5xxx_wr_rambar1
    .global _mcf5xxx_wr_rambar1
    .global mcf5xxx_wr_mpcr
    .global _mcf5xxx_wr_mpcr
    .global mcf5xxx_wr_secmbar
    .global _mcf5xxx_wr_secmbar
    .global mcf5xxx_wr_mbar
    .global _mcf5xxx_wr_mbar

/*
 * The following define the registers that are
 * maintained by the debugger.
 */
#define r_d0    0
#define r_d1    4
#define r_d2    8
#define r_d3    12
#define r_d4    16
#define r_d5    20
#define r_d6    24
#define r_d7    28
#define r_a0    32
#define r_a1    36
#define r_a2    40
#define r_a3    44
#define r_a4    48
#define r_a5    52
#define r_a6    56
#define r_a7    60
#define r_fp0   64
#define r_fp1   72
#define r_fp2   80
#define r_fp3   88
#define r_fp4   96
#define r_fp5   104
#define r_fp6   112
#define r_fp7   120
#define r_fpcr  128
#define r_fpsr  132
#define r_fpiar 136
#define r_pc    140
#define r_sr    144
#define r_sp    r_a7

    .text

/********************************************************************/
/*
 * This routine is responsible for restoring a user
 * register set and executing it.
 * Since all registers about to be restored, use any
 * register.
 *
 * call from C:  asm_switch_context(REGISTERS *context);
 */
asm_switch_context:
_asm_switch_context:

    move.l  4(sp),a0        /* point to cpu data structure */

    /* ColdFire 5xxx requires stack frames be 0 modula 4 */

    /* calculate format field encoding */
    move.l  r_sp(a0),d6         /* sp for stack adjustment  */
    move.l  d6,d7               /* sp for comparisons   */
    andi.l  #0x00000003,d7      /* last two bits of a7  */
    beq.s   ff0100              /* format field 0100    */
    cmpi.l  #1,d7
    beq.s   ff0101              /* format field 0101    */
    cmpi.l  #2,d7
    beq.s   ff0110              /* format field 0110    */
    /* must be format field 0111 */

ff0111:
    subq.l  #3,d6           /* adjust sp 3 bytes to align   */
    move.l  #0x70000000,d7  /* encode format 0111   */
    bra.s   write_frame
ff0110:
    subq.l  #2,d6           /* adjust sp 2 bytes to align   */
    move.l  #0x60000000,d7  /* encode format 0110   */
    bra.s   write_frame
ff0101:
    subq.l  #1,d6           /* adjust sp 1 bytes to align   */
    move.l  #0x50000000,d7  /* encode format 0101   */
    bra.s   write_frame
ff0100:
    /* no stack adjustment necessary */
    move.l  #0x40000000,d7  /* encode format 0100   */


write_frame:

    /* Build stack frame before switching stacks */
    move.l  d6,a6
    move.l  r_pc(a0),-(a6)  /* sp                           */
    move.w  r_sr(a0),d7     /* sr (format already in d7)    */
    move.l  d7,-(a6)
    nop                     /* force pending writes         */

    /* Restore user SP */
    move.l  a6,sp

    /* Restore user floating point registers */
    fmovem  r_fp0(a0),fp0-fp7   /* 0xF228D0FF0040 */
    fmove.l r_fpcr(a0),FPCR     /* 0xF22890000080 */
    fmove.l r_fpsr(a0),FPSR     /* 0xF22888000084 */
    fmove.l r_fpiar(a0),FPIAR   /* 0xF22884000088 */

    /* Restore user data and address registers */
    movem.l (a0),d0-d7/a0-a6

    /* Here we go! */
    nop
    rte

/********************************************************************/
/*
 * This routine is the lowest-level exception handler for ColdFire.
 * This routine switches SP to a known-good RAM location, and then
 * saves the registers.  This routine should work even if the user
 * code has a bad stack pointer.
 */
asm_exception_handler:
_asm_exception_handler:

    move.w  #0x2700,sr  /* if doing interrupt i/o, then comment out */

    /* Change to dBUG stack space */
    move.l  sp,__SP_INIT
    move.l  #__SP_INIT,sp

    move.l  a0,-(sp)
    lea     context,a0

    movem.l d0-d7/a0-a7,(a0)    /* d0-d7/a0-a7 (a0/a7 are bad) */

    /* Save off floating point registers */
    fmovem  fp0-fp7,r_fp0(a0)   /* 0xF228F0FF0040 */
    fmove.l FPCR,r_fpcr(a0)     /* 0xF228B0000080 */
    fmove.l FPSR,r_fpsr(a0)     /* 0xF228A8000084 */
    fmove.l FPIAR,r_fpiar(a0)   /* 0xF228A4000088 */

    move.l  (sp)+,r_a0(a0)      /* a0    */
    move.l  (sp),a1
    move.l  a1,r_sp(a0)         /* sp/a7 at end of stack frame   */
    move.l  4(a1),r_pc(a0)      /* pc    */
    move.w  2(a1),r_sr(a0)      /* sr    */

    /* Flush caches and disable them. */
    jsr     cpu_cache_flush

/*
 * all regs are saved and correct except SP, but SP taken care of
 * in cpu_handler():  int cpu_handler (STACK_FRAME *framep);
 */
    move.l  a1,-(sp)
    jsr     cpu_handler
    lea     4(sp),sp
    tst.l   d0
    bne.s   backtomonitor

/*
 * restore registers modified:  a0,d0,a1,d1,sp
 * sr in stack frame
 */
    lea     context,a0

/*
 * sp must have been adjusted properly for RTE
 * since cpu_handler() initially knocks off the
 * frame from the user stack. (see ispdelta)
 */
    move.l  r_sp(a0),sp

    move.l  r_d1(a0),d1
    move.l  r_a1(a0),a1
    move.l  r_d0(a0),d0
    move.l  r_a0(a0),a0 /* This one must be done LAST!!! */

    rte

backtomonitor:
    move.w  #0x2700,sr
    jmp mainloop

/********************************************************************/
/*
 * This routine is called from within/by a user system call to save the
 * context and return to dBUG cleanly.  This routine expects a pointer
 * to the exception stack frame.  This pointer provides three pieces of
 * information.  1) The SP (which points to end of exception stack frame),
 * 2) the PC, and 3) the SR.  All other regs are preserved from their
 * values entering this routine.  This routine must be called via a JSR
 * or BSR instruction.
 *
 * So, stack coming into this routine looks like:
 *
 *                  |       ...        |
 *                  |    Return PC     |
 *                  | Format/Vector/SR | <-- SP after exception
 *                  |       ...        |
 *                  |  Stack Frame Ptr | (The SP after exception)
 *                  |   JSR Return PC  | (not used)
 *                  |                  |
 */
asm_sc_exit_to_dbug:
_asm_sc_exit_to_dbug:
    /* Save off general purpose registers */

        move.w      #0x2700,sr

        move.l      a0,-(sp)
        lea         context,a0
        move.l      d0,r_d0(a0)
        move.l      d1,r_d1(a0)
        move.l      d2,r_d2(a0)
        move.l      d3,r_d3(a0)
        move.l      d4,r_d4(a0)
        move.l      d5,r_d5(a0)
        move.l      d6,r_d6(a0)
        move.l      d7,r_d7(a0)
        move.l      a1,r_a1(a0)
        move.l      a2,r_a2(a0)
        move.l      a3,r_a3(a0)
        move.l      a4,r_a4(a0)
        move.l      a5,r_a5(a0)
        move.l      a6,r_a6(a0)
        move.l      (sp)+,a1
        move.l      a1,r_a0(a0)

    /* Now get info from stack frame pointer */

        move.l      4(sp),a1        /* Stack frame pointer argument  */
        move.l      a1,r_a7(a0)     /* SP at end of exception    */
        move.l      4(a1),r_pc(a0)  /* pc    */
        move.w      2(a1),r_sr(a0)  /* sr    */

/*
 * Now that context has been stored off, change to dBUG stack
 * and prepare to enter the debugger again.
 */
        move.l      #__SP_INIT,sp

    /* Flush caches and disable them */
        jsr         cpu_cache_flush
        jmp         mainloop

/********************************************************************/
/*
 * This routines changes the IPL to the value passed into the routine.
 * It also returns the old IPL value back.
 * Calling convention from C:
 *   old_ipl = asm_set_ipl(new_ipl);
 * For the Diab Data C compiler, it passes return value thru D0.
 * Note that only the least significant three bits of the passed
 * value are used.
 */

    .text
asm_set_ipl:
_asm_set_ipl:
    link    a6,#-8
    movem.l d6-d7,(sp)

        move.w  sr,d7       /* current sr    */

        move.l  d7,d0       /* prepare return value  */
        andi.l  #0x0700,d0  /* mask out IPL  */
        lsr.l   #8,d0       /* IPL   */

        move.l  8(a6),d6    /* get argument  */
        andi.l  #0x07,d6        /* least significant three bits  */
        lsl.l   #8,d6       /* move over to make mask    */

        andi.l  #0x0000F8FF,d7  /* zero out current IPL  */
        or.l    d6,d7           /* place new IPL in sr   */
        move.w  d7,sr

    movem.l (sp),d6-d7
    lea     8(sp),sp
    unlk    a6
    rts

/********************************************************************/
/*
 * This is the low-level Interrupt Service Routine code for ISRs
 * that are registered within the dBUG monitor.
 */

asm_isr_handler:
_asm_isr_handler:
    link        a6,#-16
    movem.l     d0-d1/a0-a1,(sp)

    move.w      4(a6),d0
    lsr.l       #2,d0
    andi.l      #0x0000FF,d0
    move.l      d0,-(sp)
    jsr         isr_execute_handler
    lea         4(sp),sp
    cmpi.l      #1,d0
    beq         handled

nothandled:
    movem.l     (sp),d0-d1/a0-a1
    unlk        a6
    jmp         asm_exception_handler

handled:
    movem.l     (sp),d0-d1/a0-a1
    unlk        a6
    rte

/********************************************************************/
/*
 * These routines write to the special purpose registers in the ColdFire
 * core.  Since these registers are write-only in the supervisor model,
 * no corresponding read routines exist.
 */

mcf5xxx_wr_sr:
_mcf5xxx_wr_sr:
    move.l  4(SP),D0
    move.w  D0,SR
    rts

mcf5xxx_wr_cacr:
_mcf5xxx_wr_cacr:
    move.l  4(SP),D0
    .long   0x4e7b0002      /* movec d0,cacr */
    nop
    rts

mcf5xxx_wr_asid:
_mcf5xxx_wr_asid:
    move.l  4(SP),D0
    .long   0x4e7b0003      /* movec d0,asid */
    nop
    rts

mcf5xxx_wr_acr0:
_mcf5xxx_wr_acr0:
    move.l  4(SP),D0
    .long   0x4e7b0004      /* movec d0,ACR0 */
    nop
    rts

mcf5xxx_wr_acr1:
_mcf5xxx_wr_acr1:
    move.l  4(SP),D0
    .long   0x4e7b0005      /* movec d0,ACR1 */
    nop
    rts

mcf5xxx_wr_acr2:
_mcf5xxx_wr_acr2:
    move.l  4(SP),D0
    .long   0x4e7b0006      /* movec d0,ACR2 */
    nop
    rts

mcf5xxx_wr_acr3:
_mcf5xxx_wr_acr3:
    move.l  4(SP),D0
    .long   0x4e7b0007      /* movec d0,ACR3 */
    nop
    rts

mcf5xxx_wr_mmubar:
_mcf5xxx_wr_mmubar:
    move.l  4(SP),D0
    .long   0x4e7b0008      /* movec d0,MBAR */
    nop
    rts

mcf5xxx_wr_other_a7:
_mcf5xxx_wr_other_a7:
    move.l  4(SP),D0
    .long   0x4e7b0800      /* movec d0,OTHER_A7 */
    nop
    rts

mcf5xxx_wr_vbr:
_mcf5xxx_wr_vbr:
    move.l  4(SP),D0
    .long   0x4e7b0801      /* movec d0,VBR */
    nop
    rts

mcf5xxx_wr_macsr:
_mcf5xxx_wr_macsr:
    move.l  4(SP),D0
    .long   0x4e7b0804      /* movec d0,MACSR */
    nop
    rts

mcf5xxx_wr_mask:
_mcf5xxx_wr_mask:
    move.l  4(SP),D0
    .long   0x4e7b0805      /* movec d0,MASK */
    nop
    rts

mcf5xxx_wr_acc0:
_mcf5xxx_wr_acc0:
    move.l  4(SP),D0
    .long   0x4e7b0806      /* movec d0,ACC0 */
    nop
    rts

mcf5xxx_wr_accext01:
_mcf5xxx_wr_accext01:
    move.l  4(SP),D0
    .long   0x4e7b0807      /* movec d0,ACCEXT01 */
    nop
    rts

mcf5xxx_wr_accext23:
_mcf5xxx_wr_accext23:
    move.l  4(SP),D0
    .long   0x4e7b0808      /* movec d0,ACCEXT23 */
    nop
    rts

mcf5xxx_wr_acc1:
_mcf5xxx_wr_acc1:
    move.l  4(SP),D0
    .long   0x4e7b0809      /* movec d0,ACC1 */
    nop
    rts

mcf5xxx_wr_acc2:
_mcf5xxx_wr_acc2:
    move.l  4(SP),D0
    .long   0x4e7b080A      /* movec d0,ACC2 */
    nop
    rts

mcf5xxx_wr_acc3:
_mcf5xxx_wr_acc3:
    move.l  4(SP),D0
    .long   0x4e7b080B      /* movec d0,ACC3 */
    nop
    rts

mcf5xxx_wr_pc:
_mcf5xxx_wr_pc:
    move.l  4(SP),D0
    .long   0x4e7b080F      /* movec d0,PC */
    nop
    rts

mcf5xxx_wr_rombar0:
_mcf5xxx_wr_rombar0:
    move.l  4(SP),D0
    .long   0x4e7b0C00      /* movec d0,ROMBAR0 */
    nop
    rts

mcf5xxx_wr_rombar1:
_mcf5xxx_wr_rombar1:
    move.l  4(SP),D0
    .long   0x4e7b0C01      /* movec d0,ROMBAR1 */
    nop
    rts

mcf5xxx_wr_rambar0:
_mcf5xxx_wr_rambar0:
    move.l  4(SP),D0
    .long   0x4e7b0C04      /* movec d0,RAMBAR0 */
    nop
    rts

mcf5xxx_wr_rambar1:
_mcf5xxx_wr_rambar1:
    move.l  4(SP),D0
    .long   0x4e7b0C05      /* movec d0,RAMBAR1 */
    nop
    rts

mcf5xxx_wr_mpcr:
_mcf5xxx_wr_mpcr:
    move.l  4(SP),D0
    .long   0x4e7b0C0C      /* movec d0,MPCR */
    nop
    rts

mcf5xxx_wr_secmbar:
_mcf5xxx_wr_secmbar:
    move.l  4(SP),D0
    .long   0x4e7b0C0E      /* movec d0,MBAR1   */
    nop
    rts

mcf5xxx_wr_mbar:
_mcf5xxx_wr_mbar:
    move.l  4(SP),D0
    .long   0x4e7b0C0F      /* movec d0,MBAR0   */
    nop
    rts

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

    .end

⌨️ 快捷键说明

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