summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Jones <mjjones@us.ibm.com>2013-06-14 08:58:18 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2013-07-10 16:28:40 -0500
commit8e6af8d1488285d670754de8f34ffba9ce57db92 (patch)
treec8bcf7f5ad64bdb9e3dfef694e1159b9cc56019e
parentc154ece8068c2f0fc366235ba952003e08df48a1 (diff)
downloadtalos-hostboot-8e6af8d1488285d670754de8f34ffba9ce57db92.tar.gz
talos-hostboot-8e6af8d1488285d670754de8f34ffba9ce57db92.zip
Add support for DDR4 DIMM SPD
Change-Id: Icc07f52aa80436d7bd6849b64683201df4d41c29 RTC: 61138 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/5014 Tested-by: Jenkins Server Reviewed-by: William H. Schwartz <whs@us.ibm.com> Reviewed-by: Donald E. Dahle <dedahle@us.ibm.com> Reviewed-by: ADAM R. MUHLE <armuhle@us.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
-rw-r--r--src/include/usr/hwpf/plat/fapiPlatAttributeService.H132
-rw-r--r--src/include/usr/vpd/spdenums.H465
-rw-r--r--src/include/usr/vpd/vpdreasoncodes.H13
-rw-r--r--src/usr/hwpf/hwp/dimm_spd_attributes.xml979
-rw-r--r--src/usr/hwpf/plat/fapiPlatAttributeService.C64
-rwxr-xr-xsrc/usr/vpd/spd.C763
-rwxr-xr-xsrc/usr/vpd/spd.H52
-rw-r--r--src/usr/vpd/spdDDR3.H453
-rw-r--r--src/usr/vpd/spdDDR4.H168
-rwxr-xr-xsrc/usr/vpd/test/spdtest.H248
10 files changed, 2310 insertions, 1027 deletions
diff --git a/src/include/usr/hwpf/plat/fapiPlatAttributeService.H b/src/include/usr/hwpf/plat/fapiPlatAttributeService.H
index fd2776f7c..a5a38267d 100644
--- a/src/include/usr/hwpf/plat/fapiPlatAttributeService.H
+++ b/src/include/usr/hwpf/plat/fapiPlatAttributeService.H
@@ -693,6 +693,138 @@ fapi::ReturnCode fapiPlatGetSlopeInterceptData (
#define ATTR_SPD_BAD_DQ_DATA_SETMACRO(ID, PTARGET, VAL) \
fapi::AttrOverrideSync::setAttrActionsFunc(fapi::ID, PTARGET, sizeof(VAL), &(VAL)), \
fapi::platAttrSvc::fapiPlatSetSpdAttr( PTARGET, SPD::DIMM_BAD_DQ_DATA, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_LR_ADDR_MIRRORING_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::LRMM_MIRRORING, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_LR_F0RC3_F0RC2_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::LRMM_F0RC3_FORC2, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_LR_F0RC5_F0RC4_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::LRMM_F0RC5_FORC4, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_LR_F1RC11_F1RC8_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::LRMM_F1RC11_F1RC8, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_LR_F1RC13_F1RC12_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::LRMM_F1RC13_F1RC12, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_LR_F1RC15_F1RC14_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::LRMM_F1RC15_F1RC14, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_LR_F3RC9_F3RC8_FOR_800_1066_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::LRMM_F3RC9_F3RC8_800_1066, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_LR_F34RC11_F34RC10_FOR_800_1066_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::LRMM_F34RC11_F34RC10_800_1066, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_LR_F56RC11_F56RC10_FOR_800_1066_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::LRMM_F56RC11_F56RC10_800_1066, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_LR_F78RC11_F78RC10_FOR_800_1066_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::LRMM_F78RC11_F78RC10_800_1066, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_LR_F910RC11_F910RC10_FOR_800_1066_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::LRMM_F910RC11_F910RC10_800_1066, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_LR_MR12_FOR_800_1066_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::LRMM_MR12_800_1066, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_LR_F3RC9_F3RC8_FOR_1333_1600_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::LRMM_F3RC9_F3RC8_1333_1600, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_LR_F34RC11_F34RC10_FOR_1333_1600_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::LRMM_F34RC11_F34RC10_1333_1600, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_LR_F56RC11_F56RC10_FOR_1333_1600_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::LRMM_F56RC11_F56RC10_1333_1600, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_LR_F78RC11_F78RC10_FOR_1333_1600_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::LRMM_F78RC11_F78RC10_1333_1600, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_LR_F910RC11_F910RC10_FOR_1333_1600_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::LRMM_F910RC11_F910RC10_1333_1600, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_LR_MR12_FOR_1333_1600_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::LRMM_MR12_1333_1600, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_LR_F3RC9_F3RC8_FOR_1866_2133_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::LRMM_F3RC9_F3RC8_1866_2133, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_LR_F34RC11_F34RC10_FOR_1866_2133_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::LRMM_F34RC11_F34RC10_1866_2133, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_LR_F56RC11_F56RC10_FOR_1866_2133_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::LRMM_F56RC11_F56RC10_1866_2133, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_LR_F78RC11_F78RC10_FOR_1866_2133_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::LRMM_F78RC11_F78RC10_1866_2133, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_LR_F910RC11_F910RC10_FOR_1866_2133_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::LRMM_F910RC11_F910RC10_1866_2133, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_LR_MR12_FOR_1866_2133_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::LRMM_MR12_FOR_1866_2133, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_SDRAM_BANKGROUPS_DDR4_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::BANK_GROUP_BITS, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_SDRAM_BANKS_DDR4_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::BANK_ADDRESS_BITS_DDR4, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_MODULE_NOMINAL_VOLTAGE_DDR4_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::MODULE_NOMINAL_VOLTAGE_DDR4, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_TIMEBASE_MTB_DDR4_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::TIMEBASES_MTB, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_TIMEBASE_FTB_DDR4_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::TIMEBASES_FTB, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_TCKMAX_DDR4_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::TCK_MAX, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_CAS_LATENCIES_SUPPORTED_DDR4_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::CAS_LATENCIES_SUPPORTED_DDR4, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_TRFC1MIN_DDR4_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::TRFC1_MIN, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_TRFC2MIN_DDR4_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::TRFC2_MIN, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_TRFC4MIN_DDR4_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::TRFC4_MIN, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_TRRDSMIN_DDR4_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::TRRDS_MIN, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_TRRDLMIN_DDR4_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::TRRDL_MIN, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_TCCDLMIN_DDR4_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::TCCDL_MIN, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_FINE_OFFSET_TCCDLMIN_DDR4_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::TCCDL_FINE_OFFSET, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_FINE_OFFSET_TRRDLMIN_DDR4_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::TRRDL_FINE_OFFSET, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_FINE_OFFSET_TRRDSMIN_DDR4_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::TRRDS_FINE_OFFSET, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_FINE_OFFSET_TCKMAX_DDR4_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::TCKMAX_FINE_OFFSET, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_CRC_BASE_CONFIG_DDR4_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::BASE_CONFIG_CRC, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_DRAM_STEPPING_DDR4_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::DRAM_STEPPING, &(VAL), sizeof(VAL) )
+#define ATTR_SPD_CRC_MNFG_SEC_DDR4_GETMACRO(ID, PTARGET, VAL) \
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \
+ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::MANUFACTURING_SECTION_CRC, &(VAL), sizeof(VAL) )
//------------------------------------------------------------------------------
// MACROs to route ATTR Base Address accesses to the correct Hostboot function
diff --git a/src/include/usr/vpd/spdenums.H b/src/include/usr/vpd/spdenums.H
index 598b3186b..49860ffd4 100644
--- a/src/include/usr/vpd/spdenums.H
+++ b/src/include/usr/vpd/spdenums.H
@@ -44,210 +44,271 @@ enum
enum
{
// ==============================================================
- // Normal SPD Kewords
- CRC_EXCLUDE = SPD_FIRST_NORM_KEYWORD | 0x00,
- SPD_BYTES_TOTAL = SPD_FIRST_NORM_KEYWORD | 0x01,
- SPD_BYTES_USED = SPD_FIRST_NORM_KEYWORD | 0x02,
- SPD_MAJOR_REVISION = SPD_FIRST_NORM_KEYWORD | 0x03,
- SPD_MINOR_REVISION = SPD_FIRST_NORM_KEYWORD | 0x04,
- BASIC_MEMORY_TYPE = SPD_FIRST_NORM_KEYWORD | 0x05,
- MODULE_TYPE = SPD_FIRST_NORM_KEYWORD | 0x06,
- BANK_ADDRESS_BITS = SPD_FIRST_NORM_KEYWORD | 0x07,
- DENSITY = SPD_FIRST_NORM_KEYWORD | 0x08,
- ROW_ADDRESS = SPD_FIRST_NORM_KEYWORD | 0x09,
- COL_ADDRESS = SPD_FIRST_NORM_KEYWORD | 0x0a,
- MODULE_NOMINAL_VOLTAGE = SPD_FIRST_NORM_KEYWORD | 0x0b,
- MODULE_RANKS = SPD_FIRST_NORM_KEYWORD | 0x0c,
- MODULE_DRAM_WIDTH = SPD_FIRST_NORM_KEYWORD | 0x0d,
- ECC_BITS = SPD_FIRST_NORM_KEYWORD | 0x0e,
- MODULE_MEMORY_BUS_WIDTH = SPD_FIRST_NORM_KEYWORD | 0x0f,
- FTB_DIVIDEND = SPD_FIRST_NORM_KEYWORD | 0x10,
- FTB_DIVISOR = SPD_FIRST_NORM_KEYWORD | 0x11,
- MTB_DIVIDEND = SPD_FIRST_NORM_KEYWORD | 0x12,
- MTB_DIVISOR = SPD_FIRST_NORM_KEYWORD | 0x13,
- TCK_MIN = SPD_FIRST_NORM_KEYWORD | 0x14,
- CAS_LATENCIES_SUPPORTED = SPD_FIRST_NORM_KEYWORD | 0x15,
- MIN_CAS_LATENCY = SPD_FIRST_NORM_KEYWORD | 0x16,
- TWR_MIN = SPD_FIRST_NORM_KEYWORD | 0x17,
- TRCD_MIN = SPD_FIRST_NORM_KEYWORD | 0x18,
- TRRD_MIN = SPD_FIRST_NORM_KEYWORD | 0x19,
- TRP_MIN = SPD_FIRST_NORM_KEYWORD | 0x1a,
- TRC_MIN = SPD_FIRST_NORM_KEYWORD | 0x1b,
- TRAS_MIN = SPD_FIRST_NORM_KEYWORD | 0x1c,
- TRFC_MIN = SPD_FIRST_NORM_KEYWORD | 0x1d,
- TWTR_MIN = SPD_FIRST_NORM_KEYWORD | 0x1e,
- TRTP_MIN = SPD_FIRST_NORM_KEYWORD | 0x1f,
- TFAW_MIN = SPD_FIRST_NORM_KEYWORD | 0x20,
- DLL_OFF = SPD_FIRST_NORM_KEYWORD | 0x21,
- RZQ_7 = SPD_FIRST_NORM_KEYWORD | 0x22,
- RZQ_6 = SPD_FIRST_NORM_KEYWORD | 0x23,
- PASR = SPD_FIRST_NORM_KEYWORD | 0x24,
- ODTS = SPD_FIRST_NORM_KEYWORD | 0x25,
- ASR = SPD_FIRST_NORM_KEYWORD | 0x26,
- ETR_1X = SPD_FIRST_NORM_KEYWORD | 0x27,
- ETR = SPD_FIRST_NORM_KEYWORD | 0x28,
- THERMAL_SENSOR_PRESENT = SPD_FIRST_NORM_KEYWORD | 0x29,
- THERMAL_SENSOR_ACCURACY = SPD_FIRST_NORM_KEYWORD | 0x2a,
- SDRAM_DEVICE_TYPE_NONSTD = SPD_FIRST_NORM_KEYWORD | 0x2b,
- SDRAM_DEVICE_TYPE = SPD_FIRST_NORM_KEYWORD | 0x2c,
- MODULE_TYPE_SPECIFIC_SECTION = SPD_FIRST_NORM_KEYWORD | 0x2d,
- MODULE_MANUFACTURER_ID = SPD_FIRST_NORM_KEYWORD | 0x2e,
- MODULE_MANUFACTURING_LOCATION = SPD_FIRST_NORM_KEYWORD | 0x2f,
- MODULE_MANUFACTURING_DATE = SPD_FIRST_NORM_KEYWORD | 0x30,
- MODULE_SERIAL_NUMBER = SPD_FIRST_NORM_KEYWORD | 0x31,
- MODULE_CRC = SPD_FIRST_NORM_KEYWORD | 0x32,
- MODULE_PART_NUMBER = SPD_FIRST_NORM_KEYWORD | 0x33,
- MODULE_REVISION_CODE = SPD_FIRST_NORM_KEYWORD | 0x34,
- DRAM_MANUFACTURER_ID = SPD_FIRST_NORM_KEYWORD | 0x35,
- MANUFACTURER_SPECIFIC_DATA = SPD_FIRST_NORM_KEYWORD | 0x36,
- TCKMIN_FINE_OFFSET = SPD_FIRST_NORM_KEYWORD | 0x37,
- TAAMIN_FINE_OFFSET = SPD_FIRST_NORM_KEYWORD | 0x38,
- TRCDMIN_FINE_OFFSET = SPD_FIRST_NORM_KEYWORD | 0x39,
- TRPMIN_FINE_OFFSET = SPD_FIRST_NORM_KEYWORD | 0x3a,
- TRCMIN_FINE_OFFSET = SPD_FIRST_NORM_KEYWORD | 0x3b,
- MODULE_THERMAL_SENSOR = SPD_FIRST_NORM_KEYWORD | 0x3c,
- SDRAM_OPTIONAL_FEATURES = SPD_FIRST_NORM_KEYWORD | 0x3d,
- SDRAM_THERMAL_REFRESH_OPTIONS = SPD_FIRST_NORM_KEYWORD | 0x3e,
- DIMM_BAD_DQ_DATA = SPD_FIRST_NORM_KEYWORD | 0x3f,
- SDRAM_DIE_COUNT = SPD_FIRST_NORM_KEYWORD | 0x40,
- SDRAM_DEVICE_TYPE_SIGNAL_LOADING = SPD_FIRST_NORM_KEYWORD | 0x41,
- CUSTOM = SPD_FIRST_NORM_KEYWORD | 0x42,
- SPD_LAST_NORM_KEYWORD,
+ // Normal SPD Keywords (Available for both DDR3 and DDR4 DIMMs)
+ CRC_EXCLUDE = SPD_FIRST_NORM_KEYWORD | 0x00,
+ SPD_BYTES_TOTAL = SPD_FIRST_NORM_KEYWORD | 0x01,
+ SPD_BYTES_USED = SPD_FIRST_NORM_KEYWORD | 0x02,
+ SPD_MAJOR_REVISION = SPD_FIRST_NORM_KEYWORD | 0x03,
+ SPD_MINOR_REVISION = SPD_FIRST_NORM_KEYWORD | 0x04,
+ BASIC_MEMORY_TYPE = SPD_FIRST_NORM_KEYWORD | 0x05,
+ CUSTOM = SPD_FIRST_NORM_KEYWORD | 0x06,
+ MODULE_TYPE = SPD_FIRST_NORM_KEYWORD | 0x07,
+ DENSITY = SPD_FIRST_NORM_KEYWORD | 0x08,
+ ROW_ADDRESS = SPD_FIRST_NORM_KEYWORD | 0x09,
+ COL_ADDRESS = SPD_FIRST_NORM_KEYWORD | 0x0a,
+ MODULE_RANKS = SPD_FIRST_NORM_KEYWORD | 0x0b,
+ MODULE_DRAM_WIDTH = SPD_FIRST_NORM_KEYWORD | 0x0c,
+ MODULE_MEMORY_BUS_WIDTH = SPD_FIRST_NORM_KEYWORD | 0x0d,
+ MODULE_MEMORY_BUS_WIDTH_EXT = SPD_FIRST_NORM_KEYWORD | 0x0e,
+ MODULE_MEMORY_BUS_WIDTH_PRI = SPD_FIRST_NORM_KEYWORD | 0x0f,
+ TCK_MIN = SPD_FIRST_NORM_KEYWORD | 0x10,
+ MIN_CAS_LATENCY = SPD_FIRST_NORM_KEYWORD | 0x11,
+ TRCD_MIN = SPD_FIRST_NORM_KEYWORD | 0x12,
+ TRP_MIN = SPD_FIRST_NORM_KEYWORD | 0x13,
+ TRC_MIN = SPD_FIRST_NORM_KEYWORD | 0x14,
+ TRAS_MIN = SPD_FIRST_NORM_KEYWORD | 0x15,
+ TFAW_MIN = SPD_FIRST_NORM_KEYWORD | 0x16,
+ SDRAM_OPTIONAL_FEATURES = SPD_FIRST_NORM_KEYWORD | 0x17,
+ SDRAM_THERMAL_REFRESH_OPTIONS = SPD_FIRST_NORM_KEYWORD | 0x18,
+ MODULE_THERMAL_SENSOR = SPD_FIRST_NORM_KEYWORD | 0x19,
+ THERMAL_SENSOR_PRESENT = SPD_FIRST_NORM_KEYWORD | 0x1a,
+ THERMAL_SENSOR_ACCURACY = SPD_FIRST_NORM_KEYWORD | 0x1b,
+ SDRAM_DEVICE_TYPE = SPD_FIRST_NORM_KEYWORD | 0x1c,
+ SDRAM_DIE_COUNT = SPD_FIRST_NORM_KEYWORD | 0x1d,
+ SDRAM_DEVICE_TYPE_SIGNAL_LOADING = SPD_FIRST_NORM_KEYWORD | 0x1e,
+ TCKMIN_FINE_OFFSET = SPD_FIRST_NORM_KEYWORD | 0x1f,
+ TAAMIN_FINE_OFFSET = SPD_FIRST_NORM_KEYWORD | 0x20,
+ TRCDMIN_FINE_OFFSET = SPD_FIRST_NORM_KEYWORD | 0x21,
+ TRPMIN_FINE_OFFSET = SPD_FIRST_NORM_KEYWORD | 0x22,
+ TRCMIN_FINE_OFFSET = SPD_FIRST_NORM_KEYWORD | 0x23,
+ MODULE_TYPE_SPECIFIC_SECTION = SPD_FIRST_NORM_KEYWORD | 0x24,
+ MODULE_MANUFACTURER_ID = SPD_FIRST_NORM_KEYWORD | 0x25,
+ MODULE_MANUFACTURING_LOCATION = SPD_FIRST_NORM_KEYWORD | 0x26,
+ MODULE_MANUFACTURING_DATE = SPD_FIRST_NORM_KEYWORD | 0x27,
+ MODULE_SERIAL_NUMBER = SPD_FIRST_NORM_KEYWORD | 0x28,
+ MODULE_PART_NUMBER = SPD_FIRST_NORM_KEYWORD | 0x29,
+ MODULE_REVISION_CODE = SPD_FIRST_NORM_KEYWORD | 0x2a,
+ DRAM_MANUFACTURER_ID = SPD_FIRST_NORM_KEYWORD | 0x2b,
+ MANUFACTURER_SPECIFIC_DATA = SPD_FIRST_NORM_KEYWORD | 0x2c,
+ DIMM_BAD_DQ_DATA = SPD_FIRST_NORM_KEYWORD | 0x2d,
// ==============================================================
- // Module Specific Keywords
- MODSPEC_COM_NOM_HEIGHT_MAX = SPD_FIRST_MOD_SPEC | 0x00,
- MODSPEC_COM_MAX_THICK_BACK = SPD_FIRST_MOD_SPEC | 0x01,
- MODSPEC_COM_MAX_THICK_FRONT = SPD_FIRST_MOD_SPEC | 0x02,
- MODSPEC_COM_RAW_CARD_EXT = SPD_FIRST_MOD_SPEC | 0x03,
- MODSPEC_COM_RAW_CARD_REV = SPD_FIRST_MOD_SPEC | 0x04,
- MODSPEC_COM_RAW_CARD = SPD_FIRST_MOD_SPEC | 0x05,
- MODSPEC_COM_ADDR_MAPPING = SPD_FIRST_MOD_SPEC | 0x06,
- RMM_ROWS_RDIMM = SPD_FIRST_MOD_SPEC | 0x07,
- RMM_REGS_RDIMM = SPD_FIRST_MOD_SPEC | 0x08,
- RMM_HEAT_SP = SPD_FIRST_MOD_SPEC | 0x09,
- RMM_HEAT_SP_CHARS = SPD_FIRST_MOD_SPEC | 0x0a,
- RMM_MFR_ID_CODE = SPD_FIRST_MOD_SPEC | 0x0b,
- RMM_REG_REV_NUM = SPD_FIRST_MOD_SPEC | 0x0c,
- RMM_REG_TYPE = SPD_FIRST_MOD_SPEC | 0x0d,
- RMM_RC1 = SPD_FIRST_MOD_SPEC | 0x0e,
- RMM_RC0 = SPD_FIRST_MOD_SPEC | 0x0f,
- RMM_RC3 = SPD_FIRST_MOD_SPEC | 0x10,
- RMM_RC2 = SPD_FIRST_MOD_SPEC | 0x11,
- RMM_RC5 = SPD_FIRST_MOD_SPEC | 0x12,
- RMM_RC4 = SPD_FIRST_MOD_SPEC | 0x13,
- RMM_RC7 = SPD_FIRST_MOD_SPEC | 0x14,
- RMM_RC6 = SPD_FIRST_MOD_SPEC | 0x15,
- RMM_RC9 = SPD_FIRST_MOD_SPEC | 0x16,
- RMM_RC8 = SPD_FIRST_MOD_SPEC | 0x17,
- RMM_RC11 = SPD_FIRST_MOD_SPEC | 0x18,
- RMM_RC10 = SPD_FIRST_MOD_SPEC | 0x19,
- RMM_RC13 = SPD_FIRST_MOD_SPEC | 0x1a,
- RMM_RC12 = SPD_FIRST_MOD_SPEC | 0x1b,
- RMM_RC15 = SPD_FIRST_MOD_SPEC | 0x1c,
- RMM_RC14 = SPD_FIRST_MOD_SPEC | 0x1d,
- LRMM_HEAT_SP = SPD_FIRST_MOD_SPEC | 0x1e,
- LRMM_RANK_NUMBERING = SPD_FIRST_MOD_SPEC | 0x1f,
- LRMM_MEMBUF_ORIEN = SPD_FIRST_MOD_SPEC | 0x20,
- LRMM_NUM_ROWS = SPD_FIRST_MOD_SPEC | 0x21,
- LRMM_MIRRORING = SPD_FIRST_MOD_SPEC | 0x22,
- LRMM_REVISION_NUM = SPD_FIRST_MOD_SPEC | 0x23,
- LRMM_MFR_ID_CODE = SPD_FIRST_MOD_SPEC | 0x24,
- LRMM_F0RC3 = SPD_FIRST_MOD_SPEC | 0x25,
- LRMM_F0RC2 = SPD_FIRST_MOD_SPEC | 0x26,
- LRMM_F0RC5 = SPD_FIRST_MOD_SPEC | 0x27,
- LRMM_F0RC4 = SPD_FIRST_MOD_SPEC | 0x28,
- LRMM_F1RC11 = SPD_FIRST_MOD_SPEC | 0x29,
- LRMM_F1RC8 = SPD_FIRST_MOD_SPEC | 0x2a,
- LRMM_F1RC13 = SPD_FIRST_MOD_SPEC | 0x2b,
- LRMM_F1RC12 = SPD_FIRST_MOD_SPEC | 0x2c,
- LRMM_F1RC15 = SPD_FIRST_MOD_SPEC | 0x2d,
- LRMM_F1RC14 = SPD_FIRST_MOD_SPEC | 0x2e,
- LRMM_F3RC9_800_1600 = SPD_FIRST_MOD_SPEC | 0x2f,
- LRMM_F3RC8_800_1600 = SPD_FIRST_MOD_SPEC | 0x30,
- LRMM_F4RC11_800_1600 = SPD_FIRST_MOD_SPEC | 0x31,
- LRMM_F3RC11_800_1600 = SPD_FIRST_MOD_SPEC | 0x32,
- LRMM_F4RC10_800_1600 = SPD_FIRST_MOD_SPEC | 0x33,
- LRMM_F3RC10_800_1600 = SPD_FIRST_MOD_SPEC | 0x34,
- LRMM_F6RC11_800_1600 = SPD_FIRST_MOD_SPEC | 0x35,
- LRMM_F5RC11_800_1600 = SPD_FIRST_MOD_SPEC | 0x36,
- LRMM_F6RC10_800_1600 = SPD_FIRST_MOD_SPEC | 0x37,
- LRMM_F5RC10_800_1600 = SPD_FIRST_MOD_SPEC | 0x38,
- LRMM_F8RC11_800_1600 = SPD_FIRST_MOD_SPEC | 0x39,
- LRMM_F7RC11_800_1600 = SPD_FIRST_MOD_SPEC | 0x3a,
- LRMM_F8RC10_800_1600 = SPD_FIRST_MOD_SPEC | 0x3b,
- LRMM_F7RC10_800_1600 = SPD_FIRST_MOD_SPEC | 0x3c,
- LRMM_F10RC11_800_1600 = SPD_FIRST_MOD_SPEC | 0x3d,
- LRMM_F9RC11_800_1600 = SPD_FIRST_MOD_SPEC | 0x3e,
- LRMM_F10RC10_800_1600 = SPD_FIRST_MOD_SPEC | 0x3f,
- LRMM_F9RC10_800_1600 = SPD_FIRST_MOD_SPEC | 0x40,
- LRMM_RTT_WR_800_1600 = SPD_FIRST_MOD_SPEC | 0x41,
- LRMM_RTT_NOM_800_1600 = SPD_FIRST_MOD_SPEC | 0x42,
- LRMM_IMPEDANCE_800_1600 = SPD_FIRST_MOD_SPEC | 0x43,
- LRMM_F3RC9_1333_1600 = SPD_FIRST_MOD_SPEC | 0x44,
- LRMM_F3RC8_1333_1600 = SPD_FIRST_MOD_SPEC | 0x45,
- LRMM_F4RC11_1333_1600 = SPD_FIRST_MOD_SPEC | 0x46,
- LRMM_F3RC11_1333_1600 = SPD_FIRST_MOD_SPEC | 0x47,
- LRMM_F4RC10_1333_1600 = SPD_FIRST_MOD_SPEC | 0x48,
- LRMM_F3RC10_1333_1600 = SPD_FIRST_MOD_SPEC | 0x49,
- LRMM_F6RC11_1333_1600 = SPD_FIRST_MOD_SPEC | 0x4a,
- LRMM_F5RC11_1333_1600 = SPD_FIRST_MOD_SPEC | 0x4b,
- LRMM_F6RC10_1333_1600 = SPD_FIRST_MOD_SPEC | 0x4c,
- LRMM_F5RC10_1333_1600 = SPD_FIRST_MOD_SPEC | 0x4d,
- LRMM_F8RC11_1333_1600 = SPD_FIRST_MOD_SPEC | 0x4e,
- LRMM_F7RC11_1333_1600 = SPD_FIRST_MOD_SPEC | 0x4f,
- LRMM_F8RC10_1333_1600 = SPD_FIRST_MOD_SPEC | 0x50,
- LRMM_F7RC10_1333_1600 = SPD_FIRST_MOD_SPEC | 0x51,
- LRMM_F10RC11_1333_1600 = SPD_FIRST_MOD_SPEC | 0x52,
- LRMM_F9RC11_1333_1600 = SPD_FIRST_MOD_SPEC | 0x53,
- LRMM_F10RC10_1333_1600 = SPD_FIRST_MOD_SPEC | 0x54,
- LRMM_F9RC10_1333_1600 = SPD_FIRST_MOD_SPEC | 0x55,
- LRMM_RTT_WR_1333_1600 = SPD_FIRST_MOD_SPEC | 0x56,
- LRMM_RTT_NOM_1333_1600 = SPD_FIRST_MOD_SPEC | 0x57,
- LRMM_IMPEDANCE_1333_1600 = SPD_FIRST_MOD_SPEC | 0x58,
- LRMM_F3RC9_1866_2133 = SPD_FIRST_MOD_SPEC | 0x59,
- LRMM_F3RC8_1866_2133 = SPD_FIRST_MOD_SPEC | 0x5a,
- LRMM_F4RC11_1866_2133 = SPD_FIRST_MOD_SPEC | 0x5b,
- LRMM_F3RC11_1866_2133 = SPD_FIRST_MOD_SPEC | 0x5c,
- LRMM_F4RC10_1866_2133 = SPD_FIRST_MOD_SPEC | 0x5d,
- LRMM_F3RC10_1866_2133 = SPD_FIRST_MOD_SPEC | 0x5e,
- LRMM_F6RC11_1866_2133 = SPD_FIRST_MOD_SPEC | 0x5f,
- LRMM_F5RC11_1866_2133 = SPD_FIRST_MOD_SPEC | 0x60,
- LRMM_F6RC10_1866_2133 = SPD_FIRST_MOD_SPEC | 0x61,
- LRMM_F5RC10_1866_2133 = SPD_FIRST_MOD_SPEC | 0x62,
- LRMM_F8RC11_1866_2133 = SPD_FIRST_MOD_SPEC | 0x63,
- LRMM_F7RC11_1866_2133 = SPD_FIRST_MOD_SPEC | 0x64,
- LRMM_F8RC10_1866_2133 = SPD_FIRST_MOD_SPEC | 0x65,
- LRMM_F7RC10_1866_2133 = SPD_FIRST_MOD_SPEC | 0x66,
- LRMM_F10RC11_1866_2133 = SPD_FIRST_MOD_SPEC | 0x67,
- LRMM_F9RC11_1866_2133 = SPD_FIRST_MOD_SPEC | 0x68,
- LRMM_F10RC10_1866_2133 = SPD_FIRST_MOD_SPEC | 0x69,
- LRMM_F9RC10_1866_2133 = SPD_FIRST_MOD_SPEC | 0x6a,
- LRMM_RTT_WR_1866_2133 = SPD_FIRST_MOD_SPEC | 0x6b,
- LRMM_RTT_NOM_1866_2133 = SPD_FIRST_MOD_SPEC | 0x6c,
- LRMM_IMPEDANCE_1866_2133 = SPD_FIRST_MOD_SPEC | 0x6d,
- LRMM_MIN_DELAY_150V = SPD_FIRST_MOD_SPEC | 0x6e,
- LRMM_MAX_DELAY_150V = SPD_FIRST_MOD_SPEC | 0x6f,
- LRMM_MIN_DELAY_135V = SPD_FIRST_MOD_SPEC | 0x70,
- LRMM_MAX_DELAY_135V = SPD_FIRST_MOD_SPEC | 0x71,
- LRMM_MIN_DELAY_125V = SPD_FIRST_MOD_SPEC | 0x72,
- LRMM_MAX_DELAY_125V = SPD_FIRST_MOD_SPEC | 0x73,
- LRMM_PERSONALITY_BYTE0 = SPD_FIRST_MOD_SPEC | 0x74,
- LRMM_PERSONALITY_BYTE1 = SPD_FIRST_MOD_SPEC | 0x75,
- LRMM_PERSONALITY_BYTE2 = SPD_FIRST_MOD_SPEC | 0x76,
- LRMM_PERSONALITY_BYTE3 = SPD_FIRST_MOD_SPEC | 0x77,
- LRMM_PERSONALITY_BYTE4 = SPD_FIRST_MOD_SPEC | 0x78,
- LRMM_PERSONALITY_BYTE5 = SPD_FIRST_MOD_SPEC | 0x79,
- LRMM_PERSONALITY_BYTE6 = SPD_FIRST_MOD_SPEC | 0x7a,
- LRMM_PERSONALITY_BYTE7 = SPD_FIRST_MOD_SPEC | 0x7b,
- LRMM_PERSONALITY_BYTE8 = SPD_FIRST_MOD_SPEC | 0x7c,
- LRMM_PERSONALITY_BYTE9 = SPD_FIRST_MOD_SPEC | 0x7d,
- LRMM_PERSONALITY_BYTE10 = SPD_FIRST_MOD_SPEC | 0x7e,
- LRMM_PERSONALITY_BYTE11 = SPD_FIRST_MOD_SPEC | 0x7f,
- LRMM_PERSONALITY_BYTE12 = SPD_FIRST_MOD_SPEC | 0x80,
- LRMM_PERSONALITY_BYTE13 = SPD_FIRST_MOD_SPEC | 0x81,
- LRMM_PERSONALITY_BYTE14 = SPD_FIRST_MOD_SPEC | 0x82,
- SPD_LAST_MOD_SPEC,
+ // Normal SPD Keywords (Available for DDR3 DIMMs only)
+ BANK_ADDRESS_BITS = SPD_FIRST_NORM_KEYWORD | 0x2e,
+ MODULE_NOMINAL_VOLTAGE = SPD_FIRST_NORM_KEYWORD | 0x2f,
+ FTB_DIVIDEND = SPD_FIRST_NORM_KEYWORD | 0x30,
+ FTB_DIVISOR = SPD_FIRST_NORM_KEYWORD | 0x31,
+ MTB_DIVIDEND = SPD_FIRST_NORM_KEYWORD | 0x32,
+ MTB_DIVISOR = SPD_FIRST_NORM_KEYWORD | 0x33,
+ CAS_LATENCIES_SUPPORTED = SPD_FIRST_NORM_KEYWORD | 0x34,
+ TWR_MIN = SPD_FIRST_NORM_KEYWORD | 0x35,
+ TRRD_MIN = SPD_FIRST_NORM_KEYWORD | 0x36,
+ TRFC_MIN = SPD_FIRST_NORM_KEYWORD | 0x37,
+ TWTR_MIN = SPD_FIRST_NORM_KEYWORD | 0x38,
+ TRTP_MIN = SPD_FIRST_NORM_KEYWORD | 0x39,
+ DLL_OFF = SPD_FIRST_NORM_KEYWORD | 0x3a,
+ RZQ_7 = SPD_FIRST_NORM_KEYWORD | 0x3b,
+ RZQ_6 = SPD_FIRST_NORM_KEYWORD | 0x3c,
+ PASR = SPD_FIRST_NORM_KEYWORD | 0x3d,
+ ODTS = SPD_FIRST_NORM_KEYWORD | 0x3e,
+ ASR = SPD_FIRST_NORM_KEYWORD | 0x3f,
+ ETR_1X = SPD_FIRST_NORM_KEYWORD | 0x40,
+ ETR = SPD_FIRST_NORM_KEYWORD | 0x41,
+ MODULE_CRC = SPD_FIRST_NORM_KEYWORD | 0x42,
+
+ // ==============================================================
+ // Normal SPD Keywords (Available for DDR4 DIMMs only)
+ BANK_GROUP_BITS = SPD_FIRST_NORM_KEYWORD | 0x43,
+ BANK_ADDRESS_BITS_DDR4 = SPD_FIRST_NORM_KEYWORD | 0x44,
+ MODULE_NOMINAL_VOLTAGE_DDR4 = SPD_FIRST_NORM_KEYWORD | 0x45,
+ TIMEBASES_MTB = SPD_FIRST_NORM_KEYWORD | 0x46,
+ TIMEBASES_FTB = SPD_FIRST_NORM_KEYWORD | 0x47,
+ TCK_MAX = SPD_FIRST_NORM_KEYWORD | 0x48,
+ CAS_LATENCIES_SUPPORTED_DDR4 = SPD_FIRST_NORM_KEYWORD | 0x49,
+ TRFC1_MIN = SPD_FIRST_NORM_KEYWORD | 0x4a,
+ TRFC2_MIN = SPD_FIRST_NORM_KEYWORD | 0x4b,
+ TRFC4_MIN = SPD_FIRST_NORM_KEYWORD | 0x4c,
+ TRRDS_MIN = SPD_FIRST_NORM_KEYWORD | 0x4d,
+ TRRDL_MIN = SPD_FIRST_NORM_KEYWORD | 0x4e,
+ TCCDL_MIN = SPD_FIRST_NORM_KEYWORD | 0x4f,
+ CONNECTOR_SDRAM_MAP = SPD_FIRST_NORM_KEYWORD | 0x50,
+ TCCDL_FINE_OFFSET = SPD_FIRST_NORM_KEYWORD | 0x51,
+ TRRDL_FINE_OFFSET = SPD_FIRST_NORM_KEYWORD | 0x52,
+ TRRDS_FINE_OFFSET = SPD_FIRST_NORM_KEYWORD | 0x53,
+ TCKMAX_FINE_OFFSET = SPD_FIRST_NORM_KEYWORD | 0x54,
+ BASE_CONFIG_CRC = SPD_FIRST_NORM_KEYWORD | 0x55,
+ DRAM_STEPPING = SPD_FIRST_NORM_KEYWORD | 0x56,
+ MANUFACTURING_SECTION_CRC = SPD_FIRST_NORM_KEYWORD | 0x57,
+ SPD_LAST_NORM_KEYWORD = SPD_FIRST_NORM_KEYWORD | 0x57,
+
+ // ==============================================================
+ // Module Specific Keywords (Available for both DDR3 and DDR4 DIMMs)
+ MODSPEC_COM_NOM_HEIGHT_MAX = SPD_FIRST_MOD_SPEC | 0x00,
+ MODSPEC_COM_MAX_THICK_BACK = SPD_FIRST_MOD_SPEC | 0x01,
+ MODSPEC_COM_MAX_THICK_FRONT = SPD_FIRST_MOD_SPEC | 0x02,
+ MODSPEC_COM_REF_RAW_CARD_EXT = SPD_FIRST_MOD_SPEC | 0x03,
+ MODSPEC_COM_REF_RAW_CARD_REV = SPD_FIRST_MOD_SPEC | 0x04,
+ MODSPEC_COM_REF_RAW_CARD = SPD_FIRST_MOD_SPEC | 0x05,
+ UMM_ADDR_MAPPING = SPD_FIRST_MOD_SPEC | 0x06,
+ RMM_ROWS_RDIMM = SPD_FIRST_MOD_SPEC | 0x07,
+ RMM_REGS_RDIMM = SPD_FIRST_MOD_SPEC | 0x08,
+ RMM_HEAT_SP = SPD_FIRST_MOD_SPEC | 0x09,
+ RMM_HEAT_SP_CHARS = SPD_FIRST_MOD_SPEC | 0x0a,
+ RMM_MFR_ID_CODE = SPD_FIRST_MOD_SPEC | 0x0b,
+ RMM_REG_REV_NUM = SPD_FIRST_MOD_SPEC | 0x0c,
+ LRMM_HEAT_SP = SPD_FIRST_MOD_SPEC | 0x0d,
+ LRMM_NUM_ROWS = SPD_FIRST_MOD_SPEC | 0x0e,
+ LRMM_MIRRORING = SPD_FIRST_MOD_SPEC | 0x0f,
+ LRMM_REVISION_NUM = SPD_FIRST_MOD_SPEC | 0x10,
+ LRMM_MFR_ID_CODE = SPD_FIRST_MOD_SPEC | 0x11,
+
+ // ==============================================================
+ // Module Specific Keywords (Available for DDR3 DIMMs only)
+ RMM_REG_TYPE = SPD_FIRST_MOD_SPEC | 0x12,
+ RMM_RC1 = SPD_FIRST_MOD_SPEC | 0x13,
+ RMM_RC0 = SPD_FIRST_MOD_SPEC | 0x14,
+ RMM_RC3 = SPD_FIRST_MOD_SPEC | 0x15,
+ RMM_RC2 = SPD_FIRST_MOD_SPEC | 0x16,
+ RMM_RC5 = SPD_FIRST_MOD_SPEC | 0x17,
+ RMM_RC4 = SPD_FIRST_MOD_SPEC | 0x18,
+ RMM_RC7 = SPD_FIRST_MOD_SPEC | 0x19,
+ RMM_RC6 = SPD_FIRST_MOD_SPEC | 0x1a,
+ RMM_RC9 = SPD_FIRST_MOD_SPEC | 0x1b,
+ RMM_RC8 = SPD_FIRST_MOD_SPEC | 0x1c,
+ RMM_RC11 = SPD_FIRST_MOD_SPEC | 0x1d,
+ RMM_RC10 = SPD_FIRST_MOD_SPEC | 0x1e,
+ RMM_RC13 = SPD_FIRST_MOD_SPEC | 0x1f,
+ RMM_RC12 = SPD_FIRST_MOD_SPEC | 0x20,
+ RMM_RC15 = SPD_FIRST_MOD_SPEC | 0x21,
+ RMM_RC14 = SPD_FIRST_MOD_SPEC | 0x22,
+ LRMM_RANK_NUMBERING = SPD_FIRST_MOD_SPEC | 0x23,
+ LRMM_MEMBUF_ORIEN = SPD_FIRST_MOD_SPEC | 0x24,
+ LRMM_F0RC3_FORC2 = SPD_FIRST_MOD_SPEC | 0x25,
+ LRMM_F0RC3 = SPD_FIRST_MOD_SPEC | 0x26,
+ LRMM_F0RC2 = SPD_FIRST_MOD_SPEC | 0x27,
+ LRMM_F0RC5_FORC4 = SPD_FIRST_MOD_SPEC | 0x28,
+ LRMM_F0RC5 = SPD_FIRST_MOD_SPEC | 0x29,
+ LRMM_F0RC4 = SPD_FIRST_MOD_SPEC | 0x2a,
+ LRMM_F1RC11_F1RC8 = SPD_FIRST_MOD_SPEC | 0x2b,
+ LRMM_F1RC11 = SPD_FIRST_MOD_SPEC | 0x2c,
+ LRMM_F1RC8 = SPD_FIRST_MOD_SPEC | 0x2d,
+ LRMM_F1RC13_F1RC12 = SPD_FIRST_MOD_SPEC | 0x2e,
+ LRMM_F1RC13 = SPD_FIRST_MOD_SPEC | 0x2f,
+ LRMM_F1RC12 = SPD_FIRST_MOD_SPEC | 0x30,
+ LRMM_F1RC15_F1RC14 = SPD_FIRST_MOD_SPEC | 0x31,
+ LRMM_F1RC15 = SPD_FIRST_MOD_SPEC | 0x32,
+ LRMM_F1RC14 = SPD_FIRST_MOD_SPEC | 0x33,
+ LRMM_F3RC9_F3RC8_800_1066 = SPD_FIRST_MOD_SPEC | 0x34,
+ LRMM_F3RC9_800_1600 = SPD_FIRST_MOD_SPEC | 0x35,
+ LRMM_F3RC8_800_1600 = SPD_FIRST_MOD_SPEC | 0x36,
+ LRMM_F34RC11_F34RC10_800_1066 = SPD_FIRST_MOD_SPEC | 0x37,
+ LRMM_F4RC11_800_1600 = SPD_FIRST_MOD_SPEC | 0x38,
+ LRMM_F3RC11_800_1600 = SPD_FIRST_MOD_SPEC | 0x39,
+ LRMM_F4RC10_800_1600 = SPD_FIRST_MOD_SPEC | 0x3a,
+ LRMM_F3RC10_800_1600 = SPD_FIRST_MOD_SPEC | 0x3b,
+ LRMM_F56RC11_F56RC10_800_1066 = SPD_FIRST_MOD_SPEC | 0x3c,
+ LRMM_F6RC11_800_1600 = SPD_FIRST_MOD_SPEC | 0x3d,
+ LRMM_F5RC11_800_1600 = SPD_FIRST_MOD_SPEC | 0x3e,
+ LRMM_F6RC10_800_1600 = SPD_FIRST_MOD_SPEC | 0x3f,
+ LRMM_F5RC10_800_1600 = SPD_FIRST_MOD_SPEC | 0x40,
+ LRMM_F78RC11_F78RC10_800_1066 = SPD_FIRST_MOD_SPEC | 0x41,
+ LRMM_F8RC11_800_1600 = SPD_FIRST_MOD_SPEC | 0x42,
+ LRMM_F7RC11_800_1600 = SPD_FIRST_MOD_SPEC | 0x43,
+ LRMM_F8RC10_800_1600 = SPD_FIRST_MOD_SPEC | 0x44,
+ LRMM_F7RC10_800_1600 = SPD_FIRST_MOD_SPEC | 0x45,
+ LRMM_F910RC11_F910RC10_800_1066 = SPD_FIRST_MOD_SPEC | 0x46,
+ LRMM_F10RC11_800_1600 = SPD_FIRST_MOD_SPEC | 0x47,
+ LRMM_F9RC11_800_1600 = SPD_FIRST_MOD_SPEC | 0x48,
+ LRMM_F10RC10_800_1600 = SPD_FIRST_MOD_SPEC | 0x49,
+ LRMM_F9RC10_800_1600 = SPD_FIRST_MOD_SPEC | 0x4a,
+ LRMM_MR12_800_1066 = SPD_FIRST_MOD_SPEC | 0x4b,
+ LRMM_RTT_WR_800_1600 = SPD_FIRST_MOD_SPEC | 0x4c,
+ LRMM_RTT_NOM_800_1600 = SPD_FIRST_MOD_SPEC | 0x4d,
+ LRMM_IMPEDANCE_800_1600 = SPD_FIRST_MOD_SPEC | 0x4e,
+ LRMM_F3RC9_F3RC8_1333_1600 = SPD_FIRST_MOD_SPEC | 0x4f,
+ LRMM_F3RC9_1333_1600 = SPD_FIRST_MOD_SPEC | 0x50,
+ LRMM_F3RC8_1333_1600 = SPD_FIRST_MOD_SPEC | 0x51,
+ LRMM_F34RC11_F34RC10_1333_1600 = SPD_FIRST_MOD_SPEC | 0x52,
+ LRMM_F4RC11_1333_1600 = SPD_FIRST_MOD_SPEC | 0x53,
+ LRMM_F3RC11_1333_1600 = SPD_FIRST_MOD_SPEC | 0x54,
+ LRMM_F4RC10_1333_1600 = SPD_FIRST_MOD_SPEC | 0x55,
+ LRMM_F3RC10_1333_1600 = SPD_FIRST_MOD_SPEC | 0x56,
+ LRMM_F56RC11_F56RC10_1333_1600 = SPD_FIRST_MOD_SPEC | 0x57,
+ LRMM_F6RC11_1333_1600 = SPD_FIRST_MOD_SPEC | 0x58,
+ LRMM_F5RC11_1333_1600 = SPD_FIRST_MOD_SPEC | 0x59,
+ LRMM_F6RC10_1333_1600 = SPD_FIRST_MOD_SPEC | 0x5a,
+ LRMM_F5RC10_1333_1600 = SPD_FIRST_MOD_SPEC | 0x5b,
+ LRMM_F78RC11_F78RC10_1333_1600 = SPD_FIRST_MOD_SPEC | 0x5c,
+ LRMM_F8RC11_1333_1600 = SPD_FIRST_MOD_SPEC | 0x5d,
+ LRMM_F7RC11_1333_1600 = SPD_FIRST_MOD_SPEC | 0x5e,
+ LRMM_F8RC10_1333_1600 = SPD_FIRST_MOD_SPEC | 0x5f,
+ LRMM_F7RC10_1333_1600 = SPD_FIRST_MOD_SPEC | 0x60,
+ LRMM_F910RC11_F910RC10_1333_1600 = SPD_FIRST_MOD_SPEC | 0x61,
+ LRMM_F10RC11_1333_1600 = SPD_FIRST_MOD_SPEC | 0x62,
+ LRMM_F9RC11_1333_1600 = SPD_FIRST_MOD_SPEC | 0x63,
+ LRMM_F10RC10_1333_1600 = SPD_FIRST_MOD_SPEC | 0x64,
+ LRMM_F9RC10_1333_1600 = SPD_FIRST_MOD_SPEC | 0x65,
+ LRMM_MR12_1333_1600 = SPD_FIRST_MOD_SPEC | 0x66,
+ LRMM_RTT_WR_1333_1600 = SPD_FIRST_MOD_SPEC | 0x67,
+ LRMM_RTT_NOM_1333_1600 = SPD_FIRST_MOD_SPEC | 0x68,
+ LRMM_IMPEDANCE_1333_1600 = SPD_FIRST_MOD_SPEC | 0x69,
+ LRMM_F3RC9_F3RC8_1866_2133 = SPD_FIRST_MOD_SPEC | 0x6a,
+ LRMM_F3RC9_1866_2133 = SPD_FIRST_MOD_SPEC | 0x6b,
+ LRMM_F3RC8_1866_2133 = SPD_FIRST_MOD_SPEC | 0x6c,
+ LRMM_F34RC11_F34RC10_1866_2133 = SPD_FIRST_MOD_SPEC | 0x6d,
+ LRMM_F4RC11_1866_2133 = SPD_FIRST_MOD_SPEC | 0x6e,
+ LRMM_F3RC11_1866_2133 = SPD_FIRST_MOD_SPEC | 0x6f,
+ LRMM_F4RC10_1866_2133 = SPD_FIRST_MOD_SPEC | 0x70,
+ LRMM_F3RC10_1866_2133 = SPD_FIRST_MOD_SPEC | 0x71,
+ LRMM_F56RC11_F56RC10_1866_2133 = SPD_FIRST_MOD_SPEC | 0x72,
+ LRMM_F6RC11_1866_2133 = SPD_FIRST_MOD_SPEC | 0x73,
+ LRMM_F5RC11_1866_2133 = SPD_FIRST_MOD_SPEC | 0x74,
+ LRMM_F6RC10_1866_2133 = SPD_FIRST_MOD_SPEC | 0x75,
+ LRMM_F5RC10_1866_2133 = SPD_FIRST_MOD_SPEC | 0x76,
+ LRMM_F78RC11_F78RC10_1866_2133 = SPD_FIRST_MOD_SPEC | 0x77,
+ LRMM_F8RC11_1866_2133 = SPD_FIRST_MOD_SPEC | 0x78,
+ LRMM_F7RC11_1866_2133 = SPD_FIRST_MOD_SPEC | 0x79,
+ LRMM_F8RC10_1866_2133 = SPD_FIRST_MOD_SPEC | 0x7a,
+ LRMM_F7RC10_1866_2133 = SPD_FIRST_MOD_SPEC | 0x7b,
+ LRMM_F910RC11_F910RC10_1866_2133 = SPD_FIRST_MOD_SPEC | 0x7c,
+ LRMM_F10RC11_1866_2133 = SPD_FIRST_MOD_SPEC | 0x7d,
+ LRMM_F9RC11_1866_2133 = SPD_FIRST_MOD_SPEC | 0x7e,
+ LRMM_F10RC10_1866_2133 = SPD_FIRST_MOD_SPEC | 0x7f,
+ LRMM_F9RC10_1866_2133 = SPD_FIRST_MOD_SPEC | 0x80,
+ LRMM_MR12_FOR_1866_2133 = SPD_FIRST_MOD_SPEC | 0x81,
+ LRMM_RTT_WR_1866_2133 = SPD_FIRST_MOD_SPEC | 0x82,
+ LRMM_RTT_NOM_1866_2133 = SPD_FIRST_MOD_SPEC | 0x83,
+ LRMM_IMPEDANCE_1866_2133 = SPD_FIRST_MOD_SPEC | 0x84,
+ LRMM_MIN_DELAY_150V = SPD_FIRST_MOD_SPEC | 0x85,
+ LRMM_MAX_DELAY_150V = SPD_FIRST_MOD_SPEC | 0x86,
+ LRMM_MIN_DELAY_135V = SPD_FIRST_MOD_SPEC | 0x87,
+ LRMM_MAX_DELAY_135V = SPD_FIRST_MOD_SPEC | 0x88,
+ LRMM_MIN_DELAY_125V = SPD_FIRST_MOD_SPEC | 0x89,
+ LRMM_MAX_DELAY_125V = SPD_FIRST_MOD_SPEC | 0x8a,
+ LRMM_PERSONALITY_BYTE0 = SPD_FIRST_MOD_SPEC | 0x8b,
+ LRMM_PERSONALITY_BYTE1 = SPD_FIRST_MOD_SPEC | 0x8c,
+ LRMM_PERSONALITY_BYTE2 = SPD_FIRST_MOD_SPEC | 0x8d,
+ LRMM_PERSONALITY_BYTE3 = SPD_FIRST_MOD_SPEC | 0x8e,
+ LRMM_PERSONALITY_BYTE4 = SPD_FIRST_MOD_SPEC | 0x8f,
+ LRMM_PERSONALITY_BYTE5 = SPD_FIRST_MOD_SPEC | 0x90,
+ LRMM_PERSONALITY_BYTE6 = SPD_FIRST_MOD_SPEC | 0x91,
+ LRMM_PERSONALITY_BYTE7 = SPD_FIRST_MOD_SPEC | 0x92,
+ LRMM_PERSONALITY_BYTE8 = SPD_FIRST_MOD_SPEC | 0x93,
+ LRMM_PERSONALITY_BYTE9 = SPD_FIRST_MOD_SPEC | 0x94,
+ LRMM_PERSONALITY_BYTE10 = SPD_FIRST_MOD_SPEC | 0x95,
+ LRMM_PERSONALITY_BYTE11 = SPD_FIRST_MOD_SPEC | 0x96,
+ LRMM_PERSONALITY_BYTE12 = SPD_FIRST_MOD_SPEC | 0x97,
+ LRMM_PERSONALITY_BYTE13 = SPD_FIRST_MOD_SPEC | 0x99,
+ LRMM_PERSONALITY_BYTE14 = SPD_FIRST_MOD_SPEC | 0x99,
+
+ // ==============================================================
+ // Module Specific Keywords (Available for DDR4 DIMMs only)
+ MODSPEC_COM_RAW_CARD_EXT = SPD_FIRST_MOD_SPEC | 0x9a,
+ UMM_CRC = SPD_FIRST_MOD_SPEC | 0x9b,
+ RMM_ADDR_MAPPING = SPD_FIRST_MOD_SPEC | 0x9c,
+ RMM_CRC = SPD_FIRST_MOD_SPEC | 0x9d,
+ LRMM_CRC = SPD_FIRST_MOD_SPEC | 0x9e,
+ SPD_LAST_MOD_SPEC = SPD_FIRST_MOD_SPEC | 0x9e,
// This keyword should be last in the list
// Invalid Keyword
diff --git a/src/include/usr/vpd/vpdreasoncodes.H b/src/include/usr/vpd/vpdreasoncodes.H
index 7e95afa58..20be0e0f6 100644
--- a/src/include/usr/vpd/vpdreasoncodes.H
+++ b/src/include/usr/vpd/vpdreasoncodes.H
@@ -59,11 +59,14 @@ enum vpdModuleId
VPD_SPD_READ_BINARY_FILE = 0x64,
VPD_SPD_WRITE_KEYWORD_VALUE = 0x65,
VPD_SPD_SPECIAL_CASES = 0x66,
- VPD_SPD_PRESENCE_DETECT = 0x67,
- VPD_SPD_CHECK_MODULE_SPECIFIC_KEYWORD = 0x68,
- VPD_SPD_WRITE_VALUE = 0x69,
- VPD_SPD_GET_KEYWORD_ENTRY = 0x6A,
- VPD_SPD_WRITE_DATA = 0x6B,
+ VPD_SPD_DDR3_SPECIAL_CASES = 0x67,
+ VPD_SPD_DDR4_SPECIAL_CASES = 0x68,
+ VPD_SPD_PRESENCE_DETECT = 0x69,
+ VPD_SPD_CHECK_MODULE_SPECIFIC_KEYWORD = 0x6A,
+ VPD_SPD_WRITE_VALUE = 0x6B,
+ VPD_SPD_GET_KEYWORD_ENTRY = 0x6C,
+ VPD_SPD_WRITE_DATA = 0x6D,
+ VPD_SPD_GET_MOD_TYPE = 0x6E,
// Centaur FRU VPD
diff --git a/src/usr/hwpf/hwp/dimm_spd_attributes.xml b/src/usr/hwpf/hwp/dimm_spd_attributes.xml
index 3624f53a3..3b7f8aa52 100644
--- a/src/usr/hwpf/hwp/dimm_spd_attributes.xml
+++ b/src/usr/hwpf/hwp/dimm_spd_attributes.xml
@@ -20,9 +20,14 @@
<!-- Origin: 30 -->
<!-- -->
<!-- IBM_PROLOG_END_TAG -->
+ <!-- $Id: dimm_spd_attributes.xml,v 1.21 2013/06/14 18:51:49 mjjones Exp $ -->
<!-- XML file specifying DIMM SPD attributes used by HW Procedures. -->
<attributes>
+<!--
+The following attributes can be queried from both DDR3 and DDR4 DIMMs
+-->
+
<attribute>
<id>ATTR_SPD_DRAM_DEVICE_TYPE</id>
<targetType>TARGET_TYPE_DIMM</targetType>
@@ -40,11 +45,11 @@
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
Module Type.
- Located in DDR3 SPD byte 3, bits 3-0.
- Note that CDIMM designation here is obsolete. See ATTR_SPD_CUSTOM
+ Located in DDR3/DDR4 SPD byte 3, bits 3-0.
+ Note that CDIMM designation here is obsolete. See ATTR_SPD_CUSTOM
</description>
<valueType>uint8</valueType>
- <enum>CDIMM = 0x00, RDIMM = 0x01, UDIMM = 0x02, LRDIMM = 0x0b</enum>
+ <enum>CDIMM = 0x00, RDIMM = 0x01, UDIMM = 0x02, SO_DIMM=0x03, LRDIMM = 0x0b</enum>
<platInit/>
</attribute>
@@ -53,8 +58,8 @@
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
Module Type is CUSTOM
- Located in DDR3 SPD byte 3, bit 7. (Most significant bit)
- If bit 7 (reserved) is a '1' then this attribute value should be set to YES
+ Located in DDR3/DDR4 SPD byte 3, bit 7. (Most significant bit)
+ If bit 7 (reserved) is a '1' then this attribute value should be set to YES
</description>
<valueType>uint8</valueType>
<enum>NO = 0x0, YES = 0x1</enum>
@@ -62,28 +67,16 @@
</attribute>
<attribute>
- <id>ATTR_SPD_SDRAM_BANKS</id>
- <targetType>TARGET_TYPE_DIMM</targetType>
- <description>
- Number of banks.
- Located in DDR3 SPD byte 4, bits 6-4.
- </description>
- <valueType>uint8</valueType>
- <enum>B8 = 0x00, B16 = 0x01, B32 = 0x02, B64 = 0x03</enum>
- <platInit/>
-</attribute>
-
-<attribute>
<id>ATTR_SPD_SDRAM_DENSITY</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
DRAM Density.
- Located in DDR3 SPD byte 4, bits 3-0.
+ Located in DDR3/DDR4 SPD byte 4, bits 3-0.
</description>
<valueType>uint8</valueType>
<enum>
D256MB = 0x00, D512Mb = 0x01, D1GB = 0x02, D2GB = 0x03, D4GB = 0x04,
- D8GB = 0x05, D16GB = 0x06
+ D8GB = 0x05, D16GB = 0x06, D32GB=0x07
</enum>
<platInit/>
</attribute>
@@ -93,10 +86,12 @@
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
Number of Rows.
- Located in DDR3 SPD byte 5, bits 5-3.
+ Located in DDR3/DDR4 SPD byte 5, bits 5-3.
</description>
<valueType>uint8</valueType>
- <enum>R12 = 0x00, R13 = 0x01, R14 = 0x02, R15 = 0x03, R16 = 0x04</enum>
+ <enum>R12 = 0x00, R13 = 0x01, R14 = 0x02, R15 = 0x03,
+ R16 = 0x04, R17 = 0x05, R18 = 0x06
+ </enum>
<platInit/>
</attribute>
@@ -105,7 +100,7 @@
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
Number of Columns.
- Located in DDR3 SPD byte 5, bits 2-0.
+ Located in DDR3/DDR4 SPD byte 5, bits 2-0.
</description>
<valueType>uint8</valueType>
<enum>C9 = 0x00, C10 = 0x01, C11 = 0x02, C12 = 0x03</enum>
@@ -113,23 +108,12 @@
</attribute>
<attribute>
- <id>ATTR_SPD_MODULE_NOMINAL_VOLTAGE</id>
- <targetType>TARGET_TYPE_DIMM</targetType>
- <description>
- Nominal voltage (bitmap).
- Located in DDR3 SPD byte 6, bits 2-0.
- </description>
- <valueType>uint8</valueType>
- <enum>NOTOP1_5 = 0x01, OP1_35 = 0x02, OP1_2X = 0x04</enum>
- <platInit/>
-</attribute>
-
-<attribute>
<id>ATTR_SPD_NUM_RANKS</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
Number of ranks.
Located in DDR3 SPD byte 7, bits 5-3.
+ Located in DDR4 SPD byte 12, bits 5-3.
</description>
<valueType>uint8</valueType>
<enum>R1 = 0x00, R2 = 0x01, R3 = 0x02, R4 = 0x03</enum>
@@ -142,6 +126,7 @@
<description>
DRAM Width.
Located in DDR3 SPD byte 7, bits 2-0.
+ Located in DDR4 SPD byte 12, bits 2-0.
</description>
<valueType>uint8</valueType>
<enum>W4 = 0x00, W8 = 0x01, W16 = 0x02, W32 = 0x03</enum>
@@ -153,10 +138,402 @@
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
Module Memory Bus Width.
- Located in DDR3 SPD byte 8, bits 2-0.
+ Located in DDR3 SPD byte 8, bits 4-0
+ Located in DDR4 SPD byte 13, bits 4-0.
+ Bits 4-3 contain the Bus Width Extension (ECC)
+ Bits 2-0 contain the Primary Bus Width
+ </description>
+ <valueType>uint8</valueType>
+ <enum>
+ W8 = 0x00, W16 = 0x01, W32 = 0x02, W64 = 0x03,
+ WE8 = 0x08, WE16 = 0x09, WE32 = 0x0a, WE64 = 0x0b
+ </enum>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_TCKMIN</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Minimum cycle time (tCKmin).
+ Located in DDR3 SPD byte 12.
+ Located in DDR4 SPD byte 18.
+ </description>
+ <valueType>uint8</valueType>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_TAAMIN</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Minimum CAS Latency Time (tAAmin).
+ Located in DDR3 SPD byte 16.
+ Located in DDR4 SPD byte 24.
+ </description>
+ <valueType>uint8</valueType>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_TRCDMIN</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Minimum RAS# to CAS# Delay Time (tRCDmin).
+ Located in DDR3 SPD byte 18.
+ Located in DDR4 SPD byte 25.
+ </description>
+ <valueType>uint8</valueType>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_TRPMIN</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Minimum Row Precharge Delay Time (tRPmin).
+ Located in DDR3 SPD byte 20.
+ Located in DDR4 SPD byte 26.
+ </description>
+ <valueType>uint8</valueType>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_TRASMIN</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Minimum Active to Precharge Delay Time (tRASmin).
+ Located in DDR3 SPD byte 21, bits 3-0 and byte 22 (LSB).
+ Located in DDR4 SPD byte 27, bits 3-0 and byte 28 (LSB)
+ </description>
+ <valueType>uint32</valueType>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_TRCMIN</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Minimum Active to Active/Refresh Delay Time (tRCmin).
+ Located in DDR3 SPD byte 21, bits 7-4 and byte 23 (LSB).
+ Located in DDR4 SPD byte 27, bits 7-4 and byte 29 (LSB)
+ </description>
+ <valueType>uint32</valueType>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_TFAWMIN</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Minimum Four Activate Window Delay Time (tFAWmin).
+ Located in DDR3 SPD byte 28, bits 3-0 and byte 29 (LSB).
+ Located in DDR4 SPD byte 36, bits 3-0 and byte 37 (LSB).
+ </description>
+ <valueType>uint32</valueType>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_SDRAM_OPTIONAL_FEATURES</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ SDRAM Optional Features (bitmap).
+ Located in DDR3 SPD byte 30.
+ Located in DDR4 SPD byte 7, will be reserved and set to 0x0.
+ </description>
+ <valueType>uint8</valueType>
+ <enum>DLL_OFF = 0x80, RZQ7 = 0x02, RZQ6 = 0x01</enum>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_SDRAM_THERMAL_AND_REFRESH_OPTIONS</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ SDRAM Thermal and Refresh Options (bitmap).
+ Located in DDR3 SPD byte 31.
+ Located in DDR4 SPD byte 8, will be reserved and set to 0x0.
+ </description>
+ <valueType>uint8</valueType>
+ <enum>PASR = 0x80, ODTS = 0x08, ASR = 0x05, ETRR = 0x02, ETR = 0x01</enum>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_MODULE_THERMAL_SENSOR</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Module Thermal Sensor.
+ Located in DDR3 SPD byte 32.
+ Located in DDR4 SPD byte 14.
+ </description>
+ <valueType>uint8</valueType>
+ <enum>PRESENT = 0x80, ACCURACY_MASK = 0x7F</enum>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_SDRAM_DEVICE_TYPE</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ SDRAM Device Type.
+ Located in DDR3 SPD byte 33, bit 7.
+ Located in DDR4 SPD byte 6, bit 7.
+ </description>
+ <valueType>uint8</valueType>
+ <enum>STANDARD_MONOLITHIC = 0x00, NON_STANDARD = 0x01</enum>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_SDRAM_DEVICE_TYPE_SIGNAL_LOADING</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ SDRAM Device Type Signal Loading for stacked DRAMs.
+ Located in DDR3 SPD byte 33, bits 1-0.
+ Located in DDR4 SPD byte 6, bit 1-0.
+ </description>
+ <valueType>uint8</valueType>
+ <enum>NOT_SPECIFIED = 0x00, MULTI_LOAD_STACK = 0x01, SINGLE_LOAD_STACK = 0x02</enum>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_SDRAM_DIE_COUNT</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ SDRAM Device Type Die Count.
+ Located in DDR3 SPD byte 33, bits 6-4.
+ Located in DDR4 SPD byte 6, bit 6-4.
+ </description>
+ <valueType>uint8</valueType>
+ <enum>DIE1 = 0x00, DIE2 = 0x01, DIE4 = 0x02, DIE8 = 0x03</enum>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_FINE_OFFSET_TCKMIN</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Fine Offset for SDRAM Minimum Cycle Time (tCKmin).
+ Located in DDR3 SPD byte 34.
+ Located in DDR4 SPD byte 125.
+ </description>
+ <valueType>uint8</valueType>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_FINE_OFFSET_TAAMIN</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Fine Offset for Minimum CAS Latency Time (tAAmin).
+ Located in DDR3 SPD byte 35.
+ Located in DDR4 SPD byte 123.
+ </description>
+ <valueType>uint8</valueType>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_FINE_OFFSET_TRCDMIN</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin).
+ Located in DDR3 SPD byte 36.
+ Located in DDR4 SPD byte 122.
+ </description>
+ <valueType>uint8</valueType>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_FINE_OFFSET_TRPMIN</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Fine Offset for Minimum Row Precharge Delay Time (tRPmin).
+ Located in DDR3 SPD byte 37.
+ Located in DDR4 SPD byte 121.
+ </description>
+ <valueType>uint8</valueType>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_FINE_OFFSET_TRCMIN</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Fine Offset for Minimum Active to Active/Refresh Delay Time (tRCmin).
+ Located in DDR3 SPD byte 38.
+ Located in DDR4 SPD byte 120.
</description>
<valueType>uint8</valueType>
- <enum>W8 = 0x00, W16 = 0x01, W32 = 0x02, W64 = 0x03</enum>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_NUM_OF_REGISTERS_USED_ON_RDIMM</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Number of Registers used on RDIMM.
+ Located in DDR3 SPD byte 63 bits 1-0.
+ </description>
+ <valueType>uint8</valueType>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_MODULE_SPECIFIC_SECTION</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Module Specific Section.
+ Located in DDR3 SPD bytes 60d - 116d.
+ Located in DDR4 SPD bytes 128 - 255d.
+ </description>
+ <valueType>uint8</valueType>
+ <array>57</array>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_MODULE_ID_MODULE_MANUFACTURERS_JEDEC_ID_CODE</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Module ID: Module Manufacturer's JEDEC ID Code.
+ Located in DDR3 SPD bytes 117 (LSB) to 118.
+ Located in DDR4 SPD bytes 320 (LSB) to 321.
+ </description>
+ <valueType>uint32</valueType>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_MODULE_ID_MODULE_MANUFACTURING_LOCATION</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Module ID: Module Manufacturing Location.
+ Located in DDR3 SPD byte 119.
+ Located in DDR4 SPD byte 322.
+ </description>
+ <valueType>uint8</valueType>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_MODULE_ID_MODULE_MANUFACTURING_DATE</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Module ID: Module Manufacturing Date.
+ Located in DDR3 SPD bytes 120 (BCD year) to byte 121 (BCD week) (LSB).
+ Located in DDR4 SPD bytes 323 (BCD year) to byte 324 (BCD week) (LSB).
+ </description>
+ <valueType>uint32</valueType>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_MODULE_ID_MODULE_SERIAL_NUMBER</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Module ID: Module Serial Number.
+ Located in DDR3 SPD bytes 122 (LSB) to 125.
+ Located in DDR4 SPD bytes 325 (LSB) to 328.
+ </description>
+ <valueType>uint32</valueType>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_CYCLICAL_REDUNDANCY_CODE</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Cyclical Redundancy Code.
+ Located in DDR3 SPD bytes 126 (LSB) to 127.
+ </description>
+ <valueType>uint32</valueType>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_MODULE_PART_NUMBER</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Module Part Number.
+ Located in DDR3 SPD bytes 128 - 145.
+ Located in DDR4 SPD bytes 329 - 348.
+ </description>
+ <valueType>uint8</valueType>
+ <array>18</array>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_MODULE_REVISION_CODE</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Module Revision Code.
+ Located in DDR3 SPD bytes 146 (LSB) to 147.
+ Located in DDR4 SPD bytes 349
+ </description>
+ <valueType>uint32</valueType>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_DRAM_MANUFACTURER_JEDEC_ID_CODE</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ DRAM Manufacturer JEDEC ID Code.
+ Located in DDR3 SPD bytes 148 (LSB) to 149.
+ Located in DDR4 SPD bytes 350 (LSB) to 351.
+ </description>
+ <valueType>uint32</valueType>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_BAD_DQ_DATA</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Bad DQ pin data stored in DIMM SPD. This data is in a special format.
+ This must only be called by a firmware HWP that knows how to decode the data.
+ HWP/PLAT firmware that needs to get/set the Bad DQ Bitmap from a Centaur
+ DQ point of view must call the dimmBadDqBitmapAccessHwp HWP.
+ </description>
+ <valueType>uint8</valueType>
+ <array>80</array>
+ <platInit/>
+ <writeable/>
+</attribute>
+
+<!--
+The following attributes can be queried from DDR3 DIMMs only
+Querying them from DDR4 DIMMs will result in an error
+-->
+
+<attribute>
+ <id>ATTR_SPD_SDRAM_BANKS</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Number of banks.
+ Located in DDR3 SPD byte 4, bits 6-4.
+ </description>
+ <valueType>uint8</valueType>
+ <enum>B8 = 0x00, B16 = 0x01, B32 = 0x02, B64 = 0x03</enum>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_MODULE_NOMINAL_VOLTAGE</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Nominal voltage (bitmap).
+ Located in DDR3 SPD byte 6, bits 2-0.
+ </description>
+ <valueType>uint8</valueType>
+ <enum>NOTOP1_5 = 0x01, OP1_35 = 0x02, OP1_2X = 0x04</enum>
<platInit/>
</attribute>
@@ -205,17 +582,6 @@
</attribute>
<attribute>
- <id>ATTR_SPD_TCKMIN</id>
- <targetType>TARGET_TYPE_DIMM</targetType>
- <description>
- Minimum cycle time (tCKmin).
- Located in DDR3 SPD byte 12.
- </description>
- <valueType>uint8</valueType>
- <platInit/>
-</attribute>
-
-<attribute>
<id>ATTR_SPD_CAS_LATENCIES_SUPPORTED</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
@@ -244,379 +610,649 @@
</attribute>
<attribute>
- <id>ATTR_SPD_TAAMIN</id>
+ <id>ATTR_SPD_TWRMIN</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
- Minimum CAS Latency Time (tAAmin).
- Located in DDR3 SPD byte 16.
+ Minimum Write Recovery Time (tWRmin).
+ Located in DDR3 SPD byte 17.
</description>
<valueType>uint8</valueType>
<platInit/>
</attribute>
<attribute>
- <id>ATTR_SPD_TWRMIN</id>
+ <id>ATTR_SPD_TRRDMIN</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
- Minimum Write Recovery Time (tWRmin).
- Located in DDR3 SPD byte 17.
+ Minimum Row Active to Row Active Delay Time (tRRDmin).
+ Located in DDR3 SPD byte 19.
</description>
<valueType>uint8</valueType>
<platInit/>
</attribute>
<attribute>
- <id>ATTR_SPD_TRCDMIN</id>
+ <id>ATTR_SPD_TRFCMIN</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
- Minimum RAS# to CAS# Delay Time (tRCDmin).
- Located in DDR3 SPD byte 18.
+ Minimum Refresh Recovery Delay Time (tRFCmin).
+ Located in DDR3 SPD byte 24 (LSB) and byte 25.
+ </description>
+ <valueType>uint32</valueType>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_TWTRMIN</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Minimum Internal Write to Read Command Delay Time (tWTRmin).
+ Located in DDR3 SPD byte 26.
</description>
<valueType>uint8</valueType>
<platInit/>
</attribute>
<attribute>
- <id>ATTR_SPD_TRRDMIN</id>
+ <id>ATTR_SPD_TRTPMIN</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
- Minimum Row Active to Row Active Delay Time (tRRDmin).
- Located in DDR3 SPD byte 19.
+ Minimum Internal Read to Precharge Command Delay Time (tRTPmin).
+ Located in DDR3 SPD byte 27.
</description>
<valueType>uint8</valueType>
<platInit/>
</attribute>
<attribute>
- <id>ATTR_SPD_TRPMIN</id>
+ <id>ATTR_SPD_LR_ADDR_MIRRORING</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
- Minimum Row Precharge Delay Time (tRPmin).
- Located in DDR3 SPD byte 20.
+ Load Reduced address mirroring attribute.
+ Located in DDR3 SPD byte 63 bits 1-0.
</description>
<valueType>uint8</valueType>
+ <enum>
+ NO_RANKS = 0x00,
+ ODD_RANKS = 0x01
+ </enum>
<platInit/>
</attribute>
<attribute>
- <id>ATTR_SPD_TRASMIN</id>
+ <id>ATTR_SPD_LR_F0RC3_F0RC2</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
- Minimum Active to Precharge Delay Time (tRASmin).
- Located in DDR3 SPD byte 21, bits 3-0 and byte 22 (LSB).
+ Load Reduced F0RC3/F0RC2.
+ Timing control AND Drive strength, Address/Command AND QxCS_n
+ Located in DDR3 SPD byte 67.
</description>
- <valueType>uint32</valueType>
+ <valueType>uint8</valueType>
<platInit/>
</attribute>
<attribute>
- <id>ATTR_SPD_TRCMIN</id>
+ <id>ATTR_SPD_LR_F0RC5_F0RC4</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
- Minimum Active to Active/Refresh Delay Time (tRCmin).
- Located in DDR3 SPD byte 21, bits 7-4 and byte 23 (LSB).
+ Load Reduced F0RC5/F0RC4.
+ Drive strength, QxODT AND QxCKE and Clock.
+ Located in DDR3 SPD byte 68.
</description>
- <valueType>uint32</valueType>
+ <valueType>uint8</valueType>
<platInit/>
</attribute>
<attribute>
- <id>ATTR_SPD_TRFCMIN</id>
+ <id>ATTR_SPD_LR_F1RC11_F1RC8</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
- Minimum Refresh Recovery Delay Time (tRFCmin).
- Located in DDR3 SPD byte 24 (LSB) and byte 25.
+ Load Reduced F1RC11/F1RC8.
+ Extended delay for clocks, QxCS_n and QxODT AND QxCKE.
+ Located in DDR3 SPD byte 69.
</description>
- <valueType>uint32</valueType>
+ <valueType>uint8</valueType>
<platInit/>
</attribute>
<attribute>
- <id>ATTR_SPD_TWTRMIN</id>
+ <id>ATTR_SPD_LR_F1RC13_F1RC12</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
- Minimum Internal Write to Read Command Delay Time (tWTRmin).
- Located in DDR3 SPD byte 26.
+ Load Reduced F1RC13/F1RC12.
+ Additive delay for QxCS_n and QxCA.
+ Located in DDR3 SPD byte 70.
</description>
<valueType>uint8</valueType>
<platInit/>
</attribute>
<attribute>
- <id>ATTR_SPD_TRTPMIN</id>
+ <id>ATTR_SPD_LR_F1RC15_F1RC14</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
- Minimum Internal Read to Precharge Command Delay Time (tRTPmin).
- Located in DDR3 SPD byte 27.
+ Load Reduced F1RC15/F1RC14.
+ Additive delay for QxODT and QxCKE.
+ Located in DDR3 SPD byte 71.
</description>
<valueType>uint8</valueType>
<platInit/>
</attribute>
<attribute>
- <id>ATTR_SPD_TFAWMIN</id>
+ <id>ATTR_SPD_LR_F3RC9_F3RC8_FOR_800_1066</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
- Minimum Four Activate Window Delay Time (tFAWmin).
- Located in DDR3 SPD byte 28, bits 3-0 and byte 29 (LSB).
+ Load Reduced F3RC9/F3RC8 for 800 AND 1066.
+ DRAM interface MDQ Termination and Drive strength.
+ Located in DDR3 SPD byte 72.
</description>
- <valueType>uint32</valueType>
+ <valueType>uint8</valueType>
<platInit/>
</attribute>
<attribute>
- <id>ATTR_SPD_SDRAM_OPTIONAL_FEATURES</id>
+ <id>ATTR_SPD_LR_F34RC11_F34RC10_FOR_800_1066</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
- SDRAM Optional Features (bitmap).
- Located in DDR3 SPD byte 30.
+ Load Reduced F[3,4]RC11/F[3,4]RC10 for 800 AND 1066.
+ Rank 0AND1 Read and Write QxODT control.
+ Located in DDR3 SPD byte 73.
</description>
<valueType>uint8</valueType>
- <enum>DLL_OFF = 0x80, RZQ7 = 0x02, RZQ6 = 0x01</enum>
<platInit/>
</attribute>
<attribute>
- <id>ATTR_SPD_SDRAM_THERMAL_AND_REFRESH_OPTIONS</id>
+ <id>ATTR_SPD_LR_F56RC11_F56RC10_FOR_800_1066</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
- SDRAM Thermal and Refresh Options (bitmap).
- Located in DDR3 SPD byte 31.
+ Load Reduced F[5,6]RC11/F[5,6]RC10 for 800 AND 1066.
+ Rank 2AND3 Read and Write QxODT control.
+ Located in DDR3 SPD byte 74.
</description>
<valueType>uint8</valueType>
- <enum>PASR = 0x80, ODTS = 0x08, ASR = 0x05, ETRR = 0x02, ETR = 0x01</enum>
<platInit/>
</attribute>
<attribute>
- <id>ATTR_SPD_MODULE_THERMAL_SENSOR</id>
+ <id>ATTR_SPD_LR_F78RC11_F78RC10_FOR_800_1066</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
- Module Thermal Sensor.
- Located in DDR3 SPD byte 32.
+ Load Reduced F[7,8]RC11/F[7,8]RC10 for 800 AND 1066.
+ Rank 4AND5 Read and Write QxODT control.
+ Located in DDR3 SPD byte 75.
</description>
<valueType>uint8</valueType>
- <enum>PRESENT = 0x80, ACCURACY_MASK = 0x7F</enum>
<platInit/>
</attribute>
<attribute>
- <id>ATTR_SPD_SDRAM_DEVICE_TYPE</id>
+ <id>ATTR_SPD_LR_F910RC11_F910RC10_FOR_800_1066</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
- SDRAM Device Type.
- Located in DDR3 SPD byte 33, bit 7.
+ Load Reduced F[9,10]RC11/F[9,10]RC10 for 800 AND 1066.
+ Rank 6AND7 Read and Write QxODT control.
+ Located in DDR3 SPD byte 76.
</description>
<valueType>uint8</valueType>
- <enum>STANDARD_MONOLITHIC = 0x00, NON_STANDARD = 0x80</enum>
<platInit/>
</attribute>
<attribute>
- <id>ATTR_SPD_SDRAM_DEVICE_TYPE_SIGNAL_LOADING</id>
+ <id>ATTR_SPD_LR_MR12_FOR_800_1066</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
- SDRAM Device Type Signal Loading for stacked DRAMs.
- Located in DDR3 SPD byte 33, bits 1-0.
+ Load Reduced MR1,2 registers for 800 AND 1066.
+ DRAM Rtt_WR for all ranks, DRAM Rtt_Nom for ranks 0 and 1, DRAM driver impedance for all ranks.
+ Located in DDR3 SPD byte 77.
</description>
<valueType>uint8</valueType>
- <enum>NOT_SPECIFIED = 0x00, MULTI_LOAD_STACK = 0x01, SINGLE_LOAD_STACK = 0x02</enum>
<platInit/>
</attribute>
<attribute>
- <id>ATTR_SPD_SDRAM_DIE_COUNT</id>
+ <id>ATTR_SPD_LR_F3RC9_F3RC8_FOR_1333_1600</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
- SDRAM Device Type Die Count.
- Located in DDR3 SPD byte 33, bits 6-4.
+ Load Reduced F3RC9/F3RC8 for 1333 AND 1600.
+ DRAM interface MDQ Termination and Drive strength.
+ Located in DDR3 SPD byte 78.
</description>
<valueType>uint8</valueType>
<platInit/>
</attribute>
<attribute>
- <id>ATTR_SPD_FINE_OFFSET_TCKMIN</id>
+ <id>ATTR_SPD_LR_F34RC11_F34RC10_FOR_1333_1600</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
- Fine Offset for SDRAM Minimum Cycle Time (tCKmin).
- Located in DDR3 SPD byte 34.
+ Load Reduced F[3,4]RC11/F[3,4]RC10 for 1333 AND 1600.
+ Rank 0AND1 Read and Write QxODT control.
+ Located in DDR3 SPD byte 79.
</description>
<valueType>uint8</valueType>
<platInit/>
</attribute>
+<attribute>
+ <id>ATTR_SPD_LR_F56RC11_F56RC10_FOR_1333_1600</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Load Reduced F[5,6]RC11/F[5,6]RC10 for 1333 AND 1600.
+ Rank 2AND3 Read and Write QxODT control.
+ Located in DDR3 SPD byte 80.
+ </description>
+ <valueType>uint8</valueType>
+ <platInit/>
+</attribute>
<attribute>
- <id>ATTR_SPD_FINE_OFFSET_TAAMIN</id>
+ <id>ATTR_SPD_LR_F78RC11_F78RC10_FOR_1333_1600</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
- Fine Offset for Minimum CAS Latency Time (tAAmin).
- Located in DDR3 SPD byte 35.
+ Load Reduced F[7,8]RC11/F[7,8]RC10 for 1333 AND 1600.
+ Rank 4AND5 Read and Write QxODT control.
+ Located in DDR3 SPD byte 81.
</description>
<valueType>uint8</valueType>
<platInit/>
</attribute>
<attribute>
- <id>ATTR_SPD_FINE_OFFSET_TRCDMIN</id>
+ <id>ATTR_SPD_LR_F910RC11_F910RC10_FOR_1333_1600</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
- Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin).
- Located in DDR3 SPD byte 36.
+ Load Reduced F[9,10]RC11/F[9,10]RC10 for 1333 AND 1600.
+ Rank 6AND7 Read and Write QxODT control.
+ Located in DDR3 SPD byte 82.
</description>
<valueType>uint8</valueType>
<platInit/>
</attribute>
<attribute>
- <id>ATTR_SPD_FINE_OFFSET_TRPMIN</id>
+ <id>ATTR_SPD_LR_MR12_FOR_1333_1600</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
- Fine Offset for Minimum Row Precharge Delay Time (tRPmin).
- Located in DDR3 SPD byte 37.
+ Load Reduced MR1,2 registers for 1333 AND 1600.
+ DRAM Rtt_WR for all ranks, DRAM Rtt_Nom for ranks 0 and 1, DRAM driver impedance for all ranks.
+ Located in DDR3 SPD byte 83.
</description>
<valueType>uint8</valueType>
<platInit/>
</attribute>
<attribute>
- <id>ATTR_SPD_FINE_OFFSET_TRCMIN</id>
+ <id>ATTR_SPD_LR_F3RC9_F3RC8_FOR_1866_2133</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
- Fine Offset for Minimum Active to Active/Refresh Delay Time (tRCmin).
- Located in DDR3 SPD byte 38.
+ Load Reduced F3RC9/F3RC8 for 1866 AND 2133.
+ DRAM interface MDQ Termination and Drive strength.
+ Located in DDR3 SPD byte 84.
</description>
<valueType>uint8</valueType>
<platInit/>
</attribute>
<attribute>
- <id>ATTR_SPD_NUM_OF_REGISTERS_USED_ON_RDIMM</id>
+ <id>ATTR_SPD_LR_F34RC11_F34RC10_FOR_1866_2133</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
- Number of Registers used on RDIMM.
- Located in DDR3 SPD byte 63 bits 1-0.
- </description>
+ Load Reduced F[3,4]RC11/F[3,4]RC10 for 1866 AND 2133.
+ Rank 0AND1 Read and Write QxODT control.
+ Located in DDR3 SPD byte 85.
+ </description>
<valueType>uint8</valueType>
<platInit/>
</attribute>
<attribute>
- <id>ATTR_SPD_MODULE_SPECIFIC_SECTION</id>
+ <id>ATTR_SPD_LR_F56RC11_F56RC10_FOR_1866_2133</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
- Module Specific Section.
- Located in DDR3 SPD bytes 60d - 116d.
+ Load Reduced F[5,6]RC11/F[5,6]RC10 for 1866 AND 2133.
+ Rank 2AND3 Read and Write QxODT control.
+ Located in DDR3 SPD byte 86.
</description>
<valueType>uint8</valueType>
- <array>57</array>
<platInit/>
</attribute>
<attribute>
- <id>ATTR_SPD_MODULE_ID_MODULE_MANUFACTURERS_JEDEC_ID_CODE</id>
+ <id>ATTR_SPD_LR_F78RC11_F78RC10_FOR_1866_2133</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
- Module ID: Module Manufacturer's JEDEC ID Code.
- Located in DDR3 SPD bytes 117 (LSB) to 118.
+ Load Reduced F[7,8]RC11/F[7,8]RC10 for 1866 AND 2133.
+ Rank 4AND5 Read and Write QxODT control.
+ Located in DDR3 SPD byte 87.
</description>
- <valueType>uint32</valueType>
+ <valueType>uint8</valueType>
<platInit/>
</attribute>
<attribute>
- <id>ATTR_SPD_MODULE_ID_MODULE_MANUFACTURING_LOCATION</id>
+ <id>ATTR_SPD_LR_F910RC11_F910RC10_FOR_1866_2133</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
- Module ID: Module Manufacturing Location.
- Located in DDR3 SPD byte 119.
+ Load Reduced F[9,10]RC11/F[9,10]RC10 for 1866 AND 2133.
+ Rank 6AND7 Read and Write QxODT control.
+ Located in DDR3 SPD byte 88.
</description>
<valueType>uint8</valueType>
<platInit/>
</attribute>
<attribute>
- <id>ATTR_SPD_MODULE_ID_MODULE_MANUFACTURING_DATE</id>
+ <id>ATTR_SPD_LR_MR12_FOR_1866_2133</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
- Module ID: Module Manufacturing Date.
- Located in DDR3 SPD bytes 120 (BCD year) to byte 121 (BCD week) (LSB).
+ Load Reduced MR1,2 registers for 1866 AND 2133.
+ DRAM Rtt_WR for all ranks, DRAM Rtt_Nom for ranks 0 and 1, DRAM driver impedance for all ranks.
+ Located in DDR3 SPD byte 89.
+ </description>
+ <valueType>uint8</valueType>
+ <platInit/>
+</attribute>
+
+<!--
+The following attributes can be queried from DDR4 DIMMs only
+Querying them from DDR3 DIMMs will result in an error
+-->
+<attribute>
+ <id>ATTR_SPD_SDRAM_BANKGROUPS_DDR4</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Number of bank groups.
+ Located in DDR4 SPD byte 4, bits 7-6.
+ </description>
+ <valueType>uint8</valueType>
+ <enum>BG0 = 0x00, BG2 = 0x01, BG4 = 0x02</enum>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_SDRAM_BANKS_DDR4</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Number of banks.
+ Located in DDR4 SPD byte 4, bits 5-4.
+ </description>
+ <valueType>uint8</valueType>
+ <enum>B4 = 0x00, B8 = 0x01</enum>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_MODULE_NOMINAL_VOLTAGE_DDR4</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Nominal voltage (bitmap).
+ Located in DDR4 SPD byte 11, bits 5-0.
+ </description>
+ <valueType>uint8</valueType>
+ <enum>
+ OP1_2V = 0x01, END1_2V = 0x02,
+ OPTBD1V = 0x04, ENDTBD1V = 0x08,
+ OPTBD2V = 0x10, ENDTBD2V = 0x20
+ </enum>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_TIMEBASE_MTB_DDR4</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ defines a value in picoseconds that represents the fundamental timebase
+ for medium grain timing calculations. This value is used as a multiplier
+ for formulating subsequent timing parameters.
+ Located in DDR4 SPD byte 17, bits 3-2.
+ </description>
+ <valueType>uint8</valueType>
+ <enum>PS125 = 0x00</enum>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_TIMEBASE_FTB_DDR4</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ defines a value in picoseconds that represents the fundamental timebase
+ for fine grain timing calculations. This value is used as a multiplier
+ for formulating subsequent timing parameters.
+ Located in DDR4 SPD byte 17, bits 1-0.
+ </description>
+ <valueType>uint8</valueType>
+ <enum>PS1 = 0x00</enum>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_TCKMAX_DDR4</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Maximum cycle time (tCKmax).
+ Located in DDR4 SPD byte 19.
+ </description>
+ <valueType>uint8</valueType>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_CAS_LATENCIES_SUPPORTED_DDR4</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ CAS Latencies supported (bitmap).
+ Located in DDR4 SPD byte 20 (LSB) through byte 23.
</description>
<valueType>uint32</valueType>
+ <enum>
+ CL_24 = 0x00020000,
+ CL_23 = 0x00010000,
+ CL_22 = 0x00008000,
+ CL_21 = 0x00004000,
+ CL_20 = 0x00002000,
+ CL_19 = 0x00001000,
+ CL_18 = 0x00000800,
+ CL_17 = 0x00000400,
+ CL_16 = 0x00000200,
+ CL_15 = 0x00000100,
+ CL_14 = 0x00000080,
+ CL_13 = 0x00000040,
+ CL_12 = 0x00000020,
+ CL_11 = 0x00000010,
+ CL_10 = 0x00000008,
+ CL_9 = 0x00000004,
+ CL_8 = 0x00000002,
+ CL_7 = 0x00000001
+ </enum>
<platInit/>
</attribute>
<attribute>
- <id>ATTR_SPD_MODULE_ID_MODULE_SERIAL_NUMBER</id>
+ <id>ATTR_SPD_TRFC1MIN_DDR4</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
- Module ID: Module Serial Number.
- Located in DDR3 SPD bytes 122 (LSB) to 125.
+ Minimum SDRAM Refresh Recovery Time Delay in medium timebase (MTB) units
+ Located in DDR4 SPD bytes 30(MSB) and 31(LSB).
</description>
<valueType>uint32</valueType>
<platInit/>
</attribute>
<attribute>
- <id>ATTR_SPD_CYCLICAL_REDUNDANCY_CODE</id>
+ <id>ATTR_SPD_TRFC2MIN_DDR4</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
- Cyclical Redundancy Code.
- Located in DDR3 SPD bytes 126 (LSB) to 127.
+ Minimum SDRAM Refresh Recovery Time Delay in medium timebase (MTB) units
+ Located in DDR4 SPD bytes 32(MSB) and 33(LSB).
</description>
<valueType>uint32</valueType>
<platInit/>
</attribute>
<attribute>
- <id>ATTR_SPD_MODULE_PART_NUMBER</id>
+ <id>ATTR_SPD_TRFC4MIN_DDR4</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
- Module Part Number.
- Located in DDR3 SPD bytes 128 - 145.
+ Minimum SDRAM Refresh Recovery Time Dealy in medium timebase (MTB) units.
+ Located in DDR4 SPD byte 34(LSB) bits 15-8 and SPD byte 35(MSB) 7-0.
+ </description>
+ <valueType>uint32</valueType>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_TRRDSMIN_DDR4</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ The minimum SDRAM Activate to Activate Delay Time to different bank
+ groups in medium timebase (MTB) units. Controller designers must also
+ note that at some frequencies, a minimum number of clocks may be required
+ resulting in a larger tRRD_Smin value than indicated in the SPD.
+ For example, tRRD_Smin for DDR4-1600 must be 4 clocks.
+ Located in DDR4 SPD byte 38
</description>
<valueType>uint8</valueType>
- <array>18</array>
<platInit/>
</attribute>
<attribute>
- <id>ATTR_SPD_MODULE_REVISION_CODE</id>
+ <id>ATTR_SPD_TRRDLMIN_DDR4</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
- Module Revision Code.
- Located in DDR3 SPD bytes 146 (LSB) to 147.
+ The minimum SDRAM Activate to Activate Delay Time to same bank
+ groups in medium timebase (MTB) units. Controller designers must also
+ note that at some frequencies, a minimum number of clocks may be required
+ resulting in a larger tRRD_Smin value than indicated in the SPD.
+ For example, tRRD_Lmin for DDR4-1600 must be 4 clocks.
+ Located in DDR4 SPD byte 39
</description>
- <valueType>uint32</valueType>
+ <valueType>uint8</valueType>
<platInit/>
</attribute>
<attribute>
- <id>ATTR_SPD_DRAM_MANUFACTURER_JEDEC_ID_CODE</id>
+ <id>ATTR_SPD_TCCDLMIN_DDR4</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
- DRAM Manufacturer JEDEC ID Code.
- Located in DDR3 SPD bytes 148 (LSB) to 149.
+ The minimum SDRAM CAS to CAS Delay Time to same bank
+ groups in medium timebase (MTB) units. Controller designers must also
+ note that at some frequencies, a minimum number of clocks may be required
+ resulting in a larger tCCD_Lmin value than indicated in the SPD.
+ For example, tCCD_Lmin for DDR4-2133 must be 6 clocks.
+ Located in DDR4 SPD byte 40
+ </description>
+ <valueType>uint8</valueType>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_FINE_OFFSET_TCCDLMIN_DDR4</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Modifies the calculation of SPD Byte 40 with a fine correction
+ using FTB units. The value of tCCD_Lmin comes from the SDRAM data
+ sheet. This value is a two.s complement multiplier for FTB units,
+ ranging from +127 to -128.
+ Located in DDR4 SPD byte 117
+ </description>
+ <valueType>uint8</valueType>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_FINE_OFFSET_TRRDLMIN_DDR4</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Modifies the calculation of SPD Byte 39 with a fine correction using
+ FTB units. The value of tRRD_Lmin comes from the SDRAM data sheet.
+ This value is a two.s complement multiplier for FTB units,
+ ranging from +127 to -128.
+ Located in DDR4 SPD byte 118
+ </description>
+ <valueType>uint8</valueType>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_FINE_OFFSET_TRRDSMIN_DDR4</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Modifies the calculation of SPD Byte 38 (MTB units) with a fine
+ correction using FTB units. The value of tRRD_Smin comes from the
+ SDRAM data sheet. This value is a two.s complement multiplier for
+ FTB units, ranging from +127 to -128.
+ Located in DDR4 SPD byte 119
+ </description>
+ <valueType>uint8</valueType>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_FINE_OFFSET_TCKMAX_DDR4</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Fine Offset for SDRAM Minimum Cycle Time (tCKAVGmax).
+ Located in DDR4 SPD byte 124.
+ </description>
+ <valueType>uint8</valueType>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_CRC_BASE_CONFIG_DDR4</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ contains the calculated CRC for bytes 0~125 (0x000~0x07D) in the SPD
+ Located in DDR4 SPD byte 126(LSB) and 127(MSB).
</description>
<valueType>uint32</valueType>
<platInit/>
</attribute>
<attribute>
- <id>ATTR_SPD_BAD_DQ_DATA</id>
+ <id>ATTR_SPD_DRAM_STEPPING_DDR4</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
- Bad DQ pin data stored in DIMM SPD. This data is in a special format.
- This must only be called by a firmware HWP that knows how to decode the data.
- HWP/PLAT firmware that needs to get/set the Bad DQ Bitmap from a Centaur
- DQ point of view must call the dimmBadDqBitmapAccessHwp HWP.
+ Defines the vendor die revision level (often called the .stepping.)
+ of the DRAMs on the module. This byte is optional.
+ For modules without DRAM stepping information, this byte should
+ be programmed to 0xFF.
+ Located in DDR4 SPD byte 352
</description>
<valueType>uint8</valueType>
- <array>80</array>
+ <platInit/>
+</attribute>
+
+<attribute>
+ <id>ATTR_SPD_CRC_MNFG_SEC_DDR4</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ contains the calculated CRC for bytes 320~381 (0x140~0x17D) in the SPD
+ Located in DDR4 SPD byte 382(LSB) and 383(MSB).
+ </description>
+ <valueType>uint32</valueType>
+ <platInit/>
+</attribute>
+
+<!-- Not yet supported by firmware
+<attribute>
+ <id>ATTR_VPD_VERSION</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ The VPD Version of this DIMM. The version number can be an indication of when different DIMM keywords are valid and is loaded from the platform. A version number of zero is unknown.
+ </description>
+ <valueType>uint32</valueType>
<platInit/>
<writeable/>
</attribute>
+-->
+
+<!--
+The following attributes are from Centaur VPD. Consider moving them from this
+file
+-->
<attribute>
<id>ATTR_VPD_DRAM_ADDRESS_MIRRORING</id>
@@ -625,7 +1261,7 @@
The C-DIMM ranks that have address mirroring.
This data is in the Record:VSPD, Keyword:AM field in C-DIMM VPD.
This attribute is only valid for C-DIMMs, an error should be returned if queried from IS-DIMMs.
- Note: Muliple ranks can be mirrored.
+ Note: Muliple ranks can be mirrored.
</description>
<valueType>uint8</valueType>
<enum>
@@ -637,4 +1273,19 @@
<platInit/>
</attribute>
+<!-- Not yet supported by firmware
+<attribute>
+ <id>ATTR_VPD_DRAM_2N_MODE</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ The 2N/2T characteristic of the DIMM from the MT keyword. If the memory controller needs to run on 2N mode, the address is presented for two cycles. By default, 2N should be set to INVALID until the platform initializes it..
+ </description>
+ <valueType>uint8</valueType>
+ <enum>INVALID = 0x00, 1N = 0x01, 2N = 0x02</enum>
+ <array>2</array>
+ <platInit/>
+ <writeable/>
+</attribute>
+-->
+
</attributes>
diff --git a/src/usr/hwpf/plat/fapiPlatAttributeService.C b/src/usr/hwpf/plat/fapiPlatAttributeService.C
index d1e0459a1..41d69d16b 100644
--- a/src/usr/hwpf/plat/fapiPlatAttributeService.C
+++ b/src/usr/hwpf/plat/fapiPlatAttributeService.C
@@ -237,62 +237,6 @@ fapi::ReturnCode setTargetingAttr(const fapi::Target * i_pFapiTarget,
}
//******************************************************************************
-// platUpdateAttrValue function reformats the Attribute value if needed based
-// on the format documented in the HWPF attributei xml file.
-//******************************************************************************
-static void platUpdateAttrValue( const uint16_t i_keyword, void * o_data )
-{
- FAPI_DBG(ENTER_MRK "platUpdateAttrValue");
-
- uint32_t l_word = 0;
- uint8_t *l_byte = static_cast<uint8_t *>(o_data);
- bool l_update = true;
-
- switch( i_keyword )
- {
- // These attributes are 4-byte uint32_t values. The DD returns 2-byte
- // left-aligned value. Need to move it to right-aligned format.
- case SPD::CAS_LATENCIES_SUPPORTED:
- case SPD::TRAS_MIN:
- case SPD::TRC_MIN:
- case SPD::TRFC_MIN:
- case SPD::TFAW_MIN:
- case SPD::MODULE_MANUFACTURING_DATE:
- case SPD::MODULE_MANUFACTURER_ID:
- l_word |= (*l_byte++ << 8);
- l_word |= (*l_byte);
- break;
- // These attributes are 4-bytes uint32_t values. The DD returns 2-byte
- // left-aligned and byte-swapped value. Need to move it to right-aligned
- // and reverse the bytes
- case SPD::MODULE_CRC:
- case SPD::MODULE_REVISION_CODE:
- l_word |= (*l_byte++);
- l_word |= (*l_byte << 8);
- break;
- // This attribute are 4-bytes uint32_t. The DD returns in big-endian
- // format. Need to change to little endian
- case SPD::MODULE_SERIAL_NUMBER:
- l_word |= (*l_byte++);
- l_word |= (*l_byte++ << 8);
- l_word |= (*l_byte++ << 16);
- l_word |= (*l_byte << 24);
- break;
- default:
- l_update = false;
- break;
- }
-
- if (l_update)
- {
- memcpy( o_data, &l_word, sizeof(l_word) );
- }
-
- FAPI_DBG(EXIT_MRK "platUpdateAttrValue");
-
-}
-
-//******************************************************************************
// fapiPlatGetSpdAttr function.
// Call SPD device driver to retrieve the SPD attribute
//******************************************************************************
@@ -326,7 +270,13 @@ fapi::ReturnCode fapiPlatGetSpdAttr(const fapi::Target * i_pFapiTarget,
}
else
{
- platUpdateAttrValue(i_keyword, o_data);
+ if ((i_len == sizeof(uint32_t)) && (l_len == sizeof(uint16_t)))
+ {
+ // This is a uint16_t attribute written to a uint32_t type.
+ // This is because FAPI attributes can only be uint8/32/64
+ // Shift the data to be right aligned
+ *(static_cast<uint32_t *>(o_data)) >>= 16;
+ }
}
}
diff --git a/src/usr/vpd/spd.C b/src/usr/vpd/spd.C
index c62bd91f4..a102ed7bd 100755
--- a/src/usr/vpd/spd.C
+++ b/src/usr/vpd/spd.C
@@ -42,6 +42,7 @@
#include <algorithm>
#include "spd.H"
#include "spdDDR3.H"
+#include "spdDDR4.H"
// ----------------------------------------------
// Trace definitions
@@ -110,6 +111,22 @@ errlHndl_t getMemType ( uint8_t & o_memType,
TARGETING::Target * i_target );
/**
+ * @brief This function will read the DIMM module type.
+ *
+ * @param[out] o_modType - The module type value to return.
+ *
+ * @param[in] i_target - The target to read data from.
+ *
+ * @param[in] i_memType - The memory type
+ *
+ * @return errlHndl_t - NULL if successful, otherwise a pointer
+ * to the error log.
+ */
+errlHndl_t getModType ( modSpecTypes_t & o_memType,
+ TARGETING::Target * i_target,
+ uint64_t i_memType );
+
+/**
* @brief This function will scan the table and return the entry
* corresponding to the keyword being requested.
*
@@ -124,7 +141,7 @@ errlHndl_t getMemType ( uint8_t & o_memType,
*/
errlHndl_t getKeywordEntry ( uint64_t i_keyword,
uint64_t i_memType,
- KeywordData *& o_entry );
+ const KeywordData *& o_entry );
// Register the perform Op with the routing code for DIMMs.
@@ -170,14 +187,13 @@ errlHndl_t spdGetKeywordValue ( DeviceFW::OperationType i_opType,
INFO_MRK"Mem Type: %04x",
memType );
- // Check the Basic Memory Type to be sure its valid before
- // continuing.
- if( SPD_DDR3 == memType )
+ // Check the Basic Memory Type
+ if(( SPD_DDR3 == memType ) || ( SPD_DDR4 == memType ))
{
// If the user wanted the Basic memory type, return this now.
if( BASIC_MEMORY_TYPE == keyword )
{
- io_buflen = MEM_TYPE_ADDR_SZ;
+ io_buflen = MEM_TYPE_SZ;
memcpy( io_buffer, &memType, io_buflen );
break;
}
@@ -254,8 +270,8 @@ errlHndl_t spdWriteKeywordValue ( DeviceFW::OperationType i_opType,
break;
}
- // Check DDR3
- if( SPD_DDR3 == memType )
+ // Check the Basic Memory Type
+ if(( SPD_DDR3 == memType ) || ( SPD_DDR4 == memType ))
{
err = spdWriteValue( keyword,
io_buffer,
@@ -441,7 +457,7 @@ errlHndl_t spdGetValue ( uint64_t i_keyword,
do
{
- KeywordData * entry = NULL;
+ const KeywordData * entry = NULL;
err = getKeywordEntry( i_keyword,
i_DDRRev,
entry );
@@ -489,19 +505,6 @@ errlHndl_t spdGetValue ( uint64_t i_keyword,
break;
}
- if( entry->isSpecialCase )
- {
- // Handle special cases where data isn't sequential
- // or is in reverse order from what would be read.
- err = spdSpecialCases( (*entry),
- io_buffer,
- io_buflen,
- i_target,
- i_DDRRev );
-
- break;
- }
-
// Check io_buflen versus size in table
err = spdCheckSize( io_buflen,
(*entry).length,
@@ -512,27 +515,43 @@ errlHndl_t spdGetValue ( uint64_t i_keyword,
break;
}
- // Read length requested
- err = spdFetchData( (*entry).offset,
- (*entry).length,
- tmpBuffer,
- i_target );
-
- if( err )
+ if( entry->isSpecialCase )
{
- break;
- }
+ // Handle special cases where data isn't sequential
+ // or is in reverse order from what would be read.
+ err = spdSpecialCases( (*entry),
+ io_buffer,
+ i_target,
+ i_DDRRev );
- // if useBitmask set, mask and then shift data
- if( (*entry).useBitMask )
+ if (err)
+ {
+ break;
+ }
+ }
+ else
{
- // Any bit mask/shifting will always be on a <1 Byte value
- // thus, we touch only byte 0.
- tmpBuffer[0] = tmpBuffer[0] & (*entry).bitMask;
- tmpBuffer[0] = tmpBuffer[0] >> (*entry).shift;
+ // Read length requested
+ err = spdFetchData( (*entry).offset,
+ (*entry).length,
+ tmpBuffer,
+ i_target );
+
+ if( err )
+ {
+ break;
+ }
+
+ // if useBitmask set, mask and then shift data
+ if( (*entry).bitMask )
+ {
+ // Any bit mask/shifting is only applied to the first byte
+ tmpBuffer[0] = tmpBuffer[0] & (*entry).bitMask;
+ tmpBuffer[0] = tmpBuffer[0] >> (*entry).shift;
+ }
}
- // Set length read
+ // Set length read to the size in the table
io_buflen = (*entry).length;
} while( 0 );
@@ -566,7 +585,7 @@ errlHndl_t spdWriteValue ( uint64_t i_keyword,
do
{
- KeywordData * entry = NULL;
+ const KeywordData * entry = NULL;
err = getKeywordEntry( i_keyword,
i_DDRRev,
entry );
@@ -644,7 +663,7 @@ errlHndl_t spdWriteValue ( uint64_t i_keyword,
// We are not handling writes that are not on a byte
// boundary until we absolutely need to. There are
// no writable keywords that are not on byte boundaries
- if( entry->useBitMask )
+ if( entry->bitMask )
{
// Error if not writable
TRACFCOMP( g_trac_spd,
@@ -709,18 +728,251 @@ errlHndl_t spdWriteValue ( uint64_t i_keyword,
return err;
}
+// ------------------------------------------------------------------
+// ddr3SpecialCases
+// ------------------------------------------------------------------
+errlHndl_t ddr3SpecialCases(const KeywordData & i_kwdData,
+ void * io_buffer,
+ TARGETING::Target * i_target)
+{
+ errlHndl_t err = NULL;
+ uint8_t * tmpBuffer = static_cast<uint8_t *>(io_buffer);
+
+ TRACSSCOMP( g_trac_spd, ENTER_MRK"ddr3SpecialCases()" );
+
+ switch( i_kwdData.keyword )
+ {
+ // ==================================================
+ // 2 byte - LSB then MSB
+ case CAS_LATENCIES_SUPPORTED:
+ case TRFC_MIN:
+ case MODULE_MANUFACTURER_ID:
+ case MODULE_REVISION_CODE:
+ case DRAM_MANUFACTURER_ID:
+ case MODULE_CRC:
+ case RMM_MFR_ID_CODE:
+ case LRMM_MFR_ID_CODE:
+ // Get MSB
+ err = spdFetchData( i_kwdData.offset,
+ 1, /* Read 1 byte at a time */
+ &tmpBuffer[0],
+ i_target );
+
+ if( err ) break;
+
+ // Mask and shift if needed
+ if( i_kwdData.bitMask )
+ {
+ tmpBuffer[0] = tmpBuffer[0] & i_kwdData.bitMask;
+ tmpBuffer[0] = tmpBuffer[0] >> i_kwdData.shift;
+ }
+
+ // Get LSB
+ err = spdFetchData( (i_kwdData.offset - 1),
+ 1, /* Read 1 byte at a time */
+ &tmpBuffer[1],
+ i_target );
+ break;
+
+ // ==================================================
+ // 2 byte - MSB with mask then LSB is 2 more than MSB
+ case TRC_MIN:
+ // Get MSB
+ err = spdFetchData( i_kwdData.offset,
+ 1, /* Read 1 byte at a time */
+ &tmpBuffer[0],
+ i_target );
+
+ if( err ) break;
+
+ // Mask and shift if needed
+ if( i_kwdData.bitMask )
+ {
+ tmpBuffer[0] = tmpBuffer[0] & i_kwdData.bitMask;
+ tmpBuffer[0] = tmpBuffer[0] >> i_kwdData.shift;
+ }
+
+ // Get LSB
+ err = spdFetchData( (i_kwdData.offset + 2),
+ 1, /* Read 1 byte at a time */
+ &tmpBuffer[1],
+ i_target );
+ break;
+
+ // ==================================================
+ default:
+ TRACFCOMP( g_trac_spd,
+ ERR_MRK"Unknown keyword (0x%04x) for DDR3 special cases!",
+ i_kwdData.keyword );
+
+ /*@
+ * @errortype
+ * @reasoncode VPD::VPD_INVALID_SPD_KEYWORD
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid VPD::VPD_SPD_DDR3_SPECIAL_CASES
+ * @userdata1 SPD Keyword
+ * @userdata2 UNUSED
+ * @devdesc Keyword is not a special case keyword.
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ VPD::VPD_SPD_DDR3_SPECIAL_CASES,
+ VPD::VPD_INVALID_SPD_KEYWORD,
+ i_kwdData.keyword,
+ 0x0 );
+ break;
+ };
+
+ TRACSSCOMP( g_trac_spd, EXIT_MRK"ddr4SpecialCases()" );
+ return err;
+}
+
+// ------------------------------------------------------------------
+// ddr4SpecialCases
+// ------------------------------------------------------------------
+errlHndl_t ddr4SpecialCases(const KeywordData & i_kwdData,
+ void * io_buffer,
+ TARGETING::Target * i_target)
+{
+ errlHndl_t err = NULL;
+ uint8_t * tmpBuffer = static_cast<uint8_t *>(io_buffer);
+
+ TRACSSCOMP( g_trac_spd, ENTER_MRK"ddr4SpecialCases()" );
+
+ switch( i_kwdData.keyword )
+ {
+ // ==================================================
+ // 2 byte - LSB then MSB
+ case TRFC1_MIN:
+ case TRFC2_MIN:
+ case TRFC4_MIN:
+ case BASE_CONFIG_CRC:
+ case MODULE_MANUFACTURER_ID:
+ case MODULE_REVISION_CODE:
+ case DRAM_MANUFACTURER_ID:
+ case MANUFACTURING_SECTION_CRC:
+ case UMM_CRC:
+ case RMM_MFR_ID_CODE:
+ case RMM_CRC:
+ case LRMM_MFR_ID_CODE:
+ case LRMM_CRC:
+ // Get MSB
+ err = spdFetchData( i_kwdData.offset,
+ 1, /* Read 1 byte at a time */
+ &tmpBuffer[0],
+ i_target );
+
+ if( err ) break;
+
+ // Mask and shift if needed
+ if( i_kwdData.bitMask )
+ {
+ tmpBuffer[0] = tmpBuffer[0] & i_kwdData.bitMask;
+ tmpBuffer[0] = tmpBuffer[0] >> i_kwdData.shift;
+ }
+
+ // Get LSB
+ err = spdFetchData( (i_kwdData.offset - 1),
+ 1, /* Read 1 byte at a time */
+ &tmpBuffer[1],
+ i_target );
+ break;
+
+ // ==================================================
+ // 2 byte - MSB with mask then LSB is 2 more than MSB
+ case TRC_MIN:
+ // Get MSB
+ err = spdFetchData( i_kwdData.offset,
+ 1, /* Read 1 byte at a time */
+ &tmpBuffer[0],
+ i_target );
+
+ if( err ) break;
+
+ // Mask and shift if needed
+ if( i_kwdData.bitMask )
+ {
+ tmpBuffer[0] = tmpBuffer[0] & i_kwdData.bitMask;
+ tmpBuffer[0] = tmpBuffer[0] >> i_kwdData.shift;
+ }
+
+ // Get LSB
+ err = spdFetchData( (i_kwdData.offset + 2),
+ 1, /* Read 1 byte at a time */
+ &tmpBuffer[1],
+ i_target );
+ break;
+
+ // ==================================================
+ // 4 byte - LSB first, no mask
+ case CAS_LATENCIES_SUPPORTED:
+ // Get 4th byte
+ err = spdFetchData( i_kwdData.offset,
+ 1, /* Read 1 byte at a time */
+ &tmpBuffer[0],
+ i_target );
+
+ if( err ) break;
+
+ // Get 3rd Byte
+ err = spdFetchData( (i_kwdData.offset - 1),
+ 1, /* Read 1 byte at a time */
+ &tmpBuffer[1],
+ i_target );
+
+ if( err ) break;
+
+ // Get 2nd Byte
+ err = spdFetchData( (i_kwdData.offset - 2),
+ 1, /* Read 1 byte at a time */
+ &tmpBuffer[2],
+ i_target );
+
+ if( err ) break;
+
+ // Get 1st Byte
+ err = spdFetchData( (i_kwdData.offset - 3),
+ 1, /* Read 1 byte at a time */
+ &tmpBuffer[3],
+ i_target );
+ break;
+
+ // ==================================================
+ default:
+ TRACFCOMP( g_trac_spd,
+ ERR_MRK"Unknown keyword (0x%04x) for DDR4 special cases!",
+ i_kwdData.keyword );
+
+ /*@
+ * @errortype
+ * @reasoncode VPD::VPD_INVALID_SPD_KEYWORD
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid VPD::VPD_SPD_DDR4_SPECIAL_CASES
+ * @userdata1 SPD Keyword
+ * @userdata2 UNUSED
+ * @devdesc Keyword is not a special case keyword.
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ VPD::VPD_SPD_DDR4_SPECIAL_CASES,
+ VPD::VPD_INVALID_SPD_KEYWORD,
+ i_kwdData.keyword,
+ 0x0 );
+ break;
+ };
+
+ TRACSSCOMP( g_trac_spd, EXIT_MRK"ddr4SpecialCases()" );
+ return err;
+}
+
// ------------------------------------------------------------------
// spdSpecialCases
// ------------------------------------------------------------------
-errlHndl_t spdSpecialCases ( KeywordData i_kwdData,
+errlHndl_t spdSpecialCases ( const KeywordData & i_kwdData,
void * io_buffer,
- size_t & io_buflen,
TARGETING::Target * i_target,
uint64_t i_DDRRev )
{
errlHndl_t err = NULL;
- uint8_t * tmpBuffer = static_cast<uint8_t *>(io_buffer);
TRACSSCOMP( g_trac_spd,
ENTER_MRK"spdSpecialCases()" );
@@ -730,147 +982,11 @@ errlHndl_t spdSpecialCases ( KeywordData i_kwdData,
// Handle each of the special cases here
if( SPD_DDR3 == i_DDRRev )
{
- switch( i_kwdData.keyword )
- {
- // ==================================================
- // 2 byte - LSB then MSB
- case CAS_LATENCIES_SUPPORTED:
- case TRFC_MIN:
- case MODULE_MANUFACTURER_ID:
- case DRAM_MANUFACTURER_ID:
- case RMM_MFR_ID_CODE:
- case LRMM_MFR_ID_CODE:
- // Check Size of buffer
- err = spdCheckSize( io_buflen,
- i_kwdData.length,
- i_kwdData.keyword );
-
- if( err ) break;
-
- // Get MSB
- err = spdFetchData( i_kwdData.offset,
- 1, /* Read 1 byte at a time */
- &tmpBuffer[0],
- i_target );
-
- if( err ) break;
-
- // Mask and shift if needed
- if( i_kwdData.useBitMask )
- {
- tmpBuffer[0] = tmpBuffer[0] & i_kwdData.bitMask;
- tmpBuffer[0] = tmpBuffer[0] >> i_kwdData.shift;
- }
-
- // Get LSB
- err = spdFetchData( (i_kwdData.offset - 1),
- 1, /* Read 1 byte at a time */
- &tmpBuffer[1],
- i_target );
-
- if( err ) break;
-
- // Set number of bytes read
- io_buflen = i_kwdData.length;
- break;
-
- // ==================================================
- // 2 byte - MSB with mask then LSB is 2 more than MSB
- case TRC_MIN:
- // Check Size of buffer
- err = spdCheckSize( io_buflen,
- i_kwdData.length,
- i_kwdData.keyword );
-
- if( err ) break;
-
- // Get MSB
- err = spdFetchData( i_kwdData.offset,
- 1, /* Read 1 byte at a time */
- &tmpBuffer[0],
- i_target );
-
- if( err ) break;
-
- // Mask and shift if needed
- if( i_kwdData.useBitMask )
- {
- tmpBuffer[0] = tmpBuffer[0] & i_kwdData.bitMask;
- tmpBuffer[0] = tmpBuffer[0] >> i_kwdData.shift;
- }
-
- // Get LSB
- err = spdFetchData( (i_kwdData.offset + 2),
- 1, /* Read 1 byte at a time */
- &tmpBuffer[1],
- i_target );
-
- if( err ) break;
-
- // Set number of bytes read
- io_buflen = i_kwdData.length;
- break;
-
- // ==================================================
- // 2 byte - MSB then LSB
- case TRAS_MIN:
- case TFAW_MIN:
- // Check size of buffer
- err = spdCheckSize( io_buflen,
- i_kwdData.length,
- i_kwdData.keyword );
-
- if( err ) break;
-
- // Get MSB
- err = spdFetchData( i_kwdData.offset,
- 1, /* Read 1 byte at a time */
- &tmpBuffer[0],
- i_target );
-
- if( err ) break;
-
- // Mask and shift if needed
- if( i_kwdData.useBitMask )
- {
- tmpBuffer[0] = tmpBuffer[0] & i_kwdData.bitMask;
- tmpBuffer[0] = tmpBuffer[0] >> i_kwdData.shift;
- }
-
- // Get LSB
- err = spdFetchData( (i_kwdData.offset + 1),
- 1, /* Read 1 byte at a time */
- &tmpBuffer[1],
- i_target );
-
- if( err ) break;
-
- // Set number of bytes read
- io_buflen = i_kwdData.length;
- break;
-
- // ==================================================
- default:
- TRACFCOMP( g_trac_spd,
- ERR_MRK"Unknown keyword (0x%04x) for DDR3 special cases!",
- i_kwdData.keyword );
-
- /*@
- * @errortype
- * @reasoncode VPD::VPD_INVALID_SPD_KEYWORD
- * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
- * @moduleid VPD::VPD_SPD_SPECIAL_CASES
- * @userdata1 SPD Keyword
- * @userdata2 UNUSED
- * @devdesc Keyword is not a special case keyword.
- */
- err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- VPD::VPD_SPD_SPECIAL_CASES,
- VPD::VPD_INVALID_SPD_KEYWORD,
- i_kwdData.keyword,
- 0x0 );
- break;
- };
+ err = ddr3SpecialCases(i_kwdData,io_buffer,i_target);
+ }
+ else if (SPD_DDR4 == i_DDRRev)
+ {
+ err = ddr4SpecialCases(i_kwdData,io_buffer,i_target);
}
else
{
@@ -1097,46 +1213,10 @@ errlHndl_t checkModSpecificKeyword ( KeywordData i_kwdData,
break;
}
- KeywordData * modTypeEntry = NULL;
- err = getKeywordEntry( MODULE_TYPE,
- i_memType,
- modTypeEntry );
-
- if( err )
- {
- break;
- }
-
- if( NULL == modTypeEntry )
- {
- TRACFCOMP( g_trac_spd,
- ERR_MRK"Keyword Entry pointer is NULL!" );
-
- /*@
- * @errortype
- * @reasoncode VPD::VPD_NULL_ENTRY
- * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
- * @moduleid VPD::VPD_SPD_CHECK_MODULE_SPECIFIC_KEYWORD
- * @userdata1 i_memType
- * @userdata2 <UNUSED>
- * @devdesc Entry to get Module type is NULL
- */
- err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- VPD::VPD_SPD_CHECK_MODULE_SPECIFIC_KEYWORD,
- VPD::VPD_NULL_ENTRY,
- i_memType,
- 0x0 );
-
- break;
- }
-
- // To check the module specific flags, also need the Module Type
- // value.
- uint8_t modType = 0x0;
- err = spdFetchData( modTypeEntry->offset,
- modTypeEntry->length,
- &modType,
- i_target );
+ // Check that a Module Specific keyword is being accessed from a DIMM
+ // of the correct Module Type.
+ modSpecTypes_t modType = NA;
+ err = getModType(modType, i_target, i_memType);
if( err )
{
@@ -1144,21 +1224,13 @@ errlHndl_t checkModSpecificKeyword ( KeywordData i_kwdData,
}
// Check Unbuffered Memory Module (UMM)
- if( (SPD_DDR3 == i_memType) &&
- ( (0x2 == modType) ||
- (0x3 == modType) ||
- (0x4 == modType) ||
- (0x6 == modType) ||
- (0x8 == modType) ||
- (0xc == modType) ||
- (0xd == modType) ) )
+ if (UMM == modType)
{
- if( 0 == (i_kwdData.modSpec & UMM) )
+ if (UMM != i_kwdData.modSpec)
{
TRACFCOMP( g_trac_spd,
ERR_MRK"Keyword (0x%04x) is not valid with UMM modules!",
i_kwdData.keyword );
-
/*@
* @errortype
* @reasoncode VPD::VPD_MOD_SPECIFIC_MISMATCH_UMM
@@ -1170,28 +1242,24 @@ errlHndl_t checkModSpecificKeyword ( KeywordData i_kwdData,
* @userdata2[32:63] Module Specific flag
* @devdesc Keyword requested was not UMM Module specific.
*/
- err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- VPD::VPD_SPD_CHECK_MODULE_SPECIFIC_KEYWORD,
- VPD::VPD_MOD_SPECIFIC_MISMATCH_UMM,
- TWO_UINT32_TO_UINT64( modType, i_memType ),
- TWO_UINT32_TO_UINT64( i_kwdData.keyword,
- i_kwdData.modSpec ) );
-
+ err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ VPD::VPD_SPD_CHECK_MODULE_SPECIFIC_KEYWORD,
+ VPD::VPD_MOD_SPECIFIC_MISMATCH_UMM,
+ TWO_UINT32_TO_UINT64( modType, i_memType ),
+ TWO_UINT32_TO_UINT64( i_kwdData.keyword,
+ i_kwdData.modSpec ) );
break;
}
}
// Check Registered Memory Module (RMM)
- else if( (SPD_DDR3 == i_memType) &&
- ( (0x1 == modType) ||
- (0x5 == modType) ||
- (0x9 == modType) ) )
+ else if (RMM == modType)
{
- if( 0 == (i_kwdData.modSpec & RMM) )
+ if (RMM != i_kwdData.modSpec)
{
TRACFCOMP( g_trac_spd,
ERR_MRK"Keyword (0x%04x) is not valid with RMM modules!",
i_kwdData.keyword );
-
/*@
* @errortype
* @reasoncode VPD::VPD_MOD_SPECIFIC_MISMATCH_RMM
@@ -1203,27 +1271,24 @@ errlHndl_t checkModSpecificKeyword ( KeywordData i_kwdData,
* @userdata2[32:63] Module Specific flag
* @devdesc Keyword requested was not RMM Module specific.
*/
- err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- VPD::VPD_SPD_CHECK_MODULE_SPECIFIC_KEYWORD,
- VPD::VPD_MOD_SPECIFIC_MISMATCH_RMM,
- TWO_UINT32_TO_UINT64( modType, i_memType ),
- TWO_UINT32_TO_UINT64( i_kwdData.keyword,
- i_kwdData.modSpec ) );
-
+ err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ VPD::VPD_SPD_CHECK_MODULE_SPECIFIC_KEYWORD,
+ VPD::VPD_MOD_SPECIFIC_MISMATCH_RMM,
+ TWO_UINT32_TO_UINT64( modType, i_memType ),
+ TWO_UINT32_TO_UINT64( i_kwdData.keyword,
+ i_kwdData.modSpec ) );
break;
}
}
// Check Clocked Memory Module (CMM)
- else if( (SPD_DDR3 == i_memType) &&
- ( (0x7 == modType) ||
- (0xa == modType) ) )
+ else if (CMM == modType)
{
- if( 0 == (i_kwdData.modSpec & CMM) )
+ if (CMM != i_kwdData.modSpec)
{
TRACFCOMP( g_trac_spd,
ERR_MRK"Keyword (0x%04x) is not valid with CMM modules!",
i_kwdData.keyword );
-
/*@
* @errortype
* @reasoncode VPD::VPD_MOD_SPECIFIC_MISMATCH_CMM
@@ -1235,26 +1300,24 @@ errlHndl_t checkModSpecificKeyword ( KeywordData i_kwdData,
* @userdata2[32:63] Module Specific flag
* @devdesc Keyword requested was not CMM Module specific.
*/
- err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- VPD::VPD_SPD_CHECK_MODULE_SPECIFIC_KEYWORD,
- VPD::VPD_MOD_SPECIFIC_MISMATCH_CMM,
- TWO_UINT32_TO_UINT64( modType, i_memType ),
- TWO_UINT32_TO_UINT64( i_kwdData.keyword,
- i_kwdData.modSpec ) );
-
+ err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ VPD::VPD_SPD_CHECK_MODULE_SPECIFIC_KEYWORD,
+ VPD::VPD_MOD_SPECIFIC_MISMATCH_CMM,
+ TWO_UINT32_TO_UINT64( modType, i_memType ),
+ TWO_UINT32_TO_UINT64( i_kwdData.keyword,
+ i_kwdData.modSpec ) );
break;
}
}
// Check Load Reduction Memory Module (LRMM)
- else if( (SPD_DDR3 == i_memType) &&
- ( (0xb == modType) ) )
+ else if (LRMM == modType)
{
- if( 0 == (i_kwdData.modSpec & LRMM) )
+ if (LRMM != i_kwdData.modSpec)
{
TRACFCOMP( g_trac_spd,
ERR_MRK"Keyword (0x%04x) is not valid with LRMM modules!",
i_kwdData.keyword );
-
/*@
* @errortype
* @reasoncode VPD::VPD_MOD_SPECIFIC_MISMATCH_LRMM
@@ -1266,13 +1329,13 @@ errlHndl_t checkModSpecificKeyword ( KeywordData i_kwdData,
* @userdata2[32:63] Module Specific flag
* @devdesc Keyword requested was not LRMM Module specific.
*/
- err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- VPD::VPD_SPD_CHECK_MODULE_SPECIFIC_KEYWORD,
- VPD::VPD_MOD_SPECIFIC_MISMATCH_LRMM,
- TWO_UINT32_TO_UINT64( modType, i_memType ),
- TWO_UINT32_TO_UINT64( i_kwdData.keyword,
- i_kwdData.modSpec ) );
-
+ err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ VPD::VPD_SPD_CHECK_MODULE_SPECIFIC_KEYWORD,
+ VPD::VPD_MOD_SPECIFIC_MISMATCH_LRMM,
+ TWO_UINT32_TO_UINT64( modType, i_memType ),
+ TWO_UINT32_TO_UINT64( i_kwdData.keyword,
+ i_kwdData.modSpec ) );
break;
}
}
@@ -1286,27 +1349,25 @@ errlHndl_t checkModSpecificKeyword ( KeywordData i_kwdData,
i_memType,
modType,
i_kwdData.keyword );
-
/*@
* @errortype
* @reasoncode VPD::VPD_MOD_SPECIFIC_UNSUPPORTED
* @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
* @moduleid VPD::VPD_SPD_CHECK_MODULE_SPECIFIC_KEYWORD
- * @userdata1[0:31] Module Type (byte 3[3:0])
- * @userdata1[32:63] Memory Type (byte 2)
- * @userdata2[0:31] SPD Keyword
- * @userdata2[32:63] Module Specific flag
- * @devdesc Unsupported Module Specific setup.
+ * @userdata1 Module Type
+ * @userdata2 Memory Type (byte 2)
+ * @devdesc Unsupported Module Type.
*/
- err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- VPD::VPD_SPD_CHECK_MODULE_SPECIFIC_KEYWORD,
- VPD::VPD_MOD_SPECIFIC_UNSUPPORTED,
- TWO_UINT32_TO_UINT64( modType, i_memType ),
- TWO_UINT32_TO_UINT64( i_kwdData.keyword,
- i_kwdData.modSpec ) );
-
+ err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ VPD::VPD_SPD_CHECK_MODULE_SPECIFIC_KEYWORD,
+ VPD::VPD_MOD_SPECIFIC_UNSUPPORTED,
+ TWO_UINT32_TO_UINT64( modType, i_memType ),
+ TWO_UINT32_TO_UINT64( i_kwdData.keyword,
+ i_kwdData.modSpec ) );
break;
}
+
} while( 0 );
TRACSSCOMP( g_trac_spd,
@@ -1325,7 +1386,7 @@ errlHndl_t getMemType ( uint8_t & o_memType,
errlHndl_t err = NULL;
err = spdFetchData( MEM_TYPE_ADDR,
- MEM_TYPE_ADDR_SZ,
+ MEM_TYPE_SZ,
&o_memType,
i_target );
@@ -1337,29 +1398,131 @@ errlHndl_t getMemType ( uint8_t & o_memType,
return err;
}
+// ------------------------------------------------------------------
+// getModType
+// ------------------------------------------------------------------
+errlHndl_t getModType ( modSpecTypes_t & o_modType,
+ TARGETING::Target * i_target,
+ uint64_t i_memType )
+{
+ errlHndl_t err = NULL;
+ o_modType = NA;
+
+ uint8_t modTypeVal = 0;
+ err = spdFetchData( MOD_TYPE_ADDR,
+ MOD_TYPE_SZ,
+ &modTypeVal,
+ i_target );
+
+ if (err)
+ {
+ TRACFCOMP( g_trac_spd,
+ ERR_MRK"SPD::getModType() - Error querying ModType" );
+ }
+ else
+ {
+ modTypeVal &= MOD_TYPE_MASK;
+
+ if (SPD_DDR3 == i_memType)
+ {
+ if ((MOD_TYPE_DDR3_UDIMM == modTypeVal) ||
+ (MOD_TYPE_DDR3_SO_DIMM == modTypeVal) ||
+ (MOD_TYPE_DDR3_MICRO_DIMM == modTypeVal) ||
+ (MOD_TYPE_DDR3_MINI_UDIMM == modTypeVal) ||
+ (MOD_TYPE_DDR3_SO_UDIMM == modTypeVal))
+ {
+ o_modType = UMM;
+ }
+ else if ((MOD_TYPE_DDR3_RDIMM == modTypeVal) ||
+ (MOD_TYPE_DDR3_MINI_RDIMM == modTypeVal) ||
+ (MOD_TYPE_DDR3_SO_RDIMM == modTypeVal))
+ {
+ o_modType = RMM;
+ }
+ else if ((MOD_TYPE_DDR3_MINI_CDIMM == modTypeVal) ||
+ (MOD_TYPE_DDR3_SO_CDIMM == modTypeVal))
+ {
+ o_modType = CMM;
+ }
+ else if (MOD_TYPE_DDR3_LRDIMM == modTypeVal)
+ {
+ o_modType = LRMM;
+ }
+ }
+ else if (SPD_DDR4 == i_memType)
+ {
+ if ((MOD_TYPE_DDR4_UDIMM == modTypeVal) ||
+ (MOD_TYPE_DDR4_SO_DIMM == modTypeVal))
+ {
+ o_modType = UMM;
+ }
+ else if (MOD_TYPE_DDR4_RDIMM == modTypeVal)
+ {
+ o_modType = RMM;
+ }
+ else if (MOD_TYPE_DDR4_LRDIMM == modTypeVal)
+ {
+ o_modType = LRMM;
+ }
+ }
+
+ if (o_modType == NA)
+ {
+ TRACFCOMP( g_trac_spd,
+ ERR_MRK"Module type 0x%02x unrecognized", modTypeVal );
+
+ /*@
+ * @errortype
+ * @reasoncode VPD::VPD_MOD_SPECIFIC_UNSUPPORTED
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid VPD::VPD_SPD_GET_MOD_TYPE
+ * @userdata1 Module Type (byte 3[3:0])
+ * @userdata2 Memory Type (byte 2)
+ * @devdesc Unrecognized Module Type.
+ */
+ err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ VPD::VPD_SPD_GET_MOD_TYPE,
+ VPD::VPD_MOD_SPECIFIC_UNSUPPORTED,
+ modTypeVal, i_memType);
+ }
+ else
+ {
+ TRACUCOMP( g_trac_spd,
+ "SPD::getModType() - Val: 0x%02x, ModType: 0x%02x",
+ modTypeVal, o_modType);
+ }
+ }
+
+ return err;
+}
+
// ------------------------------------------------------------------
// getKeywordEntry
// ------------------------------------------------------------------
errlHndl_t getKeywordEntry ( uint64_t i_keyword,
uint64_t i_memType,
- KeywordData *& o_entry )
+ const KeywordData *& o_entry )
{
errlHndl_t err = NULL;
- KeywordData * kwdData;
+ const KeywordData * kwdData;
uint32_t arraySize = 0x0;
- TRACSSCOMP( g_trac_spd,
- ENTER_MRK"getKeywordEntry()" );
+ TRACSSCOMP( g_trac_spd, ENTER_MRK"getKeywordEntry()" );
do
{
- if( SPD_DDR3 == i_memType )
+ if ( SPD_DDR3 == i_memType )
{
- // Put the table into an array
arraySize = (sizeof(ddr3Data)/sizeof(ddr3Data[0]));
kwdData = ddr3Data;
}
+ else if ( SPD_DDR4 == i_memType )
+ {
+ arraySize = (sizeof(ddr4Data)/sizeof(ddr4Data[0]));
+ kwdData = ddr4Data;
+ }
else
{
TRACFCOMP( g_trac_spd,
@@ -1387,10 +1550,10 @@ errlHndl_t getKeywordEntry ( uint64_t i_keyword,
// Set the searching structure equal to the keyword we're looking for.
KeywordData tmpKwdData;
tmpKwdData.keyword = i_keyword;
- KeywordData * entry = std::lower_bound( kwdData,
- &kwdData[arraySize],
- tmpKwdData,
- compareEntries );
+ const KeywordData * entry = std::lower_bound( kwdData,
+ &kwdData[arraySize],
+ tmpKwdData,
+ compareEntries );
if( ( entry == &kwdData[arraySize] ) ||
( i_keyword != entry->keyword ) )
diff --git a/src/usr/vpd/spd.H b/src/usr/vpd/spd.H
index 267c5aa48..15bfbe481 100755
--- a/src/usr/vpd/spd.H
+++ b/src/usr/vpd/spd.H
@@ -44,15 +44,34 @@ namespace SPD
*/
enum
{
- MEM_TYPE_ADDR = 0x2, // DIMM Basic Memory Type address
- MEM_TYPE_ADDR_SZ = 0x1, // DIMM Basic Memory Type address size
+ // Memory Type address/size/constants for both DDR3 and DDR4
+ MEM_TYPE_ADDR = 0x2,
+ MEM_TYPE_SZ = 0x1,
+ SPD_DDR3 = 0xB,
+ SPD_DDR4 = 0xC,
+
+ // Module Type address/size/mask/constants for both DDR3 and DDR4
+ MOD_TYPE_ADDR = 0x03,
+ MOD_TYPE_SZ = 0x01,
+ MOD_TYPE_MASK = 0x0f,
+ MOD_TYPE_DDR3_RDIMM = 0x01,
+ MOD_TYPE_DDR3_UDIMM = 0x02,
+ MOD_TYPE_DDR3_SO_DIMM = 0x03,
+ MOD_TYPE_DDR3_MICRO_DIMM = 0x04,
+ MOD_TYPE_DDR3_MINI_RDIMM = 0x05,
+ MOD_TYPE_DDR3_MINI_UDIMM = 0x06,
+ MOD_TYPE_DDR3_MINI_CDIMM = 0x07,
+ MOD_TYPE_DDR3_SO_UDIMM = 0x08,
+ MOD_TYPE_DDR3_SO_RDIMM = 0x09,
+ MOD_TYPE_DDR3_SO_CDIMM = 0x0a,
+ MOD_TYPE_DDR3_LRDIMM = 0x0b,
+ MOD_TYPE_DDR4_RDIMM = 0x01,
+ MOD_TYPE_DDR4_UDIMM = 0x02,
+ MOD_TYPE_DDR4_SO_DIMM = 0x03,
+ MOD_TYPE_DDR4_LRDIMM = 0x04,
DIMM_SPD_SECTION_SIZE = 0x200, // Size each DIMM SPD section
DIMM_SPD_MAX_SECTIONS = 512, // Maximum number of sections
-
- // Basic Memory Type Enumerations
- SPD_DDR3 = 0xB,
- SPD_DDR4 = 0xC, // @todo - Proposed value from draft Spec. (RTC:61138)
};
/**
@@ -61,10 +80,10 @@ enum
typedef enum
{
NA = 0x00,
- UMM = 0x01,
- RMM = 0x02,
- CMM = 0x04,
- LRMM = 0x08,
+ UMM = 0x01, // Unbuffered Memory Modules
+ RMM = 0x02, // Registered Memory Modules
+ CMM = 0x04, // Clocked Memory Modules
+ LRMM = 0x08, // Load Reduction Memory Modules
ALL = 0xFFFF,
} modSpecTypes_t;
@@ -76,11 +95,10 @@ typedef enum
struct KeywordData
{
uint16_t keyword; // SPD keyword this data corresponds to
- uint8_t offset; // Byte offset in the SPD data
+ uint16_t offset; // Byte offset in the SPD data
uint8_t length; // Number of bytes to retrieve
- bool useBitMask; // Use the bitmask to mask off bits, if true, length must be
- // l byte, unless it is a "special" case
- uint8_t bitMask; // Bit mask
+ uint8_t bitMask; // Bit mask, if non-zero it is used to mask off bits.
+ // This applies to only byte0 in a non special case
uint8_t shift; // Used for fields < 1 byte to right justify all values.
bool isSpecialCase; // Whether or not this entry is a special case.
bool writable; // Whether this keyword can be written to.
@@ -258,17 +276,13 @@ errlHndl_t spdWriteValue ( uint64_t i_keyword,
* @param[in/out] io_buffer - The buffer that will contain the data
* read from the SPD data.
*
- * @param[in/out] io_buflen - The requested number of bytes to read.
- * The actual number of bytes read will be returned.
- *
* @param[in] i_target - The target DIMM to access the data for.
*
* @return errlHndl_t - NULL if successful, otherwise a pointer to the
* error log.
*/
-errlHndl_t spdSpecialCases ( KeywordData i_kwdData,
+errlHndl_t spdSpecialCases ( const KeywordData & i_kwdData,
void * io_buffer,
- size_t & io_buflen,
TARGETING::Target * i_target,
uint64_t i_DDRRev );
diff --git a/src/usr/vpd/spdDDR3.H b/src/usr/vpd/spdDDR3.H
index 76d608e5b..e7c701ca8 100644
--- a/src/usr/vpd/spdDDR3.H
+++ b/src/usr/vpd/spdDDR3.H
@@ -26,7 +26,7 @@
/**
* @file spdDDR3.H
*
- * @brief Provides the enumerations for the DDR 3 fields to read.
+ * @brief brief Provides the DDR3 field information
*
*/
@@ -42,219 +42,254 @@ namespace SPD
* @brief Pre-defined lookup table for DDR3 keywords and the
* information needed to read that data from the SPD data.
*/
-KeywordData ddr3Data[] =
+const KeywordData ddr3Data[] =
{
// ----------------------------------------------------------------------------------
- // NOTE: This list must remain an ordered list! There will be a testcase that checks
- // this. When adding new keywords to the list, be sure that the keyword in each
- // entry (value 0) are in ascending order.
+ // NOTE: This list must remain an ordered list! The Keyword must be in numerical
+ // order (values defined in spdenums.H) to allow efficient searching, a unit
+ // test enforces this.
// ----------------------------------------------------------------------------------
// Bit order for each byte is [7:0] as defined by the JEDEC spec (little endian)
//
- // Special cases listed below will be handled out of the normal table lookup
- // handler code.
- // ---------------------------------------------------------------------------------------
- // Keyword offset size Use Bitmsk Shift Spec Writ- Mod
- // Bitmsk Number Case able Spec
- // ---------------------------------------------------------------------------------------
- { CRC_EXCLUDE, 0x00, 0x01, true, 0x80, 0x07, false, false, NA },
- { SPD_BYTES_TOTAL, 0x00, 0x01, true, 0x70, 0x04, false, false, NA },
- { SPD_BYTES_USED, 0x00, 0x01, true, 0x0F, 0x00, false, false, NA },
- { SPD_MAJOR_REVISION, 0x01, 0x01, true, 0xF0, 0x04, false, false, NA },
- { SPD_MINOR_REVISION, 0x01, 0x01, true, 0x0F, 0x00, false, false, NA },
- { BASIC_MEMORY_TYPE, 0x02, 0x01, false, 0x00, 0x00, false, false, NA },
- { MODULE_TYPE, 0x03, 0x01, true, 0x0F, 0x00, false, false, NA },
- { BANK_ADDRESS_BITS, 0x04, 0x01, true, 0x70, 0x04, false, false, NA },
- { DENSITY, 0x04, 0x01, true, 0x0F, 0x00, false, false, NA },
- { ROW_ADDRESS, 0x05, 0x01, true, 0x38, 0x03, false, false, NA },
- { COL_ADDRESS, 0x05, 0x01, true, 0x07, 0x00, false, false, NA },
- { MODULE_NOMINAL_VOLTAGE, 0x06, 0x01, true, 0x07, 0x00, false, false, NA },
- { MODULE_RANKS, 0x07, 0x01, true, 0x38, 0x03, false, false, NA },
- { MODULE_DRAM_WIDTH, 0x07, 0x01, true, 0x07, 0x00, false, false, NA },
- { ECC_BITS, 0x08, 0x01, true, 0x18, 0x03, false, false, NA },
- { MODULE_MEMORY_BUS_WIDTH, 0x08, 0x01, true, 0x07, 0x00, false, false, NA },
- { FTB_DIVIDEND, 0x09, 0x01, true, 0xF0, 0x04, false, false, NA },
- { FTB_DIVISOR, 0x09, 0x01, true, 0x0F, 0x00, false, false, NA },
- { MTB_DIVIDEND, 0x0a, 0x01, false, 0x00, 0x00, false, false, NA },
- { MTB_DIVISOR, 0x0b, 0x01, false, 0x00, 0x00, false, false, NA },
- { TCK_MIN, 0x0c, 0x01, false, 0x00, 0x00, false, false, NA },
- { CAS_LATENCIES_SUPPORTED, 0x0f, 0x02, true, 0x7F, 0x00, true, false, NA },
- { MIN_CAS_LATENCY, 0x10, 0x01, false, 0x00, 0x00, false, false, NA },
- { TWR_MIN, 0x11, 0x01, false, 0x00, 0x00, false, false, NA },
- { TRCD_MIN, 0x12, 0x01, false, 0x00, 0x00, false, false, NA },
- { TRRD_MIN, 0x13, 0x01, false, 0x00, 0x00, false, false, NA },
- { TRP_MIN, 0x14, 0x01, false, 0x00, 0x00, false, false, NA },
- { TRC_MIN, 0x15, 0x02, true, 0xF0, 0x04, true, false, NA },
- { TRAS_MIN, 0x15, 0x02, true, 0x0F, 0x00, true, false, NA },
- { TRFC_MIN, 0x19, 0x02, false, 0x00, 0x00, true, false, NA },
- { TWTR_MIN, 0x1a, 0x01, false, 0x00, 0x00, false, false, NA },
- { TRTP_MIN, 0x1b, 0x01, false, 0x00, 0x00, false, false, NA },
- { TFAW_MIN, 0x1c, 0x02, true, 0x0F, 0x00, true, false, NA },
- { DLL_OFF, 0x1e, 0x01, true, 0x80, 0x07, false, false, NA },
- { RZQ_7, 0x1e, 0x01, true, 0x02, 0x01, false, false, NA },
- { RZQ_6, 0x1e, 0x01, true, 0x01, 0x00, false, false, NA },
- { PASR, 0x1f, 0x01, true, 0x80, 0x07, false, false, NA },
- { ODTS, 0x1f, 0x01, true, 0x08, 0x03, false, false, NA },
- { ASR, 0x1f, 0x01, true, 0x04, 0x02, false, false, NA },
- { ETR_1X, 0x1f, 0x01, true, 0x02, 0x01, false, false, NA },
- { ETR, 0x1f, 0x01, true, 0x01, 0x00, false, false, NA },
- { THERMAL_SENSOR_PRESENT, 0x20, 0x01, true, 0x80, 0x07, false, false, NA },
- { THERMAL_SENSOR_ACCURACY, 0x20, 0x01, true, 0x7F, 0x00, false, false, NA },
- { SDRAM_DEVICE_TYPE_NONSTD, 0x21, 0x01, true, 0x80, 0x07, false, false, NA },
- { SDRAM_DEVICE_TYPE, 0x21, 0x01, true, 0x7F, 0x00, false, false, NA },
- { MODULE_TYPE_SPECIFIC_SECTION, 0x3c, 0x39, false, 0x00, 0x00, false, false, NA },
- { MODULE_MANUFACTURER_ID, 0x76, 0x02, false, 0x00, 0x00, true, false, NA },
- { MODULE_MANUFACTURING_LOCATION, 0x77, 0x01, false, 0x00, 0x00, false, false, NA },
- { MODULE_MANUFACTURING_DATE, 0x78, 0x02, false, 0x00, 0x00, false, false, NA },
- { MODULE_SERIAL_NUMBER, 0x7a, 0x04, false, 0x00, 0x00, false, false, NA },
- { MODULE_CRC, 0x7e, 0x02, false, 0x00, 0x00, false, false, NA },
- { MODULE_PART_NUMBER, 0x80, 0x12, false, 0x00, 0x00, false, false, NA },
- { MODULE_REVISION_CODE, 0x92, 0x02, false, 0x00, 0x00, false, false, NA },
- { DRAM_MANUFACTURER_ID, 0x95, 0x02, false, 0x00, 0x00, true, false, NA },
- { MANUFACTURER_SPECIFIC_DATA, 0x96, 0x1a, false, 0x00, 0x00, false, false, NA },
- { TCKMIN_FINE_OFFSET, 0x22, 0x01, false, 0x00, 0x00, false, false, NA },
- { TAAMIN_FINE_OFFSET, 0x23, 0x01, false, 0x00, 0x00, false, false, NA },
- { TRCDMIN_FINE_OFFSET, 0x24, 0x01, false, 0x00, 0x00, false, false, NA },
- { TRPMIN_FINE_OFFSET, 0x25, 0x01, false, 0x00, 0x00, false, false, NA },
- { TRCMIN_FINE_OFFSET, 0x26, 0x01, false, 0x00, 0x00, false, false, NA },
- { MODULE_THERMAL_SENSOR, 0x20, 0x01, false, 0x00, 0x00, false, false, NA },
- { SDRAM_OPTIONAL_FEATURES, 0x1e, 0x01, false, 0x00, 0x00, false, false, NA },
- { SDRAM_THERMAL_REFRESH_OPTIONS, 0x1f, 0x01, false, 0x00, 0x00, false, false, NA },
- { DIMM_BAD_DQ_DATA, 0xb0, 0x50, false, 0x00, 0x00, false, true, NA },
- { SDRAM_DIE_COUNT, 0x21, 0x01, true, 0x70, 0x04, false, false, NA },
- { SDRAM_DEVICE_TYPE_SIGNAL_LOADING,0x21, 0x01, true, 0x03, 0x00, false, false, NA },
- { CUSTOM, 0x03, 0x01, true, 0x80, 0x07, false, false, NA },
- { MODSPEC_COM_NOM_HEIGHT_MAX, 0x3c, 0x01, true, 0x0f, 0x00, false, false, ALL },
- { MODSPEC_COM_MAX_THICK_BACK, 0x3d, 0x01, true, 0xf0, 0x04, false, false, ALL },
- { MODSPEC_COM_MAX_THICK_FRONT, 0x3d, 0x01, true, 0x0f, 0x00, false, false, ALL },
- { MODSPEC_COM_RAW_CARD_EXT, 0x3e, 0x01, true, 0x80, 0x07, false, false, ALL },
- { MODSPEC_COM_RAW_CARD_REV, 0x3e, 0x01, true, 0x60, 0x05, false, false, ALL },
- { MODSPEC_COM_RAW_CARD, 0x3e, 0x01, true, 0x0f, 0x00, false, false, ALL },
- { MODSPEC_COM_ADDR_MAPPING, 0x3f, 0x01, true, 0x01, 0x00, false, false, ALL },
- { RMM_ROWS_RDIMM, 0x3f, 0x01, true, 0x0c, 0x02, false, false, RMM },
- { RMM_REGS_RDIMM, 0x3f, 0x01, true, 0x03, 0x00, false, false, RMM },
- { RMM_HEAT_SP, 0x40, 0x01, true, 0x80, 0x07, false, false, RMM },
- { RMM_HEAT_SP_CHARS, 0x40, 0x01, true, 0x7F, 0x00, false, false, RMM },
- { RMM_MFR_ID_CODE, 0x42, 0x02, false, 0x00, 0x00, true, false, RMM },
- { RMM_REG_REV_NUM, 0x43, 0x01, false, 0x00, 0x00, false, false, RMM },
- { RMM_REG_TYPE, 0x44, 0x01, true, 0x07, 0x00, false, false, RMM },
- { RMM_RC1, 0x45, 0x01, true, 0xf0, 0x04, false, false, RMM },
- { RMM_RC0, 0x45, 0x01, true, 0x0f, 0x00, false, false, RMM },
- { RMM_RC3, 0x46, 0x01, true, 0xf0, 0x04, false, false, RMM },
- { RMM_RC2, 0x46, 0x01, true, 0x0f, 0x00, false, false, RMM },
- { RMM_RC5, 0x47, 0x01, true, 0xf0, 0x04, false, false, RMM },
- { RMM_RC4, 0x47, 0x01, true, 0x0f, 0x00, false, false, RMM },
- { RMM_RC7, 0x48, 0x01, true, 0xf0, 0x04, false, false, RMM },
- { RMM_RC6, 0x48, 0x01, true, 0x0f, 0x00, false, false, RMM },
- { RMM_RC9, 0x49, 0x01, true, 0xf0, 0x04, false, false, RMM },
- { RMM_RC8, 0x49, 0x01, true, 0x0f, 0x00, false, false, RMM },
- { RMM_RC11, 0x4a, 0x01, true, 0xf0, 0x04, false, false, RMM },
- { RMM_RC10, 0x4a, 0x01, true, 0x0f, 0x00, false, false, RMM },
- { RMM_RC13, 0x4b, 0x01, true, 0xf0, 0x04, false, false, RMM },
- { RMM_RC12, 0x4b, 0x01, true, 0x0f, 0x00, false, false, RMM },
- { RMM_RC15, 0x4c, 0x01, true, 0xf0, 0x04, false, false, RMM },
- { RMM_RC14, 0x4c, 0x01, true, 0x0f, 0x00, false, false, RMM },
- { LRMM_HEAT_SP, 0x3f, 0x01, true, 0x80, 0x07, false, false, LRMM },
- { LRMM_RANK_NUMBERING, 0x3f, 0x01, true, 0x20, 0x05, false, false, LRMM },
- { LRMM_MEMBUF_ORIEN, 0x3f, 0x01, true, 0x10, 0x04, false, false, LRMM },
- { LRMM_NUM_ROWS, 0x3f, 0x01, true, 0x0c, 0x02, false, false, LRMM },
- { LRMM_MIRRORING, 0x3f, 0x01, true, 0x03, 0x00, false, false, LRMM },
- { LRMM_REVISION_NUM, 0x40, 0x01, false, 0x00, 0x00, false, false, LRMM },
- { LRMM_MFR_ID_CODE, 0x42, 0x02, false, 0x00, 0x00, true, false, LRMM },
- { LRMM_F0RC3, 0x43, 0x01, true, 0xf0, 0x04, false, false, LRMM },
- { LRMM_F0RC2, 0x43, 0x01, true, 0x0f, 0x00, false, false, LRMM },
- { LRMM_F0RC5, 0x44, 0x01, true, 0xf0, 0x04, false, false, LRMM },
- { LRMM_F0RC4, 0x44, 0x01, true, 0x0f, 0x00, false, false, LRMM },
- { LRMM_F1RC11, 0x45, 0x01, true, 0xf0, 0x04, false, false, LRMM },
- { LRMM_F1RC8, 0x45, 0x01, true, 0x0f, 0x00, false, false, LRMM },
- { LRMM_F1RC13, 0x46, 0x01, true, 0xf0, 0x04, false, false, LRMM },
- { LRMM_F1RC12, 0x46, 0x01, true, 0x0f, 0x00, false, false, LRMM },
- { LRMM_F1RC15, 0x47, 0x01, true, 0xf0, 0x04, false, false, LRMM },
- { LRMM_F1RC14, 0x47, 0x01, true, 0x0f, 0x00, false, false, LRMM },
- { LRMM_F3RC9_800_1600, 0x48, 0x01, true, 0xf0, 0x04, false, false, LRMM },
- { LRMM_F3RC8_800_1600, 0x48, 0x01, true, 0x0f, 0x00, false, false, LRMM },
- { LRMM_F4RC11_800_1600, 0x49, 0x01, true, 0xc0, 0x06, false, false, LRMM },
- { LRMM_F3RC11_800_1600, 0x49, 0x01, true, 0x30, 0x04, false, false, LRMM },
- { LRMM_F4RC10_800_1600, 0x49, 0x01, true, 0x0c, 0x02, false, false, LRMM },
- { LRMM_F3RC10_800_1600, 0x49, 0x01, true, 0x03, 0x00, false, false, LRMM },
- { LRMM_F6RC11_800_1600, 0x4a, 0x01, true, 0xc0, 0x06, false, false, LRMM },
- { LRMM_F5RC11_800_1600, 0x4a, 0x01, true, 0x30, 0x04, false, false, LRMM },
- { LRMM_F6RC10_800_1600, 0x4a, 0x01, true, 0x0c, 0x02, false, false, LRMM },
- { LRMM_F5RC10_800_1600, 0x4a, 0x01, true, 0x03, 0x00, false, false, LRMM },
- { LRMM_F8RC11_800_1600, 0x4b, 0x01, true, 0xc0, 0x06, false, false, LRMM },
- { LRMM_F7RC11_800_1600, 0x4b, 0x01, true, 0x30, 0x04, false, false, LRMM },
- { LRMM_F8RC10_800_1600, 0x4b, 0x01, true, 0x0c, 0x02, false, false, LRMM },
- { LRMM_F7RC10_800_1600, 0x4b, 0x01, true, 0x03, 0x00, false, false, LRMM },
- { LRMM_F10RC11_800_1600, 0x4c, 0x01, true, 0xc0, 0x06, false, false, LRMM },
- { LRMM_F9RC11_800_1600, 0x4c, 0x01, true, 0x30, 0x04, false, false, LRMM },
- { LRMM_F10RC10_800_1600, 0x4c, 0x01, true, 0x0c, 0x02, false, false, LRMM },
- { LRMM_F9RC10_800_1600, 0x4c, 0x01, true, 0x03, 0x00, false, false, LRMM },
- { LRMM_RTT_WR_800_1600, 0x4d, 0x01, true, 0xc0, 0x06, false, false, LRMM },
- { LRMM_RTT_NOM_800_1600, 0x4d, 0x01, true, 0x1c, 0x02, false, false, LRMM },
- { LRMM_IMPEDANCE_800_1600, 0x4d, 0x01, true, 0x03, 0x00, false, false, LRMM },
- { LRMM_F3RC9_1333_1600, 0x4e, 0x01, true, 0xF0, 0x04, false, false, LRMM },
- { LRMM_F3RC8_1333_1600, 0x4e, 0x01, true, 0x0F, 0x00, false, false, LRMM },
- { LRMM_F4RC11_1333_1600, 0x4f, 0x01, true, 0xc0, 0x06, false, false, LRMM },
- { LRMM_F3RC11_1333_1600, 0x4f, 0x01, true, 0x30, 0x04, false, false, LRMM },
- { LRMM_F4RC10_1333_1600, 0x4f, 0x01, true, 0x0c, 0x02, false, false, LRMM },
- { LRMM_F3RC10_1333_1600, 0x4f, 0x01, true, 0x03, 0x00, false, false, LRMM },
- { LRMM_F6RC11_1333_1600, 0x50, 0x01, true, 0xc0, 0x06, false, false, LRMM },
- { LRMM_F5RC11_1333_1600, 0x50, 0x01, true, 0x30, 0x04, false, false, LRMM },
- { LRMM_F6RC10_1333_1600, 0x50, 0x01, true, 0x0c, 0x02, false, false, LRMM },
- { LRMM_F5RC10_1333_1600, 0x50, 0x01, true, 0x03, 0x00, false, false, LRMM },
- { LRMM_F8RC11_1333_1600, 0x51, 0x01, true, 0xc0, 0x06, false, false, LRMM },
- { LRMM_F7RC11_1333_1600, 0x51, 0x01, true, 0x30, 0x04, false, false, LRMM },
- { LRMM_F8RC10_1333_1600, 0x51, 0x01, true, 0x0c, 0x02, false, false, LRMM },
- { LRMM_F7RC10_1333_1600, 0x51, 0x01, true, 0x03, 0x00, false, false, LRMM },
- { LRMM_F10RC11_1333_1600, 0x52, 0x01, true, 0xc0, 0x06, false, false, LRMM },
- { LRMM_F9RC11_1333_1600, 0x52, 0x01, true, 0x30, 0x04, false, false, LRMM },
- { LRMM_F10RC10_1333_1600, 0x52, 0x01, true, 0x0c, 0x02, false, false, LRMM },
- { LRMM_F9RC10_1333_1600, 0x52, 0x01, true, 0x03, 0x00, false, false, LRMM },
- { LRMM_RTT_WR_1333_1600, 0x53, 0x01, true, 0xc0, 0x06, false, false, LRMM },
- { LRMM_RTT_NOM_1333_1600, 0x53, 0x01, true, 0x1c, 0x02, false, false, LRMM },
- { LRMM_IMPEDANCE_1333_1600, 0x53, 0x01, true, 0x03, 0x00, false, false, LRMM },
- { LRMM_F3RC9_1866_2133, 0x54, 0x01, true, 0xf0, 0x04, false, false, LRMM },
- { LRMM_F3RC8_1866_2133, 0x54, 0x01, true, 0x0f, 0x00, false, false, LRMM },
- { LRMM_F4RC11_1866_2133, 0x55, 0x01, true, 0xc0, 0x06, false, false, LRMM },
- { LRMM_F3RC11_1866_2133, 0x55, 0x01, true, 0x30, 0x04, false, false, LRMM },
- { LRMM_F4RC10_1866_2133, 0x55, 0x01, true, 0x0c, 0x02, false, false, LRMM },
- { LRMM_F3RC10_1866_2133, 0x55, 0x01, true, 0x03, 0x00, false, false, LRMM },
- { LRMM_F6RC11_1866_2133, 0x56, 0x01, true, 0xc0, 0x06, false, false, LRMM },
- { LRMM_F5RC11_1866_2133, 0x56, 0x01, true, 0x30, 0x04, false, false, LRMM },
- { LRMM_F6RC10_1866_2133, 0x56, 0x01, true, 0x0c, 0x02, false, false, LRMM },
- { LRMM_F5RC10_1866_2133, 0x56, 0x01, true, 0x03, 0x00, false, false, LRMM },
- { LRMM_F8RC11_1866_2133, 0x57, 0x01, true, 0xc0, 0x06, false, false, LRMM },
- { LRMM_F7RC11_1866_2133, 0x57, 0x01, true, 0x30, 0x04, false, false, LRMM },
- { LRMM_F8RC10_1866_2133, 0x57, 0x01, true, 0x0c, 0x02, false, false, LRMM },
- { LRMM_F7RC10_1866_2133, 0x57, 0x01, true, 0x03, 0x00, false, false, LRMM },
- { LRMM_F10RC11_1866_2133, 0x58, 0x01, true, 0xc0, 0x06, false, false, LRMM },
- { LRMM_F9RC11_1866_2133, 0x58, 0x01, true, 0x30, 0x04, false, false, LRMM },
- { LRMM_F10RC10_1866_2133, 0x58, 0x01, true, 0x0c, 0x02, false, false, LRMM },
- { LRMM_F9RC10_1866_2133, 0x58, 0x01, true, 0x03, 0x00, false, false, LRMM },
- { LRMM_RTT_WR_1866_2133, 0x59, 0x01, true, 0xc0, 0x06, false, false, LRMM },
- { LRMM_RTT_NOM_1866_2133, 0x59, 0x01, true, 0x1c, 0x02, false, false, LRMM },
- { LRMM_IMPEDANCE_1866_2133, 0x59, 0x01, true, 0x03, 0x00, false, false, LRMM },
- { LRMM_MIN_DELAY_150V, 0x5a, 0x01, true, 0x7f, 0x00, false, false, LRMM },
- { LRMM_MAX_DELAY_150V, 0x5b, 0x01, true, 0x7f, 0x00, false, false, LRMM },
- { LRMM_MIN_DELAY_135V, 0x5c, 0x01, true, 0x7f, 0x00, false, false, LRMM },
- { LRMM_MAX_DELAY_135V, 0x5d, 0x01, true, 0x7f, 0x00, false, false, LRMM },
- { LRMM_MIN_DELAY_125V, 0x5e, 0x01, true, 0x7f, 0x00, false, false, LRMM },
- { LRMM_MAX_DELAY_125V, 0x5f, 0x01, true, 0x7f, 0x00, false, false, LRMM },
- { LRMM_PERSONALITY_BYTE0, 0x66, 0x01, false, 0x00, 0x00, false, false, LRMM },
- { LRMM_PERSONALITY_BYTE1, 0x67, 0x01, false, 0x00, 0x00, false, false, LRMM },
- { LRMM_PERSONALITY_BYTE2, 0x68, 0x01, false, 0x00, 0x00, false, false, LRMM },
- { LRMM_PERSONALITY_BYTE3, 0x69, 0x01, false, 0x00, 0x00, false, false, LRMM },
- { LRMM_PERSONALITY_BYTE4, 0x6a, 0x01, false, 0x00, 0x00, false, false, LRMM },
- { LRMM_PERSONALITY_BYTE5, 0x6b, 0x01, false, 0x00, 0x00, false, false, LRMM },
- { LRMM_PERSONALITY_BYTE6, 0x6c, 0x01, false, 0x00, 0x00, false, false, LRMM },
- { LRMM_PERSONALITY_BYTE7, 0x6d, 0x01, false, 0x00, 0x00, false, false, LRMM },
- { LRMM_PERSONALITY_BYTE8, 0x6e, 0x01, false, 0x00, 0x00, false, false, LRMM },
- { LRMM_PERSONALITY_BYTE9, 0x6f, 0x01, false, 0x00, 0x00, false, false, LRMM },
- { LRMM_PERSONALITY_BYTE10, 0x70, 0x01, false, 0x00, 0x00, false, false, LRMM },
- { LRMM_PERSONALITY_BYTE11, 0x71, 0x01, false, 0x00, 0x00, false, false, LRMM },
- { LRMM_PERSONALITY_BYTE12, 0x72, 0x01, false, 0x00, 0x00, false, false, LRMM },
- { LRMM_PERSONALITY_BYTE13, 0x73, 0x01, false, 0x00, 0x00, false, false, LRMM },
- { LRMM_PERSONALITY_BYTE14, 0x74, 0x01, false, 0x00, 0x00, false, false, LRMM },
+ // For multi-byte fields, the offset specifies the byte that is placed at offset 0 in
+ // the output buffer.
+ // - If SpecialCase=false then the next byte in SPD is placed at the next offset in
+ // the output buffer until complete. Any bitmask/shift only affects the byte at
+ // offset 0
+ // - If SpecialCase=true then spd.C handles the field in a custom way (e.g. working
+ // backwards through SPD bytes).
+ // Typically for a 2-byte field consisting of (LSB,MSB), the offset points to MSB and
+ // it is a SpecialCase where spd.C first copies the MSB to the output buffer then
+ // copies the previous byte (LSB) to the output buffer (big endian).
+ // ------------------------------------------------------------------------------------------
+ // Keyword offset size Bitmsk Shift Spec Writ- Mod
+ // Number Case able Spec
+ // ------------------------------------------------------------------------------------------
+ // Normal fields supported on both DDR3 and DDR4
+ { CRC_EXCLUDE, 0x00, 0x01, 0x80, 0x07, false, false, NA },
+ { SPD_BYTES_TOTAL, 0x00, 0x01, 0x70, 0x04, false, false, NA },
+ { SPD_BYTES_USED, 0x00, 0x01, 0x0F, 0x00, false, false, NA },
+ { SPD_MAJOR_REVISION, 0x01, 0x01, 0xF0, 0x04, false, false, NA },
+ { SPD_MINOR_REVISION, 0x01, 0x01, 0x0F, 0x00, false, false, NA },
+ { BASIC_MEMORY_TYPE, 0x02, 0x01, 0x00, 0x00, false, false, NA },
+ { CUSTOM, 0x03, 0x01, 0x80, 0x07, false, false, NA },
+ { MODULE_TYPE, 0x03, 0x01, 0x0F, 0x00, false, false, NA },
+ { DENSITY, 0x04, 0x01, 0x0F, 0x00, false, false, NA },
+ { ROW_ADDRESS, 0x05, 0x01, 0x38, 0x03, false, false, NA },
+ { COL_ADDRESS, 0x05, 0x01, 0x07, 0x00, false, false, NA },
+ { MODULE_RANKS, 0x07, 0x01, 0x38, 0x03, false, false, NA },
+ { MODULE_DRAM_WIDTH, 0x07, 0x01, 0x07, 0x00, false, false, NA },
+ { MODULE_MEMORY_BUS_WIDTH, 0x08, 0x01, 0x1f, 0x00, false, false, NA },
+ { MODULE_MEMORY_BUS_WIDTH_EXT, 0x08, 0x01, 0x18, 0x03, false, false, NA },
+ { MODULE_MEMORY_BUS_WIDTH_PRI, 0x08, 0x01, 0x07, 0x00, false, false, NA },
+ { TCK_MIN, 0x0c, 0x01, 0x00, 0x00, false, false, NA },
+ { MIN_CAS_LATENCY, 0x10, 0x01, 0x00, 0x00, false, false, NA },
+ { TRCD_MIN, 0x12, 0x01, 0x00, 0x00, false, false, NA },
+ { TRP_MIN, 0x14, 0x01, 0x00, 0x00, false, false, NA },
+ { TRC_MIN, 0x15, 0x02, 0xF0, 0x04, true, false, NA },
+ { TRAS_MIN, 0x15, 0x02, 0x0F, 0x00, false, false, NA },
+ { TFAW_MIN, 0x1c, 0x02, 0x0F, 0x00, false, false, NA },
+ { SDRAM_OPTIONAL_FEATURES, 0x1e, 0x01, 0x00, 0x00, false, false, NA },
+ { SDRAM_THERMAL_REFRESH_OPTIONS, 0x1f, 0x01, 0x00, 0x00, false, false, NA },
+ { MODULE_THERMAL_SENSOR, 0x20, 0x01, 0x00, 0x00, false, false, NA },
+ { THERMAL_SENSOR_PRESENT, 0x20, 0x01, 0x80, 0x07, false, false, NA },
+ { THERMAL_SENSOR_ACCURACY, 0x20, 0x01, 0x7F, 0x00, false, false, NA },
+ { SDRAM_DEVICE_TYPE, 0x21, 0x01, 0x80, 0x07, false, false, NA },
+ { SDRAM_DIE_COUNT, 0x21, 0x01, 0x70, 0x04, false, false, NA },
+ { SDRAM_DEVICE_TYPE_SIGNAL_LOADING, 0x21, 0x01, 0x03, 0x00, false, false, NA },
+ { TCKMIN_FINE_OFFSET, 0x22, 0x01, 0x00, 0x00, false, false, NA },
+ { TAAMIN_FINE_OFFSET, 0x23, 0x01, 0x00, 0x00, false, false, NA },
+ { TRCDMIN_FINE_OFFSET, 0x24, 0x01, 0x00, 0x00, false, false, NA },
+ { TRPMIN_FINE_OFFSET, 0x25, 0x01, 0x00, 0x00, false, false, NA },
+ { TRCMIN_FINE_OFFSET, 0x26, 0x01, 0x00, 0x00, false, false, NA },
+ { MODULE_TYPE_SPECIFIC_SECTION, 0x3c, 0x39, 0x00, 0x00, false, false, NA },
+ { MODULE_MANUFACTURER_ID, 0x76, 0x02, 0x00, 0x00, true, false, NA },
+ { MODULE_MANUFACTURING_LOCATION, 0x77, 0x01, 0x00, 0x00, false, false, NA },
+ { MODULE_MANUFACTURING_DATE, 0x78, 0x02, 0x00, 0x00, false, false, NA },
+ { MODULE_SERIAL_NUMBER, 0x7a, 0x04, 0x00, 0x00, false, false, NA },
+ { MODULE_PART_NUMBER, 0x80, 0x12, 0x00, 0x00, false, false, NA },
+ { MODULE_REVISION_CODE, 0x92, 0x02, 0x00, 0x00, true, false, NA },
+ { DRAM_MANUFACTURER_ID, 0x95, 0x02, 0x00, 0x00, true, false, NA },
+ { MANUFACTURER_SPECIFIC_DATA, 0x96, 0x1a, 0x00, 0x00, false, false, NA },
+ { DIMM_BAD_DQ_DATA, 0xb0, 0x50, 0x00, 0x00, false, true, NA },
+ // Normal fields supported on DDR3 only
+ { BANK_ADDRESS_BITS, 0x04, 0x01, 0x70, 0x04, false, false, NA },
+ { MODULE_NOMINAL_VOLTAGE, 0x06, 0x01, 0x07, 0x00, false, false, NA },
+ { FTB_DIVIDEND, 0x09, 0x01, 0xF0, 0x04, false, false, NA },
+ { FTB_DIVISOR, 0x09, 0x01, 0x0F, 0x00, false, false, NA },
+ { MTB_DIVIDEND, 0x0a, 0x01, 0x00, 0x00, false, false, NA },
+ { MTB_DIVISOR, 0x0b, 0x01, 0x00, 0x00, false, false, NA },
+ { CAS_LATENCIES_SUPPORTED, 0x0f, 0x02, 0x7F, 0x00, true, false, NA },
+ { TWR_MIN, 0x11, 0x01, 0x00, 0x00, false, false, NA },
+ { TRRD_MIN, 0x13, 0x01, 0x00, 0x00, false, false, NA },
+ { TRFC_MIN, 0x19, 0x02, 0x00, 0x00, true, false, NA },
+ { TWTR_MIN, 0x1a, 0x01, 0x00, 0x00, false, false, NA },
+ { TRTP_MIN, 0x1b, 0x01, 0x00, 0x00, false, false, NA },
+ { DLL_OFF, 0x1e, 0x01, 0x80, 0x07, false, false, NA },
+ { RZQ_7, 0x1e, 0x01, 0x02, 0x01, false, false, NA },
+ { RZQ_6, 0x1e, 0x01, 0x01, 0x00, false, false, NA },
+ { PASR, 0x1f, 0x01, 0x80, 0x07, false, false, NA },
+ { ODTS, 0x1f, 0x01, 0x08, 0x03, false, false, NA },
+ { ASR, 0x1f, 0x01, 0x04, 0x02, false, false, NA },
+ { ETR_1X, 0x1f, 0x01, 0x02, 0x01, false, false, NA },
+ { ETR, 0x1f, 0x01, 0x01, 0x00, false, false, NA },
+ { MODULE_CRC, 0x7e, 0x02, 0x00, 0x00, true, false, NA },
+ // Module Specific fields supported on both DDR3 and DDR4
+ { MODSPEC_COM_NOM_HEIGHT_MAX, 0x3c, 0x01, 0x1f, 0x00, false, false, ALL },
+ { MODSPEC_COM_MAX_THICK_BACK, 0x3d, 0x01, 0xf0, 0x04, false, false, ALL },
+ { MODSPEC_COM_MAX_THICK_FRONT, 0x3d, 0x01, 0x0f, 0x00, false, false, ALL },
+ { MODSPEC_COM_REF_RAW_CARD_EXT, 0x3e, 0x01, 0x80, 0x07, false, false, ALL },
+ { MODSPEC_COM_REF_RAW_CARD_REV, 0x3e, 0x01, 0x60, 0x05, false, false, ALL },
+ { MODSPEC_COM_REF_RAW_CARD, 0x3e, 0x01, 0x1f, 0x00, false, false, ALL },
+ { UMM_ADDR_MAPPING, 0x3f, 0x01, 0x01, 0x00, false, false, UMM },
+ { RMM_ROWS_RDIMM, 0x3f, 0x01, 0x0c, 0x02, false, false, RMM },
+ { RMM_REGS_RDIMM, 0x3f, 0x01, 0x03, 0x00, false, false, RMM },
+ { RMM_HEAT_SP, 0x40, 0x01, 0x80, 0x07, false, false, RMM },
+ { RMM_HEAT_SP_CHARS, 0x40, 0x01, 0x7F, 0x00, false, false, RMM },
+ { RMM_MFR_ID_CODE, 0x42, 0x02, 0x00, 0x00, true, false, RMM },
+ { RMM_REG_REV_NUM, 0x43, 0x01, 0x00, 0x00, false, false, RMM },
+ { LRMM_HEAT_SP, 0x3f, 0x01, 0x80, 0x07, false, false, LRMM },
+ { LRMM_NUM_ROWS, 0x3f, 0x01, 0x0c, 0x02, false, false, LRMM },
+ { LRMM_MIRRORING, 0x3f, 0x01, 0x03, 0x00, false, false, LRMM },
+ { LRMM_REVISION_NUM, 0x40, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_MFR_ID_CODE, 0x42, 0x02, 0x00, 0x00, true, false, LRMM },
+ // Module Specific fields supported on DDR3 only
+ { RMM_REG_TYPE, 0x44, 0x01, 0x07, 0x00, false, false, RMM },
+ { RMM_RC1, 0x45, 0x01, 0xf0, 0x04, false, false, RMM },
+ { RMM_RC0, 0x45, 0x01, 0x0f, 0x00, false, false, RMM },
+ { RMM_RC3, 0x46, 0x01, 0xf0, 0x04, false, false, RMM },
+ { RMM_RC2, 0x46, 0x01, 0x0f, 0x00, false, false, RMM },
+ { RMM_RC5, 0x47, 0x01, 0xf0, 0x04, false, false, RMM },
+ { RMM_RC4, 0x47, 0x01, 0x0f, 0x00, false, false, RMM },
+ { RMM_RC7, 0x48, 0x01, 0xf0, 0x04, false, false, RMM },
+ { RMM_RC6, 0x48, 0x01, 0x0f, 0x00, false, false, RMM },
+ { RMM_RC9, 0x49, 0x01, 0xf0, 0x04, false, false, RMM },
+ { RMM_RC8, 0x49, 0x01, 0x0f, 0x00, false, false, RMM },
+ { RMM_RC11, 0x4a, 0x01, 0xf0, 0x04, false, false, RMM },
+ { RMM_RC10, 0x4a, 0x01, 0x0f, 0x00, false, false, RMM },
+ { RMM_RC13, 0x4b, 0x01, 0xf0, 0x04, false, false, RMM },
+ { RMM_RC12, 0x4b, 0x01, 0x0f, 0x00, false, false, RMM },
+ { RMM_RC15, 0x4c, 0x01, 0xf0, 0x04, false, false, RMM },
+ { RMM_RC14, 0x4c, 0x01, 0x0f, 0x00, false, false, RMM },
+ { LRMM_RANK_NUMBERING, 0x3f, 0x01, 0x20, 0x05, false, false, LRMM },
+ { LRMM_MEMBUF_ORIEN, 0x3f, 0x01, 0x10, 0x04, false, false, LRMM },
+ { LRMM_F0RC3_FORC2, 0x43, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_F0RC3, 0x43, 0x01, 0xf0, 0x04, false, false, LRMM },
+ { LRMM_F0RC2, 0x43, 0x01, 0x0f, 0x00, false, false, LRMM },
+ { LRMM_F0RC5_FORC4, 0x44, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_F0RC5, 0x44, 0x01, 0xf0, 0x04, false, false, LRMM },
+ { LRMM_F0RC4, 0x44, 0x01, 0x0f, 0x00, false, false, LRMM },
+ { LRMM_F1RC11_F1RC8, 0x45, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_F1RC11, 0x45, 0x01, 0xf0, 0x04, false, false, LRMM },
+ { LRMM_F1RC8, 0x45, 0x01, 0x0f, 0x00, false, false, LRMM },
+ { LRMM_F1RC13_F1RC12, 0x46, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_F1RC13, 0x46, 0x01, 0xf0, 0x04, false, false, LRMM },
+ { LRMM_F1RC12, 0x46, 0x01, 0x0f, 0x00, false, false, LRMM },
+ { LRMM_F1RC15_F1RC14, 0x47, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_F1RC15, 0x47, 0x01, 0xf0, 0x04, false, false, LRMM },
+ { LRMM_F1RC14, 0x47, 0x01, 0x0f, 0x00, false, false, LRMM },
+ { LRMM_F3RC9_F3RC8_800_1066, 0x48, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_F3RC9_800_1600, 0x48, 0x01, 0xf0, 0x04, false, false, LRMM },
+ { LRMM_F3RC8_800_1600, 0x48, 0x01, 0x0f, 0x00, false, false, LRMM },
+ { LRMM_F34RC11_F34RC10_800_1066, 0x49, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_F4RC11_800_1600, 0x49, 0x01, 0xc0, 0x06, false, false, LRMM },
+ { LRMM_F3RC11_800_1600, 0x49, 0x01, 0x30, 0x04, false, false, LRMM },
+ { LRMM_F4RC10_800_1600, 0x49, 0x01, 0x0c, 0x02, false, false, LRMM },
+ { LRMM_F3RC10_800_1600, 0x49, 0x01, 0x03, 0x00, false, false, LRMM },
+ { LRMM_F56RC11_F56RC10_800_1066, 0x4a, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_F6RC11_800_1600, 0x4a, 0x01, 0xc0, 0x06, false, false, LRMM },
+ { LRMM_F5RC11_800_1600, 0x4a, 0x01, 0x30, 0x04, false, false, LRMM },
+ { LRMM_F6RC10_800_1600, 0x4a, 0x01, 0x0c, 0x02, false, false, LRMM },
+ { LRMM_F5RC10_800_1600, 0x4a, 0x01, 0x03, 0x00, false, false, LRMM },
+ { LRMM_F78RC11_F78RC10_800_1066, 0x4b, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_F8RC11_800_1600, 0x4b, 0x01, 0xc0, 0x06, false, false, LRMM },
+ { LRMM_F7RC11_800_1600, 0x4b, 0x01, 0x30, 0x04, false, false, LRMM },
+ { LRMM_F8RC10_800_1600, 0x4b, 0x01, 0x0c, 0x02, false, false, LRMM },
+ { LRMM_F7RC10_800_1600, 0x4b, 0x01, 0x03, 0x00, false, false, LRMM },
+ { LRMM_F910RC11_F910RC10_800_1066, 0x4c, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_F10RC11_800_1600, 0x4c, 0x01, 0xc0, 0x06, false, false, LRMM },
+ { LRMM_F9RC11_800_1600, 0x4c, 0x01, 0x30, 0x04, false, false, LRMM },
+ { LRMM_F10RC10_800_1600, 0x4c, 0x01, 0x0c, 0x02, false, false, LRMM },
+ { LRMM_F9RC10_800_1600, 0x4c, 0x01, 0x03, 0x00, false, false, LRMM },
+ { LRMM_MR12_800_1066, 0x4d, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_RTT_WR_800_1600, 0x4d, 0x01, 0xc0, 0x06, false, false, LRMM },
+ { LRMM_RTT_NOM_800_1600, 0x4d, 0x01, 0x1c, 0x02, false, false, LRMM },
+ { LRMM_IMPEDANCE_800_1600, 0x4d, 0x01, 0x03, 0x00, false, false, LRMM },
+ { LRMM_F3RC9_F3RC8_1333_1600, 0x4e, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_F3RC9_1333_1600, 0x4e, 0x01, 0xF0, 0x04, false, false, LRMM },
+ { LRMM_F3RC8_1333_1600, 0x4e, 0x01, 0x0F, 0x00, false, false, LRMM },
+ { LRMM_F34RC11_F34RC10_1333_1600, 0x4f, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_F4RC11_1333_1600, 0x4f, 0x01, 0xc0, 0x06, false, false, LRMM },
+ { LRMM_F3RC11_1333_1600, 0x4f, 0x01, 0x30, 0x04, false, false, LRMM },
+ { LRMM_F4RC10_1333_1600, 0x4f, 0x01, 0x0c, 0x02, false, false, LRMM },
+ { LRMM_F3RC10_1333_1600, 0x4f, 0x01, 0x03, 0x00, false, false, LRMM },
+ { LRMM_F56RC11_F56RC10_1333_1600, 0x50, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_F6RC11_1333_1600, 0x50, 0x01, 0xc0, 0x06, false, false, LRMM },
+ { LRMM_F5RC11_1333_1600, 0x50, 0x01, 0x30, 0x04, false, false, LRMM },
+ { LRMM_F6RC10_1333_1600, 0x50, 0x01, 0x0c, 0x02, false, false, LRMM },
+ { LRMM_F5RC10_1333_1600, 0x50, 0x01, 0x03, 0x00, false, false, LRMM },
+ { LRMM_F78RC11_F78RC10_1333_1600, 0x51, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_F8RC11_1333_1600, 0x51, 0x01, 0xc0, 0x06, false, false, LRMM },
+ { LRMM_F7RC11_1333_1600, 0x51, 0x01, 0x30, 0x04, false, false, LRMM },
+ { LRMM_F8RC10_1333_1600, 0x51, 0x01, 0x0c, 0x02, false, false, LRMM },
+ { LRMM_F7RC10_1333_1600, 0x51, 0x01, 0x03, 0x00, false, false, LRMM },
+ { LRMM_F910RC11_F910RC10_1333_1600, 0x52, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_F10RC11_1333_1600, 0x52, 0x01, 0xc0, 0x06, false, false, LRMM },
+ { LRMM_F9RC11_1333_1600, 0x52, 0x01, 0x30, 0x04, false, false, LRMM },
+ { LRMM_F10RC10_1333_1600, 0x52, 0x01, 0x0c, 0x02, false, false, LRMM },
+ { LRMM_F9RC10_1333_1600, 0x52, 0x01, 0x03, 0x00, false, false, LRMM },
+ { LRMM_MR12_1333_1600, 0x53, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_RTT_WR_1333_1600, 0x53, 0x01, 0xc0, 0x06, false, false, LRMM },
+ { LRMM_RTT_NOM_1333_1600, 0x53, 0x01, 0x1c, 0x02, false, false, LRMM },
+ { LRMM_IMPEDANCE_1333_1600, 0x53, 0x01, 0x03, 0x00, false, false, LRMM },
+ { LRMM_F3RC9_F3RC8_1866_2133, 0x54, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_F3RC9_1866_2133, 0x54, 0x01, 0xf0, 0x04, false, false, LRMM },
+ { LRMM_F3RC8_1866_2133, 0x54, 0x01, 0x0f, 0x00, false, false, LRMM },
+ { LRMM_F34RC11_F34RC10_1866_2133, 0x55, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_F4RC11_1866_2133, 0x55, 0x01, 0xc0, 0x06, false, false, LRMM },
+ { LRMM_F3RC11_1866_2133, 0x55, 0x01, 0x30, 0x04, false, false, LRMM },
+ { LRMM_F4RC10_1866_2133, 0x55, 0x01, 0x0c, 0x02, false, false, LRMM },
+ { LRMM_F3RC10_1866_2133, 0x55, 0x01, 0x03, 0x00, false, false, LRMM },
+ { LRMM_F56RC11_F56RC10_1866_2133, 0x56, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_F6RC11_1866_2133, 0x56, 0x01, 0xc0, 0x06, false, false, LRMM },
+ { LRMM_F5RC11_1866_2133, 0x56, 0x01, 0x30, 0x04, false, false, LRMM },
+ { LRMM_F6RC10_1866_2133, 0x56, 0x01, 0x0c, 0x02, false, false, LRMM },
+ { LRMM_F5RC10_1866_2133, 0x56, 0x01, 0x03, 0x00, false, false, LRMM },
+ { LRMM_F78RC11_F78RC10_1866_2133, 0x57, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_F8RC11_1866_2133, 0x57, 0x01, 0xc0, 0x06, false, false, LRMM },
+ { LRMM_F7RC11_1866_2133, 0x57, 0x01, 0x30, 0x04, false, false, LRMM },
+ { LRMM_F8RC10_1866_2133, 0x57, 0x01, 0x0c, 0x02, false, false, LRMM },
+ { LRMM_F7RC10_1866_2133, 0x57, 0x01, 0x03, 0x00, false, false, LRMM },
+ { LRMM_F910RC11_F910RC10_1866_2133, 0x58, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_F10RC11_1866_2133, 0x58, 0x01, 0xc0, 0x06, false, false, LRMM },
+ { LRMM_F9RC11_1866_2133, 0x58, 0x01, 0x30, 0x04, false, false, LRMM },
+ { LRMM_F10RC10_1866_2133, 0x58, 0x01, 0x0c, 0x02, false, false, LRMM },
+ { LRMM_F9RC10_1866_2133, 0x58, 0x01, 0x03, 0x00, false, false, LRMM },
+ { LRMM_MR12_FOR_1866_2133, 0x59, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_RTT_WR_1866_2133, 0x59, 0x01, 0xc0, 0x06, false, false, LRMM },
+ { LRMM_RTT_NOM_1866_2133, 0x59, 0x01, 0x1c, 0x02, false, false, LRMM },
+ { LRMM_IMPEDANCE_1866_2133, 0x59, 0x01, 0x03, 0x00, false, false, LRMM },
+ { LRMM_MIN_DELAY_150V, 0x5a, 0x01, 0x7f, 0x00, false, false, LRMM },
+ { LRMM_MAX_DELAY_150V, 0x5b, 0x01, 0x7f, 0x00, false, false, LRMM },
+ { LRMM_MIN_DELAY_135V, 0x5c, 0x01, 0x7f, 0x00, false, false, LRMM },
+ { LRMM_MAX_DELAY_135V, 0x5d, 0x01, 0x7f, 0x00, false, false, LRMM },
+ { LRMM_MIN_DELAY_125V, 0x5e, 0x01, 0x7f, 0x00, false, false, LRMM },
+ { LRMM_MAX_DELAY_125V, 0x5f, 0x01, 0x7f, 0x00, false, false, LRMM },
+ { LRMM_PERSONALITY_BYTE0, 0x66, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_PERSONALITY_BYTE1, 0x67, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_PERSONALITY_BYTE2, 0x68, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_PERSONALITY_BYTE3, 0x69, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_PERSONALITY_BYTE4, 0x6a, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_PERSONALITY_BYTE5, 0x6b, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_PERSONALITY_BYTE6, 0x6c, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_PERSONALITY_BYTE7, 0x6d, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_PERSONALITY_BYTE8, 0x6e, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_PERSONALITY_BYTE9, 0x6f, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_PERSONALITY_BYTE10, 0x70, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_PERSONALITY_BYTE11, 0x71, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_PERSONALITY_BYTE12, 0x72, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_PERSONALITY_BYTE13, 0x73, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_PERSONALITY_BYTE14, 0x74, 0x01, 0x00, 0x00, false, false, LRMM },
//---------------------------------------------------------------------------------------
};
diff --git a/src/usr/vpd/spdDDR4.H b/src/usr/vpd/spdDDR4.H
new file mode 100644
index 000000000..7f165d85a
--- /dev/null
+++ b/src/usr/vpd/spdDDR4.H
@@ -0,0 +1,168 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/vpd/spdDDR4.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2013 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __SPDDDR4_H
+#define __SPDDDR4_H
+
+/**
+ * @file spdDDR4.H
+ *
+ * @brief Provides the DDR4 field information
+ *
+ */
+
+// ----------------------------------------------
+// Includes
+// ----------------------------------------------
+#include "spd.H"
+
+namespace SPD
+{
+
+/**
+ * @brief Pre-defined lookup table for DDR4 keywords and the
+ * information needed to read that data from the SPD data.
+ */
+const KeywordData ddr4Data[] =
+{
+ // ----------------------------------------------------------------------------------
+ // NOTE: This list must remain an ordered list! The Keyword must be in numerical
+ // order (values defined in spdenums.H) to allow efficient searching, a unit
+ // test enforces this.
+ // ----------------------------------------------------------------------------------
+ // Bit order for each byte is [7:0] as defined by the JEDEC spec (little endian)
+ //
+ // For multi-byte fields, the offset specifies the byte that is placed at offset 0 in
+ // the output buffer.
+ // - If SpecialCase=false then the next byte in SPD is placed at the next offset in
+ // the output buffer until complete. Any bitmask/shift only affects the byte at
+ // offset 0
+ // - If SpecialCase=true then spd.C handles the field in a custom way (e.g. working
+ // backwards through SPD bytes).
+ // Typically for a 2-byte field consisting of (LSB,MSB), the offset points to MSB and
+ // it is a SpecialCase where spd.C first copies the MSB to the output buffer then
+ // copies the previous byte (LSB) to the output buffer (big endian).
+ // ------------------------------------------------------------------------------------------
+ // Keyword offset size Bitmsk Shift Spec Writ- Mod
+ // Number Case able Spec
+ // ------------------------------------------------------------------------------------------
+ // Normal fields supported on both DDR3 and DDR4
+ { CRC_EXCLUDE, 0x00, 0x01, 0x80, 0x07, false, false, NA },
+ { SPD_BYTES_TOTAL, 0x00, 0x01, 0x70, 0x04, false, false, NA },
+ { SPD_BYTES_USED, 0x00, 0x01, 0x0F, 0x00, false, false, NA },
+ { SPD_MAJOR_REVISION, 0x01, 0x01, 0xF0, 0x04, false, false, NA },
+ { SPD_MINOR_REVISION, 0x01, 0x01, 0x0F, 0x00, false, false, NA },
+ { BASIC_MEMORY_TYPE, 0x02, 0x01, 0x00, 0x00, false, false, NA },
+ { CUSTOM, 0x03, 0x01, 0x80, 0x07, false, false, NA },
+ { MODULE_TYPE, 0x03, 0x01, 0x0F, 0x00, false, false, NA },
+ { DENSITY, 0x04, 0x01, 0x0F, 0x00, false, false, NA },
+ { ROW_ADDRESS, 0x05, 0x01, 0x38, 0x03, false, false, NA },
+ { COL_ADDRESS, 0x05, 0x01, 0x07, 0x00, false, false, NA },
+ { MODULE_RANKS, 0x0c, 0x01, 0x38, 0x03, false, false, NA },
+ { MODULE_DRAM_WIDTH, 0x0c, 0x01, 0x07, 0x00, false, false, NA },
+ { MODULE_MEMORY_BUS_WIDTH, 0x0d, 0x01, 0x1f, 0x00, false, false, NA },
+ { MODULE_MEMORY_BUS_WIDTH_EXT, 0x0d, 0x01, 0x18, 0x03, false, false, NA },
+ { MODULE_MEMORY_BUS_WIDTH_PRI, 0x0d, 0x01, 0x07, 0x00, false, false, NA },
+ { TCK_MIN, 0x12, 0x01, 0x00, 0x00, false, false, NA },
+ { MIN_CAS_LATENCY, 0x18, 0x01, 0x00, 0x00, false, false, NA },
+ { TRCD_MIN, 0x19, 0x01, 0x00, 0x00, false, false, NA },
+ { TRP_MIN, 0x1a, 0x01, 0x00, 0x00, false, false, NA },
+ { TRC_MIN, 0x1b, 0x02, 0xF0, 0x04, true, false, NA },
+ { TRAS_MIN, 0x1b, 0x02, 0x0F, 0x00, false, false, NA },
+ { TFAW_MIN, 0x24, 0x02, 0x0F, 0x00, false, false, NA },
+ { SDRAM_OPTIONAL_FEATURES, 0x07, 0x01, 0x00, 0x00, false, false, NA },
+ { SDRAM_THERMAL_REFRESH_OPTIONS, 0x08, 0x01, 0x00, 0x00, false, false, NA },
+ { MODULE_THERMAL_SENSOR, 0x0e, 0x01, 0x00, 0x00, false, false, NA },
+ { THERMAL_SENSOR_PRESENT, 0x0e, 0x01, 0x80, 0x07, false, false, NA },
+ { THERMAL_SENSOR_ACCURACY, 0x0e, 0x01, 0x7F, 0x00, false, false, NA },
+ { SDRAM_DEVICE_TYPE , 0x06, 0x01, 0x80, 0x07, false, false, NA },
+ { SDRAM_DIE_COUNT, 0x06, 0x01, 0x70, 0x04, false, false, NA },
+ { SDRAM_DEVICE_TYPE_SIGNAL_LOADING, 0x06, 0x01, 0x03, 0x00, false, false, NA },
+ { TCKMIN_FINE_OFFSET, 0x7d, 0x01, 0x00, 0x00, false, false, NA },
+ { TAAMIN_FINE_OFFSET, 0x7b, 0x01, 0x00, 0x00, false, false, NA },
+ { TRCDMIN_FINE_OFFSET, 0x7a, 0x01, 0x00, 0x00, false, false, NA },
+ { TRPMIN_FINE_OFFSET, 0x79, 0x01, 0x00, 0x00, false, false, NA },
+ { TRCMIN_FINE_OFFSET, 0x78, 0x01, 0x00, 0x00, false, false, NA },
+ { MODULE_TYPE_SPECIFIC_SECTION, 0x80, 0x80, 0x00, 0x00, false, false, NA },
+ { MODULE_MANUFACTURER_ID, 0x141, 0x02, 0x00, 0x00, true, false, NA },
+ { MODULE_MANUFACTURING_LOCATION, 0x142, 0x01, 0x00, 0x00, false, false, NA },
+ { MODULE_MANUFACTURING_DATE, 0x143, 0x02, 0x00, 0x00, false, false, NA },
+ { MODULE_SERIAL_NUMBER, 0x145, 0x04, 0x00, 0x00, false, false, NA },
+ { MODULE_PART_NUMBER, 0x149, 0x14, 0x00, 0x00, false, false, NA },
+ { MODULE_REVISION_CODE, 0x15d, 0x01, 0x00, 0x00, true, false, NA },
+ { DRAM_MANUFACTURER_ID, 0x15f, 0x02, 0x00, 0x00, true, false, NA },
+ { MANUFACTURER_SPECIFIC_DATA, 0x161, 0x1d, 0x00, 0x00, false, false, NA },
+ { DIMM_BAD_DQ_DATA, 0x180, 0x50, 0x00, 0x00, false, true, NA },
+ // Normal fields supported on DDR4 only
+ { BANK_GROUP_BITS, 0x04, 0x01, 0xC0, 0x06, false, false, NA },
+ { BANK_ADDRESS_BITS_DDR4, 0x04, 0x01, 0x30, 0x04, false, false, NA },
+ { MODULE_NOMINAL_VOLTAGE_DDR4, 0x0b, 0x01, 0x3F, 0x00, false, false, NA },
+ { TIMEBASES_MTB , 0x11, 0x01, 0x0C, 0x02, false, false, NA },
+ { TIMEBASES_FTB, 0x11, 0x01, 0x03, 0x00, false, false, NA },
+ { TCK_MAX, 0x13, 0x01, 0x00, 0x00, false, false, NA },
+ { CAS_LATENCIES_SUPPORTED_DDR4, 0x17, 0x04, 0x00, 0x00, true, false, NA },
+ { TRFC1_MIN, 0x1f, 0x02, 0x00, 0x00, true, false, NA },
+ { TRFC2_MIN, 0x21, 0x02, 0x00, 0x00, true, false, NA },
+ { TRFC4_MIN, 0x23, 0x02, 0x00, 0x00, true, false, NA },
+ { TRRDS_MIN, 0x26, 0x01, 0x00, 0x00, false, false, NA },
+ { TRRDL_MIN, 0x27, 0x01, 0x00, 0x00, false, false, NA },
+ { TCCDL_MIN, 0x28, 0x01, 0x00, 0x00, false, false, NA },
+ { CONNECTOR_SDRAM_MAP, 0x3C, 0x12, 0x00, 0x00, false, false, NA },
+ { TCCDL_FINE_OFFSET, 0x75, 0x01, 0x00, 0x00, false, false, NA },
+ { TRRDL_FINE_OFFSET, 0x76, 0x01, 0x00, 0x00, false, false, NA },
+ { TRRDS_FINE_OFFSET, 0x77, 0x01, 0x00, 0x00, false, false, NA },
+ { TCKMAX_FINE_OFFSET, 0x7c, 0x01, 0x00, 0x00, false, false, NA },
+ { BASE_CONFIG_CRC, 0x7f, 0x02, 0x00, 0x00, true, false, NA },
+ { DRAM_STEPPING, 0x160, 0x01, 0x00, 0x00, false, false, NA },
+ { MANUFACTURING_SECTION_CRC, 0x17f, 0x02, 0x00, 0x00, true, false, NA },
+ // Module Specific fields supported on both DDR3 and DDR4
+ { MODSPEC_COM_NOM_HEIGHT_MAX, 0x80, 0x01, 0x1f, 0x00, false, false, ALL },
+ { MODSPEC_COM_MAX_THICK_BACK, 0x81, 0x01, 0xf0, 0x04, false, false, ALL },
+ { MODSPEC_COM_MAX_THICK_FRONT, 0x81, 0x01, 0x0f, 0x00, false, false, ALL },
+ { MODSPEC_COM_REF_RAW_CARD_EXT, 0x82, 0x01, 0x80, 0x07, false, false, ALL },
+ { MODSPEC_COM_REF_RAW_CARD_REV, 0x82, 0x01, 0x60, 0x05, false, false, ALL },
+ { MODSPEC_COM_REF_RAW_CARD, 0x82, 0x01, 0x1f, 0x00, false, false, ALL },
+ { UMM_ADDR_MAPPING, 0x83, 0x01, 0x01, 0x00, false, false, UMM },
+ { RMM_ROWS_RDIMM, 0x83, 0x01, 0x0c, 0x02, false, false, RMM },
+ { RMM_REGS_RDIMM, 0x83, 0x01, 0x03, 0x00, false, false, RMM },
+ { RMM_HEAT_SP, 0x84, 0x01, 0x80, 0x07, false, false, RMM },
+ { RMM_HEAT_SP_CHARS, 0x84, 0x01, 0x7F, 0x00, false, false, RMM },
+ { RMM_MFR_ID_CODE, 0x86, 0x02, 0x00, 0x00, true, false, RMM },
+ { RMM_REG_REV_NUM, 0x87, 0x01, 0x00, 0x00, false, false, RMM },
+ { LRMM_HEAT_SP, 0x83, 0x01, 0x80, 0x07, false, false, LRMM },
+ { LRMM_NUM_ROWS, 0x83, 0x01, 0x0c, 0x02, false, false, LRMM },
+ { LRMM_MIRRORING, 0x83, 0x01, 0x03, 0x00, false, false, LRMM },
+ { LRMM_REVISION_NUM, 0x84, 0x01, 0x00, 0x00, false, false, LRMM },
+ { LRMM_MFR_ID_CODE, 0x86, 0x02, 0x00, 0x00, true, false, LRMM },
+ // Module Specific fields supported on DDR4 only
+ { MODSPEC_COM_RAW_CARD_EXT, 0x80, 0x01, 0xe0, 0x05, false, false, ALL },
+ { UMM_CRC, 0xff, 0x02, 0x00, 0x00, true, false, UMM },
+ { RMM_ADDR_MAPPING, 0x88, 0x01, 0x01, 0x00, false, false, RMM },
+ { RMM_CRC, 0xff, 0x02, 0x00, 0x00, true, false, RMM },
+ { LRMM_CRC, 0xff, 0x02, 0x00, 0x00, true, false, LRMM },
+ //---------------------------------------------------------------------------------------
+};
+
+
+}; // end SPD namespace
+
+#endif // __SPDDDR4_H
diff --git a/src/usr/vpd/test/spdtest.H b/src/usr/vpd/test/spdtest.H
index 5ef8a6107..d2c28d2e1 100755
--- a/src/usr/vpd/test/spdtest.H
+++ b/src/usr/vpd/test/spdtest.H
@@ -40,6 +40,7 @@
#include <vpd/vpdreasoncodes.H>
#include <vpd/spdenums.H>
#include "../spdDDR3.H"
+#include "../spdDDR4.H"
#include "../spd.H"
extern trace_desc_t* g_trac_spd;
@@ -125,7 +126,7 @@ class SPDTest: public CxxTest::TestSuite
}
for( uint64_t keyword = SPD::SPD_FIRST_NORM_KEYWORD;
- keyword < SPD::SPD_LAST_NORM_KEYWORD; keyword++ )
+ keyword <= SPD::SPD_LAST_NORM_KEYWORD; keyword++ )
{
cmds++;
if( NULL != theData )
@@ -149,19 +150,25 @@ class SPDTest: public CxxTest::TestSuite
}
}
}
- else
+ else if( SPD_DDR4 == memType )
{
- // Nothing else supported yet!
- // Not really a fail, just not supported
- cmds--;
- continue;
+ for( entry = 0;
+ entry < (sizeof(ddr4Data)/sizeof(ddr4Data[0]));
+ entry++ )
+ {
+ if( keyword == ddr4Data[entry].keyword )
+ {
+ theSize = ddr4Data[entry].length;
+ break;
+ }
+ }
}
- if( 0x0 == theSize )
+ if( 0 == theSize )
{
- fails++;
- TS_FAIL( "testSpdRead - Keyword (0x%04x) size = 0x0",
- entry );
+ // memType not supported or Keyword not supported on
+ // this memType
+ cmds--;
continue;
}
@@ -183,10 +190,36 @@ class SPDTest: public CxxTest::TestSuite
continue;
}
- // Read was successful, print out first byte of data read
- TRACFCOMP( g_trac_spd,
- "testSpdRead - kwd: 0x%04x, val: %02x, size: %d",
- keyword, theData[0], theSize );
+ // Read was successful, print out the data read
+ if (theSize == 1)
+ {
+ TRACFCOMP( g_trac_spd,
+ "testSpdRead - kwd: 0x%04x, val: 0x%02x, size: 1",
+ keyword, theData[0] );
+ }
+ else if (theSize == 2)
+ {
+ TRACFCOMP( g_trac_spd,
+ "testSpdRead - kwd: 0x%04x, val: 0x%04x, size: 2",
+ keyword,
+ reinterpret_cast<uint16_t *>(theData)[0] );
+ }
+ else if (theSize == 3)
+ {
+ TRACFCOMP( g_trac_spd,
+ "testSpdRead - kwd: 0x%04x, val: 0x%02x%02x%02x, size: 3",
+ keyword, theData[0], theData[1], theData[2],
+ theSize );
+ }
+ else
+ {
+ // For 4 bytes or larger, just print the first 4 bytes
+ TRACFCOMP( g_trac_spd,
+ "testSpdRead - kwd: 0x%04x, val: 0x%08x, size: %d",
+ keyword,
+ reinterpret_cast<uint32_t *>(theData)[0],
+ theSize );
+ }
if( NULL != theData )
{
@@ -281,6 +314,19 @@ class SPDTest: public CxxTest::TestSuite
}
}
}
+ else if( SPD_DDR4 == memType )
+ {
+ for( uint32_t entry = 0;
+ entry < (sizeof(ddr4Data)/sizeof(ddr4Data[0]));
+ entry++ )
+ {
+ if( SPD::DIMM_BAD_DQ_DATA == ddr4Data[entry].keyword )
+ {
+ theSize = ddr4Data[entry].length;
+ break;
+ }
+ }
+ }
else
{
fails++;
@@ -462,12 +508,30 @@ class SPDTest: public CxxTest::TestSuite
entry++ )
{
if( ddr3Data[entry].writable
- && ddr3Data[entry].useBitMask )
+ && ddr3Data[entry].bitMask )
{
theSize = ddr3Data[entry].length;
theKeyword = ddr3Data[entry].keyword;
TRACFCOMP( g_trac_spd,
- "testSpdWriteSmall - Using keyword 0x%04x",
+ "testSpdWriteSmall - Using DDR3 keyword 0x%04x",
+ theKeyword );
+ break;
+ }
+ }
+ }
+ else if( SPD_DDR4 == memType )
+ {
+ for( uint32_t entry = 0;
+ entry < (sizeof(ddr4Data)/sizeof(ddr4Data[0]));
+ entry++ )
+ {
+ if( ddr4Data[entry].writable
+ && ddr4Data[entry].bitMask )
+ {
+ theSize = ddr4Data[entry].length;
+ theKeyword = ddr4Data[entry].keyword;
+ TRACFCOMP( g_trac_spd,
+ "testSpdWriteSmall - Using DDR4 keyword 0x%04x",
theKeyword );
break;
}
@@ -761,17 +825,16 @@ class SPDTest: public CxxTest::TestSuite
/**
* @brief This test will test reading the Module specific keywords.
*/
- void testspdDDR3ModSpecKwds( void )
+ void testspdModSpecKwds( void )
{
errlHndl_t err = NULL;
uint64_t cmds = 0x0;
uint64_t fails = 0x0;
uint8_t memType = 0x0;
- uint8_t modType = 0x0;
uint8_t * theData = NULL;
TRACFCOMP( g_trac_spd,
- ENTER_MRK"testspdDDR3ModSpecKwds()" );
+ ENTER_MRK"testspdModSpecKwds()" );
do
{
@@ -785,7 +848,7 @@ class SPDTest: public CxxTest::TestSuite
( NULL == dimmList[0] ) )
{
TRACFCOMP( g_trac_spd,
- "testspdDDR3ModSpecKwds - No DIMMs found!" );
+ "testspdModSpecKwds - No DIMMs found!" );
break;
}
@@ -804,32 +867,16 @@ class SPDTest: public CxxTest::TestSuite
if( err )
{
fails++;
- TS_FAIL( "testspdDDR3ModSpecKwds- Failure reading Basic "
+ TS_FAIL( "testspdModSpecKwds- Failure reading Basic "
"memory type!" );
errlCommit( err,
VPD_COMP_ID );
break;
}
- // Get the Module Type
- err = deviceRead( theTarget,
- &modType,
- tmpSize,
- DEVICE_SPD_ADDRESS( SPD::MODULE_TYPE ) );
-
- if( err )
- {
- fails++;
- TS_FAIL( "testspdDDR3ModSpecKwds - Failure reading Module "
- "type" );
- errlCommit( err,
- VPD_COMP_ID );
- break;
- }
-
// The real Keyword read testing
for( uint64_t keyword = SPD::SPD_FIRST_MOD_SPEC;
- keyword < SPD::SPD_LAST_MOD_SPEC; keyword++ )
+ keyword <= SPD::SPD_LAST_MOD_SPEC; keyword++ )
{
cmds++;
if( NULL != theData )
@@ -854,40 +901,44 @@ class SPDTest: public CxxTest::TestSuite
break;
}
}
-
- // Check type of module.
- TRACFCOMP( g_trac_spd,
- INFO_MRK"SPD Error traces will follow!!! "
- "Not all module specific keywords will be "
- "valid for all types of modules. IGNORE!!" );
- err = checkModSpecificKeyword( kwdData,
- memType,
- theTarget );
-
- if( err )
+ }
+ else if( SPD_DDR4 == memType )
+ {
+ for( entry = 0;
+ entry < (sizeof(ddr4Data)/sizeof(ddr4Data[0]));
+ entry++ )
{
- // This keyword isn't supported with this module
- // type
- cmds--;
- delete err;
- err = NULL;
- continue;
+ if( keyword == ddr4Data[entry].keyword )
+ {
+ kwdData = ddr4Data[entry];
+ theSize = ddr4Data[entry].length;
+ break;
+ }
}
}
- else
+
+ if( 0 == theSize )
{
- // Nothing else supported yet!
- // Not really a fail, just not supported
+ // memType not supported or Keyword not supported on
+ // this memType
cmds--;
continue;
}
- if( 0x0 == theSize )
+ // Check that the module type supports this keyword
+ TRACFCOMP( g_trac_spd,
+ INFO_MRK"SPD Error traces will follow!!! "
+ "Not all module specific keywords will be "
+ "valid for all types of modules. IGNORE!!" );
+ err = checkModSpecificKeyword( kwdData,
+ memType,
+ theTarget );
+ if( err )
{
- fails++;
- TS_FAIL( "testspdDDR3ModSpecKwds - Keyword (0x%04x) "
- "size = 0x0",
- entry );
+ // This keyword isn't supported with this module type
+ cmds--;
+ delete err;
+ err = NULL;
continue;
}
@@ -901,19 +952,43 @@ class SPDTest: public CxxTest::TestSuite
if( err )
{
fails++;
- TS_FAIL( "testspdDDR3ModSpecKwds - Failure on keyword"
- "d: %04x",
+ TS_FAIL( "testspdModSpecKwds - Failure on keyword: %04x",
keyword );
errlCommit( err,
VPD_COMP_ID );
continue;
}
- // Read was successful, print out first 2 bytes of data read
- TRACFCOMP( g_trac_spd,
- "testspdDDR3ModSpecKwds - kwd: 0x%04x, val: "
- "%02x, size: %d",
- keyword, theData[0], theSize );
+ // Read was successful, print out the data read
+ if (theSize == 1)
+ {
+ TRACFCOMP( g_trac_spd,
+ "testspdModSpecKwds - kwd: 0x%04x, val: 0x%02x, size: 1",
+ keyword, theData[0] );
+ }
+ else if (theSize == 2)
+ {
+ TRACFCOMP( g_trac_spd,
+ "testspdModSpecKwds - kwd: 0x%04x, val: 0x%04x, size: 2",
+ keyword,
+ reinterpret_cast<uint16_t *>(theData)[0] );
+ }
+ else if (theSize == 3)
+ {
+ TRACFCOMP( g_trac_spd,
+ "testspdModSpecKwds - kwd: 0x%04x, val: 0x%02x%02x%02x, size: 3",
+ keyword, theData[0], theData[1], theData[2],
+ theSize );
+ }
+ else
+ {
+ // For 4 bytes or larger, just print the first 4 bytes
+ TRACFCOMP( g_trac_spd,
+ "testspdModSpecKwds - kwd: 0x%04x, val: 0x%08x, size: %d",
+ keyword,
+ reinterpret_cast<uint32_t *>(theData)[0],
+ theSize );
+ }
if( NULL != theData )
{
@@ -930,7 +1005,7 @@ class SPDTest: public CxxTest::TestSuite
}
TRACFCOMP( g_trac_spd,
- "testspdDDR3ModSpecKwds - %d/%d fails",
+ "testspdModSpecKwds - %d/%d fails",
fails, cmds );
}
@@ -968,7 +1043,38 @@ class SPDTest: public CxxTest::TestSuite
fails );
}
+ /**
+ * @brief This test will ensure that the DDR4 lookup table is in a
+ * sorted order, according to the keyword enumeration, to enable
+ * the search algorithm to work correctly.
+ */
+ void testspdDDR4TableOrder ( void )
+ {
+ uint64_t prevKeyword = 0x0;
+ uint64_t fails = 0x0;
+
+ TRACFCOMP( g_trac_spd,
+ ENTER_MRK"testspdDDR4TableOrder()" );
+
+ for( uint32_t entry = 0;
+ entry < (sizeof(ddr4Data)/sizeof(ddr4Data[0]));
+ entry++ )
+ {
+ if( !(ddr4Data[entry].keyword >= prevKeyword) )
+ {
+ fails++;
+ TS_FAIL( "testspdDDR4TableOrder - DDR4 table out of order! Cur kwd: "
+ "0x%04x, Pre kwd: 0x%04x",
+ ddr4Data[entry].keyword,
+ prevKeyword );
+ }
+ prevKeyword = ddr4Data[entry].keyword;
+ }
+ TRACFCOMP( g_trac_spd,
+ EXIT_MRK"testspdDDR4TableOrder() - fails: %d",
+ fails );
+ }
};
#endif
OpenPOWER on IntegriCloud