Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:50

0001 /*
0002  * start.S -- startup file for JMR3904 BSP based upon crt0.S from
0003  * newlib-1.8.2/libgloss/mips and adapted for RTEMS.
0004  *
0005  * crt0.S -- startup file for MIPS.
0006  *
0007  * Copyright (c) 1995, 1996, 1997 Cygnus Support
0008  *
0009  * The authors hereby grant permission to use, copy, modify, distribute,
0010  * and license this software and its documentation for any purpose, provided
0011  * that existing copyright notices are retained in all copies and that this
0012  * notice is included verbatim in any distributions. No written agreement,
0013  * license, or royalty fee is required for any of the authorized uses.
0014  * Modifications to this software may be copyrighted by their authors
0015  * and need not follow the licensing terms described here, provided that
0016  * the new terms are clearly indicated on the first page of each file where
0017  * they apply.
0018  */
0019 
0020 #include <rtems/asm.h>
0021 #include <bsp/regs.h>
0022 
0023 #ifdef __mips16
0024 /* This file contains 32 bit assembly code.  */
0025     .set nomips16
0026 #endif
0027 
0028 /* This is for referencing addresses that are not in the .sdata or
0029    .sbss section under embedded-pic, or before we've set up gp.  */
0030 #ifdef __mips_embedded_pic
0031 # ifdef __mips64
0032 #  define LA(t,x) la t,x-PICBASE ; daddu t,s0,t
0033 # else
0034 #  define LA(t,x) la t,x-PICBASE ; addu t,s0,t
0035 # endif
0036 #else /* __mips_embedded_pic */
0037 # define LA(t,x) la t,x
0038 #endif /* __mips_embedded_pic */
0039 
0040     .text
0041     .align  2
0042 
0043 /* Without the following nop, GDB thinks _start is a data variable.
0044  * This is probably a bug in GDB in handling a symbol that is at the
0045  * start of the .text section.
0046  */
0047     nop
0048 
0049     .globl  _start
0050     .ent    _start
0051 _start:
0052     .set    noreorder
0053     /* Get the address of start into $5 in a position independent fashion.
0054     ** This lets us know whether we have been relocated or not.
0055     */
0056     $LF1 = . + 8
0057     bal     $LF1
0058     nop
0059 _branch:
0060     move    $5, $31             # $5 == where are we
0061     li  $6, 0x8800000c          # $6 == where we want to be
0062 /*  #la      $6,_branch */
0063     beq $5, $6, _start_in_ram
0064     nop
0065     /* relocate the code from EEPROM to RAM */
0066         la  $7, _edata
0067 relocate:
0068     lw  $8, ($5)            # $8 = *EEPROM
0069     addu    $5, $5, 4           # EEPROM++
0070         sw      $8, ($6)            # *RAM = $8
0071     addu    $6, $6, 4           # RAM++
0072     bne $6, $7, relocate        # copied all the way to edata?
0073     nop
0074     la  $6, _start_in_ram
0075     jr  $6
0076     nop
0077     .end _start
0078 
0079     .globl  _start_in_ram
0080     .ent _start_in_ram
0081 _start_in_ram:
0082     nop
0083 
0084 #ifdef __mips_embedded_pic
0085     PICBASE = .+8
0086         bal PICBASE
0087     nop
0088     move    s0,$31
0089 #endif
0090 
0091     li  v0, SR_CU1|SR_PE|SR_FR|SR_KX|SR_SX|SR_UX
0092     mtc0    v0, C0_SR
0093     mtc0    zero, C0_CAUSE
0094 
0095 /* Check for FPU presence */
0096 #ifndef __mips_soft_float
0097 /* This doesn't work if there is no FPU.  We get illegal instruction
0098    exceptions.  */
0099     li  t2,0xAAAA5555
0100     mtc1    t2,fp0      /* write to FPR 0 */
0101     mtc1    zero,fp1    /* write to FPR 1 */
0102     mfc1    t0,fp0
0103     mfc1    t1,fp1
0104     nop
0105     bne t0,t2,1f    /* check for match */
0106     nop
0107     bne t1,zero,1f  /* double check */
0108     nop
0109 #ifndef __mips64  /* Clear the FR bit */
0110     li  v0, SR_CU1|SR_PE|SR_KX|SR_SX|SR_UX
0111     mtc0    v0, C0_SR
0112 #endif
0113     j   2f
0114     nop
0115 #endif
0116 1:
0117     li  v0, SR_PE|SR_FR|SR_KX|SR_SX|SR_UX
0118     mtc0    v0, C0_SR
0119 2:
0120 /* Fix high bits, if any, of the PC so that exception handling
0121    doesn't get confused.  */
0122     LA (v0, 3f)
0123     jr  v0
0124     nop
0125 3:
0126     LA (gp, _gp)                # set the global data pointer
0127     .end _start_in_ram
0128 
0129 /*
0130  * zero out the bss section.
0131  */
0132     .globl  zerobss
0133     .ent    zerobss
0134 zerobss:
0135     LA (v0, _fbss)
0136     LA (v1, _end)
0137 3:
0138     sw  zero,0(v0)
0139     bltu    v0,v1,3b
0140     addiu   v0,v0,4             # executed in delay slot
0141 
0142     la  t0, _ISR_Stack_area_end # initialize stack so we
0143     /* We must subtract 24 bytes for the 3 8 byte arguments to main, in
0144        case main wants to write them back to the stack.  The caller is
0145        supposed to allocate stack space for parameters in registers in
0146        the old MIPS ABIs.  We must do this even though we aren't passing
0147        arguments, because main might be declared to have them.
0148 
0149        Some ports need a larger alignment for the stack, so we subtract
0150        32, which satisifes the stack for the arguments and keeps the
0151        stack pointer better aligned.  */
0152     subu    t0,t0,32
0153     move    sp,t0               # set stack pointer
0154     .end    zerobss
0155 
0156     .globl  exit .text
0157     .globl  init
0158     .ent    init
0159 init:
0160 
0161     move    a0,zero             # set command line to 0
0162     jal boot_card           # call the program start function
0163     nop
0164 
0165     /* fall through to the "exit" routine */
0166     jal _sys_exit           /* call libc exit to run the G++ */
0167                         /* destructors */
0168     move    a0,v0               /* pass through the exit code */
0169     .end    init
0170 
0171 /*
0172  * _sys_exit -- Exit from the application. Normally we cause a user trap
0173  *          to return to the ROM monitor for another run. NOTE: This is
0174  *      the only other routine we provide in the crt0.o object, since
0175  *          it may be tied to the "_start" routine. It also allows
0176  *          executables that contain a complete world to be linked with
0177  *          just the crt0.o object.
0178  */
0179     .globl  bsp_reset
0180 bsp_reset:
0181     .globl  _sys_exit
0182     .ent _sys_exit
0183 _sys_exit:
0184 7:
0185 #ifdef GCRT0
0186     jal _mcleanup
0187     nop
0188 #endif
0189     /* break instruction can cope with 0xfffff, but GAS limits the range: */
0190     break   1023
0191     nop
0192     b   7b              # but loop back just in-case
0193     nop
0194     .end _sys_exit
0195 
0196 /* EOF crt0.S */