blob: aea24a0c0c294595f26f4da5111b7e0079cf9386 [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.com91a092f2023-09-18 23:39:44 -0500517 auto reply = bus.call(method, dbusTimeout);
Tom Josephca7b2522020-11-18 12:27:11 +0530518 std::variant<BaseBIOSTable> varBiosTable{};
519 reply.read(varBiosTable);
520 biosTable = std::get<BaseBIOSTable>(varBiosTable);
521 }
522 // Failed to read the BaseBIOSTable, so update the BaseBIOSTable with the
523 // default values populated from the BIOS JSONs to keep PLDM and
524 // bios-settings-manager in sync
525 catch (const std::exception& e)
526 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600527 error("Failed to read BaseBIOSTable property, ERROR={ERR_EXCEP}",
528 "ERR_EXCEP", e.what());
Tom Josephca7b2522020-11-18 12:27:11 +0530529 }
530
John Wangd9659342020-02-27 16:46:05 +0800531 Table attrTable, attrValueTable;
532
533 for (auto& attr : biosAttributes)
534 {
535 try
536 {
Tom Josephca7b2522020-11-18 12:27:11 +0530537 auto iter = biosTable.find(attr->name);
538 if (iter == biosTable.end())
539 {
540 attr->constructEntry(biosStringTable, attrTable, attrValueTable,
541 std::nullopt);
542 }
543 else
544 {
545 attr->constructEntry(
546 biosStringTable, attrTable, attrValueTable,
547 std::get<static_cast<uint8_t>(Index::currentValue)>(
548 iter->second));
549 }
John Wangd9659342020-02-27 16:46:05 +0800550 }
551 catch (const std::exception& e)
552 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600553 error("Construct Table Entry Error, AttributeName = {ATTR_NAME}",
554 "ATTR_NAME", attr->name);
John Wangd9659342020-02-27 16:46:05 +0800555 }
556 }
557
558 table::appendPadAndChecksum(attrTable);
559 table::appendPadAndChecksum(attrValueTable);
George Liu1b180d82020-07-23 14:01:58 +0800560 setBIOSTable(PLDM_BIOS_ATTR_TABLE, attrTable);
561 setBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE, attrValueTable);
John Wangd9659342020-02-27 16:46:05 +0800562}
563
564std::optional<Table> BIOSConfig::buildAndStoreStringTable()
565{
566 std::set<std::string> strings;
567 auto handler = [&strings](const Json& entry) {
568 strings.emplace(entry.at("attribute_name"));
569 };
570
Sagar Srinivas11ce8d22022-07-28 11:32:34 -0500571 load(jsonDir / sysType / stringJsonFile, handler);
572 load(jsonDir / sysType / integerJsonFile, handler);
573 load(jsonDir / sysType / enumJsonFile, [&strings](const Json& entry) {
John Wangd9659342020-02-27 16:46:05 +0800574 strings.emplace(entry.at("attribute_name"));
575 auto possibleValues = entry.at("possible_values");
576 for (auto& pv : possibleValues)
577 {
578 strings.emplace(pv);
579 }
580 });
581
582 if (strings.empty())
583 {
584 return std::nullopt;
585 }
586
587 Table table;
588 for (const auto& elem : strings)
589 {
590 table::string::constructEntry(table, elem);
591 }
592
593 table::appendPadAndChecksum(table);
George Liu1b180d82020-07-23 14:01:58 +0800594 setBIOSTable(PLDM_BIOS_STRING_TABLE, table);
John Wangd9659342020-02-27 16:46:05 +0800595 return table;
596}
597
598void BIOSConfig::storeTable(const fs::path& path, const Table& table)
599{
600 BIOSTable biosTable(path.c_str());
601 biosTable.store(table);
602}
603
604std::optional<Table> BIOSConfig::loadTable(const fs::path& path)
605{
606 BIOSTable biosTable(path.c_str());
607 if (biosTable.isEmpty())
608 {
609 return std::nullopt;
610 }
611
612 Table table;
613 biosTable.load(table);
614 return table;
615}
616
617void BIOSConfig::load(const fs::path& filePath, ParseHandler handler)
618{
619 std::ifstream file;
620 Json jsonConf;
621 if (fs::exists(filePath))
622 {
623 try
624 {
625 file.open(filePath);
626 jsonConf = Json::parse(file);
627 auto entries = jsonConf.at("entries");
628 for (auto& entry : entries)
629 {
630 try
631 {
632 handler(entry);
633 }
634 catch (const std::exception& e)
635 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600636 error(
637 "Failed to parse JSON config file(entry handler) : {JSON_PATH}, {ERR_EXCEP}",
638 "JSON_PATH", filePath.c_str(), "ERR_EXCEP", e.what());
John Wangd9659342020-02-27 16:46:05 +0800639 }
640 }
641 }
642 catch (const std::exception& e)
643 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600644 error("Failed to parse JSON config file : {JSON_PATH}", "JSON_PATH",
645 filePath.c_str());
John Wangd9659342020-02-27 16:46:05 +0800646 }
647 }
648}
649
Sagar Srinivascac0ebb2021-11-23 07:50:28 -0600650std::string BIOSConfig::decodeStringFromStringEntry(
651 const pldm_bios_string_table_entry* stringEntry)
652{
653 auto strLength =
654 pldm_bios_table_string_entry_decode_string_length(stringEntry);
655 std::vector<char> buffer(strLength + 1 /* sizeof '\0' */);
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930656 // Preconditions are upheld therefore no error check necessary
657 pldm_bios_table_string_entry_decode_string_check(stringEntry, buffer.data(),
658 buffer.size());
Sagar Srinivascac0ebb2021-11-23 07:50:28 -0600659 return std::string(buffer.data(), buffer.data() + strLength);
660}
661
662std::string
663 BIOSConfig::displayStringHandle(uint16_t handle, uint8_t index,
664 const std::optional<Table>& attrTable,
665 const std::optional<Table>& stringTable)
666{
667 auto attrEntry = pldm_bios_table_attr_find_by_handle(
668 attrTable->data(), attrTable->size(), handle);
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930669 uint8_t pvNum;
670 int rc = pldm_bios_table_attr_entry_enum_decode_pv_num_check(attrEntry,
671 &pvNum);
672 if (rc != PLDM_SUCCESS)
673 {
674 error(
675 "Failed to decode BIOS table possible values for attribute entry: {LIPBLDM_ERROR}",
676 "LIBPLDM_ERROR", rc);
677 throw std::runtime_error(
678 "Failed to decode BIOS table possible values for attribute entry");
679 }
680
Sagar Srinivascac0ebb2021-11-23 07:50:28 -0600681 std::vector<uint16_t> pvHandls(pvNum);
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930682 // Preconditions are upheld therefore no error check necessary
683 pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
684 attrEntry, pvHandls.data(), pvHandls.size());
Sagar Srinivascac0ebb2021-11-23 07:50:28 -0600685
686 std::string displayString = std::to_string(pvHandls[index]);
687
688 auto stringEntry = pldm_bios_table_string_find_by_handle(
689 stringTable->data(), stringTable->size(), pvHandls[index]);
690
691 auto decodedStr = decodeStringFromStringEntry(stringEntry);
692
693 return decodedStr + "(" + displayString + ")";
694}
695
696void BIOSConfig::traceBIOSUpdate(
697 const pldm_bios_attr_val_table_entry* attrValueEntry,
698 const pldm_bios_attr_table_entry* attrEntry, bool isBMC)
699{
700 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
701 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
702
Patrick Williams6da4f912023-05-10 07:50:53 -0500703 auto [attrHandle,
704 attrType] = table::attribute_value::decodeHeader(attrValueEntry);
Sagar Srinivascac0ebb2021-11-23 07:50:28 -0600705
706 auto attrHeader = table::attribute::decodeHeader(attrEntry);
707 BIOSStringTable biosStringTable(*stringTable);
708 auto attrName = biosStringTable.findString(attrHeader.stringHandle);
709
710 switch (attrType)
711 {
712 case PLDM_BIOS_ENUMERATION:
713 case PLDM_BIOS_ENUMERATION_READ_ONLY:
714 {
715 auto count = pldm_bios_table_attr_value_entry_enum_decode_number(
716 attrValueEntry);
717 std::vector<uint8_t> handles(count);
718 pldm_bios_table_attr_value_entry_enum_decode_handles(
719 attrValueEntry, handles.data(), handles.size());
720
721 for (uint8_t handle : handles)
722 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600723 auto nwVal = displayStringHandle(attrHandle, handle, attrTable,
724 stringTable);
725 auto chkBMC = isBMC ? "true" : "false";
726 info(
727 "BIOS:{ATTR_NAME}, updated to value: {NEW_VAL}, by BMC: {CHK_BMC} ",
728 "ATTR_NAME", attrName, "NEW_VAL", nwVal, "CHK_BMC", chkBMC);
Sagar Srinivascac0ebb2021-11-23 07:50:28 -0600729 }
730 break;
731 }
732 case PLDM_BIOS_INTEGER:
733 case PLDM_BIOS_INTEGER_READ_ONLY:
734 {
735 auto value =
736 table::attribute_value::decodeIntegerEntry(attrValueEntry);
Riya Dixit49cfb132023-03-02 04:26:53 -0600737 auto chkBMC = isBMC ? "true" : "false";
738 info(
739 "BIOS: {ATTR_NAME}, updated to value: {UPDATED_VAL}, by BMC: {CHK_BMC}",
740 "ATTR_NAME", attrName, "UPDATED_VAL", value, "CHK_BMC", chkBMC);
Sagar Srinivascac0ebb2021-11-23 07:50:28 -0600741 break;
742 }
743 case PLDM_BIOS_STRING:
744 case PLDM_BIOS_STRING_READ_ONLY:
745 {
746 auto value =
747 table::attribute_value::decodeStringEntry(attrValueEntry);
Riya Dixit49cfb132023-03-02 04:26:53 -0600748 auto chkBMC = isBMC ? "true" : "false";
749 info(
750 "BIOS: {ATTR_NAME}, updated to value: {UPDATED_VAL}, by BMC: {CHK_BMC}",
751 "ATTR_NAME", attrName, "UPDATED_VAL", value, "CHK_BMC", chkBMC);
Sagar Srinivascac0ebb2021-11-23 07:50:28 -0600752 break;
753 }
754 default:
755 break;
756 };
757}
758
John Wang8241b342020-06-05 10:49:17 +0800759int BIOSConfig::checkAttrValueToUpdate(
760 const pldm_bios_attr_val_table_entry* attrValueEntry,
761 const pldm_bios_attr_table_entry* attrEntry, Table&)
762
763{
Patrick Williams6da4f912023-05-10 07:50:53 -0500764 auto [attrHandle,
765 attrType] = table::attribute_value::decodeHeader(attrValueEntry);
John Wang8241b342020-06-05 10:49:17 +0800766
767 switch (attrType)
768 {
769 case PLDM_BIOS_ENUMERATION:
George Liu5bb9edb2021-08-05 20:10:32 +0800770 case PLDM_BIOS_ENUMERATION_READ_ONLY:
John Wang8241b342020-06-05 10:49:17 +0800771 {
772 auto value =
773 table::attribute_value::decodeEnumEntry(attrValueEntry);
Patrick Williams6da4f912023-05-10 07:50:53 -0500774 auto [pvHdls,
775 defIndex] = table::attribute::decodeEnumEntry(attrEntry);
Varsha Kaverappa6a4d1cf2021-11-24 21:15:42 -0600776 if (!(value.size() == 1))
777 {
778 return PLDM_ERROR_INVALID_LENGTH;
779 }
John Wang8241b342020-06-05 10:49:17 +0800780 if (value[0] >= pvHdls.size())
781 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600782 error("Enum: Illgeal index, Index = {ATTR_INDEX}", "ATTR_INDEX",
783 (int)value[0]);
John Wang8241b342020-06-05 10:49:17 +0800784 return PLDM_ERROR_INVALID_DATA;
785 }
John Wang8241b342020-06-05 10:49:17 +0800786 return PLDM_SUCCESS;
787 }
788 case PLDM_BIOS_INTEGER:
George Liu5bb9edb2021-08-05 20:10:32 +0800789 case PLDM_BIOS_INTEGER_READ_ONLY:
John Wang8241b342020-06-05 10:49:17 +0800790 {
791 auto value =
792 table::attribute_value::decodeIntegerEntry(attrValueEntry);
Patrick Williams6da4f912023-05-10 07:50:53 -0500793 auto [lower, upper, scalar,
794 def] = table::attribute::decodeIntegerEntry(attrEntry);
John Wang8241b342020-06-05 10:49:17 +0800795
796 if (value < lower || value > upper)
797 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600798 error("Integer: out of bound, value = {ATTR_VALUE}",
799 "ATTR_VALUE", value);
John Wang8241b342020-06-05 10:49:17 +0800800 return PLDM_ERROR_INVALID_DATA;
801 }
802 return PLDM_SUCCESS;
803 }
804 case PLDM_BIOS_STRING:
George Liu5bb9edb2021-08-05 20:10:32 +0800805 case PLDM_BIOS_STRING_READ_ONLY:
John Wang8241b342020-06-05 10:49:17 +0800806 {
807 auto stringConf = table::attribute::decodeStringEntry(attrEntry);
808 auto value =
809 table::attribute_value::decodeStringEntry(attrValueEntry);
810 if (value.size() < stringConf.minLength ||
811 value.size() > stringConf.maxLength)
812 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600813 error(
814 "String: Length error, string = {ATTR_VALUE} length {LEN}",
815 "ATTR_VALUE", value, "LEN", value.size());
John Wang8241b342020-06-05 10:49:17 +0800816 return PLDM_ERROR_INVALID_LENGTH;
817 }
818 return PLDM_SUCCESS;
819 }
820 default:
Riya Dixit49cfb132023-03-02 04:26:53 -0600821 error("ReadOnly or Unspported type, type = {ATTR_TYPE}",
822 "ATTR_TYPE", attrType);
John Wang8241b342020-06-05 10:49:17 +0800823 return PLDM_ERROR;
824 };
825}
826
Sagar Srinivascac0ebb2021-11-23 07:50:28 -0600827int BIOSConfig::setAttrValue(const void* entry, size_t size, bool isBMC,
828 bool updateDBus, bool updateBaseBIOSTable)
John Wangd9659342020-02-27 16:46:05 +0800829{
830 auto attrValueTable = getBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE);
831 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
832 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
833 if (!attrValueTable || !attrTable || !stringTable)
834 {
835 return PLDM_BIOS_TABLE_UNAVAILABLE;
836 }
837
John Wangd9659342020-02-27 16:46:05 +0800838 auto attrValueEntry =
839 reinterpret_cast<const pldm_bios_attr_val_table_entry*>(entry);
840
841 auto attrValHeader = table::attribute_value::decodeHeader(attrValueEntry);
842
Patrick Williams6da4f912023-05-10 07:50:53 -0500843 auto attrEntry = table::attribute::findByHandle(*attrTable,
844 attrValHeader.attrHandle);
John Wangd9659342020-02-27 16:46:05 +0800845 if (!attrEntry)
846 {
847 return PLDM_ERROR;
848 }
849
John Wang8241b342020-06-05 10:49:17 +0800850 auto rc = checkAttrValueToUpdate(attrValueEntry, attrEntry, *stringTable);
851 if (rc != PLDM_SUCCESS)
852 {
853 return rc;
854 }
855
Patrick Williams6da4f912023-05-10 07:50:53 -0500856 auto destTable = table::attribute_value::updateTable(*attrValueTable, entry,
857 size);
John Wang8241b342020-06-05 10:49:17 +0800858
859 if (!destTable)
860 {
861 return PLDM_ERROR;
862 }
863
John Wangd9659342020-02-27 16:46:05 +0800864 try
865 {
866 auto attrHeader = table::attribute::decodeHeader(attrEntry);
867
868 BIOSStringTable biosStringTable(*stringTable);
869 auto attrName = biosStringTable.findString(attrHeader.stringHandle);
Patrick Williamsa6756622023-10-20 11:19:15 -0500870 auto iter = std::find_if(
871 biosAttributes.begin(), biosAttributes.end(),
872 [&attrName](const auto& attr) { return attr->name == attrName; });
John Wangd9659342020-02-27 16:46:05 +0800873
874 if (iter == biosAttributes.end())
875 {
876 return PLDM_ERROR;
877 }
George Liu6d6d1e82021-02-16 11:08:55 +0800878 if (updateDBus)
879 {
880 (*iter)->setAttrValueOnDbus(attrValueEntry, attrEntry,
881 biosStringTable);
882 }
John Wangd9659342020-02-27 16:46:05 +0800883 }
884 catch (const std::exception& e)
885 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600886 error("Set attribute value error: {ERR_EXCEP}", "ERR_EXCEP", e.what());
John Wangd9659342020-02-27 16:46:05 +0800887 return PLDM_ERROR;
888 }
889
Tom Joseph7f839f92020-09-21 10:20:44 +0530890 setBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE, *destTable, updateBaseBIOSTable);
George Liu5c3192b2020-08-13 17:35:43 +0800891
Sagar Srinivascac0ebb2021-11-23 07:50:28 -0600892 traceBIOSUpdate(attrValueEntry, attrEntry, isBMC);
893
John Wangd9659342020-02-27 16:46:05 +0800894 return PLDM_SUCCESS;
895}
896
897void BIOSConfig::removeTables()
898{
899 try
900 {
901 fs::remove(tableDir / stringTableFile);
902 fs::remove(tableDir / attrTableFile);
903 fs::remove(tableDir / attrValueTableFile);
904 }
905 catch (const std::exception& e)
906 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600907 error("Remove the tables error: {ERR_EXCEP}", "ERR_EXCEP", e.what());
John Wangd9659342020-02-27 16:46:05 +0800908 }
909}
910
Sampa Misra46ece062020-03-18 07:17:44 -0500911void BIOSConfig::processBiosAttrChangeNotification(
912 const DbusChObjProperties& chProperties, uint32_t biosAttrIndex)
913{
914 const auto& dBusMap = biosAttributes[biosAttrIndex]->getDBusMap();
915 const auto& propertyName = dBusMap->propertyName;
916 const auto& attrName = biosAttributes[biosAttrIndex]->name;
917
918 const auto it = chProperties.find(propertyName);
919 if (it == chProperties.end())
920 {
921 return;
922 }
923
924 PropertyValue newPropVal = it->second;
925 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
926 if (!stringTable.has_value())
927 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600928 error("BIOS string table unavailable");
Sampa Misra46ece062020-03-18 07:17:44 -0500929 return;
930 }
931 BIOSStringTable biosStringTable(*stringTable);
932 uint16_t attrNameHdl{};
933 try
934 {
935 attrNameHdl = biosStringTable.findHandle(attrName);
936 }
Patrick Williams51330582021-10-06 12:48:56 -0500937 catch (const std::invalid_argument& e)
Sampa Misra46ece062020-03-18 07:17:44 -0500938 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600939 error("Could not find handle for BIOS string, ATTRIBUTE={ATTR_NAME}",
940 "ATTR_NAME", attrName.c_str());
Sampa Misra46ece062020-03-18 07:17:44 -0500941 return;
942 }
943
944 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
945 if (!attrTable.has_value())
946 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600947 error("Attribute table not present");
Sampa Misra46ece062020-03-18 07:17:44 -0500948 return;
949 }
950 const struct pldm_bios_attr_table_entry* tableEntry =
951 table::attribute::findByStringHandle(*attrTable, attrNameHdl);
952 if (tableEntry == nullptr)
953 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600954 error(
955 "Attribute not found in attribute table, name= {ATTR_NAME} name handle={ATTR_HANDLE}",
956 "ATTR_NAME", attrName.c_str(), "ATTR_HANDLE", attrNameHdl);
Sampa Misra46ece062020-03-18 07:17:44 -0500957 return;
958 }
959
Patrick Williams6da4f912023-05-10 07:50:53 -0500960 auto [attrHdl, attrType,
961 stringHdl] = table::attribute::decodeHeader(tableEntry);
Sampa Misra46ece062020-03-18 07:17:44 -0500962
963 auto attrValueSrcTable = getBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE);
964
965 if (!attrValueSrcTable.has_value())
966 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600967 error("Attribute value table not present");
Sampa Misra46ece062020-03-18 07:17:44 -0500968 return;
969 }
970
971 Table newValue;
972 auto rc = biosAttributes[biosAttrIndex]->updateAttrVal(
973 newValue, attrHdl, attrType, newPropVal);
974 if (rc != PLDM_SUCCESS)
975 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600976 error(
977 "Could not update the attribute value table for attribute handle={ATTR_HANDLE} and type={ATTR_TYPE}",
978 "ATTR_HANDLE", attrHdl, "ATTR_TYPE", (uint32_t)attrType);
Sampa Misra46ece062020-03-18 07:17:44 -0500979 return;
980 }
981 auto destTable = table::attribute_value::updateTable(
982 *attrValueSrcTable, newValue.data(), newValue.size());
983 if (destTable.has_value())
984 {
985 storeTable(tableDir / attrValueTableFile, *destTable);
986 }
Sampa Misra0f262332021-02-15 00:13:51 -0600987
Sagar Srinivascac0ebb2021-11-23 07:50:28 -0600988 rc = setAttrValue(newValue.data(), newValue.size(), true, false);
Sampa Misra0f262332021-02-15 00:13:51 -0600989 if (rc != PLDM_SUCCESS)
990 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600991 error("could not setAttrValue on base bios table and dbus, rc = {RC}",
992 "RC", rc);
Sampa Misra0f262332021-02-15 00:13:51 -0600993 }
Sampa Misra46ece062020-03-18 07:17:44 -0500994}
995
George Liu1244acf2020-08-14 09:11:11 +0800996uint16_t BIOSConfig::findAttrHandle(const std::string& attrName)
997{
998 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
999 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
1000
1001 BIOSStringTable biosStringTable(*stringTable);
1002 pldm::bios::utils::BIOSTableIter<PLDM_BIOS_ATTR_TABLE> attrTableIter(
1003 attrTable->data(), attrTable->size());
1004 auto stringHandle = biosStringTable.findHandle(attrName);
1005
1006 for (auto entry : pldm::bios::utils::BIOSTableIter<PLDM_BIOS_ATTR_TABLE>(
1007 attrTable->data(), attrTable->size()))
1008 {
1009 auto header = table::attribute::decodeHeader(entry);
1010 if (header.stringHandle == stringHandle)
1011 {
1012 return header.attrHandle;
1013 }
1014 }
1015
1016 throw std::invalid_argument("Unknow attribute Name");
1017}
1018
1019void BIOSConfig::constructPendingAttribute(
1020 const PendingAttributes& pendingAttributes)
1021{
Tom Joseph7f839f92020-09-21 10:20:44 +05301022 std::vector<uint16_t> listOfHandles{};
1023
George Liu1244acf2020-08-14 09:11:11 +08001024 for (auto& attribute : pendingAttributes)
1025 {
1026 std::string attributeName = attribute.first;
1027 auto& [attributeType, attributevalue] = attribute.second;
1028
1029 auto iter = std::find_if(biosAttributes.begin(), biosAttributes.end(),
1030 [&attributeName](const auto& attr) {
Patrick Williams6da4f912023-05-10 07:50:53 -05001031 return attr->name == attributeName;
1032 });
George Liu1244acf2020-08-14 09:11:11 +08001033
1034 if (iter == biosAttributes.end())
1035 {
Riya Dixit49cfb132023-03-02 04:26:53 -06001036 error("Wrong attribute name, attributeName = {ATTR_NAME}",
1037 "ATTR_NAME", attributeName);
George Liu1244acf2020-08-14 09:11:11 +08001038 continue;
1039 }
1040
1041 Table attrValueEntry(sizeof(pldm_bios_attr_val_table_entry), 0);
1042 auto entry = reinterpret_cast<pldm_bios_attr_val_table_entry*>(
1043 attrValueEntry.data());
1044
1045 auto handler = findAttrHandle(attributeName);
1046 auto type =
1047 BIOSConfigManager::convertAttributeTypeFromString(attributeType);
1048
1049 if (type != BIOSConfigManager::AttributeType::Enumeration &&
1050 type != BIOSConfigManager::AttributeType::String &&
1051 type != BIOSConfigManager::AttributeType::Integer)
1052 {
Riya Dixit49cfb132023-03-02 04:26:53 -06001053 error("Attribute type not supported, attributeType = {ATTR_TYPE}",
1054 "ATTR_TYPE", attributeType);
George Liu1244acf2020-08-14 09:11:11 +08001055 continue;
1056 }
1057
George Liu4876c542022-06-08 15:59:54 +08001058 const auto [attrType, readonlyStatus, displayName, description,
Patrick Williams6da4f912023-05-10 07:50:53 -05001059 menuPath, currentValue, defaultValue,
1060 option] = baseBIOSTableMaps.at(attributeName);
George Liu4876c542022-06-08 15:59:54 +08001061
George Liu1244acf2020-08-14 09:11:11 +08001062 entry->attr_handle = htole16(handler);
George Liu4876c542022-06-08 15:59:54 +08001063
1064 // Need to verify that the current value has really changed
1065 if (attributeType == attrType && attributevalue != currentValue)
1066 {
1067 listOfHandles.emplace_back(htole16(handler));
1068 }
Tom Joseph7f839f92020-09-21 10:20:44 +05301069
George Liu1244acf2020-08-14 09:11:11 +08001070 (*iter)->generateAttributeEntry(attributevalue, attrValueEntry);
1071
Sagar Srinivascac0ebb2021-11-23 07:50:28 -06001072 setAttrValue(attrValueEntry.data(), attrValueEntry.size(), true);
Tom Joseph7f839f92020-09-21 10:20:44 +05301073 }
1074
1075 if (listOfHandles.size())
1076 {
1077#ifdef OEM_IBM
1078 auto rc = pldm::responder::platform::sendBiosAttributeUpdateEvent(
Andrew Jefferya330b2f2023-05-04 14:55:37 +09301079 eid, instanceIdDb, listOfHandles, handler);
Tom Joseph7f839f92020-09-21 10:20:44 +05301080 if (rc != PLDM_SUCCESS)
1081 {
1082 return;
1083 }
1084#endif
George Liu1244acf2020-08-14 09:11:11 +08001085 }
1086}
1087
1088void BIOSConfig::listenPendingAttributes()
1089{
1090 constexpr auto objPath = "/xyz/openbmc_project/bios_config/manager";
1091 constexpr auto objInterface = "xyz.openbmc_project.BIOSConfig.Manager";
1092
1093 using namespace sdbusplus::bus::match::rules;
Patrick Williams84b790c2022-07-22 19:26:56 -05001094 auto updateBIOSMatch = std::make_unique<sdbusplus::bus::match_t>(
George Liu1244acf2020-08-14 09:11:11 +08001095 pldm::utils::DBusHandler::getBus(),
1096 propertiesChanged(objPath, objInterface),
Patrick Williams84b790c2022-07-22 19:26:56 -05001097 [this](sdbusplus::message_t& msg) {
Patrick Williams6da4f912023-05-10 07:50:53 -05001098 constexpr auto propertyName = "PendingAttributes";
George Liu1244acf2020-08-14 09:11:11 +08001099
Patrick Williams6da4f912023-05-10 07:50:53 -05001100 using Value =
1101 std::variant<std::string, PendingAttributes, BaseBIOSTable>;
1102 using Properties = std::map<DbusProp, Value>;
George Liu1244acf2020-08-14 09:11:11 +08001103
Patrick Williams6da4f912023-05-10 07:50:53 -05001104 Properties props{};
1105 std::string intf;
1106 msg.read(intf, props);
George Liu1244acf2020-08-14 09:11:11 +08001107
Patrick Williams6da4f912023-05-10 07:50:53 -05001108 auto valPropMap = props.find(propertyName);
1109 if (valPropMap == props.end())
1110 {
1111 return;
1112 }
George Liu1244acf2020-08-14 09:11:11 +08001113
Patrick Williams6da4f912023-05-10 07:50:53 -05001114 PendingAttributes pendingAttributes =
1115 std::get<PendingAttributes>(valPropMap->second);
1116 this->constructPendingAttribute(pendingAttributes);
Patrick Williamsa6756622023-10-20 11:19:15 -05001117 });
George Liu1244acf2020-08-14 09:11:11 +08001118
1119 biosAttrMatch.emplace_back(std::move(updateBIOSMatch));
1120}
1121
John Wangd9659342020-02-27 16:46:05 +08001122} // namespace bios
1123} // namespace responder
1124} // namespace pldm