summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/include/usr/hwpf/hwp/dimmBadDqBitmapAccessHwp.H44
-rw-r--r--src/include/usr/hwpf/hwp/mvpd_accessors/getMBvpdSpareDramData.H56
-rw-r--r--src/include/usr/hwpf/hwpf_reasoncodes.H2
-rw-r--r--src/include/usr/hwpf/plat/fapiPlatAttributeService.H75
-rw-r--r--src/usr/hwpf/hwp/dimmBadDqBitmapAccessHwp.C220
-rw-r--r--src/usr/hwpf/hwp/dimmBadDqBitmapFuncs.C30
-rw-r--r--src/usr/hwpf/hwp/dimm_spd_attributes.xml64
-rw-r--r--src/usr/hwpf/hwp/fapiTestHwpDq.C104
-rw-r--r--src/usr/hwpf/hwp/mvpd_accessors/getMBvpdSpareDramData.C210
-rw-r--r--src/usr/hwpf/hwp/mvpd_accessors/mvpd.mk3
-rw-r--r--src/usr/hwpf/plat/fapiPlatAttributeService.C145
11 files changed, 805 insertions, 148 deletions
diff --git a/src/include/usr/hwpf/hwp/dimmBadDqBitmapAccessHwp.H b/src/include/usr/hwpf/hwp/dimmBadDqBitmapAccessHwp.H
index fc7703ebc..7a3eb9925 100644
--- a/src/include/usr/hwpf/hwp/dimmBadDqBitmapAccessHwp.H
+++ b/src/include/usr/hwpf/hwp/dimmBadDqBitmapAccessHwp.H
@@ -1,25 +1,25 @@
-// IBM_PROLOG_BEGIN_TAG
-// This is an automatically generated prolog.
-//
-// $Source: src/include/usr/hwpf/hwp/dimmBadDqBitmapAccessHwp.H $
-//
-// IBM CONFIDENTIAL
-//
-// COPYRIGHT International Business Machines Corp. 2012
-//
-// p1
-//
-// Object Code Only (OCO) source materials
-// Licensed Internal Code Source Materials
-// IBM HostBoot Licensed Internal Code
-//
-// The source code for this program is not published or other-
-// wise divested of its trade secrets, irrespective of what has
-// been deposited with the U.S. Copyright Office.
-//
-// Origin: 30
-//
-// IBM_PROLOG_END
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/usr/hwpf/hwp/dimmBadDqBitmapAccessHwp.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2012,2013 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
/**
* @file dimmBadDqBitmapAccessHwp.H
*
diff --git a/src/include/usr/hwpf/hwp/mvpd_accessors/getMBvpdSpareDramData.H b/src/include/usr/hwpf/hwp/mvpd_accessors/getMBvpdSpareDramData.H
new file mode 100644
index 000000000..6e05fb3f3
--- /dev/null
+++ b/src/include/usr/hwpf/hwp/mvpd_accessors/getMBvpdSpareDramData.H
@@ -0,0 +1,56 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/usr/hwpf/hwp/mvpd_accessors/getMBvpdSpareDramData.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2013 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef GETMBVPDSPAREDRAMDATA_H_
+#define GETMBVPDSPAREDRAMDATA_H_
+
+#include <fapi.H>
+#include <dimmConsts.H>
+
+typedef fapi::ReturnCode (*getMBvpdSpareDramData_FP_t)(
+ const fapi::Target &,
+ const fapi::Target &,
+ uint8_t &);
+
+extern "C"
+{
+
+/**
+ * @brief FW Team HWP that, for C-DIMMs, queries MBvpd to determine spare DRAM
+ * availability and, for IS-DIMMS, returns NO_SPARE.
+ *
+ * This HWP should be called through the VPD_DIMM_SPARE attribute.
+ *
+ * @param[in] i_mba Reference to MBA Target associated with the DIMM.
+ * @param[in] i_dimm Reference to DIMM Target.
+ * @param[out] o_data Reference to spare DRAM data.
+ *
+ * @return ReturnCode
+ */
+fapi::ReturnCode getMBvpdSpareDramData(
+ const fapi::Target & i_mba,
+ const fapi::Target & i_dimm,
+ uint8_t &o_data);
+
+}
+
+#endif
diff --git a/src/include/usr/hwpf/hwpf_reasoncodes.H b/src/include/usr/hwpf/hwpf_reasoncodes.H
index ea80fbfc2..871297e4c 100644
--- a/src/include/usr/hwpf/hwpf_reasoncodes.H
+++ b/src/include/usr/hwpf/hwpf_reasoncodes.H
@@ -60,6 +60,8 @@ namespace fapi
MOD_VDDR_PROC_MSG = 0x15,
MOD_VDDR_PROC_VDDR_MSG = 0x16,
MOD_VDDR_SEND_MSG = 0x17,
+ MOD_PLAT_ATTR_SVC_GET_MIRR_DATA = 0x18,
+ MOD_PLAT_ATTR_SVC_GET_SPARE_DATA = 0x19,
};
/**
diff --git a/src/include/usr/hwpf/plat/fapiPlatAttributeService.H b/src/include/usr/hwpf/plat/fapiPlatAttributeService.H
index 89b876a30..670b5125f 100644
--- a/src/include/usr/hwpf/plat/fapiPlatAttributeService.H
+++ b/src/include/usr/hwpf/plat/fapiPlatAttributeService.H
@@ -36,6 +36,7 @@
* mjjones 06/27/2011 Created.
* bofferdn 09/13/2011 Support fapi->hb mapping
* thi 01/28/2013 Add SPD CUSTOM attr
+ * dedahle 06/20/2013 Add Bad DIMM DQ Bitmap attr
*/
#ifndef FAPIPLATATTRIBUTESERVICE_H_
@@ -57,6 +58,7 @@
#include <hwpf/hwp/mvpd_accessors/getMBvpdAddrMirrorData.H>
#include <hwpf/hwp/mvpd_accessors/getMBvpdTermData.H>
#include <hwpf/hwp/mvpd_accessors/getMBvpdSlopeInterceptData.H>
+#include <hwpf/hwp/mvpd_accessors/getMBvpdSpareDramData.H>
#include <vpd/spdenums.H>
#include <dimmConsts.H>
#include <util/singleton.H>
@@ -499,6 +501,59 @@ fapi::ReturnCode fapiPlatGetSlopeInterceptData (
const fapi::Target * i_pTarget,
const fapi::MBvpdSlopeIntercept i_attr,
uint32_t & o_Val);
+
+//------------------------------------------------------------------------------
+// Prototypes to support BAD_DQ_BITMAP attribute
+// See dimm_spd_attributes.xml for detailed descriptions
+//------------------------------------------------------------------------------
+
+/**
+ * @brief This function is called by the FAPI_ATTR_GET macro when getting
+ * the Bad DQ Bitmap attribute
+ * It should not be called directly.
+ *
+ * @param[in] i_pTarget Target pointer
+ * @param[out] o_data Bad DIMM DQ Bitmap
+ * @return ReturnCode. Zero on success, else platform specified error
+ */
+fapi::ReturnCode fapiPlatDimmGetBadDqBitmap (
+ const fapi::Target * i_pTarget,
+ uint8_t (&o_data)[DIMM_DQ_MAX_DIMM_RANKS]\
+ [DIMM_DQ_RANK_BITMAP_SIZE]);
+
+/**
+ * @brief This function is called by the FAPI_ATTR_SET macro when setting
+ * the Bad DQ Bitmap attribute
+ * It should not be called directly.
+ *
+ * @param[in] i_pTarget Target pointer
+ * @param[in] i_data Bad DIMM DQ Bitmap
+ * @return ReturnCode. Zero on success, else platform specified error
+ */
+fapi::ReturnCode fapiPlatDimmSetBadDqBitmap (
+ const fapi::Target * i_pTarget,
+ uint8_t (&i_data)[DIMM_DQ_MAX_DIMM_RANKS]\
+ [DIMM_DQ_RANK_BITMAP_SIZE]);
+
+//------------------------------------------------------------------------------
+// Prototype to support VPD_DIMM_SPARE attribute
+// See dimm_spd_attributes.xml for detailed description
+//------------------------------------------------------------------------------
+
+/**
+ * @brief This function is called by the FAPI_ATTR_GET macro when getting
+ * the VPD DIMM Spare attribute
+ * It should not be called directly.
+ *
+ * @param[in] i_pTarget Target pointer
+ * @param[out] o_data Spare DRAM availability for DIMM
+ * @return ReturnCode. Zero on success, else platform specified error
+ */
+fapi::ReturnCode fapiPlatDimmGetSpareDram (
+ const fapi::Target * i_pTarget,
+ uint8_t &o_data);
+
+
} // namespace platAttrSvc
} // namespace fapi
@@ -1444,4 +1499,24 @@ fapi::ReturnCode fapiPlatGetSlopeInterceptData (
fapi::platAttrSvc::fapiPlatGetSlopeInterceptData\
(PTARGET, fapi::SUPPLIER_POWER_INTERCEPT , VAL)
+//------------------------------------------------------------------------------
+// MACRO to support BAD_DQ_BITMAP Attribute
+//------------------------------------------------------------------------------
+#define ATTR_BAD_DQ_BITMAP_GETMACRO(ID, PTARGET, VAL)\
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ?\
+ fapi::FAPI_RC_SUCCESS : fapi::platAttrSvc::fapiPlatDimmGetBadDqBitmap\
+ (PTARGET, VAL)
+#define ATTR_BAD_DQ_BITMAP_SETMACRO(ID, PTARGET, VAL)\
+ fapi::AttrOverrideSync::setAttrActionsFunc(fapi::ID, PTARGET,\
+ sizeof(VAL), &VAL),\
+ fapi::platAttrSvc::fapiPlatDimmSetBadDqBitmap(PTARGET, VAL)
+
+//------------------------------------------------------------------------------
+// MACRO to support VPD_DIMM_SPARE Attribute
+//------------------------------------------------------------------------------
+#define ATTR_VPD_DIMM_SPARE_GETMACRO(ID, PTARGET, VAL)\
+ fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ?\
+ fapi::FAPI_RC_SUCCESS : fapi::platAttrSvc::fapiPlatDimmGetSpareDram\
+ (PTARGET, VAL)
+
#endif // FAPIPLATATTRIBUTESERVICE_H_
diff --git a/src/usr/hwpf/hwp/dimmBadDqBitmapAccessHwp.C b/src/usr/hwpf/hwp/dimmBadDqBitmapAccessHwp.C
index 8b3f879ed..439f21ce0 100644
--- a/src/usr/hwpf/hwp/dimmBadDqBitmapAccessHwp.C
+++ b/src/usr/hwpf/hwp/dimmBadDqBitmapAccessHwp.C
@@ -33,6 +33,7 @@
* mjjones 02/17/2012 Created.
* mjjones 01/30/2013 Cope with platform endian
* differences
+ * dedahle 06/22/2013 Show unconnected DQ lines
*/
#include <dimmBadDqBitmapAccessHwp.H>
@@ -40,6 +41,8 @@
// DQ Data format in DIMM SPD
const uint32_t DIMM_BAD_DQ_MAGIC_NUMBER = 0xbadd4471;
const uint8_t DIMM_BAD_DQ_VERSION = 1;
+const uint8_t ECC_DQ_BYTE_NUMBER_INDEX = 8;
+const uint8_t SPARE_DRAM_DQ_BYTE_NUMBER_INDEX = 9;
struct dimmBadDqDataFormat
{
@@ -51,6 +54,83 @@ struct dimmBadDqDataFormat
uint8_t iv_bitmaps[DIMM_DQ_MAX_DIMM_RANKS][DIMM_DQ_RANK_BITMAP_SIZE];
};
+
+extern "C"
+{
+
+/**
+ * @brief Called by dimmBadDqBitmapAccessHwp() to query ATR_VPD_DIMM_SPARE
+ * and set bits for unconnected spare DRAM in caller's data.
+ *
+ *
+ * @param[in] i_dimm Reference to DIMM Target.
+ * @param[o] o_data Reference to Bad DQ Bitmap set by
+ * the caller. Only the SPARE_DRAM_DQ_BYTE_NUMBER_INDEX
+ * byte is modified by this function.
+ *
+ * @return ReturnCode
+ */
+
+fapi::ReturnCode dimmUpdateDqBitmapSpareByte(
+ const fapi::Target & i_dimm,
+ uint8_t (&o_data)[DIMM_DQ_MAX_DIMM_RANKS][DIMM_DQ_RANK_BITMAP_SIZE])
+{
+ fapi::ReturnCode l_rc;
+
+ do
+ {
+ // Spare DRAM Attribute
+ uint8_t l_dimmSpare = 0;
+ l_rc = FAPI_ATTR_GET(ATTR_VPD_DIMM_SPARE, &i_dimm, l_dimmSpare);
+ if (l_rc)
+ {
+ FAPI_ERR("dimmCheckSpareDram: "
+ "Error getting DRAM Spare data");
+ break;
+ }
+
+ // Bitmask and beginning bit shift values for decoding
+ // ATTR_VPD_DIMM_SPARE attribute as described in
+ // dimm_spd_attributes.xml.
+ uint8_t l_dimmMask = 0xC0;
+ uint8_t l_rankBitShift = 6;
+
+ // Iterate through each rank of this DIMM
+ for (uint8_t i = 0; i < DIMM_DQ_MAX_DIMM_RANKS; i++)
+ {
+ // Handle spare DRAM configuration cases
+ switch ((l_dimmSpare & l_dimmMask) >> l_rankBitShift)
+ {
+ case fapi::ENUM_ATTR_VPD_DIMM_SPARE_NO_SPARE:
+ // Set DQ bits reflecting unconnected
+ // spare DRAM in caller's data
+ o_data[i][SPARE_DRAM_DQ_BYTE_NUMBER_INDEX] = 0xFF;
+ break;
+
+ case fapi::ENUM_ATTR_VPD_DIMM_SPARE_LOW_NIBBLE:
+ o_data[i][SPARE_DRAM_DQ_BYTE_NUMBER_INDEX] = 0x0F;
+ break;
+
+ case fapi::ENUM_ATTR_VPD_DIMM_SPARE_HIGH_NIBBLE:
+ o_data[i][SPARE_DRAM_DQ_BYTE_NUMBER_INDEX] = 0xF0;
+ break;
+
+ case fapi::ENUM_ATTR_VPD_DIMM_SPARE_FULL_BYTE:
+ // As erroneous value will not be encountered.
+ default:
+ o_data[i][SPARE_DRAM_DQ_BYTE_NUMBER_INDEX] = 0x00;
+ break;
+ }
+
+ l_dimmMask >>= 2;
+ l_rankBitShift -= 2;
+ }
+ }while(0);
+ return l_rc;
+}
+
+}
+
extern "C"
{
@@ -82,20 +162,26 @@ fapi::ReturnCode dimmBadDqBitmapAccessHwp(
*(reinterpret_cast<uint8_t(*)[DIMM_DQ_SPD_DATA_SIZE]>
(new uint8_t[DIMM_DQ_SPD_DATA_SIZE]));
+ // Memory Bus Width Attribute
+ uint8_t l_eccBits = 0;
+
dimmBadDqDataFormat * l_pSpdData =
reinterpret_cast<dimmBadDqDataFormat *>(l_spdData);
// Get the Centaur DQ to DIMM Connector DQ Wiring attribute. Note that for
// C-DIMMs, this will return a simple 1:1 mapping. This code cannot tell
// the difference between C-DIMMs and IS-DIMMs
- l_rc = FAPI_ATTR_GET(ATTR_CEN_DQ_TO_DIMM_CONN_DQ, &i_dimm, l_wiringData);
-
- if (l_rc)
- {
- FAPI_ERR("dimmBadDqBitmapAccessHwp: Error getting wiring attribute");
- }
- else
+ do
{
+ l_rc = FAPI_ATTR_GET(ATTR_CEN_DQ_TO_DIMM_CONN_DQ,
+ &i_dimm, l_wiringData);
+
+ if (l_rc)
+ {
+ FAPI_ERR("dimmBadDqBitmapAccessHwp: "
+ "Error getting wiring attribute");
+ break;
+ }
if (i_get)
{
// Get the SPD DQ attribute
@@ -104,62 +190,96 @@ fapi::ReturnCode dimmBadDqBitmapAccessHwp(
if (l_rc)
{
FAPI_ERR("dimmBadDqBitmapAccessHwp: Error getting SPD data");
+ break;
+ }
+ // Zero caller's data
+ memset(io_data, 0, sizeof(io_data));
+ // Check the magic number and version number. Note that the
+ // magic number is stored in SPD in big endian format and
+ // platforms of any endianness can access it
+ if ((FAPI_BE32TOH(l_pSpdData->iv_magicNumber) !=
+ DIMM_BAD_DQ_MAGIC_NUMBER) ||
+ (l_pSpdData->iv_version != DIMM_BAD_DQ_VERSION))
+ {
+ FAPI_INF("dimmBadDqBitmapAccessHwp: SPD DQ not initialized");
}
else
{
- // Zero caller's data
- memset(io_data, 0, sizeof(io_data));
-
- // Check the magic number and version number. Note that the
- // magic number is stored in SPD in big endian format and
- // platforms of any endianness can access it
- if ((FAPI_BE32TOH(l_pSpdData->iv_magicNumber) !=
- DIMM_BAD_DQ_MAGIC_NUMBER) ||
- (l_pSpdData->iv_version != DIMM_BAD_DQ_VERSION))
- {
- // SPD DQ data not initialized, return zeros
- FAPI_INF("dimmBadDqBitmapAccessHwp: SPD DQ not initialized");
- }
- else
+ // Translate bitmap from DIMM DQ to Centaur DQ point of view
+ // for each rank
+ for (uint8_t i = 0; i < DIMM_DQ_MAX_DIMM_RANKS; i++)
{
- // Translate bitmap from DIMM DQ to Centaur DQ point of view
- // for each rank
- for (uint8_t i = 0; i < DIMM_DQ_MAX_DIMM_RANKS; i++)
+ // Iterate through all the DQ bits in the rank
+ for (uint8_t j = 0; j < DIMM_DQ_NUM_DQS; j++)
{
- // Iterate through all the DQ bits in the rank
- for (uint8_t j = 0; j < DIMM_DQ_NUM_DQS; j++)
+ // There is a byte for each 8 DQs, j/8 gives the
+ // byte number. The MSB in each byte is the lowest
+ // DQ, (0x80 >> (j % 8)) gives the bit mask
+ // corresponding to the DQ within the byte
+ if ((l_pSpdData->iv_bitmaps[i][j/8]) &
+ (0x80 >> (j % 8)))
{
- // There is a byte for each 8 DQs, j/8 gives the
- // byte number. The MSB in each byte is the lowest
- // DQ, (0x80 >> (j % 8)) gives the bit mask
- // corresponding to the DQ within the byte
- if ((l_pSpdData->iv_bitmaps[i][j/8]) &
- (0x80 >> (j % 8)))
+ // DIMM DQ bit is set in SPD data.
+ // Set Centaur DQ bit in caller's data.
+ // The wiring data maps Centaur DQ to DIMM DQ
+ // Find the Centaur DQ that maps to this DIMM DQ
+ uint8_t k = 0;
+ for (; k < DIMM_DQ_NUM_DQS; k++)
{
- // DIMM DQ bit is set in SPD data.
- // Set Centaur DQ bit in caller's data.
- // The wiring data maps Centaur DQ to DIMM DQ
- // Find the Centaur DQ that maps to this DIMM DQ
- uint8_t k = 0;
- for (; k < DIMM_DQ_NUM_DQS; k++)
+ if (l_wiringData[k] == j)
{
- if (l_wiringData[k] == j)
- {
- io_data[i][k/8] |= (0x80 >> (k % 8));
- break;
- }
+ io_data[i][k/8] |= (0x80 >> (k % 8));
+ break;
}
+ }
- if (k == DIMM_DQ_NUM_DQS)
- {
- FAPI_ERR("dimmBadDqBitmapAccessHwp: Centaur DQ not found for %d!",
- j);
- }
+ if (k == DIMM_DQ_NUM_DQS)
+ {
+ FAPI_INF("dimmBadDqBitmapAccessHwp: "
+ "Centaur DQ not found for %d!",j);
}
}
}
}
}
+ // Set bits for any unconnected DQs.
+ // First, check ECC.
+ l_rc = FAPI_ATTR_GET(ATTR_SPD_MODULE_MEMORY_BUS_WIDTH,
+ &i_dimm, l_eccBits);
+ if (l_rc)
+ {
+ FAPI_ERR("dimmBadDqBitmapAccessHwp: "
+ "Error getting ECC data");
+ break;
+ }
+
+ // The ATTR_SPD_MODULE_MEMORY_BUS_WIDTH contains ENUM values
+ // for bus widths of 8, 16, 32, and 64 bits both with ECC
+ // and without ECC. WExx ENUMS deonote the ECC extension
+ // is present, and all have bit 3 set. Therefore,
+ // it is only required to check against the WE8 = 0x08 ENUM
+ // value in order to determine if ECC lines are present.
+
+ // If ECCs are disconnected
+ if (!(fapi::ENUM_ATTR_SPD_MODULE_MEMORY_BUS_WIDTH_WE8 &
+ l_eccBits))
+ {
+ // Iterate through each rank and set DQ bits in
+ // caller's data.
+ for (uint8_t i = 0; i < DIMM_DQ_MAX_DIMM_RANKS; i++)
+ {
+ // Set DQ bits in caller's data
+ io_data[i][ECC_DQ_BYTE_NUMBER_INDEX] = 0xFF;
+ }
+ }
+ // Check spare DRAM
+ l_rc = dimmUpdateDqBitmapSpareByte(i_dimm, io_data);
+ if (l_rc)
+ {
+ FAPI_ERR("dimmBadDqBitmapAccessHwp: "
+ "Error getting spare DRAM data");
+ break;
+ }
}
else
{
@@ -196,13 +316,13 @@ fapi::ReturnCode dimmBadDqBitmapAccessHwp(
if (l_rc)
{
FAPI_ERR("dimmBadDqBitmapAccessHwp: Error setting SPD data");
+ break;
}
}
- }
+ }while(0);
delete [] &l_wiringData;
delete [] &l_spdData;
-
FAPI_INF("<<dimmBadDqBitmapAccessHwp");
return l_rc;
}
diff --git a/src/usr/hwpf/hwp/dimmBadDqBitmapFuncs.C b/src/usr/hwpf/hwp/dimmBadDqBitmapFuncs.C
index 788ee3223..67a4f5640 100644
--- a/src/usr/hwpf/hwp/dimmBadDqBitmapFuncs.C
+++ b/src/usr/hwpf/hwp/dimmBadDqBitmapFuncs.C
@@ -31,6 +31,9 @@
* Flag Defect/Feature User Date Description
* ------ -------------- ---------- ----------- ----------------------------
* mjjones 02/17/2012 Created.
+ * dedahle 06/20/2013 dimmGetBadDqBitmap/
+ * dimmSetBadDqBitmap funcs
+ * get/set ATTR_BAD_DQ_BITMAP
*/
#include <dimmBadDqBitmapFuncs.H>
@@ -39,16 +42,6 @@
extern "C"
{
-// TODO
-// For the dimmGetBadDqBitmap and dimmSetBadDqBitmap funcs, the original plan to
-// get/set the bitmap was to get/set a HWPF attribute called ATTR_BAD_DQ_BITMAP.
-// This would automatically call the dimmBadDqBitmapAccessHwp HWP which would
-// access the ATTR_SPD_BAD_DQ_DATA HWPF attribute and decode the data. However,
-// automatically bridging an attribute request to a HWP turns out to be
-// difficult due to the fact that the FAPI_ATTR_GET macro returns a ReturnCode
-// and the FAPI_EXEC_HWP macro takes a ReturnCode as parameter. For now call the
-// HWP directly and revisit later
-
//------------------------------------------------------------------------------
// Utility function to check parameters and find a DIMM target
@@ -158,20 +151,21 @@ fapi::ReturnCode dimmGetBadDqBitmap(const fapi::Target & i_mba,
if (!l_rc)
{
- // Get the Bad DQ bitmap by calling the dimmBadDqBitmapAccessHwp HWP.
+ // Get the Bad DQ bitmap by querying ATTR_BAD_DQ_BITMAP.
// Use a heap based array to avoid large stack alloc
uint8_t (&l_dqBitmap)[DIMM_DQ_MAX_DIMM_RANKS][DIMM_DQ_RANK_BITMAP_SIZE] =
*(reinterpret_cast<uint8_t(*)[DIMM_DQ_MAX_DIMM_RANKS][DIMM_DQ_RANK_BITMAP_SIZE]>
(new uint8_t[DIMM_DQ_MAX_DIMM_RANKS*DIMM_DQ_RANK_BITMAP_SIZE]));
- FAPI_EXEC_HWP(l_rc, dimmBadDqBitmapAccessHwp, l_dimm, l_dqBitmap, true);
+ l_rc = FAPI_ATTR_GET(ATTR_BAD_DQ_BITMAP, &l_dimm, l_dqBitmap);
if (l_rc)
{
- FAPI_ERR("dimmGetBadDqBitmap: Error from dimmBadDqBitmapAccessHwp");
+ FAPI_ERR("dimmGetBadDqBitmap: Error getting ATTR_BAD_DQ_BITMAP for dimm");
}
else
{
+ //Write contents of DQ bitmap for specific rank to o_data.
memcpy(o_data, l_dqBitmap[i_rank], DIMM_DQ_RANK_BITMAP_SIZE);
}
@@ -200,28 +194,28 @@ fapi::ReturnCode dimmSetBadDqBitmap(
if (!l_rc)
{
- // Get the Bad DQ bitmap by calling the dimmBadDqBitmapAccessHwp HWP.
+ // Get the Bad DQ bitmap by querying ATTR_BAD_DQ_BITMAP.
// Use a heap based array to avoid large stack alloc
uint8_t (&l_dqBitmap)[DIMM_DQ_MAX_DIMM_RANKS][DIMM_DQ_RANK_BITMAP_SIZE] =
*(reinterpret_cast<uint8_t(*)[DIMM_DQ_MAX_DIMM_RANKS][DIMM_DQ_RANK_BITMAP_SIZE]>
(new uint8_t[DIMM_DQ_MAX_DIMM_RANKS*DIMM_DQ_RANK_BITMAP_SIZE]));
- FAPI_EXEC_HWP(l_rc, dimmBadDqBitmapAccessHwp, l_dimm, l_dqBitmap, true);
+ l_rc = FAPI_ATTR_GET(ATTR_BAD_DQ_BITMAP, &l_dimm, l_dqBitmap);
if (l_rc)
{
- FAPI_ERR("dimmSetBadDqBitmap: Error from dimmBadDqBitmapAccessHwp (get)");
+ FAPI_ERR("dimmSetBadDqBitmap: Error getting ATTR_BAD_DQ_BITMAP for dimm");
}
else
{
// Add the rank bitmap to the DIMM bitmap and write the bitmap
memcpy(l_dqBitmap[i_rank], i_data, DIMM_DQ_RANK_BITMAP_SIZE);
- FAPI_EXEC_HWP(l_rc, dimmBadDqBitmapAccessHwp, l_dimm, l_dqBitmap, false);
+ l_rc = FAPI_ATTR_SET(ATTR_BAD_DQ_BITMAP, &l_dimm, l_dqBitmap);
if (l_rc)
{
- FAPI_ERR("dimmSetBadDqBitmap: Error from dimmBadDqBitmapAccessHwp (set)");
+ FAPI_ERR("dimmSetBadDqBitmap: Error setting ATTR_BAD_DQ_BITMAP for dimm");
}
}
diff --git a/src/usr/hwpf/hwp/dimm_spd_attributes.xml b/src/usr/hwpf/hwp/dimm_spd_attributes.xml
index 12eea1672..38d50c5f6 100644
--- a/src/usr/hwpf/hwp/dimm_spd_attributes.xml
+++ b/src/usr/hwpf/hwp/dimm_spd_attributes.xml
@@ -485,10 +485,11 @@ The following attributes can be queried from both DDR3 and DDR4 DIMMs
<id>ATTR_SPD_BAD_DQ_DATA</id>
<targetType>TARGET_TYPE_DIMM</targetType>
<description>
- Bad DQ pin data stored in DIMM SPD. This data is in a special format.
- This must only be called by a firmware HWP that knows how to decode the data.
- HWP/PLAT firmware that needs to get/set the Bad DQ Bitmap from a Centaur
- DQ point of view must call the dimmBadDqBitmapAccessHwp HWP.
+ Bad DQ pin data stored in DIMM SPD. This data is in a special fomat.
+ This must only be called by a firmware HWP that knows how to
+ decode the data. HWP/PLAT firmware that needs to get/set the
+ Bad DQ Bitmap from a Centaur DQ point of view must use the
+ ATTR_BAD_DQ_BITMAP attribute.
</description>
<valueType>uint8</valueType>
<array>80</array>
@@ -1298,4 +1299,59 @@ file
</attribute>
-->
+
+<attribute>
+ <id>ATTR_BAD_DQ_BITMAP</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Bad DQ bitmap from a Centaur:MBA point of view.
+ The data is a 10 byte bitmap for each of 4 possible ranks.
+ The bad DQ data is stored in DIMM SPD, it is stored in a special format
+ and is translated to a DIMM Connector point of view for IS-DIMMs.
+ All of these details are hidden from the user of this attribute.
+ </description>
+ <valueType>uint8</valueType>
+ <array>4 10</array>
+ <platInit/>
+ <writeable/>
+</attribute>
+
+<attribute>
+ <id>ATTR_VPD_DIMM_SPARE</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ Spare DRAM availability for each rank on the DIMM.
+ There are 8 DQ lines to spare DRAMs.
+ - NO_SPARE: No spare DRAMs
+ - LOW_NIBBLE: x4 DRAMs in use, one spare DRAM connected to SP_DQ0-3
+ - HIGH_NIBBLE: x4 DRAMs in use, one spare DRAM connected to SP_DQ4-7
+ - FULL_BYTE: Either
+ 1/ x4 DRAMs in use, two spare DRAMs connected to SP_DQ0-7
+ 2/ x8 DRAMs in use, one spare DRAM connected to SP_DQ0-7
+ For C-DIMMs, this is in a VPD field : Record:VSPD, Keyword:AM
+ For IS-DIMMs, the platform should return 0 indicating
+ no spares for any rank.
+ The top 2 bits are for rank 0 e.g:
+ if (((val AND 0xc0) >> 6) ==
+ ENUM_ATTR_VPD_DIMM_SPARE_LOW_NIBBLE) {...}
+ The next 2 bits are for rank 1 e.g:
+ if (((val AND 0x30) >> 4) ==
+ ENUM_ATTR_VPD_DIMM_SPARE_NO_SPARE) {...}
+ The next 2 bits are for rank 2 e.g:
+ if (((val AND 0x0c) >> 2) ==
+ ENUM_ATTR_VPD_DIMM_SPARE_HIGH_NIBBLE) {...}
+ The bottom 2 bits are for rank 3 e.g:
+ if ((val AND 0x03) ==
+ ENUM_ATTR_VPD_DIMM_SPARE_FULL_BYTE) {...}
+ </description>
+ <valueType>uint8</valueType>
+ <enum>
+ NO_SPARE = 0x00,
+ LOW_NIBBLE = 0x01,
+ HIGH_NIBBLE = 0x02,
+ FULL_BYTE = 0x03
+ </enum>
+ <platInit/>
+</attribute>
+
</attributes>
diff --git a/src/usr/hwpf/hwp/fapiTestHwpDq.C b/src/usr/hwpf/hwp/fapiTestHwpDq.C
index 9ea23ec89..6fadbe27d 100644
--- a/src/usr/hwpf/hwp/fapiTestHwpDq.C
+++ b/src/usr/hwpf/hwp/fapiTestHwpDq.C
@@ -1,26 +1,25 @@
-/* IBM_PROLOG_BEGIN_TAG
- * This is an automatically generated prolog.
- *
- * $Source: src/usr/hwpf/hwp/fapiTestHwpDq.C $
- *
- * IBM CONFIDENTIAL
- *
- * COPYRIGHT International Business Machines Corp. 2012
- *
- * p1
- *
- * Object Code Only (OCO) source materials
- * Licensed Internal Code Source Materials
- * IBM HostBoot Licensed Internal Code
- *
- * The source code for this program is not published or other-
- * wise divested of its trade secrets, irrespective of what has
- * been deposited with the U.S. Copyright Office.
- *
- * Origin: 30
- *
- * IBM_PROLOG_END_TAG
- */
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/hwpf/hwp/fapiTestHwpDq.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2012,2013 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
/**
* @file fapiTestHwpDq.C
*
@@ -102,48 +101,51 @@ fapi::ReturnCode fapiTestHwpDq(const fapi::Target & i_mba)
break;
}
- // Get the bad DQ Bitmap for the DIMM, rank 3
- l_rc = dimmGetBadDqBitmap(i_mba, l_port, l_dimm, 3, l_dqBitmap);
-
- if (l_rc)
+ // Get the bad DQ Bitmap for all ranks and print any non-zero data
+ uint8_t l_rank = 0;
+ for (l_rank = 0; l_rank < 3; l_rank++)
{
- FAPI_ERR("fapiTestHwpDq: Error from dimmGetBadDqBitmap");
- break;
- }
-
- // If the data is not all zeroes then skip the rest of the test, do not
- // want to modify any real Bad DQ records
- bool l_nonZeroData = false;
+ // Get the bad DQ Bitmap for the rank
+ l_rc = dimmGetBadDqBitmap(i_mba, l_port, l_dimm, l_rank,
+ l_dqBitmap);
- for (uint8_t i = 0; i < DIMM_DQ_RANK_BITMAP_SIZE; i++)
- {
- if (l_dqBitmap[i] != 0)
+ if (l_rc)
{
- FAPI_INF("fapiTestHwpDq: Non-zero DQ data, skipping test");
- l_nonZeroData = true;
+ FAPI_ERR("fapiTestHwpDq: Error from dimmGetBadDqBitmap");
break;
}
+
+ // Trace any bad DQs
+ for (uint8_t i = 0; i < DIMM_DQ_RANK_BITMAP_SIZE; i++)
+ {
+ if (l_dqBitmap[i] != 0)
+ {
+ FAPI_INF("fapiTestHwpDq: Non-zero DQ data. Rank:%d, Byte:%d, Val:0x02%x",
+ l_rank, i, l_dqBitmap[i]);
+ }
+ }
}
- if (l_nonZeroData)
+ if (l_rc)
{
break;
}
+ // Record the two bytes of the bad DQ bitmap that this function
+ // will change so that it can be restored
+ uint8_t l_origDq2 = l_dqBitmap[2];
+ uint8_t l_origDq6 = l_dqBitmap[6];
+
// Set 2 bad DQ bits
l_dqBitmap[2] = 0x40;
l_dqBitmap[6] = 0x20;
- // Set the bad DQ Bitmap
- l_rc = dimmSetBadDqBitmap(i_mba, 1, 0, 3, l_dqBitmap);
+ // Set the bad DQ Bitmap for the last rank
+ l_rc = dimmSetBadDqBitmap(i_mba, l_port, l_dimm, l_rank, l_dqBitmap);
if (l_rc)
{
FAPI_ERR("fapiTestHwpDq: Error from dimmSetBadDqBitmap");
-
- // TODO
- FAPI_ERR("fapiTestHwpDq: Waiting for SPD DD support for writes (story 35766)");
- l_rc = fapi::FAPI_RC_SUCCESS;
break;
}
@@ -151,7 +153,7 @@ fapi::ReturnCode fapiTestHwpDq(const fapi::Target & i_mba)
l_dqBitmap[2] = 0;
l_dqBitmap[6] = 0;
- l_rc = dimmGetBadDqBitmap(i_mba, 1, 0, 3, l_dqBitmap);
+ l_rc = dimmGetBadDqBitmap(i_mba, l_port, l_dimm, l_rank, l_dqBitmap);
if (l_rc)
{
@@ -169,11 +171,11 @@ fapi::ReturnCode fapiTestHwpDq(const fapi::Target & i_mba)
break;
}
- // Write the data back to zero
- l_dqBitmap[2] = 0;
- l_dqBitmap[6] = 0;
+ // Write the original data back
+ l_dqBitmap[2] = l_origDq2;
+ l_dqBitmap[6] = l_origDq6;
- l_rc = dimmSetBadDqBitmap(i_mba, 1, 0, 3, l_dqBitmap);
+ l_rc = dimmSetBadDqBitmap(i_mba, l_port, l_dimm, l_rank, l_dqBitmap);
if (l_rc)
{
diff --git a/src/usr/hwpf/hwp/mvpd_accessors/getMBvpdSpareDramData.C b/src/usr/hwpf/hwp/mvpd_accessors/getMBvpdSpareDramData.C
new file mode 100644
index 000000000..665a9e76c
--- /dev/null
+++ b/src/usr/hwpf/hwp/mvpd_accessors/getMBvpdSpareDramData.C
@@ -0,0 +1,210 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/hwpf/hwp/mvpd_accessors/getMBvpdSpareDramData.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2013 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include <stdint.h>
+
+// fapi support
+#include <fapi.H>
+#include <dimmConsts.H>
+#include <getMBvpdSpareDramData.H>
+
+extern "C"
+{
+using namespace fapi;
+
+fapi::ReturnCode getMBvpdSpareDramData(const fapi::Target &i_mba,
+ const fapi::Target &i_dimm,
+ uint8_t &o_data)
+
+{
+ // AM keyword layout
+ const uint8_t NUM_MBAS = 2; // Two MBAs per Centaur
+ const uint8_t NUM_PORTS = 2; // Two ports per MBA
+ const uint8_t NUM_DIMMS = 2; // Two DIMMS per port
+ const uint8_t NUM_MIRR_BYTES = 4; // Size of address mirror data
+
+ // Struct for AM Keyword buffer
+ // Contains a simple array for the address mirror data and
+ // a 2D array for the spare DRAM data.
+ struct MirrorData
+ {
+ uint8_t iv_mirrorData[NUM_MIRR_BYTES];
+ };
+ struct DimmSpareData
+ {
+ // This contains information for all ranks and is returned in o_data
+ uint8_t iv_dimmSpareData;
+ };
+ struct PortSpareData
+ {
+ DimmSpareData iv_dimmSpareData[NUM_DIMMS];
+ };
+ struct MbaSpareData
+ {
+ PortSpareData iv_portSpareData[NUM_PORTS];
+ };
+ struct AmKeyword
+ {
+ MirrorData mirrorData;
+ MbaSpareData iv_mbaSpareData[NUM_MBAS];
+ };
+
+ // Old VPD without the Spare Data
+ const uint8_t VPD_WITHOUT_SPARE_DATA_SIZE = sizeof(MirrorData);
+
+ // Current VPD AM keyword size
+ const uint32_t AM_KEYWORD_SIZE = sizeof(AmKeyword);
+ fapi::ReturnCode l_rc;
+ // Centaur target
+ fapi::Target l_mbTarget;
+ // MBvpd AM keyword buffer
+ AmKeyword * l_pAmBuffer = NULL;
+ uint32_t l_AmBufSize = sizeof(AmKeyword);
+
+ do
+ {
+ // Check to see if IS-DIMM
+ uint8_t l_dimmType = 0;
+ l_rc = FAPI_ATTR_GET(ATTR_SPD_CUSTOM, &i_dimm, l_dimmType);
+ if (l_rc)
+ {
+ FAPI_ERR("getMBvpdSpareDramData: "
+ "Error getting ATTR_SPD_CUSTOM");
+ break;
+ }
+ if (fapi::ENUM_ATTR_SPD_CUSTOM_NO == l_dimmType)
+ {
+ //IS-DIMM, return NO_SPARE
+ o_data = fapi::ENUM_ATTR_VPD_DIMM_SPARE_NO_SPARE;
+ break;
+ }
+
+ // find the Centaur memory buffer from the passed MBA
+ l_rc = fapiGetParentChip (i_mba,l_mbTarget);
+ if (l_rc)
+ {
+ FAPI_ERR("getMBvpdSpareDramData: Finding the parent mb failed ");
+ break;
+ }
+
+ // Read AM keyword field
+ l_pAmBuffer = new AmKeyword;
+ l_rc = fapiGetMBvpdField(fapi::MBVPD_RECORD_VSPD,
+ fapi::MBVPD_KEYWORD_AM,
+ l_mbTarget,
+ reinterpret_cast<uint8_t *>(l_pAmBuffer),
+ l_AmBufSize);
+
+ if (l_rc)
+ {
+ FAPI_ERR("getMBvpdSpareDramData: Read of AM keyword failed");
+ break;
+ }
+
+ // Check correct amount of data returned
+ if (l_AmBufSize < AM_KEYWORD_SIZE)
+ {
+
+ // If Old VPD
+ if (VPD_WITHOUT_SPARE_DATA_SIZE == l_AmBufSize)
+ {
+ // Because prior VPD AM keyword does not contain
+ // spare DRAM data, the ATTR_SPD_DRAM_WIDTH
+ // attribute is used to determine spare DRAM availability.
+ // If x4 configuration, assume LOW_NIBBLE.
+ // Otherwise, FULL_BYTE.
+ uint8_t l_dramWidth = 0;
+ l_rc = FAPI_ATTR_GET(ATTR_SPD_DRAM_WIDTH, &i_dimm, l_dramWidth);
+ if (l_rc)
+ {
+ FAPI_ERR("getMBvpdSpareDramData: "
+ "Error getting DRAM spare data");
+ break;
+ }
+ // If x4 configuration, low nibble.
+ if (fapi::ENUM_ATTR_SPD_DRAM_WIDTH_W4 == l_dramWidth)
+ {
+ o_data = fapi::ENUM_ATTR_VPD_DIMM_SPARE_LOW_NIBBLE;
+ break;
+ }
+ // Else, full spare.
+ else
+ {
+ o_data = fapi::ENUM_ATTR_VPD_DIMM_SPARE_FULL_BYTE;
+ break;
+ }
+ }
+
+ else
+ {
+ FAPI_ERR("getMBvpdSpareDramData: "
+ "Insufficient amount of data returned:"
+ " %u < %u", l_AmBufSize, AM_KEYWORD_SIZE);
+ const uint32_t & KEYWORD = fapi::MBVPD_KEYWORD_AM;
+ const uint32_t & RETURNED_SIZE = l_AmBufSize;
+ FAPI_SET_HWP_ERROR(l_rc,
+ RC_MBVPD_INSUFFICIENT_VPD_RETURNED);
+ break;
+ }
+ }
+
+
+ // Return the spare DRAM availability for particular dimm
+ // Find the position of the passed mba on the centuar
+ uint8_t l_mba = 0;
+ l_rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &i_mba, l_mba);
+ if (l_rc)
+ {
+ FAPI_ERR("getMBvpdSpareDramData: Get MBA position failed ");
+ break;
+ }
+ // Find the mba port this dimm is connected to
+ uint8_t l_mbaPort = 0;
+ l_rc = FAPI_ATTR_GET(ATTR_MBA_PORT, &i_dimm, l_mbaPort);
+ if (l_rc)
+ {
+ FAPI_ERR("getMBvpdSpareDramData: "
+ "Error getting MBA port number");
+ break;
+ }
+ // Find the dimm number associated with this dimm
+ uint8_t l_dimm = 0;
+ l_rc = FAPI_ATTR_GET(ATTR_MBA_DIMM, &i_dimm, l_dimm);
+ if (l_rc)
+ {
+ FAPI_ERR("getMBvpdSpareDramData: "
+ "Error getting dimm number");
+ break;
+ }
+
+ o_data = l_pAmBuffer->iv_mbaSpareData[l_mba].\
+ iv_portSpareData[l_mbaPort].\
+ iv_dimmSpareData[l_dimm].iv_dimmSpareData;
+
+ }while(0);
+
+ delete l_pAmBuffer;
+ l_pAmBuffer = NULL;
+ return l_rc;
+}
+
+} // extern "C"
diff --git a/src/usr/hwpf/hwp/mvpd_accessors/mvpd.mk b/src/usr/hwpf/hwp/mvpd_accessors/mvpd.mk
index 19ea33724..0f598f554 100644
--- a/src/usr/hwpf/hwp/mvpd_accessors/mvpd.mk
+++ b/src/usr/hwpf/hwp/mvpd_accessors/mvpd.mk
@@ -32,5 +32,6 @@ OBJS += getMvpdRing.o \
getMBvpdPhaseRotatorData.o \
getMBvpdAddrMirrorData.o \
getMBvpdTermData.o \
- getMBvpdSlopeInterceptData.o
+ getMBvpdSlopeInterceptData.o \
+ getMBvpdSpareDramData.o
diff --git a/src/usr/hwpf/plat/fapiPlatAttributeService.C b/src/usr/hwpf/plat/fapiPlatAttributeService.C
index 41d69d16b..c3ab3567a 100644
--- a/src/usr/hwpf/plat/fapiPlatAttributeService.C
+++ b/src/usr/hwpf/plat/fapiPlatAttributeService.C
@@ -46,6 +46,7 @@
#include <hwpf/hwp/mvpd_accessors/getMBvpdAddrMirrorData.H>
#include <hwpf/hwp/mvpd_accessors/getMBvpdTermData.H>
#include <hwpf/hwp/mvpd_accessors/getMBvpdSlopeInterceptData.H>
+#include <hwpf/hwp/mvpd_accessors/getMBvpdSpareDramData.H>
// The following file checks at compile time that all HWPF attributes are
// handled by Hostboot. This is done to ensure that the HTML file listing
@@ -1206,7 +1207,7 @@ fapi::ReturnCode fapiPlatGetAddrMirrorData (
/*@
* @errortype
- * @moduleid fapi::MOD_PLAT_ATTR_SVC_GET_TARG_ATTR
+ * @moduleid fapi::MOD_PLAT_ATTR_SVC_GET_MIRR_DATA
* @reasoncode fapi::RC_NO_SINGLE_MBA
* @userdata1 Number of MBAs
* @devdesc fapiPlatGetAddrMirrorData could not find the
@@ -1214,7 +1215,7 @@ fapi::ReturnCode fapiPlatGetAddrMirrorData (
*/
errlHndl_t l_pError = new ERRORLOG::ErrlEntry(
ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- fapi::MOD_PLAT_ATTR_SVC_GET_TARG_ATTR,
+ fapi::MOD_PLAT_ATTR_SVC_GET_MIRR_DATA,
fapi::RC_NO_SINGLE_MBA,
l_mbaList.size());
@@ -1318,6 +1319,146 @@ fapi::ReturnCode fapiPlatGetEnableAttr ( fapi::AttributeId i_id,
return l_rc;
}
+
+//------------------------------------------------------------------------------
+// Functions to support BAD_DQ_BITMAP_attribute
+// See dimm_spd_attributes.xml for detailed descriptions
+//------------------------------------------------------------------------------
+
+
+/**
+ * @brief This function is called by the FAPI_ATTR_GET macro when getting
+ * the Bad DQ Bitmap attribute
+ * It should not be called directly.
+ *
+ * @param[in] i_pTarget Target pointer
+ * @param[out] o_data Bad DIMM DQ Bitmap
+ * @return ReturnCode. Zero on success, else platform specified error
+ */
+fapi::ReturnCode fapiPlatDimmGetBadDqBitmap (
+ const fapi::Target * i_pTarget,
+ uint8_t (&o_data)[DIMM_DQ_MAX_DIMM_RANKS]\
+ [DIMM_DQ_RANK_BITMAP_SIZE])
+{
+ fapi::ReturnCode l_rc;
+ FAPI_EXEC_HWP(l_rc, dimmBadDqBitmapAccessHwp, *i_pTarget, o_data, true);
+
+ if (l_rc)
+ {
+ FAPI_ERR("dimmGetBadDqBitmap: "
+ "Error from dimmBadDqBitmapAccessHwp (get)");
+ }
+ return l_rc;
+}
+
+
+/**
+ * @brief This function is called by the FAPI_ATTR_SET macro when setting
+ * the Bad DQ Bitmap attribute
+ * It should not be called directly.
+ *
+ * @param[in] i_pTarget Target pointer
+ * @param[in] i_data Bad DIMM DQ Bitmap
+ * @return ReturnCode. Zero on success, else platform specified error
+ */
+fapi::ReturnCode fapiPlatDimmSetBadDqBitmap (
+ const fapi::Target * i_pTarget,
+ uint8_t (&i_data)[DIMM_DQ_MAX_DIMM_RANKS]\
+ [DIMM_DQ_RANK_BITMAP_SIZE])
+{
+ fapi::ReturnCode l_rc;
+ FAPI_EXEC_HWP(l_rc, dimmBadDqBitmapAccessHwp, *i_pTarget, i_data, false);
+
+ if (l_rc)
+ {
+ FAPI_ERR("dimmSetBadDqBitmap: "
+ "Error from dimmBadDqBitmapAccessHwp (set)");
+ }
+ return l_rc;
+}
+
+//------------------------------------------------------------------------------
+// Function to support VPD_DIMM_SPARE attribute
+// See dimm_spd_attributes.xml for detailed description
+//------------------------------------------------------------------------------
+
+/**
+ * @brief This function is called by the FAPI_ATTR_GET macro when getting
+ * the VPD DIMM Spare attribute
+ * It should not be called directly.
+ *
+ * @param[in] i_pTarget Target pointer
+ * @param[out] o_data Spare DRAM availability for DIMM
+ * @return ReturnCode. Zero on success, else platform specified error
+ */
+fapi::ReturnCode fapiPlatDimmGetSpareDram (
+ const fapi::Target * i_pTarget,
+ uint8_t &o_data)
+{
+
+ fapi::ReturnCode l_rc;
+ TARGETING::Target * l_pTarget = NULL;
+ TARGETING::TargetHandleList l_mbaList;
+ do
+ {
+ // Get the Targeting Target
+ l_rc = getTargetingTarget(i_pTarget, l_pTarget);
+ if (l_rc)
+ {
+ FAPI_ERR("fapiPlatDimmGetSpareDram:Error from getTargetingTarget");
+ break;
+ }
+
+ // Find MBA target from DIMM target
+ getParentAffinityTargets(l_mbaList, l_pTarget, TARGETING::CLASS_UNIT,
+ TARGETING::TYPE_MBA, false);
+
+
+ if (l_mbaList.size() != 1 )
+ {
+ FAPI_ERR("fapiPlatDimmGetSpareDram: expect 1 mba %d ",
+ l_mbaList.size());
+
+ /*@
+ * @errortype
+ * @moduleid fapi::MOD_PLAT_ATTR_SVC_GET_SPARE_DATA
+ * @reasoncode fapi::RC_NO_SINGLE_MBA
+ * @userdata1 Number of MBAs
+ * @devdesc fapiPlatDimmGetSpareDram could not find the
+ * expected 1 mba from the passed dimm target
+ */
+ errlHndl_t l_pError = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ fapi::MOD_PLAT_ATTR_SVC_GET_SPARE_DATA,
+ fapi::RC_NO_SINGLE_MBA,
+ l_mbaList.size());
+
+ // Attach the error log to the fapi::ReturnCode
+ l_rc.setPlatError(reinterpret_cast<void *> (l_pError));
+ break;
+ }
+
+
+ // Create the Fapi Target
+ fapi::Target l_mbaTarget(TARGET_TYPE_MBA_CHIPLET,
+ static_cast<void *>(l_mbaList[0]));
+
+
+ FAPI_EXEC_HWP(l_rc, getMBvpdSpareDramData, l_mbaTarget, *i_pTarget,
+ o_data);
+
+ if (l_rc)
+ {
+ FAPI_ERR("fapiPlatDimmGetSpareDram: "
+ "Error from getMBvpdSpareDramData");
+ break;
+ }
+
+ }while(0);
+
+ return l_rc;
+}
+
} // End platAttrSvc namespace
} // End fapi namespace
OpenPOWER on IntegriCloud