summaryrefslogtreecommitdiffstats
path: root/src/usr/htmgt
diff options
context:
space:
mode:
authorDoug Gilbert <dgilbert@us.ibm.com>2015-01-26 14:41:54 -0600
committerA. Patrick Williams III <iawillia@us.ibm.com>2015-02-28 05:49:51 -0600
commit29581aca6a1ed02d3374e5688e5f32fcb6f104bc (patch)
tree11f3ef76e83a0e18b313e2aa67b45292190e4b2a /src/usr/htmgt
parent9ca7f528d22e488c53d2dfbad32423806b47ddb0 (diff)
downloadtalos-hostboot-29581aca6a1ed02d3374e5688e5f32fcb6f104bc.tar.gz
talos-hostboot-29581aca6a1ed02d3374e5688e5f32fcb6f104bc.zip
HTMGT: Implement OCC Reset
Change-Id: Icb713497d662d1ab55718409675bf4b23ac2c3ec RTC: 121721 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/15530 Tested-by: Jenkins Server Reviewed-by: Christopher Cain <cjcain@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/htmgt')
-rw-r--r--src/usr/htmgt/htmgt.C93
-rw-r--r--src/usr/htmgt/htmgt_activate.C22
-rw-r--r--src/usr/htmgt/htmgt_activate.H4
-rw-r--r--src/usr/htmgt/htmgt_cfgdata.C2
-rw-r--r--src/usr/htmgt/htmgt_occ.C184
-rw-r--r--src/usr/htmgt/htmgt_occ.H103
-rw-r--r--src/usr/htmgt/htmgt_occcmd.C6
-rw-r--r--src/usr/htmgt/htmgt_occcmd.H10
-rw-r--r--src/usr/htmgt/htmgt_poll.C170
-rw-r--r--src/usr/htmgt/htmgt_poll.H16
10 files changed, 497 insertions, 113 deletions
diff --git a/src/usr/htmgt/htmgt.C b/src/usr/htmgt/htmgt.C
index b6498ca05..33d4f16c2 100644
--- a/src/usr/htmgt/htmgt.C
+++ b/src/usr/htmgt/htmgt.C
@@ -43,6 +43,9 @@
#include <targeting/common/attributes.H>
#include <targeting/common/targetservice.H>
+// HBOCC support
+#include <hwpf/hwp/occ/occ_common.H>
+
#include <sys/time.h>
@@ -92,10 +95,16 @@ namespace HTMGT
// Make sure OCCs are ready for communication
occMgr::instance().waitForOccCheckpoint();
+#ifdef __HOSTBOOT_RUNTIME
+ // TODO RTC 124738 Final solution TBD
+ // Perhapse POLL scom 0x6a214 until bit 31 is set?
+ nanosleep(1,0);
+#endif
+
// Send poll to establish comm
TMGT_INF("Send initial poll to all OCCs to"
" establish comm");
- l_err = sendOccPoll();
+ l_err = OccManager::sendOccPoll();
if (l_err)
{
// Continue even if failed (poll will be retried)
@@ -121,7 +130,7 @@ namespace HTMGT
// Set active sensors for all OCCs,
// so BMC can start communication with OCCs
- l_err = setOccActiveSensors();
+ l_err = setOccActiveSensors(true);
if (l_err)
{
// Continue even if failed to update sensor
@@ -137,7 +146,7 @@ namespace HTMGT
// Poll the OCCs to retrieve any errors that may
// have been created
TMGT_INF("Send final poll to all OCCs");
- l_err = sendOccPoll(true);
+ l_err = OccManager::sendOccPoll(true);
if (l_err)
{
ERRORLOG::errlCommit(l_err, HTMGT_COMP_ID);
@@ -235,10 +244,20 @@ namespace HTMGT
// Notify HTMGT that an OCC has an error to report
- void processOccError(TARGETING::Target * i_occTarget)
+ void processOccError(TARGETING::Target * i_proc)
{
- const uint32_t l_huid = i_occTarget->getAttr<TARGETING::ATTR_HUID>();
+ const uint32_t l_huid = i_proc->getAttr<TARGETING::ATTR_HUID>();
TMGT_INF("processOccError(HUID=0x%08X) called", l_huid);
+
+ //TARGETING::Target * failedOccTarget = NULL;
+ // Get OCC target (one per proc)
+ TARGETING::TargetHandleList pOccs;
+ getChildChiplets(pOccs, i_proc, TARGETING::TYPE_OCC);
+ if (pOccs.size() > 0)
+ {
+ // failedOccTarget = pOccs[0];
+ }
+
// TODO RTC 109224
} // end processOccError()
@@ -246,13 +265,67 @@ namespace HTMGT
// Notify HTMGT that an OCC has failed and needs to be reset
- void processOccReset(TARGETING::Target * i_failedOccTarget)
+ void processOccReset(TARGETING::Target * i_proc)
{
- const uint32_t l_huid =
- i_failedOccTarget->getAttr<TARGETING::ATTR_HUID>();
- TMGT_INF("processOccReset(HUID=0x%08X) called", l_huid);
- // TODO RTC 115296
+ errlHndl_t errl = NULL;
+ TARGETING::Target * failedOccTarget = NULL;
+
+ TARGETING::Target* sys = NULL;
+ TARGETING::targetService().getTopLevelTarget(sys);
+ uint8_t safeMode = 0;
+ // If the system is in safemode then ignore request to reset OCCs
+ if(sys &&
+ sys->tryGetAttr<TARGETING::ATTR_HTMGT_SAFEMODE>(safeMode) &&
+ safeMode)
+ {
+ return;
+ }
+
+ // Get functional OCC (one per proc)
+ TARGETING::TargetHandleList pOccs;
+ getChildChiplets(pOccs, i_proc, TARGETING::TYPE_OCC);
+ if (pOccs.size() > 0)
+ {
+ failedOccTarget = pOccs[0];
+ }
+
+ if(NULL != failedOccTarget)
+ {
+ uint32_t huid = failedOccTarget->getAttr<TARGETING::ATTR_HUID>();
+ TMGT_INF("processOccReset(HUID=0x%08X) called", huid);
+ }
+ else
+ {
+ uint32_t huid = i_proc->getAttr<TARGETING::ATTR_HUID>();
+ TMGT_INF("processOccReset: Invalid OCC target (proc huid=0x08X)"
+ "resetting OCCs anyway",
+ huid);
+
+ /*@
+ * @errortype
+ * @reasoncode HTMGT_RC_INVALID_PARAMETER
+ * @moduleid HTMGT_MOD_PROCESS_OCC_RESET
+ * @userdata1[0:7] Processor HUID
+ * @devdesc No OCC target found for proc Target,
+ */
+ bldErrLog(errl,
+ HTMGT_MOD_PROCESS_OCC_RESET,
+ HTMGT_RC_INVALID_PARAMETER,
+ huid, 0, 0, 1,
+ ERRORLOG::ERRL_SEV_INFORMATIONAL);
+
+ // Add HB firmware callout
+ errl->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_MED);
+ ERRORLOG::errlCommit(errl, HTMGT_COMP_ID); // sets errl to NULL
+ }
+
+ errl = OccManager::resetOccs(failedOccTarget);
+ if(errl)
+ {
+ ERRORLOG::errlCommit(errl, HTMGT_COMP_ID); // sets errl to NULL
+ }
} // end processOccReset()
diff --git a/src/usr/htmgt/htmgt_activate.C b/src/usr/htmgt/htmgt_activate.C
index a18d5039e..c23e8b0a4 100644
--- a/src/usr/htmgt/htmgt_activate.C
+++ b/src/usr/htmgt/htmgt_activate.C
@@ -73,7 +73,7 @@ namespace HTMGT
do
{
// Poll all OCCs
- l_err = sendOccPoll();
+ l_err = OccManager::sendOccPoll();
++numPolls;
if (NULL != l_err)
{
@@ -148,13 +148,25 @@ namespace HTMGT
- // Set active sensors for all OCCs so BMC can start communication
- errlHndl_t setOccActiveSensors()
+ // Set active/inactive sensors for all OCCs so BMC can start communication
+ errlHndl_t setOccActiveSensors(bool i_activate)
{
errlHndl_t l_err = NULL;
- TMGT_INF("setOccActiveSensors: STUB");
- // TODO RTC 119073
+ TMGT_INF("setOccActiveSensors:");
+ std::vector<Occ*> occList = occMgr::instance().getOccArray();
+ for (std::vector<Occ*>::iterator itr = occList.begin();
+ (itr < occList.end());
+ ++itr)
+ {
+ Occ * occ = (*itr);
+ l_err = occ->ipmiSensor(i_activate);
+ if( l_err )
+ {
+ ERRORLOG::errlCommit(l_err, HTMGT_COMP_ID);
+ }
+ }
+
return l_err;
}
diff --git a/src/usr/htmgt/htmgt_activate.H b/src/usr/htmgt/htmgt_activate.H
index 74bf8ee70..7e2480f54 100644
--- a/src/usr/htmgt/htmgt_activate.H
+++ b/src/usr/htmgt/htmgt_activate.H
@@ -49,9 +49,11 @@ namespace HTMGT
/**
* @brief Set active sensors for all OCCs so BMC can start communication
*
+ * @param[in] i_activate [true - set active | false - set inactive]
* @return NULL if all sensors were updated, else error handle
+ *
*/
- errlHndl_t setOccActiveSensors();
+ errlHndl_t setOccActiveSensors(bool i_activate);
/**
diff --git a/src/usr/htmgt/htmgt_cfgdata.C b/src/usr/htmgt/htmgt_cfgdata.C
index 66a1a237c..338e29efa 100644
--- a/src/usr/htmgt/htmgt_cfgdata.C
+++ b/src/usr/htmgt/htmgt_cfgdata.C
@@ -211,7 +211,7 @@ namespace HTMGT
}
// Send poll between config packets to flush errors
- l_err = sendOccPoll();
+ l_err = OccManager::sendOccPoll();
if (l_err)
{
ERRORLOG::errlCommit(l_err, HTMGT_COMP_ID);
diff --git a/src/usr/htmgt/htmgt_occ.C b/src/usr/htmgt/htmgt_occ.C
index d31694c6d..237df3e16 100644
--- a/src/usr/htmgt/htmgt_occ.C
+++ b/src/usr/htmgt/htmgt_occ.C
@@ -40,6 +40,8 @@
#include <ecmdDataBufferBase.H>
#include <hwpf/hwp/occ/occAccess.H>
+#include <hwpf/hwp/occ/occ.H>
+#include <hwpf/hwp/occ/occ_common.H>
namespace HTMGT
{
@@ -61,6 +63,7 @@ namespace HTMGT
iv_target(i_target),
iv_lastPollValid(false),
iv_occsPresent(1 << i_instance),
+ iv_resetCount(0),
iv_version(0x01)
{
}
@@ -172,6 +175,52 @@ namespace HTMGT
};
+ // Reset OCC
+ bool Occ::resetPrep()
+ {
+ errlHndl_t err = NULL;
+ bool atThreshold = false;
+
+ // Send resetPrep command
+ uint8_t cmdData[2];
+ cmdData[0] = OCC_RESET_CMD_VERSION;
+
+ if(iv_failed)
+ {
+ cmdData[1] = OCC_RESET_FAIL_THIS_OCC;
+ ++iv_resetCount;
+ if(iv_resetCount > OCC_RESET_COUNT_THRESHOLD)
+ {
+ atThreshold = true;
+ }
+ }
+ else
+ {
+ cmdData[1] = OCC_RESET_FAIL_OTHER_OCC;
+ }
+
+ OccCmd cmd(this, OCC_CMD_RESET_PREP, sizeof(cmdData), cmdData);
+ err = cmd.sendOccCmd();
+ if(err)
+ {
+ // log error and keep going
+ TMGT_ERR("OCC::resetPrep: OCC%d resetPrep failed with rc = 0x%04x",
+ iv_instance,
+ err->reasonCode());
+
+ ERRORLOG::errlCommit(err, HTMGT_COMP_ID);
+ }
+
+ // poll and flush error logs from OCC - Check Ex return code
+ err = pollForErrors(true);
+ if(err)
+ {
+ ERRORLOG::errlCommit(err, HTMGT_COMP_ID);
+ }
+
+ return atThreshold;
+ }
+
/////////////////////////////////////////////////////////////////
@@ -187,6 +236,7 @@ namespace HTMGT
OccManager::~OccManager()
{
+ _removeAllOccs();
}
@@ -214,6 +264,15 @@ namespace HTMGT
{
TMGT_INF("buildOccs called");
+#if defined(__HOSTBOOT_RUNTIME)
+ // At runtime need to keep occ state, only build OCC objects once.
+ if(iv_occArray.size() > 0 && iv_occMaster != NULL)
+ {
+ TMGT_INF("buildOccs: Existing OCC Targets kept = %d",
+ iv_occArray.size());
+ return iv_occArray.size();
+ }
+#endif
// Remove existing OCC objects
_removeAllOccs();
@@ -480,6 +539,125 @@ namespace HTMGT
} // end OccManager::_setOccState()
+ errlHndl_t OccManager::_resetOccs(TARGETING::Target * i_failedOccTarget)
+ {
+ errlHndl_t err = NULL;
+ bool atThreshold = false;
+
+ _buildOccs(); // if not a already built.
+ err = setOccActiveSensors(false); // Set OCC sensor to inactive
+ if( err )
+ {
+ TMGT_ERR("_resetOccs: Set OCC sensors to inactive failed.");
+ // log and continue
+ ERRORLOG::errlCommit(err, HTMGT_COMP_ID);
+ }
+
+ // Send poll cmd to all OCCs to establish comm
+ err = _sendOccPoll(false,NULL);
+ if (err)
+ {
+ TMGT_ERR("_resetOccs: Poll OCCs failed.");
+ // Proceed with reset even if failed
+ ERRORLOG::errlCommit(err, HTMGT_COMP_ID);
+ }
+
+ for(occList_t::const_iterator occ = iv_occArray.begin();
+ occ != iv_occArray.end();
+ ++occ)
+ {
+ if((*occ)->getTarget() == i_failedOccTarget)
+ {
+ (*occ)->failed(true);
+ }
+
+ if((*occ)->resetPrep())
+ {
+ atThreshold = true;
+ }
+ }
+
+ uint64_t retryCount = OCC_RESET_COUNT_THRESHOLD;
+ while(retryCount)
+ {
+ // Reset all OCCs
+ TMGT_INF("Calling HBOCC::stopAllOCCs");
+ err = HBOCC::stopAllOCCs();
+ if(!err)
+ {
+ break;
+ }
+ --retryCount;
+
+ if(retryCount)
+ {
+ // log if not last retry
+ ERRORLOG::errlCommit(err, HTMGT_COMP_ID);
+ }
+ else
+ {
+ TMGT_ERR("_resetOCCs: stopAllOCCs failed. "
+ "Leaving OCCs in reset state");
+ // pass err handle back
+ err->collectTrace("HTMGT");
+ }
+ }
+
+ if(!atThreshold && !err)
+ {
+ for(occList_t::const_iterator occ = iv_occArray.begin();
+ occ != iv_occArray.end();
+ ++occ)
+ {
+ (*occ)->failed(false);
+ }
+
+ TMGT_INF("Calling HBOCC::activateOCCs");
+
+ err = HBOCC::activateOCCs();
+ if(err)
+ {
+ TMGT_ERR("_resetOCCs: activateOCCs failed. ");
+ err->collectTrace("HTMGT");
+ }
+ }
+ else if (!err) // Reset Threshold reached and no other err
+ {
+ // Create threshold error
+ TMGT_ERR("_resetOCCs: Retry Threshold reached. "
+ "Leaving OCCs in reset state");
+ /*@
+ * @errortype
+ * @moduleid HTMTG_MOD_OCC_RESET
+ * @reasoncode HTMGT_RC_OCC_RESET_THREHOLD
+ * @devdesc OCC reset threshold reached.
+ * Leaving OCCs in reset state
+ */
+ bldErrLog(err,
+ HTMTG_MOD_OCC_RESET,
+ HTMGT_RC_OCC_RESET_THREHOLD,
+ 0, 0, 0, 0,
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE);
+ }
+
+ // Any error at this point means OCCs were not reactivated
+ if(err)
+ {
+ err->setSev(ERRORLOG::ERRL_SEV_UNRECOVERABLE);
+
+ TARGETING::Target* sys = NULL;
+ TARGETING::targetService().getTopLevelTarget(sys);
+ uint8_t safeMode = 1;
+
+ // Put into safemode
+ if(sys)
+ {
+ sys->setAttr<TARGETING::ATTR_HTMGT_SAFEMODE>(safeMode);
+ }
+ }
+
+ return err;
+ }
// Wait for all OCCs to reach communications checkpoint
void OccManager::_waitForOccCheckpoint()
@@ -592,6 +770,12 @@ namespace HTMGT
return Singleton<OccManager>::instance()._setOccState(i_state);
}
+ errlHndl_t OccManager::resetOccs(TARGETING::Target * i_failedOccTarget)
+ {
+ return
+ Singleton<OccManager>::instance()._resetOccs(i_failedOccTarget);
+ }
+
occStateId OccManager::getTargetState()
{
diff --git a/src/usr/htmgt/htmgt_occ.H b/src/usr/htmgt/htmgt_occ.H
index 72834346d..13d17a1a5 100644
--- a/src/usr/htmgt/htmgt_occ.H
+++ b/src/usr/htmgt/htmgt_occ.H
@@ -28,6 +28,9 @@
#include <stdint.h>
#include <vector>
+#if defined(CONFIG_BMC_IPMI)
+#include <ipmi/ipmisensor.H>
+#endif
namespace HTMGT
@@ -59,6 +62,11 @@ namespace HTMGT
OCC_ROLE_FIR_MASTER = 0x80
};
+ enum
+ {
+ OCC_RESET_COUNT_THRESHOLD = 3,
+ };
+
/**
@@ -129,13 +137,17 @@ namespace HTMGT
/**
- * @brief Process an OCC poll response
+ * @brief Poll for Errors
*
- * @param[in] i_pollResponse pointer to the response
- * @param[in] i_pollResponseSize length of the poll response
+ * @param[in] i_flushAllErrors:
+ * If set to true, HTMGT will send poll cmds
+ * to the OCC as long as the OCC continues
+ * to report errors. If false, only one
+ * poll will be sent.
+ *
+ * @return NULL on success, else error handle
*/
- void pollRspHandler(const uint8_t * i_pollResponse,
- const uint16_t i_pollResponseSize);
+ errlHndl_t pollForErrors(const bool i_flushAllErrors = false);
/**
@@ -175,6 +187,36 @@ namespace HTMGT
*/
occStateId getState() { return iv_state; };
+ /**
+ * @brief Prepare this OCC for reset
+ * @return return true if at threshold otherwise false
+ */
+ bool resetPrep();
+
+ /**
+ * @brief Set IPMI OCC sensor state
+ * @param i_activate: true - set active
+ * false - set inactive
+ *
+ * @return error log on error
+ */
+ errlHndl_t ipmiSensor(bool i_activate)
+ {
+#if !defined(CONFIG_BMC_IPMI)
+ return NULL;
+#else
+ return SENSOR::OCCActiveSensor(iv_target).setState
+ (i_activate ? SENSOR::OCCActiveSensor::OCC_ACTIVE :
+ SENSOR::OCCActiveSensor::OCC_NOT_ACTIVE);
+#endif
+ }
+
+ /**
+ * @brief Set failed state
+ * @param[in] failed state
+ */
+ void failed(bool i_state) { iv_failed = i_state; }
+
/**
* @brief Return OCCs present bits
@@ -195,6 +237,17 @@ namespace HTMGT
*/
void updateOccPresentBits(uint8_t i_slavePresent);
+ private: // functions
+
+ /**
+ * @brief Process an OCC poll response
+ *
+ * @param[in] i_pollResponse pointer to the response
+ * @param[in] i_pollResponseSize length of the poll response
+ */
+ void pollRspHandler(const uint8_t * i_pollResponse,
+ const uint16_t i_pollResponseSize);
+
protected:
// Instance number of this OCC: 0 = first physical OCC
@@ -226,6 +279,8 @@ namespace HTMGT
private:
+ // Reset count
+ uint8_t iv_resetCount;
// Version of data stored (0 = not written)
uint8_t iv_version;
@@ -298,6 +353,14 @@ namespace HTMGT
*/
static Occ * getMasterOcc();
+ /**
+ * @brief Reset the OCCs
+ *
+ * @param[in] Failing occ target
+ * @return Error Log | NULL
+ */
+ static errlHndl_t resetOccs(TARGETING::Target * i_failedOccTarget);
+
/**
* @brief Set the state of the OCCs. If i_state is
@@ -336,9 +399,29 @@ namespace HTMGT
void waitForOccCheckpoint();
+ /**
+ * @brief Send a poll command to one or all OCCs
+ *
+ * @param[in] i_flushAllErrors:
+ * If set to true, HTMGT will send poll cmds
+ * to each OCC that is selected as long as that OCC
+ * continues to report errors. If false, only one
+ * poll will be send to each OCC.
+ * @param[in] i_occTarget: The Selected OCC or NULL for all OCCs
+ *
+ * @return NULL on success, else error handle
+ */
+ static errlHndl_t
+ sendOccPoll(const bool i_flushAllErrors = false,
+ TARGETING::Target * i_occTarget = NULL);
+
+
private:
+
+ typedef std::vector<Occ*> occList_t;
+
Occ * iv_occMaster;
- std::vector<Occ*> iv_occArray;
+ occList_t iv_occArray;
occStateId iv_state;
occStateId iv_targetState;
@@ -388,6 +471,14 @@ namespace HTMGT
void _waitForOccCheckpoint();
+ /** See resetOccs() above */
+ errlHndl_t _resetOccs(TARGETING::Target * i_failedOccTarget);
+
+ /** See sendOccPoll() above */
+ errlHndl_t
+ _sendOccPoll(const bool i_flushAllErrors,
+ TARGETING::Target * i_occTarget);
+
};
typedef Singleton<OccManager> occMgr;
diff --git a/src/usr/htmgt/htmgt_occcmd.C b/src/usr/htmgt/htmgt_occcmd.C
index 579b6d7d5..3e60c5775 100644
--- a/src/usr/htmgt/htmgt_occcmd.C
+++ b/src/usr/htmgt/htmgt_occcmd.C
@@ -77,7 +77,7 @@ namespace HTMGT
{OCC_CMD_SET_POWER_CAP, 0x80, OCC_CHECK_RSP_LENGTH_NONE,
0x0000, TO_20SEC, 0x0090, OCC_TRACE_EXTENDED},
{OCC_CMD_RESET_PREP, 0x80, OCC_CHECK_RSP_LENGTH_GREATER,
- 0x0006, TO_20SEC, 0x0190, OCC_TRACE_ALWAYS},
+ 0x0000, TO_20SEC, 0x0190, OCC_TRACE_ALWAYS},
{OCC_CMD_GET_FIELD_DEBUG_DATA, 0x80, OCC_CHECK_RSP_LENGTH_GREATER,
0x0001, TO_20SEC, RD_MAX, OCC_TRACE_NEVER},
@@ -814,7 +814,7 @@ namespace HTMGT
bldErrLog(l_excErr, HTMGT_MOD_HANLDE_OCC_EXCEPTION,
(htmgtReasonCode)(OCCC_COMP_ID | iv_OccRsp.returnStatus),
iv_OccRsp.returnStatus, iv_OccRsp.dataLength, 0, 0,
- ERRORLOG::ERRL_SEV_INFORMATIONAL);
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE);
const uint8_t * const exceptionData = iv_Occ->iv_homer + OCC_RSP_ADDR;
l_excErr->addFFDC(OCCC_COMP_ID,
exceptionData,
@@ -861,6 +861,8 @@ namespace HTMGT
{
TMGT_ERR("writeOccCmd: Error writing to OCC Circular Buffer,"
" rc=0x%04X", l_err->reasonCode());
+
+ ERRORLOG::errlCommit(l_err, HTMGT_COMP_ID);
}
#endif
diff --git a/src/usr/htmgt/htmgt_occcmd.H b/src/usr/htmgt/htmgt_occcmd.H
index 252fc3852..a75dd5528 100644
--- a/src/usr/htmgt/htmgt_occcmd.H
+++ b/src/usr/htmgt/htmgt_occcmd.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014 */
+/* Contributors Listed Below - COPYRIGHT 2014,2015 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -80,6 +80,14 @@ namespace HTMGT
OCC_CMD_END_OF_TABLE = 0xFF
};
+ enum occResetReasonType
+ {
+ OCC_RESET_CMD_VERSION = 0x00,
+ OCC_RESET_NON_FAILURE = 0x00,
+ OCC_RESET_FAIL_THIS_OCC = 0x01,
+ OCC_RESET_FAIL_OTHER_OCC = 0x02,
+ };
+
enum occCheckRspLengthType
{
OCC_CHECK_RSP_LENGTH_NONE = 0x00,
diff --git a/src/usr/htmgt/htmgt_poll.C b/src/usr/htmgt/htmgt_poll.C
index 29ca416cc..6729b652c 100644
--- a/src/usr/htmgt/htmgt_poll.C
+++ b/src/usr/htmgt/htmgt_poll.C
@@ -42,100 +42,126 @@
namespace HTMGT
{
- // Send a poll command to all OCCs
- errlHndl_t sendOccPoll(const bool i_flushAllErrors)
+ errlHndl_t OccManager::_sendOccPoll(const bool i_flushAllErrors,
+ TARGETING::Target * i_occTarget)
{
- errlHndl_t l_err = NULL;
- uint8_t * l_poll_rsp = NULL;
+ errlHndl_t err = NULL;
TMGT_INF("sendOccPoll(flush=%c)", i_flushAllErrors?'y':'n');
- // Loop through all functional OCCs
- std::vector<Occ*> occList = occMgr::instance().getOccArray();
- for (std::vector<Occ*>::iterator itr = occList.begin();
- (itr < occList.end()) && (NULL == l_err);
- ++itr)
+ for(occList_t::const_iterator occ_itr = iv_occArray.begin();
+ (occ_itr != iv_occArray.end()) && (NULL == err);
+ ++occ_itr)
{
- Occ * occ = (*itr);
- const uint8_t occInstance = occ->getInstance();
+ Occ * occ = *occ_itr;
+ if(NULL == i_occTarget || occ->iv_target == i_occTarget)
+ {
+ err = occ->pollForErrors(i_flushAllErrors);
+ }
+ }
+
+ return err;
+ }
+
+
+ errlHndl_t OccManager::sendOccPoll(const bool i_flushAllErrors,
+ TARGETING::Target * i_occTarget)
+ {
+ return
+ Singleton<OccManager>::instance()._sendOccPoll(i_flushAllErrors,
+ i_occTarget);
+ }
+
+
+ errlHndl_t Occ::pollForErrors(const bool i_flushAllErrors)
+ {
+ errlHndl_t err = NULL;
+ uint8_t * poll_rsp = NULL;
- TMGT_INF("sendOccPoll: Polling OCC%d", occInstance);
- bool continuePolling = false;
- size_t elogCount = 10;
- do
+ TMGT_INF("sendOccPoll: Polling OCC%d", iv_instance);
+ bool continuePolling = false;
+ size_t elogCount = 10;
+
+ do
+ {
+ // create 1 byte buffer for poll command data
+ const uint8_t l_cmdData[1] = { 0x10 /*version*/ };
+
+ OccCmd cmd(this,
+ OCC_CMD_POLL,
+ sizeof(l_cmdData),
+ l_cmdData);
+
+ err = cmd.sendOccCmd();
+ if (err != NULL)
{
- // create 1 byte buffer for poll command data
- const uint8_t l_cmdData[1] = { 0x10 /*version*/ };
+ // Poll failed
+ TMGT_ERR("sendOccPoll: OCC%d poll failed with rc=0x%04X",
+ iv_instance,
+ err->reasonCode());
- OccCmd cmd(occ, OCC_CMD_POLL, sizeof(l_cmdData), l_cmdData);
- l_err = cmd.sendOccCmd();
- if (l_err != NULL)
- {
- // Poll failed
- TMGT_ERR("sendOccPoll: OCC%d poll failed with rc=0x%04X",
- occInstance, l_err->reasonCode());
- }
- else
+ continuePolling = false;
+ }
+ else
+ {
+ // Poll succeeded, check response
+ uint32_t poll_rsp_size = cmd.getResponseData(poll_rsp);
+ if (poll_rsp_size >= OCC_POLL_DATA_MIN_SIZE)
{
- // Poll succeeded, check response
- uint32_t l_poll_rsp_size = cmd.getResponseData(l_poll_rsp);
- if (l_poll_rsp_size >= OCC_POLL_DATA_MIN_SIZE)
+ if (i_flushAllErrors)
{
- if (i_flushAllErrors)
+ const occPollRspStruct_t *currentPollRsp =
+ (occPollRspStruct_t *) poll_rsp;
+ if (currentPollRsp->errorId != 0)
{
- const occPollRspStruct_t *currentPollRsp =
- (occPollRspStruct_t *) l_poll_rsp;
- if (currentPollRsp->errorId != 0)
+ if (--elogCount > 0)
{
- if (--elogCount > 0)
- {
- // An error was returned, keep polling OCC
- continuePolling = true;
- }
- else
- {
- // Limit number of elogs retrieved so
- // we do not get stuck in loop
- TMGT_INF("sendOccPoll: OCC%d still has"
- "more errors to report.",
- occInstance);
- continuePolling = false;
- }
+ // An error was returned, keep polling OCC
+ continuePolling = true;
}
else
{
+ // Limit number of elogs retrieved so
+ // we do not get stuck in loop
+ TMGT_INF("sendOccPoll: OCC%d still has"
+ "more errors to report.",
+ iv_instance);
continuePolling = false;
}
}
- occ->pollRspHandler(l_poll_rsp, l_poll_rsp_size);
- }
- else
- {
- TMGT_ERR("sendOccPoll: OCC%d poll command response "
- "failed with invalid data length %d",
- occInstance, l_poll_rsp_size);
- /*@
- * @errortype
- * @reasoncode HTMGT_RC_INVALID_LENGTH
- * @moduleid HTMGT_MOD_OCC_POLL
- * @userdata1 OCC instance
- * @devdesc Invalid POLL response length
- */
- bldErrLog(l_err, HTMGT_MOD_OCC_POLL,
- HTMGT_RC_INVALID_LENGTH,
- occInstance, 0, 0, 0,
- ERRORLOG::ERRL_SEV_INFORMATIONAL);
+ else
+ {
+ continuePolling = false;
+ }
}
+ pollRspHandler(poll_rsp, poll_rsp_size);
}
- }
- while (continuePolling);
-
- } // for each OCC
-
- return l_err;
+ else
+ {
+ TMGT_ERR("sendOccPoll: OCC%d poll command response "
+ "failed with invalid data length %d",
+ iv_instance, poll_rsp_size);
+ /*@
+ * @errortype
+ * @reasoncode HTMGT_RC_INVALID_LENGTH
+ * @moduleid HTMGT_MOD_OCC_POLL
+ * @userdata1 OCC instance
+ * @devdesc Invalid POLL response length
+ */
+ bldErrLog(err,
+ HTMGT_MOD_OCC_POLL,
+ HTMGT_RC_INVALID_LENGTH,
+ iv_instance, 0, 0, 0,
+ ERRORLOG::ERRL_SEV_INFORMATIONAL);
- } // end sendOccPoll()
+ continuePolling = false;
+ }
+ }
+ }
+ while (continuePolling);
+ return err;
+ }
// Handle OCC poll response
diff --git a/src/usr/htmgt/htmgt_poll.H b/src/usr/htmgt/htmgt_poll.H
index 631a1d365..faf133028 100644
--- a/src/usr/htmgt/htmgt_poll.H
+++ b/src/usr/htmgt/htmgt_poll.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014 */
+/* Contributors Listed Below - COPYRIGHT 2014,2015 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -69,19 +69,5 @@ namespace HTMGT
const uint32_t HTMGT_OCC_POLL_DATA_SIZE = sizeof(occPollRspStruct_t);
- /**
- * @brief Send a poll command to each OCC
- *
- * @param[in] i_flushAllErrors If set to true, TMGT will send poll cmds
- * to each OCC as long as that OCC continues
- * to report errors. If false, only one
- * poll will be send to each OCC.
- *
- * @return NULL on success, else error handle
- */
- errlHndl_t sendOccPoll(const bool i_flushAllErrors = false);
-
-
-
} // end namespace
#endif
OpenPOWER on IntegriCloud