summaryrefslogtreecommitdiffstats
path: root/src/usr/htmgt/htmgt_occcmd.C
diff options
context:
space:
mode:
authorChris Cain <cjcain@us.ibm.com>2014-09-29 11:18:13 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2014-11-18 09:59:50 -0600
commit58fb1308bfdf6cd8546cf3187a8d9f7831ade552 (patch)
tree1e4d86a8d82a093c7fe431858e6fa483e5c229dc /src/usr/htmgt/htmgt_occcmd.C
parent36282dfad11d98c0d71ff8c0714b4fdf975c1163 (diff)
downloadtalos-hostboot-58fb1308bfdf6cd8546cf3187a8d9f7831ade552.tar.gz
talos-hostboot-58fb1308bfdf6cd8546cf3187a8d9f7831ade552.zip
HTMGT Base Communication
Change-Id: Ie1d9401128d6cfe21a6be1be1760c3ddb0059148 RTC: 115442 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/13863 Tested-by: Jenkins Server 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/htmgt_occcmd.C')
-rw-r--r--src/usr/htmgt/htmgt_occcmd.C1210
1 files changed, 1210 insertions, 0 deletions
diff --git a/src/usr/htmgt/htmgt_occcmd.C b/src/usr/htmgt/htmgt_occcmd.C
new file mode 100644
index 000000000..7a238b5d5
--- /dev/null
+++ b/src/usr/htmgt/htmgt_occcmd.C
@@ -0,0 +1,1210 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/htmgt/htmgt_occcmd.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2014 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#include <htmgt/htmgt.H>
+#include <htmgt/htmgt_reasoncodes.H>
+#include "htmgt_occcmd.H"
+#include "htmgt_config.H"
+#include "htmgt_poll.H"
+
+// Targeting support
+#include <targeting/common/commontargeting.H>
+#include <targeting/common/utilFilter.H>
+#include <targeting/common/attributes.H>
+#include <targeting/common/targetservice.H>
+
+#include <ecmdDataBufferBase.H>
+
+#include <sys/time.h>
+#include <trace/interface.H>
+#include <errl/errlmanager.H>
+#include <stdio.h>
+
+// TODO RTC 115922
+#ifdef __HOSTBOOT_RUNTIME
+#include <runtime/interface.h>
+#endif
+
+
+
+// TODO: RTC 115922
+#if 0
+#include <hwpf/hwp/occ/occAccess.H>
+#else
+namespace HBOCC
+{
+
+ /**
+ * @brief Write OCC Circular Buffer
+ *
+ * @param[in] i_pTarget PROC or OCC target pointer
+ * @param[in] i_dataBuf Reference to data buffer
+ * @return errlHndl_t Error log if operation failed
+ */
+ errlHndl_t writeCircularBuffer(const TARGETING::Target*i_pTarget,
+ ecmdDataBufferBase & i_dataBuf)
+ {
+ errlHndl_t l_err = NULL;
+ TRACFCOMP( HTMGT::g_trac_htmgt, "writeCircularBuffer(STUB): "
+ "setting status to 0xFF");
+ return l_err;
+ } // end writeCircularBuffer()
+
+} //end OCC namespace
+#endif
+
+
+
+namespace HTMGT
+{
+ uint8_t g_cmd = 0;
+ uint8_t g_seq = 0;
+
+ struct occCircBufferCmd_t
+ {
+ uint8_t senderId;
+ uint8_t commandType;
+ uint8_t reserved[6];
+ }__attribute__((packed));
+
+
+ // Note: Read length must be 8 byte aligned (for SRAM reads)
+ const uint16_t RD_MAX = (OCC_MAX_DATA_LENGTH - 8);
+ const uint16_t TO_20SEC = 20 * 1000;
+ const occCommandTable_t OccCmd::cv_occCommandTable[] =
+ {
+ // Command Support RspCheck
+ // RspLen Timeout ReadMax Tracing
+ {OCC_CMD_POLL, 0xE0, OCC_CHECK_RSP_LENGTH_GREATER,
+ 0x0028, TO_20SEC, 0x0017, OCC_TRACE_EXTENDED},
+ {OCC_CMD_CLEAR_ERROR_LOG, 0xC0, OCC_CHECK_RSP_LENGTH_EQUALS,
+ 0x0000, TO_20SEC, 0x0008, OCC_TRACE_EXTENDED},
+ {OCC_CMD_SET_STATE, 0xE0, OCC_CHECK_RSP_LENGTH_EQUALS,
+ 0x0000, TO_20SEC, 0x0008, OCC_TRACE_ALWAYS},
+ {OCC_CMD_SETUP_CFG_DATA, 0x80, OCC_CHECK_RSP_LENGTH_EQUALS,
+ 0x0000, TO_20SEC, 0x0008, OCC_TRACE_CONDITIONAL},
+ {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},
+ {OCC_CMD_GET_FIELD_DEBUG_DATA, 0x80, OCC_CHECK_RSP_LENGTH_GREATER,
+ 0x0001, TO_20SEC, RD_MAX, OCC_TRACE_NEVER},
+
+ {OCC_CMD_END_OF_TABLE, 0x00, OCC_CHECK_RSP_LENGTH_EQUALS,
+ 0x0000, 0x0000, 0x0000, OCC_TRACE_NEVER}
+ };
+
+
+ /**
+ * @brief Get the index of the specified command in the command table
+ *
+ * @param[in] i_cmd OCC command type
+ *
+ * @note If command not found/invalid, index to END_OF_TABLE will
+ * be returned and checked by caller
+ *
+ * @return index into command table
+ */
+ uint8_t OccCmd::getCmdIndex(const occCommandType i_cmd)
+ {
+ uint8_t l_index = 0;
+
+ // TODO RTC 109066 - convert to use lower_bound
+ //= find(&cv_occCommandTable[0],
+ // &cv_occCommandTable[OCC_CMDTABLE_SIZE-1],
+ // i_cmd);
+
+ while ((cv_occCommandTable[l_index].cmdType != OCC_CMD_END_OF_TABLE) &&
+ (cv_occCommandTable[l_index].cmdType != i_cmd))
+ {
+ l_index++;
+ }
+
+ if (cv_occCommandTable[l_index].cmdType == OCC_CMD_END_OF_TABLE)
+ {
+ TMGT_ERR("getCmdIndex: Invalid cmd (0x%02X) specified", i_cmd);
+ }
+
+ return l_index;
+ }
+
+
+
+ /**
+ * @brief Convert OCC response status to a string
+ *
+ * @param[in] i_status OCC response status
+ *
+ * @return text string describing status
+ */
+ const char *rsp_status_string(const occReturnCodes i_status)
+ {
+ const uint8_t STATUS_STRING_COUNT = 11;
+ struct string_data_t
+ {
+ uint8_t str_num;
+ const char *str_data;
+ };
+ const static struct string_data_t L_status_string[STATUS_STRING_COUNT]=
+ {
+ {OCC_RC_SUCCESS, "SUCCESS"},
+ {OCC_RC_INVALID_COMMAND, "INVALID_COMMAND"},
+ {OCC_RC_INVALID_COMMAND_LENGTH, "INVALID_COMMAND_LENGTH"},
+ {OCC_RC_INVALID_DATA_FIELD, "INVALID_DATA_FIELD"},
+ {OCC_RC_CHECKSUM_FAILURE, "CHECKSUM_FAILURE"},
+ {OCC_RC_INTERNAL_ERROR, "INTERNAL_ERROR"},
+ {OCC_RC_PRESENT_STATE_PROHIBITS, "PRESENT_STATE_PROHIBITS"},
+ {OCC_RC_OCC_EXCEPTION, "OCC_EXCEPTION"},
+ {OCC_RC_OCC_INIT_CHECKPOINT, "OCC_INIT_FAILURE"},
+ {OCC_COMMAND_IN_PROGRESS, "IN_PROGRESS"},
+ {OCC_COMMAND_IN_PROGRESS, "UNKNOWN"}
+ };
+
+ uint8_t l_idx = 0;
+ // TODO RTC 109066
+ for (l_idx=0; l_idx < STATUS_STRING_COUNT; l_idx++)
+ {
+ if (i_status == L_status_string[l_idx].str_num)
+ {
+ // Return Code found
+ break;
+ }
+ }
+
+ if (STATUS_STRING_COUNT == l_idx)
+ {
+ // Set index to last entry record
+ l_idx = STATUS_STRING_COUNT - 1;
+ }
+
+ return L_status_string[l_idx].str_data;
+ }
+
+
+
+ // Constructor for OccCmd
+ OccCmd::OccCmd(Occ * i_occ,
+ const occCommandType i_cmd,
+ const uint16_t i_cmdDataLength,
+ const uint8_t *i_data)
+ :iv_RetryCmd(false),
+ iv_OccCmd(),
+ iv_OccRsp(),
+ iv_Occ(i_occ)
+ {
+ iv_OccCmd.cmdType = i_cmd;
+ iv_OccCmd.dataLength = i_cmdDataLength;
+ if (0 != i_cmdDataLength)
+ {
+ if (i_cmdDataLength > OCC_MAX_DATA_LENGTH)
+ {
+ TMGT_ERR("OccCmd: truncating data length (0x%04X)",
+ i_cmdDataLength);
+ iv_OccCmd.dataLength = OCC_MAX_DATA_LENGTH;
+ }
+ memcpy(iv_OccCmd.cmdData, i_data, iv_OccCmd.dataLength);
+ }
+
+ } // end OccCmd()
+
+
+
+ // Destructor for OccCmd
+ OccCmd::~OccCmd()
+ {
+ }
+
+
+ // Determine if command needs to be traced and if so, trace it.
+ bool OccCmd::traceCommand()
+ {
+ bool o_cmdWasTraced = true;
+ const uint8_t l_instance = iv_Occ->instance;
+
+ const uint8_t l_cmd_index = getCmdIndex(iv_OccCmd.cmdType);
+ if (OCC_CMD_END_OF_TABLE != cv_occCommandTable[l_cmd_index].cmdType)
+ {
+ switch(cv_occCommandTable[l_cmd_index].traceCmd)
+ {
+ case OCC_TRACE_ALWAYS:
+ // Always trace command
+ break;
+
+ case OCC_TRACE_EXTENDED:
+ // Trace command when tracing enabled
+ o_cmdWasTraced = (G_debug_trace & DEBUG_TRACE_OCCCMD);
+ break;
+
+ case OCC_TRACE_NEVER:
+ // Never trace these cmds (unless full tracing enabled)
+ o_cmdWasTraced = (G_debug_trace&DEBUG_TRACE_OCCCMD_FULL);
+ break;
+
+ default:
+ if ((OCC_CMD_SETUP_CFG_DATA==iv_OccCmd.cmdType) &&
+ (iv_OccCmd.dataLength > 0) &&
+ ((iv_OccCmd.cmdData[0] ==
+ OCC_CFGDATA_PSTATE_SSTRUCT)))
+ {
+ // Dont trace Pstate data (unless full tracing)
+ o_cmdWasTraced = (G_debug_trace &
+ DEBUG_TRACE_OCCCMD_FULL);
+ }
+ break;
+ }
+ }
+
+ if (o_cmdWasTraced)
+ {
+ // Trace command (and up to 16 bytes of data)
+ if ((OCC_CMD_SETUP_CFG_DATA == iv_OccCmd.cmdType) &&
+ (iv_OccCmd.dataLength > 0))
+ {
+ // Trace config format and first parms since TRACFBIN does
+ // not always work
+ TMGT_INF("Send OCC%d cmd=0x%02X (%s), length=0x%04X,"
+ " data=0x%08X...",
+ l_instance, iv_OccCmd.cmdType,
+ command_string(iv_OccCmd.cmdType),
+ iv_OccCmd.dataLength,
+ UINT32_GET(iv_OccCmd.cmdData));
+ }
+ else
+ {
+ TMGT_INF("Send OCC%d cmd=0x%02X (%s), length=0x%04X",
+ l_instance, iv_OccCmd.cmdType,
+ command_string(iv_OccCmd.cmdType),
+ iv_OccCmd.dataLength);
+ }
+ if (iv_OccCmd.dataLength > 0)
+ {
+ TMGT_BIN("cmd data", iv_OccCmd.cmdData,
+ std::min(iv_OccCmd.dataLength,(uint16_t)16));
+ }
+ }
+
+ return o_cmdWasTraced;
+
+ } // end OccCmd::traceCommand()
+
+
+ void OccCmd::traceResponse()
+ {
+ char l_rsp_status_string[64] = "";
+ const uint8_t l_instance = iv_Occ->instance;
+
+ if (iv_OccRsp.returnStatus != OCC_RC_SUCCESS)
+ {
+ sprintf(l_rsp_status_string, " (%s)",
+ rsp_status_string(iv_OccRsp.returnStatus));
+ }
+
+ // TODO RTC 109224 - refactor/optimize trace strings
+ TMGT_INF("OCC%d rsp status=0x%02X%s, length=0x%04X",
+ l_instance, iv_OccRsp.returnStatus,
+ l_rsp_status_string, iv_OccRsp.dataLength);
+ if (iv_OccRsp.dataLength > 0)
+ {
+ TMGT_BIN("rsp data:", iv_OccRsp.rspData,
+ std::min(iv_OccRsp.dataLength,(uint16_t)16));
+ }
+ }
+
+
+ // Process the OCC response and determine if retry is required
+ void OccCmd::processOccResponse(errlHndl_t & io_errlHndl,
+ const bool i_traceRsp)
+ {
+ const uint8_t l_instance = iv_Occ->instance;
+ const bool alreadyRetriedOnce = iv_RetryCmd;
+ iv_RetryCmd = false;
+
+ if (i_traceRsp)
+ {
+ traceResponse();
+ }
+
+ if (io_errlHndl == NULL)
+ {
+ // A response was received
+ io_errlHndl = checkOccResponse();
+ if (io_errlHndl != NULL)
+ {
+ // Error checking on response failed...
+ if ((alreadyRetriedOnce == false) &&
+ (OCC_RC_PRESENT_STATE_PROHIBITS != iv_OccRsp.returnStatus))
+ {
+ // A retry has not been sent yet, commit/delete the error
+ // and retry. Add OCC command data to user details
+ // TODO RTC 115922
+ //io_errlHndl->addUsrDtls(iv_OccCmd.cmdData,
+ // iv_OccCmd.dataLength, HTMGT_COMP_ID,
+ // 0/*version*/, TMGT_OCC_CMD_DATA);
+ ERRORLOG::errlCommit(io_errlHndl, HTMGT_COMP_ID);
+ iv_RetryCmd = true;
+ // Clear/init the response data structure
+ memset(&iv_OccRsp, 0x00, sizeof(occResponseStruct_t));
+ iv_OccRsp.returnStatus = OCC_COMMAND_IN_PROGRESS;
+ }
+ else
+ {
+ // A retry has already been sent...
+ TMGT_ERR("OCC%d cmd 0x%02X failed retry, status=0x%02X,"
+ " returned length=0x%04X",
+ l_instance, iv_OccCmd.cmdType,
+ iv_OccRsp.returnStatus, iv_OccRsp.dataLength);
+ if (iv_OccRsp.dataLength)
+ {
+ TMGT_BIN("OCC rsp data:", iv_OccRsp.rspData,
+ iv_OccRsp.dataLength);
+ }
+
+ if ( /*(TMGT_RC_CHECKSUM_FAIL == io_errlHndl->getRC()) ||*/
+ (OCC_RC_CHECKSUM_FAILURE == iv_OccRsp.returnStatus) ||
+ (OCC_RC_INTERNAL_ERROR == iv_OccRsp.returnStatus) )
+ {
+ // failed due to rsp data checksum failure... reset OCC
+ TMGT_ERR("processOccResponse: OCC%d response had"
+ " checksum or internal error,"
+ " need to RESET OCC", l_instance);
+ iv_Occ->needsReset = true;
+ // Mark OCC as failed
+ iv_Occ->failed = true;
+ }
+ }
+ }
+ // else response was good
+ }
+ else
+ {
+ // Send of OCC command failed
+ if ( /*(TMGT_RC_SEND_FAIL == io_errlHndl->getRC()) &&*/
+ (alreadyRetriedOnce == true) )
+ {
+ // failed due to send/receive problem and retry has been
+ // sent... reset OCC
+ TMGT_ERR("Sending OCC%d command failed twice, need to RESET"
+ " OCC", l_instance);
+ iv_Occ->needsReset = true;
+ // Unable to communicate with OCC, mark as failed
+ iv_Occ->failed = true;
+ }
+ else
+ {
+ if ((alreadyRetriedOnce == false) &&
+ (OCC_RC_PRESENT_STATE_PROHIBITS != iv_OccRsp.returnStatus))
+ {
+ // A retry has not been sent yet, commit the error
+ // and retry.
+ // Add OCC command data to user details
+ // TODO RTC 115922
+ //io_errlHndl->addUsrDtls(iv_OccCmd.cmdData,
+ //iv_OccCmd.dataLength, HTMGT_COMP_ID,
+ //0/*version*/, TMGT_OCC_CMD_DATA);
+ ERRORLOG::errlCommit(io_errlHndl, HTMGT_COMP_ID);
+ iv_RetryCmd = true;
+
+ // Clear/init the response data structure
+ memset(&iv_OccRsp, 0x00, sizeof(occResponseStruct_t));
+ iv_OccRsp.returnStatus = OCC_COMMAND_IN_PROGRESS;
+ }
+ else
+ {
+ // A retry has already been sent...
+ TMGT_ERR("OCC%d cmd 0x%02X failed. status=0x%02X,"
+ " returned length=0x%04X",
+ l_instance, iv_OccCmd.cmdType,
+ iv_OccRsp.returnStatus, iv_OccRsp.dataLength);
+ if (iv_OccRsp.dataLength)
+ {
+ TMGT_BIN("response data:", iv_OccRsp.rspData,
+ iv_OccRsp.dataLength);
+ }
+
+ if ( /*(TMGT_RC_CHECKSUM_FAIL == io_errlHndl->getRC()) ||*/
+ (OCC_RC_CHECKSUM_FAILURE == iv_OccRsp.returnStatus) ||
+ (OCC_RC_INTERNAL_ERROR == iv_OccRsp.returnStatus) )
+ {
+ // failed due to rsp data checksum failure... reset OCC
+ TMGT_ERR("processOccResponse: OCC%d response had"
+ " checksum or internal error,"
+ " need to RESET OCC", l_instance);
+ iv_Occ->needsReset = true;
+ // Unable to communicate with OCC, mark as failed
+ iv_Occ->failed = true;
+ }
+ }
+ }
+ }
+ } // end OccCmd::processOccResponse()
+
+
+ // Send command to OCC
+ errlHndl_t OccCmd::sendOccCmd()
+ {
+ errlHndl_t l_errlHndl = NULL;
+ uint8_t l_cmd_index = 0;
+ iv_OccRsp.returnStatus = OCC_COMMAND_IN_PROGRESS;
+
+ if (iv_Occ != NULL)
+ {
+ const occStateId l_occState = iv_Occ->state;
+ l_cmd_index = getCmdIndex(iv_OccCmd.cmdType);
+ if (OCC_CMD_END_OF_TABLE!=cv_occCommandTable[l_cmd_index].cmdType)
+ {
+ const bool cmdTraced = traceCommand();
+
+ const bool l_commEstablished = iv_Occ->commEstablished;
+ if ( (true == l_commEstablished) ||
+ ((false == l_commEstablished) &&
+ (OCC_CMD_POLL == iv_OccCmd.cmdType)) )
+ {
+ iv_RetryCmd = false;
+ do
+ {
+ // Send the command and receive the response
+ l_errlHndl = writeOccCmd();
+
+ processOccResponse(l_errlHndl, cmdTraced);
+
+ } while (iv_RetryCmd);
+ }
+ else
+ {
+ // Ignore failure on GET_FIELD_DEBUG_DATA
+ if (OCC_CMD_GET_FIELD_DEBUG_DATA != iv_OccCmd.cmdType)
+ {
+ // Comm not established or command not supported
+ /*@
+ * @errortype
+ * @reasoncode HTMGT_RC_OCC_UNAVAILABLE
+ * @moduleid HTMGT_MOD_SEND_OCC_CMD
+ * @userdata1 OCC command
+ * @userdata2 comm established
+ * @userdata3 OCC state
+ * @userdata4 1
+ * @devdesc OCC comm not established or command is not
+ * supported
+ */
+ bldErrLog(l_errlHndl, HTMGT_MOD_SEND_OCC_CMD,
+ HTMGT_RC_OCC_UNAVAILABLE,
+ iv_OccCmd.cmdType, l_commEstablished,
+ l_occState, 1,
+ ERRORLOG::ERRL_SEV_INFORMATIONAL);
+ }
+ }
+ }
+ else
+ {
+ TMGT_ERR("sendOccCmd: ignoring invalid command 0x%02X",
+ iv_OccCmd.cmdType);
+ /*@
+ * @errortype
+ * @reasoncode HTMGT_RC_INVALID_DATA
+ * @moduleid HTMGT_MOD_SEND_OCC_CMD
+ * @userdata1 OCC command type
+ * @devdesc Ignoring invalid command
+ */
+ bldErrLog(l_errlHndl, HTMGT_MOD_SEND_OCC_CMD,
+ HTMGT_RC_INVALID_DATA,
+ iv_OccCmd.cmdType, 0, 0, 0,
+ ERRORLOG::ERRL_SEV_INFORMATIONAL);
+ }
+ }
+ else
+ {
+ TMGT_ERR("sendOccCmd: ignoring command 0x%02X due to NULL OCC",
+ iv_OccCmd.cmdType);
+ /*@
+ * @errortype
+ * @reasoncode HTMGT_RC_INTERNAL_ERROR
+ * @moduleid HTMGT_MOD_SEND_OCC_CMD
+ * @userdata1 OCC command type
+ * @devdesc OCC is not valid
+ */
+ bldErrLog(l_errlHndl, HTMGT_MOD_SEND_OCC_CMD,
+ HTMGT_RC_INTERNAL_ERROR,
+ iv_OccCmd.cmdType, 0, 0, 0,
+ ERRORLOG::ERRL_SEV_INFORMATIONAL);
+ }
+
+ if (l_errlHndl)
+ {
+ // Add OCC command data to user details
+ // TODO RTC 115922
+ //l_errlHndl->addUsrDtls(iv_OccCmd.cmdData,
+ // iv_OccCmd.dataLength, HTMGT_COMP_ID,
+ // 0/*version*/, TMGT_OCC_CMD_DATA);
+ }
+
+ return l_errlHndl;
+
+ } // end OccCmd::sendOccCmd()
+
+
+
+#ifdef SIMICS_TESTING
+ // Auto-responder for testing in simics
+ void OccCmd::fakeOccResponse()
+ {
+ static uint8_t L_state = 0;
+ static uint8_t L_prior_status = 0x00;
+ static uint8_t L_prior_sequence = 0x00;
+ uint8_t * const rspBuffer = iv_Occ->homer + HTMGT_OCC_RSP_ADDR;
+
+ if (0 == L_state)
+ {
+ if (G_debug_data != 0x02)
+ {
+ TMGT_INF("fakeOccResponse: status=0xFF");
+ rspBuffer[0] = g_seq;
+ rspBuffer[1] = g_cmd;
+ rspBuffer[2] = 0xFF; // status
+ ++L_state;
+
+ if (G_debug_data == 0x01)
+ {
+ L_state = 0; // force command timeout
+ }
+ }
+ }
+ else
+ {
+ if (G_debug_data != 0xE0)
+ {
+ TMGT_INF("fakeOccResponse: status=0x00");
+ rspBuffer[2] = 0x00; // status
+
+ // Add full reseponse data
+ const uint16_t dataLength = OCC_POLL_DATA_MIN_SIZE;
+ const occPollRspStruct_t poll_rsp_data = {
+ // Status 0x8B = Master, AttnEnabled, ObsReady, ActReady
+ 0x8B,
+ 0, // extStatus;
+ 0x01, // occsPresent;
+ 0, // requestedCfg;
+ 0, // state;
+ 0x0000, // reserved;
+ 0, // errorId;
+ 0x00000000, // errorAddress;
+ 0x0000, // errorLength;
+ 0x0000, // reserved2;
+ { "occ825_simicsFF" }, // codeLevel[16];
+ { 'S', 'E', 'N', 'S', 'O', 'R' }, // sensor[6];
+ 0, // numBlocks;
+ 0x01 // version;
+ //uint8_t sensorData[4049];
+ };
+ UINT16_PUT(&rspBuffer[3], dataLength);
+ TMGT_INF("fakeOccResponse: data length=%d", dataLength);
+ if (dataLength)
+ {
+ memcpy(&rspBuffer[5], &poll_rsp_data, dataLength);
+ }
+ uint16_t checksum = 0;
+ const uint16_t checksumOffset = OCC_RSP_HDR_LENGTH +
+ dataLength - 2;
+ for (uint16_t l_index = 0; l_index < checksumOffset; l_index++)
+ {
+ checksum += rspBuffer[l_index];
+ }
+ if (G_debug_data == 0x03)
+ {
+ TMGT_INF("fakeOccResponse: corrupting checksum"
+ " (good=0x%04X)", checksum);
+ checksum++;
+ }
+ TMGT_INF("fakeOccResponse: Writing checksum 0x%04X to offset"
+ " 0x%04X", checksum, checksumOffset);
+ UINT16_PUT(&rspBuffer[checksumOffset], checksum);
+ }
+ else
+ {
+ TMGT_INF("fakeOccResponse: status=0xE1");
+ rspBuffer[2] = 0xE0; // status
+ const uint16_t dataLength = 32;
+ UINT16_PUT(&rspBuffer[3], dataLength);
+ const uint8_t excpData[dataLength] = { 0x11, 0x22, 0x33, 0x44 };
+ TMGT_INF("fakeOccResponse: data length=%d", dataLength);
+ if (dataLength)
+ {
+ memcpy(&rspBuffer[5], &excpData, dataLength);
+ }
+ }
+
+ L_state = 0;
+ }
+
+ // Check response buffer
+ if (L_prior_status != rspBuffer[2])
+ {
+ TMGT_INF("fakeOccResponse: status updated to 0x%02X",
+ rspBuffer[2]);
+ L_prior_status = rspBuffer[2];
+ }
+ if (L_prior_sequence != rspBuffer[0])
+ {
+ TMGT_INF("fakeOccResponse: sequence updated to 0x%02X"
+ " (expecting=0x%02X)",
+ rspBuffer[0], iv_Occ->seqNumber);
+ L_prior_sequence = rspBuffer[0];
+ }
+
+ } // end fakeOccResponse()
+#endif
+
+
+
+ // Returns true if timeout waiting for response
+ bool OccCmd::waitForOccRsp(uint32_t i_timeout)
+ {
+ const uint8_t * const rspBuffer = iv_Occ->homer + HTMGT_OCC_RSP_ADDR;
+ uint16_t rspLength = 0;
+ if (G_debug_trace & DEBUG_TRACE_VERBOSE)
+ {
+ TMGT_INF("waitForOccRsp(%d) address=0x%08X", i_timeout, rspBuffer);
+ }
+
+ bool l_time_expired = true;
+ const uint32_t OCC_RSP_SAMPLE_TIME = 100; // in milliseconds
+ uint32_t l_msec_remaining = std::max(i_timeout, OCC_RSP_SAMPLE_TIME);
+ while (l_msec_remaining > 0)
+ {
+#ifdef SIMICS_TESTING
+ fakeOccResponse();
+#endif
+ // 1. When OCC receives the command, they will set the status to
+ // COMMAND_IN_PROGRESS.
+ // 2. When the response is ready they will update the full
+ // response buffer (except the status)
+ // 3. The status field is updated last to indicate response ready
+ //
+ // Note: Need to check the sequence number to be sure we are
+ // processing the expected response
+ if ((OCC_COMMAND_IN_PROGRESS != rspBuffer[2]) &&
+ (iv_Occ->seqNumber == rspBuffer[0]))
+ {
+ // Need an 'isync' here to ensure that previous instructions
+ // have completed before the code continues on. This is a type
+ // of read-barrier. Without this the processor can do
+ // speculative reads of the HOMER data and you can actually
+ // get stale data as part of the instructions that happen
+ // afterwards. Another 'weak consistency' issue.
+ isync();
+
+ // OCC must have processed the command
+ const uint16_t rspDataLen = UINT16_GET(&rspBuffer[3]);
+ rspLength = OCC_RSP_HDR_LENGTH + rspDataLen;
+ if (G_debug_trace & DEBUG_TRACE_OCCCMD)
+ {
+ TMGT_INF("waitForOccRsp: OCC%d rsp (huid=0x%08X,"
+ " rsp length=%d)",
+ iv_Occ->instance, iv_Occ->huid, rspLength);
+ TMGT_BIN("waitForOccRsp: OCC rsp data (up to 256 bytes)",
+ rspBuffer, std::min(rspLength, (uint16_t)256));
+ }
+ l_time_expired = false;
+ break;
+ }
+
+ // delay before next check
+ const uint32_t l_sleep_msec = std::min(l_msec_remaining,
+ OCC_RSP_SAMPLE_TIME);
+
+ // TODO RTC 115922
+#ifndef __HOSTBOOT_RUNTIME
+ nanosleep( 0, NS_PER_MSEC * l_sleep_msec );
+#else
+ if(g_hostInterfaces && g_hostInterfaces->nanosleep)
+ {
+ g_hostInterfaces->nanosleep(0, NS_PER_MSEC * l_sleep_msec);
+ }
+#endif
+ l_msec_remaining -= l_sleep_msec;
+
+ } // while
+
+ if (l_time_expired)
+ {
+ // timeout waiting for response
+ TMGT_ERR("waitForOccRsp: OCC%d timeout waiting for response"
+ " (%d sec)",
+ iv_Occ->instance, i_timeout/1000);
+ }
+
+ return l_time_expired;
+
+ } // end OccCmd::waitForOccRsp()
+
+
+
+ // Create/commit an error log with the OCC exception data
+ void OccCmd::handleOccException(void)
+ {
+ // Exception length includes response header (w/o checksum) and
+ // the data length
+ uint32_t l_exceptionDataLength = OCC_RSP_HDR_LENGTH - 2 +
+ iv_OccRsp.dataLength;
+
+ TMGT_ERR("handleOccException: OCC%d returned abnormal rsp status of"
+ " 0x%02X, rsp len=%d",
+ iv_Occ->instance, iv_OccRsp.returnStatus,
+ l_exceptionDataLength);
+ if (l_exceptionDataLength > 4*KILOBYTE)
+ {
+ TMGT_INF("handleOccException: truncating data length to 4K");
+ l_exceptionDataLength = 4*KILOBYTE;
+ // TODO RTC 109224 - HB elogs are only 4K
+ }
+
+ /*@
+ * @errortype
+ * @reasoncode HTMGT_RC_INTERNAL_ERROR
+ * @moduleid HTMGT_MOD_HANLDE_OCC_EXCEPTION
+ * @userdata1[0-15] rsp status
+ * @userdata1[16-31] exception data length
+ * @userdata2[0-15] huid
+ * @userdata2[16-31]
+ * @devdesc OCC reported exception
+ */
+ errlHndl_t l_excErr = NULL;
+ bldErrLog(l_excErr, HTMGT_MOD_HANLDE_OCC_EXCEPTION,
+ (htmgtReasonCode)(OCCC_COMP_ID | iv_OccRsp.returnStatus),
+ iv_OccRsp.returnStatus, iv_OccRsp.dataLength,
+ iv_Occ->huid, 0,
+ ERRORLOG::ERRL_SEV_INFORMATIONAL //,
+ //false, // dont skip traces
+ // OCCC_COMP_ID);
+ // TODO RTC 115922
+ //l_excErr->addUsrDtls(l_excp_buffer, l_excp_length,
+ // OCCC_COMP_ID, 1 /*version*/,
+ // iv_OccRsp.returnStatus/*type*/
+ );
+ ERRORLOG::errlCommit(l_excErr, HTMGT_COMP_ID);
+
+ } // end OccCmd::handleOccException()
+
+
+
+ // Build OCC command buffer in HOMER, notify OCC and wait for
+ // the response or timeout
+ errlHndl_t OccCmd::writeOccCmd()
+ {
+ errlHndl_t l_err = NULL;
+ if (G_debug_trace & DEBUG_TRACE_VERBOSE)
+ {
+ TMGT_INF("writeOccCmd() called");
+ }
+
+ // Write the command to HOMER
+ buildOccCmdBuffer();
+
+ // Notify OCC that command is available (via circular buffer)
+ const uint32_t l_bitsToSend = sizeof(occCircBufferCmd_t) * 8;
+ ecmdDataBufferBase l_circ_buffer(l_bitsToSend);
+ const occCircBufferCmd_t tmgtDataWriteAttention =
+ {
+ 0x10, // sender: HTMGT
+ 0x01, // command: Command Write Attention
+ {0, 0, 0, 0, 0, 0} // reserved
+ };
+ l_circ_buffer.insert((uint8_t*)&tmgtDataWriteAttention, 0,
+ l_bitsToSend);
+ if (G_debug_trace & DEBUG_TRACE_VERBOSE)
+ {
+ TMGT_INF("writeOccCmd: Calling writeCircularBuffer()");
+ }
+ l_err = HBOCC::writeCircularBuffer(iv_Occ->target, l_circ_buffer);
+ if (NULL != l_err)
+ {
+ TMGT_ERR("writeOccCmd: Error writing to OCC Circular Buffer");
+ }
+ else
+ {
+ // Wait for response from the OCC
+ const uint8_t l_instance = iv_Occ->instance;
+ const uint8_t l_index = getCmdIndex(iv_OccCmd.cmdType);
+ // l_index should be valid since validation was done in sendOccCmd()
+ const uint16_t l_read_timeout = cv_occCommandTable[l_index].timeout;
+
+ // Wait for OCC to process command and send response
+ waitForOccRsp(l_read_timeout);
+
+ // Parse the OCC response (called even on timeout to collect
+ // rsp buffer)
+ l_err = parseOccResponse();
+
+ bool l_timeout = false;
+ if (OCC_COMMAND_IN_PROGRESS != iv_OccRsp.returnStatus)
+ {
+ // Status of 0xE0-EF are reserved for OCC exceptions,
+ // must collect data for these
+ if (0xE0 == (iv_OccRsp.returnStatus & 0xF0))
+ {
+ handleOccException();
+ }
+ else
+ {
+ if (iv_OccRsp.sequenceNumber !=
+ iv_OccCmd.sequenceNumber)
+ {
+ // Sequence number mismatch
+ TMGT_ERR("writeOccCmd: OCC%d sequence number mismatch"
+ " (from cmd: 0x%02X, rsp: 0x%02X)",
+ l_instance, iv_OccCmd.sequenceNumber,
+ iv_OccRsp.sequenceNumber);
+ l_timeout = true;
+ }
+ }
+ }
+ else
+ {
+ // OCC must not have completed processing the command before
+ // timeout
+ l_timeout = true;
+ }
+
+ if (l_timeout)
+ {
+ /*@
+ * @errortype
+ * @reasoncode HTMGT_RC_TIMEOUT
+ * @moduleid HTMGT_MOD_WRITE_OCC_CMD
+ * @userdata1[0-15] command
+ * @userdata1[16-31] read timeout
+ * @userdata2[0-15] response sequence number
+ * @userdata2[16-31] response status
+ * @devdesc Timeout waiting for OCC response
+ */
+ bldErrLog(l_err, HTMGT_MOD_WRITE_OCC_CMD, HTMGT_RC_TIMEOUT,
+ iv_OccCmd.cmdType, l_read_timeout,
+ iv_OccRsp.sequenceNumber,
+ iv_OccRsp.returnStatus,
+ ERRORLOG::ERRL_SEV_INFORMATIONAL);
+
+ // The response buffer did not contain correct sequence number,
+ // or staus is still in progress save 1K rsp data
+ // TODO RTC 115922
+ //l_err->addUsrDtls(l_err, l_excp_length,
+ // OCCC_COMP_ID, 1 /*version*/, 0xF0 /*type*/);
+
+ // timeout waiting for response (no data to return)
+ iv_OccRsp.dataLength = 0;
+ } // end timeout
+ }
+
+ return l_err;
+
+ } /* end of OccCmd::writeOccCmd() */
+
+
+
+ // Copy OCC command into command buffer in HOMER
+ uint16_t OccCmd::buildOccCmdBuffer()
+ {
+ uint8_t * const cmdBuffer = iv_Occ->homer + HTMGT_OCC_CMD_ADDR;
+ uint16_t l_send_length = 0;
+
+ if (0 == ++iv_Occ->seqNumber)
+ {
+ // Do not use 0 for sequence number
+ ++iv_Occ->seqNumber;
+ }
+ iv_OccCmd.sequenceNumber = iv_Occ->seqNumber;
+ cmdBuffer[l_send_length++] = iv_OccCmd.sequenceNumber;
+ cmdBuffer[l_send_length++] = iv_OccCmd.cmdType;
+ cmdBuffer[l_send_length++] = (iv_OccCmd.dataLength >> 8) & 0xFF;
+ cmdBuffer[l_send_length++] = iv_OccCmd.dataLength & 0xFF;
+ memcpy(&cmdBuffer[l_send_length], iv_OccCmd.cmdData,
+ iv_OccCmd.dataLength);
+ l_send_length += iv_OccCmd.dataLength;
+
+ // Calculate checksum
+ iv_OccCmd.checksum = 0;
+ for (uint16_t l_index = 0; l_index < l_send_length; l_index++)
+ {
+ iv_OccCmd.checksum += cmdBuffer[l_index];
+ }
+ cmdBuffer[l_send_length++] = (iv_OccCmd.checksum >> 8) & 0xFF;
+ cmdBuffer[l_send_length++] = iv_OccCmd.checksum & 0xFF;
+
+ if (G_debug_trace & DEBUG_TRACE_OCCCMD)
+ {
+ // Trace the command
+ TMGT_BIN("buildOccCmdBuffer: OCC command",
+ cmdBuffer, l_send_length);
+ }
+
+#ifdef SIMICS_TESTING
+ g_seq = iv_OccCmd.sequenceNumber;
+ g_cmd = iv_OccCmd.cmdType;
+#endif
+
+ // When the P8 processor writes to memory (such as the HOMER) there is
+ // no certainty that the writes happen in order or that they have
+ // actually completed by the time the instructions complete. 'sync'
+ // is a memory barrier to ensure the HOMER data has actually been made
+ // consistent with respect to memory, so that if the OCC were to read
+ // it they would see all of the data. Otherwise, there is potential
+ // for them to get stale or incomplete data.
+ sync();
+
+ return l_send_length;
+
+ } // end OccCmd::buildOccCmdBuffer()
+
+
+
+ // Copy response into object
+ errlHndl_t OccCmd::parseOccResponse()
+ {
+ errlHndl_t l_errlHndl = NULL;
+ uint16_t l_index = 0;
+ const uint8_t * const rspBuffer = iv_Occ->homer + HTMGT_OCC_RSP_ADDR;
+ const uint16_t rspLen = OCC_RSP_HDR_LENGTH + UINT16_GET(&rspBuffer[3]);
+
+ if ((NULL != rspBuffer) && (rspLen >= OCC_RSP_HDR_LENGTH))
+ {
+ iv_OccRsp.sequenceNumber = rspBuffer[l_index++];
+ iv_OccRsp.cmdType = (enum occCommandType)rspBuffer[l_index++];
+ iv_OccRsp.returnStatus = (occReturnCodes)rspBuffer[l_index++];
+
+ iv_OccRsp.dataLength = UINT16_GET(&rspBuffer[l_index]);
+ l_index += 2;
+ if (rspLen >= (iv_OccRsp.dataLength + OCC_RSP_HDR_LENGTH))
+ {
+ if (iv_OccRsp.dataLength > 0)
+ {
+ if (iv_OccRsp.dataLength > OCC_MAX_DATA_LENGTH)
+ {
+ TMGT_ERR("parseOccResponse: truncating data (0x%04X)",
+ iv_OccRsp.dataLength);
+ iv_OccRsp.dataLength = OCC_MAX_DATA_LENGTH;
+ }
+ memcpy(iv_OccRsp.rspData, &rspBuffer[l_index],
+ iv_OccRsp.dataLength);
+ l_index += iv_OccRsp.dataLength;
+ }
+ iv_OccRsp.checksum = UINT16_GET(&rspBuffer[l_index]);
+ l_index += 2;
+ }
+ else
+ {
+ // Log invalid read length (not enough data received)
+ /*@
+ * @errortype
+ * @reasoncode HTMGT_RC_SEND_FAIL
+ * @moduleid HTMGT_MOD_PARSE_OCC_RSP
+ * @userdata1[0-15] response length
+ * @userdata1[16-31] response buffer[0-3]
+ * @userdata2[0-15] response buffer[4-7]
+ * @userdata2[16-31]
+ * @devdesc Invalid response length received
+ */
+ bldErrLog(l_errlHndl, HTMGT_MOD_PARSE_OCC_RSP,
+ HTMGT_RC_SEND_FAIL,
+ rspLen, UINT32_GET(rspBuffer),
+ UINT32_GET(&rspBuffer[4]), 0,
+ ERRORLOG::ERRL_SEV_INFORMATIONAL);
+ }
+ }
+ else
+ {
+ uint32_t l_data[2] = {0};
+ if (NULL != rspBuffer)
+ {
+ memcpy(l_data, rspBuffer, sizeof(l_data));
+ }
+ // Log invalid read length (rsp too short)
+ bldErrLog(l_errlHndl, HTMGT_MOD_PARSE_OCC_RSP, HTMGT_RC_SEND_FAIL,
+ rspLen, l_data[0], l_data[1], 0,
+ ERRORLOG::ERRL_SEV_INFORMATIONAL);
+ }
+
+ if (l_errlHndl)
+ {
+ // Add full OCC response to user details
+ // TODO RTC 115922
+ //l_errlHndl->addUsrDtls(rspBuffer, rspLen, HTMGT_COMP_ID,
+ // 0/*version*/, TMGT_OCC_RSP_DATA);
+ }
+
+ return l_errlHndl;
+
+ } // end OccCmd::parseOccResponse()
+
+
+
+ // Verify status, checksum and length of OCC response
+ errlHndl_t OccCmd::checkOccResponse()
+ {
+ errlHndl_t l_errlHndl = NULL;
+ uint16_t l_calc_checksum = 0, l_index = 0;
+
+ // Calculate checksum on response
+ l_calc_checksum += iv_OccRsp.sequenceNumber;
+ l_calc_checksum += iv_OccRsp.cmdType;
+ l_calc_checksum += iv_OccRsp.returnStatus;
+ l_calc_checksum += (iv_OccRsp.dataLength >> 8) & 0xFF;
+ l_calc_checksum += iv_OccRsp.dataLength & 0xFF;
+ for (l_index = 0; l_index < iv_OccRsp.dataLength; l_index++)
+ {
+ l_calc_checksum += iv_OccRsp.rspData[l_index];
+ }
+
+ if (l_calc_checksum == iv_OccRsp.checksum)
+ {
+ if (OCC_RC_SUCCESS == iv_OccRsp.returnStatus)
+ {
+ occCheckRspLengthType l_check_rsp_length;
+ uint16_t l_rsp_length = 0;
+
+ // Verify response length and log errors if bad
+ l_index = getCmdIndex(iv_OccRsp.cmdType);
+ // l_index should be valid since validation was done
+ // in sendOccCmd()
+ l_check_rsp_length = cv_occCommandTable[l_index].checkRspLength;
+ l_rsp_length = cv_occCommandTable[l_index].rspLength;
+
+ if (OCC_CHECK_RSP_LENGTH_EQUALS == l_check_rsp_length)
+ {
+ if ( iv_OccRsp.dataLength != l_rsp_length )
+ {
+ TMGT_ERR("Invalid length in OCC response for"
+ " cmd=0x%02X, length=0x%04X",
+ iv_OccRsp.cmdType,
+ iv_OccRsp.dataLength);
+ /*@
+ * @errortype
+ * @reasoncode HTMGT_RC_OCC_CMD_FAIL
+ * @moduleid HTMGT_MOD_CHECK_OCC_RSP
+ * @userdata1[0-15] OCC command type
+ * @userdata1[16-31] response data length
+ * @devdesc Invalid length in OCC response
+ */
+ bldErrLog(l_errlHndl, HTMGT_MOD_CHECK_OCC_RSP,
+ HTMGT_RC_OCC_CMD_FAIL,
+ iv_OccRsp.cmdType,
+ iv_OccRsp.dataLength, 0, 1,
+ ERRORLOG::ERRL_SEV_INFORMATIONAL);
+ }
+ }
+ else if (OCC_CHECK_RSP_LENGTH_GREATER == l_check_rsp_length)
+ {
+ if ( iv_OccRsp.dataLength < l_rsp_length )
+ {
+ TMGT_ERR("Invalid length in OCC response for"
+ " cmd=0x%02X, length=0x%04X",
+ iv_OccRsp.cmdType,
+ iv_OccRsp.dataLength);
+ bldErrLog(l_errlHndl, HTMGT_MOD_CHECK_OCC_RSP,
+ HTMGT_RC_OCC_CMD_FAIL,
+ iv_OccRsp.cmdType,
+ iv_OccRsp.dataLength, 0, 2,
+ ERRORLOG::ERRL_SEV_INFORMATIONAL);
+ }
+ }
+ else if (OCC_CHECK_RSP_LENGTH_NONE != l_check_rsp_length)
+ {
+ TMGT_ERR("Invalid check response length=0x%02X in OCC"
+ " command table for cmd = 0x%02X",
+ l_check_rsp_length, iv_OccRsp.cmdType);
+ bldErrLog(l_errlHndl, HTMGT_MOD_CHECK_OCC_RSP,
+ HTMGT_RC_OCC_CMD_FAIL,
+ iv_OccRsp.cmdType, iv_OccRsp.dataLength,
+ 0, 0, ERRORLOG::ERRL_SEV_INFORMATIONAL);
+ }
+ }
+ else
+ {
+ // Command was not successfully processed
+ uint8_t l_error_log_id = 0;
+
+ if (1 == iv_OccRsp.dataLength)
+ {
+ // Data should be error log id created for this failure
+ l_error_log_id = iv_OccRsp.rspData[0];
+
+ TMGT_ERR("checkOccResponse: Bad status (0x%02X=%s) from OCC"
+ " (returned elog=0x%02X)",
+ iv_OccRsp.returnStatus,
+ rsp_status_string(iv_OccRsp.returnStatus),
+ l_error_log_id);
+ }
+ else
+ {
+ TMGT_ERR("checkOccResponse: Bad status (0x%02X=%s) from OCC"
+ " (data len=%d)",
+ iv_OccRsp.returnStatus,
+ rsp_status_string(iv_OccRsp.returnStatus),
+ iv_OccRsp.dataLength);
+
+ TMGT_ERR("OCC response packet length invalid (0x%04X)",
+ iv_OccRsp.dataLength);
+ l_error_log_id = 0;
+ }
+ /* */
+ bldErrLog(l_errlHndl, HTMGT_MOD_CHECK_OCC_RSP,
+ HTMGT_RC_OCC_CMD_FAIL,
+ iv_OccRsp.returnStatus, l_error_log_id,
+ iv_OccRsp.cmdType, 3,
+ ERRORLOG::ERRL_SEV_INFORMATIONAL);
+ }
+ }
+ else
+ {
+ /*@
+ * @errortype
+ * @reasoncode HTMGT_RC_CHECKSUM_FAIL
+ * @moduleid HTMGT_MOD_CHECK_OCC_RSP
+ * @userdata1 OCC command type
+ * @userdata2 sequence number
+ * @userdata3 checksum
+ * @userdata4 calculated checksum
+ * @devdesc OCC response had checksum failure
+ */
+ bldErrLog(l_errlHndl, HTMGT_MOD_CHECK_OCC_RSP,
+ HTMGT_RC_CHECKSUM_FAIL,
+ iv_OccRsp.cmdType, iv_OccRsp.sequenceNumber,
+ iv_OccRsp.checksum, l_calc_checksum,
+ ERRORLOG::ERRL_SEV_INFORMATIONAL);
+ }
+
+ if (l_errlHndl)
+ {
+ // Add OCC response data to user details
+ // TODO RTC 115922
+ // l_errlHndl->addUsrDtls(iv_OccRsp.rspData,
+ // iv_OccRsp.dataLength, HTMGT_COMP_ID,
+ // 0/*version*/, TMGT_OCC_RSP_DATA);
+ }
+
+ return(l_errlHndl);
+
+ } /* end of OccCmd::checkOccResponse() */
+
+
+}
+
OpenPOWER on IntegriCloud