Back to home page

LXR

 
 

    


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

0001 /*
0002 
0003 Based upon IDT provided code with the following release:
0004 
0005 This source code has been made available to you by IDT on an AS-IS
0006 basis. Anyone receiving this source is licensed under IDT copyrights
0007 to use it in any way he or she deems fit, including copying it,
0008 modifying it, compiling it, and redistributing it either with or
0009 without modifications.  No license under IDT patents or patent
0010 applications is to be implied by the copyright license.
0011 
0012 Any user of this software should understand that IDT cannot provide
0013 technical support for this software and will not be responsible for
0014 any consequences resulting from the use of this software.
0015 
0016 Any person who transfers this source code or any derivative work must
0017 include the IDT copyright notice, this paragraph, and the preceeding
0018 two paragraphs in the transferred software.
0019 
0020 COPYRIGHT IDT CORPORATION 1996
0021 LICENSED MATERIAL - PROGRAM PROPERTY OF IDT
0022 
0023 
0024 *************************************************************************
0025 **
0026 ** Copyright 1991-95 Integrated Device Technology, Inc.
0027 **  All Rights Reserved
0028 **
0029 ** idt_csu.S -- IDT stand alone startup code
0030 **
0031 **************************************************************************/
0032 #include <rtems/mips/iregdef.h>
0033 #include <rtems/mips/idtcpu.h>
0034 #include <rtems/asm.h>
0035 
0036 #include <bsp.h>
0037 
0038     .extern mon_flush_cache
0039 
0040 #if 0
0041     .extern _fdata,4        /* this is defined by the linker */
0042     .extern _edata,4        /* this is defined by the linker */
0043     .extern _idata,4        /* this is defined by the linker */
0044 #endif
0045     .extern _fbss,4         /* this is defined by the linker */
0046     .extern end,4           /* this is defined by the linker */
0047 
0048     .lcomm sim_mem_cfg_struct,12
0049 
0050     .text
0051 
0052 #define HARD_CODED_MEM_SIZE 0x1000000   /* RBTX4925 has 16 megabytes of RAM */
0053 #define PMON_VECTOR 0xbfc00500
0054 
0055 #define TMP_STKSIZE  1024
0056 
0057 /*
0058 ** P_STACKSIZE is the size of the Prom Stack.
0059 ** the prom stack grows downward
0060 */
0061 #define P_STACKSIZE 0x2000   /* sets stack size to 8k */
0062 
0063 
0064 /**************************************************************************
0065 **
0066 **  start - Typical standalone start up code required for R3000/R4000
0067 **
0068 **
0069 **  1)  Initialize the STATUS Register
0070 **      a) Clear parity error bit
0071 **      b) Set co_processor 1 usable bit ON
0072 **      c) Clear all IntMask Enables
0073 **      d) Set kernel/disabled mode
0074 **  2)  Initialize Cause Register
0075 **      a)  clear software interrupt bits
0076 **  3)  Determine FPU installed or not
0077 **      if not, clear CoProcessor 1 usable bit
0078 **  4)  Initialize data areas. Clear bss area.
0079 **  5)  MUST allocate temporary stack until memory size determined
0080 **      It MUST be uncached to prevent overwriting when caches are cleared
0081 **  6)  Install exception handlers
0082 **  7)  Determine memory and cache sizes
0083 **  8)  Establish permanent stack (cached or uncached as defined by bss)
0084 **  9)  Flush Instruction and Data caches
0085 **  10)  If there is a Translation Lookaside Buffer, Clear the TLB
0086 **  11)  Execute initialization code if the IDT/c library is to be used
0087 **
0088 **  12)  Jump to user's "main()"
0089 **  13)  Jump to promexit
0090 **
0091 **  IDT/C 5.x defines _R3000, IDT/C 6.x defines _R4000 internally.
0092 **  This is used to mark code specific to R3xxx or R4xxx processors.
0093 **  IDT/C 6.x defines __mips to be the ISA level for which we're
0094 **  generating code. This is used to make sure the stack etc. is
0095 **  double word aligned, when using -mips3 (default) or -mips2,
0096 **  when compiling with IDT/C6.x
0097 **
0098 ***************************************************************************/
0099 
0100 FRAME(start,sp,0,ra)
0101 
0102     .set    noreorder
0103 #if __mips_fpr == 64
0104     li  v0,SR_CU1|SR_FR     /* initally clear ERL, enable FPU with 64 bit regs */
0105 #else
0106     li  v0,SR_CU1       /* initally clear ERL, enable FPU with 32 bit regs */
0107 #endif
0108 
0109     mtc0    v0,C0_SR        /* clr IntMsks/ kernel/disabled mode */
0110     nop
0111     mtc0    zero,C0_CAUSE       /* clear software interrupts */
0112     nop
0113 
0114     li  v0,CFG_C_NONCOHERENT    /* initialise default cache mode */
0115     mtc0    v0,C0_CONFIG
0116 
0117 /*
0118 **  check to see if a fpu is really plugged in
0119 */
0120     li  t3,0xaaaa5555       /*  put a's and 5's in t3   */
0121     mtc1    t3,fp0          /* try to write them into fp0   */
0122     mtc1    zero,fp1        /* try to write zero in fp  */
0123     mfc1    t0,fp0
0124     mfc1    t1,fp1
0125     nop
0126     bne t0,t3,1f        /* branch if no match  */
0127     nop
0128     bne t1,zero,1f      /* double check for positive id   */
0129     nop
0130     /* We have a FPU. clear fcsr */
0131     ctc1    zero, fcr31
0132     j   2f          /* status register already correct  */
0133     nop
0134 1:
0135         li      v0,0x0          /* clear ERL and disable FPA */
0136 
0137     mtc0    v0, C0_SR       /* reset status register */
0138 2:
0139     la      gp, _gp         /* Initialize gp register (pointer to "small" data)*/
0140 
0141 #if 0
0142                     /* Initialize data sections from "rom" copy */
0143     la  t0,_idata       /* address of initialization data (copy of data sections placed in ROM) */
0144     la  t1,_fdata       /* start of initialized data section */
0145     la  t2,_edata       /* end of initialized data section */
0146 3:
0147     lw  t3,0(t0)
0148     sw  t3,0(t1)
0149     addiu   t1,t1,4
0150     bne t1,t2,3b
0151     addiu   t0,t0,4
0152 #endif
0153 
0154                     /* clear bss before using it */
0155     la  v0,_fbss        /* start of bss */
0156     la  v1,end          /* end of bss */
0157 4:  sw  zero,0(v0)
0158     bltu    v0,v1,4b
0159     add v0,4
0160 
0161 
0162 /************************************************************************
0163 **
0164 **  Temporary Stack - needed to  handle stack saves until
0165 **            memory size is determined and permanent stack set
0166 **
0167 **            MUST be uncached to avoid confusion at cache
0168 **                 switching during memory sizing
0169 **
0170 *************************************************************************/
0171     /* For MIPS 3, we need to be sure that the stack is aligned on a
0172      * double word boundary.
0173      */
0174     andi    t0, v0, 0x7
0175     beqz    t0, 11f   /* Last three bits Zero, already aligned */
0176     nop
0177     add v0, 4
0178 11:
0179 
0180     or  v0, K1BASE      /* switch to uncached */
0181     add v1, v0, TMP_STKSIZE     /* end of bss + length of tmp stack */
0182     sub v1, v1, (4*4)       /* overhead */
0183     move    sp, v1          /* set sp to top of stack */
0184 4:  sw  zero, 0(v0)
0185     bltu    v0, v1, 4b      /* clear out temp stack */
0186     add v0, 4
0187 
0188 /*  jal init_exc_vecs */        /* install exception handlers */
0189 /*  nop */              /* MUST do before memory probes */
0190 
0191                     /* Force processor into uncached space during memory/cache probes */
0192     la  v0, 5f
0193     li  v1, K1BASE
0194     or  v0, v1
0195     j   v0
0196     nop
0197 5:
0198 
0199     li  a0, HARD_CODED_MEM_SIZE /* Set memory size global */
0200     jal set_memory_size
0201     nop
0202 
0203     la  a0, sim_mem_cfg_struct
0204     jal get_mem_conf        /* Make call to get mem size */
0205     nop
0206     la  a0, sim_mem_cfg_struct
0207     lw  a0, 0(a0)       /* Get memory size from struct */
0208 
0209     jal config_cache        /* determine size of D & I caches */
0210     nop
0211 
0212     move    v0, a0          /* mem_size */
0213 
0214     /* For MIPS 3, we need to be sure that the stack (and hence v0
0215      * here) is aligned on a double word boundary.
0216      */
0217     andi    t0, v0, 0x7
0218     beqz    t0, 12f   /* Last three bits Zero, already aligned */
0219     nop
0220     subu    v0, 4   /* mem_size was not aligned on doubleword bdry????*/
0221 12:
0222 
0223 
0224 
0225 /**************************************************************************
0226 **
0227 **  Permanent Stack - now know top of memory, put permanent stack there
0228 **
0229 ***************************************************************************/
0230 
0231     la  t2, _fbss       /* cache mode as linked */
0232     and t2, 0xF0000000      /* isolate segment */
0233     la  t1, 6f
0234     j   t1          /* back to original cache mode */
0235     nop
0236 6:
0237     or  v0, t2          /* stack back to original cache mode */
0238     addiu   v0,v0,-16       /* overhead */
0239     move    sp, v0          /* now replace count w top of memory */
0240     move    v1, v0
0241     subu    v1, P_STACKSIZE     /* clear requested stack size */
0242 
0243 7:  sw  zero, 0(v1)     /* clear P_STACKSIZE  stack */
0244     bltu    v1,v0,7b
0245     add v1, 4
0246 
0247 
0248 /* Invalidate data cache*/
0249     lui t0, 0x8000      /* Set starting address */
0250     addi    t1, t0, 0x2000      /* Calculate end address (assume worst case of 32 KByte / 4 Way cache) */
0251                     /* D-Cache Writeback and Invalidate */
0252 1:  bge t0, t1, 2f      /* if(t0>=end_addr) then exit */
0253     nop
0254     cache   1, 0(t0)        /* Index_Writeback_Inv_D way 0 */
0255     cache   1, 1(t0)        /* Index_Writeback_Inv_D way 1 */
0256     cache   1, 2(t0)        /* Index_Writeback_Inv_D way 2 */
0257     cache   1, 3(t0)        /* Index_Writeback_Inv_D way 3 */
0258     b   1b
0259     addi    t0, t0, 32
0260 2:
0261 
0262 /* Invalidate instruction cache*/
0263     lui t0, 0x8000      /* Set starting address */
0264     addi    t1, t0, 0x2000      /* Calculate end address (assume worst case of 32 KByte / 4 Way cache) */
0265                     /* I-Cache Disable */
0266     mfc0    t2, C0_CONFIG       /* get C0_Config */
0267     lui t3, 0x2         /* C0_CONFIG#17 ICE# */
0268     or  t3, t2, t3      /* set ICE# bit */
0269     mtc0    t3, C0_CONFIG       /* set C_Config */
0270     b   1f          /* stop streaming */
0271     nop
0272                     /* I-Cache Invalidate */
0273 1:  bge t0, t1, 2f      /* if(t0>=end_addr) then exit */
0274     nop
0275     cache   0, 0(t0)        /* Index_Invalidate_I way 0 */
0276     cache   0, 1(t0)        /* Index_Invalidate_I way 1 */
0277     cache   0, 2(t0)        /* Index_Invalidate_I way 2 */
0278     cache   0, 3(t0)        /* Index_Invalidate_I way 3 */
0279     b   1b
0280     addi    t0, t0, 32
0281                         /* I-Cache Enable */
0282 2:  mtc0    t2, C0_CONFIG       /* set C0_Config */
0283     nop
0284 
0285 /* Lock first 4k of PMON into instruction cache. This includes interrupt service code which
0286  we don't want to run out of slow flash device. */
0287 
0288     la  t0,0x9fc00000
0289     li  t1, 0x1000
0290 
0291     move    t3, t0
0292     addu    t1, t0, t1
0293 1:  bge t0, t1, 2f
0294     nop
0295     lui t2, 0x1fff      /* MASK */
0296     ori t2, t2, 0xf000
0297     and t2, t3, t2      /* virtual->physical */
0298     srl t2, t2, 4       /* [31:12] --> [35:8] */
0299     ori t2, t2, 0x00c4      /* Set Valid & Lock Bits */
0300     mtc0    t2, C0_TAGLO        /* Load data to TagLo reg. */
0301     nop
0302     cache   0x08, 3(t0)     /* 2(I)=0x08: Index_Store_Tag(I$) Way3*/
0303     nop
0304     cache   0x14, 3(t0)     /* 5(I)=0x14: Fill(Memory->Cache) Way3*/
0305     b   1b
0306     addi    t0, t0, 32
0307 2:  nop
0308 
0309     .set    reorder
0310 
0311 /*
0312 ** Clear Translation Lookaside Buffer (TLB)
0313 */
0314     jal init_tlb        /* clear the tlb */
0315 
0316 /*
0317 ** End of CPU initialization, ready to start kernel
0318 */
0319     move    a0,zero     /* Set argc passed to main */
0320     la  sp,_ISR_Stack_area_end # Use configuration defined stack
0321     subu    sp,sp,32
0322     jal boot_card
0323     nop
0324 
0325 /* Kernel has been shutdown, jump to the "exit" routine */
0326     jal _sys_exit
0327     move    a0,v0               # pass through the exit code
0328 
0329 1:
0330     beq zero,zero,1b
0331     nop
0332 
0333 ENDFRAME(start)
0334 
0335 /*
0336  * _sys_exit -- Exit from the application. Normally we cause a user trap
0337  *          to return to the ROM monitor for another run. NOTE: This is
0338  *      the only other routine we provide in the crt0.o object, since
0339  *          it may be tied to the "_start" routine. It also allows
0340  *          executables that contain a complete world to be linked with
0341  *          just the crt0.o object.
0342  */
0343 FRAME(_sys_exit,sp,0,ra)
0344 
0345     break   1023
0346     nop
0347 13:
0348     b   13b             # but loop back just in-case
0349     nop
0350 
0351 ENDFRAME(_sys_exit)
0352 
0353 
0354 
0355     .globl  __sizemem
0356     .ent    __sizemem
0357 __sizemem:
0358     li  v0,HARD_CODED_MEM_SIZE
0359     j   ra
0360     nop
0361     .end    __sizemem
0362