summaryrefslogtreecommitdiffstats
path: root/src/usr
diff options
context:
space:
mode:
authorDan Crowell <dcrowell@us.ibm.com>2019-06-27 14:49:31 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2019-07-01 17:07:18 -0500
commit08b6443e65d37146d77953f9dbe47a382734fde3 (patch)
tree0ab9c1ea4e4de9d87acfe13c8733c32acc532abb /src/usr
parent710af45a83d85a451d356113086957e5b2712e23 (diff)
downloadtalos-hostboot-08b6443e65d37146d77953f9dbe47a382734fde3.tar.gz
talos-hostboot-08b6443e65d37146d77953f9dbe47a382734fde3.zip
Push ATTR_NVDIMM_ARMED down to FSP to handle MPIPL case
If the NVDIMM is not armed when the save/flush call is made during a mpipl reboot, it will cause errors in the memory. To avoid this we need HBRT to push down the armed state to the FSP so that HWSV can skip the save call in the case where the NVDIMM is not armed. Change-Id: I16611e8fcb5274c3cb0aee6fec1300a95579b11b Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/79825 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr')
-rw-r--r--src/usr/isteps/nvdimm/nvdimm.C75
-rw-r--r--src/usr/util/runtime/rt_fwreq_helper.C283
2 files changed, 353 insertions, 5 deletions
diff --git a/src/usr/isteps/nvdimm/nvdimm.C b/src/usr/isteps/nvdimm/nvdimm.C
index 4925be6c7..004aaa68e 100644
--- a/src/usr/isteps/nvdimm/nvdimm.C
+++ b/src/usr/isteps/nvdimm/nvdimm.C
@@ -130,15 +130,19 @@ typedef union {
} encryption_key_validation_t;
/**
- * @brief Utility function to set ATTR_
+ * @brief Utility function to send the value of
+ * ATTR_NVDIMM_ARMED to the FSP
+ */
+void send_ATTR_NVDIMM_ARMED( Target* i_nvdimm,
+ ATTR_NVDIMM_ARMED_type& i_val );
+
+/**
+ * @brief Utility function to set ATTR_NVDIMM_ENCRYPTION_KEYS_FW
* and send the value to the FSP
*/
void set_ATTR_NVDIMM_ENCRYPTION_KEYS_FW(
ATTR_NVDIMM_ENCRYPTION_KEYS_FW_typeStdArr& i_val )
{
-#ifdef __HOSTBOOT_RUNTIME
- errlHndl_t l_err = nullptr;
-
Target* l_sys = nullptr;
targetService().getTopLevelTarget( l_sys );
assert(l_sys, "set_ATTR_NVDIMM_ENCRYPTION_KEYS_FW: no TopLevelTarget");
@@ -146,6 +150,9 @@ void set_ATTR_NVDIMM_ENCRYPTION_KEYS_FW(
l_sys->setAttrFromStdArr
<ATTR_NVDIMM_ENCRYPTION_KEYS_FW>(i_val);
+#ifdef __HOSTBOOT_RUNTIME
+ errlHndl_t l_err = nullptr;
+
// Send attr to HWSV if at runtime
AttributeTank::Attribute l_attr = {};
if( !makeAttributeStdArr<ATTR_NVDIMM_ENCRYPTION_KEYS_FW>
@@ -2841,13 +2848,18 @@ errlHndl_t notifyNvdimmProtectionChange(Target* i_target,
ATTR_NVDIMM_ARMED_type l_armed_state = {};
l_armed_state = l_nvdimm->getAttr<ATTR_NVDIMM_ARMED>();
+ // If we change the armed state, need to tell FSP
+ bool l_armed_change = false;
+
switch (i_state)
{
case NVDIMM_ARMED:
l_armed_state.armed = 1;
+ l_armed_change = true;
break;
case NVDIMM_DISARMED:
l_armed_state.armed = 0;
+ l_armed_change = true;
break;
case OCC_ACTIVE:
l_armed_state.occ_active = 1;
@@ -2863,8 +2875,12 @@ errlHndl_t notifyNvdimmProtectionChange(Target* i_target,
break;
}
+ // Set the attribute and send it to the FSP if needed
l_nvdimm->setAttr<ATTR_NVDIMM_ARMED>(l_armed_state);
-
+ if( l_armed_change )
+ {
+ send_ATTR_NVDIMM_ARMED( l_nvdimm, l_armed_state );
+ }
// Get the nv status flag attr and update it
ATTR_NV_STATUS_FLAG_type l_nv_status =
@@ -3007,5 +3023,54 @@ errlHndl_t notifyNvdimmProtectionChange(Target* i_target,
return l_err;
}
+/*
+ * @brief Utility function to send the value of
+ * ATTR_NVDIMM_ARMED to the FSP
+ */
+void send_ATTR_NVDIMM_ARMED( Target* i_nvdimm,
+ ATTR_NVDIMM_ARMED_type& i_val )
+{
+#ifdef __HOSTBOOT_RUNTIME
+ errlHndl_t l_err = nullptr;
+
+ // Send attr to HWSV if at runtime
+ AttributeTank::Attribute l_attr = {};
+ if( !makeAttribute<ATTR_NVDIMM_ENCRYPTION_ENABLE>
+ (i_nvdimm, l_attr) )
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"send_ATTR_NVDIMM_ARMED() Could not create Attribute");
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_CANNOT_MAKE_ATTRIBUTE
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid SEND_ATTR_NVDIMM_ARMED
+ *@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,
+ SEND_ATTR_NVDIMM_ARMED,
+ NVDIMM_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_nvdimm, ERR_MRK"send_ATTR_NVDIMM_ARMED() Error sending ATTR_NVDIMM_ARMED down to FSP");
+ l_err->setSev(ERRORLOG::ERRL_SEV_PREDICTIVE);
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ }
+#endif //__HOSTBOOT_RUNTIME
+}
+
} // end NVDIMM namespace
diff --git a/src/usr/util/runtime/rt_fwreq_helper.C b/src/usr/util/runtime/rt_fwreq_helper.C
index f94dab238..ce2a1baf6 100644
--- a/src/usr/util/runtime/rt_fwreq_helper.C
+++ b/src/usr/util/runtime/rt_fwreq_helper.C
@@ -27,6 +27,7 @@
#include <runtime/interface.h> // hostInterfaces
#include <runtime/runtime_reasoncodes.H> // MOD_RT_FIRMWARE_REQUEST, etc
#include <errl/errlmanager.H> // errlCommit
+#include <targeting/common/targetUtil.H> // makeAttribute
using namespace ERRORLOG;
using namespace RUNTIME;
@@ -629,3 +630,285 @@ errlHndl_t firmware_request_helper(uint64_t i_reqLen, void *i_req,
return l_err;
};
+
+/**
+ * @brief A handy utility to create the firmware request and response
+ * messages, for FSP, where the messages must be of equal size.
+ */
+bool createGenericFspMsg(uint32_t i_fspReqPayloadSize,
+ uint32_t &o_fspMsgSize,
+ uint64_t &o_requestMsgSize,
+ hostInterfaces::hbrt_fw_msg* &o_requestMsg,
+ uint64_t &o_responseMsgSize,
+ hostInterfaces::hbrt_fw_msg* &o_responseMsg)
+{
+ // Default the return value to true, assume things will go right
+ bool l_retVal(true);
+
+ // Do some quick initialization of the output data
+ o_fspMsgSize = o_requestMsgSize = o_responseMsgSize = 0;
+ o_requestMsg = o_responseMsg = nullptr;
+
+ // Calculate the total size of the Generic FSP Message.
+ o_fspMsgSize = GENERIC_FSP_MBOX_MESSAGE_BASE_SIZE +
+ i_fspReqPayloadSize;
+
+ // The total Generic FSP Message size must be at a minimum the
+ // size of the FSP generic message (sizeof(GenericFspMboxMessage_t))
+ if (o_fspMsgSize < sizeof(GenericFspMboxMessage_t))
+ {
+ o_fspMsgSize = sizeof(GenericFspMboxMessage_t);
+ }
+
+ // Calculate the total size of the hbrt_fw_msgs which
+ // means only adding hostInterfaces::HBRT_FW_MSG_BASE_SIZE to
+ // the previous calculated Generic FSP Message size.
+ o_requestMsgSize = o_responseMsgSize =
+ hostInterfaces::HBRT_FW_MSG_BASE_SIZE + o_fspMsgSize;
+
+ // Create the hbrt_fw_msgs
+ o_responseMsg = reinterpret_cast<hostInterfaces::hbrt_fw_msg *>
+ (new uint8_t[o_responseMsgSize]);
+ o_requestMsg = reinterpret_cast<hostInterfaces::hbrt_fw_msg *>
+ (new uint8_t[o_requestMsgSize]);
+
+ // If any one of these two message's memory can't be allocated, then
+ // delete both messages (in case one did allocate memory), set both
+ // messages to NULL pointers and set their respective sizes to zero.
+ if (!o_responseMsg || !o_requestMsg)
+ {
+ // OK to delete a NULL pointer if it happens
+ delete []o_responseMsg;
+ delete []o_requestMsg;
+
+ // Return output data zeroed out
+ o_responseMsg = o_requestMsg = nullptr;
+ o_fspMsgSize = o_requestMsgSize = o_responseMsgSize = 0;
+
+ // Return false, indicating that this function had an issue creating
+ // the request and/or response message
+ l_retVal = false;
+ }
+ else
+ {
+ // Initialize/zero out hbrt_fw_msgs
+ o_requestMsg->generic_msg.initialize();
+ memset(o_responseMsg, 0, o_responseMsgSize);
+
+ // We can at least set these parameters based on current usage
+ o_requestMsg->io_type = hostInterfaces::HBRT_FW_MSG_HBRT_FSP_REQ;
+ o_requestMsg->generic_msg.dataSize = o_fspMsgSize;
+ o_requestMsg->generic_msg.__req = GenericFspMboxMessage_t::REQUEST;
+ }
+
+ return l_retVal;
+} // end createGenericFspMsg
+
+
+/**
+ * @brief Serializes a list of Attributes to be sent to FSP
+ */
+errlHndl_t sendAttributes(const std::vector<TARGETING::AttributeTank::Attribute>&
+ i_attributeList)
+{
+ TRACFCOMP(g_trac_runtime,
+ ENTER_MRK"sendAttributes - number of attributes to send %d",
+ i_attributeList.size());
+
+ // Handle to error log
+ errlHndl_t l_err{nullptr};
+
+ // Handles to the firmware messages
+ hostInterfaces::hbrt_fw_msg *l_fwRequestMsg{nullptr}; // request message
+ hostInterfaces::hbrt_fw_msg *l_fwResponseMsg{nullptr}; // response message
+
+ do
+ {
+ // If caller passes in an empty list, then nothing to do
+ if (!i_attributeList.size())
+ {
+ TRACFCOMP(g_trac_runtime, "sendAttributes: attribute list is "
+ "empty,nothing to do ...");
+ break;
+ }
+
+ // Make sure we have all of our function pointers setup right
+ if ((nullptr == g_hostInterfaces) ||
+ (nullptr == g_hostInterfaces->firmware_request))
+ {
+ TRACFCOMP(g_trac_runtime, ERR_MRK"sendAttributes: "
+ "Hypervisor firmware_request interface not linked");
+
+ /*@
+ * @errortype
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_RT_FIRMWARE_REQUEST
+ * @reasoncode RC_FW_REQUEST_RT_NULL_PTR
+ * @userdata1 Number of Attributes to serialize and send
+ * @devdesc Hypervisor firmware request interface not linked
+ * @custdesc Internal firmware error
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ RUNTIME::MOD_RT_FIRMWARE_REQUEST,
+ RUNTIME::RC_FW_REQUEST_RT_NULL_PTR,
+ i_attributeList.size(),
+ 0,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+
+ break;
+ }
+
+ /// Calculate the size requirements needed to serialize
+ /// the Attribute info
+ // Aggregate the size of the incoming Attributes
+ uint32_t l_aggregatedAttributeSize(0);
+ for (auto l_attribute: i_attributeList)
+ {
+ l_aggregatedAttributeSize += l_attribute.getSize();
+ }
+
+ // Combine the size of the AttributeSetter_t itself to the size of
+ // incoming Attributes to get the full size requirement needed
+ uint32_t l_dataSize(sizeof(AttributeSetter_t) +
+ l_aggregatedAttributeSize);
+
+ // Create and initialize to zero a few needed variables
+ uint32_t l_fullFspDataSize(0);
+ uint64_t l_fwRequestMsgSize(0), l_fwResponseMsgSize(0);
+
+ // Create the dynamic firmware messages
+ if (!createGenericFspMsg(l_dataSize,
+ l_fullFspDataSize,
+ l_fwRequestMsgSize,
+ l_fwRequestMsg,
+ l_fwResponseMsgSize,
+ l_fwResponseMsg) )
+ {
+ TRACFCOMP(g_trac_runtime, ERR_MRK"sendAttributes: "
+ "Unable to allocate firmware request messages");
+
+ /*@
+ * @errortype
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_SEND_ATTRIBUTES_TO_FSP
+ * @reasoncode RC_NULL_FIRMWARE_MSG_PTR
+ * @userdata1 Number of Attributes to serialize and send
+ * @devdesc Unable to allocate firmware request messages
+ * @custdesc Internal firmware error
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ RUNTIME::MOD_SEND_ATTRIBUTES_TO_FSP,
+ RUNTIME::RC_NULL_FIRMWARE_MSG_PTR,
+ i_attributeList.size(),
+ 0,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+
+ break;
+ }
+
+ // Populate the 'message queue' and 'message type' for this message
+ l_fwRequestMsg->generic_msg.msgq = MBOX::FSP_NVDIMM_KEYS_MSGQ_ID;
+ l_fwRequestMsg->generic_msg.msgType =
+ GenericFspMboxMessage_t::MSG_ATTR_WRITE_OP;
+
+ // Create a useful struct to populate the generic_msg::data field
+ AttributeSetter_t* l_attributeSetter =
+ reinterpret_cast<AttributeSetter_t*>
+ (&(l_fwRequestMsg->generic_msg.data));
+
+ // Initialize the AttributeSetter to default values
+ l_attributeSetter->initialize();
+
+ // The number of attributes being copied can be obtained from
+ // size of the attrbute input list
+ l_attributeSetter->iv_numAttributes = i_attributeList.size();
+
+ // Retrieve the individual attributes (header and value)
+ // Create a useful struct to poulate attribute data
+ uint8_t* l_attributeData = l_attributeSetter->iv_attrData;
+ uint32_t l_sizeOfDataCopied(0);
+
+ // Iterate thru the attribute list and serialize the attributes
+ for (const auto & l_attribute: i_attributeList)
+ {
+ if (l_aggregatedAttributeSize >= l_attribute.getSize())
+ {
+ l_sizeOfDataCopied = l_attribute.serialize(
+ l_attributeData, l_aggregatedAttributeSize);
+
+ if (!l_sizeOfDataCopied)
+ {
+ TRACFCOMP(g_trac_runtime, ERR_MRK"sendAttributes: "
+ "Serialization of an Attribute failed, "
+ "should never happen")
+
+ /*@
+ * @errortype
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_SEND_ATTRIBUTES_TO_FSP
+ * @reasoncode RC_SERIALIZE_ATTRIBUTE_FAILED
+ * @userdata1 Number of Attributes to serialize and send
+ * @devdesc Serialization of an Attribute Failed
+ * @custdesc Internal firmware error
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ RUNTIME::MOD_SEND_ATTRIBUTES_TO_FSP,
+ RUNTIME::RC_SERIALIZE_ATTRIBUTE_FAILED,
+ i_attributeList.size(),
+ 0,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+
+ break;
+ } // end if (!l_sizeOfDataCopied)
+ }
+ else
+ {
+ TRACFCOMP(g_trac_runtime, ERR_MRK"sendAttributes: "
+ "Miscalculation of aggregated size of attributes, "
+ "should never happen")
+
+ /*@
+ * @errortype
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_SEND_ATTRIBUTES_TO_FSP
+ * @reasoncode RC_NO_SPACE_FOR_ATTRIBUTE_SERIALIZATION
+ * @userdata1 Number of Attributes to serialize and send
+ * @devdesc Serialization data of Attribute to large
+ * for given buffer
+ * @custdesc Internal firmware error
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ RUNTIME::MOD_SEND_ATTRIBUTES_TO_FSP,
+ RUNTIME::RC_NO_SPACE_FOR_ATTRIBUTE_SERIALIZATION,
+ i_attributeList.size(),
+ 0,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+
+ break;
+ }
+
+ // Decrement/increment our counters/pointers
+ l_aggregatedAttributeSize -= l_sizeOfDataCopied;
+ l_attributeData += l_sizeOfDataCopied;
+ } // end for (const auto & l_attribute: i_attributeList)
+
+ // Make the firmware_request call
+ l_err = firmware_request_helper(l_fwRequestMsgSize,
+ l_fwRequestMsg,
+ &l_fwResponseMsgSize,
+ l_fwResponseMsg);
+ } while (0);
+
+ // Release the firmware messages and set to NULL
+ delete []l_fwRequestMsg;
+ delete []l_fwResponseMsg;
+ l_fwRequestMsg = l_fwResponseMsg = nullptr;
+
+ TRACFCOMP(g_trac_runtime, EXIT_MRK"sendAttributes - exit with %s",
+ (nullptr == l_err ? "no error" : "error"));
+
+
+ return l_err;
+}
OpenPOWER on IntegriCloud