blob: 0ee4ed6700b79032b0b6c903b6ad7626704024fc [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
142/** @brief Handler for GetFileTable command
143 *
144 * @param[in] request - pointer to PLDM request payload
145 * @param[in] payloadLength - length of the message payload
146 *
147 * @return PLDM response message
148 */
149Response getFileTable(const pldm_msg* request, size_t payloadLength);
vkaverap5b914c32019-06-30 22:23:54 -0500150
151/** @brief Handler for readFile command
152 *
153 * @param[in] request - PLDM request msg
154 * @param[in] payloadLength - length of the message payload
155 *
156 * @return PLDM response message
157 */
158Response readFile(const pldm_msg* request, size_t payloadLength);
159
160/** @brief Handler for writeFile command
161 *
162 * @param[in] request - PLDM request msg
163 * @param[in] payloadLength - length of the message payload
164 *
165 * @return PLDM response message
166 */
167Response writeFile(const pldm_msg* request, size_t payloadLength);
Jinu Joy Thomas7f57f442019-06-13 20:38:49 +0530168} // namespace responder
169} // namespace pldm