前面已经初始化内存和龙芯的缓存,那么现在已经差不多把新房子已经建立好了,要进入新房居住了。在
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
的出现。