xref: /openbmc/smbios-mdr/src/pcieslot.cpp (revision ce89a37c177728bdf9f032f1d4ef3ca07f9ac382)
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