diff options
author | Chris Cain <cjcain@us.ibm.com> | 2016-04-29 07:59:12 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2016-05-05 00:50:03 -0400 |
commit | 05c9e64889edbedd858b5db4af45d67cafd60e44 (patch) | |
tree | ba260c9b618ce5097b1670fb74d1ecc00e689e02 /src/usr/htmgt | |
parent | 92dd480074616a2d32927084405113e72950be16 (diff) | |
download | talos-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.C | 99 | ||||
-rw-r--r-- | src/usr/htmgt/htmgt_occ.C | 124 | ||||
-rw-r--r-- | src/usr/htmgt/htmgt_occ.H | 41 | ||||
-rw-r--r-- | src/usr/htmgt/htmgt_utility.H | 3 |
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 }; |