Create GPU Inventory device

adds Item.accelerator interface for GPU devices

Tested
```
root@gb200nvl-obmc:~# busctl introspect xyz.openbmc_project.GpuSensor /xyz/openbmc_project/inventory/NVIDIA_GB200_GPU_0
NAME                                           TYPE      SIGNATURE RESULT/VALUE FLAGS
org.freedesktop.DBus.Introspectable            interface -         -            -
.Introspect                                    method    -         s            -
org.freedesktop.DBus.Peer                      interface -         -            -
.GetMachineId                                  method    -         s            -
.Ping                                          method    -         -            -
org.freedesktop.DBus.Properties                interface -         -            -
.Get                                           method    ss        v            -
.GetAll                                        method    s         a{sv}        -
.Set                                           method    ssv       -            -
.PropertiesChanged                             signal    sa{sv}as  -            -
xyz.openbmc_project.Inventory.Item.Accelerator interface -         -            -
.Type                                          property  s         "GPU"        emits-change
```

Change-Id: I20434529860cb37889e63651bbcd97cadfa9d54e
Signed-off-by: Rohit PAI <ropai@nvidia.com>
diff --git a/src/nvidia-gpu/Inventory.cpp b/src/nvidia-gpu/Inventory.cpp
new file mode 100644
index 0000000..9522e42
--- /dev/null
+++ b/src/nvidia-gpu/Inventory.cpp
@@ -0,0 +1,39 @@
+#include "Inventory.hpp"
+
+#include "Utils.hpp"
+
+#include <phosphor-logging/lg2.hpp>
+
+static constexpr const char* inventoryPrefix =
+    "/xyz/openbmc_project/inventory/";
+static constexpr const char* acceleratorIfaceName =
+    "xyz.openbmc_project.Inventory.Item.Accelerator";
+static constexpr const char* assetIfaceName =
+    "xyz.openbmc_project.Inventory.Decorator.Asset";
+
+Inventory::Inventory(
+    const std::shared_ptr<sdbusplus::asio::connection>& /*conn*/,
+    sdbusplus::asio::object_server& objectServer,
+    const std::string& inventoryName, mctp::MctpRequester& mctpRequester,
+    DeviceType deviceType, uint8_t eid) :
+    name(escapeName(inventoryName)), mctpRequester(mctpRequester),
+    deviceType(deviceType), eid(eid)
+{
+    if (deviceType == DeviceType::GPU)
+    {
+        std::string path = std::string(inventoryPrefix) + name;
+        try
+        {
+            acceleratorInterface =
+                objectServer.add_interface(path, acceleratorIfaceName);
+            acceleratorInterface->register_property("Type", std::string("GPU"));
+            acceleratorInterface->initialize();
+        }
+        catch (const std::exception& e)
+        {
+            lg2::error(
+                "Failed to add accelerator interface. path='{PATH}', error='{ERROR}'",
+                "PATH", path, "ERROR", e.what());
+        }
+    }
+}
diff --git a/src/nvidia-gpu/Inventory.hpp b/src/nvidia-gpu/Inventory.hpp
new file mode 100644
index 0000000..255a5a4
--- /dev/null
+++ b/src/nvidia-gpu/Inventory.hpp
@@ -0,0 +1,35 @@
+#pragma once
+
+#include "MctpRequester.hpp"
+
+#include <NvidiaGpuMctpVdm.hpp>
+#include <sdbusplus/asio/connection.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+
+#include <array>
+#include <memory>
+#include <string>
+
+class Inventory
+{
+  public:
+    enum class DeviceType
+    {
+        Unknown,
+        GPU,
+    };
+
+    Inventory(const std::shared_ptr<sdbusplus::asio::connection>& conn,
+              sdbusplus::asio::object_server& objectServer,
+              const std::string& inventoryName,
+              mctp::MctpRequester& mctpRequester, DeviceType deviceType,
+              uint8_t eid);
+
+  private:
+    std::shared_ptr<sdbusplus::asio::dbus_interface> acceleratorInterface;
+
+    std::string name;
+    mctp::MctpRequester& mctpRequester;
+    DeviceType deviceType;
+    uint8_t eid;
+};
diff --git a/src/nvidia-gpu/NvidiaGpuDevice.cpp b/src/nvidia-gpu/NvidiaGpuDevice.cpp
index e966d57..6bb8d71 100644
--- a/src/nvidia-gpu/NvidiaGpuDevice.cpp
+++ b/src/nvidia-gpu/NvidiaGpuDevice.cpp
@@ -6,6 +6,7 @@
 
 #include "NvidiaGpuDevice.hpp"
 
+#include "Inventory.hpp"
 #include "NvidiaDeviceDiscovery.hpp"
 #include "NvidiaGpuSensor.hpp"
 #include "Thresholds.hpp"
@@ -41,6 +42,9 @@
     mctpRequester(mctpRequester), conn(conn), objectServer(objectServer),
     configs(configs), name(escapeName(name)), path(path)
 {
+    inventory =
+        std::make_unique<Inventory>(conn, objectServer, name, mctpRequester,
+                                    Inventory::DeviceType::GPU, eid);
     makeSensors();
 }
 
diff --git a/src/nvidia-gpu/NvidiaGpuDevice.hpp b/src/nvidia-gpu/NvidiaGpuDevice.hpp
index 6cfed42..a1be4ff 100644
--- a/src/nvidia-gpu/NvidiaGpuDevice.hpp
+++ b/src/nvidia-gpu/NvidiaGpuDevice.hpp
@@ -6,6 +6,7 @@
 
 #pragma once
 
+#include "Inventory.hpp"
 #include "MctpRequester.hpp"
 #include "NvidiaDeviceDiscovery.hpp"
 #include "NvidiaGpuPowerSensor.hpp"
@@ -17,6 +18,7 @@
 #include <boost/asio/steady_timer.hpp>
 #include <sdbusplus/asio/connection.hpp>
 #include <sdbusplus/asio/object_server.hpp>
+#include <sdbusplus/asio/property.hpp>
 
 #include <chrono>
 #include <cstdint>
@@ -66,4 +68,6 @@
     std::string name;
 
     std::string path;
+
+    std::unique_ptr<Inventory> inventory;
 };
diff --git a/src/nvidia-gpu/NvidiaGpuMctpVdm.cpp b/src/nvidia-gpu/NvidiaGpuMctpVdm.cpp
index 937e1b0..6ebf963 100644
--- a/src/nvidia-gpu/NvidiaGpuMctpVdm.cpp
+++ b/src/nvidia-gpu/NvidiaGpuMctpVdm.cpp
@@ -417,7 +417,6 @@
     return 0;
 }
 
-
 int encodeGetInventoryInformationRequest(uint8_t instanceId, uint8_t propertyId,
                                          std::span<uint8_t> buf)
 {
diff --git a/src/nvidia-gpu/NvidiaGpuSensorMain.cpp b/src/nvidia-gpu/NvidiaGpuSensorMain.cpp
index 6ccbb05..1a3b675 100644
--- a/src/nvidia-gpu/NvidiaGpuSensorMain.cpp
+++ b/src/nvidia-gpu/NvidiaGpuSensorMain.cpp
@@ -46,6 +46,7 @@
     auto systemBus = std::make_shared<sdbusplus::asio::connection>(io);
     sdbusplus::asio::object_server objectServer(systemBus, true);
     objectServer.add_manager("/xyz/openbmc_project/sensors");
+    objectServer.add_manager("/xyz/openbmc_project/inventory");
     systemBus->request_name("xyz.openbmc_project.GpuSensor");
 
     mctp::MctpRequester mctpRequester(io);
diff --git a/src/nvidia-gpu/meson.build b/src/nvidia-gpu/meson.build
index 39ce871..5c7f958 100644
--- a/src/nvidia-gpu/meson.build
+++ b/src/nvidia-gpu/meson.build
@@ -10,6 +10,7 @@
     'NvidiaGpuThresholds.cpp',
     'NvidiaGpuVoltageSensor.cpp',
     'OcpMctpVdm.cpp',
+    'Inventory.cpp',
 )
 
 gpusensor_include_dir = include_directories('.', is_system: true)