Add support for the coreCount property in DBus
This commit introduces support for counting the number of CPU cores
during BMC power-on and populates this information to a DBus property
named coreCount. Upon BMC power-on, the remote terminus detects the
number of CPU cores and send this data and PLDM will updates the
coreCount property accordingly.
Tested:
tested on simulator for hosting DBus property
Change-Id: I37adbe399414fcff3f089fb819349ca4bb537edd
Signed-off-by: Kamalkumar Patel <kamalkumar.patel@ibm.com>
diff --git a/oem/ibm/libpldmresponder/utils.cpp b/oem/ibm/libpldmresponder/utils.cpp
index 88fe1b9..59d418c 100644
--- a/oem/ibm/libpldmresponder/utils.cpp
+++ b/oem/ibm/libpldmresponder/utils.cpp
@@ -3,6 +3,7 @@
#include "common/utils.hpp"
#include <libpldm/base.h>
+#include <libpldm/platform.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
@@ -197,6 +198,80 @@
return portObjects;
}
+
} // namespace utils
+
+namespace oem_ibm_utils
+{
+using namespace pldm::utils;
+
+int pldm::responder::oem_ibm_utils::Handler::setCoreCount(
+ const EntityAssociations& Associations, const EntityMaps entityMaps)
+{
+ int coreCountRef = 0;
+ // get the CPU pldm entities
+ for (const auto& entries : Associations)
+ {
+ auto parent = pldm_entity_extract(entries[0]);
+ // entries[0] would be the parent in the entity association map
+ if (parent.entity_type == PLDM_ENTITY_PROC)
+ {
+ int& coreCount = coreCountRef;
+ for (const auto& entry : entries)
+ {
+ auto child = pldm_entity_extract(entry);
+ if (child.entity_type == (PLDM_ENTITY_PROC | 0x8000))
+ {
+ // got a core child
+ ++coreCount;
+ }
+ }
+ try
+ {
+ auto grand_parent = pldm_entity_get_parent(entries[0]);
+ std::string grepWord = std::format(
+ "{}{}/{}{}", entityMaps.at(grand_parent.entity_type),
+ std::to_string(grand_parent.entity_instance_num),
+ entityMaps.at(parent.entity_type),
+ std::to_string(parent.entity_instance_num));
+ static constexpr auto searchpath = "/xyz/openbmc_project/";
+ std::vector<std::string> cpuInterface = {
+ "xyz.openbmc_project.Inventory.Item.Cpu"};
+ pldm::utils::GetSubTreeResponse response = dBusIntf->getSubtree(
+ searchpath, 0 /* depth */, cpuInterface);
+ for (const auto& [objectPath, serviceMap] : response)
+ {
+ // find the object path with first occurance of coreX
+ if (objectPath.contains(grepWord))
+ {
+ pldm::utils::DBusMapping dbusMapping{
+ objectPath, cpuInterface[0], "CoreCount",
+ "uint16_t"};
+ pldm::utils::PropertyValue value =
+ static_cast<uint16_t>(coreCount);
+ try
+ {
+ dBusIntf->setDbusProperty(dbusMapping, value);
+ }
+ catch (const std::exception& e)
+ {
+ error(
+ "Failed to set the core count property at interface '{INTERFACE}': {ERROR}",
+ "INTERFACE", cpuInterface[0], "ERROR", e);
+ }
+ }
+ }
+ }
+ catch (const std::exception& e)
+ {
+ error("Failed to searching CoreCount property: {ERROR}",
+ "ERROR", e);
+ }
+ }
+ }
+ return coreCountRef;
+}
+
+} // namespace oem_ibm_utils
} // namespace responder
} // namespace pldm
diff --git a/oem/ibm/libpldmresponder/utils.hpp b/oem/ibm/libpldmresponder/utils.hpp
index bfdd251..4e849f5 100644
--- a/oem/ibm/libpldmresponder/utils.hpp
+++ b/oem/ibm/libpldmresponder/utils.hpp
@@ -1,5 +1,7 @@
#pragma once
+#include "libpldmresponder/oem_handler.hpp"
+
#include <cstdint>
#include <string>
#include <vector>
@@ -54,5 +56,33 @@
std::vector<std::string> findPortObjects(const std::string& adapterObjPath);
} // namespace utils
+
+namespace oem_ibm_utils
+{
+
+class Handler : public oem_utils::Handler
+{
+ public:
+ Handler(const pldm::utils::DBusHandler* dBusIntf) :
+ oem_utils::Handler(dBusIntf), dBusIntf(dBusIntf)
+ {}
+
+ /** @brief Collecting core count data and setting to Dbus properties
+ *
+ * @param[in] associations - the data of entity association
+ * @param[in] entityMaps - the mapping of entity to DBus string
+ *
+ */
+ virtual int
+ setCoreCount(const pldm::utils::EntityAssociations& associations,
+ const pldm::utils::EntityMaps entityMaps);
+
+ virtual ~Handler() = default;
+
+ protected:
+ const pldm::utils::DBusHandler* dBusIntf;
+};
+
+} // namespace oem_ibm_utils
} // namespace responder
} // namespace pldm
diff --git a/oem/ibm/test/entitymap_test.json b/oem/ibm/test/entitymap_test.json
new file mode 100644
index 0000000..7dc08f2
--- /dev/null
+++ b/oem/ibm/test/entitymap_test.json
@@ -0,0 +1,19 @@
+{
+ "Description": {
+ "_comment": [
+ "This file serves as a crucial tool for testing JSON parsing capabilities, facilitating the population of the Entitymap by harnessing its data."
+ ]
+ },
+ "EntityTypeToDbusStringMap": {
+ "45": "chassis",
+ "60": "io_board",
+ "63": "system_management_module",
+ "64": "motherboard",
+ "67": "dcm",
+ "80": "io_module",
+ "135": "cpu",
+ "190": "socket",
+ "32813": "system",
+ "32903": "core"
+ }
+}
diff --git a/oem/ibm/test/libpldmresponder_oem_platform_test.cpp b/oem/ibm/test/libpldmresponder_oem_platform_test.cpp
index ea9b97a..21b6914 100644
--- a/oem/ibm/test/libpldmresponder_oem_platform_test.cpp
+++ b/oem/ibm/test/libpldmresponder_oem_platform_test.cpp
@@ -1,23 +1,40 @@
#include "common/test/mocked_utils.hpp"
#include "common/utils.hpp"
+#include "host-bmc/utils.hpp"
#include "libpldmresponder/event_parser.hpp"
#include "libpldmresponder/pdr.hpp"
#include "libpldmresponder/pdr_utils.hpp"
#include "libpldmresponder/platform.hpp"
#include "oem/ibm/libpldmresponder/inband_code_update.hpp"
#include "oem/ibm/libpldmresponder/oem_ibm_handler.hpp"
+#include "oem/ibm/libpldmresponder/utils.hpp"
#include "test/test_instance_id.hpp"
#include <libpldm/entity.h>
#include <libpldm/oem/ibm/entity.h>
+#include <libpldm/pdr.h>
+#include <nlohmann/json.hpp>
+#include <phosphor-logging/lg2.hpp>
#include <sdeventplus/event.hpp>
+#include <filesystem>
+#include <fstream>
+
using namespace pldm::utils;
using namespace pldm::responder;
using namespace pldm::responder::pdr;
using namespace pldm::responder::pdr_utils;
using namespace pldm::responder::oem_ibm_platform;
+using ::testing::Return;
+
+class MockOemUtilsHandler : public oem_ibm_utils::Handler
+{
+ public:
+ MockOemUtilsHandler(const pldm::utils::DBusHandler* dBusIntf) :
+ oem_ibm_utils::Handler(dBusIntf)
+ {}
+};
class MockCodeUpdate : public CodeUpdate
{
@@ -409,3 +426,86 @@
mockoemPlatformHandler->updateOemDbusPaths(dbuspath);
EXPECT_EQ(dbuspath, "/inventory/system/chassis/motherboard/dcm0");
}
+
+TEST(SetCoreCount, testgoodpath)
+{
+ pldm::utils::EntityMaps entityMaps = pldm::hostbmc::utils::parseEntityMap(
+ "../../oem/ibm/test/entitymap_test.json");
+ MockdBusHandler mockedDbusUtils;
+ pldm_entity entities[9]{};
+
+ entities[0].entity_type = 45;
+ entities[0].entity_container_id = 0;
+
+ entities[1].entity_type = 64;
+ entities[1].entity_container_id = 1;
+
+ entities[2].entity_type = 67;
+ entities[2].entity_container_id = 2;
+ entities[3].entity_type = 67;
+ entities[3].entity_container_id = 2;
+
+ entities[4].entity_type = 135;
+ entities[4].entity_container_id = 3;
+ entities[5].entity_type = 135;
+ entities[5].entity_container_id = 3;
+ entities[6].entity_type = 135;
+ entities[6].entity_container_id = 3;
+ entities[7].entity_type = 135;
+ entities[7].entity_container_id = 3;
+ entities[8].entity_type = 32903;
+ entities[8].entity_container_id = 3;
+
+ auto tree = pldm_entity_association_tree_init();
+
+ auto l1 = pldm_entity_association_tree_add_entity(
+ tree, &entities[0], 1, nullptr, PLDM_ENTITY_ASSOCIAION_PHYSICAL, true,
+ true, 0xFFFF);
+
+ auto l2 = pldm_entity_association_tree_add_entity(
+ tree, &entities[1], 1, l1, PLDM_ENTITY_ASSOCIAION_PHYSICAL, true, true,
+ 0xFFFF);
+
+ auto l3a = pldm_entity_association_tree_add_entity(
+ tree, &entities[2], 0, l2, PLDM_ENTITY_ASSOCIAION_PHYSICAL, true, true,
+ 0xFFFF);
+ auto l3b = pldm_entity_association_tree_add_entity(
+ tree, &entities[3], 1, l2, PLDM_ENTITY_ASSOCIAION_PHYSICAL, true, true,
+ 0xFFFF);
+
+ auto l4a = pldm_entity_association_tree_add_entity(
+ tree, &entities[4], 0, l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL, true, true,
+ 0xFFFF);
+ auto l4b = pldm_entity_association_tree_add_entity(
+ tree, &entities[5], 1, l3a, PLDM_ENTITY_ASSOCIAION_PHYSICAL, true, true,
+ 0xFFFF);
+
+ auto l5a = pldm_entity_association_tree_add_entity(
+ tree, &entities[6], 0, l3b, PLDM_ENTITY_ASSOCIAION_PHYSICAL, true, true,
+ 0xFFFF);
+ auto l5b = pldm_entity_association_tree_add_entity(
+ tree, &entities[7], 1, l3b, PLDM_ENTITY_ASSOCIAION_PHYSICAL, true, true,
+ 0xFFFF);
+
+ auto l5c = pldm_entity_association_tree_add_entity(
+ tree, &entities[8], 0, l5a, PLDM_ENTITY_ASSOCIAION_PHYSICAL, true, true,
+ 0xFFFF);
+
+ auto l5ca = pldm_entity_association_tree_add_entity(
+ tree, &entities[8], 0, l5b, PLDM_ENTITY_ASSOCIAION_PHYSICAL, true, true,
+ 0xFFFF);
+
+ pldm::utils::EntityAssociations entityAssociations = {
+ {l1, l2}, {l2, l3a, l3b}, {l3a, l4a, l4b},
+ {l3b, l5a, l5b}, {l5a, l5c}, {l5b, l5ca}};
+
+ DBusMapping dbusMapping{"/foo/bar", "xyz.openbmc_project.Foo.Bar",
+ "propertyName", "uint64_t"};
+ std::vector<std::string> cpuInterface = {"xyz.openbmc_project.Foo.Bar"};
+ auto oemMockedUtils =
+ std::make_unique<MockOemUtilsHandler>(&mockedDbusUtils);
+ int coreCount = oemMockedUtils->setCoreCount(entityAssociations,
+ entityMaps);
+ EXPECT_EQ(coreCount, 2);
+ pldm_entity_association_tree_destroy(tree);
+}