blob: 3789e97d2cda8781f67cfbda2c5bde42023d04c1 [file] [log] [blame]
Deepak Kodihallicb7f2d42019-06-19 13:25:31 +05301#include "bios_table.hpp"
2
ArchanaKakani561c0192022-12-06 02:40:52 -06003#include "libpldm/base.h"
Manojkiran Edab941eeb2022-08-18 07:11:22 +05304#include "libpldm/bios_table.h"
ArchanaKakani561c0192022-12-06 02:40:52 -06005#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{
Deepak Kodihallicb7f2d42019-06-19 13:25:31 +053015BIOSTable::BIOSTable(const char* filePath) : filePath(filePath)
George Liu6492f522020-06-16 10:34:05 +080016{}
Deepak Kodihallicb7f2d42019-06-19 13:25:31 +053017
18bool BIOSTable::isEmpty() const noexcept
19{
20 bool empty = false;
21 try
22 {
23 empty = fs::is_empty(filePath);
24 }
Patrick Williams51330582021-10-06 12:48:56 -050025 catch (const fs::filesystem_error& e)
Deepak Kodihallicb7f2d42019-06-19 13:25:31 +053026 {
27 return true;
28 }
29 return empty;
30}
31
32void BIOSTable::store(const Table& table)
33{
34 std::ofstream stream(filePath.string(), std::ios::out | std::ios::binary);
35 stream.write(reinterpret_cast<const char*>(table.data()), table.size());
36}
37
38void BIOSTable::load(Response& response) const
39{
40 auto currSize = response.size();
41 auto fileSize = fs::file_size(filePath);
42 response.resize(currSize + fileSize);
43 std::ifstream stream(filePath.string(), std::ios::in | std::ios::binary);
44 stream.read(reinterpret_cast<char*>(response.data() + currSize), fileSize);
45}
46
John Wange297b9f2020-02-03 10:18:13 +080047BIOSStringTable::BIOSStringTable(const Table& stringTable) :
48 stringTable(stringTable)
George Liu6492f522020-06-16 10:34:05 +080049{}
John Wange297b9f2020-02-03 10:18:13 +080050
51BIOSStringTable::BIOSStringTable(const BIOSTable& biosTable)
52{
53 biosTable.load(stringTable);
John Wangf719f3b2020-01-17 08:46:22 +080054}
55
56std::string BIOSStringTable::findString(uint16_t handle) const
57{
58 auto stringEntry = pldm_bios_table_string_find_by_handle(
59 stringTable.data(), stringTable.size(), handle);
60 if (stringEntry == nullptr)
61 {
62 throw std::invalid_argument("Invalid String Handle");
63 }
John Wang29683b52020-02-27 16:41:44 +080064 return table::string::decodeString(stringEntry);
John Wangf719f3b2020-01-17 08:46:22 +080065}
66
John Wange297b9f2020-02-03 10:18:13 +080067uint16_t BIOSStringTable::findHandle(const std::string& name) const
68{
69 auto stringEntry = pldm_bios_table_string_find_by_string(
70 stringTable.data(), stringTable.size(), name.c_str());
71 if (stringEntry == nullptr)
72 {
73 throw std::invalid_argument("Invalid String Name");
74 }
75
John Wang29683b52020-02-27 16:41:44 +080076 return table::string::decodeHandle(stringEntry);
John Wange2efdcc2020-02-12 17:02:06 +080077}
78
John Wang29683b52020-02-27 16:41:44 +080079namespace table
80{
John Wangd9659342020-02-27 16:46:05 +080081void appendPadAndChecksum(Table& table)
82{
83 auto sizeWithoutPad = table.size();
84 auto padAndChecksumSize = pldm_bios_table_pad_checksum_size(sizeWithoutPad);
85 table.resize(table.size() + padAndChecksumSize);
86
87 pldm_bios_table_append_pad_checksum(table.data(), table.size(),
88 sizeWithoutPad);
89}
90
John Wang29683b52020-02-27 16:41:44 +080091namespace string
92{
John Wang29683b52020-02-27 16:41:44 +080093uint16_t decodeHandle(const pldm_bios_string_table_entry* entry)
John Wange2efdcc2020-02-12 17:02:06 +080094{
95 return pldm_bios_table_string_entry_decode_handle(entry);
96}
97
John Wang29683b52020-02-27 16:41:44 +080098std::string decodeString(const pldm_bios_string_table_entry* entry)
John Wange2efdcc2020-02-12 17:02:06 +080099{
100 auto strLength = pldm_bios_table_string_entry_decode_string_length(entry);
101 std::vector<char> buffer(strLength + 1 /* sizeof '\0' */);
102 pldm_bios_table_string_entry_decode_string(entry, buffer.data(),
103 buffer.size());
104 return std::string(buffer.data(), buffer.data() + strLength);
John Wange297b9f2020-02-03 10:18:13 +0800105}
John Wangd9659342020-02-27 16:46:05 +0800106const pldm_bios_string_table_entry* constructEntry(Table& table,
107 const std::string& str)
108{
109 auto tableSize = table.size();
110 auto entryLength = pldm_bios_table_string_entry_encode_length(str.length());
111 table.resize(tableSize + entryLength);
112 pldm_bios_table_string_entry_encode(table.data() + tableSize, entryLength,
113 str.c_str(), str.length());
114 return reinterpret_cast<pldm_bios_string_table_entry*>(table.data() +
115 tableSize);
116}
John Wange297b9f2020-02-03 10:18:13 +0800117
John Wang29683b52020-02-27 16:41:44 +0800118} // namespace string
119
120namespace attribute
121{
John Wang29683b52020-02-27 16:41:44 +0800122TableHeader decodeHeader(const pldm_bios_attr_table_entry* entry)
123{
124 auto attrHandle = pldm_bios_table_attr_entry_decode_attribute_handle(entry);
125 auto attrType = pldm_bios_table_attr_entry_decode_attribute_type(entry);
126 auto stringHandle = pldm_bios_table_attr_entry_decode_string_handle(entry);
127 return {attrHandle, attrType, stringHandle};
128}
129
John Wangd9659342020-02-27 16:46:05 +0800130const pldm_bios_attr_table_entry* findByHandle(const Table& table,
131 uint16_t handle)
132{
133 return pldm_bios_table_attr_find_by_handle(table.data(), table.size(),
134 handle);
135}
136
John Wang45fed202020-04-01 16:42:26 +0800137const pldm_bios_attr_table_entry* findByStringHandle(const Table& table,
138 uint16_t handle)
139{
140 return pldm_bios_table_attr_find_by_string_handle(table.data(),
141 table.size(), handle);
142}
143
John Wang29683b52020-02-27 16:41:44 +0800144const pldm_bios_attr_table_entry*
145 constructStringEntry(Table& table,
146 pldm_bios_table_attr_entry_string_info* info)
147{
148 auto entryLength =
149 pldm_bios_table_attr_entry_string_encode_length(info->def_length);
150
151 auto tableSize = table.size();
152 table.resize(tableSize + entryLength, 0);
153 pldm_bios_table_attr_entry_string_encode(table.data() + tableSize,
154 entryLength, info);
155 return reinterpret_cast<pldm_bios_attr_table_entry*>(table.data() +
156 tableSize);
157}
158
John Wang95e6b3c2020-02-13 09:43:24 +0800159const pldm_bios_attr_table_entry*
160 constructIntegerEntry(Table& table,
161 pldm_bios_table_attr_entry_integer_info* info)
162{
163 auto entryLength = pldm_bios_table_attr_entry_integer_encode_length();
164 auto tableSize = table.size();
165 table.resize(tableSize + entryLength, 0);
166 pldm_bios_table_attr_entry_integer_encode(table.data() + tableSize,
167 entryLength, info);
168 return reinterpret_cast<pldm_bios_attr_table_entry*>(table.data() +
169 tableSize);
170}
171
John Wang29683b52020-02-27 16:41:44 +0800172StringField decodeStringEntry(const pldm_bios_attr_table_entry* entry)
173{
174 auto strType = pldm_bios_table_attr_entry_string_decode_string_type(entry);
175 auto minLength = pldm_bios_table_attr_entry_string_decode_min_length(entry);
176 auto maxLength = pldm_bios_table_attr_entry_string_decode_max_length(entry);
177 auto defLength =
178 pldm_bios_table_attr_entry_string_decode_def_string_length(entry);
179
180 std::vector<char> buffer(defLength + 1);
181 pldm_bios_table_attr_entry_string_decode_def_string(entry, buffer.data(),
182 buffer.size());
183 return {strType, minLength, maxLength, defLength,
184 std::string(buffer.data(), buffer.data() + defLength)};
185}
186
John Wang95e6b3c2020-02-13 09:43:24 +0800187IntegerField decodeIntegerEntry(const pldm_bios_attr_table_entry* entry)
188{
189 uint64_t lower, upper, def;
190 uint32_t scalar;
191
192 pldm_bios_table_attr_entry_integer_decode(entry, &lower, &upper, &scalar,
193 &def);
194 return {lower, upper, scalar, def};
195}
196
John Wang3be70852020-02-13 15:59:04 +0800197const pldm_bios_attr_table_entry*
198 constructEnumEntry(Table& table, pldm_bios_table_attr_entry_enum_info* info)
199{
200 auto entryLength = pldm_bios_table_attr_entry_enum_encode_length(
201 info->pv_num, info->def_num);
202
203 auto tableSize = table.size();
204 table.resize(tableSize + entryLength, 0);
205 pldm_bios_table_attr_entry_enum_encode(table.data() + tableSize,
206 entryLength, info);
207
208 return reinterpret_cast<pldm_bios_attr_table_entry*>(table.data() +
209 tableSize);
210}
211
212EnumField decodeEnumEntry(const pldm_bios_attr_table_entry* entry)
213{
214 uint8_t pvNum = pldm_bios_table_attr_entry_enum_decode_pv_num(entry);
215 std::vector<uint16_t> pvHdls(pvNum, 0);
216 pldm_bios_table_attr_entry_enum_decode_pv_hdls(entry, pvHdls.data(), pvNum);
217 auto defNum = pldm_bios_table_attr_entry_enum_decode_def_num(entry);
218 std::vector<uint8_t> defIndices(defNum, 0);
219 pldm_bios_table_attr_entry_enum_decode_def_indices(entry, defIndices.data(),
220 defIndices.size());
221 return {pvHdls, defIndices};
222}
223
John Wang29683b52020-02-27 16:41:44 +0800224} // namespace attribute
225
226namespace attribute_value
227{
John Wang29683b52020-02-27 16:41:44 +0800228TableHeader 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