龙芯软件开发(15)-- 搬家前的准备

龙芯软件开发(15)-- 搬家前的准备
任何人在搬家前,都需要把新房子修建好,然后再经过装修才能住到新房子里,然而这里的启动程序也不例外,需要把自己的房子先修好,并且通过装修才会住进里面。当然,程序所需要的房子,不是普通的房子,而是内存空间。由于在ROM运行的速度都是比较慢,并且空间有限,不能随时更改ROM里的内容。同时为了下一阶段作好准备,就需要把ROM里的引导程序搬到内存里运行。但是SDRAM在加电后,并不能立即使用,需要进行初始化,设置好参数才能保存数据。比如设置内存的刷新时间,如果设置时间不对,SDRAM就不能保存数据,以前我就有设置不对的参数,导致拷贝到内存的数据很快就丢失了。
在龙芯电脑里,使用的内存是标准的笔记本内存,也就是叫做SO-DIMM内存。这种内存是工业上的标准,出货量都比较大,相对来说是比较便宜的。INTEL公司为了电脑配件标准化,就定义了一套叫做内存检测标准。在那个标准里,就定义了内存初始化时使用方式,内存类型标识等等。由于内存的参数是不同的厂家不一样,不同的类型也不一样,不同的大小也是不一样,既然是这样的话,就让厂家在出厂前把所有内存的配置信息写到一个EEPROM里,让BIOS启动时再去读取参数,并且进行内存初始化。要读取EEPROM中的信息,就需要使用I2C总线来读取。I2C总线是由PHILIPS公司定义IC之间的相互通讯的协议,它是一种分主从的两线通讯协议,一条线表示时钟信号,一条线表示数据信号,不管数据是读取,还是写入,都是通过数据线来进行的。无论是读取,还是写入数据,都是由主方先发开始信号,然后发送从设备的地址,相应地址的从设备就要响应后面的命令,而不同地址的设备就不会响应后面的命令。为什么读取DIMM内存上的EEPROM,就需要按I2C的协议进行通讯,才会读取内存的参数,并对内存进行初始化。下面这段程序,就是做这样的事情:
PRINTSTR("DIMM read/r/n")
/* only one memory slot, slave address is 1010000b */
lia1, 0x0
1:
lia0,0xa1
bal i2cread
nop
# save a1
move t1, a1
#print
move a0, v0
balhexserial
nop
PRINTSTR("/r/n")
# restore a1
movea1,t1
addiu a1,a1,1
li v0, 0x20
bleua1, v0, 1b
nop
limsize,0
# set some parameters for DDR333
# rank number and DDR type field will be filled later
# to check: fix TCAS?
lisdCfg, 0x341043df
lia0,0xa1
/* read DIMM memory type (must be DDRAM) */
#li a1,2
#bal i2cread
#nop
#bne v0,7,.nodimm
#nop
PRINTSTR("read memory type/r/n")
/* read DIMM number of rows */
lia0,0xa1
lia1,3
bal i2cread
nop
move a0, v0
subu v0, 12
move s1, v0
bgtu v0, 2,.nodimm
nop
PRINTSTR("read number of rows/r/n")
2:/* read DIMM number of cols */
lia0,0xa1
lia1,4
bal i2cread
nop
subu v0, 8
bgtu v0, 4,.nodimm
nop
move t1, s1
bne t1, 0, 10f
nop
bne v0, 2, 20f
nop
liv0, 0
b .ddrtype
nop
20: bne v0, 1, 21f
nop
liv0, 1
b .ddrtype
nop
21: bne v0, 0, 22f
nop
liv0, 2
b .ddrtype
nop
22: bne v0, 3, 33f
nop
liv0, 3
b .ddrtype
nop
10: bne t1, 1, 11f
nop
bne v0, 3, 20f
nop
liv0, 4
b .ddrtype
nop
20: bne v0, 2, 21f
nop
liv0, 5
b .ddrtype
nop
21: bne v0, 1, 22f
nop
liv0, 6
b .ddrtype
nop
22: bne v0, 4, 33f
nop
liv0, 7
b .ddrtype
nop
11: bne t1, 2, 33f
nop
bne v0, 4, 20f
nop
liv0, 8
b .ddrtype
nop
20: bne v0, 3, 21f
nop
liv0, 9
b .ddrtype
nop
21: bne v0, 2, 33f
nop
liv0, 10
b .ddrtype
nop
33: PRINTSTR("DDR type not supported!/r/n");
34: b 34b
nop
.ddrtype:
#bit 25:22 is DDR type field
sll v0, 22
and v0,0x03c00000
orsdCfg,v0
/* read DIMM memory size per side */
lia0,0xa1
lia1,31
bal i2cread
nop
beqz v0,.nodimm
nop
sll tmpsize,v0,22 # multiply by 4M
PRINTSTR("read memory size per side/r/n")
2:/* read DIMM number of blocks-per-ddrram */
lia1,17
bal i2cread
nop
beq v0,2,2f
nop
bne v0,4,.nodimm
nop
PRINTSTR("read blocks per ddrram/r/n")
2:/* read DIMM number of sides (banks) */
lia1,5
bal i2cread
nop
beq v0,1,2f
nop
bne v0,2,.nodimm
nop
sll tmpsize,1# msize *= 2
orsdCfg, 0x1<<27
PRINTSTR("read number of sides/r/n")
2:/* read DIMM width */
lia1,6
bal i2cread
nop
bleu v0,36,2f
nop
bgtu v0,72,.nodimm
nop
PRINTSTR("read width/r/n")
2:addu msize,tmpsize
b 2f
nop
.nodimm:
move dbg,a0
PRINTSTR ("/r/nNo DIMM in slot ")
move a0,dbg
bal hexserial
nop
PRINTSTR("/r/n")
move a0,dbg
#limsize,0x10000000
#li sdCfg,0x3d9043df#~133MHz
limsize,0x20000000
lisdCfg,0x3d5043df #~133MHz
2:
PRINTSTR("DIMM SIZE=")
move a0,msize
bal hexserial
nop
PRINTSTR("/r/n")
lit0, 0xbff00008
sdsdCfg, 0(t0)
#### gx 2006-03-17: mode ####
#li t1,0x20
lit1,0x28
lit0, 0xbff00000
sdt1,0(t0)
nop
lit1,0x0
lit0, 0xbff00000
sdt1,0x30(t0)
nop
#### setup high memory window ####
li t1, 0x10000000
blt msize, t1, 1f
nop
lui t1,0x2000
sdt1,0x20(t0)
nop
lui t1,0x1000
sdt1,0x28(t0)
nop
1:
PRINTSTR("sdcfg=");
move a0,sdCfg
bal hexserial
nop
PRINTSTR("/r/n");
PRINTSTR("msize=");
move a0,msize
bal hexserial
nop
PRINTSTR("/r/n")
skipdimm:
lit1,0 # accumulate pcimembasecfg settings
/* set bar0 mask and translation to point to SDRAM */
sub t0,msize,1
not t0
srl t0,BONITO_PCIMEMBASECFG_ASHIFT-BONITO_PCIMEMBASECFG_MEMBASE0_MASK_SHIFT
and t0,BONITO_PCIMEMBASECFG_MEMBASE0_MASK
ort1,t0
lit0,0x00000000
srl t0,BONITO_PCIMEMBASECFG_ASHIFT-BONITO_PCIMEMBASECFG_MEMBASE0_TRANS_SHIFT
and t0,BONITO_PCIMEMBASECFG_MEMBASE0_TRANS
ort1,t0
ort1,BONITO_PCIMEMBASECFG_MEMBASE0_CACHED
/* set bar1 to minimum size to conserve PCI space */
lit0, ~0
srl t0,BONITO_PCIMEMBASECFG_ASHIFT-BONITO_PCIMEMBASECFG_MEMBASE1_MASK_SHIFT
and t0,BONITO_PCIMEMBASECFG_MEMBASE1_MASK
ort1,t0
lit0,0x00000000
srl t0,BONITO_PCIMEMBASECFG_ASHIFT-BONITO_PCIMEMBASECFG_MEMBASE1_TRANS_SHIFT
and t0,BONITO_PCIMEMBASECFG_MEMBASE1_TRANS
ort1,t0
ort1,BONITO_PCIMEMBASECFG_MEMBASE1_CACHED
swt1,BONITO_PCIMEMBASECFG(bonito)
/* enable configuration cycles now */
lwt0,BONITO_BONPONCFG(bonito)
and t0,~BONITO_BONPONCFG_CONFIG_DIS
swt0,BONITO_BONPONCFG(bonito)
/* 蔡军生 2007-1-1 于深圳 */
PRINTSTR("Init SDRAM Done!/r/n");
下一次再来仔细地分析这段程序是怎么样实现的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值