summaryrefslogtreecommitdiffstats
path: root/src/usr/util/runtime/rt_fwnotify.C
diff options
context:
space:
mode:
authorRoland Veloz <rveloz@us.ibm.com>2017-12-04 17:37:05 -0600
committerDaniel M. Crowell <dcrowell@us.ibm.com>2017-12-21 00:12:25 -0500
commit44d0f070400aabde3a06eb7b836923577a117cc0 (patch)
tree464a51f429057595436e47e510913a9a7a03f8d2 /src/usr/util/runtime/rt_fwnotify.C
parenta334e5aa3f11fe4f4657ba89139ac0a543845af1 (diff)
downloadtalos-hostboot-44d0f070400aabde3a06eb7b836923577a117cc0.tar.gz
talos-hostboot-44d0f070400aabde3a06eb7b836923577a117cc0.zip
Handles FSP reset-reload in HBRT messages
For every instance where a firmware_request is made, it is possible to get an error if the FSP is doing a reset/reload. Now, if an error returned from the firmware_request call indicates that the FSP is doing a reset/reload, the firmware_request call will be made again. Also refactored the code. Consolidated the calls to firmware_request to another file to facilitate the adding/updating of messages. Change-Id: I5be440927ab255c55b40a0a0ed26f786d31a9317 RTC:182606 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/50505 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/util/runtime/rt_fwnotify.C')
-rw-r--r--src/usr/util/runtime/rt_fwnotify.C380
1 files changed, 190 insertions, 190 deletions
diff --git a/src/usr/util/runtime/rt_fwnotify.C b/src/usr/util/runtime/rt_fwnotify.C
index 9441519ab..fd6037512 100644
--- a/src/usr/util/runtime/rt_fwnotify.C
+++ b/src/usr/util/runtime/rt_fwnotify.C
@@ -22,35 +22,14 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/util/runtime/rt_fwnotify.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
-/* [+] 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 <sbeio/sbe_retry_handler.H> // SbeRetryHandler
-#include <runtime/interface.h> // firmware_notify
+#include <util/runtime/rt_fwreq_helper.H> // firmware_request_helper
+#include <runtime/interface.h> // g_hostInterfaces
#include <runtime/runtime_reasoncodes.H> // MOD_RT_FIRMWARE_NOTIFY, etc
#include <errl/errlentry.H> // ErrlEntry
#include <errl/errlmanager.H> // errlCommit
+#include <errl/hberrltypes.H> // TWO_UINT32_TO_UINT64
#include <targeting/common/target.H> // TargetHandle_t, getTargetFromHuid
using namespace TARGETING;
@@ -59,36 +38,39 @@ using namespace ERRORLOG;
using namespace MBOX;
using namespace SBEIO;
-trace_desc_t* g_trac_hwsv = nullptr;
-TRAC_INIT(&g_trac_hwsv, "HWSV_TRACE", 4*KILOBYTE);
+// Trace definition
+extern trace_desc_t* g_trac_runtime;
/**
- * @brief The lower and upper bounds for the sequence ID.
- **/
-const uint16_t GFMM_SEQ_ID_MIN = 0x0000;
-const uint16_t GFMM_SEQ_ID_MAX = 0x7FFF;
+ * @brief The lower and upper bounds for the sequence ID.
+ **/
+const uint16_t SEQ_ID_MIN = 0x0000;
+const uint16_t SEQ_ID_MAX = 0x7FFF;
/**
- * @brief Set the sequence ID to the minimum value
- **/
-uint16_t SeqId_t::GFMM_SEQ_ID = GFMM_SEQ_ID_MIN;
+ * @brief Set the sequence ID to the minimum value
+ **/
+uint16_t SeqId_t::SEQ_ID = SEQ_ID_MIN;
/**
- * @brief Gets the next sequence ID.
- * @return The next sequence ID value within it's lower and upper bound
+ * @brief Gets the next sequence ID.
+ * @return The next sequence ID value within its lower and upper bound
+ * @note This code is thread safe, no need for a mutex around this because
+ * HBRT never runs in multi-thread.
+ *
**/
uint16_t SeqId_t::getNextSeqId()
{
- if (SeqId_t::GFMM_SEQ_ID < GFMM_SEQ_ID_MAX)
+ if (SeqId_t::SEQ_ID < SEQ_ID_MAX)
{
- ++SeqId_t::GFMM_SEQ_ID;
+ ++SeqId_t::SEQ_ID;
}
else
{
- SeqId_t::GFMM_SEQ_ID = GFMM_SEQ_ID_MIN;
+ SeqId_t::SEQ_ID = SEQ_ID_MIN;
}
- return SeqId_t::GFMM_SEQ_ID;
+ return SeqId_t::SEQ_ID;
}
/**
@@ -97,7 +79,7 @@ uint16_t SeqId_t::getNextSeqId()
**/
uint16_t SeqId_t::getCurrentSeqId()
{
- return SeqId_t::GFMM_SEQ_ID;
+ return SeqId_t::SEQ_ID;
}
/**
@@ -108,34 +90,34 @@ uint16_t SeqId_t::getCurrentSeqId()
**/
void sbeAttemptRecovery(uint64_t i_data)
{
+ // Create a useful struct to get to the data
+ // The data is expected to be a plid (in the first 4 bytes)
+ // followed by a HUID (in the last 4 bytes).
+ HbrtFspData_t *l_hbrtFspData = reinterpret_cast<HbrtFspData_t*>(&i_data);
+
+ TRACFCOMP(g_trac_runtime, ENTER_MRK"sbeAttemptRecovery: plid:0x%X, "
+ "HUID:0x%X", l_hbrtFspData->plid, l_hbrtFspData->userData);
+
errlHndl_t l_err = nullptr;
do
{
- // Create a useful structure to get to the data
- // The data is expected to be a plid (in the first 4 bytes)
- // followed by a HUID (in the last 4 bytes).
- struct sbeErrorData_t
- {
- uint32_t plid;
- uint32_t huid;
- } PACKED ;
-
- sbeErrorData_t *l_sbeErrorDataReq = (sbeErrorData_t*)(&i_data);
-
// Extract the target from the given HUID
TargetHandle_t l_target =
- Target::getTargetFromHuid(l_sbeErrorDataReq->huid);
+ Target::getTargetFromHuid(l_hbrtFspData->userData);
// If HUID invalid, log error and quit
if (nullptr == l_target)
{
- TRACFCOMP( g_trac_hwsv, "firmware_notify: No target assoicated "
- "with HUID:0x%.8X", l_sbeErrorDataReq->huid);
+ TRACFCOMP(g_trac_runtime, ERR_MRK"sbeAttemptRecovery: "
+ "No target associated with HUID:0x%.8X",
+ l_hbrtFspData->userData);
+
/*@
- * @errortype ERRL_SEV_PREDICTIVE
- * @moduleid RUNTIME::MOD_RT_FIRMWARE_NOTIFY
- * @reasoncode RUNTIME::RC_SBE_RT_INVALID_HUID
+ * @errortype
+ * @severity ERRL_SEV_PREDICTIVE
+ * @moduleid MOD_RT_FIRMWARE_NOTIFY
+ * @reasoncode RC_SBE_RT_INVALID_HUID
* @userdata1 HUID of target
* @userdata2 HWSV error log id (plid)
* @devdesc SBE error recovery attempt failed
@@ -143,8 +125,8 @@ void sbeAttemptRecovery(uint64_t i_data)
l_err = new ErrlEntry( ERRL_SEV_PREDICTIVE,
MOD_RT_FIRMWARE_NOTIFY,
RC_SBE_RT_INVALID_HUID,
- l_sbeErrorDataReq->huid,
- l_sbeErrorDataReq->plid,
+ l_hbrtFspData->userData,
+ l_hbrtFspData->plid,
true);
break;
}
@@ -163,13 +145,14 @@ void sbeAttemptRecovery(uint64_t i_data)
if (nullptr == g_hostInterfaces ||
nullptr == g_hostInterfaces->firmware_request)
{
- TRACFCOMP( g_trac_hwsv, "firmware_notify: Hypervisor "
- "firmware_request interface not linked");
+ TRACFCOMP(g_trac_runtime, ERR_MRK"sbeAttemptRecovery: "
+ "Hypervisor firmware_request interface not linked");
/*@
- * @errortype ERRL_SEV_PREDICTIVE
- * @moduleid RUNTIME::MOD_RT_FIRMWARE_NOTIFY
- * @reasoncode RUNTIME::RC_FW_REQUEST_RT_NULL_PTR
+ * @errortype
+ * @severity ERRL_SEV_PREDICTIVE
+ * @moduleid MOD_RT_FIRMWARE_NOTIFY
+ * @reasoncode RC_FW_REQUEST_RT_NULL_PTR
* @userdata1 HUID of target
* @userdata2 HWSV error log id (plid)
* @devdesc SBE error recovery attempt failed
@@ -177,105 +160,60 @@ void sbeAttemptRecovery(uint64_t i_data)
l_err = new ErrlEntry( ERRL_SEV_PREDICTIVE,
MOD_RT_FIRMWARE_NOTIFY,
RC_FW_REQUEST_RT_NULL_PTR,
- l_sbeErrorDataReq->huid,
- l_sbeErrorDataReq->plid,
+ l_hbrtFspData->userData,
+ l_hbrtFspData->plid,
true);
-
break;
}
- // Create the firmware_request request structure to send data
+ // Create the firmware_request request struct to send data
hostInterfaces::hbrt_fw_msg l_req_fw_msg;
- memset(&l_req_fw_msg, 0, sizeof(l_req_fw_msg));
+ uint64_t l_req_fw_msg_size = sizeof(l_req_fw_msg);
- // Set the data for the request
- l_req_fw_msg.io_type = hostInterfaces::HBRT_FW_MSG_HBRT_FSP_REQ;
+ // Initialize the firmware_request request struct
l_req_fw_msg.generic_msg.initialize();
- l_req_fw_msg.generic_msg.msgq = GFMM_MSG_SBE_ERROR;
- l_req_fw_msg.generic_msg.__req = GFMM_REQUEST;
- l_req_fw_msg.generic_msg.__onlyError = GFMM_NOT_ERROR_ONLY;
+
+ // Populate the firmware_request request struct with given data
+ l_req_fw_msg.io_type = hostInterfaces::HBRT_FW_MSG_HBRT_FSP_REQ;
+ l_req_fw_msg.generic_msg.msgq = GenericFspMboxMessage_t::MSG_SBE_ERROR;
+ l_req_fw_msg.generic_msg.__req = GenericFspMboxMessage_t::REQUEST;
l_req_fw_msg.generic_msg.data = i_data;
+ // Set msgType based on recovery success or failure
if (l_recoverySuccessful)
{
- l_req_fw_msg.generic_msg.msgType= GFMM_MSG_SBE_RECOVERY_SUCCESS;
+ l_req_fw_msg.generic_msg.msgType =
+ GenericFspMboxMessage_t::MSG_SBE_RECOVERY_SUCCESS;
}
else
{
- l_req_fw_msg.generic_msg.msgType = GFMM_MSG_SBE_RECOVERY_FAILED;
+ l_req_fw_msg.generic_msg.msgType =
+ GenericFspMboxMessage_t::MSG_SBE_RECOVERY_FAILED;
}
- // Create the firmware_request response structure to receive data
+ // Create the firmware_request response struct to receive data
+ // NOTE: For messages to the FSP the response size must match
+ // the request size
+ // No need to check for expected response size > request
+ // size because they use the same base structure
hostInterfaces::hbrt_fw_msg l_resp_fw_msg;
- size_t l_resp_fw_msg_size = sizeof(l_resp_fw_msg);
+ uint64_t l_resp_fw_msg_size = sizeof(l_resp_fw_msg);
memset(&l_resp_fw_msg, 0, l_resp_fw_msg_size);
- size_t rc = g_hostInterfaces->firmware_request(sizeof(l_req_fw_msg),
- &l_req_fw_msg,
- &l_resp_fw_msg_size,
- &l_resp_fw_msg);
-
- // Error log id
- uint32_t l_errPlid(0);
+ // Trace out the request structure
+ TRACFBIN( g_trac_runtime, INFO_MRK"Sending firmware_request",
+ &l_req_fw_msg,
+ l_req_fw_msg_size);
- sbeErrorData_t *l_sbeErrorDataResp =
- (sbeErrorData_t*)&(l_resp_fw_msg.generic_msg.data);
+ // Make the firmware_request call
+ l_err = firmware_request_helper(l_req_fw_msg_size,
+ &l_req_fw_msg,
+ &l_resp_fw_msg_size,
+ &l_resp_fw_msg);
- // Capture the error log ID if any
- // The return code (rc) may return OK, but there still may be an issue
- // with the HWSV code on the FSP.
- if ((hostInterfaces::HBRT_FW_MSG_HBRT_FSP_RESP
- == l_resp_fw_msg.io_type) &&
- (GFMM_ERROR_ONLY == l_resp_fw_msg.generic_msg.__onlyError) &&
- (0 != l_sbeErrorDataResp->plid) )
+ if (l_err)
{
- l_errPlid = l_sbeErrorDataResp->plid;
- }
-
- // Gather up the error data and create an error log out of it
- if (rc || l_errPlid)
- {
- /*@
- * @errortype ERRL_SEV_PREDICTIVE
- * @moduleid RUNTIME::MOD_RT_FIRMWARE_NOTIFY
- * @reasoncode RUNTIME::RC_SBE_RT_RECOVERY_ERR
- * @userdata1[0:31] Firmware Request return code
- * @userdata1[32:63] HWSV error log id (plid)
- * @userdata2[0:31] MBOX message type
- * @userdata2[32:63] Message Tyepe
- * @devdesc SBE error recovery attempt failed
- */
- l_err = new ERRORLOG::ErrlEntry(
- ERRL_SEV_PREDICTIVE,
- MOD_RT_FIRMWARE_NOTIFY,
- RC_SBE_RT_RECOVERY_ERR,
- TWO_UINT32_TO_UINT64(rc, l_errPlid),
- TWO_UINT32_TO_UINT64(
- l_resp_fw_msg.generic_msg.msgq,
- l_resp_fw_msg.generic_msg.msgType),
- true);
-
- l_err->addFFDC( RUNTIME_COMP_ID,
- &l_resp_fw_msg,
- l_resp_fw_msg_size,
- 0, 0, false );
-
- if (sizeof(l_req_fw_msg) > 0)
- {
- l_err->addFFDC( RUNTIME_COMP_ID,
- &l_req_fw_msg,
- sizeof(l_req_fw_msg),
- 0, 0, false );
- }
-
- l_err->collectTrace( "SBE", 256);
-
- if (l_errPlid)
- {
- l_err->plid(l_errPlid);
- }
-
break;
}
} while(0);
@@ -285,84 +223,146 @@ void sbeAttemptRecovery(uint64_t i_data)
//Commit the error if it exists
errlCommit(l_err, RUNTIME_COMP_ID);
}
+
+ TRACFCOMP(g_trac_runtime, EXIT_MRK"sbeAttemptRecovery");
}
/**
- * @brief Receive an async notification from firmware
- * @param[in] i_len length of notification data
- * @param[in] i_data notification data
- * @platform FSP, OpenPOWER
+ * @see src/include/runtime/interface.h for definition of call
+ *
*/
void firmware_notify( uint64_t i_len, void *i_data )
{
+ TRACFCOMP(g_trac_runtime, ENTER_MRK"firmware_notify: "
+ "i_len:%d", i_len );
+
+ TRACFBIN(g_trac_runtime, "firmware_notify: i_data", i_data, i_len);
+
errlHndl_t l_err = nullptr;
+ // Flag to detect an invlaid/unknown/not used message
+ bool l_badMessage = false;
+
+ // Capture the unique message data associated with errant message
+ uint64_t l_userData1(0), l_userData2(0);
+
do
{
// make sure the length of the data is not less than the
- // structure we are expecting to receive
- if (i_len < sizeof(GenericFspMboxMessage_t))
+ // data necessary to determine type of message
+ if (i_len < hostInterfaces::HBRT_FW_MSG_BASE_SIZE)
{
- TRACFCOMP( g_trac_hwsv,
- "firmware_notify: Received a non GenericFspMboxMessage "
- "data stream" );
+ l_badMessage = true;
- /*@
- * @errortype
- * @moduleid RUNTIME::MOD_RT_FIRMWARE_NOTIFY
- * @reasoncode RUNTIME::RC_FW_NOTIFY_RT_INVALID_MSG
- * @userdata1 Unused
- * @userdata2 Unused
- * @devdesc Error with Firmware Notify request
- */
- l_err = new ErrlEntry( ERRL_SEV_PREDICTIVE,
- MOD_RT_FIRMWARE_NOTIFY,
- RC_FW_NOTIFY_RT_INVALID_MSG,
- 0, 0, true);
- break;
- }
+ TRACFCOMP(g_trac_runtime, ERR_MRK"firmware_notify: "
+ "Received a non hostInterfaces::hbrt_fw_msg data stream" );
- // Cast the data to the structure we wish to parse
- GenericFspMboxMessage_t* genericMsg =
- static_cast<GenericFspMboxMessage_t*>(i_data);
+ break;
+ }
- // Do function based on message type (msgType)
- switch(genericMsg->msgType)
+ // Cast the data to an hbrt_fw_msg to extract the input type
+ hostInterfaces::hbrt_fw_msg* l_hbrt_fw_msg =
+ static_cast<hostInterfaces::hbrt_fw_msg*>(i_data);
+ switch (l_hbrt_fw_msg->io_type)
{
- case GFMM_MSG_SBE_ERROR: sbeAttemptRecovery(genericMsg->data);
- break;
+
+ case hostInterfaces::HBRT_FW_MSG_HBRT_FSP_REQ:
+ {
+
+ // Extract the message type
+ switch(l_hbrt_fw_msg->generic_msg.msgType)
+ {
+
+ case GenericFspMboxMessage_t::MSG_SBE_ERROR:
+ sbeAttemptRecovery(l_hbrt_fw_msg->generic_msg.data);
+
+ break;
+
+ default:
+ {
+ l_badMessage = true;
+
+ TRACFCOMP(g_trac_runtime, ERR_MRK"firmware_notify: "
+ "Unknown FSP message type:0x%.8X, "
+ "message queue id:0x%.8X, seqNum:%d ",
+ l_hbrt_fw_msg->generic_msg.msgq,
+ l_hbrt_fw_msg->generic_msg.msgType,
+ l_hbrt_fw_msg->generic_msg.seqnum);
+
+ // Pack user data 1 with message input type and
+ // firmware request message sequence number
+ l_userData1 = TWO_UINT32_TO_UINT64(
+ l_hbrt_fw_msg->io_type,
+ l_hbrt_fw_msg->generic_msg.seqnum);
+
+ // Pack user data 2 with message queue and message type
+ l_userData2 = TWO_UINT32_TO_UINT64(
+ l_hbrt_fw_msg->generic_msg.msgq,
+ l_hbrt_fw_msg->generic_msg.msgType);
+ }
+
+ break; // END default
+
+ } // END switch(l_genericMsg->msgType)
+ } // END case HBRT_FW_MSG_HBRT_FSP_REQ:
+
+ break;
default:
{
- TRACFCOMP( g_trac_hwsv, "firmware_notify: Unknown "
- "message type:0x%.8X, message queue id:0x%.8X ",
- genericMsg->msgq, genericMsg->msgType);
-
- /*@
- * @errortype
- * @moduleid RUNTIME::MOD_RT_FIRMWARE_NOTIFY
- * @reasoncode RUNTIME::RC_FW_NOTIFY_RT_INVALID_MSG_TYPE
- * @userdata1 Message Queue ID
- * @userdata2 Message Type
- * @devdesc Error with Firmware Notify request
- */
- l_err = new ErrlEntry( ERRL_SEV_PREDICTIVE,
- MOD_RT_FIRMWARE_NOTIFY,
- RC_FW_NOTIFY_RT_INVALID_MSG_TYPE,
- genericMsg->msgq,
- genericMsg->msgType,
- true);
- }
+ l_badMessage = true;
+
+ TRACFCOMP(g_trac_runtime, ERR_MRK"firmware_notify: "
+ "Unknown firmware request input type:0x%.8X ",
+ l_hbrt_fw_msg->io_type);
+
+ l_userData1 = l_hbrt_fw_msg->io_type;
+ } // END default
+
break;
- };
+
+ }; // END switch (l_hbrt_fw_msg->io_type)
} while(0);
+ if (l_badMessage)
+ {
+ /*@
+ * @errortype
+ * @severity ERRL_SEV_PREDICTIVE
+ * @moduleid MOD_RT_FIRMWARE_NOTIFY
+ * @reasoncode RC_FW_NOTIFY_RT_INVALID_MSG
+ * @userdata1[0:31] Firmware Request type
+ * @userdata1[32:63] Sequence number (FSP msg)
+ * @userdata2[0:31] MBOX message type (FSP msg)
+ * @userdata2[32:63] Message Type (FSP msg)
+ * @devdesc Error with Firmware Notify request
+ */
+ l_err = new ErrlEntry(ERRL_SEV_PREDICTIVE,
+ MOD_RT_FIRMWARE_NOTIFY,
+ RC_FW_NOTIFY_RT_INVALID_MSG,
+ l_userData1,
+ l_userData2,
+ true);
+
+ if (i_len > 0)
+ {
+ l_err->addFFDC(RUNTIME_COMP_ID,
+ i_data,
+ i_len,
+ 0, 0, false );
+ }
+
+ l_err->collectTrace( "FW_REQ", 256);
+ }
+
if (l_err)
{
//Commit the error if it exists
errlCommit(l_err, RUNTIME_COMP_ID);
}
+
+ TRACFCOMP(g_trac_runtime, EXIT_MRK"firmware_notify");
};
struct registerFwNotify
OpenPOWER on IntegriCloud