Refactor: bios: Construct the attribute value table
when constructing the attribute value table, we need to traverse
the attribute table. But there is a bug in the previous version
when traversing the attribute table.
Now we use the iterator of the last commit implementation to rebuild
attribute value table.
Signed-off-by: John Wang <wangzqbj@inspur.com>
Change-Id: I9fe2b6eabf2b01e124b780fc0fc8615d492c1fed
diff --git a/libpldm/bios_table.c b/libpldm/bios_table.c
index 26d30bf..89f7241 100644
--- a/libpldm/bios_table.c
+++ b/libpldm/bios_table.c
@@ -20,6 +20,12 @@
return PLDM_ERROR_INVALID_DATA; \
} while (0)
+#define BUFFER_SIZE_EXPECT(current_size, expected_size) \
+ do { \
+ if (current_size < expected_size) \
+ return PLDM_ERROR_INVALID_LENGTH; \
+ } while (0)
+
uint8_t pldm_bios_table_attr_entry_enum_decode_pv_num(
const struct pldm_bios_attr_table_entry *entry)
{
@@ -54,6 +60,35 @@
return PLDM_SUCCESS;
}
+uint8_t pldm_bios_table_attr_entry_enum_decode_pv_hdls(
+ const struct pldm_bios_attr_table_entry *entry, uint16_t *pv_hdls,
+ uint8_t pv_num)
+{
+ uint8_t num = pldm_bios_table_attr_entry_enum_decode_pv_num(entry);
+ num = num < pv_num ? num : pv_num;
+ size_t i;
+ for (i = 0; i < num; i++) {
+ uint16_t *hdl = (uint16_t *)(entry->metadata + sizeof(uint8_t) +
+ i * sizeof(uint16_t));
+ pv_hdls[i] = le16toh(*hdl);
+ }
+ return num;
+}
+
+int pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
+ const struct pldm_bios_attr_table_entry *entry, uint16_t *pv_hdls,
+ uint8_t pv_num)
+{
+ POINTER_CHECK(entry);
+ POINTER_CHECK(pv_hdls);
+ ATTR_TYPE_EXPECT(entry->attr_type, PLDM_BIOS_ENUMERATION);
+ uint8_t num = pldm_bios_table_attr_entry_enum_decode_pv_num(entry);
+ if (num != pv_num)
+ return PLDM_ERROR_INVALID_DATA;
+ pldm_bios_table_attr_entry_enum_decode_pv_hdls(entry, pv_hdls, pv_num);
+ return PLDM_SUCCESS;
+}
+
/** @brief Get length of an enum attribute entry
*/
static size_t
@@ -142,6 +177,85 @@
return attr_table_entry->entry_length_handler(entry);
}
+size_t pldm_bios_table_attr_value_entry_encode_enum_length(uint8_t count)
+{
+ return sizeof(struct pldm_bios_attr_val_table_entry) - 1 +
+ sizeof(count) + count;
+}
+
+void pldm_bios_table_attr_value_entry_encode_enum(
+ void *entry, size_t entry_length, uint16_t attr_handle, uint8_t attr_type,
+ uint8_t count, uint8_t *handles)
+{
+ size_t length =
+ pldm_bios_table_attr_value_entry_encode_enum_length(count);
+ assert(length <= entry_length);
+
+ struct pldm_bios_attr_val_table_entry *table_entry = entry;
+ table_entry->attr_handle = htole16(attr_handle);
+ table_entry->attr_type = attr_type;
+ table_entry->value[0] = count;
+ if (count != 0)
+ memcpy(&table_entry->value[1], handles, count);
+}
+
+int pldm_bios_table_attr_value_entry_encode_enum_check(
+ void *entry, size_t entry_length, uint16_t attr_handle, uint8_t attr_type,
+ uint8_t count, uint8_t *handles)
+{
+ POINTER_CHECK(entry);
+ if (count != 0 && handles == NULL)
+ return PLDM_ERROR_INVALID_DATA;
+ ATTR_TYPE_EXPECT(attr_type, PLDM_BIOS_ENUMERATION);
+ size_t length =
+ pldm_bios_table_attr_value_entry_encode_enum_length(count);
+ BUFFER_SIZE_EXPECT(entry_length, length);
+ pldm_bios_table_attr_value_entry_encode_enum(
+ entry, entry_length, attr_handle, attr_type, count, handles);
+ return PLDM_SUCCESS;
+}
+
+size_t
+pldm_bios_table_attr_value_entry_encode_string_length(uint16_t string_length)
+{
+ return sizeof(struct pldm_bios_attr_val_table_entry) - 1 +
+ sizeof(string_length) + string_length;
+}
+
+void pldm_bios_table_attr_value_entry_encode_string(
+ void *entry, size_t entry_length, uint16_t attr_handle, uint8_t attr_type,
+ uint16_t str_length, const char *str)
+{
+ size_t length =
+ pldm_bios_table_attr_value_entry_encode_string_length(str_length);
+ assert(length <= entry_length);
+
+ struct pldm_bios_attr_val_table_entry *table_entry = entry;
+ table_entry->attr_handle = htole16(attr_handle);
+ table_entry->attr_type = attr_type;
+ if (str_length != 0)
+ memcpy(table_entry->value + sizeof(str_length), str,
+ str_length);
+ str_length = htole16(str_length);
+ memcpy(table_entry->value, &str_length, sizeof(str_length));
+}
+
+int pldm_bios_table_attr_value_entry_encode_string_check(
+ void *entry, size_t entry_length, uint16_t attr_handle, uint8_t attr_type,
+ uint16_t str_length, const char *str)
+{
+ POINTER_CHECK(entry);
+ if (str_length != 0 && str == NULL)
+ return PLDM_ERROR_INVALID_DATA;
+ ATTR_TYPE_EXPECT(attr_type, PLDM_BIOS_STRING);
+ size_t length =
+ pldm_bios_table_attr_value_entry_encode_string_length(str_length);
+ BUFFER_SIZE_EXPECT(entry_length, length);
+ pldm_bios_table_attr_value_entry_encode_string(
+ entry, entry_length, attr_handle, attr_type, str_length, str);
+ return PLDM_SUCCESS;
+}
+
struct pldm_bios_table_iter {
const uint8_t *table_data;
size_t table_len;
@@ -196,4 +310,4 @@
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
index 3d17f3c..0b20109 100644
--- a/libpldm/bios_table.h
+++ b/libpldm/bios_table.h
@@ -91,6 +91,30 @@
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 possible values string handles
+ * @param[in] entry - Pointer to bios attribute table entry
+ * @param[out] pv_hdls - Pointer to a buffer to stroe
+ * PossibleValuesStringHandles
+ * @param[in] pv_num - Number of PossibleValuesStringHandles expected
+ * @return pldm_completion_codes
+ */
+uint8_t pldm_bios_table_attr_entry_enum_decode_pv_hdls(
+ const struct pldm_bios_attr_table_entry *entry, uint16_t *pv_hdls,
+ uint8_t pv_num);
+
+/** @brief Get possible values string handles and check the validity of the
+ * parameters
+ * @param[in] entry - Pointer to bios attribute table entry
+ * @param[out] pv_hdls - Pointer to a buffer to stroe
+ * PossibleValuesStringHandles
+ * @param[in] pv_num - Number of PossibleValuesStringHandles the buffer can
+ * stroe
+ * @return Number of PossibleValuesStringHandles decoded
+ */
+int pldm_bios_table_attr_entry_enum_decode_pv_hdls_check(
+ const struct pldm_bios_attr_table_entry *entry, uint16_t *pv_hdls,
+ uint8_t pv_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
@@ -108,6 +132,83 @@
const struct pldm_bios_attr_table_entry *entry,
uint16_t *def_string_length);
+/** @brief Get length that an attribute value entry(type: enum) will take
+ * @param[in] count - Total number of current values for this enumeration
+ * @return The length that an entry(type: enum) will take
+ */
+size_t pldm_bios_table_attr_value_entry_encode_enum_length(uint8_t count);
+
+/** @brief Create an attribute value entry(type: enum)
+ * @param[out] entry - Pointer to bios attribute value entry
+ * @param[in] entry_length - Length of attribute value entry
+ * @param[in] attr_handle - This handle points to an attribute in the
+ * BIOS Attribute Vlaue Table.
+ * @param[in] attr_type - Type of this attribute in the BIOS Attribute Value
+ * Table
+ * @param[in] count - Total number of current values for this enum attribute
+ * @param[in] handle_indexes - Index into the array(provided in the BIOS
+ * Attribute Table) of the possible values of string handles for this attribute.
+ */
+void pldm_bios_table_attr_value_entry_encode_enum(
+ void *entry, size_t entry_length, uint16_t attr_handle, uint8_t attr_type,
+ uint8_t count, uint8_t *handle_indexes);
+
+/** @brief Create an attribute value entry(type: enum) and check the validity of
+ * the parameters
+ * @param[out] entry - Pointer to bios attribute value entry
+ * @param[in] entry_length - Length of attribute value entry
+ * @param[in] attr_handle - This handle points to an attribute in the
+ * BIOS Attribute Vlaue Table.
+ * @param[in] attr_type - Type of this attribute in the BIOS Attribute Value
+ * Table
+ * @param[in] count - Total number of current values for this enum attribute
+ * @param[in] handle_indexes - Index into the array(provided in the BIOS
+ * Attribute Table) of the possible values of string handles for this attribute.
+ * @return pldm_completion_codes
+ */
+int pldm_bios_table_attr_value_entry_encode_enum_check(
+ void *entry, size_t entry_length, uint16_t attr_handle, uint8_t attr_type,
+ uint8_t count, uint8_t *handle_indexes);
+
+/** @brief Get length that an attribute value entry(type: string) will take
+ * @param[in] string_length - Length of the current string in byte, 0 indicates
+ * that the current string value is not set.
+ * @return The length that an entry(type: string) will take
+ */
+size_t
+pldm_bios_table_attr_value_entry_encode_string_length(uint16_t string_length);
+
+/** @brief Create an attribute value entry(type: string)
+ * @param[out] entry - Pointer to bios attribute value entry
+ * @param[in] entry_length - Length of attribute value entry
+ * @param[in] attr_handle - This handle points to an attribute in the
+ * BIOS Attribute Vlaue Table.
+ * @param[in] attr_type - Type of this attribute in the BIOS Attribute Value
+ * Table
+ * @param[in] string_length - Length of current string in bytes. 0 indicates
+ * that the current string value is not set.
+ * @param[in] string - The current string itsel
+ */
+void pldm_bios_table_attr_value_entry_encode_string(
+ void *entry, size_t entry_length, uint16_t attr_handle, uint8_t attr_type,
+ uint16_t string_length, const char *string);
+/** @brief Create an attribute value entry(type: string) and check the validity
+ * of the parameters
+ * @param[out] entry - Pointer to bios attribute value entry
+ * @param[in] entry_length - Length of attribute value entry
+ * @param[in] attr_handle - This handle points to an attribute in the
+ * BIOS Attribute Vlaue Table.
+ * @param[in] attr_type - Type of this attribute in the BIOS Attribute Value
+ * Table
+ * @param[in] string_length - Length of current string in bytes. 0 indicates
+ * that the current string value is not set.
+ * @param[in] string - The current string itsel
+ * @return pldm_completion_codes
+ */
+int pldm_bios_table_attr_value_entry_encode_string_check(
+ void *entry, size_t entry_length, uint16_t attr_handle, uint8_t attr_type,
+ uint16_t string_length, const char *string);
+
#ifdef __cplusplus
}
#endif