summaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--src/include/runtime/generic_hbrt_fsp_message.H107
-rw-r--r--src/include/runtime/interface.h9
-rw-r--r--src/include/usr/isteps/tod/runtime/rt_todintf.H9
-rw-r--r--src/include/usr/isteps/tod_init_reasoncodes.H3
-rw-r--r--src/include/usr/runtime/runtime_reasoncodes.H5
-rw-r--r--src/include/usr/util/runtime/rt_fwreq_helper.H60
-rw-r--r--src/include/usr/vpd/vpdreasoncodes.H5
-rw-r--r--src/usr/errl/runtime/makefile2
-rw-r--r--src/usr/errl/runtime/rt_errlmanager.C84
-rw-r--r--src/usr/isteps/pm/runtime/rt_pm.C139
-rw-r--r--src/usr/isteps/pm/runtime/test/firmwareRequestTest.H11
-rw-r--r--src/usr/isteps/tod/runtime/makefile4
-rw-r--r--src/usr/isteps/tod/runtime/rt_todintf.C465
-rw-r--r--src/usr/testcore/rtloader/loader.H11
-rw-r--r--src/usr/util/runtime/makefile1
-rw-r--r--src/usr/util/runtime/rt_fwnotify.C380
-rw-r--r--src/usr/util/runtime/rt_fwreq_helper.C455
-rw-r--r--src/usr/vpd/runtime/makefile2
-rw-r--r--src/usr/vpd/runtime/rt_vpd.C198
19 files changed, 1164 insertions, 786 deletions
diff --git a/src/include/runtime/generic_hbrt_fsp_message.H b/src/include/runtime/generic_hbrt_fsp_message.H
index 1eebb7b09..6fa9ae9cb 100644
--- a/src/include/runtime/generic_hbrt_fsp_message.H
+++ b/src/include/runtime/generic_hbrt_fsp_message.H
@@ -35,43 +35,6 @@
*/
-/**
- * Values for the GenericFspMboxMessage_t::magic
- * and GenericFspMboxMessage_t::structVer data members
- */
-const uint32_t GFMM_MAGIC_NUMBER = 0x4746464D; // `GFFM`
-const uint16_t GFMM_VERSION = 1;
-
-/**
- * Values for the GenericFspMboxMessage_t::__req flag
- */
-enum GENERIC_FSP_MBOX_MESSAGE_FLOW
-{
- GFMM_RESPONSE = 0,
- GFMM_REQUEST = 1,
-};
-
-/**
- * Values for the GenericFspMboxMessage_t::__onlyError flag
- */
-enum GENERIC_FSP_MBOX_MESSAGE_ERROR_FLAG
-{
- GFMM_NOT_ERROR_ONLY = 0,
- GFMM_ERROR_ONLY = 1,
-};
-
-/**
- * The different message types for the GenericFspMboxMessage_t
- */
-enum GENERIC_FSP_MBOX_MESSAGE_MSG_TYPE
-{
- GFMM_MSG_TOD_BACKUP_RESET = 0x0001,
- GFMM_MSG_TOD_BACKUP_RESET_INFORM_PHYP = 0x0002,
- GFMM_MSG_TOD_TOPOLOGY_DATA = 0x0003,
- GFMM_MSG_SBE_ERROR = 0x000000E1,
- GFMM_MSG_SBE_RECOVERY_SUCCESS = 0x000000E2,
- GFMM_MSG_SBE_RECOVERY_FAILED = 0x000000E3,
-};
/**
* This generates a sequence ID that the GenericFspMboxMessage_t
@@ -84,14 +47,74 @@ public:
static uint16_t getCurrentSeqId();
private:
- static uint16_t GFMM_SEQ_ID;
+ static uint16_t SEQ_ID;
};
/**
+ * A useful struct to access the PLID from GenericFspMboxMessage_t.data
+ * The PLID will be in the first 4 bytes followed by some other data.
+ */
+struct HbrtFspData_t
+{
+ uint32_t plid;
+ uint32_t userData;
+} PACKED ;
+
+/**
* This struct sends/receives an MBox message to the FSP
*/
struct GenericFspMboxMessage_t
{
+
+ /**
+ * Value for the GenericFspMboxMessage_t::magic
+ */
+ static constexpr uint32_t MAGIC_NUMBER = 0x4746464D; // `GFFM`
+
+ /**
+ * GenericFspMboxMessage_t Version info
+ *
+ */
+ enum GENERIC_FSP_MBOX_MESSAGE_VERSION
+ {
+ STRUCT_VERSION_FIRST = 0x1,
+ STRUCT_VERSION_LATEST = STRUCT_VERSION_FIRST,
+ };
+
+ /**
+ * Values for the GenericFspMboxMessage_t::__req flag
+ */
+ enum GENERIC_FSP_MBOX_MESSAGE_FLOW
+ {
+ RESPONSE = 0,
+ REQUEST = 1,
+ };
+
+ /**
+ * Values for the GenericFspMboxMessage_t::__onlyError flag
+ */
+ enum GENERIC_FSP_MBOX_MESSAGE_ERROR_FLAG
+ {
+ NOT_ERROR_ONLY = 0,
+ ERROR_ONLY = 1,
+ };
+
+ /**
+ * The different message types for the GenericFspMboxMessage_t
+ */
+ enum GENERIC_FSP_MBOX_MESSAGE_MSG_TYPE
+ {
+ MSG_TOD_BACKUP_RESET = 0x0001,
+ MSG_TOD_BACKUP_RESET_INFORM_PHYP = 0x0002,
+ MSG_TOD_TOPOLOGY_DATA = 0x0003,
+ MSG_SBE_ERROR = 0x000000E1,
+ MSG_SBE_RECOVERY_SUCCESS = 0x000000E2,
+ MSG_SBE_RECOVERY_FAILED = 0x000000E3,
+ };
+
+ /**
+ * GenericFspMboxMessage_t data members
+ */
uint32_t magic; // ='GFMM'
uint32_t dataSize; // total number of bytes in the entire message,
// includes structure plus data buffer,
@@ -120,16 +143,16 @@ struct GenericFspMboxMessage_t
// A method to set the local vars to a default state
void initialize()
{
- magic = GFMM_MAGIC_NUMBER;
+ magic = MAGIC_NUMBER;
dataSize = sizeof(GenericFspMboxMessage_t);
- structVer = GFMM_VERSION;
+ structVer = STRUCT_VERSION_LATEST;
reserved = 0;
seqnum = SeqId_t::getNextSeqId();
msgq = 0;
msgType = 0;
- __req = GFMM_RESPONSE;
+ __req = RESPONSE;
__async = 0;
- __onlyError = GFMM_NOT_ERROR_ONLY;
+ __onlyError = NOT_ERROR_ONLY;
__unused = 0;
data = 0;
};
diff --git a/src/include/runtime/interface.h b/src/include/runtime/interface.h
index 96eb62c2c..3a6ac6b93 100644
--- a/src/include/runtime/interface.h
+++ b/src/include/runtime/interface.h
@@ -147,6 +147,15 @@ enum MemoryError_t
/* PHYP fixes */
#define HBRT_CAPS_SET2_PHYP 2
+/* FSP failed due to a a reset/reload. Only applicable when
+ * hostInterfaces::hbrt_fw_msg::io_type is set to
+ * HBRT_FW_MSG_HBRT_FSP_REQ
+ */
+#define HBRT_RC_FSPDEAD -8193 //0x2001
+
+/* FSP failed due to a a reset/reload */
+#define HBRT_FW_REQUEST_RETRIES 1
+
/** @typedef hostInterfaces_t
* @brief Interfaces provided by the underlying environment (ex. Sapphire).
diff --git a/src/include/usr/isteps/tod/runtime/rt_todintf.H b/src/include/usr/isteps/tod/runtime/rt_todintf.H
index b79e24c1c..4e0c005ae 100644
--- a/src/include/usr/isteps/tod/runtime/rt_todintf.H
+++ b/src/include/usr/isteps/tod/runtime/rt_todintf.H
@@ -44,14 +44,15 @@ namespace TOD
* @brief This interface creates a new backup TOD topology. This request
* is sent to the FSP for resetting the backup topology.
*
- * @param[in] i_oscPos the ordinal ID of the failing OSC. Value of
- * 0xFFFFFFFF means no OSC to avoid.
+ * @param[in] i_oscPos the ordinal ID of the failing OSC (Oscillator).
+ * Value of 0xFFFFFFFF means no OSC to avoid.
* @param[in] i_procOscTgt target of the processor with which the failing OSC
* is associated with. If ordinal ID is 0xFFFFFFFF then this should
* be NULL, otherwise provide a valid target. If ordinal ID is
* 0xFFFFFFFF, i_procOscTgt is ignored regardless of it's validity.
- * @param[in] i_badChipList input list of targets.
- * @param[in] i_informPhyp flag to inform the PHYP that it won't have a
+ * @param[in] i_badChipList list of oscillator targets that have been marked
+ * by PRD as faulty.
+ * @param[in] i_informPhyp flag to inform PHYP that it won't have a
* backup available for fail over while we are re-configuring it.
*
* @return Error log handle indicating the status of the request
diff --git a/src/include/usr/isteps/tod_init_reasoncodes.H b/src/include/usr/isteps/tod_init_reasoncodes.H
index 9580e890b..17f8cea23 100644
--- a/src/include/usr/isteps/tod_init_reasoncodes.H
+++ b/src/include/usr/isteps/tod_init_reasoncodes.H
@@ -94,8 +94,7 @@ namespace TOD
TOD_DRAWER_SET_MDMT = TOD_COMP_ID | 0x18,
TOD_TOP_LEVEL_TARGET_NOT_FOUND = TOD_COMP_ID | 0x19,
TOD_RT_NULL_FIRMWARE_REQUEST_PTR = TOD_COMP_ID | 0x1A,
- TOD_RT_TOPOLOGY_RESET_BACKUP_ERR = TOD_COMP_ID | 0x1B,
- TOD_RT_TOPOLOGY_DATA_ERR = TOD_COMP_ID | 0x1C,
+ TOD_XXX = TOD_COMP_ID | 0x1C,
};
enum TODUserDetailDataSubSection
diff --git a/src/include/usr/runtime/runtime_reasoncodes.H b/src/include/usr/runtime/runtime_reasoncodes.H
index 5b38a8b08..7ff89d712 100644
--- a/src/include/usr/runtime/runtime_reasoncodes.H
+++ b/src/include/usr/runtime/runtime_reasoncodes.H
@@ -59,8 +59,8 @@ namespace RUNTIME
MOD_POPULATE_TPMINFOBYNODE = 0x19, /**< populate_hbruntime.C */
MOD_FILL_RSVMEM_HBDATA = 0x20, /**< populate_hbruntime.C */
MOD_ATTR_RUNTIME_CHECK_PREP_FAIL = 0x21, /**< populate_hbruntime.C */
- MOD_PM_RT_FIRMWARE_REQUEST = 0x22, /**< rt_pm.C */
MOD_RT_FIRMWARE_NOTIFY = 0x23, /**< rt_fwnotify.C */
+ MOD_RT_FIRMWARE_REQUEST = 0x24, /**< rt_fwreq_helper.C */
};
enum RuntimeReasonCode
@@ -120,6 +120,9 @@ namespace RUNTIME
RC_FW_REQUEST_RT_NULL_PTR = RUNTIME_COMP_ID | 0x34,
RC_SBE_RT_INVALID_HUID = RUNTIME_COMP_ID | 0x35,
RC_SBE_RT_RECOVERY_ERR = RUNTIME_COMP_ID | 0x36,
+ RC_FW_REQUEST_HWSV_ERR = RUNTIME_COMP_ID | 0x37,
+ RC_FW_REQUEST_RESET_RELOAD_ERR = RUNTIME_COMP_ID | 0x38,
+ RC_FW_REQUEST_ERR = RUNTIME_COMP_ID | 0x39,
};
enum UserDetailsTypes
diff --git a/src/include/usr/util/runtime/rt_fwreq_helper.H b/src/include/usr/util/runtime/rt_fwreq_helper.H
new file mode 100644
index 000000000..ceac3a031
--- /dev/null
+++ b/src/include/usr/util/runtime/rt_fwreq_helper.H
@@ -0,0 +1,60 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/usr/util/runtime/rt_fwreq_helper.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2010,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 */
+#ifndef __RUNTIME_FWREQ_HELPER_H
+#define __RUNTIME_FWREQ_HELPER_H
+
+#include <errl/errlentry.H> // errlHndl_t
+
+/**
+ * @brief This is a wrapper function for the
+ * hostInterfaces::firmware_request method. This method
+ * will do the repetitious job of checking for errors,
+ * retry call if necessary and logging errors.
+ * @details
+ * req_len bytes are sent to runtime firmware, and resp_len
+ * bytes received in response.
+ *
+ * Both req and resp are allocated by the caller. If resp_len
+ * is not large enough to contain the full response, an error
+ * is returned.
+ *
+ * @param[in] i_reqLen length of request data
+ * @param[in] i_req request data
+ * @param[inout] o_respLen in: size of request data buffer
+ * out: length of response data
+ * @param[in] o_resp response data
+ * @return errlHndl_t NULL if successful, otherwise a pointer
+ * to the error log.
+ * @see src/include/runtime/interface.h for definition of call
+ */
+errlHndl_t
+firmware_request_helper(uint64_t i_reqLen,
+ void *i_req,
+ uint64_t* o_respLen,
+ void *o_resp);
+
+
+
+#endif // __RUNTIME_FWREQ_HELPER_H
diff --git a/src/include/usr/vpd/vpdreasoncodes.H b/src/include/usr/vpd/vpdreasoncodes.H
index 8007d0a7b..a9c62aca5 100644
--- a/src/include/usr/vpd/vpdreasoncodes.H
+++ b/src/include/usr/vpd/vpdreasoncodes.H
@@ -92,8 +92,7 @@ enum vpdModuleId
VPD_RT_WRITE_PNOR = 0x81,
VPD_BLD_RT_IMAGE = 0x82,
VPD_SEND_MBOX_WRITE_MESSAGE = 0x83,
- VPD_RT_FIRMWARE_REQUEST = 0x84,
-
+ VPD_MOD_XXX = 0x84,
};
/**
@@ -141,7 +140,7 @@ enum vpdReasonCode
VPD_CACHE_SIZE_EXCEEDED = VPD_COMP_ID | 0x35,
VPD_INVALID_LENGTH = VPD_COMP_ID | 0x36,
VPD_RT_NULL_FIRMWARE_REQUEST_PTR = VPD_COMP_ID | 0x37,
- VPD_RT_WRITE_MSG_ERR = VPD_COMP_ID | 0x38,
+ VPD_RC_XXX = VPD_COMP_ID | 0x38,
};
diff --git a/src/usr/errl/runtime/makefile b/src/usr/errl/runtime/makefile
index ec449ea5d..d4d097dfe 100644
--- a/src/usr/errl/runtime/makefile
+++ b/src/usr/errl/runtime/makefile
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2013,2015
+# Contributors Listed Below - COPYRIGHT 2013,2017
# [+] International Business Machines Corp.
#
#
diff --git a/src/usr/errl/runtime/rt_errlmanager.C b/src/usr/errl/runtime/rt_errlmanager.C
index cea88de64..4361a691d 100644
--- a/src/usr/errl/runtime/rt_errlmanager.C
+++ b/src/usr/errl/runtime/rt_errlmanager.C
@@ -31,7 +31,8 @@
#include <sys/task.h>
#include <stdlib.h>
#include <string.h>
-#include <runtime/interface.h>
+#include <runtime/interface.h> // g_hostInterfaces
+#include <util/runtime/rt_fwreq_helper.H> // firmware_request_helper
#include <targeting/common/targetservice.H>
#include <pnor/pnorif.H>
#include <hwas/common/deconfigGard.H>
@@ -89,7 +90,8 @@ ErrlManager::ErrlManager() :
}
else
{
- TRACFCOMP( g_trac_errl, "Error log being created before TARGETING is ready..." );
+ TRACFCOMP( g_trac_errl, "Error log being created before "
+ "TARGETING is ready..." );
}
if(sys)
{
@@ -116,7 +118,8 @@ ErrlManager::ErrlManager() :
spfn.baseServices))
{
iv_isSpBaseServices = false;
- TRACFCOMP( g_trac_errl, INFO_MRK"no baseServices, setting up to save to pnor" );
+ TRACFCOMP( g_trac_errl, INFO_MRK"no baseServices, setting "
+ "up to save to pnor" );
setupPnorInfo();
}
else
@@ -146,6 +149,10 @@ ErrlManager::~ErrlManager()
///////////////////////////////////////////////////////////////////////////////
void ErrlManager::sendMboxMsg ( errlHndl_t& io_err )
{
+ // Put the handle to the firmware_request request struct
+ // out here so it is easier to free later
+ hostInterfaces::hbrt_fw_msg *l_req_fw_msg = nullptr;
+
do
{
if (!iv_isSpBaseServices)
@@ -155,8 +162,8 @@ void ErrlManager::sendMboxMsg ( errlHndl_t& io_err )
bool l_savedToPnor = saveErrLogToPnor(io_err);
if (!l_savedToPnor)
{
- TRACFCOMP( g_trac_errl, ENTER_MRK"saveErrLogToPnor didn't save 0x%X",
- io_err->eid());
+ TRACFCOMP( g_trac_errl, ENTER_MRK"saveErrLogToPnor "
+ "didn't save 0x%X", io_err->eid());
}
}
@@ -186,8 +193,8 @@ void ErrlManager::sendMboxMsg ( errlHndl_t& io_err )
if(rc)
{
- TRACFCOMP(g_trac_errl, ERR_MRK
- "Failed sending error log to FSP via "
+ TRACFCOMP(g_trac_errl,
+ ERR_MRK"Failed sending error log to FSP via "
"sendErrorLog. rc: %d. plid: 0x%08x",
rc,
io_err->plid() );
@@ -197,43 +204,53 @@ void ErrlManager::sendMboxMsg ( errlHndl_t& io_err )
}
else if (g_hostInterfaces->firmware_request)
{
- // Get an accurate size of memory actually
- // needed to transport the data
- size_t l_req_fw_msg_size =
- hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
- sizeof(hostInterfaces::hbrt_fw_msg::error_log) +
- l_msgSize;
-
- // Create the firmware_request structure
- // to carry the error log data
+ // Get an accurate size of memory needed to transport
+ // the data for the firmware_request request struct
+ uint64_t l_req_fw_msg_size =
+ hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
+ sizeof(hostInterfaces::hbrt_fw_msg::error_log) +
+ l_msgSize -
+ sizeof(hostInterfaces::hbrt_fw_msg::error_log.i_data);
+
+ // Create the firmware_request request struct to send data
hostInterfaces::hbrt_fw_msg *l_req_fw_msg =
(hostInterfaces::hbrt_fw_msg *)malloc(l_req_fw_msg_size);
-
memset(l_req_fw_msg, 0, l_req_fw_msg_size);
- // Populate the firmware_request structure with given data
+ // Populate the firmware_request request struct with given data
l_req_fw_msg->io_type =
hostInterfaces::HBRT_FW_MSG_TYPE_ERROR_LOG;
l_req_fw_msg->error_log.i_plid = io_err->plid();
l_req_fw_msg->error_log.i_errlSize = l_msgSize;
io_err->flatten (&(l_req_fw_msg->error_log.i_data), l_msgSize);
+ // Trace out firmware request info
+ TRACFCOMP(g_trac_errl,
+ INFO_MRK"Error log firmware request info: "
+ "io_type:%d, plid: 0x%08x, errlSize:%d",
+ l_req_fw_msg->io_type,
+ l_req_fw_msg->error_log.i_plid,
+ l_req_fw_msg->error_log.i_errlSize);
+
+ TRACFBIN(g_trac_errl, "Error log firmware request data: ",
+ &(l_req_fw_msg->error_log.i_data),
+ l_req_fw_msg->error_log.i_errlSize);
+
+ // Create the firmware_request response struct to receive data
hostInterfaces::hbrt_fw_msg l_resp_fw_msg;
uint64_t l_resp_fw_msg_size = sizeof(l_resp_fw_msg);
- size_t rc = g_hostInterfaces->
- firmware_request(l_req_fw_msg_size, l_req_fw_msg,
- &l_resp_fw_msg_size, &l_resp_fw_msg);
+ memset(&l_resp_fw_msg, 0, l_resp_fw_msg_size);
- if(rc)
- {
- TRACFCOMP(g_trac_errl, ERR_MRK
- "Failed sending error log to FSP "
- "via firmware_request. rc: %d. plid: 0x%08x",
- rc,
- io_err->plid() );
- }
- free(l_req_fw_msg);
+ // Make the firmware_request call
+ errlHndl_t l_err = firmware_request_helper(l_req_fw_msg_size,
+ l_req_fw_msg,
+ &l_resp_fw_msg_size,
+ &l_resp_fw_msg);
+
+ // Should not get an error log, but if it happens,
+ // just delete it.
+ delete l_err, l_err = nullptr;
}
else
{
@@ -258,6 +275,10 @@ void ErrlManager::sendMboxMsg ( errlHndl_t& io_err )
} while (0);
+ // Release the firmware_request request struct
+ free(l_req_fw_msg);
+ l_req_fw_msg = nullptr;
+
TRACFCOMP( g_trac_errl, EXIT_MRK"sendToHypervisor()" );
return;
}
@@ -341,7 +362,8 @@ bool rt_processCallout(errlHndl_t &io_errl,
if (!l_err)
{
- errlHndl_t errl = HWAS::theDeconfigGard().platCreateGardRecord(pTarget,
+ errlHndl_t errl = HWAS::theDeconfigGard().platCreateGardRecord
+ (pTarget,
io_errl->eid(),
pCalloutUD->gardErrorType);
if (errl)
diff --git a/src/usr/isteps/pm/runtime/rt_pm.C b/src/usr/isteps/pm/runtime/rt_pm.C
index 33d2014d1..ecddab2a2 100644
--- a/src/usr/isteps/pm/runtime/rt_pm.C
+++ b/src/usr/isteps/pm/runtime/rt_pm.C
@@ -28,16 +28,19 @@
#include <errl/errlmanager.H>
#include <errno.h>
#include <sys/misc.h>
+
#include <trace/interface.H>
#include <util/utillidmgr.H>
#include <pm/pm_common.H>
#include <isteps/pm/pm_common_ext.H>
-#include <runtime/interface.h>
+#include <runtime/interface.h> // g_hostInterfaces
+#include <runtime/rt_fwreq_helper.H> // firmware_request_helper
#include <runtime/rt_targeting.H>
#include <runtime/runtime_reasoncodes.H>
+
#include <initservice/isteps_trace.H>
// targeting support
@@ -49,6 +52,7 @@
using namespace TARGETING;
using namespace RUNTIME;
+using namespace ERRORLOG;
namespace ISTEPS_TRACE
{
@@ -342,6 +346,7 @@ namespace RTPM
"/firmware_request interface not linked");
/*@
* @errortype
+ * @severity ERRL_SEV_INFORMATIONAL
* @moduleid MOD_PM_RT_HCODE_UPDATE
* @reasoncode RC_PM_RT_INTERFACE_ERR
* @userdata1[0:31] Target HUID
@@ -350,14 +355,13 @@ namespace RTPM
* @devdesc HCODE scom update runtime
* interface not linked.
*/
- l_err= new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_INFORMATIONAL,
- MOD_PM_RT_HCODE_UPDATE,
- RC_PM_RT_INTERFACE_ERR,
- TWO_UINT32_TO_UINT64(
- TARGETING::get_huid(i_target),
- i_section),
- i_rel_scom_addr);
+ l_err= new ErrlEntry(ERRL_SEV_INFORMATIONAL,
+ MOD_PM_RT_HCODE_UPDATE,
+ RC_PM_RT_INTERFACE_ERR,
+ TWO_UINT32_TO_UINT64(
+ TARGETING::get_huid(i_target),
+ i_section),
+ i_rel_scom_addr);
break;
}
@@ -411,32 +415,37 @@ namespace RTPM
TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
ERR_MRK"hcode_update: "
"HCODE scom update failed. "
- "rc 0x%X target 0x%llX chipId 0x%llX section 0x%X "
- "operation 0x%X scomAddr 0x%llX scomData 0x%llX",
+ "rc: 0x%X, target: 0x%llX, chipId: 0x%llX, "
+ "section: 0x%X, operation: 0x%X, scomAddr: 0x%llX, "
+ "scomData: 0x%llX",
rc, get_huid(i_target), l_chipId, i_section,
i_operation, l_scomAddr, i_scom_data);
- // convert rc to error log
/*@
* @errortype
+ * @severity ERRL_SEV_INFORMATIONAL
* @moduleid MOD_PM_RT_HCODE_UPDATE
* @reasoncode RC_PM_RT_HCODE_UPDATE_ERR
* @userdata1 Hypervisor return code
* @userdata2 SCOM address
* @devdesc HCODE SCOM update error
*/
- l_err=new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_INFORMATIONAL,
- MOD_PM_RT_HCODE_UPDATE,
- RC_PM_RT_HCODE_UPDATE_ERR,
- rc,
- l_scomAddr);
+ l_err = new ErrlEntry( ERRL_SEV_INFORMATIONAL,
+ MOD_PM_RT_HCODE_UPDATE,
+ RC_PM_RT_HCODE_UPDATE_ERR,
+ rc,
+ l_scomAddr);
break;
}
}
else if (g_hostInterfaces->firmware_request != nullptr)
{
+ // Create the firmware_request request struct to send data
hostInterfaces::hbrt_fw_msg l_req_fw_msg;
+ uint64_t l_req_fw_msg_size = sizeof(l_req_fw_msg);
+ memset(&l_req_fw_msg, 0, l_req_fw_msg_size);
+
+ // Populate the firmware_request request struct with given data
l_req_fw_msg.io_type =
hostInterfaces::HBRT_FW_MSG_TYPE_REQ_HCODE_UPDATE;
l_req_fw_msg.req_hcode_update.i_chipId = l_chipId;
@@ -445,82 +454,35 @@ namespace RTPM
l_req_fw_msg.req_hcode_update.i_scomAddr = l_scomAddr;
l_req_fw_msg.req_hcode_update.i_scomData = i_scom_data;
+ // Trace out firmware request info
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ INFO_MRK"HCODE update firmware request info: "
+ "io_type:%d, chipId:0x%llX, section:0x%X, "
+ "operation:0x%X, scomAddr:0x%llX, scomData:0x%llX",
+ l_req_fw_msg.io_type,
+ l_req_fw_msg.req_hcode_update.i_chipId,
+ l_req_fw_msg.req_hcode_update.i_section,
+ l_req_fw_msg.req_hcode_update.i_operation,
+ l_req_fw_msg.req_hcode_update.i_scomAddr,
+ l_req_fw_msg.req_hcode_update.i_scomData);
+
+ // Create the firmware_request response struct to receive data
hostInterfaces::hbrt_fw_msg l_resp_fw_msg;
uint64_t l_resp_fw_msg_size = sizeof(l_resp_fw_msg);
- rc = g_hostInterfaces->firmware_request(sizeof(l_req_fw_msg),
- &l_req_fw_msg, &l_resp_fw_msg_size, &l_resp_fw_msg);
- if(rc)
- {
- TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
- ERR_MRK"firmware request: "
- "firmware request for hcode scom update failed. "
- "rc 0x%X target 0x%llX chipId 0x%llX section 0x%X "
- "operation 0x%X scomAddr 0x%llX scomData 0x%llX",
- rc, get_huid(i_target), l_chipId, i_section,
- i_operation, l_scomAddr, i_scom_data);
+ memset(&l_resp_fw_msg, 0, l_resp_fw_msg_size);
- // convert rc to error log
- /*@
- * @errortype
- * @moduleid MOD_PM_RT_FIRMWARE_REQUEST
- * @reasoncode RC_PM_RT_HCODE_UPDATE_ERR
- * @userdata1[0:31] Firmware Request return code
- * @userdata1[32:63] SCOM address
- * @userdata2[0:31] Generic response code - if it exists
- * @userdata2[32:63] Firmware Response type
- * @devdesc Firmware Request for
- * HCODE SCOM update error
- */
- //
- // Pack the generic response code if the response
- // is of type "RESP_GENERIC"
- // else just send the response type alone
- uint64_t l_userData2 = 0;
- if (l_resp_fw_msg_size >=
- hostInterfaces::HBRT_FW_MSG_BASE_SIZE)
- {
- // just assign the response type for now
- l_userData2 = l_resp_fw_msg.io_type;
-
- // Pack the response code if it is available
- if ((l_resp_fw_msg_size >=
- (hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
- sizeof(l_resp_fw_msg.resp_generic))) &&
- hostInterfaces::HBRT_FW_MSG_TYPE_RESP_GENERIC ==
- l_resp_fw_msg.io_type)
- {
- l_userData2 = TWO_UINT32_TO_UINT64
- (l_resp_fw_msg.resp_generic.o_status,
- l_resp_fw_msg.io_type);
- }
- }
-
- l_err=new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_INFORMATIONAL,
- MOD_PM_RT_FIRMWARE_REQUEST,
- RC_PM_RT_HCODE_UPDATE_ERR,
- TWO_UINT32_TO_UINT64(rc, l_scomAddr),
- l_userData2);
-
- if (l_resp_fw_msg_size > 0)
- {
- l_err->addFFDC( ISTEP_COMP_ID,
- &l_resp_fw_msg,
- l_resp_fw_msg_size,
- 0, 0, false );
- }
-
- if (sizeof(l_req_fw_msg) > 0)
- {
- l_err->addFFDC( ISTEP_COMP_ID,
- &l_req_fw_msg,
- sizeof(l_req_fw_msg),
- 0, 0, false );
- }
+ // 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);
+ if (l_err)
+ {
+ // If error, break out of encompassing while loop
break;
}
- }
+ } // END else if (g_hostInterfaces->firmware_request != nullptr)
// Disable special wakeup
l_err = handleSpecialWakeup(i_target,false);
@@ -572,3 +534,4 @@ namespace RTPM
registerPm g_registerPm;
};
+
diff --git a/src/usr/isteps/pm/runtime/test/firmwareRequestTest.H b/src/usr/isteps/pm/runtime/test/firmwareRequestTest.H
index 01085dbae..2e2abe25e 100644
--- a/src/usr/isteps/pm/runtime/test/firmwareRequestTest.H
+++ b/src/usr/isteps/pm/runtime/test/firmwareRequestTest.H
@@ -187,7 +187,8 @@ class FirmwareRequestTest : public CxxTest::TestSuite
hostInterfaces::hbrt_fw_msg l_req_fw_msg;
l_req_fw_msg.generic_msg.initialize();
- if (l_req_fw_msg.generic_msg.magic != GFMM_MAGIC_NUMBER)
+ if (l_req_fw_msg.generic_msg.magic !=
+ GenericFspMboxMessage_t::MAGIC_NUMBER)
{
TS_FAIL("FirmwareRequestTest::testFirmwareRequestHbrtToFsp: "
"magic was not properly initialized");
@@ -200,7 +201,8 @@ class FirmwareRequestTest : public CxxTest::TestSuite
"dataSize was not properly initialized");
}
- if (l_req_fw_msg.generic_msg.structVer != GFMM_VERSION)
+ if (l_req_fw_msg.generic_msg.structVer !=
+ GenericFspMboxMessage_t::STRUCT_VERSION_LATEST)
{
TS_FAIL("FirmwareRequestTest::testFirmwareRequestHbrtToFsp: "
"structVer was not properly initialized");
@@ -220,8 +222,9 @@ class FirmwareRequestTest : public CxxTest::TestSuite
l_req_fw_msg.generic_msg.seqnum = 0x300;
l_req_fw_msg.generic_msg.msgq = 0x400;
l_req_fw_msg.generic_msg.msgType = 0x500;
- l_req_fw_msg.generic_msg.__req = GFMM_REQUEST;
- l_req_fw_msg.generic_msg.__onlyError = GFMM_ERROR_ONLY;
+ l_req_fw_msg.generic_msg.__req = GenericFspMboxMessage_t::REQUEST;
+ l_req_fw_msg.generic_msg.__onlyError =
+ GenericFspMboxMessage_t::ERROR_ONLY;
uint32_t l_plid = 0x600;
uint32_t l_huid = 0x700;
l_req_fw_msg.generic_msg.data =
diff --git a/src/usr/isteps/tod/runtime/makefile b/src/usr/isteps/tod/runtime/makefile
index 5c65fd3ff..2d7946358 100644
--- a/src/usr/isteps/tod/runtime/makefile
+++ b/src/usr/isteps/tod/runtime/makefile
@@ -30,7 +30,9 @@ ROOTPATH = ../../../../..
MODULE = tod_rt
EXTRAINCDIR += ${ROOTPATH}/src/usr/isteps/tod
-EXTRAINCDIR += ${ROOTPATH}/src/include/usr/isteps/
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/isteps
+EXTRAINCDIR += ${ROOTPATH}/src/usr/errl
+#EXTRAINCDIR += ${ROOTPATH}/src/include/usr/util
OBJS += rt_todintf.o
diff --git a/src/usr/isteps/tod/runtime/rt_todintf.C b/src/usr/isteps/tod/runtime/rt_todintf.C
index c79419604..180049d18 100644
--- a/src/usr/isteps/tod/runtime/rt_todintf.C
+++ b/src/usr/isteps/tod/runtime/rt_todintf.C
@@ -28,8 +28,13 @@
#include <TodUtils.H> // GETHUID
#include <TodSvcUtil.H> // getMaxProcsOnSystem
-#include <runtime/interface.h> // g_hostInterfaces
-#include <tod_init_reasoncodes.H> // TOD_RT_TOPOLOGY_RESET_BACKUP, etc
+#include <runtime/interface.h> // g_hostInterfaces
+#include <util/runtime/rt_fwreq_helper.H> // firmware_request_helper
+#include <tod_init_reasoncodes.H> // TOD_RT_TOPOLOGY_RESET_BACKUP, etc
+#include <errlmanager_common.C> // errlCommit
+
+
+using namespace ERRORLOG;
namespace TOD
{
@@ -51,38 +56,42 @@ errlHndl_t resetBackupTopology(
TOD_ENTER("resetBackupTopology");
errlHndl_t l_err = nullptr;
- // Put the handle to the firmware request out here
- // so it is easier to free later
+ // Put the handle to the firmware_request request struct
+ // out here so it is easier to free later
hostInterfaces::hbrt_fw_msg *l_req_fw_msg = nullptr;
+ hostInterfaces::hbrt_fw_msg *l_resp_fw_msg = nullptr;
do
{
if ((nullptr == g_hostInterfaces) ||
(nullptr == g_hostInterfaces->firmware_request))
{
+ TOD_ERR("resetBackupTopology: "
+ "Hypervisor firmware_request interface not linked");
+
/*@
* @errortype
- * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
- * @moduleid TOD::TOD_RT_TOPOLOGY_RESET_BACKUP
- * @reasoncode TOD::TOD_RT_NULL_FIRMWARE_REQUEST_PTR
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid TOD_RT_TOPOLOGY_RESET_BACKUP
+ * @reasoncode TOD_RT_NULL_FIRMWARE_REQUEST_PTR
+ * @userdata1 None
+ * @userdata2 None
* @devdesc Host interfaces are not initialized
- * @custdesc An internal error occurred. This will force the
- * Time of Day function to run with complete
- * redundancy.
+ * @custdesc An internal error occurred. This will
+ * force the Time of Day function to run
+ * with complete redundancy.
*/
- l_err = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- TOD::TOD_RT_TOPOLOGY_RESET_BACKUP,
- TOD::TOD_RT_NULL_FIRMWARE_REQUEST_PTR,
+ l_err = new ErrlEntry( ERRL_SEV_UNRECOVERABLE,
+ TOD_RT_TOPOLOGY_RESET_BACKUP,
+ TOD_RT_NULL_FIRMWARE_REQUEST_PTR,
0, 0, true);
break;
}
- // First, I'll present the format of the data
- // to help with the understanding of the code that follows
// The format of the data to be sent, according to the document
// "Handle PRD Request for resetting backup TOD topology" is as follows
+ // All data members below are 4 bytes long (32 bits)
// Ordinal ID - 0xFFFFFFFF means no OSC to be avoided
// HUID of the node - This field should be considered only if Ordinal
// ID is NOT set to 0xFFFFFFFF otherwise it is set
@@ -90,82 +99,89 @@ errlHndl_t resetBackupTopology(
// HUID of the first processor
// HUID of the second processor, etc
+ // Check if we get conflicting data, if so send a Trace out
+ if ((0xFFFFFFFF == i_oscPos) && (nullptr != i_procOscTgt))
+ {
+ TOD_ERR("Conflicting input data, input oscillator position "
+ "(i_oscPos) has value 0xFFFFFFFF, meaning no oscillator "
+ "to be avoided but input oscillator target (i_procOscTgt) "
+ "has a valid value" );
+ }
+ else if ((0xFFFFFFFF != i_oscPos) && (nullptr == i_procOscTgt))
+ {
+ TOD_ERR("Conflicting input data, input oscillator position "
+ "(i_oscPos) has value 0x%X, meaning avoid oscillator "
+ "but input oscillator target (i_procOscTgt) "
+ "has a NULL value", i_oscPos);
+ }
// Flag to determine if the OSC data will be added to the data
bool l_addOscData = (0xFFFFFFFF != i_oscPos) &&
(nullptr != i_procOscTgt);
- // Calculate the size of the data that is being added to the
- // generic struct
- size_t l_data_size = 0;
+ // Default the request data size to the size of the
+ // GenericFspMboxMessage_t minus the size of the
+ // GenericFspMboxMessage_t's data. The size of the
+ // GenericFspMboxMessage_t's data will be added later
+ uint32_t l_req_data_size = sizeof(GenericFspMboxMessage_t) -
+ sizeof(GenericFspMboxMessage_t::data);
- // Add to the size iff there is data needing to be passed
+ // Add to the request data size iff there is data needing to be passed
if (i_badChipList.size() > 0)
{
// if the bad chip list has any items then increase size to
// accommodate for an ordinal ID and a HUID, regardless if
// they have relevant data or not, because they are expected
// before the HUID list.
- l_data_size += (MSG_OSC_SIZE_OF_DETAILS * sizeof(uint32_t)) +
- (i_badChipList.size() * sizeof(uint32_t));
+ l_req_data_size += (MSG_OSC_SIZE_OF_DETAILS * sizeof(uint32_t)) +
+ (i_badChipList.size() * sizeof(uint32_t));
}
else if (l_addOscData)
{
// if there is a valid OSC then accommodate for an ordinal ID
// and HUID of node, but don't need space for HUID list because,
// if we are here, the list is empty
- l_data_size += (MSG_OSC_SIZE_OF_DETAILS * sizeof(uint32_t));
+ l_req_data_size += (MSG_OSC_SIZE_OF_DETAILS * sizeof(uint32_t));
}
- // Update the data size with the size of the generic msg struct
- if (l_data_size < sizeof(hostInterfaces::hbrt_fw_msg::generic_msg.data))
- {
- // If the current size of the data is less than the size of the
- // data within the generic message (GenericFspMboxMessage_t.data),
- // then default the data size to just the generic message because
- // the size of the data to be passed in
- // GenericFspMboxMessage_t.dataSize has be at the minimum - the
- // size of the generic message (sizeof(GenericFspMboxMessage_t)).
- l_data_size = sizeof(hostInterfaces::hbrt_fw_msg::generic_msg);
- }
- else
+ // The request data size must be at a minimum the size of the
+ // FSP generic message (sizeof(GenericFspMboxMessage_t))
+ if (l_req_data_size < sizeof(GenericFspMboxMessage_t))
{
- // If the current size of the data is greater than the size of the
- // data within the generic message (GenericFspMboxMessage_t.data),
- // then add the size of the generic message minus the size of
- // generic message's data.
- l_data_size += sizeof(hostInterfaces::hbrt_fw_msg::generic_msg) -
- sizeof(hostInterfaces::hbrt_fw_msg::generic_msg.data);
+ l_req_data_size = sizeof(GenericFspMboxMessage_t);
}
- // At last. Calculate the TOTAL size of hostInterfaces::hbrt_fw_msg
- // which means only adding hostInterfaces::HBRT_FW_MSG_BASE_SIZE to
- // the previous calculated data size
- size_t l_req_fw_msg_size = hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
- l_data_size;
+ // Calculate the TOTAL size of hostInterfaces::hbrt_fw_msg which
+ // means only adding hostInterfaces::HBRT_FW_MSG_BASE_SIZE to
+ // the previous calculated request data size
+ uint64_t l_req_fw_msg_size = hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
+ l_req_data_size;
- // Create the firmware request structure to carry the TOD data
- l_req_fw_msg =(hostInterfaces::hbrt_fw_msg *)malloc(l_req_fw_msg_size);
+ // Create the firmware_request request struct to send data
+ l_req_fw_msg =
+ (hostInterfaces::hbrt_fw_msg *)malloc(l_req_fw_msg_size);
- // 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.dataSize = l_data_size;
+
+ // 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.dataSize = l_req_data_size;
l_req_fw_msg->generic_msg.msgq = MBOX::FSP_TOD_MSGQ;
l_req_fw_msg->generic_msg.msgType = (false == i_informPhyp ?
- GFMM_MSG_TOD_BACKUP_RESET:
- GFMM_MSG_TOD_BACKUP_RESET_INFORM_PHYP);
- l_req_fw_msg->generic_msg.__req = GFMM_REQUEST;
- l_req_fw_msg->generic_msg.__onlyError = GFMM_NOT_ERROR_ONLY;
+ GenericFspMboxMessage_t::MSG_TOD_BACKUP_RESET:
+ GenericFspMboxMessage_t::MSG_TOD_BACKUP_RESET_INFORM_PHYP);
+ l_req_fw_msg->generic_msg.__req = GenericFspMboxMessage_t::REQUEST;
// A convenient way to populate the data
- uint32_t* l_dataPtr = (uint32_t*)&(l_req_fw_msg->generic_msg.data);
+ uint32_t* l_dataPtr =
+ reinterpret_cast<uint32_t*>(&(l_req_fw_msg->generic_msg.data));
if (i_badChipList.size() > 0)
{
// set the ordinal ID
l_dataPtr[MSG_OSC_ORDINAL_ID_LOC] = i_oscPos;
- // attach the HUIDs from bad chip list to end of structure
+ // attach the HUIDs from bad chip list to end of struct
size_t i = MSG_OSC_HUIDS_LOC;
for (auto l_target : i_badChipList)
{
@@ -194,120 +210,59 @@ errlHndl_t resetBackupTopology(
{
/*@
* @errortype
- * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
- * @moduleid TOD::TOD_RT_TOPOLOGY_RESET_BACKUP
- * @reasoncode TOD::TOD_INVALID_TARGET
- * @devdesc No parent for processor osc target
- * @custdesc An internal error occurred. This will force
- * the Time of Day function to run with complete
- * redundancy.
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid TOD_RT_TOPOLOGY_RESET_BACKUP
+ * @reasoncode TOD_INVALID_TARGET
+ * @userdata1 The number of parents found osc target
+ * @userdata2 None
+ * @devdesc No/Multiple parent(s) found for
+ * processor osc target
+ * @custdesc An internal error occurred. This will
+ * force the Time of Day function to run
+ * with complete redundancy.
*/
- l_err = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- TOD::TOD_RT_TOPOLOGY_RESET_BACKUP,
- TOD::TOD_INVALID_TARGET,
- 0, 0, true);
+ l_err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE,
+ TOD_RT_TOPOLOGY_RESET_BACKUP,
+ TOD_INVALID_TARGET,
+ l_list.size(), 0, true);
break;
}
}
- // No data is returning from the call, just capture any errors
- hostInterfaces::hbrt_fw_msg l_resp_fw_msg;
- size_t l_resp_fw_msg_size = sizeof(l_resp_fw_msg);
-
- // Clear the response structure
- memset(&l_resp_fw_msg, 0, l_resp_fw_msg_size);
-
- // Send the data via a firmware request
- size_t rc = g_hostInterfaces->firmware_request(
- l_req_fw_msg_size, l_req_fw_msg,
- &l_resp_fw_msg_size, &l_resp_fw_msg);
+ // Create the firmware_request response struct to receive data
+ // NOTE: For messages to the FSP the response size must match
+ // the request size
+ uint64_t l_resp_fw_msg_size = l_req_fw_msg_size;
+ l_resp_fw_msg =
+ (hostInterfaces::hbrt_fw_msg *)malloc(l_resp_fw_msg_size);
+ memset(l_resp_fw_msg, 0, l_resp_fw_msg_size);
- // Error log id
- uint32_t l_errPlid(0);
+ // Trace out the request structure
+ TRACFBIN(ISTEPS_TRACE::g_trac_isteps_trace,
+ INFO_MRK"TOD::Sending firmware_request",
+ l_req_fw_msg,
+ l_req_fw_msg_size);
- // Create a useful structure to get to the PLID
- // The PLID is expected to be in the first 4 bytes of the data
- // if it exists
- struct hbrtFspRespData_t
- {
- uint32_t plid;
- uint32_t otherData;
- } PACKED ;
-
- hbrtFspRespData_t *l_hbrtFspRespData =
- (hbrtFspRespData_t*)&(l_resp_fw_msg.generic_msg.data);
-
- // 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_hbrtFspRespData->plid) )
- {
- l_errPlid = l_hbrtFspRespData->plid;
- }
+ // 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);
- // Gather up the error data and create an error log out of it
- if (rc || l_errPlid)
+ if (l_err)
{
- /*@
- * @errortype
- * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
- * @moduleid TOD::TOD_RT_TOPOLOGY_RESET_BACKUP
- * @reasoncode TOD::TOD_RT_TOPOLOGY_RESET_BACKUP_ERR
- * @userdata1[0..31] Hypervisor return code
- * @userdata1[32:63] HWSV error log id (if any)
- * @userdata2[0:31] MBOX message type
- * @userdata2[32:63] TOD message type
- * @devdesc TOD reset backup topology failed
- * @custdesc An internal error occurred. This will force
- * the Time of Day function to run with complete
- * redundancy.
- */
- l_err = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- TOD::TOD_RT_TOPOLOGY_RESET_BACKUP,
- TOD::TOD_RT_TOPOLOGY_RESET_BACKUP_ERR,
- TWO_UINT32_TO_UINT64(rc, l_errPlid),
- TWO_UINT32_TO_UINT64(
- l_req_fw_msg->generic_msg.msgq,
- l_req_fw_msg->generic_msg.msgType),
- true);
-
- l_err->addFFDC( ISTEP_COMP_ID,
- &l_resp_fw_msg,
- l_resp_fw_msg_size,
- 0, 0, false );
-
- if (sizeof(l_req_fw_msg) > 0)
- {
- l_err->addFFDC( ISTEP_COMP_ID,
- l_req_fw_msg,
- sizeof(l_req_fw_msg),
- 0, 0, false );
- }
-
- l_err->collectTrace( "TOD", 256);
-
- if (l_errPlid)
- {
- l_err->plid(l_errPlid);
- }
-
break;
}
- }
- while (0);
+ } while (0);
- // The firmware request message is no longer needed - free the data
+ // Release the firmware messages
free(l_req_fw_msg);
+ free(l_resp_fw_msg);
+ l_req_fw_msg = l_resp_fw_msg = nullptr;
TOD_EXIT("resetBackupTopology");
return l_err;
-
} // end resetBackupTopology
@@ -319,170 +274,100 @@ errlHndl_t readTodProcDataFromFile(TodChipDataContainer& o_todChipData)
TOD_ENTER("readTodProcDataFromFile");
errlHndl_t l_err = nullptr;
- // Put the handle to the firmware response out here
+ // Put the handle to the firmware messages out here
// so it is easier to free later
+ hostInterfaces::hbrt_fw_msg *l_req_fw_msg = nullptr;
hostInterfaces::hbrt_fw_msg *l_resp_fw_msg = nullptr;
+ // clear the out data, regardless of the code to follow
+ o_todChipData.clear();
+
do
{
- // clear the out data, regardless of the code to follow
- o_todChipData.clear();
-
if ((nullptr == g_hostInterfaces) ||
(nullptr == g_hostInterfaces->firmware_request))
{
+ TOD_ERR("readTodProcDataFromFile: "
+ "Hypervisor firmware_request interface not linked");
+
/*@
* @errortype
- * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
- * @moduleid TOD::TOD_RT_TOPOLOGY_DATA
- * @reasoncode TOD::TOD_RT_NULL_FIRMWARE_REQUEST_PTR
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid TOD_RT_TOPOLOGY_DATA
+ * @reasoncode TOD_RT_NULL_FIRMWARE_REQUEST_PTR
* @devdesc Host interfaces are not initialized
- * @custdesc An internal error occurred. This will force the
- * Time of Day function to run with complete
- * redundancy.
+ * @custdesc An internal error occurred. This will
+ * force the Time of Day function to run
+ * with complete redundancy.
*/
- l_err = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- TOD::TOD_RT_TOPOLOGY_DATA,
- TOD::TOD_RT_NULL_FIRMWARE_REQUEST_PTR,
+ l_err = new ErrlEntry( ERRL_SEV_UNRECOVERABLE,
+ TOD_RT_TOPOLOGY_DATA,
+ TOD_RT_NULL_FIRMWARE_REQUEST_PTR,
0, 0, true);
break;
}
- // Create the firmware request structure. No data is being
- // passed via this structure so this step may be moot.
- // Maybe just passing size of 0 and a null pointer would be better?
- hostInterfaces::hbrt_fw_msg l_req_fw_msg;
- size_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;
- l_req_fw_msg.generic_msg.initialize();
- l_req_fw_msg.generic_msg.msgq = MBOX::FSP_TOD_MSGQ;
- l_req_fw_msg.generic_msg.msgType = GFMM_MSG_TOD_TOPOLOGY_DATA;
- l_req_fw_msg.generic_msg.__req = GFMM_REQUEST;
- l_req_fw_msg.generic_msg.__onlyError = GFMM_NOT_ERROR_ONLY;
-
- // Calculate the size of the response - the number
- // of TodChipData items that will be returned.
+ // Default the response data size to the size of the
+ // GenericFspMboxMessage_t minus the size of the
+ // GenericFspMboxMessage_t's data. The size of the
+ // GenericFspMboxMessage_t's data will be added later
+ uint32_t l_resp_data_size = sizeof(GenericFspMboxMessage_t) -
+ sizeof(GenericFspMboxMessage_t::data);
+
+ // Get the number of TodChipData items that will be returned.
uint32_t l_nTodChips = TodSvcUtil::getMaxProcsOnSystem();
- // Calculate the size of the data that is being added to the
- // generic struct
- size_t l_data_size = (l_nTodChips * sizeof(TodChipData));
+ // Add to the response data size iff there is data needing to be passed
+ l_resp_data_size += (l_nTodChips * sizeof(TodChipData));
- // Update the data size with the size of the generic msg struct
- if (l_data_size < sizeof(hostInterfaces::hbrt_fw_msg::generic_msg.data))
- {
- // If the current size of the data is less than the size of the
- // data within the generic message (GenericFspMboxMessage_t.data),
- // then default the data size to just the generic message because
- // the size of the data to be passed in
- // GenericFspMboxMessage_t.dataSize has be at the minimum - the
- // size of the generic message (sizeof(GenericFspMboxMessage_t)).
- l_data_size = sizeof(hostInterfaces::hbrt_fw_msg::generic_msg);
- }
- else
+ // The response data size must be at a minimum the size of the
+ // FSP generic message (sizeof(GenericFspMboxMessage_t))
+ if (l_resp_data_size < sizeof(GenericFspMboxMessage_t))
{
- // If the current size of the data is greater than the size of the
- // data within the generic message (GenericFspMboxMessage_t.data),
- // then add the size of the generic message minus the size of
- // generic message's data.
- l_data_size += sizeof(hostInterfaces::hbrt_fw_msg::generic_msg) -
- sizeof(hostInterfaces::hbrt_fw_msg::generic_msg.data);
+ l_resp_data_size = sizeof(GenericFspMboxMessage_t);
}
- // At last. Calculate the TOTAL size of hostInterfaces::hbrt_fw_msg
- // which means only adding hostInterfaces::HBRT_FW_MSG_BASE_SIZE to
- // the previous calculated data size
- size_t l_resp_fw_msg_size = hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
- l_data_size;
+ // Calculate the TOTAL size of hostInterfaces::hbrt_fw_msg which
+ // means only adding hostInterfaces::HBRT_FW_MSG_BASE_SIZE to
+ // the previous calculated response data size
+ uint64_t l_resp_fw_msg_size = hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
+ l_resp_data_size;
- // Create the firmware response structure to return the data
+ // Create the firmware_request response struct to receive data
l_resp_fw_msg =
(hostInterfaces::hbrt_fw_msg *)malloc(l_resp_fw_msg_size);
-
- // Clear the response structure
memset(l_resp_fw_msg, 0, l_resp_fw_msg_size);
- // Send the data via a firmware request
- size_t rc = g_hostInterfaces->firmware_request(
- l_req_fw_msg_size, &l_req_fw_msg,
- &l_resp_fw_msg_size, l_resp_fw_msg);
+ // Create the firmware_request request struct to send data
+ uint64_t l_req_fw_msg_size = l_resp_fw_msg_size;
+ l_req_fw_msg =
+ (hostInterfaces::hbrt_fw_msg *)malloc(l_req_fw_msg_size);
- // Error log id
- uint32_t l_errPlid(0);
-
- // Create a useful structure to get to the PLID
- // The PLID is expected to be in the first 4 bytes of the data
- struct hbrtFspRespData_t
- {
- uint32_t plid;
- uint32_t otherData;
- } PACKED ;
-
- hbrtFspRespData_t *l_hbrtFspRespData =
- (hbrtFspRespData_t*)&(l_resp_fw_msg->generic_msg.data);
-
- // 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_hbrtFspRespData->plid) )
- {
- l_errPlid = l_hbrtFspRespData->plid;
- }
+ // Initialize the firmware_request request struct
+ l_req_fw_msg->generic_msg.initialize();
- // Gather up the error data and create an error log out of it
- if (rc || l_errPlid)
+ // 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 = MBOX::FSP_TOD_MSGQ;
+ l_req_fw_msg->generic_msg.msgType =
+ GenericFspMboxMessage_t::MSG_TOD_TOPOLOGY_DATA;
+ l_req_fw_msg->generic_msg.__req = GenericFspMboxMessage_t::REQUEST;
+
+ // Trace out the request structure
+ TRACFBIN(ISTEPS_TRACE::g_trac_isteps_trace,
+ INFO_MRK"TOD::Sending firmware_request",
+ l_req_fw_msg,
+ l_req_fw_msg_size);
+
+ // 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);
+
+ if (l_err)
{
- /*@
- * @errortype
- * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
- * @moduleid TOD::TOD_RT_TOPOLOGY_DATA
- * @reasoncode TOD::TOD_RT_TOPOLOGY_DATA_ERR
- * @userdata1[0..31] Hypervisor return code
- * @userdata1[32:63] HWSV error log id (if any)
- * @userdata2[0:31] MBOX message type
- * @userdata2[32:63] TOD message type
- * @devdesc TOD read proc data failed
- * @custdesc An internal error occurred. This will force
- * the Time of Day function to run with complete
- * redundancy.
- */
- l_err = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- TOD::TOD_RT_TOPOLOGY_DATA,
- TOD::TOD_RT_TOPOLOGY_DATA_ERR,
- TWO_UINT32_TO_UINT64(rc, l_errPlid),
- TWO_UINT32_TO_UINT64(
- l_req_fw_msg.generic_msg.msgq,
- l_req_fw_msg.generic_msg.msgType),
- true);
-
- if (l_resp_fw_msg_size > 0)
- {
- l_err->addFFDC( ISTEP_COMP_ID,
- l_resp_fw_msg,
- l_resp_fw_msg_size,
- 0, 0, false );
- }
-
- l_err->addFFDC( ISTEP_COMP_ID,
- &l_req_fw_msg,
- sizeof(l_req_fw_msg),
- 0, 0, false );
-
- l_err->collectTrace( "TOD", 256);
-
- if (l_errPlid)
- {
- l_err->plid(l_errPlid);
- }
-
break;
}
@@ -500,15 +385,17 @@ errlHndl_t readTodProcDataFromFile(TodChipDataContainer& o_todChipData)
}
while (0);
- // Free the memory associated with the response
+ // Release the firmware messages
+ free(l_req_fw_msg);
free(l_resp_fw_msg);
+ l_req_fw_msg = l_resp_fw_msg = nullptr;
TOD_EXIT("readTodProcDataFromFile");
return l_err;
} // end readTodProcDataFromFile
// This code was ported over from the FIPS code -
-// /esw/fips910/Builds/b1005a_1742.910/
+// fips910/Builds/b1005a_1742.910/
// src/hwsv/server/services/todservice/hwsvTodSvc.C
// It was decided that a port of the code is not needed but to hold onto
// the code since the majority of it has been ported.
diff --git a/src/usr/testcore/rtloader/loader.H b/src/usr/testcore/rtloader/loader.H
index 973afd158..d80b93cb6 100644
--- a/src/usr/testcore/rtloader/loader.H
+++ b/src/usr/testcore/rtloader/loader.H
@@ -833,6 +833,12 @@ class RuntimeLoaderTest : public CxxTest::TestSuite
break;
}
+ if (i_reqLen != *o_respLen)
+ {
+ retVal = -EINVAL;
+ break;
+ }
+
uint32_t* l_data =
(uint32_t*) &(l_req_fw_msg->generic_msg.data);
TRACFCOMP(g_trac_hbrt,
@@ -868,9 +874,10 @@ class RuntimeLoaderTest : public CxxTest::TestSuite
l_resp_fw_msg->generic_msg.seqnum = 0x30;
l_resp_fw_msg->generic_msg.msgq = 0x40;
l_resp_fw_msg->generic_msg.msgType = 0x50;
- l_resp_fw_msg->generic_msg.__req = GFMM_RESPONSE;
+ l_resp_fw_msg->generic_msg.__req =
+ GenericFspMboxMessage_t::RESPONSE;
l_resp_fw_msg->generic_msg.__onlyError =
- GFMM_NOT_ERROR_ONLY;
+ GenericFspMboxMessage_t::NOT_ERROR_ONLY;
l_resp_data.plid = 0x60;
l_resp_data.huid = 0x70;
memcpy(&(l_resp_fw_msg->generic_msg.data),
diff --git a/src/usr/util/runtime/makefile b/src/usr/util/runtime/makefile
index ff5509e5e..b926c9209 100644
--- a/src/usr/util/runtime/makefile
+++ b/src/usr/util/runtime/makefile
@@ -53,6 +53,7 @@ OBJS += utilrsvdmem.o
OBJS += utilxipimage.o
OBJS += utilcommonattr.o
OBJS += rt_fwnotify.o
+OBJS += rt_fwreq_helper.o
SUBDIRS += test.d
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
diff --git a/src/usr/util/runtime/rt_fwreq_helper.C b/src/usr/util/runtime/rt_fwreq_helper.C
new file mode 100644
index 000000000..16c9de777
--- /dev/null
+++ b/src/usr/util/runtime/rt_fwreq_helper.C
@@ -0,0 +1,455 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/util/runtime/rt_fwreq_helper.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2013,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 <util/runtime/rt_fwreq_helper.H>
+#include <runtime/interface.h> // hostInterfaces
+#include <runtime/runtime_reasoncodes.H> // MOD_RT_FIRMWARE_REQUEST, etc
+#include <errl/errlmanager.H> // errlCommit
+
+using namespace ERRORLOG;
+using namespace RUNTIME;
+using namespace TRACE;
+
+// Trace definition
+trace_desc_t *g_trac_runtime = nullptr;
+TRAC_INIT(&g_trac_runtime, RUNTIME_COMP_NAME, KILOBYTE);
+
+
+/*****************************************************************************/
+// firmware_request_helper
+/*****************************************************************************/
+errlHndl_t firmware_request_helper(uint64_t i_reqLen, void *i_req,
+ uint64_t* o_respLen, void *o_resp)
+{
+ errlHndl_t l_err = nullptr;
+
+ // Cast incoming parameters to useful structs
+ hostInterfaces::hbrt_fw_msg *l_req_fw_msg =
+ reinterpret_cast<hostInterfaces::hbrt_fw_msg *>(i_req);
+ hostInterfaces::hbrt_fw_msg *l_resp_fw_msg =
+ reinterpret_cast<hostInterfaces::hbrt_fw_msg *>(o_resp);
+
+ // Capture the Reset/Reload error log if it happens
+ bool l_isResetReloadErr = false;
+
+ // Retry the firmware_request call if the call is made while the
+ // FSP is doing a reset/reload.
+ // If there is a reset/reload error create an error log and try again.
+ // If subsequent calls cause an error, commit the reset/reload error,
+ // and return the latest error back to the user.
+ // If there is an initial error that IS NOT a reset/reload error
+ // then break out of the retry loop and return error to user.
+ // If no error (a successful call) then delete any previous error
+ // (don't want to confuse caller) and break out of retry loop
+ for (int i = 0; i <= HBRT_FW_REQUEST_RETRIES; ++i)
+ {
+ // Make the firmware_request call
+ int rc = g_hostInterfaces->firmware_request(i_reqLen, i_req,
+ o_respLen, o_resp);
+
+ // Not all request messages that fail require an error log, most do
+ bool l_createErrorLog = true;
+
+ // The error log user data 1 and user data 2 will change
+ // based on response message type
+ uint64_t l_userData1(0), l_userData2(0);
+
+ // Error with FSP resetting and/or reloading? If so, then retry
+ if (HBRT_RC_FSPDEAD == rc)
+ {
+ // This is a reset/reload err
+ l_isResetReloadErr = true;
+
+ // Commit any previous errors
+ if (l_err)
+ {
+ // Commit any previous error log
+ errlCommit(l_err, RUNTIME_COMP_ID);
+ }
+
+ // Print trace info based on request message and populate error
+ // log user data 1 and user data 2 based on request message
+ switch (l_req_fw_msg->io_type)
+ {
+ case hostInterfaces::HBRT_FW_MSG_TYPE_REQ_HCODE_UPDATE:
+ {
+ TRACFCOMP(g_trac_runtime,
+ ERR_MRK"FSP is doing a reset/reload, "
+ "HCODE update failed. "
+ "retry:%d/%d, rc:%d, io_type:%d, chipId:0x%llX, "
+ "section:0x%X, operation:0x%X, scomAddr:0x%llX, "
+ "scomData:0x%llX",
+ i,
+ HBRT_FW_REQUEST_RETRIES,
+ rc,
+ l_req_fw_msg->io_type,
+ l_req_fw_msg->req_hcode_update.i_chipId,
+ l_req_fw_msg->req_hcode_update.i_section,
+ l_req_fw_msg->req_hcode_update.i_operation,
+ l_req_fw_msg->req_hcode_update.i_scomAddr,
+ l_req_fw_msg->req_hcode_update.i_scomData);
+
+ // Pack user data 1 with Hypervisor return code and
+ // firmware request message type
+ l_userData1 = TWO_UINT32_TO_UINT64(rc,
+ l_req_fw_msg->io_type);
+
+ // Pack user data 2 with HCODE scom address and
+ // HCODE scom data
+ l_userData2 = TWO_UINT32_TO_UINT64(
+ l_req_fw_msg->req_hcode_update.i_scomAddr,
+ l_req_fw_msg->req_hcode_update.i_scomData);
+ }
+ break;//END case hostInterfaces::HBRT_FW_MSG_TYPE_REQ_HCODE_UPDATE:
+
+ case hostInterfaces::HBRT_FW_MSG_TYPE_ERROR_LOG:
+ {
+ TRACFCOMP(g_trac_runtime,
+ ERR_MRK"FSP is doing a reset/reload, "
+ "sending error log to FSP failed. "
+ "retry:%d/%d, rc:%d, plid:0x%08x",
+ i,
+ HBRT_FW_REQUEST_RETRIES,
+ rc,
+ l_req_fw_msg->error_log.i_plid);
+
+ // Don't create an error log for this request type
+ l_createErrorLog = false;
+ }
+ break; // END case hostInterfaces::HBRT_FW_MSG_TYPE_ERROR_LOG:
+
+ case hostInterfaces::HBRT_FW_MSG_HBRT_FSP_REQ:
+ {
+ TRACFCOMP(g_trac_runtime,
+ "FSP is doing a reset/reload, "
+ "doing a VPD write failed. "
+ "retry:%d/%d, rc:%d, io_type:%d, dataSize:%d, "
+ "seqnum:0x%X, msgq:0x%X, msgType:0x%X, __req:%d, "
+ "__onlyError:%d",
+ i,
+ HBRT_FW_REQUEST_RETRIES,
+ rc,
+ l_req_fw_msg->io_type,
+ l_req_fw_msg->generic_msg.dataSize,
+ l_req_fw_msg->generic_msg.seqnum,
+ l_req_fw_msg->generic_msg.msgq,
+ l_req_fw_msg->generic_msg.msgType,
+ l_req_fw_msg->generic_msg.__req,
+ l_req_fw_msg->generic_msg.__onlyError);
+
+ // Pack user data 1 with Hypervisor return code and
+ // firmware request message sequence number
+ l_userData1 = TWO_UINT32_TO_UINT64(
+ rc,
+ l_req_fw_msg->generic_msg.seqnum);
+
+ // Pack user data 2 with message queue and message type
+ l_userData2 = TWO_UINT32_TO_UINT64(
+ l_req_fw_msg->generic_msg.msgq,
+ l_req_fw_msg->generic_msg.msgType);
+ }
+ break; // END case hostInterfaces::HBRT_FW_MSG_HBRT_FSP_REQ:
+
+ default:
+ break;
+ } // END switch (l_req_fw_msg->io_type)
+
+ if (l_createErrorLog)
+ {
+ /*@
+ * @errortype
+ * @severity ERRL_SEV_INFORMATIONAL
+ * @moduleid MOD_RT_FIRMWARE_REQUEST
+ * @reasoncode RC_FW_REQUEST_RESET_RELOAD_ERR
+ * @userdata1[0:31] Hypervisor return code
+ * @userdata1[32:63] Firmware Request type (HCODE Update) ||
+ sequence number (FSP MSG)
+ * @userdata2[0:31] SCOM address (HCODE Update) ||
+ MBOX message type (FSP MSG)
+ * @userdata2[32:63] SCOM data (HCODE Update) ||
+ Message Type (FSP MSG)
+ * @devdesc The Firmware Request call failed
+ */
+ l_err = new ErrlEntry(ERRL_SEV_INFORMATIONAL,
+ MOD_RT_FIRMWARE_REQUEST,
+ RC_FW_REQUEST_RESET_RELOAD_ERR,
+ l_userData1,
+ l_userData2,
+ true);
+ } // END if (l_createErrorLog)
+
+ // Try the firmware_request call again
+ continue;
+ } // END if (hbrt_rc_fspdead == rc)
+ // Error is not with FSP resetting and/or reloading, so log the error
+ else if (rc)
+ {
+ if (l_err)
+ {
+ // Commit any previous reset/reload error log
+ errlCommit(l_err, RUNTIME_COMP_ID);
+ }
+
+ // This NOT a reset/reload error
+ l_isResetReloadErr = false;
+
+ // Print trace info based on request message type and populate
+ // error log user data 1 & user data 2 based on response message
+ switch (l_req_fw_msg->io_type)
+ {
+ case hostInterfaces::HBRT_FW_MSG_TYPE_REQ_HCODE_UPDATE:
+ {
+ // Default user data 1 wirh Hypervisor return code
+ // and firmware request message type
+ l_userData1 = TWO_UINT32_TO_UINT64(
+ rc,
+ l_req_fw_msg->io_type);
+
+ // Pack user data 1 with Hypervisor return code and
+ // generic response code if the response is of type
+ // "RESP_GENERIC" else leave as is
+ // 1st check if the response size is large enough
+ // for the type needed
+ // 2nd make sure the message type is of
+ // type HBRT_FW_MSG_TYPE_RESP_GENERIC
+ // 3rd make sure there is actaully a value in the status
+ // If all these conditions are correct,
+ // then extract HWSV error
+ if ((*o_respLen >=
+ (hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
+ sizeof(l_resp_fw_msg->resp_generic))) &&
+ hostInterfaces::HBRT_FW_MSG_TYPE_RESP_GENERIC ==
+ l_resp_fw_msg->io_type &&
+ 0 != l_resp_fw_msg->resp_generic.o_status )
+ {
+ l_userData1 = TWO_UINT32_TO_UINT64(
+ rc,
+ l_resp_fw_msg->resp_generic.o_status);
+ } // END if (*o_respLen >= ...
+
+ // Pack user data 2 with HCODE scom
+ // and HCODE scom data
+ l_userData2 = TWO_UINT32_TO_UINT64(
+ l_req_fw_msg->req_hcode_update.i_scomAddr,
+ l_req_fw_msg->req_hcode_update.i_scomData);
+
+ TRACFCOMP(g_trac_runtime,
+ ERR_MRK"Failed doing an HCODE update. "
+ "rc:%d, io_type:%d, chipId:0x%llX, section:0x%X, "
+ "operation:0x%X, scomAddr:0x%llX, scomData:0x%llX",
+ rc,
+ l_req_fw_msg->io_type,
+ l_req_fw_msg->req_hcode_update.i_chipId,
+ l_req_fw_msg->req_hcode_update.i_section,
+ l_req_fw_msg->req_hcode_update.i_operation,
+ l_req_fw_msg->req_hcode_update.i_scomAddr,
+ l_req_fw_msg->req_hcode_update.i_scomData);
+
+ }
+ break;//END case hostInterfaces::HBRT_FW_MSG_TYPE_REQ_HCODE_UPDATE:
+
+ case hostInterfaces::HBRT_FW_MSG_TYPE_ERROR_LOG:
+ {
+ TRACFCOMP(g_trac_runtime,
+ ERR_MRK"Failed sending error log to FSP "
+ "via firmware_request. rc:%d, plid:0x%08X",
+ rc,
+ l_req_fw_msg->error_log.i_plid);
+
+ // Don't create an error log for this request type
+ l_createErrorLog = false;
+ }
+ break; // END case hostInterfaces::HBRT_FW_MSG_TYPE_ERROR_LOG:
+
+
+ case hostInterfaces::HBRT_FW_MSG_HBRT_FSP_REQ:
+ {
+ TRACFCOMP(g_trac_runtime,
+ ERR_MRK"Failed doing a VPD write. "
+ "rc:%d, io_type:%d, dataSize:%d, "
+ "seqnum:0x%X, msgq:0x%X, msgType:0x%X, __req:%d, "
+ "__onlyError:%d",
+ rc,
+ l_req_fw_msg->io_type,
+ l_req_fw_msg->generic_msg.dataSize,
+ l_req_fw_msg->generic_msg.seqnum,
+ l_req_fw_msg->generic_msg.msgq,
+ l_req_fw_msg->generic_msg.msgType,
+ l_req_fw_msg->generic_msg.__req,
+ l_req_fw_msg->generic_msg.__onlyError);
+
+ // Pack user data 1 with Hypervisor return code and
+ // firmware request message sequence number
+ l_userData1 = TWO_UINT32_TO_UINT64(
+ rc,
+ l_req_fw_msg->generic_msg.seqnum);
+
+ // Pack user data 2 with message queue and message type
+ l_userData2 = TWO_UINT32_TO_UINT64(
+ l_req_fw_msg->generic_msg.msgq,
+ l_req_fw_msg->generic_msg.msgType);
+ }
+ break; // END case hostInterfaces::HBRT_FW_MSG_HBRT_FSP_REQ:
+
+ default:
+ break;
+ } // END switch (l_req_fw_msg->io_type)
+
+ if (l_createErrorLog)
+ {
+ /*@
+ * @errortype
+ * @severity ERRL_SEV_PREDICTIVE
+ * @moduleid MOD_RT_FIRMWARE_REQUEST
+ * @reasoncode RC_FW_REQUEST_ERR
+ * @userdata1[0:31] Hypervisor return code
+ * @userdata1[32:63] Firmware Request type (HCODE Update) ||
+ sequence number (FSP MSG)
+ * @userdata2[0:31] SCOM address (HCODE Update) ||
+ MBOX message type (FSP MSG)
+ * @userdata2[32:63] SCOM data (HCODE Update) ||
+ Message Type (FSP MSG)
+ * @devdesc The Firmware Request call failed
+ */
+ l_err = new ErrlEntry(ERRL_SEV_PREDICTIVE,
+ MOD_RT_FIRMWARE_REQUEST,
+ RC_FW_REQUEST_ERR,
+ l_userData1,
+ l_userData2,
+ true);
+ } // END if (l_createErrorLog)
+
+ // Break out of the retry loop
+ break;
+ } // END else if (rc) generic_msg
+ // There was no RC returned from the FSP request, there could be an issue
+ // with HWSV. If so then a PLID will be returned in the first
+ // 4 bytes of the 'data' member for an HBRT_FW_MSG_HBRT_FSP_RESP type.
+ // 1st check if the response size is large enough for the type needed
+ // 2nd make sure the message is of HBRT_FW_MSG_HBRT_FSP_RESP type.
+ // 3rd check if the 'data' member will contain an error ID (PLID)
+ // 4th make sure the PLID has a value
+ // If all these conditions are correct, then pull out PLID
+ else if ((*o_respLen >=
+ (hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
+ sizeof(hostInterfaces::hbrt_fw_msg::generic_msg))) &&
+ (hostInterfaces::HBRT_FW_MSG_HBRT_FSP_RESP ==
+ l_resp_fw_msg->io_type) &&
+ (GenericFspMboxMessage_t::ERROR_ONLY ==
+ l_resp_fw_msg->generic_msg.__onlyError) &&
+ (0 != (l_resp_fw_msg->generic_msg.data >> 32)))
+
+ {
+ if (l_err)
+ {
+ // Commit any previous reset/reload error log
+ errlCommit(l_err, RUNTIME_COMP_ID);
+ }
+
+ // This NOT a reset/reload error
+ l_isResetReloadErr = false;
+
+ uint32_t l_errPlid = l_resp_fw_msg->generic_msg.data >> 32;
+
+ TRACFCOMP(g_trac_runtime,
+ ERR_MRK"Failed doing a VPD write. "
+ "rc:%d, plid:0x%X, io_type:%d, dataSize:%d, "
+ "seqnum:0x%X, msgq:0x%X, msgType:0x%X, __req:%d, "
+ "__onlyError:%d",
+ rc,
+ l_errPlid,
+ l_req_fw_msg->io_type,
+ l_req_fw_msg->generic_msg.dataSize,
+ l_req_fw_msg->generic_msg.seqnum,
+ l_req_fw_msg->generic_msg.msgq,
+ l_req_fw_msg->generic_msg.msgType,
+ l_req_fw_msg->generic_msg.__req,
+ l_req_fw_msg->generic_msg.__onlyError);
+
+ /*@
+ * @errortype
+ * @severity ERRL_SEV_PREDICTIVE
+ * @moduleid MOD_RT_FIRMWARE_REQUEST
+ * @reasoncode RC_FW_REQUEST_HWSV_ERR
+ * @userdata1[0:31] HWSV error log id (PLID)
+ * @userdata1[32:63] Sequence number
+ * @userdata2[0:31] MBOX message type
+ * @userdata2[32:63] Message Type
+ * @devdesc The Firmware Request call failed
+ */
+ l_err = new ErrlEntry(ERRL_SEV_PREDICTIVE,
+ MOD_RT_FIRMWARE_REQUEST,
+ RC_FW_REQUEST_HWSV_ERR,
+ TWO_UINT32_TO_UINT64(
+ l_errPlid,
+ l_req_fw_msg->generic_msg.seqnum),
+ TWO_UINT32_TO_UINT64(
+ l_req_fw_msg->generic_msg.msgq,
+ l_req_fw_msg->generic_msg.msgType),
+ true);
+
+ // Break out of the retry loop
+ break;
+ }
+ else
+ {
+ // Break out of the retry loop, the call was successful
+ // But first delete any previous errors. It can be confusing
+ // if an error is committed or returned on a successful call
+ delete l_err, l_err = nullptr;
+ break;
+ }
+ } // END for (int i = 0; i <= HBRT_FW_REQUEST_RETRIES; ++i)
+
+ // If there is an error, then call addFFDC
+ // with request/response sructs
+ if (l_err)
+ {
+ // Hit the max attempts (currently should only one retry) and hitting
+ // reset/reload error
+ if (l_isResetReloadErr)
+ {
+ // Change the severity of a reset/reload error to predictive
+ l_err->setSev(ERRL_SEV_PREDICTIVE);
+ }
+
+ l_err->addFFDC(RUNTIME_COMP_ID,
+ l_req_fw_msg,
+ i_reqLen,
+ 0, 0, false );
+
+ if (*o_respLen > 0)
+ {
+ l_err->addFFDC(RUNTIME_COMP_ID,
+ l_resp_fw_msg,
+ *o_respLen,
+ 0, 0, false );
+ }
+
+ l_err->collectTrace( "FW_REQ", 256);
+ } // END if (l_err)
+
+ return l_err;
+};
diff --git a/src/usr/vpd/runtime/makefile b/src/usr/vpd/runtime/makefile
index 7943ffcb0..1f2ed00d7 100644
--- a/src/usr/vpd/runtime/makefile
+++ b/src/usr/vpd/runtime/makefile
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2013,2015
+# Contributors Listed Below - COPYRIGHT 2013,2017
# [+] International Business Machines Corp.
#
#
diff --git a/src/usr/vpd/runtime/rt_vpd.C b/src/usr/vpd/runtime/rt_vpd.C
index d85440e56..dba37f1c2 100644
--- a/src/usr/vpd/runtime/rt_vpd.C
+++ b/src/usr/vpd/runtime/rt_vpd.C
@@ -22,6 +22,7 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
#include <trace/interface.H>
#include <errl/errlentry.H>
#include <errl/errlmanager.H>
@@ -30,7 +31,8 @@
#include <initservice/initserviceif.H>
#include <devicefw/driverif.H>
#include <i2c/eepromif.H>
-#include <runtime/interface.h>
+#include <runtime/interface.h> // g_hostInterfaces
+#include <util/runtime/rt_fwreq_helper.H> // firmware_request_helper
#include <targeting/common/util.H>
#include <util/runtime/util_rt.H>
#include <runtime/interface.h>
@@ -41,6 +43,8 @@
#include "cvpd.H"
#include "spd.H"
+using namespace ERRORLOG;
+
extern trace_desc_t* g_trac_vpd;
// ------------------------
@@ -313,7 +317,8 @@ errlHndl_t writePNOR ( uint64_t i_byteAddr,
//--------------------------------
if(INITSERVICE::spBaseServicesEnabled())
{
- TRACFCOMP(g_trac_vpd,ERR_MRK"rt_vpd:writePNOR not supported with FSP, skipping");
+ TRACFCOMP(g_trac_vpd,
+ ERR_MRK"rt_vpd:writePNOR not supported with FSP, skipping");
break;
}
@@ -378,6 +383,11 @@ errlHndl_t sendMboxWriteMsg ( size_t i_numBytes,
{
errlHndl_t l_err = nullptr;
+ // Put the handle to the firmware messages out here
+ // so it is easier to free later
+ hostInterfaces::hbrt_fw_msg *l_req_fw_msg = nullptr;
+ hostInterfaces::hbrt_fw_msg *l_resp_fw_msg = nullptr;
+
TRACFCOMP( g_trac_vpd, INFO_MRK
"sendMboxWriteMsg: Send msg to FSP to write VPD type %.8X, "
"record %d, offset 0x%X",
@@ -385,9 +395,6 @@ errlHndl_t sendMboxWriteMsg ( size_t i_numBytes,
i_record.rec_num,
i_record.offset );
- hostInterfaces::hbrt_fw_msg* l_req_fw_msg = nullptr;
- hostInterfaces::hbrt_fw_msg* l_resp_fw_msg = nullptr;
-
do
{
if(!INITSERVICE::spBaseServicesEnabled())
@@ -401,153 +408,91 @@ errlHndl_t sendMboxWriteMsg ( size_t i_numBytes,
if ((nullptr == g_hostInterfaces) ||
(nullptr == g_hostInterfaces->firmware_request))
{
+ TRACFCOMP(g_trac_vpd, ERR_MRK"sendMboxWriteMsg: "
+ "Hypervisor firmware_request interface not linked");
+
/*@
* @errortype
- * @severity ERRORLOG::ERRL_SEV_INFORMATIONAL
- * @moduleid VPD::VPD_SEND_MBOX_WRITE_MESSAGE
- * @reasoncode VPD::VPD_RT_NULL_FIRMWARE_REQUEST_PTR
+ * @severity ERRL_SEV_INFORMATIONAL
+ * @moduleid VPD_SEND_MBOX_WRITE_MESSAGE
+ * @reasoncode VPD_RT_NULL_FIRMWARE_REQUEST_PTR
* @userdata1 HUID of target
* @userdata2 VPD message type
* @devdesc MBOX send not supported in HBRT
*/
- l_err= new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_INFORMATIONAL,
- VPD::VPD_SEND_MBOX_WRITE_MESSAGE,
- VPD::VPD_RT_NULL_FIRMWARE_REQUEST_PTR,
- TARGETING::get_huid(i_target),
- i_type);
+ l_err= new ErrlEntry(ERRL_SEV_INFORMATIONAL,
+ VPD_SEND_MBOX_WRITE_MESSAGE,
+ VPD_RT_NULL_FIRMWARE_REQUEST_PTR,
+ TARGETING::get_huid(i_target),
+ i_type, true);
break;
}
- // Get an accurate size of memory actually needed to transport the data
- size_t l_generic_msg_size =
- sizeof(hostInterfaces::hbrt_fw_msg::generic_msg) +
- i_numBytes -
- sizeof(hostInterfaces::hbrt_fw_msg::generic_msg.data);
- size_t l_req_fw_msg_size = hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
- l_generic_msg_size;
+ // Get an accurate size of memory needed to transport
+ // the data for the firmware_request request struct
+ uint32_t l_req_data_size = sizeof(GenericFspMboxMessage_t) +
+ i_numBytes -
+ sizeof(GenericFspMboxMessage_t::data);
+
+ // The request data size must be at a minimum the size of the
+ // FSP generic message (sizeof(GenericFspMboxMessage_t))
+ if (l_req_data_size < sizeof(GenericFspMboxMessage_t))
+ {
+ l_req_data_size = sizeof(GenericFspMboxMessage_t);
+ }
+
+ // Calculate the TOTAL size of hostInterfaces::hbrt_fw_msg which
+ // means only adding hostInterfaces::HBRT_FW_MSG_BASE_SIZE to
+ // the previous calculated data size
+ uint64_t l_req_fw_msg_size = hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
+ l_req_data_size;
- //create the firmware_request structure to carry the vpd write msg data
+ // Create the firmware_request request struct to send data
l_req_fw_msg =
- (hostInterfaces::hbrt_fw_msg *)malloc(l_req_fw_msg_size) ;
- memset(l_req_fw_msg, 0, l_req_fw_msg_size);
+ (hostInterfaces::hbrt_fw_msg *)malloc(l_req_fw_msg_size);
- // populate the firmware_request structure with given data
- 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.dataSize = l_generic_msg_size;
+
+ // 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.dataSize = l_req_data_size;
l_req_fw_msg->generic_msg.msgq = MBOX::FSP_VPD_MSGQ;
l_req_fw_msg->generic_msg.msgType = i_type;
- l_req_fw_msg->generic_msg.__req = GFMM_REQUEST;
- l_req_fw_msg->generic_msg.__onlyError = GFMM_NOT_ERROR_ONLY;
+ l_req_fw_msg->generic_msg.__req = GenericFspMboxMessage_t::REQUEST;
memcpy(&l_req_fw_msg->generic_msg.data, i_data, i_numBytes);
- // set up the response struct, note that for messages to the FSP
- // the response size must match the request size
- l_resp_fw_msg =
- (hostInterfaces::hbrt_fw_msg *)malloc(l_req_fw_msg_size);
- memset(l_resp_fw_msg, 0, l_req_fw_msg_size);
+ // 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
uint64_t l_resp_fw_msg_size = l_req_fw_msg_size;
- // Note - no need to check for expected response size > request
- // size because they use the same base structure
-
- // make the firmware request
+ l_resp_fw_msg =
+ (hostInterfaces::hbrt_fw_msg *)malloc(l_resp_fw_msg_size);
+ memset(l_resp_fw_msg, 0, l_resp_fw_msg_size);
+
+ // Trace out the request structure
TRACFBIN( g_trac_vpd, INFO_MRK"Sending firmware_request",
l_req_fw_msg,
- hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
- sizeof(hostInterfaces::hbrt_fw_msg::generic_msg) );
- size_t rc = g_hostInterfaces->firmware_request(l_req_fw_msg_size,
- l_req_fw_msg,
- &l_resp_fw_msg_size,
- l_resp_fw_msg);
- uint64_t l_userData1(0), l_userData2(0);
-
- // Capture the err 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.
- // Only checking for a PLID regardless of what the flag __onlyError is
- // set to. I am not expecting any extra data and not sure what to do
- // with it if I get it.
- if ( (hostInterfaces::HBRT_FW_MSG_HBRT_FSP_RESP ==
- l_resp_fw_msg->io_type) &&
- (0 != l_resp_fw_msg->generic_msg.data >> 32) )
- {
- // extract the plid from the first 32 bits
- l_userData2 = l_resp_fw_msg->generic_msg.data >> 32;
- }
+ l_req_fw_msg_size);
- // gather up the error data and create an err log out of it
- if (rc || l_userData2)
- {
- TRACFCOMP(g_trac_vpd,
- ERR_MRK"firmware request: "
- "firmware request for FSP VPD write message rc: 0x%X, "
- "HUID:0x%llX, plid:%.8X, VPD type:%.8X, "
- "record:%d, offset:0x%X, ",
- rc, get_huid(i_target), l_userData2,
- i_type, i_record.rec_num, i_record.offset );
+ // 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);
- /*@
- * @errortype
- * @moduleid VPD::VPD_RT_FIRMWARE_REQUEST
- * @reasoncode VPD::VPD_RT_WRITE_MSG_ERR
- * @userdata1[0:31] Firmware Request return code (if any)
- * @userdata1[32:63] HUID of target
- * @userdata2 HWSV error log id (if any)
- * @devdesc Firmware Request for
- * VPD Write Msg error
- */
-
- // Capture the return code (rc), if any
- // this will indicate an issue with actually sending the msg
- if (rc)
- {
- l_userData1 = TWO_UINT32_TO_UINT64(rc,
- TARGETING::get_huid(i_target));
- }
- else
- {
- l_userData1 = TARGETING::get_huid(i_target);
- }
-
- l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
- VPD::VPD_RT_FIRMWARE_REQUEST,
- VPD::VPD_RT_WRITE_MSG_ERR,
- l_userData1,
- l_userData2);
-
- if (l_resp_fw_msg_size > 0)
- {
- l_err->addFFDC( MBOX_COMP_ID,
- l_resp_fw_msg,
- l_resp_fw_msg_size,
- 0, 0, false );
- }
-
- if (l_req_fw_msg_size > 0)
- {
- l_err->addFFDC( MBOX_COMP_ID,
- l_req_fw_msg,
- l_req_fw_msg_size,
- 0, 0, false );
- }
-
- l_err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
- HWAS::SRCI_PRIORITY_HIGH);
-
- if (l_userData2)
- {
- l_err->plid(l_userData2);
- }
-
- l_err->collectTrace( "VPD", 256);
- } // end (rc || l_userData2)
-
- }
- while (0);
+ if (l_err)
+ {
+ break;
+ }
+ } while (0);
// release the memory created
if( l_req_fw_msg ) { free(l_req_fw_msg); }
if( l_resp_fw_msg ) { free(l_resp_fw_msg); }
+ l_req_fw_msg = l_resp_fw_msg = nullptr;
if (l_err)
{
@@ -560,5 +505,4 @@ errlHndl_t sendMboxWriteMsg ( size_t i_numBytes,
return l_err;
}
-
}; // end namepsace VPD
OpenPOWER on IntegriCloud