blob: b347960e9c60553abc690339cc5a4d5f74fb061f [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
George Liu6492f522020-06-16 10:34:05 +08005#include "libpldm/base.h"
6
Sampa Misra854e61f2019-08-22 04:36:47 -05007#include "file_io_by_type.hpp"
Tom Joseph0c6d22c2019-06-26 09:58:41 +05308#include "file_table.hpp"
Ravi Tejace1c96f2020-10-05 23:13:01 -05009#include "utils.hpp"
Sampa Misra854e61f2019-08-22 04:36:47 -050010#include "xyz/openbmc_project/Common/error.hpp"
Jinu Joy Thomasf666db12019-05-29 05:22:31 -050011
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053012#include <fcntl.h>
13#include <sys/mman.h>
14#include <sys/stat.h>
15#include <sys/types.h>
16#include <unistd.h>
17
18#include <cstring>
19#include <fstream>
Sampa Misraaa8ae722019-12-12 03:20:40 -060020#include <iostream>
Sampa Misra854e61f2019-08-22 04:36:47 -050021#include <memory>
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053022
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053023namespace pldm
24{
Ravi Tejace1c96f2020-10-05 23:13:01 -050025using namespace pldm::responder::utils;
Sampa Misra854e61f2019-08-22 04:36:47 -050026using namespace sdbusplus::xyz::openbmc_project::Common::Error;
27
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053028namespace responder
29{
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053030namespace fs = std::filesystem;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053031
32namespace dma
33{
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053034/** @struct AspeedXdmaOp
35 *
36 * Structure representing XDMA operation
37 */
38struct AspeedXdmaOp
39{
40 uint64_t hostAddr; //!< the DMA address on the host side, configured by
41 //!< PCI subsystem.
42 uint32_t len; //!< the size of the transfer in bytes, it should be a
43 //!< multiple of 16 bytes
44 uint32_t upstream; //!< boolean indicating the direction of the DMA
45 //!< operation, true means a transfer from BMC to host.
46};
47
Deepak Kodihalli134cc1b2019-10-04 01:51:02 -050048constexpr auto xdmaDev = "/dev/aspeed-xdma";
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053049
Ravi Tejace1c96f2020-10-05 23:13:01 -050050int DMA::transferHostDataToSocket(int fd, uint32_t length, uint64_t address)
51{
52 static const size_t pageSize = getpagesize();
53 uint32_t numPages = length / pageSize;
54 uint32_t pageAlignedLength = numPages * pageSize;
55
56 if (length > pageAlignedLength)
57 {
58 pageAlignedLength += pageSize;
59 }
60
61 auto mmapCleanup = [pageAlignedLength](void* vgaMem) {
62 munmap(vgaMem, pageAlignedLength);
63 };
64
65 int dmaFd = -1;
66 int rc = 0;
67 dmaFd = open(xdmaDev, O_RDWR);
68 if (dmaFd < 0)
69 {
70 rc = -errno;
Jayashankar Padathe64f5522022-09-28 21:30:24 -050071 std::cerr << "transferHostDataToSocket: Failed to open the XDMA device,"
72 " RC="
73 << rc << "\n";
Ravi Tejace1c96f2020-10-05 23:13:01 -050074 return rc;
75 }
76
77 pldm::utils::CustomFD xdmaFd(dmaFd);
78
79 void* vgaMem;
80 vgaMem =
81 mmap(nullptr, pageAlignedLength, PROT_READ, MAP_SHARED, xdmaFd(), 0);
82 if (MAP_FAILED == vgaMem)
83 {
84 rc = -errno;
Jayashankar Padathe64f5522022-09-28 21:30:24 -050085 std::cerr << "transferHostDataToSocket: Failed to mmap the XDMA device,"
86 " RC="
87 << rc << "\n";
Ravi Tejace1c96f2020-10-05 23:13:01 -050088 return rc;
89 }
90
91 std::unique_ptr<void, decltype(mmapCleanup)> vgaMemPtr(vgaMem, mmapCleanup);
92
93 AspeedXdmaOp xdmaOp;
94 xdmaOp.upstream = 0;
95 xdmaOp.hostAddr = address;
96 xdmaOp.len = length;
97
98 rc = write(xdmaFd(), &xdmaOp, sizeof(xdmaOp));
99 if (rc < 0)
100 {
101 rc = -errno;
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500102 std::cerr << "transferHostDataToSocket: Failed to execute the DMA "
103 "operation, RC="
104 << rc << " ADDRESS=" << address << " LENGTH=" << length
105 << "\n";
Ravi Tejace1c96f2020-10-05 23:13:01 -0500106 return rc;
107 }
108
109 rc = writeToUnixSocket(fd, static_cast<const char*>(vgaMemPtr.get()),
110 length);
111 if (rc < 0)
112 {
113 rc = -errno;
114 close(fd);
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500115 std::cerr << "transferHostDataToSocket: Closing socket as "
116 "writeToUnixSocket faile with RC="
117 << rc << std::endl;
Ravi Tejace1c96f2020-10-05 23:13:01 -0500118 return rc;
119 }
120 return 0;
121}
122
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600123int DMA::transferDataHost(int fd, uint32_t offset, uint32_t length,
124 uint64_t address, bool upstream)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530125{
126 static const size_t pageSize = getpagesize();
127 uint32_t numPages = length / pageSize;
128 uint32_t pageAlignedLength = numPages * pageSize;
129
130 if (length > pageAlignedLength)
131 {
132 pageAlignedLength += pageSize;
133 }
134
ArchanaKakani93409752022-04-19 00:36:04 -0500135 int rc = 0;
136 auto mmapCleanup = [pageAlignedLength, &rc](void* vgaMem) {
137 if (rc != -EINTR)
138 {
139 munmap(vgaMem, pageAlignedLength);
140 }
141 else
142 {
143 std::cerr
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500144 << "transferDataHost: Received interrupt during DMA transfer."
145 " Skipping Unmap."
ArchanaKakani93409752022-04-19 00:36:04 -0500146 << std::endl;
147 }
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530148 };
149
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600150 int dmaFd = -1;
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600151 dmaFd = open(xdmaDev, O_RDWR);
152 if (dmaFd < 0)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530153 {
154 rc = -errno;
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500155 std::cerr << "transferDataHost: Failed to open the XDMA device, RC="
156 << rc << "\n";
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530157 return rc;
158 }
159
George Liu83409572019-12-24 18:42:54 +0800160 pldm::utils::CustomFD xdmaFd(dmaFd);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530161
162 void* vgaMem;
163 vgaMem = mmap(nullptr, pageAlignedLength, upstream ? PROT_WRITE : PROT_READ,
164 MAP_SHARED, xdmaFd(), 0);
165 if (MAP_FAILED == vgaMem)
166 {
167 rc = -errno;
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500168 std::cerr << "transferDataHost: Failed to mmap the XDMA device, RC="
169 << rc << "\n";
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530170 return rc;
171 }
172
173 std::unique_ptr<void, decltype(mmapCleanup)> vgaMemPtr(vgaMem, mmapCleanup);
174
175 if (upstream)
176 {
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600177 rc = lseek(fd, offset, SEEK_SET);
178 if (rc == -1)
179 {
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500180 std::cerr << "transferDataHost upstream: lseek failed, ERROR="
181 << errno << ", UPSTREAM=" << upstream
182 << ", OFFSET=" << offset << "\n";
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600183 return rc;
184 }
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530185
186 // Writing to the VGA memory should be aligned at page boundary,
187 // otherwise write data into a buffer aligned at page boundary and
188 // then write to the VGA memory.
189 std::vector<char> buffer{};
190 buffer.resize(pageAlignedLength);
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600191 rc = read(fd, buffer.data(), length);
192 if (rc == -1)
193 {
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500194 std::cerr << "transferDataHost upstream: file read failed, ERROR="
195 << errno << ", UPSTREAM=" << upstream
196 << ", LENGTH=" << length << ", OFFSET=" << offset << "\n";
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600197 return rc;
198 }
199 if (rc != static_cast<int>(length))
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530200 {
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500201 std::cerr << "transferDataHost upstream: mismatch between number of"
202 << "characters to read and the length read, LENGTH="
203 << length << " COUNT=" << rc << "\n";
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530204 return -1;
205 }
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600206 memcpy(static_cast<char*>(vgaMemPtr.get()), buffer.data(),
207 pageAlignedLength);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530208 }
209
210 AspeedXdmaOp xdmaOp;
211 xdmaOp.upstream = upstream ? 1 : 0;
212 xdmaOp.hostAddr = address;
213 xdmaOp.len = length;
214
215 rc = write(xdmaFd(), &xdmaOp, sizeof(xdmaOp));
216 if (rc < 0)
217 {
218 rc = -errno;
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500219 std::cerr << "transferDataHost: Failed to execute the DMA operation,"
220 " RC="
221 << rc << " UPSTREAM=" << upstream << " ADDRESS=" << address
Sampa Misraaa8ae722019-12-12 03:20:40 -0600222 << " LENGTH=" << length << "\n";
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530223 return rc;
224 }
225
226 if (!upstream)
227 {
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600228 rc = lseek(fd, offset, SEEK_SET);
229 if (rc == -1)
Sampa Misra854e61f2019-08-22 04:36:47 -0500230 {
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500231 std::cerr << "transferDataHost downstream: lseek failed, ERROR="
232 << errno << ", UPSTREAM=" << upstream
233 << ", OFFSET=" << offset << "\n";
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600234 return rc;
Sampa Misra854e61f2019-08-22 04:36:47 -0500235 }
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600236 rc = write(fd, static_cast<const char*>(vgaMemPtr.get()), length);
237 if (rc == -1)
238 {
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500239 std::cerr << "transferDataHost downstream: file write failed,"
240 " ERROR="
241 << errno << ", UPSTREAM=" << upstream
242 << ", LENGTH=" << length << ", OFFSET=" << offset << "\n";
Deepak Kodihalli15211b42019-12-14 02:24:49 -0600243 return rc;
244 }
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530245 }
246
247 return 0;
248}
249
250} // namespace dma
251
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600252namespace oem_ibm
253{
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600254Response Handler::readFileIntoMemory(const pldm_msg* request,
255 size_t payloadLength)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530256{
257 uint32_t fileHandle = 0;
258 uint32_t offset = 0;
259 uint32_t length = 0;
260 uint64_t address = 0;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530261
262 Response response((sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_RESP_BYTES), 0);
263 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
264
265 if (payloadLength != PLDM_RW_FILE_MEM_REQ_BYTES)
266 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530267 encode_rw_file_memory_resp(request->hdr.instance_id,
268 PLDM_READ_FILE_INTO_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530269 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
270 return response;
271 }
272
Zahed Hossain223a73d2019-07-04 12:46:18 -0500273 decode_rw_file_memory_req(request, payloadLength, &fileHandle, &offset,
274 &length, &address);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530275
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530276 using namespace pldm::filetable;
277 auto& table = buildFileTable(FILE_TABLE_JSON);
278 FileEntry value{};
279
280 try
281 {
282 value = table.at(fileHandle);
283 }
Patrick Williams51330582021-10-06 12:48:56 -0500284 catch (const std::exception& e)
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530285 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600286 std::cerr << "File handle does not exist in the file table, HANDLE="
287 << fileHandle << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530288 encode_rw_file_memory_resp(request->hdr.instance_id,
289 PLDM_READ_FILE_INTO_MEMORY,
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530290 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
291 return response;
292 }
293
294 if (!fs::exists(value.fsPath))
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530295 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600296 std::cerr << "File does not exist, HANDLE=" << fileHandle << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530297 encode_rw_file_memory_resp(request->hdr.instance_id,
298 PLDM_READ_FILE_INTO_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530299 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
300 return response;
301 }
302
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530303 auto fileSize = fs::file_size(value.fsPath);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530304 if (offset >= fileSize)
305 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600306 std::cerr << "Offset exceeds file size, OFFSET=" << offset
307 << " FILE_SIZE=" << fileSize << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530308 encode_rw_file_memory_resp(request->hdr.instance_id,
309 PLDM_READ_FILE_INTO_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530310 PLDM_DATA_OUT_OF_RANGE, 0, responsePtr);
311 return response;
312 }
313
314 if (offset + length > fileSize)
315 {
316 length = fileSize - offset;
317 }
318
319 if (length % dma::minSize)
320 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600321 std::cerr << "Read length is not a multiple of DMA minSize, LENGTH="
322 << length << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530323 encode_rw_file_memory_resp(request->hdr.instance_id,
324 PLDM_READ_FILE_INTO_MEMORY,
Deepak Kodihalli3bf5c552020-04-20 06:16:01 -0500325 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530326 return response;
327 }
328
329 using namespace dma;
330 DMA intf;
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530331 return transferAll<DMA>(&intf, PLDM_READ_FILE_INTO_MEMORY, value.fsPath,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530332 offset, length, address, true,
333 request->hdr.instance_id);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530334}
335
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600336Response Handler::writeFileFromMemory(const pldm_msg* request,
337 size_t payloadLength)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530338{
339 uint32_t fileHandle = 0;
340 uint32_t offset = 0;
341 uint32_t length = 0;
342 uint64_t address = 0;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530343
344 Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_RESP_BYTES, 0);
345 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
346
347 if (payloadLength != PLDM_RW_FILE_MEM_REQ_BYTES)
348 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530349 encode_rw_file_memory_resp(request->hdr.instance_id,
350 PLDM_WRITE_FILE_FROM_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530351 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
352 return response;
353 }
354
Zahed Hossain223a73d2019-07-04 12:46:18 -0500355 decode_rw_file_memory_req(request, payloadLength, &fileHandle, &offset,
356 &length, &address);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530357
358 if (length % dma::minSize)
359 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600360 std::cerr << "Write length is not a multiple of DMA minSize, LENGTH="
361 << length << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530362 encode_rw_file_memory_resp(request->hdr.instance_id,
363 PLDM_WRITE_FILE_FROM_MEMORY,
Deepak Kodihalli3bf5c552020-04-20 06:16:01 -0500364 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530365 return response;
366 }
367
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530368 using namespace pldm::filetable;
369 auto& table = buildFileTable(FILE_TABLE_JSON);
370 FileEntry value{};
371
372 try
373 {
374 value = table.at(fileHandle);
375 }
Patrick Williams51330582021-10-06 12:48:56 -0500376 catch (const std::exception& e)
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530377 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600378 std::cerr << "File handle does not exist in the file table, HANDLE="
379 << fileHandle << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530380 encode_rw_file_memory_resp(request->hdr.instance_id,
381 PLDM_WRITE_FILE_FROM_MEMORY,
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530382 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
383 return response;
384 }
385
386 if (!fs::exists(value.fsPath))
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530387 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600388 std::cerr << "File does not exist, HANDLE=" << fileHandle << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530389 encode_rw_file_memory_resp(request->hdr.instance_id,
390 PLDM_WRITE_FILE_FROM_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530391 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
392 return response;
393 }
394
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530395 auto fileSize = fs::file_size(value.fsPath);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530396 if (offset >= fileSize)
397 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600398 std::cerr << "Offset exceeds file size, OFFSET=" << offset
399 << " FILE_SIZE=" << fileSize << "\n";
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530400 encode_rw_file_memory_resp(request->hdr.instance_id,
401 PLDM_WRITE_FILE_FROM_MEMORY,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530402 PLDM_DATA_OUT_OF_RANGE, 0, responsePtr);
403 return response;
404 }
405
406 using namespace dma;
407 DMA intf;
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530408 return transferAll<DMA>(&intf, PLDM_WRITE_FILE_FROM_MEMORY, value.fsPath,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530409 offset, length, address, false,
410 request->hdr.instance_id);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530411}
412
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600413Response Handler::getFileTable(const pldm_msg* request, size_t payloadLength)
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530414{
415 uint32_t transferHandle = 0;
416 uint8_t transferFlag = 0;
417 uint8_t tableType = 0;
418
419 Response response(sizeof(pldm_msg_hdr) +
420 PLDM_GET_FILE_TABLE_MIN_RESP_BYTES);
421 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
422
423 if (payloadLength != PLDM_GET_FILE_TABLE_REQ_BYTES)
424 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530425 encode_get_file_table_resp(request->hdr.instance_id,
426 PLDM_ERROR_INVALID_LENGTH, 0, 0, nullptr, 0,
427 responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530428 return response;
429 }
430
Zahed Hossain223a73d2019-07-04 12:46:18 -0500431 auto rc = decode_get_file_table_req(request, payloadLength, &transferHandle,
432 &transferFlag, &tableType);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530433 if (rc)
434 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530435 encode_get_file_table_resp(request->hdr.instance_id, rc, 0, 0, nullptr,
436 0, responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530437 return response;
438 }
439
440 if (tableType != PLDM_FILE_ATTRIBUTE_TABLE)
441 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530442 encode_get_file_table_resp(request->hdr.instance_id,
443 PLDM_INVALID_FILE_TABLE_TYPE, 0, 0, nullptr,
444 0, responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530445 return response;
446 }
447
448 using namespace pldm::filetable;
449 auto table = buildFileTable(FILE_TABLE_JSON);
450 auto attrTable = table();
451 response.resize(response.size() + attrTable.size());
452 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
453
454 if (attrTable.empty())
455 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530456 encode_get_file_table_resp(request->hdr.instance_id,
457 PLDM_FILE_TABLE_UNAVAILABLE, 0, 0, nullptr,
458 0, responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530459 return response;
460 }
461
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530462 encode_get_file_table_resp(request->hdr.instance_id, PLDM_SUCCESS, 0,
463 PLDM_START_AND_END, attrTable.data(),
464 attrTable.size(), responsePtr);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530465 return response;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530466}
467
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600468Response Handler::readFile(const pldm_msg* request, size_t payloadLength)
vkaverap5b914c32019-06-30 22:23:54 -0500469{
470 uint32_t fileHandle = 0;
471 uint32_t offset = 0;
472 uint32_t length = 0;
473
474 Response response(sizeof(pldm_msg_hdr) + PLDM_READ_FILE_RESP_BYTES);
475 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
476
477 if (payloadLength != PLDM_READ_FILE_REQ_BYTES)
478 {
479 encode_read_file_resp(request->hdr.instance_id,
480 PLDM_ERROR_INVALID_LENGTH, length, responsePtr);
481 return response;
482 }
483
484 auto rc = decode_read_file_req(request, payloadLength, &fileHandle, &offset,
485 &length);
486
487 if (rc)
488 {
489 encode_read_file_resp(request->hdr.instance_id, rc, 0, responsePtr);
490 return response;
491 }
492
493 using namespace pldm::filetable;
494 auto& table = buildFileTable(FILE_TABLE_JSON);
495 FileEntry value{};
496
497 try
498 {
499 value = table.at(fileHandle);
500 }
Patrick Williams51330582021-10-06 12:48:56 -0500501 catch (const std::exception& e)
vkaverap5b914c32019-06-30 22:23:54 -0500502 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600503 std::cerr << "File handle does not exist in the file table, HANDLE="
504 << fileHandle << "\n";
vkaverap5b914c32019-06-30 22:23:54 -0500505 encode_read_file_resp(request->hdr.instance_id,
506 PLDM_INVALID_FILE_HANDLE, length, responsePtr);
507 return response;
508 }
509
510 if (!fs::exists(value.fsPath))
511 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600512 std::cerr << "File does not exist, HANDLE=" << fileHandle << "\n";
vkaverap5b914c32019-06-30 22:23:54 -0500513 encode_read_file_resp(request->hdr.instance_id,
514 PLDM_INVALID_FILE_HANDLE, length, responsePtr);
515 return response;
516 }
517
518 auto fileSize = fs::file_size(value.fsPath);
519 if (offset >= fileSize)
520 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600521 std::cerr << "Offset exceeds file size, OFFSET=" << offset
522 << " FILE_SIZE=" << fileSize << "\n";
vkaverap5b914c32019-06-30 22:23:54 -0500523 encode_read_file_resp(request->hdr.instance_id, PLDM_DATA_OUT_OF_RANGE,
524 length, responsePtr);
525 return response;
526 }
527
528 if (offset + length > fileSize)
529 {
530 length = fileSize - offset;
531 }
532
533 response.resize(response.size() + length);
534 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
535 auto fileDataPos = reinterpret_cast<char*>(responsePtr);
536 fileDataPos += sizeof(pldm_msg_hdr) + sizeof(uint8_t) + sizeof(length);
537
538 std::ifstream stream(value.fsPath, std::ios::in | std::ios::binary);
539 stream.seekg(offset);
540 stream.read(fileDataPos, length);
541
542 encode_read_file_resp(request->hdr.instance_id, PLDM_SUCCESS, length,
543 responsePtr);
544
545 return response;
546}
547
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600548Response Handler::writeFile(const pldm_msg* request, size_t payloadLength)
vkaverap5b914c32019-06-30 22:23:54 -0500549{
550 uint32_t fileHandle = 0;
551 uint32_t offset = 0;
552 uint32_t length = 0;
553 size_t fileDataOffset = 0;
554
555 Response response(sizeof(pldm_msg_hdr) + PLDM_WRITE_FILE_RESP_BYTES);
556 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
557
558 if (payloadLength < PLDM_WRITE_FILE_REQ_BYTES)
559 {
560 encode_write_file_resp(request->hdr.instance_id,
561 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
562 return response;
563 }
564
565 auto rc = decode_write_file_req(request, payloadLength, &fileHandle,
566 &offset, &length, &fileDataOffset);
567
568 if (rc)
569 {
570 encode_write_file_resp(request->hdr.instance_id, rc, 0, responsePtr);
571 return response;
572 }
573
574 using namespace pldm::filetable;
575 auto& table = buildFileTable(FILE_TABLE_JSON);
576 FileEntry value{};
577
578 try
579 {
580 value = table.at(fileHandle);
581 }
Patrick Williams51330582021-10-06 12:48:56 -0500582 catch (const std::exception& e)
vkaverap5b914c32019-06-30 22:23:54 -0500583 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600584 std::cerr << "File handle does not exist in the file table, HANDLE="
585 << fileHandle << "\n";
vkaverap5b914c32019-06-30 22:23:54 -0500586 encode_write_file_resp(request->hdr.instance_id,
587 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
588 return response;
589 }
590
591 if (!fs::exists(value.fsPath))
592 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600593 std::cerr << "File does not exist, HANDLE=" << fileHandle << "\n";
vkaverap5b914c32019-06-30 22:23:54 -0500594 encode_write_file_resp(request->hdr.instance_id,
595 PLDM_INVALID_FILE_HANDLE, 0, responsePtr);
596 return response;
597 }
598
599 auto fileSize = fs::file_size(value.fsPath);
600 if (offset >= fileSize)
601 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600602 std::cerr << "Offset exceeds file size, OFFSET=" << offset
603 << " FILE_SIZE=" << fileSize << "\n";
vkaverap5b914c32019-06-30 22:23:54 -0500604 encode_write_file_resp(request->hdr.instance_id, PLDM_DATA_OUT_OF_RANGE,
605 0, responsePtr);
606 return response;
607 }
608
609 auto fileDataPos =
610 reinterpret_cast<const char*>(request->payload) + fileDataOffset;
611
612 std::ofstream stream(value.fsPath,
613 std::ios::in | std::ios::out | std::ios::binary);
614 stream.seekp(offset);
615 stream.write(fileDataPos, length);
616
617 encode_write_file_resp(request->hdr.instance_id, PLDM_SUCCESS, length,
618 responsePtr);
619
620 return response;
621}
622
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600623Response rwFileByTypeIntoMemory(uint8_t cmd, const pldm_msg* request,
Sampa Misra69508502020-09-08 00:08:21 -0500624 size_t payloadLength,
625 oem_platform::Handler* oemPlatformHandler)
Sampa Misra854e61f2019-08-22 04:36:47 -0500626{
627 Response response(
628 sizeof(pldm_msg_hdr) + PLDM_RW_FILE_BY_TYPE_MEM_RESP_BYTES, 0);
629 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
630
631 if (payloadLength != PLDM_RW_FILE_BY_TYPE_MEM_REQ_BYTES)
632 {
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600633 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd,
634 PLDM_ERROR_INVALID_LENGTH, 0,
635 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500636 return response;
637 }
638
639 uint16_t fileType{};
640 uint32_t fileHandle{};
641 uint32_t offset{};
642 uint32_t length{};
643 uint64_t address{};
644 auto rc = decode_rw_file_by_type_memory_req(request, payloadLength,
645 &fileType, &fileHandle, &offset,
646 &length, &address);
647 if (rc != PLDM_SUCCESS)
648 {
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600649 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd, rc, 0,
650 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500651 return response;
652 }
653 if (length % dma::minSize)
654 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600655 std::cerr << "Length is not a multiple of DMA minSize, LENGTH="
656 << length << "\n";
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600657 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd,
Deepak Kodihalli3bf5c552020-04-20 06:16:01 -0500658 PLDM_ERROR_INVALID_LENGTH, 0,
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600659 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500660 return response;
661 }
662
663 std::unique_ptr<FileHandler> handler{};
664 try
665 {
666 handler = getHandlerByType(fileType, fileHandle);
667 }
668 catch (const InternalFailure& e)
669 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600670 std::cerr << "unknown file type, TYPE=" << fileType << "\n";
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600671 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd,
672 PLDM_INVALID_FILE_TYPE, 0,
673 responsePtr);
Sampa Misra854e61f2019-08-22 04:36:47 -0500674 return response;
675 }
676
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600677 rc = cmd == PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY
Sampa Misra69508502020-09-08 00:08:21 -0500678 ? handler->writeFromMemory(offset, length, address,
679 oemPlatformHandler)
680 : handler->readIntoMemory(offset, length, address,
681 oemPlatformHandler);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600682 encode_rw_file_by_type_memory_resp(request->hdr.instance_id, cmd, rc,
Sampa Misra854e61f2019-08-22 04:36:47 -0500683 length, responsePtr);
684 return response;
685}
686
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600687Response Handler::writeFileByTypeFromMemory(const pldm_msg* request,
688 size_t payloadLength)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600689{
690 return rwFileByTypeIntoMemory(PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY, request,
Sampa Misra69508502020-09-08 00:08:21 -0500691 payloadLength, oemPlatformHandler);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600692}
693
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600694Response Handler::readFileByTypeIntoMemory(const pldm_msg* request,
695 size_t payloadLength)
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600696{
697 return rwFileByTypeIntoMemory(PLDM_READ_FILE_BY_TYPE_INTO_MEMORY, request,
Sampa Misra69508502020-09-08 00:08:21 -0500698 payloadLength, oemPlatformHandler);
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600699}
700
Sampa Misra18967162020-01-14 02:31:41 -0600701Response Handler::writeFileByType(const pldm_msg* request, size_t payloadLength)
702{
703 Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_BY_TYPE_RESP_BYTES);
704 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
705
Sampa Misrad823cc02020-03-24 04:53:20 -0500706 if (payloadLength < PLDM_RW_FILE_BY_TYPE_REQ_BYTES)
Sampa Misra18967162020-01-14 02:31:41 -0600707 {
708 encode_rw_file_by_type_resp(request->hdr.instance_id,
709 PLDM_WRITE_FILE_BY_TYPE,
710 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
711 return response;
712 }
713 uint16_t fileType{};
714 uint32_t fileHandle{};
715 uint32_t offset{};
716 uint32_t length{};
717
718 auto rc = decode_rw_file_by_type_req(request, payloadLength, &fileType,
719 &fileHandle, &offset, &length);
720 if (rc != PLDM_SUCCESS)
721 {
722 encode_rw_file_by_type_resp(request->hdr.instance_id,
723 PLDM_WRITE_FILE_BY_TYPE, rc, 0,
724 responsePtr);
725 return response;
726 }
727
728 std::unique_ptr<FileHandler> handler{};
729 try
730 {
731 handler = getHandlerByType(fileType, fileHandle);
732 }
733 catch (const InternalFailure& e)
734 {
735 std::cerr << "unknown file type, TYPE=" << fileType << "\n";
736 encode_rw_file_by_type_resp(request->hdr.instance_id,
737 PLDM_WRITE_FILE_BY_TYPE,
738 PLDM_INVALID_FILE_TYPE, 0, responsePtr);
739 return response;
740 }
741
742 rc = handler->write(reinterpret_cast<const char*>(
Sampa Misrad823cc02020-03-24 04:53:20 -0500743 request->payload + PLDM_RW_FILE_BY_TYPE_REQ_BYTES),
Sampa Misra69508502020-09-08 00:08:21 -0500744 offset, length, oemPlatformHandler);
Sampa Misra18967162020-01-14 02:31:41 -0600745 encode_rw_file_by_type_resp(request->hdr.instance_id,
746 PLDM_WRITE_FILE_BY_TYPE, rc, length,
747 responsePtr);
748 return response;
749}
750
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600751Response Handler::readFileByType(const pldm_msg* request, size_t payloadLength)
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600752{
753 Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_BY_TYPE_RESP_BYTES);
754 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
755
756 if (payloadLength != PLDM_RW_FILE_BY_TYPE_REQ_BYTES)
757 {
758 encode_rw_file_by_type_resp(request->hdr.instance_id,
759 PLDM_READ_FILE_BY_TYPE,
760 PLDM_ERROR_INVALID_LENGTH, 0, responsePtr);
761 return response;
762 }
763 uint16_t fileType{};
764 uint32_t fileHandle{};
765 uint32_t offset{};
766 uint32_t length{};
767
768 auto rc = decode_rw_file_by_type_req(request, payloadLength, &fileType,
769 &fileHandle, &offset, &length);
770 if (rc != PLDM_SUCCESS)
771 {
772 encode_rw_file_by_type_resp(request->hdr.instance_id,
773 PLDM_READ_FILE_BY_TYPE, rc, 0, responsePtr);
774 return response;
775 }
776
777 std::unique_ptr<FileHandler> handler{};
778 try
779 {
780 handler = getHandlerByType(fileType, fileHandle);
781 }
782 catch (const InternalFailure& e)
783 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600784 std::cerr << "unknown file type, TYPE=" << fileType << "\n";
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600785 encode_rw_file_by_type_resp(request->hdr.instance_id,
786 PLDM_READ_FILE_BY_TYPE,
787 PLDM_INVALID_FILE_TYPE, 0, responsePtr);
788 return response;
789 }
790
Sampa Misra69508502020-09-08 00:08:21 -0500791 rc = handler->read(offset, length, response, oemPlatformHandler);
Deepak Kodihalli9a26f892019-12-10 06:48:06 -0600792 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
Deepak Kodihalli75e02f82019-11-20 02:51:05 -0600793 encode_rw_file_by_type_resp(request->hdr.instance_id,
794 PLDM_READ_FILE_BY_TYPE, rc, length,
795 responsePtr);
796 return response;
797}
798
Deepak Kodihalli2da1bfe2019-12-14 08:28:09 -0600799Response Handler::fileAck(const pldm_msg* request, size_t payloadLength)
800{
801 Response response(sizeof(pldm_msg_hdr) + PLDM_FILE_ACK_RESP_BYTES);
802 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
803
804 if (payloadLength != PLDM_FILE_ACK_REQ_BYTES)
805 {
806 encode_file_ack_resp(request->hdr.instance_id,
807 PLDM_ERROR_INVALID_LENGTH, responsePtr);
808 return response;
809 }
810 uint16_t fileType{};
811 uint32_t fileHandle{};
812 uint8_t fileStatus{};
813
814 auto rc = decode_file_ack_req(request, payloadLength, &fileType,
815 &fileHandle, &fileStatus);
816 if (rc != PLDM_SUCCESS)
817 {
818 encode_file_ack_resp(request->hdr.instance_id, rc, responsePtr);
819 return response;
820 }
821
822 std::unique_ptr<FileHandler> handler{};
823 try
824 {
825 handler = getHandlerByType(fileType, fileHandle);
826 }
Sampa Misra18967162020-01-14 02:31:41 -0600827
Deepak Kodihalli2da1bfe2019-12-14 08:28:09 -0600828 catch (const InternalFailure& e)
829 {
830 encode_file_ack_resp(request->hdr.instance_id, PLDM_INVALID_FILE_TYPE,
831 responsePtr);
832 return response;
833 }
834
835 rc = handler->fileAck(fileStatus);
836 encode_file_ack_resp(request->hdr.instance_id, rc, responsePtr);
837 return response;
838}
839
George Liu89aad712020-03-12 13:34:51 +0800840Response Handler::getAlertStatus(const pldm_msg* request, size_t payloadLength)
841{
842 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_ALERT_STATUS_RESP_BYTES);
843 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
844 if (payloadLength != PLDM_GET_ALERT_STATUS_REQ_BYTES)
845 {
846 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
847 }
848
849 uint8_t versionId{};
850
851 auto rc = decode_get_alert_status_req(request, payloadLength, &versionId);
852 if (rc != PLDM_SUCCESS)
853 {
854 return CmdHandler::ccOnlyResponse(request, rc);
855 }
856
857 if (versionId != 0)
858 {
859 return CmdHandler::ccOnlyResponse(request,
860 PLDM_HOST_UNSUPPORTED_FORMAT_VERSION);
861 }
862
863 constexpr uint32_t rackEntry = 0xFF000030;
864 constexpr uint32_t priCecNode = 0x00008030;
865 rc = encode_get_alert_status_resp(request->hdr.instance_id, PLDM_SUCCESS,
866 rackEntry, priCecNode, responsePtr,
867 PLDM_GET_ALERT_STATUS_RESP_BYTES);
868 if (rc != PLDM_SUCCESS)
869 {
870 return CmdHandler::ccOnlyResponse(request, rc);
871 }
872
873 return response;
874}
875
Sampa Misra18967162020-01-14 02:31:41 -0600876Response Handler::newFileAvailable(const pldm_msg* request,
877 size_t payloadLength)
878{
879 Response response(sizeof(pldm_msg_hdr) + PLDM_NEW_FILE_RESP_BYTES);
880
881 if (payloadLength != PLDM_NEW_FILE_REQ_BYTES)
882 {
883 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
884 }
885 uint16_t fileType{};
886 uint32_t fileHandle{};
887 uint64_t length{};
888
889 auto rc = decode_new_file_req(request, payloadLength, &fileType,
890 &fileHandle, &length);
891
892 if (rc != PLDM_SUCCESS)
893 {
894 return CmdHandler::ccOnlyResponse(request, rc);
895 }
896
897 std::unique_ptr<FileHandler> handler{};
898 try
899 {
900 handler = getHandlerByType(fileType, fileHandle);
901 }
902 catch (const InternalFailure& e)
903 {
904 std::cerr << "unknown file type, TYPE=" << fileType << "\n";
905 return CmdHandler::ccOnlyResponse(request, PLDM_INVALID_FILE_TYPE);
906 }
907
908 rc = handler->newFileAvailable(length);
909 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
910 encode_new_file_resp(request->hdr.instance_id, rc, responsePtr);
911 return response;
912}
913
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600914} // namespace oem_ibm
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530915} // namespace responder
916} // namespace pldm