blob: 771d038920fef8310e1b12a7a522a2b5f7adc369 [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
George Liu6492f522020-06-16 10:34:05 +08005#include "libpldm/base.h"
6#include "oem/ibm/libpldm/file_io.h"
7#include "oem/ibm/libpldm/host.h"
8
Deepak Kodihallid130e1a2020-06-17 05:55:32 -05009#include "common/utils.hpp"
Deepak Kodihalli1521f6d2020-06-16 08:51:02 -050010#include "pldmd/handler.hpp"
Deepak Kodihallibc669f12019-11-28 08:52:07 -060011
Deepak Kodihalli15211b42019-12-14 02:24:49 -060012#include <fcntl.h>
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053013#include <stdint.h>
Deepak Kodihalli15211b42019-12-14 02:24:49 -060014#include <sys/stat.h>
15#include <sys/types.h>
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053016#include <unistd.h>
17
18#include <filesystem>
Deepak Kodihalli15211b42019-12-14 02:24:49 -060019#include <iostream>
Priyanga8b976652019-06-27 11:30:33 -050020#include <vector>
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053021
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053022namespace pldm
23{
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053024namespace responder
25{
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053026namespace dma
27{
28
29// The minimum data size of dma transfer in bytes
30constexpr uint32_t minSize = 16;
31
Deepak Kodihalli4c164b02020-03-07 03:23:31 -060032constexpr size_t maxSize = DMA_MAXSIZE;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053033
34namespace fs = std::filesystem;
35
36/**
37 * @class DMA
38 *
39 * Expose API to initiate transfer of data by DMA
40 *
41 * This class only exposes the public API transferDataHost to transfer data
42 * between BMC and host using DMA. This allows for mocking the transferDataHost
43 * for unit testing purposes.
44 */
45class DMA
46{
47 public:
48 /** @brief API to transfer data between BMC and host using DMA
49 *
50 * @param[in] path - pathname of the file to transfer data from or to
51 * @param[in] offset - offset in the file
52 * @param[in] length - length of the data to transfer
53 * @param[in] address - DMA address on the host
54 * @param[in] upstream - indicates direction of the transfer; true indicates
55 * transfer to the host
56 *
57 * @return returns 0 on success, negative errno on failure
58 */
Deepak Kodihalli15211b42019-12-14 02:24:49 -060059 int transferDataHost(int fd, uint32_t offset, uint32_t length,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053060 uint64_t address, bool upstream);
Ravi Tejace1c96f2020-10-05 23:13:01 -050061
62 /** @brief API to transfer data on to unix socket from host using DMA
63 *
64 * @param[in] path - pathname of the file to transfer data from or to
65 * @param[in] length - length of the data to transfer
66 * @param[in] address - DMA address on the host
67 *
68 * @return returns 0 on success, negative errno on failure
69 */
70 int transferHostDataToSocket(int fd, uint32_t length, uint64_t address);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053071};
72
73/** @brief Transfer the data between BMC and host using DMA.
74 *
75 * There is a max size for each DMA operation, transferAll API abstracts this
76 * and the requested length is broken down into multiple DMA operations if the
77 * length exceed max size.
78 *
79 * @tparam[in] T - DMA interface type
80 * @param[in] intf - interface passed to invoke DMA transfer
81 * @param[in] command - PLDM command
82 * @param[in] path - pathname of the file to transfer data from or to
83 * @param[in] offset - offset in the file
84 * @param[in] length - length of the data to transfer
85 * @param[in] address - DMA address on the host
86 * @param[in] upstream - indicates direction of the transfer; true indicates
87 * transfer to the host
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +053088 * @param[in] instanceId - Message's instance id
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053089 * @return PLDM response message
90 */
91
92template <class DMAInterface>
93Response transferAll(DMAInterface* intf, uint8_t command, fs::path& path,
94 uint32_t offset, uint32_t length, uint64_t address,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +053095 bool upstream, uint8_t instanceId)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053096{
97 uint32_t origLength = length;
98 Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_RESP_BYTES, 0);
99 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
100
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600101 int flags{};
102 if (upstream)
103 {
104 flags = O_RDONLY;
105 }
106 else if (fs::exists(path))
107 {
108 flags = O_RDWR;
109 }
110 else
111 {
112 flags = O_WRONLY;
113 }
114 int file = open(path.string().c_str(), flags);
115 if (file == -1)
116 {
117 std::cerr << "File does not exist, path = " << path.string() << "\n";
118 encode_rw_file_memory_resp(instanceId, command, PLDM_ERROR, 0,
119 responsePtr);
120 return response;
121 }
George Liu83409572019-12-24 18:42:54 +0800122 pldm::utils::CustomFD fd(file);
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600123
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530124 while (length > dma::maxSize)
125 {
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600126 auto rc = intf->transferDataHost(fd(), offset, dma::maxSize, address,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530127 upstream);
128 if (rc < 0)
129 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530130 encode_rw_file_memory_resp(instanceId, command, PLDM_ERROR, 0,
131 responsePtr);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530132 return response;
133 }
134
135 offset += dma::maxSize;
136 length -= dma::maxSize;
137 address += dma::maxSize;
138 }
139
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600140 auto rc = intf->transferDataHost(fd(), offset, length, address, upstream);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530141 if (rc < 0)
142 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530143 encode_rw_file_memory_resp(instanceId, command, PLDM_ERROR, 0,
144 responsePtr);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530145 return response;
146 }
147
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530148 encode_rw_file_memory_resp(instanceId, command, PLDM_SUCCESS, origLength,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530149 responsePtr);
150 return response;
151}
152
153} // namespace dma
154
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600155namespace oem_ibm
156{
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600157class Handler : public CmdHandler
158{
159 public:
160 Handler()
161 {
162 handlers.emplace(PLDM_READ_FILE_INTO_MEMORY,
163 [this](const pldm_msg* request, size_t payloadLength) {
164 return this->readFileIntoMemory(request,
165 payloadLength);
166 });
167 handlers.emplace(PLDM_WRITE_FILE_FROM_MEMORY,
168 [this](const pldm_msg* request, size_t payloadLength) {
169 return this->writeFileFromMemory(request,
170 payloadLength);
171 });
172 handlers.emplace(PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY,
173 [this](const pldm_msg* request, size_t payloadLength) {
174 return this->writeFileByTypeFromMemory(
175 request, payloadLength);
176 });
177 handlers.emplace(PLDM_READ_FILE_BY_TYPE_INTO_MEMORY,
178 [this](const pldm_msg* request, size_t payloadLength) {
179 return this->readFileByTypeIntoMemory(
180 request, payloadLength);
181 });
182 handlers.emplace(PLDM_READ_FILE_BY_TYPE, [this](const pldm_msg* request,
183 size_t payloadLength) {
184 return this->readFileByType(request, payloadLength);
185 });
Sampa Misra18967162020-01-14 02:31:41 -0600186 handlers.emplace(PLDM_WRITE_FILE_BY_TYPE,
187 [this](const pldm_msg* request, size_t payloadLength) {
188 return this->writeFileByType(request,
189 payloadLength);
190 });
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600191 handlers.emplace(PLDM_GET_FILE_TABLE,
192 [this](const pldm_msg* request, size_t payloadLength) {
193 return this->getFileTable(request, payloadLength);
194 });
195 handlers.emplace(PLDM_READ_FILE,
196 [this](const pldm_msg* request, size_t payloadLength) {
197 return this->readFile(request, payloadLength);
198 });
199 handlers.emplace(PLDM_WRITE_FILE,
200 [this](const pldm_msg* request, size_t payloadLength) {
201 return this->writeFile(request, payloadLength);
202 });
Deepak Kodihalli2da1bfe2019-12-14 08:28:09 -0600203 handlers.emplace(PLDM_FILE_ACK,
204 [this](const pldm_msg* request, size_t payloadLength) {
205 return this->fileAck(request, payloadLength);
206 });
George Liu89aad712020-03-12 13:34:51 +0800207 handlers.emplace(PLDM_HOST_GET_ALERT_STATUS,
208 [this](const pldm_msg* request, size_t payloadLength) {
209 return this->getAlertStatus(request,
210 payloadLength);
211 });
Sampa Misra18967162020-01-14 02:31:41 -0600212 handlers.emplace(PLDM_NEW_FILE_AVAILABLE,
213 [this](const pldm_msg* request, size_t payloadLength) {
214 return this->newFileAvailable(request,
215 payloadLength);
216 });
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600217 }
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530218
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600219 /** @brief Handler for readFileIntoMemory command
220 *
221 * @param[in] request - pointer to PLDM request payload
222 * @param[in] payloadLength - length of the message
223 *
224 * @return PLDM response message
225 */
226 Response readFileIntoMemory(const pldm_msg* request, size_t payloadLength);
Sampa Misra854e61f2019-08-22 04:36:47 -0500227
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600228 /** @brief Handler for writeFileIntoMemory command
229 *
230 * @param[in] request - pointer to PLDM request payload
231 * @param[in] payloadLength - length of the message
232 *
233 * @return PLDM response message
234 */
235 Response writeFileFromMemory(const pldm_msg* request, size_t payloadLength);
Sampa Misra854e61f2019-08-22 04:36:47 -0500236
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600237 /** @brief Handler for writeFileByTypeFromMemory command
238 *
239 * @param[in] request - pointer to PLDM request payload
240 * @param[in] payloadLength - length of the message
241 *
242 * @return PLDM response message
243 */
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600244
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600245 Response writeFileByTypeFromMemory(const pldm_msg* request,
246 size_t payloadLength);
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600247
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600248 /** @brief Handler for readFileByTypeIntoMemory command
249 *
250 * @param[in] request - pointer to PLDM request payload
251 * @param[in] payloadLength - length of the message
252 *
253 * @return PLDM response message
254 */
255 Response readFileByTypeIntoMemory(const pldm_msg* request,
256 size_t payloadLength);
vkaverap5b914c32019-06-30 22:23:54 -0500257
Sampa Misra18967162020-01-14 02:31:41 -0600258 /** @brief Handler for writeFileByType command
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600259 *
260 * @param[in] request - pointer to PLDM request payload
261 * @param[in] payloadLength - length of the message
262 *
263 * @return PLDM response message
264 */
265 Response readFileByType(const pldm_msg* request, size_t payloadLength);
vkaverap5b914c32019-06-30 22:23:54 -0500266
Sampa Misra18967162020-01-14 02:31:41 -0600267 Response writeFileByType(const pldm_msg* request, size_t payloadLength);
268
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600269 /** @brief Handler for GetFileTable command
270 *
271 * @param[in] request - pointer to PLDM request payload
272 * @param[in] payloadLength - length of the message payload
273 *
274 * @return PLDM response message
275 */
276 Response getFileTable(const pldm_msg* request, size_t payloadLength);
277
278 /** @brief Handler for readFile command
279 *
280 * @param[in] request - PLDM request msg
281 * @param[in] payloadLength - length of the message payload
282 *
283 * @return PLDM response message
284 */
285 Response readFile(const pldm_msg* request, size_t payloadLength);
286
287 /** @brief Handler for writeFile command
288 *
289 * @param[in] request - PLDM request msg
290 * @param[in] payloadLength - length of the message payload
291 *
292 * @return PLDM response message
293 */
294 Response writeFile(const pldm_msg* request, size_t payloadLength);
Deepak Kodihalli2da1bfe2019-12-14 08:28:09 -0600295
296 Response fileAck(const pldm_msg* request, size_t payloadLength);
George Liu89aad712020-03-12 13:34:51 +0800297
298 /** @brief Handler for getAlertStatus command
299 *
300 * @param[in] request - PLDM request msg
301 * @param[in] payloadLength - length of the message payload
302 *
303 * @return PLDM response message
304 */
305 Response getAlertStatus(const pldm_msg* request, size_t payloadLength);
Sampa Misra18967162020-01-14 02:31:41 -0600306
307 /** @brief Handler for newFileAvailable command
308 *
309 * @param[in] request - PLDM request msg
310 * @param[in] payloadLength - length of the message payload
311 *
312 * @return PLDM response message
313 */
314 Response newFileAvailable(const pldm_msg* request, size_t payloadLength);
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600315};
316
317} // namespace oem_ibm
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530318} // namespace responder
319} // namespace pldm