firmware-update:Add Support to get fwSecurityVer
Add support to read BKC and SVN version for BMC Active and Recovery
image.
Tested:
Command : ipmitool raw 0x08 0x21 //get firmware security version
Response: 02 01 01 01 02 01 01
Signed-off-by: Punith Nadur Basavarajaiah <punitx.basavarajaiah@intel.com>
Change-Id: I25a801fe00fef3c4c65b57aacb59089be1705d58
diff --git a/src/firmware-update.cpp b/src/firmware-update.cpp
index ec1d14a..d27b8c6 100644
--- a/src/firmware-update.cpp
+++ b/src/firmware-update.cpp
@@ -72,6 +72,13 @@
}
} // namespace ipmi
+static constexpr size_t imageCount = 2;
+std::array<std::array<uint8_t, imageCount>, imageCount> imgFwSecurityVersion = {
+ (0, 0), (0, 0)};
+static constexpr size_t svnActiveVerOffsetInPfm = 0x404;
+static constexpr size_t bkcActiveVerOffsetInPfm = 0x405;
+static constexpr size_t svnRecoveryVerOffsetInPfm = 0x804;
+static constexpr size_t bkcRecoveryVerOffsetInPfm = 0x805;
static constexpr const char* bmcStateIntf = "xyz.openbmc_project.State.BMC";
static constexpr const char* bmcStatePath = "/xyz/openbmc_project/state/bmc0";
static constexpr const char* bmcStateReady =
@@ -888,14 +895,65 @@
return ipmi::responseSuccess(fwVerInfoList.size(), fwVerInfoList);
}
-using fwSecurityVersionInfoType = std::tuple<uint8_t, // ID Tag
- uint8_t, // BKC Version
- uint8_t>; // SVN Version
-ipmi::RspType<uint8_t, std::vector<fwSecurityVersionInfoType>>
+
+std::array<uint8_t, imageCount> getSecurityVersionInfo(const char* mtdDevBuf,
+ size_t svnVerOffsetInPfm,
+ size_t bkcVerOffsetInPfm)
+{
+ constexpr size_t bufLength = 1;
+ std::array<uint8_t, imageCount> fwSecurityVersionBuf = {0}, temp;
+ constexpr uint8_t svnIndexValue = 0x00;
+ constexpr uint8_t bkcIndexValue = 0x01;
+ constexpr uint8_t tempIndexValue = 0x00;
+ try
+ {
+ SPIDev spiDev(mtdDevBuf);
+ spiDev.spiReadData(svnVerOffsetInPfm, bufLength, temp.data());
+ fwSecurityVersionBuf.at(svnIndexValue) = temp.at(tempIndexValue);
+ spiDev.spiReadData(bkcVerOffsetInPfm, bufLength, temp.data());
+ fwSecurityVersionBuf.at(bkcIndexValue) = temp.at(tempIndexValue);
+ }
+ catch (const std::exception& e)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "Exception caught in getSecurityVersionInfo",
+ phosphor::logging::entry("MSG=%s", e.what()));
+ fwSecurityVersionBuf = {0, 0};
+ }
+
+ return fwSecurityVersionBuf;
+}
+
+ipmi::RspType<
+ uint8_t, // device ID
+ uint8_t, // Active Image Value
+ std::array<uint8_t, imageCount>, // Security version for Active Image
+ uint8_t, // recovery Image Value
+ std::array<uint8_t, imageCount>> // Security version for Recovery Image
ipmiGetFwSecurityVersionInfo()
{
- // TODO: Need to add support.
- return ipmi::responseInvalidCommand();
+ static bool cacheFlag = false;
+ constexpr std::array<const char*, imageCount> mtdDevBuf = {
+ bmcActivePfmMTDDev, bmcRecoveryImgMTDDev};
+
+ // To avoid multiple reading from SPI device
+ if (!cacheFlag)
+ {
+ imgFwSecurityVersion[0] = getSecurityVersionInfo(
+ mtdDevBuf[0], svnActiveVerOffsetInPfm, bkcActiveVerOffsetInPfm);
+ imgFwSecurityVersion[1] = getSecurityVersionInfo(
+ mtdDevBuf[1], svnRecoveryVerOffsetInPfm, bkcRecoveryVerOffsetInPfm);
+ cacheFlag = true;
+ }
+
+ constexpr uint8_t ActivePfmMTDDev = 0x00;
+ constexpr uint8_t RecoveryImgMTDDev = 0x01;
+
+ return ipmi::responseSuccess(
+ imageCount, static_cast<uint8_t>(FWDeviceIDTag::bmcActiveImage),
+ imgFwSecurityVersion[ActivePfmMTDDev],
+ static_cast<uint8_t>(FWDeviceIDTag::bmcRecoveryImage),
+ imgFwSecurityVersion[RecoveryImgMTDDev]);
}
ipmi::RspType<std::array<uint8_t, certKeyLen>,