oem-ibm: Sync boot side file with bios attributes
This change adds support to update the boot side file to keep it
in sync with boot side bios attributes
Change-Id: I2bea293500c69a883f400ddaadc436705bbe5ab4
Signed-off-by: Archana Kakani <archana.kakani@ibm.com>
diff --git a/common/types.hpp b/common/types.hpp
index 2c1b319..b61184f 100644
--- a/common/types.hpp
+++ b/common/types.hpp
@@ -4,6 +4,7 @@
#include <bitset>
#include <cstdint>
+#include <functional>
#include <map>
#include <memory>
#include <set>
@@ -234,4 +235,30 @@
} // namespace pdr
+namespace bios
+{
+
+using AttributeName = std::string;
+using AttributeType = std::string;
+using ReadonlyStatus = bool;
+using DisplayName = std::string;
+using Description = std::string;
+using MenuPath = std::string;
+using CurrentValue = std::variant<int64_t, std::string>;
+using DefaultValue = std::variant<int64_t, std::string>;
+using OptionString = std::string;
+using OptionValue = std::variant<int64_t, std::string>;
+using ValueDisplayName = std::string;
+using Option =
+ std::vector<std::tuple<OptionString, OptionValue, ValueDisplayName>>;
+using BIOSTableObj =
+ std::tuple<AttributeType, ReadonlyStatus, DisplayName, Description,
+ MenuPath, CurrentValue, DefaultValue, Option>;
+using BaseBIOSTable = std::map<AttributeName, BIOSTableObj>;
+using PendingObj = std::tuple<AttributeType, CurrentValue>;
+using PendingAttributes = std::map<AttributeName, PendingObj>;
+using Callback = std::function<void()>;
+
+} // namespace bios
+
} // namespace pldm
diff --git a/libpldmresponder/bios.hpp b/libpldmresponder/bios.hpp
index eab143e..d6d7bbb 100644
--- a/libpldmresponder/bios.hpp
+++ b/libpldmresponder/bios.hpp
@@ -92,6 +92,17 @@
Response setBIOSAttributeCurrentValue(const pldm_msg* request,
size_t payloadLength);
+ pldm::responder::oem_bios::Handler* oemBiosHandler = nullptr;
+
+ /** @brief Set OEM bios handler
+ *
+ * @param[in] oemBiosHandler - OEM Bios handler
+ */
+ inline void setOemBiosHandler(pldm::responder::oem_bios::Handler* handler)
+ {
+ biosConfig.setOemBiosHandler(handler);
+ }
+
private:
BIOSConfig biosConfig;
};
diff --git a/libpldmresponder/bios_config.cpp b/libpldmresponder/bios_config.cpp
index cabb0bd..6b1b918 100644
--- a/libpldmresponder/bios_config.cpp
+++ b/libpldmresponder/bios_config.cpp
@@ -522,6 +522,10 @@
auto method = bus.new_method_call(service.c_str(), biosConfigPath,
dbusProperties, "Set");
std::variant<BaseBIOSTable> value = baseBIOSTableMaps;
+ if (oemBiosHandler)
+ {
+ oemBiosHandler->processOEMBaseBiosTable(baseBIOSTableMaps);
+ }
method.append(biosConfigInterface, biosConfigPropertyName, value);
bus.call_noreply(method, dbusTimeout);
}
diff --git a/libpldmresponder/bios_config.hpp b/libpldmresponder/bios_config.hpp
index 05f960d..db8b303 100644
--- a/libpldmresponder/bios_config.hpp
+++ b/libpldmresponder/bios_config.hpp
@@ -3,6 +3,7 @@
#include "bios_attribute.hpp"
#include "bios_table.hpp"
#include "common/instance_id.hpp"
+#include "common/types.hpp"
#include "oem_handler.hpp"
#include "platform_config.hpp"
#include "requester/handler.hpp"
@@ -12,7 +13,6 @@
#include <nlohmann/json.hpp>
#include <phosphor-logging/lg2.hpp>
-#include <functional>
#include <iostream>
#include <memory>
#include <optional>
@@ -38,27 +38,7 @@
OneOf
};
-using AttributeName = std::string;
-using AttributeType = std::string;
-using ReadonlyStatus = bool;
-using DisplayName = std::string;
-using Description = std::string;
-using MenuPath = std::string;
-using CurrentValue = std::variant<int64_t, std::string>;
-using DefaultValue = std::variant<int64_t, std::string>;
-using OptionString = std::string;
-using OptionValue = std::variant<int64_t, std::string>;
-using ValueDisplayName = std::string;
-using Option =
- std::vector<std::tuple<OptionString, OptionValue, ValueDisplayName>>;
-using BIOSTableObj =
- std::tuple<AttributeType, ReadonlyStatus, DisplayName, Description,
- MenuPath, CurrentValue, DefaultValue, Option>;
-using BaseBIOSTable = std::map<AttributeName, BIOSTableObj>;
-
-using PendingObj = std::tuple<AttributeType, CurrentValue>;
-using PendingAttributes = std::map<AttributeName, PendingObj>;
-using Callback = std::function<void()>;
+using namespace pldm::bios;
/** @class BIOSConfig
* @brief Manager BIOS Attributes
@@ -140,6 +120,15 @@
*/
void initBIOSAttributes(const std::string& sysType, bool registerService);
+ /** @brief Set OEM bios handler
+ *
+ * @param[in] oemBiosHandler - OEM Bios handler
+ */
+ inline void setOemBiosHandler(pldm::responder::oem_bios::Handler* handler)
+ {
+ oemBiosHandler = handler;
+ }
+
private:
/** @enum Index into the fields in the BaseBIOSTable
*/
@@ -159,6 +148,7 @@
const fs::path tableDir;
pldm::utils::DBusHandler* const dbusHandler;
BaseBIOSTable baseBIOSTableMaps;
+ pldm::responder::oem_bios::Handler* oemBiosHandler = nullptr;
/** @brief MCTP EID of host firmware */
uint8_t eid;
diff --git a/libpldmresponder/oem_handler.hpp b/libpldmresponder/oem_handler.hpp
index d8ca132..9e131ee 100644
--- a/libpldmresponder/oem_handler.hpp
+++ b/libpldmresponder/oem_handler.hpp
@@ -185,6 +185,26 @@
} // namespace oem_utils
+namespace oem_bios
+{
+using namespace pldm::utils;
+
+class Handler : public CmdHandler
+{
+ public:
+ Handler() {}
+
+ /** @brief Process BaseBiosTable and update the locally cached attributes
+ * @param[in] biosTable - Bios table
+ */
+ virtual void processOEMBaseBiosTable(
+ const pldm::bios::BaseBIOSTable& biosTable) = 0;
+
+ virtual ~Handler() = default;
+};
+
+} // namespace oem_bios
+
} // namespace responder
} // namespace pldm
diff --git a/oem/ibm/libpldmresponder/inband_code_update.cpp b/oem/ibm/libpldmresponder/inband_code_update.cpp
index 855258d..d031855 100644
--- a/oem/ibm/libpldmresponder/inband_code_update.cpp
+++ b/oem/ibm/libpldmresponder/inband_code_update.cpp
@@ -24,6 +24,7 @@
namespace responder
{
using namespace oem_ibm_platform;
+using namespace oem_ibm_bios;
/** @brief Directory where the lid files without a header are stored */
auto lidDirPath = fs::path(LID_STAGING_DIR) / "lid";
@@ -40,9 +41,6 @@
/** @brief The file name of the hostfw image */
constexpr auto hostfwImageName = "image-hostfw";
-/** @brief The filename of the file where bootside data will be saved */
-constexpr auto bootSideFileName = "bootSide";
-
/** @brief The path to the code update tarball file */
auto tarImagePath = fs::path(imageDirPath) / tarImageName;
@@ -59,9 +57,6 @@
/** @brief Next boot side */
constexpr auto bootNextSideAttrName = "fw_boot_side";
-/** @brief The filepath of file where bootside data will be saved */
-auto bootSideDirPath = fs::path("/var/lib/pldm/") / bootSideFileName;
-
std::string CodeUpdate::fetchCurrentBootSide()
{
return currBootSide;
@@ -202,6 +197,7 @@
static constexpr auto activeObjPath =
"/xyz/openbmc_project/software/active";
static constexpr auto propIntf = "org.freedesktop.DBus.Properties";
+ static constexpr auto pathIntf = "xyz.openbmc_project.Common.FilePath";
auto& bus = dBusIntf->getBus();
try
@@ -215,6 +211,9 @@
reply.read(paths);
runningVersion = std::get<std::vector<std::string>>(paths)[0];
+ auto runningPathPropValue = dBusIntf->getDbusPropertyVariant(
+ runningVersion.c_str(), "Path", pathIntf);
+ const auto& runningPath = std::get<std::string>(runningPathPropValue);
auto method1 =
bus.new_method_call(mapperService, activeObjPath, propIntf, "Get");
@@ -249,12 +248,13 @@
else
{
info(
- "Boot side is not initialized yet, so setting default value");
+ "Boot side is not initialized yet, so setting default value(Temp). Request was ignored to set the Boot side to {SIDE}",
+ "SIDE", nextBootSideBiosValue);
nextBootSideBiosValue = "Temp";
}
pldmBootSideData.current_boot_side = nextBootSideBiosValue;
pldmBootSideData.next_boot_side = nextBootSideBiosValue;
- pldmBootSideData.running_version_object = runningVersion;
+ pldmBootSideData.running_version_object = runningPath;
writeBootSideFile(pldmBootSideData);
biosAttrList.emplace_back(std::make_pair(
@@ -270,11 +270,11 @@
else
{
pldm_boot_side_data pldmBootSideData = readBootSideFile();
- if (pldmBootSideData.running_version_object != runningVersion)
+ if (pldmBootSideData.running_version_object != runningPath)
{
info(
"BMC have booted with the new image runningPath={RUNN_PATH}",
- "RUNN_PATH", runningVersion.c_str());
+ "RUNN_PATH", runningPath.c_str());
info("Previous Image was: {RUNN_VERS}", "RUNN_VERS",
pldmBootSideData.running_version_object);
auto current_boot_side =
@@ -282,7 +282,7 @@
: "Temp");
pldmBootSideData.current_boot_side = current_boot_side;
pldmBootSideData.next_boot_side = current_boot_side;
- pldmBootSideData.running_version_object = runningVersion;
+ pldmBootSideData.running_version_object = runningPath;
writeBootSideFile(pldmBootSideData);
biosAttrList.emplace_back(std::make_pair(
bootSideAttrName,
@@ -489,12 +489,12 @@
{
try
{
- fs::create_directories(bootSideDirPath.parent_path());
+ fs::create_directories(fs::path(bootSideDirPath).parent_path());
std::ofstream writeFile(bootSideDirPath, std::ios::out);
if (!writeFile.is_open())
{
error("Failed to open bootside file {FILE} for writing", "FILE",
- bootSideDirPath.string());
+ bootSideDirPath);
return;
}
@@ -527,7 +527,7 @@
{
pldm_boot_side_data pldmBootSideDataRead{};
- std::ifstream readFile(bootSideDirPath.string(), std::ios::in);
+ std::ifstream readFile(bootSideDirPath, std::ios::in);
if (!readFile)
{
@@ -551,6 +551,7 @@
void CodeUpdate::processPriorityChangeNotification(
const DbusChangedProps& chProperties)
{
+ error("Processing priority change notification");
static constexpr auto propName = "Priority";
const auto it = chProperties.find(propName);
if (it == chProperties.end())
@@ -558,8 +559,31 @@
return;
}
uint8_t newVal = std::get<uint8_t>(it->second);
- nextBootSide = (newVal == 0) ? currBootSide
- : ((currBootSide == Tside) ? Pside : Tside);
+
+ pldm_boot_side_data pldmBootSideData = readBootSideFile();
+ pldmBootSideData.next_boot_side =
+ (newVal == 0)
+ ? pldmBootSideData.current_boot_side
+ : ((pldmBootSideData.current_boot_side == "Temp") ? "Perm"
+ : "Temp");
+ writeBootSideFile(pldmBootSideData);
+ nextBootSide = (pldmBootSideData.next_boot_side == "Temp" ? Tside : Pside);
+ std::string currNextBootSide;
+ auto attributeValue = getBiosAttrValue<std::string>(bootNextSideAttrName);
+ if (attributeValue.has_value())
+ {
+ currNextBootSide = attributeValue.value();
+ }
+
+ if (currNextBootSide == nextBootSide)
+ {
+ return;
+ }
+ PendingAttributesList biosAttrList;
+ biosAttrList.push_back(std::make_pair(
+ bootNextSideAttrName,
+ std::make_tuple(EnumAttribute, pldmBootSideData.next_boot_side)));
+ setBiosAttr(biosAttrList);
}
void CodeUpdate::setOemPlatformHandler(
diff --git a/oem/ibm/libpldmresponder/oem_ibm_handler.hpp b/oem/ibm/libpldmresponder/oem_ibm_handler.hpp
index 52769ab..380a256 100644
--- a/oem/ibm/libpldmresponder/oem_ibm_handler.hpp
+++ b/oem/ibm/libpldmresponder/oem_ibm_handler.hpp
@@ -3,6 +3,7 @@
#include "collect_slot_vpd.hpp"
#include "common/utils.hpp"
#include "inband_code_update.hpp"
+#include "libpldmresponder/bios_config.hpp"
#include "libpldmresponder/oem_handler.hpp"
#include "libpldmresponder/pdr_utils.hpp"
#include "libpldmresponder/platform.hpp"
@@ -24,26 +25,11 @@
{
using ObjectPath = std::string;
using AssociatedEntityMap = std::map<ObjectPath, pldm_entity>;
+using namespace pldm::bios;
+using namespace pldm::utils;
+
namespace oem_ibm_platform
{
-using AttributeName = std::string;
-using AttributeType = std::string;
-using ReadonlyStatus = bool;
-using DisplayName = std::string;
-using Description = std::string;
-using MenuPath = std::string;
-using CurrentValue = std::variant<int64_t, std::string>;
-using DefaultValue = std::variant<int64_t, std::string>;
-using OptionString = std::string;
-using OptionValue = std::variant<int64_t, std::string>;
-using Option = std::vector<std::tuple<OptionString, OptionValue>>;
-using BIOSTableObj =
- std::tuple<AttributeType, ReadonlyStatus, DisplayName, Description,
- MenuPath, CurrentValue, DefaultValue, Option>;
-using BaseBIOSTable = std::map<AttributeName, BIOSTableObj>;
-using PendingObj = std::tuple<AttributeType, CurrentValue>;
-using PendingAttributes = std::map<AttributeName, PendingObj>;
-
constexpr uint16_t ENTITY_INSTANCE_0 = 0;
constexpr uint16_t ENTITY_INSTANCE_1 = 1;
@@ -455,6 +441,59 @@
} // namespace oem_ibm_platform
+namespace oem_ibm_bios
+{
+/** @brief The file where bootside data will be saved */
+constexpr auto bootSideDirPath = "/var/lib/pldm/bootSide";
+
+class Handler : public oem_bios::Handler
+{
+ public:
+ Handler() {}
+
+ void processOEMBaseBiosTable(const BaseBIOSTable& biosTable)
+ {
+ for (const auto& [attrName, biostabObj] : biosTable)
+ {
+ // The additional check to see if /var/lib/pldm/bootSide file exists
+ // is added to make sure we are doing the fw_boot_side setting after
+ // the base bios table is initialised.
+ if ((attrName == "fw_boot_side") && fs::exists(bootSideDirPath))
+ {
+ PendingAttributesList biosAttrList;
+
+ std::string nextBootSide =
+ std::get<std::string>(std::get<5>(biostabObj));
+
+ std::string currNextBootSide;
+ auto attributeValue =
+ getBiosAttrValue<std::string>("fw_boot_side");
+
+ if (attributeValue.has_value())
+ {
+ currNextBootSide = attributeValue.value();
+ }
+ else
+ {
+ info(
+ "Boot side is not initialized yet, so setting default value");
+ currNextBootSide = "Temp";
+ }
+
+ if (currNextBootSide != nextBootSide)
+ {
+ biosAttrList.emplace_back(std::make_pair(
+ attrName,
+ std::make_tuple(EnumAttribute, nextBootSide)));
+ setBiosAttr(biosAttrList);
+ }
+ }
+ }
+ }
+};
+
+} // namespace oem_ibm_bios
+
} // namespace responder
} // namespace pldm
diff --git a/pldmd/oem_ibm.hpp b/pldmd/oem_ibm.hpp
index 3f5802b..e3fbddf 100644
--- a/pldmd/oem_ibm.hpp
+++ b/pldmd/oem_ibm.hpp
@@ -52,6 +52,7 @@
* @param[in] platformHandler - platformHandler handler
* @param[in] fruHandler - fruHandler handler
* @param[in] baseHandler - baseHandler handler
+ * @param[in] biosHandler - biosHandler handler
* @param[in] reqHandler - reqHandler handler
*/
explicit OemIBM(
@@ -62,6 +63,7 @@
responder::platform::Handler* platformHandler,
responder::fru::Handler* fruHandler,
responder::base::Handler* baseHandler,
+ responder::bios::Handler* biosHandler,
pldm::requester::Handler<pldm::requester::Request>* reqHandler) :
dBusIntf(dBusIntf), mctp_fd(mctp_fd), mctp_eid(mctp_eid), repo(repo),
instanceIdDb(instanceIdDb), event(event), invoker(invoker),
@@ -73,6 +75,9 @@
createOemIbmFruHandler();
oemIbmFruHandler->setIBMFruHandler(fruHandler);
+ createOemIbmBiosHandler();
+ biosHandler->setOemBiosHandler(oemIbmBiosHandler.get());
+
createCodeUpdate();
createSlotHandler();
createOemPlatformHandler();
@@ -119,6 +124,13 @@
instanceIdDb, event, reqHandler);
}
+ /** @brief Method for creating oemIbmBiosHandler */
+ void createOemIbmBiosHandler()
+ {
+ oemIbmBiosHandler =
+ std::make_unique<responder::oem_ibm_bios::Handler>();
+ }
+
/** @brief Method for creating oemIbmPlatformHandler */
void createOemIbmPlatformHandler()
{
@@ -211,6 +223,9 @@
/** @brief oem IBM Fru handler*/
pldm::responder::oem_ibm_fru::Handler* oemIbmFruHandler = nullptr;
+ /** @brief pointer to the oem IBM Bios handler*/
+ std::unique_ptr<responder::oem_bios::Handler> oemIbmBiosHandler{};
+
std::unique_ptr<pldm::led::HostLampTest> hostLampTest;
/** @brief oem IBM Utils handler*/
diff --git a/pldmd/pldmd.cpp b/pldmd/pldmd.cpp
index ba448e6..ac9db67 100644
--- a/pldmd/pldmd.cpp
+++ b/pldmd/pldmd.cpp
@@ -307,7 +307,7 @@
platformConfigHandler.get(), &reqHandler, event, true,
addOnEventHandlers);
- auto biosHandler = std::make_unique<bios::Handler>(
+ auto biosHandler = std::make_unique<pldm::responder::bios::Handler>(
pldmTransport.getEventSource(), hostEID, &instanceIdDb, &reqHandler,
platformConfigHandler.get(), requestPLDMServiceName);
@@ -326,7 +326,7 @@
&dbusHandler, pldmTransport.getEventSource(), hostEID, pdrRepo.get(),
instanceIdDb, event, invoker, hostPDRHandler.get(),
platformHandler.get(), fruHandler.get(), baseHandler.get(),
- &reqHandler);
+ biosHandler.get(), &reqHandler);
#endif
invoker.registerHandler(PLDM_BIOS, std::move(biosHandler));