summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Raybuck <matthew.raybuck@ibm.com>2019-05-14 14:32:05 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2019-05-29 15:52:24 -0500
commitae7fd02c211501aa83e81e9593c28017633da629 (patch)
treeec62ec25ea1708b48374f55d27c7b5510d5b90cd
parente60c6842b51dd9c79e85c921471c7bb409995473 (diff)
downloadtalos-hostboot-ae7fd02c211501aa83e81e9593c28017633da629.tar.gz
talos-hostboot-ae7fd02c211501aa83e81e9593c28017633da629.zip
Refactor keyword support for various DIMM types
The existing keyword logic didn't use bitmasking when searching for the correct keyword entry. This commit refactors the code to allow for bitmasking and changing the NA module specific keyword to mean that no keyword was found for the given target rather than its previous ambiguous meaning that could be confused with the ALL module specific keyword. Change-Id: I661b70c4eff2740911cd63f8c1042ee8a084d63a RTC:203788 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/77357 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com> Reviewed-by: Michael Baiocchi <mbaiocch@us.ibm.com> Reviewed-by: Glenn Miles <milesg@ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
-rw-r--r--src/include/usr/vpd/spdenums.H4
-rw-r--r--src/include/usr/vpd/vpdreasoncodes.H10
-rwxr-xr-xsrc/usr/targeting/common/xmltohb/attribute_types_hb.xml2
-rw-r--r--src/usr/vpd/ocmb_spd.C79
-rw-r--r--src/usr/vpd/ocmb_spd.H89
-rw-r--r--src/usr/vpd/spd.C424
-rwxr-xr-xsrc/usr/vpd/spd.H35
-rw-r--r--src/usr/vpd/spdDDR3.H136
-rwxr-xr-xsrc/usr/vpd/spdDDR4.H140
-rwxr-xr-xsrc/usr/vpd/spdDDR4_DDIMM.H137
-rwxr-xr-xsrc/usr/vpd/test/spdtest.H130
11 files changed, 671 insertions, 515 deletions
diff --git a/src/include/usr/vpd/spdenums.H b/src/include/usr/vpd/spdenums.H
index 87606349c..a6577ed12 100644
--- a/src/include/usr/vpd/spdenums.H
+++ b/src/include/usr/vpd/spdenums.H
@@ -341,9 +341,7 @@ enum
LRMM_ODT_RTT_PARK_2400_3200 = SPD_FIRST_MOD_SPEC | 0xb2,
RMM_CRC = SPD_FIRST_MOD_SPEC | 0xb3,
LRMM_CRC = SPD_FIRST_MOD_SPEC | 0xb4,
- OCMB_MODULE_PART_NUMBER = SPD_FIRST_MOD_SPEC | 0xb5,
- OCMB_MODULE_SERIAL_NUMBER = SPD_FIRST_MOD_SPEC | 0xb6,
- SPD_LAST_MOD_SPEC = SPD_FIRST_MOD_SPEC | 0xb7,
+ SPD_LAST_MOD_SPEC = SPD_FIRST_MOD_SPEC | 0xb5,
// 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 e4336c9f8..8d9d6943b 100644
--- a/src/include/usr/vpd/vpdreasoncodes.H
+++ b/src/include/usr/vpd/vpdreasoncodes.H
@@ -125,10 +125,10 @@ enum vpdReasonCode
VPD_MEMTYPE_NOT_SUPPORTED = VPD_COMP_ID | 0x0A,
VPD_KEYWORD_NOT_WRITABLE = VPD_COMP_ID | 0x0B,
VPD_NOT_SUPPORTED = VPD_COMP_ID | 0x0C,
- VPD_MOD_SPECIFIC_MISMATCH_UMM = VPD_COMP_ID | 0x0D,
- VPD_MOD_SPECIFIC_MISMATCH_RMM = VPD_COMP_ID | 0x0E,
- VPD_MOD_SPECIFIC_MISMATCH_CMM = VPD_COMP_ID | 0x0F,
- VPD_MOD_SPECIFIC_MISMATCH_LRMM = VPD_COMP_ID | 0x10,
+ VPD_MOD_SPECIFIC_MISMATCH_UMM = VPD_COMP_ID | 0x0D, // Deprecated
+ VPD_MOD_SPECIFIC_MISMATCH_RMM = VPD_COMP_ID | 0x0E, // Deprecated
+ VPD_MOD_SPECIFIC_MISMATCH_CMM = VPD_COMP_ID | 0x0F, // Deprecated
+ VPD_MOD_SPECIFIC_MISMATCH_LRMM = VPD_COMP_ID | 0x10, // Deprecated
VPD_MOD_SPECIFIC_UNSUPPORTED = VPD_COMP_ID | 0x11,
VPD_SIZE_MISMATCH = VPD_COMP_ID | 0x12,
VPD_INVALID_WRITE_METHOD = VPD_COMP_ID | 0x13,
@@ -158,7 +158,7 @@ enum vpdReasonCode
VPD_BAD_REC_NUM = VPD_COMP_ID | 0x3e,
VPD_INVALID_MASTER_I2C_PATH = VPD_COMP_ID | 0x3f,
VPD_NULL_I2C_MASTER = VPD_COMP_ID | 0x40,
- VPD_MOD_SPECIFIC_MISMATCH_DDIMM = VPD_COMP_ID | 0x41,
+ VPD_INVALID_EEPROM_CONTENT_TYPE = VPD_COMP_ID | 0x41,
};
diff --git a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml
index 476eb6a9f..b8584c544 100755
--- a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml
+++ b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml
@@ -995,7 +995,7 @@
<description>The part number for a particular FRU target</description>
<simpleType>
<uint8_t/>
- <array>20</array>
+ <array>48</array>
</simpleType>
<persistency>volatile-zeroed</persistency>
<readable/>
diff --git a/src/usr/vpd/ocmb_spd.C b/src/usr/vpd/ocmb_spd.C
index 2ca877a3d..454f7a327 100644
--- a/src/usr/vpd/ocmb_spd.C
+++ b/src/usr/vpd/ocmb_spd.C
@@ -28,6 +28,7 @@
#include <errl/errlentry.H>
#include <vpd/vpdreasoncodes.H>
+#include "ocmb_spd.H"
#include "spd.H"
#include "errlud_vpd.H"
@@ -44,9 +45,6 @@ namespace SPD
/**
* @brief Handle SPD READ deviceOp to OCMB_CHIP targets
- * This function performs read operations on OCMBs by in turn performing
- * an EEPROM deviceOp on this target, reading the first 2 KB of the OCMB's
- * Primary VPD eeprom and returning it via a buffer
*
* @param[in] i_opType Operation type, see driverif.H
* @param[in] i_target MMIO target
@@ -59,8 +57,6 @@ namespace SPD
* In this function, there is one argument,
* the l_keyword, so far we only support ENTIRE_SPD
* @return errlHndl_t
- *
- * NOTE: ONLY ENTIRE_SPD READ SUPPORTED CURRENTLY
*/
errlHndl_t ocmbSPDPerformOp(DeviceFW::OperationType i_opType,
T::TargetHandle_t i_target,
@@ -69,28 +65,6 @@ errlHndl_t ocmbSPDPerformOp(DeviceFW::OperationType i_opType,
int64_t i_accessType,
va_list i_args);
-/**
- * @param This function is a wrapper for reading the correct keyword.
- *
- * @param[in] i_target The target DDIMM to access.
- *
- * @param[in] i_byteAddr The offset into the JEDEC SPD layout.
- *
- * @param[in] i_numbytes Number of bytes to read.
- *
- * @param[out] o_data The data buffer that will return the data read.
- *
- * @param[in] i_location The SPD source (PNOR/SEEPROM).
- *
- * @return errlHndl_t nullptr if successful, otherwise a pointer to the
- * error log.
- */
-errlHndl_t ocmbFetchData(T::TargetHandle_t i_target,
- uint64_t i_byteAddr,
- size_t i_numBytes,
- void* o_data,
- EEPROM::EEPROM_SOURCE i_location);
-
// Register the perform Op with the routing code for OCMBs.
DEVICE_REGISTER_ROUTE(DeviceFW::READ,
DeviceFW::SPD,
@@ -130,7 +104,7 @@ errlHndl_t ocmbGetSPD(T::TargetHandle_t i_target,
i_memType,
i_target,
entry);
- if (l_errl)
+ if (l_errl != nullptr)
{
break;
}
@@ -168,33 +142,30 @@ errlHndl_t ocmbGetSPD(T::TargetHandle_t i_target,
break;
}
- // For now only support DDIMM, NA keywords with offset less than 128,
- // and the ENTIRE_SPD keyword.
- if ( ((entry->modSpec != DDIMM)
- && (entry->modSpec == NA && entry->offset >= 0x80))
- && (i_keyword != ENTIRE_SPD))
+ // Only allow keywords supported by DDIMM
+ l_errl = checkModSpecificKeyword(*entry,
+ i_memType,
+ i_target,
+ VPD::SEEPROM);
+
+ if (l_errl != nullptr)
{
- TRACFCOMP(g_trac_spd,
- "ocmbGetSPD() keyword 0x%X is not supported",
- i_keyword);
- /*@
- * @errortype
- * @moduleid VPD::VPD_OCMB_GET_SPD
- * @reasoncode VPD::VPD_NOT_SUPPORTED
- * @userdata1 Keyword Enum
- * @userdata2 Target huid
- * @devdesc Attempted to lookup SPD keyword not supported
- * @custdesc Firmware error during system IPL
- */
- l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- VPD::VPD_OCMB_GET_SPD,
- VPD::VPD_NOT_SUPPORTED,
- i_keyword,
- i_target->getAttr<TARGETING::ATTR_HUID>(),
- ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
break;
}
+ if (entry->isSpecialCase)
+ {
+ l_errl = spdSpecialCases(*entry,
+ io_buffer,
+ i_target,
+ i_memType,
+ VPD::SEEPROM);
+ if (l_errl != nullptr)
+ {
+ break;
+ }
+ }
+
// For ENTIRE_SPD, we must read OCMB SPD and EFD combined size.
size_t dataSize = entry->length;
if (i_keyword == ENTIRE_SPD)
@@ -379,14 +350,16 @@ errlHndl_t ocmbSPDPerformOp(DeviceFW::OperationType i_opType,
* @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
* @moduleid VPD::VPD_OCMB_SPD_PERFORM_OP
* @reasoncode VPD::VPD_INVALID_BASIC_MEMORY_TYPE
- * @userdata1 Basic Memory Type (Byte 2)
+ * @userdata1[00:31] Basic Memory Type (Byte 2)
+ * @userdata1[32:63] Target HUID
* @userdata2 Keyword Requested
* @devdesc Invalid Basic Memory Type
*/
errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
VPD::VPD_OCMB_SPD_PERFORM_OP,
VPD::VPD_INVALID_BASIC_MEMORY_TYPE,
- memType,
+ TWO_UINT32_TO_UINT64(memType,
+ T::get_huid(i_target)),
keyword);
// User could have installed a bad/unsupported dimm
diff --git a/src/usr/vpd/ocmb_spd.H b/src/usr/vpd/ocmb_spd.H
new file mode 100644
index 000000000..2e02d776e
--- /dev/null
+++ b/src/usr/vpd/ocmb_spd.H
@@ -0,0 +1,89 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/vpd/ocmb_spd.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __OCMB_SPD_H
+#define __OCMB_SPD_H
+
+#include <i2c/eeprom_const.H>
+
+namespace SPD
+{
+
+/**
+* @brief Read keyword from SPD
+*
+* Currently used to detect I2C_MUTEX and OCMB_CHIP targets
+*
+* @param[in] i_target OCMB target to read data from
+* @param[in/out] io_buffer databuffer SPD will be written to
+* @param[in/out] io_buflen length of the given data buffer
+* @param[in] i_keyword keyword from spdenums.H to read
+* @param[in] i_memType The memory type of this target.
+* @param[in] i_location The EEPROM source (CACHE/HARDWARE).
+*
+* @pre io_buffer and i_target must be non-null
+* @pre currenlty only supported value for i_keyword is ENTIRE_SPD
+*
+* @return errlHndl_t
+*/
+errlHndl_t ocmbGetSPD(TARGETING::TargetHandle_t i_target,
+ void* io_buffer,
+ size_t& io_buflen,
+ const VPD::vpdKeyword i_keyword,
+ const uint8_t i_memType,
+ EEPROM::EEPROM_SOURCE i_location);
+
+// @TODO RTC 203788 doxygen
+bool isValidOcmbDimmType(const uint8_t i_dimmType);
+
+// @TODO RTC 203788 doxygen
+errlHndl_t getMemType(uint8_t& o_memType,
+ TARGETING::TargetHandle_t i_target,
+ EEPROM::EEPROM_SOURCE i_location);
+
+/**
+ * @param This function is a wrapper for reading the correct keyword.
+ *
+ * @param[in] i_target The target DDIMM to access.
+ *
+ * @param[in] i_byteAddr The offset into the JEDEC SPD layout.
+ *
+ * @param[in] i_numbytes Number of bytes to read.
+ *
+ * @param[out] o_data The data buffer that will return the data read.
+ *
+ * @param[in] i_location The EEPROM source (CACHE/HARDWARE).
+ *
+ * @return errlHndl_t nullptr if successful, otherwise a pointer to the
+ * error log.
+ */
+errlHndl_t ocmbFetchData(TARGETING::TargetHandle_t i_target,
+ uint64_t i_byteAddr,
+ size_t i_numBytes,
+ void* o_data,
+ EEPROM::EEPROM_SOURCE i_location);
+
+}
+
+#endif
diff --git a/src/usr/vpd/spd.C b/src/usr/vpd/spd.C
index bd54bc35b..247a60cc2 100644
--- a/src/usr/vpd/spd.C
+++ b/src/usr/vpd/spd.C
@@ -48,8 +48,10 @@
#include <vpd/spdenums.H>
#include <algorithm>
#include "spd.H"
+#include "ocmb_spd.H"
#include "spdDDR3.H"
#include "spdDDR4.H"
+#include "spdDDR4_DDIMM.H"
#include "errlud_vpd.H"
#include <config.h>
@@ -1227,6 +1229,38 @@ errlHndl_t ddr3SpecialCases(const KeywordData & i_kwdData,
return err;
}
+
+errlHndl_t fetchDataFromEepromType(uint64_t i_byteAddr,
+ size_t i_numBytes,
+ void * o_data,
+ TARGETING::Target * i_target,
+ VPD::vpdCmdTarget i_location,
+ TARGETING::EEPROM_CONTENT_TYPE i_eepromType)
+{
+ errlHndl_t errl = nullptr;
+
+ if (i_eepromType == TARGETING::EEPROM_CONTENT_TYPE_ISDIMM)
+ {
+ errl = spdFetchData(i_byteAddr,
+ i_numBytes,
+ o_data,
+ i_target,
+ i_location);
+ }
+ else if (i_eepromType == TARGETING::EEPROM_CONTENT_TYPE_DDIMM)
+ {
+#ifndef __HOSTBOOT_RUNTIME
+ errl = ocmbFetchData(i_target,
+ i_byteAddr,
+ i_numBytes,
+ o_data,
+ EEPROM::AUTOSELECT);
+#endif
+ }
+
+ return errl;
+}
+
// ------------------------------------------------------------------
// ddr4SpecialCases
// ------------------------------------------------------------------
@@ -1240,6 +1274,12 @@ errlHndl_t ddr4SpecialCases(const KeywordData & i_kwdData,
TRACSSCOMP( g_trac_spd, ENTER_MRK"ddr4SpecialCases()" );
+ auto eepromVpd =
+ i_target->getAttr<TARGETING::ATTR_EEPROM_VPD_PRIMARY_INFO>();
+
+ TARGETING::EEPROM_CONTENT_TYPE eepromType =
+ static_cast<TARGETING::EEPROM_CONTENT_TYPE>(eepromVpd.eepromContentType);
+
switch( i_kwdData.keyword )
{
// ==================================================
@@ -1256,12 +1296,14 @@ errlHndl_t ddr4SpecialCases(const KeywordData & i_kwdData,
case RMM_CRC:
case MODSPEC_MM_MFR_ID_CODE:
case LRMM_CRC:
+
// Get MSB
- err = spdFetchData( i_kwdData.offset,
- 1, /* Read 1 byte at a time */
- &tmpBuffer[0],
- i_target,
- i_location );
+ err = fetchDataFromEepromType(i_kwdData.offset,
+ 1, /* Read 1 byte at a time */
+ &tmpBuffer[0],
+ i_target,
+ i_location,
+ eepromType);
if( err ) break;
@@ -1273,22 +1315,24 @@ errlHndl_t ddr4SpecialCases(const KeywordData & i_kwdData,
}
// Get LSB
- err = spdFetchData( (i_kwdData.offset - 1),
- 1, /* Read 1 byte at a time */
- &tmpBuffer[1],
- i_target,
- i_location );
+ err = fetchDataFromEepromType((i_kwdData.offset - 1),
+ 1, /* Read 1 byte at a time */
+ &tmpBuffer[1],
+ i_target,
+ i_location,
+ eepromType);
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,
- i_location );
+ err = fetchDataFromEepromType(i_kwdData.offset,
+ 1, /* Read 1 byte at a time */
+ &tmpBuffer[0],
+ i_target,
+ i_location,
+ eepromType);
if( err ) break;
@@ -1300,49 +1344,54 @@ errlHndl_t ddr4SpecialCases(const KeywordData & i_kwdData,
}
// Get LSB
- err = spdFetchData( (i_kwdData.offset + 2),
- 1, /* Read 1 byte at a time */
- &tmpBuffer[1],
- i_target,
- i_location );
+ err = fetchDataFromEepromType((i_kwdData.offset + 2),
+ 1, /* Read 1 byte at a time */
+ &tmpBuffer[1],
+ i_target,
+ i_location,
+ eepromType);
break;
// ==================================================
// 4 byte - LSB first, no mask
case CAS_LATENCIES_SUPPORTED_DDR4:
// Get 4th byte
- err = spdFetchData( i_kwdData.offset,
- 1, /* Read 1 byte at a time */
- &tmpBuffer[0],
- i_target,
- i_location );
+ err = fetchDataFromEepromType(i_kwdData.offset,
+ 1, /* Read 1 byte at a time */
+ &tmpBuffer[0],
+ i_target,
+ i_location,
+ eepromType);
if( err ) break;
// Get 3rd Byte
- err = spdFetchData( (i_kwdData.offset - 1),
- 1, /* Read 1 byte at a time */
- &tmpBuffer[1],
- i_target,
- i_location );
+ err = fetchDataFromEepromType((i_kwdData.offset - 1),
+ 1, /* Read 1 byte at a time */
+ &tmpBuffer[1],
+ i_target,
+ i_location,
+ eepromType);
if( err ) break;
// Get 2nd Byte
- err = spdFetchData( (i_kwdData.offset - 2),
- 1, /* Read 1 byte at a time */
- &tmpBuffer[2],
- i_target,
- i_location );
+ err = fetchDataFromEepromType((i_kwdData.offset - 2),
+ 1, /* Read 1 byte at a time */
+ &tmpBuffer[2],
+ i_target,
+ i_location,
+ eepromType);
if( err ) break;
// Get 1st Byte
- err = spdFetchData( (i_kwdData.offset - 3),
- 1, /* Read 1 byte at a time */
- &tmpBuffer[3],
- i_target,
- i_location );
+ err = fetchDataFromEepromType((i_kwdData.offset - 3),
+ 1, /* Read 1 byte at a time */
+ &tmpBuffer[3],
+ i_target,
+ i_location,
+ eepromType);
break;
// ==================================================
@@ -1665,12 +1714,6 @@ errlHndl_t checkModSpecificKeyword ( KeywordData i_kwdData,
do
{
- // If not a Module Specific keyword, skip this logic
- if( NA == i_kwdData.modSpec )
- {
- break;
- }
-
// Check that a Module Specific keyword is being accessed from a DIMM
// of the correct Module Type.
modSpecTypes_t modType = NA;
@@ -1681,263 +1724,43 @@ errlHndl_t checkModSpecificKeyword ( KeywordData i_kwdData,
break;
}
- // Check Unbuffered Memory Module (UMM)
- if (UMM == modType)
- {
- if ((UMM != i_kwdData.modSpec) &&
- (ALL != i_kwdData.modSpec) )
- {
- TRACFCOMP( g_trac_spd, ERR_MRK"checkModSpecificKeyword: "
- "Keyword (0x%04x) is not valid with UMM modules!",
- i_kwdData.keyword );
- /*@
- * @errortype
- * @reasoncode VPD::VPD_MOD_SPECIFIC_MISMATCH_UMM
- * @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 Keyword requested was not UMM Module
- * specific.
- * @custdesc A problem occurred during the IPL
- * of the system.
- */
- 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 ) );
-
- // HB code asked for an unsupprted keyword for this Module
- err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
- HWAS::SRCI_PRIORITY_HIGH);
-
- // Or user could have installed a bad/unsupported dimm
- err->addHwCallout( i_target,
- HWAS::SRCI_PRIORITY_LOW,
- HWAS::DECONFIG,
- HWAS::GARD_NULL );
-
- err->collectTrace( "SPD", 256);
-
- break;
- }
- }
- // Check Registered Memory Module (RMM)
- else if (RMM == modType)
- {
- if ((RMM != i_kwdData.modSpec) &&
- (ALL != i_kwdData.modSpec) )
- {
- TRACFCOMP( g_trac_spd, ERR_MRK"checkModSpecificKeyword: "
- "Keyword (0x%04x) is not valid with RMM modules!",
- i_kwdData.keyword );
- /*@
- * @errortype
- * @reasoncode VPD::VPD_MOD_SPECIFIC_MISMATCH_RMM
- * @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 Keyword requested was not RMM Module
- * specific.
- * @custdesc A problem occurred during the IPL
- * of the system.
- */
- 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 ) );
-
- // HB code asked for an unsupprted keyword for this Module
- err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
- HWAS::SRCI_PRIORITY_HIGH);
-
- // Or user could have installed a bad/unsupported dimm
- err->addHwCallout( i_target,
- HWAS::SRCI_PRIORITY_LOW,
- HWAS::DECONFIG,
- HWAS::GARD_NULL );
-
- err->collectTrace( "SPD", 256);
-
- break;
- }
- }
- // Check Clocked Memory Module (CMM)
- else if (CMM == modType)
- {
- if ((CMM != i_kwdData.modSpec) &&
- (ALL != i_kwdData.modSpec) )
- {
- TRACFCOMP( g_trac_spd, ERR_MRK"checkModSpecificKeyword: "
- "Keyword (0x%04x) is not valid with CMM modules!",
- i_kwdData.keyword );
- /*@
- * @errortype
- * @reasoncode VPD::VPD_MOD_SPECIFIC_MISMATCH_CMM
- * @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 Keyword requested was not CMM Module
- * specific.
- * @custdesc A problem occurred during the IPL
- * of the system.
- */
- 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 ) );
-
- // HB code asked for an unsupprted keyword for this Module
- err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
- HWAS::SRCI_PRIORITY_HIGH);
-
- // Or user could have installed a bad/unsupported dimm
- err->addHwCallout( i_target,
- HWAS::SRCI_PRIORITY_LOW,
- HWAS::DECONFIG,
- HWAS::GARD_NULL );
-
- err->collectTrace( "SPD", 256);
-
- break;
- }
- }
- // Check Load Reduction Memory Module (LRMM)
- else if (LRMM == modType)
- {
- if ((LRMM != i_kwdData.modSpec) &&
- (ALL != i_kwdData.modSpec) )
- {
- TRACFCOMP( g_trac_spd, ERR_MRK"checkModSpecificKeyword: "
- "Keyword (0x%04x) is not valid with LRMM modules!",
- i_kwdData.keyword );
- /*@
- * @errortype
- * @reasoncode VPD::VPD_MOD_SPECIFIC_MISMATCH_LRMM
- * @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 Keyword requested was not LRMM Module
- * specific.
- * @custdesc A problem occurred during the IPL
- * of the system.
- */
- 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 ) );
-
- // HB code asked for an unsupprted keyword for this Module
- err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
- HWAS::SRCI_PRIORITY_HIGH);
-
- // Or user could have installed a bad/unsupported dimm
- err->addHwCallout( i_target,
- HWAS::SRCI_PRIORITY_LOW,
- HWAS::DECONFIG,
- HWAS::GARD_NULL );
-
- err->collectTrace( "SPD", 256);
-
- break;
- }
- }
- else if(DDIMM == modType)
- {
- if ((DDIMM != i_kwdData.modSpec) &&
- (ALL != i_kwdData.modSpec) )
- {
- TRACFCOMP( g_trac_spd, ERR_MRK"checkModSpecificKeyword: "
- "Keyword (0x%04x) is not valid with DDIMM modules!",
- i_kwdData.keyword );
- /*@
- * @errortype
- * @reasoncode VPD::VPD_MOD_SPECIFIC_MISMATCH_DDIMM
- * @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 Keyword requested was not LRMM Module
- * specific.
- * @custdesc A problem occurred during the IPL
- * of the system.
- */
- err = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- VPD::VPD_SPD_CHECK_MODULE_SPECIFIC_KEYWORD,
- VPD::VPD_MOD_SPECIFIC_MISMATCH_DDIMM,
- TWO_UINT32_TO_UINT64( modType, i_memType ),
- TWO_UINT32_TO_UINT64( i_kwdData.keyword,
- i_kwdData.modSpec ) );
-
- // HB code asked for an unsupprted keyword for this Module
- err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
- HWAS::SRCI_PRIORITY_HIGH);
-
- // Or user could have installed a bad/unsupported dimm
- err->addHwCallout( i_target,
- HWAS::SRCI_PRIORITY_LOW,
- HWAS::DECONFIG,
- HWAS::GARD_NULL );
-
- err->collectTrace( "SPD", 256);
-
- break;
- }
- }
- else
+ if (!(modType & i_kwdData.modSpec))
{
TRACFCOMP( g_trac_spd, ERR_MRK"checkModSpecificKeyword: "
"Module specific keyword could not be matched with an "
"appropriate scenario!" );
+
TRACFCOMP( g_trac_spd, ERR_MRK
" Mem Type: 0x%04x, Mod Type: 0x%04x, Keyword: 0x%04x",
i_memType,
modType,
i_kwdData.keyword );
+
+ uint32_t udUpper32 = TWO_UINT16_TO_UINT32(modType, i_memType);
+ uint32_t udLower32 = TWO_UINT16_TO_UINT32(i_kwdData.keyword,
+ i_kwdData.modSpec);
+ uint64_t userdata1 = TWO_UINT32_TO_UINT64(udUpper32, udLower32);
+
/*@
* @errortype
- * @reasoncode VPD::VPD_MOD_SPECIFIC_UNSUPPORTED
* @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
* @moduleid VPD::VPD_SPD_CHECK_MODULE_SPECIFIC_KEYWORD
- * @userdata1 Module Type
- * @userdata2 Memory Type (byte 2)
+ * @reasoncode VPD::VPD_MOD_SPECIFIC_UNSUPPORTED
+ * @userdata1[00:15] Memory Module Type
+ * @userdata1[16:31] Memory Type (byte 2)
+ * @userdata1[32:47] SPD Keyword
+ * @userdata1[48:63] Module Specific Flag
+ * @userdata2 Target HUID
* @devdesc Unsupported Module Type.
* @custdesc A problem occurred during the IPL
* of the system.
*/
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 ) );
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ VPD::VPD_SPD_CHECK_MODULE_SPECIFIC_KEYWORD,
+ VPD::VPD_MOD_SPECIFIC_UNSUPPORTED,
+ userdata1,
+ TARGETING::get_huid(i_target));
// HB code asked for an unsupprted keyword for this Module
err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
@@ -1998,12 +1821,19 @@ errlHndl_t getModType ( modSpecTypes_t & o_modType,
errlHndl_t err{nullptr};
o_modType = NA;
+ auto eepromVpd =
+ i_target->getAttr<TARGETING::ATTR_EEPROM_VPD_PRIMARY_INFO>();
+
+ TARGETING::EEPROM_CONTENT_TYPE eepromType =
+ static_cast<TARGETING::EEPROM_CONTENT_TYPE>(eepromVpd.eepromContentType);
+
uint8_t modTypeVal = 0;
- err = spdFetchData( MOD_TYPE_ADDR,
- MOD_TYPE_SZ,
- &modTypeVal,
- i_target,
- i_location );
+ err = fetchDataFromEepromType(MOD_TYPE_ADDR,
+ MOD_TYPE_SZ,
+ &modTypeVal,
+ i_target,
+ i_location,
+ eepromType);
if (err)
{
@@ -2125,8 +1955,18 @@ errlHndl_t getKeywordEntry ( VPD::vpdKeyword i_keyword,
}
else if ( SPD_DDR4_TYPE == i_memType )
{
- arraySize = (sizeof(ddr4Data)/sizeof(ddr4Data[0]));
- kwdData = ddr4Data;
+ modSpecTypes_t modType = NA;
+ err = getModType(modType, i_target, i_memType, VPD::AUTOSELECT);
+ if (modType == DDIMM)
+ {
+ arraySize = (sizeof(ddr4DDIMMData)/sizeof(ddr4DDIMMData[0]));
+ kwdData = ddr4DDIMMData;
+ }
+ else
+ {
+ arraySize = (sizeof(ddr4Data)/sizeof(ddr4Data[0]));
+ kwdData = ddr4Data;
+ }
}
else
{
diff --git a/src/usr/vpd/spd.H b/src/usr/vpd/spd.H
index c3cb7b038..b5cd95f82 100755
--- a/src/usr/vpd/spd.H
+++ b/src/usr/vpd/spd.H
@@ -94,13 +94,13 @@ enum
*/
typedef enum
{
- NA = 0x00,
- UMM = 0x01, // Unbuffered Memory Modules
- RMM = 0x02, // Registered Memory Modules
- CMM = 0x04, // Clocked Memory Modules
- LRMM = 0x08, // Load Reduction Memory Modules
- DDIMM = 0x0A,
- ALL = 0xFFFF,
+ NA = 0x00, // Invalid Type
+ UMM = 0x01, // Unbuffered Memory Modules
+ RMM = 0x02, // Registered Memory Modules
+ CMM = 0x04, // Clocked Memory Modules
+ LRMM = 0x08, // Load Reduction Memory Modules
+ DDIMM = 0x10, // Differential DIMM
+ ALL = 0xFFFF,
} modSpecTypes_t;
@@ -391,6 +391,27 @@ errlHndl_t dimmPresenceDetect( DeviceFW::OperationType i_opType,
size_t & io_buflen,
int64_t i_accessType,
va_list i_args );
+
+
+/**
+ * @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
+ *
+ * @param[in] i_location - The SPD source (PNOR/SEEPROM).
+ *
+ * @return errlHndl_t - NULL if successful, otherwise a pointer
+ * to the error log.
+ */
+errlHndl_t getModType ( modSpecTypes_t & o_modType,
+ TARGETING::Target * i_target,
+ uint64_t i_memType,
+ VPD::vpdCmdTarget i_location );
+
/**
* @brief This function will scan the table and return the entry
* corresponding to the keyword being requested.
diff --git a/src/usr/vpd/spdDDR3.H b/src/usr/vpd/spdDDR3.H
index 06fc33aa5..26aa36660 100644
--- a/src/usr/vpd/spdDDR3.H
+++ b/src/usr/vpd/spdDDR3.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2015 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -68,74 +68,74 @@ const KeywordData ddr3Data[] =
// 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 },
- { 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 },
+ { CRC_EXCLUDE, 0x00, 0x01, 0x80, 0x07, false, false, ALL },
+ { SPD_BYTES_TOTAL, 0x00, 0x01, 0x70, 0x04, false, false, ALL },
+ { SPD_BYTES_USED, 0x00, 0x01, 0x0F, 0x00, false, false, ALL },
+ { SPD_MAJOR_REVISION, 0x01, 0x01, 0xF0, 0x04, false, false, ALL },
+ { SPD_MINOR_REVISION, 0x01, 0x01, 0x0F, 0x00, false, false, ALL },
+ { BASIC_MEMORY_TYPE, 0x02, 0x01, 0x00, 0x00, false, false, ALL },
+ { CUSTOM, 0x03, 0x01, 0x80, 0x07, false, false, ALL },
+ { MODULE_TYPE, 0x03, 0x01, 0x0F, 0x00, false, false, ALL },
+ { DENSITY, 0x04, 0x01, 0x0F, 0x00, false, false, ALL },
+ { ROW_ADDRESS, 0x05, 0x01, 0x38, 0x03, false, false, ALL },
+ { COL_ADDRESS, 0x05, 0x01, 0x07, 0x00, false, false, ALL },
+ { MODULE_RANKS, 0x07, 0x01, 0x38, 0x03, false, false, ALL },
+ { MODULE_DRAM_WIDTH, 0x07, 0x01, 0x07, 0x00, false, false, ALL },
+ { MODULE_MEMORY_BUS_WIDTH, 0x08, 0x01, 0x1f, 0x00, false, false, ALL },
+ { MODULE_MEMORY_BUS_WIDTH_EXT, 0x08, 0x01, 0x18, 0x03, false, false, ALL },
+ { MODULE_MEMORY_BUS_WIDTH_PRI, 0x08, 0x01, 0x07, 0x00, false, false, ALL },
+ { TCK_MIN, 0x0c, 0x01, 0x00, 0x00, false, false, ALL },
+ { MIN_CAS_LATENCY, 0x10, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRCD_MIN, 0x12, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRP_MIN, 0x14, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRC_MIN, 0x15, 0x02, 0xF0, 0x04, true, false, ALL },
+ { TRAS_MIN, 0x15, 0x02, 0x0F, 0x00, false, false, ALL },
+ { TFAW_MIN, 0x1c, 0x02, 0x0F, 0x00, false, false, ALL },
+ { SDRAM_OPTIONAL_FEATURES, 0x1e, 0x01, 0x00, 0x00, false, false, ALL },
+ { SDRAM_THERMAL_REFRESH_OPTIONS, 0x1f, 0x01, 0x00, 0x00, false, false, ALL },
+ { MODULE_THERMAL_SENSOR, 0x20, 0x01, 0x00, 0x00, false, false, ALL },
+ { THERMAL_SENSOR_PRESENT, 0x20, 0x01, 0x80, 0x07, false, false, ALL },
+ { THERMAL_SENSOR_ACCURACY, 0x20, 0x01, 0x7F, 0x00, false, false, ALL },
+ { SDRAM_DEVICE_TYPE, 0x21, 0x01, 0x80, 0x07, false, false, ALL },
+ { SDRAM_DIE_COUNT, 0x21, 0x01, 0x70, 0x04, false, false, ALL },
+ { SDRAM_DEVICE_TYPE_SIGNAL_LOADING, 0x21, 0x01, 0x03, 0x00, false, false, ALL },
+ { TCKMIN_FINE_OFFSET, 0x22, 0x01, 0x00, 0x00, false, false, ALL },
+ { TAAMIN_FINE_OFFSET, 0x23, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRCDMIN_FINE_OFFSET, 0x24, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRPMIN_FINE_OFFSET, 0x25, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRCMIN_FINE_OFFSET, 0x26, 0x01, 0x00, 0x00, false, false, ALL },
+ { MODULE_TYPE_SPECIFIC_SECTION, 0x3c, 0x39, 0x00, 0x00, false, false, ALL },
+ { MODULE_MANUFACTURER_ID, 0x76, 0x02, 0x00, 0x00, true, false, ALL },
+ { MODULE_MANUFACTURING_LOCATION, 0x77, 0x01, 0x00, 0x00, false, false, ALL },
+ { MODULE_MANUFACTURING_DATE, 0x78, 0x02, 0x00, 0x00, false, false, ALL },
+ { MODULE_SERIAL_NUMBER, 0x7a, 0x04, 0x00, 0x00, false, false, ALL },
+ { MODULE_PART_NUMBER, 0x80, 0x12, 0x00, 0x00, false, false, ALL },
+ { DRAM_MANUFACTURER_ID, 0x95, 0x02, 0x00, 0x00, true, false, ALL },
+ { MANUFACTURER_SPECIFIC_DATA, 0x96, 0x1a, 0x00, 0x00, false, false, ALL },
+ { DIMM_BAD_DQ_DATA, 0xb0, 0x50, 0x00, 0x00, false, true, ALL },
// 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, 0x7f, 0x02, 0x00, 0x00, true, false, NA },
- { MODULE_REVISION_CODE, 0x93, 0x02, 0x00, 0x00, true, false, NA },
+ { BANK_ADDRESS_BITS, 0x04, 0x01, 0x70, 0x04, false, false, ALL },
+ { MODULE_NOMINAL_VOLTAGE, 0x06, 0x01, 0x07, 0x00, false, false, ALL },
+ { FTB_DIVIDEND, 0x09, 0x01, 0xF0, 0x04, false, false, ALL },
+ { FTB_DIVISOR, 0x09, 0x01, 0x0F, 0x00, false, false, ALL },
+ { MTB_DIVIDEND, 0x0a, 0x01, 0x00, 0x00, false, false, ALL },
+ { MTB_DIVISOR, 0x0b, 0x01, 0x00, 0x00, false, false, ALL },
+ { CAS_LATENCIES_SUPPORTED, 0x0f, 0x02, 0x7F, 0x00, true, false, ALL },
+ { TWR_MIN, 0x11, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRRD_MIN, 0x13, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRFC_MIN, 0x19, 0x02, 0x00, 0x00, true, false, ALL },
+ { TWTR_MIN, 0x1a, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRTP_MIN, 0x1b, 0x01, 0x00, 0x00, false, false, ALL },
+ { DLL_OFF, 0x1e, 0x01, 0x80, 0x07, false, false, ALL },
+ { RZQ_7, 0x1e, 0x01, 0x02, 0x01, false, false, ALL },
+ { RZQ_6, 0x1e, 0x01, 0x01, 0x00, false, false, ALL },
+ { PASR, 0x1f, 0x01, 0x80, 0x07, false, false, ALL },
+ { ODTS, 0x1f, 0x01, 0x08, 0x03, false, false, ALL },
+ { ASR, 0x1f, 0x01, 0x04, 0x02, false, false, ALL },
+ { ETR_1X, 0x1f, 0x01, 0x02, 0x01, false, false, ALL },
+ { ETR, 0x1f, 0x01, 0x01, 0x00, false, false, ALL },
+ { MODULE_CRC, 0x7f, 0x02, 0x00, 0x00, true, false, ALL },
+ { MODULE_REVISION_CODE, 0x93, 0x02, 0x00, 0x00, true, false, ALL },
// 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 },
diff --git a/src/usr/vpd/spdDDR4.H b/src/usr/vpd/spdDDR4.H
index b71eb92e1..b29a1043f 100755
--- a/src/usr/vpd/spdDDR4.H
+++ b/src/usr/vpd/spdDDR4.H
@@ -69,76 +69,76 @@ const KeywordData ddr4Data[] =
// ------------------------------------------------------------------------------------------
//
// Normal fields supported on both DDR3 and DDR4
- { 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 },
- { 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 },
- // Note - All data below 128 is common across all DDR4 DIMMs, even DDIMM
- { 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 },
- { 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 },
- { MODULE_REVISION_CODE, 0x15d, 0x01, 0x00, 0x00, false, false, NA },
+ { SPD_BYTES_TOTAL, 0x00, 0x01, 0x70, 0x04, false, false, ALL },
+ { SPD_BYTES_USED, 0x00, 0x01, 0x0F, 0x00, false, false, ALL },
+ { SPD_MAJOR_REVISION, 0x01, 0x01, 0xF0, 0x04, false, false, ALL },
+ { SPD_MINOR_REVISION, 0x01, 0x01, 0x0F, 0x00, false, false, ALL },
+ { BASIC_MEMORY_TYPE, 0x02, 0x01, 0x00, 0x00, false, false, ALL },
+ { CUSTOM, 0x03, 0x01, 0x80, 0x07, false, false, ALL },
+ { MODULE_TYPE, 0x03, 0x01, 0x0F, 0x00, false, false, ALL },
+ { DENSITY, 0x04, 0x01, 0x0F, 0x00, false, false, ALL },
+ { ROW_ADDRESS, 0x05, 0x01, 0x38, 0x03, false, false, ALL },
+ { COL_ADDRESS, 0x05, 0x01, 0x07, 0x00, false, false, ALL },
+ { MODULE_RANKS, 0x0c, 0x01, 0x38, 0x03, false, false, ALL },
+ { MODULE_DRAM_WIDTH, 0x0c, 0x01, 0x07, 0x00, false, false, ALL },
+ { MODULE_MEMORY_BUS_WIDTH, 0x0d, 0x01, 0x1f, 0x00, false, false, ALL },
+ { MODULE_MEMORY_BUS_WIDTH_EXT, 0x0d, 0x01, 0x18, 0x03, false, false, ALL },
+ { MODULE_MEMORY_BUS_WIDTH_PRI, 0x0d, 0x01, 0x07, 0x00, false, false, ALL },
+ { TCK_MIN, 0x12, 0x01, 0x00, 0x00, false, false, ALL },
+ { MIN_CAS_LATENCY, 0x18, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRCD_MIN, 0x19, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRP_MIN, 0x1a, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRC_MIN, 0x1b, 0x02, 0xF0, 0x04, true, false, ALL },
+ { TRAS_MIN, 0x1b, 0x02, 0x0F, 0x00, false, false, ALL },
+ { TFAW_MIN, 0x24, 0x02, 0x0F, 0x00, false, false, ALL },
+ { SDRAM_OPTIONAL_FEATURES, 0x07, 0x01, 0x00, 0x00, false, false, ALL },
+ { SDRAM_THERMAL_REFRESH_OPTIONS, 0x08, 0x01, 0x00, 0x00, false, false, ALL },
+ { MODULE_THERMAL_SENSOR, 0x0e, 0x01, 0x00, 0x00, false, false, ALL },
+ { THERMAL_SENSOR_PRESENT, 0x0e, 0x01, 0x80, 0x07, false, false, ALL },
+ { SDRAM_DEVICE_TYPE , 0x06, 0x01, 0x80, 0x07, false, false, ALL },
+ { SDRAM_DIE_COUNT, 0x06, 0x01, 0x70, 0x04, false, false, ALL },
+ { SDRAM_DEVICE_TYPE_SIGNAL_LOADING, 0x06, 0x01, 0x03, 0x00, false, false, ALL },
+ { TCKMIN_FINE_OFFSET, 0x7d, 0x01, 0x00, 0x00, false, false, ALL },
+ { TAAMIN_FINE_OFFSET, 0x7b, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRCDMIN_FINE_OFFSET, 0x7a, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRPMIN_FINE_OFFSET, 0x79, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRCMIN_FINE_OFFSET, 0x78, 0x01, 0x00, 0x00, false, false, ALL },
+ // Note - All data below 128 is common across all DDR4 DIMMs, except DDIMM
+ { MODULE_TYPE_SPECIFIC_SECTION, 0x80, 0x80, 0x00, 0x00, false, false, ALL },
+ { MODULE_MANUFACTURER_ID, 0x141, 0x02, 0x00, 0x00, true, false, ALL },
+ { MODULE_MANUFACTURING_LOCATION, 0x142, 0x01, 0x00, 0x00, false, false, ALL },
+ { MODULE_MANUFACTURING_DATE, 0x143, 0x02, 0x00, 0x00, false, false, ALL },
+ { MODULE_SERIAL_NUMBER, 0x145, 0x04, 0x00, 0x00, false, false, ALL },
+ { MODULE_PART_NUMBER, 0x149, 0x14, 0x00, 0x00, false, false, ALL },
+ { DRAM_MANUFACTURER_ID, 0x15f, 0x02, 0x00, 0x00, true, false, ALL },
+ { MANUFACTURER_SPECIFIC_DATA, 0x161, 0x1d, 0x00, 0x00, false, false, ALL },
+ { DIMM_BAD_DQ_DATA, 0x180, 0x50, 0x00, 0x00, false, true, ALL },
+ { MODULE_REVISION_CODE, 0x15d, 0x01, 0x00, 0x00, false, false, ALL },
// 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 },
- { NVM_INIT_TIME, 0xCB, 0x01, 0x00, 0x00, false, false, NA },
- { RAW_MODULE_PRODUCT_ID, 0xc0, 0x02, 0x00, 0x00, false, false, NA },
- { RAW_MODULE_MANUFACTURER_ID, 0x140, 0x02, 0x00, 0x00, false, false, NA },
+ { BANK_GROUP_BITS, 0x04, 0x01, 0xC0, 0x06, false, false, ALL },
+ { BANK_ADDRESS_BITS_DDR4, 0x04, 0x01, 0x30, 0x04, false, false, ALL },
+ { MODULE_NOMINAL_VOLTAGE_DDR4, 0x0b, 0x01, 0x3F, 0x00, false, false, ALL },
+ { TIMEBASES_MTB, 0x11, 0x01, 0x0C, 0x02, false, false, ALL },
+ { TIMEBASES_FTB, 0x11, 0x01, 0x03, 0x00, false, false, ALL },
+ { TCK_MAX, 0x13, 0x01, 0x00, 0x00, false, false, ALL },
+ { CAS_LATENCIES_SUPPORTED_DDR4, 0x17, 0x04, 0x00, 0x00, true, false, ALL },
+ { TRFC1_MIN, 0x1f, 0x02, 0x00, 0x00, true, false, ALL },
+ { TRFC2_MIN, 0x21, 0x02, 0x00, 0x00, true, false, ALL },
+ { TRFC4_MIN, 0x23, 0x02, 0x00, 0x00, true, false, ALL },
+ { TRRDS_MIN, 0x26, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRRDL_MIN, 0x27, 0x01, 0x00, 0x00, false, false, ALL },
+ { TCCDL_MIN, 0x28, 0x01, 0x00, 0x00, false, false, ALL },
+ { CONNECTOR_SDRAM_MAP, 0x3C, 0x12, 0x00, 0x00, false, false, ALL },
+ { TCCDL_FINE_OFFSET, 0x75, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRRDL_FINE_OFFSET, 0x76, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRRDS_FINE_OFFSET, 0x77, 0x01, 0x00, 0x00, false, false, ALL },
+ { TCKMAX_FINE_OFFSET, 0x7c, 0x01, 0x00, 0x00, false, false, ALL },
+ { BASE_CONFIG_CRC, 0x7f, 0x02, 0x00, 0x00, true, false, ALL },
+ { DRAM_STEPPING, 0x160, 0x01, 0x00, 0x00, false, false, ALL },
+ { MANUFACTURING_SECTION_CRC, 0x17f, 0x02, 0x00, 0x00, true, false, ALL },
+ { NVM_INIT_TIME, 0xCB, 0x01, 0x00, 0x00, false, false, ALL },
+ { RAW_MODULE_PRODUCT_ID, 0xc0, 0x02, 0x00, 0x00, false, false, ALL },
+ { RAW_MODULE_MANUFACTURER_ID, 0x140, 0x02, 0x00, 0x00, false, false, ALL },
// 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 },
@@ -186,8 +186,6 @@ const KeywordData ddr4Data[] =
{ LRMM_ODT_RTT_PARK_2400_3200, 0x9a, 0x01, 0x00, 0x00, false, false, LRMM },
{ RMM_CRC, 0xff, 0x02, 0x00, 0x00, true, false, RMM },
{ LRMM_CRC, 0xff, 0x02, 0x00, 0x00, true, false, LRMM },
- { OCMB_MODULE_PART_NUMBER, 0x209, 0x30, 0x00, 0x00, false, false, DDIMM },
- { OCMB_MODULE_SERIAL_NUMBER, 0x205, 0x04, 0x00, 0x00, false, false, DDIMM },
{ ENTIRE_SPD, 0x00, 0x200, 0x00, 0x00, false, false, ALL },
//---------------------------------------------------------------------------------------
};
diff --git a/src/usr/vpd/spdDDR4_DDIMM.H b/src/usr/vpd/spdDDR4_DDIMM.H
new file mode 100755
index 000000000..36d27aea8
--- /dev/null
+++ b/src/usr/vpd/spdDDR4_DDIMM.H
@@ -0,0 +1,137 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/vpd/spdDDR4_DDIMM.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __SPDDDR4_DDIMM_H
+#define __SPDDDR4_DDIMM_H
+
+/**
+ * @file spdDDR4_DDIMM.H
+ *
+ * @brief Provides the DDR4 field information for DDIMM
+ *
+ */
+
+// ----------------------------------------------
+// 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 ddr4DDIMMData[] =
+{
+ // ----------------------------------------------------------------------------------
+ // 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
+ { SPD_BYTES_TOTAL, 0x00, 0x01, 0x70, 0x04, false, false, ALL },
+ { SPD_BYTES_USED, 0x00, 0x01, 0x0F, 0x00, false, false, ALL },
+ { SPD_MAJOR_REVISION, 0x01, 0x01, 0xF0, 0x04, false, false, ALL },
+ { SPD_MINOR_REVISION, 0x01, 0x01, 0x0F, 0x00, false, false, ALL },
+ { BASIC_MEMORY_TYPE, 0x02, 0x01, 0x00, 0x00, false, false, ALL },
+ { CUSTOM, 0x03, 0x01, 0x80, 0x07, false, false, ALL },
+ { MODULE_TYPE, 0x03, 0x01, 0x0F, 0x00, false, false, ALL },
+ { DENSITY, 0x04, 0x01, 0x0F, 0x00, false, false, ALL },
+ { ROW_ADDRESS, 0x05, 0x01, 0x38, 0x03, false, false, ALL },
+ { COL_ADDRESS, 0x05, 0x01, 0x07, 0x00, false, false, ALL },
+ { MODULE_RANKS, 0x0c, 0x01, 0x38, 0x03, false, false, ALL },
+ { MODULE_DRAM_WIDTH, 0x0c, 0x01, 0x07, 0x00, false, false, ALL },
+ { MODULE_MEMORY_BUS_WIDTH, 0x0d, 0x01, 0x1f, 0x00, false, false, ALL },
+ { MODULE_MEMORY_BUS_WIDTH_EXT, 0x0d, 0x01, 0x18, 0x03, false, false, ALL },
+ { MODULE_MEMORY_BUS_WIDTH_PRI, 0x0d, 0x01, 0x07, 0x00, false, false, ALL },
+ { TCK_MIN, 0x12, 0x01, 0x00, 0x00, false, false, ALL },
+ { MIN_CAS_LATENCY, 0x18, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRCD_MIN, 0x19, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRP_MIN, 0x1a, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRC_MIN, 0x1b, 0x02, 0xF0, 0x04, true, false, ALL },
+ { TRAS_MIN, 0x1b, 0x02, 0x0F, 0x00, false, false, ALL },
+ { TFAW_MIN, 0x24, 0x02, 0x0F, 0x00, false, false, ALL },
+ { SDRAM_OPTIONAL_FEATURES, 0x07, 0x01, 0x00, 0x00, false, false, ALL },
+ { SDRAM_THERMAL_REFRESH_OPTIONS, 0x08, 0x01, 0x00, 0x00, false, false, ALL },
+ { MODULE_THERMAL_SENSOR, 0x0e, 0x01, 0x00, 0x00, false, false, ALL },
+ { THERMAL_SENSOR_PRESENT, 0x0e, 0x01, 0x80, 0x07, false, false, ALL },
+ { SDRAM_DEVICE_TYPE , 0x06, 0x01, 0x80, 0x07, false, false, ALL },
+ { SDRAM_DIE_COUNT, 0x06, 0x01, 0x70, 0x04, false, false, ALL },
+ { SDRAM_DEVICE_TYPE_SIGNAL_LOADING, 0x06, 0x01, 0x03, 0x00, false, false, ALL },
+ { TCKMIN_FINE_OFFSET, 0x7d, 0x01, 0x00, 0x00, false, false, ALL },
+ { TAAMIN_FINE_OFFSET, 0x7b, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRCDMIN_FINE_OFFSET, 0x7a, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRPMIN_FINE_OFFSET, 0x79, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRCMIN_FINE_OFFSET, 0x78, 0x01, 0x00, 0x00, false, false, ALL },
+ // Note - All data below 128 is common across all DDR4 DIMMs, except DDIMM
+ { MODULE_SERIAL_NUMBER, 0x205, 0x04, 0x00, 0x00, false, false, ALL },
+ { MODULE_PART_NUMBER, 0x209, 0x30, 0x00, 0x00, false, false, ALL },
+ // Normal fields supported on DDR4 only
+ { BANK_GROUP_BITS, 0x04, 0x01, 0xC0, 0x06, false, false, ALL },
+ { BANK_ADDRESS_BITS_DDR4, 0x04, 0x01, 0x30, 0x04, false, false, ALL },
+ { MODULE_NOMINAL_VOLTAGE_DDR4, 0x0b, 0x01, 0x3F, 0x00, false, false, ALL },
+ { TIMEBASES_MTB, 0x11, 0x01, 0x0C, 0x02, false, false, ALL },
+ { TIMEBASES_FTB, 0x11, 0x01, 0x03, 0x00, false, false, ALL },
+ { TCK_MAX, 0x13, 0x01, 0x00, 0x00, false, false, ALL },
+ { CAS_LATENCIES_SUPPORTED_DDR4, 0x17, 0x04, 0x00, 0x00, true, false, ALL },
+ { TRFC1_MIN, 0x1f, 0x02, 0x00, 0x00, true, false, ALL },
+ { TRFC2_MIN, 0x21, 0x02, 0x00, 0x00, true, false, ALL },
+ { TRFC4_MIN, 0x23, 0x02, 0x00, 0x00, true, false, ALL },
+ { TRRDS_MIN, 0x26, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRRDL_MIN, 0x27, 0x01, 0x00, 0x00, false, false, ALL },
+ { TCCDL_MIN, 0x28, 0x01, 0x00, 0x00, false, false, ALL },
+ { CONNECTOR_SDRAM_MAP, 0x3C, 0x12, 0x00, 0x00, false, false, ALL },
+ { TCCDL_FINE_OFFSET, 0x75, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRRDL_FINE_OFFSET, 0x76, 0x01, 0x00, 0x00, false, false, ALL },
+ { TRRDS_FINE_OFFSET, 0x77, 0x01, 0x00, 0x00, false, false, ALL },
+ { TCKMAX_FINE_OFFSET, 0x7c, 0x01, 0x00, 0x00, false, false, ALL },
+ { BASE_CONFIG_CRC, 0x7f, 0x02, 0x00, 0x00, true, false, ALL },
+ // Module Specific fields supported on DDR4 only
+ { ENTIRE_SPD, 0x00, 0x200, 0x00, 0x00, false, false, ALL },
+ //---------------------------------------------------------------------------------------
+};
+
+
+}; // end SPD namespace
+
+#endif // __SPDDDR4_DDR4_H
diff --git a/src/usr/vpd/test/spdtest.H b/src/usr/vpd/test/spdtest.H
index bd7f6ef5b..a2e4c7b70 100755
--- a/src/usr/vpd/test/spdtest.H
+++ b/src/usr/vpd/test/spdtest.H
@@ -43,6 +43,7 @@
#include <vpd/spdenums.H>
#include "../spdDDR3.H"
#include "../spdDDR4.H"
+#include "../spdDDR4_DDIMM.H"
#include "../spd.H"
extern trace_desc_t* g_trac_spd;
@@ -117,16 +118,31 @@ class SPDTest: public CxxTest::TestSuite
uint8_t memType = 0x0;
err = getMemType( theTarget,
memType );
+ if( err )
+ {
+ fails++;
+ TS_FAIL("testSpdRead- Failure reading Basic memory type!" );
+ errlCommit( err,
+ VPD_COMP_ID );
+ break;
+ }
+ // Get the module type.
+ modSpecTypes_t modType = NA;
+ err = getModType(modType,
+ theTarget,
+ memType,
+ VPD::AUTOSELECT);
if( err )
{
fails++;
- TS_FAIL( "testSpdRead- Failure reading Basic memory type!" );
+ TS_FAIL("testSpdRead- Failure reading memory module type!");
errlCommit( err,
VPD_COMP_ID );
- break;;
+ break;
}
+
for( uint64_t keyword = SPD::SPD_FIRST_NORM_KEYWORD;
keyword <= SPD::SPD_LAST_NORM_KEYWORD; keyword++ )
{
@@ -154,14 +170,29 @@ class SPDTest: public CxxTest::TestSuite
}
else if( SPD_DDR4_TYPE == memType )
{
+ size_t dataSize = (modType == DDIMM)
+ ? (sizeof(ddr4DDIMMData)/sizeof(ddr4DDIMMData[0]))
+ : (sizeof(ddr4Data)/sizeof(ddr4Data[0]));
+
for( entry = 0;
- entry < (sizeof(ddr4Data)/sizeof(ddr4Data[0]));
+ entry < dataSize;
entry++ )
{
- if( keyword == ddr4Data[entry].keyword )
+ if (modType == DDIMM)
{
- theSize = ddr4Data[entry].length;
- break;
+ if( keyword == ddr4DDIMMData[entry].keyword )
+ {
+ theSize = ddr4DDIMMData[entry].length;
+ break;
+ }
+ }
+ else
+ {
+ if( keyword == ddr4Data[entry].keyword )
+ {
+ theSize = ddr4Data[entry].length;
+ break;
+ }
}
}
}
@@ -304,6 +335,21 @@ class SPDTest: public CxxTest::TestSuite
break;
}
+ // Get the module type.
+ modSpecTypes_t modType = NA;
+ err = getModType(modType,
+ theTarget,
+ memType,
+ VPD::AUTOSELECT);
+ if( err )
+ {
+ fails++;
+ TS_FAIL("testSpdRead- Failure reading memory module type!");
+ errlCommit( err,
+ VPD_COMP_ID );
+ break;
+ }
+
// Get the size
if( SPD_DDR3_TYPE == memType )
{
@@ -320,14 +366,29 @@ class SPDTest: public CxxTest::TestSuite
}
else if( SPD_DDR4_TYPE == memType )
{
+ size_t dataSize = (modType == DDIMM)
+ ? (sizeof(ddr4DDIMMData)/sizeof(ddr4DDIMMData[0]))
+ : (sizeof(ddr4Data)/sizeof(ddr4Data[0]));
+
for( uint32_t entry = 0;
- entry < (sizeof(ddr4Data)/sizeof(ddr4Data[0]));
+ entry < dataSize;
entry++ )
{
- if( SPD::DIMM_BAD_DQ_DATA == ddr4Data[entry].keyword )
+ if (modType == DDIMM)
{
- theSize = ddr4Data[entry].length;
- break;
+ if( SPD::DIMM_BAD_DQ_DATA == ddr4DDIMMData[entry].keyword )
+ {
+ theSize = ddr4DDIMMData[entry].length;
+ break;
+ }
+ }
+ else
+ {
+ if( SPD::DIMM_BAD_DQ_DATA == ddr4Data[entry].keyword )
+ {
+ theSize = ddr4Data[entry].length;
+ break;
+ }
}
}
}
@@ -343,6 +404,14 @@ class SPDTest: public CxxTest::TestSuite
break;
}
+ if( 0 == theSize )
+ {
+ // memType not supported or Keyword not supported on
+ // this memType
+ cmds++;
+ break;
+ }
+
// Allocate data buffer
origData = static_cast<uint8_t*>(malloc( theSize ));
@@ -892,6 +961,21 @@ class SPDTest: public CxxTest::TestSuite
break;
}
+ // Get the module type.
+ modSpecTypes_t modType = NA;
+ err = getModType(modType,
+ theTarget,
+ memType,
+ VPD::AUTOSELECT);
+ if( err )
+ {
+ fails++;
+ TS_FAIL("testSpdRead- Failure reading memory 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++ )
@@ -922,15 +1006,31 @@ class SPDTest: public CxxTest::TestSuite
}
else if( SPD_DDR4_TYPE == memType )
{
+ size_t dataSize = (modType == DDIMM)
+ ? (sizeof(ddr4DDIMMData)/sizeof(ddr4DDIMMData[0]))
+ : (sizeof(ddr4Data)/sizeof(ddr4Data[0]));
+
for( entry = 0;
- entry < (sizeof(ddr4Data)/sizeof(ddr4Data[0]));
+ entry < dataSize;
entry++ )
{
- if( keyword == ddr4Data[entry].keyword )
+ if (modType == DDIMM)
{
- kwdData = ddr4Data[entry];
- theSize = ddr4Data[entry].length;
- break;
+ if( keyword == ddr4DDIMMData[entry].keyword )
+ {
+ kwdData = ddr4DDIMMData[entry];
+ theSize = ddr4DDIMMData[entry].length;
+ break;
+ }
+ }
+ else
+ {
+ if( keyword == ddr4Data[entry].keyword )
+ {
+ kwdData = ddr4Data[entry];
+ theSize = ddr4Data[entry].length;
+ break;
+ }
}
}
}
OpenPOWER on IntegriCloud