smbios-mdr: Parse PCIE slot tables
System slot tables have SMBIOS table type 9. Parse system slot tables
and select all PCIE slots. PCIE slot inventory DBus objects will have
the xyz.openbmc_project.Inventory.Item.PCIeSlot interface defined in
phosphor-dbus-interfaces.
Tested:
Tests on a Intel platform. Some DBus command outputs as follows:
busctl introspect xyz.openbmc_project.Smbios.MDR_V2 \
/xyz/openbmc_project/inventory/system/chassis/motherboard/pcieslot3
NAME TYPE SIGNATURE RESULT/VALUE FLAGS
org.freedesktop.DBus.Introspectable interface - - -herboard/p
.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.Decorator.LocationCode interface - - -
.LocationCode property s "PE3" emits-change writable
xyz.openbmc_project.Inventory.Item interface - - -
.Present property b true emits-change writable
.PrettyName property s "" emits-change writable
xyz.openbmc_project.Inventory.Item.PCIeSlot interface - - -
.Generation property s "xyz.openbmc_project.Inventory.Item.P... emits-change writable
.HotPluggable property b false emits-change writable
.Lanes property u 16 emits-change writable
.SlotType property s "xyz.openbmc_project.Inventory.Item.P... emits-change writable
busctl get-property xyz.openbmc_project.Smbios.MDR_V2 \
/xyz/openbmc_project/inventory/system/chassis/motherboard/pcieslot3 \
xyz.openbmc_project.Inventory.Item.PCIeSlot Generation
s "xyz.openbmc_project.Inventory.Item.PCIeSlot.Generations.Gen5"
busctl get-property xyz.openbmc_project.Smbios.MDR_V2 \
/xyz/openbmc_project/inventory/system/chassis/motherboard/pcieslot3 \
xyz.openbmc_project.Inventory.Item.PCIeSlot SlotType
s "xyz.openbmc_project.Inventory.Item.PCIeSlot.SlotTypes.Unknown"
Note that it shows unknown PCIE slot types, as SMBIOS system slot record
does not have the information that a PCIE slot is full-length,
half-length or low-profile.
Signed-off-by: Jie Yang <jjy@google.com>
Change-Id: Ie9179ceb57dea3f659c15939611e873411de7320
diff --git a/src/pcieslot.cpp b/src/pcieslot.cpp
new file mode 100644
index 0000000..1b46407
--- /dev/null
+++ b/src/pcieslot.cpp
@@ -0,0 +1,109 @@
+#include "pcieslot.hpp"
+
+#include <cstdint>
+#include <map>
+
+namespace phosphor
+{
+namespace smbios
+{
+
+void Pcie::pcieInfoUpdate()
+{
+ uint8_t* dataIn = getSMBIOSTypePtr(storage, systemSlots);
+
+ if (dataIn == nullptr)
+ {
+ return;
+ }
+
+ /* offset 5 points to the slot type */
+ for (uint8_t index = 0;
+ index < pcieNum ||
+ pcieSmbiosType.find(*(dataIn + 5)) == pcieSmbiosType.end();)
+ {
+ dataIn = smbiosNextPtr(dataIn);
+ if (dataIn == nullptr)
+ {
+ return;
+ }
+ dataIn = getSMBIOSTypePtr(dataIn, systemSlots);
+ if (dataIn == nullptr)
+ {
+ return;
+ }
+ if (pcieSmbiosType.find(*(dataIn + 5)) != pcieSmbiosType.end())
+ {
+ index++;
+ }
+ }
+
+ auto pcieInfo = reinterpret_cast<struct SystemSlotInfo*>(dataIn);
+
+ pcieGeneration(pcieInfo->slotType);
+ pcieType(pcieInfo->slotType);
+ pcieLaneSize(pcieInfo->slotDataBusWidth);
+ pcieIsHotPluggable(pcieInfo->characteristics2);
+ pcieLocation(pcieInfo->slotDesignation, pcieInfo->length, dataIn);
+
+ /* Pcie slot is embedded on the board. Always be true */
+ Item::present(true);
+}
+
+void Pcie::pcieGeneration(const uint8_t type)
+{
+ std::map<uint8_t, PCIeGeneration>::const_iterator it =
+ pcieGenerationTable.find(type);
+ if (it == pcieGenerationTable.end())
+ {
+ PCIeSlot::generation(PCIeGeneration::Unknown);
+ }
+ else
+ {
+ PCIeSlot::generation(it->second);
+ }
+}
+
+void Pcie::pcieType(const uint8_t type)
+{
+ std::map<uint8_t, PCIeType>::const_iterator it = pcieTypeTable.find(type);
+ if (it == pcieTypeTable.end())
+ {
+ PCIeSlot::slotType(PCIeType::Unknown);
+ }
+ else
+ {
+ PCIeSlot::slotType(it->second);
+ }
+}
+
+void Pcie::pcieLaneSize(const uint8_t width)
+{
+ std::map<uint8_t, size_t>::const_iterator it = pcieLanesTable.find(width);
+ if (it == pcieLanesTable.end())
+ {
+ PCIeSlot::lanes(0);
+ }
+ else
+ {
+ PCIeSlot::lanes(it->second);
+ }
+}
+
+void Pcie::pcieIsHotPluggable(const uint8_t characteristics)
+{
+ /* Bit 1 of slot characteristics 2 indicates if slot supports hot-plug
+ * devices
+ */
+ PCIeSlot::hotPluggable(characteristics & 0x2);
+}
+
+void Pcie::pcieLocation(const uint8_t slotDesignation, const uint8_t structLen,
+ uint8_t* dataIn)
+{
+ location::locationCode(
+ positionToString(slotDesignation, structLen, dataIn));
+}
+
+} // namespace smbios
+} // namespace phosphor