summaryrefslogtreecommitdiffstats
path: root/src/usr/htmgt
diff options
context:
space:
mode:
authorChris Cain <cjcain@us.ibm.com>2016-04-29 07:59:12 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2016-05-05 00:50:03 -0400
commit05c9e64889edbedd858b5db4af45d67cafd60e44 (patch)
treeba260c9b618ce5097b1670fb74d1ecc00e689e02 /src/usr/htmgt
parent92dd480074616a2d32927084405113e72950be16 (diff)
downloadtalos-hostboot-05c9e64889edbedd858b5db4af45d67cafd60e44.tar.gz
talos-hostboot-05c9e64889edbedd858b5db4af45d67cafd60e44.zip
Add way to clear reset count and exit safe mode
Change-Id: I88de38fe700770abadb90b442f47198eb3532c87 Original-Change-Id: I82c56f8684f5ca3cee14a3e7bcdee968b65513fb RTC: 149231 ForwardPort: yes Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/23998 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/24108 Tested-by: Jenkins Server Tested-by: FSP CI Jenkins Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/htmgt')
-rw-r--r--src/usr/htmgt/htmgt.C99
-rw-r--r--src/usr/htmgt/htmgt_occ.C124
-rw-r--r--src/usr/htmgt/htmgt_occ.H41
-rw-r--r--src/usr/htmgt/htmgt_utility.H3
4 files changed, 239 insertions, 28 deletions
diff --git a/src/usr/htmgt/htmgt.C b/src/usr/htmgt/htmgt.C
index 304fd9a37..e2e508025 100644
--- a/src/usr/htmgt/htmgt.C
+++ b/src/usr/htmgt/htmgt.C
@@ -104,9 +104,9 @@ namespace HTMGT
{
if (OccManager::occNeedsReset())
{
- // No need to continue if a reset is required
- TMGT_ERR("sendOccConfigData(): OCCs need to "
- "be reset");
+ // No need to continue if reset is required
+ TMGT_ERR("sendOccConfigData(): OCCs need "
+ "to be reset");
break;
}
else
@@ -186,8 +186,8 @@ namespace HTMGT
if (NULL != l_err)
{
- TMGT_ERR("OCCs not all active (rc=0x%04X). Attempting OCC Reset",
- l_err->reasonCode());
+ TMGT_ERR("OCCs not all active (rc=0x%04X). Attempting OCC "
+ "Reset", l_err->reasonCode());
TMGT_CONSOLE("OCCs are not active (rc=0x%04X). "
"Attempting OCC Reset",
l_err->reasonCode());
@@ -212,6 +212,7 @@ namespace HTMGT
ERRORLOG::errlCommit(l_err, HTMGT_COMP_ID);
}
}
+
TMGT_INF("<<processOccStartStatus()");
} // end processOccStartStatus()
@@ -529,6 +530,94 @@ namespace HTMGT
}
break;
+ case PASSTHRU_SEND_OCC_COMMAND:
+ if (i_cmdLength >= 3)
+ {
+ const uint8_t occInstance = i_cmdData[1];
+ const occCommandType occCmd =
+ (occCommandType)i_cmdData[2];
+ const uint16_t dataLen = i_cmdLength-3;
+ Occ *occPtr = OccManager::getOcc(occInstance);
+ if (occPtr)
+ {
+ TMGT_INF("passThruCommand: Send OCC%d command "
+ "0x%02X (%d bytes)",
+ occInstance, occCmd, dataLen);
+ OccCmd cmd(occPtr, occCmd, dataLen, &i_cmdData[3]);
+ err = cmd.sendOccCmd();
+ if (err != NULL)
+ {
+ TMGT_ERR("passThruCommand: OCC%d cmd 0x%02X "
+ "failed with rc 0x%04X",
+ occInstance, occCmd,
+ err->reasonCode());
+ }
+ else
+ {
+ uint8_t *rspPtr = NULL;
+ o_rspLength = cmd.getResponseData(rspPtr);
+ memcpy(o_rspData, rspPtr, o_rspLength);
+ TMGT_INF("passThruCommand: OCC%d rsp status "
+ "0x%02X (%d bytes)", occInstance,
+ o_rspData[2], o_rspLength);
+ }
+ }
+ else
+ {
+ TMGT_ERR("passThruCommand: Unable to find OCC%d",
+ occInstance);
+ /*@
+ * @errortype
+ * @reasoncode HTMGT_RC_OCC_UNAVAILABLE
+ * @moduleid HTMGT_MOD_PASS_THRU
+ * @userdata1 command data[0-7]
+ * @userdata2 command data length
+ * @devdesc Specified OCC not available
+ */
+ failingSrc = HTMGT_RC_OCC_UNAVAILABLE;
+ }
+ }
+ else
+ {
+ TMGT_ERR("passThruCommand: invalid OCC command "
+ "length %d", i_cmdLength);
+ failingSrc = HTMGT_RC_INVALID_LENGTH;
+ }
+ break;
+
+ case PASSTHRU_CLEAR_RESET_COUNTS:
+ TMGT_INF("passThruCommand: Clear all OCC reset counts");
+ OccManager::clearResetCounts();
+ break;
+
+ case PASSTHRU_EXIT_SAFE_MODE:
+ {
+ TMGT_INF("passThruCommand: Clear Safe Mode");
+ // Clear OCC reset counts and failed flags
+ OccManager::clearResetCounts();
+ // Clear safe mode reason
+ OccManager::updateSafeModeReason(0, 0);
+ // Clear system safe mode flag/attribute
+ TARGETING::Target* sys = NULL;
+ TARGETING::targetService().getTopLevelTarget(sys);
+ const uint8_t safeMode = 0;
+ if(sys)
+ {
+ sys->setAttr<TARGETING::ATTR_HTMGT_SAFEMODE>
+ (safeMode);
+ }
+ // Reset the OCCs (do not increment reset count
+ // or attempt comm with OCC since they are in reset)
+ TMGT_INF("passThruCommand: Calling resetOccs");
+ err = OccManager::resetOccs(NULL, true, true);
+ if (err != NULL)
+ {
+ TMGT_ERR("passThruCommand: resetOccs failed "
+ "with rc 0x%04X", err->reasonCode());
+ }
+ }
+ break;
+
default:
TMGT_ERR("passThruCommand: Invalid command 0x%08X "
"(%d bytes)", UINT32_GET(i_cmdData), i_cmdLength);
diff --git a/src/usr/htmgt/htmgt_occ.C b/src/usr/htmgt/htmgt_occ.C
index d76b9e800..e0aa26c55 100644
--- a/src/usr/htmgt/htmgt_occ.C
+++ b/src/usr/htmgt/htmgt_occ.C
@@ -505,6 +505,26 @@ namespace HTMGT
} // end OccManager::_addOcc()
+ // Get pointer to specified OCC
+ Occ * OccManager::_getOcc(const uint8_t i_instance)
+ {
+ Occ *targetOcc = NULL;
+ for (std::vector<Occ*>::iterator pOcc = iv_occArray.begin();
+ pOcc < iv_occArray.end();
+ pOcc++)
+ {
+ if ((*pOcc)->getInstance() == i_instance)
+ {
+ targetOcc = (*pOcc);
+ break;
+ }
+ }
+
+ return targetOcc;
+
+ } // eng OccManager::_getOcc()
+
+
// Set the OCC state
errlHndl_t OccManager::_setOccState(const occStateId i_state)
{
@@ -666,7 +686,8 @@ namespace HTMGT
errlHndl_t OccManager::_resetOccs(TARGETING::Target * i_failedOccTarget,
- bool i_skipCountIncrement)
+ bool i_skipCountIncrement,
+ bool i_skipComm)
{
errlHndl_t err = NULL;
bool atThreshold = false;
@@ -682,13 +703,16 @@ namespace HTMGT
ERRORLOG::errlCommit(err, HTMGT_COMP_ID);
}
- // Send poll cmd to all OCCs to establish comm
- err = _sendOccPoll(false,NULL);
- if (err)
+ if (false == i_skipComm)
{
- TMGT_ERR("_resetOccs: Poll OCCs failed.");
- // Proceed with reset even if failed
- 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();
@@ -700,15 +724,20 @@ namespace HTMGT
(*occ)->failed(true);
}
- if((*occ)->resetPrep())
+
+ if (false == i_skipComm)
{
- atThreshold = true;
+ // Send reset prep cmd to all OCCs
+ if((*occ)->resetPrep())
+ {
+ atThreshold = true;
+ }
}
}
if ((false == i_skipCountIncrement) && (false == _occFailed()))
{
- // No OCC has been marked failed, increment system reset count
+ // No OCC has been marked failed, increment sys reset count
++iv_resetCount;
TMGT_INF("_resetOCCs: Incrementing system OCC reset count"
@@ -719,7 +748,15 @@ namespace HTMGT
atThreshold = true;
}
}
- // else the failed OCC reset count will be incremented automatically
+ // else failed OCC reset count will be incremented automatically
+
+ // Update OCC states to RESET
+ for(occList_t::const_iterator occ = iv_occArray.begin();
+ occ != iv_occArray.end();
+ ++occ)
+ {
+ (*occ)->iv_state = OCC_STATE_RESET;
+ }
uint64_t retryCount = OCC_RESET_COUNT_THRESHOLD;
while(retryCount)
@@ -813,11 +850,12 @@ namespace HTMGT
TARGETING::targetService().getTopLevelTarget(sys);
const uint8_t safeMode = 1;
- // Put into safemode
+ // Mark system as being in safe mode
if(sys)
{
sys->setAttr<TARGETING::ATTR_HTMGT_SAFEMODE>(safeMode);
}
+ iv_state = OCC_STATE_SAFE;
_updateSafeModeReason(io_err->reasonCode(), 0);
@@ -908,9 +946,11 @@ namespace HTMGT
void OccManager::_updateSafeModeReason(uint32_t i_src,
uint32_t i_instance)
{
- if (cv_safeReturnCode == 0)
+ if ((cv_safeReturnCode == 0) ||
+ ((i_src == 0) && (i_instance == 0)))
{
- // Only update safe mode reason for the first failure
+ // Only update safe mode reason for the first failure,
+ // or if trying to clear safe mode
cv_safeReturnCode = i_src;
cv_safeOccInstance = i_instance;
}
@@ -1088,6 +1128,42 @@ namespace HTMGT
}
+ // Clear all OCC reset counts
+ void OccManager::_clearResetCounts()
+ {
+ TARGETING::Target* sys = NULL;
+ TARGETING::targetService().getTopLevelTarget(sys);
+ uint8_t safeMode = 0;
+ if (sys)
+ {
+ sys->tryGetAttr<TARGETING::ATTR_HTMGT_SAFEMODE>(safeMode);
+ }
+ for (std::vector<Occ*>::iterator pOcc = iv_occArray.begin();
+ pOcc < iv_occArray.end();
+ pOcc++)
+ {
+ if ((*pOcc)->iv_resetCount != 0)
+ {
+ TMGT_INF("_clearResetCounts: Clearing OCC%d reset count "
+ "(was %d)",
+ (*pOcc)->getInstance(), (*pOcc)->iv_resetCount);
+ (*pOcc)->iv_resetCount = 0;
+ if (safeMode)
+ {
+ // Clear OCC flags (failed, commEstablished, etc)
+ (*pOcc)->postResetClear();
+ }
+ }
+ }
+ if (iv_resetCount != 0)
+ {
+ TMGT_INF("_clearResetCounts: Clearing system reset count "
+ "(was %d)", iv_resetCount);
+ iv_resetCount = 0;
+ }
+ }
+
+
uint8_t OccManager::getNumOccs()
{
return Singleton<OccManager>::instance()._getNumOccs();
@@ -1112,15 +1188,26 @@ namespace HTMGT
}
+ Occ * OccManager::getOcc(const uint8_t i_instance)
+ {
+ return Singleton<OccManager>::instance()._getOcc(i_instance);
+ }
+
+
errlHndl_t OccManager::setOccState(const occStateId i_state)
{
return Singleton<OccManager>::instance()._setOccState(i_state);
}
- errlHndl_t OccManager::resetOccs(TARGETING::Target * i_failedOccTarget)
+
+ errlHndl_t OccManager::resetOccs(TARGETING::Target * i_failedOccTarget,
+ bool i_skipCountIncrement,
+ bool i_skipComm)
{
return
- Singleton<OccManager>::instance()._resetOccs(i_failedOccTarget);
+ Singleton<OccManager>::instance()._resetOccs(i_failedOccTarget,
+ i_skipCountIncrement,
+ i_skipComm);
}
@@ -1178,6 +1265,11 @@ namespace HTMGT
Singleton<OccManager>::instance()._setPstateTable(i_useNormal);
}
+ void OccManager::clearResetCounts()
+ {
+ Singleton<OccManager>::instance()._clearResetCounts();
+ }
+
void OccManager::syncOccStates()
{
Singleton<OccManager>::instance()._syncOccStates();
diff --git a/src/usr/htmgt/htmgt_occ.H b/src/usr/htmgt/htmgt_occ.H
index 3e9e87b3f..e29565fe6 100644
--- a/src/usr/htmgt/htmgt_occ.H
+++ b/src/usr/htmgt/htmgt_occ.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2015 */
+/* Contributors Listed Below - COPYRIGHT 2014,2016 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -419,13 +419,29 @@ namespace HTMGT
*/
static Occ * getMasterOcc();
+
+ /**
+ * @brief Return pointer to specified OCC
+ *
+ * @return pointer to specified OCC or NULL if not found
+ */
+ static Occ * getOcc(const uint8_t i_instance);
+
+
/**
* @brief Reset the OCCs
*
* @param[in] Failing occ target
+ * @param[in] i_skipCountIncrement true will prevent incrementing
+ * the system reset count
+ * @param[in] i_skipComm true will prevent attempts to
+ * communicate with OCC before reset (poll/resetPrep)
+ * Used when exiting safe mode.
* @return Error Log | NULL
*/
- static errlHndl_t resetOccs(TARGETING::Target * i_failedOccTarget);
+ static errlHndl_t resetOccs(TARGETING::Target * i_failedOccTarget,
+ bool i_skipCountIncrement = false,
+ bool i_skipComm = false);
/**
@@ -574,6 +590,13 @@ namespace HTMGT
static void syncOccStates();
+ /**
+ * @brief Clear all OCC reset counts
+ *
+ */
+ static void clearResetCounts();
+
+
private:
typedef std::vector<Occ*> occList_t;
@@ -638,18 +661,19 @@ namespace HTMGT
Occ * _getMasterOcc() { return iv_occMaster; };
+ /* See getOcc() above */
+ Occ * _getOcc(const uint8_t i_instance);
+
+
/* See setOccState() above */
errlHndl_t _setOccState(const occStateId i_state);
void _waitForOccCheckpoint();
/* See resetOccs() above */
- /* @param[in] i_skipCountIncrement true will prevent incrementing
- * the system reset count (used in loadPstate)
- * false (default) will increment counts as normal
- */
errlHndl_t _resetOccs(TARGETING::Target * i_failedOccTarget,
- bool i_skipCountIncrement = false);
+ bool i_skipCountIncrement = false,
+ bool i_skipComm = false);
/** See sendOccPoll() above */
errlHndl_t
@@ -689,6 +713,9 @@ namespace HTMGT
/** See syncOccStates() above */
void _syncOccStates();
+
+ /** See clearResetCounts() above */
+ void _clearResetCounts();
};
typedef Singleton<OccManager> occMgr;
diff --git a/src/usr/htmgt/htmgt_utility.H b/src/usr/htmgt/htmgt_utility.H
index 19becae35..ad93a0575 100644
--- a/src/usr/htmgt/htmgt_utility.H
+++ b/src/usr/htmgt/htmgt_utility.H
@@ -123,6 +123,9 @@ namespace HTMGT
enum htmgtPassThruCmds
{
PASSTHRU_OCC_STATUS = 0x01,
+ PASSTHRU_SEND_OCC_COMMAND = 0x03, // send raw OCC command
+ PASSTHRU_CLEAR_RESET_COUNTS = 0x04,
+ PASSTHRU_EXIT_SAFE_MODE = 0x05,
PASSTHRU_GENERATE_MFG_PSTATE = 0x81,
PASSTHRU_LOAD_PSTATE = 0x82
};
OpenPOWER on IntegriCloud