summaryrefslogtreecommitdiffstats
path: root/src/usr/htmgt/htmgt_occ.C
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/htmgt/htmgt_occ.C')
-rw-r--r--src/usr/htmgt/htmgt_occ.C184
1 files changed, 184 insertions, 0 deletions
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()
{
OpenPOWER on IntegriCloud