blob: f4c5ecc22b23ccf6d51e41c91c1aa8c35449d646 [file] [log] [blame]
Sridevi Ramesh98576432019-11-27 10:10:28 -06001#include "pldm_bios_cmd.hpp"
2
Deepak Kodihallid130e1a2020-06-17 05:55:32 -05003#include "common/bios_utils.hpp"
4#include "common/utils.hpp"
Sridevi Ramesh98576432019-11-27 10:10:28 -06005#include "pldm_cmd_helper.hpp"
John Wangb754eee2020-02-15 16:10:25 +08006
George Liuc453e162022-12-21 17:16:23 +08007#include <libpldm/bios_table.h>
8#include <libpldm/utils.h>
9
John Wangb754eee2020-02-15 16:10:25 +080010#include <map>
11#include <optional>
Sridevi Ramesh98576432019-11-27 10:10:28 -060012
Sridevi Ramesh98576432019-11-27 10:10:28 -060013namespace pldmtool
14{
15
16namespace bios
17{
18
19namespace
20{
21
22using namespace pldmtool::helper;
John Wangb754eee2020-02-15 16:10:25 +080023using namespace pldm::bios::utils;
Brad Bishop5079ac42021-08-19 18:35:06 -040024using namespace pldm::utils;
Sridevi Ramesh98576432019-11-27 10:10:28 -060025
26std::vector<std::unique_ptr<CommandInterface>> commands;
27
Sridevi Rameshcdfe1142020-01-31 05:42:50 -060028const std::map<const char*, pldm_bios_table_types> pldmBIOSTableTypes{
29 {"StringTable", PLDM_BIOS_STRING_TABLE},
30 {"AttributeTable", PLDM_BIOS_ATTR_TABLE},
31 {"AttributeValueTable", PLDM_BIOS_ATTR_VAL_TABLE},
32};
33
Sridevi Ramesh98576432019-11-27 10:10:28 -060034} // namespace
35
36class GetDateTime : public CommandInterface
37{
38 public:
39 ~GetDateTime() = default;
40 GetDateTime() = delete;
41 GetDateTime(const GetDateTime&) = delete;
42 GetDateTime(GetDateTime&&) = default;
43 GetDateTime& operator=(const GetDateTime&) = delete;
44 GetDateTime& operator=(GetDateTime&&) = default;
45
46 using CommandInterface::CommandInterface;
47
48 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
49 {
50 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr));
51 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
52
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -060053 auto rc = encode_get_date_time_req(instanceId, request);
Sridevi Ramesh98576432019-11-27 10:10:28 -060054 return {rc, requestMsg};
55 }
56
57 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
58 {
59 uint8_t cc = 0;
60
61 uint8_t seconds, minutes, hours, day, month;
62 uint16_t year;
Patrick Williams6da4f912023-05-10 07:50:53 -050063 auto rc = decode_get_date_time_resp(responsePtr, payloadLength, &cc,
64 &seconds, &minutes, &hours, &day,
65 &month, &year);
Sridevi Ramesh98576432019-11-27 10:10:28 -060066 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
67 {
68 std::cerr << "Response Message Error: "
69 << "rc=" << rc << ",cc=" << (int)cc << std::endl;
70 return;
71 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -050072
73 std::stringstream dt;
74 ordered_json data;
75 dt << bcd2dec16(year) << "-" << setWidth(month) << "-" << setWidth(day)
76 << " " << setWidth(hours) << ":" << setWidth(minutes) << ":"
77 << setWidth(seconds);
78 data["Response"] = dt.str();
79 pldmtool::helper::DisplayInJson(data);
Sridevi Ramesh98576432019-11-27 10:10:28 -060080 }
81
82 private:
Sridevi Rameshca4a8152020-08-11 09:26:19 -050083 static std::string setWidth(uint8_t data)
Sridevi Ramesh98576432019-11-27 10:10:28 -060084 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -050085 std::stringstream s;
86 s << std::setfill('0') << std::setw(2)
87 << static_cast<uint32_t>(bcd2dec8(data));
88 return s.str();
Sridevi Ramesh98576432019-11-27 10:10:28 -060089 }
90};
91
George Liud6649362019-11-27 19:06:51 +080092class SetDateTime : public CommandInterface
93{
94 public:
95 ~SetDateTime() = default;
96 SetDateTime() = delete;
97 SetDateTime(const SetDateTime&) = delete;
98 SetDateTime(SetDateTime&&) = default;
99 SetDateTime& operator=(const SetDateTime&) = delete;
100 SetDateTime& operator=(SetDateTime&&) = default;
101
102 explicit SetDateTime(const char* type, const char* name, CLI::App* app) :
103 CommandInterface(type, name, app)
104 {
105 app->add_option("-d,--data", tmData,
106 "set date time data\n"
107 "eg: YYYYMMDDHHMMSS")
108 ->required();
109 }
110
111 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
112 {
113 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
114 sizeof(struct pldm_set_date_time_req));
115 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
116 uint16_t year = 0;
117 uint8_t month = 0;
118 uint8_t day = 0;
119 uint8_t hours = 0;
120 uint8_t minutes = 0;
121 uint8_t seconds = 0;
122
123 if (!uintToDate(tmData, &year, &month, &day, &hours, &minutes,
124 &seconds))
125 {
126 std::cerr << "decode date Error: "
127 << "tmData=" << tmData << std::endl;
128
129 return {PLDM_ERROR_INVALID_DATA, requestMsg};
130 }
131
132 auto rc = encode_set_date_time_req(
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600133 instanceId, seconds, minutes, hours, day, month, year, request,
134 sizeof(struct pldm_set_date_time_req));
George Liud6649362019-11-27 19:06:51 +0800135
136 return {rc, requestMsg};
137 }
138
139 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
140 {
141 uint8_t completionCode = 0;
142 auto rc = decode_set_date_time_resp(responsePtr, payloadLength,
143 &completionCode);
144
145 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
146 {
147 std::cerr << "Response Message Error: "
148 << "rc=" << rc << ",cc=" << (int)completionCode
149 << std::endl;
150 return;
151 }
152
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500153 ordered_json data;
154 data["Response"] = "SUCCESS";
155 pldmtool::helper::DisplayInJson(data);
George Liud6649362019-11-27 19:06:51 +0800156 }
157
158 private:
159 uint64_t tmData;
160};
161
Adair Li4dd11a72020-04-24 14:52:59 +0800162class GetBIOSTableHandler : public CommandInterface
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600163{
164 public:
Adair Li4dd11a72020-04-24 14:52:59 +0800165 ~GetBIOSTableHandler() = default;
166 GetBIOSTableHandler() = delete;
167 GetBIOSTableHandler(const GetBIOSTableHandler&) = delete;
168 GetBIOSTableHandler(GetBIOSTableHandler&&) = delete;
169 GetBIOSTableHandler& operator=(const GetBIOSTableHandler&) = delete;
170 GetBIOSTableHandler& operator=(GetBIOSTableHandler&&) = delete;
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600171
John Wangb754eee2020-02-15 16:10:25 +0800172 using Table = std::vector<uint8_t>;
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600173
Adair Li4dd11a72020-04-24 14:52:59 +0800174 using CommandInterface::CommandInterface;
175
176 static inline const std::map<pldm_bios_attribute_type, const char*>
177 attrTypeMap = {
178 {PLDM_BIOS_ENUMERATION, "BIOSEnumeration"},
179 {PLDM_BIOS_ENUMERATION_READ_ONLY, "BIOSEnumerationReadOnly"},
180 {PLDM_BIOS_STRING, "BIOSString"},
181 {PLDM_BIOS_STRING_READ_ONLY, "BIOSStringReadOnly"},
182 {PLDM_BIOS_PASSWORD, "BIOSPassword"},
183 {PLDM_BIOS_PASSWORD_READ_ONLY, "BIOSPasswordReadOnly"},
184 {PLDM_BIOS_INTEGER, "BIOSInteger"},
185 {PLDM_BIOS_INTEGER_READ_ONLY, "BIOSIntegerReadOnly"},
186
187 };
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600188
189 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
190 {
John Wangb754eee2020-02-15 16:10:25 +0800191 return {PLDM_ERROR, {}};
192 }
Adair Li4dd11a72020-04-24 14:52:59 +0800193
Patrick Williams6da4f912023-05-10 07:50:53 -0500194 void parseResponseMsg(pldm_msg*, size_t) override {}
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600195
John Wangb754eee2020-02-15 16:10:25 +0800196 std::optional<Table> getBIOSTable(pldm_bios_table_types tableType)
197 {
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600198 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
199 PLDM_GET_BIOS_TABLE_REQ_BYTES);
200 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
201
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600202 auto rc = encode_get_bios_table_req(instanceId, 0, PLDM_GET_FIRSTPART,
203 tableType, request);
John Wangb754eee2020-02-15 16:10:25 +0800204 if (rc != PLDM_SUCCESS)
205 {
206 std::cerr << "Encode GetBIOSTable Error, tableType=," << tableType
207 << " ,rc=" << rc << std::endl;
208 return std::nullopt;
209 }
210 std::vector<uint8_t> responseMsg;
211 rc = pldmSendRecv(requestMsg, responseMsg);
212 if (rc != PLDM_SUCCESS)
213 {
214 std::cerr << "PLDM: Communication Error, rc =" << rc << std::endl;
215 return std::nullopt;
216 }
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600217
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600218 uint8_t cc = 0, transferFlag = 0;
219 uint32_t nextTransferHandle = 0;
220 size_t bios_table_offset;
John Wangb754eee2020-02-15 16:10:25 +0800221 auto responsePtr =
222 reinterpret_cast<struct pldm_msg*>(responseMsg.data());
223 auto payloadLength = responseMsg.size() - sizeof(pldm_msg_hdr);
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600224
John Wangb754eee2020-02-15 16:10:25 +0800225 rc = decode_get_bios_table_resp(responsePtr, payloadLength, &cc,
226 &nextTransferHandle, &transferFlag,
227 &bios_table_offset);
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600228
229 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
230 {
John Wangb754eee2020-02-15 16:10:25 +0800231 std::cerr << "GetBIOSTable Response Error: tableType=" << tableType
232 << ", rc=" << rc << ", cc=" << (int)cc << std::endl;
233 return std::nullopt;
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600234 }
235 auto tableData =
236 reinterpret_cast<char*>((responsePtr->payload) + bios_table_offset);
John Wangb754eee2020-02-15 16:10:25 +0800237 auto tableSize = payloadLength - sizeof(nextTransferHandle) -
238 sizeof(transferFlag) - sizeof(cc);
239 return std::make_optional<Table>(tableData, tableData + tableSize);
240 }
241
Adair Lice041e22020-05-09 17:27:43 +0800242 const pldm_bios_attr_table_entry*
243 findAttrEntryByName(const std::string& name, const Table& attrTable,
244 const Table& stringTable)
John Wangb754eee2020-02-15 16:10:25 +0800245 {
Adair Li4dd11a72020-04-24 14:52:59 +0800246 auto stringEntry = pldm_bios_table_string_find_by_string(
247 stringTable.data(), stringTable.size(), name.c_str());
248 if (stringEntry == nullptr)
John Wangb754eee2020-02-15 16:10:25 +0800249 {
Adair Lice041e22020-05-09 17:27:43 +0800250 return nullptr;
Adair Li4dd11a72020-04-24 14:52:59 +0800251 }
John Wangb754eee2020-02-15 16:10:25 +0800252
Adair Li4dd11a72020-04-24 14:52:59 +0800253 auto nameHandle =
254 pldm_bios_table_string_entry_decode_handle(stringEntry);
John Wangb754eee2020-02-15 16:10:25 +0800255
Adair Li4dd11a72020-04-24 14:52:59 +0800256 for (auto attr : BIOSTableIter<PLDM_BIOS_ATTR_TABLE>(attrTable.data(),
257 attrTable.size()))
258 {
259 auto attrNameHandle =
260 pldm_bios_table_attr_entry_decode_string_handle(attr);
261 if (attrNameHandle == nameHandle)
262 {
Adair Lice041e22020-05-09 17:27:43 +0800263 return attr;
John Wangb754eee2020-02-15 16:10:25 +0800264 }
265 }
Adair Lice041e22020-05-09 17:27:43 +0800266 return nullptr;
267 }
268
269 std::optional<uint16_t> findAttrHandleByName(const std::string& name,
270 const Table& attrTable,
271 const Table& stringTable)
272 {
273 auto attribute = findAttrEntryByName(name, attrTable, stringTable);
274 if (attribute == nullptr)
275 {
276 return std::nullopt;
277 }
278
279 return pldm_bios_table_attr_entry_decode_attribute_handle(attribute);
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600280 }
281
John Wangb754eee2020-02-15 16:10:25 +0800282 std::string decodeStringFromStringEntry(
283 const pldm_bios_string_table_entry* stringEntry)
284 {
285 auto strLength =
286 pldm_bios_table_string_entry_decode_string_length(stringEntry);
287 std::vector<char> buffer(strLength + 1 /* sizeof '\0' */);
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930288 // Preconditions are upheld therefore no error check necessary
289 pldm_bios_table_string_entry_decode_string_check(
290 stringEntry, buffer.data(), buffer.size());
John Wangb754eee2020-02-15 16:10:25 +0800291
292 return std::string(buffer.data(), buffer.data() + strLength);
293 }
294
295 std::string displayStringHandle(uint16_t handle,
Adair Li4dd11a72020-04-24 14:52:59 +0800296 const std::optional<Table>& stringTable,
297 bool displayHandle = true)
John Wangb754eee2020-02-15 16:10:25 +0800298 {
299 std::string displayString = std::to_string(handle);
300 if (!stringTable)
301 {
302 return displayString;
303 }
304 auto stringEntry = pldm_bios_table_string_find_by_handle(
305 stringTable->data(), stringTable->size(), handle);
306 if (stringEntry == nullptr)
307 {
308 return displayString;
309 }
310
Adair Li4dd11a72020-04-24 14:52:59 +0800311 auto decodedStr = decodeStringFromStringEntry(stringEntry);
312 if (!displayHandle)
313 {
314 return decodedStr;
315 }
316
317 return displayString + "(" + decodedStr + ")";
John Wangb754eee2020-02-15 16:10:25 +0800318 }
319
320 std::string displayEnumValueByIndex(uint16_t attrHandle, uint8_t index,
321 const std::optional<Table>& attrTable,
322 const std::optional<Table>& stringTable)
323 {
324 std::string displayString;
325 if (!attrTable)
326 {
327 return displayString;
328 }
329
330 auto attrEntry = pldm_bios_table_attr_find_by_handle(
331 attrTable->data(), attrTable->size(), attrHandle);
332 if (attrEntry == nullptr)
333 {
334 return displayString;
335 }
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930336 uint8_t pvNum;
337 int rc = pldm_bios_table_attr_entry_enum_decode_pv_num_check(attrEntry,
338 &pvNum);
339 if (rc != PLDM_SUCCESS)
340 {
341 return displayString;
342 }
John Wangb754eee2020-02-15 16:10:25 +0800343 std::vector<uint16_t> pvHandls(pvNum);
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930344 // Preconditions are upheld therefore no error check necessary
345 pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
John Wangb754eee2020-02-15 16:10:25 +0800346 attrEntry, pvHandls.data(), pvHandls.size());
Adair Li4dd11a72020-04-24 14:52:59 +0800347 return displayStringHandle(pvHandls[index], stringTable, false);
John Wangb754eee2020-02-15 16:10:25 +0800348 }
349
Adair Li4dd11a72020-04-24 14:52:59 +0800350 void displayAttributeValueEntry(
351 const pldm_bios_attr_val_table_entry* tableEntry,
352 const std::optional<Table>& attrTable,
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500353 const std::optional<Table>& stringTable, bool verbose,
354 ordered_json& output)
Adair Li4dd11a72020-04-24 14:52:59 +0800355 {
356 auto attrHandle =
357 pldm_bios_table_attr_value_entry_decode_attribute_handle(
358 tableEntry);
359 auto attrType = static_cast<pldm_bios_attribute_type>(
360 pldm_bios_table_attr_value_entry_decode_attribute_type(tableEntry));
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500361
John Wang2cd07da2020-06-19 15:45:39 +0800362 if (verbose)
363 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500364 output["AttributeHandle"] = attrHandle;
George Liubd5e2ea2021-04-22 20:33:06 +0800365 if (attrTypeMap.contains(attrType))
366 {
367 output["AttributeType"] = attrTypeMap.at(attrType);
368 }
369 else
370 {
371 std::cout << "Get AttributeType failed.\n";
372 }
John Wang2cd07da2020-06-19 15:45:39 +0800373 }
Adair Li4dd11a72020-04-24 14:52:59 +0800374 switch (attrType)
375 {
376 case PLDM_BIOS_ENUMERATION:
377 case PLDM_BIOS_ENUMERATION_READ_ONLY:
378 {
379 auto count =
380 pldm_bios_table_attr_value_entry_enum_decode_number(
381 tableEntry);
382 std::vector<uint8_t> handles(count);
383 pldm_bios_table_attr_value_entry_enum_decode_handles(
384 tableEntry, handles.data(), handles.size());
John Wang2cd07da2020-06-19 15:45:39 +0800385 if (verbose)
386 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500387 output["NumberOfCurrentValues"] = (int)count;
John Wang2cd07da2020-06-19 15:45:39 +0800388 }
Adair Li4dd11a72020-04-24 14:52:59 +0800389 for (size_t i = 0; i < handles.size(); i++)
390 {
John Wang2cd07da2020-06-19 15:45:39 +0800391 if (verbose)
392 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500393 output["CurrentValueStringHandleIndex[" +
394 std::to_string(i) + "]"] =
395 displayEnumValueByIndex(attrHandle, handles[i],
396 attrTable, stringTable);
John Wang2cd07da2020-06-19 15:45:39 +0800397 }
398 else
399 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500400 output["CurrentValue"] = displayEnumValueByIndex(
401 attrHandle, handles[i], attrTable, stringTable);
John Wang2cd07da2020-06-19 15:45:39 +0800402 }
Adair Li4dd11a72020-04-24 14:52:59 +0800403 }
404 break;
405 }
406 case PLDM_BIOS_INTEGER:
407 case PLDM_BIOS_INTEGER_READ_ONLY:
408 {
409 auto cv = pldm_bios_table_attr_value_entry_integer_decode_cv(
410 tableEntry);
John Wang2cd07da2020-06-19 15:45:39 +0800411 if (verbose)
412 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500413 output["CurrentValue"] = cv;
John Wang2cd07da2020-06-19 15:45:39 +0800414 }
415 else
416 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500417 output["CurrentValue"] = cv;
John Wang2cd07da2020-06-19 15:45:39 +0800418 }
Adair Li4dd11a72020-04-24 14:52:59 +0800419 break;
420 }
421 case PLDM_BIOS_STRING:
422 case PLDM_BIOS_STRING_READ_ONLY:
423 {
424 variable_field currentString;
425 pldm_bios_table_attr_value_entry_string_decode_string(
426 tableEntry, &currentString);
John Wang2cd07da2020-06-19 15:45:39 +0800427 if (verbose)
428 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500429 output["CurrentStringLength"] = currentString.length;
430 output["CurrentString"] = std::string(
431 reinterpret_cast<const char*>(currentString.ptr),
432 currentString.length);
John Wang2cd07da2020-06-19 15:45:39 +0800433 }
434 else
435 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500436 output["CurrentValue"] = std::string(
437 reinterpret_cast<const char*>(currentString.ptr),
438 currentString.length);
John Wang2cd07da2020-06-19 15:45:39 +0800439 }
Adair Li4dd11a72020-04-24 14:52:59 +0800440
441 break;
442 }
443 case PLDM_BIOS_PASSWORD:
444 case PLDM_BIOS_PASSWORD_READ_ONLY:
445 {
446 std::cout << "Password attribute: Not Supported" << std::endl;
447 break;
448 }
449 }
450 }
451};
452
453class GetBIOSTable : public GetBIOSTableHandler
454{
455 public:
456 ~GetBIOSTable() = default;
457 GetBIOSTable() = delete;
458 GetBIOSTable(const GetBIOSTable&) = delete;
459 GetBIOSTable(GetBIOSTable&&) = default;
460 GetBIOSTable& operator=(const GetBIOSTable&) = delete;
461 GetBIOSTable& operator=(GetBIOSTable&&) = default;
462
463 using Table = std::vector<uint8_t>;
464
465 explicit GetBIOSTable(const char* type, const char* name, CLI::App* app) :
466 GetBIOSTableHandler(type, name, app)
467 {
468 app->add_option("-t,--type", pldmBIOSTableType, "pldm bios table type")
469 ->required()
470 ->transform(
471 CLI::CheckedTransformer(pldmBIOSTableTypes, CLI::ignore_case));
472 }
473
474 void exec() override
475 {
476 switch (pldmBIOSTableType)
477 {
478 case PLDM_BIOS_STRING_TABLE:
479 {
480 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
481 decodeStringTable(stringTable);
482 break;
483 }
484 case PLDM_BIOS_ATTR_TABLE:
485 {
486 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
487 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
488
489 decodeAttributeTable(attrTable, stringTable);
490 break;
491 }
492 case PLDM_BIOS_ATTR_VAL_TABLE:
493 {
494 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
495 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
496 auto attrValTable = getBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE);
497
498 decodeAttributeValueTable(attrValTable, attrTable, stringTable);
499 break;
500 }
501 }
502 }
503
504 private:
505 pldm_bios_table_types pldmBIOSTableType;
506
John Wangb754eee2020-02-15 16:10:25 +0800507 void decodeStringTable(const std::optional<Table>& stringTable)
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600508 {
John Wangb754eee2020-02-15 16:10:25 +0800509 if (!stringTable)
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600510 {
John Wangb754eee2020-02-15 16:10:25 +0800511 std::cerr << "GetBIOSStringTable Error" << std::endl;
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600512 return;
513 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500514 ordered_json stringdata;
John Wangb754eee2020-02-15 16:10:25 +0800515
516 for (auto tableEntry : BIOSTableIter<PLDM_BIOS_STRING_TABLE>(
517 stringTable->data(), stringTable->size()))
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600518 {
John Wangb754eee2020-02-15 16:10:25 +0800519 auto strHandle =
520 pldm_bios_table_string_entry_decode_handle(tableEntry);
521 auto strTableData = decodeStringFromStringEntry(tableEntry);
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500522 stringdata[std::to_string(strHandle)] = strTableData;
John Wangb754eee2020-02-15 16:10:25 +0800523 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500524 pldmtool::helper::DisplayInJson(stringdata);
John Wangb754eee2020-02-15 16:10:25 +0800525 }
526 void decodeAttributeTable(const std::optional<Table>& attrTable,
527 const std::optional<Table>& stringTable)
528 {
John Wangb754eee2020-02-15 16:10:25 +0800529 if (!stringTable)
530 {
531 std::cerr << "GetBIOSAttributeTable Error" << std::endl;
532 return;
533 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500534 ordered_json output;
535
John Wangb754eee2020-02-15 16:10:25 +0800536 for (auto entry : BIOSTableIter<PLDM_BIOS_ATTR_TABLE>(
537 attrTable->data(), attrTable->size()))
538 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500539 ordered_json attrdata;
540
John Wangb754eee2020-02-15 16:10:25 +0800541 auto attrHandle =
542 pldm_bios_table_attr_entry_decode_attribute_handle(entry);
543 auto attrNameHandle =
544 pldm_bios_table_attr_entry_decode_string_handle(entry);
545 auto attrType = static_cast<pldm_bios_attribute_type>(
546 pldm_bios_table_attr_entry_decode_attribute_type(entry));
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500547
548 attrdata["AttributeHandle"] = attrHandle;
549 attrdata["AttributeNameHandle"] =
550 displayStringHandle(attrNameHandle, stringTable);
George Liubd5e2ea2021-04-22 20:33:06 +0800551 if (attrTypeMap.contains(attrType))
552 {
553 attrdata["AttributeType"] = attrTypeMap.at(attrType);
554 }
555 else
556 {
557 std::cout << "Get AttributeType failed.\n";
558 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500559
John Wangb754eee2020-02-15 16:10:25 +0800560 switch (attrType)
561 {
562 case PLDM_BIOS_ENUMERATION:
563 case PLDM_BIOS_ENUMERATION_READ_ONLY:
564 {
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930565 uint8_t pvNum;
566 // Preconditions are upheld therefore no error check
567 // necessary
568 pldm_bios_table_attr_entry_enum_decode_pv_num_check(entry,
569 &pvNum);
John Wangb754eee2020-02-15 16:10:25 +0800570 std::vector<uint16_t> pvHandls(pvNum);
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930571 // Preconditions are upheld therefore no error check
572 // necessary
573 pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
John Wangb754eee2020-02-15 16:10:25 +0800574 entry, pvHandls.data(), pvHandls.size());
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930575 uint8_t defNum;
576 // Preconditions are upheld therefore no error check
577 // necessary
578 pldm_bios_table_attr_entry_enum_decode_def_num_check(
579 entry, &defNum);
John Wangb754eee2020-02-15 16:10:25 +0800580 std::vector<uint8_t> defIndices(defNum);
581 pldm_bios_table_attr_entry_enum_decode_def_indices(
582 entry, defIndices.data(), defIndices.size());
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500583
584 attrdata["NumberOfPossibleValues"] = (int)pvNum;
John Wangb754eee2020-02-15 16:10:25 +0800585
586 for (size_t i = 0; i < pvHandls.size(); i++)
587 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500588 attrdata["PossibleValueStringHandle[" +
589 std::to_string(i) + "]"] =
590 displayStringHandle(pvHandls[i], stringTable);
John Wangb754eee2020-02-15 16:10:25 +0800591 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500592 attrdata["NumberOfDefaultValues"] = (int)defNum;
John Wangb754eee2020-02-15 16:10:25 +0800593 for (size_t i = 0; i < defIndices.size(); i++)
594 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500595 attrdata["DefaultValueStringHandleIndex[" +
596 std::to_string(i) + "]"] = (int)defIndices[i];
George Liua6daacb2021-03-23 11:18:41 +0800597 attrdata["DefaultValueStringHandle"] =
598 displayStringHandle(pvHandls[defIndices[i]],
599 stringTable);
John Wangb754eee2020-02-15 16:10:25 +0800600 }
601 break;
602 }
603 case PLDM_BIOS_INTEGER:
604 case PLDM_BIOS_INTEGER_READ_ONLY:
605 {
606 uint64_t lower, upper, def;
607 uint32_t scalar;
608 pldm_bios_table_attr_entry_integer_decode(
609 entry, &lower, &upper, &scalar, &def);
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500610 attrdata["LowerBound"] = lower;
611 attrdata["UpperBound"] = upper;
612 attrdata["ScalarIncrement"] = scalar;
613 attrdata["DefaultValue"] = def;
John Wangb754eee2020-02-15 16:10:25 +0800614 break;
615 }
616 case PLDM_BIOS_STRING:
617 case PLDM_BIOS_STRING_READ_ONLY:
618 {
619 auto strType =
620 pldm_bios_table_attr_entry_string_decode_string_type(
621 entry);
622 auto min =
623 pldm_bios_table_attr_entry_string_decode_min_length(
624 entry);
625 auto max =
626 pldm_bios_table_attr_entry_string_decode_max_length(
627 entry);
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930628 uint16_t def;
629 // Preconditions are upheld therefore no error check
630 // necessary
631 pldm_bios_table_attr_entry_string_decode_def_string_length_check(
632 entry, &def);
John Wangb754eee2020-02-15 16:10:25 +0800633 std::vector<char> defString(def + 1);
634 pldm_bios_table_attr_entry_string_decode_def_string(
635 entry, defString.data(), defString.size());
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500636
637 std::stringstream stringtype;
638 stringtype << "0x" << std::hex << std::setw(2)
639 << std::setfill('0') << (int)strType << std::dec
640 << std::setw(0);
641 attrdata["StringType"] = stringtype.str();
642 attrdata["MinimumStringLength"] = (int)min;
643 attrdata["MaximumStringLength"] = (int)max;
644 attrdata["DefaultStringLength"] = (int)def;
645 attrdata["DefaultString"] = defString.data();
John Wangb754eee2020-02-15 16:10:25 +0800646 break;
647 }
648 case PLDM_BIOS_PASSWORD:
649 case PLDM_BIOS_PASSWORD_READ_ONLY:
650 std::cout << "Password attribute: Not Supported"
651 << std::endl;
652 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500653 output.emplace_back(std::move(attrdata));
John Wangb754eee2020-02-15 16:10:25 +0800654 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500655 pldmtool::helper::DisplayInJson(output);
John Wangb754eee2020-02-15 16:10:25 +0800656 }
657 void decodeAttributeValueTable(const std::optional<Table>& attrValTable,
658 const std::optional<Table>& attrTable,
659 const std::optional<Table>& stringTable)
660 {
John Wangb754eee2020-02-15 16:10:25 +0800661 if (!attrValTable)
662 {
663 std::cerr << "GetBIOSAttributeValueTable Error" << std::endl;
664 return;
665 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500666 ordered_json output;
John Wangb754eee2020-02-15 16:10:25 +0800667 for (auto tableEntry : BIOSTableIter<PLDM_BIOS_ATTR_VAL_TABLE>(
668 attrValTable->data(), attrValTable->size()))
669 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500670 ordered_json attrValueData;
671 displayAttributeValueEntry(tableEntry, attrTable, stringTable, true,
672 attrValueData);
673 output.emplace_back(attrValueData);
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600674 }
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500675 pldmtool::helper::DisplayInJson(output);
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600676 }
677};
678
Adair Li4dd11a72020-04-24 14:52:59 +0800679class GetBIOSAttributeCurrentValueByHandle : public GetBIOSTableHandler
680{
681 public:
682 ~GetBIOSAttributeCurrentValueByHandle() = default;
683 GetBIOSAttributeCurrentValueByHandle(
684 const GetBIOSAttributeCurrentValueByHandle&) = delete;
685 GetBIOSAttributeCurrentValueByHandle(
686 GetBIOSAttributeCurrentValueByHandle&&) = delete;
687 GetBIOSAttributeCurrentValueByHandle&
688 operator=(const GetBIOSAttributeCurrentValueByHandle&) = delete;
689 GetBIOSAttributeCurrentValueByHandle&
690 operator=(GetBIOSAttributeCurrentValueByHandle&&) = delete;
691
692 explicit GetBIOSAttributeCurrentValueByHandle(const char* type,
693 const char* name,
694 CLI::App* app) :
695 GetBIOSTableHandler(type, name, app)
696 {
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500697 app->add_option("-a, --attribute", attrName, "pldm BIOS attribute name")
Adair Li4dd11a72020-04-24 14:52:59 +0800698 ->required();
699 }
700
701 void exec()
702 {
703 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
704 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
705
706 if (!stringTable || !attrTable)
707 {
708 std::cout << "StringTable/AttrTable Unavaliable" << std::endl;
709 return;
710 }
711
712 auto handle = findAttrHandleByName(attrName, *attrTable, *stringTable);
John Wangcee24b62020-06-19 17:23:10 +0800713 if (!handle)
714 {
John Wangcee24b62020-06-19 17:23:10 +0800715 std::cerr << "Can not find the attribute " << attrName << std::endl;
716 return;
717 }
Adair Li4dd11a72020-04-24 14:52:59 +0800718
719 std::vector<uint8_t> requestMsg(
720 sizeof(pldm_msg_hdr) +
721 PLDM_GET_BIOS_ATTR_CURR_VAL_BY_HANDLE_REQ_BYTES);
722 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
723
724 auto rc = encode_get_bios_attribute_current_value_by_handle_req(
725 instanceId, 0, PLDM_GET_FIRSTPART, *handle, request);
726 if (rc != PLDM_SUCCESS)
727 {
728 std::cerr << "PLDM: Request Message Error, rc =" << rc << std::endl;
729 return;
730 }
731
732 std::vector<uint8_t> responseMsg;
733 rc = pldmSendRecv(requestMsg, responseMsg);
734 if (rc != PLDM_SUCCESS)
735 {
736 std::cerr << "PLDM: Communication Error, rc =" << rc << std::endl;
737 return;
738 }
739
740 uint8_t cc = 0, transferFlag = 0;
741 uint32_t nextTransferHandle = 0;
742 struct variable_field attributeData;
743 auto responsePtr =
744 reinterpret_cast<struct pldm_msg*>(responseMsg.data());
745 auto payloadLength = responseMsg.size() - sizeof(pldm_msg_hdr);
746
747 rc = decode_get_bios_attribute_current_value_by_handle_resp(
748 responsePtr, payloadLength, &cc, &nextTransferHandle, &transferFlag,
749 &attributeData);
750 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
751 {
752 std::cerr << "Response Message Error: "
753 << "rc=" << rc << ",cc=" << (int)cc << std::endl;
754 return;
755 }
756
757 auto tableEntry =
758 reinterpret_cast<const struct pldm_bios_attr_val_table_entry*>(
759 attributeData.ptr);
760
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500761 ordered_json avdata;
762 displayAttributeValueEntry(tableEntry, attrTable, stringTable, false,
763 avdata);
764 pldmtool::helper::DisplayInJson(avdata);
Adair Li4dd11a72020-04-24 14:52:59 +0800765 }
766
767 private:
768 std::string attrName;
769};
770
Adair Lice041e22020-05-09 17:27:43 +0800771class SetBIOSAttributeCurrentValue : public GetBIOSTableHandler
772{
773 public:
774 ~SetBIOSAttributeCurrentValue() = default;
775 SetBIOSAttributeCurrentValue() = delete;
776 SetBIOSAttributeCurrentValue(const SetBIOSAttributeCurrentValue&) = delete;
777 SetBIOSAttributeCurrentValue(SetBIOSAttributeCurrentValue&&) = default;
778 SetBIOSAttributeCurrentValue&
779 operator=(const SetBIOSAttributeCurrentValue&) = delete;
780 SetBIOSAttributeCurrentValue&
781 operator=(SetBIOSAttributeCurrentValue&&) = default;
782
783 explicit SetBIOSAttributeCurrentValue(const char* type, const char* name,
784 CLI::App* app) :
785 GetBIOSTableHandler(type, name, app)
786 {
787 app->add_option("-a, --attribute", attrName, "pldm attribute name")
788 ->required();
789 app->add_option("-d, --data", attrValue, "pldm attribute value")
790 ->required();
791 // -v is conflict with --verbose in class CommandInterface, so used -d
792 }
793
794 void exec()
795 {
796 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
797 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
798 auto attrValueTable = getBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE);
799
800 if (!stringTable || !attrTable)
801 {
802 std::cout << "StringTable/AttrTable Unavaliable" << std::endl;
803 return;
804 }
805
Patrick Williams6da4f912023-05-10 07:50:53 -0500806 auto attrEntry = findAttrEntryByName(attrName, *attrTable,
807 *stringTable);
Adair Lice041e22020-05-09 17:27:43 +0800808 if (attrEntry == nullptr)
809 {
810 std::cout << "Could not find attribute :" << attrName << std::endl;
811 return;
812 }
813
814 std::vector<uint8_t> requestMsg;
815
816 int rc = 0;
817 auto attrType = attrEntry->attr_type;
818 size_t entryLength = 1;
819 std::vector<uint8_t> attrValueEntry(entryLength, 0);
820
821 switch (attrType)
822 {
Adair Lice041e22020-05-09 17:27:43 +0800823 case PLDM_BIOS_ENUMERATION:
George Liu5bb9edb2021-08-05 20:10:32 +0800824 case PLDM_BIOS_ENUMERATION_READ_ONLY:
Adair Lice041e22020-05-09 17:27:43 +0800825 {
826 entryLength =
827 pldm_bios_table_attr_value_entry_encode_enum_length(1);
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930828 uint8_t pvNum;
829 // Preconditions are upheld therefore no error check necessary
830 pldm_bios_table_attr_entry_enum_decode_pv_num_check(attrEntry,
831 &pvNum);
Adair Lice041e22020-05-09 17:27:43 +0800832 std::vector<uint16_t> pvHdls(pvNum, 0);
Andrew Jeffery488f19d2023-06-13 20:43:39 +0930833 // Preconditions are upheld therefore no error check necessary
834 pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
Adair Lice041e22020-05-09 17:27:43 +0800835 attrEntry, pvHdls.data(), pvNum);
836 auto stringEntry = pldm_bios_table_string_find_by_string(
837 stringTable->data(), stringTable->size(),
838 attrValue.c_str());
839 if (stringEntry == nullptr)
840 {
841 std::cout
842 << "Set Attribute Error: It's not a possible value"
843 << std::endl;
844 return;
845 }
846 auto valueHandle =
847 pldm_bios_table_string_entry_decode_handle(stringEntry);
848
849 uint8_t i;
850 for (i = 0; i < pvNum; i++)
851 {
852 if (valueHandle == pvHdls[i])
853 break;
854 }
855 if (i == pvNum)
856 {
857 std::cout
858 << "Set Attribute Error: It's not a possible value"
859 << std::endl;
860 return;
861 }
862
863 attrValueEntry.resize(entryLength);
864 std::vector<uint8_t> handles = {i};
Andrew Jefferyd15ecf92023-06-27 15:57:22 +0930865 int rc = pldm_bios_table_attr_value_entry_encode_enum_check(
Adair Lice041e22020-05-09 17:27:43 +0800866 attrValueEntry.data(), attrValueEntry.size(),
867 attrEntry->attr_handle, attrType, 1, handles.data());
Andrew Jefferyd15ecf92023-06-27 15:57:22 +0930868 if (rc != PLDM_SUCCESS)
869 {
870 std::cout
871 << "Failed to encode BIOS table attribute enum: " << rc
872 << std::endl;
873 return;
874 }
Adair Lice041e22020-05-09 17:27:43 +0800875 break;
876 }
877 case PLDM_BIOS_STRING:
George Liu5bb9edb2021-08-05 20:10:32 +0800878 case PLDM_BIOS_STRING_READ_ONLY:
Adair Lice041e22020-05-09 17:27:43 +0800879 {
880 entryLength =
881 pldm_bios_table_attr_value_entry_encode_string_length(
882 attrValue.size());
883
884 attrValueEntry.resize(entryLength);
885
Andrew Jefferyd15ecf92023-06-27 15:57:22 +0930886 int rc = pldm_bios_table_attr_value_entry_encode_string_check(
Adair Lice041e22020-05-09 17:27:43 +0800887 attrValueEntry.data(), entryLength, attrEntry->attr_handle,
888 attrType, attrValue.size(), attrValue.c_str());
Andrew Jefferyd15ecf92023-06-27 15:57:22 +0930889 if (rc != PLDM_SUCCESS)
890 {
891 std::cout
892 << "Failed to encode BIOS table attribute string: "
893 << rc << std::endl;
894 return;
895 }
Adair Lice041e22020-05-09 17:27:43 +0800896 break;
897 }
898 case PLDM_BIOS_INTEGER:
George Liu5bb9edb2021-08-05 20:10:32 +0800899 case PLDM_BIOS_INTEGER_READ_ONLY:
Adair Lice041e22020-05-09 17:27:43 +0800900 {
901 uint64_t value = std::stoll(attrValue);
902 entryLength =
903 pldm_bios_table_attr_value_entry_encode_integer_length();
904 attrValueEntry.resize(entryLength);
905 pldm_bios_table_attr_value_entry_encode_integer(
906 attrValueEntry.data(), entryLength, attrEntry->attr_handle,
907 attrType, value);
908 break;
909 }
910 }
911
912 requestMsg.resize(entryLength + sizeof(pldm_msg_hdr) +
913 PLDM_SET_BIOS_ATTR_CURR_VAL_MIN_REQ_BYTES);
914
915 rc = encode_set_bios_attribute_current_value_req(
916 instanceId, 0, PLDM_START_AND_END, attrValueEntry.data(),
917 attrValueEntry.size(),
918 reinterpret_cast<pldm_msg*>(requestMsg.data()),
919 requestMsg.size() - sizeof(pldm_msg_hdr));
920
921 if (rc != PLDM_SUCCESS)
922 {
923 std::cerr << "PLDM: Request Message Error, rc =" << rc << std::endl;
924 return;
925 }
926 std::vector<uint8_t> responseMsg;
927 rc = pldmSendRecv(requestMsg, responseMsg);
928 if (rc != PLDM_SUCCESS)
929 {
930 std::cerr << "PLDM: Communication Error, rc =" << rc << std::endl;
931 return;
932 }
933 uint8_t cc = 0;
934 uint32_t nextTransferHandle = 0;
935 auto responsePtr =
936 reinterpret_cast<struct pldm_msg*>(responseMsg.data());
937 auto payloadLength = responseMsg.size() - sizeof(pldm_msg_hdr);
938
939 rc = decode_set_bios_attribute_current_value_resp(
940 responsePtr, payloadLength, &cc, &nextTransferHandle);
941 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
942 {
943 std::cerr << "Response Message Error: "
944 << "rc=" << rc << ",cc=" << (int)cc << std::endl;
945 return;
946 }
947
Sridevi Rameshca4a8152020-08-11 09:26:19 -0500948 ordered_json data;
949 data["Response"] = "SUCCESS";
950 pldmtool::helper::DisplayInJson(data);
Adair Lice041e22020-05-09 17:27:43 +0800951 }
952
953 private:
954 std::string attrName;
955 std::string attrValue;
956};
957
Sridevi Ramesh98576432019-11-27 10:10:28 -0600958void registerCommand(CLI::App& app)
959{
960 auto bios = app.add_subcommand("bios", "bios type command");
961 bios->require_subcommand(1);
962 auto getDateTime = bios->add_subcommand("GetDateTime", "get date time");
963 commands.push_back(
964 std::make_unique<GetDateTime>("bios", "GetDateTime", getDateTime));
George Liud6649362019-11-27 19:06:51 +0800965
Patrick Williams6da4f912023-05-10 07:50:53 -0500966 auto setDateTime = bios->add_subcommand("SetDateTime",
967 "set host date time");
George Liud6649362019-11-27 19:06:51 +0800968 commands.push_back(
969 std::make_unique<SetDateTime>("bios", "setDateTime", setDateTime));
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600970
971 auto getBIOSTable = bios->add_subcommand("GetBIOSTable", "get bios table");
972 commands.push_back(
973 std::make_unique<GetBIOSTable>("bios", "GetBIOSTable", getBIOSTable));
Adair Li4dd11a72020-04-24 14:52:59 +0800974
975 auto getBIOSAttributeCurrentValueByHandle =
976 bios->add_subcommand("GetBIOSAttributeCurrentValueByHandle",
977 "get bios attribute current value by handle");
978 commands.push_back(std::make_unique<GetBIOSAttributeCurrentValueByHandle>(
979 "bios", "GetBIOSAttributeCurrentValueByHandle",
980 getBIOSAttributeCurrentValueByHandle));
Adair Lice041e22020-05-09 17:27:43 +0800981
982 auto setBIOSAttributeCurrentValue = bios->add_subcommand(
983 "SetBIOSAttributeCurrentValue", "set bios attribute current value");
984 commands.push_back(std::make_unique<SetBIOSAttributeCurrentValue>(
985 "bios", "SetBIOSAttributeCurrentValue", setBIOSAttributeCurrentValue));
Sridevi Ramesh98576432019-11-27 10:10:28 -0600986}
987
988} // namespace bios
989
990} // namespace pldmtool