IPMI OEM BIC - Get Bios Flash Size
Register an IPMI command handler with NetFn: 0x38 Cmd: 0x19
send this command to BIC through IPMB to get the Bios flash
size.
TESTED : Verified in YosemiteV2 platform and able to get
bios flash size.
Signed-off-by: Kumar Thangavel <thangavel.k@hcl.com>
Change-Id: I8a82f2495c1c7d4fefb49de471052cd9d740e75d
diff --git a/include/biccommands.hpp b/include/biccommands.hpp
index 8702380..1520702 100644
--- a/include/biccommands.hpp
+++ b/include/biccommands.hpp
@@ -5,8 +5,12 @@
CMD_OEM_GET_BIC_GPIO_STATE = 0x3,
CMD_OEM_SEND_POST_BUFFER_TO_BMC = 0x8,
CMD_OEM_SET_HOST_POWER_STATE = 0x0C,
+ CMD_OEM_GET_FLASH_SIZE = 0x19,
};
+// Flash size response length
+constexpr uint8_t flashSizeRespLen = 0x7;
+
const char* dbusObj = "/xyz/openbmc_project/state/boot/raw";
const char* dbusService = "xyz.openbmc_project.State.Boot.Raw";
diff --git a/include/commandutils.hpp b/include/commandutils.hpp
index d51c0e8..b9290d0 100644
--- a/include/commandutils.hpp
+++ b/include/commandutils.hpp
@@ -23,6 +23,7 @@
static constexpr bool debug = false;
using IanaType = std::array<uint8_t, 3>;
+using flashSize = std::array<uint8_t, 4>;
static constexpr IanaType iana = {0x15, 0xA0, 0x0}; // Meta's IANA
diff --git a/src/biccommands.cpp b/src/biccommands.cpp
index 13907e1..91416ad 100644
--- a/src/biccommands.cpp
+++ b/src/biccommands.cpp
@@ -29,6 +29,9 @@
namespace ipmi
{
+int sendBicCmd(uint8_t, uint8_t, uint8_t, std::vector<uint8_t>&,
+ std::vector<uint8_t>&);
+
using namespace phosphor::logging;
#ifdef BIC_ENABLED
@@ -206,6 +209,59 @@
return ipmi::responseSuccess(reqIana);
}
+//----------------------------------------------------------------------
+// ipmiOemGetBiosFlashSize (CMD_OEM_GET_FLASH_SIZE)
+// This Function will return the bios flash size
+// netfn=0x38 and cmd=0x19 send the response back to the sender.
+//----------------------------------------------------------------------
+
+ipmi::RspType<IanaType, flashSize>
+ ipmiOemGetBiosFlashSize(ipmi::Context::ptr ctx, IanaType ianaReq,
+ uint8_t target)
+{
+ if (iana != ianaReq)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "Invalid IANA ID length received");
+ return ipmi::responseReqDataLenInvalid();
+ }
+
+ std::vector<uint8_t> respData;
+ uint8_t bicAddr = (uint8_t)ctx->hostIdx << 2;
+ std::vector<uint8_t> reqData(ianaReq.begin(), ianaReq.end());
+ reqData.emplace_back(target);
+
+ if (sendBicCmd(ctx->netFn, ctx->cmd, bicAddr, reqData, respData))
+ {
+ return ipmi::responseUnspecifiedError();
+ }
+
+ if (respData.size() != flashSizeRespLen)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "Invalid Response Data length received");
+ return ipmi::responseReqDataLenInvalid();
+ }
+
+ IanaType ianaResp;
+ std::copy_n(respData.begin(), ianaResp.size(), ianaResp.begin());
+
+ if (iana != ianaResp)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "Invalid IANA ID received");
+ return ipmi::responseInvalidCommand();
+ }
+
+ flashSize flashResp;
+ std::vector<uint8_t>::iterator respDataIter = respData.begin();
+ std::advance(respDataIter, ianaResp.size());
+ std::copy_n(respDataIter, flashResp.size(), flashResp.begin());
+
+ // sending the success response.
+ return ipmi::responseSuccess(ianaResp, flashResp);
+}
+
[[maybe_unused]] static void registerBICFunctions(void)
{
@@ -227,6 +283,9 @@
ipmi::prioOpenBmcBase, ipmi::netFnOemFive,
static_cast<Cmd>(fb_bic_cmds::CMD_OEM_SET_HOST_POWER_STATE),
ipmi::Privilege::User, ipmiOemSetHostPowerState);
+ ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnOemFive,
+ static_cast<Cmd>(fb_bic_cmds::CMD_OEM_GET_FLASH_SIZE),
+ ipmi::Privilege::User, ipmiOemGetBiosFlashSize);
return;
}