Pavithra Barithaya | a410c65 | 2021-07-22 01:32:47 -0500 | [diff] [blame] | 1 | #include "fru_oem_ibm.hpp" |
| 2 | |
| 3 | #include <phosphor-logging/lg2.hpp> |
| 4 | |
| 5 | #include <ranges> |
| 6 | |
| 7 | PHOSPHOR_LOG2_USING; |
| 8 | |
| 9 | namespace pldm |
| 10 | { |
| 11 | namespace responder |
| 12 | { |
| 13 | namespace oem_ibm_fru |
| 14 | { |
| 15 | |
| 16 | void pldm::responder::oem_ibm_fru::Handler::setIBMFruHandler( |
| 17 | pldm::responder::fru::Handler* handler) |
| 18 | { |
| 19 | fruHandler = handler; |
| 20 | } |
| 21 | |
| 22 | int pldm::responder::oem_ibm_fru::Handler::processOEMFRUTable( |
| 23 | const std::vector<uint8_t>& fruData) |
| 24 | { |
| 25 | uint8_t dataSize = 0; |
| 26 | const uint8_t* data = fruData.data(); |
| 27 | |
| 28 | while (dataSize < fruData.size()) |
| 29 | { |
| 30 | auto record = |
| 31 | reinterpret_cast<const pldm_fru_record_data_format*>(data); |
| 32 | if (!record) |
| 33 | { |
| 34 | return PLDM_ERROR_INVALID_DATA; |
| 35 | } |
| 36 | |
| 37 | auto& entityAssociationMap = getAssociateEntityMap(); |
| 38 | uint16_t fruRSI = le16toh(record->record_set_id); |
| 39 | |
| 40 | dataSize += sizeof(pldm_fru_record_data_format) - |
| 41 | sizeof(pldm_fru_record_tlv); |
| 42 | data += dataSize; |
| 43 | |
| 44 | for ([[maybe_unused]] const auto& i : |
| 45 | std::views::iota(0, (int)record->num_fru_fields)) |
| 46 | { |
| 47 | auto tlv = reinterpret_cast<const pldm_fru_record_tlv*>(data); |
| 48 | if (!tlv) |
| 49 | { |
| 50 | return PLDM_ERROR_INVALID_DATA; |
| 51 | } |
| 52 | |
| 53 | if (tlv->type == PLDM_OEM_FRU_FIELD_TYPE_PCIE_CONFIG_SPACE_DATA) |
| 54 | { |
| 55 | auto pcieData = |
| 56 | reinterpret_cast<const PcieConfigSpaceData*>(tlv->value); |
| 57 | |
| 58 | if (!pcieData) |
| 59 | { |
| 60 | return PLDM_ERROR_INVALID_DATA; |
| 61 | } |
| 62 | auto vendorId = std::to_string(htole16(pcieData->vendorId)); |
| 63 | auto deviceId = std::to_string(htole16(pcieData->deviceId)); |
| 64 | auto revisionId = std::to_string(pcieData->revisionId); |
| 65 | |
| 66 | std::stringstream ss; |
| 67 | |
| 68 | for (const auto& ele : pcieData->classCode) |
| 69 | { |
| 70 | ss << std::setfill('0') << std::setw(2) << std::hex << ele; |
| 71 | } |
| 72 | std::string classCode = ss.str(); |
| 73 | |
| 74 | auto subSystemVendorId = |
| 75 | std::to_string(htole16(pcieData->subSystemVendorId)); |
| 76 | auto subSystemId = |
| 77 | std::to_string(htole16(pcieData->subSystemId)); |
| 78 | |
| 79 | updateDBusProperty(fruRSI, entityAssociationMap, vendorId, |
| 80 | deviceId, revisionId, classCode, |
| 81 | subSystemVendorId, subSystemId); |
| 82 | } |
| 83 | // length of tlv is removed from the structure pldm_fru_record_tlv |
| 84 | // and the new tlv length is added back. |
| 85 | dataSize += sizeof(pldm_fru_record_tlv) - sizeof(uint8_t) + |
| 86 | tlv->length; |
| 87 | data += dataSize; |
| 88 | } |
| 89 | } |
| 90 | |
| 91 | return PLDM_SUCCESS; |
| 92 | } |
| 93 | |
| 94 | void Handler::updateDBusProperty( |
| 95 | uint16_t fruRSI, const AssociatedEntityMap& fruAssociationMap, |
| 96 | const std::string& vendorId, const std::string& deviceId, |
| 97 | const std::string& revisionId, const std::string& classCode, |
| 98 | const std::string& subSystemVendorId, const std::string& subSystemId) |
| 99 | { |
| 100 | uint16_t entityType{}; |
| 101 | uint16_t entityInstanceNum{}; |
| 102 | uint16_t containerId{}; |
| 103 | uint16_t terminusHandle{}; |
| 104 | const pldm_pdr_record* record{}; |
| 105 | |
| 106 | record = pldm_pdr_fru_record_set_find_by_rsi( |
| 107 | pdrRepo, fruRSI, &terminusHandle, &entityType, &entityInstanceNum, |
| 108 | &containerId); |
| 109 | |
| 110 | if (record) |
| 111 | { |
| 112 | for (const auto& [key, value] : fruAssociationMap) |
| 113 | { |
| 114 | if (entityInstanceNum == value.entity_instance_num && |
| 115 | entityType == value.entity_type && |
| 116 | containerId == value.entity_container_id) |
| 117 | { |
| 118 | dbus_map_update(key, "Function0VendorId", vendorId); |
| 119 | dbus_map_update(key, "Function0DeviceId", deviceId); |
| 120 | dbus_map_update(key, "Function0RevisionId", revisionId); |
| 121 | dbus_map_update(key, "Function0ClassCode", classCode); |
| 122 | dbus_map_update(key, "Function0SubsystemVendorId", |
| 123 | subSystemVendorId); |
| 124 | dbus_map_update(key, "Function0SubsystemId", subSystemId); |
| 125 | } |
| 126 | } |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | void Handler::dbus_map_update(const std::string& adapterObjPath, |
| 131 | const std::string& propertyName, |
| 132 | const std::string& propValue) |
| 133 | { |
| 134 | pldm::utils::PropertyValue value = propValue; |
| 135 | pldm::utils::DBusMapping dbusMapping; |
| 136 | dbusMapping.objectPath = adapterObjPath; |
| 137 | dbusMapping.interface = "xyz.openbmc_project.Inventory.Item.PCIeDevice"; |
| 138 | dbusMapping.propertyName = propertyName; |
| 139 | dbusMapping.propertyType = "string"; |
| 140 | try |
| 141 | { |
| 142 | pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value); |
| 143 | } |
| 144 | catch (const std::exception& e) |
| 145 | { |
| 146 | error("Failed to set '{PROPERTY}' property: {ERROR}", "PROPERTY", |
| 147 | propertyName, "ERROR", e); |
| 148 | } |
| 149 | } |
| 150 | } // namespace oem_ibm_fru |
| 151 | } // namespace responder |
| 152 | } // namespace pldm |