diff mbox series

[V2,10/10] pldm/ibm/libpldm: Import oem IBM libpldm library

Message ID 20220315124914.51569-11-clombard@linux.vnet.ibm.com
State Superseded
Headers show
Series Import external libraries for MCTP/PLDM protocols | expand

Checks

Context Check Description
snowpatch_ozlabs/github-Docker_builds_and_checks success Successfully ran 7 jobs.

Commit Message

Christophe Lombard March 15, 2022, 12:49 p.m. UTC
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 <clombard@linux.vnet.ibm.com>
---
 Makefile.main                       |   3 +-
 pldm/ibm/libpldm/Makefile.inc       |  17 +
 pldm/ibm/libpldm/README.skiboot     |  15 +
 pldm/ibm/libpldm/file_io.c          | 841 ++++++++++++++++++++++++++++
 pldm/ibm/libpldm/file_io.h          | 725 ++++++++++++++++++++++++
 pldm/ibm/libpldm/fru.h              |  21 +
 pldm/ibm/libpldm/host.c             | 106 ++++
 pldm/ibm/libpldm/host.h             | 108 ++++
 pldm/ibm/libpldm/platform_oem_ibm.c |  50 ++
 pldm/ibm/libpldm/platform_oem_ibm.h |  56 ++
 10 files changed, 1941 insertions(+), 1 deletion(-)
 create mode 100644 pldm/ibm/libpldm/Makefile.inc
 create mode 100644 pldm/ibm/libpldm/README.skiboot
 create mode 100644 pldm/ibm/libpldm/file_io.c
 create mode 100644 pldm/ibm/libpldm/file_io.h
 create mode 100644 pldm/ibm/libpldm/fru.h
 create mode 100644 pldm/ibm/libpldm/host.c
 create mode 100644 pldm/ibm/libpldm/host.h
 create mode 100644 pldm/ibm/libpldm/platform_oem_ibm.c
 create mode 100644 pldm/ibm/libpldm/platform_oem_ibm.h

Comments

Frederic Barrat April 3, 2023, 4:42 p.m. UTC | #1
On 15/03/2022 13:49, Christophe Lombard wrote:
> 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<clombard@linux.vnet.ibm.com>
> ---


libpldm has seen some activity since you've forked it and it is now in 
its own repo and no longer part of the pldm repository. The oem/IBM part 
has also been moved into the new libpldm repo. So my guess is that we 
should refresh and keep the same directory structure under 'libpldm' in 
the skiboot tree. Right?

   Fred
Christophe Lombard April 4, 2023, 8:59 a.m. UTC | #2
Le 03/04/2023 à 18:42, Frederic Barrat a écrit :
>
>
> On 15/03/2022 13:49, Christophe Lombard wrote:
>> 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<clombard@linux.vnet.ibm.com>
>> ---
>
>
> libpldm has seen some activity since you've forked it and it is now in 
> its own repo and no longer part of the pldm repository. The oem/IBM 
> part has also been moved into the new libpldm repo. So my guess is 
> that we should refresh and keep the same directory structure under 
> 'libpldm' in the skiboot tree. Right?
>
>   Fred

Correct. We must be consistent with the source repo.

Thanks
diff mbox series

Patch

diff --git a/Makefile.main b/Makefile.main
index a65220c6..35b8dc00 100644
--- a/Makefile.main
+++ b/Makefile.main
@@ -308,6 +308,7 @@  include $(SRC)/libstb/Makefile.inc
 ifeq ($(CONFIG_PLDM),1)
 include $(SRC)/libmctp/Makefile.inc
 include $(SRC)/pldm/libpldm/Makefile.inc
+include $(SRC)/pldm/ibm/libpldm/Makefile.inc
 endif
 
 # hack for travis-ci and coverity
@@ -334,7 +335,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/ibm/libpldm/Makefile.inc b/pldm/ibm/libpldm/Makefile.inc
new file mode 100644
index 00000000..d8a40ece
--- /dev/null
+++ b/pldm/ibm/libpldm/Makefile.inc
@@ -0,0 +1,17 @@ 
+# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+# Copyright 2022 IBM Corp.
+
+LIBPLDM_IBM_DIR ?= pldm/ibm/libpldm
+SUBDIRS += $(LIBPLDM_IBM_DIR)
+
+LIBPLDM_IBM_OBJS = file_io.o host.o platform_oem_ibm.o
+
+CPPFLAGS += -I$(SRC)/pldm/libpldm/
+
+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/ibm/libpldm/README.skiboot b/pldm/ibm/libpldm/README.skiboot
new file mode 100644
index 00000000..c76bc430
--- /dev/null
+++ b/pldm/ibm/libpldm/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/ibm/libpldm/file_io.c b/pldm/ibm/libpldm/file_io.c
new file mode 100644
index 00000000..262af470
--- /dev/null
+++ b/pldm/ibm/libpldm/file_io.c
@@ -0,0 +1,841 @@ 
+#include "file_io.h"
+#include <endian.h>
+#include <string.h>
+
+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;
+}
diff --git a/pldm/ibm/libpldm/file_io.h b/pldm/ibm/libpldm/file_io.h
new file mode 100644
index 00000000..07db4ed0
--- /dev/null
+++ b/pldm/ibm/libpldm/file_io.h
@@ -0,0 +1,725 @@ 
+#ifndef FILEIO_H
+#define FILEIO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "base.h"
+
+/** @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,
+};
+
+/** @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,
+};
+
+/** @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,
+};
+
+#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
+
+/** @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);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FILEIO_H */
diff --git a/pldm/ibm/libpldm/fru.h b/pldm/ibm/libpldm/fru.h
new file mode 100644
index 00000000..c97f8b08
--- /dev/null
+++ b/pldm/ibm/libpldm/fru.h
@@ -0,0 +1,21 @@ 
+#ifndef OEM_IBM_FRU_H
+#define OEM_IBM_FRU_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+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/ibm/libpldm/host.c b/pldm/ibm/libpldm/host.c
new file mode 100644
index 00000000..caaaf9e4
--- /dev/null
+++ b/pldm/ibm/libpldm/host.c
@@ -0,0 +1,106 @@ 
+#include <endian.h>
+#include <string.h>
+
+#include "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/ibm/libpldm/host.h b/pldm/ibm/libpldm/host.h
new file mode 100644
index 00000000..ed121ae0
--- /dev/null
+++ b/pldm/ibm/libpldm/host.h
@@ -0,0 +1,108 @@ 
+#ifndef OEM_IBM_HOST_H
+#define OEM_IBM_HOST_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+#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/ibm/libpldm/platform_oem_ibm.c b/pldm/ibm/libpldm/platform_oem_ibm.c
new file mode 100644
index 00000000..e81a9fd0
--- /dev/null
+++ b/pldm/ibm/libpldm/platform_oem_ibm.c
@@ -0,0 +1,50 @@ 
+#include "platform_oem_ibm.h"
+#include <pldm/libpldm/platform.h>
+#include <string.h>
+
+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;
+}
diff --git a/pldm/ibm/libpldm/platform_oem_ibm.h b/pldm/ibm/libpldm/platform_oem_ibm.h
new file mode 100644
index 00000000..f0aafd36
--- /dev/null
+++ b/pldm/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 <stddef.h>
+#include <stdint.h>
+
+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