1 #pragma once 2 3 #include "libpldm/bios.h" 4 #include "libpldm/bios_table.h" 5 6 #include <stdint.h> 7 8 #include <filesystem> 9 #include <optional> 10 #include <string> 11 #include <vector> 12 13 namespace pldm 14 { 15 16 namespace responder 17 { 18 19 namespace bios 20 { 21 22 using Table = std::vector<uint8_t>; 23 using Response = std::vector<uint8_t>; 24 namespace fs = std::filesystem; 25 26 /** @class BIOSTable 27 * 28 * @brief Provides APIs for storing and loading BIOS tables 29 * 30 * Typical usage is as follows: 31 * BIOSTable table(BIOS_STRING_TABLE_FILE_PATH); 32 * if (table.isEmpty()) { // no persisted table 33 * // construct BIOSTable 't' 34 * // prepare Response 'r' 35 * // send response to GetBIOSTable 36 * table.store(t); // persisted 37 * } 38 * else { // persisted table exists 39 * // create Response 'r' which has response fields (except 40 * // the table itself) to a GetBIOSTable command 41 * table.load(r); // actual table will be pushed back to the vector 42 * } 43 */ 44 class BIOSTable 45 { 46 public: 47 /** @brief Ctor - set file path to persist BIOS table 48 * 49 * @param[in] filePath - file where BIOS table should be persisted 50 */ 51 BIOSTable(const char* filePath); 52 53 /** @brief Checks if there's a persisted BIOS table 54 * 55 * @return bool - true if table exists, false otherwise 56 */ 57 bool isEmpty() const noexcept; 58 59 /** @brief Persist a BIOS table(string/attribute/attribute value) 60 * 61 * @param[in] table - BIOS table 62 */ 63 void store(const Table& table); 64 65 /** @brief Load BIOS table from persistent store to memory 66 * 67 * @param[in,out] response - PLDM response message to GetBIOSTable 68 * (excluding table), table will be pushed back to this. 69 */ 70 void load(Response& response) const; 71 72 private: 73 // file storing PLDM BIOS table 74 fs::path filePath; 75 }; 76 77 /** @class BIOSStringTableInterface 78 * @brief Provide interfaces to the BIOS string table operations 79 */ 80 class BIOSStringTableInterface 81 { 82 public: 83 virtual ~BIOSStringTableInterface() = default; 84 85 /** @brief Find the string name from the BIOS string table for a string 86 * handle 87 * @param[in] handle - string handle 88 * @return name of the corresponding BIOS string 89 */ 90 virtual std::string findString(uint16_t handle) const = 0; 91 92 /** @brief Find the string handle from the BIOS string table by the given 93 * name 94 * @param[in] name - name of the BIOS string 95 * @return handle of the string 96 */ 97 virtual uint16_t findHandle(const std::string& name) const = 0; 98 }; 99 100 /** @class BIOSStringTable 101 * @brief Collection of BIOS string table operations. 102 */ 103 class BIOSStringTable : public BIOSStringTableInterface 104 { 105 public: 106 /** @brief Constructs BIOSStringTable 107 * 108 * @param[in] stringTable - The stringTable in RAM 109 */ 110 BIOSStringTable(const Table& stringTable); 111 112 /** @brief Constructs BIOSStringTable 113 * 114 * @param[in] biosTable - The BIOSTable 115 */ 116 BIOSStringTable(const BIOSTable& biosTable); 117 118 /** @brief Find the string name from the BIOS string table for a string 119 * handle 120 * @param[in] handle - string handle 121 * @return name of the corresponding BIOS string 122 * @throw std::invalid_argument if the string can not be found. 123 */ 124 std::string findString(uint16_t handle) const override; 125 126 /** @brief Find the string handle from the BIOS string table by the given 127 * name 128 * @param[in] name - name of the BIOS string 129 * @return handle of the string 130 * @throw std::invalid_argument if the string can not be found 131 */ 132 uint16_t findHandle(const std::string& name) const override; 133 134 private: 135 Table stringTable; 136 }; 137 138 namespace table 139 { 140 141 /** @brief Append Pad and Checksum 142 * 143 * @param[in,out] table - table to be appended with pad and checksum 144 */ 145 void appendPadAndChecksum(Table& table); 146 147 namespace string 148 { 149 150 /** @brief Get the string handle for the entry 151 * @param[in] entry - Pointer to a bios string table entry 152 * @return Handle to identify a string in the bios string table 153 */ 154 uint16_t decodeHandle(const pldm_bios_string_table_entry* entry); 155 156 /** @brief Get the string from the entry 157 * @param[in] entry - Pointer to a bios string table entry 158 * @return The String 159 */ 160 std::string decodeString(const pldm_bios_string_table_entry* entry); 161 162 /** @brief construct entry of string table at the end of the given 163 * table 164 * @param[in,out] table - The given table 165 * @param[in] str - string itself 166 * @return pointer to the constructed entry 167 */ 168 const pldm_bios_string_table_entry* constructEntry(Table& table, 169 const std::string& str); 170 171 } // namespace string 172 173 namespace attribute 174 { 175 176 /** @struct TableHeader 177 * @brief Header of attribute table 178 */ 179 struct TableHeader 180 { 181 uint16_t attrHandle; 182 uint8_t attrType; 183 uint16_t stringHandle; 184 }; 185 186 /** @brief Decode header of attribute table entry 187 * @param[in] entry - Pointer to an attribute table entry 188 * @return Attribute table header 189 */ 190 TableHeader decodeHeader(const pldm_bios_attr_table_entry* entry); 191 192 /** @brief Find attribute entry by handle 193 * @param[in] table - attribute table 194 * @param[in] handle - attribute handle 195 * @return Pointer to the attribute table entry 196 */ 197 const pldm_bios_attr_table_entry* findByHandle(const Table& table, 198 uint16_t handle); 199 200 /** @brief Find attribute entry by string handle 201 * @param[in] table - attribute table 202 * @param[in] handle - string handle 203 * @return Pointer to the attribute table entry 204 */ 205 const pldm_bios_attr_table_entry* findByStringHandle(const Table& table, 206 uint16_t handle); 207 208 /** @struct StringField 209 * @brief String field of attribute table 210 */ 211 struct StringField 212 { 213 uint8_t stringType; 214 uint16_t minLength; 215 uint16_t maxLength; 216 uint16_t defLength; 217 std::string defString; 218 }; 219 220 /** @brief decode string entry of attribute table 221 * @param[in] entry - Pointer to an attribute table entry 222 * @return String field of the entry 223 */ 224 StringField decodeStringEntry(const pldm_bios_attr_table_entry* entry); 225 226 /** @brief construct string entry of attribute table at the end of the given 227 * table 228 * @param[in,out] table - The given table 229 * @param[in] info - string info 230 * @return pointer to the constructed entry 231 */ 232 const pldm_bios_attr_table_entry* 233 constructStringEntry(Table& table, 234 pldm_bios_table_attr_entry_string_info* info); 235 236 /** @struct IntegerField 237 * @brief Integer field of attribute table 238 */ 239 struct IntegerField 240 { 241 uint64_t lowerBound; 242 uint64_t upperBound; 243 uint32_t scalarIncrement; 244 uint64_t defaultValue; 245 }; 246 247 /** @brief construct integer entry of attribute table at the end of the 248 * given table 249 * @param[in,out] table - The given table 250 * @param[in] info - integer info 251 * @return pointer to the constructed entry 252 */ 253 const pldm_bios_attr_table_entry* 254 constructIntegerEntry(Table& table, 255 pldm_bios_table_attr_entry_integer_info* info); 256 257 /** @brief decode integer entry of attribute table 258 * @param[in] entry - Pointer to an attribute table entry 259 * @return Integer field of the entry 260 */ 261 IntegerField decodeIntegerEntry(const pldm_bios_attr_table_entry* entry); 262 263 /** @struct EnumField 264 * @brief Enum field of attribute table 265 */ 266 struct EnumField 267 { 268 std::vector<uint16_t> possibleValueStringHandle; 269 std::vector<uint8_t> defaultValueIndex; 270 }; 271 272 /** @brief decode enum entry of attribute table 273 * @param[in] entry - Pointer to an attribute table entry 274 * @return Enum field of the entry 275 */ 276 EnumField decodeEnumEntry(const pldm_bios_attr_table_entry* entry); 277 278 /** @brief construct enum entry of attribute table at the end of the 279 * given table 280 * @param[in,out] table - The given table 281 * @param[in] info - enum info 282 * @return pointer to the constructed entry 283 */ 284 const pldm_bios_attr_table_entry* 285 constructEnumEntry(Table& table, 286 pldm_bios_table_attr_entry_enum_info* info); 287 288 } // namespace attribute 289 290 namespace attribute_value 291 { 292 293 /** @struct TableHeader 294 * @brief Header of attribute value table 295 */ 296 struct TableHeader 297 { 298 uint16_t attrHandle; 299 uint8_t attrType; 300 }; 301 302 /** @brief Decode header of attribute value table 303 * @param[in] entry - Pointer to an attribute value table entry 304 * @return Attribute value table header 305 */ 306 TableHeader decodeHeader(const pldm_bios_attr_val_table_entry* entry); 307 308 /** @brief Decode string entry of attribute value table 309 * @param[in] entry - Pointer to an attribute value table entry 310 * @return The decoded string 311 */ 312 std::string decodeStringEntry(const pldm_bios_attr_val_table_entry* entry); 313 314 /** @brief Decode integer entry of attribute value table 315 * @param[in] entry - Pointer to an attribute value table entry 316 * @return The decoded integer 317 */ 318 uint64_t decodeIntegerEntry(const pldm_bios_attr_val_table_entry* entry); 319 320 /** @brief Decode enum entry of attribute value table 321 * @param[in] entry - Pointer to an attribute value table entry 322 * @return Current value string handle indices 323 */ 324 std::vector<uint8_t> 325 decodeEnumEntry(const pldm_bios_attr_val_table_entry* entry); 326 327 /** @brief Construct string entry of attribute value table at the end of the 328 * given table 329 * @param[in] table - The given table 330 * @param[in] attrHandle - attribute handle 331 * @param[in] attrType - attribute type 332 * @param[in] str - The string 333 * @return Pointer to the constructed entry 334 */ 335 const pldm_bios_attr_val_table_entry* 336 constructStringEntry(Table& table, uint16_t attrHandle, uint8_t attrType, 337 const std::string& str); 338 339 /** @brief Construct integer entry of attribute value table at the end of 340 * the given table 341 * @param[in] table - The given table 342 * @param[in] attrHandle - attribute handle 343 * @param[in] attrType - attribute type 344 * @param[in] value - The integer 345 * @return Pointer to the constructed entry 346 */ 347 const pldm_bios_attr_val_table_entry* constructIntegerEntry(Table& table, 348 uint16_t attrHandle, 349 uint8_t attrType, 350 uint64_t value); 351 352 /** @brief Construct enum entry of attribute value table at the end of 353 * the given table 354 * @param[in] table - The given table 355 * @param[in] attrHandle - attribute handle 356 * @param[in] attrType - attribute type 357 * @param[in] handleIndices - handle indices 358 * @return Pointer to the constructed entry 359 */ 360 const pldm_bios_attr_val_table_entry* 361 constructEnumEntry(Table& table, uint16_t attrHandle, uint8_t attrType, 362 const std::vector<uint8_t>& handleIndices); 363 364 /** @brief construct a table with an new entry 365 * @param[in] table - the table need to be updated 366 * @param[in] entry - the new attribute value entry 367 * @param[in] size - size of the new entry 368 * @return newly constructed table, std::nullopt if failed 369 */ 370 std::optional<Table> updateTable(const Table& table, const void* entry, 371 size_t size); 372 373 } // namespace attribute_value 374 375 } // namespace table 376 377 } // namespace bios 378 } // namespace responder 379 } // namespace pldm 380