summaryrefslogtreecommitdiffstats
path: root/src/usr/util/runtime/rt_fwnotify.C
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/util/runtime/rt_fwnotify.C')
-rw-r--r--src/usr/util/runtime/rt_fwnotify.C767
1 files changed, 640 insertions, 127 deletions
diff --git a/src/usr/util/runtime/rt_fwnotify.C b/src/usr/util/runtime/rt_fwnotify.C
index dae81e7d6..556a1c31f 100644
--- a/src/usr/util/runtime/rt_fwnotify.C
+++ b/src/usr/util/runtime/rt_fwnotify.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017,2019 */
+/* Contributors Listed Below - COPYRIGHT 2017,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -31,10 +31,14 @@
#include <errl/errlmanager.H> // errlCommit
#include <errl/hberrltypes.H> // TWO_UINT32_TO_UINT64
#include <targeting/common/target.H> // TargetHandle_t, getTargetFromHuid
+#include <targeting/runtime/rt_targeting.H> // RT_TARG::getHbTarget
#include <attributeenums.H> // ATTRIBUTE_ID
#ifdef CONFIG_NVDIMM
-#include <isteps/nvdimm/nvdimm.H> // notify NVDIMM protection change
+#include <isteps/nvdimm/nvdimm.H> // NVDIMM related activities
+#include <targeting/common/targetUtil.H> // makeAttribute
+#include <runtime/hbrt_utilities.H>
+using namespace NVDIMM;
#endif
using namespace TARGETING;
@@ -43,6 +47,7 @@ using namespace ERRORLOG;
using namespace MBOX;
using namespace SBEIO;
+
// Trace definition
extern trace_desc_t* g_trac_runtime;
extern trace_desc_t* g_trac_hbrt;
@@ -51,7 +56,7 @@ extern trace_desc_t* g_trac_hbrt;
* @brief The lower and upper bounds for the sequence ID.
**/
const uint16_t SEQ_ID_MIN = 0x0000;
-const uint16_t SEQ_ID_MAX = 0x7FFF;
+const uint16_t SEQ_ID_MAX = 0x7FFF;
/**
* @brief Set the sequence ID to the minimum value
@@ -85,7 +90,7 @@ uint16_t SeqId_t::getNextSeqId()
**/
uint16_t SeqId_t::getCurrentSeqId()
{
- return SeqId_t::SEQ_ID;
+ return SeqId_t::SEQ_ID;
}
/**
@@ -96,12 +101,12 @@ 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 HUID (in the first 4 bytes)
- // followed by a PLID (in the last 4 bytes).
- SbeRetryReqData_t *l_sbeRetryData = reinterpret_cast<SbeRetryReqData_t*>(&i_data);
+ // Create a useful struct to get to the data
+ // The data is expected to be a HUID (in the first 4 bytes)
+ // followed by a PLID (in the last 4 bytes).
+ SbeRetryReqData_t *l_sbeRetryData = reinterpret_cast<SbeRetryReqData_t*>(&i_data);
- TRACFCOMP(g_trac_runtime, ENTER_MRK"sbeAttemptRecovery: plid:0x%X, "
+ TRACFCOMP(g_trac_runtime, ENTER_MRK"sbeAttemptRecovery: plid:0x%X, "
"HUID:0x%X", l_sbeRetryData->plid, l_sbeRetryData->huid);
errlHndl_t l_err = nullptr;
@@ -115,7 +120,7 @@ void sbeAttemptRecovery(uint64_t i_data)
// If HUID invalid, log error and quit
if (nullptr == l_target)
{
- TRACFCOMP(g_trac_runtime, ERR_MRK"sbeAttemptRecovery: "
+ TRACFCOMP(g_trac_runtime, ERR_MRK"sbeAttemptRecovery: "
"No target associated with HUID:0x%.8X",
l_sbeRetryData->huid);
@@ -149,7 +154,7 @@ void sbeAttemptRecovery(uint64_t i_data)
if (nullptr == g_hostInterfaces ||
nullptr == g_hostInterfaces->firmware_request)
{
- TRACFCOMP(g_trac_runtime, ERR_MRK"sbeAttemptRecovery: "
+ TRACFCOMP(g_trac_runtime, ERR_MRK"sbeAttemptRecovery: "
"Hypervisor firmware_request interface not linked");
/*@
@@ -260,12 +265,12 @@ void occActiveNotification( void * i_data )
if (*l_active)
{
l_err = NVDIMM::notifyNvdimmProtectionChange(l_proc,
- NVDIMM::PROTECTED);
+ NVDIMM::OCC_ACTIVE);
}
else
{
l_err = NVDIMM::notifyNvdimmProtectionChange(l_proc,
- NVDIMM::NOT_PROTECTED);
+ NVDIMM::OCC_INACTIVE);
}
// commit error if it exists
@@ -294,12 +299,12 @@ void attrSyncRequest( void * i_data)
HbrtAttrSyncData_t * l_hbrtAttrData =
reinterpret_cast<HbrtAttrSyncData_t*>(i_data);
TRACFCOMP(g_trac_runtime, ENTER_MRK"attrSyncRequest: Target HUID 0x%0X "
- "for AttrID: 0x%0X with AttrSize: %lld", l_hbrtAttrData->huid,
- l_hbrtAttrData->attrID, l_hbrtAttrData->sizeOfAttrData);
+ "for AttrID: 0x%0X with AttrSize: %lld", l_hbrtAttrData->huid,
+ l_hbrtAttrData->attrID, l_hbrtAttrData->sizeOfAttrData);
TRACFBIN(g_trac_runtime, "Attribute data: ",
- &(l_hbrtAttrData->attrDataStart),
- l_hbrtAttrData->sizeOfAttrData);
+ &(l_hbrtAttrData->attrDataStart),
+ l_hbrtAttrData->sizeOfAttrData);
// extract the target from the given HUID
TargetHandle_t l_target = Target::getTargetFromHuid(l_hbrtAttrData->huid);
@@ -325,36 +330,496 @@ void attrSyncRequest( void * i_data)
memcpy(&l_attrData, &(l_hbrtAttrData->attrDataStart), l_attrSize);
/*@
- * @errortype
- * @severity ERRL_SEV_PREDICTIVE
- * @moduleid MOD_RT_ATTR_SYNC_REQUEST
- * @reasoncode RC_ATTR_UPDATE_FAILED
- * @userdata1[0:31] Target HUID
- * @userdata1[32:63] Attribute ID
- * @userdata2[0:31] Data Size
- * @userdata2[32:63] Up to 4 bytes of attribute data
- * @devdesc Attribute failed to update on HBRT side
- */
- errlHndl_t l_err = new ErrlEntry(ERRL_SEV_PREDICTIVE,
- MOD_RT_ATTR_SYNC_REQUEST,
- RC_ATTR_UPDATE_FAILED,
- TWO_UINT32_TO_UINT64(
+ * @errortype
+ * @severity ERRL_SEV_PREDICTIVE
+ * @moduleid MOD_RT_ATTR_SYNC_REQUEST
+ * @reasoncode RC_ATTR_UPDATE_FAILED
+ * @userdata1[0:31] Target HUID
+ * @userdata1[32:63] Attribute ID
+ * @userdata2[0:31] Data Size
+ * @userdata2[32:63] Up to 4 bytes of attribute data
+ * @devdesc Attribute failed to update on HBRT side
+ */
+ errlHndl_t l_err = new ErrlEntry(ERRL_SEV_PREDICTIVE,
+ MOD_RT_ATTR_SYNC_REQUEST,
+ RC_ATTR_UPDATE_FAILED,
+ TWO_UINT32_TO_UINT64(
l_hbrtAttrData->huid,
l_hbrtAttrData->attrID),
- TWO_UINT32_TO_UINT64(
+ TWO_UINT32_TO_UINT64(
l_hbrtAttrData->sizeOfAttrData,
l_attrData),
- true);
+ true);
- l_err->collectTrace(RUNTIME_COMP_NAME, 256);
+ l_err->collectTrace(RUNTIME_COMP_NAME, 256);
- //Commit the error
- errlCommit(l_err, RUNTIME_COMP_ID);
+ //Commit the error
+ errlCommit(l_err, RUNTIME_COMP_ID);
}
TRACFCOMP(g_trac_runtime, EXIT_MRK"attrSyncRequest");
}
+#ifdef CONFIG_NVDIMM
+/**
+ * @brief Utility function to set ATTR_NVDIMM_ENCRYPTION_ENABLE
+ * and send the value to the FSP
+ */
+void set_ATTR_NVDIMM_ENCRYPTION_ENABLE(
+ ATTR_NVDIMM_ENCRYPTION_ENABLE_type i_val )
+{
+ errlHndl_t l_err = nullptr;
+
+ Target* l_sys = nullptr;
+ targetService().getTopLevelTarget( l_sys );
+ assert(l_sys, "set_ATTR_NVDIMM_ENCRYPTION_ENABLE: no TopLevelTarget");
+ l_sys->setAttr<ATTR_NVDIMM_ENCRYPTION_ENABLE>(i_val);
+
+ // Send it down to the FSP
+ AttributeTank::Attribute l_attr = {};
+ if( !makeAttribute<ATTR_NVDIMM_ENCRYPTION_ENABLE>
+ (l_sys, l_attr) )
+ {
+ TRACFCOMP(g_trac_runtime, ERR_MRK"set_ATTR_NVDIMM_ENCRYPTION_ENABLE() Could not create Attribute");
+ /*@
+ *@errortype
+ *@reasoncode RC_CANNOT_MAKE_ATTRIBUTE
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid SET_ATTR_NVDIMM_ENCRYPTION_ENABLE
+ *@devdesc Couldn't create an Attribute to send the data
+ * to the FSP
+ *@custdesc NVDIMM encryption error
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ SET_ATTR_NVDIMM_ENCRYPTION_ENABLE,
+ RC_CANNOT_MAKE_ATTRIBUTE,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT );
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ else
+ {
+ std::vector<TARGETING::AttributeTank::Attribute> l_attrList;
+ l_attrList.push_back(l_attr);
+ l_err = sendAttributes( l_attrList );
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_runtime, ERR_MRK"set_ATTR_NVDIMM_ENCRYPTION_ENABLE() Error sending ATTR_NVDIMM_ENCRYPTION_ENABLE down to FSP");
+ l_err->setSev(ERRORLOG::ERRL_SEV_PREDICTIVE);
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ }
+}
+#endif //CONFIG_NVDIMM
+
+/**
+ * @brief Perform an NVDIMM operation
+ * @param[in] i_nvDimmOp - A struct that contains the operation(s) to perform
+ * and a flag indicating whether to perform operation
+ * on all processors or a given single processor.
+ *
+ * @Note The arming/disarming operations below are in the order of which they
+ * should be performed. If a new sequence is added to the
+ * arming/disarming sequence, make sure it is inserted in the
+ * correct order.
+ * The current order is: disarm -> disable encryption -> remove keys ->
+ * enable encryption -> arm
+ **/
+int doNvDimmOperation(const hostInterfaces::nvdimm_operation_t& i_nvDimmOp)
+{
+ int rc = 0;
+#ifndef CONFIG_NVDIMM
+ TRACFCOMP(g_trac_runtime, ENTER_MRK"doNvDimmOperation: not an "
+ "NVDIMM configuration, this call becomes a noop.");
+
+#else
+ TRACFCOMP(g_trac_runtime, ENTER_MRK"doNvDimmOperation: Operation(s) "
+ "0x%0X, processor ID 0x%0X",
+ i_nvDimmOp.opType,
+ i_nvDimmOp.procId);
+
+ // Error log handle for capturing any errors
+ errlHndl_t l_err{nullptr};
+ // List of NVDIMM Targets to execute NVDIMM operation on
+ TargetHandleList l_nvDimmTargetList;
+
+ // Perform the operations requested
+ do
+ {
+ /// Populate the NVDIMM target list
+ // If requesting to perform operation on all NVDIMMs, then
+ // retrieve all NVDIMMs from system
+ if (HBRT_NVDIMM_OPERATION_APPLY_TO_ALL_NVDIMMS == i_nvDimmOp.procId)
+ {
+ nvdimm_getNvdimmList(l_nvDimmTargetList);
+ }
+ // Else retrieve only the NVDIMMs from given processor ID
+ else
+ {
+ /// Get the NVDIMMs associated with procId
+ // Convert the procId to a real boy, uh, I mean target
+ TARGETING::TargetHandle_t l_procTarget;
+ l_err = RT_TARG::getHbTarget(i_nvDimmOp.procId, l_procTarget);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: Error getting "
+ "HB Target from processor ID 0x%0X, "
+ "exiting ...",
+ i_nvDimmOp.procId);
+ rc = -1;
+ break;
+ }
+
+ // Get the list of NVDIMMs associated with processor target
+ l_nvDimmTargetList = TARGETING::getProcNVDIMMs(l_procTarget);
+ }
+
+ // No point in continuing if the list of NVDIMM Targets is empty
+ if (!l_nvDimmTargetList.size())
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: No NVDIMMs found, "
+ "exiting ...");
+ rc = -1;
+ break;
+ }
+
+ // Perform the arming/disarming operations. If anyone fails in the
+ // sequence, no point in calling the next, if there is a next operation.
+ do
+ {
+ // Disarm the NV logic
+ if (i_nvDimmOp.opType & hostInterfaces::HBRT_FW_NVDIMM_DISARM)
+ {
+ // Make call to disarm
+ if (!nvdimmDisarm(l_nvDimmTargetList))
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to disarm failed. Will not perform any "
+ "more arming/disarming calls, if they exist");
+ rc = -1;
+ break;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to disarm succeeded");
+ }
+ }
+
+ // Disable encryption on the NVDIMM and clear saved values from FW
+ if (i_nvDimmOp.opType &
+ hostInterfaces::HBRT_FW_NVDIMM_DISABLE_ENCRYPTION)
+ {
+ // Make call to disable encryption
+ if (!nvdimm_crypto_erase(l_nvDimmTargetList))
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to disable encryption failed. Will not "
+ "perform any more arming/disarming calls, if "
+ "they exist");
+
+ // Clear the encryption enable attribute
+ set_ATTR_NVDIMM_ENCRYPTION_ENABLE(0);
+
+ rc = -1;
+ break;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to disable encryption succeeded.");
+ }
+
+ // Clear the encryption enable attribute
+ set_ATTR_NVDIMM_ENCRYPTION_ENABLE(0);
+ }
+
+ // Remove keys
+ if (i_nvDimmOp.opType & hostInterfaces::HBRT_FW_NVDIMM_REMOVE_KEYS)
+ {
+ // Make call to remove keys
+ if (!nvdimm_remove_keys())
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to remove keys failed. Will not perform "
+ "any more arming/disarming calls, if they exist");
+ rc = -1;
+ break;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to remove keys succeeded.");
+ }
+ }
+
+ // Enable encryption on the NVDIMM
+ if (i_nvDimmOp.opType &
+ hostInterfaces::HBRT_FW_NVDIMM_ENABLE_ENCRYPTION)
+ {
+ // Set the encryption enable attribute
+ set_ATTR_NVDIMM_ENCRYPTION_ENABLE(1);
+
+ // Make call to generate keys before enabling encryption
+ if(!nvdimm_gen_keys())
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to generate keys failed, unable to enable "
+ "encryption. Will not perform any more "
+ "arming/disarming calls, if they exist");
+ rc = -1;
+ break;
+ }
+ else
+ {
+ // Make call to enable encryption
+ if (!nvdimm_encrypt_enable(l_nvDimmTargetList))
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to enable encryption failed. "
+ "Will not perform any more arming/disarming "
+ "calls, if they exist");
+ rc = -1;
+ break;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to enable encryption succeeded.");
+ }
+ } // end if(!nvdimm_gen_keys()) ... else ...
+ }
+
+ // Arm the NV logic
+ if (i_nvDimmOp.opType & hostInterfaces::HBRT_FW_NVDIMM_ARM)
+ {
+ // Make call to arm
+ if (!nvdimmArm(l_nvDimmTargetList))
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to arm failed.");
+ rc = -1;
+ break;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to arm succeeded.");
+ }
+ } // end if (nvDimmOp.opType & hostInterfaces::HBRT_FW_NVDIMM_ARM)
+ } while (0); // end Perform the arming/disarming operations.
+
+ // Perform the ES (energy source) health check operation
+ if (i_nvDimmOp.opType & hostInterfaces::HBRT_FW_MNFG_ES_HEALTH_CHECK)
+ {
+ if (!nvDimmEsCheckHealthStatus(l_nvDimmTargetList))
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to do an ES (energy source) health check failed.");
+ rc = -1;
+ break;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to do an ES (energy source) health check succeeded.");
+ }
+ }
+
+ // Perform the NVM (non-volatile memory) health check operation
+ if (i_nvDimmOp.opType & hostInterfaces::HBRT_FW_MNFG_NVM_HEALTH_CHECK)
+ {
+ if (!nvDimmNvmCheckHealthStatus(l_nvDimmTargetList))
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to do a NVM (non-volatile memory) health check failed.");
+ rc = -1;
+ break;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to do a NVM (non-volatile memory) health check succeeded.");
+ }
+ }
+
+ // Perform the factory default operation
+ if (i_nvDimmOp.opType & hostInterfaces::HBRT_FW_NVDIMM_FACTORY_DEFAULT)
+ {
+ if (!nvdimmFactoryDefault(l_nvDimmTargetList))
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to do NVDIMM Factory Default operation failed.");
+ rc = -1;
+ break;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to do NVDIMM Factory Default operation succeeded.");
+ }
+ }
+
+ // Perform the secure erase verify start operation
+ if (i_nvDimmOp.opType & hostInterfaces::HBRT_FW_NVDIMM_SECURE_EV_START)
+ {
+ if (!nvdimmSecureEraseVerifyStart(l_nvDimmTargetList))
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to do NVDIMM Secure Erase Verify Start failed.");
+ rc = -1;
+ break;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to do NVDIMM Secure Erase Verify Start succeeded.");
+ }
+ }
+
+ // Perform the secure erase verify status operation
+ if (i_nvDimmOp.opType & hostInterfaces::HBRT_FW_NVDIMM_SECURE_EV_STATUS)
+ {
+ if (!nvdimmSecureEraseVerifyStatus(l_nvDimmTargetList))
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to do NVDIMM Secure Erase Verify Status failed.");
+ rc = -1;
+ break;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to do NVDIMM Secure Erase Verify Status succeeded.");
+ }
+ }
+
+ } while(0); // end Perform the operations requested
+
+ if (l_err)
+ {
+ //Commit the error if it exists
+ errlCommit(l_err, RUNTIME_COMP_ID);
+ }
+
+#endif
+
+ TRACFCOMP(g_trac_runtime, EXIT_MRK"doNvDimmOperation")
+ return rc;
+}
+
+/**
+ * @brief Log the gard event from PHYP/OPAL
+ *
+ * @param[in] i_gardEvent - The details of the gard event
+ * @see hostInterfaces::gard_event_t for more info
+ *
+ **/
+void logGardEvent(const hostInterfaces::gard_event_t& i_gardEvent)
+{
+ // Trace input components
+ TRACFCOMP(g_trac_runtime,
+ ENTER_MRK"logGardEvent: Gard Event Data: "
+ "error type(0x%.8X), processor ID(0x%.8X), "
+ "PLID(0x%.8X), sub unit mask(0x.%4X), "
+ "recovery level(0x.%4X)",
+ i_gardEvent.i_error_type,
+ i_gardEvent.i_procId,
+ i_gardEvent.i_plid,
+ i_gardEvent.i_sub_unit_mask,
+ i_gardEvent.i_recovery_level);
+
+ errlHndl_t l_err{nullptr};
+
+ do
+ {
+ // Make sure the error type is valid, if not, log it
+ if ((i_gardEvent.i_error_type == hostInterfaces::HBRT_GARD_ERROR_UNKNOWN ) ||
+ (i_gardEvent.i_error_type >= hostInterfaces::HBRT_GARD_ERROR_LAST) )
+ {
+ TRACFCOMP(g_trac_runtime, "logGardEvent: ERROR: unknown/invalid "
+ "error type 0x%.8X",
+ i_gardEvent.i_error_type);
+
+ /* @
+ * @errortype
+ * @severity ERRL_SEV_PREDICTIVE
+ * @moduleid MOD_RT_FIRMWARE_NOTIFY
+ * @reasoncode RC_LOG_GARD_EVENT_UNKNOWN_ERROR_TYPE
+ * @userdata1[0:31] GARD error type
+ * @userdata1[32:63] Processor ID
+ * @userdata2[0:31] Sub unit mask
+ * @userdata2[32:63] Recovery level
+ * @devdesc Unknown/invalid error type
+ * @custdesc Internal firmware error
+ */
+ l_err = new ErrlEntry( ERRL_SEV_PREDICTIVE,
+ MOD_RT_FIRMWARE_NOTIFY,
+ RC_LOG_GARD_EVENT_UNKNOWN_ERROR_TYPE,
+ TWO_UINT32_TO_UINT64(
+ i_gardEvent.i_error_type,
+ i_gardEvent.i_procId),
+ TWO_UINT32_TO_UINT64(
+ i_gardEvent.i_sub_unit_mask,
+ i_gardEvent.i_recovery_level),
+ ErrlEntry::ADD_SW_CALLOUT);
+ break;
+ }
+
+
+ // Get the Target associated with processor ID
+ TARGETING::TargetHandle_t l_procTarget{nullptr};
+ l_err = RT_TARG::getHbTarget(i_gardEvent.i_procId, l_procTarget);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_runtime, "logGardEvent: Error getting "
+ "HB Target from processor ID 0x%0X, "
+ "exiting ...",
+ i_gardEvent.i_procId);
+ break;
+ }
+
+ // Log the GARD event
+ /* @
+ * @errortype
+ * @severity ERRL_SEV_PREDICTIVE
+ * @moduleid MOD_RT_FIRMWARE_NOTIFY
+ * @reasoncode RC_LOG_GARD_EVENT
+ * @userdata1[0:31] GARD error type
+ * @userdata1[32:63] Processor ID
+ * @userdata2[0:31] Sub unit mask
+ * @userdata2[32:63] Recovery level
+ * @devdesc Gard event from Opal/Phyp
+ * @custdesc Hardware error detected at runtime
+ */
+ l_err = new ErrlEntry( ERRL_SEV_PREDICTIVE,
+ MOD_RT_FIRMWARE_NOTIFY,
+ RC_LOG_GARD_EVENT,
+ TWO_UINT32_TO_UINT64(
+ i_gardEvent.i_error_type,
+ i_gardEvent.i_procId),
+ TWO_UINT32_TO_UINT64(
+ i_gardEvent.i_sub_unit_mask,
+ i_gardEvent.i_recovery_level));
+
+ // Set the PLID to the given gard event PLID if it exist
+ if (i_gardEvent.i_plid)
+ {
+ l_err->plid(i_gardEvent.i_plid);
+ }
+
+ // Do the actual gard
+ l_err->addHwCallout( l_procTarget, HWAS::SRCI_PRIORITY_MED,
+ HWAS::NO_DECONFIG, HWAS::GARD_PHYP);
+ } while(0);
+
+ // Commit any error log that occurred.
+ errlCommit(l_err, RUNTIME_COMP_ID);
+
+ TRACFCOMP(g_trac_runtime, EXIT_MRK"logGardEvent")
+}
/**
* @see src/include/runtime/interface.h for definition of call
@@ -362,12 +827,12 @@ void attrSyncRequest( void * i_data)
*/
void firmware_notify( uint64_t i_len, void *i_data )
{
- TRACFCOMP(g_trac_hbrt, ENTER_MRK"firmware_notify: "
+ TRACFCOMP(g_trac_hbrt, ENTER_MRK"firmware_notify: "
"i_len:%d", i_len );
- TRACFBIN(g_trac_runtime, "firmware_notify: i_data", i_data, i_len);
+ TRACFBIN(g_trac_runtime, "firmware_notify: i_data", i_data, i_len);
- errlHndl_t l_err = nullptr;
+ errlHndl_t l_err = nullptr;
// Flag to detect an invalid/unknown/not used message
bool l_badMessage = false;
@@ -381,12 +846,12 @@ void firmware_notify( uint64_t i_len, void *i_data )
// data necessary to determine type of message
if (i_len < hostInterfaces::HBRT_FW_MSG_BASE_SIZE)
{
- l_badMessage = true;
+ l_badMessage = true;
- TRACFCOMP(g_trac_runtime, ERR_MRK"firmware_notify: "
- "Received a non hostInterfaces::hbrt_fw_msg data stream" );
+ TRACFCOMP(g_trac_runtime, ERR_MRK"firmware_notify: Received "
+ "a non hostInterfaces::hbrt_fw_msg data stream" );
- break;
+ break;
}
// Cast the data to an hbrt_fw_msg to extract the input type
@@ -394,68 +859,116 @@ void firmware_notify( uint64_t i_len, void *i_data )
static_cast<hostInterfaces::hbrt_fw_msg*>(i_data);
switch (l_hbrt_fw_msg->io_type)
{
- case hostInterfaces::HBRT_FW_MSG_HBRT_FSP_REQ:
- {
- // Distinguish based on msgType and msgq
- if ( (l_hbrt_fw_msg->generic_msg.msgType ==
+ case hostInterfaces::HBRT_FW_MSG_HBRT_FSP_REQ:
+ {
+ // Distinguish based on msgType and msgq
+ if ( (l_hbrt_fw_msg->generic_msg.msgType ==
GenericFspMboxMessage_t::MSG_ATTR_SYNC_REQUEST) &&
(l_hbrt_fw_msg->generic_msg.msgq ==
MBOX::HB_ATTR_SYNC_MSGQ) )
- {
- attrSyncRequest((void*)&(l_hbrt_fw_msg->generic_msg.data));
- }
- else if ((l_hbrt_fw_msg->generic_msg.msgType ==
- GenericFspMboxMessage_t::MSG_OCC_ACTIVE) &&
- (l_hbrt_fw_msg->generic_msg.msgq ==
- MBOX::FSP_OCC_MSGQ_ID) )
- {
- occActiveNotification((void*)&(l_hbrt_fw_msg->generic_msg.data));
- }
- // Placing this at end as it does not have a msgq specified
- // Want to match msgType & msgq combos first
- else if (l_hbrt_fw_msg->generic_msg.msgType ==
- GenericFspMboxMessage_t::MSG_SBE_ERROR)
- {
- sbeAttemptRecovery(l_hbrt_fw_msg->generic_msg.data);
- }
- else
- {
- 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.msgType,
- l_hbrt_fw_msg->generic_msg.msgq,
- 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);
- }
- } // END case HBRT_FW_MSG_HBRT_FSP_REQ:
+ {
+ attrSyncRequest((void*)&(l_hbrt_fw_msg->generic_msg.data));
+ }
+ else if ((l_hbrt_fw_msg->generic_msg.msgType ==
+ GenericFspMboxMessage_t::MSG_OCC_ACTIVE) &&
+ (l_hbrt_fw_msg->generic_msg.msgq ==
+ MBOX::FSP_OCC_MSGQ_ID) )
+ {
+ occActiveNotification((void*)&(l_hbrt_fw_msg->generic_msg.data));
+ }
+ // Placing this at end as it does not have a msgq specified
+ // Want to match msgType & msgq combos first
+ else if (l_hbrt_fw_msg->generic_msg.msgType ==
+ GenericFspMboxMessage_t::MSG_SBE_ERROR)
+ {
+ sbeAttemptRecovery(l_hbrt_fw_msg->generic_msg.data);
+ }
+ else
+ {
+ 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.msgType,
+ l_hbrt_fw_msg->generic_msg.msgq,
+ 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);
+ } // END if ( (l_hbrt_fw_msg->generic_msg.msgType ... else ...
+ } // END case hostInterfaces::HBRT_FW_MSG_HBRT_FSP_REQ:
+ break;
- break;
+ case hostInterfaces::HBRT_FW_MSG_TYPE_NVDIMM_OPERATION:
+ {
+ uint64_t l_minMsgSize = hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
+ sizeof(hostInterfaces::hbrt_fw_msg::nvdimm_operation);
+ if (i_len < l_minMsgSize)
+ {
+ l_badMessage = true;
+
+ TRACFCOMP(g_trac_runtime, ERR_MRK"firmware_notify: "
+ "Received message HBRT_FW_MSG_TYPE_NVDIMM_OPERATION, "
+ "but size of message data(%d) is not adequate for a "
+ "complete message of this type, with size requirement of "
+ "%d", i_len, l_minMsgSize );
+
+ // Pack user data 1 with the message input type, the only
+ // data that can be safely retrieved
+ l_userData1 = l_hbrt_fw_msg->io_type;
+
+ break;
+ }
+
+ doNvDimmOperation(l_hbrt_fw_msg->nvdimm_operation);
+ } // END case hostInterfaces::HBRT_FW_MSG_TYPE_NVDIMM_OPERATION:
+ break;
- default:
- {
- l_badMessage = true;
+ case hostInterfaces::HBRT_FW_MSG_TYPE_GARD_EVENT:
+ {
+ uint64_t l_minMsgSize = hostInterfaces::HBRT_FW_MSG_BASE_SIZE +
+ sizeof(hostInterfaces::hbrt_fw_msg::gard_event);
+ if (i_len < l_minMsgSize)
+ {
+ l_badMessage = true;
+
+ TRACFCOMP(g_trac_runtime, ERR_MRK"firmware_notify: "
+ "Received message HBRT_FW_MSG_TYPE_GARD_EVENT, "
+ "but size of message data(%d) is not adequate for a "
+ "complete message of this type, with size requirement of "
+ "%d", i_len, l_minMsgSize );
+
+ // Pack user data 1 with the message input type, the only
+ // data that can be safely retrieved
+ l_userData1 = l_hbrt_fw_msg->io_type;
+
+ break;
+ }
+
+ logGardEvent(l_hbrt_fw_msg->gard_event);
+ } // END case hostInterfaces::HBRT_FW_MSG_TYPE_GARD_EVENT:
+ break;
- TRACFCOMP(g_trac_runtime, ERR_MRK"firmware_notify: "
- "Unknown firmware request input type:0x%.8X ",
- l_hbrt_fw_msg->io_type);
+ default:
+ {
+ l_badMessage = true;
- l_userData1 = l_hbrt_fw_msg->io_type;
- } // END default
+ TRACFCOMP(g_trac_runtime, ERR_MRK"firmware_notify: "
+ "Unknown firmware request input type:0x%.8X ",
+ l_hbrt_fw_msg->io_type);
- break;
+ l_userData1 = l_hbrt_fw_msg->io_type;
+ } // END default
+ break;
}; // END switch (l_hbrt_fw_msg->io_type)
@@ -463,42 +976,42 @@ void firmware_notify( uint64_t i_len, void *i_data )
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);
+ /*@
+ * @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(RUNTIME_COMP_NAME, 256);
}
if (l_err)
{
- //Commit the error if it exists
- errlCommit(l_err, RUNTIME_COMP_ID);
+ //Commit the error if it exists
+ errlCommit(l_err, RUNTIME_COMP_ID);
}
- TRACFCOMP(g_trac_hbrt, EXIT_MRK"firmware_notify");
+ TRACFCOMP(g_trac_hbrt, EXIT_MRK"firmware_notify");
};
struct registerFwNotify
OpenPOWER on IntegriCloud