透过 Intel SMBus Controller 读取 DDR4 SPD

BIOS 在POST的过程中会透过SMBus 去读取DIMM上的 EEPROM中之 SPD (serial presence detect) 数据来配置內存控制器(memory controller)。不太熟悉 SMBus 可以先参考 初学 SMBus

在DDR4的时候,JEDEC 定义了一种新的非标准 EE1004 类型,SPD大小增加到4-Kbit (4 * 1024 / 8 = 512 Bytes),分为两个Page,各256Bytes。 (可以参考 4-Kbit Serial Presence Detect (SPD) EEPROM compatible with JEDEC EE1004 (st.com))

如果需要读取数据,要采用switch page的方式,使用一个Byte表示要读取的位址。因此

  • 读取EEPROM 前256 Bytes的资料,需要切到page0
  • 读取EEPROM 后256 Bytes的资料,需要切到page1

如下图,如果要读EEPROM中的offset 0x135的位址,page和要带入的offset关系可以套用以下公式:

#define EE1004_PAGE_SHIFT        8
page = offset >> EE1004_PAGE_SHIFT;
offset &= (1 << EE1004_PAGE_SHIFT) - 1;

page = 0x135 >>8 = 0x01  -->切到page1
offset = 0x135 & ((1<<8) -1) = 0x135 & 0xFF = 0x35 --> offset为 0x35

由此可知,读取DDR4的SPD做法和DDR3差不多,只是多了切page的动作。切page的方式是对 0x36 (SPA0) 或 0x37 (SPA1) 的7 bits address写入一个byte (这边的data可以忽略,填0x00就好)。这个指令对照SMBus Spec 就是Send Byte 

(*0x36 是7bit address, 要加上一个R/W# bit=0 才会是最后送出的address,所以 0x36 <<1 | 0 = 0x6C)

切完page之后,就可以使用Read Byte(或是Byte、Block)将数据读出来,这边R/W# bit要记得设为1

 

最后读出来的数据可以对照 JESD21-C Annex L: Serial Presence Detect for DDR4 SDRAM Modules 翻成明文 

以上可以另外参考

---

最后,如果想要透过操作SMBus Controller 的方式将SPD给读出来,步骤可以分为三个部分

  • 初始化SMBus (只需要做一次)
  • 切PAGE
  • 读SPD (可以用Byte、Byte Data或是Block)

初始化SMBus

// SMBus Controller 
addr = PCI_BASE | (PCI_SMBUS_BUS << 16) | (PCI_SMBUS_DEV << 11) | (PCI_SMBUS_FUN << 8);

// Set the I/O Space enable bit
// PCICMD_OFFSET 0x04
outpd(0xCF8, addr + PCICMD_OFFSET);
data = inpd(0xCFC);
if ((data & 0x01) == 0)
{
	outpd(0xCFC, data | 0x01);
}

// Set the HST_EN bit
// HOSTC_OFFSET 0x40
outpd(0xCF8, addr + HOSTC_OFFSET);
data = inpd(0xCFC);
if ((data & 0x01) == 0)
{
	data = outpd(0xCFC, data | 0x01);
}

// Program the SMBus Base Address Register
// SMB_BASE_OFFSET 0x20
outpd(0xCF8, addr + SMB_BASE_OFFSET);
SMBBASE = inpd(0xCFC) & 0xFFE0;

 

切PAGE

// Clear the status bits
// HST_STS (Host Status Register) 0x00
outp(SMBBASE + HST_STS, 0x1E);

// ee1004 set current page
// XMIT_SLVA (Transmit Slave Address Register)  0x04
// 0x6C for page0, and 0x6E for page1
outp(SMBBASE + XMIT_SLVA, 0x6C); 

// Data is ignored
// HST_CMD (Host Command Register) 0x03
outp(SMBBASE + HST_CMD, 0x00); 

// Execute the Byte command
// HST_CNT (Host Control Register) 0x02
outp(SMBBASE + HST_CNT, 0x44);  

// Error handling

 

读SPD (这边使用Byte Data)

// Clear the status bits
// HST_STS (Host Status Register) 0x00
outp(SMBBASE + HST_STS, 0x1E);

// Set Address
// XMIT_SLVA (Transmit Slave Address Register)  0x04
outp(SMBBASE + XMIT_SLVA, Addr << 1 | 1); 

// HST_CMD (Host Command Register) 0x03
outp(SMBBASE + HST_CMD, offset2read); 

// Execute the Byte Data command
// HST_CNT (Host Control Register) 0x02
outp(SMBBASE + HST_CNT, 0x48);      

// Error handling

// Read data from Data0 register
// HST_D0 (Host Data 0 Register) 0x05
SPDData = inp(SMBBASE + HST_D0);

  • 4
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值