smbios-mdr: Add TPM Device Information

Type 43 of SMBIOS records defines the data structure to expose
TPM Device information. Add patch which displays the TPM Device
information on dbus.
Introduced `TPM_DBUS` meson option which will be disabled by default
When enabled, the TPM information is populated on DBUS.

Tested:

TPM information is available under dbus tree of smbios-mdr
```
:~# busctl tree xyz.openbmc_project.Smbios.MDR_V2
`- /xyz
  `- /xyz/openbmc_project
    |- /xyz/openbmc_project/Smbios
    | `- /xyz/openbmc_project/Smbios/MDR_V2
    |- /xyz/openbmc_project/inventory
    | `- /xyz/openbmc_project/inventory/system
    |   `- /xyz/openbmc_project/inventory/system/chassis
    |       |- /xyz/openbmc_project/inventory/system/chassis/motherboard/bios
    |       `- /xyz/openbmc_project/inventory/system/chassis/motherboard/tpm
```

Change-Id: Icd42f4f043bf5a970f4829e5d318568360fe4b59
Signed-off-by: Prithvi Pai <ppai@nvidia.com>
diff --git a/src/mdrv2.cpp b/src/mdrv2.cpp
index 25ef98a..f33fbc1 100644
--- a/src/mdrv2.cpp
+++ b/src/mdrv2.cpp
@@ -619,6 +619,38 @@
         }
     }
 
+#ifdef TPM_DBUS
+
+    num = getTotalTpm();
+    if (!num)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>("get tpm failed");
+        return;
+    }
+    // In case the new size is smaller than old, trim the vector
+    if (*num < tpms.size())
+    {
+        tpms.resize(*num);
+    }
+
+    for (unsigned int index = 0; index < *num; index++)
+    {
+        std::string path =
+            smbiosInventoryPath + tpmSuffix + std::to_string(index);
+        if (index + 1 > tpms.size())
+        {
+            tpms.emplace_back(std::make_unique<phosphor::smbios::Tpm>(
+                *bus, path, index, smbiosDir.dir[smbiosDirIndex].dataStorage,
+                motherboardPath));
+        }
+        else
+        {
+            tpms[index]->tpmInfoUpdate(
+                smbiosDir.dir[smbiosDirIndex].dataStorage, motherboardPath);
+        }
+    }
+#endif
+
     system.reset();
     system = std::make_unique<System>(bus, smbiosInventoryPath + systemSuffix,
                                       smbiosDir.dir[smbiosDirIndex].dataStorage,
@@ -734,6 +766,40 @@
     return num;
 }
 
+std::optional<size_t> MDRV2::getTotalTpm()
+{
+    uint8_t* dataIn = smbiosDir.dir[smbiosDirIndex].dataStorage;
+    size_t num = 0;
+
+    if (dataIn == nullptr)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Fail to get tpm total slot - no storage data");
+        return std::nullopt;
+    }
+
+    while (1)
+    {
+        dataIn = getSMBIOSTypePtr(dataIn, tpmDeviceType);
+        if (dataIn == nullptr)
+        {
+            break;
+        }
+        num++;
+        dataIn = smbiosNextPtr(dataIn);
+        if (dataIn == nullptr)
+        {
+            break;
+        }
+        if (num >= limitEntryLen)
+        {
+            break;
+        }
+    }
+
+    return num;
+}
+
 bool MDRV2::checkSMBIOSVersion(uint8_t* dataIn)
 {
     const std::string anchorString21 = "_SM_";