blob: 5cfd372a262c52cceb43a7aefc9927aca7f88386 [file] [log] [blame]
Deepak Kodihallicb7f2d42019-06-19 13:25:31 +05301#include "bios_table.hpp"
2
George Liuc453e162022-12-21 17:16:23 +08003#include <libpldm/base.h>
4#include <libpldm/bios_table.h>
5#include <libpldm/utils.h>
John Wangf719f3b2020-01-17 08:46:22 +08006
George Liu6492f522020-06-16 10:34:05 +08007#include <fstream>
8
Deepak Kodihallicb7f2d42019-06-19 13:25:31 +05309namespace pldm
10{
Deepak Kodihallicb7f2d42019-06-19 13:25:31 +053011namespace responder
12{
Deepak Kodihallicb7f2d42019-06-19 13:25:31 +053013namespace bios
14{
Patrick Williams6da4f912023-05-10 07:50:53 -050015BIOSTable::BIOSTable(const char* filePath) : filePath(filePath) {}
Deepak Kodihallicb7f2d42019-06-19 13:25:31 +053016
17bool BIOSTable::isEmpty() const noexcept
18{
19 bool empty = false;
20 try
21 {
22 empty = fs::is_empty(filePath);
23 }
Patrick Williams51330582021-10-06 12:48:56 -050024 catch (const fs::filesystem_error& e)
Deepak Kodihallicb7f2d42019-06-19 13:25:31 +053025 {
26 return true;
27 }
28 return empty;
29}
30
31void BIOSTable::store(const Table& table)
32{
33 std::ofstream stream(filePath.string(), std::ios::out | std::ios::binary);
34 stream.write(reinterpret_cast<const char*>(table.data()), table.size());
35}
36
37void BIOSTable::load(Response& response) const
38{
39 auto currSize = response.size();
40 auto fileSize = fs::file_size(filePath);
41 response.resize(currSize + fileSize);
42 std::ifstream stream(filePath.string(), std::ios::in | std::ios::binary);
43 stream.read(reinterpret_cast<char*>(response.data() + currSize), fileSize);
44}
45
John Wange297b9f2020-02-03 10:18:13 +080046BIOSStringTable::BIOSStringTable(const Table& stringTable) :
47 stringTable(stringTable)
George Liu6492f522020-06-16 10:34:05 +080048{}
John Wange297b9f2020-02-03 10:18:13 +080049
50BIOSStringTable::BIOSStringTable(const BIOSTable& biosTable)
51{
52 biosTable.load(stringTable);
John Wangf719f3b2020-01-17 08:46:22 +080053}
54
55std::string BIOSStringTable::findString(uint16_t handle) const
56{
57 auto stringEntry = pldm_bios_table_string_find_by_handle(
58 stringTable.data(), stringTable.size(), handle);
59 if (stringEntry == nullptr)
60 {
61 throw std::invalid_argument("Invalid String Handle");
62 }
John Wang29683b52020-02-27 16:41:44 +080063 return table::string::decodeString(stringEntry);
John Wangf719f3b2020-01-17 08:46:22 +080064}
65
John Wange297b9f2020-02-03 10:18:13 +080066uint16_t BIOSStringTable::findHandle(const std::string& name) const
67{
68 auto stringEntry = pldm_bios_table_string_find_by_string(
69 stringTable.data(), stringTable.size(), name.c_str());
70 if (stringEntry == nullptr)
71 {
72 throw std::invalid_argument("Invalid String Name");
73 }
74
John Wang29683b52020-02-27 16:41:44 +080075 return table::string::decodeHandle(stringEntry);
John Wange2efdcc2020-02-12 17:02:06 +080076}
77
John Wang29683b52020-02-27 16:41:44 +080078namespace table
79{
John Wangd9659342020-02-27 16:46:05 +080080void appendPadAndChecksum(Table& table)
81{
82 auto sizeWithoutPad = table.size();
83 auto padAndChecksumSize = pldm_bios_table_pad_checksum_size(sizeWithoutPad);
84 table.resize(table.size() + padAndChecksumSize);
85
86 pldm_bios_table_append_pad_checksum(table.data(), table.size(),
87 sizeWithoutPad);
88}
89
John Wang29683b52020-02-27 16:41:44 +080090namespace string
91{
John Wang29683b52020-02-27 16:41:44 +080092uint16_t decodeHandle(const pldm_bios_string_table_entry* entry)
John Wange2efdcc2020-02-12 17:02:06 +080093{
94 return pldm_bios_table_string_entry_decode_handle(entry);
95}
96
John Wang29683b52020-02-27 16:41:44 +080097std::string decodeString(const pldm_bios_string_table_entry* entry)
John Wange2efdcc2020-02-12 17:02:06 +080098{
99 auto strLength = pldm_bios_table_string_entry_decode_string_length(entry);
100 std::vector<char> buffer(strLength + 1 /* sizeof '\0' */);
101 pldm_bios_table_string_entry_decode_string(entry, buffer.data(),
102 buffer.size());
103 return std::string(buffer.data(), buffer.data() + strLength);
John Wange297b9f2020-02-03 10:18:13 +0800104}
John Wangd9659342020-02-27 16:46:05 +0800105const pldm_bios_string_table_entry* constructEntry(Table& table,
106 const std::string& str)
107{
108 auto tableSize = table.size();
109 auto entryLength = pldm_bios_table_string_entry_encode_length(str.length());
110 table.resize(tableSize + entryLength);
111 pldm_bios_table_string_entry_encode(table.data() + tableSize, entryLength,
112 str.c_str(), str.length());
113 return reinterpret_cast<pldm_bios_string_table_entry*>(table.data() +
114 tableSize);
115}
John Wange297b9f2020-02-03 10:18:13 +0800116
John Wang29683b52020-02-27 16:41:44 +0800117} // namespace string
118
119namespace attribute
120{
John Wang29683b52020-02-27 16:41:44 +0800121TableHeader decodeHeader(const pldm_bios_attr_table_entry* entry)
122{
123 auto attrHandle = pldm_bios_table_attr_entry_decode_attribute_handle(entry);
124 auto attrType = pldm_bios_table_attr_entry_decode_attribute_type(entry);
125 auto stringHandle = pldm_bios_table_attr_entry_decode_string_handle(entry);
126 return {attrHandle, attrType, stringHandle};
127}
128
John Wangd9659342020-02-27 16:46:05 +0800129const pldm_bios_attr_table_entry* findByHandle(const Table& table,
130 uint16_t handle)
131{
132 return pldm_bios_table_attr_find_by_handle(table.data(), table.size(),
133 handle);
134}
135
John Wang45fed202020-04-01 16:42:26 +0800136const pldm_bios_attr_table_entry* findByStringHandle(const Table& table,
137 uint16_t handle)
138{
139 return pldm_bios_table_attr_find_by_string_handle(table.data(),
140 table.size(), handle);
141}
142
John Wang29683b52020-02-27 16:41:44 +0800143const pldm_bios_attr_table_entry*
144 constructStringEntry(Table& table,
145 pldm_bios_table_attr_entry_string_info* info)
146{
147 auto entryLength =
148 pldm_bios_table_attr_entry_string_encode_length(info->def_length);
149
150 auto tableSize = table.size();
151 table.resize(tableSize + entryLength, 0);
152 pldm_bios_table_attr_entry_string_encode(table.data() + tableSize,
153 entryLength, info);
154 return reinterpret_cast<pldm_bios_attr_table_entry*>(table.data() +
155 tableSize);
156}
157
John Wang95e6b3c2020-02-13 09:43:24 +0800158const pldm_bios_attr_table_entry*
159 constructIntegerEntry(Table& table,
160 pldm_bios_table_attr_entry_integer_info* info)
161{
162 auto entryLength = pldm_bios_table_attr_entry_integer_encode_length();
163 auto tableSize = table.size();
164 table.resize(tableSize + entryLength, 0);
165 pldm_bios_table_attr_entry_integer_encode(table.data() + tableSize,
166 entryLength, info);
167 return reinterpret_cast<pldm_bios_attr_table_entry*>(table.data() +
168 tableSize);
169}
170
John Wang29683b52020-02-27 16:41:44 +0800171StringField decodeStringEntry(const pldm_bios_attr_table_entry* entry)
172{
173 auto strType = pldm_bios_table_attr_entry_string_decode_string_type(entry);
174 auto minLength = pldm_bios_table_attr_entry_string_decode_min_length(entry);
175 auto maxLength = pldm_bios_table_attr_entry_string_decode_max_length(entry);
176 auto defLength =
177 pldm_bios_table_attr_entry_string_decode_def_string_length(entry);
178
179 std::vector<char> buffer(defLength + 1);
180 pldm_bios_table_attr_entry_string_decode_def_string(entry, buffer.data(),
181 buffer.size());
182 return {strType, minLength, maxLength, defLength,
183 std::string(buffer.data(), buffer.data() + defLength)};
184}
185
John Wang95e6b3c2020-02-13 09:43:24 +0800186IntegerField decodeIntegerEntry(const pldm_bios_attr_table_entry* entry)
187{
188 uint64_t lower, upper, def;
189 uint32_t scalar;
190
191 pldm_bios_table_attr_entry_integer_decode(entry, &lower, &upper, &scalar,
192 &def);
193 return {lower, upper, scalar, def};
194}
195
John Wang3be70852020-02-13 15:59:04 +0800196const pldm_bios_attr_table_entry*
197 constructEnumEntry(Table& table, pldm_bios_table_attr_entry_enum_info* info)
198{
199 auto entryLength = pldm_bios_table_attr_entry_enum_encode_length(
200 info->pv_num, info->def_num);
201
202 auto tableSize = table.size();
203 table.resize(tableSize + entryLength, 0);
204 pldm_bios_table_attr_entry_enum_encode(table.data() + tableSize,
205 entryLength, info);
206
207 return reinterpret_cast<pldm_bios_attr_table_entry*>(table.data() +
208 tableSize);
209}
210
211EnumField decodeEnumEntry(const pldm_bios_attr_table_entry* entry)
212{
213 uint8_t pvNum = pldm_bios_table_attr_entry_enum_decode_pv_num(entry);
214 std::vector<uint16_t> pvHdls(pvNum, 0);
215 pldm_bios_table_attr_entry_enum_decode_pv_hdls(entry, pvHdls.data(), pvNum);
216 auto defNum = pldm_bios_table_attr_entry_enum_decode_def_num(entry);
217 std::vector<uint8_t> defIndices(defNum, 0);
218 pldm_bios_table_attr_entry_enum_decode_def_indices(entry, defIndices.data(),
219 defIndices.size());
220 return {pvHdls, defIndices};
221}
222
John Wang29683b52020-02-27 16:41:44 +0800223} // namespace attribute
224
225namespace attribute_value
226{
John Wang29683b52020-02-27 16:41:44 +0800227TableHeader decodeHeader(const pldm_bios_attr_val_table_entry* entry)
228{
229 auto handle =
230 pldm_bios_table_attr_value_entry_decode_attribute_handle(entry);
231 auto type = pldm_bios_table_attr_value_entry_decode_attribute_type(entry);
232 return {handle, type};
233}
234
235std::string decodeStringEntry(const pldm_bios_attr_val_table_entry* entry)
236{
237 variable_field currentString{};
238 pldm_bios_table_attr_value_entry_string_decode_string(entry,
239 &currentString);
240 return std::string(currentString.ptr,
241 currentString.ptr + currentString.length);
242}
243
John Wang95e6b3c2020-02-13 09:43:24 +0800244uint64_t decodeIntegerEntry(const pldm_bios_attr_val_table_entry* entry)
245{
246 return pldm_bios_table_attr_value_entry_integer_decode_cv(entry);
247}
248
John Wang3be70852020-02-13 15:59:04 +0800249std::vector<uint8_t>
250 decodeEnumEntry(const pldm_bios_attr_val_table_entry* entry)
251{
252 auto number = pldm_bios_table_attr_value_entry_enum_decode_number(entry);
253 std::vector<uint8_t> currHdls(number, 0);
254 pldm_bios_table_attr_value_entry_enum_decode_handles(entry, currHdls.data(),
255 currHdls.size());
256 return currHdls;
257}
258
John Wang29683b52020-02-27 16:41:44 +0800259const pldm_bios_attr_val_table_entry*
260 constructStringEntry(Table& table, uint16_t attrHandle, uint8_t attrType,
261 const std::string& str)
262{
263 auto strLen = str.size();
264 auto entryLength =
265 pldm_bios_table_attr_value_entry_encode_string_length(strLen);
266 auto tableSize = table.size();
267 table.resize(tableSize + entryLength);
268 pldm_bios_table_attr_value_entry_encode_string(
269 table.data() + tableSize, entryLength, attrHandle, attrType, strLen,
270 str.c_str());
271 return reinterpret_cast<pldm_bios_attr_val_table_entry*>(table.data() +
272 tableSize);
273}
John Wang95e6b3c2020-02-13 09:43:24 +0800274
275const pldm_bios_attr_val_table_entry* constructIntegerEntry(Table& table,
276 uint16_t attrHandle,
277 uint8_t attrType,
278 uint64_t value)
279{
280 auto entryLength = pldm_bios_table_attr_value_entry_encode_integer_length();
281
282 auto tableSize = table.size();
283 table.resize(tableSize + entryLength);
284 pldm_bios_table_attr_value_entry_encode_integer(
285 table.data() + tableSize, entryLength, attrHandle, attrType, value);
286 return reinterpret_cast<pldm_bios_attr_val_table_entry*>(table.data() +
287 tableSize);
288}
289
John Wang3be70852020-02-13 15:59:04 +0800290const pldm_bios_attr_val_table_entry*
291 constructEnumEntry(Table& table, uint16_t attrHandle, uint8_t attrType,
292 const std::vector<uint8_t>& handleIndices)
293{
294 auto entryLength = pldm_bios_table_attr_value_entry_encode_enum_length(
295 handleIndices.size());
296 auto tableSize = table.size();
297 table.resize(tableSize + entryLength);
298 pldm_bios_table_attr_value_entry_encode_enum(
299 table.data() + tableSize, entryLength, attrHandle, attrType,
300 handleIndices.size(), handleIndices.data());
301 return reinterpret_cast<pldm_bios_attr_val_table_entry*>(table.data() +
302 tableSize);
303}
304
John Wangd9659342020-02-27 16:46:05 +0800305std::optional<Table> updateTable(const Table& table, const void* entry,
306 size_t size)
307{
308 // Replace the old attribute with the new attribute, the size of table will
309 // change:
310 // sizeof(newTableBuffer) = srcTableSize + sizeof(newAttribute) -
311 // sizeof(oldAttribute) + pad(4-byte alignment, max =
312 // 3)
313 // For simplicity, we use
314 // sizeof(newTableBuffer) = srcTableSize + sizeof(newAttribute) + 3
315 size_t destBufferLength = table.size() + size + 3;
316 Table destTable(destBufferLength);
317
318 auto rc = pldm_bios_table_attr_value_copy_and_update(
319 table.data(), table.size(), destTable.data(), &destBufferLength, entry,
320 size);
321 if (rc != PLDM_SUCCESS)
322 {
323 return std::nullopt;
324 }
325 destTable.resize(destBufferLength);
326
327 return destTable;
328}
John Wang29683b52020-02-27 16:41:44 +0800329
330} // namespace attribute_value
331
332} // namespace table
333
Deepak Kodihallicb7f2d42019-06-19 13:25:31 +0530334} // namespace bios
335} // namespace responder
336} // namespace pldm