blob: b8fa713e28ff92ef48cc07672ea60cc96ee05ebe [file] [log] [blame]
Deepak Kodihallicb7f2d42019-06-19 13:25:31 +05301#include "bios_table.hpp"
2
3#include <fstream>
4
John Wangf719f3b2020-01-17 08:46:22 +08005#include "bios_table.h"
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)
17{
18}
19
20bool BIOSTable::isEmpty() const noexcept
21{
22 bool empty = false;
23 try
24 {
25 empty = fs::is_empty(filePath);
26 }
27 catch (fs::filesystem_error& e)
28 {
29 return true;
30 }
31 return empty;
32}
33
34void BIOSTable::store(const Table& table)
35{
36 std::ofstream stream(filePath.string(), std::ios::out | std::ios::binary);
37 stream.write(reinterpret_cast<const char*>(table.data()), table.size());
38}
39
40void BIOSTable::load(Response& response) const
41{
42 auto currSize = response.size();
43 auto fileSize = fs::file_size(filePath);
44 response.resize(currSize + fileSize);
45 std::ifstream stream(filePath.string(), std::ios::in | std::ios::binary);
46 stream.read(reinterpret_cast<char*>(response.data() + currSize), fileSize);
47}
48
John Wange297b9f2020-02-03 10:18:13 +080049BIOSStringTable::BIOSStringTable(const Table& stringTable) :
50 stringTable(stringTable)
John Wangf719f3b2020-01-17 08:46:22 +080051{
John Wange297b9f2020-02-03 10:18:13 +080052}
53
54BIOSStringTable::BIOSStringTable(const BIOSTable& biosTable)
55{
56 biosTable.load(stringTable);
John Wangf719f3b2020-01-17 08:46:22 +080057}
58
59std::string BIOSStringTable::findString(uint16_t handle) const
60{
61 auto stringEntry = pldm_bios_table_string_find_by_handle(
62 stringTable.data(), stringTable.size(), handle);
63 if (stringEntry == nullptr)
64 {
65 throw std::invalid_argument("Invalid String Handle");
66 }
John Wang29683b52020-02-27 16:41:44 +080067 return table::string::decodeString(stringEntry);
John Wangf719f3b2020-01-17 08:46:22 +080068}
69
John Wange297b9f2020-02-03 10:18:13 +080070uint16_t BIOSStringTable::findHandle(const std::string& name) const
71{
72 auto stringEntry = pldm_bios_table_string_find_by_string(
73 stringTable.data(), stringTable.size(), name.c_str());
74 if (stringEntry == nullptr)
75 {
76 throw std::invalid_argument("Invalid String Name");
77 }
78
John Wang29683b52020-02-27 16:41:44 +080079 return table::string::decodeHandle(stringEntry);
John Wange2efdcc2020-02-12 17:02:06 +080080}
81
John Wang29683b52020-02-27 16:41:44 +080082namespace table
83{
84
John Wangd9659342020-02-27 16:46:05 +080085void appendPadAndChecksum(Table& table)
86{
87 auto sizeWithoutPad = table.size();
88 auto padAndChecksumSize = pldm_bios_table_pad_checksum_size(sizeWithoutPad);
89 table.resize(table.size() + padAndChecksumSize);
90
91 pldm_bios_table_append_pad_checksum(table.data(), table.size(),
92 sizeWithoutPad);
93}
94
John Wang29683b52020-02-27 16:41:44 +080095namespace string
96{
97
98uint16_t decodeHandle(const pldm_bios_string_table_entry* entry)
John Wange2efdcc2020-02-12 17:02:06 +080099{
100 return pldm_bios_table_string_entry_decode_handle(entry);
101}
102
John Wang29683b52020-02-27 16:41:44 +0800103std::string decodeString(const pldm_bios_string_table_entry* entry)
John Wange2efdcc2020-02-12 17:02:06 +0800104{
105 auto strLength = pldm_bios_table_string_entry_decode_string_length(entry);
106 std::vector<char> buffer(strLength + 1 /* sizeof '\0' */);
107 pldm_bios_table_string_entry_decode_string(entry, buffer.data(),
108 buffer.size());
109 return std::string(buffer.data(), buffer.data() + strLength);
John Wange297b9f2020-02-03 10:18:13 +0800110}
John Wangd9659342020-02-27 16:46:05 +0800111const pldm_bios_string_table_entry* constructEntry(Table& table,
112 const std::string& str)
113{
114 auto tableSize = table.size();
115 auto entryLength = pldm_bios_table_string_entry_encode_length(str.length());
116 table.resize(tableSize + entryLength);
117 pldm_bios_table_string_entry_encode(table.data() + tableSize, entryLength,
118 str.c_str(), str.length());
119 return reinterpret_cast<pldm_bios_string_table_entry*>(table.data() +
120 tableSize);
121}
John Wange297b9f2020-02-03 10:18:13 +0800122
John Wang29683b52020-02-27 16:41:44 +0800123} // namespace string
124
125namespace attribute
126{
127
128TableHeader decodeHeader(const pldm_bios_attr_table_entry* entry)
129{
130 auto attrHandle = pldm_bios_table_attr_entry_decode_attribute_handle(entry);
131 auto attrType = pldm_bios_table_attr_entry_decode_attribute_type(entry);
132 auto stringHandle = pldm_bios_table_attr_entry_decode_string_handle(entry);
133 return {attrHandle, attrType, stringHandle};
134}
135
John Wangd9659342020-02-27 16:46:05 +0800136const pldm_bios_attr_table_entry* findByHandle(const Table& table,
137 uint16_t handle)
138{
139 return pldm_bios_table_attr_find_by_handle(table.data(), table.size(),
140 handle);
141}
142
John Wang45fed202020-04-01 16:42:26 +0800143const pldm_bios_attr_table_entry* findByStringHandle(const Table& table,
144 uint16_t handle)
145{
146 return pldm_bios_table_attr_find_by_string_handle(table.data(),
147 table.size(), handle);
148}
149
John Wang29683b52020-02-27 16:41:44 +0800150const pldm_bios_attr_table_entry*
151 constructStringEntry(Table& table,
152 pldm_bios_table_attr_entry_string_info* info)
153{
154 auto entryLength =
155 pldm_bios_table_attr_entry_string_encode_length(info->def_length);
156
157 auto tableSize = table.size();
158 table.resize(tableSize + entryLength, 0);
159 pldm_bios_table_attr_entry_string_encode(table.data() + tableSize,
160 entryLength, info);
161 return reinterpret_cast<pldm_bios_attr_table_entry*>(table.data() +
162 tableSize);
163}
164
John Wang95e6b3c2020-02-13 09:43:24 +0800165const pldm_bios_attr_table_entry*
166 constructIntegerEntry(Table& table,
167 pldm_bios_table_attr_entry_integer_info* info)
168{
169 auto entryLength = pldm_bios_table_attr_entry_integer_encode_length();
170 auto tableSize = table.size();
171 table.resize(tableSize + entryLength, 0);
172 pldm_bios_table_attr_entry_integer_encode(table.data() + tableSize,
173 entryLength, info);
174 return reinterpret_cast<pldm_bios_attr_table_entry*>(table.data() +
175 tableSize);
176}
177
John Wang29683b52020-02-27 16:41:44 +0800178StringField decodeStringEntry(const pldm_bios_attr_table_entry* entry)
179{
180 auto strType = pldm_bios_table_attr_entry_string_decode_string_type(entry);
181 auto minLength = pldm_bios_table_attr_entry_string_decode_min_length(entry);
182 auto maxLength = pldm_bios_table_attr_entry_string_decode_max_length(entry);
183 auto defLength =
184 pldm_bios_table_attr_entry_string_decode_def_string_length(entry);
185
186 std::vector<char> buffer(defLength + 1);
187 pldm_bios_table_attr_entry_string_decode_def_string(entry, buffer.data(),
188 buffer.size());
189 return {strType, minLength, maxLength, defLength,
190 std::string(buffer.data(), buffer.data() + defLength)};
191}
192
John Wang95e6b3c2020-02-13 09:43:24 +0800193IntegerField decodeIntegerEntry(const pldm_bios_attr_table_entry* entry)
194{
195 uint64_t lower, upper, def;
196 uint32_t scalar;
197
198 pldm_bios_table_attr_entry_integer_decode(entry, &lower, &upper, &scalar,
199 &def);
200 return {lower, upper, scalar, def};
201}
202
John Wang3be70852020-02-13 15:59:04 +0800203const pldm_bios_attr_table_entry*
204 constructEnumEntry(Table& table, pldm_bios_table_attr_entry_enum_info* info)
205{
206 auto entryLength = pldm_bios_table_attr_entry_enum_encode_length(
207 info->pv_num, info->def_num);
208
209 auto tableSize = table.size();
210 table.resize(tableSize + entryLength, 0);
211 pldm_bios_table_attr_entry_enum_encode(table.data() + tableSize,
212 entryLength, info);
213
214 return reinterpret_cast<pldm_bios_attr_table_entry*>(table.data() +
215 tableSize);
216}
217
218EnumField decodeEnumEntry(const pldm_bios_attr_table_entry* entry)
219{
220 uint8_t pvNum = pldm_bios_table_attr_entry_enum_decode_pv_num(entry);
221 std::vector<uint16_t> pvHdls(pvNum, 0);
222 pldm_bios_table_attr_entry_enum_decode_pv_hdls(entry, pvHdls.data(), pvNum);
223 auto defNum = pldm_bios_table_attr_entry_enum_decode_def_num(entry);
224 std::vector<uint8_t> defIndices(defNum, 0);
225 pldm_bios_table_attr_entry_enum_decode_def_indices(entry, defIndices.data(),
226 defIndices.size());
227 return {pvHdls, defIndices};
228}
229
John Wang29683b52020-02-27 16:41:44 +0800230} // namespace attribute
231
232namespace attribute_value
233{
234
235TableHeader decodeHeader(const pldm_bios_attr_val_table_entry* entry)
236{
237 auto handle =
238 pldm_bios_table_attr_value_entry_decode_attribute_handle(entry);
239 auto type = pldm_bios_table_attr_value_entry_decode_attribute_type(entry);
240 return {handle, type};
241}
242
243std::string decodeStringEntry(const pldm_bios_attr_val_table_entry* entry)
244{
245 variable_field currentString{};
246 pldm_bios_table_attr_value_entry_string_decode_string(entry,
247 &currentString);
248 return std::string(currentString.ptr,
249 currentString.ptr + currentString.length);
250}
251
John Wang95e6b3c2020-02-13 09:43:24 +0800252uint64_t decodeIntegerEntry(const pldm_bios_attr_val_table_entry* entry)
253{
254 return pldm_bios_table_attr_value_entry_integer_decode_cv(entry);
255}
256
John Wang3be70852020-02-13 15:59:04 +0800257std::vector<uint8_t>
258 decodeEnumEntry(const pldm_bios_attr_val_table_entry* entry)
259{
260 auto number = pldm_bios_table_attr_value_entry_enum_decode_number(entry);
261 std::vector<uint8_t> currHdls(number, 0);
262 pldm_bios_table_attr_value_entry_enum_decode_handles(entry, currHdls.data(),
263 currHdls.size());
264 return currHdls;
265}
266
John Wang29683b52020-02-27 16:41:44 +0800267const pldm_bios_attr_val_table_entry*
268 constructStringEntry(Table& table, uint16_t attrHandle, uint8_t attrType,
269 const std::string& str)
270{
271 auto strLen = str.size();
272 auto entryLength =
273 pldm_bios_table_attr_value_entry_encode_string_length(strLen);
274 auto tableSize = table.size();
275 table.resize(tableSize + entryLength);
276 pldm_bios_table_attr_value_entry_encode_string(
277 table.data() + tableSize, entryLength, attrHandle, attrType, strLen,
278 str.c_str());
279 return reinterpret_cast<pldm_bios_attr_val_table_entry*>(table.data() +
280 tableSize);
281}
John Wang95e6b3c2020-02-13 09:43:24 +0800282
283const pldm_bios_attr_val_table_entry* constructIntegerEntry(Table& table,
284 uint16_t attrHandle,
285 uint8_t attrType,
286 uint64_t value)
287{
288 auto entryLength = pldm_bios_table_attr_value_entry_encode_integer_length();
289
290 auto tableSize = table.size();
291 table.resize(tableSize + entryLength);
292 pldm_bios_table_attr_value_entry_encode_integer(
293 table.data() + tableSize, entryLength, attrHandle, attrType, value);
294 return reinterpret_cast<pldm_bios_attr_val_table_entry*>(table.data() +
295 tableSize);
296}
297
John Wang3be70852020-02-13 15:59:04 +0800298const pldm_bios_attr_val_table_entry*
299 constructEnumEntry(Table& table, uint16_t attrHandle, uint8_t attrType,
300 const std::vector<uint8_t>& handleIndices)
301{
302 auto entryLength = pldm_bios_table_attr_value_entry_encode_enum_length(
303 handleIndices.size());
304 auto tableSize = table.size();
305 table.resize(tableSize + entryLength);
306 pldm_bios_table_attr_value_entry_encode_enum(
307 table.data() + tableSize, entryLength, attrHandle, attrType,
308 handleIndices.size(), handleIndices.data());
309 return reinterpret_cast<pldm_bios_attr_val_table_entry*>(table.data() +
310 tableSize);
311}
312
John Wangd9659342020-02-27 16:46:05 +0800313std::optional<Table> updateTable(const Table& table, const void* entry,
314 size_t size)
315{
316 // Replace the old attribute with the new attribute, the size of table will
317 // change:
318 // sizeof(newTableBuffer) = srcTableSize + sizeof(newAttribute) -
319 // sizeof(oldAttribute) + pad(4-byte alignment, max =
320 // 3)
321 // For simplicity, we use
322 // sizeof(newTableBuffer) = srcTableSize + sizeof(newAttribute) + 3
323 size_t destBufferLength = table.size() + size + 3;
324 Table destTable(destBufferLength);
325
326 auto rc = pldm_bios_table_attr_value_copy_and_update(
327 table.data(), table.size(), destTable.data(), &destBufferLength, entry,
328 size);
329 if (rc != PLDM_SUCCESS)
330 {
331 return std::nullopt;
332 }
333 destTable.resize(destBufferLength);
334
335 return destTable;
336}
John Wang29683b52020-02-27 16:41:44 +0800337
338} // namespace attribute_value
339
340} // namespace table
341
Deepak Kodihallicb7f2d42019-06-19 13:25:31 +0530342} // namespace bios
343} // namespace responder
344} // namespace pldm