📄 init_mips.s
字号:
*/ /* * Copy the code and data */ la v0,_ftext la v1,_image_end move s0,TEXTBASE # li s0,IMAGE_TARGET1: lw t0,0(v0) lw t1,4(v0) lw t2,8(v0) lw t3,12(v0) lw t4,16(v0) lw t5,20(v0) lw t6,24(v0) lw t7,28(v0) sw t0,0(s0) sw t1,4(s0) sw t2,8(s0) sw t3,12(s0) sw t4,16(s0) sw t5,20(s0) sw t6,24(s0) sw t7,28(s0) addu v0,32 addu s0,32 blt v0,v1,1b__DoRelocs: move RELOCOFFSET,TEXTBASE la v0,_ftext subu RELOCOFFSET,v0 /* * Process the DYNAMIC section, gathering interesting * information into CPU registers. */ SETLEDS('R','E','L','O') la v0,_DYNAMIC 11: lw t0,0(v0) # End of DYNAMIC table beq t0,DT_NULL,22f bne t0,DT_REL,1f # Relocation section lw REG_REL,4(v0) addu REG_REL,RELOCOFFSET b 33f1: bne t0,DT_RELSZ,1f # Size of relocation section lw REG_RELSZ,4(v0) b 33f1: bne t0,DT_SYMTAB,1f # Symbol table section lw REG_SYMTAB,4(v0) addu REG_SYMTAB,RELOCOFFSET b 33f1: bne t0,DT_PLTGOT,1f # GOT section lw REG_PLTGOT,4(v0) addu REG_PLTGOT,RELOCOFFSET b 33f1: bne t0,DT_MIPS_LOCAL_GOTNO,1f # Size of GOT section lw REG_GOTNO,4(v0) b 33f1: bne t0,DT_MIPS_SYMTABNO,1f # Size of symbol table lw REG_SYMTABNO,4(v0) b 33f1: bne t0,DT_MIPS_GOTSYM,1f # Number of GOT symbols lw REG_GOTSYM,4(v0) b 33f1:33: add v0,8 # Advance to next entry b 11b # go back for more. /* * Relocate the local GOT entries. Skip the first * entry, or the first two entries if entry #2 has its * high bit set. */__LocalGOT:22: li v0,1 lw t0,4(REG_PLTGOT) # Skip first entry bge t0,zero,1f # and second entry if high bit set li v0,2 add REG_PLTGOT,41: add REG_PLTGOT,4 /* * Now, apply 'relocbase' to the local GOT entries. */1: lw t0,0(REG_PLTGOT) addu t0,RELOCOFFSET # Relocation base sw t0,0(REG_PLTGOT) add REG_PLTGOT,4 add v0,1 blt v0,REG_GOTNO,1b /* * Do the global GOT entries. */__GlobalGOT: sll REG_GOTSYM,4 # mult by 16 for offset sll REG_SYMTABNO,4 # do ending offset too. add v0,REG_SYMTAB,REG_GOTSYM # SYMTAB points at symbol table add v1,REG_SYMTAB,REG_SYMTABNO # v1 points at end of sym table1: lw t0,R_ELF32SYM_ST_VALUE(v0) addu t0,RELOCOFFSET # Relocation base sw t0,0(REG_PLTGOT) add REG_PLTGOT,4 # next GOT entry add v0,16 # next SYM entry blt v0,v1,1b /* * Do the symbol table. */__DoSymTab: add v1,REG_REL,REG_RELSZ # V1 points at end of symbol table1: bge v0,v1,33f lw t0,R_REL_OFFSET(v0) # Get symbol value addu t0,RELOCOFFSET # Relocation base lw t1,R_REL_INFO(v0) # Get symbol type andi t2,t1,M_REL_TYPE # Ignore R_MIPS_NONE bne t2,K_REL_TYPE_REL32,2f # only take R_MIPS_R32#define SUPPORT_OLD_BINUTILS#ifdef SUPPORT_OLD_BINUTILS /* * sbtools 2.7.x (binutils prior to 2.14) and earlier toolchains * need the symbol value added in when relocating. With new * toolchains, which are more correct w.r.t. the SVR4 ABI, doing * that is incorrect and * will cause the firmware to be * relocated badly. * * We use a heuristic: if the relocated value with the symbol * value added in is less than the relocated object base, we * recalculate without the symbol value. The theory is that no * relocations will point outside the firmware. */ srl t1,S_REL_SYM # Symbol "info" is index sll t1,4 # back to symtab index add t1,t1,REG_SYMTAB # t1 points at symtab entry lw t2,R_ELF32SYM_ST_VALUE(t1) # Symbol value addu t2,RELOCOFFSET # Relocation base lw t1,0(t0) # Read original word addu t1,t2 # Add in offset .set push .set noat sltu AT, t1, TEXTBASE beqz AT, 3f nop .set pop#endif lw t1,0(t0) # Read original word addu t1,RELOCOFFSET # Add in relocation offset#ifdef SUPPORT_OLD_BINUTILS3:#endif sw t1,0(t0) # Write it back out2: add v0,8 # more punishment. b 1b33:#endif#------------------------------------------------------------------------------ /* * Zero BSS */ SETLEDS('Z','B','S','S') la a0,segment_table__ZeroBss: LR v0,R_SEG_FBSS(a0) LR v1,R_SEG_END(a0) ADD v0,RELOCOFFSET # Relocate to actual data segment ADD v1,RELOCOFFSET1: SR zero,0(v0) # Zero one cacheline at a time SR zero,(REGSIZE*1)(v0) SR zero,(REGSIZE*2)(v0) SR zero,(REGSIZE*3)(v0) add v0,REGSIZE*4 blt v0,v1,1b#------------------------------------------------------------------------------ /* * Copy initialized data (non-relocating case only, and * not when we're using the PromICE memory as RAM) */#if (!CFG_RELOC)#if (CFG_BOOTRAM == 0) SETLEDS('D','A','T','A') la a0,segment_table__CopyData: LR t1,R_SEG_ETEXT(a0) li t0,15 add t1,t0 not t0 and t1,t0 # t1 = _etext rounded up to 16-byte boundary LR t2,R_SEG_FDATA(a0) LR t3,R_SEG_EDATA(a0) ADD t2,RELOCOFFSET # Relocate to actual data segment ADD t3,RELOCOFFSET1: LR t4,0(t1) # read one cache line LR t5,(REGSIZE*1)(t1) LR t6,(REGSIZE*2)(t1) LR t7,(REGSIZE*3)(t1) SR t4,0(t2) # write one cache line SR t5,(REGSIZE*1)(t2) SR t6,(REGSIZE*2)(t2) SR t7,(REGSIZE*3)(t2) add t1,(REGSIZE*4) add t2,(REGSIZE*4) bltu t2,t3,1b#endif /* (CFG_BOOTRAM == 0) */#endif /* (!CFG_RELOC) */#------------------------------------------------------------------------------#if (CFG_RELOC)#if CFG_RUNFROMKSEG0 SETLEDS('L','1','2','F') li a0,CFE_CACHE_FLUSH_D | CFE_CACHE_FLUSH_L2 JAL(CPUCFG_CACHEOPS) li a0,CFE_CACHE_INVAL_I JAL(CPUCFG_CACHEOPS)#endif /* CFG_RUNFROMKSEG0 */__GoRelo: la t0,1f addu gp,RELOCOFFSET addu t0,RELOCOFFSET jr t01:#endif /* CFG_RELOC */ /* * Remember total amount of memory. This is *still* in k0 * after all this time. Hopefully. */__MemVars: SR k0,mem_totalsize SR RELOCOFFSET,mem_datareloc move v0,zero la a0,segment_table # trashed by l2 cache flush#if (CFG_RELOC) LR v0,R_SEG_FTEXT(a0)#else LR v0,R_SEG_FDATA(a0) ADD v0,RELOCOFFSET#endif LR v1,R_SEG_END(a0)#if !CFG_RELOC ADD v1,RELOCOFFSET#endif#if CFG_RELOC ADD v1,31 # Realign _END so it and v1,~31 # is on a 64-bit boundary.#endif SR v0,mem_bottomofmem SR v1,mem_heapstart add v1,(CFG_HEAP_SIZE*1024) # Otherwise add v1,STACK_SIZE SR v1,mem_topofmem SR RELOCOFFSET,mem_textreloc LR t1,R_SEG_FTEXT(a0) LR t0,R_SEG_ETEXT(a0) sub t0,t0,t1 SR t0,mem_textsize SR t1,mem_textbase#------------------------------------------------------------------------------#if CFG_MULTI_CPUS /* * Let secondary CPU(s) run their idle loops. Set the * mailbox register to our relocation factor so we can read * it out of the mailbox register and relocate GP properly. */ move a0,RELOCOFFSET JAL(CPUCFG_ALTCPU_START2)#endif#ifdef _SB1250_PASS1_WORKAROUNDS_ /* * Okay, it's safe now to be coherent. * Flush the D cache to invalidate all the lines we have, * then change the config register back. */ li a0,CFE_CACHE_FLUSH_D JAL(CPUCFG_CACHEOPS) SETCCAMODE(v0,K_CFG_K0COH_COHERENT) /* cacheable coherent */#endif /* * Stash away some config register stuff */ mfc0 v0,C0_PRID SR v0,cpu_prid #------------------------------------------------------------------------------ /* * Set up the "C" stack and jump to the main routine. */ SETLEDS('M','A','I','N') LR sp,mem_heapstart ADD sp,((CFG_HEAP_SIZE*1024)+STACK_SIZE - 8) li a0,0 # call as "cfe_main(0,0)" li a1,0__LaunchMain: JAL(cfe_main) /* * Terminate the simulator. */crash_sim: li $2,1 li $4,0 syscall 0xCA b cpu_reset/* ********************************************************************* * CPU_KSEG0_SWITCH * * Hack the return address so we will come back in KSEG0 * * Input parameters: * nothing * * Return value: * nothing ********************************************************************* */cpu_kseg0_switch: and ra,(K0SIZE-1) or ra,K0BASE jr ra/* ********************************************************************* * CFE_LAUNCH * * Start the user program. The program is passed a handle * that must be passed back when calling the firmware. * * Parameters passed to the called program are as follows: * * a0 - CFE handle * a1 - entry vector * a2 - reserved, will be 0 * a3 - entrypoint signature. * * Input parameters: * a0 - entry vector * * Return value: * does not return ********************************************************************* */LEAF(cfe_launch) sub sp,8 SR a0,0(sp) /* * Mask all interrupts. */ mfc0 v0,C0_SR # Get current interrupt flag li v1,M_SR_IE # master interrupt control not v1 # disable interrupts and v0,v1 # SR now has IE=0 mtc0 v0,C0_SR # put back into CP0 /* * Flush the D-Cache, since the program we loaded is "data". * Invalidate the I-Cache, so that addresses in the program * region will miss and need to be filled from the data we * just flushed above. */ li a0,CFE_CACHE_FLUSH_D|CFE_CACHE_INVAL_I JAL(CPUCFG_CACHEOPS) /* * Set things up for launching the program. Pass the * handle in A0 - apps need to remember that and pass it * back. */ j RunProgram /* * This is a nice place to set a breakpoint. */RunProgram: la a2,cpu_apientry # a2 = entry point move t0,a0 # move a1,zero # A1 = 0 move a0,gp # A0 = handle (GOT pointer) li a3,CFE_EPTSEAL # A3 = entrypoint signature LR t0,0(sp) # entry point j t0 # go for it.END(cfe_launch)/* ********************************************************************* * CFE_LEDS * * Set the on-board LEDs. * * Input parameters: * a0 - LEDs * * Return value: * nothing ********************************************************************* */LEAF(cfe_leds) JMP(board_setleds) # jump to BSP routineEND(cfe_leds)/* ********************************************************************* * TLB Fill Exeption Handler * * In the SVR4 PIC case, get our GOT pointer from the locore area * and use that. Then, restore GP. Otherwise, just load the * address and go. ********************************************************************* */cpu_tlbfill: .set noat#if CFG_RELOC LDADDR(k1,CPUCFG_TLBHANDLER)#else la k1,CPUCFG_TLBHANDLER j k1 # Dispatch to handler#endif .set at/* ********************************************************************* * XTLB Fill Exception Handler (shouldn't happen) ********************************************************************* */cpu_xtlbfill: LDADDR(k1,_exc_entry) j k1/* ********************************************************************* * Cache Error Exception Handler ********************************************************************* */cpu_cacheerr:#if defined(_CSWARM_) || defined(_SWARM_) || defined(_BCM91120C_) || defined(_PTSWARM_) || defined(_BCM91250PT_) || defined(_BIGSUR_)#define LED_CHAR0 (32+8*3)#define LED_CHAR1 (32+8*2)#define LED_CHAR2 (32+8*1)#define LED_CHAR3 (32+8*0)#if defined(_PTSWARM_) || defined(_BCM91250PT_) li k0,0xBB0A0000 /* address of LEDs */#else li k0,0xB00A0000 /* address of LEDs */#endif li k1,'C' sb k1,LED_CHAR0(k0) li k1,'e' sb k1,LED_CHAR1(k0) li k1,'r' sb k1,LED_CHAR2(k0) li k1,'2' sb k1,LED_CHAR3(k0) SETLEDS1('C','e','r','2')#endifcpu_cache_death: b cpu_cache_death/* ********************************************************************* * General Exception Handler (shouldn't happen) ********************************************************************* */cpu_exception: JMP(_exc_entry)/* ********************************************************************* * General Interrupt Handler (shouldn't happen) ********************************************************************* */cpu_interrupt: JMP(_exc_entry)/* ********************************************************************* * EJTAG Debug Exception Handler ********************************************************************* */cpu_ejtag: .set push .set mips64 deret .set pop j cpu_reset/* ********************************************************************* * End ********************************************************************* */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -