summaryrefslogtreecommitdiffstats
path: root/src/usr/vpd/spd.C
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/vpd/spd.C')
-rw-r--r--src/usr/vpd/spd.C851
1 files changed, 507 insertions, 344 deletions
diff --git a/src/usr/vpd/spd.C b/src/usr/vpd/spd.C
index a58398e4a..47dfe0f83 100644
--- a/src/usr/vpd/spd.C
+++ b/src/usr/vpd/spd.C
@@ -48,10 +48,12 @@
#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>
+#include "ocmb_spd.H"
// ----------------------------------------------
// Trace definitions
@@ -115,12 +117,27 @@ const bool g_usePNOR = true;
*
* @param[in] i_dimmType - The DIMM to verify if valid
*
-* @return boolean - return true if given paramter is a known DIMM type,
+* @return boolean - return true if given parameter is a known DIMM type,
* false otherwise
*/
bool isValidDimmType ( uint8_t i_dimmType );
/**
+ * @brief Determines if the given DIMM type is a known DIMM type or not by
+ * calling the correct isValidDimmType function for OCMB_SPD or SPD.
+ *
+ * @param[in] i_dimmType - The DIMM to verify if valid
+ *
+ * @param[in] i_eepromType - The eeprom content type of the DIMM
+ *
+ * @return boolean - return true if given paramter is a known DIMM type,
+ * false otherwise
+ */
+bool isValidDimmType(uint8_t i_dimmType,
+ TARGETING::EEPROM_CONTENT_TYPE i_eepromType);
+
+
+/**
* @brief Compare two values and return whether e2 is greater than
* the e1 value. This is used during lower_bound to cut
* search time down.
@@ -140,18 +157,42 @@ bool compareEntries ( const KeywordData e1,
/**
* @brief This function will read the DIMM memory type.
*
- * @param[out] o_memType - The memory type value to return.
+ * @param[out] o_memType - The memory type value to return.
*
- * @param[in] i_target - The target to read data from.
+ * @param[in] i_target - The target to read data from.
*
- * @param[in] i_location - The SPD source (PNOR/SEEPROM).
+ * @param[in] i_location - The SPD source (PNOR/SEEPROM).
+ *
+ * @param[in] i_eepromSource - The EEPROM source (CACHE/HARDWARE).
+ * Default to AUTOSELECT.
*
* @return errlHndl_t - NULL if successful, otherwise a pointer
* to the error log.
*/
-errlHndl_t getMemType ( uint8_t & o_memType,
- TARGETING::Target * i_target,
- VPD::vpdCmdTarget i_location );
+errlHndl_t getMemType(uint8_t & o_memType,
+ TARGETING::Target * i_target,
+ VPD::vpdCmdTarget i_location,
+ EEPROM::EEPROM_SOURCE i_eepromSource = EEPROM::AUTOSELECT);
+
+/**
+ * @brief This function will read the DIMM memory type by calling the correct
+ * function given the eeprom content type.
+ *
+ * @param[out] o_memType - The memory type value to return.
+ *
+ * @param[in] i_target - The target to read data from.
+ *
+ * @param[in] i_eepromType - The Eeprom content type of the target.
+ *
+ * @param[in] i_eepromSource - The EEPROM source (CACHE/HARDWARE).
+ *
+ * @return errlHndl_t - NULL if successful, otherwise a pointer
+ * to the error log.
+ */
+errlHndl_t getMemType(uint8_t & o_memType,
+ TARGETING::Target * i_target,
+ TARGETING::EEPROM_CONTENT_TYPE i_eepromType,
+ EEPROM::EEPROM_SOURCE i_eepromSource);
/**
* @brief This function will read the DIMM module type.
@@ -173,26 +214,6 @@ errlHndl_t getModType ( modSpecTypes_t & o_modType,
VPD::vpdCmdTarget i_location );
/**
- * @brief This function will scan the table and return the entry
- * corresponding to the keyword being requested.
- *
- * @param[in] i_keyword - The keyword being requested.
- *
- * @param[in] i_memType - The memory type of the target.
- *
- * @param[in] i_target - Target (only used for callouts)
- *
- * @param[out] o_entry - The table entry corresponding to the keyword.
- *
- * @return errlHndl_t - NULL if successful, otherwise a pointer to
- * the error log.
- */
-errlHndl_t getKeywordEntry ( VPD::vpdKeyword i_keyword,
- uint64_t i_memType,
- TARGETING::Target * i_target,
- const KeywordData *& o_entry );
-
-/**
* @brief This function will set the size of SPD for the given target based on
* the DIMM type.
*
@@ -226,6 +247,29 @@ bool isValidDimmType ( const uint8_t i_dimmType )
( SPD_DDR4_TYPE == i_dimmType ) );
}
+
+bool isValidDimmType(uint8_t i_memType,
+ TARGETING::EEPROM_CONTENT_TYPE i_eepromType)
+{
+ bool isValid = false;
+
+// TODO RTC:204341 Add support for reading/write EECACHE during runtime
+#ifndef __HOSTBOOT_RUNTIME
+ if (i_eepromType == TARGETING::EEPROM_CONTENT_TYPE_ISDIMM)
+ {
+ isValid = isValidDimmType(i_memType);
+ }
+ else if (i_eepromType == TARGETING::EEPROM_CONTENT_TYPE_DDIMM)
+ {
+ isValid = isValidOcmbDimmType(i_memType);
+ }
+
+#endif
+
+ return isValid;
+}
+
+
// ------------------------------------------------------------------
// spdGetKeywordValue
// ------------------------------------------------------------------
@@ -456,11 +500,12 @@ errlHndl_t spdWriteKeywordValue ( DeviceFW::OperationType i_opType,
// ------------------------------------------------------------------
// spdFetchData
// ------------------------------------------------------------------
-errlHndl_t spdFetchData ( uint64_t i_byteAddr,
- size_t i_numBytes,
- void * o_data,
- TARGETING::Target * i_target,
- VPD::vpdCmdTarget i_location )
+errlHndl_t spdFetchData ( uint64_t i_byteAddr,
+ size_t i_numBytes,
+ void * o_data,
+ TARGETING::Target * i_target,
+ VPD::vpdCmdTarget i_location,
+ EEPROM::EEPROM_SOURCE i_eepromSource)
{
errlHndl_t err{nullptr};
@@ -516,7 +561,7 @@ errlHndl_t spdFetchData ( uint64_t i_byteAddr,
DEVICE_EEPROM_ADDRESS(
EEPROM::VPD_PRIMARY,
i_byteAddr,
- EEPROM::AUTOSELECT) );
+ i_eepromSource));
if( err )
{
TRACFCOMP(g_trac_spd,
@@ -640,12 +685,13 @@ errlHndl_t spdWriteData ( uint64_t i_offset,
// ------------------------------------------------------------------
// spdGetValue
// ------------------------------------------------------------------
-errlHndl_t spdGetValue ( VPD::vpdKeyword i_keyword,
- void * io_buffer,
- size_t & io_buflen,
- TARGETING::Target * i_target,
- uint64_t i_DDRRev,
- VPD::vpdCmdTarget i_location )
+errlHndl_t spdGetValue(VPD::vpdKeyword i_keyword,
+ void * io_buffer,
+ size_t & io_buflen,
+ TARGETING::Target * i_target,
+ uint64_t i_DDRRev,
+ VPD::vpdCmdTarget i_location,
+ EEPROM::EEPROM_SOURCE i_eepromSource)
{
errlHndl_t err{nullptr};
uint8_t * tmpBuffer = static_cast<uint8_t *>(io_buffer);
@@ -1247,6 +1293,36 @@ 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)
+ {
+ errl = ocmbFetchData(i_target,
+ i_byteAddr,
+ i_numBytes,
+ o_data,
+ EEPROM::AUTOSELECT);
+ }
+
+ return errl;
+}
+
// ------------------------------------------------------------------
// ddr4SpecialCases
// ------------------------------------------------------------------
@@ -1260,6 +1336,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 )
{
// ==================================================
@@ -1276,12 +1358,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;
@@ -1293,22 +1377,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;
@@ -1320,49 +1406,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;
// ==================================================
@@ -1685,12 +1776,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;
@@ -1701,263 +1786,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,
@@ -1987,9 +1852,10 @@ errlHndl_t checkModSpecificKeyword ( KeywordData i_kwdData,
// ------------------------------------------------------------------
// getMemType
// ------------------------------------------------------------------
-errlHndl_t getMemType ( uint8_t & o_memType,
- TARGETING::Target * i_target,
- VPD::vpdCmdTarget i_location )
+errlHndl_t getMemType(uint8_t & o_memType,
+ TARGETING::Target * i_target,
+ VPD::vpdCmdTarget i_location,
+ EEPROM::EEPROM_SOURCE i_eepromSource)
{
errlHndl_t err{nullptr};
@@ -1997,7 +1863,8 @@ errlHndl_t getMemType ( uint8_t & o_memType,
MEM_TYPE_SZ,
&o_memType,
i_target,
- i_location );
+ i_location,
+ i_eepromSource);
TRACUCOMP( g_trac_spd,
EXIT_MRK"SPD::getMemType() - MemType: 0x%02x, Error: %s",
@@ -2007,6 +1874,57 @@ errlHndl_t getMemType ( uint8_t & o_memType,
return err;
}
+
+errlHndl_t getMemType(uint8_t & o_memType,
+ TARGETING::Target * i_target,
+ TARGETING::EEPROM_CONTENT_TYPE i_eepromType,
+ EEPROM::EEPROM_SOURCE i_eepromSource)
+{
+ errlHndl_t err = nullptr;
+
+// @TODO RTC 204341 Implement for runtime
+#ifndef __HOSTBOOT_RUNTIME
+
+ if (i_eepromType == TARGETING::EEPROM_CONTENT_TYPE_ISDIMM)
+ {
+ err = getMemType(o_memType,
+ i_target,
+ VPD::AUTOSELECT,
+ i_eepromSource);
+ }
+ else if (i_eepromType == TARGETING::EEPROM_CONTENT_TYPE_DDIMM)
+ {
+ err = getMemType(o_memType,
+ i_target,
+ i_eepromSource);
+ }
+ else
+ {
+ /*@
+ * @errortype
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid VPD::VPD_GET_MEMTYPE
+ * @reasoncode VPD::VPD_INVALID_EEPROM_CONTENT_TYPE
+ * @userdata1 Eeprom Content Type Given
+ * @userdata2 Target HUID
+ * @devdesc An unsupported eeprom content type was supplied.
+ * @custdesc A problem occurred during the IPL
+ * of the system.
+ */
+ err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ VPD::VPD_GET_MEMTYPE,
+ VPD::VPD_INVALID_EEPROM_CONTENT_TYPE,
+ i_eepromType,
+ TARGETING::get_huid(i_target),
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ }
+
+#endif
+
+ return err;
+
+}
+
// ------------------------------------------------------------------
// getModType
// ------------------------------------------------------------------
@@ -2018,12 +1936,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)
{
@@ -2145,8 +2070,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
{
@@ -2354,6 +2289,214 @@ void setPartAndSerialNumberAttributes( TARGETING::Target * i_target )
TRACSSCOMP(g_trac_spd, EXIT_MRK"spd.C::setPartAndSerialNumberAttributes()");
}
+/*
+ * @brief Read keyword from SPD by determining which function to call based on
+ * eeprom content type.
+ *
+ * @param[in] i_target target to read data from
+ * @param[in] i_eepromType Eeprom content type of the target.
+ * @param[in] i_keyword keyword from spdenums.H to read
+ * @param[in] i_memType The memory type of this target.
+ * @param[in/out] io_buffer data buffer SPD will be written to
+ * @param[in/out] io_buflen length of the given data buffer
+ * @param[in] i_eepromSource The EEPROM source (CACHE/HARDWARE).
+ *
+ *
+ * @return errlHndl_t nullptr on success. Otherwise, error log.
+ */
+errlHndl_t readFromEepromSource(TARGETING::Target* i_target,
+ TARGETING::EEPROM_CONTENT_TYPE i_eepromType,
+ const VPD::vpdKeyword i_keyword,
+ const uint8_t i_memType,
+ void* io_buffer,
+ size_t& io_buflen,
+ EEPROM::EEPROM_SOURCE i_eepromSource)
+{
+ errlHndl_t err = nullptr;
+
+ TRACSSCOMP(g_trac_spd, ENTER_MRK
+ "readFromEepromSource: i_eepromSource %d , i_memType %d, i_eepromType %d",
+ i_eepromSource, i_memType, i_eepromType);
+
+// @TODO RTC 204341 Implement for runtime
+#ifndef __HOSTBOOT_RUNTIME
+ if (i_eepromType == TARGETING::EEPROM_CONTENT_TYPE_ISDIMM)
+ {
+ err = spdGetValue(i_keyword,
+ io_buffer,
+ io_buflen,
+ i_target,
+ i_memType,
+ VPD::SEEPROM,
+ i_eepromSource);
+ }
+ else if (i_eepromType == TARGETING::EEPROM_CONTENT_TYPE_DDIMM)
+ {
+ err = ocmbGetSPD(i_target,
+ io_buffer,
+ io_buflen,
+ i_keyword,
+ i_memType,
+ i_eepromSource);
+ }
+ else
+ {
+ /*@
+ * @errortype
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid VPD::VPD_READ_FROM_EEPROM_SOURCE
+ * @reasoncode VPD::VPD_INVALID_EEPROM_CONTENT_TYPE
+ * @userdata1 Eeprom Content Type Given
+ * @userdata2 Target HUID
+ * @devdesc An unsupported eeprom content type was supplied.
+ * @custdesc A problem occurred during the IPL
+ * of the system.
+ */
+ err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ VPD::VPD_READ_FROM_EEPROM_SOURCE,
+ VPD::VPD_INVALID_EEPROM_CONTENT_TYPE,
+ i_eepromType,
+ TARGETING::get_huid(i_target),
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ }
+#endif
+
+ return err;
+}
+
+
+// ------------------------------------------------------------------
+// cmpEecacheToEeprom
+// ------------------------------------------------------------------
+errlHndl_t cmpEecacheToEeprom(TARGETING::Target * i_target,
+ TARGETING::EEPROM_CONTENT_TYPE i_eepromType,
+ VPD::vpdKeyword i_keyword,
+ bool &o_match)
+{
+ errlHndl_t err = nullptr;
+
+ TRACSSCOMP(g_trac_spd, ENTER_MRK"cmpEecacheToEeprom()");
+
+ o_match = false;
+ do
+ {
+ // Read the Basic Memory Type from the Eeprom Cache
+ uint8_t memTypeCache(MEM_TYPE_INVALID);
+ err = getMemType(memTypeCache,
+ i_target,
+ i_eepromType,
+ EEPROM::CACHE);
+ if (err)
+ {
+ break;
+ }
+
+ if (!isValidDimmType(memTypeCache, i_eepromType))
+ {
+ TRACFCOMP(g_trac_spd, ERR_MRK
+ "cmpEecacheToEeprom() Invalid DIMM type found in cache copy of eeprom,"
+ " we will not be able to understand contents");
+ break;
+ }
+
+ // Read the Basic Memory Type from HARDWARE
+ uint8_t memTypeHardware(MEM_TYPE_INVALID);
+ err = getMemType(memTypeHardware,
+ i_target,
+ i_eepromType,
+ EEPROM::HARDWARE);
+ if (err)
+ {
+ break;
+ }
+
+ if (!isValidDimmType(memTypeHardware, i_eepromType))
+ {
+ // Leave o_match == false and exit.
+ TRACFCOMP(g_trac_spd, ERR_MRK"cmpEecacheToEeprom() Invalid DIMM type found in hw copy of eeprom");
+ break;
+ }
+
+ if (memTypeCache != memTypeHardware)
+ {
+ // CACHE and HARDWARE don't match.
+ // Leave o_match == false and exit.
+ break;
+ }
+
+ // Get the keyword size
+ const KeywordData* entry = nullptr;
+ err = getKeywordEntry(i_keyword,
+ memTypeHardware,
+ i_target,
+ entry);
+ if (err)
+ {
+ break;
+ }
+ size_t dataSize = entry->length;
+
+
+ // Read the keyword from HARDWARE
+ size_t sizeHardware = dataSize;
+ uint8_t dataHardware[sizeHardware];
+ err = readFromEepromSource(i_target,
+ i_eepromType,
+ i_keyword,
+ memTypeHardware,
+ dataHardware,
+ sizeHardware,
+ EEPROM::HARDWARE);
+ if (err)
+ {
+ break;
+ }
+
+ // Read the keyword from CACHE
+ size_t sizeCache = dataSize;
+ uint8_t dataCache[sizeCache];
+ err = readFromEepromSource(i_target,
+ i_eepromType,
+ i_keyword,
+ memTypeHardware,
+ dataCache,
+ sizeCache,
+ EEPROM::CACHE);
+ if (err)
+ {
+ // CACHE may not be loaded, ignore the error
+ delete err;
+ err = NULL;
+ break;
+ }
+
+ // Compare the HARDWARE/CACHE keyword size/data
+ if (sizeHardware != sizeCache)
+ {
+ // CACHE and HARDWARE don't match.
+ // Leave o_match == false and exit.
+ break;
+ }
+ if (memcmp(dataHardware, dataCache, sizeHardware))
+ {
+ // CACHE and HARDWARE don't match.
+ // Leave o_match == false and exit.
+ break;
+ }
+
+ o_match = true;
+
+ } while(0);
+
+ TRACDBIN(g_trac_spd, "Hardware data : ", dataHardware, sizeHardware);
+ TRACDBIN(g_trac_spd, "Cache data : ", dataCache, sizeCache);
+
+ TRACSSCOMP( g_trac_spd, EXIT_MRK"cmpEecacheToEeprom(): returning %s errors. o_match = 0x%X ",
+ (err ? "with" : "with no"), o_match );
+
+ return err;
+ }
+
// ------------------------------------------------------------------
// cmpPnorToSeeprom
// ------------------------------------------------------------------
@@ -2368,17 +2511,37 @@ errlHndl_t cmpPnorToSeeprom ( TARGETING::Target * i_target,
o_match = false;
do
{
- // Read the Basic Memory Type
- uint8_t memType(MEM_TYPE_INVALID);
- err = getMemType( memType,
+ // Read the Basic Memory Type from the Seeprom
+ uint8_t memTypeSeeprom(MEM_TYPE_INVALID);
+ err = getMemType( memTypeSeeprom,
i_target,
- VPD::AUTOSELECT );
+ VPD::SEEPROM );
if( err )
{
break;
}
- if( false == isValidDimmType(memType) )
+ if( false == isValidDimmType(memTypeSeeprom) )
+ {
+ break;
+ }
+
+ // Read the Basic Memory Type from PNOR
+ uint8_t memTypePnor(MEM_TYPE_INVALID);
+ err = getMemType( memTypePnor,
+ i_target,
+ VPD::PNOR );
+ if( err )
+ {
+ break;
+ }
+
+ if( false == isValidDimmType(memTypePnor) )
+ {
+ break;
+ }
+
+ if (memTypeSeeprom != memTypePnor)
{
break;
}
@@ -2386,7 +2549,7 @@ errlHndl_t cmpPnorToSeeprom ( TARGETING::Target * i_target,
// Get the keyword size
const KeywordData* entry = NULL;
err = getKeywordEntry( i_keyword,
- memType,
+ memTypePnor,
i_target,
entry );
if( err )
@@ -2403,7 +2566,7 @@ errlHndl_t cmpPnorToSeeprom ( TARGETING::Target * i_target,
dataPnor,
sizePnor,
i_target,
- memType,
+ memTypePnor,
VPD::PNOR );
if( err )
{
@@ -2420,7 +2583,7 @@ errlHndl_t cmpPnorToSeeprom ( TARGETING::Target * i_target,
dataSeeprom,
sizeSeeprom,
i_target,
- memType,
+ memTypePnor,
VPD::SEEPROM );
if( err )
{
OpenPOWER on IntegriCloud