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 {