oem-ibm : New record to backplane vpd
This commit is to support a new VPD record called PSPD that contains
few keywords called #D and VM. Since these keywords are typically
larger in size (4K bytes) than what is managed by PLDM, we are adding
a file into which these keywords will be extracted. This keyword file
is transferred to the HB PLDM layer with a readFileByType request
from HB.
Signed-off-by: Varsha Kaverappa <vkaverap@in.ibm.com>
Change-Id: I94ed20bb54e704173a2c0a2dd6dbea853174b7de
diff --git a/oem/ibm/libpldmresponder/file_io_by_type.cpp b/oem/ibm/libpldmresponder/file_io_by_type.cpp
index ec001fa..356ad89 100644
--- a/oem/ibm/libpldmresponder/file_io_by_type.cpp
+++ b/oem/ibm/libpldmresponder/file_io_by_type.cpp
@@ -8,6 +8,7 @@
#include "file_io_type_lid.hpp"
#include "file_io_type_pel.hpp"
#include "file_io_type_progress_src.hpp"
+#include "file_io_type_vpd.hpp"
#include "xyz/openbmc_project/Common/error.hpp"
#include <libpldm/base.h>
@@ -169,6 +170,10 @@
return std::make_unique<LidHandler>(fileHandle, false,
PLDM_FILE_TYPE_LID_RUNNING);
}
+ case PLDM_FILE_TYPE_PSPD_VPD_PDD_KEYWORD:
+ {
+ return std::make_unique<keywordHandler>(fileHandle, fileType);
+ }
default:
{
throw InternalFailure();
diff --git a/oem/ibm/libpldmresponder/file_io_type_vpd.cpp b/oem/ibm/libpldmresponder/file_io_type_vpd.cpp
new file mode 100644
index 0000000..07530a8
--- /dev/null
+++ b/oem/ibm/libpldmresponder/file_io_type_vpd.cpp
@@ -0,0 +1,103 @@
+#include "file_io_type_vpd.hpp"
+
+#include "libpldm/base.h"
+#include "libpldm/file_io.h"
+
+#include "common/utils.hpp"
+
+#include <stdint.h>
+
+#include <iostream>
+
+typedef uint8_t byte;
+
+namespace pldm
+{
+namespace responder
+{
+int keywordHandler::read(uint32_t offset, uint32_t& length, Response& response,
+ oem_platform::Handler* /*oemPlatformHandler*/)
+{
+ const char* keywrdObjPath =
+ "/xyz/openbmc_project/inventory/system/chassis/motherboard";
+ const char* keywrdPropName = "PD_D";
+ const char* keywrdInterface = "com.ibm.ipzvpd.PSPD";
+
+ std::variant<std::vector<byte>> keywrd;
+
+ try
+ {
+ auto& bus = DBusHandler::getBus();
+ auto service = pldm::utils::DBusHandler().getService(keywrdObjPath,
+ keywrdInterface);
+ auto method =
+ bus.new_method_call(service.c_str(), keywrdObjPath,
+ "org.freedesktop.DBus.Properties", "Get");
+ method.append(keywrdInterface, keywrdPropName);
+ auto reply = bus.call(method);
+ reply.read(keywrd);
+ }
+ catch (const std::exception& e)
+ {
+ std::cerr << "Get keyword error from dbus interface : "
+ << keywrdInterface << " ERROR= " << e.what() << std::endl;
+ }
+
+ auto keywrdSize = std::get<std::vector<byte>>(keywrd).size();
+
+ if (length < keywrdSize)
+ {
+ std::cerr << "length requested is less the keyword size, length: "
+ << length << " keyword size: " << keywrdSize << std::endl;
+ return PLDM_ERROR_INVALID_DATA;
+ }
+
+ namespace fs = std::filesystem;
+ constexpr auto keywrdDirPath = "/tmp/pldm/";
+ constexpr auto keywrdFilePath = "/tmp/pldm/vpdKeywrd.bin";
+
+ if (!fs::exists(keywrdDirPath))
+ {
+ fs::create_directories(keywrdDirPath);
+ fs::permissions(keywrdDirPath,
+ fs::perms::others_read | fs::perms::owner_write);
+ }
+
+ std::ofstream keywrdFile("vpdKeywrd.bin");
+ keywrdFile.open(keywrdFilePath, std::ios::out | std::ofstream::binary);
+ if (!keywrdFile)
+ {
+ std::cerr << "VPD keyword file open error: " << keywrdFilePath
+ << " errno: " << errno << std::endl;
+ pldm::utils::reportError(
+ "xyz.openbmc_project.PLDM.Error.readKeywordHandler.keywordFileOpenError",
+ pldm::PelSeverity::ERROR);
+ return PLDM_ERROR;
+ }
+ keywrdFile.write((const char*)std::get<std::vector<byte>>(keywrd).data(),
+ keywrdSize);
+ if (keywrdFile.bad())
+ {
+ std::cerr << "Error while writing to file: " << keywrdFilePath
+ << std::endl;
+ }
+ keywrdFile.close();
+
+ // length of keyword data should be same as keyword data size in dbus object
+ length = (uint32_t)keywrdSize;
+
+ auto rc = readFile(keywrdFilePath, offset, keywrdSize, response);
+ fs::remove(keywrdFilePath);
+ if (rc)
+ {
+ std::cerr << "Read error for keyword file with size: " << keywrdSize
+ << std::endl;
+ pldm::utils::reportError(
+ "xyz.openbmc_project.PLDM.Error.readKeywordHandler.keywordFileReadError",
+ pldm::PelSeverity::ERROR);
+ return PLDM_ERROR;
+ }
+ return PLDM_SUCCESS;
+}
+} // namespace responder
+} // namespace pldm
diff --git a/oem/ibm/libpldmresponder/file_io_type_vpd.hpp b/oem/ibm/libpldmresponder/file_io_type_vpd.hpp
new file mode 100644
index 0000000..516b7ad
--- /dev/null
+++ b/oem/ibm/libpldmresponder/file_io_type_vpd.hpp
@@ -0,0 +1,76 @@
+#pragma once
+
+#include "file_io_by_type.hpp"
+
+namespace pldm
+{
+namespace responder
+{
+using vpdFileType = uint16_t;
+/** @class keywordFileHandler
+ *
+ * @brief Inherits and implements FileHandler. This class is used
+ * to read #D keyword file
+ */
+class keywordHandler : public FileHandler
+{
+ public:
+ /** @brief Handler constructor
+ */
+ keywordHandler(uint32_t fileHandle, uint16_t fileType) :
+ FileHandler(fileHandle), vpdFileType(fileType)
+ {}
+ virtual int writeFromMemory(uint32_t /*offset*/, uint32_t /*length*/,
+ uint64_t /*address*/,
+ oem_platform::Handler* /*oemPlatformHandler*/)
+ {
+ return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
+ }
+ virtual int readIntoMemory(uint32_t /*offset*/, uint32_t& /*length*/,
+ uint64_t /*address*/,
+ oem_platform::Handler* /*oemPlatformHandler*/)
+ {
+ return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
+ }
+ virtual int read(uint32_t offset, uint32_t& length, Response& response,
+ oem_platform::Handler* /*oemPlatformHandler*/);
+ virtual int write(const char* /*buffer*/, uint32_t /*offset*/,
+ uint32_t& /*length*/,
+ oem_platform::Handler* /*oemPlatformHandler*/)
+ {
+ return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
+ }
+ virtual int fileAck(uint8_t /*fileStatus*/)
+ {
+ return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
+ }
+ virtual int newFileAvailable(uint64_t /*length*/)
+ {
+ return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
+ }
+ virtual int fileAckWithMetaData(uint8_t /*fileStatus*/,
+ uint32_t /*metaDataValue1*/,
+ uint32_t /*metaDataValue2*/,
+ uint32_t /*metaDataValue3*/,
+ uint32_t /*metaDataValue4*/)
+ {
+ return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
+ }
+ virtual int newFileAvailableWithMetaData(uint64_t /*length*/,
+ uint32_t /*metaDataValue1*/,
+ uint32_t /*metaDataValue2*/,
+ uint32_t /*metaDataValue3*/,
+ uint32_t /*metaDataValue4*/)
+ {
+ return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
+ }
+ /** @brief keywordHandler destructor
+ */
+ ~keywordHandler()
+ {}
+
+ private:
+ uint16_t vpdFileType; //!< type of the VPD file
+};
+} // namespace responder
+} // namespace pldm