diff options
Diffstat (limited to 'src/usr/htmgt/htmgt_occ.C')
-rw-r--r-- | src/usr/htmgt/htmgt_occ.C | 254 |
1 files changed, 232 insertions, 22 deletions
diff --git a/src/usr/htmgt/htmgt_occ.C b/src/usr/htmgt/htmgt_occ.C index 7722563ea..61cb04e71 100644 --- a/src/usr/htmgt/htmgt_occ.C +++ b/src/usr/htmgt/htmgt_occ.C @@ -29,6 +29,7 @@ #include "htmgt_occcmd.H" #include "htmgt_cfgdata.H" #include "htmgt_occ.H" +#include "htmgt_poll.H" // Targeting support #include <targeting/common/commontargeting.H> @@ -37,9 +38,6 @@ #include <targeting/common/targetservice.H> -using namespace HTMGT; - - namespace HTMGT { @@ -48,21 +46,19 @@ namespace HTMGT uint8_t * i_homer, TARGETING::TargetHandle_t i_target, const occRole i_role) - :instance(i_instance), - masterCapable(i_masterCapable), - role(i_role), - state(OCC_STATE_UNKNOWN), - commEstablished(false), - needsReset(false), - failed(false), - seqNumber(0), - homer(i_homer), - target(i_target), - lastPollValid(false), - version(0x01) + :iv_instance(i_instance), + iv_masterCapable(i_masterCapable), + iv_role(i_role), + iv_state(OCC_STATE_UNKNOWN), + iv_commEstablished(false), + iv_needsReset(false), + iv_failed(false), + iv_seqNumber(0), + iv_homer(i_homer), + iv_target(i_target), + iv_lastPollValid(false), + iv_version(0x01) { - // Probably not needed... - huid = i_target->getAttr<TARGETING::ATTR_HUID>(); } Occ::~Occ() @@ -70,8 +66,99 @@ namespace HTMGT } + // Return true if specified status bit is set in last poll response + bool Occ::statusBitSet(const uint8_t i_statusBit) + { + bool isSet = false; + + if (iv_lastPollValid) + { + const occPollRspStruct_t *lastPoll = + (occPollRspStruct_t*)iv_lastPollResponse; + isSet = ((lastPoll->status & i_statusBit) == i_statusBit); + } + + return isSet; + } + + + // Set state of the OCC + errlHndl_t Occ::setState(const occStateId i_state) + { + errlHndl_t l_err = NULL; + + if (OCC_ROLE_MASTER == iv_role) + { + const uint8_t l_cmdData[3] = + { + 0x00, // version + i_state, + 0x00 // reserved + }; + + OccCmd cmd(this, OCC_CMD_SET_STATE, + sizeof(l_cmdData), l_cmdData); + l_err = cmd.sendOccCmd(); + if (l_err != NULL) + { + TMGT_ERR("setState: Failed to set OCC%d state, rc=0x%04X", + iv_instance, l_err->reasonCode()); + } + else + { + if (OCC_RC_SUCCESS != cmd.getRspStatus()) + { + TMGT_ERR("setState: Set OCC%d state failed" + " with OCC status 0x%02X", + iv_instance, cmd.getRspStatus()); + /*@ + * @errortype + * @moduleid HTMGT_MOD_OCC_SET_STATE + * @reasoncode HTMGT_RC_OCC_CMD_FAIL + * @userdata1[0-15] OCC instance + * @userdata1[16-31] Requested state + * @userdata2[0-15] OCC response status + * @userdata2[16-31] current OCC state + * @devdesc Set of OCC state failed + */ + bldErrLog(l_err, HTMGT_MOD_OCC_SET_STATE, + HTMGT_RC_OCC_CMD_FAIL, + iv_instance, i_state, + cmd.getRspStatus(), iv_state, + ERRORLOG::ERRL_SEV_INFORMATIONAL); + } + } + } + else + { + TMGT_ERR("setState: State only allowed to be set on master OCC"); + /*@ + * @errortype + * @moduleid HTMGT_MOD_OCC_SET_STATE + * @reasoncode HTMGT_RC_INTERNAL_ERROR + * @userdata1[0-15] OCC instance + * @userdata1[16-31] Requested state + * @devdesc Set state only allowed on master OCC + */ + bldErrLog(l_err, HTMGT_MOD_OCC_SET_STATE, + HTMGT_RC_INTERNAL_ERROR, + iv_instance, i_state, 0, 0, + ERRORLOG::ERRL_SEV_INFORMATIONAL); + } + + return l_err; + + } // end Occ::setState() + + + + ///////////////////////////////////////////////////////////////// + + + OccManager::OccManager() - :iv_occMaster(NULL), + :iv_configDataBuilt(false), + iv_occMaster(NULL), iv_state(OCC_STATE_UNKNOWN) { } @@ -128,7 +215,10 @@ namespace HTMGT // Get HOMER virtual address uint8_t * homer = (uint8_t*) ((*proc)->getAttr<TARGETING::ATTR_HOMER_VIRT_ADDR>()); - TMGT_INF("buildOccs: homer = 0x%08X (from proc 0)", homer); + const uint8_t * homerPhys = (uint8_t*) + ((*proc)->getAttr<TARGETING::ATTR_HOMER_PHYS_ADDR>()); + TMGT_INF("buildOccs: homer = 0x%08X (virt) / 0x%08X (phys)" + " for Proc%d", homer, homerPhys, instance); #ifdef SIMICS_TESTING // Starting of OCCs is not supported in SIMICS, so fake out // HOMER memory area for testing @@ -140,7 +230,7 @@ namespace HTMGT { // Allocate a fake HOMER area G_simicsHomerBuffer = - new uint8_t [HTMGT_OCC_CMD_ADDR+0x2000]; + new uint8_t [OCC_CMD_ADDR+0x2000]; } homer = G_simicsHomerBuffer; TMGT_ERR("buildOccs: Using hardcoded HOMER of 0x%08lX", @@ -183,7 +273,7 @@ namespace HTMGT - /* Add a functional OCC to be monitored */ + // Add a functional OCC to be monitored void OccManager::_addOcc(const uint8_t i_instance, const bool i_masterCapable, uint8_t * i_homer, @@ -224,6 +314,121 @@ namespace HTMGT } // end OccManager::_addOcc() + // Set the OCC state + errlHndl_t OccManager::_setOccState(const occStateId i_state) + { + errlHndl_t l_err = NULL; + + + if ((i_state == OCC_STATE_ACTIVE) || + (i_state == OCC_STATE_OBSERVATION)) + { + if (NULL != iv_occMaster) + { + TMGT_INF("_setOccState(state=0x%02X)", i_state); + + const uint8_t occInstance = iv_occMaster->getInstance(); + bool needsRetry = false; + do + { + l_err = iv_occMaster->setState(i_state); + if (NULL == l_err) + { + needsRetry = false; + } + else + { + TMGT_ERR("_setOccState: Failed to set OCC%d state," + " rc=0x%04X", + occInstance, l_err->reasonCode()); + if (false == needsRetry) + { + ERRORLOG::errlCommit(l_err, HTMGT_COMP_ID); + l_err = NULL; + needsRetry = true; + } + else + { + // Only one retry, return error handle + needsRetry = false; + } + } + } + while (needsRetry); + } + else + { + /*@ + * @errortype + * @moduleid HTMGT_MOD_OCCMGR_SET_STATE + * @reasoncode HTMGT_RC_INTERNAL_ERROR + * @devdesc Unable to set state of master OCC + */ + bldErrLog(l_err, HTMGT_MOD_OCCMGR_SET_STATE, + HTMGT_RC_INTERNAL_ERROR, + 0, 0, 0, 0, + ERRORLOG::ERRL_SEV_INFORMATIONAL); + } + + if (NULL == l_err) + { + // Send poll to query state of all OCCs + // and flush any errors reported by the OCCs + errlHndl_t l_err = sendOccPoll(true); + if (l_err) + { + TMGT_ERR("_setOccState: Poll all OCCs failed"); + ERRORLOG::errlCommit(l_err, HTMGT_COMP_ID); + } + + // Make sure all OCCs went to active state + for (std::vector<Occ*>::iterator pOcc = iv_occArray.begin(); + pOcc < iv_occArray.end(); + pOcc++) + { + if (i_state != (*pOcc)->getState()) + { + TMGT_ERR("_setOccState: OCC%d is not in 0x%02X state", + (*pOcc)->getInstance(), i_state); + /*@ + * @errortype + * @moduleid HTMGT_MOD_OCCMGR_SET_STATE + * @reasoncode HTMGT_RC_OCC_UNEXPECTED_STATE + * @userdata1[0-15] requested state + * @userdata1[16-31] OCC state + * @userdata2[0-15] OCC instance + * @devdesc OCC did not change to requested state + */ + bldErrLog(l_err, HTMGT_MOD_OCCMGR_SET_STATE, + HTMGT_RC_OCC_UNEXPECTED_STATE, + i_state, (*pOcc)->getState(), + (*pOcc)->getInstance(), 0, + ERRORLOG::ERRL_SEV_INFORMATIONAL); + break; + } + } + } + } + else + { + TMGT_ERR("_setOccState: Invalid state 0x%02X requested", i_state); + /*@ + * @errortype + * @moduleid HTMGT_MOD_OCCMGR_SET_STATE + * @reasoncode HTMGT_RC_INVALID_DATA + * @userdata1[0-15] requested state + * @devdesc Invalid OCC state requested + */ + bldErrLog(l_err, HTMGT_MOD_OCCMGR_SET_STATE, + HTMGT_RC_INVALID_DATA, + i_state, 0, 0, 0, + ERRORLOG::ERRL_SEV_INFORMATIONAL); + } + + return l_err; + + } // end OccManager::_setOccState() + uint8_t OccManager::getNumOccs() { @@ -249,9 +454,14 @@ namespace HTMGT } + errlHndl_t OccManager::setOccState(const occStateId i_state) + { + return Singleton<OccManager>::instance()._setOccState(i_state); + } + #if 0 - // TODO: RTC 109066 + // TODO: RTC 115296 void update_occ_data() { if (occMgr::instance().getNumOccs() > 0) |