前面已经初始化内存和龙芯的缓存,那么现在已经差不多把新房子已经建立好了,要进入新房居住了。在SDRAM里的存取速度比ROM里快很多,并且可以随时修改数据,而在ROM是不能修改的,就算可以修改,也是非常慢的。
从上面初始化缓存回来后,就运行到下面的程序:
#####xuhua########open cp1
#if 1
mfc0 t0,COP_0_STATUS_REG
and t0,0xdbffffff
or t0,t0,0x24000000
mtc0 t0,COP_0_STATUS_REG
#endif
#################
上面的程序打开了CP1处理器,也就是浮点处理器。先从状态寄存器里取得32位中高4位的协处理器状态,然后先用通过0x2400 0000来打开浮点协处理器,把值改写回到状态寄存器。
/* close L2 cache */
li a0, 0xbfe00164
sw zero, 0(a0);
mfc0 a0,COP_0_CONFIG
and a0,a0,~((1<<12) | 3)
or a0,a0,2
mtc0 a0,COP_0_CONFIG
上面的程序关闭了二级缓存。
TTYDBG("Copy PMON to execute location...\r\n")
#ifdef DEBUG_LOCORE
TTYDBG(" start = 0x")
la a0, start
bal hexserial
nop
TTYDBG("\r\n s0 = 0x")
move a0, s0
bal hexserial
nop
TTYDBG("\r\n")
#endif
上面的代码是调试时显示当前ROM开始地址。
la a0, start
li a1, 0xbfc00000
la a2, _edata
or a0, 0xa0000000
or a2, 0xa0000000
subu t1, a2, a0
srl t1, t1, 2
move t0, a0
move t1, a1
move t2, a2
上面的代码是计算ROM里的代码开始位置和代码的长度,以及RAM里的开始。a0保存要RAM的开始地址0xa001 0000, a1保存ROM的开始地址0xbfc0 0000,a2保存RAM里的结束地址。
/* copy text section */
1: and t3,t0,0x0000ffff
bnez t3,2f
nop
move a0,t0
bal hexserial
nop
li a0,'\r'
bal tgt_putchar
nop
2: lw t3, 0(t1)
nop
sw t3, 0(t0)
addu t0, 4
addu t1, 4
bne t2, t0, 1b
nop
上面的代码是首先显示拷贝的字符,然后在2标号那里用lw从ROM读取4字节数据,接着在后面用sw保存4字节数据到RAM里,最后判断是否拷贝数据完成。
PRINTSTR("\ncopy text section done.\r\n")
/* Clear BSS */
la a0, _edata
la a2, _end
2: sw zero, 0(a0)
bne a2, a0, 2b
addu a0, 4
TTYDBG("Copy PMON to execute location done.\r\n")
上面的代码是清空数据区。
TTYDBG("sp=");
move a0, sp
bal hexserial
nop
#if 1
mfc0 a0,COP_0_CONFIG
and a0,a0,0xfffffff8
or a0,a0,0x3
mtc0 a0,COP_0_CONFIG
#endif
li a0, 4096*1024
sw a0, CpuTertiaryCacheSize /* Set L3 cache size */
上面的代码显示栈的位置,然后设置配置寄存里的kseg0的一致性算法。最后就是保存三级缓存的大小到变量里。
move a0,msize
srl a0,20
/* pass pointer to kseg1 tgt_putchar */
la a1, tgt_putchar
addu a1,a1,s0
la a2, stringserial
addu a2,a2,s0
la v0, initmips
jalr v0
nop
上面代码先把内存大小msize放到参数0里,把输出字符函数指针放到参数1里,把字符串输出函数指针放到参数2里,然后取得C函数initmips入口地址,直接跳到那里运行,永远不再返回来。不过,后面还有一段防止出错的代码,如下:
stuck:
#ifdef DEBUG_LOCORE
TTYDBG("Dumping GT64240 setup.\r\n")
TTYDBG("offset----data------------------------.\r\n")
li s3, 0
1:
move a0, s3
bal hexserial
nop
TTYDBG(": ")
2:
add a0, s3, bonito
lw a0, 0(a0)
bal hexserial
addiu s3, 4
TTYDBG(" ")
li a0, 0xfff
and a0, s3
beqz a0, 3f
li a0, 0x01f
and a0, s3
bnez a0, 2b
TTYDBG("\r\n")
b 1b
nop
3:
b 3b
nop
#else
b stuck
nop
#endif
上面主要是调试的代码,其实就是一个死循环在那里。
到这里,就已经把汇编代码看完了,进入到C的世界,就是更加方便编程和理解了,尽可能写更多的C代码,减少BUG的出现。
查看本文来源