bios: Implement an iterator for bios attribute table
Traversing bios attribute table should be platform-independent, so
implement a c-version bios attribute table iterator in libpldm, also
implement a c++ auxiliary function to traverse a bios table.
Signed-off-by: John Wang <wangzqbj@inspur.com>
Change-Id: I2afcaac306603410e711aa4772ba35b5e0b131d5
diff --git a/libpldm/bios_table.c b/libpldm/bios_table.c
new file mode 100644
index 0000000..26d30bf
--- /dev/null
+++ b/libpldm/bios_table.c
@@ -0,0 +1,199 @@
+#include <assert.h>
+#include <endian.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "bios.h"
+#include "bios_table.h"
+
+#define POINTER_CHECK(pointer) \
+ do { \
+ if (pointer == NULL) \
+ return PLDM_ERROR_INVALID_DATA; \
+ } while (0)
+
+#define ATTR_TYPE_EXPECT(type, expected) \
+ do { \
+ if (type != expected && type != (expected | 0x80)) \
+ return PLDM_ERROR_INVALID_DATA; \
+ } while (0)
+
+uint8_t pldm_bios_table_attr_entry_enum_decode_pv_num(
+ const struct pldm_bios_attr_table_entry *entry)
+{
+ return entry->metadata[0];
+}
+
+int pldm_bios_table_attr_entry_enum_decode_pv_num_check(
+ const struct pldm_bios_attr_table_entry *entry, uint8_t *pv_num)
+{
+ POINTER_CHECK(entry);
+ POINTER_CHECK(pv_num);
+ ATTR_TYPE_EXPECT(entry->attr_type, PLDM_BIOS_ENUMERATION);
+ *pv_num = pldm_bios_table_attr_entry_enum_decode_pv_num(entry);
+ return PLDM_SUCCESS;
+}
+
+uint8_t pldm_bios_table_attr_entry_enum_decode_def_num(
+ const struct pldm_bios_attr_table_entry *entry)
+{
+ uint8_t pv_num = pldm_bios_table_attr_entry_enum_decode_pv_num(entry);
+ return entry->metadata[sizeof(uint8_t) /* pv_num */ +
+ sizeof(uint16_t) * pv_num];
+}
+
+int pldm_bios_table_attr_entry_enum_decode_def_num_check(
+ const struct pldm_bios_attr_table_entry *entry, uint8_t *def_num)
+{
+ POINTER_CHECK(entry);
+ POINTER_CHECK(def_num);
+ ATTR_TYPE_EXPECT(entry->attr_type, PLDM_BIOS_ENUMERATION);
+ *def_num = pldm_bios_table_attr_entry_enum_decode_def_num(entry);
+ return PLDM_SUCCESS;
+}
+
+/** @brief Get length of an enum attribute entry
+ */
+static size_t
+attr_table_entry_length_enum(const struct pldm_bios_attr_table_entry *entry)
+{
+ uint8_t pv_num = pldm_bios_table_attr_entry_enum_decode_pv_num(entry);
+ uint8_t def_num = pldm_bios_table_attr_entry_enum_decode_def_num(entry);
+ return sizeof(*entry) - 1 + sizeof(pv_num) + pv_num * sizeof(uint16_t) +
+ sizeof(def_num) + def_num;
+}
+
+#define ATTR_ENTRY_STRING_LENGTH_MIN \
+ sizeof(uint8_t) /* string type */ + \
+ sizeof(uint16_t) /* minimum string length */ + \
+ sizeof(uint16_t) /* maximum string length */ + \
+ sizeof(uint16_t) /* default string length */
+
+uint16_t pldm_bios_table_attr_entry_string_decode_def_string_length(
+ const struct pldm_bios_attr_table_entry *entry)
+{
+ int def_string_pos = ATTR_ENTRY_STRING_LENGTH_MIN - sizeof(uint16_t);
+ uint16_t def_string_length =
+ *(uint16_t *)(entry->metadata + def_string_pos);
+ return le16toh(def_string_length);
+}
+
+int pldm_bios_table_attr_entry_string_decode_def_string_length_check(
+ const struct pldm_bios_attr_table_entry *entry, uint16_t *def_string_length)
+{
+ POINTER_CHECK(entry);
+ POINTER_CHECK(def_string_length);
+ ATTR_TYPE_EXPECT(entry->attr_type, PLDM_BIOS_STRING);
+ *def_string_length =
+ pldm_bios_table_attr_entry_string_decode_def_string_length(entry);
+ return PLDM_SUCCESS;
+}
+
+/** @brief Get length of a string attribute entry
+ */
+static size_t
+attr_table_entry_length_string(const struct pldm_bios_attr_table_entry *entry)
+{
+ uint16_t def_string_len =
+ pldm_bios_table_attr_entry_string_decode_def_string_length(entry);
+ return sizeof(*entry) - 1 + ATTR_ENTRY_STRING_LENGTH_MIN +
+ def_string_len;
+}
+
+struct attr_table_entry {
+ uint8_t attr_type;
+ size_t (*entry_length_handler)(
+ const struct pldm_bios_attr_table_entry *);
+};
+
+static struct attr_table_entry attr_table_entrys[] = {
+ {.attr_type = PLDM_BIOS_ENUMERATION,
+ .entry_length_handler = attr_table_entry_length_enum},
+ {.attr_type = PLDM_BIOS_ENUMERATION_READ_ONLY,
+ .entry_length_handler = attr_table_entry_length_enum},
+ {.attr_type = PLDM_BIOS_STRING,
+ .entry_length_handler = attr_table_entry_length_string},
+ {.attr_type = PLDM_BIOS_STRING_READ_ONLY,
+ .entry_length_handler = attr_table_entry_length_string},
+};
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
+
+static struct attr_table_entry *find_attr_table_entry_by_type(uint8_t attr_type)
+{
+ size_t i;
+ for (i = 0; i < ARRAY_SIZE(attr_table_entrys); i++) {
+ if (attr_type == attr_table_entrys[i].attr_type)
+ return &attr_table_entrys[i];
+ }
+ return NULL;
+}
+
+static size_t attr_table_entry_length(const void *table_entry)
+{
+ const struct pldm_bios_attr_table_entry *entry = table_entry;
+ struct attr_table_entry *attr_table_entry =
+ find_attr_table_entry_by_type(entry->attr_type);
+ assert(attr_table_entry != NULL);
+ assert(attr_table_entry->entry_length_handler != NULL);
+
+ return attr_table_entry->entry_length_handler(entry);
+}
+
+struct pldm_bios_table_iter {
+ const uint8_t *table_data;
+ size_t table_len;
+ size_t current_pos;
+ size_t (*entry_length_handler)(const void *table_entry);
+};
+
+struct pldm_bios_table_iter *
+pldm_bios_table_iter_create(const void *table, size_t length,
+ enum pldm_bios_table_types type)
+{
+ struct pldm_bios_table_iter *iter = malloc(sizeof(*iter));
+ assert(iter != NULL);
+ iter->table_data = table;
+ iter->table_len = length;
+ iter->current_pos = 0;
+ iter->entry_length_handler = NULL;
+ switch (type) {
+ case PLDM_BIOS_STRING_TABLE:
+ break;
+ case PLDM_BIOS_ATTR_TABLE:
+ iter->entry_length_handler = attr_table_entry_length;
+ break;
+ case PLDM_BIOS_ATTR_VAL_TABLE:
+ break;
+ }
+
+ return iter;
+}
+
+void pldm_bios_table_iter_free(struct pldm_bios_table_iter *iter)
+{
+ free(iter);
+}
+
+#define pad_and_check_max 7
+bool pldm_bios_table_iter_is_end(const struct pldm_bios_table_iter *iter)
+{
+ if (iter->table_len - iter->current_pos <= pad_and_check_max)
+ return true;
+ return false;
+}
+
+void pldm_bios_table_iter_next(struct pldm_bios_table_iter *iter)
+{
+ if (pldm_bios_table_iter_is_end(iter))
+ return;
+ const void *entry = iter->table_data + iter->current_pos;
+ iter->current_pos += iter->entry_length_handler(entry);
+}
+
+const void *pldm_bios_table_iter_value(struct pldm_bios_table_iter *iter)
+{
+ return iter->table_data + iter->current_pos;
+}
\ No newline at end of file
diff --git a/libpldm/bios_table.h b/libpldm/bios_table.h
new file mode 100644
index 0000000..3d17f3c
--- /dev/null
+++ b/libpldm/bios_table.h
@@ -0,0 +1,115 @@
+#ifndef BIOS_TABLE_H__
+#define BIOS_TABLE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "bios.h"
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+/** @struct pldm_bios_table_iter
+ * structure representing bios table iterator
+ */
+struct pldm_bios_table_iter;
+
+/** @brief Create a bios table iterator
+ * @param[in] table - Pointer to table data
+ * @param[in] length - Length of table data
+ * @param[in] type - Type of pldm bios table
+ * @return Iterator to the beginning
+ */
+struct pldm_bios_table_iter *
+pldm_bios_table_iter_create(const void *table, size_t length,
+ enum pldm_bios_table_types type);
+
+/** @brief Release a bios table iterator
+ * @param[in] iter - Pointer to bios table iterator
+ */
+void pldm_bios_table_iter_free(struct pldm_bios_table_iter *iter);
+
+/** @brief Check if the iterator reaches the end of the bios table
+ * @param[in] iter - Pointer to the bios table iterator
+ * @return true if iterator reaches the end
+ * @note *end* is a position after the last entry.
+ */
+bool pldm_bios_table_iter_is_end(const struct pldm_bios_table_iter *iter);
+
+/** @brief Get iterator to next entry
+ * @param[in] iter - Pointer the bios table iterator
+ */
+void pldm_bios_table_iter_next(struct pldm_bios_table_iter *iter);
+
+/** @brief Get the bios table entry that the iterator points to
+ * @param[in] iter - Pointer to the bios table iterator
+ * @return Pointer to an entry in bios table
+ */
+const void *pldm_bios_table_iter_value(struct pldm_bios_table_iter *iter);
+
+/** @brief Get the bios attribute table entry that the iterator points to
+ * @param[in] iter - Pointer the bios attribute table iterator
+ * @return Pointer to an entry in bios attribute table
+ */
+static inline const struct pldm_bios_attr_table_entry *
+pldm_bios_table_iter_attr_entry_value(struct pldm_bios_table_iter *iter)
+{
+ return (const struct pldm_bios_attr_table_entry *)
+ pldm_bios_table_iter_value(iter);
+}
+
+/** @brief Get the total number of possible values for the entry
+ * @param[in] entry - Pointer to bios attribute table entry
+ * @return total number of possible values
+ */
+uint8_t pldm_bios_table_attr_entry_enum_decode_pv_num(
+ const struct pldm_bios_attr_table_entry *entry);
+
+/** @brief Get the total number of possible values for the entry and check the
+ * validity of the parameters
+ * @param[in] entry - Pointer to bios attribute table entry
+ * @param[out] pv_num - Pointer to total number of possible values
+ * @return pldm_completion_codes
+ */
+int pldm_bios_table_attr_entry_enum_decode_pv_num_check(
+ const struct pldm_bios_attr_table_entry *entry, uint8_t *pv_num);
+
+/** @brief Get the total number of default values for the entry
+ * @param[in] entry - Pointer to bios attribute table entry
+ * @return total number of default values
+ */
+uint8_t pldm_bios_table_attr_entry_enum_decode_def_num(
+ const struct pldm_bios_attr_table_entry *entry);
+
+/** @brief Get the total number of default values for the entry and check the
+ * validity of the parameters
+ * @param[in] entry - Pointer to bios attribute table entry
+ * @param[out] def_num - Pointer to total number of default values
+ * @return pldm_completion_codes
+ */
+int pldm_bios_table_attr_entry_enum_decode_def_num_check(
+ const struct pldm_bios_attr_table_entry *entry, uint8_t *def_num);
+
+/** @brief Get the length of default string in bytes for the entry
+ * @param[in] entry - Pointer to bios attribute table entry
+ * @return length of default string in bytes
+ */
+uint16_t pldm_bios_table_attr_entry_string_decode_def_string_length(
+ const struct pldm_bios_attr_table_entry *entry);
+
+/** @brief Get the length of default string in bytes for the entry and check the
+ * validity of the parameters
+ * @param[in] entry - Pointer to bios attribute table entry
+ * @param[out] def_string_length Pointer to length of default string in bytes
+ * @return pldm_completion_codes
+ */
+int pldm_bios_table_attr_entry_string_decode_def_string_length_check(
+ const struct pldm_bios_attr_table_entry *entry,
+ uint16_t *def_string_length);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libpldm/meson.build b/libpldm/meson.build
index 5473c82..4cd9ba3 100644
--- a/libpldm/meson.build
+++ b/libpldm/meson.build
@@ -3,6 +3,7 @@
'pldm_types.h',
'platform.h',
'bios.h',
+ 'bios_table.h',
'states.h',
'fru.h',
'utils.h'
@@ -12,6 +13,7 @@
'base.c',
'platform.c',
'bios.c',
+ 'bios_table.c',
'fru.c',
'utils.c'
]
diff --git a/libpldmresponder/bios.cpp b/libpldmresponder/bios.cpp
index a1288b4..a133b2d 100644
--- a/libpldmresponder/bios.cpp
+++ b/libpldmresponder/bios.cpp
@@ -9,6 +9,7 @@
#include <chrono>
#include <ctime>
#include <iostream>
+#include <memory>
#include <numeric>
#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/log.hpp>
@@ -764,6 +765,30 @@
} // end namespace bios_type_string
+void traverseBIOSAttrTable(const Table& biosAttrTable,
+ AttrTableEntryHandler handler)
+{
+ std::unique_ptr<pldm_bios_table_iter, decltype(&pldm_bios_table_iter_free)>
+ iter(pldm_bios_table_iter_create(biosAttrTable.data(),
+ biosAttrTable.size(),
+ PLDM_BIOS_ATTR_TABLE),
+ pldm_bios_table_iter_free);
+ while (!pldm_bios_table_iter_is_end(iter.get()))
+ {
+ auto table_entry = pldm_bios_table_iter_attr_entry_value(iter.get());
+ try
+ {
+ handler(table_entry);
+ }
+ catch (const std::exception& e)
+ {
+ log<level::ERR>("handler fails when traversing BIOSAttrTable",
+ entry("ERROR=%s", e.what()));
+ }
+ pldm_bios_table_iter_next(iter.get());
+ }
+}
+
using typeHandler =
std::function<void(const BIOSTable& BIOSStringTable,
const char* biosJsonDir, Table& attributeTable)>;
diff --git a/libpldmresponder/bios.hpp b/libpldmresponder/bios.hpp
index 9bb7d23..412e07a 100644
--- a/libpldmresponder/bios.hpp
+++ b/libpldmresponder/bios.hpp
@@ -7,10 +7,12 @@
#include <stdint.h>
+#include <functional>
#include <map>
#include <vector>
#include "libpldm/bios.h"
+#include "libpldm/bios_table.h"
namespace pldm
{
@@ -23,6 +25,12 @@
namespace responder
{
+using AttrTableEntryHandler =
+ std::function<void(const struct pldm_bios_attr_table_entry*)>;
+
+void traverseBIOSAttrTable(const bios::Table& BIOSAttrTable,
+ AttrTableEntryHandler handler);
+
namespace bios
{
/** @brief Register handlers for command from the platform spec
diff --git a/test/libpldm_bios_table_test.cpp b/test/libpldm_bios_table_test.cpp
new file mode 100644
index 0000000..ea94bfe
--- /dev/null
+++ b/test/libpldm_bios_table_test.cpp
@@ -0,0 +1,175 @@
+#include <string.h>
+
+#include <cstring>
+#include <vector>
+
+#include "libpldm/base.h"
+#include "libpldm/bios.h"
+#include "libpldm/bios_table.h"
+
+#include <gtest/gtest.h>
+
+using Table = std::vector<uint8_t>;
+
+void buildTable(Table& table)
+{
+ auto padSize = ((table.size() % 4) ? (4 - table.size() % 4) : 0);
+ table.insert(table.end(), padSize, 0);
+ table.insert(table.end(), sizeof(uint32_t) /*checksum*/, 0);
+}
+
+template <typename First, typename... Rest>
+void buildTable(Table& table, First& first, Rest&... rest)
+{
+ table.insert(table.end(), first.begin(), first.end());
+ buildTable(table, rest...);
+}
+
+TEST(AttrTable, EnumEntryDecodeTest)
+{
+ std::vector<uint8_t> enumEntry{
+ 0, 0, /* attr handle */
+ 0, /* attr type */
+ 1, 0, /* attr name handle */
+ 2, /* number of possible value */
+ 2, 0, /* possible value handle */
+ 3, 0, /* possible value handle */
+ 1, /* number of default value */
+ 0 /* defaut value string handle index */
+ };
+
+ auto entry =
+ reinterpret_cast<struct pldm_bios_attr_table_entry*>(enumEntry.data());
+ uint8_t pvNumber = pldm_bios_table_attr_entry_enum_decode_pv_num(entry);
+ EXPECT_EQ(pvNumber, 2);
+ uint8_t defNumber = pldm_bios_table_attr_entry_enum_decode_def_num(entry);
+ EXPECT_EQ(defNumber, 1);
+
+ pvNumber = 0;
+ auto rc =
+ pldm_bios_table_attr_entry_enum_decode_pv_num_check(entry, &pvNumber);
+ EXPECT_EQ(rc, PLDM_SUCCESS);
+ EXPECT_EQ(pvNumber, 2);
+ defNumber = 0;
+ rc =
+ pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, &defNumber);
+ EXPECT_EQ(rc, PLDM_SUCCESS);
+ EXPECT_EQ(defNumber, 1);
+
+ rc =
+ pldm_bios_table_attr_entry_enum_decode_pv_num_check(nullptr, &pvNumber);
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+ rc = pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, nullptr);
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+ entry->attr_type = PLDM_BIOS_STRING;
+ rc = pldm_bios_table_attr_entry_enum_decode_pv_num_check(entry, &pvNumber);
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+ rc =
+ pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, &defNumber);
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(AttrTable, StringEntryDecodeTest)
+{
+ std::vector<uint8_t> stringEntry{
+ 1, 0, /* attr handle */
+ 1, /* attr type */
+ 12, 0, /* attr name handle */
+ 1, /* string type */
+ 1, 0, /* minimum length of the string in bytes */
+ 100, 0, /* maximum length of the string in bytes */
+ 3, 0, /* length of default string in length */
+ 'a', 'b', 'c' /* default string */
+ };
+
+ auto entry = reinterpret_cast<struct pldm_bios_attr_table_entry*>(
+ stringEntry.data());
+ uint16_t def_string_length =
+ pldm_bios_table_attr_entry_string_decode_def_string_length(entry);
+ EXPECT_EQ(def_string_length, 3);
+
+ def_string_length = 0;
+ auto rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
+ entry, &def_string_length);
+ EXPECT_EQ(rc, PLDM_SUCCESS);
+ EXPECT_EQ(def_string_length, 3);
+
+ rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
+ entry, nullptr);
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+ rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
+ nullptr, &def_string_length);
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+ entry->attr_type = PLDM_BIOS_INTEGER;
+ rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
+ entry, &def_string_length);
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+ rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
+ nullptr, &def_string_length);
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
+TEST(AttrTable, ItearatorTest)
+{
+ std::vector<uint8_t> enumEntry{
+ 0, 0, /* attr handle */
+ 0, /* attr type */
+ 1, 0, /* attr name handle */
+ 2, /* number of possible value */
+ 2, 0, /* possible value handle */
+ 3, 0, /* possible value handle */
+ 1, /* number of default value */
+ 0 /* defaut value string handle index */
+ };
+ std::vector<uint8_t> stringEntry{
+ 1, 0, /* attr handle */
+ 1, /* attr type */
+ 12, 0, /* attr name handle */
+ 1, /* string type */
+ 1, 0, /* minimum length of the string in bytes */
+ 100, 0, /* maximum length of the string in bytes */
+ 3, 0, /* length of default string in length */
+ 'a', 'b', 'c' /* default string */
+ };
+
+ Table table;
+ buildTable(table, enumEntry, stringEntry, enumEntry);
+ auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
+ PLDM_BIOS_ATTR_TABLE);
+ auto entry = pldm_bios_table_iter_attr_entry_value(iter);
+ auto rc = std::memcmp(entry, enumEntry.data(), enumEntry.size());
+ EXPECT_EQ(rc, 0);
+
+ pldm_bios_table_iter_next(iter);
+ entry = pldm_bios_table_iter_attr_entry_value(iter);
+ rc = std::memcmp(entry, stringEntry.data(), stringEntry.size());
+ EXPECT_EQ(rc, 0);
+
+ pldm_bios_table_iter_next(iter);
+ entry = pldm_bios_table_iter_attr_entry_value(iter);
+ rc = std::memcmp(entry, enumEntry.data(), enumEntry.size());
+ EXPECT_EQ(rc, 0);
+
+ pldm_bios_table_iter_next(iter);
+ EXPECT_TRUE(pldm_bios_table_iter_is_end(iter));
+ pldm_bios_table_iter_free(iter);
+}
+
+TEST(Itearator, DeathTest)
+{
+
+ Table table(256, 0);
+
+ /* first entry */
+ auto attr_entry =
+ reinterpret_cast<struct pldm_bios_attr_table_entry*>(table.data());
+ auto iter = pldm_bios_table_iter_create(table.data(), table.size(),
+ PLDM_BIOS_ATTR_TABLE);
+ attr_entry->attr_type = PLDM_BIOS_PASSWORD;
+ EXPECT_DEATH(pldm_bios_table_iter_next(iter), "attr_table_entry != NULL");
+ attr_entry->attr_type = PLDM_BIOS_INTEGER;
+ EXPECT_DEATH(pldm_bios_table_iter_next(iter), "attr_table_entry != NULL");
+ pldm_bios_table_iter_free(iter);
+}
diff --git a/test/libpldmresponder_bios_test.cpp b/test/libpldmresponder_bios_test.cpp
index 417c0ae..1df46cc 100644
--- a/test/libpldmresponder_bios_test.cpp
+++ b/test/libpldmresponder_bios_test.cpp
@@ -5,6 +5,7 @@
#include <string.h>
#include <array>
+#include <cstring>
#include <ctime>
#include <filesystem>
@@ -122,6 +123,56 @@
std::out_of_range);
}
+TEST(traverseBIOSTable, attrTableScenarios)
+{
+ std::vector<uint8_t> enumEntry{
+ 0, 0, /* attr handle */
+ 0, /* attr type */
+ 1, 0, /* attr name handle */
+ 2, /* number of possible value */
+ 2, 0, /* possible value handle */
+ 3, 0, /* possible value handle */
+ 1, /* number of default value */
+ 0 /* defaut value string handle index */
+ };
+ std::vector<uint8_t> stringEntry{
+ 4, 0, /* attr handle */
+ 1, /* attr type */
+ 12, 0, /* attr name handle */
+ 1, /* string type */
+ 1, 0, /* minimum length of the string in bytes */
+ 100, 0, /* maximum length of the string in bytes */
+ 3, 0, /* length of default string in length */
+ 'a', 'b', 'c' /* default string */
+ };
+ std::vector<uint8_t> table;
+ table.insert(table.end(), enumEntry.begin(), enumEntry.end());
+ table.insert(table.end(), stringEntry.begin(), stringEntry.end());
+ auto padSize = ((table.size() % 4) ? (4 - table.size() % 4) : 0);
+
+ table.insert(table.end(), padSize, 0);
+ table.insert(table.end(), sizeof(uint32_t) /*checksum*/, 0);
+
+ pldm::responder::traverseBIOSAttrTable(
+ table, [&](const struct pldm_bios_attr_table_entry* entry) {
+ int rc;
+ switch (entry->attr_type)
+ {
+ case 0:
+ rc = std::memcmp(entry, enumEntry.data(), enumEntry.size());
+ EXPECT_EQ(rc, 0);
+ break;
+ case 1:
+ rc = std::memcmp(entry, stringEntry.data(),
+ stringEntry.size());
+ EXPECT_EQ(rc, 0);
+ break;
+ default:
+ break;
+ }
+ });
+}
+
namespace fs = std::filesystem;
class TestAllBIOSTables : public ::testing::Test
{
diff --git a/test/meson.build b/test/meson.build
index e219db5..db250a7 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -20,6 +20,7 @@
'libpldm_platform_test',
'libpldmresponder_base_test',
'libpldm_bios_test',
+ 'libpldm_bios_table_test',
'libpldmresponder_bios_test',
'libpldmresponder_pdr_state_effecter_test',
'libpldmresponder_bios_table_test',