blob: b67f0f947737e6af0260aadcb32fd9f24204ea45 [file] [log] [blame]
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +05301#pragma once
2
3#include <stdint.h>
4#include <unistd.h>
5
6#include <filesystem>
Priyanga8b976652019-06-27 11:30:33 -05007#include <vector>
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +05308
9#include "libpldm/base.h"
Deepak Kodihallida87ec62019-07-02 01:01:16 -050010#include "oem/ibm/libpldm/file_io.h"
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053011
12namespace pldm
13{
14
15namespace responder
16{
17
Jinu Joy Thomasf666db12019-05-29 05:22:31 -050018namespace oem_ibm
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053019{
Jinu Joy Thomasf666db12019-05-29 05:22:31 -050020/** @brief Register handlers for command from the platform spec
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053021 */
Jinu Joy Thomasf666db12019-05-29 05:22:31 -050022void registerHandlers();
23} // namespace oem_ibm
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053024
Jinu Joy Thomasf666db12019-05-29 05:22:31 -050025using Response = std::vector<uint8_t>;
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053026
27namespace dma
28{
29
30// The minimum data size of dma transfer in bytes
31constexpr uint32_t minSize = 16;
32
33// 16MB - 4096B (16773120 bytes) is the maximum data size of DMA transfer
34constexpr size_t maxSize = (16 * 1024 * 1024) - 4096;
35
36namespace fs = std::filesystem;
37
38/**
39 * @class DMA
40 *
41 * Expose API to initiate transfer of data by DMA
42 *
43 * This class only exposes the public API transferDataHost to transfer data
44 * between BMC and host using DMA. This allows for mocking the transferDataHost
45 * for unit testing purposes.
46 */
47class DMA
48{
49 public:
50 /** @brief API to transfer data between BMC and host using DMA
51 *
52 * @param[in] path - pathname of the file to transfer data from or to
53 * @param[in] offset - offset in the file
54 * @param[in] length - length of the data to transfer
55 * @param[in] address - DMA address on the host
56 * @param[in] upstream - indicates direction of the transfer; true indicates
57 * transfer to the host
58 *
59 * @return returns 0 on success, negative errno on failure
60 */
61 int transferDataHost(const fs::path& path, uint32_t offset, uint32_t length,
62 uint64_t address, bool upstream);
63};
64
65/** @brief Transfer the data between BMC and host using DMA.
66 *
67 * There is a max size for each DMA operation, transferAll API abstracts this
68 * and the requested length is broken down into multiple DMA operations if the
69 * length exceed max size.
70 *
71 * @tparam[in] T - DMA interface type
72 * @param[in] intf - interface passed to invoke DMA transfer
73 * @param[in] command - PLDM command
74 * @param[in] path - pathname of the file to transfer data from or to
75 * @param[in] offset - offset in the file
76 * @param[in] length - length of the data to transfer
77 * @param[in] address - DMA address on the host
78 * @param[in] upstream - indicates direction of the transfer; true indicates
79 * transfer to the host
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +053080 * @param[in] instanceId - Message's instance id
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053081 * @return PLDM response message
82 */
83
84template <class DMAInterface>
85Response transferAll(DMAInterface* intf, uint8_t command, fs::path& path,
86 uint32_t offset, uint32_t length, uint64_t address,
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +053087 bool upstream, uint8_t instanceId)
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +053088{
89 uint32_t origLength = length;
90 Response response(sizeof(pldm_msg_hdr) + PLDM_RW_FILE_MEM_RESP_BYTES, 0);
91 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
92
93 while (length > dma::maxSize)
94 {
95 auto rc = intf->transferDataHost(path, offset, dma::maxSize, address,
96 upstream);
97 if (rc < 0)
98 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +053099 encode_rw_file_memory_resp(instanceId, command, PLDM_ERROR, 0,
100 responsePtr);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530101 return response;
102 }
103
104 offset += dma::maxSize;
105 length -= dma::maxSize;
106 address += dma::maxSize;
107 }
108
109 auto rc = intf->transferDataHost(path, offset, length, address, upstream);
110 if (rc < 0)
111 {
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530112 encode_rw_file_memory_resp(instanceId, command, PLDM_ERROR, 0,
113 responsePtr);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530114 return response;
115 }
116
Jinu Joy Thomas33705fd2019-07-02 16:03:05 +0530117 encode_rw_file_memory_resp(instanceId, command, PLDM_SUCCESS, origLength,
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530118 responsePtr);
119 return response;
120}
121
122} // namespace dma
123
124/** @brief Handler for readFileIntoMemory command
125 *
126 * @param[in] request - pointer to PLDM request payload
Jinu Joy Thomasf666db12019-05-29 05:22:31 -0500127 * @param[in] payloadLength - length of the message
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530128 *
129 * @return PLDM response message
130 */
Jinu Joy Thomasf666db12019-05-29 05:22:31 -0500131Response readFileIntoMemory(const pldm_msg* request, size_t payloadLength);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530132
133/** @brief Handler for writeFileIntoMemory command
134 *
135 * @param[in] request - pointer to PLDM request payload
Jinu Joy Thomasf666db12019-05-29 05:22:31 -0500136 * @param[in] payloadLength - length of the message
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530137 *
138 * @return PLDM response message
139 */
Jinu Joy Thomasf666db12019-05-29 05:22:31 -0500140Response writeFileFromMemory(const pldm_msg* request, size_t payloadLength);
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530141
Sampa Misra854e61f2019-08-22 04:36:47 -0500142/** @brief Handler for writeFileByTypeFromMemory command
143 *
144 * @param[in] request - pointer to PLDM request payload
145 * @param[in] payloadLength - length of the message
146 *
147 * @return PLDM response message
148 */
149
150Response writeFileByTypeFromMemory(const pldm_msg* request,
151 size_t payloadLength);
152
Deepak Kodihallif6d3a832019-11-19 07:00:29 -0600153/** @brief Handler for readFileByTypeIntoMemory command
154 *
155 * @param[in] request - pointer to PLDM request payload
156 * @param[in] payloadLength - length of the message
157 *
158 * @return PLDM response message
159 */
160Response readFileByTypeIntoMemory(const pldm_msg* request,
161 size_t payloadLength);
162
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530163/** @brief Handler for GetFileTable command
164 *
165 * @param[in] request - pointer to PLDM request payload
166 * @param[in] payloadLength - length of the message payload
167 *
168 * @return PLDM response message
169 */
170Response getFileTable(const pldm_msg* request, size_t payloadLength);
vkaverap5b914c32019-06-30 22:23:54 -0500171
172/** @brief Handler for readFile command
173 *
174 * @param[in] request - PLDM request msg
175 * @param[in] payloadLength - length of the message payload
176 *
177 * @return PLDM response message
178 */
179Response readFile(const pldm_msg* request, size_t payloadLength);
180
181/** @brief Handler for writeFile command
182 *
183 * @param[in] request - PLDM request msg
184 * @param[in] payloadLength - length of the message payload
185 *
186 * @return PLDM response message
187 */
188Response writeFile(const pldm_msg* request, size_t payloadLength);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530189} // namespace responder
190} // namespace pldm