[Skiboot] [PATCH v3 5/9] core/pldm/test : Implement pldm bios specification test
Abhishek Singh Tomar
abhishek at linux.ibm.com
Wed May 18 17:43:00 AEST 2022
PLDM BIOS specification defines the data structures and
messages for communicating BIOS settings, BIOS attributes,
boot configurations, and boot order settings.
The patch contains test for PLDM_GET_BIOS_TABLE implementation
to get string table, attribute table and value table. It also
contains test for implementaion to find lid.
Signed-off-by: Abhishek Singh Tomar <abhishek at linux.ibm.com>
---
core/pldm/test/Makefile.check | 1 +
core/pldm/test/common/test-pldm-common.c | 1 +
core/pldm/test/test-pldm-bios.c | 289 +++++++++++++++++++++++
3 files changed, 291 insertions(+)
create mode 100644 core/pldm/test/test-pldm-bios.c
diff --git a/core/pldm/test/Makefile.check b/core/pldm/test/Makefile.check
index 7af66ccf..c63b3eeb 100644
--- a/core/pldm/test/Makefile.check
+++ b/core/pldm/test/Makefile.check
@@ -1,5 +1,6 @@
# -*-Makefile-*-
PLDM_TEST := core/pldm/test/test-pldm-fileio \
+ core/pldm/test/test-pldm-bios
LCOV_EXCLUDE += $(PLDM_TEST:%=%.c)
diff --git a/core/pldm/test/common/test-pldm-common.c b/core/pldm/test/common/test-pldm-common.c
index 4acbfd35..8b138454 100644
--- a/core/pldm/test/common/test-pldm-common.c
+++ b/core/pldm/test/common/test-pldm-common.c
@@ -49,6 +49,7 @@ static inline unsigned long mftb(void);
#include "../../pldm-watchdog.c"
#include "../../pldm-fru-requests.c"
#include "../../pldm-platform-requests.c"
+#include "../../pldm-lid-files.c"
#include "../../../device.c"
diff --git a/core/pldm/test/test-pldm-bios.c b/core/pldm/test/test-pldm-bios.c
new file mode 100644
index 00000000..53ee5a32
--- /dev/null
+++ b/core/pldm/test/test-pldm-bios.c
@@ -0,0 +1,289 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+// Copyright 2022 IBM Corp.
+
+#include "common/test-pldm-common.c"
+
+
+#define TEST_BIOS_STRING "hb_lid_ids"
+#define TEST_BIOS_STRING_HANDLE 60
+#define TEST_ATTR_HANDLE 0
+#define TEST_ATTR_STRING_MIN_LEN 0
+#define TEST_ATTR_STRING_MAX_LEN 0
+#define TEST_ATTR_STRING_DEFAULT_LEN 0
+#define TEST_ATTR_STRING_DEFAULT ""
+#define TEST_VALUE_TABLE_CURRENT_STR "ATTR_PERM=81e00663,ATTR_TMP=81e00664,NVRAM=81e0066b"
+#define TEST_VALID_ATTR_NAME "ATTR_TMP"
+
+
+/*
+ * This function duplicates BMC functionality for Pldm self test
+ * It will handle pldm response message
+ * For now we don't have any response
+ */
+int pldm_test_verify_response(void *response_msg, size_t response_len)
+{
+ if (response_len > 0 || response_msg != NULL)
+ return OPAL_PARAMETER;
+
+ return OPAL_PARAMETER;
+
+}
+
+
+int pldm_test_reply_request_bios(void *request_msg, size_t request_len,
+ void **response_msg, size_t *response_len);
+
+/*
+ * This function duplicates BMC functionality for Pldm self test
+ * It generate bios table for self test based on input parameter tabletype
+ */
+uint32_t get_test_table_entry(uint8_t tableType, uint8_t **bios_table,
+ uint32_t *bios_table_length)
+{
+ int pad_len = 0;
+ uint32_t checksum = 0;
+ struct pldm_bios_string_table_entry *string_entry;
+ struct pldm_bios_table_attr_entry_string_info info;
+
+ switch (tableType) {
+
+ case PLDM_BIOS_STRING_TABLE:
+ *bios_table_length = sizeof(struct pldm_bios_string_table_entry)
+ + strlen(TEST_BIOS_STRING) - 1;
+
+ /* calculate padding length */
+ if (*bios_table_length % 4)
+ pad_len = 4 - (*bios_table_length % 4);
+ else
+ pad_len = 0;
+ *bios_table_length += sizeof(uint32_t) + pad_len;
+
+ *bios_table = malloc(*bios_table_length);
+ if (*bios_table == NULL)
+ return OPAL_RESOURCE;
+
+ memset(*bios_table, 0, *bios_table_length);
+
+ string_entry = (struct pldm_bios_string_table_entry *)(*bios_table);
+ string_entry->string_handle = htole16(TEST_BIOS_STRING_HANDLE);
+ string_entry->string_length = htole16(strlen(TEST_BIOS_STRING));
+ memcpy(string_entry->name, TEST_BIOS_STRING, string_entry->string_length);
+ break;
+
+ case PLDM_BIOS_ATTR_TABLE:
+
+ *bios_table_length = sizeof(struct pldm_bios_attr_table_entry)
+ + sizeof(struct attr_table_string_entry_fields)
+ + strlen(TEST_ATTR_STRING_DEFAULT);
+
+ /* calculate padding length */
+ if (*bios_table_length % 4)
+ pad_len = 4 - (*bios_table_length % 4);
+ else
+ pad_len = 0;
+ *bios_table_length += sizeof(uint32_t) + pad_len;
+
+ *bios_table = malloc(*bios_table_length);
+ if (*bios_table == NULL)
+ return OPAL_RESOURCE;
+
+ memset(*bios_table, 0, *bios_table_length);
+
+ info.name_handle = TEST_BIOS_STRING_HANDLE;
+ info.read_only = 0;
+ info.string_type = PLDM_BIOS_STRING;
+ info.min_length = TEST_ATTR_STRING_MIN_LEN;
+ info.max_length = TEST_ATTR_STRING_MAX_LEN;
+ info.def_length = TEST_ATTR_STRING_DEFAULT_LEN;
+ info.def_string = malloc(strlen(TEST_ATTR_STRING_DEFAULT));
+ if (info.def_string == NULL)
+ return OPAL_RESOURCE;
+
+ memcpy((uint8_t *)info.def_string, TEST_ATTR_STRING_DEFAULT,
+ strlen(TEST_ATTR_STRING_DEFAULT));
+ pldm_bios_table_attr_entry_string_encode(*bios_table, *bios_table_length, &info);
+
+ free((uint8_t *)info.def_string);
+ break;
+
+ case PLDM_BIOS_ATTR_VAL_TABLE:
+ *bios_table_length = sizeof(struct pldm_bios_attr_val_table_entry)
+ + sizeof(uint16_t) + sizeof(TEST_VALUE_TABLE_CURRENT_STR) - 1;
+
+ /* calculate padding length */
+ if (*bios_table_length % 4)
+ pad_len = 4 - (*bios_table_length % 4);
+ else
+ pad_len = 0;
+ *bios_table_length += sizeof(uint32_t) + pad_len;
+
+ *bios_table = malloc(*bios_table_length);
+ if (*bios_table == NULL)
+ return OPAL_RESOURCE;
+
+ memset(*bios_table, 0, *bios_table_length);
+
+ pldm_bios_table_attr_value_entry_encode_string(*bios_table, *bios_table_length,
+ TEST_ATTR_HANDLE, PLDM_BIOS_STRING,
+ sizeof(TEST_VALUE_TABLE_CURRENT_STR),
+ TEST_VALUE_TABLE_CURRENT_STR);
+ break;
+ default:
+ printf("PLDM_TEST Failed: INvalid Table type");
+ return OPAL_PARAMETER;
+
+ }
+
+ /* Add padding data */
+ memset(*bios_table + *bios_table_length - sizeof(uint32_t) - pad_len, 0, pad_len);
+
+
+ checksum = htole32(pldm_crc32(*bios_table, *bios_table_length - sizeof(uint32_t)
+ - pad_len));
+ memcpy(*bios_table + *bios_table_length - sizeof(uint32_t), (void *)&checksum,
+ sizeof(uint32_t));
+
+ return OPAL_SUCCESS;
+
+}
+
+/*
+ * This function duplicates BMC functionality for Pldm self test
+ * It will only handle PLDM_BIOS type request
+ * As bios test will have only pldm request of type = PLDM_BIOS
+ */
+int pldm_test_reply_request(void *request_msg, size_t request_len,
+ void **response_msg, size_t *response_len)
+{
+ switch (((struct pldm_msg *)request_msg)->hdr.type) {
+ case PLDM_BIOS:
+ return pldm_test_reply_request_bios(request_msg, request_len,
+ response_msg, response_len);
+
+ default:
+ printf("PLDM_TEST Failed : hdr type %d not expected\n",
+ ((struct pldm_msg *)request_msg)->hdr.type);
+ return OPAL_PARAMETER;
+ }
+
+}
+
+/*
+ * This function duplicates BMC functionality for Pldm self test
+ * it handle PLDM_REQUEST for PLDM_BIOS and reply with appropriate
+ * PLDM_RESPONSE message
+ */
+int pldm_test_reply_request_bios(void *request_msg, size_t request_len,
+ void **response_msg, size_t *response_len)
+{
+ int rc;
+ uint32_t transfer_handle;
+ uint8_t transfer_op_flag, table_type;
+ uint8_t *bios_table;
+ uint32_t bios_table_length = 0;
+ size_t payload_length;
+
+
+
+ /*
+ * check if command send is PLDM_GET_BIOS_TABLE then only
+ * reply response message and return PLDM_SUCCESS
+ * else return error
+ */
+ if (((struct pldm_msg *)request_msg)->hdr.command == PLDM_GET_BIOS_TABLE) {
+ payload_length = request_len - sizeof(struct pldm_msg_hdr);
+ rc = decode_get_bios_table_req(request_msg, payload_length, &transfer_handle,
+ &transfer_op_flag, &table_type);
+ if (rc != PLDM_SUCCESS)
+ return OPAL_PARAMETER;
+
+ /* get table entry to reply request on behalf on BMC for PLDM self test */
+ rc = get_test_table_entry(table_type, &bios_table, &bios_table_length);
+ if (rc != OPAL_SUCCESS)
+ return rc;
+
+ payload_length = bios_table_length + sizeof(struct pldm_get_bios_table_resp) - 1;
+
+ *response_len = sizeof(struct pldm_msg_hdr)
+ + payload_length - 1;
+
+ *response_msg = malloc(*response_len);
+ if (*response_msg == NULL)
+ return OPAL_RESOURCE;
+
+ rc = encode_get_bios_table_resp(((struct pldm_msg *)request_msg)->hdr.instance_id,
+ PLDM_SUCCESS, PLDM_GET_NEXTPART, PLDM_START_AND_END,
+ bios_table, payload_length, *response_msg);
+ if (rc != PLDM_SUCCESS)
+ return OPAL_PARAMETER;
+
+ free(bios_table);
+ return OPAL_SUCCESS;
+ } else
+ return OPAL_PARAMETER;
+
+ return OPAL_SUCCESS;
+}
+
+
+int main(void)
+{
+ size_t rc;
+ char *lid;
+ char name[] = "Error";
+ struct blocklevel_device *bl;
+
+ /*
+ * Attempt to call pldm_bios_find_lid_by_attr_name()
+ * before pldm_bios_init() return error OPAL_HARDWARE
+ */
+ rc = pldm_bios_find_lid_by_attr_name(TEST_VALID_ATTR_NAME, &lid);
+ if (rc != OPAL_HARDWARE) {
+ printf("PLDM_TEST Failed: pldm_bios_find_lid_by_attr_name",
+ " called before pldm_bios_init.",
+ " expected=%d received=%d\n", OPAL_HARDWARE, rc);
+ return rc;
+ }
+
+ /* Init Pldm bios */
+ rc = pldm_bios_init();
+ if (rc != OPAL_SUCCESS) {
+ printf("PLDM_TEST Failed : pldm_bios_init failed received=%d\n", rc);
+ return rc;
+ }
+
+ /*
+ * Attempt to call pldm_bios_find_lid_by_attr_name()
+ * when name argument not present return error OPAL_PARAMETER
+ */
+ rc = pldm_bios_find_lid_by_attr_name(name, &lid);
+ if (rc != OPAL_PARAMETER) {
+
+ printf("PLDM_TEST Failed : pldm_bios_find_lid_by_attr_name",
+ " called when name argument that is not present.",
+ " expected=%d received=%d\n", OPAL_PARAMETER, rc);
+ return rc;
+ }
+
+ /*
+ * Attempt to call pldm_bios_find_lid_by_attr_name()
+ * when name argument present return OPAL_SUCCESS
+ */
+ rc = pldm_bios_find_lid_by_attr_name(TEST_VALID_ATTR_NAME, &lid);
+ if (rc != OPAL_SUCCESS) {
+ printf("PLDM_TEST Failed : pldm_bios_find_lid_by_attr_name",
+ " called when name argument that is present.",
+ " expected=%d received=%d\n", OPAL_PARAMETER, rc);
+ return rc;
+ }
+
+
+ /* Init pldm_lid_files_init */
+ rc = pldm_lid_files_init(&bl);
+ if (rc != OPAL_SUCCESS) {
+ printf("PLDM_TEST Failed : pldm_lid_files_init received=%d\n", rc);
+ return rc;
+ }
+ return 0;
+}
+
--
2.34.1
More information about the Skiboot
mailing list