xref: /openbmc/dbus-sensors/src/nvidia-gpu/NvidiaDeviceDiscovery.cpp (revision 0ad3a7e885ded75ec5a0e0ca78792784daeefa54)
14ecdfaaaSHarshit Aghera /*
24ecdfaaaSHarshit Aghera  * SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION &
34ecdfaaaSHarshit Aghera  * AFFILIATES. All rights reserved.
44ecdfaaaSHarshit Aghera  * SPDX-License-Identifier: Apache-2.0
54ecdfaaaSHarshit Aghera  */
64ecdfaaaSHarshit Aghera 
74ecdfaaaSHarshit Aghera #include "NvidiaDeviceDiscovery.hpp"
84ecdfaaaSHarshit Aghera 
94ecdfaaaSHarshit Aghera #include "NvidiaGpuDevice.hpp"
108951c87eSHarshit Aghera #include "NvidiaSmaDevice.hpp"
114ecdfaaaSHarshit Aghera #include "Utils.hpp"
124ecdfaaaSHarshit Aghera 
134ecdfaaaSHarshit Aghera #include <bits/basic_string.h>
144ecdfaaaSHarshit Aghera 
154ecdfaaaSHarshit Aghera #include <MctpRequester.hpp>
164ecdfaaaSHarshit Aghera #include <NvidiaGpuMctpVdm.hpp>
174ecdfaaaSHarshit Aghera #include <OcpMctpVdm.hpp>
184ecdfaaaSHarshit Aghera #include <boost/asio/io_context.hpp>
194ecdfaaaSHarshit Aghera #include <boost/container/flat_map.hpp>
204ecdfaaaSHarshit Aghera #include <phosphor-logging/lg2.hpp>
214ecdfaaaSHarshit Aghera #include <sdbusplus/asio/connection.hpp>
224ecdfaaaSHarshit Aghera #include <sdbusplus/asio/object_server.hpp>
234ecdfaaaSHarshit Aghera #include <sdbusplus/message.hpp>
244ecdfaaaSHarshit Aghera #include <sdbusplus/message/native_types.hpp>
254ecdfaaaSHarshit Aghera 
264ecdfaaaSHarshit Aghera #include <algorithm>
274ecdfaaaSHarshit Aghera #include <array>
284ecdfaaaSHarshit Aghera #include <cstdint>
294ecdfaaaSHarshit Aghera #include <memory>
304ecdfaaaSHarshit Aghera #include <span>
31*0ad3a7e8SDeepak Kodihalli #include <stdexcept>
324ecdfaaaSHarshit Aghera #include <string>
334ecdfaaaSHarshit Aghera #include <utility>
344ecdfaaaSHarshit Aghera #include <variant>
354ecdfaaaSHarshit Aghera #include <vector>
364ecdfaaaSHarshit Aghera 
37*0ad3a7e8SDeepak Kodihalli static constexpr auto sensorPollRateMs = 1000;
38*0ad3a7e8SDeepak Kodihalli 
processQueryDeviceIdResponse(boost::asio::io_context & io,sdbusplus::asio::object_server & objectServer,boost::container::flat_map<std::string,std::shared_ptr<GpuDevice>> & gpuDevices,boost::container::flat_map<std::string,std::shared_ptr<SmaDevice>> & smaDevices,const std::shared_ptr<sdbusplus::asio::connection> & conn,mctp::MctpRequester & mctpRequester,const SensorConfigs & configs,const std::string & path,uint8_t eid,int sendRecvMsgResult,std::span<uint8_t> queryDeviceIdentificationResponse)394ecdfaaaSHarshit Aghera void processQueryDeviceIdResponse(
404ecdfaaaSHarshit Aghera     boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
414ecdfaaaSHarshit Aghera     boost::container::flat_map<std::string, std::shared_ptr<GpuDevice>>&
424ecdfaaaSHarshit Aghera         gpuDevices,
438951c87eSHarshit Aghera     boost::container::flat_map<std::string, std::shared_ptr<SmaDevice>>&
448951c87eSHarshit Aghera         smaDevices,
454ecdfaaaSHarshit Aghera     const std::shared_ptr<sdbusplus::asio::connection>& conn,
464ecdfaaaSHarshit Aghera     mctp::MctpRequester& mctpRequester, const SensorConfigs& configs,
474ecdfaaaSHarshit Aghera     const std::string& path, uint8_t eid, int sendRecvMsgResult,
484ecdfaaaSHarshit Aghera     std::span<uint8_t> queryDeviceIdentificationResponse)
494ecdfaaaSHarshit Aghera {
504ecdfaaaSHarshit Aghera     if (sendRecvMsgResult != 0)
514ecdfaaaSHarshit Aghera     {
524ecdfaaaSHarshit Aghera         lg2::error(
534ecdfaaaSHarshit Aghera             "Error processing MCTP endpoint with eid {EID} : sending message over MCTP failed, rc={RC}",
544ecdfaaaSHarshit Aghera             "EID", eid, "RC", sendRecvMsgResult);
554ecdfaaaSHarshit Aghera         return;
564ecdfaaaSHarshit Aghera     }
574ecdfaaaSHarshit Aghera 
584ecdfaaaSHarshit Aghera     ocp::accelerator_management::CompletionCode cc{};
594ecdfaaaSHarshit Aghera     uint16_t reasonCode = 0;
604ecdfaaaSHarshit Aghera     uint8_t responseDeviceType = 0;
614ecdfaaaSHarshit Aghera     uint8_t responseInstanceId = 0;
624ecdfaaaSHarshit Aghera 
634ecdfaaaSHarshit Aghera     auto rc = gpu::decodeQueryDeviceIdentificationResponse(
644ecdfaaaSHarshit Aghera         queryDeviceIdentificationResponse, cc, reasonCode, responseDeviceType,
654ecdfaaaSHarshit Aghera         responseInstanceId);
664ecdfaaaSHarshit Aghera 
674ecdfaaaSHarshit Aghera     if (rc != 0 || cc != ocp::accelerator_management::CompletionCode::SUCCESS)
684ecdfaaaSHarshit Aghera     {
694ecdfaaaSHarshit Aghera         lg2::error(
704ecdfaaaSHarshit Aghera             "Error processing MCTP endpoint with eid {EID} : decode failed, rc={RC}, cc={CC}, reasonCode={RESC}",
714ecdfaaaSHarshit Aghera             "EID", eid, "RC", rc, "CC", cc, "RESC", reasonCode);
724ecdfaaaSHarshit Aghera         return;
734ecdfaaaSHarshit Aghera     }
744ecdfaaaSHarshit Aghera 
758951c87eSHarshit Aghera     switch (static_cast<gpu::DeviceIdentification>(responseDeviceType))
768951c87eSHarshit Aghera     {
778951c87eSHarshit Aghera         case gpu::DeviceIdentification::DEVICE_GPU:
784ecdfaaaSHarshit Aghera         {
794ecdfaaaSHarshit Aghera             lg2::info(
804ecdfaaaSHarshit Aghera                 "Found the GPU with EID {EID}, DeviceType {DEVTYPE}, InstanceId {IID}.",
814ecdfaaaSHarshit Aghera                 "EID", eid, "DEVTYPE", responseDeviceType, "IID",
824ecdfaaaSHarshit Aghera                 responseInstanceId);
834ecdfaaaSHarshit Aghera 
848951c87eSHarshit Aghera             auto gpuName = configs.name + '_' +
858951c87eSHarshit Aghera                            std::to_string(responseInstanceId);
864ecdfaaaSHarshit Aghera 
878951c87eSHarshit Aghera             gpuDevices[gpuName] =
888951c87eSHarshit Aghera                 std::make_shared<GpuDevice>(configs, gpuName, path, conn, eid,
898951c87eSHarshit Aghera                                             io, mctpRequester, objectServer);
908951c87eSHarshit Aghera             break;
918951c87eSHarshit Aghera         }
928951c87eSHarshit Aghera 
938951c87eSHarshit Aghera         case gpu::DeviceIdentification::DEVICE_SMA:
948951c87eSHarshit Aghera         {
958951c87eSHarshit Aghera             lg2::info(
968951c87eSHarshit Aghera                 "Found the SMA Device with EID {EID}, DeviceType {DEVTYPE}, InstanceId {IID}.",
978951c87eSHarshit Aghera                 "EID", eid, "DEVTYPE", responseDeviceType, "IID",
988951c87eSHarshit Aghera                 responseInstanceId);
998951c87eSHarshit Aghera 
1008951c87eSHarshit Aghera             auto smaName = configs.name + "_SMA_" +
1018951c87eSHarshit Aghera                            std::to_string(responseInstanceId);
1028951c87eSHarshit Aghera 
1038951c87eSHarshit Aghera             smaDevices[smaName] =
1048951c87eSHarshit Aghera                 std::make_shared<SmaDevice>(configs, smaName, path, conn, eid,
1058951c87eSHarshit Aghera                                             io, mctpRequester, objectServer);
1068951c87eSHarshit Aghera             break;
1078951c87eSHarshit Aghera         }
1084ecdfaaaSHarshit Aghera     }
1094ecdfaaaSHarshit Aghera }
1104ecdfaaaSHarshit Aghera 
queryDeviceIdentification(boost::asio::io_context & io,sdbusplus::asio::object_server & objectServer,boost::container::flat_map<std::string,std::shared_ptr<GpuDevice>> & gpuDevices,boost::container::flat_map<std::string,std::shared_ptr<SmaDevice>> & smaDevices,const std::shared_ptr<sdbusplus::asio::connection> & conn,mctp::MctpRequester & mctpRequester,const SensorConfigs & configs,const std::string & path,uint8_t eid)1114ecdfaaaSHarshit Aghera void queryDeviceIdentification(
1124ecdfaaaSHarshit Aghera     boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
1134ecdfaaaSHarshit Aghera     boost::container::flat_map<std::string, std::shared_ptr<GpuDevice>>&
1144ecdfaaaSHarshit Aghera         gpuDevices,
1158951c87eSHarshit Aghera     boost::container::flat_map<std::string, std::shared_ptr<SmaDevice>>&
1168951c87eSHarshit Aghera         smaDevices,
1174ecdfaaaSHarshit Aghera     const std::shared_ptr<sdbusplus::asio::connection>& conn,
1184ecdfaaaSHarshit Aghera     mctp::MctpRequester& mctpRequester, const SensorConfigs& configs,
1194ecdfaaaSHarshit Aghera     const std::string& path, uint8_t eid)
1204ecdfaaaSHarshit Aghera {
1214ecdfaaaSHarshit Aghera     auto queryDeviceIdentificationRequest = std::make_shared<
1224ecdfaaaSHarshit Aghera         std::array<uint8_t, sizeof(gpu::QueryDeviceIdentificationRequest)>>();
1234ecdfaaaSHarshit Aghera 
1244ecdfaaaSHarshit Aghera     auto queryDeviceIdentificationResponse = std::make_shared<
1254ecdfaaaSHarshit Aghera         std::array<uint8_t, sizeof(gpu::QueryDeviceIdentificationResponse)>>();
1264ecdfaaaSHarshit Aghera 
1274ecdfaaaSHarshit Aghera     auto rc = gpu::encodeQueryDeviceIdentificationRequest(
1284ecdfaaaSHarshit Aghera         0, *queryDeviceIdentificationRequest);
1294ecdfaaaSHarshit Aghera     if (rc != 0)
1304ecdfaaaSHarshit Aghera     {
1314ecdfaaaSHarshit Aghera         lg2::error(
1324ecdfaaaSHarshit Aghera             "Error processing MCTP endpoint with eid {EID} : encode failed, rc={RC}",
1334ecdfaaaSHarshit Aghera             "EID", eid, "RC", rc);
1344ecdfaaaSHarshit Aghera         return;
1354ecdfaaaSHarshit Aghera     }
1364ecdfaaaSHarshit Aghera 
1374ecdfaaaSHarshit Aghera     mctpRequester.sendRecvMsg(
1384ecdfaaaSHarshit Aghera         eid, *queryDeviceIdentificationRequest,
1394ecdfaaaSHarshit Aghera         *queryDeviceIdentificationResponse,
1408951c87eSHarshit Aghera         [&io, &objectServer, &gpuDevices, &smaDevices, conn, &mctpRequester,
1418951c87eSHarshit Aghera          configs, path, eid, queryDeviceIdentificationRequest,
1424ecdfaaaSHarshit Aghera          queryDeviceIdentificationResponse](int sendRecvMsgResult) {
1434ecdfaaaSHarshit Aghera             processQueryDeviceIdResponse(
1448951c87eSHarshit Aghera                 io, objectServer, gpuDevices, smaDevices, conn, mctpRequester,
1458951c87eSHarshit Aghera                 configs, path, eid, sendRecvMsgResult,
1464ecdfaaaSHarshit Aghera                 *queryDeviceIdentificationResponse);
1474ecdfaaaSHarshit Aghera         });
1484ecdfaaaSHarshit Aghera }
1494ecdfaaaSHarshit Aghera 
processEndpoint(boost::asio::io_context & io,sdbusplus::asio::object_server & objectServer,boost::container::flat_map<std::string,std::shared_ptr<GpuDevice>> & gpuDevices,boost::container::flat_map<std::string,std::shared_ptr<SmaDevice>> & smaDevices,const std::shared_ptr<sdbusplus::asio::connection> & conn,mctp::MctpRequester & mctpRequester,const SensorConfigs & configs,const std::string & path,const boost::system::error_code & ec,const SensorBaseConfigMap & endpoint)1504ecdfaaaSHarshit Aghera void processEndpoint(
1514ecdfaaaSHarshit Aghera     boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
1524ecdfaaaSHarshit Aghera     boost::container::flat_map<std::string, std::shared_ptr<GpuDevice>>&
1534ecdfaaaSHarshit Aghera         gpuDevices,
1548951c87eSHarshit Aghera     boost::container::flat_map<std::string, std::shared_ptr<SmaDevice>>&
1558951c87eSHarshit Aghera         smaDevices,
1564ecdfaaaSHarshit Aghera     const std::shared_ptr<sdbusplus::asio::connection>& conn,
1574ecdfaaaSHarshit Aghera     mctp::MctpRequester& mctpRequester, const SensorConfigs& configs,
1584ecdfaaaSHarshit Aghera     const std::string& path, const boost::system::error_code& ec,
1594ecdfaaaSHarshit Aghera     const SensorBaseConfigMap& endpoint)
1604ecdfaaaSHarshit Aghera {
1614ecdfaaaSHarshit Aghera     if (ec)
1624ecdfaaaSHarshit Aghera     {
1634ecdfaaaSHarshit Aghera         lg2::error("Error processing MCTP endpoint: Error:{ERROR}", "ERROR",
1644ecdfaaaSHarshit Aghera                    ec.message());
1654ecdfaaaSHarshit Aghera         return;
1664ecdfaaaSHarshit Aghera     }
1674ecdfaaaSHarshit Aghera 
1684ecdfaaaSHarshit Aghera     auto hasEid = endpoint.find("EID");
1694ecdfaaaSHarshit Aghera     uint8_t eid{};
1704ecdfaaaSHarshit Aghera 
1714ecdfaaaSHarshit Aghera     if (hasEid != endpoint.end())
1724ecdfaaaSHarshit Aghera     {
1734ecdfaaaSHarshit Aghera         const auto* eidPtr = std::get_if<uint8_t>(&hasEid->second);
1744ecdfaaaSHarshit Aghera         if (eidPtr != nullptr)
1754ecdfaaaSHarshit Aghera         {
1764ecdfaaaSHarshit Aghera             eid = *eidPtr;
1774ecdfaaaSHarshit Aghera         }
1784ecdfaaaSHarshit Aghera         else
1794ecdfaaaSHarshit Aghera         {
1804ecdfaaaSHarshit Aghera             lg2::error(
1814ecdfaaaSHarshit Aghera                 "Error processing MCTP endpoint: Property EID does not have valid type.");
1824ecdfaaaSHarshit Aghera             return;
1834ecdfaaaSHarshit Aghera         }
1844ecdfaaaSHarshit Aghera     }
1854ecdfaaaSHarshit Aghera     else
1864ecdfaaaSHarshit Aghera     {
1874ecdfaaaSHarshit Aghera         lg2::error(
1884ecdfaaaSHarshit Aghera             "Error processing MCTP endpoint: Property EID not found in the configuration.");
1894ecdfaaaSHarshit Aghera         return;
1904ecdfaaaSHarshit Aghera     }
1914ecdfaaaSHarshit Aghera 
1924ecdfaaaSHarshit Aghera     auto hasMctpTypes = endpoint.find("SupportedMessageTypes");
1934ecdfaaaSHarshit Aghera     std::vector<uint8_t> mctpTypes{};
1944ecdfaaaSHarshit Aghera 
1954ecdfaaaSHarshit Aghera     if (hasMctpTypes != endpoint.end())
1964ecdfaaaSHarshit Aghera     {
1974ecdfaaaSHarshit Aghera         const auto* mctpTypePtr =
1984ecdfaaaSHarshit Aghera             std::get_if<std::vector<uint8_t>>(&hasMctpTypes->second);
1994ecdfaaaSHarshit Aghera         if (mctpTypePtr != nullptr)
2004ecdfaaaSHarshit Aghera         {
2014ecdfaaaSHarshit Aghera             mctpTypes = *mctpTypePtr;
2024ecdfaaaSHarshit Aghera         }
2034ecdfaaaSHarshit Aghera         else
2044ecdfaaaSHarshit Aghera         {
2054ecdfaaaSHarshit Aghera             lg2::error(
2064ecdfaaaSHarshit Aghera                 "Error processing MCTP endpoint with eid {EID} : Property SupportedMessageTypes does not have valid type.",
2074ecdfaaaSHarshit Aghera                 "EID", eid);
2084ecdfaaaSHarshit Aghera             return;
2094ecdfaaaSHarshit Aghera         }
2104ecdfaaaSHarshit Aghera     }
2114ecdfaaaSHarshit Aghera     else
2124ecdfaaaSHarshit Aghera     {
2134ecdfaaaSHarshit Aghera         lg2::error(
2144ecdfaaaSHarshit Aghera             "Error processing MCTP endpoint with eid {EID} : Property SupportedMessageTypes not found in the configuration.",
2154ecdfaaaSHarshit Aghera             "EID", eid);
2164ecdfaaaSHarshit Aghera         return;
2174ecdfaaaSHarshit Aghera     }
2184ecdfaaaSHarshit Aghera 
2194ecdfaaaSHarshit Aghera     if (std::find(mctpTypes.begin(), mctpTypes.end(),
2204ecdfaaaSHarshit Aghera                   ocp::accelerator_management::messageType) != mctpTypes.end())
2214ecdfaaaSHarshit Aghera     {
2224ecdfaaaSHarshit Aghera         lg2::info("Found OCP MCTP VDM Endpoint with ID {EID}", "EID", eid);
2238951c87eSHarshit Aghera         queryDeviceIdentification(io, objectServer, gpuDevices, smaDevices,
2248951c87eSHarshit Aghera                                   conn, mctpRequester, configs, path, eid);
2254ecdfaaaSHarshit Aghera     }
2264ecdfaaaSHarshit Aghera }
2274ecdfaaaSHarshit Aghera 
queryEndpoints(boost::asio::io_context & io,sdbusplus::asio::object_server & objectServer,boost::container::flat_map<std::string,std::shared_ptr<GpuDevice>> & gpuDevices,boost::container::flat_map<std::string,std::shared_ptr<SmaDevice>> & smaDevices,const std::shared_ptr<sdbusplus::asio::connection> & conn,mctp::MctpRequester & mctpRequester,const SensorConfigs & configs,const std::string & path,const boost::system::error_code & ec,const GetSubTreeType & ret)2284ecdfaaaSHarshit Aghera void queryEndpoints(
2294ecdfaaaSHarshit Aghera     boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
2304ecdfaaaSHarshit Aghera     boost::container::flat_map<std::string, std::shared_ptr<GpuDevice>>&
2314ecdfaaaSHarshit Aghera         gpuDevices,
2328951c87eSHarshit Aghera     boost::container::flat_map<std::string, std::shared_ptr<SmaDevice>>&
2338951c87eSHarshit Aghera         smaDevices,
2344ecdfaaaSHarshit Aghera     const std::shared_ptr<sdbusplus::asio::connection>& conn,
2354ecdfaaaSHarshit Aghera     mctp::MctpRequester& mctpRequester, const SensorConfigs& configs,
2364ecdfaaaSHarshit Aghera     const std::string& path, const boost::system::error_code& ec,
2374ecdfaaaSHarshit Aghera     const GetSubTreeType& ret)
2384ecdfaaaSHarshit Aghera {
2394ecdfaaaSHarshit Aghera     if (ec)
2404ecdfaaaSHarshit Aghera     {
2414ecdfaaaSHarshit Aghera         lg2::error("Error processing MCTP endpoints: {ERROR}", "ERROR",
2424ecdfaaaSHarshit Aghera                    ec.message());
2434ecdfaaaSHarshit Aghera         return;
2444ecdfaaaSHarshit Aghera     }
2454ecdfaaaSHarshit Aghera 
2464ecdfaaaSHarshit Aghera     if (ret.empty())
2474ecdfaaaSHarshit Aghera     {
2484ecdfaaaSHarshit Aghera         return;
2494ecdfaaaSHarshit Aghera     }
2504ecdfaaaSHarshit Aghera 
2514ecdfaaaSHarshit Aghera     for (const auto& [objPath, services] : ret)
2524ecdfaaaSHarshit Aghera     {
2534ecdfaaaSHarshit Aghera         for (const auto& [service, ifaces] : services)
2544ecdfaaaSHarshit Aghera         {
2554ecdfaaaSHarshit Aghera             for (const auto& iface : ifaces)
2564ecdfaaaSHarshit Aghera             {
2574ecdfaaaSHarshit Aghera                 if (iface == "xyz.openbmc_project.MCTP.Endpoint")
2584ecdfaaaSHarshit Aghera                 {
2594ecdfaaaSHarshit Aghera                     conn->async_method_call(
2608951c87eSHarshit Aghera                         [&io, &objectServer, &gpuDevices, &smaDevices, conn,
2618951c87eSHarshit Aghera                          &mctpRequester, configs,
2628951c87eSHarshit Aghera                          path](const boost::system::error_code& ec,
2634ecdfaaaSHarshit Aghera                                const SensorBaseConfigMap& endpoint) {
2648951c87eSHarshit Aghera                             processEndpoint(io, objectServer, gpuDevices,
2658951c87eSHarshit Aghera                                             smaDevices, conn, mctpRequester,
2668951c87eSHarshit Aghera                                             configs, path, ec, endpoint);
2674ecdfaaaSHarshit Aghera                         },
2684ecdfaaaSHarshit Aghera                         service, objPath, "org.freedesktop.DBus.Properties",
2694ecdfaaaSHarshit Aghera                         "GetAll", iface);
2704ecdfaaaSHarshit Aghera                 }
2714ecdfaaaSHarshit Aghera             }
2724ecdfaaaSHarshit Aghera         }
2734ecdfaaaSHarshit Aghera     }
2744ecdfaaaSHarshit Aghera }
2754ecdfaaaSHarshit Aghera 
discoverDevices(boost::asio::io_context & io,sdbusplus::asio::object_server & objectServer,boost::container::flat_map<std::string,std::shared_ptr<GpuDevice>> & gpuDevices,boost::container::flat_map<std::string,std::shared_ptr<SmaDevice>> & smaDevices,const std::shared_ptr<sdbusplus::asio::connection> & conn,mctp::MctpRequester & mctpRequester,const SensorConfigs & configs,const std::string & path)2764ecdfaaaSHarshit Aghera void discoverDevices(
2774ecdfaaaSHarshit Aghera     boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
2784ecdfaaaSHarshit Aghera     boost::container::flat_map<std::string, std::shared_ptr<GpuDevice>>&
2794ecdfaaaSHarshit Aghera         gpuDevices,
2808951c87eSHarshit Aghera     boost::container::flat_map<std::string, std::shared_ptr<SmaDevice>>&
2818951c87eSHarshit Aghera         smaDevices,
2824ecdfaaaSHarshit Aghera     const std::shared_ptr<sdbusplus::asio::connection>& conn,
2834ecdfaaaSHarshit Aghera     mctp::MctpRequester& mctpRequester, const SensorConfigs& configs,
2844ecdfaaaSHarshit Aghera     const std::string& path)
2854ecdfaaaSHarshit Aghera {
2864ecdfaaaSHarshit Aghera     std::string searchPath{"/au/com/codeconstruct/"};
2874ecdfaaaSHarshit Aghera     std::vector<std::string> ifaceList{{"xyz.openbmc_project.MCTP.Endpoint"}};
2884ecdfaaaSHarshit Aghera 
2894ecdfaaaSHarshit Aghera     conn->async_method_call(
2908951c87eSHarshit Aghera         [&io, &objectServer, &gpuDevices, &smaDevices, conn, &mctpRequester,
2918951c87eSHarshit Aghera          configs,
2924ecdfaaaSHarshit Aghera          path](const boost::system::error_code& ec, const GetSubTreeType& ret) {
2938951c87eSHarshit Aghera             queryEndpoints(io, objectServer, gpuDevices, smaDevices, conn,
2948951c87eSHarshit Aghera                            mctpRequester, configs, path, ec, ret);
2954ecdfaaaSHarshit Aghera         },
2964ecdfaaaSHarshit Aghera         "xyz.openbmc_project.ObjectMapper",
2974ecdfaaaSHarshit Aghera         "/xyz/openbmc_project/object_mapper",
2984ecdfaaaSHarshit Aghera         "xyz.openbmc_project.ObjectMapper", "GetSubTree", searchPath, 0,
2994ecdfaaaSHarshit Aghera         ifaceList);
3004ecdfaaaSHarshit Aghera }
3014ecdfaaaSHarshit Aghera 
processSensorConfigs(boost::asio::io_context & io,sdbusplus::asio::object_server & objectServer,boost::container::flat_map<std::string,std::shared_ptr<GpuDevice>> & gpuDevices,boost::container::flat_map<std::string,std::shared_ptr<SmaDevice>> & smaDevices,const std::shared_ptr<sdbusplus::asio::connection> & dbusConnection,mctp::MctpRequester & mctpRequester,const ManagedObjectType & resp)3024ecdfaaaSHarshit Aghera void processSensorConfigs(
3034ecdfaaaSHarshit Aghera     boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
3044ecdfaaaSHarshit Aghera     boost::container::flat_map<std::string, std::shared_ptr<GpuDevice>>&
3054ecdfaaaSHarshit Aghera         gpuDevices,
3068951c87eSHarshit Aghera     boost::container::flat_map<std::string, std::shared_ptr<SmaDevice>>&
3078951c87eSHarshit Aghera         smaDevices,
3084ecdfaaaSHarshit Aghera     const std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
3094ecdfaaaSHarshit Aghera     mctp::MctpRequester& mctpRequester, const ManagedObjectType& resp)
3104ecdfaaaSHarshit Aghera {
3114ecdfaaaSHarshit Aghera     for (const auto& [path, interfaces] : resp)
3124ecdfaaaSHarshit Aghera     {
3134ecdfaaaSHarshit Aghera         for (const auto& [intf, cfg] : interfaces)
3144ecdfaaaSHarshit Aghera         {
3154ecdfaaaSHarshit Aghera             if (intf != configInterfaceName(deviceType))
3164ecdfaaaSHarshit Aghera             {
3174ecdfaaaSHarshit Aghera                 continue;
3184ecdfaaaSHarshit Aghera             }
3194ecdfaaaSHarshit Aghera 
3204ecdfaaaSHarshit Aghera             SensorConfigs configs;
3214ecdfaaaSHarshit Aghera 
3224ecdfaaaSHarshit Aghera             configs.name = loadVariant<std::string>(cfg, "Name");
3234ecdfaaaSHarshit Aghera 
324*0ad3a7e8SDeepak Kodihalli             try
325*0ad3a7e8SDeepak Kodihalli             {
3264ecdfaaaSHarshit Aghera                 configs.pollRate = loadVariant<uint64_t>(cfg, "PollRate");
327*0ad3a7e8SDeepak Kodihalli             }
328*0ad3a7e8SDeepak Kodihalli             catch (const std::invalid_argument&)
329*0ad3a7e8SDeepak Kodihalli             {
330*0ad3a7e8SDeepak Kodihalli                 // PollRate is an optional config
331*0ad3a7e8SDeepak Kodihalli                 configs.pollRate = sensorPollRateMs;
332*0ad3a7e8SDeepak Kodihalli             }
3334ecdfaaaSHarshit Aghera 
3348951c87eSHarshit Aghera             discoverDevices(io, objectServer, gpuDevices, smaDevices,
3358951c87eSHarshit Aghera                             dbusConnection, mctpRequester, configs, path);
3364ecdfaaaSHarshit Aghera 
3374ecdfaaaSHarshit Aghera             lg2::info(
3384ecdfaaaSHarshit Aghera                 "Detected configuration {NAME} of type {TYPE} at path: {PATH}.",
3394ecdfaaaSHarshit Aghera                 "NAME", configs.name, "TYPE", deviceType, "PATH", path);
3404ecdfaaaSHarshit Aghera         }
3414ecdfaaaSHarshit Aghera     }
3424ecdfaaaSHarshit Aghera }
3434ecdfaaaSHarshit Aghera 
createSensors(boost::asio::io_context & io,sdbusplus::asio::object_server & objectServer,boost::container::flat_map<std::string,std::shared_ptr<GpuDevice>> & gpuDevices,boost::container::flat_map<std::string,std::shared_ptr<SmaDevice>> & smaDevices,const std::shared_ptr<sdbusplus::asio::connection> & dbusConnection,mctp::MctpRequester & mctpRequester)3444ecdfaaaSHarshit Aghera void createSensors(
3454ecdfaaaSHarshit Aghera     boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
3464ecdfaaaSHarshit Aghera     boost::container::flat_map<std::string, std::shared_ptr<GpuDevice>>&
3474ecdfaaaSHarshit Aghera         gpuDevices,
3488951c87eSHarshit Aghera     boost::container::flat_map<std::string, std::shared_ptr<SmaDevice>>&
3498951c87eSHarshit Aghera         smaDevices,
3504ecdfaaaSHarshit Aghera     const std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
3514ecdfaaaSHarshit Aghera     mctp::MctpRequester& mctpRequester)
3524ecdfaaaSHarshit Aghera {
3534ecdfaaaSHarshit Aghera     if (!dbusConnection)
3544ecdfaaaSHarshit Aghera     {
3554ecdfaaaSHarshit Aghera         lg2::error("Connection not created");
3564ecdfaaaSHarshit Aghera         return;
3574ecdfaaaSHarshit Aghera     }
3584ecdfaaaSHarshit Aghera     dbusConnection->async_method_call(
3598951c87eSHarshit Aghera         [&gpuDevices, &smaDevices, &mctpRequester, dbusConnection, &io,
3608951c87eSHarshit Aghera          &objectServer](boost::system::error_code ec,
3618951c87eSHarshit Aghera                         const ManagedObjectType& resp) {
3624ecdfaaaSHarshit Aghera             if (ec)
3634ecdfaaaSHarshit Aghera             {
3644ecdfaaaSHarshit Aghera                 lg2::error("Error contacting entity manager");
3654ecdfaaaSHarshit Aghera                 return;
3664ecdfaaaSHarshit Aghera             }
3674ecdfaaaSHarshit Aghera 
3688951c87eSHarshit Aghera             processSensorConfigs(io, objectServer, gpuDevices, smaDevices,
3698951c87eSHarshit Aghera                                  dbusConnection, mctpRequester, resp);
3704ecdfaaaSHarshit Aghera         },
3714ecdfaaaSHarshit Aghera         entityManagerName, "/xyz/openbmc_project/inventory",
3724ecdfaaaSHarshit Aghera         "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
3734ecdfaaaSHarshit Aghera }
3744ecdfaaaSHarshit Aghera 
interfaceRemoved(sdbusplus::message_t & message,boost::container::flat_map<std::string,std::shared_ptr<GpuDevice>> & gpuDevices,boost::container::flat_map<std::string,std::shared_ptr<SmaDevice>> & smaDevices)3754ecdfaaaSHarshit Aghera void interfaceRemoved(
3764ecdfaaaSHarshit Aghera     sdbusplus::message_t& message,
3774ecdfaaaSHarshit Aghera     boost::container::flat_map<std::string, std::shared_ptr<GpuDevice>>&
3788951c87eSHarshit Aghera         gpuDevices,
3798951c87eSHarshit Aghera     boost::container::flat_map<std::string, std::shared_ptr<SmaDevice>>&
3808951c87eSHarshit Aghera         smaDevices)
3814ecdfaaaSHarshit Aghera {
3824ecdfaaaSHarshit Aghera     if (message.is_method_error())
3834ecdfaaaSHarshit Aghera     {
3844ecdfaaaSHarshit Aghera         lg2::error("interfacesRemoved callback method error");
3854ecdfaaaSHarshit Aghera         return;
3864ecdfaaaSHarshit Aghera     }
3874ecdfaaaSHarshit Aghera 
3884ecdfaaaSHarshit Aghera     sdbusplus::message::object_path removedPath;
3894ecdfaaaSHarshit Aghera     std::vector<std::string> interfaces;
3904ecdfaaaSHarshit Aghera 
3914ecdfaaaSHarshit Aghera     message.read(removedPath, interfaces);
3924ecdfaaaSHarshit Aghera 
3934ecdfaaaSHarshit Aghera     // If the xyz.openbmc_project.Confguration.X interface was removed
3944ecdfaaaSHarshit Aghera     // for one or more sensors, delete those sensor objects.
3954ecdfaaaSHarshit Aghera     auto sensorIt = gpuDevices.begin();
3964ecdfaaaSHarshit Aghera     while (sensorIt != gpuDevices.end())
3974ecdfaaaSHarshit Aghera     {
3984ecdfaaaSHarshit Aghera         if ((sensorIt->second->getPath() == removedPath) &&
3994ecdfaaaSHarshit Aghera             (std::find(interfaces.begin(), interfaces.end(),
4004ecdfaaaSHarshit Aghera                        configInterfaceName(deviceType)) != interfaces.end()))
4014ecdfaaaSHarshit Aghera         {
4024ecdfaaaSHarshit Aghera             sensorIt = gpuDevices.erase(sensorIt);
4034ecdfaaaSHarshit Aghera         }
4044ecdfaaaSHarshit Aghera         else
4054ecdfaaaSHarshit Aghera         {
4064ecdfaaaSHarshit Aghera             sensorIt++;
4074ecdfaaaSHarshit Aghera         }
4084ecdfaaaSHarshit Aghera     }
4098951c87eSHarshit Aghera 
4108951c87eSHarshit Aghera     auto smaSensorIt = smaDevices.begin();
4118951c87eSHarshit Aghera     while (smaSensorIt != smaDevices.end())
4128951c87eSHarshit Aghera     {
4138951c87eSHarshit Aghera         if ((smaSensorIt->second->getPath() == removedPath) &&
4148951c87eSHarshit Aghera             (std::find(interfaces.begin(), interfaces.end(),
4158951c87eSHarshit Aghera                        configInterfaceName(deviceType)) != interfaces.end()))
4168951c87eSHarshit Aghera         {
4178951c87eSHarshit Aghera             smaSensorIt = smaDevices.erase(smaSensorIt);
4188951c87eSHarshit Aghera         }
4198951c87eSHarshit Aghera         else
4208951c87eSHarshit Aghera         {
4218951c87eSHarshit Aghera             smaSensorIt++;
4228951c87eSHarshit Aghera         }
4238951c87eSHarshit Aghera     }
4244ecdfaaaSHarshit Aghera }
425