bios: Move en/decodes for String Table to libpldm
Move encode/decode functions for BIOS String Table to libpldm.
And implement an iterator to traverse the string table.
Signed-off-by: John Wang <wangzqbj@inspur.com>
Change-Id: I409a935dc6fed0b8a16ac37e11401e82d070612c
diff --git a/libpldm/bios_table.c b/libpldm/bios_table.c
index 89f7241..d9c2505 100644
--- a/libpldm/bios_table.c
+++ b/libpldm/bios_table.c
@@ -26,6 +26,96 @@
return PLDM_ERROR_INVALID_LENGTH; \
} while (0)
+#define MEMBER_SIZE(type, member) sizeof(((struct type *)0)->member)
+
+static uint16_t get_bios_string_handle()
+{
+ static uint16_t handle = 0;
+ assert(handle != UINT16_MAX);
+
+ return handle++;
+}
+
+size_t pldm_bios_table_string_entry_encode_length(uint16_t string_length)
+{
+ return sizeof(struct pldm_bios_string_table_entry) -
+ MEMBER_SIZE(pldm_bios_string_table_entry, name) + string_length;
+}
+
+void pldm_bios_table_string_entry_encode(void *entry, size_t entry_length,
+ const char *str, uint16_t str_length)
+{
+ size_t length = pldm_bios_table_string_entry_encode_length(str_length);
+ assert(length <= entry_length);
+ struct pldm_bios_string_table_entry *string_entry = entry;
+ string_entry->string_handle = htole16(get_bios_string_handle());
+ string_entry->string_length = htole16(str_length);
+ memcpy(string_entry->name, str, str_length);
+}
+
+int pldm_bios_table_string_entry_encode_check(void *entry, size_t entry_length,
+ const char *str,
+ uint16_t str_length)
+{
+ if (str_length == 0)
+ return PLDM_ERROR_INVALID_DATA;
+ POINTER_CHECK(entry);
+ POINTER_CHECK(str);
+ size_t length = pldm_bios_table_string_entry_encode_length(str_length);
+ BUFFER_SIZE_EXPECT(entry_length, length);
+ pldm_bios_table_string_entry_encode(entry, entry_length, str,
+ str_length);
+ return PLDM_SUCCESS;
+}
+
+uint16_t pldm_bios_table_string_entry_decode_handle(
+ const struct pldm_bios_string_table_entry *entry)
+{
+ return le16toh(entry->string_handle);
+}
+
+uint16_t pldm_bios_table_string_entry_decode_string_length(
+ const struct pldm_bios_string_table_entry *entry)
+{
+ return le16toh(entry->string_length);
+}
+
+uint16_t pldm_bios_table_string_entry_decode_string(
+ const struct pldm_bios_string_table_entry *entry, char *buffer, size_t size)
+{
+ uint16_t length =
+ pldm_bios_table_string_entry_decode_string_length(entry);
+ length = length < size ? length : size;
+ memcpy(buffer, entry->name, length);
+ buffer[length] = 0;
+ return length;
+}
+
+int pldm_bios_table_string_entry_decode_string_check(
+ const struct pldm_bios_string_table_entry *entry, char *buffer, size_t size)
+{
+ POINTER_CHECK(entry);
+ POINTER_CHECK(buffer);
+ size_t length =
+ pldm_bios_table_string_entry_decode_string_length(entry);
+ BUFFER_SIZE_EXPECT(size, length + 1);
+ pldm_bios_table_string_entry_decode_string(entry, buffer, size);
+ return PLDM_SUCCESS;
+}
+
+static size_t string_table_entry_length(const void *table_entry)
+{
+ const struct pldm_bios_string_table_entry *entry = table_entry;
+ return sizeof(*entry) - sizeof(entry->name) +
+ pldm_bios_table_string_entry_decode_string_length(entry);
+}
+
+#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)
{
@@ -275,6 +365,7 @@
iter->entry_length_handler = NULL;
switch (type) {
case PLDM_BIOS_STRING_TABLE:
+ iter->entry_length_handler = string_table_entry_length;
break;
case PLDM_BIOS_ATTR_TABLE:
iter->entry_length_handler = attr_table_entry_length;
@@ -311,3 +402,69 @@
{
return iter->table_data + iter->current_pos;
}
+
+static const void *
+pldm_bios_table_entry_find(struct pldm_bios_table_iter *iter, const void *key,
+ int (*equal)(const void *entry, const void *key))
+{
+ const void *entry;
+ while (!pldm_bios_table_iter_is_end(iter)) {
+ entry = pldm_bios_table_iter_value(iter);
+ if (equal(entry, key))
+ return entry;
+ pldm_bios_table_iter_next(iter);
+ }
+ return NULL;
+}
+
+static int string_table_handle_equal(const void *entry, const void *key)
+{
+ const struct pldm_bios_string_table_entry *string_entry = entry;
+ uint16_t handle = *(uint16_t *)key;
+ if (pldm_bios_table_string_entry_decode_handle(string_entry) == handle)
+ return true;
+ return false;
+}
+
+struct string_equal_arg {
+ uint16_t str_length;
+ const char *str;
+};
+
+static int string_table_string_equal(const void *entry, const void *key)
+{
+ const struct pldm_bios_string_table_entry *string_entry = entry;
+ const struct string_equal_arg *arg = key;
+ if (arg->str_length !=
+ pldm_bios_table_string_entry_decode_string_length(string_entry))
+ return false;
+ if (memcmp(string_entry->name, arg->str, arg->str_length) != 0)
+ return false;
+ return true;
+}
+
+const struct pldm_bios_string_table_entry *
+pldm_bios_table_string_find_by_string(const void *table, size_t length,
+ const char *str)
+{
+ uint16_t str_length = strlen(str);
+ struct string_equal_arg arg = {str_length, str};
+ struct pldm_bios_table_iter *iter =
+ pldm_bios_table_iter_create(table, length, PLDM_BIOS_STRING_TABLE);
+ const void *entry =
+ pldm_bios_table_entry_find(iter, &arg, string_table_string_equal);
+ pldm_bios_table_iter_free(iter);
+ return entry;
+}
+
+const struct pldm_bios_string_table_entry *
+pldm_bios_table_string_find_by_handle(const void *table, size_t length,
+ uint16_t handle)
+{
+ struct pldm_bios_table_iter *iter =
+ pldm_bios_table_iter_create(table, length, PLDM_BIOS_STRING_TABLE);
+ const void *entry = pldm_bios_table_entry_find(
+ iter, &handle, string_table_handle_equal);
+ pldm_bios_table_iter_free(iter);
+ return entry;
+}
diff --git a/libpldm/bios_table.h b/libpldm/bios_table.h
index 0b20109..fc9c0eb 100644
--- a/libpldm/bios_table.h
+++ b/libpldm/bios_table.h
@@ -59,6 +59,99 @@
pldm_bios_table_iter_value(iter);
}
+/** @brief Get the bios string table entry that the iterator ponit to
+ * @param[in] iter - Pointer the bios string table iterator
+ * @return Pointer to an entry in bios string table
+ */
+static inline const struct pldm_bios_string_table_entry *
+pldm_bios_table_iter_string_entry_value(struct pldm_bios_table_iter *iter)
+{
+ return (const struct pldm_bios_string_table_entry *)
+ pldm_bios_table_iter_value(iter);
+}
+
+/** @brief Get the length of an entry in the BIOS String Table
+ * @param[in] string_length - Length of string
+ * @return Length of an entry in bytes
+ */
+size_t pldm_bios_table_string_entry_encode_length(uint16_t string_length);
+
+/** @brief Create an entry of BIOS String Table
+ * @param[out] entry - Pointer to a buffer to create an entry
+ * @param[in] entry_length - Length of the buffer to create an entry
+ * @param[in] str - String itself
+ * @param[in] str_length - Length of the string
+ */
+void pldm_bios_table_string_entry_encode(void *entry, size_t entry_length,
+ const char *str, uint16_t str_length);
+
+/** @brief Create an entry of BIOS String Table and check the validity of the
+ * parameters
+ * @param[out] entry - Pointer to a buffer to create an entry
+ * @param[in] entry_length - Length of the buffer to create an entry
+ * @param[in] str - String itself
+ * @param[in] str_length - Length of the string
+ * @return pldm_completion_codes
+ */
+int pldm_bios_table_string_entry_encode_check(void *entry, size_t entry_length,
+ const char *str,
+ uint16_t str_length);
+
+/** @brief Get the string handle for the entry
+ * @param[in] entry - Pointer to a bios string table entry
+ * @return Handle to identify a string in the bios string table
+ */
+uint16_t pldm_bios_table_string_entry_decode_handle(
+ const struct pldm_bios_string_table_entry *entry);
+
+/** @brief Get the string length for the entry
+ * @param[in] entry - Pointer to a bios string table entry
+ * @return Length of string in bytes
+ */
+uint16_t pldm_bios_table_string_entry_decode_string_length(
+ const struct pldm_bios_string_table_entry *entry);
+
+/** @brief Get the string(at most one less than *size* characters) from the
+ * entry
+ * @param[in] entry - Pointer to a bios string table entry
+ * @param[out] buffer - Pointer to a buffer to store the string
+ * @param[in] size - Size of the buffer to store the string
+ * @return Length of the string decoded
+ */
+uint16_t pldm_bios_table_string_entry_decode_string(
+ const struct pldm_bios_string_table_entry *entry, char *buffer,
+ size_t size);
+
+/** @brief Get the string from the entry and check the validity of the
+ * parameters
+ * @param[in] entry - Pointer to a bios string table entry
+ * @param[out] buffer - Pointer to a buffer to store the string
+ * @param[in] size - Size of the buffer to store the string
+ * @return pldm_completion_codes
+ */
+int pldm_bios_table_string_entry_decode_string_check(
+ const struct pldm_bios_string_table_entry *entry, char *buffer,
+ size_t size);
+
+/** @brief Find an entry in bios string table by string
+ * @param[in] table - The BIOS String Table
+ * @param[in] length - Length of the BIOS String Table
+ * @param[in] str - String itself
+ * @return Pointer to an entry in the bios string table
+ */
+const struct pldm_bios_string_table_entry *
+pldm_bios_table_string_find_by_string(const void *table, size_t length,
+ const char *str);
+/** @brief Find an entry in bios string table by handle
+ * @param[in] table - The BIOS String Table
+ * @param[in] length - Length of the BIOS String Table
+ * @param[in] handle - Handle to identify a string in the bios string table
+ * @return Pointer to an entry in the bios string table
+ */
+const struct pldm_bios_string_table_entry *
+pldm_bios_table_string_find_by_handle(const void *table, size_t length,
+ uint16_t handle);
+
/** @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