• SPD5详解


    SPD介绍

    SPD(serial presence detect),即串行存在检测,是DIMM的相关描述信息。

    在每根内存条上,都有一份SPD数据,这份数据保存在一个可擦写的eeprom芯片中。SPD数据记录了该内存的许多重要信息,诸如内存的芯片及模组厂商、工作频率、工作电压、速度、容量、电压与行、列地址带宽等参数。SPD数据一般都是在出厂前,由DIMM制造商根据内存芯片的实际性能写入到eeprom芯片中。

    SPD 中的数据主要是供 BIOS 在引导阶段给初始化内存时使用的,如果数据有误或者没有数据将导致内存初始化失败。随着技术发展尤其是 CXL 技术的发展,出现了多种支持 DDR 扩展的外设,这种情况下 SPD 还可能被外设的 fw 读取来进行初始化内存。

    注:如无特别说明,本文档基于 SPD5 进行说明。

    EEPROM 数据

    不同类型的DDR,他们的SPD数据长度和格式可能会不一样,比如:

    • DDR2、DDR3的DIMM,对应的SPD数据长度为256B;
    • DDR4的DIMM,对应的SPD数据长度为512B;
    • DDR5的DIMM,对应的SPD数据长度为1024B。

    但是,在这些不同长度的SPD数据中,有一些字段偏移可能是不兼容的。对于一些很基础的信息,他们的格式是一致的,比如DDR4与DDR3中,第0-5字节,他们表示的含义是相同的,其他则可能就不同。
    下图是 DDR5 中 SPD 的数据布局:

     其中 annexes N.1.x 表示不同类型的内存设备会有不同的格式,具体参考这些章节。

    • Annex A.1: Solder down memory applications
    • Annex A.2: UDIMMs
    • Annex A.3: RDIMM
    • Annex A.4: LRDIMM
    • Annex A.5: DDIMM
    • Annex A.6: NVDIMM-N
    • Annex A.7: NVDIMM-P

    DDR5 可以划分为多个 block:

    • Blocks 0~1: Base Configuration and DRAM Parameters
    • Block 2: Reserved for future use
    • Blocks 3~6: Module Specific Parameters
    • Block 7: Reserved for future use
    • Blocks 8~9: Manufacturing Information
    • Blocks 10~15: End User Programmable

    共 16 个 bolck, 每个 block 包含64bytes,是一个写保护单元。即在 DDR5 的 SPD 中,写保护是按照 block 来进行的。

    DDR5 SPD Revision

    DDR5 SPD Revision 按照 section 划分,每个 section 都有自己的 revision bytes。

     需要注意的是,revision 分成两个部分 x.y,两个部分的数值都是只增不减,如果高位增加,低位也不会降低。比如版本从 1.2 升到 1.3,下一版升高版本时应该是 3.3。

    即使在编码级别增加之后,添加级别也不会降低。例如,如果当前 SPD 修订级别为 1.2,并且编码级别的更改获得批准,则下一个修订级别将是 2.2。如果对修订 2.2 的补充获得批准,下一个修订将是 2.3。然而,编码级别的更改极为罕见,因为它们会导致与旧系统不兼容。

    数据格式

    这里只显示几个常用的字节的数据格式,所有的数据请查看《JESD400-5_DDR5 Serial Presence Detect(SPD) Contents_Rev 0.89》

    Byte 0 (0x000): Number of Bytes in SPD Device
    这个字节表示 SPD 的数据长度。

    Byte 1 (0x001): SPD Revision for Base Configuration Parameters
    这个字节表示 SPD 中 EEPROM 匹配的版本,分为 Encoding Level (高半字节) 和 Additions Level (低半字节)两个部分。其中 Encoding Level 表示发行版本,软件需要读取这部分内容以确定其合法性以及准确性。Additions Level 是可选的,定义了哪些附加字节或属性位。

    Byte 2 (0x002): Key Byte / Host Bus Command Protocol Type
    这个 byte 表示DDR 的版本和类别等信息,BIOS 会根据这个 byte 的值来确定如何解析整个 EEPROM 的内容。
    同时这个 byte 也决定了后面的 block 3-6 里面包含的内容。

    Byte 3 (0x003): Key Byte / Module Type
    这个 byte 表示了 SPD 对应的内存的类型,分为3段表示,bit[3:0]表示 SDRAM 类型,bit[6:4] 表示内存设备类型, bit[7]区分有无混合类型。
    所谓混合类型是指该内存设备除 SDRAM 外还有其他模块用于数据存储。

     其他 EEPROM 内容参见: JESD400-5 DDR5 Serial Presence Detect (SPD) Contents

    SPD 寄存器

    前面描述的 1KB 内容是 EEPROM 的数据,这些数据保存了关于 SDRAM 和 DDR 的配置和性能信息等。对于 SPD 和 EEPROM 本身,还有128个寄存器(每个寄存器 8bits) "MR0 - MR127" 来进行描述和配置。

    Register Map

    •  ROE : Read Only and Persistent
    • RV : Reserved
    • RW : Read and Write
    • RWE : Read Write and Persistent
    • RO : Read Only
    • 1O : Write 1 Only

    Register Description

    这里只记录部分用到过的寄存器的内容。

    MR0 - Device Type; Most Significant Byte

    MR1 - Device Type; Least Significant Byte

    MR11 - I2C Legacy Mode Device Configuration

    这个寄存器设置了 SPD 作为 I2C Slave 时使用的地址模式,1Byte地址或者2Byte地址。使用 1Byte 地址模式时,I2C 的数据包中地址仅占 7bits,只能访问到 128 bytes 范围内的内容,而 EEPROM 占 1KB,所以后面要使用 page 来进行页面选择。使用 2 Bytes 地址模式时,I2C 数据包地址占两个 Bytes,可以直接访问所有的偏移,不需要使用 page。

    Note1:Once any register bit is set to ‘1’, it can only be cleared when the SPD5 Hub device is in offline tester mode of operation.

    Note2:The write (or update) transaction to this register must be followed by STOP operation to allow SPD5 Hub device to update the setting.

    其他寄存器内容参见:JESD300-5 SPD5118, SPD5108 Hub and Serial Presence Detect Device Standard

    I2C 访问 SPD

    访问 SPD 指的是访问 SPD 内的寄存器或者 EEPROM。前面的内容提到,SPD5 有128个配置寄存器,一个 1KB 大小的 EEPROM,这两者空间的偏移都是从 0x00 开始(寄存器:0x00 - 0x7F,EEPROM:0x000 - 0x3FF)。但是这两个空间又同时不在系统的 MMIO 空间中,要使用 I2C/I3C 协议来对它们进行访问,此时如何区分这两个空间就很关键了。

    SPD5 Slave Address

    系统软件对 SPD 的访问一般是通过 I2C/I3C 协议来进行的,SPD 作为 Slave device MIPI 分配有固定的 address。SPD 的 7-bit Address 中高 4 位固定为 ‘a’,低 3 位根据 Hub 的不同有不同的值。其地址分配如下:

     

    I2C Slave Protocol - Host to SPD5 Hub Device

    前面提到的 EEPROM 和 SPD Registers 都属于 SPD5 Hub Device 本身的内容,所以它们使用的 Slave Address 就是 0xaX。后面我们我们还将看到 PMIC 和 RCD 等内容则属于 SPD5 Hub Local Device,此时可以将 SPD5 理解为一个 Hub,其下还可以挂接不同的 PMIC 和 RCD 等作为下游设备挂接到 SPD5 Hub 下,理所当然地它们拥有不同的 Slave Address。

    I2C 访问 SPD5 Hub Device 和 访问 SPD5 Hub Local Device 使用的协议包格式是不一样的,这里主要讲前者。

    前面讲 MR11 寄存器时有提到,SPD5 支持两种地址模式,默认情况下采用的是 2bytes 模式.如果主动修改,也是可以使用 1byte 模式的,但只能应用于 SPD5 Hub Device,不能应用于 PMIC 和 RCD 等。所以 I2C 协议的数据包也会有两种格式。

    SPD 寄存器和 EEPROM 的偏移都是从 0 开始的,所以数据包中定义了一个 MemReg bit 来表示访问的是哪一个区域。

    注:SPD4 或之前只有 1byte 模式一种。

    Write Operation - Data Packet

    MemReg = 0 : 访问 SPD 寄存器,此时 Blk Addr 被当作高位地址
    MemReg = 1 : 访问 EEPROM

    1byte mode write

     这是 1bytes 模式下,Host 写操作的数据包,只取 Address 的低 6 位,Blk Addr[0] 表示取 page 的低 128bytes 还是高 128bytes。由于最多只能访问 256 bytes,要访问其他 EEPROM 位置需要首先向 MR11[2:0] 写入对应的 page 值。

    注:这里的 Blk Addr[0] 和 Address[5:0] 可以看作一个 Address[6:0],这样就避免了分两个位置的麻烦。

    其流程如下,注意 Start/Ack/Stop 等信号由硬件发出,不需要程序员参与:

    1. Host 发送 Start 信号 + Slave Addr;
    2. SPD 回 Ack;
    3. Host 发送要写入的地址: [MemReg, Blk Addr[0], Address[5:0]]
    4. SPD 回 Ack;
    5. Host 发送要写入的数据 1byte;
    6. SPD 回 Ack;
    7. 如果写多个数据,重复步骤5和6,此时数据会依次写入 Address 后面的地址;
    8. Host 发送 Stop,结束通信。

    2bytes mode write

     可以看到,Address被划分到两个字节中,其中[6:0]与 MemReg 组成第一个字节,剩下的[10:7]保存在第二个字节内。对于 SPD5,2bytes 模式下会将地址限制在 1KB 以内(即0x0 - 0x3FF,地址占 10bits),所以这里的 Blk Addr[4] 的值是无效的。

    流程如下:

    1. Host 发送 Start 信号 + Slave Addr;
    2. SPD 回 Ack;
    3. Host 发送地址第一个字节 [MemReg + Address[6:0]];
    4. SPD 回 Ack;
    5. Host 发生地址第二个字节 [Address[10:7]];
    6. SPD 回 Ack;
    7. Host 发送要写入的数据 1byte;
    8. SPD 回 Ack;
    9. 如果写多个数据,重复步骤5和6,此时数据会依次写入 Address 后面的地址;
    10. Host 发送 Stop,结束通信。

    Read Operation - Data Packet

    使用 I2C 进行读操作时,先写入读取地址,再发起第二次通信进行数据读取。读数据时根据协议要求,第一字节 bit0 应该置1,但这是硬件会去完成的操作,对于软件,我们在写入第一个包后,只需从 I2C 数据寄存器中读取内容即可。

    除了第一个消息中不包含要写入的数据,以及写完之后多一个读数据寄存器的步骤,读的操作与写操作基本一致,也通过 MemReg bit来表示读取 EEPROM 或 内部寄存器。

    1byte mode read

     我们只要关注前面 W=0 的部分即可。

    2bytes mode read

    Default Read Address Pointer Mode
    除了上述两种读模式之外, SPD5 还提供了一个叫做“默认读”模式,主要是为了提高从同一地址读取关键数据的效率。在这种模式下,只要发送 Slave ID + 读取命令,不需要写入地址即可从某一地址连续读取数据。该地址在 I2C 初始化时即被写入到寄存器 MR18 中,且只能读取寄存器区域的内容。

     相比于 2bytes mode,这种模式可以节省2个字节的包长度。

    BIOS 对 SPD 的处理

    SPD 的数据按照 section 划分,每个 section 末尾会有两个字节的 CRC 校验值,表示该 section 的数据是否合法。如下图所示:

     BIOS 在处理 SPD 时会按照以下步骤:

    step1. 分析 SPD 数据合法性 : 按照图示,读取每一个 section 的 CRC 校验值,如果校验通过表示 SPD 合法。

    step2. 判断 DDR type 是否正确 : 通过读取 byte2 来判断当前 DIMM 是否是目标类型。比如 byte2 = 0x12 表示 DDR5。

    step3. 验证 SPD 兼容性 : SPD byte1 表示 SPD 的版本信息,当系统比较旧或者发生严重的错误时,强制要求系统停止初始化内存。SPD 版本的增加可能会影响到内部有效数据的长度,但是出于向后兼容的考虑,新的版本的内容通常能覆盖旧的版本。如果 BIOS 仅支持到 SPD 1.2,那么对于1.3 或以上版本的 SPD,BIOS 只能从中提取 1.2 版本定义的信息。

    注:在 DDR5 SPD 中 SPD revision 只表示本段的版本,比如 byte1 表示 byte0-127的版本,其他的 section 都有自己单独 revison byte。这样可以使得各个 section 单独更新而不影响其他 section。

    step4. 确定内存模块类型 : 这里的模块类型是指 RDIMM, UDIMM 等,由 byte3 表示。

    Module Type

    Byte 3

    Solder Down

    0x0B

    UDIMM

    0x02

    SO-DIMM

    0x03

    RDIMM

    0x01

    LRDIMM

    0x04

    DDIMM

    0x07

    NVDIMM-N Hybrid

    0x9x

    NVDIMM-P Hybrid

    0xAx

     step5. 确定内存基本配置 : 分析 byte0-127, 所有的模块类型都需要分析这部分内容。

    step6. 配置标准的内存模块接口 : 分析 byte192 - 447。

    参考资料

    一步一步带你理解DDR基本原理_百里杨的博客-CSDN博客_ddr层次

    JESD400-5 DDR5 Serial Presence Detect (SPD) Contents

    JESD300-5 SPD5118, SPD5108 Hub and Serial Presence Detect Device Standard

  • 相关阅读:
    网络安全(黑客技术)—2024自学
    银河麒麟4.0.2安装带有opengl的Qt5.12.9
    MySQL InnoDB Cluster部署
    电脑浏览器主页被360锁定 - 解决方案
    12306 抢票小助手: 完整易用的抢票解决方案 | 开源日报 0917
    Python反射机制
    基于 Vite + Vue3 + TS + sass + router + element-plus 的项目搭建
    实用篇-认识微服务
    如何创建springboot项目
    戴森创“新”公开课再度开讲,持续助力打造洁净居家环境 以升级科技守护家庭健康
  • 原文地址:https://blog.csdn.net/rangfei/article/details/127037470