内存参数读取节能

2020-11-16 淮安装修公司

前面已经介绍通过读取内存条上的EEPR仅城六区就有22个小商品批发市场OM来获取内存配置参数的,现在来仔细地分析这段代码是怎么样实现的。

lia1, 0x0

1:

lia0,0xa1

bal i2cread

nop

上面这段代码,把0设置给a1,然后把0xa1设置给a0,然后就调用I2C的子函数来读取数据。下面去看函数i2cread是怎么样读取I2C数据。

/* a0: slave address

a1: reg off

*/

LEAF(i2cread)

/* set device address */

liv0, 0xbfd00000 + SMBUS_HOST_ADDRESS

lia0, 0xa1

sba0, 0(v0);

上面代码是输出从设备的地址。

/* store register offset */

liv0, 0xbfd00000 + SMBUS_HOST_COMMAND

sba1, 0(v0);

上面代码是输出从设备的寄存器偏移量。

/* read byte data protocol */

liv0, 0x08

liv1, 0xbfd并且在交易中遵守严格的交易流程00000 + SMBUS_HOST_CONTROL

sbv0, 0(v1);

/* make sure SMB host ready to start, important!--zfx */

liv1, 0xbfd00000 + SMBUS_HOST_STATUS

lbu v0, 0(v1)

andi v0,v0, 0x1f

beqzv0,1f

nop

sbv0, 0(v1)

lbu v0, 0(v1) #flush the write

1:

上面代码是查看数据总线是否准备好数据。

/* start */

liv1, 0xbfd00000 + SMBUS_HOST_CONTROL

lbu v0, 0(v1)

ori v0, v0, 0x40

sbv0, 0(v1);

/* wait */

liv1, 0xbfd00000 + SMBUS_HOST_STATUS

lia1, 0x1000

1:

#if 1

/* delay */

li a0, 0x1000

2:

bnez a0,2b

addiua0, -1

#endif

addiua1, -1

beqz a1, 1f

nop

lbuv0, 0(v1)

andi v0, SMBUS_HOST_STATUS_BUSY

bnezv0, 1b#IDEL ?

nop

上面代码是查看总线是否在忙状态。

1:

liv1, 0xbfd00000 + SMBUS_HOST_STATUS

lbu v0, 0(v1)

andi v0,v0, 0x1f

beqzv0,1f

nop

sbv0, 0(v1) #reset

lbu v0, 0(v1) #flush the write

1:

liv1, 0xbfd00000 + SMBUS_HOST_DATA0

lbuv0, 0(v1)

上面代码是已经把命令成功发送出去,然后成功地读取回来数据,保存在v0寄存里。

jrra

nop

END(i2cread)

通过上面的子函数,就可以通过I2C总线去读取内存条上的EEPROM参数,以便后面进行内存初始化。

在这里第一次读取是第一个字节,在SPD规范里定义为使用了EEPROM多少个字节。为了清楚地知道那些参数是什么东西,这里给出一个简单的说明。

第0字节 表示厂商使用的字节数。

第1字节 表示EERPOM存储容量。

第2字节 表示内存类型。

第3字节 表示行地址位数。

第4字节 表示列地址位数。

第5字节 表示排数。

第6字节 表示数据宽度(低字节)。

第7字节 表示数据宽度(高字节)。

第8字节 表示信号电平。

第9字节 表示SDRAM最高时钟频率。

第10字节 表示SDRAM访问时间。

第11字节 表示配置类型。

第12字节 表示刷行率/类型。

第13字节 表示最小SDRAM颗粒数据宽度。

第16字节 表示支持突发传输长度。

第17字节 表示逻辑BANK数。

第18字节 表示CAS延时。

第23字节 表示SDRM时钟。是2的最大指数倍。

第24字节 表示SDRAM访问时间。

第34字节 表示输入数据建立时间。

第35字节 表示输入数据保持时间。

第62字节 表示SPD版本号。

其它的字节,就要参考SPD文档了。后面一大段程序就是实现了读取这些参数,然后根据这些参数来设置龙芯内存的SDRAM寄存器。

/* 蔡军生 于深圳 */

2:

PRINTSTR("DIMM SIZE=")

move a0,msize

bal hexserial

nop

PRINTSTR("\r\n")

当运行到上面的程序时,已经计算出来有多少内存了。并且也可以用上面的参数去设置内存管理器,如下:

lit0, 0xbff00008

sdsdCfg, 0(t0)

上面代码是设置SDRAM寄存器。

#### gx : 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, 0x

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")

最后再配置BONITO_PCIMEMBASECFG和BONITO_BONPONCFG寄存器,就可以把内存初始化完成了。下一次开始学习怎么样初始化龙芯的缓存。

查看本文来源

肝纤维化早期吃什么药物
金昌哪里能治疗白癜风
武汉治疗白癜风费用
为你推荐