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 --- 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 ++ 5 files changed, 1249 insertions(+) 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 (limited to 'pldm/libpldm') 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