1 // SPDX-License-Identifier: Apache-2.0
2
3 #include "pldm_utils.hpp"
4
5 #include "dump_utils.hpp"
6 #include "xyz/openbmc_project/Common/error.hpp"
7
8 #include <libpldm/transport.h>
9 #include <libpldm/transport/mctp-demux.h>
10 #include <poll.h>
11
12 #include <phosphor-logging/elog-errors.hpp>
13 #include <phosphor-logging/lg2.hpp>
14
15 namespace phosphor
16 {
17 namespace dump
18 {
19 namespace pldm
20 {
21
22 using namespace phosphor::logging;
23 using NotAllowed = sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
24 using Reason = xyz::openbmc_project::Common::NotAllowed::REASON;
25
26 pldm_instance_db* pldmInstanceIdDb = nullptr;
27 pldm_transport* pldmTransport = nullptr;
28 pldm_transport_mctp_demux* mctpDemux = nullptr;
29
PLDMInstanceManager()30 PLDMInstanceManager::PLDMInstanceManager()
31 {
32 initPLDMInstanceIdDb();
33 }
34
~PLDMInstanceManager()35 PLDMInstanceManager::~PLDMInstanceManager()
36 {
37 destroyPLDMInstanceIdDb();
38 }
39
initPLDMInstanceIdDb()40 void PLDMInstanceManager::initPLDMInstanceIdDb()
41 {
42 auto rc = pldm_instance_db_init_default(&pldmInstanceIdDb);
43 if (rc)
44 {
45 lg2::error("Error calling pldm_instance_db_init_default, rc = {RC}",
46 "RC", rc);
47 elog<NotAllowed>(Reason(
48 "Required host dump action via pldm is not allowed due "
49 "to pldm_open failed"));
50 }
51 }
52
destroyPLDMInstanceIdDb()53 void PLDMInstanceManager::destroyPLDMInstanceIdDb()
54 {
55 auto rc = pldm_instance_db_destroy(pldmInstanceIdDb);
56 if (rc)
57 {
58 lg2::error("pldm_instance_db_destroy failed rc = {RC}", "RC", rc);
59 }
60 }
61
getPLDMInstanceID(uint8_t tid)62 pldm_instance_id_t getPLDMInstanceID(uint8_t tid)
63 {
64 pldm_instance_id_t instanceID = 0;
65
66 auto rc = pldm_instance_id_alloc(pldmInstanceIdDb, tid, &instanceID);
67 if (rc == -EAGAIN)
68 {
69 std::this_thread::sleep_for(std::chrono::milliseconds(100));
70 rc = pldm_instance_id_alloc(pldmInstanceIdDb, tid, &instanceID);
71 }
72
73 if (rc)
74 {
75 lg2::error("Failed to get instance id, rc = {RC}", "RC", rc);
76 elog<NotAllowed>(Reason(
77 "Failure in communicating with libpldm service, "
78 "service may not be running"));
79 }
80 lg2::info("Got instanceId: {INSTANCE_ID} from PLDM eid: {EID}",
81 "INSTANCE_ID", instanceID, "EID", tid);
82
83 return instanceID;
84 }
85
freePLDMInstanceID(pldm_instance_id_t instanceID,uint8_t tid)86 void freePLDMInstanceID(pldm_instance_id_t instanceID, uint8_t tid)
87 {
88 auto rc = pldm_instance_id_free(pldmInstanceIdDb, tid, instanceID);
89 if (rc)
90 {
91 lg2::error(
92 "pldm_instance_id_free failed to free id = {ID} of tid = {TID} rc = {RC}",
93 "ID", instanceID, "TID", tid, "RC", rc);
94 }
95 }
96
openPLDM(mctp_eid_t eid)97 int openPLDM(mctp_eid_t eid)
98 {
99 auto fd = -1;
100 if (pldmTransport)
101 {
102 lg2::error("open: pldmTransport already setup!");
103 elog<NotAllowed>(Reason(
104 "Required host dump action via pldm is not allowed due "
105 "to openPLDM failed"));
106 return fd;
107 }
108
109 fd = openMctpDemuxTransport(eid);
110 if (fd < 0)
111 {
112 auto e = errno;
113 lg2::error("openPLDM failed, errno: {ERRNO}, FD: FD", "ERRNO", e, "FD",
114 fd);
115 elog<NotAllowed>(Reason(
116 "Required host dump action via pldm is not allowed due "
117 "to openPLDM failed"));
118 }
119 return fd;
120 }
121
openMctpDemuxTransport(mctp_eid_t eid)122 int openMctpDemuxTransport(mctp_eid_t eid)
123 {
124 int rc = pldm_transport_mctp_demux_init(&mctpDemux);
125 if (rc)
126 {
127 lg2::error(
128 "openMctpDemuxTransport: Failed to init MCTP demux transport. rc = {RC}",
129 "RC", rc);
130 return rc;
131 }
132
133 rc = pldm_transport_mctp_demux_map_tid(mctpDemux, eid, eid);
134 if (rc)
135 {
136 lg2::error(
137 "openMctpDemuxTransport: Failed to setup tid to eid mapping. rc = {RC}",
138 "RC", rc);
139 pldmClose();
140 return rc;
141 }
142 pldmTransport = pldm_transport_mctp_demux_core(mctpDemux);
143
144 struct pollfd pollfd;
145 rc = pldm_transport_mctp_demux_init_pollfd(pldmTransport, &pollfd);
146 if (rc)
147 {
148 lg2::error("openMctpDemuxTransport: Failed to get pollfd. rc = {RC}",
149 "RC", rc);
150 pldmClose();
151 return rc;
152 }
153 return pollfd.fd;
154 }
155
pldmClose()156 void pldmClose()
157 {
158 pldm_transport_mctp_demux_destroy(mctpDemux);
159 mctpDemux = nullptr;
160 pldmTransport = nullptr;
161 }
162
163 } // namespace pldm
164 } // namespace dump
165 } // namespace phosphor
166