blob: a9d77234c3d723428b08171c355b9ad6b931bd94 [file] [log] [blame]
John Wangd9659342020-02-27 16:46:05 +08001#include "bios_config.hpp"
2
John Wang3be70852020-02-13 15:59:04 +08003#include "bios_enum_attribute.hpp"
John Wang95e6b3c2020-02-13 09:43:24 +08004#include "bios_integer_attribute.hpp"
John Wangd9659342020-02-27 16:46:05 +08005#include "bios_string_attribute.hpp"
Sampa Misra46ece062020-03-18 07:17:44 -05006#include "bios_table.hpp"
George Liu1b180d82020-07-23 14:01:58 +08007#include "common/bios_utils.hpp"
John Wangd9659342020-02-27 16:46:05 +08008
Riya Dixit49cfb132023-03-02 04:26:53 -06009#include <phosphor-logging/lg2.hpp>
George Liu1244acf2020-08-14 09:11:11 +080010#include <xyz/openbmc_project/BIOSConfig/Manager/server.hpp>
11
John Wangd9659342020-02-27 16:46:05 +080012#include <fstream>
13#include <iostream>
14
Tom Joseph7f839f92020-09-21 10:20:44 +053015#ifdef OEM_IBM
16#include "oem/ibm/libpldmresponder/platform_oem_ibm.hpp"
17#endif
18
Riya Dixit49cfb132023-03-02 04:26:53 -060019PHOSPHOR_LOG2_USING;
20
Brad Bishop5079ac42021-08-19 18:35:06 -040021using namespace pldm::utils;
22
John Wangd9659342020-02-27 16:46:05 +080023namespace pldm
24{
25namespace responder
26{
27namespace bios
28{
29namespace
30{
George Liu1244acf2020-08-14 09:11:11 +080031using BIOSConfigManager =
32 sdbusplus::xyz::openbmc_project::BIOSConfig::server::Manager;
33
John Wangd9659342020-02-27 16:46:05 +080034constexpr auto enumJsonFile = "enum_attrs.json";
35constexpr auto stringJsonFile = "string_attrs.json";
36constexpr auto integerJsonFile = "integer_attrs.json";
37
38constexpr auto stringTableFile = "stringTable";
39constexpr auto attrTableFile = "attributeTable";
40constexpr auto attrValueTableFile = "attributeValueTable";
41
42} // namespace
43
Sampa Misrac0c79482021-06-02 08:01:54 -050044BIOSConfig::BIOSConfig(
45 const char* jsonDir, const char* tableDir, DBusHandler* const dbusHandler,
Andrew Jefferya330b2f2023-05-04 14:55:37 +093046 int fd, uint8_t eid, pldm::InstanceIdDb* instanceIdDb,
Sampa Misrac0c79482021-06-02 08:01:54 -050047 pldm::requester::Handler<pldm::requester::Request>* handler) :
John Wangd9659342020-02-27 16:46:05 +080048 jsonDir(jsonDir),
Tom Joseph7f839f92020-09-21 10:20:44 +053049 tableDir(tableDir), dbusHandler(dbusHandler), fd(fd), eid(eid),
Andrew Jefferya330b2f2023-05-04 14:55:37 +093050 instanceIdDb(instanceIdDb), handler(handler)
Tom Joseph7f839f92020-09-21 10:20:44 +053051
John Wangd9659342020-02-27 16:46:05 +080052{
George Liu9d8921e2020-05-14 15:41:50 +080053 fs::create_directories(tableDir);
John Wangd9659342020-02-27 16:46:05 +080054 constructAttributes();
George Liu1244acf2020-08-14 09:11:11 +080055 listenPendingAttributes();
John Wangd9659342020-02-27 16:46:05 +080056}
57
58void BIOSConfig::buildTables()
59{
John Wangd9659342020-02-27 16:46:05 +080060 auto stringTable = buildAndStoreStringTable();
61 if (stringTable)
62 {
63 buildAndStoreAttrTables(*stringTable);
64 }
65}
66
67std::optional<Table> BIOSConfig::getBIOSTable(pldm_bios_table_types tableType)
68{
69 fs::path tablePath;
70 switch (tableType)
71 {
72 case PLDM_BIOS_STRING_TABLE:
73 tablePath = tableDir / stringTableFile;
74 break;
75 case PLDM_BIOS_ATTR_TABLE:
76 tablePath = tableDir / attrTableFile;
77 break;
78 case PLDM_BIOS_ATTR_VAL_TABLE:
79 tablePath = tableDir / attrValueTableFile;
80 break;
81 }
82 return loadTable(tablePath);
83}
84
Tom Joseph7f839f92020-09-21 10:20:44 +053085int BIOSConfig::setBIOSTable(uint8_t tableType, const Table& table,
86 bool updateBaseBIOSTable)
George Liu1b180d82020-07-23 14:01:58 +080087{
88 fs::path stringTablePath(tableDir / stringTableFile);
89 fs::path attrTablePath(tableDir / attrTableFile);
90 fs::path attrValueTablePath(tableDir / attrValueTableFile);
91
92 if (!pldm_bios_table_checksum(table.data(), table.size()))
93 {
94 return PLDM_INVALID_BIOS_TABLE_DATA_INTEGRITY_CHECK;
95 }
96
97 if (tableType == PLDM_BIOS_STRING_TABLE)
98 {
99 storeTable(stringTablePath, table);
100 }
101 else if (tableType == PLDM_BIOS_ATTR_TABLE)
102 {
103 BIOSTable biosStringTable(stringTablePath.c_str());
104 if (biosStringTable.isEmpty())
105 {
106 return PLDM_INVALID_BIOS_TABLE_TYPE;
107 }
108
109 auto rc = checkAttributeTable(table);
110 if (rc != PLDM_SUCCESS)
111 {
112 return rc;
113 }
114
115 storeTable(attrTablePath, table);
116 }
117 else if (tableType == PLDM_BIOS_ATTR_VAL_TABLE)
118 {
119 BIOSTable biosStringTable(stringTablePath.c_str());
120 BIOSTable biosStringValueTable(attrTablePath.c_str());
121 if (biosStringTable.isEmpty() || biosStringValueTable.isEmpty())
122 {
123 return PLDM_INVALID_BIOS_TABLE_TYPE;
124 }
125
126 auto rc = checkAttributeValueTable(table);
127 if (rc != PLDM_SUCCESS)
128 {
129 return rc;
130 }
131
132 storeTable(attrValueTablePath, table);
George Liu1b180d82020-07-23 14:01:58 +0800133 }
134 else
135 {
136 return PLDM_INVALID_BIOS_TABLE_TYPE;
137 }
138
Tom Joseph7f839f92020-09-21 10:20:44 +0530139 if ((tableType == PLDM_BIOS_ATTR_VAL_TABLE) && updateBaseBIOSTable)
George Liu1b180d82020-07-23 14:01:58 +0800140 {
George Liu1b180d82020-07-23 14:01:58 +0800141 updateBaseBIOSTableProperty();
142 }
143
144 return PLDM_SUCCESS;
145}
146
147int BIOSConfig::checkAttributeTable(const Table& table)
148{
149 using namespace pldm::bios::utils;
150 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
151 for (auto entry :
152 BIOSTableIter<PLDM_BIOS_ATTR_TABLE>(table.data(), table.size()))
153 {
154 auto attrNameHandle =
155 pldm_bios_table_attr_entry_decode_string_handle(entry);
156
157 auto stringEnty = pldm_bios_table_string_find_by_handle(
158 stringTable->data(), stringTable->size(), attrNameHandle);
159 if (stringEnty == nullptr)
160 {
161 return PLDM_INVALID_BIOS_ATTR_HANDLE;
162 }
163
164 auto attrType = static_cast<pldm_bios_attribute_type>(
165 pldm_bios_table_attr_entry_decode_attribute_type(entry));
166
167 switch (attrType)
168 {
169 case PLDM_BIOS_ENUMERATION:
170 case PLDM_BIOS_ENUMERATION_READ_ONLY:
171 {
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930172 uint8_t pvNum;
173 // Preconditions are upheld therefore no error check necessary
174 pldm_bios_table_attr_entry_enum_decode_pv_num_check(entry,
175 &pvNum);
George Liu1b180d82020-07-23 14:01:58 +0800176 std::vector<uint16_t> pvHandls(pvNum);
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930177 // Preconditions are upheld therefore no error check necessary
178 pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
George Liu1b180d82020-07-23 14:01:58 +0800179 entry, pvHandls.data(), pvHandls.size());
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930180 uint8_t defNum;
181 pldm_bios_table_attr_entry_enum_decode_def_num_check(entry,
182 &defNum);
George Liu1b180d82020-07-23 14:01:58 +0800183 std::vector<uint8_t> defIndices(defNum);
184 pldm_bios_table_attr_entry_enum_decode_def_indices(
185 entry, defIndices.data(), defIndices.size());
186
187 for (size_t i = 0; i < pvHandls.size(); i++)
188 {
189 auto stringEntry = pldm_bios_table_string_find_by_handle(
190 stringTable->data(), stringTable->size(), pvHandls[i]);
191 if (stringEntry == nullptr)
192 {
193 return PLDM_INVALID_BIOS_ATTR_HANDLE;
194 }
195 }
196
197 for (size_t i = 0; i < defIndices.size(); i++)
198 {
199 auto stringEntry = pldm_bios_table_string_find_by_handle(
200 stringTable->data(), stringTable->size(),
201 pvHandls[defIndices[i]]);
202 if (stringEntry == nullptr)
203 {
204 return PLDM_INVALID_BIOS_ATTR_HANDLE;
205 }
206 }
207 break;
208 }
209 case PLDM_BIOS_INTEGER:
210 case PLDM_BIOS_INTEGER_READ_ONLY:
211 case PLDM_BIOS_STRING:
212 case PLDM_BIOS_STRING_READ_ONLY:
213 case PLDM_BIOS_PASSWORD:
214 case PLDM_BIOS_PASSWORD_READ_ONLY:
215 break;
216 default:
217 return PLDM_INVALID_BIOS_ATTR_HANDLE;
218 }
219 }
220
221 return PLDM_SUCCESS;
222}
223
224int BIOSConfig::checkAttributeValueTable(const Table& table)
225{
226 using namespace pldm::bios::utils;
227 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
228 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
229
230 baseBIOSTableMaps.clear();
231
232 for (auto tableEntry :
233 BIOSTableIter<PLDM_BIOS_ATTR_VAL_TABLE>(table.data(), table.size()))
234 {
235 AttributeName attributeName{};
236 AttributeType attributeType{};
237 ReadonlyStatus readonlyStatus{};
238 DisplayName displayName{};
239 Description description{};
240 MenuPath menuPath{};
241 CurrentValue currentValue{};
242 DefaultValue defaultValue{};
243 Option options{};
244
245 auto attrValueHandle =
246 pldm_bios_table_attr_value_entry_decode_attribute_handle(
247 tableEntry);
248 auto attrType = static_cast<pldm_bios_attribute_type>(
249 pldm_bios_table_attr_value_entry_decode_attribute_type(tableEntry));
250
251 auto attrEntry = pldm_bios_table_attr_find_by_handle(
252 attrTable->data(), attrTable->size(), attrValueHandle);
253 if (attrEntry == nullptr)
254 {
255 return PLDM_INVALID_BIOS_ATTR_HANDLE;
256 }
257 auto attrHandle =
258 pldm_bios_table_attr_entry_decode_attribute_handle(attrEntry);
259 auto attrNameHandle =
260 pldm_bios_table_attr_entry_decode_string_handle(attrEntry);
261
262 auto stringEntry = pldm_bios_table_string_find_by_handle(
263 stringTable->data(), stringTable->size(), attrNameHandle);
264 if (stringEntry == nullptr)
265 {
266 return PLDM_INVALID_BIOS_ATTR_HANDLE;
267 }
268 auto strLength =
269 pldm_bios_table_string_entry_decode_string_length(stringEntry);
270 std::vector<char> buffer(strLength + 1 /* sizeof '\0' */);
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930271 // Preconditions are upheld therefore no error check necessary
272 pldm_bios_table_string_entry_decode_string_check(
273 stringEntry, buffer.data(), buffer.size());
274
George Liu1b180d82020-07-23 14:01:58 +0800275 attributeName = std::string(buffer.data(), buffer.data() + strLength);
276
277 if (!biosAttributes.empty())
278 {
279 readonlyStatus =
George Liub1fbeec2020-09-04 09:59:46 +0800280 biosAttributes[attrHandle % biosAttributes.size()]->readOnly;
George Liu92bb4022020-09-03 14:58:24 +0800281 description =
282 biosAttributes[attrHandle % biosAttributes.size()]->helpText;
283 displayName =
284 biosAttributes[attrHandle % biosAttributes.size()]->displayName;
George Liu1b180d82020-07-23 14:01:58 +0800285 }
286
287 switch (attrType)
288 {
289 case PLDM_BIOS_ENUMERATION:
290 case PLDM_BIOS_ENUMERATION_READ_ONLY:
291 {
292 auto getValue = [](uint16_t handle,
293 const Table& table) -> std::string {
294 auto stringEntry = pldm_bios_table_string_find_by_handle(
295 table.data(), table.size(), handle);
296
297 auto strLength =
298 pldm_bios_table_string_entry_decode_string_length(
299 stringEntry);
300 std::vector<char> buffer(strLength + 1 /* sizeof '\0' */);
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930301 // Preconditions are upheld therefore no error check
302 // necessary
303 pldm_bios_table_string_entry_decode_string_check(
George Liu1b180d82020-07-23 14:01:58 +0800304 stringEntry, buffer.data(), buffer.size());
305
306 return std::string(buffer.data(),
307 buffer.data() + strLength);
308 };
309
310 attributeType = "xyz.openbmc_project.BIOSConfig.Manager."
311 "AttributeType.Enumeration";
312
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930313 uint8_t pvNum;
314 // Preconditions are upheld therefore no error check necessary
315 pldm_bios_table_attr_entry_enum_decode_pv_num_check(attrEntry,
316 &pvNum);
George Liu1b180d82020-07-23 14:01:58 +0800317 std::vector<uint16_t> pvHandls(pvNum);
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930318 // Preconditions are upheld therefore no error check necessary
319 pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
George Liu1b180d82020-07-23 14:01:58 +0800320 attrEntry, pvHandls.data(), pvHandls.size());
321
322 // get possible_value
323 for (size_t i = 0; i < pvHandls.size(); i++)
324 {
325 options.push_back(
326 std::make_tuple("xyz.openbmc_project.BIOSConfig."
327 "Manager.BoundType.OneOf",
328 getValue(pvHandls[i], *stringTable)));
329 }
330
331 auto count =
332 pldm_bios_table_attr_value_entry_enum_decode_number(
333 tableEntry);
334 std::vector<uint8_t> handles(count);
335 pldm_bios_table_attr_value_entry_enum_decode_handles(
336 tableEntry, handles.data(), handles.size());
337
338 // get current_value
339 for (size_t i = 0; i < handles.size(); i++)
340 {
341 currentValue = getValue(pvHandls[handles[i]], *stringTable);
342 }
343
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930344 uint8_t defNum;
345 // Preconditions are upheld therefore no error check necessary
346 pldm_bios_table_attr_entry_enum_decode_def_num_check(attrEntry,
347 &defNum);
George Liu1b180d82020-07-23 14:01:58 +0800348 std::vector<uint8_t> defIndices(defNum);
349 pldm_bios_table_attr_entry_enum_decode_def_indices(
350 attrEntry, defIndices.data(), defIndices.size());
351
352 // get default_value
353 for (size_t i = 0; i < defIndices.size(); i++)
354 {
Patrick Williams6da4f912023-05-10 07:50:53 -0500355 defaultValue = getValue(pvHandls[defIndices[i]],
356 *stringTable);
George Liu1b180d82020-07-23 14:01:58 +0800357 }
358
359 break;
360 }
361 case PLDM_BIOS_INTEGER:
362 case PLDM_BIOS_INTEGER_READ_ONLY:
363 {
364 attributeType = "xyz.openbmc_project.BIOSConfig.Manager."
365 "AttributeType.Integer";
366 currentValue = static_cast<int64_t>(
367 pldm_bios_table_attr_value_entry_integer_decode_cv(
368 tableEntry));
369
370 uint64_t lower, upper, def;
371 uint32_t scalar;
372 pldm_bios_table_attr_entry_integer_decode(
373 attrEntry, &lower, &upper, &scalar, &def);
374 options.push_back(
375 std::make_tuple("xyz.openbmc_project.BIOSConfig.Manager."
376 "BoundType.LowerBound",
377 static_cast<int64_t>(lower)));
378 options.push_back(
379 std::make_tuple("xyz.openbmc_project.BIOSConfig.Manager."
380 "BoundType.UpperBound",
381 static_cast<int64_t>(upper)));
382 options.push_back(
383 std::make_tuple("xyz.openbmc_project.BIOSConfig.Manager."
384 "BoundType.ScalarIncrement",
385 static_cast<int64_t>(scalar)));
386 defaultValue = static_cast<int64_t>(def);
387 break;
388 }
389 case PLDM_BIOS_STRING:
390 case PLDM_BIOS_STRING_READ_ONLY:
391 {
392 attributeType = "xyz.openbmc_project.BIOSConfig.Manager."
393 "AttributeType.String";
394 variable_field currentString;
395 pldm_bios_table_attr_value_entry_string_decode_string(
396 tableEntry, &currentString);
397 currentValue = std::string(
398 reinterpret_cast<const char*>(currentString.ptr),
399 currentString.length);
400 auto min = pldm_bios_table_attr_entry_string_decode_min_length(
401 attrEntry);
402 auto max = pldm_bios_table_attr_entry_string_decode_max_length(
403 attrEntry);
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930404 uint16_t def;
405 // Preconditions are upheld therefore no error check necessary
406 pldm_bios_table_attr_entry_string_decode_def_string_length_check(
407 attrEntry, &def);
George Liu1b180d82020-07-23 14:01:58 +0800408 std::vector<char> defString(def + 1);
409 pldm_bios_table_attr_entry_string_decode_def_string(
410 attrEntry, defString.data(), defString.size());
411 options.push_back(
412 std::make_tuple("xyz.openbmc_project.BIOSConfig.Manager."
413 "BoundType.MinStringLength",
414 static_cast<int64_t>(min)));
415 options.push_back(
416 std::make_tuple("xyz.openbmc_project.BIOSConfig.Manager."
417 "BoundType.MaxStringLength",
418 static_cast<int64_t>(max)));
419 defaultValue = defString.data();
420 break;
421 }
422 case PLDM_BIOS_PASSWORD:
423 case PLDM_BIOS_PASSWORD_READ_ONLY:
424 {
425 attributeType = "xyz.openbmc_project.BIOSConfig.Manager."
426 "AttributeType.Password";
427 break;
428 }
429 default:
430 return PLDM_INVALID_BIOS_ATTR_HANDLE;
431 }
432 baseBIOSTableMaps.emplace(
433 std::move(attributeName),
434 std::make_tuple(attributeType, readonlyStatus, displayName,
435 description, menuPath, currentValue, defaultValue,
436 std::move(options)));
437 }
438
439 return PLDM_SUCCESS;
440}
441
442void BIOSConfig::updateBaseBIOSTableProperty()
443{
444 constexpr static auto biosConfigPath =
445 "/xyz/openbmc_project/bios_config/manager";
446 constexpr static auto biosConfigInterface =
447 "xyz.openbmc_project.BIOSConfig.Manager";
448 constexpr static auto biosConfigPropertyName = "BaseBIOSTable";
449 constexpr static auto dbusProperties = "org.freedesktop.DBus.Properties";
450
451 if (baseBIOSTableMaps.empty())
452 {
453 return;
454 }
455
456 try
457 {
458 auto& bus = dbusHandler->getBus();
Patrick Williams6da4f912023-05-10 07:50:53 -0500459 auto service = dbusHandler->getService(biosConfigPath,
460 biosConfigInterface);
George Liu1b180d82020-07-23 14:01:58 +0800461 auto method = bus.new_method_call(service.c_str(), biosConfigPath,
462 dbusProperties, "Set");
463 std::variant<BaseBIOSTable> value = baseBIOSTableMaps;
464 method.append(biosConfigInterface, biosConfigPropertyName, value);
465 bus.call_noreply(method);
466 }
467 catch (const std::exception& e)
468 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600469 error("failed to update BaseBIOSTable property, ERROR={ERR_EXCEP}",
470 "ERR_EXCEP", e.what());
George Liu1b180d82020-07-23 14:01:58 +0800471 }
472}
473
John Wangd9659342020-02-27 16:46:05 +0800474void BIOSConfig::constructAttributes()
475{
476 load(jsonDir / stringJsonFile, [this](const Json& entry) {
477 constructAttribute<BIOSStringAttribute>(entry);
478 });
John Wang3be70852020-02-13 15:59:04 +0800479 load(jsonDir / integerJsonFile, [this](const Json& entry) {
John Wang95e6b3c2020-02-13 09:43:24 +0800480 constructAttribute<BIOSIntegerAttribute>(entry);
481 });
John Wang3be70852020-02-13 15:59:04 +0800482 load(jsonDir / enumJsonFile, [this](const Json& entry) {
483 constructAttribute<BIOSEnumAttribute>(entry);
484 });
John Wangd9659342020-02-27 16:46:05 +0800485}
486
487void BIOSConfig::buildAndStoreAttrTables(const Table& stringTable)
488{
489 BIOSStringTable biosStringTable(stringTable);
490
491 if (biosAttributes.empty())
492 {
493 return;
494 }
495
Tom Josephca7b2522020-11-18 12:27:11 +0530496 BaseBIOSTable biosTable{};
497 constexpr auto biosObjPath = "/xyz/openbmc_project/bios_config/manager";
498 constexpr auto biosInterface = "xyz.openbmc_project.BIOSConfig.Manager";
499
500 try
501 {
502 auto& bus = dbusHandler->getBus();
503 auto service = dbusHandler->getService(biosObjPath, biosInterface);
Patrick Williams6da4f912023-05-10 07:50:53 -0500504 auto method = bus.new_method_call(service.c_str(), biosObjPath,
505 "org.freedesktop.DBus.Properties",
506 "Get");
Tom Josephca7b2522020-11-18 12:27:11 +0530507 method.append(biosInterface, "BaseBIOSTable");
vkaverap@in.ibm.com9138c202023-05-19 07:50:47 -0500508 auto reply = bus.call(
509 method,
510 std::chrono::duration_cast<microsec>(sec(DBUS_TIMEOUT)).count());
Tom Josephca7b2522020-11-18 12:27:11 +0530511 std::variant<BaseBIOSTable> varBiosTable{};
512 reply.read(varBiosTable);
513 biosTable = std::get<BaseBIOSTable>(varBiosTable);
514 }
515 // Failed to read the BaseBIOSTable, so update the BaseBIOSTable with the
516 // default values populated from the BIOS JSONs to keep PLDM and
517 // bios-settings-manager in sync
518 catch (const std::exception& e)
519 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600520 error("Failed to read BaseBIOSTable property, ERROR={ERR_EXCEP}",
521 "ERR_EXCEP", e.what());
Tom Josephca7b2522020-11-18 12:27:11 +0530522 }
523
John Wangd9659342020-02-27 16:46:05 +0800524 Table attrTable, attrValueTable;
525
526 for (auto& attr : biosAttributes)
527 {
528 try
529 {
Tom Josephca7b2522020-11-18 12:27:11 +0530530 auto iter = biosTable.find(attr->name);
531 if (iter == biosTable.end())
532 {
533 attr->constructEntry(biosStringTable, attrTable, attrValueTable,
534 std::nullopt);
535 }
536 else
537 {
538 attr->constructEntry(
539 biosStringTable, attrTable, attrValueTable,
540 std::get<static_cast<uint8_t>(Index::currentValue)>(
541 iter->second));
542 }
John Wangd9659342020-02-27 16:46:05 +0800543 }
544 catch (const std::exception& e)
545 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600546 error("Construct Table Entry Error, AttributeName = {ATTR_NAME}",
547 "ATTR_NAME", attr->name);
John Wangd9659342020-02-27 16:46:05 +0800548 }
549 }
550
551 table::appendPadAndChecksum(attrTable);
552 table::appendPadAndChecksum(attrValueTable);
George Liu1b180d82020-07-23 14:01:58 +0800553 setBIOSTable(PLDM_BIOS_ATTR_TABLE, attrTable);
554 setBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE, attrValueTable);
John Wangd9659342020-02-27 16:46:05 +0800555}
556
557std::optional<Table> BIOSConfig::buildAndStoreStringTable()
558{
559 std::set<std::string> strings;
560 auto handler = [&strings](const Json& entry) {
561 strings.emplace(entry.at("attribute_name"));
562 };
563
564 load(jsonDir / stringJsonFile, handler);
565 load(jsonDir / integerJsonFile, handler);
566 load(jsonDir / enumJsonFile, [&strings](const Json& entry) {
567 strings.emplace(entry.at("attribute_name"));
568 auto possibleValues = entry.at("possible_values");
569 for (auto& pv : possibleValues)
570 {
571 strings.emplace(pv);
572 }
573 });
574
575 if (strings.empty())
576 {
577 return std::nullopt;
578 }
579
580 Table table;
581 for (const auto& elem : strings)
582 {
583 table::string::constructEntry(table, elem);
584 }
585
586 table::appendPadAndChecksum(table);
George Liu1b180d82020-07-23 14:01:58 +0800587 setBIOSTable(PLDM_BIOS_STRING_TABLE, table);
John Wangd9659342020-02-27 16:46:05 +0800588 return table;
589}
590
591void BIOSConfig::storeTable(const fs::path& path, const Table& table)
592{
593 BIOSTable biosTable(path.c_str());
594 biosTable.store(table);
595}
596
597std::optional<Table> BIOSConfig::loadTable(const fs::path& path)
598{
599 BIOSTable biosTable(path.c_str());
600 if (biosTable.isEmpty())
601 {
602 return std::nullopt;
603 }
604
605 Table table;
606 biosTable.load(table);
607 return table;
608}
609
610void BIOSConfig::load(const fs::path& filePath, ParseHandler handler)
611{
612 std::ifstream file;
613 Json jsonConf;
614 if (fs::exists(filePath))
615 {
616 try
617 {
618 file.open(filePath);
619 jsonConf = Json::parse(file);
620 auto entries = jsonConf.at("entries");
621 for (auto& entry : entries)
622 {
623 try
624 {
625 handler(entry);
626 }
627 catch (const std::exception& e)
628 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600629 error(
630 "Failed to parse JSON config file(entry handler) : {JSON_PATH}, {ERR_EXCEP}",
631 "JSON_PATH", filePath.c_str(), "ERR_EXCEP", e.what());
John Wangd9659342020-02-27 16:46:05 +0800632 }
633 }
634 }
635 catch (const std::exception& e)
636 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600637 error("Failed to parse JSON config file : {JSON_PATH}", "JSON_PATH",
638 filePath.c_str());
John Wangd9659342020-02-27 16:46:05 +0800639 }
640 }
641}
642
Sagar Srinivascac0ebb2021-11-23 07:50:28 -0600643std::string BIOSConfig::decodeStringFromStringEntry(
644 const pldm_bios_string_table_entry* stringEntry)
645{
646 auto strLength =
647 pldm_bios_table_string_entry_decode_string_length(stringEntry);
648 std::vector<char> buffer(strLength + 1 /* sizeof '\0' */);
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930649 // Preconditions are upheld therefore no error check necessary
650 pldm_bios_table_string_entry_decode_string_check(stringEntry, buffer.data(),
651 buffer.size());
Sagar Srinivascac0ebb2021-11-23 07:50:28 -0600652 return std::string(buffer.data(), buffer.data() + strLength);
653}
654
655std::string
656 BIOSConfig::displayStringHandle(uint16_t handle, uint8_t index,
657 const std::optional<Table>& attrTable,
658 const std::optional<Table>& stringTable)
659{
660 auto attrEntry = pldm_bios_table_attr_find_by_handle(
661 attrTable->data(), attrTable->size(), handle);
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930662 uint8_t pvNum;
663 int rc = pldm_bios_table_attr_entry_enum_decode_pv_num_check(attrEntry,
664 &pvNum);
665 if (rc != PLDM_SUCCESS)
666 {
667 error(
668 "Failed to decode BIOS table possible values for attribute entry: {LIPBLDM_ERROR}",
669 "LIBPLDM_ERROR", rc);
670 throw std::runtime_error(
671 "Failed to decode BIOS table possible values for attribute entry");
672 }
673
Sagar Srinivascac0ebb2021-11-23 07:50:28 -0600674 std::vector<uint16_t> pvHandls(pvNum);
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930675 // Preconditions are upheld therefore no error check necessary
676 pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
677 attrEntry, pvHandls.data(), pvHandls.size());
Sagar Srinivascac0ebb2021-11-23 07:50:28 -0600678
679 std::string displayString = std::to_string(pvHandls[index]);
680
681 auto stringEntry = pldm_bios_table_string_find_by_handle(
682 stringTable->data(), stringTable->size(), pvHandls[index]);
683
684 auto decodedStr = decodeStringFromStringEntry(stringEntry);
685
686 return decodedStr + "(" + displayString + ")";
687}
688
689void BIOSConfig::traceBIOSUpdate(
690 const pldm_bios_attr_val_table_entry* attrValueEntry,
691 const pldm_bios_attr_table_entry* attrEntry, bool isBMC)
692{
693 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
694 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
695
Patrick Williams6da4f912023-05-10 07:50:53 -0500696 auto [attrHandle,
697 attrType] = table::attribute_value::decodeHeader(attrValueEntry);
Sagar Srinivascac0ebb2021-11-23 07:50:28 -0600698
699 auto attrHeader = table::attribute::decodeHeader(attrEntry);
700 BIOSStringTable biosStringTable(*stringTable);
701 auto attrName = biosStringTable.findString(attrHeader.stringHandle);
702
703 switch (attrType)
704 {
705 case PLDM_BIOS_ENUMERATION:
706 case PLDM_BIOS_ENUMERATION_READ_ONLY:
707 {
708 auto count = pldm_bios_table_attr_value_entry_enum_decode_number(
709 attrValueEntry);
710 std::vector<uint8_t> handles(count);
711 pldm_bios_table_attr_value_entry_enum_decode_handles(
712 attrValueEntry, handles.data(), handles.size());
713
714 for (uint8_t handle : handles)
715 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600716 auto nwVal = displayStringHandle(attrHandle, handle, attrTable,
717 stringTable);
718 auto chkBMC = isBMC ? "true" : "false";
719 info(
720 "BIOS:{ATTR_NAME}, updated to value: {NEW_VAL}, by BMC: {CHK_BMC} ",
721 "ATTR_NAME", attrName, "NEW_VAL", nwVal, "CHK_BMC", chkBMC);
Sagar Srinivascac0ebb2021-11-23 07:50:28 -0600722 }
723 break;
724 }
725 case PLDM_BIOS_INTEGER:
726 case PLDM_BIOS_INTEGER_READ_ONLY:
727 {
728 auto value =
729 table::attribute_value::decodeIntegerEntry(attrValueEntry);
Riya Dixit49cfb132023-03-02 04:26:53 -0600730 auto chkBMC = isBMC ? "true" : "false";
731 info(
732 "BIOS: {ATTR_NAME}, updated to value: {UPDATED_VAL}, by BMC: {CHK_BMC}",
733 "ATTR_NAME", attrName, "UPDATED_VAL", value, "CHK_BMC", chkBMC);
Sagar Srinivascac0ebb2021-11-23 07:50:28 -0600734 break;
735 }
736 case PLDM_BIOS_STRING:
737 case PLDM_BIOS_STRING_READ_ONLY:
738 {
739 auto value =
740 table::attribute_value::decodeStringEntry(attrValueEntry);
Riya Dixit49cfb132023-03-02 04:26:53 -0600741 auto chkBMC = isBMC ? "true" : "false";
742 info(
743 "BIOS: {ATTR_NAME}, updated to value: {UPDATED_VAL}, by BMC: {CHK_BMC}",
744 "ATTR_NAME", attrName, "UPDATED_VAL", value, "CHK_BMC", chkBMC);
Sagar Srinivascac0ebb2021-11-23 07:50:28 -0600745 break;
746 }
747 default:
748 break;
749 };
750}
751
John Wang8241b342020-06-05 10:49:17 +0800752int BIOSConfig::checkAttrValueToUpdate(
753 const pldm_bios_attr_val_table_entry* attrValueEntry,
754 const pldm_bios_attr_table_entry* attrEntry, Table&)
755
756{
Patrick Williams6da4f912023-05-10 07:50:53 -0500757 auto [attrHandle,
758 attrType] = table::attribute_value::decodeHeader(attrValueEntry);
John Wang8241b342020-06-05 10:49:17 +0800759
760 switch (attrType)
761 {
762 case PLDM_BIOS_ENUMERATION:
George Liu5bb9edb2021-08-05 20:10:32 +0800763 case PLDM_BIOS_ENUMERATION_READ_ONLY:
John Wang8241b342020-06-05 10:49:17 +0800764 {
765 auto value =
766 table::attribute_value::decodeEnumEntry(attrValueEntry);
Patrick Williams6da4f912023-05-10 07:50:53 -0500767 auto [pvHdls,
768 defIndex] = table::attribute::decodeEnumEntry(attrEntry);
Varsha Kaverappa6a4d1cf2021-11-24 21:15:42 -0600769 if (!(value.size() == 1))
770 {
771 return PLDM_ERROR_INVALID_LENGTH;
772 }
John Wang8241b342020-06-05 10:49:17 +0800773 if (value[0] >= pvHdls.size())
774 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600775 error("Enum: Illgeal index, Index = {ATTR_INDEX}", "ATTR_INDEX",
776 (int)value[0]);
John Wang8241b342020-06-05 10:49:17 +0800777 return PLDM_ERROR_INVALID_DATA;
778 }
John Wang8241b342020-06-05 10:49:17 +0800779 return PLDM_SUCCESS;
780 }
781 case PLDM_BIOS_INTEGER:
George Liu5bb9edb2021-08-05 20:10:32 +0800782 case PLDM_BIOS_INTEGER_READ_ONLY:
John Wang8241b342020-06-05 10:49:17 +0800783 {
784 auto value =
785 table::attribute_value::decodeIntegerEntry(attrValueEntry);
Patrick Williams6da4f912023-05-10 07:50:53 -0500786 auto [lower, upper, scalar,
787 def] = table::attribute::decodeIntegerEntry(attrEntry);
John Wang8241b342020-06-05 10:49:17 +0800788
789 if (value < lower || value > upper)
790 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600791 error("Integer: out of bound, value = {ATTR_VALUE}",
792 "ATTR_VALUE", value);
John Wang8241b342020-06-05 10:49:17 +0800793 return PLDM_ERROR_INVALID_DATA;
794 }
795 return PLDM_SUCCESS;
796 }
797 case PLDM_BIOS_STRING:
George Liu5bb9edb2021-08-05 20:10:32 +0800798 case PLDM_BIOS_STRING_READ_ONLY:
John Wang8241b342020-06-05 10:49:17 +0800799 {
800 auto stringConf = table::attribute::decodeStringEntry(attrEntry);
801 auto value =
802 table::attribute_value::decodeStringEntry(attrValueEntry);
803 if (value.size() < stringConf.minLength ||
804 value.size() > stringConf.maxLength)
805 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600806 error(
807 "String: Length error, string = {ATTR_VALUE} length {LEN}",
808 "ATTR_VALUE", value, "LEN", value.size());
John Wang8241b342020-06-05 10:49:17 +0800809 return PLDM_ERROR_INVALID_LENGTH;
810 }
811 return PLDM_SUCCESS;
812 }
813 default:
Riya Dixit49cfb132023-03-02 04:26:53 -0600814 error("ReadOnly or Unspported type, type = {ATTR_TYPE}",
815 "ATTR_TYPE", attrType);
John Wang8241b342020-06-05 10:49:17 +0800816 return PLDM_ERROR;
817 };
818}
819
Sagar Srinivascac0ebb2021-11-23 07:50:28 -0600820int BIOSConfig::setAttrValue(const void* entry, size_t size, bool isBMC,
821 bool updateDBus, bool updateBaseBIOSTable)
John Wangd9659342020-02-27 16:46:05 +0800822{
823 auto attrValueTable = getBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE);
824 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
825 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
826 if (!attrValueTable || !attrTable || !stringTable)
827 {
828 return PLDM_BIOS_TABLE_UNAVAILABLE;
829 }
830
John Wangd9659342020-02-27 16:46:05 +0800831 auto attrValueEntry =
832 reinterpret_cast<const pldm_bios_attr_val_table_entry*>(entry);
833
834 auto attrValHeader = table::attribute_value::decodeHeader(attrValueEntry);
835
Patrick Williams6da4f912023-05-10 07:50:53 -0500836 auto attrEntry = table::attribute::findByHandle(*attrTable,
837 attrValHeader.attrHandle);
John Wangd9659342020-02-27 16:46:05 +0800838 if (!attrEntry)
839 {
840 return PLDM_ERROR;
841 }
842
John Wang8241b342020-06-05 10:49:17 +0800843 auto rc = checkAttrValueToUpdate(attrValueEntry, attrEntry, *stringTable);
844 if (rc != PLDM_SUCCESS)
845 {
846 return rc;
847 }
848
Patrick Williams6da4f912023-05-10 07:50:53 -0500849 auto destTable = table::attribute_value::updateTable(*attrValueTable, entry,
850 size);
John Wang8241b342020-06-05 10:49:17 +0800851
852 if (!destTable)
853 {
854 return PLDM_ERROR;
855 }
856
John Wangd9659342020-02-27 16:46:05 +0800857 try
858 {
859 auto attrHeader = table::attribute::decodeHeader(attrEntry);
860
861 BIOSStringTable biosStringTable(*stringTable);
862 auto attrName = biosStringTable.findString(attrHeader.stringHandle);
Patrick Williams6da4f912023-05-10 07:50:53 -0500863 auto iter = std::find_if(biosAttributes.begin(), biosAttributes.end(),
864 [&attrName](const auto& attr) {
865 return attr->name == attrName;
866 });
John Wangd9659342020-02-27 16:46:05 +0800867
868 if (iter == biosAttributes.end())
869 {
870 return PLDM_ERROR;
871 }
George Liu6d6d1e82021-02-16 11:08:55 +0800872 if (updateDBus)
873 {
874 (*iter)->setAttrValueOnDbus(attrValueEntry, attrEntry,
875 biosStringTable);
876 }
John Wangd9659342020-02-27 16:46:05 +0800877 }
878 catch (const std::exception& e)
879 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600880 error("Set attribute value error: {ERR_EXCEP}", "ERR_EXCEP", e.what());
John Wangd9659342020-02-27 16:46:05 +0800881 return PLDM_ERROR;
882 }
883
Tom Joseph7f839f92020-09-21 10:20:44 +0530884 setBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE, *destTable, updateBaseBIOSTable);
George Liu5c3192b2020-08-13 17:35:43 +0800885
Sagar Srinivascac0ebb2021-11-23 07:50:28 -0600886 traceBIOSUpdate(attrValueEntry, attrEntry, isBMC);
887
John Wangd9659342020-02-27 16:46:05 +0800888 return PLDM_SUCCESS;
889}
890
891void BIOSConfig::removeTables()
892{
893 try
894 {
895 fs::remove(tableDir / stringTableFile);
896 fs::remove(tableDir / attrTableFile);
897 fs::remove(tableDir / attrValueTableFile);
898 }
899 catch (const std::exception& e)
900 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600901 error("Remove the tables error: {ERR_EXCEP}", "ERR_EXCEP", e.what());
John Wangd9659342020-02-27 16:46:05 +0800902 }
903}
904
Sampa Misra46ece062020-03-18 07:17:44 -0500905void BIOSConfig::processBiosAttrChangeNotification(
906 const DbusChObjProperties& chProperties, uint32_t biosAttrIndex)
907{
908 const auto& dBusMap = biosAttributes[biosAttrIndex]->getDBusMap();
909 const auto& propertyName = dBusMap->propertyName;
910 const auto& attrName = biosAttributes[biosAttrIndex]->name;
911
912 const auto it = chProperties.find(propertyName);
913 if (it == chProperties.end())
914 {
915 return;
916 }
917
918 PropertyValue newPropVal = it->second;
919 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
920 if (!stringTable.has_value())
921 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600922 error("BIOS string table unavailable");
Sampa Misra46ece062020-03-18 07:17:44 -0500923 return;
924 }
925 BIOSStringTable biosStringTable(*stringTable);
926 uint16_t attrNameHdl{};
927 try
928 {
929 attrNameHdl = biosStringTable.findHandle(attrName);
930 }
Patrick Williams51330582021-10-06 12:48:56 -0500931 catch (const std::invalid_argument& e)
Sampa Misra46ece062020-03-18 07:17:44 -0500932 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600933 error("Could not find handle for BIOS string, ATTRIBUTE={ATTR_NAME}",
934 "ATTR_NAME", attrName.c_str());
Sampa Misra46ece062020-03-18 07:17:44 -0500935 return;
936 }
937
938 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
939 if (!attrTable.has_value())
940 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600941 error("Attribute table not present");
Sampa Misra46ece062020-03-18 07:17:44 -0500942 return;
943 }
944 const struct pldm_bios_attr_table_entry* tableEntry =
945 table::attribute::findByStringHandle(*attrTable, attrNameHdl);
946 if (tableEntry == nullptr)
947 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600948 error(
949 "Attribute not found in attribute table, name= {ATTR_NAME} name handle={ATTR_HANDLE}",
950 "ATTR_NAME", attrName.c_str(), "ATTR_HANDLE", attrNameHdl);
Sampa Misra46ece062020-03-18 07:17:44 -0500951 return;
952 }
953
Patrick Williams6da4f912023-05-10 07:50:53 -0500954 auto [attrHdl, attrType,
955 stringHdl] = table::attribute::decodeHeader(tableEntry);
Sampa Misra46ece062020-03-18 07:17:44 -0500956
957 auto attrValueSrcTable = getBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE);
958
959 if (!attrValueSrcTable.has_value())
960 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600961 error("Attribute value table not present");
Sampa Misra46ece062020-03-18 07:17:44 -0500962 return;
963 }
964
965 Table newValue;
966 auto rc = biosAttributes[biosAttrIndex]->updateAttrVal(
967 newValue, attrHdl, attrType, newPropVal);
968 if (rc != PLDM_SUCCESS)
969 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600970 error(
971 "Could not update the attribute value table for attribute handle={ATTR_HANDLE} and type={ATTR_TYPE}",
972 "ATTR_HANDLE", attrHdl, "ATTR_TYPE", (uint32_t)attrType);
Sampa Misra46ece062020-03-18 07:17:44 -0500973 return;
974 }
975 auto destTable = table::attribute_value::updateTable(
976 *attrValueSrcTable, newValue.data(), newValue.size());
977 if (destTable.has_value())
978 {
979 storeTable(tableDir / attrValueTableFile, *destTable);
980 }
Sampa Misra0f262332021-02-15 00:13:51 -0600981
Sagar Srinivascac0ebb2021-11-23 07:50:28 -0600982 rc = setAttrValue(newValue.data(), newValue.size(), true, false);
Sampa Misra0f262332021-02-15 00:13:51 -0600983 if (rc != PLDM_SUCCESS)
984 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600985 error("could not setAttrValue on base bios table and dbus, rc = {RC}",
986 "RC", rc);
Sampa Misra0f262332021-02-15 00:13:51 -0600987 }
Sampa Misra46ece062020-03-18 07:17:44 -0500988}
989
George Liu1244acf2020-08-14 09:11:11 +0800990uint16_t BIOSConfig::findAttrHandle(const std::string& attrName)
991{
992 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
993 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
994
995 BIOSStringTable biosStringTable(*stringTable);
996 pldm::bios::utils::BIOSTableIter<PLDM_BIOS_ATTR_TABLE> attrTableIter(
997 attrTable->data(), attrTable->size());
998 auto stringHandle = biosStringTable.findHandle(attrName);
999
1000 for (auto entry : pldm::bios::utils::BIOSTableIter<PLDM_BIOS_ATTR_TABLE>(
1001 attrTable->data(), attrTable->size()))
1002 {
1003 auto header = table::attribute::decodeHeader(entry);
1004 if (header.stringHandle == stringHandle)
1005 {
1006 return header.attrHandle;
1007 }
1008 }
1009
1010 throw std::invalid_argument("Unknow attribute Name");
1011}
1012
1013void BIOSConfig::constructPendingAttribute(
1014 const PendingAttributes& pendingAttributes)
1015{
Tom Joseph7f839f92020-09-21 10:20:44 +05301016 std::vector<uint16_t> listOfHandles{};
1017
George Liu1244acf2020-08-14 09:11:11 +08001018 for (auto& attribute : pendingAttributes)
1019 {
1020 std::string attributeName = attribute.first;
1021 auto& [attributeType, attributevalue] = attribute.second;
1022
1023 auto iter = std::find_if(biosAttributes.begin(), biosAttributes.end(),
1024 [&attributeName](const auto& attr) {
Patrick Williams6da4f912023-05-10 07:50:53 -05001025 return attr->name == attributeName;
1026 });
George Liu1244acf2020-08-14 09:11:11 +08001027
1028 if (iter == biosAttributes.end())
1029 {
Riya Dixit49cfb132023-03-02 04:26:53 -06001030 error("Wrong attribute name, attributeName = {ATTR_NAME}",
1031 "ATTR_NAME", attributeName);
George Liu1244acf2020-08-14 09:11:11 +08001032 continue;
1033 }
1034
1035 Table attrValueEntry(sizeof(pldm_bios_attr_val_table_entry), 0);
1036 auto entry = reinterpret_cast<pldm_bios_attr_val_table_entry*>(
1037 attrValueEntry.data());
1038
1039 auto handler = findAttrHandle(attributeName);
1040 auto type =
1041 BIOSConfigManager::convertAttributeTypeFromString(attributeType);
1042
1043 if (type != BIOSConfigManager::AttributeType::Enumeration &&
1044 type != BIOSConfigManager::AttributeType::String &&
1045 type != BIOSConfigManager::AttributeType::Integer)
1046 {
Riya Dixit49cfb132023-03-02 04:26:53 -06001047 error("Attribute type not supported, attributeType = {ATTR_TYPE}",
1048 "ATTR_TYPE", attributeType);
George Liu1244acf2020-08-14 09:11:11 +08001049 continue;
1050 }
1051
George Liu4876c542022-06-08 15:59:54 +08001052 const auto [attrType, readonlyStatus, displayName, description,
Patrick Williams6da4f912023-05-10 07:50:53 -05001053 menuPath, currentValue, defaultValue,
1054 option] = baseBIOSTableMaps.at(attributeName);
George Liu4876c542022-06-08 15:59:54 +08001055
George Liu1244acf2020-08-14 09:11:11 +08001056 entry->attr_handle = htole16(handler);
George Liu4876c542022-06-08 15:59:54 +08001057
1058 // Need to verify that the current value has really changed
1059 if (attributeType == attrType && attributevalue != currentValue)
1060 {
1061 listOfHandles.emplace_back(htole16(handler));
1062 }
Tom Joseph7f839f92020-09-21 10:20:44 +05301063
George Liu1244acf2020-08-14 09:11:11 +08001064 (*iter)->generateAttributeEntry(attributevalue, attrValueEntry);
1065
Sagar Srinivascac0ebb2021-11-23 07:50:28 -06001066 setAttrValue(attrValueEntry.data(), attrValueEntry.size(), true);
Tom Joseph7f839f92020-09-21 10:20:44 +05301067 }
1068
1069 if (listOfHandles.size())
1070 {
1071#ifdef OEM_IBM
1072 auto rc = pldm::responder::platform::sendBiosAttributeUpdateEvent(
Andrew Jefferya330b2f2023-05-04 14:55:37 +09301073 eid, instanceIdDb, listOfHandles, handler);
Tom Joseph7f839f92020-09-21 10:20:44 +05301074 if (rc != PLDM_SUCCESS)
1075 {
1076 return;
1077 }
1078#endif
George Liu1244acf2020-08-14 09:11:11 +08001079 }
1080}
1081
1082void BIOSConfig::listenPendingAttributes()
1083{
1084 constexpr auto objPath = "/xyz/openbmc_project/bios_config/manager";
1085 constexpr auto objInterface = "xyz.openbmc_project.BIOSConfig.Manager";
1086
1087 using namespace sdbusplus::bus::match::rules;
Patrick Williams84b790c2022-07-22 19:26:56 -05001088 auto updateBIOSMatch = std::make_unique<sdbusplus::bus::match_t>(
George Liu1244acf2020-08-14 09:11:11 +08001089 pldm::utils::DBusHandler::getBus(),
1090 propertiesChanged(objPath, objInterface),
Patrick Williams84b790c2022-07-22 19:26:56 -05001091 [this](sdbusplus::message_t& msg) {
Patrick Williams6da4f912023-05-10 07:50:53 -05001092 constexpr auto propertyName = "PendingAttributes";
George Liu1244acf2020-08-14 09:11:11 +08001093
Patrick Williams6da4f912023-05-10 07:50:53 -05001094 using Value =
1095 std::variant<std::string, PendingAttributes, BaseBIOSTable>;
1096 using Properties = std::map<DbusProp, Value>;
George Liu1244acf2020-08-14 09:11:11 +08001097
Patrick Williams6da4f912023-05-10 07:50:53 -05001098 Properties props{};
1099 std::string intf;
1100 msg.read(intf, props);
George Liu1244acf2020-08-14 09:11:11 +08001101
Patrick Williams6da4f912023-05-10 07:50:53 -05001102 auto valPropMap = props.find(propertyName);
1103 if (valPropMap == props.end())
1104 {
1105 return;
1106 }
George Liu1244acf2020-08-14 09:11:11 +08001107
Patrick Williams6da4f912023-05-10 07:50:53 -05001108 PendingAttributes pendingAttributes =
1109 std::get<PendingAttributes>(valPropMap->second);
1110 this->constructPendingAttribute(pendingAttributes);
George Liu1244acf2020-08-14 09:11:11 +08001111 });
1112
1113 biosAttrMatch.emplace_back(std::move(updateBIOSMatch));
1114}
1115
John Wangd9659342020-02-27 16:46:05 +08001116} // namespace bios
1117} // namespace responder
1118} // namespace pldm