blob: dec7b3f115359d0f6ff550ab438ad40104c18acb [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,
Sagar Srinivas11ce8d22022-07-28 11:32:34 -050047 pldm::requester::Handler<pldm::requester::Request>* handler,
48 pldm::responder::oem_bios::Handler* oemBiosHandler) :
John Wangd9659342020-02-27 16:46:05 +080049 jsonDir(jsonDir),
Tom Joseph7f839f92020-09-21 10:20:44 +053050 tableDir(tableDir), dbusHandler(dbusHandler), fd(fd), eid(eid),
Sagar Srinivas11ce8d22022-07-28 11:32:34 -050051 instanceIdDb(instanceIdDb), handler(handler), oemBiosHandler(oemBiosHandler)
Tom Joseph7f839f92020-09-21 10:20:44 +053052
John Wangd9659342020-02-27 16:46:05 +080053{
Sagar Srinivas11ce8d22022-07-28 11:32:34 -050054 if (oemBiosHandler)
55 {
56 auto systemType = oemBiosHandler->getPlatformName();
57 if (systemType.has_value())
58 {
59 sysType = systemType.value();
60 }
61 }
George Liu9d8921e2020-05-14 15:41:50 +080062 fs::create_directories(tableDir);
John Wangd9659342020-02-27 16:46:05 +080063 constructAttributes();
George Liu1244acf2020-08-14 09:11:11 +080064 listenPendingAttributes();
John Wangd9659342020-02-27 16:46:05 +080065}
66
67void BIOSConfig::buildTables()
68{
John Wangd9659342020-02-27 16:46:05 +080069 auto stringTable = buildAndStoreStringTable();
70 if (stringTable)
71 {
72 buildAndStoreAttrTables(*stringTable);
73 }
74}
75
76std::optional<Table> BIOSConfig::getBIOSTable(pldm_bios_table_types tableType)
77{
78 fs::path tablePath;
79 switch (tableType)
80 {
81 case PLDM_BIOS_STRING_TABLE:
82 tablePath = tableDir / stringTableFile;
83 break;
84 case PLDM_BIOS_ATTR_TABLE:
85 tablePath = tableDir / attrTableFile;
86 break;
87 case PLDM_BIOS_ATTR_VAL_TABLE:
88 tablePath = tableDir / attrValueTableFile;
89 break;
90 }
91 return loadTable(tablePath);
92}
93
Tom Joseph7f839f92020-09-21 10:20:44 +053094int BIOSConfig::setBIOSTable(uint8_t tableType, const Table& table,
95 bool updateBaseBIOSTable)
George Liu1b180d82020-07-23 14:01:58 +080096{
97 fs::path stringTablePath(tableDir / stringTableFile);
98 fs::path attrTablePath(tableDir / attrTableFile);
99 fs::path attrValueTablePath(tableDir / attrValueTableFile);
100
101 if (!pldm_bios_table_checksum(table.data(), table.size()))
102 {
103 return PLDM_INVALID_BIOS_TABLE_DATA_INTEGRITY_CHECK;
104 }
105
106 if (tableType == PLDM_BIOS_STRING_TABLE)
107 {
108 storeTable(stringTablePath, table);
109 }
110 else if (tableType == PLDM_BIOS_ATTR_TABLE)
111 {
112 BIOSTable biosStringTable(stringTablePath.c_str());
113 if (biosStringTable.isEmpty())
114 {
115 return PLDM_INVALID_BIOS_TABLE_TYPE;
116 }
117
118 auto rc = checkAttributeTable(table);
119 if (rc != PLDM_SUCCESS)
120 {
121 return rc;
122 }
123
124 storeTable(attrTablePath, table);
125 }
126 else if (tableType == PLDM_BIOS_ATTR_VAL_TABLE)
127 {
128 BIOSTable biosStringTable(stringTablePath.c_str());
129 BIOSTable biosStringValueTable(attrTablePath.c_str());
130 if (biosStringTable.isEmpty() || biosStringValueTable.isEmpty())
131 {
132 return PLDM_INVALID_BIOS_TABLE_TYPE;
133 }
134
135 auto rc = checkAttributeValueTable(table);
136 if (rc != PLDM_SUCCESS)
137 {
138 return rc;
139 }
140
141 storeTable(attrValueTablePath, table);
George Liu1b180d82020-07-23 14:01:58 +0800142 }
143 else
144 {
145 return PLDM_INVALID_BIOS_TABLE_TYPE;
146 }
147
Tom Joseph7f839f92020-09-21 10:20:44 +0530148 if ((tableType == PLDM_BIOS_ATTR_VAL_TABLE) && updateBaseBIOSTable)
George Liu1b180d82020-07-23 14:01:58 +0800149 {
George Liu1b180d82020-07-23 14:01:58 +0800150 updateBaseBIOSTableProperty();
151 }
152
153 return PLDM_SUCCESS;
154}
155
156int BIOSConfig::checkAttributeTable(const Table& table)
157{
158 using namespace pldm::bios::utils;
159 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
160 for (auto entry :
161 BIOSTableIter<PLDM_BIOS_ATTR_TABLE>(table.data(), table.size()))
162 {
163 auto attrNameHandle =
164 pldm_bios_table_attr_entry_decode_string_handle(entry);
165
166 auto stringEnty = pldm_bios_table_string_find_by_handle(
167 stringTable->data(), stringTable->size(), attrNameHandle);
168 if (stringEnty == nullptr)
169 {
170 return PLDM_INVALID_BIOS_ATTR_HANDLE;
171 }
172
173 auto attrType = static_cast<pldm_bios_attribute_type>(
174 pldm_bios_table_attr_entry_decode_attribute_type(entry));
175
176 switch (attrType)
177 {
178 case PLDM_BIOS_ENUMERATION:
179 case PLDM_BIOS_ENUMERATION_READ_ONLY:
180 {
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930181 uint8_t pvNum;
182 // Preconditions are upheld therefore no error check necessary
183 pldm_bios_table_attr_entry_enum_decode_pv_num_check(entry,
184 &pvNum);
George Liu1b180d82020-07-23 14:01:58 +0800185 std::vector<uint16_t> pvHandls(pvNum);
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930186 // Preconditions are upheld therefore no error check necessary
187 pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
George Liu1b180d82020-07-23 14:01:58 +0800188 entry, pvHandls.data(), pvHandls.size());
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930189 uint8_t defNum;
190 pldm_bios_table_attr_entry_enum_decode_def_num_check(entry,
191 &defNum);
George Liu1b180d82020-07-23 14:01:58 +0800192 std::vector<uint8_t> defIndices(defNum);
193 pldm_bios_table_attr_entry_enum_decode_def_indices(
194 entry, defIndices.data(), defIndices.size());
195
196 for (size_t i = 0; i < pvHandls.size(); i++)
197 {
198 auto stringEntry = pldm_bios_table_string_find_by_handle(
199 stringTable->data(), stringTable->size(), pvHandls[i]);
200 if (stringEntry == nullptr)
201 {
202 return PLDM_INVALID_BIOS_ATTR_HANDLE;
203 }
204 }
205
206 for (size_t i = 0; i < defIndices.size(); i++)
207 {
208 auto stringEntry = pldm_bios_table_string_find_by_handle(
209 stringTable->data(), stringTable->size(),
210 pvHandls[defIndices[i]]);
211 if (stringEntry == nullptr)
212 {
213 return PLDM_INVALID_BIOS_ATTR_HANDLE;
214 }
215 }
216 break;
217 }
218 case PLDM_BIOS_INTEGER:
219 case PLDM_BIOS_INTEGER_READ_ONLY:
220 case PLDM_BIOS_STRING:
221 case PLDM_BIOS_STRING_READ_ONLY:
222 case PLDM_BIOS_PASSWORD:
223 case PLDM_BIOS_PASSWORD_READ_ONLY:
224 break;
225 default:
226 return PLDM_INVALID_BIOS_ATTR_HANDLE;
227 }
228 }
229
230 return PLDM_SUCCESS;
231}
232
233int BIOSConfig::checkAttributeValueTable(const Table& table)
234{
235 using namespace pldm::bios::utils;
236 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
237 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
238
239 baseBIOSTableMaps.clear();
240
241 for (auto tableEntry :
242 BIOSTableIter<PLDM_BIOS_ATTR_VAL_TABLE>(table.data(), table.size()))
243 {
244 AttributeName attributeName{};
245 AttributeType attributeType{};
246 ReadonlyStatus readonlyStatus{};
247 DisplayName displayName{};
248 Description description{};
249 MenuPath menuPath{};
250 CurrentValue currentValue{};
251 DefaultValue defaultValue{};
252 Option options{};
253
254 auto attrValueHandle =
255 pldm_bios_table_attr_value_entry_decode_attribute_handle(
256 tableEntry);
257 auto attrType = static_cast<pldm_bios_attribute_type>(
258 pldm_bios_table_attr_value_entry_decode_attribute_type(tableEntry));
259
260 auto attrEntry = pldm_bios_table_attr_find_by_handle(
261 attrTable->data(), attrTable->size(), attrValueHandle);
262 if (attrEntry == nullptr)
263 {
264 return PLDM_INVALID_BIOS_ATTR_HANDLE;
265 }
266 auto attrHandle =
267 pldm_bios_table_attr_entry_decode_attribute_handle(attrEntry);
268 auto attrNameHandle =
269 pldm_bios_table_attr_entry_decode_string_handle(attrEntry);
270
271 auto stringEntry = pldm_bios_table_string_find_by_handle(
272 stringTable->data(), stringTable->size(), attrNameHandle);
273 if (stringEntry == nullptr)
274 {
275 return PLDM_INVALID_BIOS_ATTR_HANDLE;
276 }
277 auto strLength =
278 pldm_bios_table_string_entry_decode_string_length(stringEntry);
279 std::vector<char> buffer(strLength + 1 /* sizeof '\0' */);
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930280 // Preconditions are upheld therefore no error check necessary
281 pldm_bios_table_string_entry_decode_string_check(
282 stringEntry, buffer.data(), buffer.size());
283
George Liu1b180d82020-07-23 14:01:58 +0800284 attributeName = std::string(buffer.data(), buffer.data() + strLength);
285
286 if (!biosAttributes.empty())
287 {
288 readonlyStatus =
George Liub1fbeec2020-09-04 09:59:46 +0800289 biosAttributes[attrHandle % biosAttributes.size()]->readOnly;
George Liu92bb4022020-09-03 14:58:24 +0800290 description =
291 biosAttributes[attrHandle % biosAttributes.size()]->helpText;
292 displayName =
293 biosAttributes[attrHandle % biosAttributes.size()]->displayName;
George Liu1b180d82020-07-23 14:01:58 +0800294 }
295
296 switch (attrType)
297 {
298 case PLDM_BIOS_ENUMERATION:
299 case PLDM_BIOS_ENUMERATION_READ_ONLY:
300 {
301 auto getValue = [](uint16_t handle,
302 const Table& table) -> std::string {
303 auto stringEntry = pldm_bios_table_string_find_by_handle(
304 table.data(), table.size(), handle);
305
306 auto strLength =
307 pldm_bios_table_string_entry_decode_string_length(
308 stringEntry);
309 std::vector<char> buffer(strLength + 1 /* sizeof '\0' */);
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930310 // Preconditions are upheld therefore no error check
311 // necessary
312 pldm_bios_table_string_entry_decode_string_check(
George Liu1b180d82020-07-23 14:01:58 +0800313 stringEntry, buffer.data(), buffer.size());
314
315 return std::string(buffer.data(),
316 buffer.data() + strLength);
317 };
318
319 attributeType = "xyz.openbmc_project.BIOSConfig.Manager."
320 "AttributeType.Enumeration";
321
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930322 uint8_t pvNum;
323 // Preconditions are upheld therefore no error check necessary
324 pldm_bios_table_attr_entry_enum_decode_pv_num_check(attrEntry,
325 &pvNum);
George Liu1b180d82020-07-23 14:01:58 +0800326 std::vector<uint16_t> pvHandls(pvNum);
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930327 // Preconditions are upheld therefore no error check necessary
328 pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
George Liu1b180d82020-07-23 14:01:58 +0800329 attrEntry, pvHandls.data(), pvHandls.size());
330
331 // get possible_value
332 for (size_t i = 0; i < pvHandls.size(); i++)
333 {
334 options.push_back(
335 std::make_tuple("xyz.openbmc_project.BIOSConfig."
336 "Manager.BoundType.OneOf",
337 getValue(pvHandls[i], *stringTable)));
338 }
339
340 auto count =
341 pldm_bios_table_attr_value_entry_enum_decode_number(
342 tableEntry);
343 std::vector<uint8_t> handles(count);
344 pldm_bios_table_attr_value_entry_enum_decode_handles(
345 tableEntry, handles.data(), handles.size());
346
347 // get current_value
348 for (size_t i = 0; i < handles.size(); i++)
349 {
350 currentValue = getValue(pvHandls[handles[i]], *stringTable);
351 }
352
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930353 uint8_t defNum;
354 // Preconditions are upheld therefore no error check necessary
355 pldm_bios_table_attr_entry_enum_decode_def_num_check(attrEntry,
356 &defNum);
George Liu1b180d82020-07-23 14:01:58 +0800357 std::vector<uint8_t> defIndices(defNum);
358 pldm_bios_table_attr_entry_enum_decode_def_indices(
359 attrEntry, defIndices.data(), defIndices.size());
360
361 // get default_value
362 for (size_t i = 0; i < defIndices.size(); i++)
363 {
Patrick Williams6da4f912023-05-10 07:50:53 -0500364 defaultValue = getValue(pvHandls[defIndices[i]],
365 *stringTable);
George Liu1b180d82020-07-23 14:01:58 +0800366 }
367
368 break;
369 }
370 case PLDM_BIOS_INTEGER:
371 case PLDM_BIOS_INTEGER_READ_ONLY:
372 {
373 attributeType = "xyz.openbmc_project.BIOSConfig.Manager."
374 "AttributeType.Integer";
375 currentValue = static_cast<int64_t>(
376 pldm_bios_table_attr_value_entry_integer_decode_cv(
377 tableEntry));
378
379 uint64_t lower, upper, def;
380 uint32_t scalar;
381 pldm_bios_table_attr_entry_integer_decode(
382 attrEntry, &lower, &upper, &scalar, &def);
383 options.push_back(
384 std::make_tuple("xyz.openbmc_project.BIOSConfig.Manager."
385 "BoundType.LowerBound",
386 static_cast<int64_t>(lower)));
387 options.push_back(
388 std::make_tuple("xyz.openbmc_project.BIOSConfig.Manager."
389 "BoundType.UpperBound",
390 static_cast<int64_t>(upper)));
391 options.push_back(
392 std::make_tuple("xyz.openbmc_project.BIOSConfig.Manager."
393 "BoundType.ScalarIncrement",
394 static_cast<int64_t>(scalar)));
395 defaultValue = static_cast<int64_t>(def);
396 break;
397 }
398 case PLDM_BIOS_STRING:
399 case PLDM_BIOS_STRING_READ_ONLY:
400 {
401 attributeType = "xyz.openbmc_project.BIOSConfig.Manager."
402 "AttributeType.String";
403 variable_field currentString;
404 pldm_bios_table_attr_value_entry_string_decode_string(
405 tableEntry, &currentString);
406 currentValue = std::string(
407 reinterpret_cast<const char*>(currentString.ptr),
408 currentString.length);
409 auto min = pldm_bios_table_attr_entry_string_decode_min_length(
410 attrEntry);
411 auto max = pldm_bios_table_attr_entry_string_decode_max_length(
412 attrEntry);
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930413 uint16_t def;
414 // Preconditions are upheld therefore no error check necessary
415 pldm_bios_table_attr_entry_string_decode_def_string_length_check(
416 attrEntry, &def);
George Liu1b180d82020-07-23 14:01:58 +0800417 std::vector<char> defString(def + 1);
418 pldm_bios_table_attr_entry_string_decode_def_string(
419 attrEntry, defString.data(), defString.size());
420 options.push_back(
421 std::make_tuple("xyz.openbmc_project.BIOSConfig.Manager."
422 "BoundType.MinStringLength",
423 static_cast<int64_t>(min)));
424 options.push_back(
425 std::make_tuple("xyz.openbmc_project.BIOSConfig.Manager."
426 "BoundType.MaxStringLength",
427 static_cast<int64_t>(max)));
428 defaultValue = defString.data();
429 break;
430 }
431 case PLDM_BIOS_PASSWORD:
432 case PLDM_BIOS_PASSWORD_READ_ONLY:
433 {
434 attributeType = "xyz.openbmc_project.BIOSConfig.Manager."
435 "AttributeType.Password";
436 break;
437 }
438 default:
439 return PLDM_INVALID_BIOS_ATTR_HANDLE;
440 }
441 baseBIOSTableMaps.emplace(
442 std::move(attributeName),
443 std::make_tuple(attributeType, readonlyStatus, displayName,
444 description, menuPath, currentValue, defaultValue,
445 std::move(options)));
446 }
447
448 return PLDM_SUCCESS;
449}
450
451void BIOSConfig::updateBaseBIOSTableProperty()
452{
453 constexpr static auto biosConfigPath =
454 "/xyz/openbmc_project/bios_config/manager";
455 constexpr static auto biosConfigInterface =
456 "xyz.openbmc_project.BIOSConfig.Manager";
457 constexpr static auto biosConfigPropertyName = "BaseBIOSTable";
458 constexpr static auto dbusProperties = "org.freedesktop.DBus.Properties";
459
460 if (baseBIOSTableMaps.empty())
461 {
462 return;
463 }
464
465 try
466 {
467 auto& bus = dbusHandler->getBus();
Patrick Williams6da4f912023-05-10 07:50:53 -0500468 auto service = dbusHandler->getService(biosConfigPath,
469 biosConfigInterface);
George Liu1b180d82020-07-23 14:01:58 +0800470 auto method = bus.new_method_call(service.c_str(), biosConfigPath,
471 dbusProperties, "Set");
472 std::variant<BaseBIOSTable> value = baseBIOSTableMaps;
473 method.append(biosConfigInterface, biosConfigPropertyName, value);
vkaverap@in.ibm.com5b71b862023-08-21 05:19:04 +0000474 bus.call_noreply(method, dbusTimeout);
George Liu1b180d82020-07-23 14:01:58 +0800475 }
476 catch (const std::exception& e)
477 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600478 error("failed to update BaseBIOSTable property, ERROR={ERR_EXCEP}",
479 "ERR_EXCEP", e.what());
George Liu1b180d82020-07-23 14:01:58 +0800480 }
481}
482
John Wangd9659342020-02-27 16:46:05 +0800483void BIOSConfig::constructAttributes()
484{
Sagar Srinivas11ce8d22022-07-28 11:32:34 -0500485 load(jsonDir / sysType / stringJsonFile, [this](const Json& entry) {
John Wangd9659342020-02-27 16:46:05 +0800486 constructAttribute<BIOSStringAttribute>(entry);
487 });
Sagar Srinivas11ce8d22022-07-28 11:32:34 -0500488 load(jsonDir / sysType / integerJsonFile, [this](const Json& entry) {
John Wang95e6b3c2020-02-13 09:43:24 +0800489 constructAttribute<BIOSIntegerAttribute>(entry);
490 });
Sagar Srinivas11ce8d22022-07-28 11:32:34 -0500491 load(jsonDir / sysType / enumJsonFile, [this](const Json& entry) {
John Wang3be70852020-02-13 15:59:04 +0800492 constructAttribute<BIOSEnumAttribute>(entry);
493 });
John Wangd9659342020-02-27 16:46:05 +0800494}
495
496void BIOSConfig::buildAndStoreAttrTables(const Table& stringTable)
497{
498 BIOSStringTable biosStringTable(stringTable);
499
500 if (biosAttributes.empty())
501 {
502 return;
503 }
504
Tom Josephca7b2522020-11-18 12:27:11 +0530505 BaseBIOSTable biosTable{};
506 constexpr auto biosObjPath = "/xyz/openbmc_project/bios_config/manager";
507 constexpr auto biosInterface = "xyz.openbmc_project.BIOSConfig.Manager";
508
509 try
510 {
511 auto& bus = dbusHandler->getBus();
512 auto service = dbusHandler->getService(biosObjPath, biosInterface);
Patrick Williams6da4f912023-05-10 07:50:53 -0500513 auto method = bus.new_method_call(service.c_str(), biosObjPath,
514 "org.freedesktop.DBus.Properties",
515 "Get");
Tom Josephca7b2522020-11-18 12:27:11 +0530516 method.append(biosInterface, "BaseBIOSTable");
vkaverap@in.ibm.com9138c202023-05-19 07:50:47 -0500517 auto reply = bus.call(
518 method,
519 std::chrono::duration_cast<microsec>(sec(DBUS_TIMEOUT)).count());
Tom Josephca7b2522020-11-18 12:27:11 +0530520 std::variant<BaseBIOSTable> varBiosTable{};
521 reply.read(varBiosTable);
522 biosTable = std::get<BaseBIOSTable>(varBiosTable);
523 }
524 // Failed to read the BaseBIOSTable, so update the BaseBIOSTable with the
525 // default values populated from the BIOS JSONs to keep PLDM and
526 // bios-settings-manager in sync
527 catch (const std::exception& e)
528 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600529 error("Failed to read BaseBIOSTable property, ERROR={ERR_EXCEP}",
530 "ERR_EXCEP", e.what());
Tom Josephca7b2522020-11-18 12:27:11 +0530531 }
532
John Wangd9659342020-02-27 16:46:05 +0800533 Table attrTable, attrValueTable;
534
535 for (auto& attr : biosAttributes)
536 {
537 try
538 {
Tom Josephca7b2522020-11-18 12:27:11 +0530539 auto iter = biosTable.find(attr->name);
540 if (iter == biosTable.end())
541 {
542 attr->constructEntry(biosStringTable, attrTable, attrValueTable,
543 std::nullopt);
544 }
545 else
546 {
547 attr->constructEntry(
548 biosStringTable, attrTable, attrValueTable,
549 std::get<static_cast<uint8_t>(Index::currentValue)>(
550 iter->second));
551 }
John Wangd9659342020-02-27 16:46:05 +0800552 }
553 catch (const std::exception& e)
554 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600555 error("Construct Table Entry Error, AttributeName = {ATTR_NAME}",
556 "ATTR_NAME", attr->name);
John Wangd9659342020-02-27 16:46:05 +0800557 }
558 }
559
560 table::appendPadAndChecksum(attrTable);
561 table::appendPadAndChecksum(attrValueTable);
George Liu1b180d82020-07-23 14:01:58 +0800562 setBIOSTable(PLDM_BIOS_ATTR_TABLE, attrTable);
563 setBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE, attrValueTable);
John Wangd9659342020-02-27 16:46:05 +0800564}
565
566std::optional<Table> BIOSConfig::buildAndStoreStringTable()
567{
568 std::set<std::string> strings;
569 auto handler = [&strings](const Json& entry) {
570 strings.emplace(entry.at("attribute_name"));
571 };
572
Sagar Srinivas11ce8d22022-07-28 11:32:34 -0500573 load(jsonDir / sysType / stringJsonFile, handler);
574 load(jsonDir / sysType / integerJsonFile, handler);
575 load(jsonDir / sysType / enumJsonFile, [&strings](const Json& entry) {
John Wangd9659342020-02-27 16:46:05 +0800576 strings.emplace(entry.at("attribute_name"));
577 auto possibleValues = entry.at("possible_values");
578 for (auto& pv : possibleValues)
579 {
580 strings.emplace(pv);
581 }
582 });
583
584 if (strings.empty())
585 {
586 return std::nullopt;
587 }
588
589 Table table;
590 for (const auto& elem : strings)
591 {
592 table::string::constructEntry(table, elem);
593 }
594
595 table::appendPadAndChecksum(table);
George Liu1b180d82020-07-23 14:01:58 +0800596 setBIOSTable(PLDM_BIOS_STRING_TABLE, table);
John Wangd9659342020-02-27 16:46:05 +0800597 return table;
598}
599
600void BIOSConfig::storeTable(const fs::path& path, const Table& table)
601{
602 BIOSTable biosTable(path.c_str());
603 biosTable.store(table);
604}
605
606std::optional<Table> BIOSConfig::loadTable(const fs::path& path)
607{
608 BIOSTable biosTable(path.c_str());
609 if (biosTable.isEmpty())
610 {
611 return std::nullopt;
612 }
613
614 Table table;
615 biosTable.load(table);
616 return table;
617}
618
619void BIOSConfig::load(const fs::path& filePath, ParseHandler handler)
620{
621 std::ifstream file;
622 Json jsonConf;
623 if (fs::exists(filePath))
624 {
625 try
626 {
627 file.open(filePath);
628 jsonConf = Json::parse(file);
629 auto entries = jsonConf.at("entries");
630 for (auto& entry : entries)
631 {
632 try
633 {
634 handler(entry);
635 }
636 catch (const std::exception& e)
637 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600638 error(
639 "Failed to parse JSON config file(entry handler) : {JSON_PATH}, {ERR_EXCEP}",
640 "JSON_PATH", filePath.c_str(), "ERR_EXCEP", e.what());
John Wangd9659342020-02-27 16:46:05 +0800641 }
642 }
643 }
644 catch (const std::exception& e)
645 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600646 error("Failed to parse JSON config file : {JSON_PATH}", "JSON_PATH",
647 filePath.c_str());
John Wangd9659342020-02-27 16:46:05 +0800648 }
649 }
650}
651
Sagar Srinivascac0ebb2021-11-23 07:50:28 -0600652std::string BIOSConfig::decodeStringFromStringEntry(
653 const pldm_bios_string_table_entry* stringEntry)
654{
655 auto strLength =
656 pldm_bios_table_string_entry_decode_string_length(stringEntry);
657 std::vector<char> buffer(strLength + 1 /* sizeof '\0' */);
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930658 // Preconditions are upheld therefore no error check necessary
659 pldm_bios_table_string_entry_decode_string_check(stringEntry, buffer.data(),
660 buffer.size());
Sagar Srinivascac0ebb2021-11-23 07:50:28 -0600661 return std::string(buffer.data(), buffer.data() + strLength);
662}
663
664std::string
665 BIOSConfig::displayStringHandle(uint16_t handle, uint8_t index,
666 const std::optional<Table>& attrTable,
667 const std::optional<Table>& stringTable)
668{
669 auto attrEntry = pldm_bios_table_attr_find_by_handle(
670 attrTable->data(), attrTable->size(), handle);
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930671 uint8_t pvNum;
672 int rc = pldm_bios_table_attr_entry_enum_decode_pv_num_check(attrEntry,
673 &pvNum);
674 if (rc != PLDM_SUCCESS)
675 {
676 error(
677 "Failed to decode BIOS table possible values for attribute entry: {LIPBLDM_ERROR}",
678 "LIBPLDM_ERROR", rc);
679 throw std::runtime_error(
680 "Failed to decode BIOS table possible values for attribute entry");
681 }
682
Sagar Srinivascac0ebb2021-11-23 07:50:28 -0600683 std::vector<uint16_t> pvHandls(pvNum);
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930684 // Preconditions are upheld therefore no error check necessary
685 pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
686 attrEntry, pvHandls.data(), pvHandls.size());
Sagar Srinivascac0ebb2021-11-23 07:50:28 -0600687
688 std::string displayString = std::to_string(pvHandls[index]);
689
690 auto stringEntry = pldm_bios_table_string_find_by_handle(
691 stringTable->data(), stringTable->size(), pvHandls[index]);
692
693 auto decodedStr = decodeStringFromStringEntry(stringEntry);
694
695 return decodedStr + "(" + displayString + ")";
696}
697
698void BIOSConfig::traceBIOSUpdate(
699 const pldm_bios_attr_val_table_entry* attrValueEntry,
700 const pldm_bios_attr_table_entry* attrEntry, bool isBMC)
701{
702 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
703 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
704
Patrick Williams6da4f912023-05-10 07:50:53 -0500705 auto [attrHandle,
706 attrType] = table::attribute_value::decodeHeader(attrValueEntry);
Sagar Srinivascac0ebb2021-11-23 07:50:28 -0600707
708 auto attrHeader = table::attribute::decodeHeader(attrEntry);
709 BIOSStringTable biosStringTable(*stringTable);
710 auto attrName = biosStringTable.findString(attrHeader.stringHandle);
711
712 switch (attrType)
713 {
714 case PLDM_BIOS_ENUMERATION:
715 case PLDM_BIOS_ENUMERATION_READ_ONLY:
716 {
717 auto count = pldm_bios_table_attr_value_entry_enum_decode_number(
718 attrValueEntry);
719 std::vector<uint8_t> handles(count);
720 pldm_bios_table_attr_value_entry_enum_decode_handles(
721 attrValueEntry, handles.data(), handles.size());
722
723 for (uint8_t handle : handles)
724 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600725 auto nwVal = displayStringHandle(attrHandle, handle, attrTable,
726 stringTable);
727 auto chkBMC = isBMC ? "true" : "false";
728 info(
729 "BIOS:{ATTR_NAME}, updated to value: {NEW_VAL}, by BMC: {CHK_BMC} ",
730 "ATTR_NAME", attrName, "NEW_VAL", nwVal, "CHK_BMC", chkBMC);
Sagar Srinivascac0ebb2021-11-23 07:50:28 -0600731 }
732 break;
733 }
734 case PLDM_BIOS_INTEGER:
735 case PLDM_BIOS_INTEGER_READ_ONLY:
736 {
737 auto value =
738 table::attribute_value::decodeIntegerEntry(attrValueEntry);
Riya Dixit49cfb132023-03-02 04:26:53 -0600739 auto chkBMC = isBMC ? "true" : "false";
740 info(
741 "BIOS: {ATTR_NAME}, updated to value: {UPDATED_VAL}, by BMC: {CHK_BMC}",
742 "ATTR_NAME", attrName, "UPDATED_VAL", value, "CHK_BMC", chkBMC);
Sagar Srinivascac0ebb2021-11-23 07:50:28 -0600743 break;
744 }
745 case PLDM_BIOS_STRING:
746 case PLDM_BIOS_STRING_READ_ONLY:
747 {
748 auto value =
749 table::attribute_value::decodeStringEntry(attrValueEntry);
Riya Dixit49cfb132023-03-02 04:26:53 -0600750 auto chkBMC = isBMC ? "true" : "false";
751 info(
752 "BIOS: {ATTR_NAME}, updated to value: {UPDATED_VAL}, by BMC: {CHK_BMC}",
753 "ATTR_NAME", attrName, "UPDATED_VAL", value, "CHK_BMC", chkBMC);
Sagar Srinivascac0ebb2021-11-23 07:50:28 -0600754 break;
755 }
756 default:
757 break;
758 };
759}
760
John Wang8241b342020-06-05 10:49:17 +0800761int BIOSConfig::checkAttrValueToUpdate(
762 const pldm_bios_attr_val_table_entry* attrValueEntry,
763 const pldm_bios_attr_table_entry* attrEntry, Table&)
764
765{
Patrick Williams6da4f912023-05-10 07:50:53 -0500766 auto [attrHandle,
767 attrType] = table::attribute_value::decodeHeader(attrValueEntry);
John Wang8241b342020-06-05 10:49:17 +0800768
769 switch (attrType)
770 {
771 case PLDM_BIOS_ENUMERATION:
George Liu5bb9edb2021-08-05 20:10:32 +0800772 case PLDM_BIOS_ENUMERATION_READ_ONLY:
John Wang8241b342020-06-05 10:49:17 +0800773 {
774 auto value =
775 table::attribute_value::decodeEnumEntry(attrValueEntry);
Patrick Williams6da4f912023-05-10 07:50:53 -0500776 auto [pvHdls,
777 defIndex] = table::attribute::decodeEnumEntry(attrEntry);
Varsha Kaverappa6a4d1cf2021-11-24 21:15:42 -0600778 if (!(value.size() == 1))
779 {
780 return PLDM_ERROR_INVALID_LENGTH;
781 }
John Wang8241b342020-06-05 10:49:17 +0800782 if (value[0] >= pvHdls.size())
783 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600784 error("Enum: Illgeal index, Index = {ATTR_INDEX}", "ATTR_INDEX",
785 (int)value[0]);
John Wang8241b342020-06-05 10:49:17 +0800786 return PLDM_ERROR_INVALID_DATA;
787 }
John Wang8241b342020-06-05 10:49:17 +0800788 return PLDM_SUCCESS;
789 }
790 case PLDM_BIOS_INTEGER:
George Liu5bb9edb2021-08-05 20:10:32 +0800791 case PLDM_BIOS_INTEGER_READ_ONLY:
John Wang8241b342020-06-05 10:49:17 +0800792 {
793 auto value =
794 table::attribute_value::decodeIntegerEntry(attrValueEntry);
Patrick Williams6da4f912023-05-10 07:50:53 -0500795 auto [lower, upper, scalar,
796 def] = table::attribute::decodeIntegerEntry(attrEntry);
John Wang8241b342020-06-05 10:49:17 +0800797
798 if (value < lower || value > upper)
799 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600800 error("Integer: out of bound, value = {ATTR_VALUE}",
801 "ATTR_VALUE", value);
John Wang8241b342020-06-05 10:49:17 +0800802 return PLDM_ERROR_INVALID_DATA;
803 }
804 return PLDM_SUCCESS;
805 }
806 case PLDM_BIOS_STRING:
George Liu5bb9edb2021-08-05 20:10:32 +0800807 case PLDM_BIOS_STRING_READ_ONLY:
John Wang8241b342020-06-05 10:49:17 +0800808 {
809 auto stringConf = table::attribute::decodeStringEntry(attrEntry);
810 auto value =
811 table::attribute_value::decodeStringEntry(attrValueEntry);
812 if (value.size() < stringConf.minLength ||
813 value.size() > stringConf.maxLength)
814 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600815 error(
816 "String: Length error, string = {ATTR_VALUE} length {LEN}",
817 "ATTR_VALUE", value, "LEN", value.size());
John Wang8241b342020-06-05 10:49:17 +0800818 return PLDM_ERROR_INVALID_LENGTH;
819 }
820 return PLDM_SUCCESS;
821 }
822 default:
Riya Dixit49cfb132023-03-02 04:26:53 -0600823 error("ReadOnly or Unspported type, type = {ATTR_TYPE}",
824 "ATTR_TYPE", attrType);
John Wang8241b342020-06-05 10:49:17 +0800825 return PLDM_ERROR;
826 };
827}
828
Sagar Srinivascac0ebb2021-11-23 07:50:28 -0600829int BIOSConfig::setAttrValue(const void* entry, size_t size, bool isBMC,
830 bool updateDBus, bool updateBaseBIOSTable)
John Wangd9659342020-02-27 16:46:05 +0800831{
832 auto attrValueTable = getBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE);
833 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
834 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
835 if (!attrValueTable || !attrTable || !stringTable)
836 {
837 return PLDM_BIOS_TABLE_UNAVAILABLE;
838 }
839
John Wangd9659342020-02-27 16:46:05 +0800840 auto attrValueEntry =
841 reinterpret_cast<const pldm_bios_attr_val_table_entry*>(entry);
842
843 auto attrValHeader = table::attribute_value::decodeHeader(attrValueEntry);
844
Patrick Williams6da4f912023-05-10 07:50:53 -0500845 auto attrEntry = table::attribute::findByHandle(*attrTable,
846 attrValHeader.attrHandle);
John Wangd9659342020-02-27 16:46:05 +0800847 if (!attrEntry)
848 {
849 return PLDM_ERROR;
850 }
851
John Wang8241b342020-06-05 10:49:17 +0800852 auto rc = checkAttrValueToUpdate(attrValueEntry, attrEntry, *stringTable);
853 if (rc != PLDM_SUCCESS)
854 {
855 return rc;
856 }
857
Patrick Williams6da4f912023-05-10 07:50:53 -0500858 auto destTable = table::attribute_value::updateTable(*attrValueTable, entry,
859 size);
John Wang8241b342020-06-05 10:49:17 +0800860
861 if (!destTable)
862 {
863 return PLDM_ERROR;
864 }
865
John Wangd9659342020-02-27 16:46:05 +0800866 try
867 {
868 auto attrHeader = table::attribute::decodeHeader(attrEntry);
869
870 BIOSStringTable biosStringTable(*stringTable);
871 auto attrName = biosStringTable.findString(attrHeader.stringHandle);
Patrick Williams6da4f912023-05-10 07:50:53 -0500872 auto iter = std::find_if(biosAttributes.begin(), biosAttributes.end(),
873 [&attrName](const auto& attr) {
874 return attr->name == attrName;
875 });
John Wangd9659342020-02-27 16:46:05 +0800876
877 if (iter == biosAttributes.end())
878 {
879 return PLDM_ERROR;
880 }
George Liu6d6d1e82021-02-16 11:08:55 +0800881 if (updateDBus)
882 {
883 (*iter)->setAttrValueOnDbus(attrValueEntry, attrEntry,
884 biosStringTable);
885 }
John Wangd9659342020-02-27 16:46:05 +0800886 }
887 catch (const std::exception& e)
888 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600889 error("Set attribute value error: {ERR_EXCEP}", "ERR_EXCEP", e.what());
John Wangd9659342020-02-27 16:46:05 +0800890 return PLDM_ERROR;
891 }
892
Tom Joseph7f839f92020-09-21 10:20:44 +0530893 setBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE, *destTable, updateBaseBIOSTable);
George Liu5c3192b2020-08-13 17:35:43 +0800894
Sagar Srinivascac0ebb2021-11-23 07:50:28 -0600895 traceBIOSUpdate(attrValueEntry, attrEntry, isBMC);
896
John Wangd9659342020-02-27 16:46:05 +0800897 return PLDM_SUCCESS;
898}
899
900void BIOSConfig::removeTables()
901{
902 try
903 {
904 fs::remove(tableDir / stringTableFile);
905 fs::remove(tableDir / attrTableFile);
906 fs::remove(tableDir / attrValueTableFile);
907 }
908 catch (const std::exception& e)
909 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600910 error("Remove the tables error: {ERR_EXCEP}", "ERR_EXCEP", e.what());
John Wangd9659342020-02-27 16:46:05 +0800911 }
912}
913
Sampa Misra46ece062020-03-18 07:17:44 -0500914void BIOSConfig::processBiosAttrChangeNotification(
915 const DbusChObjProperties& chProperties, uint32_t biosAttrIndex)
916{
917 const auto& dBusMap = biosAttributes[biosAttrIndex]->getDBusMap();
918 const auto& propertyName = dBusMap->propertyName;
919 const auto& attrName = biosAttributes[biosAttrIndex]->name;
920
921 const auto it = chProperties.find(propertyName);
922 if (it == chProperties.end())
923 {
924 return;
925 }
926
927 PropertyValue newPropVal = it->second;
928 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
929 if (!stringTable.has_value())
930 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600931 error("BIOS string table unavailable");
Sampa Misra46ece062020-03-18 07:17:44 -0500932 return;
933 }
934 BIOSStringTable biosStringTable(*stringTable);
935 uint16_t attrNameHdl{};
936 try
937 {
938 attrNameHdl = biosStringTable.findHandle(attrName);
939 }
Patrick Williams51330582021-10-06 12:48:56 -0500940 catch (const std::invalid_argument& e)
Sampa Misra46ece062020-03-18 07:17:44 -0500941 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600942 error("Could not find handle for BIOS string, ATTRIBUTE={ATTR_NAME}",
943 "ATTR_NAME", attrName.c_str());
Sampa Misra46ece062020-03-18 07:17:44 -0500944 return;
945 }
946
947 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
948 if (!attrTable.has_value())
949 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600950 error("Attribute table not present");
Sampa Misra46ece062020-03-18 07:17:44 -0500951 return;
952 }
953 const struct pldm_bios_attr_table_entry* tableEntry =
954 table::attribute::findByStringHandle(*attrTable, attrNameHdl);
955 if (tableEntry == nullptr)
956 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600957 error(
958 "Attribute not found in attribute table, name= {ATTR_NAME} name handle={ATTR_HANDLE}",
959 "ATTR_NAME", attrName.c_str(), "ATTR_HANDLE", attrNameHdl);
Sampa Misra46ece062020-03-18 07:17:44 -0500960 return;
961 }
962
Patrick Williams6da4f912023-05-10 07:50:53 -0500963 auto [attrHdl, attrType,
964 stringHdl] = table::attribute::decodeHeader(tableEntry);
Sampa Misra46ece062020-03-18 07:17:44 -0500965
966 auto attrValueSrcTable = getBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE);
967
968 if (!attrValueSrcTable.has_value())
969 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600970 error("Attribute value table not present");
Sampa Misra46ece062020-03-18 07:17:44 -0500971 return;
972 }
973
974 Table newValue;
975 auto rc = biosAttributes[biosAttrIndex]->updateAttrVal(
976 newValue, attrHdl, attrType, newPropVal);
977 if (rc != PLDM_SUCCESS)
978 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600979 error(
980 "Could not update the attribute value table for attribute handle={ATTR_HANDLE} and type={ATTR_TYPE}",
981 "ATTR_HANDLE", attrHdl, "ATTR_TYPE", (uint32_t)attrType);
Sampa Misra46ece062020-03-18 07:17:44 -0500982 return;
983 }
984 auto destTable = table::attribute_value::updateTable(
985 *attrValueSrcTable, newValue.data(), newValue.size());
986 if (destTable.has_value())
987 {
988 storeTable(tableDir / attrValueTableFile, *destTable);
989 }
Sampa Misra0f262332021-02-15 00:13:51 -0600990
Sagar Srinivascac0ebb2021-11-23 07:50:28 -0600991 rc = setAttrValue(newValue.data(), newValue.size(), true, false);
Sampa Misra0f262332021-02-15 00:13:51 -0600992 if (rc != PLDM_SUCCESS)
993 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600994 error("could not setAttrValue on base bios table and dbus, rc = {RC}",
995 "RC", rc);
Sampa Misra0f262332021-02-15 00:13:51 -0600996 }
Sampa Misra46ece062020-03-18 07:17:44 -0500997}
998
George Liu1244acf2020-08-14 09:11:11 +0800999uint16_t BIOSConfig::findAttrHandle(const std::string& attrName)
1000{
1001 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
1002 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
1003
1004 BIOSStringTable biosStringTable(*stringTable);
1005 pldm::bios::utils::BIOSTableIter<PLDM_BIOS_ATTR_TABLE> attrTableIter(
1006 attrTable->data(), attrTable->size());
1007 auto stringHandle = biosStringTable.findHandle(attrName);
1008
1009 for (auto entry : pldm::bios::utils::BIOSTableIter<PLDM_BIOS_ATTR_TABLE>(
1010 attrTable->data(), attrTable->size()))
1011 {
1012 auto header = table::attribute::decodeHeader(entry);
1013 if (header.stringHandle == stringHandle)
1014 {
1015 return header.attrHandle;
1016 }
1017 }
1018
1019 throw std::invalid_argument("Unknow attribute Name");
1020}
1021
1022void BIOSConfig::constructPendingAttribute(
1023 const PendingAttributes& pendingAttributes)
1024{
Tom Joseph7f839f92020-09-21 10:20:44 +05301025 std::vector<uint16_t> listOfHandles{};
1026
George Liu1244acf2020-08-14 09:11:11 +08001027 for (auto& attribute : pendingAttributes)
1028 {
1029 std::string attributeName = attribute.first;
1030 auto& [attributeType, attributevalue] = attribute.second;
1031
1032 auto iter = std::find_if(biosAttributes.begin(), biosAttributes.end(),
1033 [&attributeName](const auto& attr) {
Patrick Williams6da4f912023-05-10 07:50:53 -05001034 return attr->name == attributeName;
1035 });
George Liu1244acf2020-08-14 09:11:11 +08001036
1037 if (iter == biosAttributes.end())
1038 {
Riya Dixit49cfb132023-03-02 04:26:53 -06001039 error("Wrong attribute name, attributeName = {ATTR_NAME}",
1040 "ATTR_NAME", attributeName);
George Liu1244acf2020-08-14 09:11:11 +08001041 continue;
1042 }
1043
1044 Table attrValueEntry(sizeof(pldm_bios_attr_val_table_entry), 0);
1045 auto entry = reinterpret_cast<pldm_bios_attr_val_table_entry*>(
1046 attrValueEntry.data());
1047
1048 auto handler = findAttrHandle(attributeName);
1049 auto type =
1050 BIOSConfigManager::convertAttributeTypeFromString(attributeType);
1051
1052 if (type != BIOSConfigManager::AttributeType::Enumeration &&
1053 type != BIOSConfigManager::AttributeType::String &&
1054 type != BIOSConfigManager::AttributeType::Integer)
1055 {
Riya Dixit49cfb132023-03-02 04:26:53 -06001056 error("Attribute type not supported, attributeType = {ATTR_TYPE}",
1057 "ATTR_TYPE", attributeType);
George Liu1244acf2020-08-14 09:11:11 +08001058 continue;
1059 }
1060
George Liu4876c542022-06-08 15:59:54 +08001061 const auto [attrType, readonlyStatus, displayName, description,
Patrick Williams6da4f912023-05-10 07:50:53 -05001062 menuPath, currentValue, defaultValue,
1063 option] = baseBIOSTableMaps.at(attributeName);
George Liu4876c542022-06-08 15:59:54 +08001064
George Liu1244acf2020-08-14 09:11:11 +08001065 entry->attr_handle = htole16(handler);
George Liu4876c542022-06-08 15:59:54 +08001066
1067 // Need to verify that the current value has really changed
1068 if (attributeType == attrType && attributevalue != currentValue)
1069 {
1070 listOfHandles.emplace_back(htole16(handler));
1071 }
Tom Joseph7f839f92020-09-21 10:20:44 +05301072
George Liu1244acf2020-08-14 09:11:11 +08001073 (*iter)->generateAttributeEntry(attributevalue, attrValueEntry);
1074
Sagar Srinivascac0ebb2021-11-23 07:50:28 -06001075 setAttrValue(attrValueEntry.data(), attrValueEntry.size(), true);
Tom Joseph7f839f92020-09-21 10:20:44 +05301076 }
1077
1078 if (listOfHandles.size())
1079 {
1080#ifdef OEM_IBM
1081 auto rc = pldm::responder::platform::sendBiosAttributeUpdateEvent(
Andrew Jefferya330b2f2023-05-04 14:55:37 +09301082 eid, instanceIdDb, listOfHandles, handler);
Tom Joseph7f839f92020-09-21 10:20:44 +05301083 if (rc != PLDM_SUCCESS)
1084 {
1085 return;
1086 }
1087#endif
George Liu1244acf2020-08-14 09:11:11 +08001088 }
1089}
1090
1091void BIOSConfig::listenPendingAttributes()
1092{
1093 constexpr auto objPath = "/xyz/openbmc_project/bios_config/manager";
1094 constexpr auto objInterface = "xyz.openbmc_project.BIOSConfig.Manager";
1095
1096 using namespace sdbusplus::bus::match::rules;
Patrick Williams84b790c2022-07-22 19:26:56 -05001097 auto updateBIOSMatch = std::make_unique<sdbusplus::bus::match_t>(
George Liu1244acf2020-08-14 09:11:11 +08001098 pldm::utils::DBusHandler::getBus(),
1099 propertiesChanged(objPath, objInterface),
Patrick Williams84b790c2022-07-22 19:26:56 -05001100 [this](sdbusplus::message_t& msg) {
Patrick Williams6da4f912023-05-10 07:50:53 -05001101 constexpr auto propertyName = "PendingAttributes";
George Liu1244acf2020-08-14 09:11:11 +08001102
Patrick Williams6da4f912023-05-10 07:50:53 -05001103 using Value =
1104 std::variant<std::string, PendingAttributes, BaseBIOSTable>;
1105 using Properties = std::map<DbusProp, Value>;
George Liu1244acf2020-08-14 09:11:11 +08001106
Patrick Williams6da4f912023-05-10 07:50:53 -05001107 Properties props{};
1108 std::string intf;
1109 msg.read(intf, props);
George Liu1244acf2020-08-14 09:11:11 +08001110
Patrick Williams6da4f912023-05-10 07:50:53 -05001111 auto valPropMap = props.find(propertyName);
1112 if (valPropMap == props.end())
1113 {
1114 return;
1115 }
George Liu1244acf2020-08-14 09:11:11 +08001116
Patrick Williams6da4f912023-05-10 07:50:53 -05001117 PendingAttributes pendingAttributes =
1118 std::get<PendingAttributes>(valPropMap->second);
1119 this->constructPendingAttribute(pendingAttributes);
George Liu1244acf2020-08-14 09:11:11 +08001120 });
1121
1122 biosAttrMatch.emplace_back(std::move(updateBIOSMatch));
1123}
1124
John Wangd9659342020-02-27 16:46:05 +08001125} // namespace bios
1126} // namespace responder
1127} // namespace pldm