1cb7f2d44SDeepak Kodihalli #include "bios_table.hpp"
2cb7f2d44SDeepak Kodihalli
3c453e164SGeorge Liu #include <libpldm/base.h>
4c453e164SGeorge Liu #include <libpldm/bios_table.h>
5c453e164SGeorge Liu #include <libpldm/utils.h>
6f719f3bfSJohn Wang
7488f19d0SAndrew Jeffery #include <phosphor-logging/lg2.hpp>
8488f19d0SAndrew Jeffery
96492f524SGeorge Liu #include <fstream>
106492f524SGeorge Liu
1189644441SRiya Dixit PHOSPHOR_LOG2_USING;
1289644441SRiya Dixit
13cb7f2d44SDeepak Kodihalli namespace pldm
14cb7f2d44SDeepak Kodihalli {
15cb7f2d44SDeepak Kodihalli namespace responder
16cb7f2d44SDeepak Kodihalli {
17cb7f2d44SDeepak Kodihalli namespace bios
18cb7f2d44SDeepak Kodihalli {
BIOSTable(const char * filePath)196da4f91bSPatrick Williams BIOSTable::BIOSTable(const char* filePath) : filePath(filePath) {}
20cb7f2d44SDeepak Kodihalli
isEmpty() const21cb7f2d44SDeepak Kodihalli bool BIOSTable::isEmpty() const noexcept
22cb7f2d44SDeepak Kodihalli {
23cb7f2d44SDeepak Kodihalli bool empty = false;
24cb7f2d44SDeepak Kodihalli try
25cb7f2d44SDeepak Kodihalli {
26cb7f2d44SDeepak Kodihalli empty = fs::is_empty(filePath);
27cb7f2d44SDeepak Kodihalli }
2858cbcaf2SKamalkumar Patel catch (const fs::filesystem_error&)
29cb7f2d44SDeepak Kodihalli {
30cb7f2d44SDeepak Kodihalli return true;
31cb7f2d44SDeepak Kodihalli }
32cb7f2d44SDeepak Kodihalli return empty;
33cb7f2d44SDeepak Kodihalli }
34cb7f2d44SDeepak Kodihalli
store(const Table & table)35cb7f2d44SDeepak Kodihalli void BIOSTable::store(const Table& table)
36cb7f2d44SDeepak Kodihalli {
37cb7f2d44SDeepak Kodihalli std::ofstream stream(filePath.string(), std::ios::out | std::ios::binary);
38cb7f2d44SDeepak Kodihalli stream.write(reinterpret_cast<const char*>(table.data()), table.size());
39cb7f2d44SDeepak Kodihalli }
40cb7f2d44SDeepak Kodihalli
load(Response & response) const41cb7f2d44SDeepak Kodihalli void BIOSTable::load(Response& response) const
42cb7f2d44SDeepak Kodihalli {
43cb7f2d44SDeepak Kodihalli auto currSize = response.size();
44cb7f2d44SDeepak Kodihalli auto fileSize = fs::file_size(filePath);
45cb7f2d44SDeepak Kodihalli response.resize(currSize + fileSize);
46cb7f2d44SDeepak Kodihalli std::ifstream stream(filePath.string(), std::ios::in | std::ios::binary);
47cb7f2d44SDeepak Kodihalli stream.read(reinterpret_cast<char*>(response.data() + currSize), fileSize);
48cb7f2d44SDeepak Kodihalli }
49cb7f2d44SDeepak Kodihalli
BIOSStringTable(const Table & stringTable)50e297b9f4SJohn Wang BIOSStringTable::BIOSStringTable(const Table& stringTable) :
51e297b9f4SJohn Wang stringTable(stringTable)
526492f524SGeorge Liu {}
53e297b9f4SJohn Wang
BIOSStringTable(const BIOSTable & biosTable)54e297b9f4SJohn Wang BIOSStringTable::BIOSStringTable(const BIOSTable& biosTable)
55e297b9f4SJohn Wang {
56e297b9f4SJohn Wang biosTable.load(stringTable);
57f719f3bfSJohn Wang }
58f719f3bfSJohn Wang
findString(uint16_t handle) const59f719f3bfSJohn Wang std::string BIOSStringTable::findString(uint16_t handle) const
60f719f3bfSJohn Wang {
61f719f3bfSJohn Wang auto stringEntry = pldm_bios_table_string_find_by_handle(
62f719f3bfSJohn Wang stringTable.data(), stringTable.size(), handle);
63f719f3bfSJohn Wang if (stringEntry == nullptr)
64f719f3bfSJohn Wang {
65f719f3bfSJohn Wang throw std::invalid_argument("Invalid String Handle");
66f719f3bfSJohn Wang }
6729683b53SJohn Wang return table::string::decodeString(stringEntry);
68f719f3bfSJohn Wang }
69f719f3bfSJohn Wang
findHandle(const std::string & name) const70e297b9f4SJohn Wang uint16_t BIOSStringTable::findHandle(const std::string& name) const
71e297b9f4SJohn Wang {
72e297b9f4SJohn Wang auto stringEntry = pldm_bios_table_string_find_by_string(
73e297b9f4SJohn Wang stringTable.data(), stringTable.size(), name.c_str());
74e297b9f4SJohn Wang if (stringEntry == nullptr)
75e297b9f4SJohn Wang {
76e297b9f4SJohn Wang throw std::invalid_argument("Invalid String Name");
77e297b9f4SJohn Wang }
78e297b9f4SJohn Wang
7929683b53SJohn Wang return table::string::decodeHandle(stringEntry);
80e2efdcceSJohn Wang }
81e2efdcceSJohn Wang
8229683b53SJohn Wang namespace table
8329683b53SJohn Wang {
appendPadAndChecksum(Table & table)84d965934fSJohn Wang void appendPadAndChecksum(Table& table)
85d965934fSJohn Wang {
86c43f2115SAndrew Jeffery size_t payloadSize = table.size();
87c43f2115SAndrew Jeffery table.resize(payloadSize + pldm_bios_table_pad_checksum_size(payloadSize));
88c43f2115SAndrew Jeffery // No validation of return value as preconditions are satisfied
890eb5bcefSAndrew Jeffery pldm_bios_table_append_pad_checksum(table.data(), table.size(),
90c43f2115SAndrew Jeffery &payloadSize);
91d965934fSJohn Wang }
92d965934fSJohn Wang
9329683b53SJohn Wang namespace string
9429683b53SJohn Wang {
decodeHandle(const pldm_bios_string_table_entry * entry)9529683b53SJohn Wang uint16_t decodeHandle(const pldm_bios_string_table_entry* entry)
96e2efdcceSJohn Wang {
97e2efdcceSJohn Wang return pldm_bios_table_string_entry_decode_handle(entry);
98e2efdcceSJohn Wang }
99e2efdcceSJohn Wang
decodeString(const pldm_bios_string_table_entry * entry)10029683b53SJohn Wang std::string decodeString(const pldm_bios_string_table_entry* entry)
101e2efdcceSJohn Wang {
102e2efdcceSJohn Wang auto strLength = pldm_bios_table_string_entry_decode_string_length(entry);
103e2efdcceSJohn Wang std::vector<char> buffer(strLength + 1 /* sizeof '\0' */);
104488f19d0SAndrew Jeffery // Preconditions are upheld therefore no error check necessary
105fe1189c1SAndrew Jeffery pldm_bios_table_string_entry_decode_string(entry, buffer.data(),
106e2efdcceSJohn Wang buffer.size());
107e2efdcceSJohn Wang return std::string(buffer.data(), buffer.data() + strLength);
108e297b9f4SJohn Wang }
constructEntry(Table & table,const std::string & str)109*366507c8SPatrick Williams const pldm_bios_string_table_entry* constructEntry(Table& table,
110*366507c8SPatrick Williams const std::string& str)
111d965934fSJohn Wang {
112d965934fSJohn Wang auto tableSize = table.size();
113d965934fSJohn Wang auto entryLength = pldm_bios_table_string_entry_encode_length(str.length());
114d965934fSJohn Wang table.resize(tableSize + entryLength);
115488f19d0SAndrew Jeffery // Preconditions are upheld therefore no error check necessary
11651d2ef27SAndrew Jeffery pldm_bios_table_string_entry_encode(table.data() + tableSize, entryLength,
11751d2ef27SAndrew Jeffery str.c_str(), str.length());
11816c2a0a0SPatrick Williams return reinterpret_cast<pldm_bios_string_table_entry*>(
11916c2a0a0SPatrick Williams table.data() + tableSize);
120d965934fSJohn Wang }
121e297b9f4SJohn Wang
12229683b53SJohn Wang } // namespace string
12329683b53SJohn Wang
12429683b53SJohn Wang namespace attribute
12529683b53SJohn Wang {
decodeHeader(const pldm_bios_attr_table_entry * entry)12629683b53SJohn Wang TableHeader decodeHeader(const pldm_bios_attr_table_entry* entry)
12729683b53SJohn Wang {
12829683b53SJohn Wang auto attrHandle = pldm_bios_table_attr_entry_decode_attribute_handle(entry);
12929683b53SJohn Wang auto attrType = pldm_bios_table_attr_entry_decode_attribute_type(entry);
13029683b53SJohn Wang auto stringHandle = pldm_bios_table_attr_entry_decode_string_handle(entry);
13129683b53SJohn Wang return {attrHandle, attrType, stringHandle};
13229683b53SJohn Wang }
13329683b53SJohn Wang
findByHandle(const Table & table,uint16_t handle)134*366507c8SPatrick Williams const pldm_bios_attr_table_entry* findByHandle(const Table& table,
135*366507c8SPatrick Williams uint16_t handle)
136d965934fSJohn Wang {
137d965934fSJohn Wang return pldm_bios_table_attr_find_by_handle(table.data(), table.size(),
138d965934fSJohn Wang handle);
139d965934fSJohn Wang }
140d965934fSJohn Wang
findByStringHandle(const Table & table,uint16_t handle)141*366507c8SPatrick Williams const pldm_bios_attr_table_entry* findByStringHandle(const Table& table,
142*366507c8SPatrick Williams uint16_t handle)
14345fed20fSJohn Wang {
14445fed20fSJohn Wang return pldm_bios_table_attr_find_by_string_handle(table.data(),
14545fed20fSJohn Wang table.size(), handle);
14645fed20fSJohn Wang }
14745fed20fSJohn Wang
constructStringEntry(Table & table,pldm_bios_table_attr_entry_string_info * info)14816c2a0a0SPatrick Williams const pldm_bios_attr_table_entry* constructStringEntry(
14916c2a0a0SPatrick Williams Table& table, pldm_bios_table_attr_entry_string_info* info)
15029683b53SJohn Wang {
15129683b53SJohn Wang auto entryLength =
15229683b53SJohn Wang pldm_bios_table_attr_entry_string_encode_length(info->def_length);
15329683b53SJohn Wang
15429683b53SJohn Wang auto tableSize = table.size();
15529683b53SJohn Wang table.resize(tableSize + entryLength, 0);
156bc28b91aSAndrew Jeffery int rc = pldm_bios_table_attr_entry_string_encode(table.data() + tableSize,
157bc28b91aSAndrew Jeffery entryLength, info);
158488f19d0SAndrew Jeffery if (rc != PLDM_SUCCESS)
159488f19d0SAndrew Jeffery {
16089644441SRiya Dixit error("Failed to encode BIOS table string entry, response code '{RC}'",
16189644441SRiya Dixit "RC", rc);
162488f19d0SAndrew Jeffery throw std::runtime_error("Failed to encode BIOS table string entry");
163488f19d0SAndrew Jeffery }
16416c2a0a0SPatrick Williams return reinterpret_cast<pldm_bios_attr_table_entry*>(
16516c2a0a0SPatrick Williams table.data() + tableSize);
16629683b53SJohn Wang }
16729683b53SJohn Wang
constructIntegerEntry(Table & table,pldm_bios_table_attr_entry_integer_info * info)16816c2a0a0SPatrick Williams const pldm_bios_attr_table_entry* constructIntegerEntry(
16916c2a0a0SPatrick Williams Table& table, pldm_bios_table_attr_entry_integer_info* info)
17095e6b3c1SJohn Wang {
17195e6b3c1SJohn Wang auto entryLength = pldm_bios_table_attr_entry_integer_encode_length();
17295e6b3c1SJohn Wang auto tableSize = table.size();
17395e6b3c1SJohn Wang table.resize(tableSize + entryLength, 0);
174228dae3eSAndrew Jeffery int rc = pldm_bios_table_attr_entry_integer_encode(table.data() + tableSize,
175228dae3eSAndrew Jeffery entryLength, info);
176d15ecf92SAndrew Jeffery if (rc != PLDM_SUCCESS)
177d15ecf92SAndrew Jeffery {
17889644441SRiya Dixit error(
17989644441SRiya Dixit "Failed to encode BIOS attribute table integer entry, response code '{RC}'",
18089644441SRiya Dixit "RC", rc);
181d15ecf92SAndrew Jeffery throw std::runtime_error(
182d15ecf92SAndrew Jeffery "Failed to encode BIOS attribute table integer entry");
183d15ecf92SAndrew Jeffery }
18416c2a0a0SPatrick Williams return reinterpret_cast<pldm_bios_attr_table_entry*>(
18516c2a0a0SPatrick Williams table.data() + tableSize);
18695e6b3c1SJohn Wang }
18795e6b3c1SJohn Wang
decodeStringEntry(const pldm_bios_attr_table_entry * entry)18829683b53SJohn Wang StringField decodeStringEntry(const pldm_bios_attr_table_entry* entry)
18929683b53SJohn Wang {
19029683b53SJohn Wang auto strType = pldm_bios_table_attr_entry_string_decode_string_type(entry);
19129683b53SJohn Wang auto minLength = pldm_bios_table_attr_entry_string_decode_min_length(entry);
19229683b53SJohn Wang auto maxLength = pldm_bios_table_attr_entry_string_decode_max_length(entry);
193488f19d0SAndrew Jeffery uint16_t defLength;
19453e342a2SAndrew Jeffery int rc = pldm_bios_table_attr_entry_string_decode_def_string_length(
195488f19d0SAndrew Jeffery entry, &defLength);
196488f19d0SAndrew Jeffery if (rc != PLDM_SUCCESS)
197488f19d0SAndrew Jeffery {
19889644441SRiya Dixit error(
19989644441SRiya Dixit "Failed to decode BIOS table string definition length, response code '{RC}'",
20089644441SRiya Dixit "RC", rc);
201488f19d0SAndrew Jeffery throw std::runtime_error(
202488f19d0SAndrew Jeffery "Failed to decode BIOS table string definitionlength");
203488f19d0SAndrew Jeffery }
20429683b53SJohn Wang
20529683b53SJohn Wang std::vector<char> buffer(defLength + 1);
20629683b53SJohn Wang pldm_bios_table_attr_entry_string_decode_def_string(entry, buffer.data(),
20729683b53SJohn Wang buffer.size());
20829683b53SJohn Wang return {strType, minLength, maxLength, defLength,
20929683b53SJohn Wang std::string(buffer.data(), buffer.data() + defLength)};
21029683b53SJohn Wang }
21129683b53SJohn Wang
decodeIntegerEntry(const pldm_bios_attr_table_entry * entry)21295e6b3c1SJohn Wang IntegerField decodeIntegerEntry(const pldm_bios_attr_table_entry* entry)
21395e6b3c1SJohn Wang {
21495e6b3c1SJohn Wang uint64_t lower, upper, def;
21595e6b3c1SJohn Wang uint32_t scalar;
21695e6b3c1SJohn Wang
21795e6b3c1SJohn Wang pldm_bios_table_attr_entry_integer_decode(entry, &lower, &upper, &scalar,
21895e6b3c1SJohn Wang &def);
21995e6b3c1SJohn Wang return {lower, upper, scalar, def};
22095e6b3c1SJohn Wang }
22195e6b3c1SJohn Wang
constructEnumEntry(Table & table,pldm_bios_table_attr_entry_enum_info * info)222*366507c8SPatrick Williams const pldm_bios_attr_table_entry* constructEnumEntry(
223*366507c8SPatrick Williams Table& table, pldm_bios_table_attr_entry_enum_info* info)
2243be7085eSJohn Wang {
2253be7085eSJohn Wang auto entryLength = pldm_bios_table_attr_entry_enum_encode_length(
2263be7085eSJohn Wang info->pv_num, info->def_num);
2273be7085eSJohn Wang
2283be7085eSJohn Wang auto tableSize = table.size();
2293be7085eSJohn Wang table.resize(tableSize + entryLength, 0);
230488f19d0SAndrew Jeffery // Preconditions are upheld therefore no error check necessary
23104883159SAndrew Jeffery pldm_bios_table_attr_entry_enum_encode(table.data() + tableSize,
2323be7085eSJohn Wang entryLength, info);
2333be7085eSJohn Wang
23416c2a0a0SPatrick Williams return reinterpret_cast<pldm_bios_attr_table_entry*>(
23516c2a0a0SPatrick Williams table.data() + tableSize);
2363be7085eSJohn Wang }
2373be7085eSJohn Wang
decodeEnumEntry(const pldm_bios_attr_table_entry * entry)2383be7085eSJohn Wang EnumField decodeEnumEntry(const pldm_bios_attr_table_entry* entry)
2393be7085eSJohn Wang {
240488f19d0SAndrew Jeffery uint8_t pvNum;
2418c05ca20SAndrew Jeffery int rc = pldm_bios_table_attr_entry_enum_decode_pv_num(entry, &pvNum);
242488f19d0SAndrew Jeffery if (rc != PLDM_SUCCESS)
243488f19d0SAndrew Jeffery {
24489644441SRiya Dixit error(
24589644441SRiya Dixit "Failed to decode the number of possible values for BIOS table enum entry, response code '{RC}'",
24689644441SRiya Dixit "RC", rc);
247488f19d0SAndrew Jeffery throw std::runtime_error(
248488f19d0SAndrew Jeffery "Failed to decode the number of possible values for BIOS table enum entry");
249488f19d0SAndrew Jeffery }
2503be7085eSJohn Wang std::vector<uint16_t> pvHdls(pvNum, 0);
251488f19d0SAndrew Jeffery // Preconditions are upheld therefore no error check necessary
2522461105eSAndrew Jeffery pldm_bios_table_attr_entry_enum_decode_pv_hdls(entry, pvHdls.data(), pvNum);
253488f19d0SAndrew Jeffery // Preconditions are upheld therefore no error check necessary
254488f19d0SAndrew Jeffery uint8_t defNum;
255ff3fb9ecSAndrew Jeffery pldm_bios_table_attr_entry_enum_decode_def_num(entry, &defNum);
2563be7085eSJohn Wang std::vector<uint8_t> defIndices(defNum, 0);
2573be7085eSJohn Wang pldm_bios_table_attr_entry_enum_decode_def_indices(entry, defIndices.data(),
2583be7085eSJohn Wang defIndices.size());
2593be7085eSJohn Wang return {pvHdls, defIndices};
2603be7085eSJohn Wang }
2613be7085eSJohn Wang
26229683b53SJohn Wang } // namespace attribute
26329683b53SJohn Wang
26429683b53SJohn Wang namespace attribute_value
26529683b53SJohn Wang {
decodeHeader(const pldm_bios_attr_val_table_entry * entry)26629683b53SJohn Wang TableHeader decodeHeader(const pldm_bios_attr_val_table_entry* entry)
26729683b53SJohn Wang {
26829683b53SJohn Wang auto handle =
26929683b53SJohn Wang pldm_bios_table_attr_value_entry_decode_attribute_handle(entry);
27029683b53SJohn Wang auto type = pldm_bios_table_attr_value_entry_decode_attribute_type(entry);
27129683b53SJohn Wang return {handle, type};
27229683b53SJohn Wang }
27329683b53SJohn Wang
decodeStringEntry(const pldm_bios_attr_val_table_entry * entry)27429683b53SJohn Wang std::string decodeStringEntry(const pldm_bios_attr_val_table_entry* entry)
27529683b53SJohn Wang {
27629683b53SJohn Wang variable_field currentString{};
27716c2a0a0SPatrick Williams pldm_bios_table_attr_value_entry_string_decode_string(
27816c2a0a0SPatrick Williams entry, ¤tString);
27929683b53SJohn Wang return std::string(currentString.ptr,
28029683b53SJohn Wang currentString.ptr + currentString.length);
28129683b53SJohn Wang }
28229683b53SJohn Wang
decodeIntegerEntry(const pldm_bios_attr_val_table_entry * entry)28395e6b3c1SJohn Wang uint64_t decodeIntegerEntry(const pldm_bios_attr_val_table_entry* entry)
28495e6b3c1SJohn Wang {
28595e6b3c1SJohn Wang return pldm_bios_table_attr_value_entry_integer_decode_cv(entry);
28695e6b3c1SJohn Wang }
28795e6b3c1SJohn Wang
decodeEnumEntry(const pldm_bios_attr_val_table_entry * entry)288*366507c8SPatrick Williams std::vector<uint8_t> decodeEnumEntry(
289*366507c8SPatrick Williams const pldm_bios_attr_val_table_entry* entry)
2903be7085eSJohn Wang {
2913be7085eSJohn Wang auto number = pldm_bios_table_attr_value_entry_enum_decode_number(entry);
2923be7085eSJohn Wang std::vector<uint8_t> currHdls(number, 0);
2933be7085eSJohn Wang pldm_bios_table_attr_value_entry_enum_decode_handles(entry, currHdls.data(),
2943be7085eSJohn Wang currHdls.size());
2953be7085eSJohn Wang return currHdls;
2963be7085eSJohn Wang }
2973be7085eSJohn Wang
constructStringEntry(Table & table,uint16_t attrHandle,uint8_t attrType,const std::string & str)29816c2a0a0SPatrick Williams const pldm_bios_attr_val_table_entry* constructStringEntry(
29916c2a0a0SPatrick Williams Table& table, uint16_t attrHandle, uint8_t attrType, const std::string& str)
30029683b53SJohn Wang {
30129683b53SJohn Wang auto strLen = str.size();
30229683b53SJohn Wang auto entryLength =
30329683b53SJohn Wang pldm_bios_table_attr_value_entry_encode_string_length(strLen);
30429683b53SJohn Wang auto tableSize = table.size();
30529683b53SJohn Wang table.resize(tableSize + entryLength);
30625d38789SAndrew Jeffery int rc = pldm_bios_table_attr_value_entry_encode_string(
30729683b53SJohn Wang table.data() + tableSize, entryLength, attrHandle, attrType, strLen,
30829683b53SJohn Wang str.c_str());
309d15ecf92SAndrew Jeffery if (rc != PLDM_SUCCESS)
310d15ecf92SAndrew Jeffery {
31189644441SRiya Dixit error(
31289644441SRiya Dixit "Failed to encode BIOS attribute table string entry, response code '{RC}'",
31389644441SRiya Dixit "RC", rc);
314d15ecf92SAndrew Jeffery throw std::runtime_error(
315d15ecf92SAndrew Jeffery "Failed to encode BIOS attribute table string entry");
316d15ecf92SAndrew Jeffery }
31716c2a0a0SPatrick Williams return reinterpret_cast<pldm_bios_attr_val_table_entry*>(
31816c2a0a0SPatrick Williams table.data() + tableSize);
31929683b53SJohn Wang }
32095e6b3c1SJohn Wang
constructIntegerEntry(Table & table,uint16_t attrHandle,uint8_t attrType,uint64_t value)32116c2a0a0SPatrick Williams const pldm_bios_attr_val_table_entry* constructIntegerEntry(
32216c2a0a0SPatrick Williams Table& table, uint16_t attrHandle, uint8_t attrType, uint64_t value)
32395e6b3c1SJohn Wang {
32495e6b3c1SJohn Wang auto entryLength = pldm_bios_table_attr_value_entry_encode_integer_length();
32595e6b3c1SJohn Wang
32695e6b3c1SJohn Wang auto tableSize = table.size();
32795e6b3c1SJohn Wang table.resize(tableSize + entryLength);
328a5f2fcdbSAndrew Jeffery int rc = pldm_bios_table_attr_value_entry_encode_integer(
32995e6b3c1SJohn Wang table.data() + tableSize, entryLength, attrHandle, attrType, value);
330c727fb40SAndrew Jeffery if (rc != PLDM_SUCCESS)
331c727fb40SAndrew Jeffery {
33289644441SRiya Dixit error(
33389644441SRiya Dixit "Failed to encode BIOS attribute table integer entry, response code '{RC}'",
33489644441SRiya Dixit "RC", rc);
335c727fb40SAndrew Jeffery throw std::runtime_error(
336c727fb40SAndrew Jeffery "Failed to encode BIOS attribute table integery entry");
337c727fb40SAndrew Jeffery }
33816c2a0a0SPatrick Williams return reinterpret_cast<pldm_bios_attr_val_table_entry*>(
33916c2a0a0SPatrick Williams table.data() + tableSize);
34095e6b3c1SJohn Wang }
34195e6b3c1SJohn Wang
constructEnumEntry(Table & table,uint16_t attrHandle,uint8_t attrType,const std::vector<uint8_t> & handleIndices)342*366507c8SPatrick Williams const pldm_bios_attr_val_table_entry* constructEnumEntry(
343*366507c8SPatrick Williams Table& table, uint16_t attrHandle, uint8_t attrType,
3443be7085eSJohn Wang const std::vector<uint8_t>& handleIndices)
3453be7085eSJohn Wang {
3463be7085eSJohn Wang auto entryLength = pldm_bios_table_attr_value_entry_encode_enum_length(
3473be7085eSJohn Wang handleIndices.size());
3483be7085eSJohn Wang auto tableSize = table.size();
3493be7085eSJohn Wang table.resize(tableSize + entryLength);
3504663aaedSAndrew Jeffery int rc = pldm_bios_table_attr_value_entry_encode_enum(
3513be7085eSJohn Wang table.data() + tableSize, entryLength, attrHandle, attrType,
3523be7085eSJohn Wang handleIndices.size(), handleIndices.data());
353d15ecf92SAndrew Jeffery if (rc != PLDM_SUCCESS)
354d15ecf92SAndrew Jeffery {
35589644441SRiya Dixit error(
35689644441SRiya Dixit "Failed to encode BIOS attribute table enum entry, response code '{RC}'",
35789644441SRiya Dixit "RC", rc);
358d15ecf92SAndrew Jeffery throw std::runtime_error(
359d15ecf92SAndrew Jeffery "Failed to encode BIOS attribute table enum entry");
360d15ecf92SAndrew Jeffery }
36116c2a0a0SPatrick Williams return reinterpret_cast<pldm_bios_attr_val_table_entry*>(
36216c2a0a0SPatrick Williams table.data() + tableSize);
3633be7085eSJohn Wang }
3643be7085eSJohn Wang
updateTable(const Table & table,const void * entry,size_t size)365d965934fSJohn Wang std::optional<Table> updateTable(const Table& table, const void* entry,
366d965934fSJohn Wang size_t size)
367d965934fSJohn Wang {
368d965934fSJohn Wang // Replace the old attribute with the new attribute, the size of table will
369d965934fSJohn Wang // change:
370d965934fSJohn Wang // sizeof(newTableBuffer) = srcTableSize + sizeof(newAttribute) -
371d965934fSJohn Wang // sizeof(oldAttribute) + pad(4-byte alignment, max =
372d965934fSJohn Wang // 3)
373d965934fSJohn Wang // For simplicity, we use
374d965934fSJohn Wang // sizeof(newTableBuffer) = srcTableSize + sizeof(newAttribute) + 3
375d965934fSJohn Wang size_t destBufferLength = table.size() + size + 3;
376d965934fSJohn Wang Table destTable(destBufferLength);
377d965934fSJohn Wang
378d965934fSJohn Wang auto rc = pldm_bios_table_attr_value_copy_and_update(
379d965934fSJohn Wang table.data(), table.size(), destTable.data(), &destBufferLength, entry,
380d965934fSJohn Wang size);
381d965934fSJohn Wang if (rc != PLDM_SUCCESS)
382d965934fSJohn Wang {
383d965934fSJohn Wang return std::nullopt;
384d965934fSJohn Wang }
385d965934fSJohn Wang destTable.resize(destBufferLength);
386d965934fSJohn Wang
387d965934fSJohn Wang return destTable;
388d965934fSJohn Wang }
38929683b53SJohn Wang
39029683b53SJohn Wang } // namespace attribute_value
39129683b53SJohn Wang
39229683b53SJohn Wang } // namespace table
39329683b53SJohn Wang
394cb7f2d44SDeepak Kodihalli } // namespace bios
395cb7f2d44SDeepak Kodihalli } // namespace responder
396cb7f2d44SDeepak Kodihalli } // namespace pldm
397