diff options
Diffstat (limited to 'src/usr')
-rw-r--r-- | src/usr/diag/prdf/common/plat/mem/prdfMemCaptureData.C | 21 | ||||
-rw-r--r-- | src/usr/diag/prdf/common/plat/prdfPlatServices_common.C | 153 | ||||
-rwxr-xr-x | src/usr/diag/prdf/common/plat/prdfPlatServices_common.H | 3 | ||||
-rw-r--r-- | src/usr/diag/prdf/plat/prdfPlatServices.C | 51 | ||||
-rw-r--r-- | src/usr/diag/prdf/plat/prdfPlatServices.H | 13 |
5 files changed, 200 insertions, 41 deletions
diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemCaptureData.C b/src/usr/diag/prdf/common/plat/mem/prdfMemCaptureData.C index 835309b6a..4e566f5d3 100644 --- a/src/usr/diag/prdf/common/plat/mem/prdfMemCaptureData.C +++ b/src/usr/diag/prdf/common/plat/mem/prdfMemCaptureData.C @@ -77,17 +77,16 @@ void addExtMemMruData( const MemoryMru & i_memMru, errlHndl_t io_errl ) if ( isBufDimm ) { - // TODO RTC 169956 - //// Get the raw card type (Centaur DIMMs only). - //CEN_SYMBOL::WiringType cardType = CEN_SYMBOL::WIRING_INVALID; - //int32_t l_rc = getMemBufRawCardType( trgt, cardType ); - //if ( SUCCESS != l_rc ) - //{ - // PRDF_ERR( PRDF_FUNC "getMemBufRawCardType() failed. MBA:0x%08x", - // getHuid(trgt) ); - // break; - //} - //extMemMru.cardType = cardType; + // Get the raw card type (Centaur DIMMs only). + CEN_SYMBOL::WiringType cardType = CEN_SYMBOL::WIRING_INVALID; + int32_t l_rc = getMemBufRawCardType( trgt, cardType ); + if ( SUCCESS != l_rc ) + { + PRDF_ERR( PRDF_FUNC "getMemBufRawCardType() failed. MBA:0x%08x", + getHuid(trgt) ); + break; + } + extMemMru.cardType = cardType; } else { diff --git a/src/usr/diag/prdf/common/plat/prdfPlatServices_common.C b/src/usr/diag/prdf/common/plat/prdfPlatServices_common.C index 97ffc839f..805e4c7bb 100644 --- a/src/usr/diag/prdf/common/plat/prdfPlatServices_common.C +++ b/src/usr/diag/prdf/common/plat/prdfPlatServices_common.C @@ -682,8 +682,113 @@ void getDimmDqAttr<TYPE_DIMM>( TargetHandle_t i_target, } // end function getDimmDqAttr //------------------------------------------------------------------------------ +// Constants defined from Serial Presence Detect (SPD) specs +//--------------------------------------------------------------------- +const uint8_t SPD_IDX_MODSPEC_COM_REF_BASIC_MEMORY_TYPE = 0x02; +const uint8_t SPD_IDX_DDR3_MODSPEC_COM_REF_RAW_CARD_EXT = 0x3e; +const uint8_t SPD_IDX_DDR3_MODSPEC_COM_REF_RAW_CARD = 0x3e; +const uint8_t SPD_IDX_DDR4_MODSPEC_COM_REF_RAW_CARD_EXT = 0x82; +const uint8_t SPD_IDX_DDR4_MODSPEC_COM_REF_RAW_CARD = 0x82; + +const uint8_t RAW_CARD_EXT_MASK = 0x80; +const uint8_t RAW_CARD_EXT_SHIFT = 0x07; +const uint8_t RAW_CARD_MASK = 0x1f; +const uint8_t BASIC_MEMORY_TYPE_DDR4 = 0x0c; + +enum SPD_MODSPEC_COM_REF_RAW_CARD +{ + SPD_MODSPEC_COM_REF_RAW_CARD_A = 0x00, + SPD_MODSPEC_COM_REF_RAW_CARD_B = 0x01, + SPD_MODSPEC_COM_REF_RAW_CARD_C = 0x02, + SPD_MODSPEC_COM_REF_RAW_CARD_D = 0x03, +}; +//--------------------------------------------------------------------- + +int32_t getSpdModspecComRefRawCard( + const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_pTarget, + uint8_t & o_rawCard ) +{ +#define PRDF_FUNC "[PlatServices::getSpdModspecComRefRawCard] " + + int32_t rc = SUCCESS; + o_rawCard = WIRING_INVALID; + size_t l_size = 0; + uint8_t * l_blobData = nullptr; + + do{ + // Grab the SPD data for this DIMM + // This has an FSP and Hostboot implementation + rc = getSpdData(i_pTarget, l_blobData, l_size); + if (rc != SUCCESS) + { + break; + } + + // Now parse the SPD data for the RawCard + uint8_t l_card = 0; + uint8_t l_cardExt = 0; // 0 or 1 + + uint8_t RawCardIdx = SPD_IDX_DDR3_MODSPEC_COM_REF_RAW_CARD; + uint8_t RawCardExtIdx = SPD_IDX_DDR3_MODSPEC_COM_REF_RAW_CARD_EXT; + + if ( (l_size > SPD_IDX_MODSPEC_COM_REF_BASIC_MEMORY_TYPE) && + l_blobData[SPD_IDX_MODSPEC_COM_REF_BASIC_MEMORY_TYPE] == + BASIC_MEMORY_TYPE_DDR4 ) + { + RawCardIdx = SPD_IDX_DDR4_MODSPEC_COM_REF_RAW_CARD; + RawCardExtIdx = SPD_IDX_DDR4_MODSPEC_COM_REF_RAW_CARD_EXT; + } + + // Get the Reference Raw Card Extension (0 or 1) + if (l_size > RawCardExtIdx) + { + l_cardExt = ( (l_blobData[RawCardExtIdx] & RAW_CARD_EXT_MASK) >> + RAW_CARD_EXT_SHIFT ); + } + else + { + PRDF_ERR( PRDF_FUNC "SPD data size too small (%ld, RAW_CARD_EXT %d)", + l_size, RawCardExtIdx ); + rc = FAIL; + break; + } + + // Get the References Raw Card (bits 4-0) + // When Reference Raw Card Extension = 0 + // Reference raw cards A through AL + // When Reference Raw Card Extension = 1 + // Reference raw cards AM through CB + if (l_size > RawCardIdx) + { + l_card = (l_blobData[RawCardIdx] & RAW_CARD_MASK); + } + else + { + PRDF_ERR( PRDF_FUNC "SPD data size too small (%d, RAW_CARD %d)", + l_size, RawCardIdx ); + rc = FAIL; + break; + } + + // Raw Card = 0x1f(ZZ) means no JEDEC reference raw card design used. + // Have one ZZ in the return merged enumeration. + if (0x1f == l_card) + { + l_cardExt = 1; //Just one ZZ in the enumeration (0x3f) + } + + // Merge into a single enumeration + o_rawCard = (l_cardExt << 5) | l_card; + + } while (0); + + free(l_blobData); + + return rc; +#undef PRDF_FUNC +} + -/* TODO RTC 169956 int32_t getMemBufRawCardType( TargetHandle_t i_mba, WiringType & o_cardType ) { @@ -718,22 +823,11 @@ int32_t getMemBufRawCardType( TargetHandle_t i_mba, // All logical DIMMs connected to this MBA are on the same card as the // MBA so we can use any connected DIMM to query for the raw card type. - - errlHndl_t errl = NULL; - fapi::Target fapiDimm = getFapiTarget( l_dimmList[0] ); uint8_t l_cardType = WIRING_INVALID; - - FAPI_INVOKE_HWP( errl, - fapi::platAttrSvc::fapiPlatGetSpdModspecComRefRawCard, - &fapiDimm, - l_cardType ); - - if ( NULL != errl ) + o_rc = getSpdModspecComRefRawCard(l_dimmList[0], l_cardType); + if ( o_rc != SUCCESS ) { - PRDF_ERR( PRDF_FUNC "fapiPlatGetSpdModspecComRefRawCard() failed on" - "DIMM 0x%08X", getHuid(l_dimmList[0]) ); - PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT ); - o_rc = FAIL; break; + break; } uint8_t l_version = getDramGen<TYPE_MBA>( i_mba ); @@ -748,12 +842,12 @@ int32_t getMemBufRawCardType( TargetHandle_t i_mba, switch ( l_cardType ) { - case ENUM_ATTR_SPD_MODSPEC_COM_REF_RAW_CARD_A: - if (ENUM_ATTR_EFF_DRAM_GEN_DDR3 == l_version) + case SPD_MODSPEC_COM_REF_RAW_CARD_A: + if (CEN_EFF_DRAM_GEN_DDR3 == l_version) { o_cardType = CEN_TYPE_A; } - else if (ENUM_ATTR_EFF_DRAM_GEN_DDR4 == l_version) + else if (CEN_EFF_DRAM_GEN_DDR4 == l_version) { o_cardType = CEN_TYPE_A4; } @@ -763,12 +857,12 @@ int32_t getMemBufRawCardType( TargetHandle_t i_mba, } break; - case ENUM_ATTR_SPD_MODSPEC_COM_REF_RAW_CARD_B: - if (ENUM_ATTR_EFF_DRAM_GEN_DDR3 == l_version) + case SPD_MODSPEC_COM_REF_RAW_CARD_B: + if (CEN_EFF_DRAM_GEN_DDR3 == l_version) { o_cardType = CEN_TYPE_B; } // end if DDR3 - else if (ENUM_ATTR_EFF_DRAM_GEN_DDR4 == l_version) + else if (CEN_EFF_DRAM_GEN_DDR4 == l_version) { o_cardType = CEN_TYPE_B4; } // end else if DDR4 @@ -778,12 +872,12 @@ int32_t getMemBufRawCardType( TargetHandle_t i_mba, } // end else unknown DRAM version break; - case ENUM_ATTR_SPD_MODSPEC_COM_REF_RAW_CARD_C: - if (ENUM_ATTR_EFF_DRAM_GEN_DDR3 == l_version) + case SPD_MODSPEC_COM_REF_RAW_CARD_C: + if (CEN_EFF_DRAM_GEN_DDR3 == l_version) { o_cardType = CEN_TYPE_C; } - else if (ENUM_ATTR_EFF_DRAM_GEN_DDR4 == l_version) + else if (CEN_EFF_DRAM_GEN_DDR4 == l_version) { o_cardType = CEN_TYPE_C4; } @@ -793,12 +887,12 @@ int32_t getMemBufRawCardType( TargetHandle_t i_mba, } break; - case ENUM_ATTR_SPD_MODSPEC_COM_REF_RAW_CARD_D: - if (ENUM_ATTR_EFF_DRAM_GEN_DDR3 == l_version) + case SPD_MODSPEC_COM_REF_RAW_CARD_D: + if (CEN_EFF_DRAM_GEN_DDR3 == l_version) { o_cardType = CEN_TYPE_D; } - else if (ENUM_ATTR_EFF_DRAM_GEN_DDR4 == l_version) + else if (CEN_EFF_DRAM_GEN_DDR4 == l_version) { o_cardType = CEN_TYPE_D4; } @@ -812,13 +906,16 @@ int32_t getMemBufRawCardType( TargetHandle_t i_mba, o_cardType = WIRING_INVALID; // Anything unsupported } + PRDF_INF( PRDF_FUNC "DIMM 0x%08x - RawType 0x%02x, version = 0x%02x => 0x%02x card type", + getHuid(l_dimmList[0]), l_cardType, l_version, o_cardType ); + } while(0); return o_rc; #undef PRDF_FUNC } -*/ + //############################################################################## //## Maintenance Command class wrapper diff --git a/src/usr/diag/prdf/common/plat/prdfPlatServices_common.H b/src/usr/diag/prdf/common/plat/prdfPlatServices_common.H index 790fb3fb6..fd85583db 100755 --- a/src/usr/diag/prdf/common/plat/prdfPlatServices_common.H +++ b/src/usr/diag/prdf/common/plat/prdfPlatServices_common.H @@ -316,10 +316,9 @@ int32_t getDimmSpareConfig( TARGETING::TargetHandle_t i_mba, CenRank i_rank, * the raw card type currently is not supported. * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise. */ -/* TODO RTC 169956 int32_t getMemBufRawCardType( TARGETING::TargetHandle_t i_mbaTarget, CEN_SYMBOL::WiringType & o_wiringType ); -*/ + /** * @brief get DIMM DQ map from FAPI routines diff --git a/src/usr/diag/prdf/plat/prdfPlatServices.C b/src/usr/diag/prdf/plat/prdfPlatServices.C index c1a09b62e..be9b44c21 100644 --- a/src/usr/diag/prdf/plat/prdfPlatServices.C +++ b/src/usr/diag/prdf/plat/prdfPlatServices.C @@ -52,6 +52,7 @@ #include <iipMopRegisterAccess.h> #include <ibscomreasoncodes.H> #include <p9_proc_gettracearray.H> +#include <fapi2_spd_access.H> using namespace TARGETING; @@ -194,6 +195,56 @@ uint32_t putScom(TARGETING::TargetHandle_t i_target, BitString& io_bs, return rc; } +//------------------------------------------------------------------------------ +uint32_t getSpdData(TARGETING::TargetHandle_t i_target, + uint8_t *& o_data, + size_t & o_len) +{ +#define PRDF_FUNC "[PlatServices::getSPDdata] " + uint32_t rc = SUCCESS; + fapi2::ReturnCode l_rc; + + o_len = 0; + + const fapi2::Target<fapi2::TARGET_TYPE_DIMM> l_fapi2_dimm(i_target); + + do { + // SPD interface call with NULL blob to get size data + l_rc = fapi2::getSPD(l_fapi2_dimm, NULL, o_len); + + // Expect to return the size or non failure + if(l_rc != fapi2::FAPI2_RC_SUCCESS) + { + PRDF_ERR( PRDF_FUNC "Failed to get SPD size from DIMM with HUID= 0x%x, rc: 0x%02X", + TARGETING::get_huid(i_target), uint32_t(l_rc) ); + rc = FAIL; + break; + } + else if (o_len == 0) + { + PRDF_ERR( PRDF_FUNC "Failed to get SPD size data of DIMM with HUID= 0x%x", + TARGETING::get_huid(i_target) ); + rc = FAIL; + break; + } + + // allocate the blob data of mem size length to hold data + o_data = reinterpret_cast<uint8_t *>(malloc(o_len)); + memset(o_data,0 ,o_len); + + l_rc = fapi2::getSPD(l_fapi2_dimm, o_data, o_len); + if ( l_rc != fapi2::FAPI2_RC_SUCCESS ) + { + PRDF_ERR( PRDF_FUNC "Failed to read data from DIMM with HUID= 0x%x", + TARGETING::get_huid(i_target) ); + rc = FAIL; + break; + } + } while (0); + + return rc; +#undef PRDF_FUNC +} //############################################################################## //## Processor specific functions diff --git a/src/usr/diag/prdf/plat/prdfPlatServices.H b/src/usr/diag/prdf/plat/prdfPlatServices.H index 9168aab82..325695288 100644 --- a/src/usr/diag/prdf/plat/prdfPlatServices.H +++ b/src/usr/diag/prdf/plat/prdfPlatServices.H @@ -102,6 +102,19 @@ uint32_t getScom(TARGETING::TargetHandle_t i_target, BitString& io_bs, uint32_t putScom(TARGETING::TargetHandle_t i_target, BitString& io_bs, uint64_t i_address); +/** + * @brief Grabs the SPD record on DIMM target + * + * @param i_target DIMM target + * @param o_data SPD record data (malloc'd memory) + * @param o_len length of record + * + * @return SUCCESS or FAIL + */ +uint32_t getSpdData(TARGETING::TargetHandle_t i_target, + uint8_t *& o_data, + size_t & o_len); + //############################################################################## //## Memory specific functions //############################################################################## |