1 #include "pcieslot.hpp"
2
3 #include <cstdint>
4 #include <map>
5
6 namespace phosphor
7 {
8 namespace smbios
9 {
10
pcieInfoUpdate(uint8_t * smbiosTableStorage,const std::string & motherboard)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, pcieInfo->slotLength);
49 pcieLaneSize(pcieInfo->slotDataBusWidth);
50 pcieIsHotPluggable(pcieInfo->characteristics2);
51 pcieLocation(pcieInfo->slotDesignation, pcieInfo->length, dataIn);
52
53 #ifdef SLOT_DRIVE_PRESENCE
54 /* Set PCIeSlot presence based on its current Usage */
55 Item::present(pcieInfo->currUsage ==
56 static_cast<uint8_t>(Availability::InUse));
57 #else
58 /* Pcie slot is embedded on the board. Always be true */
59 Item::present(true);
60 #endif
61
62 if (!motherboardPath.empty())
63 {
64 std::vector<std::tuple<std::string, std::string, std::string>> assocs;
65 assocs.emplace_back("chassis", "pcie_slots", motherboardPath);
66 association::associations(assocs);
67 }
68 }
69
pcieGeneration(const uint8_t type)70 void Pcie::pcieGeneration(const uint8_t type)
71 {
72 std::map<uint8_t, PCIeGeneration>::const_iterator it =
73 pcieGenerationTable.find(type);
74 if (it == pcieGenerationTable.end())
75 {
76 PCIeSlot::generation(PCIeGeneration::Unknown);
77 }
78 else
79 {
80 PCIeSlot::generation(it->second);
81 }
82 }
83
pcieType(const uint8_t type,const uint8_t slotLength)84 void Pcie::pcieType(const uint8_t type, const uint8_t slotLength)
85 {
86 // Try to find PCIeType in the main table
87 auto it = pcieTypeTable.find(type);
88 PCIeType pcieSlotType = PCIeType::Unknown;
89
90 if (it != pcieTypeTable.end())
91 {
92 pcieSlotType = it->second;
93 }
94 else
95 {
96 // If not found in `pcieTypeTable`, check `PCIeTypeByLength`
97 auto slotIt = PCIeTypeByLength.find(slotLength);
98 if (slotIt != PCIeTypeByLength.end())
99 {
100 pcieSlotType = slotIt->second;
101 }
102 }
103
104 // Set the slot type
105 PCIeSlot::slotType(pcieSlotType);
106 }
107
pcieLaneSize(const uint8_t width)108 void Pcie::pcieLaneSize(const uint8_t width)
109 {
110 std::map<uint8_t, size_t>::const_iterator it = pcieLanesTable.find(width);
111 if (it == pcieLanesTable.end())
112 {
113 PCIeSlot::lanes(0);
114 }
115 else
116 {
117 PCIeSlot::lanes(it->second);
118 }
119 }
120
pcieIsHotPluggable(const uint8_t characteristics)121 void Pcie::pcieIsHotPluggable(const uint8_t characteristics)
122 {
123 /* Bit 1 of slot characteristics 2 indicates if slot supports hot-plug
124 * devices
125 */
126 PCIeSlot::hotPluggable(characteristics & 0x2);
127 }
128
pcieLocation(const uint8_t slotDesignation,const uint8_t structLen,uint8_t * dataIn)129 void Pcie::pcieLocation(const uint8_t slotDesignation, const uint8_t structLen,
130 uint8_t* dataIn)
131 {
132 location::locationCode(
133 positionToString(slotDesignation, structLen, dataIn));
134 }
135
136 } // namespace smbios
137 } // namespace phosphor
138