summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/usr/diag/prdf/common/plat/mem/prdfMemCaptureData.C21
-rw-r--r--src/usr/diag/prdf/common/plat/prdfPlatServices_common.C153
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/prdfPlatServices_common.H3
-rw-r--r--src/usr/diag/prdf/plat/prdfPlatServices.C51
-rw-r--r--src/usr/diag/prdf/plat/prdfPlatServices.H13
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
//##############################################################################
OpenPOWER on IntegriCloud