diff options
Diffstat (limited to 'src/usr/vpd/spd.C')
-rw-r--r-- | src/usr/vpd/spd.C | 851 |
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 ) { |