blob: 37bb645528bdb1c4fb2e91b41bf87e79333f1831 [file] [log] [blame]
Pavithra Barithayaa410c652021-07-22 01:32:47 -05001#include "fru_oem_ibm.hpp"
2
Pavithra Barithayac8bcefb2021-11-23 07:03:00 -06003#include <com/ibm/VPD/Manager/client.hpp>
Pavithra Barithayaa410c652021-07-22 01:32:47 -05004#include <phosphor-logging/lg2.hpp>
5
Pavithra Barithaya8db5f192024-03-19 09:44:38 -05006#include <format>
Pavithra Barithayaa410c652021-07-22 01:32:47 -05007#include <ranges>
8
9PHOSPHOR_LOG2_USING;
10
11namespace pldm
12{
13namespace responder
14{
15namespace oem_ibm_fru
16{
17
18void pldm::responder::oem_ibm_fru::Handler::setIBMFruHandler(
19 pldm::responder::fru::Handler* handler)
20{
21 fruHandler = handler;
22}
23
24int 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);
Pavithra Barithaya44f88042024-08-19 15:36:29 +053044
45 data += sizeof(pldm_fru_record_data_format) -
46 sizeof(pldm_fru_record_tlv);
Pavithra Barithayaa410c652021-07-22 01:32:47 -050047
48 for ([[maybe_unused]] const auto& i :
49 std::views::iota(0, (int)record->num_fru_fields))
50 {
51 auto tlv = reinterpret_cast<const pldm_fru_record_tlv*>(data);
52 if (!tlv)
53 {
54 return PLDM_ERROR_INVALID_DATA;
55 }
56
57 if (tlv->type == PLDM_OEM_FRU_FIELD_TYPE_PCIE_CONFIG_SPACE_DATA)
58 {
59 auto pcieData =
60 reinterpret_cast<const PcieConfigSpaceData*>(tlv->value);
61
62 if (!pcieData)
63 {
64 return PLDM_ERROR_INVALID_DATA;
65 }
Pavithra Barithayaa410c652021-07-22 01:32:47 -050066
Patrick Williams16c2a0a2024-08-16 15:20:59 -040067 auto vendorId =
68 std::format("0x{:04x}", htole16(pcieData->vendorId));
69 auto deviceId =
70 std::format("0x{:04x}", htole16(pcieData->deviceId));
71 auto revisionId =
72 std::format("0x{:02x}", htole16(pcieData->revisionId));
Pavithra Barithayaa410c652021-07-22 01:32:47 -050073
Pavithra Barithaya8db5f192024-03-19 09:44:38 -050074 std::string classCode = "0x";
Pavithra Barithayaa410c652021-07-22 01:32:47 -050075 for (const auto& ele : pcieData->classCode)
76 {
Pavithra Barithaya8db5f192024-03-19 09:44:38 -050077 classCode += std::format("{:02x}", ele);
Pavithra Barithayaa410c652021-07-22 01:32:47 -050078 }
Pavithra Barithayaa410c652021-07-22 01:32:47 -050079
Pavithra Barithaya8db5f192024-03-19 09:44:38 -050080 auto subSystemVendorId = std::format(
81 "0x{:04x}", htole16(pcieData->subSystemVendorId));
Patrick Williams16c2a0a2024-08-16 15:20:59 -040082 auto subSystemId =
83 std::format("0x{:04x}", htole16(pcieData->subSystemId));
Pavithra Barithayaa410c652021-07-22 01:32:47 -050084
85 updateDBusProperty(fruRSI, entityAssociationMap, vendorId,
86 deviceId, revisionId, classCode,
87 subSystemVendorId, subSystemId);
88 }
Pavithra Barithayac8bcefb2021-11-23 07:03:00 -060089
90 if (tlv->type == PLDM_OEM_IBM_FRU_FIELD_TYPE_FIRMWARE_UAK)
91 {
92 std::vector<uint8_t> value(&tlv->value[0],
93 &tlv->value[tlv->length]);
94 setFirmwareUAK(value);
95 }
Pavithra Barithaya44f88042024-08-19 15:36:29 +053096
Pavithra Barithayaa410c652021-07-22 01:32:47 -050097 dataSize += sizeof(pldm_fru_record_tlv) - sizeof(uint8_t) +
98 tlv->length;
Pavithra Barithaya44f88042024-08-19 15:36:29 +053099
100 // Increment data pointer by the size of the current TLV
101 data += sizeof(pldm_fru_record_tlv) - sizeof(uint8_t) + tlv->length;
Pavithra Barithayaa410c652021-07-22 01:32:47 -0500102 }
103 }
104
105 return PLDM_SUCCESS;
106}
107
108void Handler::updateDBusProperty(
109 uint16_t fruRSI, const AssociatedEntityMap& fruAssociationMap,
110 const std::string& vendorId, const std::string& deviceId,
111 const std::string& revisionId, const std::string& classCode,
112 const std::string& subSystemVendorId, const std::string& subSystemId)
113{
114 uint16_t entityType{};
115 uint16_t entityInstanceNum{};
116 uint16_t containerId{};
117 uint16_t terminusHandle{};
118 const pldm_pdr_record* record{};
119
120 record = pldm_pdr_fru_record_set_find_by_rsi(
121 pdrRepo, fruRSI, &terminusHandle, &entityType, &entityInstanceNum,
122 &containerId);
123
124 if (record)
125 {
126 for (const auto& [key, value] : fruAssociationMap)
127 {
128 if (entityInstanceNum == value.entity_instance_num &&
129 entityType == value.entity_type &&
130 containerId == value.entity_container_id)
131 {
Pavithra Barithaya5e542be2021-08-13 00:33:31 -0500132 if (!(pldm::responder::utils::checkIfIBMFru(key)))
133 {
134 pldm::utils::setFruPresence(key, true);
135 }
Pavithra Barithayaa410c652021-07-22 01:32:47 -0500136 dbus_map_update(key, "Function0VendorId", vendorId);
137 dbus_map_update(key, "Function0DeviceId", deviceId);
138 dbus_map_update(key, "Function0RevisionId", revisionId);
139 dbus_map_update(key, "Function0ClassCode", classCode);
140 dbus_map_update(key, "Function0SubsystemVendorId",
141 subSystemVendorId);
142 dbus_map_update(key, "Function0SubsystemId", subSystemId);
143 }
144 }
145 }
146}
147
148void Handler::dbus_map_update(const std::string& adapterObjPath,
149 const std::string& propertyName,
150 const std::string& propValue)
151{
152 pldm::utils::PropertyValue value = propValue;
153 pldm::utils::DBusMapping dbusMapping;
154 dbusMapping.objectPath = adapterObjPath;
155 dbusMapping.interface = "xyz.openbmc_project.Inventory.Item.PCIeDevice";
156 dbusMapping.propertyName = propertyName;
157 dbusMapping.propertyType = "string";
158 try
159 {
160 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
161 }
162 catch (const std::exception& e)
163 {
Riya Dixitfc84f632024-04-06 14:00:02 -0500164 error(
165 "Failed to set property '{PROPERTY} at path '{PATH}' and interface '{INTERFACE}', error - {ERROR}",
166 "PROPERTY", propertyName, "PATH", adapterObjPath, "INTERFACE",
167 dbusMapping.interface, "ERROR", e);
Pavithra Barithayaa410c652021-07-22 01:32:47 -0500168 }
169}
Pavithra Barithayac8bcefb2021-11-23 07:03:00 -0600170
171void Handler::setFirmwareUAK(const std::vector<uint8_t>& data)
172{
173 using VPDManager = sdbusplus::client::com::ibm::vpd::Manager<>;
174
175 static constexpr auto uakObjPath = "/com/ibm/VPD/Manager";
176 static constexpr auto fruPath =
177 "/xyz/openbmc_project/inventory/system/chassis/motherboard";
178
179 auto& bus = pldm::utils::DBusHandler::getBus();
180 try
181 {
182 auto service = pldm::utils::DBusHandler().getService(
183 uakObjPath, VPDManager::interface);
184 auto method = bus.new_method_call(
185 service.c_str(), uakObjPath, VPDManager::interface, "WriteKeyword");
186 method.append(static_cast<sdbusplus::message::object_path>(fruPath),
187 "UTIL", "D8", data);
Jayashankar Padathef0b76d2024-10-08 07:11:32 -0500188 bus.call_noreply(method, dbusTimeout);
Pavithra Barithayac8bcefb2021-11-23 07:03:00 -0600189 }
190 catch (const std::exception& e)
191 {
Riya Dixitfc84f632024-04-06 14:00:02 -0500192 error("Failed to make a DBus call to VPD manager, error - {ERROR}",
193 "ERROR", e);
Pavithra Barithayac8bcefb2021-11-23 07:03:00 -0600194 }
195}
196
Pavithra Barithayaa410c652021-07-22 01:32:47 -0500197} // namespace oem_ibm_fru
198} // namespace responder
199} // namespace pldm