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, 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 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 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 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 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 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