Refactoring: Firmware image write data command.
Updated firmware write data command as per new design.
Tested:
Tested firmware update utility via KCS interface
Signed-off-by: Rajashekar Gade Reddy <raja.sekhar.reddy.gade@linux.intel.com>
Change-Id: I59bd15f639634cf34a9d188ce62cc6529fe038fb
diff --git a/src/firmware-update.cpp b/src/firmware-update.cpp
index b4c7608..6bd057a 100644
--- a/src/firmware-update.cpp
+++ b/src/firmware-update.cpp
@@ -35,7 +35,8 @@
namespace firmware
{
constexpr Cmd cmdGetFwVersionInfo = 0x20;
-constexpr ipmi::Cmd cmdFwGetRootCertData = 0x25;
+constexpr Cmd cmdFwGetRootCertData = 0x25;
+constexpr Cmd cmdFwImageWriteData = 0x2c;
} // namespace firmware
} // namespace ipmi
@@ -1563,38 +1564,49 @@
}
#endif
-static ipmi_ret_t ipmi_firmware_write_data(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
- ipmi_request_t request,
- ipmi_response_t response,
- ipmi_data_len_t data_len,
- ipmi_context_t context)
+ipmi::RspType<uint32_t>
+ ipmiFwImageWriteData(const std::vector<uint8_t> &writeData)
{
- if (DEBUG)
- std::cerr << "write fw data (" << *data_len << " bytes)\n";
+ const uint8_t ccCmdNotSupportedInPresentState = 0xD5;
+ size_t writeDataLen = writeData.size();
- auto bytes_in = *data_len;
- *data_len = 0;
+ if (!writeDataLen)
+ {
+ return ipmi::responseReqDataLenInvalid();
+ }
+
if (fw_update_status.state() != fw_update_status_cache::FW_STATE_DOWNLOAD)
- return IPMI_CC_INVALID;
+ {
+ phosphor::logging::log<phosphor::logging::level::DEBUG>(
+ "Invalid firmware update state.");
+ return ipmi::response(ccCmdNotSupportedInPresentState);
+ }
std::ofstream out(FIRMWARE_BUFFER_FILE,
std::ofstream::binary | std::ofstream::app);
if (!out)
{
- return IPMI_CC_UNSPECIFIED_ERROR;
+ phosphor::logging::log<phosphor::logging::level::DEBUG>(
+ "Error while opening file.");
+ return ipmi::responseUnspecifiedError();
}
uint64_t fileDataLen = out.tellp();
- if (fileDataLen > FIRMWARE_BUFFER_MAX_SIZE)
+
+ if ((fileDataLen + writeDataLen) > FIRMWARE_BUFFER_MAX_SIZE)
{
- return IPMI_CC_INVALID_FIELD_REQUEST;
+ phosphor::logging::log<phosphor::logging::level::DEBUG>(
+ "Firmware image size exceeds the limit");
+ return ipmi::responseInvalidFieldRequest();
}
- auto data = reinterpret_cast<uint8_t *>(request);
- out.write(reinterpret_cast<char *>(data), bytes_in);
+
+ const char *data = reinterpret_cast<const char *>(writeData.data());
+ out.write(data, writeDataLen);
out.close();
+
if (xfer_hash_check)
{
- xfer_hash_check->hash({data, data + bytes_in});
+ xfer_hash_check->hash(writeData);
}
#ifdef INTEL_PFR_ENABLED
@@ -1612,7 +1624,8 @@
/* Get the PFR block 0 data and read the uploaded image
* information( Image type, length etc) */
- if ((fileDataLen >= sizeof(PFRImageBlock0)) && (!block0Mapped))
+ if (((fileDataLen + writeDataLen) >= sizeof(PFRImageBlock0)) &&
+ (!block0Mapped))
{
struct PFRImageBlock0 block0Data = {0};
@@ -1626,7 +1639,9 @@
/* Validate the magic number */
if (magicNum != perBlock0MagicNum)
{
- return IPMI_CC_INVALID_FIELD_REQUEST;
+ phosphor::logging::log<phosphor::logging::level::DEBUG>(
+ "PFR image magic number not matched");
+ return ipmi::responseInvalidFieldRequest();
}
// Note:imgLength, imgType and block0Mapped are in global scope, as
// these are used in cascaded updates.
@@ -1635,7 +1650,7 @@
block0Mapped = true;
}
#endif // end of INTEL_PFR_ENABLED
- return IPMI_CC_OK;
+ return ipmi::responseSuccess(writeDataLen);
}
struct intc_app_get_buffer_size_resp
@@ -1673,7 +1688,6 @@
static constexpr ipmi_cmd_t IPMI_CMD_FW_UPDATE_CONTROL = 0x29;
static constexpr ipmi_cmd_t IPMI_CMD_FW_GET_STATUS = 0x2a;
static constexpr ipmi_cmd_t IPMI_CMD_FW_SET_FW_UPDATE_OPTIONS = 0x2b;
-static constexpr ipmi_cmd_t IPMI_CMD_FW_IMAGE_WRITE = 0x2c;
static constexpr ipmi_cmd_t IPMI_CMD_FW_GET_TIMESTAMP = 0x2d;
static constexpr ipmi_cmd_t IPMI_CMD_FW_GET_UPDATE_ERR_MSG = 0xe0;
static constexpr ipmi_cmd_t IPMI_CMD_FW_GET_REMOTE_FW_INFO = 0xf0;
@@ -1756,8 +1770,9 @@
NULL, ipmi_firmware_update_options, PRIVILEGE_ADMIN);
// write image data
- ipmi_register_callback(NETFUN_FIRMWARE, IPMI_CMD_FW_IMAGE_WRITE, NULL,
- ipmi_firmware_write_data, PRIVILEGE_ADMIN);
+ ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnFirmware,
+ ipmi::firmware::cmdFwImageWriteData,
+ ipmi::Privilege::Admin, ipmiFwImageWriteData);
// get buffer size is used by fw update (exclusively?)
ipmi_register_callback(NETFUN_INTC_APP, IPMI_CMD_INTC_GET_BUFFER_SIZE, NULL,