support specifying MB FRU eeprom path
The MB FRUID should be exposed with ID 0 for BIOS to get the data to
fill out SMBIOS table during POST. However, current IDs depend on the
ordering of the FruDevice object paths.
(1) Using the object with "Type: EEPROM" and "Name: MB FRU" in the
EntityManager to figure out the MB FRU eeprom path. Other FRUIDs still
depend on the ordering of the FruDevice object paths.
example of the entity-manager config:
```
{
"Address": "$address",
"Bus": "$bus",
"Name": "MB FRU",
"Type": "EEPROM"
},
```
(2) For System GUID that BIOS populates into SMBIOS table during POST,
also use the MB FRU eeprom path instead of the hardcoding eeprom path.
Change-Id: If950c471f92b99180bab1a629d56d3a912d3b5f4
Signed-off-by: Cosmo Chou <cosmo.chou@quantatw.com>
diff --git a/src/commandutils.cpp b/src/commandutils.cpp
new file mode 100644
index 0000000..007bb09
--- /dev/null
+++ b/src/commandutils.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2023-present Facebook.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <commandutils.hpp>
+#include <ipmid/utils.hpp>
+#include <phosphor-logging/log.hpp>
+
+std::optional<std::pair<uint8_t, uint8_t>> getMbFruDevice(void)
+{
+ static std::optional<std::pair<uint8_t, uint8_t>> device = std::nullopt;
+
+ if (device)
+ {
+ return device;
+ }
+
+ sdbusplus::bus_t dbus(ipmid_get_sd_bus_connection());
+ auto mapperCall = dbus.new_method_call("xyz.openbmc_project.ObjectMapper",
+ "/xyz/openbmc_project/object_mapper",
+ "xyz.openbmc_project.ObjectMapper",
+ "GetSubTreePaths");
+ static constexpr int32_t depth = 0;
+ static constexpr auto iface = "xyz.openbmc_project.Configuration.EEPROM";
+ static constexpr auto entityManager = "xyz.openbmc_project.EntityManager";
+ static constexpr std::array<const char*, 1> interface = {iface};
+ mapperCall.append("/xyz/openbmc_project/inventory/", depth, interface);
+
+ std::vector<std::string> paths;
+ try
+ {
+ auto resp = dbus.call(mapperCall);
+ resp.read(paths);
+ }
+ catch (const sdbusplus::exception_t& e)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(e.what());
+ return std::nullopt;
+ }
+
+ const std::string suffix = "/MB_FRU";
+ for (const auto& path : paths)
+ {
+ if (path.ends_with(suffix))
+ {
+ uint8_t fruBus = std::get<uint64_t>(
+ ipmi::getDbusProperty(dbus, entityManager, path, iface, "Bus"));
+ uint8_t fruAddr = std::get<uint64_t>(ipmi::getDbusProperty(
+ dbus, entityManager, path, iface, "Address"));
+ device = std::make_pair(fruBus, fruAddr);
+ break;
+ }
+ }
+
+ return device;
+}