[Skiboot] [PATCH 1/4] core/pldm/test : pldm file io test
Abhishek Singh Tomar
abhishek at linux.ibm.com
Wed May 4 16:55:52 AEST 2022
The self test for PLDM FIle IO implementation
Signed-off-by: Abhishek Singh Tomar <abhishek at linux.ibm.com>
---
core/pldm/pldm-file-io-requests.c | 12 +-
core/pldm/pldm.h | 2 +-
core/pldm/test/Makefile.check | 42 ++++
core/pldm/test/common/test_pldm-common.c | 181 ++++++++++++++
core/pldm/test/test_pldm-fileio.c | 303 +++++++++++++++++++++++
5 files changed, 538 insertions(+), 2 deletions(-)
create mode 100644 core/pldm/test/Makefile.check
create mode 100644 core/pldm/test/common/test_pldm-common.c
create mode 100644 core/pldm/test/test_pldm-fileio.c
diff --git a/core/pldm/pldm-file-io-requests.c b/core/pldm/pldm-file-io-requests.c
index 94828fcd..50ddb0e4 100644
--- a/core/pldm/pldm-file-io-requests.c
+++ b/core/pldm/pldm-file-io-requests.c
@@ -155,9 +155,15 @@ static int read_file_req(uint32_t file_handle, uint32_t file_length,
file_req.length = MAX_TRANSFER_SIZE_BYTES;
}
+#ifndef __TEST__
prlog(PR_TRACE, "%s - file_handle: %d, offset: 0x%x, size: 0x%llx num_transfers: %d\n",
__func__, file_handle, file_req.offset,
size, num_transfers);
+#else
+ prlog(PR_TRACE, "%s - file_handle: %d, offset: 0x%x, size: 0x%lx num_transfers: %d\n",
+ __func__, file_handle, file_req.offset,
+ size, num_transfers);
+#endif
for (i = 0; i < num_transfers; i++) {
file_req.offset = offset + (i * MAX_TRANSFER_SIZE_BYTES);
@@ -210,9 +216,13 @@ static int read_file_req(uint32_t file_handle, uint32_t file_length,
total_read += resp_length;
curr_buf += resp_length;
free(response_msg);
-
+#ifndef __TEST__
prlog(PR_TRACE, "%s - file_handle: %d, resp_length: 0x%x, total_read: 0x%llx\n",
__func__, file_handle, resp_length, total_read);
+#else
+ prlog(PR_TRACE, "%s - file_handle: %d, resp_length: 0x%x, total_read: 0x%lx\n",
+ __func__, file_handle, resp_length, total_read);
+#endif
if (total_read == size)
break;
diff --git a/core/pldm/pldm.h b/core/pldm/pldm.h
index 81df9f8b..5ac9c443 100644
--- a/core/pldm/pldm.h
+++ b/core/pldm/pldm.h
@@ -45,7 +45,7 @@ extern int watchdog_period_sec;
* @example enum_bit(1) = 0x00000002
* @example enum_bit(4) = 0x00000010
*/
-inline uint32_t enum_bit(unsigned int enumeration)
+extern inline uint32_t enum_bit(unsigned int enumeration)
{
return 1 << enumeration;
}
diff --git a/core/pldm/test/Makefile.check b/core/pldm/test/Makefile.check
new file mode 100644
index 00000000..42d60993
--- /dev/null
+++ b/core/pldm/test/Makefile.check
@@ -0,0 +1,42 @@
+# -*-Makefile-*-
+PLDM_TEST := core/pldm/test/test_pldm-fileio \
+
+LCOV_EXCLUDE += $(PLDM_TEST:%=%.c)
+
+.PHONY : core-pldm-check core-pldm-coverage
+core-pldm-check: $(PLDM_TEST:%=%-check)
+core-pldm-coverage: $(PLDM_TEST:%=%-gcov-run)
+HOSTCFLAG_PLDM:= $(filter-out -Wdeclaration-after-statement,$(HOSTCFLAGS))
+HOSTCFLAG_PLDM:= $(filter-out -Wstrict-prototypes,$(HOSTCFLAG_PLDM))
+HOSTCFLAG_PLDM:= $(filter-out -Wjump-misses-init,$(HOSTCFLAG_PLDM))
+HOSTCFLAG_PLDM:= $(filter-out -Wmissing-prototypes,$(HOSTCFLAG_PLDM))
+HOSTCFLAG_PLDM:= $(filter-out -Wmissing-declarations,$(HOSTCFLAG_PLDM))
+
+check: core-pldm-check
+coverage: core-pldm-coverage
+
+$(PLDM_TEST:%=%-gcov-run) : %-run: %
+ $(call Q, TEST-COVERAGE ,$< , $<)
+
+$(PLDM_TEST:%=%-check) : %-check: %
+ $(call Q, RUN-TEST ,$(VALGRIND) $<, $<)
+
+core/test/stubs.o: core/test/stubs.c
+ $(call Q, HOSTCC ,$(HOSTCC) $(HOSTCFLAGS) -I . -I include -Wno-error=attributes -g -c -o core/test/stubs.o core/test/stubs.c, $<)
+
+$(PLDM_TEST) : % : %.c core/test/stubs.o
+ $(call Q, HOSTCC ,$(HOSTCC) $(HOSTCFLAG_PLDM) -O0 -g -I include -I . -I pldm/libpldm/ -I libfdt -o $@ $< core/test/stubs.o -g, $<)
+
+$(PLDM_TEST:%=%-gcov): %-gcov : %.c %
+ $(call Q, HOSTCC ,$(HOSTCC) $(HOSTFLAG_PLDM) $(HOSTGCOVCFLAGS) -I include -I . -I pldm/libpldm/ -I libfdt -lgcov -o $@ $<, $<)
+
+$(PLDM_TEST:%=%-gcov): % : $(%.d:-gcov=)
+
+-include $(wildcard core/pldm/test/*.d)
+
+clean: pldm-test-clean
+
+pldm-test-clean:
+ $(RM) -f core/pldm/test/*.[od] $(PLDM_TEST) $(PLDM_TEST:%=%-gcov)
+ $(RM) -f *.gcda *.gcno skiboot.info
+ $(RM) -rf coverage-report
diff --git a/core/pldm/test/common/test_pldm-common.c b/core/pldm/test/common/test_pldm-common.c
new file mode 100644
index 00000000..8a6d12b9
--- /dev/null
+++ b/core/pldm/test/common/test_pldm-common.c
@@ -0,0 +1,181 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <types.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include <timer.h>
+#include <ccan/list/list.h>
+#include <ccan/short_types/short_types.h>
+
+#define __LITTLE_ENDIAN_BITFIELD
+#define __TEST__
+#define __SKIBOOT__
+#define zalloc(bytes) calloc((bytes), 1)
+static inline unsigned long mftb(void);
+#include <timebase.h>
+#include <op-panel.h>
+#include <include/platform.h>
+#include "../../pldm.h"
+#include <include/pldm.h>
+#include <ast.h>
+#ifdef ARRAY_SIZE
+#undef ARRAY_SIZE
+#endif
+
+
+#include <pldm/libpldm/bios_table.h>
+#include <pldm/libpldm/bios_table.c>
+#undef pr_fmt
+#include "../../pldm-bios-requests.c"
+#include <pldm/libpldm/base.c>
+#include <pldm/libpldm/pdr.c>
+#include <pldm/libpldm/bios.c>
+#include <pldm/libpldm/platform.c>
+#include <pldm/libpldm/utils.c>
+#include <pldm/ibm/libpldm/file_io.c>
+#include <pldm/libpldm/fru.c>
+#include "../../pldm-file-io-requests.c"
+#include "../../pldm-requester.c"
+#include "../../pldm-common.c"
+#include "../../pldm-responder.c"
+#include "../../pldm-base-requests.c"
+#include "../../pldm-watchdog.c"
+#include "../../pldm-fru-requests.c"
+#include "../../pldm-platform-requests.c"
+#include "../../../device.c"
+
+
+
+char __rodata_start[1], __rodata_end[1];
+unsigned long tb_hz = 512000000;
+struct dt_node *dt_root;
+struct debug_descriptor debug_descriptor;
+struct platform platform;
+
+int pldm_test_reply_request(void *request_msg, size_t request_len,
+ void **response_msg, size_t *response_len);
+int pldm_test_verify_response(void *response_msg, size_t response_len);
+
+void time_wait_ms(unsigned long ms)
+{
+ usleep(ms * 1000);
+}
+void init_timer(struct timer *t, timer_func_t expiry, void *data)
+{
+ t->link.next = t->link.prev = NULL;
+ t->target = 0;
+ t->expiry = expiry;
+ t->user_data = data;
+ t->running = NULL;
+}
+uint64_t schedule_timer(struct timer *t, uint64_t how_long)
+{
+ if (t != NULL)
+ return how_long;
+ return 0;
+}
+void cancel_timer(struct timer *t)
+{
+ t->link.next = t->link.prev = NULL;
+}
+
+static inline unsigned long mftb(void)
+{
+ unsigned long clk;
+
+ clk = clock();
+ return clk;
+}
+
+int ast_mctp_init(void (*fn)(uint8_t src_eid, bool tag_owner, uint8_t msg_tag, void *data,
+ void *msg, size_t len))
+{
+ if (fn != NULL)
+ return PLDM_SUCCESS;
+ return PLDM_ERROR_INVALID_DATA;
+}
+
+int ast_mctp_message_tx(uint8_t eid, uint8_t *msg, int len)
+{
+ int ret;
+ uint8_t *pldm_received_msg = msg+1;
+ void *response_msg;
+ char *vmsg;
+ size_t response_len;
+
+ // TEST if eid is BMC_ID
+ if (eid != BMC_EID)
+ return OPAL_PARAMETER;
+
+ // TEST if Message TYPE: PLDM = 0x01 (000_0001b) as per MCTP - DSP0240
+
+ if (msg[0] != 0x01) {
+ printf("TEST : %s : request MCTP message type not set for PLDM\n", __func__);
+ return OPAL_PARAMETER;
+ }
+
+ if (((struct pldm_msg *)pldm_received_msg)->hdr.request == PLDM_RESPONSE) {
+ ret = pldm_test_verify_response(pldm_received_msg, len-1);
+ if (ret != PLDM_SUCCESS)
+ return ret;
+ }
+
+// Reply to requests
+ else if (((struct pldm_msg *)pldm_received_msg)->hdr.request == PLDM_REQUEST) {
+ ret = pldm_test_verify_response(pldm_received_msg, len-1);
+ ret = pldm_test_reply_request(pldm_received_msg, len-1,
+ &response_msg, &response_len);
+ if (ret != PLDM_SUCCESS)
+ return ret;
+ vmsg = malloc(response_len+1);
+ // TYPE: PLDM = 0x01 (000_0001b) as per MCTP - DSP0240
+ vmsg[0] = 0x01;
+ memcpy(vmsg + 1, response_msg, response_len);
+
+ pldm_rx_message(BMC_EID, 0, 0, NULL, vmsg, response_len+1);
+ }
+
+ return PLDM_SUCCESS;
+}
+
+void ast_mctp_exit(void)
+{
+ return;
+}
+
+void lock_caller(struct lock *l, const char *caller)
+{
+ (void)caller;
+ assert(!l->lock_val);
+ l->lock_val++;
+}
+
+int _opal_queue_msg(enum opal_msg_type msg_type, void *data,
+ void (*consumed)(void *data, int status),
+ size_t params_size, const void *params)
+{
+ (void)msg_type;
+ if (data != NULL || consumed != NULL)
+ return OPAL_PARAMETER;
+ if (params != NULL && params_size > 0)
+ return OPAL_PARAMETER;
+ return PLDM_SUCCESS;
+
+}
+
+
+void unlock(struct lock *l)
+{
+ assert(l->lock_val);
+ l->lock_val = 0;
+}
+
+void prd_occ_reset(uint32_t proc)
+{
+ (void)proc;
+}
+
diff --git a/core/pldm/test/test_pldm-fileio.c b/core/pldm/test/test_pldm-fileio.c
new file mode 100644
index 00000000..bf6cbfce
--- /dev/null
+++ b/core/pldm/test/test_pldm-fileio.c
@@ -0,0 +1,303 @@
+#include "common/test_pldm-common.c"
+
+
+#define TEST_FILE_IO_NAME "81e0066b.lid"
+#define TEST_FILE_IO_HANDLE 11
+#define TEST_FILE_IO_LENGTH 50
+#define TEST_FILE_IO_BUF1 "This is Test buffer Open power Foundation"
+
+void *pldm_file_io_buff[TEST_FILE_IO_LENGTH];
+uint32_t test_Filetable_entry_generate(uint8_t **file_attr_table);
+int pldm_test_reply_request_file_io(void *request_msg, size_t request_len,
+ void **response_msg, size_t *response_len);
+
+int pldm_test_reply_request(void *request_msg, size_t request_len,
+ void **response_msg, size_t *response_len);
+
+
+/*
+ * This function tries to duplicate 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;
+
+}
+
+/*
+ * This function tries to duplicate BMC functionality for Pldm self test
+ * This Genrate Filetable entry for self test
+ * The file table contains the list of files available and
+ * their attributes.
+ *
+ * Ex:
+ * {
+ * "FileHandle": "11",
+ * "FileNameLength": 12,
+ * "FileName": "81e0066b.lid",
+ * "FileSize": 589824,
+ * "FileTraits": 6
+ * }
+ */
+uint32_t test_Filetable_entry_generate(uint8_t **file_attr_table)
+{
+ struct pldm_file_attr_table_entry *pldm_file_attr_table_entry;
+ uint8_t FileName[] = TEST_FILE_IO_NAME;
+ uint32_t file_length = TEST_FILE_IO_LENGTH;
+ int size;
+
+ // calculate sizeof whole struct
+ size = sizeof(struct pldm_file_attr_table_entry *) + strlen(FileName)
+ + sizeof(file_length) - 1;
+ *file_attr_table = malloc(size);
+
+ pldm_file_attr_table_entry = (struct pldm_file_attr_table_entry *)*file_attr_table;
+ pldm_file_attr_table_entry->file_handle = TEST_FILE_IO_HANDLE;
+ pldm_file_attr_table_entry->file_name_length = strlen(FileName);
+ memcpy(pldm_file_attr_table_entry->file_attr_table_nst, FileName,
+ strlen(FileName));
+
+ memcpy(pldm_file_attr_table_entry->file_attr_table_nst + strlen(FileName),
+ (uint8_t *)&file_length, sizeof(file_length));
+
+ return size;
+
+
+}
+/*
+ * This function tries to duplicate BMC functionality for Pldm self test
+ * It will only handle PLDM_OEM type request
+ * As fileio test will have only pldm request of type = PLDM_OEM
+ */
+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_OEM:
+ return pldm_test_reply_request_file_io(request_msg, request_len,
+ response_msg, response_len);
+ default:
+ printf("PLDM_TEST: Not equal to PLDM_OEM\n");
+ return OPAL_PARAMETER;
+ }
+
+
+}
+
+
+/*
+ * This function tries to duplicate BMC functionality for Pldm self test
+ * it tries to handle PLDM_REQUEST for fileio and reply with appropriate PLDM_RESPONSE
+ * message
+ */
+int pldm_test_reply_request_file_io(void *request_msg, size_t request_len,
+ void **response_msg, size_t *response_len)
+{
+ int size = 0;
+ int ret;
+ void *payload_data;
+ int payload_len = 0;
+ uint32_t offset; //!< Offset to file where write starts
+ uint32_t length;
+ uint32_t file_handle; //!< Handle to file
+ size_t file_data_offset = 0;
+ uint32_t transfer_handle;
+ uint8_t transfer_opflag;
+ uint8_t table_type;
+ uint8_t *file_attr_table;
+ uint32_t table_size;
+ struct pldm_write_file_req file_req;
+
+
+// check command received and reply with appropriate pldm response message
+ switch (((struct pldm_msg *)request_msg)->hdr.command) {
+ case PLDM_GET_FILE_TABLE:
+
+ payload_len = request_len - sizeof(struct pldm_msg_hdr);
+
+ ret = decode_get_file_table_req(request_msg, payload_len, &transfer_handle,
+ &transfer_opflag, &table_type);
+ if (ret != PLDM_SUCCESS)
+ return ret;
+
+ // Generate Filetable entry for self test
+ table_size = test_Filetable_entry_generate(&file_attr_table);
+
+ *response_len = sizeof(struct pldm_msg_hdr)
+ + sizeof(struct pldm_get_file_table_resp)
+ + table_size - 1;
+ *response_msg = malloc(*response_len);
+
+ ret = encode_get_file_table_resp(((struct pldm_msg *)request_msg)->hdr.instance_id,
+ PLDM_SUCCESS, PLDM_GET_NEXTPART, PLDM_START_AND_END,
+ file_attr_table, table_size, *response_msg);
+ if (ret != PLDM_SUCCESS)
+ return ret;
+
+ free(file_attr_table);
+
+ break;
+ case PLDM_WRITE_FILE:
+
+ payload_len = request_len - sizeof(struct pldm_msg_hdr);
+
+
+ ret = decode_write_file_req(request_msg, payload_len, &file_handle,
+ &offset, &length, &file_data_offset);
+ if (ret != PLDM_SUCCESS)
+ return ret;
+
+ // TEST : if file handle received is same as that we send while making
+ // call to pldm request (i.e. TEST_FILE_IO_HANDLE).
+ // so PLDM message are recieved without any distortion in path.
+ if (file_handle != TEST_FILE_IO_HANDLE)
+ return PLDM_ERROR_INVALID_DATA;
+
+ payload_data = ((struct pldm_msg *)request_msg)->payload
+ + sizeof(file_req.file_handle)
+ + sizeof(file_req.offset)
+ + sizeof(file_req.length);
+
+ memcpy(pldm_file_io_buff, payload_data, length);
+
+ // TEST : if file buff received is same as that we send while making
+ // call to pldm request (i.e TEST_FILE_IO_BUF1).
+ // so PLDM message are transferred without distortion in path.
+ if (strncmp(TEST_FILE_IO_BUF1, (char *)payload_data, length) != 0) {
+ perror("TEST :: String not matched");
+ return PLDM_ERROR_INVALID_DATA;
+ }
+ *response_len = sizeof(struct pldm_msg_hdr) +
+ sizeof(struct pldm_write_file_resp);
+ *response_msg = malloc(*response_len);
+
+ ret = encode_write_file_resp(
+ ((struct pldm_msg *)request_msg)->hdr.instance_id,
+ PLDM_SUCCESS, size, *response_msg);
+ if (ret != PLDM_SUCCESS)
+ return ret;
+
+ break;
+ case PLDM_READ_FILE:
+
+ payload_len = request_len - sizeof(struct pldm_msg_hdr);
+ ret = decode_read_file_req(request_msg, payload_len, &file_handle, &offset,
+ &length);
+
+ if (ret != PLDM_SUCCESS)
+ return ret;
+
+ // TEST : if file handle received is same as that we send while making
+ // call to pldm request (i.e. TEST_FILE_IO_HANDLE).
+ // so PLDM message are transferred without any distortion in path.
+ if (file_handle != TEST_FILE_IO_HANDLE) {
+ perror("TEST :: File Handle not matched");
+ return PLDM_ERROR_INVALID_DATA;
+
+ }
+
+ // check if length + offset < TEST_FILE_IO_LENGTH
+ // so required data length can be readed
+ if (file_handle != TEST_FILE_IO_HANDLE ||
+ length + offset > TEST_FILE_IO_LENGTH) {
+ perror("TEST : length+offset Invalid");
+ return PLDM_ERROR_INVALID_DATA;
+ }
+
+ size = length;
+
+ *response_len = sizeof(struct pldm_msg_hdr) +
+ sizeof(struct pldm_read_file_resp) + size - 1;
+ *response_msg = malloc(*response_len);
+
+
+
+ encode_read_file_resp(((struct pldm_msg *)request_msg)->hdr.instance_id,
+ PLDM_SUCCESS, size, *response_msg);
+
+ if (ret != PLDM_SUCCESS)
+ return ret;
+
+ struct pldm_read_file_resp *response = (struct pldm_read_file_resp *)
+ ((struct pldm_msg *)*response_msg)->payload;
+
+ // Copy required buffer to end of PLDM response
+ memcpy(response->file_data, pldm_file_io_buff + offset, size);
+ break;
+
+ default:
+ return PLDM_ERROR_INVALID_DATA;
+
+ }
+
+ return PLDM_SUCCESS;
+
+
+
+}
+
+
+int main(void)
+{
+ size_t ret;
+ char buf_read[TEST_FILE_IO_LENGTH];
+ char buf_write[TEST_FILE_IO_LENGTH] = TEST_FILE_IO_BUF1;
+ uint64_t size = strlen(buf_write);
+
+// Initialize test buffer for represent file with 0
+ bzero(pldm_file_io_buff, TEST_FILE_IO_LENGTH);
+
+
+// Attempt to write using pldm file io before init should return error OPAL_PARAMTER
+ ret = pldm_file_io_write_file(TEST_FILE_IO_HANDLE, TEST_FILE_IO_BUF1, 0, size);
+ if (ret != OPAL_PARAMETER) {
+ perror("pldm_file_io_write_file");
+ return ret;
+ }
+
+// Attempt to read using pldm file io before init should return error OPAL_PARAMTER
+ ret = pldm_file_io_read_file(TEST_FILE_IO_HANDLE, TEST_FILE_IO_LENGTH, buf_read, 0, size);
+ if (ret != OPAL_PARAMETER) {
+ perror("pldm_file_io_write_file");
+ return ret;
+ }
+
+// Init PLDM File IO
+ ret = pldm_file_io_init();
+ if (ret != PLDM_SUCCESS) {
+ perror("pldm_file_io_write_file");
+ return ret;
+ }
+
+// Attempt to write using pldm file io should return PLDM SUCCESS after init
+ ret = pldm_file_io_write_file(TEST_FILE_IO_HANDLE, TEST_FILE_IO_BUF1,
+ 0, size);
+ if (ret != PLDM_SUCCESS) {
+ perror("pldm_file_io_write_file");
+ return ret;
+ }
+
+// Attempt to read: using pldm file io should return PLDM SUCCESS after init
+ ret = pldm_file_io_read_file(TEST_FILE_IO_HANDLE, TEST_FILE_IO_LENGTH, buf_read, 0, size);
+ if (ret != PLDM_SUCCESS) {
+ perror("pldm_file_io_write_file");
+ return ret;
+ }
+
+// Test if buffer read same as buffer send
+ if (strncmp(buf_read, TEST_FILE_IO_BUF1, size) != 0) {
+
+ perror("pldm read string mismatch");
+ return OPAL_PARAMETER;
+ }
+
+ return PLDM_SUCCESS;
+}
+
+
--
2.34.1
More information about the Skiboot
mailing list