Back to home page

LXR

 
 

    


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

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