bios: Move en/decodes for Attribute Table to libpldm
BIOS Attribute Table has various attribute types, the existing
code implements enum/string.
This commit moves the existing encode/decode functions for
BIOS Attribute Table to libplm.
Signed-off-by: John Wang <wangzqbj@inspur.com>
Change-Id: I60757ee346464d3d108d1667e6074a1345e6e150
diff --git a/libpldm/bios_table.c b/libpldm/bios_table.c
index d9c2505..8782a16 100644
--- a/libpldm/bios_table.c
+++ b/libpldm/bios_table.c
@@ -110,6 +110,72 @@
pldm_bios_table_string_entry_decode_string_length(entry);
}
+static uint16_t get_bios_attr_handle()
+{
+ static uint16_t handle = 0;
+ assert(handle != UINT16_MAX);
+
+ return handle++;
+}
+
+static void attr_table_entry_encode_header(void *entry, size_t length,
+ uint8_t attr_type,
+ uint16_t string_handle)
+{
+ struct pldm_bios_attr_table_entry *attr_entry = entry;
+ assert(sizeof(*attr_entry) <= length);
+ attr_entry->attr_handle = htole16(get_bios_attr_handle());
+ attr_entry->attr_type = attr_type;
+ attr_entry->string_handle = htole16(string_handle);
+}
+
+size_t pldm_bios_table_attr_entry_enum_encode_length(uint8_t pv_num,
+ uint8_t def_num)
+{
+ return sizeof(struct pldm_bios_attr_table_entry) -
+ MEMBER_SIZE(pldm_bios_attr_table_entry, metadata) +
+ sizeof(pv_num) + pv_num * sizeof(uint16_t) + sizeof(def_num) +
+ def_num;
+}
+
+void pldm_bios_table_attr_entry_enum_encode(
+ void *entry, size_t entry_length,
+ const struct pldm_bios_table_attr_entry_enum_info *info)
+{
+ size_t length = pldm_bios_table_attr_entry_enum_encode_length(
+ info->pv_num, info->def_num);
+ assert(length <= entry_length);
+ uint8_t attr_type = info->read_only ? PLDM_BIOS_ENUMERATION_READ_ONLY
+ : PLDM_BIOS_ENUMERATION;
+ attr_table_entry_encode_header(entry, entry_length, attr_type,
+ info->name_handle);
+ struct pldm_bios_attr_table_entry *attr_entry = entry;
+ attr_entry->metadata[0] = info->pv_num;
+ uint16_t *pv_hdls =
+ (uint16_t *)(attr_entry->metadata + 1 /* sizeof(pv num) */);
+ size_t i;
+ for (i = 0; i < info->pv_num; i++)
+ pv_hdls[i] = htole16(info->pv_handle[i]);
+ attr_entry->metadata[1 + info->pv_num * sizeof(uint16_t)] =
+ info->def_num;
+ memcpy(attr_entry->metadata + 1 /* sizeof(pv num) */ +
+ info->pv_num * sizeof(uint16_t) + 1 /* sizeof(def num)*/,
+ info->def_index, info->def_num);
+}
+
+int pldm_bios_table_attr_entry_enum_encode_check(
+ void *entry, size_t entry_length,
+ const struct pldm_bios_table_attr_entry_enum_info *info)
+{
+ POINTER_CHECK(entry);
+ POINTER_CHECK(info);
+ size_t length = pldm_bios_table_attr_entry_enum_encode_length(
+ info->pv_num, info->def_num);
+ BUFFER_SIZE_EXPECT(entry_length, length);
+ pldm_bios_table_attr_entry_enum_encode(entry, entry_length, info);
+ return PLDM_SUCCESS;
+}
+
#define ATTR_TYPE_EXPECT(type, expected) \
do { \
if (type != expected && type != (expected | 0x80)) \
@@ -186,23 +252,74 @@
{
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;
+ return pldm_bios_table_attr_entry_enum_encode_length(pv_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 */
+struct attr_table_string_entry_fields {
+ uint8_t string_type;
+ uint16_t min_length;
+ uint16_t max_length;
+ uint16_t def_length;
+ uint8_t def_string[1];
+} __attribute__((packed));
+
+size_t pldm_bios_table_attr_entry_string_encode_length(uint16_t def_str_len)
+{
+ return sizeof(struct pldm_bios_attr_table_entry) -
+ MEMBER_SIZE(pldm_bios_attr_table_entry, metadata) +
+ sizeof(struct attr_table_string_entry_fields) -
+ MEMBER_SIZE(attr_table_string_entry_fields, def_string) +
+ def_str_len;
+}
+
+void pldm_bios_table_attr_entry_string_encode(
+ void *entry, size_t entry_length,
+ const struct pldm_bios_table_attr_entry_string_info *info)
+{
+ size_t length =
+ pldm_bios_table_attr_entry_string_encode_length(info->def_length);
+ assert(length <= entry_length);
+ uint8_t attr_type =
+ info->read_only ? PLDM_BIOS_STRING_READ_ONLY : PLDM_BIOS_STRING;
+ attr_table_entry_encode_header(entry, entry_length, attr_type,
+ info->name_handle);
+ struct pldm_bios_attr_table_entry *attr_entry = entry;
+ struct attr_table_string_entry_fields *attr_fields =
+ (struct attr_table_string_entry_fields *)attr_entry->metadata;
+ attr_fields->string_type = info->string_type;
+ attr_fields->min_length = htole16(info->min_length);
+ attr_fields->max_length = htole16(info->max_length);
+ attr_fields->def_length = htole16(info->def_length);
+ if (info->def_length != 0 && info->def_string != NULL)
+ memcpy(attr_fields->def_string, info->def_string,
+ info->def_length);
+}
+
+int pldm_bios_table_attr_entry_string_encode_check(
+ void *entry, size_t entry_length,
+ const struct pldm_bios_table_attr_entry_string_info *info)
+{
+ POINTER_CHECK(entry);
+ POINTER_CHECK(info);
+ size_t length =
+ pldm_bios_table_attr_entry_string_encode_length(info->def_length);
+ BUFFER_SIZE_EXPECT(entry_length, length);
+ if (info->def_length > info->max_length ||
+ info->def_length < info->min_length ||
+ info->min_length > info->max_length)
+ return PLDM_ERROR_INVALID_DATA;
+ if (info->string_type > 5 && info->string_type != 0xFF)
+ return PLDM_ERROR_INVALID_DATA;
+ pldm_bios_table_attr_entry_string_encode(entry, entry_length, info);
+ return PLDM_SUCCESS;
+}
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);
+ struct attr_table_string_entry_fields *fields =
+ (struct attr_table_string_entry_fields *)entry->metadata;
+ return le16toh(fields->def_length);
}
int pldm_bios_table_attr_entry_string_decode_def_string_length_check(
@@ -221,10 +338,9 @@
static size_t
attr_table_entry_length_string(const struct pldm_bios_attr_table_entry *entry)
{
- uint16_t def_string_len =
+ uint16_t def_str_len =
pldm_bios_table_attr_entry_string_decode_def_string_length(entry);
- return sizeof(*entry) - 1 + ATTR_ENTRY_STRING_LENGTH_MIN +
- def_string_len;
+ return pldm_bios_table_attr_entry_string_encode_length(def_str_len);
}
struct attr_table_entry {
diff --git a/libpldm/bios_table.h b/libpldm/bios_table.h
index fc9c0eb..97c64ce 100644
--- a/libpldm/bios_table.h
+++ b/libpldm/bios_table.h
@@ -152,6 +152,51 @@
pldm_bios_table_string_find_by_handle(const void *table, size_t length,
uint16_t handle);
+/** @struct pldm_bios_table_attr_entry_enum_info
+ *
+ * An auxiliary structure for passing parameters to @ref
+ * pldm_bios_table_attr_entry_enum_encode
+ *
+ */
+struct pldm_bios_table_attr_entry_enum_info {
+ uint16_t name_handle; //!< attribute name handle
+ bool read_only; //!< indicate whether the attribute is read-only
+ uint8_t pv_num; //!< number of possible values
+ const uint16_t *pv_handle; //!< handles of possible values
+ uint8_t def_num; //!< nnumber of default values
+ const uint8_t *def_index; //!< indices of default values.
+};
+
+/** @brief Get length that an attribute entry(type: enum) will take
+ * @param[in] pv_num - Number of possible values
+ * @param[in] def_num - Number of default values
+ * @return The length that an entry(type: enum) will take
+ */
+size_t pldm_bios_table_attr_entry_enum_encode_length(uint8_t pv_num,
+ uint8_t def_num);
+
+/** @brief Create an entry of BIOS Attribute Table (type: enum)
+ * @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] info - Pointer to an auxiliary structure @ref
+ * pldm_bios_table_attr_entry_enum_info
+ */
+void pldm_bios_table_attr_entry_enum_encode(
+ void *entry, size_t entry_length,
+ const struct pldm_bios_table_attr_entry_enum_info *info);
+
+/** @brief Create an entry of BIOS Attribute Table (type: enum) 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] info - Pointer to an auxiliary structure @ref
+ * pldm_bios_table_attr_entry_enum_info
+ * @return pldm_completion_codes
+ */
+int pldm_bios_table_attr_entry_enum_encode_check(
+ void *entry, size_t entry_length,
+ const struct pldm_bios_table_attr_entry_enum_info *info);
+
/** @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
@@ -208,6 +253,50 @@
const struct pldm_bios_attr_table_entry *entry, uint16_t *pv_hdls,
uint8_t pv_num);
+/** @struct pldm_bios_table_attr_entry_string_info
+ *
+ * An auxiliary structure for passing parameters to @ref
+ * pldm_bios_table_attr_entry_string_encode
+ *
+ */
+struct pldm_bios_table_attr_entry_string_info {
+ uint16_t name_handle; //!< attribute name handle
+ bool read_only; //!< indicate whether the attribute is read-only
+ uint8_t string_type; //!< The type of the string
+ uint16_t min_length; //!< The minimum length of the string in bytes
+ uint16_t max_length; //!< The maximum length of the string in bytes
+ uint16_t def_length; //!< The length of the defaut string in bytes
+ const char *def_string; //!< The default string itself
+};
+
+/** @brief Get length that an attribute entry(type: string) will take
+ * @param[in] def_str_len - Length of default string
+ * @return The length that an entry(type: string) will take
+ */
+size_t pldm_bios_table_attr_entry_string_encode_length(uint16_t def_str_len);
+
+/** @brief Create an entry of BIOS Attribute Table (type: string)
+ * @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] info - Pointer to an auxiliary structure @ref
+ * pldm_bios_table_attr_entry_string_info
+ */
+void pldm_bios_table_attr_entry_string_encode(
+ void *entry, size_t entry_length,
+ const struct pldm_bios_table_attr_entry_string_info *info);
+
+/** @brief Create an entry of BIOS Attribute Table (type: string) 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] info - Pointer to an auxiliary structure @ref
+ * pldm_bios_table_attr_entry_string_info
+ * @return pldm_completion_codes
+ */
+int pldm_bios_table_attr_entry_string_encode_check(
+ void *entry, size_t entry_length,
+ const struct pldm_bios_table_attr_entry_string_info *info);
+
/** @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