blob: afd34d839202c3989d15cfd88e422d73617a2b36 [file] [log] [blame]
Sridevi Ramesh98576432019-11-27 10:10:28 -06001#include "pldm_bios_cmd.hpp"
2
John Wangb754eee2020-02-15 16:10:25 +08003#include "bios_utils.hpp"
Sridevi Ramesh98576432019-11-27 10:10:28 -06004#include "pldm_cmd_helper.hpp"
John Wangb754eee2020-02-15 16:10:25 +08005#include "utils.hpp"
6
7#include <map>
8#include <optional>
Sridevi Ramesh98576432019-11-27 10:10:28 -06009
Sridevi Rameshcdfe1142020-01-31 05:42:50 -060010#include "libpldm/bios_table.h"
Sridevi Ramesh98576432019-11-27 10:10:28 -060011#include "libpldm/utils.h"
12
13namespace 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;
Sridevi Ramesh98576432019-11-27 10:10:28 -060024
25std::vector<std::unique_ptr<CommandInterface>> commands;
26
Sridevi Rameshcdfe1142020-01-31 05:42:50 -060027const std::map<const char*, pldm_bios_table_types> pldmBIOSTableTypes{
28 {"StringTable", PLDM_BIOS_STRING_TABLE},
29 {"AttributeTable", PLDM_BIOS_ATTR_TABLE},
30 {"AttributeValueTable", PLDM_BIOS_ATTR_VAL_TABLE},
31};
32
Sridevi Ramesh98576432019-11-27 10:10:28 -060033} // namespace
34
35class GetDateTime : public CommandInterface
36{
37 public:
38 ~GetDateTime() = default;
39 GetDateTime() = delete;
40 GetDateTime(const GetDateTime&) = delete;
41 GetDateTime(GetDateTime&&) = default;
42 GetDateTime& operator=(const GetDateTime&) = delete;
43 GetDateTime& operator=(GetDateTime&&) = default;
44
45 using CommandInterface::CommandInterface;
46
47 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
48 {
49 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr));
50 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
51
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -060052 auto rc = encode_get_date_time_req(instanceId, request);
Sridevi Ramesh98576432019-11-27 10:10:28 -060053 return {rc, requestMsg};
54 }
55
56 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
57 {
58 uint8_t cc = 0;
59
60 uint8_t seconds, minutes, hours, day, month;
61 uint16_t year;
62 auto rc =
63 decode_get_date_time_resp(responsePtr, payloadLength, &cc, &seconds,
64 &minutes, &hours, &day, &month, &year);
65 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
66 {
67 std::cerr << "Response Message Error: "
68 << "rc=" << rc << ",cc=" << (int)cc << std::endl;
69 return;
70 }
71 std::cout << "Date & Time : " << std::endl;
Sridevi Ramesh213a8552020-02-03 00:59:30 -060072 std::cout << "YYYY-MM-DD HH:MM:SS - ";
73 std::cout << bcd2dec16(year);
Sridevi Ramesh98576432019-11-27 10:10:28 -060074 std::cout << "-";
75 setWidth(month);
Sridevi Ramesh213a8552020-02-03 00:59:30 -060076 std::cout << "-";
77 setWidth(day);
78 std::cout << " ";
Sridevi Ramesh98576432019-11-27 10:10:28 -060079 setWidth(hours);
80 std::cout << ":";
81 setWidth(minutes);
82 std::cout << ":";
83 setWidth(seconds);
84 std::cout << std::endl;
85 }
86
87 private:
88 void setWidth(uint8_t data)
89 {
90 std::cout << std::setfill('0') << std::setw(2)
91 << static_cast<uint32_t>(bcd2dec8(data));
92 }
93};
94
George Liud6649362019-11-27 19:06:51 +080095class SetDateTime : public CommandInterface
96{
97 public:
98 ~SetDateTime() = default;
99 SetDateTime() = delete;
100 SetDateTime(const SetDateTime&) = delete;
101 SetDateTime(SetDateTime&&) = default;
102 SetDateTime& operator=(const SetDateTime&) = delete;
103 SetDateTime& operator=(SetDateTime&&) = default;
104
105 explicit SetDateTime(const char* type, const char* name, CLI::App* app) :
106 CommandInterface(type, name, app)
107 {
108 app->add_option("-d,--data", tmData,
109 "set date time data\n"
110 "eg: YYYYMMDDHHMMSS")
111 ->required();
112 }
113
114 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
115 {
116 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
117 sizeof(struct pldm_set_date_time_req));
118 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
119 uint16_t year = 0;
120 uint8_t month = 0;
121 uint8_t day = 0;
122 uint8_t hours = 0;
123 uint8_t minutes = 0;
124 uint8_t seconds = 0;
125
126 if (!uintToDate(tmData, &year, &month, &day, &hours, &minutes,
127 &seconds))
128 {
129 std::cerr << "decode date Error: "
130 << "tmData=" << tmData << std::endl;
131
132 return {PLDM_ERROR_INVALID_DATA, requestMsg};
133 }
134
135 auto rc = encode_set_date_time_req(
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600136 instanceId, seconds, minutes, hours, day, month, year, request,
137 sizeof(struct pldm_set_date_time_req));
George Liud6649362019-11-27 19:06:51 +0800138
139 return {rc, requestMsg};
140 }
141
142 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
143 {
144 uint8_t completionCode = 0;
145 auto rc = decode_set_date_time_resp(responsePtr, payloadLength,
146 &completionCode);
147
148 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
149 {
150 std::cerr << "Response Message Error: "
151 << "rc=" << rc << ",cc=" << (int)completionCode
152 << std::endl;
153 return;
154 }
155
156 std::cout << "SetDateTime: SUCCESS" << std::endl;
157 }
158
159 private:
160 uint64_t tmData;
161};
162
Adair Li4dd11a72020-04-24 14:52:59 +0800163class GetBIOSTableHandler : public CommandInterface
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600164{
165 public:
Adair Li4dd11a72020-04-24 14:52:59 +0800166 ~GetBIOSTableHandler() = default;
167 GetBIOSTableHandler() = delete;
168 GetBIOSTableHandler(const GetBIOSTableHandler&) = delete;
169 GetBIOSTableHandler(GetBIOSTableHandler&&) = delete;
170 GetBIOSTableHandler& operator=(const GetBIOSTableHandler&) = delete;
171 GetBIOSTableHandler& operator=(GetBIOSTableHandler&&) = delete;
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600172
John Wangb754eee2020-02-15 16:10:25 +0800173 using Table = std::vector<uint8_t>;
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600174
Adair Li4dd11a72020-04-24 14:52:59 +0800175 using CommandInterface::CommandInterface;
176
177 static inline const std::map<pldm_bios_attribute_type, const char*>
178 attrTypeMap = {
179 {PLDM_BIOS_ENUMERATION, "BIOSEnumeration"},
180 {PLDM_BIOS_ENUMERATION_READ_ONLY, "BIOSEnumerationReadOnly"},
181 {PLDM_BIOS_STRING, "BIOSString"},
182 {PLDM_BIOS_STRING_READ_ONLY, "BIOSStringReadOnly"},
183 {PLDM_BIOS_PASSWORD, "BIOSPassword"},
184 {PLDM_BIOS_PASSWORD_READ_ONLY, "BIOSPasswordReadOnly"},
185 {PLDM_BIOS_INTEGER, "BIOSInteger"},
186 {PLDM_BIOS_INTEGER_READ_ONLY, "BIOSIntegerReadOnly"},
187
188 };
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600189
190 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
191 {
John Wangb754eee2020-02-15 16:10:25 +0800192 return {PLDM_ERROR, {}};
193 }
Adair Li4dd11a72020-04-24 14:52:59 +0800194
John Wangb754eee2020-02-15 16:10:25 +0800195 void parseResponseMsg(pldm_msg*, size_t) override
196 {
197 }
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600198
John Wangb754eee2020-02-15 16:10:25 +0800199 std::optional<Table> getBIOSTable(pldm_bios_table_types tableType)
200 {
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600201 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
202 PLDM_GET_BIOS_TABLE_REQ_BYTES);
203 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
204
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -0600205 auto rc = encode_get_bios_table_req(instanceId, 0, PLDM_GET_FIRSTPART,
206 tableType, request);
John Wangb754eee2020-02-15 16:10:25 +0800207 if (rc != PLDM_SUCCESS)
208 {
209 std::cerr << "Encode GetBIOSTable Error, tableType=," << tableType
210 << " ,rc=" << rc << std::endl;
211 return std::nullopt;
212 }
213 std::vector<uint8_t> responseMsg;
214 rc = pldmSendRecv(requestMsg, responseMsg);
215 if (rc != PLDM_SUCCESS)
216 {
217 std::cerr << "PLDM: Communication Error, rc =" << rc << std::endl;
218 return std::nullopt;
219 }
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600220
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600221 uint8_t cc = 0, transferFlag = 0;
222 uint32_t nextTransferHandle = 0;
223 size_t bios_table_offset;
John Wangb754eee2020-02-15 16:10:25 +0800224 auto responsePtr =
225 reinterpret_cast<struct pldm_msg*>(responseMsg.data());
226 auto payloadLength = responseMsg.size() - sizeof(pldm_msg_hdr);
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600227
John Wangb754eee2020-02-15 16:10:25 +0800228 rc = decode_get_bios_table_resp(responsePtr, payloadLength, &cc,
229 &nextTransferHandle, &transferFlag,
230 &bios_table_offset);
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600231
232 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
233 {
John Wangb754eee2020-02-15 16:10:25 +0800234 std::cerr << "GetBIOSTable Response Error: tableType=" << tableType
235 << ", rc=" << rc << ", cc=" << (int)cc << std::endl;
236 return std::nullopt;
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600237 }
238 auto tableData =
239 reinterpret_cast<char*>((responsePtr->payload) + bios_table_offset);
John Wangb754eee2020-02-15 16:10:25 +0800240 auto tableSize = payloadLength - sizeof(nextTransferHandle) -
241 sizeof(transferFlag) - sizeof(cc);
242 return std::make_optional<Table>(tableData, tableData + tableSize);
243 }
244
Adair Lice041e22020-05-09 17:27:43 +0800245 const pldm_bios_attr_table_entry*
246 findAttrEntryByName(const std::string& name, const Table& attrTable,
247 const Table& stringTable)
John Wangb754eee2020-02-15 16:10:25 +0800248 {
Adair Li4dd11a72020-04-24 14:52:59 +0800249 auto stringEntry = pldm_bios_table_string_find_by_string(
250 stringTable.data(), stringTable.size(), name.c_str());
251 if (stringEntry == nullptr)
John Wangb754eee2020-02-15 16:10:25 +0800252 {
Adair Lice041e22020-05-09 17:27:43 +0800253 std::cout << "StringTable initialize failed" << std::endl;
254 return nullptr;
Adair Li4dd11a72020-04-24 14:52:59 +0800255 }
John Wangb754eee2020-02-15 16:10:25 +0800256
Adair Li4dd11a72020-04-24 14:52:59 +0800257 auto nameHandle =
258 pldm_bios_table_string_entry_decode_handle(stringEntry);
John Wangb754eee2020-02-15 16:10:25 +0800259
Adair Li4dd11a72020-04-24 14:52:59 +0800260 for (auto attr : BIOSTableIter<PLDM_BIOS_ATTR_TABLE>(attrTable.data(),
261 attrTable.size()))
262 {
263 auto attrNameHandle =
264 pldm_bios_table_attr_entry_decode_string_handle(attr);
265 if (attrNameHandle == nameHandle)
266 {
Adair Lice041e22020-05-09 17:27:43 +0800267 return attr;
John Wangb754eee2020-02-15 16:10:25 +0800268 }
269 }
Adair Lice041e22020-05-09 17:27:43 +0800270 return nullptr;
271 }
272
273 std::optional<uint16_t> findAttrHandleByName(const std::string& name,
274 const Table& attrTable,
275 const Table& stringTable)
276 {
277 auto attribute = findAttrEntryByName(name, attrTable, stringTable);
278 if (attribute == nullptr)
279 {
280 return std::nullopt;
281 }
282
283 return pldm_bios_table_attr_entry_decode_attribute_handle(attribute);
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600284 }
285
John Wangb754eee2020-02-15 16:10:25 +0800286 std::string decodeStringFromStringEntry(
287 const pldm_bios_string_table_entry* stringEntry)
288 {
289 auto strLength =
290 pldm_bios_table_string_entry_decode_string_length(stringEntry);
291 std::vector<char> buffer(strLength + 1 /* sizeof '\0' */);
292 pldm_bios_table_string_entry_decode_string(stringEntry, buffer.data(),
293 buffer.size());
294
295 return std::string(buffer.data(), buffer.data() + strLength);
296 }
297
298 std::string displayStringHandle(uint16_t handle,
Adair Li4dd11a72020-04-24 14:52:59 +0800299 const std::optional<Table>& stringTable,
300 bool displayHandle = true)
John Wangb754eee2020-02-15 16:10:25 +0800301 {
302 std::string displayString = std::to_string(handle);
303 if (!stringTable)
304 {
305 return displayString;
306 }
307 auto stringEntry = pldm_bios_table_string_find_by_handle(
308 stringTable->data(), stringTable->size(), handle);
309 if (stringEntry == nullptr)
310 {
311 return displayString;
312 }
313
Adair Li4dd11a72020-04-24 14:52:59 +0800314 auto decodedStr = decodeStringFromStringEntry(stringEntry);
315 if (!displayHandle)
316 {
317 return decodedStr;
318 }
319
320 return displayString + "(" + decodedStr + ")";
John Wangb754eee2020-02-15 16:10:25 +0800321 }
322
323 std::string displayEnumValueByIndex(uint16_t attrHandle, uint8_t index,
324 const std::optional<Table>& attrTable,
325 const std::optional<Table>& stringTable)
326 {
327 std::string displayString;
328 if (!attrTable)
329 {
330 return displayString;
331 }
332
333 auto attrEntry = pldm_bios_table_attr_find_by_handle(
334 attrTable->data(), attrTable->size(), attrHandle);
335 if (attrEntry == nullptr)
336 {
337 return displayString;
338 }
339 auto pvNum = pldm_bios_table_attr_entry_enum_decode_pv_num(attrEntry);
340 std::vector<uint16_t> pvHandls(pvNum);
341 pldm_bios_table_attr_entry_enum_decode_pv_hdls(
342 attrEntry, pvHandls.data(), pvHandls.size());
Adair Li4dd11a72020-04-24 14:52:59 +0800343 return displayStringHandle(pvHandls[index], stringTable, false);
John Wangb754eee2020-02-15 16:10:25 +0800344 }
345
Adair Li4dd11a72020-04-24 14:52:59 +0800346 void displayAttributeValueEntry(
347 const pldm_bios_attr_val_table_entry* tableEntry,
348 const std::optional<Table>& attrTable,
349 const std::optional<Table>& stringTable)
350 {
351 auto attrHandle =
352 pldm_bios_table_attr_value_entry_decode_attribute_handle(
353 tableEntry);
354 auto attrType = static_cast<pldm_bios_attribute_type>(
355 pldm_bios_table_attr_value_entry_decode_attribute_type(tableEntry));
356 switch (attrType)
357 {
358 case PLDM_BIOS_ENUMERATION:
359 case PLDM_BIOS_ENUMERATION_READ_ONLY:
360 {
361 auto count =
362 pldm_bios_table_attr_value_entry_enum_decode_number(
363 tableEntry);
364 std::vector<uint8_t> handles(count);
365 pldm_bios_table_attr_value_entry_enum_decode_handles(
366 tableEntry, handles.data(), handles.size());
367 for (size_t i = 0; i < handles.size(); i++)
368 {
369 std::cout << "CurrentValue: "
370 << displayEnumValueByIndex(attrHandle, handles[i],
371 attrTable, stringTable)
372 << std::endl;
373 }
374 break;
375 }
376 case PLDM_BIOS_INTEGER:
377 case PLDM_BIOS_INTEGER_READ_ONLY:
378 {
379 auto cv = pldm_bios_table_attr_value_entry_integer_decode_cv(
380 tableEntry);
381 std::cout << "CurrentValue: " << cv << std::endl;
382 break;
383 }
384 case PLDM_BIOS_STRING:
385 case PLDM_BIOS_STRING_READ_ONLY:
386 {
387 variable_field currentString;
388 pldm_bios_table_attr_value_entry_string_decode_string(
389 tableEntry, &currentString);
390 std::cout << "CurrentValue: "
391 << std::string(reinterpret_cast<const char*>(
392 currentString.ptr),
393 currentString.length)
394 << std::endl;
395
396 break;
397 }
398 case PLDM_BIOS_PASSWORD:
399 case PLDM_BIOS_PASSWORD_READ_ONLY:
400 {
401 std::cout << "Password attribute: Not Supported" << std::endl;
402 break;
403 }
404 }
405 }
406};
407
408class GetBIOSTable : public GetBIOSTableHandler
409{
410 public:
411 ~GetBIOSTable() = default;
412 GetBIOSTable() = delete;
413 GetBIOSTable(const GetBIOSTable&) = delete;
414 GetBIOSTable(GetBIOSTable&&) = default;
415 GetBIOSTable& operator=(const GetBIOSTable&) = delete;
416 GetBIOSTable& operator=(GetBIOSTable&&) = default;
417
418 using Table = std::vector<uint8_t>;
419
420 explicit GetBIOSTable(const char* type, const char* name, CLI::App* app) :
421 GetBIOSTableHandler(type, name, app)
422 {
423 app->add_option("-t,--type", pldmBIOSTableType, "pldm bios table type")
424 ->required()
425 ->transform(
426 CLI::CheckedTransformer(pldmBIOSTableTypes, CLI::ignore_case));
427 }
428
429 void exec() override
430 {
431 switch (pldmBIOSTableType)
432 {
433 case PLDM_BIOS_STRING_TABLE:
434 {
435 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
436 decodeStringTable(stringTable);
437 break;
438 }
439 case PLDM_BIOS_ATTR_TABLE:
440 {
441 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
442 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
443
444 decodeAttributeTable(attrTable, stringTable);
445 break;
446 }
447 case PLDM_BIOS_ATTR_VAL_TABLE:
448 {
449 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
450 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
451 auto attrValTable = getBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE);
452
453 decodeAttributeValueTable(attrValTable, attrTable, stringTable);
454 break;
455 }
456 }
457 }
458
459 private:
460 pldm_bios_table_types pldmBIOSTableType;
461
John Wangb754eee2020-02-15 16:10:25 +0800462 void decodeStringTable(const std::optional<Table>& stringTable)
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600463 {
John Wangb754eee2020-02-15 16:10:25 +0800464 if (!stringTable)
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600465 {
John Wangb754eee2020-02-15 16:10:25 +0800466 std::cerr << "GetBIOSStringTable Error" << std::endl;
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600467 return;
468 }
John Wangb754eee2020-02-15 16:10:25 +0800469 std::cout << "PLDM StringTable: " << std::endl;
470 std::cout << "BIOSStringHandle : BIOSString" << std::endl;
471
472 for (auto tableEntry : BIOSTableIter<PLDM_BIOS_STRING_TABLE>(
473 stringTable->data(), stringTable->size()))
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600474 {
John Wangb754eee2020-02-15 16:10:25 +0800475 auto strHandle =
476 pldm_bios_table_string_entry_decode_handle(tableEntry);
477 auto strTableData = decodeStringFromStringEntry(tableEntry);
478 std::cout << strHandle << " : " << strTableData << std::endl;
479 }
480 }
481 void decodeAttributeTable(const std::optional<Table>& attrTable,
482 const std::optional<Table>& stringTable)
483 {
John Wangb754eee2020-02-15 16:10:25 +0800484 if (!stringTable)
485 {
486 std::cerr << "GetBIOSAttributeTable Error" << std::endl;
487 return;
488 }
489 std::cout << "PLDM AttributeTable: " << std::endl;
490 for (auto entry : BIOSTableIter<PLDM_BIOS_ATTR_TABLE>(
491 attrTable->data(), attrTable->size()))
492 {
493 auto attrHandle =
494 pldm_bios_table_attr_entry_decode_attribute_handle(entry);
495 auto attrNameHandle =
496 pldm_bios_table_attr_entry_decode_string_handle(entry);
497 auto attrType = static_cast<pldm_bios_attribute_type>(
498 pldm_bios_table_attr_entry_decode_attribute_type(entry));
499 std::cout << "AttributeHandle: " << attrHandle
500 << ", AttributeNameHandle: "
501 << displayStringHandle(attrNameHandle, stringTable)
502 << std::endl;
503 std::cout << "\tAttributeType: " << attrTypeMap.at(attrType)
504 << std::endl;
505 switch (attrType)
506 {
507 case PLDM_BIOS_ENUMERATION:
508 case PLDM_BIOS_ENUMERATION_READ_ONLY:
509 {
510 auto pvNum =
511 pldm_bios_table_attr_entry_enum_decode_pv_num(entry);
512 std::vector<uint16_t> pvHandls(pvNum);
513 pldm_bios_table_attr_entry_enum_decode_pv_hdls(
514 entry, pvHandls.data(), pvHandls.size());
515 auto defNum =
516 pldm_bios_table_attr_entry_enum_decode_def_num(entry);
517 std::vector<uint8_t> defIndices(defNum);
518 pldm_bios_table_attr_entry_enum_decode_def_indices(
519 entry, defIndices.data(), defIndices.size());
520 std::cout << "\tNumberOfPossibleValues: " << (int)pvNum
521 << std::endl;
522
523 for (size_t i = 0; i < pvHandls.size(); i++)
524 {
525 std::cout
526 << "\t\tPossibleValueStringHandle"
527 << "[" << i << "] = "
528 << displayStringHandle(pvHandls[i], stringTable)
529 << std::endl;
530 }
531 std::cout << "\tNumberOfDefaultValues: " << (int)defNum
532 << std::endl;
533 for (size_t i = 0; i < defIndices.size(); i++)
534 {
535 std::cout << "\t\tDefaultValueStringHandleIndex"
536 << "[" << i << "] = " << (int)defIndices[i]
537 << ", StringHandle = "
538 << displayStringHandle(
539 pvHandls[defIndices[i]], stringTable)
540 << std::endl;
541 }
542 break;
543 }
544 case PLDM_BIOS_INTEGER:
545 case PLDM_BIOS_INTEGER_READ_ONLY:
546 {
547 uint64_t lower, upper, def;
548 uint32_t scalar;
549 pldm_bios_table_attr_entry_integer_decode(
550 entry, &lower, &upper, &scalar, &def);
551 std::cout << "\tLowerBound: " << lower << std::endl
552 << "\tUpperBound: " << upper << std::endl
553 << "\tScalarIncrement: " << scalar << std::endl
554 << "\tDefaultValue: " << def << std::endl;
555 break;
556 }
557 case PLDM_BIOS_STRING:
558 case PLDM_BIOS_STRING_READ_ONLY:
559 {
560 auto strType =
561 pldm_bios_table_attr_entry_string_decode_string_type(
562 entry);
563 auto min =
564 pldm_bios_table_attr_entry_string_decode_min_length(
565 entry);
566 auto max =
567 pldm_bios_table_attr_entry_string_decode_max_length(
568 entry);
569 auto def =
570 pldm_bios_table_attr_entry_string_decode_def_string_length(
571 entry);
572 std::vector<char> defString(def + 1);
573 pldm_bios_table_attr_entry_string_decode_def_string(
574 entry, defString.data(), defString.size());
575 std::cout
576 << "\tStringType: 0x" << std::hex << std::setw(2)
577 << std::setfill('0') << (int)strType << std::dec
578 << std::setw(0) << std::endl
579 << "\tMinimumStringLength: " << (int)min << std::endl
580 << "\tMaximumStringLength: " << (int)max << std::endl
581 << "\tDefaultStringLength: " << (int)def << std::endl
582 << "\tDefaultString: " << defString.data() << std::endl;
583 break;
584 }
585 case PLDM_BIOS_PASSWORD:
586 case PLDM_BIOS_PASSWORD_READ_ONLY:
587 std::cout << "Password attribute: Not Supported"
588 << std::endl;
589 }
590 }
591 }
592 void decodeAttributeValueTable(const std::optional<Table>& attrValTable,
593 const std::optional<Table>& attrTable,
594 const std::optional<Table>& stringTable)
595 {
John Wangb754eee2020-02-15 16:10:25 +0800596 if (!attrValTable)
597 {
598 std::cerr << "GetBIOSAttributeValueTable Error" << std::endl;
599 return;
600 }
601 std::cout << "PLDM AttributeValueTable: " << std::endl;
602 for (auto tableEntry : BIOSTableIter<PLDM_BIOS_ATTR_VAL_TABLE>(
603 attrValTable->data(), attrValTable->size()))
604 {
Adair Li4dd11a72020-04-24 14:52:59 +0800605 displayAttributeValueEntry(tableEntry, attrTable, stringTable);
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600606 }
607 }
608};
609
Adair Li4dd11a72020-04-24 14:52:59 +0800610class GetBIOSAttributeCurrentValueByHandle : public GetBIOSTableHandler
611{
612 public:
613 ~GetBIOSAttributeCurrentValueByHandle() = default;
614 GetBIOSAttributeCurrentValueByHandle(
615 const GetBIOSAttributeCurrentValueByHandle&) = delete;
616 GetBIOSAttributeCurrentValueByHandle(
617 GetBIOSAttributeCurrentValueByHandle&&) = delete;
618 GetBIOSAttributeCurrentValueByHandle&
619 operator=(const GetBIOSAttributeCurrentValueByHandle&) = delete;
620 GetBIOSAttributeCurrentValueByHandle&
621 operator=(GetBIOSAttributeCurrentValueByHandle&&) = delete;
622
623 explicit GetBIOSAttributeCurrentValueByHandle(const char* type,
624 const char* name,
625 CLI::App* app) :
626 GetBIOSTableHandler(type, name, app)
627 {
628 app->add_option("-a, --attribute", attrName, "pldm bios attribute name")
629 ->required();
630 }
631
632 void exec()
633 {
634 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
635 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
636
637 if (!stringTable || !attrTable)
638 {
639 std::cout << "StringTable/AttrTable Unavaliable" << std::endl;
640 return;
641 }
642
643 auto handle = findAttrHandleByName(attrName, *attrTable, *stringTable);
644
645 std::vector<uint8_t> requestMsg(
646 sizeof(pldm_msg_hdr) +
647 PLDM_GET_BIOS_ATTR_CURR_VAL_BY_HANDLE_REQ_BYTES);
648 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
649
650 auto rc = encode_get_bios_attribute_current_value_by_handle_req(
651 instanceId, 0, PLDM_GET_FIRSTPART, *handle, request);
652 if (rc != PLDM_SUCCESS)
653 {
654 std::cerr << "PLDM: Request Message Error, rc =" << rc << std::endl;
655 return;
656 }
657
658 std::vector<uint8_t> responseMsg;
659 rc = pldmSendRecv(requestMsg, responseMsg);
660 if (rc != PLDM_SUCCESS)
661 {
662 std::cerr << "PLDM: Communication Error, rc =" << rc << std::endl;
663 return;
664 }
665
666 uint8_t cc = 0, transferFlag = 0;
667 uint32_t nextTransferHandle = 0;
668 struct variable_field attributeData;
669 auto responsePtr =
670 reinterpret_cast<struct pldm_msg*>(responseMsg.data());
671 auto payloadLength = responseMsg.size() - sizeof(pldm_msg_hdr);
672
673 rc = decode_get_bios_attribute_current_value_by_handle_resp(
674 responsePtr, payloadLength, &cc, &nextTransferHandle, &transferFlag,
675 &attributeData);
676 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
677 {
678 std::cerr << "Response Message Error: "
679 << "rc=" << rc << ",cc=" << (int)cc << std::endl;
680 return;
681 }
682
683 auto tableEntry =
684 reinterpret_cast<const struct pldm_bios_attr_val_table_entry*>(
685 attributeData.ptr);
686
687 displayAttributeValueEntry(tableEntry, attrTable, stringTable);
688 }
689
690 private:
691 std::string attrName;
692};
693
Adair Lice041e22020-05-09 17:27:43 +0800694class SetBIOSAttributeCurrentValue : public GetBIOSTableHandler
695{
696 public:
697 ~SetBIOSAttributeCurrentValue() = default;
698 SetBIOSAttributeCurrentValue() = delete;
699 SetBIOSAttributeCurrentValue(const SetBIOSAttributeCurrentValue&) = delete;
700 SetBIOSAttributeCurrentValue(SetBIOSAttributeCurrentValue&&) = default;
701 SetBIOSAttributeCurrentValue&
702 operator=(const SetBIOSAttributeCurrentValue&) = delete;
703 SetBIOSAttributeCurrentValue&
704 operator=(SetBIOSAttributeCurrentValue&&) = default;
705
706 explicit SetBIOSAttributeCurrentValue(const char* type, const char* name,
707 CLI::App* app) :
708 GetBIOSTableHandler(type, name, app)
709 {
710 app->add_option("-a, --attribute", attrName, "pldm attribute name")
711 ->required();
712 app->add_option("-d, --data", attrValue, "pldm attribute value")
713 ->required();
714 // -v is conflict with --verbose in class CommandInterface, so used -d
715 }
716
717 void exec()
718 {
719 auto stringTable = getBIOSTable(PLDM_BIOS_STRING_TABLE);
720 auto attrTable = getBIOSTable(PLDM_BIOS_ATTR_TABLE);
721 auto attrValueTable = getBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE);
722
723 if (!stringTable || !attrTable)
724 {
725 std::cout << "StringTable/AttrTable Unavaliable" << std::endl;
726 return;
727 }
728
729 auto attrEntry =
730 findAttrEntryByName(attrName, *attrTable, *stringTable);
731 if (attrEntry == nullptr)
732 {
733 std::cout << "Could not find attribute :" << attrName << std::endl;
734 return;
735 }
736
737 std::vector<uint8_t> requestMsg;
738
739 int rc = 0;
740 auto attrType = attrEntry->attr_type;
741 size_t entryLength = 1;
742 std::vector<uint8_t> attrValueEntry(entryLength, 0);
743
744 switch (attrType)
745 {
746 case PLDM_BIOS_ENUMERATION_READ_ONLY:
747 case PLDM_BIOS_STRING_READ_ONLY:
748 case PLDM_BIOS_INTEGER_READ_ONLY:
749 {
750 std::cerr << "Set attribute error: " << attrName
751 << "is read only." << std::endl;
752 return;
753 }
754 case PLDM_BIOS_ENUMERATION:
755 {
756 entryLength =
757 pldm_bios_table_attr_value_entry_encode_enum_length(1);
758 auto pvNum =
759 pldm_bios_table_attr_entry_enum_decode_pv_num(attrEntry);
760 std::vector<uint16_t> pvHdls(pvNum, 0);
761 pldm_bios_table_attr_entry_enum_decode_pv_hdls(
762 attrEntry, pvHdls.data(), pvNum);
763 auto stringEntry = pldm_bios_table_string_find_by_string(
764 stringTable->data(), stringTable->size(),
765 attrValue.c_str());
766 if (stringEntry == nullptr)
767 {
768 std::cout
769 << "Set Attribute Error: It's not a possible value"
770 << std::endl;
771 return;
772 }
773 auto valueHandle =
774 pldm_bios_table_string_entry_decode_handle(stringEntry);
775
776 uint8_t i;
777 for (i = 0; i < pvNum; i++)
778 {
779 if (valueHandle == pvHdls[i])
780 break;
781 }
782 if (i == pvNum)
783 {
784 std::cout
785 << "Set Attribute Error: It's not a possible value"
786 << std::endl;
787 return;
788 }
789
790 attrValueEntry.resize(entryLength);
791 std::vector<uint8_t> handles = {i};
792 pldm_bios_table_attr_value_entry_encode_enum(
793 attrValueEntry.data(), attrValueEntry.size(),
794 attrEntry->attr_handle, attrType, 1, handles.data());
795 break;
796 }
797 case PLDM_BIOS_STRING:
798 {
799 entryLength =
800 pldm_bios_table_attr_value_entry_encode_string_length(
801 attrValue.size());
802
803 attrValueEntry.resize(entryLength);
804
805 pldm_bios_table_attr_value_entry_encode_string(
806 attrValueEntry.data(), entryLength, attrEntry->attr_handle,
807 attrType, attrValue.size(), attrValue.c_str());
808 break;
809 }
810 case PLDM_BIOS_INTEGER:
811 {
812 uint64_t value = std::stoll(attrValue);
813 entryLength =
814 pldm_bios_table_attr_value_entry_encode_integer_length();
815 attrValueEntry.resize(entryLength);
816 pldm_bios_table_attr_value_entry_encode_integer(
817 attrValueEntry.data(), entryLength, attrEntry->attr_handle,
818 attrType, value);
819 break;
820 }
821 }
822
823 requestMsg.resize(entryLength + sizeof(pldm_msg_hdr) +
824 PLDM_SET_BIOS_ATTR_CURR_VAL_MIN_REQ_BYTES);
825
826 rc = encode_set_bios_attribute_current_value_req(
827 instanceId, 0, PLDM_START_AND_END, attrValueEntry.data(),
828 attrValueEntry.size(),
829 reinterpret_cast<pldm_msg*>(requestMsg.data()),
830 requestMsg.size() - sizeof(pldm_msg_hdr));
831
832 if (rc != PLDM_SUCCESS)
833 {
834 std::cerr << "PLDM: Request Message Error, rc =" << rc << std::endl;
835 return;
836 }
837 std::vector<uint8_t> responseMsg;
838 rc = pldmSendRecv(requestMsg, responseMsg);
839 if (rc != PLDM_SUCCESS)
840 {
841 std::cerr << "PLDM: Communication Error, rc =" << rc << std::endl;
842 return;
843 }
844 uint8_t cc = 0;
845 uint32_t nextTransferHandle = 0;
846 auto responsePtr =
847 reinterpret_cast<struct pldm_msg*>(responseMsg.data());
848 auto payloadLength = responseMsg.size() - sizeof(pldm_msg_hdr);
849
850 rc = decode_set_bios_attribute_current_value_resp(
851 responsePtr, payloadLength, &cc, &nextTransferHandle);
852 if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
853 {
854 std::cerr << "Response Message Error: "
855 << "rc=" << rc << ",cc=" << (int)cc << std::endl;
856 return;
857 }
858
859 std::cout << "SetBIOSAttributeCurrentValue: SUCCESS" << std::endl;
860 }
861
862 private:
863 std::string attrName;
864 std::string attrValue;
865};
866
Sridevi Ramesh98576432019-11-27 10:10:28 -0600867void registerCommand(CLI::App& app)
868{
869 auto bios = app.add_subcommand("bios", "bios type command");
870 bios->require_subcommand(1);
871 auto getDateTime = bios->add_subcommand("GetDateTime", "get date time");
872 commands.push_back(
873 std::make_unique<GetDateTime>("bios", "GetDateTime", getDateTime));
George Liud6649362019-11-27 19:06:51 +0800874
875 auto setDateTime =
876 bios->add_subcommand("SetDateTime", "set host date time");
877 commands.push_back(
878 std::make_unique<SetDateTime>("bios", "setDateTime", setDateTime));
Sridevi Rameshcdfe1142020-01-31 05:42:50 -0600879
880 auto getBIOSTable = bios->add_subcommand("GetBIOSTable", "get bios table");
881 commands.push_back(
882 std::make_unique<GetBIOSTable>("bios", "GetBIOSTable", getBIOSTable));
Adair Li4dd11a72020-04-24 14:52:59 +0800883
884 auto getBIOSAttributeCurrentValueByHandle =
885 bios->add_subcommand("GetBIOSAttributeCurrentValueByHandle",
886 "get bios attribute current value by handle");
887 commands.push_back(std::make_unique<GetBIOSAttributeCurrentValueByHandle>(
888 "bios", "GetBIOSAttributeCurrentValueByHandle",
889 getBIOSAttributeCurrentValueByHandle));
Adair Lice041e22020-05-09 17:27:43 +0800890
891 auto setBIOSAttributeCurrentValue = bios->add_subcommand(
892 "SetBIOSAttributeCurrentValue", "set bios attribute current value");
893 commands.push_back(std::make_unique<SetBIOSAttributeCurrentValue>(
894 "bios", "SetBIOSAttributeCurrentValue", setBIOSAttributeCurrentValue));
Sridevi Ramesh98576432019-11-27 10:10:28 -0600895}
896
897} // namespace bios
898
899} // namespace pldmtool