Message ID | 20220504065555.20551-1-abhishek@linux.ibm.com |
---|---|
State | Superseded |
Headers | show |
Series | [1/4] core/pldm/test : pldm file io test | expand |
Le 04/05/2022 à 08:55, Abhishek Singh Tomar a écrit : > The self test for PLDM FIle IO implementation It might be interesting to include a cover letter with your patch series describing why the series has been created and ... A changelog may be added in the futur. I also think that the summary phrase and theexplanation body of each patch should be more descriptive. Thanks, Christophe > Signed-off-by: Abhishek Singh Tomar<abhishek@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; > +} > + > +
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; +} + +
The self test for PLDM FIle IO implementation Signed-off-by: Abhishek Singh Tomar <abhishek@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