From 67064d0dbf8e6b825e94cc9a7bb9824a408fe9cd Mon Sep 17 00:00:00 2001 From: Christophe Lombard Date: Tue, 20 Jun 2023 16:52:07 +0200 Subject: pldm/ibm/libpldm: Import oem IBM libpldm library This library implements IBM OEM commands support for PLDM and specially encode and decode APIs for in-band readFile and writeFile commands. The source is located here: https://github.com/openbmc/pldm/tree/master/oem/ibm/libpldm and use as is, without any update. The oem IBM libpldm code is integrated into the folder ./pldm/ibm/libpldm as a set of sources, compilated if the compiler flag CONFIG_PLDM is set. Signed-off-by: Christophe Lombard Acked-by: Nicholas Piggin Signed-off-by: Reza Arbab --- Makefile.main | 3 +- .../libpldm/oem/ibm/libpldm/entity_oem_ibm.h | 17 + pldm/include/libpldm/oem/ibm/libpldm/file_io.h | 915 +++++++++++++++++ pldm/include/libpldm/oem/ibm/libpldm/fru_oem_ibm.h | 21 + pldm/include/libpldm/oem/ibm/libpldm/host.h | 108 ++ .../libpldm/oem/ibm/libpldm/platform_oem_ibm.h | 56 ++ .../libpldm/oem/ibm/libpldm/state_set_oem_ibm.h | 58 ++ pldm/libpldm/oem/ibm/Makefile.inc | 19 + pldm/libpldm/oem/ibm/README.skiboot | 15 + pldm/libpldm/oem/ibm/file_io.c | 1057 ++++++++++++++++++++ pldm/libpldm/oem/ibm/host.c | 108 ++ pldm/libpldm/oem/ibm/platform.c | 50 + 12 files changed, 2426 insertions(+), 1 deletion(-) create mode 100644 pldm/include/libpldm/oem/ibm/libpldm/entity_oem_ibm.h create mode 100644 pldm/include/libpldm/oem/ibm/libpldm/file_io.h create mode 100644 pldm/include/libpldm/oem/ibm/libpldm/fru_oem_ibm.h create mode 100644 pldm/include/libpldm/oem/ibm/libpldm/host.h create mode 100644 pldm/include/libpldm/oem/ibm/libpldm/platform_oem_ibm.h create mode 100644 pldm/include/libpldm/oem/ibm/libpldm/state_set_oem_ibm.h create mode 100644 pldm/libpldm/oem/ibm/Makefile.inc create mode 100644 pldm/libpldm/oem/ibm/README.skiboot create mode 100644 pldm/libpldm/oem/ibm/file_io.c create mode 100644 pldm/libpldm/oem/ibm/host.c create mode 100644 pldm/libpldm/oem/ibm/platform.c diff --git a/Makefile.main b/Makefile.main index 31ad841..5240d71 100644 --- a/Makefile.main +++ b/Makefile.main @@ -305,6 +305,7 @@ include $(SRC)/libstb/Makefile.inc ifeq ($(CONFIG_PLDM),1) include $(SRC)/libmctp/Makefile.inc include $(SRC)/pldm/libpldm/Makefile.inc +include $(SRC)/pldm/libpldm/oem/ibm/Makefile.inc endif # hack for travis-ci and coverity @@ -331,7 +332,7 @@ all: $(TARGET).lid.stb $(TARGET).lid.xz.stb OBJS := $(ASM) $(CORE) $(HW) $(PLATFORMS) $(LIBFDT) $(LIBXZ) $(LIBFLASH) $(LIBSTB) OBJS += $(LIBC) $(CCAN) $(DEVSRC_OBJ) $(LIBPORE) ifeq ($(CONFIG_PLDM),1) -OBJS += $(LIBMCTP) $(LIBPLDM) +OBJS += $(LIBMCTP) $(LIBPLDM) $(LIBPLDM_IBM) endif OBJS_NO_VER = $(OBJS) ALL_OBJS = $(OBJS) version.o diff --git a/pldm/include/libpldm/oem/ibm/libpldm/entity_oem_ibm.h b/pldm/include/libpldm/oem/ibm/libpldm/entity_oem_ibm.h new file mode 100644 index 0000000..dd80f56 --- /dev/null +++ b/pldm/include/libpldm/oem/ibm/libpldm/entity_oem_ibm.h @@ -0,0 +1,17 @@ +#ifndef OEM_IBM_ENTITY_H +#define OEM_IBM_ENTITY_H + +#ifdef __cplusplus +extern "C" { +#endif + +enum pldm_oem_ibm_entity_id_codes { + PLDM_OEM_IBM_ENTITY_TPM = 24576, + PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE = 24577, +}; + +#ifdef __cplusplus +} +#endif + +#endif /* OEM_IBM_ENTITY_H */ diff --git a/pldm/include/libpldm/oem/ibm/libpldm/file_io.h b/pldm/include/libpldm/oem/ibm/libpldm/file_io.h new file mode 100644 index 0000000..5b4bb32 --- /dev/null +++ b/pldm/include/libpldm/oem/ibm/libpldm/file_io.h @@ -0,0 +1,915 @@ +#ifndef FILEIO_H +#define FILEIO_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +struct pldm_msg; +/** @brief PLDM Commands in IBM OEM type + */ +enum pldm_fileio_commands { + PLDM_GET_FILE_TABLE = 0x1, + PLDM_READ_FILE = 0x4, + PLDM_WRITE_FILE = 0x5, + PLDM_READ_FILE_INTO_MEMORY = 0x6, + PLDM_WRITE_FILE_FROM_MEMORY = 0x7, + PLDM_READ_FILE_BY_TYPE_INTO_MEMORY = 0x8, + PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY = 0x9, + PLDM_NEW_FILE_AVAILABLE = 0xA, + PLDM_READ_FILE_BY_TYPE = 0xB, + PLDM_WRITE_FILE_BY_TYPE = 0xC, + PLDM_FILE_ACK = 0xD, + PLDM_NEW_FILE_AVAILABLE_WITH_META_DATA = 0xE, + PLDM_FILE_ACK_WITH_META_DATA = 0xF, +}; + +/** @brief PLDM Command specific codes + */ +enum pldm_fileio_completion_codes { + PLDM_FILE_TABLE_UNAVAILABLE = 0x83, + PLDM_INVALID_FILE_TABLE_TYPE = 0x85, + PLDM_INVALID_FILE_HANDLE = 0x86, + PLDM_DATA_OUT_OF_RANGE = 0x87, + PLDM_INVALID_FILE_TYPE = 0x89, + PLDM_ERROR_FILE_DISCARDED = 0x8A, +}; + +/** @brief PLDM File I/O table types + */ +enum pldm_fileio_table_type { + PLDM_FILE_ATTRIBUTE_TABLE = 0, + PLDM_OEM_FILE_ATTRIBUTE_TABLE = 1, +}; + +/** @brief PLDM File I/O table types + */ +enum pldm_fileio_file_type { + PLDM_FILE_TYPE_PEL = 0x0, + PLDM_FILE_TYPE_LID_PERM = 0x1, + PLDM_FILE_TYPE_LID_TEMP = 0x2, + PLDM_FILE_TYPE_DUMP = 0x3, + PLDM_FILE_TYPE_CERT_SIGNING_REQUEST = 0x4, + PLDM_FILE_TYPE_SIGNED_CERT = 0x5, + PLDM_FILE_TYPE_ROOT_CERT = 0x6, + PLDM_FILE_TYPE_LID_MARKER = 0x7, + PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS = 0x8, + PLDM_FILE_TYPE_RESOURCE_DUMP = 0x9, + PLDM_FILE_TYPE_PROGRESS_SRC = 0xA, + PLDM_FILE_TYPE_ADJUNCT_DUMP = 0xB, + PLDM_FILE_TYPE_DEVICE_DUMP = 0xC, + PLDM_FILE_TYPE_COD_LICENSE_KEY = 0xD, + PLDM_FILE_TYPE_COD_LICENSED_RESOURCES = 0xE, + PLDM_FILE_TYPE_BMC_DUMP = 0xF, + PLDM_FILE_TYPE_SBE_DUMP = 0x10, + PLDM_FILE_TYPE_HOSTBOOT_DUMP = 0x11, + PLDM_FILE_TYPE_HARDWARE_DUMP = 0x12, + PLDM_FILE_TYPE_LID_RUNNING = 0x13, + PLDM_FILE_TYPE_PCIE_TOPOLOGY = 0x14, + PLDM_FILE_TYPE_CABLE_INFO = 0x15, + PLDM_FILE_TYPE_PSPD_VPD_PDD_KEYWORD = 0x16, +}; + +#define PLDM_RW_FILE_MEM_REQ_BYTES 20 +#define PLDM_RW_FILE_MEM_RESP_BYTES 5 +#define PLDM_GET_FILE_TABLE_REQ_BYTES 6 +#define PLDM_GET_FILE_TABLE_MIN_RESP_BYTES 6 +#define PLDM_READ_FILE_REQ_BYTES 12 +#define PLDM_READ_FILE_RESP_BYTES 5 +#define PLDM_WRITE_FILE_REQ_BYTES 12 +#define PLDM_WRITE_FILE_RESP_BYTES 5 +#define PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES 22 +#define PLDM_RW_FILE_BY_TYPE_MEM_RESP_BYTES 5 +#define PLDM_NEW_FILE_REQ_BYTES 14 +#define PLDM_NEW_FILE_RESP_BYTES 1 +#define PLDM_RW_FILE_BY_TYPE_REQ_BYTES 14 +#define PLDM_RW_FILE_BY_TYPE_RESP_BYTES 5 +#define PLDM_FILE_ACK_REQ_BYTES 7 +#define PLDM_FILE_ACK_RESP_BYTES 1 +#define PLDM_FILE_ACK_WITH_META_DATA_REQ_BYTES 23 +#define PLDM_FILE_ACK_WITH_META_DATA_RESP_BYTES 1 +#define PLDM_NEW_FILE_AVAILABLE_WITH_META_DATA_REQ_BYTES 30 +#define PLDM_NEW_FILE_AVAILABLE_WITH_META_DATA_RESP_BYTES 1 + +/** @struct pldm_read_write_file_memory_req + * + * Structure representing ReadFileIntoMemory request and WriteFileFromMemory + * request + */ +struct pldm_read_write_file_memory_req { + uint32_t file_handle; //!< A Handle to the file + uint32_t offset; //!< Offset to the file + uint32_t length; //!< Number of bytes to be read/write + uint64_t address; //!< Memory address of the file +} __attribute__((packed)); + +/** @struct pldm_read_write_file_memory_resp + * + * Structure representing ReadFileIntoMemory response and WriteFileFromMemory + * response + */ +struct pldm_read_write_file_memory_resp { + uint8_t completion_code; //!< completion code + uint32_t length; //!< Number of bytes read/written +} __attribute__((packed)); + +/** @brief Decode ReadFileIntoMemory and WriteFileFromMemory commands request + * data + * + * @param[in] msg - Pointer to PLDM request message + * @param[in] payload_length - Length of request payload + * @param[out] file_handle - A handle to the file + * @param[out] offset - Offset to the file at which the read should begin + * @param[out] length - Number of bytes to be read + * @param[out] address - Memory address where the file content has to be + * written to + * @return pldm_completion_codes + */ +int decode_rw_file_memory_req(const struct pldm_msg *msg, size_t payload_length, + uint32_t *file_handle, uint32_t *offset, + uint32_t *length, uint64_t *address); + +/** @brief Create a PLDM response for ReadFileIntoMemory and + * WriteFileFromMemory + * + * @param[in] instance_id - Message's instance id + * @param[in] command - PLDM command + * @param[in] completion_code - PLDM completion code + * @param[in] length - Number of bytes read. This could be less than what the + requester asked for. + * @param[in,out] msg - Message will be written to this + * @return pldm_completion_codes + * @note Caller is responsible for memory alloc and dealloc of param 'msg' + */ +int encode_rw_file_memory_resp(uint8_t instance_id, uint8_t command, + uint8_t completion_code, uint32_t length, + struct pldm_msg *msg); + +/** @brief Encode ReadFileIntoMemory and WriteFileFromMemory + * commands request data + * + * @param[in] instance_id - Message's instance id + * @param[in] command - PLDM command + * @param[in] file_handle - A handle to the file + * @param[in] offset - Offset to the file at which the read should begin + * @param[in] length - Number of bytes to be read/written + * @param[in] address - Memory address where the file content has to be + * written to + * @param[out] msg - Message will be written to this + * @return pldm_completion_codes + */ +int encode_rw_file_memory_req(uint8_t instance_id, uint8_t command, + uint32_t file_handle, uint32_t offset, + uint32_t length, uint64_t address, + struct pldm_msg *msg); + +/** @brief Decode ReadFileIntoMemory and WriteFileFromMemory + * commands response data + * + * @param[in] msg - pointer to PLDM response message + * @param[in] payload_length - Length of response payload + * @param[out] completion_code - PLDM completion code + * @param[out] length - Number of bytes to be read/written + * @return pldm_completion_codes + */ +int decode_rw_file_memory_resp(const struct pldm_msg *msg, + size_t payload_length, uint8_t *completion_code, + uint32_t *length); + +/** @struct pldm_get_file_table_req + * + * Structure representing GetFileTable request + */ +struct pldm_get_file_table_req { + uint32_t transfer_handle; //!< Data transfer handle + uint8_t operation_flag; //!< Transfer operation flag + uint8_t table_type; //!< Table type +} __attribute__((packed)); + +/** @struct pldm_get_file_table_resp + * + * Structure representing GetFileTable response fixed data + */ +struct pldm_get_file_table_resp { + uint8_t completion_code; //!< Completion code + uint32_t next_transfer_handle; //!< Next data transfer handle + uint8_t transfer_flag; //!< Transfer flag + uint8_t table_data[1]; //!< Table Data +} __attribute__((packed)); + +/** @struct pldm_file_attr_table_entry + * + * Structure representing File attribute table entry + */ +struct pldm_file_attr_table_entry { + uint32_t file_handle; //!< File Handle + uint16_t file_name_length; //!< File name length + uint8_t file_attr_table_nst[1]; //!< File name size traits +} __attribute__((packed)); + +/** @brief Decode GetFileTable command request data + * + * @param[in] msg - Pointer to PLDM request message + * @param[in] payload_length - Length of request payload + * @param[out] trasnfer_handle - the handle of data + * @param[out] transfer_opflag - Transfer operation flag + * @param[out] table_type - the type of file table + * @return pldm_completion_codes + */ +int decode_get_file_table_req(const struct pldm_msg *msg, size_t payload_length, + uint32_t *transfer_handle, + uint8_t *transfer_opflag, uint8_t *table_type); + +/** @brief Create a PLDM response for GetFileTable command + * + * @param[in] instance_id - Message's instance id + * @param[in] completion_code - PLDM completion code + * @param[in] next_transfer_handle - Handle to identify next portion of + * data transfer + * @param[in] transfer_flag - Represents the part of transfer + * @param[in] table_data - pointer to file table data + * @param[in] table_size - file table size + * @param[in,out] msg - Message will be written to this + * @return pldm_completion_codes + * @note Caller is responsible for memory alloc and dealloc of param 'msg' + */ +int encode_get_file_table_resp(uint8_t instance_id, uint8_t completion_code, + uint32_t next_transfer_handle, + uint8_t transfer_flag, const uint8_t *table_data, + size_t table_size, struct pldm_msg *msg); + +/** @brief Encode GetFileTable command request data + * + * @param[in] instance_id - Message's instance id + * @param[in] transfer_handle - the handle of data + * @param[in] transfer_opflag - Transfer operation flag + * @param[in] table_type - the type of file table + * @param[out] msg - Message will be written to this + * @return pldm_completion_codes + */ +int encode_get_file_table_req(uint8_t instance_id, uint32_t transfer_handle, + uint8_t transfer_opflag, uint8_t table_type, + struct pldm_msg *msg); + +/** @brief Decode GetFileTable command response data + * @param[in] msg - Response message + * @param[in] payload_length - length of response message payload + * @param[out] completion_code - PLDM completion code + * @param[out] next_transfer_handle - Handle to identify next portion of data + * transfer + * @param[out] transfer_flag - Represents the part of transfer + * @param[out] file_table_data_start_offset - This data is a portion of the + * overall File Table + * @param[out] file_table_length - Length of the File table data + * @return pldm_completion_codes + */ +int decode_get_file_table_resp(const struct pldm_msg *msg, + size_t payload_length, uint8_t *completion_code, + uint32_t *next_transfer_handle, + uint8_t *transfer_flag, + uint8_t *file_table_data_start_offset, + size_t *file_table_length); + +/** @struct pldm_read_file_req + * + * Structure representing ReadFile request + */ +struct pldm_read_file_req { + uint32_t file_handle; //!< Handle to file + uint32_t offset; //!< Offset to file where read starts + uint32_t length; //!< Bytes to be read +} __attribute__((packed)); + +/** @struct pldm_read_file_resp + * + * Structure representing ReadFile response data + */ +struct pldm_read_file_resp { + uint8_t completion_code; //!< Completion code + uint32_t length; //!< Number of bytes read + uint8_t file_data[1]; //!< Address of this is where file data starts +} __attribute__((packed)); + +/** @struct pldm_write_file_req + * + * Structure representing WriteFile request + */ +struct pldm_write_file_req { + uint32_t file_handle; //!< Handle to file + uint32_t offset; //!< Offset to file where write starts + uint32_t length; //!< Bytes to be written + uint8_t file_data[1]; //!< Address of this is where file data starts +} __attribute__((packed)); + +/** @struct pldm_write_file_resp + * + * Structure representing WriteFile response data + */ +struct pldm_write_file_resp { + uint8_t completion_code; //!< Completion code + uint32_t length; //!< Bytes written +} __attribute__((packed)); + +/** @brief Decode Read File commands request + * + * @param[in] msg - PLDM request message payload + * @param[in] payload_length - Length of request payload + * @param[out] file_handle - A handle to the file + * @param[out] offset - Offset to the file at which the read should begin + * @param[out] length - Number of bytes read + * @return pldm_completion_codes + */ +int decode_read_file_req(const struct pldm_msg *msg, size_t payload_length, + uint32_t *file_handle, uint32_t *offset, + uint32_t *length); + +/** @brief Encode Read File commands request + * + * @param[in] instance_id - Message's instance id + * @param[in] file_handle - A handle to the file + * @param[in] offset - Offset to the file at which the read should begin + * @param[in] length - Number of bytes read + * @param[in,out] msg - Message will be written to this + * @return pldm_completion_codes + * @note Caller is responsible for memory alloc and dealloc of param 'msg' + */ +int encode_read_file_req(uint8_t instance_id, uint32_t file_handle, + uint32_t offset, uint32_t length, + struct pldm_msg *msg); + +/** @brief Decode Read File commands response + * + * @param[in] msg - PLDM response message payload + * @param[in] payload_length - Length of request payload + * @param[out] completion_code - PLDM completion code + * @param[out] length - Number of bytes read. This could be less than what the + * requester asked for. + * @param[out] file_data_offset - Offset where file data should be read in pldm + * msg. + * @return pldm_completion_codes + */ +int decode_read_file_resp(const struct pldm_msg *msg, size_t payload_length, + uint8_t *completion_code, uint32_t *length, + size_t *file_data_offset); + +/** @brief Create a PLDM response for Read File + * + * @param[in] instance_id - Message's instance id + * @param[in] completion_code - PLDM completion code + * @param[in] length - Number of bytes read. This could be less than what the + * requester asked for. + * @param[in,out] msg - Message will be written to this + * @return pldm_completion_codes + * @note Caller is responsible for memory alloc and dealloc of param 'msg'. + * Although read file command response includes file data, this function + * does not encode the file data to prevent additional copying of the data. + * The position of file data is calculated by caller from address and size + * of other input arguments. + */ +int encode_read_file_resp(uint8_t instance_id, uint8_t completion_code, + uint32_t length, struct pldm_msg *msg); + +/** @brief Decode Write File commands request + * + * @param[in] msg - PLDM request message payload + * @param[in] payload_length - Length of request payload + * @param[out] file_handle - A handle to the file + * @param[out] offset - Offset to the file at which the write should begin + * @param[out] length - Number of bytes to write + * @param[out] file_data_offset - Offset where file data write begins in pldm + * msg. + * @return pldm_completion_codes + */ +int decode_write_file_req(const struct pldm_msg *msg, size_t payload_length, + uint32_t *file_handle, uint32_t *offset, + uint32_t *length, size_t *file_data_offset); + +/** @brief Create a PLDM request for Write File + * + * @param[in] instance_id - Message's instance id + * @param[in] file_handle - A handle to the file + * @param[in] offset - Offset to the file at which the read should begin + * @param[in] length - Number of bytes written. This could be less than what + * the requester asked for. + * @param[in,out] msg - Message will be written to this + * @return pldm_completion_codes + * @note Caller is responsible for memory alloc and dealloc of param 'msg'. + * Although write file command request includes file data, this function + * does not encode the file data to prevent additional copying of the data. + * The position of file data is calculated by caller from address and size + * of other input arguments. + */ +int encode_write_file_req(uint8_t instance_id, uint32_t file_handle, + uint32_t offset, uint32_t length, + struct pldm_msg *msg); + +/** @brief Decode Write File commands response + * + * @param[in] msg - PLDM request message payload + * @param[in] payload_length - Length of request payload + * @param[out] completion_code - PLDM completion code + * @param[out] length - Number of bytes written + * @return pldm_completion_codes + */ +int decode_write_file_resp(const struct pldm_msg *msg, size_t payload_length, + uint8_t *completion_code, uint32_t *length); + +/** @brief Create a PLDM response for Write File + * + * @param[in] instance_id - Message's instance id + * @param[in] completion_code - PLDM completion code + * @param[in] length - Number of bytes written. This could be less than what + * the requester asked for. + * @param[in,out] msg - Message will be written to this + * @return pldm_completion_codes + * @note Caller is responsible for memory alloc and dealloc of param 'msg' + */ +int encode_write_file_resp(uint8_t instance_id, uint8_t completion_code, + uint32_t length, struct pldm_msg *msg); + +/** @struct pldm_read_write_file_by_type_memory_req + * + * Structure representing ReadFileByTypeIntoMemory and + * WriteFileByTypeFromMemory request + */ +struct pldm_read_write_file_by_type_memory_req { + uint16_t file_type; //!< Type of file + uint32_t file_handle; //!< Handle to file + uint32_t offset; //!< Offset to file where read starts + uint32_t length; //!< Bytes to be read + uint64_t address; //!< Memory address of the file +} __attribute__((packed)); + +/** @struct pldm_read_write_file_by_type_memory_resp + * + * Structure representing ReadFileByTypeIntoMemory and + * WriteFileByTypeFromMemory response + */ +struct pldm_read_write_file_by_type_memory_resp { + uint8_t completion_code; //!< Completion code + uint32_t length; //!< Number of bytes read +} __attribute__((packed)); + +/** @brief Decode ReadFileByTypeIntoMemory and WriteFileByTypeFromMemory + * commands request data + * + * @param[in] msg - Pointer to PLDM request message + * @param[in] payload_length - Length of request payload + * @param[in] file_type - Type of the file + * @param[out] file_handle - A handle to the file + * @param[out] offset - Offset to the file at which the read should begin + * @param[out] length - Number of bytes to be read + * @param[out] address - Memory address of the file content + * @return pldm_completion_codes + */ +int decode_rw_file_by_type_memory_req(const struct pldm_msg *msg, + size_t payload_length, + uint16_t *file_type, + uint32_t *file_handle, uint32_t *offset, + uint32_t *length, uint64_t *address); + +/** @brief Create a PLDM response for ReadFileByTypeIntoMemory and + * WriteFileByTypeFromMemory + * + * @param[in] instance_id - Message's instance id + * @param[in] command - PLDM command + * @param[in] completion_code - PLDM completion code + * @param[in] length - Number of bytes read. This could be less than what the + * requester asked for. + * @param[in,out] msg - Message will be written to this + * @return pldm_completion_codes + * @note Caller is responsible for memory alloc and dealloc of param 'msg' + */ +int encode_rw_file_by_type_memory_resp(uint8_t instance_id, uint8_t command, + uint8_t completion_code, uint32_t length, + struct pldm_msg *msg); + +/** @brief Encode ReadFileByTypeIntoMemory and WriteFileByTypeFromMemory + * commands request data + * + * @param[in] instance_id - Message's instance id + * @param[in] command - PLDM command + * @param[in] file_type - Type of the file + * @param[in] file_handle - A handle to the file + * @param[in] offset - Offset to the file at which the read should begin + * @param[in] length - Number of bytes to be read/written + * @param[in] address - Memory address where the file content has to be + * written to + * @param[out] msg - Message will be written to this + * @return pldm_completion_codes + */ +int encode_rw_file_by_type_memory_req(uint8_t instance_id, uint8_t command, + uint16_t file_type, uint32_t file_handle, + uint32_t offset, uint32_t length, + uint64_t address, struct pldm_msg *msg); + +/** @brief Decode ReadFileTypeIntoMemory and WriteFileTypeFromMemory + * commands response data + * + * @param[in] msg - pointer to PLDM response message + * @param[in] payload_length - Length of response payload + * @param[out] completion_code - PLDM completion code + * @param[out] length - Number of bytes to be read/written + * @return pldm_completion_codes + */ +int decode_rw_file_by_type_memory_resp(const struct pldm_msg *msg, + size_t payload_length, + uint8_t *completion_code, + uint32_t *length); + +/** @struct pldm_new_file_req + * + * Structure representing NewFile request + */ +struct pldm_new_file_req { + uint16_t file_type; //!< Type of file + uint32_t file_handle; //!< Handle to file + uint64_t length; //!< Number of bytes in new file +} __attribute__((packed)); + +/** @struct pldm_new_file_resp + * + * Structure representing NewFile response data + */ +struct pldm_new_file_resp { + uint8_t completion_code; //!< Completion code +} __attribute__((packed)); + +/** @brief Decode NewFileAvailable command request data + * + * @param[in] msg - Pointer to PLDM request message + * @param[in] payload_length - Length of request payload + * @param[in] file_type - Type of the file + * @param[out] file_handle - A handle to the file + * @param[out] length - Number of bytes in new file + * @return pldm_completion_codes + */ +int decode_new_file_req(const struct pldm_msg *msg, size_t payload_length, + uint16_t *file_type, uint32_t *file_handle, + uint64_t *length); + +/** @brief Create a PLDM response for NewFileAvailable + * + * @param[in] instance_id - Message's instance id + * @param[in] completion_code - PLDM completion code + * @param[in,out] msg - Message will be written to this + * @return pldm_completion_codes + * @note Caller is responsible for memory alloc and dealloc of param 'msg' + */ +int encode_new_file_resp(uint8_t instance_id, uint8_t completion_code, + struct pldm_msg *msg); + +/** @brief Encode NewFileAvailable command request data + * + * @param[in] instance_id - Message's instance id + * @param[in] file_type - Type of the file + * @param[in] file_handle - A handle to the file + * @param[in] length - Number of bytes in new file + * @param[out] msg - Message will be written to this + * @return pldm_completion_codes + */ +int encode_new_file_req(uint8_t instance_id, uint16_t file_type, + uint32_t file_handle, uint64_t length, + struct pldm_msg *msg); + +/** @brief Decode NewFileAvailable command response data + * + * @param[in] msg - pointer to PLDM response message + * @param[in] payload_length - Length of response payload + * @param[out] completion_code - PLDM completion code + * @return pldm_completion_codes + */ +int decode_new_file_resp(const struct pldm_msg *msg, size_t payload_length, + uint8_t *completion_code); + +/** @struct pldm_read_write_file_by_type_req + * + * Structure representing ReadFileByType and + * WriteFileByType request + */ +struct pldm_read_write_file_by_type_req { + uint16_t file_type; //!< Type of file + uint32_t file_handle; //!< Handle to file + uint32_t offset; //!< Offset to file where read/write starts + uint32_t length; //!< Bytes to be read +} __attribute__((packed)); + +/** @struct pldm_read_write_file_by_type_resp + * + * Structure representing ReadFileByType and + * WriteFileByType response + */ +struct pldm_read_write_file_by_type_resp { + uint8_t completion_code; //!< Completion code + uint32_t length; //!< Number of bytes read +} __attribute__((packed)); + +/** @brief Decode ReadFileByType and WriteFileByType + * commands request data + * + * @param[in] msg - Pointer to PLDM request message + * @param[in] payload_length - Length of request payload + * @param[out] file_type - Type of the file + * @param[out] file_handle - A handle to the file + * @param[out] offset - Offset to the file at which the read/write should begin + * @param[out] length - Number of bytes to be read/written + * @return pldm_completion_codes + */ +int decode_rw_file_by_type_req(const struct pldm_msg *msg, + size_t payload_length, uint16_t *file_type, + uint32_t *file_handle, uint32_t *offset, + uint32_t *length); + +/** @brief Create a PLDM response for ReadFileByType and + * WriteFileByType + * + * @param[in] instance_id - Message's instance id + * @param[in] command - PLDM command + * @param[in] completion_code - PLDM completion code + * @param[in] length - Number of bytes read/written. This could be less than + * what the requester asked for. + * @param[in,out] msg - Message will be written to this + * @return pldm_completion_codes + * @note Caller is responsible for memory alloc and dealloc of param 'msg' + * @note File content has to be copied directly by the caller. + */ +int encode_rw_file_by_type_resp(uint8_t instance_id, uint8_t command, + uint8_t completion_code, uint32_t length, + struct pldm_msg *msg); + +/** @brief Encode ReadFileByType and WriteFileByType + * commands request data + * + * @param[in] instance_id - Message's instance id + * @param[in] command - PLDM command + * @param[in] file_type - Type of the file + * @param[in] file_handle - A handle to the file + * @param[in] offset - Offset to the file at which the read should begin + * @param[in] length - Number of bytes to be read/written + * @param[out] msg - Message will be written to this + * @return pldm_completion_codes + * @note File content has to be read directly by the caller. + */ +int encode_rw_file_by_type_req(uint8_t instance_id, uint8_t command, + uint16_t file_type, uint32_t file_handle, + uint32_t offset, uint32_t length, + struct pldm_msg *msg); + +/** @brief Decode ReadFileByType and WriteFileByType + * commands response data + * + * @param[in] msg - pointer to PLDM response message + * @param[in] payload_length - Length of response payload + * @param[out] completion_code - PLDM completion code + * @param[out] length - Number of bytes to be read/written + * @return pldm_completion_codes + */ +int decode_rw_file_by_type_resp(const struct pldm_msg *msg, + size_t payload_length, uint8_t *completion_code, + uint32_t *length); + +/** @struct pldm_file_ack_req + * + * Structure representing FileAck request + */ +struct pldm_file_ack_req { + uint16_t file_type; //!< Type of file + uint32_t file_handle; //!< Handle to file + uint8_t file_status; //!< Status of file processing +} __attribute__((packed)); + +/** @struct pldm_file_ack_resp + * + * Structure representing NewFile response data + */ +struct pldm_file_ack_resp { + uint8_t completion_code; //!< Completion code +} __attribute__((packed)); + +/** @brief Decode FileAck command request data + * + * @param[in] msg - Pointer to PLDM request message + * @param[in] payload_length - Length of request payload + * @param[out] file_type - Type of the file + * @param[out] file_handle - A handle to the file + * @param[out] file_status - Status of file processing + * @return pldm_completion_codes + */ +int decode_file_ack_req(const struct pldm_msg *msg, size_t payload_length, + uint16_t *file_type, uint32_t *file_handle, + uint8_t *file_status); + +/** @brief Create a PLDM response for FileAck + * + * @param[in] instance_id - Message's instance id + * @param[in] completion_code - PLDM completion code + * @param[in,out] msg - Message will be written to this + * @return pldm_completion_codes + * @note Caller is responsible for memory alloc and dealloc of param 'msg' + */ +int encode_file_ack_resp(uint8_t instance_id, uint8_t completion_code, + struct pldm_msg *msg); + +/** @brief Encode FileAck command request data + * + * @param[in] instance_id - Message's instance id + * @param[in] file_type - Type of the file + * @param[in] file_handle - A handle to the file + * @param[in] file_status - Status of file processing + * @param[out] msg - Message will be written to this + * @return pldm_completion_codes + */ +int encode_file_ack_req(uint8_t instance_id, uint16_t file_type, + uint32_t file_handle, uint8_t file_status, + struct pldm_msg *msg); + +/** @brief Decode FileAck command response data + * + * @param[in] msg - pointer to PLDM response message + * @param[in] payload_length - Length of response payload + * @param[out] completion_code - PLDM completion code + * @return pldm_completion_codes + */ +int decode_file_ack_resp(const struct pldm_msg *msg, size_t payload_length, + uint8_t *completion_code); + +/* FileAckWithMetadata */ + +/** @struct pldm_file_ack_with_meta_data_req + * + * Structure representing FileAckWithMetadata request + */ +struct pldm_file_ack_with_meta_data_req { + uint16_t file_type; //!< Type of file + uint32_t file_handle; //!< Handle to file + uint8_t file_status; //!< Status of file processing + uint32_t file_meta_data_1; //!< Meta data specific to file type 1 + uint32_t file_meta_data_2; //!< Meta data specific to file type 2 + uint32_t file_meta_data_3; //!< Meta data specific to file type 3 + uint32_t file_meta_data_4; //!< meta data specific to file type 4 +} __attribute__((packed)); + +/** @struct pldm_file_ack_with_meta_data_resp + * + * Structure representing FileAckWithMetadata response + */ +struct pldm_file_ack_with_meta_data_resp { + uint8_t completion_code; //!< Completion code +} __attribute__((packed)); + +/** @brief Encode FileAckWithMetadata request data + * + * @param[in] instance_id - Message's instance id + * @param[in] file_type - Type of the file + * @param[in] file_handle - A handle to the file + * @param[in] file_status - Status of file processing + * @param[in] file_meta_data_1 - meta data specific to file type 1 + * @param[in] file_meta_data_2 - meta data specific to file type 2 + * @param[in] file_meta_data_3 - meta data specific to file type 3 + * @param[in] file_meta_data_4 - Meta data specific to file type 4 + * @param[out] msg - Message will be written to this + * @return pldm_completion_codes + */ +int encode_file_ack_with_meta_data_req( + uint8_t instance_id, uint16_t file_type, uint32_t file_handle, + uint8_t file_status, uint32_t file_meta_data_1, + uint32_t file_meta_data_2, uint32_t file_meta_data_3, + uint32_t file_meta_data_4, struct pldm_msg *msg); + +/** @brief Decode FileAckWithMetadata command response data + * + * @param[in] msg - pointer to PLDM response message + * @param[in] payload_length - Length of response payload + * @param[out] completion_code - PLDM completion code + * @return pldm_completion_codes + */ +int decode_file_ack_with_meta_data_resp(const struct pldm_msg *msg, + size_t payload_length, + uint8_t *completion_code); + +/** @brief Decode FileAckWithMetadata request data + * + * @param[in] msg - Pointer to PLDM request message + * @param[in] payload_length - Length of request payload + * @param[out] file_type - Type of the file + * @param[out] file_handle - A handle to the file + * @param[out] file_status - Status of file processing + * @param[out] file_meta_data_1 - meta data specific to file type 1 + * @param[out] file_meta_data_2 - meta data specific to file type 2 + * @param[out] file_meta_data_3 - meta data specific to file type 3 + * @param[out] file_meta_data_4 - Meta data specific to file type 4 + * @return pldm_completion_codes + */ +int decode_file_ack_with_meta_data_req( + const struct pldm_msg *msg, size_t payload_length, uint16_t *file_type, + uint32_t *file_handle, uint8_t *file_status, uint32_t *file_meta_data_1, + uint32_t *file_meta_data_2, uint32_t *file_meta_data_3, + uint32_t *file_meta_data_4); + +/** @brief Create a PLDM response message for FileAckWithMetadata + * + * @param[in] instance_id - Message's instance id + * @param[in] completion_code - PLDM completion code + * @param[in,out] msg - Message will be written to this + * @return pldm_completion_codes + */ +int encode_file_ack_with_meta_data_resp(uint8_t instance_id, + uint8_t completion_code, + struct pldm_msg *msg); + +/* NewFileAvailableWithMetaData */ + +/** @struct pldm_new_file_with_metadata_req + * + * Structure representing NewFileAvailableWithMetaData request + */ + +struct pldm_new_file_with_metadata_req { + uint16_t file_type; //!< Type of file + uint32_t file_handle; //!< Handle to file + uint64_t length; //!< Number of bytes in new file + uint32_t file_meta_data_1; //!< Meta data specific to file type 1 + uint32_t file_meta_data_2; //!< Meta data specific to file type 2 + uint32_t file_meta_data_3; //!< Meta data specific to file type 3 + uint32_t file_meta_data_4; //!< Meta data specific to file type 4 +} __attribute__((packed)); + +/** @struct pldm_new_file_with_metadata_resp + * + * Structure representing NewFileAvailableWithMetaData response data + */ +struct pldm_new_file_with_metadata_resp { + uint8_t completion_code; //!< Completion code +} __attribute__((packed)); + +/** @brief Encode NewFileAvailableWithMetaData request data + * + * @param[in] instance_id - Message's instance id + * @param[in] file_type - Type of the file + * @param[in] file_handle - A handle to the file + * @param[in] length - Number of bytes in new file + * @param[in] file_meta_data_1 - Meta data specific to file type 1 + * @param[in] file_meta_data_2 - Meta data specific to file type 2 + * @param[in] file_meta_data_3 - Meta data specific to file type 3 + * @param[in] file_meta_data_4 - Meta data specific to file type 4 + * @param[out] msg - Message will be written to this + * @return pldm_completion_codes + */ +int encode_new_file_with_metadata_req(uint8_t instance_id, uint16_t file_type, + uint32_t file_handle, uint64_t length, + uint32_t file_meta_data_1, + uint32_t file_meta_data_2, + uint32_t file_meta_data_3, + uint32_t file_meta_data_4, + struct pldm_msg *msg); + +/** @brief Decode NewFileAvailableWithMetaData response data + * + * @param[in] msg - pointer to PLDM response message + * @param[in] payload_length - Length of response payload + * @param[out] completion_code - PLDM completion code + * @return pldm_completion_codes + */ +int decode_new_file_with_metadata_resp(const struct pldm_msg *msg, + size_t payload_length, + uint8_t *completion_code); + +/** @brief Decode NewFileAvailableWithMetaData request data + * + * @param[in] msg - Pointer to PLDM request message + * @param[in] payload_length - Length of request payload + * @param[out] file_type - Type of the file + * @param[out] file_handle - A handle to the file + * @param[out] length - Number of bytes in new file + * @param[out] file_meta_data_1 - Meta data specific to file type 1 + * @param[out] file_meta_data_2 - Meta data specific to file type 2 + * @param[out] file_meta_data_3 - Meta data specific to file type 3 + * @param[out] file_meta_data_4 - Meta data specific to file type 4 + * @return pldm_completion_codes + */ +int decode_new_file_with_metadata_req( + const struct pldm_msg *msg, size_t payload_length, uint16_t *file_type, + uint32_t *file_handle, uint64_t *length, uint32_t *file_meta_data_1, + uint32_t *file_meta_data_2, uint32_t *file_meta_data_3, + uint32_t *file_meta_data_4); + +/** @brief Create a PLDM response for NewFileAvailableWithMetaData + * + * @param[in] instance_id - Message's instance id + * @param[in] completion_code - PLDM completion code + * @param[in,out] msg - Message will be written to this + * @return pldm_completion_codes + * @note Caller is responsible for memory alloc and dealloc of param 'msg' + */ +int encode_new_file_with_metadata_resp(uint8_t instance_id, + uint8_t completion_code, + struct pldm_msg *msg); + +#ifdef __cplusplus +} +#endif + +#endif /* FILEIO_H */ diff --git a/pldm/include/libpldm/oem/ibm/libpldm/fru_oem_ibm.h b/pldm/include/libpldm/oem/ibm/libpldm/fru_oem_ibm.h new file mode 100644 index 0000000..c97f8b0 --- /dev/null +++ b/pldm/include/libpldm/oem/ibm/libpldm/fru_oem_ibm.h @@ -0,0 +1,21 @@ +#ifndef OEM_IBM_FRU_H +#define OEM_IBM_FRU_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +enum pldm_oem_ibm_fru_field_type { + PLDM_OEM_FRU_FIELD_TYPE_IANA = 0X01, + PLDM_OEM_FRU_FIELD_TYPE_RT = 0X02, + PLDM_OEM_FRU_FIELD_TYPE_LOCATION_CODE = 0XFE, +}; + +#ifdef __cplusplus +} +#endif + +#endif /* OEM_IBM_FRU_H */ diff --git a/pldm/include/libpldm/oem/ibm/libpldm/host.h b/pldm/include/libpldm/oem/ibm/libpldm/host.h new file mode 100644 index 0000000..ed121ae --- /dev/null +++ b/pldm/include/libpldm/oem/ibm/libpldm/host.h @@ -0,0 +1,108 @@ +#ifndef OEM_IBM_HOST_H +#define OEM_IBM_HOST_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include "base.h" + +/* Maximum size for request */ +#define PLDM_GET_ALERT_STATUS_REQ_BYTES 1 + +/* Response lengths are inclusive of completion code */ +#define PLDM_GET_ALERT_STATUS_RESP_BYTES 9 + +enum pldm_host_commands { + PLDM_HOST_GET_ALERT_STATUS = 0xF0 // Custom oem cmd +}; + +/** @brief PLDM Command specific codes + */ +enum pldm_host_completion_codes { PLDM_HOST_UNSUPPORTED_FORMAT_VERSION = 0x81 }; + +/** @struct pldm_get_alert_states_resp + * + * Structure representing GetAlertStatus response packet + */ +struct pldm_get_alert_status_resp { + uint8_t completion_code; + uint32_t rack_entry; + uint32_t pri_cec_node; +} __attribute__((packed)); + +/* Requester */ + +/* GetAlertStatus */ + +/** @brief Create a PLDM request message for GetAlertStatus + * + * @param[in] instance_id - Message's instance id + * @param[in] version_id - The command/response format. 0x00 for this format + * @param[out] msg - Message will be written to this + * @param[in] payload_length - Length of request message payload + * @return pldm_completion_codes + * @note Caller is responsible for memory alloc and dealloc of param + * 'msg.payload' + */ +int encode_get_alert_status_req(uint8_t instance_id, uint8_t version_id, + struct pldm_msg *msg, size_t payload_length); + +/** @brief Decode GetAlertStatus response data + * + * Note: + * * If the return value is not PLDM_SUCCESS, it represents a + * transport layer error. + * * If the completion_code value is not PLDM_SUCCESS, it represents a + * protocol layer error and all the out-parameters are invalid. + * + * @param[in] msg - Request message + * @param[in] payload_length - Length of request message payload + * @param[out] completion_code - PLDM completion code + * @param[out] rack_entry - Enclosure ID, Alert Status, Flags, Config ID + * @param[out] pri_cec_node - Enclosure ID, Alert Status, Flags, Config ID + * @return pldm_completion_codes + */ +int decode_get_alert_status_resp(const struct pldm_msg *msg, + size_t payload_length, + uint8_t *completion_code, uint32_t *rack_entry, + uint32_t *pri_cec_node); + +/* Responder */ + +/* GetAlertStatus */ + +/** @brief Decode GetAlertStatus request data + * + * @param[in] msg - Request message + * @param[in] payload_length - Length of request message payload + * @param[out] version_id - the command/response format. 0x00 for this format + * @return pldm_completion_codes + */ +int decode_get_alert_status_req(const struct pldm_msg *msg, + size_t payload_length, uint8_t *version_id); + +/** @brief Create a PLDM OEM response message for GetAlertStatus + * + * @param[in] instance_id - Message's instance id + * @param[in] completion_code - PLDM completion code + * @param[in] rack_entry - Enclosure ID, Alert Status, Flags, Config ID + * @param[in] pri_cec_node - Enclosure ID, Alert Status, Flags, Config ID + * @param[out] msg - Message will be written to this + * @param[in] payload_length - Length of request message payload + * @return pldm_completion_codes + * @note Caller is responsible for memory alloc and dealloc of param + * 'msg.body.payload' + */ +int encode_get_alert_status_resp(uint8_t instance_id, uint8_t completion_code, + uint32_t rack_entry, uint32_t pri_cec_node, + struct pldm_msg *msg, size_t payload_length); + +#ifdef __cplusplus +} +#endif + +#endif /* OEM_IBM_HOST_H */ diff --git a/pldm/include/libpldm/oem/ibm/libpldm/platform_oem_ibm.h b/pldm/include/libpldm/oem/ibm/libpldm/platform_oem_ibm.h new file mode 100644 index 0000000..f0aafd3 --- /dev/null +++ b/pldm/include/libpldm/oem/ibm/libpldm/platform_oem_ibm.h @@ -0,0 +1,56 @@ +#ifndef PLATFORM_OEM_IBM_H +#define PLATFORM_OEM_IBM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "base.h" +#include +#include + +enum pldm_event_types_ibm_oem { + PLDM_EVENT_TYPE_OEM_EVENT_BIOS_ATTRIBUTE_UPDATE = 0xF0, +}; + +/** @struct pldm_bios_attribute_update_event_req + * + * Structure representing PlatformEventMessage command request data for OEM + * event type BIOS attribute update. + */ +struct pldm_bios_attribute_update_event_req { + uint8_t format_version; + uint8_t tid; + uint8_t event_class; + uint8_t num_handles; + uint8_t bios_attribute_handles[1]; +} __attribute__((packed)); + +/** @brief Encode PlatformEventMessage request data for BIOS attribute update + * + * @param[in] instance_id - Message's instance id + * @param[in] format_version - Version of the event format + * @param[in] tid - Terminus ID for the terminus that originated the event + * message + * @param[in] num_handles - Number of BIOS handles with an update + * @param[in] list_of_handles - Pointer to the list of BIOS attribute handles + * @param[in] payload_length - Length of request message payload + * @param[out] msg - Message will be written to this + * + * @return pldm_completion_codes + * + * @note Caller is responsible for memory alloc and dealloc of param + * 'msg.payload' + */ +int encode_bios_attribute_update_event_req(uint8_t instance_id, + uint8_t format_version, uint8_t tid, + uint8_t num_handles, + const uint8_t *list_of_handles, + size_t payload_length, + struct pldm_msg *msg); + +#ifdef __cplusplus +} +#endif + +#endif /* PLATFORM_OEM_IBM_H */ \ No newline at end of file diff --git a/pldm/include/libpldm/oem/ibm/libpldm/state_set_oem_ibm.h b/pldm/include/libpldm/oem/ibm/libpldm/state_set_oem_ibm.h new file mode 100644 index 0000000..5c8378b --- /dev/null +++ b/pldm/include/libpldm/oem/ibm/libpldm/state_set_oem_ibm.h @@ -0,0 +1,58 @@ +#ifndef STATE_SET_OEM_IBM_H +#define STATE_SET_OEM_IBM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief IBM OEM State Set IDs */ +enum ibm_oem_pldm_state_set_ids { + PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE = 32768, + PLDM_OEM_IBM_BOOT_STATE = 32769, + PLDM_OEM_IBM_VERIFICATION_STATE = 32770, + PLDM_OEM_IBM_SYSTEM_POWER_STATE = 32771, + PLDM_OEM_IBM_SBE_MAINTENANCE_STATE = 32772, + PLDM_OEM_IBM_SBE_HRESET_STATE = 32776, +}; + +enum ibm_oem_pldm_state_set_firmware_update_state_values { + START = 0x1, + END = 0x2, + FAIL = 0x3, + ABORT = 0x4, + ACCEPT = 0x5, + REJECT = 0x6, +}; + +enum ibm_oem_pldm_state_set_boot_state_values { + P = 0x1, + T = 0x2, +}; + +enum ibm_oem_pldm_state_set_verification_state_values { + VALID = 0x0, + ENTITLEMENT_FAIL = 0x1, + BANNED_PLATFORM_FAIL = 0x2, + MIN_MIF_FAIL = 0x4, +}; + +enum ibm_oem_pldm_state_set_system_power_state_values { + POWER_CYCLE_HARD = 0x1 +}; + +enum ibm_oem_pldm_state_set_sbe_dump_state_values { + SBE_DUMP_COMPLETED = 0x1, + SBE_RETRY_REQUIRED = 0x2, +}; + +enum ibm_oem_pldm_state_set_sbe_hreset_state_values { + SBE_HRESET_NOT_READY = 0x1, + SBE_HRESET_READY = 0x2, + SBE_HRESET_FAILED = 0x3, +}; + +#ifdef __cplusplus +} +#endif + +#endif /* STATE_SET_OEM_IBM_H */ diff --git a/pldm/libpldm/oem/ibm/Makefile.inc b/pldm/libpldm/oem/ibm/Makefile.inc new file mode 100644 index 0000000..e107539 --- /dev/null +++ b/pldm/libpldm/oem/ibm/Makefile.inc @@ -0,0 +1,19 @@ +# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +# Copyright 2022 IBM Corp. + +LIBPLDM_IBM_DIR ?= pldm/libpldm/oem/ibm +SUBDIRS += $(LIBPLDM_IBM_DIR) + +LIBPLDM_IBM_OBJS = file_io.o host.o platform.o + +CPPFLAGS += -I$(SRC)/pldm/include/ \ + -I$(SRC)/pldm/include/libpldm/ \ + -I$(SRC)/pldm/include/libpldm/oem/ibm/ + +CFLAGS_$(LIBPLDM_IBM_DIR)/ = -Wno-error \ + -Wno-declaration-after-statement \ + -Wno-strict-prototypes + +LIBPLDM_IBM = $(LIBPLDM_IBM_DIR)/built-in.a + +$(LIBPLDM_IBM): $(LIBPLDM_IBM_OBJS:%=$(LIBPLDM_IBM_DIR)/%) diff --git a/pldm/libpldm/oem/ibm/README.skiboot b/pldm/libpldm/oem/ibm/README.skiboot new file mode 100644 index 0000000..c76bc43 --- /dev/null +++ b/pldm/libpldm/oem/ibm/README.skiboot @@ -0,0 +1,15 @@ +skiboot/pldm/ibm/libpldm/ is a minimally modified version of upstream +ibm/libpldm/ that is distributed with the openbmc project +hosted at https://github.com/openbmc/pldm.git + +This version is taken from pldm.git commit 8fadc9e03fdb ("pldmtool: Fix +tool to show the oem entities") by copying most of files from the +pldm/oem/ibm/libpldm directory. + +The only modifications from the upstream source are the additions of +this file, Makefile.inc which has been derived from the original +Makefile.inc, an update of platform_oem_ibm.c (change an include +definition) and the removal of several unnecessary folders and files. + +Local libpldm changes should be kept to a minimum, and submitted +upstream if possible. diff --git a/pldm/libpldm/oem/ibm/file_io.c b/pldm/libpldm/oem/ibm/file_io.c new file mode 100644 index 0000000..79132a1 --- /dev/null +++ b/pldm/libpldm/oem/ibm/file_io.c @@ -0,0 +1,1057 @@ +#include "libpldm/file_io.h" +#include "base.h" +#include +#include + +int decode_rw_file_memory_req(const struct pldm_msg *msg, size_t payload_length, + uint32_t *file_handle, uint32_t *offset, + uint32_t *length, uint64_t *address) +{ + if (msg == NULL || file_handle == NULL || offset == NULL || + length == NULL || address == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + if (payload_length != PLDM_RW_FILE_MEM_REQ_BYTES) { + return PLDM_ERROR_INVALID_LENGTH; + } + + struct pldm_read_write_file_memory_req *request = + (struct pldm_read_write_file_memory_req *)msg->payload; + + *file_handle = le32toh(request->file_handle); + *offset = le32toh(request->offset); + *length = le32toh(request->length); + *address = le64toh(request->address); + + return PLDM_SUCCESS; +} + +int encode_rw_file_memory_resp(uint8_t instance_id, uint8_t command, + uint8_t completion_code, uint32_t length, + struct pldm_msg *msg) +{ + if (msg == NULL) { + return PLDM_ERROR_INVALID_LENGTH; + } + + struct pldm_header_info header = {0}; + header.msg_type = PLDM_RESPONSE; + header.instance = instance_id; + header.pldm_type = PLDM_OEM; + header.command = command; + uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); + if (rc != PLDM_SUCCESS) { + return rc; + } + + struct pldm_read_write_file_memory_resp *response = + (struct pldm_read_write_file_memory_resp *)msg->payload; + response->completion_code = completion_code; + if (response->completion_code == PLDM_SUCCESS) { + response->length = htole32(length); + } + + return PLDM_SUCCESS; +} + +int encode_rw_file_memory_req(uint8_t instance_id, uint8_t command, + uint32_t file_handle, uint32_t offset, + uint32_t length, uint64_t address, + struct pldm_msg *msg) +{ + if (msg == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + struct pldm_header_info header = {0}; + header.msg_type = PLDM_REQUEST; + header.instance = instance_id; + header.pldm_type = PLDM_OEM; + header.command = command; + uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); + if (rc != PLDM_SUCCESS) { + return rc; + } + + struct pldm_read_write_file_memory_req *req = + (struct pldm_read_write_file_memory_req *)msg->payload; + req->file_handle = htole32(file_handle); + req->offset = htole32(offset); + req->length = htole32(length); + req->address = htole64(address); + return PLDM_SUCCESS; +} + +int decode_rw_file_memory_resp(const struct pldm_msg *msg, + size_t payload_length, uint8_t *completion_code, + uint32_t *length) +{ + if (msg == NULL || length == NULL || completion_code == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + if (payload_length != PLDM_RW_FILE_MEM_RESP_BYTES) { + return PLDM_ERROR_INVALID_LENGTH; + } + + struct pldm_read_write_file_memory_resp *response = + (struct pldm_read_write_file_memory_resp *)msg->payload; + *completion_code = response->completion_code; + if (*completion_code == PLDM_SUCCESS) { + *length = le32toh(response->length); + } + + return PLDM_SUCCESS; +} + +int decode_get_file_table_req(const struct pldm_msg *msg, size_t payload_length, + uint32_t *transfer_handle, + uint8_t *transfer_opflag, uint8_t *table_type) +{ + if (msg == NULL || transfer_handle == NULL || transfer_opflag == NULL || + table_type == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + if (payload_length != PLDM_GET_FILE_TABLE_REQ_BYTES) { + return PLDM_ERROR_INVALID_LENGTH; + } + + struct pldm_get_file_table_req *request = + (struct pldm_get_file_table_req *)msg->payload; + + *transfer_handle = le32toh(request->transfer_handle); + *transfer_opflag = request->operation_flag; + *table_type = request->table_type; + + return PLDM_SUCCESS; +} + +int encode_get_file_table_resp(uint8_t instance_id, uint8_t completion_code, + uint32_t next_transfer_handle, + uint8_t transfer_flag, const uint8_t *table_data, + size_t table_size, struct pldm_msg *msg) +{ + if (msg == NULL) { + return PLDM_ERROR_INVALID_LENGTH; + } + + struct pldm_header_info header = {0}; + header.msg_type = PLDM_RESPONSE; + header.instance = instance_id; + header.pldm_type = PLDM_OEM; + header.command = PLDM_GET_FILE_TABLE; + uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); + if (rc != PLDM_SUCCESS) { + return rc; + } + + struct pldm_get_file_table_resp *response = + (struct pldm_get_file_table_resp *)msg->payload; + response->completion_code = completion_code; + + if (completion_code == PLDM_SUCCESS) { + response->next_transfer_handle = htole32(next_transfer_handle); + response->transfer_flag = transfer_flag; + memcpy(response->table_data, table_data, table_size); + } + + return PLDM_SUCCESS; +} + +int encode_get_file_table_req(uint8_t instance_id, uint32_t transfer_handle, + uint8_t transfer_opflag, uint8_t table_type, + struct pldm_msg *msg) +{ + if (msg == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + struct pldm_header_info header = {0}; + header.msg_type = PLDM_REQUEST; + header.instance = instance_id; + header.pldm_type = PLDM_OEM; + header.command = PLDM_GET_FILE_TABLE; + uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); + if (rc != PLDM_SUCCESS) { + return rc; + } + + struct pldm_get_file_table_req *request = + (struct pldm_get_file_table_req *)msg->payload; + + request->transfer_handle = htole32(transfer_handle); + request->operation_flag = transfer_opflag; + request->table_type = table_type; + return PLDM_SUCCESS; +} + +int decode_get_file_table_resp(const struct pldm_msg *msg, + size_t payload_length, uint8_t *completion_code, + uint32_t *next_transfer_handle, + uint8_t *transfer_flag, + uint8_t *file_table_data_start_offset, + size_t *file_table_length) +{ + if (msg == NULL || transfer_flag == NULL || + next_transfer_handle == NULL || completion_code == NULL || + file_table_data_start_offset == NULL || file_table_length == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + if (payload_length <= PLDM_GET_FILE_TABLE_MIN_RESP_BYTES) { + return PLDM_ERROR_INVALID_LENGTH; + } + + *completion_code = msg->payload[0]; + + if (PLDM_SUCCESS != *completion_code) { + return PLDM_SUCCESS; + } + + struct pldm_get_file_table_resp *response = + (struct pldm_get_file_table_resp *)msg->payload; + + *next_transfer_handle = le32toh(response->next_transfer_handle); + *transfer_flag = response->transfer_flag; + *file_table_data_start_offset = sizeof(*completion_code) + + sizeof(*next_transfer_handle) + + sizeof(*transfer_flag); + *file_table_length = + payload_length - PLDM_GET_FILE_TABLE_MIN_RESP_BYTES; + + return PLDM_SUCCESS; +} + +int decode_read_file_req(const struct pldm_msg *msg, size_t payload_length, + uint32_t *file_handle, uint32_t *offset, + uint32_t *length) +{ + if (msg == NULL || file_handle == NULL || offset == NULL || + length == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + if (payload_length != PLDM_READ_FILE_REQ_BYTES) { + return PLDM_ERROR_INVALID_LENGTH; + } + + struct pldm_read_file_req *request = + (struct pldm_read_file_req *)msg->payload; + + *file_handle = le32toh(request->file_handle); + *offset = le32toh(request->offset); + *length = le32toh(request->length); + + return PLDM_SUCCESS; +} + +int encode_read_file_req(uint8_t instance_id, uint32_t file_handle, + uint32_t offset, uint32_t length, struct pldm_msg *msg) +{ + if (msg == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + if (length == 0) { + return PLDM_ERROR_INVALID_LENGTH; + } + + struct pldm_header_info header = {0}; + header.msg_type = PLDM_REQUEST; + header.instance = instance_id; + header.pldm_type = PLDM_OEM; + header.command = PLDM_READ_FILE; + uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); + if (rc != PLDM_SUCCESS) { + return rc; + } + + struct pldm_read_file_req *request = + (struct pldm_read_file_req *)msg->payload; + + request->file_handle = htole32(file_handle); + request->offset = htole32(offset); + request->length = htole32(length); + + return PLDM_SUCCESS; +} + +int decode_read_file_resp(const struct pldm_msg *msg, size_t payload_length, + uint8_t *completion_code, uint32_t *length, + size_t *file_data_offset) +{ + if (msg == NULL || completion_code == NULL || length == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + if (payload_length < PLDM_READ_FILE_RESP_BYTES) { + return PLDM_ERROR_INVALID_LENGTH; + } + + struct pldm_read_file_resp *response = + (struct pldm_read_file_resp *)msg->payload; + + *completion_code = response->completion_code; + if (*completion_code == PLDM_SUCCESS) { + *length = le32toh(response->length); + if (payload_length != PLDM_READ_FILE_RESP_BYTES + *length) { + return PLDM_ERROR_INVALID_LENGTH; + } + *file_data_offset = sizeof(*completion_code) + sizeof(*length); + } + + return PLDM_SUCCESS; +} + +int encode_read_file_resp(uint8_t instance_id, uint8_t completion_code, + uint32_t length, struct pldm_msg *msg) +{ + if (msg == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + struct pldm_header_info header = {0}; + header.msg_type = PLDM_RESPONSE; + header.instance = instance_id; + header.pldm_type = PLDM_OEM; + header.command = PLDM_READ_FILE; + uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); + if (rc != PLDM_SUCCESS) { + return rc; + } + + struct pldm_read_file_resp *response = + (struct pldm_read_file_resp *)msg->payload; + response->completion_code = completion_code; + + if (response->completion_code == PLDM_SUCCESS) { + response->length = htole32(length); + } + + return PLDM_SUCCESS; +} + +int decode_write_file_req(const struct pldm_msg *msg, size_t payload_length, + uint32_t *file_handle, uint32_t *offset, + uint32_t *length, size_t *file_data_offset) +{ + if (msg == NULL || file_handle == NULL || length == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + if (payload_length < PLDM_WRITE_FILE_REQ_BYTES) { + return PLDM_ERROR_INVALID_LENGTH; + } + + struct pldm_write_file_req *request = + (struct pldm_write_file_req *)msg->payload; + + *file_handle = le32toh(request->file_handle); + *offset = le32toh(request->offset); + *length = le32toh(request->length); + if (payload_length != PLDM_WRITE_FILE_REQ_BYTES + *length) { + return PLDM_ERROR_INVALID_LENGTH; + } + *file_data_offset = + sizeof(*file_handle) + sizeof(*offset) + sizeof(*length); + + return PLDM_SUCCESS; +} + +int encode_write_file_req(uint8_t instance_id, uint32_t file_handle, + uint32_t offset, uint32_t length, + struct pldm_msg *msg) +{ + if (msg == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + if (length == 0) { + return PLDM_ERROR_INVALID_LENGTH; + } + + struct pldm_header_info header = {0}; + header.msg_type = PLDM_REQUEST; + header.instance = instance_id; + header.pldm_type = PLDM_OEM; + header.command = PLDM_WRITE_FILE; + uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); + if (rc != PLDM_SUCCESS) { + return rc; + } + + struct pldm_write_file_req *request = + (struct pldm_write_file_req *)msg->payload; + + request->file_handle = htole32(file_handle); + request->offset = htole32(offset); + request->length = htole32(length); + + return PLDM_SUCCESS; +} + +int decode_write_file_resp(const struct pldm_msg *msg, size_t payload_length, + uint8_t *completion_code, uint32_t *length) +{ + if (msg == NULL || completion_code == NULL || length == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + if (payload_length != PLDM_WRITE_FILE_RESP_BYTES) { + return PLDM_ERROR_INVALID_LENGTH; + } + + struct pldm_write_file_resp *response = + (struct pldm_write_file_resp *)msg->payload; + + *completion_code = le32toh(response->completion_code); + if (response->completion_code == PLDM_SUCCESS) { + *length = le32toh(response->length); + } + + return PLDM_SUCCESS; +} + +int encode_write_file_resp(uint8_t instance_id, uint8_t completion_code, + uint32_t length, struct pldm_msg *msg) +{ + if (msg == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + struct pldm_header_info header = {0}; + header.msg_type = PLDM_RESPONSE; + header.instance = instance_id; + header.pldm_type = PLDM_OEM; + header.command = PLDM_WRITE_FILE; + uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); + if (rc != PLDM_SUCCESS) { + return rc; + } + + struct pldm_write_file_resp *response = + (struct pldm_write_file_resp *)msg->payload; + response->completion_code = completion_code; + + if (response->completion_code == PLDM_SUCCESS) { + response->length = htole32(length); + } + + return PLDM_SUCCESS; +} + +int decode_rw_file_by_type_memory_req(const struct pldm_msg *msg, + size_t payload_length, + uint16_t *file_type, + uint32_t *file_handle, uint32_t *offset, + uint32_t *length, uint64_t *address) +{ + if (msg == NULL || file_type == NULL || file_handle == NULL || + offset == NULL || length == NULL || address == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + if (payload_length != PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES) { + return PLDM_ERROR_INVALID_LENGTH; + } + + struct pldm_read_write_file_by_type_memory_req *request = + (struct pldm_read_write_file_by_type_memory_req *)msg->payload; + *file_type = le16toh(request->file_type); + *file_handle = le32toh(request->file_handle); + *offset = le32toh(request->offset); + *length = le32toh(request->length); + *address = le64toh(request->address); + + return PLDM_SUCCESS; +} + +int encode_rw_file_by_type_memory_resp(uint8_t instance_id, uint8_t command, + uint8_t completion_code, uint32_t length, + struct pldm_msg *msg) +{ + if (msg == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + struct pldm_header_info header = {0}; + header.msg_type = PLDM_RESPONSE; + header.instance = instance_id; + header.pldm_type = PLDM_OEM; + header.command = command; + uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); + if (rc != PLDM_SUCCESS) { + return rc; + } + + struct pldm_read_write_file_by_type_memory_resp *response = + (struct pldm_read_write_file_by_type_memory_resp *)msg->payload; + response->completion_code = completion_code; + if (response->completion_code == PLDM_SUCCESS) { + response->length = htole32(length); + } + + return PLDM_SUCCESS; +} + +int encode_rw_file_by_type_memory_req(uint8_t instance_id, uint8_t command, + uint16_t file_type, uint32_t file_handle, + uint32_t offset, uint32_t length, + uint64_t address, struct pldm_msg *msg) +{ + if (msg == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + struct pldm_header_info header = {0}; + header.msg_type = PLDM_REQUEST; + header.instance = instance_id; + header.pldm_type = PLDM_OEM; + header.command = command; + uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); + if (rc != PLDM_SUCCESS) { + return rc; + } + + struct pldm_read_write_file_by_type_memory_req *req = + (struct pldm_read_write_file_by_type_memory_req *)msg->payload; + req->file_type = htole16(file_type); + req->file_handle = htole32(file_handle); + req->offset = htole32(offset); + req->length = htole32(length); + req->address = htole64(address); + + return PLDM_SUCCESS; +} + +int decode_rw_file_by_type_memory_resp(const struct pldm_msg *msg, + size_t payload_length, + uint8_t *completion_code, + uint32_t *length) +{ + if (msg == NULL || length == NULL || completion_code == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + if (payload_length != PLDM_RW_FILE_BY_TYPE_MEM_RESP_BYTES) { + return PLDM_ERROR_INVALID_LENGTH; + } + + struct pldm_read_write_file_by_type_memory_resp *response = + (struct pldm_read_write_file_by_type_memory_resp *)msg->payload; + *completion_code = response->completion_code; + if (*completion_code == PLDM_SUCCESS) { + *length = le32toh(response->length); + } + + return PLDM_SUCCESS; +} + +int decode_new_file_req(const struct pldm_msg *msg, size_t payload_length, + uint16_t *file_type, uint32_t *file_handle, + uint64_t *length) +{ + if (msg == NULL || file_type == NULL || file_handle == NULL || + length == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + if (payload_length != PLDM_NEW_FILE_REQ_BYTES) { + return PLDM_ERROR_INVALID_LENGTH; + } + + struct pldm_new_file_req *request = + (struct pldm_new_file_req *)msg->payload; + *file_type = le16toh(request->file_type); + *file_handle = le32toh(request->file_handle); + *length = le64toh(request->length); + + return PLDM_SUCCESS; +} + +int encode_new_file_resp(uint8_t instance_id, uint8_t completion_code, + struct pldm_msg *msg) +{ + if (msg == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + struct pldm_header_info header = {0}; + header.msg_type = PLDM_RESPONSE; + header.instance = instance_id; + header.pldm_type = PLDM_OEM; + header.command = PLDM_NEW_FILE_AVAILABLE; + uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); + if (rc != PLDM_SUCCESS) { + return rc; + } + + struct pldm_new_file_resp *response = + (struct pldm_new_file_resp *)msg->payload; + response->completion_code = completion_code; + + return PLDM_SUCCESS; +} + +int encode_new_file_req(uint8_t instance_id, uint16_t file_type, + uint32_t file_handle, uint64_t length, + struct pldm_msg *msg) +{ + if (msg == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + struct pldm_header_info header = {0}; + header.msg_type = PLDM_REQUEST; + header.instance = instance_id; + header.pldm_type = PLDM_OEM; + header.command = PLDM_NEW_FILE_AVAILABLE; + uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); + if (rc != PLDM_SUCCESS) { + return rc; + } + + struct pldm_new_file_req *req = + (struct pldm_new_file_req *)msg->payload; + req->file_type = htole16(file_type); + req->file_handle = htole32(file_handle); + req->length = htole64(length); + + return PLDM_SUCCESS; +} + +int decode_new_file_resp(const struct pldm_msg *msg, size_t payload_length, + uint8_t *completion_code) +{ + if (msg == NULL || completion_code == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + if (payload_length != PLDM_NEW_FILE_RESP_BYTES) { + return PLDM_ERROR_INVALID_LENGTH; + } + + struct pldm_new_file_resp *response = + (struct pldm_new_file_resp *)msg->payload; + *completion_code = response->completion_code; + + return PLDM_SUCCESS; +} + +int decode_rw_file_by_type_req(const struct pldm_msg *msg, + size_t payload_length, uint16_t *file_type, + uint32_t *file_handle, uint32_t *offset, + uint32_t *length) +{ + if (msg == NULL || file_type == NULL || file_handle == NULL || + offset == NULL || length == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + if (payload_length < PLDM_RW_FILE_BY_TYPE_REQ_BYTES) { + return PLDM_ERROR_INVALID_LENGTH; + } + + struct pldm_read_write_file_by_type_req *request = + (struct pldm_read_write_file_by_type_req *)msg->payload; + *file_type = le16toh(request->file_type); + *file_handle = le32toh(request->file_handle); + *offset = le32toh(request->offset); + *length = le32toh(request->length); + + return PLDM_SUCCESS; +} + +int encode_rw_file_by_type_resp(uint8_t instance_id, uint8_t command, + uint8_t completion_code, uint32_t length, + struct pldm_msg *msg) +{ + if (msg == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + if (command != PLDM_READ_FILE_BY_TYPE && + command != PLDM_WRITE_FILE_BY_TYPE) { + return PLDM_ERROR_INVALID_DATA; + } + + struct pldm_header_info header = {0}; + header.msg_type = PLDM_RESPONSE; + header.instance = instance_id; + header.pldm_type = PLDM_OEM; + header.command = command; + uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); + if (rc != PLDM_SUCCESS) { + return rc; + } + + struct pldm_read_write_file_by_type_resp *response = + (struct pldm_read_write_file_by_type_resp *)msg->payload; + response->completion_code = completion_code; + if (response->completion_code == PLDM_SUCCESS) { + response->length = htole32(length); + } + + return PLDM_SUCCESS; +} + +int encode_rw_file_by_type_req(uint8_t instance_id, uint8_t command, + uint16_t file_type, uint32_t file_handle, + uint32_t offset, uint32_t length, + struct pldm_msg *msg) +{ + if (msg == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + if (command != PLDM_READ_FILE_BY_TYPE && + command != PLDM_WRITE_FILE_BY_TYPE) { + return PLDM_ERROR_INVALID_DATA; + } + + struct pldm_header_info header = {0}; + header.msg_type = PLDM_REQUEST; + header.instance = instance_id; + header.pldm_type = PLDM_OEM; + header.command = command; + uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); + if (rc != PLDM_SUCCESS) { + return rc; + } + + struct pldm_read_write_file_by_type_req *req = + (struct pldm_read_write_file_by_type_req *)msg->payload; + req->file_type = htole16(file_type); + req->file_handle = htole32(file_handle); + req->offset = htole32(offset); + req->length = htole32(length); + + return PLDM_SUCCESS; +} + +int decode_rw_file_by_type_resp(const struct pldm_msg *msg, + size_t payload_length, uint8_t *completion_code, + uint32_t *length) +{ + if (msg == NULL || length == NULL || completion_code == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + if (payload_length != PLDM_RW_FILE_BY_TYPE_RESP_BYTES) { + return PLDM_ERROR_INVALID_LENGTH; + } + + struct pldm_read_write_file_by_type_resp *response = + (struct pldm_read_write_file_by_type_resp *)msg->payload; + *completion_code = response->completion_code; + if (*completion_code == PLDM_SUCCESS) { + *length = le32toh(response->length); + } + + return PLDM_SUCCESS; +} + +int decode_file_ack_req(const struct pldm_msg *msg, size_t payload_length, + uint16_t *file_type, uint32_t *file_handle, + uint8_t *file_status) +{ + if (msg == NULL || file_type == NULL || file_handle == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + if (payload_length != PLDM_FILE_ACK_REQ_BYTES) { + return PLDM_ERROR_INVALID_LENGTH; + } + + struct pldm_file_ack_req *request = + (struct pldm_file_ack_req *)msg->payload; + *file_type = le16toh(request->file_type); + *file_handle = le32toh(request->file_handle); + *file_status = request->file_status; + + return PLDM_SUCCESS; +} + +int encode_file_ack_resp(uint8_t instance_id, uint8_t completion_code, + struct pldm_msg *msg) +{ + if (msg == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + struct pldm_header_info header = {0}; + header.msg_type = PLDM_RESPONSE; + header.instance = instance_id; + header.pldm_type = PLDM_OEM; + header.command = PLDM_FILE_ACK; + uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); + if (rc != PLDM_SUCCESS) { + return rc; + } + + struct pldm_file_ack_resp *response = + (struct pldm_file_ack_resp *)msg->payload; + response->completion_code = completion_code; + + return PLDM_SUCCESS; +} + +int encode_file_ack_req(uint8_t instance_id, uint16_t file_type, + uint32_t file_handle, uint8_t file_status, + struct pldm_msg *msg) +{ + if (msg == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + struct pldm_header_info header = {0}; + header.msg_type = PLDM_REQUEST; + header.instance = instance_id; + header.pldm_type = PLDM_OEM; + header.command = PLDM_FILE_ACK; + uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); + if (rc != PLDM_SUCCESS) { + return rc; + } + + struct pldm_file_ack_req *req = + (struct pldm_file_ack_req *)msg->payload; + req->file_type = htole16(file_type); + req->file_handle = htole32(file_handle); + req->file_status = file_status; + + return PLDM_SUCCESS; +} + +int decode_file_ack_resp(const struct pldm_msg *msg, size_t payload_length, + uint8_t *completion_code) +{ + if (msg == NULL || completion_code == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + if (payload_length != PLDM_FILE_ACK_RESP_BYTES) { + return PLDM_ERROR_INVALID_LENGTH; + } + + struct pldm_file_ack_resp *response = + (struct pldm_file_ack_resp *)msg->payload; + *completion_code = response->completion_code; + + return PLDM_SUCCESS; +} + +int encode_file_ack_with_meta_data_req( + uint8_t instance_id, uint16_t file_type, uint32_t file_handle, + uint8_t file_status, uint32_t file_meta_data_1, uint32_t file_meta_data_2, + uint32_t file_meta_data_3, uint32_t file_meta_data_4, struct pldm_msg *msg) +{ + if (msg == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + struct pldm_header_info header = {0}; + header.msg_type = PLDM_REQUEST; + header.instance = instance_id; + header.pldm_type = PLDM_OEM; + header.command = PLDM_FILE_ACK_WITH_META_DATA; + uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); + if (rc != PLDM_SUCCESS) { + return rc; + } + + struct pldm_file_ack_with_meta_data_req *req = + (struct pldm_file_ack_with_meta_data_req *)msg->payload; + req->file_type = htole16(file_type); + req->file_handle = htole32(file_handle); + req->file_status = file_status; + req->file_meta_data_1 = htole32(file_meta_data_1); + req->file_meta_data_2 = htole32(file_meta_data_2); + req->file_meta_data_3 = htole32(file_meta_data_3); + req->file_meta_data_4 = htole32(file_meta_data_4); + + return PLDM_SUCCESS; +} + +int decode_file_ack_with_meta_data_resp(const struct pldm_msg *msg, + size_t payload_length, + uint8_t *completion_code) +{ + if (msg == NULL || completion_code == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + if (payload_length != PLDM_FILE_ACK_WITH_META_DATA_RESP_BYTES) { + return PLDM_ERROR_INVALID_LENGTH; + } + + struct pldm_file_ack_with_meta_data_resp *response = + (struct pldm_file_ack_with_meta_data_resp *)msg->payload; + *completion_code = response->completion_code; + + return PLDM_SUCCESS; +} + +int decode_file_ack_with_meta_data_req( + const struct pldm_msg *msg, size_t payload_length, uint16_t *file_type, + uint32_t *file_handle, uint8_t *file_status, uint32_t *file_meta_data_1, + uint32_t *file_meta_data_2, uint32_t *file_meta_data_3, + uint32_t *file_meta_data_4) +{ + if (msg == NULL || file_type == NULL || file_handle == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + if (payload_length != PLDM_FILE_ACK_WITH_META_DATA_REQ_BYTES) { + return PLDM_ERROR_INVALID_LENGTH; + } + + struct pldm_file_ack_with_meta_data_req *request = + (struct pldm_file_ack_with_meta_data_req *)msg->payload; + *file_type = le16toh(request->file_type); + *file_handle = le32toh(request->file_handle); + *file_status = request->file_status; + *file_meta_data_1 = le32toh(request->file_meta_data_1); + *file_meta_data_2 = le32toh(request->file_meta_data_2); + *file_meta_data_3 = le32toh(request->file_meta_data_3); + *file_meta_data_4 = le32toh(request->file_meta_data_4); + + return PLDM_SUCCESS; +} + +int encode_file_ack_with_meta_data_resp(uint8_t instance_id, + uint8_t completion_code, + struct pldm_msg *msg) +{ + if (msg == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + struct pldm_header_info header = {0}; + header.msg_type = PLDM_RESPONSE; + header.instance = instance_id; + header.pldm_type = PLDM_OEM; + header.command = PLDM_FILE_ACK_WITH_META_DATA; + uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); + if (rc != PLDM_SUCCESS) { + return rc; + } + + struct pldm_file_ack_with_meta_data_resp *response = + (struct pldm_file_ack_with_meta_data_resp *)msg->payload; + response->completion_code = completion_code; + + return PLDM_SUCCESS; +} + +int encode_new_file_with_metadata_req( + uint8_t instance_id, uint16_t file_type, uint32_t file_handle, + uint64_t length, uint32_t file_meta_data_1, uint32_t file_meta_data_2, + uint32_t file_meta_data_3, uint32_t file_meta_data_4, struct pldm_msg *msg) +{ + if (msg == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + struct pldm_header_info header = {0}; + header.msg_type = PLDM_REQUEST; + header.instance = instance_id; + header.pldm_type = PLDM_OEM; + header.command = PLDM_NEW_FILE_AVAILABLE_WITH_META_DATA; + uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); + if (rc != PLDM_SUCCESS) { + return rc; + } + + struct pldm_new_file_with_metadata_req *req = + (struct pldm_new_file_with_metadata_req *)msg->payload; + req->file_type = htole16(file_type); + req->file_handle = htole32(file_handle); + req->length = htole64(length); + req->file_meta_data_1 = htole32(file_meta_data_1); + req->file_meta_data_2 = htole32(file_meta_data_2); + req->file_meta_data_3 = htole32(file_meta_data_3); + req->file_meta_data_4 = htole32(file_meta_data_4); + + return PLDM_SUCCESS; +} + +int decode_new_file_with_metadata_resp(const struct pldm_msg *msg, + size_t payload_length, + uint8_t *completion_code) +{ + if (msg == NULL || completion_code == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + if (payload_length != + PLDM_NEW_FILE_AVAILABLE_WITH_META_DATA_RESP_BYTES) { + return PLDM_ERROR_INVALID_LENGTH; + } + + struct pldm_new_file_with_metadata_resp *response = + (struct pldm_new_file_with_metadata_resp *)msg->payload; + + *completion_code = msg->payload[0]; + if (*completion_code == PLDM_SUCCESS) { + *completion_code = response->completion_code; + } + return PLDM_SUCCESS; +} + +int decode_new_file_with_metadata_req( + const struct pldm_msg *msg, size_t payload_length, uint16_t *file_type, + uint32_t *file_handle, uint64_t *length, uint32_t *file_meta_data_1, + uint32_t *file_meta_data_2, uint32_t *file_meta_data_3, + uint32_t *file_meta_data_4) +{ + if (msg == NULL || file_type == NULL || file_handle == NULL || + length == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + if (payload_length != + PLDM_NEW_FILE_AVAILABLE_WITH_META_DATA_REQ_BYTES) { + return PLDM_ERROR_INVALID_LENGTH; + } + + struct pldm_new_file_with_metadata_req *request = + (struct pldm_new_file_with_metadata_req *)msg->payload; + *file_type = le16toh(request->file_type); + *file_handle = le32toh(request->file_handle); + *length = le64toh(request->length); + *file_meta_data_1 = le32toh(request->file_meta_data_1); + *file_meta_data_2 = le32toh(request->file_meta_data_2); + *file_meta_data_3 = le32toh(request->file_meta_data_3); + *file_meta_data_4 = le32toh(request->file_meta_data_4); + + return PLDM_SUCCESS; +} + +int encode_new_file_with_metadata_resp(uint8_t instance_id, + uint8_t completion_code, + struct pldm_msg *msg) +{ + if (msg == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + struct pldm_header_info header = {0}; + header.msg_type = PLDM_RESPONSE; + header.instance = instance_id; + header.pldm_type = PLDM_OEM; + header.command = PLDM_NEW_FILE_AVAILABLE_WITH_META_DATA; + uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); + if (rc != PLDM_SUCCESS) { + return rc; + } + + struct pldm_new_file_with_metadata_resp *response = + (struct pldm_new_file_with_metadata_resp *)msg->payload; + + if (response->completion_code == PLDM_SUCCESS) { + response->completion_code = completion_code; + } + + return PLDM_SUCCESS; +} diff --git a/pldm/libpldm/oem/ibm/host.c b/pldm/libpldm/oem/ibm/host.c new file mode 100644 index 0000000..5cdcf74 --- /dev/null +++ b/pldm/libpldm/oem/ibm/host.c @@ -0,0 +1,108 @@ +#include "base.h" +#include +#include +#include + +#include "libpldm/host.h" + +int encode_get_alert_status_req(uint8_t instance_id, uint8_t version_id, + struct pldm_msg *msg, size_t payload_length) +{ + if (msg == NULL) { + return PLDM_ERROR_INVALID_LENGTH; + } + + if (payload_length != PLDM_GET_ALERT_STATUS_REQ_BYTES) { + return PLDM_ERROR_INVALID_LENGTH; + } + + struct pldm_header_info header = {0}; + header.msg_type = PLDM_REQUEST; + header.instance = instance_id; + header.pldm_type = PLDM_OEM; + header.command = PLDM_HOST_GET_ALERT_STATUS; + uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); + if (rc != PLDM_SUCCESS) { + return rc; + } + + msg->payload[0] = version_id; + + return PLDM_SUCCESS; +} + +int decode_get_alert_status_resp(const struct pldm_msg *msg, + size_t payload_length, + uint8_t *completion_code, uint32_t *rack_entry, + uint32_t *pri_cec_node) +{ + if (msg == NULL || completion_code == NULL || rack_entry == NULL || + pri_cec_node == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + *completion_code = msg->payload[0]; + if (PLDM_SUCCESS != *completion_code) { + return PLDM_SUCCESS; + } + + if (payload_length != PLDM_GET_ALERT_STATUS_RESP_BYTES) { + return PLDM_ERROR_INVALID_LENGTH; + } + + struct pldm_get_alert_status_resp *response = + (struct pldm_get_alert_status_resp *)msg->payload; + + *rack_entry = le32toh(response->rack_entry); + *pri_cec_node = le32toh(response->pri_cec_node); + + return PLDM_SUCCESS; +} + +int decode_get_alert_status_req(const struct pldm_msg *msg, + size_t payload_length, uint8_t *version_id) +{ + if (msg == NULL || version_id == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + if (payload_length != PLDM_GET_ALERT_STATUS_REQ_BYTES) { + return PLDM_ERROR_INVALID_LENGTH; + } + + *version_id = msg->payload[0]; + + return PLDM_SUCCESS; +} + +int encode_get_alert_status_resp(uint8_t instance_id, uint8_t completion_code, + uint32_t rack_entry, uint32_t pri_cec_node, + struct pldm_msg *msg, size_t payload_length) +{ + if (msg == NULL) { + return PLDM_ERROR_INVALID_LENGTH; + } + + if (payload_length != PLDM_GET_ALERT_STATUS_RESP_BYTES) { + return PLDM_ERROR_INVALID_DATA; + } + + struct pldm_header_info header = {0}; + header.msg_type = PLDM_RESPONSE; + header.instance = instance_id; + header.pldm_type = PLDM_OEM; + header.command = PLDM_HOST_GET_ALERT_STATUS; + uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); + if (rc != PLDM_SUCCESS) { + return rc; + } + + struct pldm_get_alert_status_resp *response = + (struct pldm_get_alert_status_resp *)msg->payload; + + response->completion_code = completion_code; + response->rack_entry = htole32(rack_entry); + response->pri_cec_node = htole32(pri_cec_node); + + return PLDM_SUCCESS; +} diff --git a/pldm/libpldm/oem/ibm/platform.c b/pldm/libpldm/oem/ibm/platform.c new file mode 100644 index 0000000..15e9463 --- /dev/null +++ b/pldm/libpldm/oem/ibm/platform.c @@ -0,0 +1,50 @@ +#include "libpldm/platform.h" +#include "libpldm/platform_oem_ibm.h" +#include + +int encode_bios_attribute_update_event_req(uint8_t instance_id, + uint8_t format_version, uint8_t tid, + uint8_t num_handles, + const uint8_t *list_of_handles, + size_t payload_length, + struct pldm_msg *msg) +{ + if (format_version != 1) { + return PLDM_ERROR_INVALID_DATA; + } + + if (msg == NULL || list_of_handles == NULL) { + return PLDM_ERROR_INVALID_DATA; + } + + if (num_handles == 0) { + return PLDM_ERROR_INVALID_DATA; + } + + if (payload_length != + (PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES + sizeof(num_handles) + + (num_handles * sizeof(uint16_t)))) { + return PLDM_ERROR_INVALID_LENGTH; + } + + struct pldm_header_info header = {0}; + header.msg_type = PLDM_REQUEST; + header.instance = instance_id; + header.pldm_type = PLDM_PLATFORM; + header.command = PLDM_PLATFORM_EVENT_MESSAGE; + uint8_t rc = pack_pldm_header(&header, &(msg->hdr)); + if (rc != PLDM_SUCCESS) { + return rc; + } + + struct pldm_bios_attribute_update_event_req *request = + (struct pldm_bios_attribute_update_event_req *)msg->payload; + request->format_version = format_version; + request->tid = tid; + request->event_class = PLDM_EVENT_TYPE_OEM_EVENT_BIOS_ATTRIBUTE_UPDATE; + request->num_handles = num_handles; + memcpy(request->bios_attribute_handles, list_of_handles, + num_handles * sizeof(uint16_t)); + + return PLDM_SUCCESS; +} -- cgit v1.1