blob: be0c95bd2e7383eb1278c271f0dec88d8c76c5be [file] [log] [blame]
Tom Joseph0c6d22c2019-06-26 09:58:41 +05301#include "config.h"
2
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +05303#include "file_io.hpp"
4
Sampa Misra854e61f2019-08-22 04:36:47 -05005#include "file_io_by_type.hpp"
Tom Joseph0c6d22c2019-06-26 09:58:41 +05306#include "file_table.hpp"
Jinu Joy Thomasf666db12019-05-29 05:22:31 -05007#include "libpldmresponder/utils.hpp"
Sampa Misra854e61f2019-08-22 04:36:47 -05008#include "xyz/openbmc_project/Common/error.hpp"
Jinu Joy Thomasf666db12019-05-29 05:22:31 -05009
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053010#include <fcntl.h>
11#include <sys/mman.h>
12#include <sys/stat.h>
13#include <sys/types.h>
14#include <unistd.h>
15
16#include <cstring>
17#include <fstream>
Sampa Misra854e61f2019-08-22 04:36:47 -050018#include <memory>
19#include <phosphor-logging/elog-errors.hpp>
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053020#include <phosphor-logging/log.hpp>
21
22#include "libpldm/base.h"
23
24namespace pldm
25{
26
Sampa Misra854e61f2019-08-22 04:36:47 -050027using namespace phosphor::logging;
28using namespace sdbusplus::xyz::openbmc_project::Common::Error;
29
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053030namespace responder
31{
32
33namespace fs = std::filesystem;
34using namespace phosphor::logging;
35
36namespace dma
37{
38
39/** @struct AspeedXdmaOp
40 *
41 * Structure representing XDMA operation
42 */
43struct AspeedXdmaOp
44{
45 uint64_t hostAddr; //!< the DMA address on the host side, configured by
46 //!< PCI subsystem.
47 uint32_t len; //!< the size of the transfer in bytes, it should be a
48 //!< multiple of 16 bytes
49 uint32_t upstream; //!< boolean indicating the direction of the DMA
50 //!< operation, true means a transfer from BMC to host.
51};
52
Deepak Kodihalli134cc1b2019-10-04 01:51:02 -050053constexpr auto xdmaDev = "/dev/aspeed-xdma";
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053054
55int DMA::transferDataHost(const fs::path& path, uint32_t offset,
56 uint32_t length, uint64_t address, bool upstream)
57{
58 static const size_t pageSize = getpagesize();
59 uint32_t numPages = length / pageSize;
60 uint32_t pageAlignedLength = numPages * pageSize;
61
62 if (length > pageAlignedLength)
63 {
64 pageAlignedLength += pageSize;
65 }
66
67 auto mmapCleanup = [pageAlignedLength](void* vgaMem) {
68 munmap(vgaMem, pageAlignedLength);
69 };
70
71 int fd = -1;
72 int rc = 0;
73 fd = open(xdmaDev, O_RDWR);
74 if (fd < 0)
75 {
76 rc = -errno;
77 log<level::ERR>("Failed to open the XDMA device", entry("RC=%d", rc));
78 return rc;
79 }
80
81 utils::CustomFD xdmaFd(fd);
82
83 void* vgaMem;
84 vgaMem = mmap(nullptr, pageAlignedLength, upstream ? PROT_WRITE : PROT_READ,
85 MAP_SHARED, xdmaFd(), 0);
86 if (MAP_FAILED == vgaMem)
87 {
88 rc = -errno;
89 log<level::ERR>("Failed to mmap the XDMA device", entry("RC=%d", rc));
90 return rc;
91 }
92
93 std::unique_ptr<void, decltype(mmapCleanup)> vgaMemPtr(vgaMem, mmapCleanup);
94
95 if (upstream)
96 {
Tom Joseph0c6d22c2019-06-26 09:58:41 +053097 std::ifstream stream(path.string(), std::ios::in | std::ios::binary);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053098 stream.seekg(offset);
Tom Joseph0c6d22c2019-06-26 09:58:41 +053099
100 // Writing to the VGA memory should be aligned at page boundary,
101 // otherwise write data into a buffer aligned at page boundary and
102 // then write to the VGA memory.
103 std::vector<char> buffer{};
104 buffer.resize(pageAlignedLength);
105 stream.read(buffer.data(), length);
106 memcpy(static_cast<char*>(vgaMemPtr.get()), buffer.data(),
107 pageAlignedLength);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530108
109 if (static_cast<uint32_t>(stream.gcount()) != length)
110 {
111 log<level::ERR>("mismatch between number of characters to read and "
112 "the length read",
113 entry("LENGTH=%d", length),
114 entry("COUNT=%d", stream.gcount()));
115 return -1;
116 }
117 }
118
119 AspeedXdmaOp xdmaOp;
120 xdmaOp.upstream = upstream ? 1 : 0;
121 xdmaOp.hostAddr = address;
122 xdmaOp.len = length;
123
124 rc = write(xdmaFd(), &xdmaOp, sizeof(xdmaOp));
125 if (rc < 0)
126 {
127 rc = -errno;
128 log<level::ERR>("Failed to execute the DMA operation",
129 entry("RC=%d", rc), entry("UPSTREAM=%d", upstream),
130 entry("ADDRESS=%lld", address),
131 entry("LENGTH=%d", length));
132 return rc;
133 }
134
135 if (!upstream)
136 {
Sampa Misra854e61f2019-08-22 04:36:47 -0500137 std::ios_base::openmode mode = std::ios::out | std::ios::binary;
138 if (fs::exists(path))
139 {
140 mode |= std::ios::in;
141 }
142 std::ofstream stream(path.string(), mode);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530143
144 stream.seekp(offset);
145 stream.write(static_cast<const char*>(vgaMemPtr.get()), length);
146 }
147
148 return 0;
149}
150
151} // namespace dma
152
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600153namespace oem_ibm
154{
155
156Response Handler::readFileIntoMemory(const pldm_msg* request,
157 size_t payloadLength)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530158{
159 uint32_t fileHandle = 0;
160 uint32_t offset = 0;
161 uint32_t length = 0;
162 uint64_t address = 0;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530163
164 Response response((sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_RESP_BYTES), 0);
165 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
166
167 if (payloadLength != PLDM_RW_FILE_MEM_REQ_BYTES)
168 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530169 encode_rw_file_memory_resp(request->hdr.instance_id,
170 PLDM_READ_FILE_INTO_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530171 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
172 return response;
173 }
174
Zahed Hossain223a73d2019-07-04 12:46:18 -0500175 decode_rw_file_memory_req(request, payloadLength, &fileHandle, &offset,
176 &length, &address);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530177
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530178 using namespace pldm::filetable;
179 auto& table = buildFileTable(FILE_TABLE_JSON);
180 FileEntry value{};
181
182 try
183 {
184 value = table.at(fileHandle);
185 }
186 catch (std::exception& e)
187 {
188 log<level::ERR>("File handle does not exist in the file table",
189 entry("HANDLE=%d", fileHandle));
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530190 encode_rw_file_memory_resp(request->hdr.instance_id,
191 PLDM_READ_FILE_INTO_MEMORY,
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530192 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
193 return response;
194 }
195
196 if (!fs::exists(value.fsPath))
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530197 {
198 log<level::ERR>("File does not exist", entry("HANDLE=%d", fileHandle));
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530199 encode_rw_file_memory_resp(request->hdr.instance_id,
200 PLDM_READ_FILE_INTO_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530201 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
202 return response;
203 }
204
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530205 auto fileSize = fs::file_size(value.fsPath);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530206 if (offset >= fileSize)
207 {
208 log<level::ERR>("Offset exceeds file size", entry("OFFSET=%d", offset),
209 entry("FILE_SIZE=%d", fileSize));
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530210 encode_rw_file_memory_resp(request->hdr.instance_id,
211 PLDM_READ_FILE_INTO_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530212 PLDM_DATA_OUT_OF_RANGE, 0, responsePtr);
213 return response;
214 }
215
216 if (offset + length > fileSize)
217 {
218 length = fileSize - offset;
219 }
220
221 if (length % dma::minSize)
222 {
223 log<level::ERR>("Read length is not a multiple of DMA minSize",
224 entry("LENGTH=%d", length));
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530225 encode_rw_file_memory_resp(request->hdr.instance_id,
226 PLDM_READ_FILE_INTO_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530227 PLDM_INVALID_READ_LENGTH, 0, responsePtr);
228 return response;
229 }
230
231 using namespace dma;
232 DMA intf;
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530233 return transferAll<DMA>(&intf, PLDM_READ_FILE_INTO_MEMORY, value.fsPath,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530234 offset, length, address, true,
235 request->hdr.instance_id);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530236}
237
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600238Response Handler::writeFileFromMemory(const pldm_msg* request,
239 size_t payloadLength)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530240{
241 uint32_t fileHandle = 0;
242 uint32_t offset = 0;
243 uint32_t length = 0;
244 uint64_t address = 0;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530245
246 Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_RESP_BYTES, 0);
247 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
248
249 if (payloadLength != PLDM_RW_FILE_MEM_REQ_BYTES)
250 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530251 encode_rw_file_memory_resp(request->hdr.instance_id,
252 PLDM_WRITE_FILE_FROM_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530253 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
254 return response;
255 }
256
Zahed Hossain223a73d2019-07-04 12:46:18 -0500257 decode_rw_file_memory_req(request, payloadLength, &fileHandle, &offset,
258 &length, &address);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530259
260 if (length % dma::minSize)
261 {
262 log<level::ERR>("Write length is not a multiple of DMA minSize",
263 entry("LENGTH=%d", length));
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530264 encode_rw_file_memory_resp(request->hdr.instance_id,
265 PLDM_WRITE_FILE_FROM_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530266 PLDM_INVALID_WRITE_LENGTH, 0, responsePtr);
267 return response;
268 }
269
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530270 using namespace pldm::filetable;
271 auto& table = buildFileTable(FILE_TABLE_JSON);
272 FileEntry value{};
273
274 try
275 {
276 value = table.at(fileHandle);
277 }
278 catch (std::exception& e)
279 {
280 log<level::ERR>("File handle does not exist in the file table",
281 entry("HANDLE=%d", fileHandle));
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530282 encode_rw_file_memory_resp(request->hdr.instance_id,
283 PLDM_WRITE_FILE_FROM_MEMORY,
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530284 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
285 return response;
286 }
287
288 if (!fs::exists(value.fsPath))
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530289 {
290 log<level::ERR>("File does not exist", entry("HANDLE=%d", fileHandle));
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530291 encode_rw_file_memory_resp(request->hdr.instance_id,
292 PLDM_WRITE_FILE_FROM_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530293 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
294 return response;
295 }
296
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530297 auto fileSize = fs::file_size(value.fsPath);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530298 if (offset >= fileSize)
299 {
300 log<level::ERR>("Offset exceeds file size", entry("OFFSET=%d", offset),
301 entry("FILE_SIZE=%d", fileSize));
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530302 encode_rw_file_memory_resp(request->hdr.instance_id,
303 PLDM_WRITE_FILE_FROM_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530304 PLDM_DATA_OUT_OF_RANGE, 0, responsePtr);
305 return response;
306 }
307
308 using namespace dma;
309 DMA intf;
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530310 return transferAll<DMA>(&intf, PLDM_WRITE_FILE_FROM_MEMORY, value.fsPath,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530311 offset, length, address, false,
312 request->hdr.instance_id);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530313}
314
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600315Response Handler::getFileTable(const pldm_msg* request, size_t payloadLength)
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530316{
317 uint32_t transferHandle = 0;
318 uint8_t transferFlag = 0;
319 uint8_t tableType = 0;
320
321 Response response(sizeof(pldm_msg_hdr) +
322 PLDM_GET_FILE_TABLE_MIN_RESP_BYTES);
323 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
324
325 if (payloadLength != PLDM_GET_FILE_TABLE_REQ_BYTES)
326 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530327 encode_get_file_table_resp(request->hdr.instance_id,
328 PLDM_ERROR_INVALID_LENGTH, 0, 0, nullptr, 0,
329 responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530330 return response;
331 }
332
Zahed Hossain223a73d2019-07-04 12:46:18 -0500333 auto rc = decode_get_file_table_req(request, payloadLength, &transferHandle,
334 &transferFlag, &tableType);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530335 if (rc)
336 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530337 encode_get_file_table_resp(request->hdr.instance_id, rc, 0, 0, nullptr,
338 0, responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530339 return response;
340 }
341
342 if (tableType != PLDM_FILE_ATTRIBUTE_TABLE)
343 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530344 encode_get_file_table_resp(request->hdr.instance_id,
345 PLDM_INVALID_FILE_TABLE_TYPE, 0, 0, nullptr,
346 0, responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530347 return response;
348 }
349
350 using namespace pldm::filetable;
351 auto table = buildFileTable(FILE_TABLE_JSON);
352 auto attrTable = table();
353 response.resize(response.size() + attrTable.size());
354 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
355
356 if (attrTable.empty())
357 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530358 encode_get_file_table_resp(request->hdr.instance_id,
359 PLDM_FILE_TABLE_UNAVAILABLE, 0, 0, nullptr,
360 0, responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530361 return response;
362 }
363
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530364 encode_get_file_table_resp(request->hdr.instance_id, PLDM_SUCCESS, 0,
365 PLDM_START_AND_END, attrTable.data(),
366 attrTable.size(), responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530367 return response;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530368}
369
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600370Response Handler::readFile(const pldm_msg* request, size_t payloadLength)
vkaverap5b914c32019-06-30 22:23:54 -0500371{
372 uint32_t fileHandle = 0;
373 uint32_t offset = 0;
374 uint32_t length = 0;
375
376 Response response(sizeof(pldm_msg_hdr) + PLDM_READ_FILE_RESP_BYTES);
377 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
378
379 if (payloadLength != PLDM_READ_FILE_REQ_BYTES)
380 {
381 encode_read_file_resp(request->hdr.instance_id,
382 PLDM_ERROR_INVALID_LENGTH, length, responsePtr);
383 return response;
384 }
385
386 auto rc = decode_read_file_req(request, payloadLength, &fileHandle, &offset,
387 &length);
388
389 if (rc)
390 {
391 encode_read_file_resp(request->hdr.instance_id, rc, 0, responsePtr);
392 return response;
393 }
394
395 using namespace pldm::filetable;
396 auto& table = buildFileTable(FILE_TABLE_JSON);
397 FileEntry value{};
398
399 try
400 {
401 value = table.at(fileHandle);
402 }
403 catch (std::exception& e)
404 {
405 log<level::ERR>("File handle does not exist in the file table",
406 entry("HANDLE=%d", fileHandle));
407 encode_read_file_resp(request->hdr.instance_id,
408 PLDM_INVALID_FILE_HANDLE, length, responsePtr);
409 return response;
410 }
411
412 if (!fs::exists(value.fsPath))
413 {
414 log<level::ERR>("File does not exist", entry("HANDLE=%d", fileHandle));
415 encode_read_file_resp(request->hdr.instance_id,
416 PLDM_INVALID_FILE_HANDLE, length, responsePtr);
417 return response;
418 }
419
420 auto fileSize = fs::file_size(value.fsPath);
421 if (offset >= fileSize)
422 {
423 log<level::ERR>("Offset exceeds file size", entry("OFFSET=%d", offset),
424 entry("FILE_SIZE=%d", fileSize));
425 encode_read_file_resp(request->hdr.instance_id, PLDM_DATA_OUT_OF_RANGE,
426 length, responsePtr);
427 return response;
428 }
429
430 if (offset + length > fileSize)
431 {
432 length = fileSize - offset;
433 }
434
435 response.resize(response.size() + length);
436 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
437 auto fileDataPos = reinterpret_cast<char*>(responsePtr);
438 fileDataPos += sizeof(pldm_msg_hdr) + sizeof(uint8_t) + sizeof(length);
439
440 std::ifstream stream(value.fsPath, std::ios::in | std::ios::binary);
441 stream.seekg(offset);
442 stream.read(fileDataPos, length);
443
444 encode_read_file_resp(request->hdr.instance_id, PLDM_SUCCESS, length,
445 responsePtr);
446
447 return response;
448}
449
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600450Response Handler::writeFile(const pldm_msg* request, size_t payloadLength)
vkaverap5b914c32019-06-30 22:23:54 -0500451{
452 uint32_t fileHandle = 0;
453 uint32_t offset = 0;
454 uint32_t length = 0;
455 size_t fileDataOffset = 0;
456
457 Response response(sizeof(pldm_msg_hdr) + PLDM_WRITE_FILE_RESP_BYTES);
458 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
459
460 if (payloadLength < PLDM_WRITE_FILE_REQ_BYTES)
461 {
462 encode_write_file_resp(request->hdr.instance_id,
463 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
464 return response;
465 }
466
467 auto rc = decode_write_file_req(request, payloadLength, &fileHandle,
468 &offset, &length, &fileDataOffset);
469
470 if (rc)
471 {
472 encode_write_file_resp(request->hdr.instance_id, rc, 0, responsePtr);
473 return response;
474 }
475
476 using namespace pldm::filetable;
477 auto& table = buildFileTable(FILE_TABLE_JSON);
478 FileEntry value{};
479
480 try
481 {
482 value = table.at(fileHandle);
483 }
484 catch (std::exception& e)
485 {
486 log<level::ERR>("File handle does not exist in the file table",
487 entry("HANDLE=%d", fileHandle));
488 encode_write_file_resp(request->hdr.instance_id,
489 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
490 return response;
491 }
492
493 if (!fs::exists(value.fsPath))
494 {
495 log<level::ERR>("File does not exist", entry("HANDLE=%d", fileHandle));
496 encode_write_file_resp(request->hdr.instance_id,
497 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
498 return response;
499 }
500
501 auto fileSize = fs::file_size(value.fsPath);
502 if (offset >= fileSize)
503 {
504 log<level::ERR>("Offset exceeds file size", entry("OFFSET=%d", offset),
505 entry("FILE_SIZE=%d", fileSize));
506 encode_write_file_resp(request->hdr.instance_id, PLDM_DATA_OUT_OF_RANGE,
507 0, responsePtr);
508 return response;
509 }
510
511 auto fileDataPos =
512 reinterpret_cast<const char*>(request->payload) + fileDataOffset;
513
514 std::ofstream stream(value.fsPath,
515 std::ios::in | std::ios::out | std::ios::binary);
516 stream.seekp(offset);
517 stream.write(fileDataPos, length);
518
519 encode_write_file_resp(request->hdr.instance_id, PLDM_SUCCESS, length,
520 responsePtr);
521
522 return response;
523}
524
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600525Response rwFileByTypeIntoMemory(uint8_t cmd, const pldm_msg* request,
526 size_t payloadLength)
Sampa Misra854e61f2019-08-22 04:36:47 -0500527{
528 Response response(
529 sizeof(pldm_msg_hdr) + PLDM_RW_FILE_BY_TYPE_MEM_RESP_BYTES, 0);
530 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
531
532 if (payloadLength != PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES)
533 {
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600534 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd,
535 PLDM_ERROR_INVALID_LENGTH, 0,
536 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500537 return response;
538 }
539
540 uint16_t fileType{};
541 uint32_t fileHandle{};
542 uint32_t offset{};
543 uint32_t length{};
544 uint64_t address{};
545 auto rc = decode_rw_file_by_type_memory_req(request, payloadLength,
546 &fileType, &fileHandle, &offset,
547 &length, &address);
548 if (rc != PLDM_SUCCESS)
549 {
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600550 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd, rc, 0,
551 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500552 return response;
553 }
554 if (length % dma::minSize)
555 {
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600556 log<level::ERR>("Length is not a multiple of DMA minSize",
Sampa Misra854e61f2019-08-22 04:36:47 -0500557 entry("LENGTH=%d", length));
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600558 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd,
559 PLDM_INVALID_WRITE_LENGTH, 0,
560 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500561 return response;
562 }
563
564 std::unique_ptr<FileHandler> handler{};
565 try
566 {
567 handler = getHandlerByType(fileType, fileHandle);
568 }
569 catch (const InternalFailure& e)
570 {
571 log<level::ERR>("unknown file type ", entry("TYPE=%d", fileType));
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600572 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd,
573 PLDM_INVALID_FILE_TYPE, 0,
574 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500575 return response;
576 }
577
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600578 rc = cmd == PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY
579 ? handler->writeFromMemory(offset, length, address)
580 : handler->readIntoMemory(offset, length, address);
581 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd, rc,
Sampa Misra854e61f2019-08-22 04:36:47 -0500582 length, responsePtr);
583 return response;
584}
585
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600586Response Handler::writeFileByTypeFromMemory(const pldm_msg* request,
587 size_t payloadLength)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600588{
589 return rwFileByTypeIntoMemory(PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY, request,
590 payloadLength);
591}
592
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600593Response Handler::readFileByTypeIntoMemory(const pldm_msg* request,
594 size_t payloadLength)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600595{
596 return rwFileByTypeIntoMemory(PLDM_READ_FILE_BY_TYPE_INTO_MEMORY, request,
597 payloadLength);
598}
599
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600600Response Handler::readFileByType(const pldm_msg* request, size_t payloadLength)
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600601{
602 Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_BY_TYPE_RESP_BYTES);
603 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
604
605 if (payloadLength != PLDM_RW_FILE_BY_TYPE_REQ_BYTES)
606 {
607 encode_rw_file_by_type_resp(request->hdr.instance_id,
608 PLDM_READ_FILE_BY_TYPE,
609 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
610 return response;
611 }
612 uint16_t fileType{};
613 uint32_t fileHandle{};
614 uint32_t offset{};
615 uint32_t length{};
616
617 auto rc = decode_rw_file_by_type_req(request, payloadLength, &fileType,
618 &fileHandle, &offset, &length);
619 if (rc != PLDM_SUCCESS)
620 {
621 encode_rw_file_by_type_resp(request->hdr.instance_id,
622 PLDM_READ_FILE_BY_TYPE, rc, 0, responsePtr);
623 return response;
624 }
625
626 std::unique_ptr<FileHandler> handler{};
627 try
628 {
629 handler = getHandlerByType(fileType, fileHandle);
630 }
631 catch (const InternalFailure& e)
632 {
633 log<level::ERR>("unknown file type", entry("TYPE=%d", fileType));
634 encode_rw_file_by_type_resp(request->hdr.instance_id,
635 PLDM_READ_FILE_BY_TYPE,
636 PLDM_INVALID_FILE_TYPE, 0, responsePtr);
637 return response;
638 }
639
640 rc = handler->read(offset, length, response);
Deepak Kodihalli9a26f892019-12-10 06:48:06 -0600641 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600642 encode_rw_file_by_type_resp(request->hdr.instance_id,
643 PLDM_READ_FILE_BY_TYPE, rc, length,
644 responsePtr);
645 return response;
646}
647
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600648} // namespace oem_ibm
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530649} // namespace responder
650} // namespace pldm