Skip to content

Commit

Permalink
Push ATTR_NVDIMM_ARMED down to FSP to handle MPIPL case
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
dcrowell77 committed Jul 1, 2019
1 parent 710af45 commit 08b6443
Show file tree
Hide file tree
Showing 4 changed files with 356 additions and 275 deletions.
272 changes: 2 additions & 270 deletions src/include/runtime/hbrt_utilities.H
Expand Up @@ -93,282 +93,14 @@ bool createGenericFspMsg(uint32_t i_fspReqPayloadSize,
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
hostInterfaces::hbrt_fw_msg* &o_responseMsg);


/**
* @brief Serializes a list of Attributes to be sent to FSP
*
* @param[in] i_attributeList List of attributes to send to FSP
*
* @return - error, NULL if no error
*/
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;
}
i_attributeList);


#endif //__HOSTBOOT_RUNTIME_INTERFACE_VERSION_ONLY
Expand Down
1 change: 1 addition & 0 deletions src/include/usr/isteps/nvdimm/nvdimmreasoncodes.H
Expand Up @@ -96,6 +96,7 @@ enum nvdimmModuleId
NVDIMM_GET_DARN_NUMBER = 0x2E,
NVDIMM_KEYIFY_RANDOM_NUMBER = 0x2F,
SET_ATTR_NVDIMM_ENCRYPTION_KEYS_FW = 0x30,
SEND_ATTR_NVDIMM_ARMED = 0x31,
};

/**
Expand Down

0 comments on commit 08b6443

Please sign in to comment.