PLDM: System specific BIOS attributes
This commit adds code to populate BIOS attributes
based on the system type that is the platform.
The BIOS Jsons are installed based on the platform/
system type. The system type is populated by entity
manager.
TESTED on hardware across different platform/system type.
On systems where the compatible system interface is not
implemented or entity manager not running, then the BIOS
Jsons with default values are installed.
Signed-off-by: Sagar Srinivas <sagar.srinivas@ibm.com>
Change-Id: I179dad34537ed0d1fb263584d687a1b8cb64c335
diff --git a/libpldmresponder/bios.cpp b/libpldmresponder/bios.cpp
index 4c46b9a..986e74a 100644
--- a/libpldmresponder/bios.cpp
+++ b/libpldmresponder/bios.cpp
@@ -70,9 +70,10 @@
DBusHandler dbusHandler;
Handler::Handler(int fd, uint8_t eid, pldm::InstanceIdDb* instanceIdDb,
- pldm::requester::Handler<pldm::requester::Request>* handler) :
+ pldm::requester::Handler<pldm::requester::Request>* handler,
+ pldm::responder::oem_bios::Handler* oemBiosHandler) :
biosConfig(BIOS_JSONS_DIR, BIOS_TABLES_DIR, &dbusHandler, fd, eid,
- instanceIdDb, handler)
+ instanceIdDb, handler, oemBiosHandler)
{
biosConfig.removeTables();
biosConfig.buildTables();
diff --git a/libpldmresponder/bios.hpp b/libpldmresponder/bios.hpp
index 517231f..bb075d2 100644
--- a/libpldmresponder/bios.hpp
+++ b/libpldmresponder/bios.hpp
@@ -33,9 +33,11 @@
* @param[in] eid - MCTP EID of host firmware
* @param[in] instanceIdDb - pointer to an InstanceIdDb object
* @param[in] handler - PLDM request handler
+ * @param[in] systemConfig - pointer to SystemConfig object
*/
Handler(int fd, uint8_t eid, pldm::InstanceIdDb* instanceIdDb,
- pldm::requester::Handler<pldm::requester::Request>* handler);
+ pldm::requester::Handler<pldm::requester::Request>* handler,
+ pldm::responder::oem_bios::Handler* oemBiosHandler);
/** @brief Handler for GetDateTime
*
diff --git a/libpldmresponder/bios_config.cpp b/libpldmresponder/bios_config.cpp
index a9d7723..094b5e5 100644
--- a/libpldmresponder/bios_config.cpp
+++ b/libpldmresponder/bios_config.cpp
@@ -44,12 +44,21 @@
BIOSConfig::BIOSConfig(
const char* jsonDir, const char* tableDir, DBusHandler* const dbusHandler,
int fd, uint8_t eid, pldm::InstanceIdDb* instanceIdDb,
- pldm::requester::Handler<pldm::requester::Request>* handler) :
+ pldm::requester::Handler<pldm::requester::Request>* handler,
+ pldm::responder::oem_bios::Handler* oemBiosHandler) :
jsonDir(jsonDir),
tableDir(tableDir), dbusHandler(dbusHandler), fd(fd), eid(eid),
- instanceIdDb(instanceIdDb), handler(handler)
+ instanceIdDb(instanceIdDb), handler(handler), oemBiosHandler(oemBiosHandler)
{
+ if (oemBiosHandler)
+ {
+ auto systemType = oemBiosHandler->getPlatformName();
+ if (systemType.has_value())
+ {
+ sysType = systemType.value();
+ }
+ }
fs::create_directories(tableDir);
constructAttributes();
listenPendingAttributes();
@@ -473,13 +482,13 @@
void BIOSConfig::constructAttributes()
{
- load(jsonDir / stringJsonFile, [this](const Json& entry) {
+ load(jsonDir / sysType / stringJsonFile, [this](const Json& entry) {
constructAttribute<BIOSStringAttribute>(entry);
});
- load(jsonDir / integerJsonFile, [this](const Json& entry) {
+ load(jsonDir / sysType / integerJsonFile, [this](const Json& entry) {
constructAttribute<BIOSIntegerAttribute>(entry);
});
- load(jsonDir / enumJsonFile, [this](const Json& entry) {
+ load(jsonDir / sysType / enumJsonFile, [this](const Json& entry) {
constructAttribute<BIOSEnumAttribute>(entry);
});
}
@@ -561,9 +570,9 @@
strings.emplace(entry.at("attribute_name"));
};
- load(jsonDir / stringJsonFile, handler);
- load(jsonDir / integerJsonFile, handler);
- load(jsonDir / enumJsonFile, [&strings](const Json& entry) {
+ load(jsonDir / sysType / stringJsonFile, handler);
+ load(jsonDir / sysType / integerJsonFile, handler);
+ load(jsonDir / sysType / enumJsonFile, [&strings](const Json& entry) {
strings.emplace(entry.at("attribute_name"));
auto possibleValues = entry.at("possible_values");
for (auto& pv : possibleValues)
diff --git a/libpldmresponder/bios_config.hpp b/libpldmresponder/bios_config.hpp
index 6e27642..2bd7c72 100644
--- a/libpldmresponder/bios_config.hpp
+++ b/libpldmresponder/bios_config.hpp
@@ -2,6 +2,7 @@
#include "bios_attribute.hpp"
#include "bios_table.hpp"
+#include "oem_handler.hpp"
#include "pldmd/instance_id.hpp"
#include "requester/handler.hpp"
@@ -76,12 +77,14 @@
* @param[in] eid - MCTP EID of host firmware
* @param[in] instanceIdDb - pointer to an InstanceIdDb object
* @param[in] handler - PLDM request handler
+ * @param[in] oemBiosHandler - pointer to oem Bios Handler
*/
explicit BIOSConfig(
const char* jsonDir, const char* tableDir,
pldm::utils::DBusHandler* const dbusHandler, int fd, uint8_t eid,
pldm::InstanceIdDb* instanceIdDb,
- pldm::requester::Handler<pldm::requester::Request>* handler);
+ pldm::requester::Handler<pldm::requester::Request>* handler,
+ pldm::responder::oem_bios::Handler* oemBiosHandler);
/** @brief Set attribute value on dbus and attribute value table
* @param[in] entry - attribute value entry
@@ -154,6 +157,9 @@
/** @brief PLDM request handler */
pldm::requester::Handler<pldm::requester::Request>* handler;
+ /** @brief oem Bios Handler*/
+ pldm::responder::oem_bios::Handler* oemBiosHandler;
+
// vector persists all attributes
using BIOSAttributes = std::vector<std::unique_ptr<BIOSAttribute>>;
BIOSAttributes biosAttributes;
@@ -167,6 +173,9 @@
// vector to catch the D-Bus property change signals for BIOS attributes
std::vector<std::unique_ptr<sdbusplus::bus::match_t>> biosAttrMatch;
+ /** @brief system type/model */
+ std::string sysType;
+
/** @brief Method to update a BIOS attribute when the corresponding Dbus
* property is changed
* @param[in] chProperties - list of properties which have changed
diff --git a/libpldmresponder/meson.build b/libpldmresponder/meson.build
index 65d4b99..ad4207b 100644
--- a/libpldmresponder/meson.build
+++ b/libpldmresponder/meson.build
@@ -49,6 +49,7 @@
'../oem/ibm/requester/dbus_to_file_handler.cpp',
'../oem/ibm/libpldmresponder/file_io_type_progress_src.cpp',
'../oem/ibm/libpldmresponder/file_io_type_vpd.cpp',
+ '../oem/ibm/libpldmresponder/bios_oem_ibm.cpp',
]
endif
@@ -67,3 +68,4 @@
if get_option('tests').enabled()
subdir('test')
endif
+
diff --git a/libpldmresponder/oem_handler.hpp b/libpldmresponder/oem_handler.hpp
index 3e3742d..accfc80 100644
--- a/libpldmresponder/oem_handler.hpp
+++ b/libpldmresponder/oem_handler.hpp
@@ -2,6 +2,7 @@
#include "common/types.hpp"
#include "common/utils.hpp"
+#include "libpldmresponder/pdr_utils.hpp"
#include "pldmd/handler.hpp"
namespace pldm
@@ -97,6 +98,28 @@
} // namespace oem_platform
+namespace oem_bios
+{
+/** Interface to the oem bios Handler class*/
+class Handler : public CmdHandler
+{
+ public:
+ Handler(const pldm::utils::DBusHandler* dBusIntf) : dBusIntf(dBusIntf) {}
+
+ /** @brief Interface to get the system type information
+ *
+ * @return - the system type information
+ */
+ virtual std::optional<std::string> getPlatformName() = 0;
+
+ virtual ~Handler() = default;
+
+ protected:
+ const pldm::utils::DBusHandler* dBusIntf;
+};
+
+} // namespace oem_bios
+
} // namespace responder
} // namespace pldm
diff --git a/libpldmresponder/test/libpldmresponder_bios_config_test.cpp b/libpldmresponder/test/libpldmresponder_bios_config_test.cpp
index 4990f5a..d70a961 100644
--- a/libpldmresponder/test/libpldmresponder_bios_config_test.cpp
+++ b/libpldmresponder/test/libpldmresponder_bios_config_test.cpp
@@ -2,6 +2,7 @@
#include "common/test/mocked_utils.hpp"
#include "libpldmresponder/bios_config.hpp"
#include "libpldmresponder/bios_string_attribute.hpp"
+#include "libpldmresponder/oem_handler.hpp"
#include "mocked_bios.hpp"
#include <nlohmann/json.hpp>
@@ -18,6 +19,8 @@
using ::testing::_;
using ::testing::ElementsAreArray;
+using ::testing::Return;
+using ::testing::StrEq;
using ::testing::Throw;
class TestBIOSConfig : public ::testing::Test
@@ -74,15 +77,28 @@
fs::path TestBIOSConfig::tableDir;
std::vector<Json> TestBIOSConfig::jsons;
+class MockBiosSystemConfig : public pldm::responder::oem_bios::Handler
+{
+ public:
+ MockBiosSystemConfig(const pldm::utils::DBusHandler* dBusIntf) :
+ pldm::responder::oem_bios::Handler(dBusIntf)
+ {}
+ MOCK_METHOD(void, ibmCompatibleAddedCallback,
+ (sdbusplus::message::message&), ());
+ MOCK_METHOD(std::optional<std::string>, getPlatformName, ());
+};
+
TEST_F(TestBIOSConfig, buildTablesTest)
{
MockdBusHandler dbusHandler;
+ MockBiosSystemConfig mockBiosSystemConfig(&dbusHandler);
+
ON_CALL(dbusHandler, getDbusPropertyVariant(_, _, _))
.WillByDefault(Throw(std::exception()));
BIOSConfig biosConfig("./bios_jsons", tableDir.c_str(), &dbusHandler, 0, 0,
- nullptr, nullptr);
+ nullptr, nullptr, &mockBiosSystemConfig);
biosConfig.buildTables();
auto stringTable = biosConfig.getBIOSTable(PLDM_BIOS_STRING_TABLE);
@@ -101,6 +117,7 @@
"Temp",
"InbandCodeUpdate",
"Allowed",
+ "Allowed",
"NotAllowed",
"CodeUpdatePolicy",
"Concurrent",
@@ -246,12 +263,87 @@
}
}
+TEST_F(TestBIOSConfig, buildTablesSystemSpecificTest)
+{
+ MockdBusHandler dbusHandler;
+
+ MockBiosSystemConfig mockBiosSystemConfig(&dbusHandler);
+
+ ON_CALL(dbusHandler, getDbusPropertyVariant(_, _, _))
+ .WillByDefault(Throw(std::exception()));
+
+ BIOSConfig biosConfig("./system_type1/bios_jsons", tableDir.c_str(),
+ &dbusHandler, 0, 0, nullptr, nullptr,
+ &mockBiosSystemConfig);
+
+ biosConfig.buildTables();
+
+ auto stringTable = biosConfig.getBIOSTable(PLDM_BIOS_STRING_TABLE);
+ auto attrTable = biosConfig.getBIOSTable(PLDM_BIOS_ATTR_TABLE);
+ auto attrValueTable = biosConfig.getBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE);
+
+ EXPECT_TRUE(stringTable);
+ EXPECT_TRUE(attrTable);
+ EXPECT_TRUE(attrValueTable);
+
+ BIOSStringTable biosStringTable(*stringTable);
+
+ for (auto entry : BIOSTableIter<PLDM_BIOS_ATTR_TABLE>(attrTable->data(),
+ attrTable->size()))
+ {
+ auto header = table::attribute::decodeHeader(entry);
+ auto attrName = biosStringTable.findString(header.stringHandle);
+ auto jsonEntry = findJsonEntry(attrName);
+ EXPECT_TRUE(jsonEntry);
+ switch (header.attrType)
+ {
+ case PLDM_BIOS_STRING:
+ case PLDM_BIOS_STRING_READ_ONLY:
+ {
+ if (attrName == "str_example2")
+ {
+ auto stringField =
+ table::attribute::decodeStringEntry(entry);
+ EXPECT_EQ(stringField.maxLength, 200);
+ }
+
+ break;
+ }
+ case PLDM_BIOS_INTEGER:
+ case PLDM_BIOS_INTEGER_READ_ONLY:
+ {
+ if (attrName == "SBE_IMAGE_MINIMUM_VALID_ECS")
+ {
+ auto integerField =
+ table::attribute::decodeIntegerEntry(entry);
+ EXPECT_EQ(integerField.upperBound, 30);
+ }
+ break;
+ }
+ case PLDM_BIOS_ENUMERATION:
+ case PLDM_BIOS_ENUMERATION_READ_ONLY:
+ {
+ if (attrName == "FWBootSide")
+ {
+ auto [pvHdls,
+ defInds] = table::attribute::decodeEnumEntry(entry);
+ auto defValue =
+ biosStringTable.findString(pvHdls[defInds[0]]);
+ EXPECT_EQ(defValue, "Temp");
+ }
+ }
+ }
+ }
+}
+
TEST_F(TestBIOSConfig, setAttrValue)
{
MockdBusHandler dbusHandler;
+ MockBiosSystemConfig mockBiosSystemConfig(&dbusHandler);
+
BIOSConfig biosConfig("./bios_jsons", tableDir.c_str(), &dbusHandler, 0, 0,
- nullptr, nullptr);
+ nullptr, nullptr, &mockBiosSystemConfig);
biosConfig.removeTables();
biosConfig.buildTables();
diff --git a/libpldmresponder/test/system_type1/bios_jsons/enum_attrs.json b/libpldmresponder/test/system_type1/bios_jsons/enum_attrs.json
new file mode 100644
index 0000000..18c221b
--- /dev/null
+++ b/libpldmresponder/test/system_type1/bios_jsons/enum_attrs.json
@@ -0,0 +1,60 @@
+{
+ "entries": [
+ {
+ "attribute_name": "HMCManagedState",
+ "possible_values": ["On", "Off"],
+ "default_values": ["On"],
+ "readOnly": false,
+ "helpText": "HMCManagedState HelpText",
+ "displayName": "HMCManagedState DisplayName",
+ "dbus": {
+ "object_path": "/xyz/abc/def",
+ "interface": "xyz.openbmc_project.HMCManaged.State",
+ "property_name": "State",
+ "property_type": "string",
+ "property_values": [
+ "xyz.openbmc_project.State.On",
+ "xyz.openbmc_project.State.Off"
+ ]
+ }
+ },
+ {
+ "attribute_name": "FWBootSide",
+ "possible_values": ["Perm", "Temp"],
+ "default_values": ["Temp"],
+ "readOnly": false,
+ "helpText": "FWBootSide HelpText",
+ "displayName": "FWBootSide DisplayName",
+ "dbus": {
+ "object_path": "/xyz/abc/def",
+ "interface": "xyz.openbmc.FWBoot.Side",
+ "property_name": "Side",
+ "property_type": "bool",
+ "property_values": [true, false]
+ }
+ },
+ {
+ "attribute_name": "InbandCodeUpdate",
+ "possible_values": ["Allowed", "NotAllowed"],
+ "default_values": ["Allowed"],
+ "readOnly": false,
+ "helpText": "InbandCodeUpdate HelpText",
+ "displayName": "InbandCodeUpdate DisplayName",
+ "dbus": {
+ "object_path": "/xyz/abc/def",
+ "interface": "xyz.openbmc.InBandCodeUpdate",
+ "property_name": "Policy",
+ "property_type": "uint8_t",
+ "property_values": [0, 1]
+ }
+ },
+ {
+ "attribute_name": "CodeUpdatePolicy",
+ "possible_values": ["Concurrent", "Disruptive"],
+ "default_values": ["Concurrent"],
+ "readOnly": true,
+ "helpText": "CodeUpdatePolicy HelpText",
+ "displayName": "CodeUpdatePolicy DisplayName"
+ }
+ ]
+}
diff --git a/libpldmresponder/test/system_type1/bios_jsons/integer_attrs.json b/libpldmresponder/test/system_type1/bios_jsons/integer_attrs.json
new file mode 100644
index 0000000..b735630
--- /dev/null
+++ b/libpldmresponder/test/system_type1/bios_jsons/integer_attrs.json
@@ -0,0 +1,40 @@
+{
+ "entries": [
+ {
+ "attribute_name": "VDD_AVSBUS_RAIL",
+ "lower_bound": 0,
+ "upper_bound": 15,
+ "scalar_increment": 1,
+ "default_value": 0,
+ "readOnly": false,
+ "helpText": "VDD_AVSBUS_RAIL HelpText",
+ "displayName": "VDD_AVSBUS_RAIL DisplayName",
+ "dbus": {
+ "object_path": "/xyz/openbmc_project/avsbus",
+ "interface": "xyz.openbmc.AvsBus.Manager",
+ "property_type": "uint8_t",
+ "property_name": "Rail"
+ }
+ },
+ {
+ "attribute_name": "SBE_IMAGE_MINIMUM_VALID_ECS",
+ "lower_bound": 1,
+ "upper_bound": 30,
+ "scalar_increment": 1,
+ "default_value": 2,
+ "readOnly": true,
+ "helpText": "SBE_IMAGE_MINIMUM_VALID_ECS HelpText",
+ "displayName": "SBE_IMAGE_MINIMUM_VALID_ECS DisplayName"
+ },
+ {
+ "attribute_name": "INTEGER_INVALID_CASE",
+ "lower_bound": 1,
+ "upper_bound": 15,
+ "scalar_increment": 2,
+ "default_value": 3,
+ "readOnly": true,
+ "helpText": "INTEGER_INVALID_CASE HelpText",
+ "displayName": "INTEGER_INVALID_CASE DisplayName"
+ }
+ ]
+}
diff --git a/libpldmresponder/test/system_type1/bios_jsons/string_attrs.json b/libpldmresponder/test/system_type1/bios_jsons/string_attrs.json
new file mode 100644
index 0000000..7e3b8f4
--- /dev/null
+++ b/libpldmresponder/test/system_type1/bios_jsons/string_attrs.json
@@ -0,0 +1,49 @@
+{
+ "entries": [
+ {
+ "attribute_name": "str_example1",
+ "string_type": "ASCII",
+ "minimum_string_length": 1,
+ "maximum_string_length": 100,
+ "default_string_length": 3,
+ "default_string": "abc",
+ "readOnly": false,
+ "helpText": "str_example1 HelpText",
+ "displayName": "str_example1 DisplayName",
+ "dbus": {
+ "object_path": "/xyz/abc/def",
+ "interface": "xyz.openbmc_project.str_example1.value",
+ "property_name": "Str_example1",
+ "property_type": "string"
+ }
+ },
+ {
+ "attribute_name": "str_example2",
+ "string_type": "Hex",
+ "minimum_string_length": 0,
+ "maximum_string_length": 200,
+ "default_string_length": 0,
+ "default_string": "",
+ "readOnly": false,
+ "helpText": "str_example2 HelpText",
+ "displayName": "str_example2 DisplayName",
+ "dbus": {
+ "object_path": "/xyz/abc/def",
+ "interface": "xyz.openbmc_project.str_example2.value",
+ "property_name": "Str_example2",
+ "property_type": "string"
+ }
+ },
+ {
+ "attribute_name": "str_example3",
+ "string_type": "Unknown",
+ "minimum_string_length": 1,
+ "maximum_string_length": 100,
+ "default_string_length": 2,
+ "default_string": "ef",
+ "readOnly": true,
+ "helpText": "str_example3 HelpText",
+ "displayName": "str_example3 DisplayName"
+ }
+ ]
+}