summaryrefslogtreecommitdiffstats
path: root/src/usr/hdat/hdatutil.C
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/hdat/hdatutil.C')
-rw-r--r--src/usr/hdat/hdatutil.C1351
1 files changed, 1351 insertions, 0 deletions
diff --git a/src/usr/hdat/hdatutil.C b/src/usr/hdat/hdatutil.C
new file mode 100644
index 000000000..4d95fbc8f
--- /dev/null
+++ b/src/usr/hdat/hdatutil.C
@@ -0,0 +1,1351 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/hdat/hdatutil.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#include "hdatutil.H"
+#include <i2c/eepromif.H>
+#include <stdio.h>
+
+#define UINT16_IN_LITTLE_ENDIAN(x) (((x) >> 8) | ((x) << 8))
+
+using namespace TARGETING;
+namespace HDAT
+{
+trace_desc_t *g_trac_hdat = NULL;
+TRAC_INIT(&g_trac_hdat,HDAT_COMP_NAME,4096);
+
+
+/*******************************************************************************
+* hdatBldErrLog
+*******************************************************************************/
+void hdatBldErrLog(errlHndl_t & io_err,
+ const uint8_t i_modid,
+ const uint16_t i_rc,
+ const uint32_t i_data1,
+ const uint32_t i_data2,
+ const uint32_t i_data3,
+ const uint32_t i_data4,
+ const ERRORLOG::errlSeverity_t i_sev,
+ const uint16_t i_version,
+ const bool i_commit,
+ const bool i_callout )
+{
+ HDAT_DBG("mod:0x%02X, rc:0x%02X, data:%08X %08X %08X %08X, sev:0x%02X",
+ i_modid, i_rc, i_data1, i_data2, i_data3, i_data4,
+ i_sev);
+
+ if (NULL == io_err)
+ {
+ io_err = new ERRORLOG::ErrlEntry(i_sev,
+ i_modid,
+ i_rc,
+ TWO_UINT32_TO_UINT64(i_data1,i_data2),
+ TWO_UINT32_TO_UINT64(i_data3,i_data4));
+ }
+ else
+ {
+ uint32_t additionalSrc[] =
+ {
+ uint32_t(HDAT_COMP_ID | i_rc), uint32_t(i_modid),
+ uint32_t(i_sev),
+ i_data1, i_data2, i_data3, i_data4
+ };
+ io_err->addFFDC(HDAT_COMP_ID,
+ additionalSrc,
+ sizeof(additionalSrc),
+ i_version,
+ SUBSEC_ADDITIONAL_SRC);
+
+ }
+
+ if ( i_callout )
+ {
+ io_err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ }
+ io_err->collectTrace(HDAT_COMP_NAME);
+ io_err->collectTrace("HDAT_DBG");
+ io_err->collectTrace("HDAT_ERR");
+
+ if ( i_commit )
+ {
+ ERRORLOG::errlCommit(io_err,HDAT_COMP_ID);
+ }
+}
+
+/*******************************************************************************
+* isFunctional
+*******************************************************************************/
+bool isFunctional( const Target* i_Target)
+{
+ bool o_funcState = false;
+ errlHndl_t l_errl = NULL;
+ do
+ {
+ if(NULL == i_Target)
+ {
+ HDAT_ERR("Input Target Pointer is NULL");
+ /*@
+ * @errortype
+ * @moduleid HDAT::MOD_UTIL_IS_FUNCTIONAL
+ * @reasoncode HDAT::RC_INVALID_OBJECT
+ * @devdesc Input Target Pointer is NULL
+ * @custdesc Firmware encountered an internal error
+ */
+ hdatBldErrLog(l_errl,
+ MOD_UTIL_IS_FUNCTIONAL,
+ RC_INVALID_OBJECT,
+ 0,0,0,0,
+ ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ HDAT_VERSION1,
+ true);
+ break;
+ }
+ else
+ {
+ o_funcState = i_Target->getAttr<ATTR_HWAS_STATE>().functional;
+ }
+ }while(0);
+ return o_funcState;
+}
+
+/*******************************************************************************
+* hdatGetIdEc
+*******************************************************************************/
+errlHndl_t hdatGetIdEc(const Target *i_pTarget,
+ uint32_t &o_ecLevel,
+ uint32_t &o_chipId)
+{
+ errlHndl_t l_err = NULL;
+
+ do
+ {
+ const TARGETING::Target *l_pCTarget = NULL;
+ if(i_pTarget->getAttr<TARGETING::ATTR_CLASS>() != TARGETING::CLASS_CHIP)
+ {
+ l_pCTarget = getParentChip(i_pTarget);
+ o_ecLevel = l_pCTarget->getAttr<TARGETING::ATTR_EC>();
+ o_chipId = l_pCTarget->getAttr<TARGETING::ATTR_CHIP_ID>();
+ }
+ else
+ {
+ o_ecLevel = i_pTarget->getAttr<TARGETING::ATTR_EC>();
+ o_chipId = i_pTarget->getAttr<TARGETING::ATTR_CHIP_ID>();
+ }
+ }
+ while(0);
+
+ return l_err;
+}
+
+/*******************************************************************************
+* hdatGetHwCardId
+*******************************************************************************/
+errlHndl_t hdatGetHwCardId(const Target *i_pTarget, uint32_t &o_cardId)
+{
+ errlHndl_t l_errl = NULL;
+ do
+ {
+ if(NULL == i_pTarget)
+ {
+ HDAT_ERR("Input Target pointer is NULL.");
+ /*@
+ * @errortype
+ * @moduleid HDAT::MOD_UTIL_CARD_ID
+ * @reasoncode HDAT::RC_INVALID_OBJECT
+ * @devdesc Input Target Pointer is NULL
+ * @custdesc Firmware encountered an internal
+ * error while retrieving target data
+ */
+ hdatBldErrLog(l_errl,
+ MOD_UTIL_CARD_ID,
+ RC_INVALID_OBJECT,
+ 0,0,0,0);
+ break;
+ }
+ if((i_pTarget->getAttr<ATTR_CLASS>() != CLASS_CARD)&&
+ (i_pTarget->getAttr<ATTR_CLASS>() != CLASS_LOGICAL_CARD)&&
+ (i_pTarget->getAttr<ATTR_CLASS>() != CLASS_CHIP))
+ {
+ HDAT_ERR("Input Target is class not supported.");
+ /*@
+ * @errortype
+ * @moduleid HDAT::MOD_UTIL_CARD_ID
+ * @reasoncode HDAT::RC_TARGET_UNSUPPORTED
+ * @devdesc Target is not currently supported
+ * @custdesc Firmware encountered an internal error
+ * while retrieving attribute data
+ */
+ hdatBldErrLog(l_errl,
+ MOD_UTIL_CARD_ID,
+ RC_TARGET_UNSUPPORTED,
+ 0,0,0,0);
+ break;
+ }
+ TARGETING::TargetHandleList targetList;
+ targetList.clear();
+ getParentAffinityTargets(targetList,i_pTarget,
+ TARGETING::CLASS_ENC,TARGETING::TYPE_NODE);
+ if(targetList.empty())
+ {
+ /*@
+ * @errortype
+ * @moduleid HDAT::MOD_UTIL_CARD_ID
+ * @reasoncode HDAT::RC_EMPTY_TARGET_LIST
+ * @devdesc Target list is empty
+ * @custdesc Firmware encountered an internal
+ * error while retrieving target data
+ */
+ hdatBldErrLog(l_errl,
+ MOD_UTIL_CARD_ID,
+ RC_EMPTY_TARGET_LIST,
+ 0,0,0,0);
+ break;
+ }
+ //get the parent node id
+ TARGETING::Target* l_pNodeTarget = targetList[0];
+ o_cardId = l_pNodeTarget->getAttr<ATTR_ORDINAL_ID>();
+ }
+ while(0);
+
+ return l_errl;
+}
+
+/**
+ * @brief This routine populates the MTM and Serial number attributes
+ of system Target
+ *
+ * @pre None
+ *
+ * @post None
+ *
+ * @param None
+ *
+ * @return None
+ */
+void hdatPopulateMTMAndSerialNumber()
+{
+ errlHndl_t l_errl = NULL;
+ TARGETING::ATTR_RAW_MTM_type l_rawMTM = {0};
+ TARGETING::ATTR_SERIAL_NUMBER_type l_serialNumber = {0};
+ TARGETING::Target *l_pSysTarget = NULL;
+ size_t l_vpdSize = 0;
+
+ (void) TARGETING::targetService().getTopLevelTarget(l_pSysTarget);
+ if(l_pSysTarget == NULL)
+ {
+ HDAT_ERR("Error in getting Top Level Target");
+ assert(l_pSysTarget != NULL);
+ }
+
+ TARGETING::PredicateCTM l_nodePredicate(TARGETING::CLASS_ENC,
+ TARGETING::TYPE_NODE);
+ TARGETING::PredicateHwas l_predHwas;
+ l_predHwas.present(true);
+
+ TARGETING::PredicatePostfixExpr l_presentNode;
+ l_presentNode.push(&l_nodePredicate).push(&l_predHwas).And();
+
+ //Get all Nodes
+ TARGETING::TargetRangeFilter l_nodeFilter(
+ TARGETING::targetService().begin(),
+ TARGETING::targetService().end(),
+ &l_presentNode);
+
+ TARGETING::Target *l_nodeTarget = (*l_nodeFilter);
+
+ l_errl = deviceRead(l_nodeTarget, NULL, l_vpdSize,
+ DEVICE_PVPD_ADDRESS( PVPD::OSYS, PVPD::MM ));
+
+ if(l_errl == NULL)
+ {
+ uint8_t l_vpddata[l_vpdSize];
+
+ l_errl = deviceRead(l_nodeTarget, l_vpddata, l_vpdSize,
+ DEVICE_PVPD_ADDRESS( PVPD::OSYS, PVPD::MM ));
+
+ if(l_errl == NULL)
+ {
+ const uint8_t l_mtmSize= 0x08;
+ //phyp would requre just 8 character of MTM
+ strncpy(l_rawMTM,reinterpret_cast<const char*>(l_vpddata),
+ l_mtmSize);
+ for(uint8_t i=0; i<sizeof(l_rawMTM); i++)
+ {
+ if(l_rawMTM[i] == '-')
+ {
+ l_rawMTM[i]='.';
+ break;
+ }
+ }
+
+ if(!l_pSysTarget->trySetAttr<TARGETING::ATTR_RAW_MTM>
+ (l_rawMTM))
+ {
+ HDAT_ERR("Error in setting MTM");
+ }
+ }
+ }
+ if(l_errl)
+ {
+ ERRORLOG::errlCommit(l_errl,HDAT_COMP_ID);
+ }
+
+ l_errl = deviceRead(l_nodeTarget, NULL, l_vpdSize,
+ DEVICE_PVPD_ADDRESS( PVPD::OSYS, PVPD::SS ));
+
+ if(l_errl == NULL)
+ {
+ uint8_t l_vpddata[l_vpdSize];
+
+ l_errl = deviceRead(l_nodeTarget, l_vpddata, l_vpdSize,
+ DEVICE_PVPD_ADDRESS( PVPD::OSYS, PVPD::SS ));
+
+ if(l_errl == NULL)
+ {
+ const uint8_t l_serialSize = 0x07;
+ //phyp would requre just 7 character of serial number
+ strncpy(reinterpret_cast<char *>(l_serialNumber),
+ reinterpret_cast<const char*>(l_vpddata),l_serialSize);
+
+ if(!l_pSysTarget->trySetAttr
+ <TARGETING::ATTR_SERIAL_NUMBER>(l_serialNumber))
+ {
+ HDAT_ERR("Error in setting Serial Number");
+ }
+ }
+ }
+
+ if(l_errl)
+ {
+ ERRORLOG::errlCommit(l_errl,HDAT_COMP_ID);
+ }
+
+}
+
+/**
+ * @brief This routine gets prefix of location code
+ *
+ * @pre None
+ *
+ * @post None
+ *
+ * @param o_locCode - output parameter - Location Code Prefix
+ *
+ * @return None
+ */
+void hdatGetLocationCodePrefix(char *o_locCode)
+{
+ TARGETING::ATTR_RAW_MTM_type l_rawMTM = {0};
+ TARGETING::ATTR_SERIAL_NUMBER_type l_serialNumber = {0};
+ TARGETING::Target *l_pSysTarget = NULL;
+
+ (void) TARGETING::targetService().getTopLevelTarget(l_pSysTarget);
+ if(l_pSysTarget == NULL)
+ {
+ HDAT_ERR("Error in getting Top Level Target");
+ assert(l_pSysTarget != NULL);
+ }
+
+ strcpy(o_locCode, "U");
+
+ //if(l_pSysTarget == TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL)
+ // {
+ // assert(false);
+ // }
+
+ if(l_pSysTarget->tryGetAttr<TARGETING::ATTR_RAW_MTM>(l_rawMTM))
+ {
+ if(l_pSysTarget->tryGetAttr<TARGETING::ATTR_SERIAL_NUMBER>
+ (l_serialNumber))
+ {
+ strcat(o_locCode,"OPWR");
+ strcat(o_locCode,".");
+ strcat(o_locCode,"BAR");
+ strcat(o_locCode,".");
+ strcat(o_locCode,(const char*)l_serialNumber);
+ }
+ else
+ {
+ HDAT_ERR("Error accessing ATTR_SERIAL_NUMBER attribute");
+ }
+ }
+ else
+ {
+ HDAT_ERR("Error accessing ATTR_RAW_MTM attribute");
+ }
+}
+
+/**
+ * @brief This routine constructs the location Code for the incoming target
+ *
+ * @pre None
+ *
+ * @post None
+ *
+ * @param i_pFruTarget - input parameter - System target
+ * i_locCodePrefix - input parameter - Location Code prefix
+ * o_locCode - output parameter - Constructed location code
+ *
+ * @return None
+ */
+void hdatGetLocationCode(TARGETING::Target *i_pFruTarget,
+ char *i_locCodePrefix,
+ char *o_locCode)
+{
+ TARGETING::ATTR_PHYS_PATH_type l_physPath;
+ char *l_pPhysPath;
+ char l_locCode[64] = {0};
+
+//@TODO:RTC 149347: Add methods to generate location codes
+
+ if(i_pFruTarget->tryGetAttr<TARGETING::ATTR_PHYS_PATH>(l_physPath))
+ {
+ char *l_cutString;
+ char *l_suffix;
+
+ l_pPhysPath = i_pFruTarget->getAttr
+ <TARGETING::ATTR_PHYS_PATH>().toString();
+
+ l_cutString = strchr(l_pPhysPath, '/');
+ l_suffix = l_cutString;
+
+ while (l_cutString != NULL)
+ {
+ l_suffix = l_cutString;
+ l_cutString = strchr(l_cutString+1, '/');
+ }
+
+#if USE_PHYS_PATH_FOR_LOC_CODE
+
+ strncpy(l_hdatslcaentry.location_code,
+ reinterpret_cast<const char *>
+ (i_Target->getAttr<TARGETING::ATTR_PHYS_PATH>().toString()),
+ l_hdatslcaentry.max_location_code_len);
+#else
+
+ sprintf(l_locCode, "%s-%s",i_locCodePrefix,(l_suffix+1));
+
+ uint8_t l_index = 0;
+ while(l_index < strlen(l_locCode))
+ {
+ if(l_locCode[l_index] != ' ')
+ {
+ *o_locCode++ = l_locCode[l_index];
+ }
+ l_index++;
+ }
+ // *o_locCode = 0;
+#endif
+ }
+ else
+ {
+ HDAT_ERR("Error accessing ATTR_PHYS_PATH attribute");
+ }
+}
+
+/******************************************************************************/
+//hdatGetAsciiKwd
+/******************************************************************************/
+
+errlHndl_t hdatGetAsciiKwd( TARGETING::Target * i_target,uint32_t &o_kwdSize,
+ char* &o_kwd,vpdType i_vpdtype,struct vpdData i_fetchVpd[],
+ uint32_t i_num, size_t theSize[])
+{
+ HDAT_ENTER();
+ errlHndl_t l_err = NULL;
+
+ switch (i_vpdtype)
+ {
+ case PROC:
+ l_err = hdatGetAsciiKwdForMvpd(i_target,o_kwdSize,o_kwd,
+ i_fetchVpd,i_num,theSize);
+ HDAT_DBG("got back kwd size=%x",o_kwdSize);
+ break;
+ case BP:
+ l_err = hdatGetAsciiKwdForPvpd(i_target,o_kwdSize,o_kwd,
+ i_fetchVpd,i_num,theSize);
+ HDAT_DBG("got back kwd size=%x",o_kwdSize);
+ break;
+ default:
+ HDAT_DBG("no appropriate vpd function to call");
+ break;
+ }
+ HDAT_EXIT();
+ return l_err;
+}//end hdatGetAsciiKwd
+
+/******************************************************************************/
+//hdatGetAsciiKwdForPvpd
+/******************************************************************************/
+errlHndl_t hdatGetAsciiKwdForPvpd(TARGETING::Target * i_target,
+ uint32_t &o_kwdSize,char* &o_kwd,
+ struct vpdData i_fetchVpd[], size_t i_num, size_t theSize[])
+{
+
+ errlHndl_t l_err = NULL;
+ uint64_t cmds = 0x0;
+ uint64_t fails = 0x0;
+ VPD::vpdRecord theRecord = 0x0;
+ VPD::vpdKeyword theKeyword = 0x0;
+
+
+ o_kwd = NULL;
+ o_kwdSize = 0;
+ //size_t theSize[i_num];
+ memset (theSize,0, sizeof(theSize));
+
+ do
+ {
+ assert(i_target != NULL);
+
+ uint8_t *theData = NULL;
+
+ const uint32_t numCmds = i_num;
+
+ for( uint32_t curCmd = 0; curCmd < numCmds; curCmd++ )
+ {
+ cmds++;
+ theRecord = i_fetchVpd[curCmd].record;
+ theKeyword = i_fetchVpd[curCmd].keyword;
+
+ if( theKeyword == PVPD::LX)
+ {
+ theSize[curCmd] = 0;
+ continue;
+ }
+ l_err = deviceRead( i_target,
+ NULL,
+ theSize[curCmd],
+ DEVICE_PVPD_ADDRESS( theRecord,
+ theKeyword ) );
+ if( l_err )
+ {
+ fails++;
+ HDAT_DBG("hdatGetAsciiKwdForPvpd::failure reading keyword size "
+ "rec: 0x%04x, kwd: 0x%04x",
+ theRecord,theKeyword );
+ /*@
+ * @errortype
+ * @moduleid HDAT::MOD_UTIL_PVPD_READ_FUNC
+ * @reasoncode HDAT::RC_PVPD_FAIL
+ * @userdata1 pvpd record
+ * @userdata2 pvpd keyword
+ * @devdesc PVPD read fail
+ * @custdesc Firmware encountered an internal error
+ */
+ hdatBldErrLog(l_err,
+ MOD_UTIL_PVPD_READ_FUNC,
+ RC_PVPD_FAIL,
+ theRecord,theKeyword,0,0,
+ ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ HDAT_VERSION1,
+ true);
+
+ continue;
+ }
+ HDAT_DBG("fetching BP kwd size PVPD, size initialised=%x "
+ " keyword =%04x",theSize[curCmd],theKeyword);
+ o_kwdSize += theSize[curCmd];
+ }
+
+ HDAT_DBG("hdatGetAsciiKwdForPvpd:: allocating total key word size %d",
+ o_kwdSize);
+ o_kwd = new char[o_kwdSize];
+
+ uint32_t loc = 0;
+ for( uint32_t curCmd = 0; curCmd < numCmds; curCmd++ )
+ {
+ theRecord = i_fetchVpd[curCmd].record;
+ theKeyword = i_fetchVpd[curCmd].keyword;
+
+ //this conidtion is , if in the top loop there is a fail then
+ //theSize[curCmd] will be 0.
+ if( theSize[curCmd] == 0)
+ {
+ continue;
+ }
+ theData = new uint8_t [theSize[curCmd]];
+
+ HDAT_DBG("hdatGetAsciiKwdForPvpd: reading %dth keyword of size %d",
+ curCmd,theSize[curCmd]);
+
+ l_err = deviceRead( i_target,
+ theData,
+ theSize[curCmd],
+ DEVICE_PVPD_ADDRESS( theRecord,
+ theKeyword ) );
+ HDAT_DBG("hdatGetAsciiKwdForPvpd: read BP data %s",theData);
+
+ if ( l_err )
+ {
+ fails++;
+ HDAT_DBG("hdatGetAsciiKwdForPvpd: Failure on Record: "
+ "0x%04x, keyword: 0x%04x, of size: 0x%04x - test %d",
+ theRecord,theKeyword,theSize,curCmd);
+ /*@
+ * @errortype
+ * @moduleid HDAT::MOD_UTIL_PVPD_READ_FUNC
+ * @reasoncode HDAT::RC_PVPD_READ_FAIL
+ * @userdata1 pvpd record
+ * @userdata2 pvpd keyword
+ * @devdesc PVPD read fail
+ * @custdesc Firmware encountered an internal error
+ */
+ hdatBldErrLog(l_err,
+ MOD_UTIL_PVPD_READ_FUNC,
+ RC_PVPD_READ_FAIL,
+ theRecord,theKeyword,0,0,
+ ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ HDAT_VERSION1,
+ true);
+
+ if ( NULL != theData )
+ {
+ delete[] theData;
+ theData = NULL;
+ }
+ continue;
+ }
+ if ( NULL != theData )
+ {
+ memcpy(reinterpret_cast<void *>(o_kwd + loc),theData,
+ theSize[curCmd]);
+
+ loc += theSize[curCmd];
+ delete[] theData;
+ theData = NULL;
+ HDAT_DBG("hdatGetAsciiKwdForPvpd: copied to main array %d kwd",
+ curCmd);
+ }
+ }
+ }while(0);
+
+ HDAT_DBG("hdatGetAsciiKwdForPvpd: returning keyword size %d and data %s",
+ o_kwdSize,o_kwd);
+ return l_err;
+
+}
+
+/******************************************************************************/
+// hdatGetAsciiKwdForMvpd
+/******************************************************************************/
+
+errlHndl_t hdatGetAsciiKwdForMvpd(TARGETING::Target * i_target,
+ uint32_t &o_kwdSize,char* &o_kwd,
+ struct vpdData i_fetchVpd[], uint32_t i_num,size_t theSize[])
+{
+ HDAT_ENTER();
+ errlHndl_t err = NULL;
+ uint64_t cmds = 0x0;
+ uint64_t fails = 0x0;
+ uint64_t theRecord = 0x0;
+ uint64_t theKeyword = 0x0;
+
+ o_kwd = NULL;
+ o_kwdSize = 0;
+
+
+ do
+ {
+ if(i_target == NULL)
+ {
+ HDAT_ERR("no functional Targets found");
+ break;
+ }
+
+ //size_t theSize[100] = {0};//assuming max kwd num 100
+ uint8_t *theData = NULL;
+
+
+ for( uint32_t curCmd = 0; curCmd < i_num; curCmd++ )
+ {
+ cmds++;
+ theRecord = (uint64_t)i_fetchVpd[curCmd].record;
+ theKeyword = (uint64_t)i_fetchVpd[curCmd].keyword;
+
+ HDAT_DBG("fetching proc kwd size MVPD, size initialised=%x",
+ theSize[curCmd]);
+ err = deviceRead( i_target,
+ NULL,
+ theSize[curCmd],
+ DEVICE_MVPD_ADDRESS( theRecord,
+ theKeyword ) );
+ HDAT_DBG("fetched proc kwd size MVPD, size=%x",theSize[curCmd]);
+
+ if( err )
+ {
+ fails++;
+ HDAT_DBG("failure reading keyword size "
+ "rec: 0x%04x, kwd: 0x%04x",
+ theRecord,theKeyword );
+ /*@
+ * @errortype
+ * @moduleid HDAT::MOD_UTIL_VPD
+ * @reasoncode HDAT::RC_DEV_READ_FAIL
+ * @devdesc Device read failed
+ * @custdesc Firmware encountered an internal error
+ */
+ hdatBldErrLog(err,
+ MOD_UTIL_VPD,
+ RC_DEV_READ_FAIL,
+ theRecord,theKeyword,0,0,
+ ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ HDAT_VERSION1,
+ true);
+ continue;
+ }
+ o_kwdSize += theSize[curCmd];
+ }
+
+ HDAT_DBG("allocating total key word size %d",
+ o_kwdSize);
+ //o_kwd = static_cast<char *>(malloc( o_kwdSize));
+ o_kwd = new char[o_kwdSize];
+
+ uint32_t loc = 0;
+ for( uint32_t curCmd = 0; curCmd < i_num; curCmd++ )
+ {
+ theRecord = (uint64_t)i_fetchVpd[curCmd].record;
+ theKeyword = (uint64_t)i_fetchVpd[curCmd].keyword;
+
+ //theData = static_cast<uint8_t*>(malloc( theSize[curCmd] ));
+ theData = new uint8_t [theSize[curCmd]];
+
+ HDAT_DBG("reading %dth keyword of size %d",
+ curCmd,theSize[curCmd]);
+
+ err = deviceRead( i_target,
+ theData,
+ theSize[curCmd],
+ DEVICE_MVPD_ADDRESS( theRecord,
+ theKeyword ) );
+ HDAT_DBG("read PROC data %s",theData);
+
+ if ( err )
+ {
+ fails++;
+ HDAT_DBG("hdatGetAsciiKwdForMvpd: Failure on Record: "
+ "0x%04x, keyword: 0x%04x, of size: 0x%04x - test %d",
+ theRecord,theKeyword,theSize,curCmd);
+
+ delete err;
+
+ if ( NULL != theData )
+ {
+ // free( theData );
+ delete[] theData;
+ theData = NULL;
+ }
+ continue;
+ }
+ if ( NULL != theData )
+ {
+ //copy to output array and free theData
+ memcpy(reinterpret_cast<void *>(o_kwd + loc),theData,
+ theSize[curCmd]);
+
+ loc += theSize[curCmd];
+ //free( theData );
+ delete[] theData;
+ theData = NULL;
+ HDAT_DBG("copied to main array %d kwd",
+ curCmd);
+ }
+ }
+
+ }while(0);
+
+ HDAT_DBG("returning keyword size %d and data %s",
+ o_kwdSize,o_kwd);
+
+ HDAT_EXIT();
+ return err;
+}//end hdatGetAsciiKwdForMvpd
+
+
+/******************************************************************************/
+// hdatGetAsciiKwdForCvpd
+/******************************************************************************/
+errlHndl_t hdatGetAsciiKwdForCvpd(TARGETING::Target * i_target,
+ uint32_t &o_kwdSize,char* &o_kwd,
+ struct vpdData i_fetchVpd[], size_t i_num,size_t theSize[])
+{
+
+ errlHndl_t l_err = NULL;
+ uint64_t cmds = 0x0;
+ uint64_t fails = 0x0;
+ VPD::vpdRecord theRecord = 0x0;
+ VPD::vpdKeyword theKeyword = 0x0;
+
+
+ o_kwd = NULL;
+ o_kwdSize = 0;
+ //size_t theSize[i_num];
+
+ do
+ {
+ assert(i_target != NULL);
+
+ uint8_t *theData = NULL;
+
+ const uint32_t numCmds = i_num;
+
+ for( uint32_t curCmd = 0; curCmd < numCmds; curCmd++ )
+ {
+ cmds++;
+ theRecord = i_fetchVpd[curCmd].record;
+ theKeyword = i_fetchVpd[curCmd].keyword;
+
+ HDAT_DBG("fetching DIMM kwd size CVPD, size initialised=%x",
+ theSize[curCmd]);
+ l_err = deviceRead( i_target,
+ NULL,
+ theSize[curCmd],
+ DEVICE_CVPD_ADDRESS( theRecord,
+ theKeyword ) );
+
+ if( l_err )
+ {
+ fails++;
+ HDAT_DBG("hdatGetAsciiKwdForCvpd::failure reading keyword size "
+ "rec: 0x%04x, kwd: 0x%04x",
+ theRecord,theKeyword );
+ /*@
+ * @errortype
+ * @moduleid HDAT::MOD_UTIL_CVPD_READ_FUNC
+ * @reasoncode HDAT::RC_CVPD_FAIL
+ * @userdata1 cvpd record
+ * @userdata2 cvpd keyword
+ * @devdesc CVPD read fail
+ * @custdesc Firmware encountered an internal error
+ */
+ hdatBldErrLog(l_err,
+ MOD_UTIL_CVPD_READ_FUNC,
+ RC_CVPD_FAIL,
+ theRecord,theKeyword,0,0,
+ ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ HDAT_VERSION1,
+ true);
+
+
+ continue;
+ }
+ o_kwdSize += theSize[curCmd];
+ }
+
+ HDAT_DBG("hdatGetAsciiKwdForCvpd:: allocating total key word size %d",
+ o_kwdSize);
+ o_kwd = new char[o_kwdSize];
+
+ uint32_t loc = 0;
+ for( uint32_t curCmd = 0; curCmd < numCmds; curCmd++ )
+ {
+ theRecord = i_fetchVpd[curCmd].record;
+ theKeyword = i_fetchVpd[curCmd].keyword;
+
+ //this conidtion is , if in the top loop there is a fail then
+ //theSize[curCmd] will be 0.
+ if( theSize[curCmd] == 0)
+ {
+ continue;
+ }
+ theData = new uint8_t [theSize[curCmd]];
+
+ HDAT_DBG("hdatGetAsciiKwdForCvpd: reading %dth keyword of size %d",
+ curCmd,theSize[curCmd]);
+
+ l_err = deviceRead( i_target,
+ theData,
+ theSize[curCmd],
+ DEVICE_CVPD_ADDRESS( theRecord,
+ theKeyword ) );
+ HDAT_DBG("hdatGetAsciiKwdForCvpd: read PROC data %s",theData);
+
+ if ( l_err )
+ {
+ fails++;
+ HDAT_DBG("hdatGetAsciiKwdForCvpd: Failure on Record: "
+ "0x%04x, keyword: 0x%04x, of size: 0x%04x - test %d",
+ theRecord,theKeyword,theSize,curCmd);
+ /*@
+ * @errortype
+ * @moduleid HDAT::MOD_UTIL_CVPD_READ_FUNC
+ * @reasoncode HDAT::RC_CVPD_READ_FAIL
+ * @userdata1 cvpd record
+ * @userdata2 cvpd keyword
+ * @devdesc CVPD read fail
+ * @custdesc Firmware encountered an internal error
+ */
+ hdatBldErrLog(l_err,
+ MOD_UTIL_CVPD_READ_FUNC,
+ RC_CVPD_READ_FAIL,
+ theRecord,theKeyword,0,0,
+ ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ HDAT_VERSION1,
+ true);
+
+ if ( NULL != theData )
+ {
+ delete[] theData;
+ theData = NULL;
+ }
+ continue;
+ }
+ if ( NULL != theData )
+ {
+ //copy to output array and free theData
+ memcpy(reinterpret_cast<void *>(o_kwd + loc),theData,
+ theSize[curCmd]);
+
+ loc += theSize[curCmd];
+ delete[] theData;
+ theData = NULL;
+ HDAT_DBG("hdatGetAsciiKwdForCvpd: copied to main array %d kwd",
+ curCmd);
+ }
+ }
+ }while(0);
+
+ HDAT_DBG("hdatGetAsciiKwdForCvpd: returning keyword size %d and data %s",
+ o_kwdSize,o_kwd);
+ return l_err;
+
+}
+
+/*******************************************************************************
+* hdatGetMaxCecNodes
+*******************************************************************************/
+
+uint32_t hdatGetMaxCecNodes()
+{
+ TARGETING::TargetHandleList l_nodeTargetList;
+ do
+ {
+ TARGETING::Target* sys = NULL;
+ TARGETING::targetService().getTopLevelTarget(sys);
+
+ PredicateCTM predNode(CLASS_ENC, TYPE_NODE);
+ PredicateHwas predFunctional;
+ predFunctional.functional(true);
+ PredicatePostfixExpr nodeCheckExpr;
+ nodeCheckExpr.push(&predNode).push(&predFunctional).And();
+ targetService().getAssociated(l_nodeTargetList, sys,
+ TargetService::CHILD, TargetService::IMMEDIATE,
+ &nodeCheckExpr);
+
+ }while(0);
+
+ return l_nodeTargetList.size();
+}
+
+/*******************************************************************************
+* hdatPrintHdrs
+*******************************************************************************/
+void hdatPrintHdrs(const hdatHDIF_t *i_hdif,
+ const hdatHDIFDataHdr_t *i_data,
+ const hdatHDIFDataArray_t *i_dataArray,
+ const hdatHDIFChildHdr_t *i_child)
+{
+ hdatHDIFDataHdr_t *l_data;
+ hdatHDIFChildHdr_t *l_child;
+ uint32_t l_idx;
+ char l_string[sizeof(i_hdif->hdatStructName)+1];
+
+ if (NULL != i_hdif)
+ {
+ // Null terminate the eye catcher string.
+ memcpy(l_string, &i_hdif->hdatStructName,
+ sizeof(i_hdif->hdatStructName));
+ l_string[sizeof(i_hdif->hdatStructName)] = 0x00;
+
+ HDAT_INF(" **hdatHDIF_t**");
+ HDAT_INF(" hdatStructId = 0X %04X ", i_hdif->hdatStructId);
+ HDAT_INF(" hdatStructName = %s", l_string);
+ HDAT_INF(" hdatInstance = %hu", i_hdif->hdatInstance);
+ HDAT_INF(" hdatVersion = %hu", i_hdif->hdatVersion);
+ HDAT_INF(" hdatSize = %u", i_hdif->hdatSize);
+ HDAT_INF(" hdatHdrSize = %u", i_hdif->hdatHdrSize);
+ HDAT_INF(" hdatDataPtrOffset = %u", i_hdif->hdatDataPtrOffset);
+ HDAT_INF(" hdatDataPtrCnt = %hu", i_hdif->hdatDataPtrCnt);
+ HDAT_INF(" hdatChildStrCnt = %hu", i_hdif->hdatChildStrCnt);
+ HDAT_INF(" hdatChildStrOffset = %u", i_hdif->hdatChildStrOffset);
+ }
+
+ if (NULL != i_data && NULL != i_hdif)
+ {
+ l_data = const_cast<hdatHDIFDataHdr_t *>(i_data);
+ HDAT_INF(" **hdatHDIFDataHdr_t**");
+ for (l_idx=0; l_idx<i_hdif->hdatDataPtrCnt; l_idx++)
+ {
+ HDAT_INF(" hdatOffset = %u", l_data->hdatOffset);
+ HDAT_INF(" hdatSize = %u", l_data->hdatSize);
+ l_data++;
+ }
+ }
+
+ if (NULL != i_child && NULL != i_hdif)
+ {
+ l_child = const_cast<hdatHDIFChildHdr_t *>(i_child);
+ HDAT_INF(" **hdatHDIFChildHdr_t**");
+ for (l_idx=0; l_idx<i_hdif->hdatChildStrCnt; l_idx++)
+ {
+ HDAT_INF(" hdatOffset = %u", l_child->hdatOffset);
+ HDAT_INF(" hdatSize = %u", l_child->hdatSize);
+ HDAT_INF(" hdatCnt = %u", l_child->hdatCnt);
+ l_child++;
+ }
+ HDAT_INF("");
+ }
+
+ if (NULL != i_dataArray)
+ {
+ HDAT_INF(" **hdatHDIFDataArray_t**");
+ HDAT_INF(" hdatOffset = %u", i_dataArray->hdatOffset);
+ HDAT_INF(" hdatArrayCnt = %u", i_dataArray->hdatArrayCnt);
+ HDAT_INF(" hdatAllocSize = %u", i_dataArray->hdatAllocSize);
+ HDAT_INF(" hdatActSize = %u", i_dataArray->hdatActSize);
+ }
+
+ return;
+}
+
+/*******************************************************************************
+* hdatPrintKwd
+*******************************************************************************/
+void hdatPrintKwd(const char *i_kwd,
+ int32_t i_kwdLen)
+{
+ const uint32_t HDAT_HEX_SIZE = 16; //16 hex characters per line
+ uint32_t l_cnt, l_lines, l_rem ;
+ char * l_kwd = const_cast<char *>(i_kwd);
+
+
+ l_lines = i_kwdLen / HDAT_HEX_SIZE;
+ l_rem = i_kwdLen % HDAT_HEX_SIZE;
+
+ HDAT_INF(" **ASCII keyword VPD**");
+ if (NULL == i_kwd)
+ {
+ HDAT_INF(" No keyword VPD");
+ }
+ else
+ {
+ for (l_cnt = 0; l_cnt < l_lines; l_cnt++)
+ {
+ HDAT_INF( "0X %08X %08X %08X %08X",
+ (*(reinterpret_cast<uint32_t *>(l_kwd ))) ,
+ (*(reinterpret_cast<uint32_t *>(l_kwd + 4))),
+ (*(reinterpret_cast<uint32_t *>(l_kwd + 8))) ,
+ (*(reinterpret_cast<uint32_t *>(l_kwd + 12))) );
+
+ i_kwd += 16;
+ } // end for loop
+
+
+ if ( l_rem > 0 )
+ {
+ // More to print, but can't go past end of storage and
+ // not easy to use TRACF statements for this
+ if ( l_rem < 5 )
+ {
+ HDAT_INF( "0X %08X ", (*(reinterpret_cast<uint32_t *>(l_kwd))) );
+ }
+ else if ( l_rem < 9 )
+ {
+ HDAT_INF( "0X %08X %08X ",
+ (*(reinterpret_cast<uint32_t *>(l_kwd ))) ,
+ (*(reinterpret_cast<uint32_t *>(l_kwd + 4))) );
+ }
+ else if ( l_rem < 13 )
+ {
+ HDAT_INF( "0X %08X %08X %08X ",
+ (*(reinterpret_cast<uint32_t *>(l_kwd ))) ,
+ (*(reinterpret_cast<uint32_t *>(l_kwd + 4))),
+ (*(reinterpret_cast<uint32_t *>(l_kwd + 8))) );
+ }
+ else
+ { // remainder is up to 15 bytes
+ HDAT_INF( "0X %08X %08X %08X %08X",
+ (*(reinterpret_cast<uint32_t *>(l_kwd ))) ,
+ (*(reinterpret_cast<uint32_t *>(l_kwd + 4))),
+ (*(reinterpret_cast<uint32_t *>(l_kwd + 8))) ,
+ (*(reinterpret_cast<uint32_t *>(l_kwd + 12))) );
+ }
+
+ } // end if remainder non-zero
+
+ } // else we have keyword VPD
+
+ return;
+}
+
+/******************************************************************************/
+// hdatGetAsciiKwdForSpd
+/******************************************************************************/
+errlHndl_t hdatGetAsciiKwdForSpd(TARGETING::Target * i_target,
+ size_t &o_kwdSize,char* &o_kwd)
+{
+
+ errlHndl_t l_err = NULL;
+ uint64_t keyword = SPD::ENTIRE_SPD;
+
+ do
+ {
+ assert(i_target != NULL);
+
+ l_err = deviceRead( i_target,
+ NULL,
+ o_kwdSize,
+ DEVICE_SPD_ADDRESS(keyword) );
+ if (l_err)
+ {
+ break;
+ }
+
+ o_kwd = new char[o_kwdSize];
+
+ l_err = deviceRead( i_target,
+ o_kwd,
+ o_kwdSize,
+ DEVICE_SPD_ADDRESS(keyword) );
+
+ }while(0);
+ if ( l_err )
+ {
+ HDAT_DBG("hdatGetAsciiKwdForSpd : Failure on "
+ " keyword: 0x%04x, of size: 0x%04x ",
+ keyword,o_kwdSize);
+ /*@
+ * @errortype
+ * @moduleid HDAT::MOD_UTIL_SPD_READ_FUNC
+ * @reasoncode HDAT::RC_SPD_READ_FAIL
+ * @userdata1 spd keyword
+ * @devdesc SPD read fail
+ * @custdesc Firmware encountered an internal error
+ */
+ hdatBldErrLog(l_err,
+ MOD_UTIL_SPD_READ_FUNC,
+ RC_SPD_READ_FAIL,
+ keyword,0,0,0,
+ ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ HDAT_VERSION1,
+ true);
+
+ if ( NULL != o_kwd)
+ {
+ delete[] o_kwd;
+ o_kwd = NULL;
+ }
+ }
+
+ HDAT_DBG("hdatGetAsciiKwdForSpd: returning keyword size %d and data %s",
+ o_kwdSize,o_kwd);
+ return l_err;
+
+}
+
+void hdatGetTarget (const hdatSpiraDataAreas i_dataArea,
+ TARGETING::TargetHandleList &o_targList)
+{
+ TARGETING::TYPE l_type;
+ TARGETING::CLASS l_class;
+
+ switch (i_dataArea)
+ {
+ case HDAT_BACKPLANE_VPD:
+ l_type = TARGETING::TYPE_NODE;
+ l_class = TARGETING::CLASS_ENC;
+ break;
+
+ case HDAT_CLOCK_VPD:
+ l_type = TARGETING::TYPE_NA;
+ l_class = TARGETING::CLASS_NA;
+ break;
+
+ case HDAT_SYS_VPD:
+ l_type = TARGETING::TYPE_SYS;
+ l_class = TARGETING::CLASS_SYS;
+ break;
+
+ case HDAT_ENCLOSURE_VPD:
+ l_type = TARGETING::TYPE_NA;
+ l_class = TARGETING::CLASS_NA;
+ break;
+
+ case HDAT_ANCHOR_VPD:
+ l_type = TARGETING::TYPE_NA;
+ l_class = TARGETING::CLASS_NA;
+ break;
+
+ case HDAT_MISC_CEC_VPD:
+ l_type = TARGETING::TYPE_NA;
+ l_class = TARGETING::CLASS_NA;
+ break;
+ default:
+ l_type = TARGETING::TYPE_NA;
+ l_class = TARGETING::CLASS_NA;
+ break;
+ }
+
+ if ( (l_type != TARGETING::TYPE_NA) &&
+ (l_class != TARGETING::CLASS_NA))
+ {
+ TARGETING::Target* l_sys = NULL;
+ TARGETING::targetService().getTopLevelTarget(l_sys);
+ assert(l_sys != NULL);
+
+ if( (l_type == TARGETING::TYPE_SYS ) &&
+ (l_class == TARGETING::CLASS_SYS))
+ {
+ o_targList.push_back(l_sys);
+ }
+ else
+ {
+ PredicateCTM predNode(l_class, l_type);
+ PredicateHwas predFunctional;
+ predFunctional.functional(true);
+ PredicatePostfixExpr nodeCheckExpr;
+ nodeCheckExpr.push(&predNode).push(&predFunctional).And();
+
+ targetService().getAssociated(o_targList, l_sys,
+ TargetService::CHILD, TargetService::IMMEDIATE,
+ &nodeCheckExpr);
+ }
+
+ }
+
+}
+
+errlHndl_t hdatformatAsciiKwd(const struct vpdData i_fetchVpd[],
+ const size_t &i_num, const size_t theSize[], char* &i_kwd,
+ const uint32_t &i_kwdSize, char* &o_fmtKwd, uint32_t &o_fmtkwdSize,
+ const HdatKeywordInfo i_Keywords[])
+{
+ HDAT_ENTER();
+
+ // i_kwdSize - data size
+ // (i_num* sizeof(uint8_t)) - individual datat size
+ // (2 * sizeof(uint8_t)) - 0x78, 0x84
+ // sizeof(uint16_t) = total data size in size
+ // (i_num* 2) - keyword size
+ o_fmtkwdSize = i_kwdSize + (i_num* sizeof(uint8_t)) +
+ (2 * sizeof(uint8_t)) + sizeof(uint16_t) + (i_num* 2);
+
+ o_fmtKwd = new char[o_fmtkwdSize];
+ //Tag for start of the section
+ uint8_t l_initial = 0x84;
+ uint16_t l_kwdSize = o_fmtkwdSize - sizeof(uint16_t) - (2*sizeof(uint8_t));
+
+ //Need to convert the size into little endian as per format
+ l_kwdSize= UINT16_IN_LITTLE_ENDIAN(l_kwdSize);
+ memcpy(reinterpret_cast<void *>(o_fmtKwd ),&l_initial,sizeof(l_initial));
+ memcpy(reinterpret_cast<void *>(o_fmtKwd + 1),&l_kwdSize,sizeof(l_kwdSize));
+
+ uint32_t l_loc = sizeof(uint16_t) + sizeof(uint8_t);
+ char *ptr = i_kwd;
+
+ for( uint32_t curCmd = 0; curCmd < i_num; curCmd++ )
+ {
+ if( theSize[curCmd] != 0)
+ {
+ memcpy(reinterpret_cast<void *>(o_fmtKwd + l_loc),
+ &i_Keywords[curCmd].keywordName, 2);
+ l_loc += 2;
+
+ uint8_t l_var = theSize[curCmd];
+ memcpy(reinterpret_cast<void *>(o_fmtKwd + l_loc),&l_var,
+ sizeof(uint8_t));
+
+ l_loc += sizeof(uint8_t);
+
+ memcpy(reinterpret_cast<void *>(o_fmtKwd + l_loc),ptr,
+ theSize[curCmd]);
+
+ l_loc += theSize[curCmd];
+
+ ptr += theSize[curCmd];
+ }
+ }
+ //End start tag of the section
+ uint8_t l_end= 0x78;
+ memcpy(reinterpret_cast<void *>(o_fmtKwd +l_loc),&l_end,sizeof(uint8_t));
+ l_loc +=sizeof(uint8_t);
+
+ HDAT_EXIT();
+ return NULL;
+}
+
+
+errlHndl_t hdatGetFullEepromVpd(TARGETING::Target * i_target,
+ size_t &io_dataSize,
+ char* &o_data)
+{
+ errlHndl_t err = NULL;
+
+ HDAT_ENTER();
+ if(i_target != NULL)
+ {
+ o_data = new char[io_dataSize];
+
+ //Collecting Full module VPD data
+ err = deviceOp( DeviceFW::READ,
+ i_target,
+ o_data,
+ io_dataSize,
+ DEVICE_EEPROM_ADDRESS(EEPROM::VPD_PRIMARY, 0));
+ if(err)
+ {
+ HDAT_ERR("Reading Full vpd from Eeprom failed");
+ /*@
+ * @errortype
+ * @moduleid HDAT::MOD_UTIL_FULL_MVPD_READ_FUNC
+ * @reasoncode HDAT::RC_DEV_READ_VPD_FAIL
+ * @devdesc Device read failed
+ * @custdesc Firmware encountered an internal error
+ */
+ hdatBldErrLog(err,
+ MOD_UTIL_FULL_MVPD_READ_FUNC,
+ RC_DEV_READ_VPD_FAIL,
+ 0,0,0,0,
+ ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ HDAT_VERSION1,
+ true);
+ if(o_data != NULL) // No point in keeping this data with err
+ {
+ delete[] o_data;
+ o_data = NULL;
+ }
+ }
+ }
+ else
+ {
+ HDAT_ERR("Input Target is Null");
+ }
+ HDAT_EXIT();
+ return(err);
+}
+
+
+} //namespace HDAT
OpenPOWER on IntegriCloud