diff options
-rw-r--r-- | src/include/usr/vpd/spdenums.H | 4 | ||||
-rw-r--r-- | src/include/usr/vpd/vpdreasoncodes.H | 10 | ||||
-rwxr-xr-x | src/usr/targeting/common/xmltohb/attribute_types_hb.xml | 2 | ||||
-rw-r--r-- | src/usr/vpd/ocmb_spd.C | 79 | ||||
-rw-r--r-- | src/usr/vpd/ocmb_spd.H | 89 | ||||
-rw-r--r-- | src/usr/vpd/spd.C | 424 | ||||
-rwxr-xr-x | src/usr/vpd/spd.H | 35 | ||||
-rw-r--r-- | src/usr/vpd/spdDDR3.H | 136 | ||||
-rwxr-xr-x | src/usr/vpd/spdDDR4.H | 140 | ||||
-rwxr-xr-x | src/usr/vpd/spdDDR4_DDIMM.H | 137 | ||||
-rwxr-xr-x | src/usr/vpd/test/spdtest.H | 130 |
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; + } } } } |