blob: d9da84b6659a0970f84a7b046ce0bbb96c257341 [file] [log] [blame]
Deepak Kodihallicb7f2d42019-06-19 13:25:31 +05301#include "bios_table.hpp"
2
Manojkiran Edab941eeb2022-08-18 07:11:22 +05303#include "libpldm/bios_table.h"
John Wangf719f3b2020-01-17 08:46:22 +08004
George Liu6492f522020-06-16 10:34:05 +08005#include <fstream>
6
Deepak Kodihallicb7f2d42019-06-19 13:25:31 +05307namespace pldm
8{
9
10namespace responder
11{
12
13namespace bios
14{
15
16BIOSTable::BIOSTable(const char* filePath) : filePath(filePath)
George Liu6492f522020-06-16 10:34:05 +080017{}
Deepak Kodihallicb7f2d42019-06-19 13:25:31 +053018
19bool BIOSTable::isEmpty() const noexcept
20{
21 bool empty = false;
22 try
23 {
24 empty = fs::is_empty(filePath);
25 }
Patrick Williams51330582021-10-06 12:48:56 -050026 catch (const fs::filesystem_error& e)
Deepak Kodihallicb7f2d42019-06-19 13:25:31 +053027 {
28 return true;
29 }
30 return empty;
31}
32
33void BIOSTable::store(const Table& table)
34{
35 std::ofstream stream(filePath.string(), std::ios::out | std::ios::binary);
36 stream.write(reinterpret_cast<const char*>(table.data()), table.size());
37}
38
39void BIOSTable::load(Response& response) const
40{
41 auto currSize = response.size();
42 auto fileSize = fs::file_size(filePath);
43 response.resize(currSize + fileSize);
44 std::ifstream stream(filePath.string(), std::ios::in | std::ios::binary);
45 stream.read(reinterpret_cast<char*>(response.data() + currSize), fileSize);
46}
47
John Wange297b9f2020-02-03 10:18:13 +080048BIOSStringTable::BIOSStringTable(const Table& stringTable) :
49 stringTable(stringTable)
George Liu6492f522020-06-16 10:34:05 +080050{}
John Wange297b9f2020-02-03 10:18:13 +080051
52BIOSStringTable::BIOSStringTable(const BIOSTable& biosTable)
53{
54 biosTable.load(stringTable);
John Wangf719f3b2020-01-17 08:46:22 +080055}
56
57std::string BIOSStringTable::findString(uint16_t handle) const
58{
59 auto stringEntry = pldm_bios_table_string_find_by_handle(
60 stringTable.data(), stringTable.size(), handle);
61 if (stringEntry == nullptr)
62 {
63 throw std::invalid_argument("Invalid String Handle");
64 }
John Wang29683b52020-02-27 16:41:44 +080065 return table::string::decodeString(stringEntry);
John Wangf719f3b2020-01-17 08:46:22 +080066}
67
John Wange297b9f2020-02-03 10:18:13 +080068uint16_t BIOSStringTable::findHandle(const std::string& name) const
69{
70 auto stringEntry = pldm_bios_table_string_find_by_string(
71 stringTable.data(), stringTable.size(), name.c_str());
72 if (stringEntry == nullptr)
73 {
74 throw std::invalid_argument("Invalid String Name");
75 }
76
John Wang29683b52020-02-27 16:41:44 +080077 return table::string::decodeHandle(stringEntry);
John Wange2efdcc2020-02-12 17:02:06 +080078}
79
John Wang29683b52020-02-27 16:41:44 +080080namespace table
81{
82
John Wangd9659342020-02-27 16:46:05 +080083void appendPadAndChecksum(Table& table)
84{
85 auto sizeWithoutPad = table.size();
86 auto padAndChecksumSize = pldm_bios_table_pad_checksum_size(sizeWithoutPad);
87 table.resize(table.size() + padAndChecksumSize);
88
89 pldm_bios_table_append_pad_checksum(table.data(), table.size(),
90 sizeWithoutPad);
91}
92
John Wang29683b52020-02-27 16:41:44 +080093namespace string
94{
95
96uint16_t decodeHandle(const pldm_bios_string_table_entry* entry)
John Wange2efdcc2020-02-12 17:02:06 +080097{
98 return pldm_bios_table_string_entry_decode_handle(entry);
99}
100
John Wang29683b52020-02-27 16:41:44 +0800101std::string decodeString(const pldm_bios_string_table_entry* entry)
John Wange2efdcc2020-02-12 17:02:06 +0800102{
103 auto strLength = pldm_bios_table_string_entry_decode_string_length(entry);
104 std::vector<char> buffer(strLength + 1 /* sizeof '\0' */);
105 pldm_bios_table_string_entry_decode_string(entry, buffer.data(),
106 buffer.size());
107 return std::string(buffer.data(), buffer.data() + strLength);
John Wange297b9f2020-02-03 10:18:13 +0800108}
John Wangd9659342020-02-27 16:46:05 +0800109const pldm_bios_string_table_entry* constructEntry(Table& table,
110 const std::string& str)
111{
112 auto tableSize = table.size();
113 auto entryLength = pldm_bios_table_string_entry_encode_length(str.length());
114 table.resize(tableSize + entryLength);
115 pldm_bios_table_string_entry_encode(table.data() + tableSize, entryLength,
116 str.c_str(), str.length());
117 return reinterpret_cast<pldm_bios_string_table_entry*>(table.data() +
118 tableSize);
119}
John Wange297b9f2020-02-03 10:18:13 +0800120
John Wang29683b52020-02-27 16:41:44 +0800121} // namespace string
122
123namespace attribute
124{
125
126TableHeader decodeHeader(const pldm_bios_attr_table_entry* entry)
127{
128 auto attrHandle = pldm_bios_table_attr_entry_decode_attribute_handle(entry);
129 auto attrType = pldm_bios_table_attr_entry_decode_attribute_type(entry);
130 auto stringHandle = pldm_bios_table_attr_entry_decode_string_handle(entry);
131 return {attrHandle, attrType, stringHandle};
132}
133
John Wangd9659342020-02-27 16:46:05 +0800134const pldm_bios_attr_table_entry* findByHandle(const Table& table,
135 uint16_t handle)
136{
137 return pldm_bios_table_attr_find_by_handle(table.data(), table.size(),
138 handle);
139}
140
John Wang45fed202020-04-01 16:42:26 +0800141const pldm_bios_attr_table_entry* findByStringHandle(const Table& table,
142 uint16_t handle)
143{
144 return pldm_bios_table_attr_find_by_string_handle(table.data(),
145 table.size(), handle);
146}
147
John Wang29683b52020-02-27 16:41:44 +0800148const pldm_bios_attr_table_entry*
149 constructStringEntry(Table& table,
150 pldm_bios_table_attr_entry_string_info* info)
151{
152 auto entryLength =
153 pldm_bios_table_attr_entry_string_encode_length(info->def_length);
154
155 auto tableSize = table.size();
156 table.resize(tableSize + entryLength, 0);
157 pldm_bios_table_attr_entry_string_encode(table.data() + tableSize,
158 entryLength, info);
159 return reinterpret_cast<pldm_bios_attr_table_entry*>(table.data() +
160 tableSize);
161}
162
John Wang95e6b3c2020-02-13 09:43:24 +0800163const pldm_bios_attr_table_entry*
164 constructIntegerEntry(Table& table,
165 pldm_bios_table_attr_entry_integer_info* info)
166{
167 auto entryLength = pldm_bios_table_attr_entry_integer_encode_length();
168 auto tableSize = table.size();
169 table.resize(tableSize + entryLength, 0);
170 pldm_bios_table_attr_entry_integer_encode(table.data() + tableSize,
171 entryLength, info);
172 return reinterpret_cast<pldm_bios_attr_table_entry*>(table.data() +
173 tableSize);
174}
175
John Wang29683b52020-02-27 16:41:44 +0800176StringField decodeStringEntry(const pldm_bios_attr_table_entry* entry)
177{
178 auto strType = pldm_bios_table_attr_entry_string_decode_string_type(entry);
179 auto minLength = pldm_bios_table_attr_entry_string_decode_min_length(entry);
180 auto maxLength = pldm_bios_table_attr_entry_string_decode_max_length(entry);
181 auto defLength =
182 pldm_bios_table_attr_entry_string_decode_def_string_length(entry);
183
184 std::vector<char> buffer(defLength + 1);
185 pldm_bios_table_attr_entry_string_decode_def_string(entry, buffer.data(),
186 buffer.size());
187 return {strType, minLength, maxLength, defLength,
188 std::string(buffer.data(), buffer.data() + defLength)};
189}
190
John Wang95e6b3c2020-02-13 09:43:24 +0800191IntegerField decodeIntegerEntry(const pldm_bios_attr_table_entry* entry)
192{
193 uint64_t lower, upper, def;
194 uint32_t scalar;
195
196 pldm_bios_table_attr_entry_integer_decode(entry, &lower, &upper, &scalar,
197 &def);
198 return {lower, upper, scalar, def};
199}
200
John Wang3be70852020-02-13 15:59:04 +0800201const pldm_bios_attr_table_entry*
202 constructEnumEntry(Table& table, pldm_bios_table_attr_entry_enum_info* info)
203{
204 auto entryLength = pldm_bios_table_attr_entry_enum_encode_length(
205 info->pv_num, info->def_num);
206
207 auto tableSize = table.size();
208 table.resize(tableSize + entryLength, 0);
209 pldm_bios_table_attr_entry_enum_encode(table.data() + tableSize,
210 entryLength, info);
211
212 return reinterpret_cast<pldm_bios_attr_table_entry*>(table.data() +
213 tableSize);
214}
215
216EnumField decodeEnumEntry(const pldm_bios_attr_table_entry* entry)
217{
218 uint8_t pvNum = pldm_bios_table_attr_entry_enum_decode_pv_num(entry);
219 std::vector<uint16_t> pvHdls(pvNum, 0);
220 pldm_bios_table_attr_entry_enum_decode_pv_hdls(entry, pvHdls.data(), pvNum);
221 auto defNum = pldm_bios_table_attr_entry_enum_decode_def_num(entry);
222 std::vector<uint8_t> defIndices(defNum, 0);
223 pldm_bios_table_attr_entry_enum_decode_def_indices(entry, defIndices.data(),
224 defIndices.size());
225 return {pvHdls, defIndices};
226}
227
John Wang29683b52020-02-27 16:41:44 +0800228} // namespace attribute
229
230namespace attribute_value
231{
232
233TableHeader decodeHeader(const pldm_bios_attr_val_table_entry* entry)
234{
235 auto handle =
236 pldm_bios_table_attr_value_entry_decode_attribute_handle(entry);
237 auto type = pldm_bios_table_attr_value_entry_decode_attribute_type(entry);
238 return {handle, type};
239}
240
241std::string decodeStringEntry(const pldm_bios_attr_val_table_entry* entry)
242{
243 variable_field currentString{};
244 pldm_bios_table_attr_value_entry_string_decode_string(entry,
245 &currentString);
246 return std::string(currentString.ptr,
247 currentString.ptr + currentString.length);
248}
249
John Wang95e6b3c2020-02-13 09:43:24 +0800250uint64_t decodeIntegerEntry(const pldm_bios_attr_val_table_entry* entry)
251{
252 return pldm_bios_table_attr_value_entry_integer_decode_cv(entry);
253}
254
John Wang3be70852020-02-13 15:59:04 +0800255std::vector<uint8_t>
256 decodeEnumEntry(const pldm_bios_attr_val_table_entry* entry)
257{
258 auto number = pldm_bios_table_attr_value_entry_enum_decode_number(entry);
259 std::vector<uint8_t> currHdls(number, 0);
260 pldm_bios_table_attr_value_entry_enum_decode_handles(entry, currHdls.data(),
261 currHdls.size());
262 return currHdls;
263}
264
John Wang29683b52020-02-27 16:41:44 +0800265const pldm_bios_attr_val_table_entry*
266 constructStringEntry(Table& table, uint16_t attrHandle, uint8_t attrType,
267 const std::string& str)
268{
269 auto strLen = str.size();
270 auto entryLength =
271 pldm_bios_table_attr_value_entry_encode_string_length(strLen);
272 auto tableSize = table.size();
273 table.resize(tableSize + entryLength);
274 pldm_bios_table_attr_value_entry_encode_string(
275 table.data() + tableSize, entryLength, attrHandle, attrType, strLen,
276 str.c_str());
277 return reinterpret_cast<pldm_bios_attr_val_table_entry*>(table.data() +
278 tableSize);
279}
John Wang95e6b3c2020-02-13 09:43:24 +0800280
281const pldm_bios_attr_val_table_entry* constructIntegerEntry(Table& table,
282 uint16_t attrHandle,
283 uint8_t attrType,
284 uint64_t value)
285{
286 auto entryLength = pldm_bios_table_attr_value_entry_encode_integer_length();
287
288 auto tableSize = table.size();
289 table.resize(tableSize + entryLength);
290 pldm_bios_table_attr_value_entry_encode_integer(
291 table.data() + tableSize, entryLength, attrHandle, attrType, value);
292 return reinterpret_cast<pldm_bios_attr_val_table_entry*>(table.data() +
293 tableSize);
294}
295
John Wang3be70852020-02-13 15:59:04 +0800296const pldm_bios_attr_val_table_entry*
297 constructEnumEntry(Table& table, uint16_t attrHandle, uint8_t attrType,
298 const std::vector<uint8_t>& handleIndices)
299{
300 auto entryLength = pldm_bios_table_attr_value_entry_encode_enum_length(
301 handleIndices.size());
302 auto tableSize = table.size();
303 table.resize(tableSize + entryLength);
304 pldm_bios_table_attr_value_entry_encode_enum(
305 table.data() + tableSize, entryLength, attrHandle, attrType,
306 handleIndices.size(), handleIndices.data());
307 return reinterpret_cast<pldm_bios_attr_val_table_entry*>(table.data() +
308 tableSize);
309}
310
John Wangd9659342020-02-27 16:46:05 +0800311std::optional<Table> updateTable(const Table& table, const void* entry,
312 size_t size)
313{
314 // Replace the old attribute with the new attribute, the size of table will
315 // change:
316 // sizeof(newTableBuffer) = srcTableSize + sizeof(newAttribute) -
317 // sizeof(oldAttribute) + pad(4-byte alignment, max =
318 // 3)
319 // For simplicity, we use
320 // sizeof(newTableBuffer) = srcTableSize + sizeof(newAttribute) + 3
321 size_t destBufferLength = table.size() + size + 3;
322 Table destTable(destBufferLength);
323
324 auto rc = pldm_bios_table_attr_value_copy_and_update(
325 table.data(), table.size(), destTable.data(), &destBufferLength, entry,
326 size);
327 if (rc != PLDM_SUCCESS)
328 {
329 return std::nullopt;
330 }
331 destTable.resize(destBufferLength);
332
333 return destTable;
334}
John Wang29683b52020-02-27 16:41:44 +0800335
336} // namespace attribute_value
337
338} // namespace table
339
Deepak Kodihallicb7f2d42019-06-19 13:25:31 +0530340} // namespace bios
341} // namespace responder
342} // namespace pldm