diff options
Diffstat (limited to 'src/usr/hwpf')
-rw-r--r-- | src/usr/hwpf/fapi/fapiHwAccess.C | 38 | ||||
-rw-r--r-- | src/usr/hwpf/fapi/fapiReturnCode.C | 10 | ||||
-rw-r--r-- | src/usr/hwpf/fapi/fapiTarget.C | 27 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/dimmBadDqBitmapAccessHwp.C | 205 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/dimmBadDqBitmapFuncs.C | 230 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/dimm_attributes.xml | 59 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/dimm_errors.xml | 49 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/dimm_spd_attributes.xml (renamed from src/usr/hwpf/hwp/DIMM_SPD_attributes.xml) | 284 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/fapiHwpErrorInfo.xml | 12 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/fapiHwpExecInitFile.C | 5 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/fapiTestHwp.C | 6 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/fapiTestHwpConfig.C | 5 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/fapiTestHwpDq.C | 151 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/makefile | 5 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/unit_attributes.xml | 34 | ||||
-rw-r--r-- | src/usr/hwpf/makefile | 7 | ||||
-rw-r--r-- | src/usr/hwpf/plat/fapiPlatAttributeService.C | 117 | ||||
-rw-r--r-- | src/usr/hwpf/plat/fapiPlatTarget.C | 14 | ||||
-rw-r--r-- | src/usr/hwpf/test/hwpftest.H | 38 |
19 files changed, 1111 insertions, 185 deletions
diff --git a/src/usr/hwpf/fapi/fapiHwAccess.C b/src/usr/hwpf/fapi/fapiHwAccess.C index 901339341..9bb2ed630 100644 --- a/src/usr/hwpf/fapi/fapiHwAccess.C +++ b/src/usr/hwpf/fapi/fapiHwAccess.C @@ -38,6 +38,8 @@ * mjjones 09/14/2011 Prepended fapi to functions * and enabled all functions * mjjones 10/13/2011 util namespace change + * mjjones 02/21/2012 Use high performance Target + * toEcmdString */ #include <fapi.H> @@ -61,12 +63,8 @@ fapi::ReturnCode fapiGetScom(const fapi::Target& i_target, if( l_traceit ) { - // get the string representation of the target - char l_string[fapi::MAX_ECMD_STRING_LEN] = {0}; - i_target.toString(l_string); - FAPI_SCAN( "TRACE : GETSCOM : %s : %.16llX %.16llX", - l_string, + i_target.toEcmdString(), i_address, o_data.getDoubleWord( 0 ) ); } @@ -90,12 +88,8 @@ fapi::ReturnCode fapiPutScom(const fapi::Target& i_target, if( l_traceit ) { - // get the string representation of the target - char l_string[fapi::MAX_ECMD_STRING_LEN] = {0}; - i_target.toString(l_string); - FAPI_SCAN( "TRACE : PUTSCOM : %s : %.16llX %.16llX", - l_string, + i_target.toEcmdString(), i_address, i_data.getDoubleWord( 0 ) ); } @@ -119,12 +113,8 @@ fapi::ReturnCode fapiPutScomUnderMask(const fapi::Target& i_target, if( l_traceit ) { - // get the string representation of the target - char l_string[fapi::MAX_ECMD_STRING_LEN] = {0}; - i_target.toString(l_string); - FAPI_SCAN( "TRACE : PUTSCOMMASK : %s : %.16llX %.16llX %.16llX", - l_string, + i_target.toEcmdString(), i_address, i_data.getDoubleWord(0), i_mask.getDoubleWord(0)); @@ -148,12 +138,8 @@ fapi::ReturnCode fapiGetCfamRegister(const fapi::Target& i_target, if( l_traceit ) { - // get the string representation of the target - char l_string[fapi::MAX_ECMD_STRING_LEN] = {0}; - i_target.toString(l_string); - FAPI_SCAN( "TRACE : GETCFAMREG : %s : %.8X %.8X", - l_string, + i_target.toEcmdString(), i_address, o_data.getWord(0) ); } @@ -176,12 +162,8 @@ fapi::ReturnCode fapiPutCfamRegister(const fapi::Target& i_target, if( l_traceit ) { - // get the string representation of the target - char l_string[fapi::MAX_ECMD_STRING_LEN] = {0}; - i_target.toString(l_string); - FAPI_SCAN( "TRACE : PUTCFAMREG : %s : %.8X %.8X", - l_string, + i_target.toEcmdString(), i_address, i_data.getWord(0) ); } @@ -205,10 +187,6 @@ fapi::ReturnCode fapiModifyCfamRegister(const fapi::Target& i_target, if( l_traceit ) { - // get the string representation of the target - char l_string[fapi::MAX_ECMD_STRING_LEN] = {0}; - i_target.toString(l_string); - // get string representation of the modify mode const char * l_pMode = NULL; @@ -230,7 +208,7 @@ fapi::ReturnCode fapiModifyCfamRegister(const fapi::Target& i_target, } FAPI_SCAN( "TRACE : MODCFAMREG : %s : %.8X %.8X %s", - l_string, + i_target.toEcmdString(), i_address, i_data.getWord(0), l_pMode ); diff --git a/src/usr/hwpf/fapi/fapiReturnCode.C b/src/usr/hwpf/fapi/fapiReturnCode.C index 2af4ec44c..2de1f8e13 100644 --- a/src/usr/hwpf/fapi/fapiReturnCode.C +++ b/src/usr/hwpf/fapi/fapiReturnCode.C @@ -40,6 +40,7 @@ * ReturnCode * mjjones 09/22/2011 Added ErrorInfo Support * mjjones 01/12/2012 Enforce correct usage + * mjjones 02/22/2012 Allow user to add Target FFDC */ #include <fapiReturnCode.H> @@ -243,7 +244,6 @@ void ReturnCode::addErrorInfo(const void * const * i_pObjects, { // This is a regular FFDC data object that can be directly // memcopied - FAPI_ERR("addErrorInfo: Adding FFDC, size: %d", l_size); addEIFfdc(l_pObject, l_size); } else @@ -257,6 +257,14 @@ void ReturnCode::addErrorInfo(const void * const * i_pObjects, static_cast<const ecmdDataBufferBase *>(l_pObject); ReturnCodeFfdc::addEIFfdc(*this, *l_pDb); } + else if (l_size == ReturnCodeFfdc::EI_FFDC_SIZE_TARGET) + { + // The FFDC is a fapi::Target + FAPI_ERR("addErrorInfo: Adding fapi::Target FFDC"); + const fapi::Target * l_pTarget = + static_cast<const fapi::Target *>(l_pObject); + ReturnCodeFfdc::addEIFfdc(*this, *l_pTarget); + } else { FAPI_ERR("addErrorInfo: Unrecognized FFDC data: %d", diff --git a/src/usr/hwpf/fapi/fapiTarget.C b/src/usr/hwpf/fapi/fapiTarget.C index 5689b756f..b6305e581 100644 --- a/src/usr/hwpf/fapi/fapiTarget.C +++ b/src/usr/hwpf/fapi/fapiTarget.C @@ -35,6 +35,7 @@ * mjjones 09/12/2011 Added isChip and isChiplet * mjjones 02/07/2012 Remove MBS_CHIPLET * Add XBUS_ENDPOINT ABUS_ENDPOINT + * mjjones 02/21/2012 Add high performance toEcmdString */ #include <fapiTarget.H> @@ -46,7 +47,7 @@ namespace fapi // Default Constructor //****************************************************************************** Target::Target() : - iv_type(TARGET_TYPE_NONE), iv_pHandle(NULL) + iv_type(TARGET_TYPE_NONE), iv_pHandle(NULL), iv_pEcmdString(NULL) { } @@ -56,7 +57,7 @@ Target::Target() : //****************************************************************************** Target::Target(const TargetType i_type, void * i_pHandle) : - iv_type(i_type), iv_pHandle(i_pHandle) + iv_type(i_type), iv_pHandle(i_pHandle), iv_pEcmdString(NULL) { } @@ -65,7 +66,7 @@ Target::Target(const TargetType i_type, // Copy Constructor //****************************************************************************** Target::Target(const Target & i_right) : - iv_type(i_right.iv_type) + iv_type(i_right.iv_type), iv_pEcmdString(NULL) { (void) copyHandle(i_right); } @@ -76,6 +77,7 @@ Target::Target(const Target & i_right) : Target::~Target() { (void) deleteHandle(); + delete [] iv_pEcmdString; } //****************************************************************************** @@ -88,6 +90,8 @@ Target & Target::operator=(const Target & i_right) { iv_type = i_right.iv_type; (void) copyHandle(i_right); + delete [] iv_pEcmdString; + iv_pEcmdString = NULL; } return *this; } @@ -168,4 +172,21 @@ bool Target::isChiplet() const TARGET_TYPE_ABUS_ENDPOINT)) != 0); } +//****************************************************************************** +// Get the ecmd-format string +//****************************************************************************** +const char * Target::toEcmdString() const +{ + if (iv_pEcmdString == NULL) + { + iv_pEcmdString = new char[fapi::MAX_ECMD_STRING_LEN]; + char (&l_ecmdString)[fapi::MAX_ECMD_STRING_LEN] = + *(reinterpret_cast<char(*)[fapi::MAX_ECMD_STRING_LEN]> + (iv_pEcmdString)); + toString(l_ecmdString); + } + + return iv_pEcmdString; +} + } diff --git a/src/usr/hwpf/hwp/dimmBadDqBitmapAccessHwp.C b/src/usr/hwpf/hwp/dimmBadDqBitmapAccessHwp.C new file mode 100644 index 000000000..9775bb3d6 --- /dev/null +++ b/src/usr/hwpf/hwp/dimmBadDqBitmapAccessHwp.C @@ -0,0 +1,205 @@ +// IBM_PROLOG_BEGIN_TAG +// This is an automatically generated prolog. +// +// $Source: src/usr/hwpf/hwp/dimmBadDqBitmapAccessHwp.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 +/** + * @file dimmBadDqBitmapAccessHwp.C + * + * @brief FW Team HWP that accesses the Bad DQ Bitmap. + */ + +/* + * Change Log ****************************************************************** + * Flag Defect/Feature User Date Description + * ------ -------------- ---------- ----------- ---------------------------- + * mjjones 02/17/2012 Created. + */ + +#include <dimmBadDqBitmapAccessHwp.H> + +// DQ Data format in DIMM SPD +const uint32_t DIMM_BAD_DQ_MAGIC_NUMBER = 0xbadd4471; +const uint8_t DIMM_BAD_DQ_VERSION = 1; + +struct dimmBadDqDataFormat +{ + uint32_t iv_magicNumber; + uint8_t iv_version; + uint8_t iv_reserved1; + uint8_t iv_reserved2; + uint8_t iv_reserved3; + uint8_t iv_bitmaps[DIMM_DQ_MAX_DIMM_RANKS][DIMM_DQ_RANK_BITMAP_SIZE]; +}; + +extern "C" +{ + +fapi::ReturnCode dimmBadDqBitmapAccessHwp( + const fapi::Target & i_dimm, + uint8_t (&io_data)[DIMM_DQ_MAX_DIMM_RANKS][DIMM_DQ_RANK_BITMAP_SIZE], + const bool i_get) +{ + if (i_get) + { + FAPI_INF(">>dimmBadDqBitmapAccessHwp: Getting bitmap"); + } + else + { + FAPI_INF(">>dimmBadDqBitmapAccessHwp: Setting bitmap"); + } + + fapi::ReturnCode l_rc; + + // Note the use of heap based arrays to avoid large stack allocations + + // Centaur DQ to DIMM Connector DQ Wiring attribute. + uint8_t (&l_wiringData)[DIMM_DQ_NUM_DQS] = + *(reinterpret_cast<uint8_t(*)[DIMM_DQ_NUM_DQS]> + (new uint8_t[DIMM_DQ_NUM_DQS])); + + // DQ SPD Attribute + uint8_t (&l_spdData)[DIMM_DQ_SPD_DATA_SIZE] = + *(reinterpret_cast<uint8_t(*)[DIMM_DQ_SPD_DATA_SIZE]> + (new uint8_t[DIMM_DQ_SPD_DATA_SIZE])); + + 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 + { + if (i_get) + { + // Get the SPD DQ attribute + l_rc = FAPI_ATTR_GET(ATTR_SPD_BAD_DQ_DATA, &i_dimm, l_spdData); + + if (l_rc) + { + FAPI_ERR("dimmBadDqBitmapAccessHwp: Error getting SPD data"); + } + else + { + // Zero caller's data + memset(io_data, 0, sizeof(io_data)); + + // Check the magic number and version number + if ((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++) + { + // 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))) + { + // 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) + { + 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); + } + } + } + } + } + } + } + else + { + // Set up the data to write to SPD + l_pSpdData->iv_magicNumber = DIMM_BAD_DQ_MAGIC_NUMBER; + l_pSpdData->iv_version = DIMM_BAD_DQ_VERSION; + l_pSpdData->iv_reserved1 = 0; + l_pSpdData->iv_reserved2 = 0; + l_pSpdData->iv_reserved3 = 0; + memset(l_pSpdData->iv_bitmaps, 0, sizeof(l_pSpdData->iv_bitmaps)); + + // Translate bitmap from Centaur DQ to DIMM 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++) + { + if ((io_data[i][j/8]) & (0x80 >> (j % 8))) + { + // Centaur DQ bit set in callers data. + // Set DIMM DQ bit in SPD data. + // The wiring data maps Centaur DQ to DIMM DQ + uint8_t dBit = l_wiringData[j]; + l_pSpdData->iv_bitmaps[i][dBit/8] |= + (0x80 >> (dBit % 8)); + } + } + } + + // Set the SPD DQ attribute + l_rc = FAPI_ATTR_SET(ATTR_SPD_BAD_DQ_DATA, &i_dimm, l_spdData); + + if (l_rc) + { + FAPI_ERR("dimmBadDqBitmapAccessHwp: Error setting SPD data"); + } + } + } + + 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 new file mode 100644 index 000000000..e9d413adc --- /dev/null +++ b/src/usr/hwpf/hwp/dimmBadDqBitmapFuncs.C @@ -0,0 +1,230 @@ +// IBM_PROLOG_BEGIN_TAG +// This is an automatically generated prolog. +// +// $Source: src/usr/hwpf/hwp/dimmBadDqBitmapFuncs.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 +/** + * @file dimmBadDqBitmapFuncs.C + * + * @brief FW Team Utility functions that accesses the Bad DQ Bitmap. + */ + +/* + * Change Log ****************************************************************** + * Flag Defect/Feature User Date Description + * ------ -------------- ---------- ----------- ---------------------------- + * mjjones 02/17/2012 Created. + */ + +#include <dimmBadDqBitmapFuncs.H> +#include <string.h> + +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 +//------------------------------------------------------------------------------ +fapi::ReturnCode dimmBadDqCheckParamFindDimm(const fapi::Target & i_mba, + const uint8_t i_port, + const uint8_t i_dimm, + const uint8_t i_rank, + fapi::Target & o_dimm) +{ + fapi::ReturnCode l_rc; + + if ((i_port >= DIMM_DQ_MAX_MBA_PORTS) || + (i_dimm >= DIMM_DQ_MAX_MBAPORT_DIMMS) || + (i_rank >= DIMM_DQ_MAX_DIMM_RANKS)) + { + FAPI_ERR("dimmBadDqCheckParams: Bad parameter. %d:%d:%d", i_port, + i_dimm, i_rank); + const uint8_t & FFDC_PORT = i_port; + const uint8_t & FFDC_DIMM = i_dimm; + const uint8_t & FFDC_RANK = i_rank; + FAPI_SET_HWP_ERROR(l_rc, RC_BAD_DQ_DIMM_BAD_PARAM); + } + else + { + std::vector<fapi::Target> l_dimms; + + // Get the functional DIMMs associated with the MBA chiplet + l_rc = fapiGetAssociatedDimms(i_mba, l_dimms); + + if (l_rc) + { + FAPI_ERR("dimmBadDqFindDimm: Error from fapiGetAssociatedDimms"); + } + else + { + // Find the DIMM with the correct MBA port/dimm + uint8_t i = 0; + uint8_t l_port = 0; + uint8_t l_dimm = 0; + + for (; i < l_dimms.size(); i++) + { + l_rc = FAPI_ATTR_GET(ATTR_MBA_PORT, &(l_dimms[i]), l_port); + + if (l_rc) + { + FAPI_ERR("dimmBadDqFindDimm: Error getting ATTR_MBA_PORT for dimm"); + break; + } + else if (l_port == i_port) + { + l_rc = FAPI_ATTR_GET(ATTR_MBA_DIMM, &(l_dimms[i]), l_dimm); + + if (l_rc) + { + FAPI_ERR("dimmBadDqFindDimm: Error getting ATTR_MBA_DIMM for dimm"); + break; + } + else if (l_dimm == i_dimm) + { + o_dimm = l_dimms[i]; + break; + } + } + } + + if (!l_rc) + { + if (i == l_dimms.size()) + { + FAPI_ERR("dimmBadDqFindDimm: Did not find DIMM for %s:%d:%d", + i_mba.toEcmdString(), i_port, i_dimm); + const fapi::Target & FFDC_MBA_TARGET = i_mba; + const uint8_t & FFDC_PORT = i_port; + const uint8_t & FFDC_DIMM = i_dimm; + FAPI_SET_HWP_ERROR(l_rc, RC_BAD_DQ_DIMM_NOT_FOUND); + } + } + } + } + + return l_rc; +} + +//------------------------------------------------------------------------------ +fapi::ReturnCode dimmGetBadDqBitmap(const fapi::Target & i_mba, + const uint8_t i_port, + const uint8_t i_dimm, + const uint8_t i_rank, + uint8_t (&o_data)[DIMM_DQ_RANK_BITMAP_SIZE]) +{ + FAPI_INF(">>dimmGetBadDqBitmap. %s:%d:%d:%d", i_mba.toEcmdString(), i_port, + i_dimm, i_rank); + + fapi::ReturnCode l_rc; + + // Check parameters and find the DIMM Target + fapi::Target l_dimm; + l_rc = dimmBadDqCheckParamFindDimm(i_mba, i_port, i_dimm, i_rank, l_dimm); + + if (!l_rc) + { + // Get the Bad DQ bitmap by calling the dimmBadDqBitmapAccessHwp HWP. + // 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); + + if (l_rc) + { + FAPI_ERR("dimmGetBadDqBitmap: Error from dimmBadDqBitmapAccessHwp"); + } + else + { + memcpy(o_data, l_dqBitmap[i_rank], DIMM_DQ_RANK_BITMAP_SIZE); + } + + delete [] &l_dqBitmap; + } + + FAPI_INF("<<dimmGetBadDqBitmap"); + return l_rc; +} + +//------------------------------------------------------------------------------ +fapi::ReturnCode dimmSetBadDqBitmap( + const fapi::Target & i_mba, + const uint8_t i_port, + const uint8_t i_dimm, + const uint8_t i_rank, + const uint8_t (&i_data)[DIMM_DQ_RANK_BITMAP_SIZE]) +{ + FAPI_INF(">>dimmSetBadDqBitmap. %s:%d:%d:%d", i_mba.toEcmdString(), i_port, i_dimm, i_rank); + + fapi::ReturnCode l_rc; + + // Check parameters and find the DIMM Target + fapi::Target l_dimm; + l_rc = dimmBadDqCheckParamFindDimm(i_mba, i_port, i_dimm, i_rank, l_dimm); + + if (!l_rc) + { + // Get the Bad DQ bitmap by calling the dimmBadDqBitmapAccessHwp HWP. + // 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); + + if (l_rc) + { + FAPI_ERR("dimmSetBadDqBitmap: Error from dimmBadDqBitmapAccessHwp (get)"); + } + 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); + + if (l_rc) + { + FAPI_ERR("dimmSetBadDqBitmap: Error from dimmBadDqBitmapAccessHwp (set)"); + } + } + + delete [] &l_dqBitmap; + } + + + FAPI_INF("<<dimmSetBadDqBitmap"); + return l_rc; +} + +} // extern "C" diff --git a/src/usr/hwpf/hwp/dimm_attributes.xml b/src/usr/hwpf/hwp/dimm_attributes.xml new file mode 100644 index 000000000..c7573cbd6 --- /dev/null +++ b/src/usr/hwpf/hwp/dimm_attributes.xml @@ -0,0 +1,59 @@ +<!-- IBM_PROLOG_BEGIN_TAG + This is an automatically generated prolog. + + $Source: src/usr/hwpf/hwp/dimm_attributes.xml $ + + 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 --> +<!-- XML file specifying DIMM attributes used by HW Procedures. --> +<attributes> + +<attribute> + <id>ATTR_CEN_DQ_TO_DIMM_CONN_DQ</id> + <targetType>TARGET_TYPE_DIMM</targetType> + <description> + Centaur DQ to DIMM connector DQ mapping. + Uint8 value for each Centaur DQ (0-79). + The value is the corresponding DIMM Connector DQ. + Therefore if (data[2] == 60) then Centaur DQ 2 maps to DIMM DQ 60 + If the logical DIMM is on a Centaur-DIMM then the value is the same as the + array index because there is no DIMM connector. + If the logical DIMM is an IS-DIMM then the value depends on board wiring. + </description> + <valueType>uint8</valueType> + <array>80</array> + <platInit/> +</attribute> + +<attribute> + <id>ATTR_MBA_PORT</id> + <targetType>TARGET_TYPE_DIMM</targetType> + <description>MBA Chiplet port this DIMM is connected to</description> + <valueType>uint8</valueType> + <platInit/> +</attribute> + +<attribute> + <id>ATTR_MBA_DIMM</id> + <targetType>TARGET_TYPE_DIMM</targetType> + <description>MBA port DIMM number of this DIMM</description> + <valueType>uint8</valueType> + <platInit/> +</attribute> + +</attributes> diff --git a/src/usr/hwpf/hwp/dimm_errors.xml b/src/usr/hwpf/hwp/dimm_errors.xml new file mode 100644 index 000000000..c0e910a10 --- /dev/null +++ b/src/usr/hwpf/hwp/dimm_errors.xml @@ -0,0 +1,49 @@ +<!-- IBM_PROLOG_BEGIN_TAG + This is an automatically generated prolog. + + $Source: src/usr/hwpf/hwp/dimm_errors.xml $ + + 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 --> +<!-- XML file specifying errors generated by DIMM HWPs. --> + +<hwpErrors> + <!-- *********************************************************************** --> + <hwpError> + <rc>RC_BAD_DQ_DIMM_BAD_PARAM</rc> + <description> + A HWP called a utility function to access the bad DQ data but specified + an invalid PORT/DIMM/RANK + </description> + <ffdc>FFDC_PORT</ffdc> + <ffdc>FFDC_DIMM</ffdc> + <ffdc>FFDC_RANK</ffdc> + </hwpError> + <!-- *********************************************************************** --> + <hwpError> + <rc>RC_BAD_DQ_DIMM_NOT_FOUND</rc> + <description> + A HWP called a utility function to accessing the bad DQ data. The + utility function could not find a functional DIMM associated with the + specified MBA/PORT/DIMM + </description> + <ffdc>FFDC_MBA_TARGET</ffdc> + <ffdc>FFDC_PORT</ffdc> + <ffdc>FFDC_DIMM</ffdc> + </hwpError> +</hwpErrors> diff --git a/src/usr/hwpf/hwp/DIMM_SPD_attributes.xml b/src/usr/hwpf/hwp/dimm_spd_attributes.xml index f8ed67b23..a08062b94 100644 --- a/src/usr/hwpf/hwp/DIMM_SPD_attributes.xml +++ b/src/usr/hwpf/hwp/dimm_spd_attributes.xml @@ -1,7 +1,7 @@ <!-- IBM_PROLOG_BEGIN_TAG This is an automatically generated prolog. - $Source: src/usr/hwpf/hwp/DIMM_SPD_attributes.xml $ + $Source: src/usr/hwpf/hwp/dimm_spd_attributes.xml $ IBM CONFIDENTIAL @@ -20,9 +20,10 @@ Origin: 30 IBM_PROLOG_END --> +<!-- XML file specifying DIMM SPD attributes used by HW Procedures. --> <attributes> - <!-- ********************************************************************* --> - <attribute> + +<attribute> <id>ATTR_SPD_DRAM_DEVICE_TYPE</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -32,9 +33,9 @@ <valueType>uint8</valueType> <enum>DDR3 = 0x0b, DDR4 = 0x0c</enum> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_MODULE_TYPE</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -44,9 +45,9 @@ <valueType>uint8</valueType> <enum>CDIMM = 0x00, RDIMM = 0x01, UDIMM = 0x02, LRDIMM = 0x0b</enum> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_SDRAM_BANKS</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -56,9 +57,9 @@ <valueType>uint8</valueType> <enum>B8 = 0x00, B16 = 0x01, B32 = 0x02, B64 = 0x03</enum> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_SDRAM_DENSITY</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -71,9 +72,9 @@ D8GB = 0x05, D16GB = 0x06 </enum> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_SDRAM_ROWS</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -83,9 +84,9 @@ <valueType>uint8</valueType> <enum>R12 = 0x00, R13 = 0x01, R14 = 0x02, R15 = 0x03, R16 = 0x04</enum> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_SDRAM_COLUMNS</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -95,9 +96,9 @@ <valueType>uint8</valueType> <enum>C9 = 0x00, C10 = 0x01, C11 = 0x02, C12 = 0x03</enum> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_MODULE_NOMINAL_VOLTAGE</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -107,9 +108,9 @@ <valueType>uint8</valueType> <enum>NOTOP1_5 = 0x01, OP1_35 = 0x02, OP1_2X = 0x04</enum> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_NUM_RANKS</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -119,9 +120,9 @@ <valueType>uint8</valueType> <enum>R1 = 0x00, R2 = 0x01, R3 = 0x02, R4 = 0x03</enum> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_DRAM_WIDTH</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -131,9 +132,9 @@ <valueType>uint8</valueType> <enum>W4 = 0x00, W8 = 0x01, W16 = 0x02, W32 = 0x03</enum> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_MODULE_MEMORY_BUS_WIDTH</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -143,9 +144,9 @@ <valueType>uint8</valueType> <enum>W8 = 0x00, W16 = 0x01, W32 = 0x02, W64 = 0x03</enum> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_FTB_DIVIDEND</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -154,9 +155,9 @@ </description> <valueType>uint8</valueType> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_FTB_DIVISOR</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -165,9 +166,9 @@ </description> <valueType>uint8</valueType> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_MTB_DIVIDEND</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -176,9 +177,9 @@ </description> <valueType>uint8</valueType> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_MTB_DIVISOR</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -187,9 +188,9 @@ </description> <valueType>uint8</valueType> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_TCKMIN</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -198,9 +199,9 @@ </description> <valueType>uint8</valueType> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_CAS_LATENCIES_SUPPORTED</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -226,9 +227,9 @@ CL_4 = 0x00000001, </enum> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_TAAMIN</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -237,9 +238,9 @@ </description> <valueType>uint8</valueType> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_TWRMIN</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -248,9 +249,9 @@ </description> <valueType>uint8</valueType> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_TRCDMIN</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -259,9 +260,9 @@ </description> <valueType>uint8</valueType> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_TRRDMIN</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -270,9 +271,9 @@ </description> <valueType>uint8</valueType> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_TRPMIN</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -281,9 +282,9 @@ </description> <valueType>uint8</valueType> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_TRASMIN</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -292,9 +293,9 @@ </description> <valueType>uint32</valueType> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_TRCMIN</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -303,9 +304,9 @@ </description> <valueType>uint32</valueType> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_TRFCMIN</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -314,9 +315,9 @@ </description> <valueType>uint32</valueType> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_TWTRMIN</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -325,9 +326,9 @@ </description> <valueType>uint8</valueType> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_TRTPMIN</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -336,9 +337,9 @@ </description> <valueType>uint8</valueType> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_TFAWMIN</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -347,9 +348,9 @@ </description> <valueType>uint32</valueType> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_SDRAM_OPTIONAL_FEATURES</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -359,9 +360,9 @@ <valueType>uint8</valueType> <enum>DLL_OFF = 0x80, RZQ7 = 0x02, RZQ6 = 0x01</enum> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_SDRAM_THERMAL_AND_REFRESH_OPTIONS</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -371,9 +372,9 @@ <valueType>uint8</valueType> <enum>PASR = 0x80, ODTS = 0x08, ASR = 0x05, ETRR = 0x02, ETR = 0x01</enum> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_MODULE_THERMAL_SENSOR</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -383,9 +384,9 @@ <valueType>uint8</valueType> <enum>PRESENT = 0x80, ACCURACY_MASK = 0x7F</enum> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_FINE_OFFSET_TCKMIN</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -394,9 +395,10 @@ </description> <valueType>uint8</valueType> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + + +<attribute> <id>ATTR_SPD_FINE_OFFSET_TAAMIN</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -405,9 +407,9 @@ </description> <valueType>uint8</valueType> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_FINE_OFFSET_TRCDMIN</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -416,9 +418,9 @@ </description> <valueType>uint8</valueType> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_FINE_OFFSET_TRPMIN</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -427,9 +429,9 @@ </description> <valueType>uint8</valueType> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_FINE_OFFSET_TRCMIN</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -438,9 +440,9 @@ </description> <valueType>uint8</valueType> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_MODULE_SPECIFIC_SECTION</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -450,9 +452,9 @@ <valueType>uint8</valueType> <array>57</array> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_MODULE_ID_MODULE_MANUFACTURERS_JEDEC_ID_CODE</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -461,9 +463,9 @@ </description> <valueType>uint32</valueType> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_MODULE_ID_MODULE_MANUFACTURING_LOCATION</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -472,9 +474,9 @@ </description> <valueType>uint8</valueType> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_MODULE_ID_MODULE_MANUFACTURING_DATE</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -483,9 +485,9 @@ </description> <valueType>uint32</valueType> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_MODULE_ID_MODULE_SERIAL_NUMBER</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -494,9 +496,9 @@ </description> <valueType>uint32</valueType> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_CYCLICAL_REDUNDANCY_CODE</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -505,9 +507,9 @@ </description> <valueType>uint32</valueType> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_MODULE_PART_NUMBER</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -517,9 +519,9 @@ <valueType>uint8</valueType> <array>18</array> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_MODULE_REVISION_CODE</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -528,9 +530,9 @@ </description> <valueType>uint32</valueType> <platInit/> - </attribute> - <!-- ********************************************************************* --> - <attribute> +</attribute> + +<attribute> <id>ATTR_SPD_DRAM_MANUFACTURER_JEDEC_ID_CODE</id> <targetType>TARGET_TYPE_DIMM</targetType> <description> @@ -539,5 +541,21 @@ </description> <valueType>uint32</valueType> <platInit/> - </attribute> +</attribute> + +<attribute> + <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. + </description> + <valueType>uint8</valueType> + <array>80</array> + <platInit/> + <writeable/> +</attribute> + </attributes> diff --git a/src/usr/hwpf/hwp/fapiHwpErrorInfo.xml b/src/usr/hwpf/hwp/fapiHwpErrorInfo.xml index 7374c965d..34b4a6752 100644 --- a/src/usr/hwpf/hwp/fapiHwpErrorInfo.xml +++ b/src/usr/hwpf/hwp/fapiHwpErrorInfo.xml @@ -67,6 +67,18 @@ </hwpError> <!-- *********************************************************************** --> <hwpError> + <rc>RC_TEST_DQ_NO_ERR_ON_BAD_PARAMS</rc> + <description>HWP DQ Unit Test did not get an expected error</description> + </hwpError> + <!-- *********************************************************************** --> + <hwpError> + <rc>RC_TEST_DQ_BAD_DATA</rc> + <description>HWP DQ Unit Test got bad data</description> + <ffdc>FFDC_DATA1</ffdc> + <ffdc>FFDC_DATA2</ffdc> + </hwpError> + <!-- *********************************************************************** --> + <hwpError> <rc>RC_INITFILE_INCORRECT_VER</rc> <description>InitFile has incorrect version</description> <!-- Collect local FFDC FFDC_IF_VER --> diff --git a/src/usr/hwpf/hwp/fapiHwpExecInitFile.C b/src/usr/hwpf/hwp/fapiHwpExecInitFile.C index 4f10de175..ae354ad68 100644 --- a/src/usr/hwpf/hwp/fapiHwpExecInitFile.C +++ b/src/usr/hwpf/hwp/fapiHwpExecInitFile.C @@ -42,6 +42,7 @@ * mjjones 01/13/2012 Use new ReturnCode interfaces * camvanng 01/20/2012 Support for using a range * indexes for array attributes + * mjjones 02/21/2012 Use new Target toEcmdString */ #include <fapiHwpExecInitFile.H> @@ -234,9 +235,7 @@ fapi::ReturnCode fapiHwpExecInitFile(const fapi::Target & i_Target, FAPI_INF(">> fapiHwpExecInitFile: Performing HWP for %s", i_file); // Print the ecmd string of the chip - char l_string[fapi::MAX_ECMD_STRING_LEN] = {0}; - i_Target.toString(l_string); - FAPI_INF("fapiHwpExecInitFile: Target: %s", l_string); + FAPI_INF("fapiHwpExecInitFile: Target: %s", i_Target.toEcmdString()); fapi::ReturnCode l_rc = fapi::FAPI_RC_SUCCESS; fapi::ReturnCode l_tmpRc = fapi::FAPI_RC_SUCCESS; diff --git a/src/usr/hwpf/hwp/fapiTestHwp.C b/src/usr/hwpf/hwp/fapiTestHwp.C index cae558593..af622ccd8 100644 --- a/src/usr/hwpf/hwp/fapiTestHwp.C +++ b/src/usr/hwpf/hwp/fapiTestHwp.C @@ -41,7 +41,7 @@ * camvanng 11/16/2011 Change function name * fapiHwpExecInitFile() * mjjones 01/13/2012 Use new ReturnCode interfaces - * + * mjjones 02/21/2012 Use new Target toEcmdString */ #include <fapiTestHwp.H> @@ -63,9 +63,7 @@ fapi::ReturnCode hwpInitialTest(const fapi::Target & i_chip) FAPI_INF("Performing HWP: hwpInitialTest"); // Print the ecmd string of the chip - char l_string[fapi::MAX_ECMD_STRING_LEN] = {0}; - i_chip.toString(l_string); - FAPI_INF("hwpInitialTest: Chip: %s", l_string); + FAPI_INF("hwpInitialTest: Chip: %s", i_chip.toEcmdString()); fapi::ReturnCode l_rc; uint32_t l_ecmdRc = ECMD_DBUF_SUCCESS; diff --git a/src/usr/hwpf/hwp/fapiTestHwpConfig.C b/src/usr/hwpf/hwp/fapiTestHwpConfig.C index 17af655a4..6a3d06897 100644 --- a/src/usr/hwpf/hwp/fapiTestHwpConfig.C +++ b/src/usr/hwpf/hwp/fapiTestHwpConfig.C @@ -35,6 +35,7 @@ * mjjones 10/06/2011 Updated traces. * camvang 10/26/2011 Updated traces. * mjjones 01/13/2012 Use new ReturnCode interfaces + * mjjones 02/21/2012 Use new Target toEcmdString */ #include <fapiTestHwpConfig.H> @@ -50,9 +51,7 @@ fapi::ReturnCode hwpTestConfig(const fapi::Target & i_chip) FAPI_INF("hwpTestConfig: Start HWP"); // Print the ecmd string of the chip - char l_string[fapi::MAX_ECMD_STRING_LEN] = {0}; - i_chip.toString(l_string); - FAPI_INF("hwpTestConfig: Chip: %s", l_string); + FAPI_INF("hwpTestConfig: Chip: %s", i_chip.toEcmdString()); fapi::ReturnCode l_rc; std::vector<fapi::Target> l_targets; diff --git a/src/usr/hwpf/hwp/fapiTestHwpDq.C b/src/usr/hwpf/hwp/fapiTestHwpDq.C new file mode 100644 index 000000000..d3de5e1eb --- /dev/null +++ b/src/usr/hwpf/hwp/fapiTestHwpDq.C @@ -0,0 +1,151 @@ +// 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 +/** + * @file fapiTestHwpDq.C + * + * @brief Implements a Test Hardware Procedure that exercises the bad DQ data + */ + +/* + * Change Log ****************************************************************** + * Flag Defect/Feature User Date Description + * ------ -------------- ---------- ----------- ---------------------------- + * mjjones 02/21/2012 Created + */ + +#include <fapiTestHwpDq.H> +#include <dimmBadDqBitmapFuncs.H> + +extern "C" +{ + +fapi::ReturnCode fapiTestHwpDq(const fapi::Target & i_mba) +{ + FAPI_INF(">>fapiTestHwpDq: %s", i_mba.toEcmdString()); + + fapi::ReturnCode l_rc; + uint8_t l_dqBitmap[DIMM_DQ_RANK_BITMAP_SIZE]; + + do + { + // Get the bad DQ Bitmap with an incorrect port + l_rc = dimmGetBadDqBitmap(i_mba, 5, 0, 0, l_dqBitmap); + + if (!l_rc) + { + FAPI_ERR("fapiTestHwpDq: Did not get expected error from dimmGetBadDqBitmap"); + FAPI_SET_HWP_ERROR(l_rc, RC_TEST_DQ_NO_ERR_ON_BAD_PARAMS); + break; + } + + // Do not log error to avoid adding an expected error to the log + FAPI_INF("fapiTestHwpDq: Got expected error from dimmGetBadDqBitmap"); + l_rc = fapi::FAPI_RC_SUCCESS; + + // Get the bad DQ Bitmap for port1, dimm0, rank3 + l_rc = dimmGetBadDqBitmap(i_mba, 1, 0, 3, l_dqBitmap); + + if (l_rc) + { + 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; + + for (uint8_t i = 0; i < DIMM_DQ_RANK_BITMAP_SIZE; i++) + { + if (l_dqBitmap[i] != 0) + { + FAPI_INF("fapiTestHwpDq: Non-zero DQ data, skipping test"); + l_nonZeroData = true; + break; + } + } + + if (l_nonZeroData) + { + break; + } + + // 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); + + 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; + } + + // Check that the data can be read back + l_dqBitmap[2] = 0; + l_dqBitmap[6] = 0; + + l_rc = dimmGetBadDqBitmap(i_mba, 1, 0, 3, l_dqBitmap); + + if (l_rc) + { + FAPI_ERR("fapiTestHwpDq: Error from dimmGetBadDqBitmap (2)"); + break; + } + + if ((l_dqBitmap[2] != 0x40) || (l_dqBitmap[6] != 0x20)) + { + FAPI_ERR("fapiTestHwpDq: Got bad data 0x%x:0x%x", + l_dqBitmap[2], l_dqBitmap[6]); + uint8_t & FFDC_DATA1 = l_dqBitmap[2]; + uint8_t & FFDC_DATA2 = l_dqBitmap[6]; + FAPI_SET_HWP_ERROR(l_rc, RC_TEST_DQ_BAD_DATA); + break; + } + + // Write the data back to zero + l_dqBitmap[2] = 0; + l_dqBitmap[6] = 0; + + l_rc = dimmSetBadDqBitmap(i_mba, 1, 0, 3, l_dqBitmap); + + if (l_rc) + { + FAPI_ERR("fapiTestHwpDq: Error from dimmSetBadDqBitmap (2)"); + break; + } + + } while (0); + + FAPI_INF("<<fapiTestHwpDq"); + return l_rc; +} + + +} // extern "C" diff --git a/src/usr/hwpf/hwp/makefile b/src/usr/hwpf/hwp/makefile index f61ada852..59d174969 100644 --- a/src/usr/hwpf/hwp/makefile +++ b/src/usr/hwpf/hwp/makefile @@ -34,7 +34,10 @@ OBJS = fapiTestHwp.o \ fapiTestHwpFfdc.o \ fapiTestHwpConfig.o \ fapiTestHwpAttr.o \ - fapiHwpExecInitFile.o + fapiTestHwpDq.o \ + fapiHwpExecInitFile.o \ + dimmBadDqBitmapFuncs.o \ + dimmBadDqBitmapAccessHwp.o SUBDIRS = dmi_training.d diff --git a/src/usr/hwpf/hwp/unit_attributes.xml b/src/usr/hwpf/hwp/unit_attributes.xml new file mode 100644 index 000000000..42b8300ad --- /dev/null +++ b/src/usr/hwpf/hwp/unit_attributes.xml @@ -0,0 +1,34 @@ +<!-- IBM_PROLOG_BEGIN_TAG + This is an automatically generated prolog. + + $Source: src/usr/hwpf/hwp/unit_attributes.xml $ + + 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 --> +<!-- XML file specifying Unit attributes used by HW Procedures. --> +<attributes> + +<attribute> + <id>ATTR_CHIP_UNIT_POS</id> + <targetType>TARGET_TYPE_EX_CHIPLET, TARGET_TYPE_MBA_CHIPLET, TARGET_TYPE_MCS_CHIPLET</targetType> + <description>A unit's offset number within the chip with respect to similar units. </description> + <valueType>uint8</valueType> + <platInit/> +</attribute> + +</attributes> diff --git a/src/usr/hwpf/makefile b/src/usr/hwpf/makefile index 09dbc61a4..a5d7ad575 100644 --- a/src/usr/hwpf/makefile +++ b/src/usr/hwpf/makefile @@ -32,14 +32,17 @@ SUBDIRS = fapi.d hwp.d plat.d test.d #------------------------------------------------------------------------------ HWP_ERROR_XML_FILES = hwp/fapiHwpErrorInfo.xml \ hwp/dmi_training/proc_cen_framelock/proc_cen_framelock_errors.xml \ - hwp/dmi_training/dmi_io_run_training/io_run_training_errors.xml + hwp/dmi_training/dmi_io_run_training/io_run_training_errors.xml \ + hwp/dimm_errors.xml HWP_ATTR_XML_FILES = hwp/memory_attributes.xml \ hwp/L2_L3_attributes.xml \ hwp/scratch_attributes.xml \ hwp/system_attributes.xml \ hwp/chip_attributes.xml \ - hwp/DIMM_SPD_attributes.xml + hwp/dimm_spd_attributes.xml \ + hwp/dimm_attributes.xml \ + hwp/unit_attributes.xml #------------------------------------------------------------------------------ # Initfiles diff --git a/src/usr/hwpf/plat/fapiPlatAttributeService.C b/src/usr/hwpf/plat/fapiPlatAttributeService.C index c10b6613d..b7a0e1904 100644 --- a/src/usr/hwpf/plat/fapiPlatAttributeService.C +++ b/src/usr/hwpf/plat/fapiPlatAttributeService.C @@ -175,22 +175,52 @@ fapi::ReturnCode fapiPlatGetSpdAttr(const fapi::Target * i_target, errlHndl_t l_err = NULL; size_t l_len = i_len; - l_err = deviceRead( l_target, o_data, l_len, DEVICE_SPD_ADDRESS(i_keyword)); + l_err = deviceRead(l_target, o_data, l_len, DEVICE_SPD_ADDRESS(i_keyword)); if (l_err) { // Add the error log pointer as data to the ReturnCode - FAPI_ERR("platGetSpdAttr: deviceOp() returns error"); + FAPI_ERR("platGetSpdAttr: deviceRead() returns error"); l_rc.setPlatError(reinterpret_cast<void *> (l_err)); } else { - platUpdateAttrValue( i_keyword, o_data ); + platUpdateAttrValue(i_keyword, o_data); } FAPI_DBG(EXIT_MRK "fapiPlatGetSpdAttr"); return l_rc; +} + +//****************************************************************************** +// fapiPlatSetSpdAttr function. +// Call SPD device driver to set the SPD attribute +//****************************************************************************** +fapi::ReturnCode fapiPlatSetSpdAttr(const fapi::Target * i_target, + const uint16_t i_keyword, + void * i_data, const size_t i_len) +{ + FAPI_DBG(ENTER_MRK "fapiPlatSetSpdAttr"); + + fapi::ReturnCode l_rc; + + // Extract the component pointer + TARGETING::Target* l_target = + reinterpret_cast<TARGETING::Target*>(i_target->get()); + errlHndl_t l_err = NULL; + size_t l_len = i_len; + l_err = deviceWrite(l_target, i_data, l_len, DEVICE_SPD_ADDRESS(i_keyword)); + + if (l_err) + { + // Add the error log pointer as data to the ReturnCode + FAPI_ERR("platSetSpdAttr: deviceWrite() returns error"); + l_rc.setPlatError(reinterpret_cast<void *> (l_err)); + } + + FAPI_DBG(EXIT_MRK "fapiPlatSetSpdAttr"); + return l_rc; } //****************************************************************************** @@ -352,6 +382,87 @@ fapi::ReturnCode fapiPlatGetMirrorBaseAddr(const fapi::Target * i_pMcsTarget, return l_rc; } +//****************************************************************************** +// fapiPlatGetDqMapping function. +//****************************************************************************** +fapi::ReturnCode fapiPlatGetDqMapping(const fapi::Target * i_pDimmTarget, + uint8_t (&o_data)[DIMM_DQ_NUM_DQS]) +{ + fapi::ReturnCode l_rc; + bool l_error = false; + + // Check that the FAPI Target pointer is not NULL + if (i_pDimmTarget == NULL) + { + FAPI_ERR("fapiPlatGetDqMapping. NULL FAPI Target passed"); + l_error = true; + } + else + { + // Extract the DIMM Hostboot Target pointer + TARGETING::Target * l_pDimmTarget = + reinterpret_cast<TARGETING::Target*>(i_pDimmTarget->get()); + + // Check that the DIMM Hostboot Target pointer is not NULL + if (l_pDimmTarget == NULL) + { + FAPI_ERR("fapiPlatGetDqMapping. NULL HB Target passed"); + l_error = true; + } + else + { + // Check that the Target is a DIMM + if (l_pDimmTarget->getAttr<TARGETING::ATTR_TYPE>() != + TARGETING::TYPE_DIMM) + { + FAPI_ERR("fapiPlatGetDqMapping. Not a DIMM (0x%x)", + l_pDimmTarget->getAttr<TARGETING::ATTR_TYPE>()); + l_error = true; + } + else + { + if (l_pDimmTarget->getAttr<TARGETING::ATTR_MODEL>() == + TARGETING::MODEL_CDIMM) + { + // C-DIMM. There is no DQ mapping from Centaur DQ to DIMM + // Connector DQ because there is no DIMM Connector. Return + // a direct 1:1 map (0->0, 1->1, etc) + for (uint8_t i = 0; i < DIMM_DQ_NUM_DQS; i++) + { + o_data[i] = i; + } + } + else + { + // IS-DIMM. Get the mapping using a Hostboot attribute + // Note that getAttr() cannot be used to get an array + // attribute so using tryGetAttr and ignoring result + l_pDimmTarget-> + tryGetAttr<TARGETING::ATTR_CEN_DQ_TO_DIMM_CONN_DQ> + (o_data); + } + } + } + } + + if (l_error) + { + /*@ + * @errortype + * @moduleid MOD_ATTR_DQ_MAP_GET + * @reasoncode RC_ATTR_BASE_BAD_PARAM + * @devdesc Failed to get DIMM DQ mapping attribute due to + * bad target parameter. + */ + errlHndl_t l_pError = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_INFORMATIONAL, + fapi::MOD_ATTR_DQ_MAP_GET, + fapi::RC_ATTR_BASE_BAD_PARAM); + l_rc.setPlatError(reinterpret_cast<void *> (l_pError)); + } + + return l_rc; +} } // End platAttrSvc namespace diff --git a/src/usr/hwpf/plat/fapiPlatTarget.C b/src/usr/hwpf/plat/fapiPlatTarget.C index f0006d889..0578278d1 100644 --- a/src/usr/hwpf/plat/fapiPlatTarget.C +++ b/src/usr/hwpf/plat/fapiPlatTarget.C @@ -122,8 +122,10 @@ void Target::toString(char (&o_ecmdString)[MAX_ECMD_STRING_LEN]) const // "p8.ex k0:n0:s0:p01:c0 " // "p8.mcs k0:n0:s0:p01:c0 " // "centaur k0:n0:s0:p01 " - const char * const ECMD_CHIP_PROC = "p8 "; - const char * const ECMD_CHIP_MEMBUF = "centaur "; + const char * const ECMD_CHIP_PROC = "p8"; + const char * const ECMD_CHIP_PROC_SPC = " "; + const char * const ECMD_CHIP_MEMBUF = "centaur"; + const char * const ECMD_CHIP_MEMBUF_SPC = " "; const char * const ECMD_CHIPLET_EX = "ex "; const char * const ECMD_CHIPLET_MCS = "mcs "; const char * const ECMD_CHIPLET_MBS = "mbs "; @@ -131,6 +133,7 @@ void Target::toString(char (&o_ecmdString)[MAX_ECMD_STRING_LEN]) const // Look for a chip in the path const char * l_pChipType = NULL; + const char * l_pChipTypeSpc = NULL; uint32_t l_chipPos = 0; for (uint32_t i = 0; ((i < l_sizePath) && (l_pChipType == NULL)); @@ -139,11 +142,13 @@ void Target::toString(char (&o_ecmdString)[MAX_ECMD_STRING_LEN]) const if (l_path[i].type == TARGETING::TYPE_PROC) { l_pChipType = ECMD_CHIP_PROC; + l_pChipTypeSpc = ECMD_CHIP_PROC_SPC; l_chipPos = l_path[i].instance; } else if (l_path[i].type == TARGETING::TYPE_MEMBUF) { l_pChipType = ECMD_CHIP_MEMBUF; + l_pChipTypeSpc = ECMD_CHIP_MEMBUF_SPC; l_chipPos = l_path[i].instance; } } @@ -200,6 +205,11 @@ void Target::toString(char (&o_ecmdString)[MAX_ECMD_STRING_LEN]) const strcpy(l_pStr, l_pChipletType); l_pStr += strlen(l_pChipletType); } + else + { + strcpy(l_pStr, l_pChipTypeSpc); + l_pStr += strlen(l_pChipTypeSpc); + } // Middle of the string strcpy(l_pStr, "k0:n0:s0:p"); diff --git a/src/usr/hwpf/test/hwpftest.H b/src/usr/hwpf/test/hwpftest.H index 3e564457f..21e26ca2c 100644 --- a/src/usr/hwpf/test/hwpftest.H +++ b/src/usr/hwpf/test/hwpftest.H @@ -38,6 +38,7 @@ #include <fapiHwpExecInitFile.H> #include <spd/spdenums.H> #include <targeting/predicates/predicatectm.H> +#include <targeting/iterators/rangefilter.H> using namespace fapi; using namespace TARGETING; @@ -694,6 +695,43 @@ public: } + /** + * @brief Call a test procedure that exercises the Bad DQ data + */ + void testHwpf9() + { + errlHndl_t l_err = NULL; + + // Look for MBA chiplets + TARGETING::PredicateCTM l_mbaFilter(CLASS_UNIT, TYPE_MBA); + TARGETING::TargetRangeFilter l_filter( + TARGETING::targetService().begin(), + TARGETING::targetService().end(), + &l_mbaFilter); + + // Invoke the HWP on the first one + if (l_filter) + { + fapi::Target l_fapiTarget(TARGET_TYPE_MBA_CHIPLET, + static_cast<void *> (*l_filter)); + + FAPI_INVOKE_HWP(l_err, fapiTestHwpDq, l_fapiTarget); + + if (l_err) + { + TS_FAIL("testHwpf9: fapiTestHwpDq failed. Error logged"); + errlCommit(l_err, HWPF_COMP_ID); + } + else + { + TS_TRACE("testHwpf9: Unit Test passed"); + } + } + else + { + TS_TRACE("testHwpf9: No MBAs found, skipping test"); + } + } }; #endif |