blob: 3f5d532aa5dcc767622a02e332fe4462249eb46a [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 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{
227
228TableHeader decodeHeader(const pldm_bios_attr_val_table_entry* entry)
229{
230 auto handle =
231 pldm_bios_table_attr_value_entry_decode_attribute_handle(entry);
232 auto type = pldm_bios_table_attr_value_entry_decode_attribute_type(entry);
233 return {handle, type};
234}
235
236std::string decodeStringEntry(const pldm_bios_attr_val_table_entry* entry)
237{
238 variable_field currentString{};
239 pldm_bios_table_attr_value_entry_string_decode_string(entry,
240 &currentString);
241 return std::string(currentString.ptr,
242 currentString.ptr + currentString.length);
243}
244
John Wang95e6b3c2020-02-13 09:43:24 +0800245uint64_t decodeIntegerEntry(const pldm_bios_attr_val_table_entry* entry)
246{
247 return pldm_bios_table_attr_value_entry_integer_decode_cv(entry);
248}
249
John Wang3be70852020-02-13 15:59:04 +0800250std::vector<uint8_t>
251 decodeEnumEntry(const pldm_bios_attr_val_table_entry* entry)
252{
253 auto number = pldm_bios_table_attr_value_entry_enum_decode_number(entry);
254 std::vector<uint8_t> currHdls(number, 0);
255 pldm_bios_table_attr_value_entry_enum_decode_handles(entry, currHdls.data(),
256 currHdls.size());
257 return currHdls;
258}
259
John Wang29683b52020-02-27 16:41:44 +0800260const pldm_bios_attr_val_table_entry*
261 constructStringEntry(Table& table, uint16_t attrHandle, uint8_t attrType,
262 const std::string& str)
263{
264 auto strLen = str.size();
265 auto entryLength =
266 pldm_bios_table_attr_value_entry_encode_string_length(strLen);
267 auto tableSize = table.size();
268 table.resize(tableSize + entryLength);
269 pldm_bios_table_attr_value_entry_encode_string(
270 table.data() + tableSize, entryLength, attrHandle, attrType, strLen,
271 str.c_str());
272 return reinterpret_cast<pldm_bios_attr_val_table_entry*>(table.data() +
273 tableSize);
274}
John Wang95e6b3c2020-02-13 09:43:24 +0800275
276const pldm_bios_attr_val_table_entry* constructIntegerEntry(Table& table,
277 uint16_t attrHandle,
278 uint8_t attrType,
279 uint64_t value)
280{
281 auto entryLength = pldm_bios_table_attr_value_entry_encode_integer_length();
282
283 auto tableSize = table.size();
284 table.resize(tableSize + entryLength);
285 pldm_bios_table_attr_value_entry_encode_integer(
286 table.data() + tableSize, entryLength, attrHandle, attrType, value);
287 return reinterpret_cast<pldm_bios_attr_val_table_entry*>(table.data() +
288 tableSize);
289}
290
John Wang3be70852020-02-13 15:59:04 +0800291const pldm_bios_attr_val_table_entry*
292 constructEnumEntry(Table& table, uint16_t attrHandle, uint8_t attrType,
293 const std::vector<uint8_t>& handleIndices)
294{
295 auto entryLength = pldm_bios_table_attr_value_entry_encode_enum_length(
296 handleIndices.size());
297 auto tableSize = table.size();
298 table.resize(tableSize + entryLength);
299 pldm_bios_table_attr_value_entry_encode_enum(
300 table.data() + tableSize, entryLength, attrHandle, attrType,
301 handleIndices.size(), handleIndices.data());
302 return reinterpret_cast<pldm_bios_attr_val_table_entry*>(table.data() +
303 tableSize);
304}
305
John Wangd9659342020-02-27 16:46:05 +0800306std::optional<Table> updateTable(const Table& table, const void* entry,
307 size_t size)
308{
309 // Replace the old attribute with the new attribute, the size of table will
310 // change:
311 // sizeof(newTableBuffer) = srcTableSize + sizeof(newAttribute) -
312 // sizeof(oldAttribute) + pad(4-byte alignment, max =
313 // 3)
314 // For simplicity, we use
315 // sizeof(newTableBuffer) = srcTableSize + sizeof(newAttribute) + 3
316 size_t destBufferLength = table.size() + size + 3;
317 Table destTable(destBufferLength);
318
319 auto rc = pldm_bios_table_attr_value_copy_and_update(
320 table.data(), table.size(), destTable.data(), &destBufferLength, entry,
321 size);
322 if (rc != PLDM_SUCCESS)
323 {
324 return std::nullopt;
325 }
326 destTable.resize(destBufferLength);
327
328 return destTable;
329}
John Wang29683b52020-02-27 16:41:44 +0800330
331} // namespace attribute_value
332
333} // namespace table
334
Deepak Kodihallicb7f2d42019-06-19 13:25:31 +0530335} // namespace bios
336} // namespace responder
337} // namespace pldm