diff --git a/src/include/runtime/hbrt_utilities.H b/src/include/runtime/hbrt_utilities.H index 8068a6b7a1c..2ee2172df41 100644 --- a/src/include/runtime/hbrt_utilities.H +++ b/src/include/runtime/hbrt_utilities.H @@ -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 - (new uint8_t[o_responseMsgSize]); - o_requestMsg = reinterpret_cast - (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& - 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 - (&(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 diff --git a/src/include/usr/isteps/nvdimm/nvdimmreasoncodes.H b/src/include/usr/isteps/nvdimm/nvdimmreasoncodes.H index 040658b402c..3e311fa7337 100644 --- a/src/include/usr/isteps/nvdimm/nvdimmreasoncodes.H +++ b/src/include/usr/isteps/nvdimm/nvdimmreasoncodes.H @@ -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, }; /** diff --git a/src/usr/isteps/nvdimm/nvdimm.C b/src/usr/isteps/nvdimm/nvdimm.C index 4925be6c72b..004aaa68e78 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 (i_val); +#ifdef __HOSTBOOT_RUNTIME + errlHndl_t l_err = nullptr; + // Send attr to HWSV if at runtime AttributeTank::Attribute l_attr = {}; if( !makeAttributeStdArr @@ -2841,13 +2848,18 @@ errlHndl_t notifyNvdimmProtectionChange(Target* i_target, ATTR_NVDIMM_ARMED_type l_armed_state = {}; l_armed_state = l_nvdimm->getAttr(); + // 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(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 + (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 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 f94dab2383c..ce2a1baf686 100644 --- a/src/usr/util/runtime/rt_fwreq_helper.C +++ b/src/usr/util/runtime/rt_fwreq_helper.C @@ -27,6 +27,7 @@ #include // hostInterfaces #include // MOD_RT_FIRMWARE_REQUEST, etc #include // errlCommit +#include // 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 + (new uint8_t[o_responseMsgSize]); + o_requestMsg = reinterpret_cast + (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& + 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 + (&(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; +}