blob: ddde7f8f458810a83ceb62bb1235e794447d01cc [file] [log] [blame]
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +05301#pragma once
2
Deepak Kodihalli4c164b02020-03-07 03:23:31 -06003#include "config.h"
4
Deepak Kodihallid130e1a2020-06-17 05:55:32 -05005#include "common/utils.hpp"
Jayashankar Padathdb124362021-01-28 21:12:34 -06006#include "oem/ibm/requester/dbus_to_file_handler.hpp"
Sampa Misraaea5dde2020-08-31 08:33:47 -05007#include "oem_ibm_handler.hpp"
Deepak Kodihalli1521f6d2020-06-16 08:51:02 -05008#include "pldmd/handler.hpp"
Sampa Misrac0c79482021-06-02 08:01:54 -05009#include "requester/handler.hpp"
Deepak Kodihallibc669f12019-11-28 08:52:07 -060010
Deepak Kodihalli15211b42019-12-14 02:24:49 -060011#include <fcntl.h>
George Liuc453e162022-12-21 17:16:23 +080012#include <libpldm/base.h>
13#include <libpldm/file_io.h>
14#include <libpldm/host.h>
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053015#include <stdint.h>
Deepak Kodihalli15211b42019-12-14 02:24:49 -060016#include <sys/stat.h>
17#include <sys/types.h>
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053018#include <unistd.h>
19
Riya Dixit49cfb132023-03-02 04:26:53 -060020#include <phosphor-logging/lg2.hpp>
21
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053022#include <filesystem>
Deepak Kodihalli15211b42019-12-14 02:24:49 -060023#include <iostream>
Priyanga8b976652019-06-27 11:30:33 -050024#include <vector>
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053025
Riya Dixit49cfb132023-03-02 04:26:53 -060026PHOSPHOR_LOG2_USING;
27
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053028namespace pldm
29{
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053030namespace responder
31{
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053032namespace dma
33{
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053034// The minimum data size of dma transfer in bytes
35constexpr uint32_t minSize = 16;
36
Deepak Kodihalli4c164b02020-03-07 03:23:31 -060037constexpr size_t maxSize = DMA_MAXSIZE;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053038
39namespace fs = std::filesystem;
40
41/**
42 * @class DMA
43 *
44 * Expose API to initiate transfer of data by DMA
45 *
46 * This class only exposes the public API transferDataHost to transfer data
47 * between BMC and host using DMA. This allows for mocking the transferDataHost
48 * for unit testing purposes.
49 */
50class DMA
51{
52 public:
53 /** @brief API to transfer data between BMC and host using DMA
54 *
55 * @param[in] path - pathname of the file to transfer data from or to
56 * @param[in] offset - offset in the file
57 * @param[in] length - length of the data to transfer
58 * @param[in] address - DMA address on the host
59 * @param[in] upstream - indicates direction of the transfer; true indicates
60 * transfer to the host
61 *
62 * @return returns 0 on success, negative errno on failure
63 */
Deepak Kodihalli15211b42019-12-14 02:24:49 -060064 int transferDataHost(int fd, uint32_t offset, uint32_t length,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053065 uint64_t address, bool upstream);
Ravi Tejace1c96f2020-10-05 23:13:01 -050066
67 /** @brief API to transfer data on to unix socket from host using DMA
68 *
69 * @param[in] path - pathname of the file to transfer data from or to
70 * @param[in] length - length of the data to transfer
71 * @param[in] address - DMA address on the host
72 *
73 * @return returns 0 on success, negative errno on failure
74 */
75 int transferHostDataToSocket(int fd, uint32_t length, uint64_t address);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053076};
77
78/** @brief Transfer the data between BMC and host using DMA.
79 *
80 * There is a max size for each DMA operation, transferAll API abstracts this
81 * and the requested length is broken down into multiple DMA operations if the
82 * length exceed max size.
83 *
84 * @tparam[in] T - DMA interface type
85 * @param[in] intf - interface passed to invoke DMA transfer
86 * @param[in] command - PLDM command
87 * @param[in] path - pathname of the file to transfer data from or to
88 * @param[in] offset - offset in the file
89 * @param[in] length - length of the data to transfer
90 * @param[in] address - DMA address on the host
91 * @param[in] upstream - indicates direction of the transfer; true indicates
92 * transfer to the host
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +053093 * @param[in] instanceId - Message's instance id
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053094 * @return PLDM response message
95 */
96
97template <class DMAInterface>
98Response transferAll(DMAInterface* intf, uint8_t command, fs::path& path,
99 uint32_t offset, uint32_t length, uint64_t address,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530100 bool upstream, uint8_t instanceId)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530101{
102 uint32_t origLength = length;
103 Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_RESP_BYTES, 0);
104 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
105
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600106 int flags{};
107 if (upstream)
108 {
109 flags = O_RDONLY;
110 }
111 else if (fs::exists(path))
112 {
113 flags = O_RDWR;
114 }
115 else
116 {
117 flags = O_WRONLY;
118 }
119 int file = open(path.string().c_str(), flags);
120 if (file == -1)
121 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600122 error("File does not exist, path = {FILE_PATH}", "FILE_PATH",
123 path.string());
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600124 encode_rw_file_memory_resp(instanceId, command, PLDM_ERROR, 0,
125 responsePtr);
126 return response;
127 }
George Liu83409572019-12-24 18:42:54 +0800128 pldm::utils::CustomFD fd(file);
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600129
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530130 while (length > dma::maxSize)
131 {
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600132 auto rc = intf->transferDataHost(fd(), offset, dma::maxSize, address,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530133 upstream);
134 if (rc < 0)
135 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530136 encode_rw_file_memory_resp(instanceId, command, PLDM_ERROR, 0,
137 responsePtr);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530138 return response;
139 }
140
141 offset += dma::maxSize;
142 length -= dma::maxSize;
143 address += dma::maxSize;
144 }
145
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600146 auto rc = intf->transferDataHost(fd(), offset, length, address, upstream);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530147 if (rc < 0)
148 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530149 encode_rw_file_memory_resp(instanceId, command, PLDM_ERROR, 0,
150 responsePtr);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530151 return response;
152 }
153
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530154 encode_rw_file_memory_resp(instanceId, command, PLDM_SUCCESS, origLength,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530155 responsePtr);
156 return response;
157}
158
159} // namespace dma
160
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600161namespace oem_ibm
162{
Jayashankar Padathdb124362021-01-28 21:12:34 -0600163static constexpr auto dumpObjPath = "/xyz/openbmc_project/dump/resource/entry/";
164static constexpr auto resDumpEntry = "com.ibm.Dump.Entry.Resource";
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500165
166static constexpr auto certObjPath = "/xyz/openbmc_project/certs/ca/";
167static constexpr auto certAuthority =
168 "xyz.openbmc_project.PLDM.Provider.Certs.Authority.CSR";
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600169class Handler : public CmdHandler
170{
171 public:
Jayashankar Padathdb124362021-01-28 21:12:34 -0600172 Handler(oem_platform::Handler* oemPlatformHandler, int hostSockFd,
Sampa Misrac0c79482021-06-02 08:01:54 -0500173 uint8_t hostEid, dbus_api::Requester* dbusImplReqester,
174 pldm::requester::Handler<pldm::requester::Request>* handler) :
Jayashankar Padathdb124362021-01-28 21:12:34 -0600175 oemPlatformHandler(oemPlatformHandler),
176 hostSockFd(hostSockFd), hostEid(hostEid),
Sampa Misrac0c79482021-06-02 08:01:54 -0500177 dbusImplReqester(dbusImplReqester), handler(handler)
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600178 {
179 handlers.emplace(PLDM_READ_FILE_INTO_MEMORY,
180 [this](const pldm_msg* request, size_t payloadLength) {
181 return this->readFileIntoMemory(request,
182 payloadLength);
183 });
184 handlers.emplace(PLDM_WRITE_FILE_FROM_MEMORY,
185 [this](const pldm_msg* request, size_t payloadLength) {
186 return this->writeFileFromMemory(request,
187 payloadLength);
188 });
189 handlers.emplace(PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY,
190 [this](const pldm_msg* request, size_t payloadLength) {
191 return this->writeFileByTypeFromMemory(
192 request, payloadLength);
193 });
194 handlers.emplace(PLDM_READ_FILE_BY_TYPE_INTO_MEMORY,
195 [this](const pldm_msg* request, size_t payloadLength) {
196 return this->readFileByTypeIntoMemory(
197 request, payloadLength);
198 });
199 handlers.emplace(PLDM_READ_FILE_BY_TYPE, [this](const pldm_msg* request,
200 size_t payloadLength) {
201 return this->readFileByType(request, payloadLength);
202 });
Sampa Misra18967162020-01-14 02:31:41 -0600203 handlers.emplace(PLDM_WRITE_FILE_BY_TYPE,
204 [this](const pldm_msg* request, size_t payloadLength) {
205 return this->writeFileByType(request,
206 payloadLength);
207 });
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600208 handlers.emplace(PLDM_GET_FILE_TABLE,
209 [this](const pldm_msg* request, size_t payloadLength) {
210 return this->getFileTable(request, payloadLength);
211 });
212 handlers.emplace(PLDM_READ_FILE,
213 [this](const pldm_msg* request, size_t payloadLength) {
214 return this->readFile(request, payloadLength);
215 });
216 handlers.emplace(PLDM_WRITE_FILE,
217 [this](const pldm_msg* request, size_t payloadLength) {
218 return this->writeFile(request, payloadLength);
219 });
Deepak Kodihalli2da1bfe2019-12-14 08:28:09 -0600220 handlers.emplace(PLDM_FILE_ACK,
221 [this](const pldm_msg* request, size_t payloadLength) {
222 return this->fileAck(request, payloadLength);
223 });
George Liu89aad712020-03-12 13:34:51 +0800224 handlers.emplace(PLDM_HOST_GET_ALERT_STATUS,
225 [this](const pldm_msg* request, size_t payloadLength) {
226 return this->getAlertStatus(request,
227 payloadLength);
228 });
Sampa Misra18967162020-01-14 02:31:41 -0600229 handlers.emplace(PLDM_NEW_FILE_AVAILABLE,
230 [this](const pldm_msg* request, size_t payloadLength) {
231 return this->newFileAvailable(request,
232 payloadLength);
233 });
Jayashankar Padathdb124362021-01-28 21:12:34 -0600234
Patrick Williams84b790c2022-07-22 19:26:56 -0500235 resDumpMatcher = std::make_unique<sdbusplus::bus::match_t>(
Jayashankar Padathdb124362021-01-28 21:12:34 -0600236 pldm::utils::DBusHandler::getBus(),
237 sdbusplus::bus::match::rules::interfacesAdded() +
238 sdbusplus::bus::match::rules::argNpath(0, dumpObjPath),
Sampa Misrac0c79482021-06-02 08:01:54 -0500239 [this, hostSockFd, hostEid, dbusImplReqester,
Patrick Williams84b790c2022-07-22 19:26:56 -0500240 handler](sdbusplus::message_t& msg) {
Jayashankar Padathdb124362021-01-28 21:12:34 -0600241 std::map<
242 std::string,
243 std::map<std::string, std::variant<std::string, uint32_t>>>
244 interfaces;
245 sdbusplus::message::object_path path;
246 msg.read(path, interfaces);
247 std::string vspstring;
248 std::string password;
249
250 for (auto& interface : interfaces)
251 {
252 if (interface.first == resDumpEntry)
253 {
254 for (const auto& property : interface.second)
255 {
256 if (property.first == "VSPString")
257 {
258 vspstring =
259 std::get<std::string>(property.second);
260 }
261 else if (property.first == "Password")
262 {
263 password =
264 std::get<std::string>(property.second);
265 }
266 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500267 dbusToFileHandlers
268 .emplace_back(
269 std::make_unique<pldm::requester::oem_ibm::
270 DbusToFileHandler>(
271 hostSockFd, hostEid, dbusImplReqester, path,
272 handler))
273 ->processNewResourceDump(vspstring, password);
Jayashankar Padathdb124362021-01-28 21:12:34 -0600274 break;
275 }
276 }
277 });
Patrick Williams84b790c2022-07-22 19:26:56 -0500278 vmiCertMatcher = std::make_unique<sdbusplus::bus::match_t>(
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500279 pldm::utils::DBusHandler::getBus(),
280 sdbusplus::bus::match::rules::interfacesAdded() +
281 sdbusplus::bus::match::rules::argNpath(0, certObjPath),
Sampa Misrac0c79482021-06-02 08:01:54 -0500282 [this, hostSockFd, hostEid, dbusImplReqester,
Patrick Williams84b790c2022-07-22 19:26:56 -0500283 handler](sdbusplus::message_t& msg) {
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500284 std::map<
285 std::string,
286 std::map<std::string, std::variant<std::string, uint32_t>>>
287 interfaces;
288 sdbusplus::message::object_path path;
289 msg.read(path, interfaces);
290 std::string csr;
291
292 for (auto& interface : interfaces)
293 {
294 if (interface.first == certAuthority)
295 {
296 for (const auto& property : interface.second)
297 {
298 if (property.first == "CSR")
299 {
300 csr = std::get<std::string>(property.second);
301 auto fileHandle =
302 sdbusplus::message::object_path(path)
303 .filename();
304
Sampa Misrac0c79482021-06-02 08:01:54 -0500305 dbusToFileHandlers
306 .emplace_back(std::make_unique<
307 pldm::requester::oem_ibm::
308 DbusToFileHandler>(
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500309 hostSockFd, hostEid, dbusImplReqester,
Sampa Misrac0c79482021-06-02 08:01:54 -0500310 path, handler))
311 ->newCsrFileAvailable(csr, fileHandle);
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500312 break;
313 }
314 }
315 break;
316 }
317 }
318 });
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600319 }
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530320
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600321 /** @brief Handler for readFileIntoMemory command
322 *
323 * @param[in] request - pointer to PLDM request payload
324 * @param[in] payloadLength - length of the message
325 *
326 * @return PLDM response message
327 */
328 Response readFileIntoMemory(const pldm_msg* request, size_t payloadLength);
Sampa Misra854e61f2019-08-22 04:36:47 -0500329
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600330 /** @brief Handler for writeFileIntoMemory command
331 *
332 * @param[in] request - pointer to PLDM request payload
333 * @param[in] payloadLength - length of the message
334 *
335 * @return PLDM response message
336 */
337 Response writeFileFromMemory(const pldm_msg* request, size_t payloadLength);
Sampa Misra854e61f2019-08-22 04:36:47 -0500338
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600339 /** @brief Handler for writeFileByTypeFromMemory command
340 *
341 * @param[in] request - pointer to PLDM request payload
342 * @param[in] payloadLength - length of the message
343 *
344 * @return PLDM response message
345 */
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600346
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600347 Response writeFileByTypeFromMemory(const pldm_msg* request,
348 size_t payloadLength);
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600349
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600350 /** @brief Handler for readFileByTypeIntoMemory command
351 *
352 * @param[in] request - pointer to PLDM request payload
353 * @param[in] payloadLength - length of the message
354 *
355 * @return PLDM response message
356 */
357 Response readFileByTypeIntoMemory(const pldm_msg* request,
358 size_t payloadLength);
vkaverap5b914c32019-06-30 22:23:54 -0500359
Sampa Misra18967162020-01-14 02:31:41 -0600360 /** @brief Handler for writeFileByType command
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600361 *
362 * @param[in] request - pointer to PLDM request payload
363 * @param[in] payloadLength - length of the message
364 *
365 * @return PLDM response message
366 */
367 Response readFileByType(const pldm_msg* request, size_t payloadLength);
vkaverap5b914c32019-06-30 22:23:54 -0500368
Sampa Misra18967162020-01-14 02:31:41 -0600369 Response writeFileByType(const pldm_msg* request, size_t payloadLength);
370
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600371 /** @brief Handler for GetFileTable command
372 *
373 * @param[in] request - pointer to PLDM request payload
374 * @param[in] payloadLength - length of the message payload
375 *
376 * @return PLDM response message
377 */
378 Response getFileTable(const pldm_msg* request, size_t payloadLength);
379
380 /** @brief Handler for readFile command
381 *
382 * @param[in] request - PLDM request msg
383 * @param[in] payloadLength - length of the message payload
384 *
385 * @return PLDM response message
386 */
387 Response readFile(const pldm_msg* request, size_t payloadLength);
388
389 /** @brief Handler for writeFile command
390 *
391 * @param[in] request - PLDM request msg
392 * @param[in] payloadLength - length of the message payload
393 *
394 * @return PLDM response message
395 */
396 Response writeFile(const pldm_msg* request, size_t payloadLength);
Deepak Kodihalli2da1bfe2019-12-14 08:28:09 -0600397
398 Response fileAck(const pldm_msg* request, size_t payloadLength);
George Liu89aad712020-03-12 13:34:51 +0800399
400 /** @brief Handler for getAlertStatus command
401 *
402 * @param[in] request - PLDM request msg
403 * @param[in] payloadLength - length of the message payload
404 *
405 * @return PLDM response message
406 */
407 Response getAlertStatus(const pldm_msg* request, size_t payloadLength);
Sampa Misra18967162020-01-14 02:31:41 -0600408
409 /** @brief Handler for newFileAvailable command
410 *
411 * @param[in] request - PLDM request msg
412 * @param[in] payloadLength - length of the message payload
413 *
414 * @return PLDM response message
415 */
416 Response newFileAvailable(const pldm_msg* request, size_t payloadLength);
Sampa Misraaea5dde2020-08-31 08:33:47 -0500417
418 private:
419 oem_platform::Handler* oemPlatformHandler;
Jayashankar Padathdb124362021-01-28 21:12:34 -0600420 int hostSockFd;
421 uint8_t hostEid;
422 dbus_api::Requester* dbusImplReqester;
423 using DBusInterfaceAdded = std::vector<std::pair<
424 std::string,
425 std::vector<std::pair<std::string, std::variant<std::string>>>>>;
Sampa Misrac0c79482021-06-02 08:01:54 -0500426 std::unique_ptr<pldm::requester::oem_ibm::DbusToFileHandler>
427 dbusToFileHandler; //!< pointer to send request to Host
Patrick Williams84b790c2022-07-22 19:26:56 -0500428 std::unique_ptr<sdbusplus::bus::match_t>
Jayashankar Padathdb124362021-01-28 21:12:34 -0600429 resDumpMatcher; //!< Pointer to capture the interface added signal
430 //!< for new resource dump
Patrick Williams84b790c2022-07-22 19:26:56 -0500431 std::unique_ptr<sdbusplus::bus::match_t>
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500432 vmiCertMatcher; //!< Pointer to capture the interface added signal
433 //!< for new csr string
Sampa Misrac0c79482021-06-02 08:01:54 -0500434 /** @brief PLDM request handler */
435 pldm::requester::Handler<pldm::requester::Request>* handler;
436 std::vector<std::unique_ptr<pldm::requester::oem_ibm::DbusToFileHandler>>
437 dbusToFileHandlers;
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600438};
439
440} // namespace oem_ibm
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530441} // namespace responder
442} // namespace pldm