Skip to content

Commit

Permalink
Move to libpldm APIs for Allocating Instance IDs and change Transport…
Browse files Browse the repository at this point in the history
… APIs

Replace the current APIs with libpldm APIs for allocating instance IDs
directly.  This eliminates the need for remote D-Bus calls to the pldm
daemon.

Replace pldm transport APIs with libpldm pldm_transport APIs. This
change migrates the application off the deprecated "requester" APIs in
libpldm. Since we currently lack the infrastructure to obtain the
correct TIDs, use the EID as the TID in the EID-to-TID mapping to
maintain the current functionality.

Change-Id: I5854aa022582ceae6a1843983fc90181b7e6d55f
Signed-off-by: Lakshmi Yadlapati <[email protected]>
  • Loading branch information
Lakshmi-y committed Jul 10, 2024
1 parent fda8206 commit eb2049a
Show file tree
Hide file tree
Showing 3 changed files with 163 additions and 30 deletions.
64 changes: 57 additions & 7 deletions include/pldm_fw.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#include "types.hpp"

#include <libpldm/instance-id.h>
#include <libpldm/transport.h>
#include <libpldm/transport/mctp-demux.h>
#include <stdint.h>

#include <vector>
Expand All @@ -21,12 +24,26 @@ class PldmFramework
/**
* @brief Construtor
*/
PldmFramework() = default;
PldmFramework()
{
int rc = pldm_instance_db_init_default(&pldmInstanceIdDb);
if (rc)
{
throw std::system_category().default_error_condition(rc);
}
}

/**
* @brief Destructor
*/
~PldmFramework() = default;
~PldmFramework()
{
int rc = pldm_instance_db_destroy(pldmInstanceIdDb);
if (rc)
{
std::cout << "pldm_instance_db_destroy failed, rc =" << rc << "\n";
}
}

/**
* @brief Send Panel Function to PHYP.
Expand All @@ -43,6 +60,19 @@ class PldmFramework
/** Host mctp eid */
static constexpr auto mctpEid = (types::Byte)9;

/** @brief Hardcoded TID */
using TerminusID = uint8_t;
static constexpr TerminusID tid = mctpEid;

/** @brief PLDM instance ID database object used to get instance IDs
*/
pldm_instance_db* pldmInstanceIdDb = nullptr;

/** pldm transport instance */
struct pldm_transport* pldmTransport = NULL;

struct pldm_transport_mctp_demux* mctpDemux = NULL;

// Constants required for PLDM packet.
static constexpr auto phypTerminusID = (types::Byte)208;
static constexpr auto frontPanelBoardEntityId = (uint16_t)32837;
Expand Down Expand Up @@ -81,12 +111,32 @@ class PldmFramework

/**
* @brief Get instance ID
* This api returns the instance id by making a dbus call to GetInstanceId
* api of Pldm. Instance id is to uniquely identify a message packet. This
* id is generated by pldm.
* This api returns the instance id by making a dbus call to libpldm
* api. Instance id is to uniquely identify a message packet.
* @return pldm_instance_id_t instance id.
*/
pldm_instance_id_t getInstanceID();

/**
* @brief Free PLDM requester instance id
* @param[in] pdrs - Panel PDR data.
*/
void freeInstanceID(pldm_instance_id_t instanceID);

/**
* @brief setup PLDM transport for sending and receiving messages
*
* @return file descriptor
*/
int openPldm();

/** @brief Opens the MCTP socket for sending and receiving messages.
*
* @return one byte instance id.
*/
types::Byte getInstanceID();
int openMctpDemuxTransport();

/** @brief Close the PLDM file */
void pldmClose();

};
} // namespace panel
4 changes: 4 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ systemd_system_unit_dir = systemd.get_variable('systemdsystemunitdir')

service_file = 'service_files/com.ibm.panel.service'

if cxx.has_header('poll.h')
add_project_arguments('-DPLDM_HAS_POLL=1', language: 'cpp')
endif

if get_option('system-vpd-dependency').enabled()
service_file = 'service_files/ibm.panel.system.vpd.dependent.service'
endif
Expand Down
125 changes: 102 additions & 23 deletions src/pldm_fw.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

#include "pldm_fw.hpp"

#include "exception.hpp"
Expand All @@ -7,33 +8,112 @@
#include <libpldm/platform.h>
#include <libpldm/pldm.h>
#include <libpldm/state_set.h>
#include <poll.h>

#include <iostream>
#include <sdbusplus/asio/connection.hpp>
#include <sdbusplus/asio/object_server.hpp>

namespace panel
{
types::Byte PldmFramework::getInstanceID()
pldm_instance_id_t PldmFramework::getInstanceID()
{
types::Byte instanceId = 0;
auto bus = sdbusplus::bus::new_default();
pldm_instance_id_t instanceID = 0;

try
auto rc = pldm_instance_id_alloc(pldmInstanceIdDb, tid, &instanceID);
if (rc == -EAGAIN)
{
auto method = bus.new_method_call(
"xyz.openbmc_project.PLDM", "/xyz/openbmc_project/pldm",
"xyz.openbmc_project.PLDM.Requester", "GetInstanceId");
method.append(mctpEid);
auto reply = bus.call(method);
reply.read(instanceId);
std::this_thread::sleep_for(std::chrono::milliseconds(100));
rc = pldm_instance_id_alloc(pldmInstanceIdDb, tid, &instanceID);
}
catch (const sdbusplus::exception::SdBusError& e)

if (rc)
{
std::cerr << e.what() << std::endl;
std::cerr << "Return code = " << rc << std::endl;
throw FunctionFailure("pldm: call to GetInstanceId failed.");
}
return instanceId;
std::cout << "Got instanceId: " << static_cast<int>(instanceID)
<< " from PLDM eid: " << static_cast<int>(tid) << std::endl;
return instanceID;
}

void PldmFramework::freeInstanceID(pldm_instance_id_t instanceID)
{
std::cout << "Free instanceId: " << static_cast<int>(instanceID)
<< std::endl;
auto rc = pldm_instance_id_free(pldmInstanceIdDb, tid, instanceID);
if (rc)
{
std::cerr << "pldm_instance_id_free failed to free id = "
<< static_cast<int>(instanceID)
<< " of tid = " << static_cast<int>(tid) << " rc = " << rc
<< std::endl;
}
}

int PldmFramework::openPldm()
{
auto fd = -1;
if (pldmTransport)
{
std::cerr << "open: pldmTransport already setup!" << std::endl;
throw FunctionFailure("Required host dump action via PLDM is not "
"allowed due to openPldm failed");
return fd;
}

fd = openMctpDemuxTransport();
if (fd < 0)
{
auto e = errno;
std::cerr << "openPldm failed, errno: " << e << ", FD: " << fd
<< std::endl;
throw FunctionFailure("Required host dump action via PLDM is not "
"allowed due to openPldm failed");
}
return fd;
}

int PldmFramework::openMctpDemuxTransport()
{
int rc = pldm_transport_mctp_demux_init(&mctpDemux);
if (rc)
{
std::cerr << "openMctpDemuxTransport: Failed to init MCTP demux "
"transport. rc = "
<< rc << std::endl;
throw FunctionFailure("Failed to init MCTP demux transport");
}

rc = pldm_transport_mctp_demux_map_tid(mctpDemux, tid, tid);
if (rc)
{
std::cerr << "openMctpDemuxTransport: Failed to setup tid to eid "
"mapping. rc = "
<< rc << std::endl;
pldmClose();
throw FunctionFailure("Failed to setup tid to eid mapping");
}
pldmTransport = pldm_transport_mctp_demux_core(mctpDemux);

struct pollfd pollfd;
rc = pldm_transport_mctp_demux_init_pollfd(pldmTransport, &pollfd);
if (rc)
{
std::cerr << "openMctpDemuxTransport: Failed to get pollfd. rc = " << rc
<< std::endl;
pldmClose();
throw FunctionFailure("Failed to get pollfd");
}
std::cout << " Lakshmi openMctpDemuxTransport done.\n" << std::endl;
return pollfd.fd;
}

void PldmFramework::pldmClose()
{
pldm_transport_mctp_demux_destroy(mctpDemux);
mctpDemux = NULL;
pldmTransport = NULL;
}

void PldmFramework::fetchPanelEffecterStateSet(const types::PdrList& pdrs,
Expand Down Expand Up @@ -128,7 +208,7 @@ void PldmFramework::sendPanelFunctionToPhyp(
return;
}

types::Byte instance = getInstanceID();
pldm_instance_id_t instance = getInstanceID();

types::PldmPacket packet =
prepareSetEffecterReq(pdrs, instance, funcNumber);
Expand All @@ -144,10 +224,10 @@ void PldmFramework::sendPanelFunctionToPhyp(
return;
}

int fd = pldm_open();
int fd = openPldm();
if (fd == -1)
{
std::cerr << "pldm_open() failed with error = " << strerror(errno)
std::cerr << "openPldm() failed with error = " << strerror(errno)
<< std::endl;
std::map<std::string, std::string> additionalData{};
additionalData.emplace("DESCRIPTION",
Expand All @@ -156,6 +236,7 @@ void PldmFramework::sendPanelFunctionToPhyp(
utils::createPEL("com.ibm.Panel.Error.HostCommunicationError",
"xyz.openbmc_project.Logging.Entry.Level.Warning",
additionalData);
freeInstanceID(instance);
return;
}

Expand All @@ -167,14 +248,12 @@ void PldmFramework::sendPanelFunctionToPhyp(
}
std::cout << std::endl;

auto rc = pldm_send(mctpEid, fd, packet.data(), packet.size());

if (close(fd) == -1)
{
std::cerr << "Close on File descriptor failed with error = "
<< strerror(errno) << std::endl;
}
pldm_tid_t pldmTID = static_cast<pldm_tid_t>(mctpEid);
auto rc = pldm_transport_send_msg(pldmTransport, pldmTID, packet.data(),
packet.size());

freeInstanceID(instance);
pldmClose();
if (rc)
{
std::map<std::string, std::string> additionalData{};
Expand Down

0 comments on commit eb2049a

Please sign in to comment.