xref: /openbmc/smbios-mdr/src/pcieslot.cpp (revision c13c8754)
1 #include "pcieslot.hpp"
2 
3 #include <cstdint>
4 #include <map>
5 
6 namespace phosphor
7 {
8 namespace smbios
9 {
10 
11 void Pcie::pcieInfoUpdate(uint8_t* smbiosTableStorage,
12                           const std::string& motherboard)
13 {
14     storage = smbiosTableStorage;
15     motherboardPath = motherboard;
16 
17     uint8_t* dataIn = getSMBIOSTypePtr(storage, systemSlots);
18 
19     if (dataIn == nullptr)
20     {
21         return;
22     }
23 
24     /* offset 5 points to the slot type */
25     for (uint8_t index = 0;
26          index < pcieNum ||
27          pcieSmbiosType.find(*(dataIn + 5)) == pcieSmbiosType.end();)
28     {
29         dataIn = smbiosNextPtr(dataIn);
30         if (dataIn == nullptr)
31         {
32             return;
33         }
34         dataIn = getSMBIOSTypePtr(dataIn, systemSlots);
35         if (dataIn == nullptr)
36         {
37             return;
38         }
39         if (pcieSmbiosType.find(*(dataIn + 5)) != pcieSmbiosType.end())
40         {
41             index++;
42         }
43     }
44 
45     auto pcieInfo = reinterpret_cast<struct SystemSlotInfo*>(dataIn);
46 
47     pcieGeneration(pcieInfo->slotType);
48     pcieType(pcieInfo->slotType);
49     pcieLaneSize(pcieInfo->slotDataBusWidth);
50     pcieIsHotPluggable(pcieInfo->characteristics2);
51     pcieLocation(pcieInfo->slotDesignation, pcieInfo->length, dataIn);
52 
53     /* Pcie slot is embedded on the board. Always be true */
54     Item::present(true);
55 
56     if (!motherboardPath.empty())
57     {
58         std::vector<std::tuple<std::string, std::string, std::string>> assocs;
59         assocs.emplace_back("chassis", "pcie_slots", motherboardPath);
60         association::associations(assocs);
61     }
62 }
63 
64 void Pcie::pcieGeneration(const uint8_t type)
65 {
66     std::map<uint8_t, PCIeGeneration>::const_iterator it =
67         pcieGenerationTable.find(type);
68     if (it == pcieGenerationTable.end())
69     {
70         PCIeSlot::generation(PCIeGeneration::Unknown);
71     }
72     else
73     {
74         PCIeSlot::generation(it->second);
75     }
76 }
77 
78 void Pcie::pcieType(const uint8_t type)
79 {
80     std::map<uint8_t, PCIeType>::const_iterator it = pcieTypeTable.find(type);
81     if (it == pcieTypeTable.end())
82     {
83         PCIeSlot::slotType(PCIeType::Unknown);
84     }
85     else
86     {
87         PCIeSlot::slotType(it->second);
88     }
89 }
90 
91 void Pcie::pcieLaneSize(const uint8_t width)
92 {
93     std::map<uint8_t, size_t>::const_iterator it = pcieLanesTable.find(width);
94     if (it == pcieLanesTable.end())
95     {
96         PCIeSlot::lanes(0);
97     }
98     else
99     {
100         PCIeSlot::lanes(it->second);
101     }
102 }
103 
104 void Pcie::pcieIsHotPluggable(const uint8_t characteristics)
105 {
106     /*  Bit 1 of slot characteristics 2 indicates if slot supports hot-plug
107      *  devices
108      */
109     PCIeSlot::hotPluggable(characteristics & 0x2);
110 }
111 
112 void Pcie::pcieLocation(const uint8_t slotDesignation, const uint8_t structLen,
113                         uint8_t* dataIn)
114 {
115     location::locationCode(
116         positionToString(slotDesignation, structLen, dataIn));
117 }
118 
119 } // namespace smbios
120 } // namespace phosphor
121