Pavithra Barithaya | a410c65 | 2021-07-22 01:32:47 -0500 | [diff] [blame] | 1 | #include "fru_oem_ibm.hpp" |
| 2 | |
Pavithra Barithaya | c8bcefb | 2021-11-23 07:03:00 -0600 | [diff] [blame] | 3 | #include <com/ibm/VPD/Manager/client.hpp> |
Pavithra Barithaya | a410c65 | 2021-07-22 01:32:47 -0500 | [diff] [blame] | 4 | #include <phosphor-logging/lg2.hpp> |
| 5 | |
Pavithra Barithaya | 8db5f19 | 2024-03-19 09:44:38 -0500 | [diff] [blame] | 6 | #include <format> |
Pavithra Barithaya | a410c65 | 2021-07-22 01:32:47 -0500 | [diff] [blame] | 7 | #include <ranges> |
| 8 | |
| 9 | PHOSPHOR_LOG2_USING; |
| 10 | |
| 11 | namespace pldm |
| 12 | { |
| 13 | namespace responder |
| 14 | { |
| 15 | namespace oem_ibm_fru |
| 16 | { |
| 17 | |
| 18 | void pldm::responder::oem_ibm_fru::Handler::setIBMFruHandler( |
| 19 | pldm::responder::fru::Handler* handler) |
| 20 | { |
| 21 | fruHandler = handler; |
| 22 | } |
| 23 | |
| 24 | int pldm::responder::oem_ibm_fru::Handler::processOEMFRUTable( |
| 25 | const std::vector<uint8_t>& fruData) |
| 26 | { |
| 27 | uint8_t dataSize = 0; |
| 28 | const uint8_t* data = fruData.data(); |
| 29 | |
| 30 | while (dataSize < fruData.size()) |
| 31 | { |
| 32 | auto record = |
| 33 | reinterpret_cast<const pldm_fru_record_data_format*>(data); |
| 34 | if (!record) |
| 35 | { |
| 36 | return PLDM_ERROR_INVALID_DATA; |
| 37 | } |
| 38 | |
| 39 | auto& entityAssociationMap = getAssociateEntityMap(); |
| 40 | uint16_t fruRSI = le16toh(record->record_set_id); |
| 41 | |
| 42 | dataSize += sizeof(pldm_fru_record_data_format) - |
| 43 | sizeof(pldm_fru_record_tlv); |
| 44 | data += dataSize; |
| 45 | |
| 46 | for ([[maybe_unused]] const auto& i : |
| 47 | std::views::iota(0, (int)record->num_fru_fields)) |
| 48 | { |
| 49 | auto tlv = reinterpret_cast<const pldm_fru_record_tlv*>(data); |
| 50 | if (!tlv) |
| 51 | { |
| 52 | return PLDM_ERROR_INVALID_DATA; |
| 53 | } |
| 54 | |
| 55 | if (tlv->type == PLDM_OEM_FRU_FIELD_TYPE_PCIE_CONFIG_SPACE_DATA) |
| 56 | { |
| 57 | auto pcieData = |
| 58 | reinterpret_cast<const PcieConfigSpaceData*>(tlv->value); |
| 59 | |
| 60 | if (!pcieData) |
| 61 | { |
| 62 | return PLDM_ERROR_INVALID_DATA; |
| 63 | } |
Pavithra Barithaya | a410c65 | 2021-07-22 01:32:47 -0500 | [diff] [blame] | 64 | |
Pavithra Barithaya | 8db5f19 | 2024-03-19 09:44:38 -0500 | [diff] [blame] | 65 | auto vendorId = std::format("0x{:04x}", |
| 66 | htole16(pcieData->vendorId)); |
| 67 | auto deviceId = std::format("0x{:04x}", |
| 68 | htole16(pcieData->deviceId)); |
| 69 | auto revisionId = std::format("0x{:02x}", |
| 70 | htole16(pcieData->revisionId)); |
Pavithra Barithaya | a410c65 | 2021-07-22 01:32:47 -0500 | [diff] [blame] | 71 | |
Pavithra Barithaya | 8db5f19 | 2024-03-19 09:44:38 -0500 | [diff] [blame] | 72 | std::string classCode = "0x"; |
Pavithra Barithaya | a410c65 | 2021-07-22 01:32:47 -0500 | [diff] [blame] | 73 | for (const auto& ele : pcieData->classCode) |
| 74 | { |
Pavithra Barithaya | 8db5f19 | 2024-03-19 09:44:38 -0500 | [diff] [blame] | 75 | classCode += std::format("{:02x}", ele); |
Pavithra Barithaya | a410c65 | 2021-07-22 01:32:47 -0500 | [diff] [blame] | 76 | } |
Pavithra Barithaya | a410c65 | 2021-07-22 01:32:47 -0500 | [diff] [blame] | 77 | |
Pavithra Barithaya | 8db5f19 | 2024-03-19 09:44:38 -0500 | [diff] [blame] | 78 | auto subSystemVendorId = std::format( |
| 79 | "0x{:04x}", htole16(pcieData->subSystemVendorId)); |
| 80 | auto subSystemId = std::format("0x{:04x}", |
| 81 | htole16(pcieData->subSystemId)); |
Pavithra Barithaya | a410c65 | 2021-07-22 01:32:47 -0500 | [diff] [blame] | 82 | |
| 83 | updateDBusProperty(fruRSI, entityAssociationMap, vendorId, |
| 84 | deviceId, revisionId, classCode, |
| 85 | subSystemVendorId, subSystemId); |
| 86 | } |
Pavithra Barithaya | c8bcefb | 2021-11-23 07:03:00 -0600 | [diff] [blame] | 87 | |
| 88 | if (tlv->type == PLDM_OEM_IBM_FRU_FIELD_TYPE_FIRMWARE_UAK) |
| 89 | { |
| 90 | std::vector<uint8_t> value(&tlv->value[0], |
| 91 | &tlv->value[tlv->length]); |
| 92 | setFirmwareUAK(value); |
| 93 | } |
Pavithra Barithaya | a410c65 | 2021-07-22 01:32:47 -0500 | [diff] [blame] | 94 | // length of tlv is removed from the structure pldm_fru_record_tlv |
| 95 | // and the new tlv length is added back. |
| 96 | dataSize += sizeof(pldm_fru_record_tlv) - sizeof(uint8_t) + |
| 97 | tlv->length; |
| 98 | data += dataSize; |
| 99 | } |
| 100 | } |
| 101 | |
| 102 | return PLDM_SUCCESS; |
| 103 | } |
| 104 | |
| 105 | void Handler::updateDBusProperty( |
| 106 | uint16_t fruRSI, const AssociatedEntityMap& fruAssociationMap, |
| 107 | const std::string& vendorId, const std::string& deviceId, |
| 108 | const std::string& revisionId, const std::string& classCode, |
| 109 | const std::string& subSystemVendorId, const std::string& subSystemId) |
| 110 | { |
| 111 | uint16_t entityType{}; |
| 112 | uint16_t entityInstanceNum{}; |
| 113 | uint16_t containerId{}; |
| 114 | uint16_t terminusHandle{}; |
| 115 | const pldm_pdr_record* record{}; |
| 116 | |
| 117 | record = pldm_pdr_fru_record_set_find_by_rsi( |
| 118 | pdrRepo, fruRSI, &terminusHandle, &entityType, &entityInstanceNum, |
| 119 | &containerId); |
| 120 | |
| 121 | if (record) |
| 122 | { |
| 123 | for (const auto& [key, value] : fruAssociationMap) |
| 124 | { |
| 125 | if (entityInstanceNum == value.entity_instance_num && |
| 126 | entityType == value.entity_type && |
| 127 | containerId == value.entity_container_id) |
| 128 | { |
Pavithra Barithaya | 5e542be | 2021-08-13 00:33:31 -0500 | [diff] [blame] | 129 | if (!(pldm::responder::utils::checkIfIBMFru(key))) |
| 130 | { |
| 131 | pldm::utils::setFruPresence(key, true); |
| 132 | } |
Pavithra Barithaya | a410c65 | 2021-07-22 01:32:47 -0500 | [diff] [blame] | 133 | dbus_map_update(key, "Function0VendorId", vendorId); |
| 134 | dbus_map_update(key, "Function0DeviceId", deviceId); |
| 135 | dbus_map_update(key, "Function0RevisionId", revisionId); |
| 136 | dbus_map_update(key, "Function0ClassCode", classCode); |
| 137 | dbus_map_update(key, "Function0SubsystemVendorId", |
| 138 | subSystemVendorId); |
| 139 | dbus_map_update(key, "Function0SubsystemId", subSystemId); |
| 140 | } |
| 141 | } |
| 142 | } |
| 143 | } |
| 144 | |
| 145 | void Handler::dbus_map_update(const std::string& adapterObjPath, |
| 146 | const std::string& propertyName, |
| 147 | const std::string& propValue) |
| 148 | { |
| 149 | pldm::utils::PropertyValue value = propValue; |
| 150 | pldm::utils::DBusMapping dbusMapping; |
| 151 | dbusMapping.objectPath = adapterObjPath; |
| 152 | dbusMapping.interface = "xyz.openbmc_project.Inventory.Item.PCIeDevice"; |
| 153 | dbusMapping.propertyName = propertyName; |
| 154 | dbusMapping.propertyType = "string"; |
| 155 | try |
| 156 | { |
| 157 | pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value); |
| 158 | } |
| 159 | catch (const std::exception& e) |
| 160 | { |
| 161 | error("Failed to set '{PROPERTY}' property: {ERROR}", "PROPERTY", |
| 162 | propertyName, "ERROR", e); |
| 163 | } |
| 164 | } |
Pavithra Barithaya | c8bcefb | 2021-11-23 07:03:00 -0600 | [diff] [blame] | 165 | |
| 166 | void Handler::setFirmwareUAK(const std::vector<uint8_t>& data) |
| 167 | { |
| 168 | using VPDManager = sdbusplus::client::com::ibm::vpd::Manager<>; |
| 169 | |
| 170 | static constexpr auto uakObjPath = "/com/ibm/VPD/Manager"; |
| 171 | static constexpr auto fruPath = |
| 172 | "/xyz/openbmc_project/inventory/system/chassis/motherboard"; |
| 173 | |
| 174 | auto& bus = pldm::utils::DBusHandler::getBus(); |
| 175 | try |
| 176 | { |
| 177 | auto service = pldm::utils::DBusHandler().getService( |
| 178 | uakObjPath, VPDManager::interface); |
| 179 | auto method = bus.new_method_call( |
| 180 | service.c_str(), uakObjPath, VPDManager::interface, "WriteKeyword"); |
| 181 | method.append(static_cast<sdbusplus::message::object_path>(fruPath), |
| 182 | "UTIL", "D8", data); |
| 183 | bus.call_noreply(method); |
| 184 | } |
| 185 | catch (const std::exception& e) |
| 186 | { |
| 187 | error("Failed to make a DBus call to VPD manager: {ERROR}", "ERROR", e); |
| 188 | } |
| 189 | } |
| 190 | |
Pavithra Barithaya | a410c65 | 2021-07-22 01:32:47 -0500 | [diff] [blame] | 191 | } // namespace oem_ibm_fru |
| 192 | } // namespace responder |
| 193 | } // namespace pldm |