blob: dcb6fd6802fc5b50c66c204d83af18357972d58c [file] [log] [blame]
Sagar Srinivasa6a8ccd2021-04-01 07:58:33 -05001#include "config.h"
2
Deepak Kodihalli1b24f972019-02-01 04:09:13 -06003#include "libpldm/base.h"
4
George Liu6492f522020-06-16 10:34:05 +08005#include "libpldm/bios.h"
6#include "libpldm/fru.h"
7#include "libpldm/platform.h"
Sagar Srinivasa6a8ccd2021-04-01 07:58:33 -05008#include "libpldm/requester/pldm.h"
George Liu6492f522020-06-16 10:34:05 +08009
Deepak Kodihalli1b24f972019-02-01 04:09:13 -060010#include "base.hpp"
Sagar Srinivasa6a8ccd2021-04-01 07:58:33 -050011#include "common/utils.hpp"
12#include "libpldmresponder/pdr.hpp"
Deepak Kodihalli1b24f972019-02-01 04:09:13 -060013
14#include <array>
Sampa Misra432e1872019-02-13 03:49:43 -060015#include <cstring>
Sagar Srinivasa6a8ccd2021-04-01 07:58:33 -050016#include <iostream>
Deepak Kodihalli1b24f972019-02-01 04:09:13 -060017#include <map>
18#include <stdexcept>
19#include <vector>
20
Sridevi Ramesh45e52542020-04-03 07:54:18 -050021#ifdef OEM_IBM
22#include "libpldm/file_io.h"
23#include "libpldm/host.h"
24#endif
25
Deepak Kodihalli1b24f972019-02-01 04:09:13 -060026namespace pldm
27{
Deepak Kodihallibc669f12019-11-28 08:52:07 -060028
29using Type = uint8_t;
30
Deepak Kodihalli1b24f972019-02-01 04:09:13 -060031namespace responder
32{
33
34using Cmd = std::vector<uint8_t>;
35
36static const std::map<Type, Cmd> capabilities{
Zahed Hossain5e4e3832019-07-05 03:43:18 -050037 {PLDM_BASE,
John Wang5c4f80d2019-07-29 11:12:18 +080038 {PLDM_GET_TID, PLDM_GET_PLDM_VERSION, PLDM_GET_PLDM_TYPES,
39 PLDM_GET_PLDM_COMMANDS}},
Sridevi Ramesh8fb11c92021-06-08 08:45:01 -050040 {PLDM_PLATFORM,
41 {PLDM_GET_PDR, PLDM_SET_STATE_EFFECTER_STATES, PLDM_SET_EVENT_RECEIVER,
42 PLDM_GET_SENSOR_READING, PLDM_GET_STATE_SENSOR_READINGS,
43 PLDM_SET_NUMERIC_EFFECTER_VALUE, PLDM_GET_NUMERIC_EFFECTER_VALUE,
44 PLDM_PLATFORM_EVENT_MESSAGE}},
John Wang8721ed62019-12-05 14:44:43 +080045 {PLDM_BIOS,
Sridevi Rameshf58d9a52020-02-14 00:30:58 -060046 {PLDM_GET_DATE_TIME, PLDM_SET_DATE_TIME, PLDM_GET_BIOS_TABLE,
Xiaochao Mad3cf57e2019-12-31 14:22:38 +080047 PLDM_GET_BIOS_ATTRIBUTE_CURRENT_VALUE_BY_HANDLE,
Sridevi Ramesh8fb11c92021-06-08 08:45:01 -050048 PLDM_SET_BIOS_ATTRIBUTE_CURRENT_VALUE, PLDM_SET_BIOS_TABLE}},
John Wang5bdde3a2020-06-16 15:02:33 +080049 {PLDM_FRU,
50 {PLDM_GET_FRU_RECORD_TABLE_METADATA, PLDM_GET_FRU_RECORD_TABLE,
51 PLDM_GET_FRU_RECORD_BY_OPTION}},
Sridevi Ramesh45e52542020-04-03 07:54:18 -050052#ifdef OEM_IBM
53 {PLDM_OEM,
54 {PLDM_HOST_GET_ALERT_STATUS, PLDM_GET_FILE_TABLE, PLDM_READ_FILE,
55 PLDM_WRITE_FILE, PLDM_READ_FILE_INTO_MEMORY, PLDM_WRITE_FILE_FROM_MEMORY,
56 PLDM_READ_FILE_BY_TYPE_INTO_MEMORY, PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY,
57 PLDM_NEW_FILE_AVAILABLE, PLDM_READ_FILE_BY_TYPE, PLDM_WRITE_FILE_BY_TYPE,
58 PLDM_FILE_ACK}},
59#endif
60};
Deepak Kodihalli1b24f972019-02-01 04:09:13 -060061
Deepak Kodihalli97e0bd52019-02-21 03:54:22 -060062static const std::map<Type, ver32_t> versions{
Sampa Misra432e1872019-02-13 03:49:43 -060063 {PLDM_BASE, {0xF1, 0xF0, 0xF0, 0x00}},
Tom Joseph0bead972020-01-28 10:54:03 +053064 {PLDM_PLATFORM, {0xF1, 0xF2, 0xF0, 0x00}},
Zahed Hossain74c1c1e2019-06-18 02:13:48 -050065 {PLDM_BIOS, {0xF1, 0xF0, 0xF0, 0x00}},
Deepak Kodihalliec482972019-11-26 07:57:10 -060066 {PLDM_FRU, {0xF1, 0xF0, 0xF0, 0x00}},
Sridevi Ramesh45e52542020-04-03 07:54:18 -050067#ifdef OEM_IBM
68 {PLDM_OEM, {0xF1, 0xF0, 0xF0, 0x00}},
69#endif
Sampa Misra432e1872019-02-13 03:49:43 -060070};
71
Jinu Joy Thomasf666db12019-05-29 05:22:31 -050072namespace base
73{
74
Deepak Kodihallibc669f12019-11-28 08:52:07 -060075Response Handler::getPLDMTypes(const pldm_msg* request,
76 size_t /*payloadLength*/)
Deepak Kodihalli1b24f972019-02-01 04:09:13 -060077{
78 // DSP0240 has this as a bitfield8[N], where N = 0 to 7
Deepak Kodihalli97e0bd52019-02-21 03:54:22 -060079 std::array<bitfield8_t, 8> types{};
Deepak Kodihalli1b24f972019-02-01 04:09:13 -060080 for (const auto& type : capabilities)
81 {
82 auto index = type.first / 8;
83 // <Type Number> = <Array Index> * 8 + <bit position>
84 auto bit = type.first - (index * 8);
Deepak Kodihalli97e0bd52019-02-21 03:54:22 -060085 types[index].byte |= 1 << bit;
Deepak Kodihalli1b24f972019-02-01 04:09:13 -060086 }
87
vkaverapa6575b82019-04-03 05:33:52 -050088 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_TYPES_RESP_BYTES, 0);
89 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
George Liufb8611d2019-12-06 10:14:15 +080090 auto rc = encode_get_types_resp(request->hdr.instance_id, PLDM_SUCCESS,
91 types.data(), responsePtr);
92 if (rc != PLDM_SUCCESS)
93 {
94 return CmdHandler::ccOnlyResponse(request, rc);
95 }
vkaverapa6575b82019-04-03 05:33:52 -050096
97 return response;
Deepak Kodihalli1b24f972019-02-01 04:09:13 -060098}
99
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600100Response Handler::getPLDMCommands(const pldm_msg* request, size_t payloadLength)
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600101{
Deepak Kodihalli97e0bd52019-02-21 03:54:22 -0600102 ver32_t version{};
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600103 Type type;
104
vkaverapa6575b82019-04-03 05:33:52 -0500105 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_COMMANDS_RESP_BYTES, 0);
106 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600107
Zahed Hossain223a73d2019-07-04 12:46:18 -0500108 auto rc = decode_get_commands_req(request, payloadLength, &type, &version);
vkaverapa6575b82019-04-03 05:33:52 -0500109
110 if (rc != PLDM_SUCCESS)
111 {
George Liufb8611d2019-12-06 10:14:15 +0800112 return CmdHandler::ccOnlyResponse(request, rc);
vkaverapa6575b82019-04-03 05:33:52 -0500113 }
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600114
115 // DSP0240 has this as a bitfield8[N], where N = 0 to 31
Deepak Kodihalli97e0bd52019-02-21 03:54:22 -0600116 std::array<bitfield8_t, 32> cmds{};
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600117 if (capabilities.find(type) == capabilities.end())
118 {
George Liufb8611d2019-12-06 10:14:15 +0800119 return CmdHandler::ccOnlyResponse(request,
120 PLDM_ERROR_INVALID_PLDM_TYPE);
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600121 }
122
123 for (const auto& cmd : capabilities.at(type))
124 {
125 auto index = cmd / 8;
126 // <Type Number> = <Array Index> * 8 + <bit position>
127 auto bit = cmd - (index * 8);
Deepak Kodihalli97e0bd52019-02-21 03:54:22 -0600128 cmds[index].byte |= 1 << bit;
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600129 }
130
George Liufb8611d2019-12-06 10:14:15 +0800131 rc = encode_get_commands_resp(request->hdr.instance_id, PLDM_SUCCESS,
132 cmds.data(), responsePtr);
133 if (rc != PLDM_SUCCESS)
134 {
135 return ccOnlyResponse(request, rc);
136 }
vkaverapa6575b82019-04-03 05:33:52 -0500137
138 return response;
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600139}
140
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600141Response Handler::getPLDMVersion(const pldm_msg* request, size_t payloadLength)
Sampa Misra432e1872019-02-13 03:49:43 -0600142{
143 uint32_t transferHandle;
144 Type type;
145 uint8_t transferFlag;
146
vkaverapa6575b82019-04-03 05:33:52 -0500147 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_VERSION_RESP_BYTES, 0);
148 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
Sampa Misra432e1872019-02-13 03:49:43 -0600149
Zahed Hossain223a73d2019-07-04 12:46:18 -0500150 uint8_t rc = decode_get_version_req(request, payloadLength, &transferHandle,
151 &transferFlag, &type);
vkaverapa6575b82019-04-03 05:33:52 -0500152
153 if (rc != PLDM_SUCCESS)
154 {
George Liufb8611d2019-12-06 10:14:15 +0800155 return CmdHandler::ccOnlyResponse(request, rc);
vkaverapa6575b82019-04-03 05:33:52 -0500156 }
Sampa Misra432e1872019-02-13 03:49:43 -0600157
Deepak Kodihalli97e0bd52019-02-21 03:54:22 -0600158 ver32_t version{};
Sampa Misra432e1872019-02-13 03:49:43 -0600159 auto search = versions.find(type);
160
161 if (search == versions.end())
162 {
George Liufb8611d2019-12-06 10:14:15 +0800163 return CmdHandler::ccOnlyResponse(request,
164 PLDM_ERROR_INVALID_PLDM_TYPE);
Sampa Misra432e1872019-02-13 03:49:43 -0600165 }
166
167 memcpy(&version, &(search->second), sizeof(version));
George Liufb8611d2019-12-06 10:14:15 +0800168 rc = encode_get_version_resp(request->hdr.instance_id, PLDM_SUCCESS, 0,
169 PLDM_START_AND_END, &version,
170 sizeof(pldm_version), responsePtr);
171 if (rc != PLDM_SUCCESS)
172 {
173 return ccOnlyResponse(request, rc);
174 }
vkaverapa6575b82019-04-03 05:33:52 -0500175
176 return response;
Sampa Misra432e1872019-02-13 03:49:43 -0600177}
178
Sagar Srinivasa6a8ccd2021-04-01 07:58:33 -0500179void Handler::processSetEventReceiver(
180 sdeventplus::source::EventBase& /*source */)
181{
182 survEvent.reset();
183 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
184 PLDM_SET_EVENT_RECEIVER_REQ_BYTES);
185 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
186 auto instanceId = requester.getInstanceId(eid);
187 uint8_t eventMessageGlobalEnable =
188 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE;
189 uint8_t transportProtocolType = PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP;
190 uint8_t eventReceiverAddressInfo = pldm::responder::pdr::BmcMctpEid;
191 uint16_t heartbeatTimer = HEARTBEAT_TIMEOUT;
192
193 auto rc = encode_set_event_receiver_req(
194 instanceId, eventMessageGlobalEnable, transportProtocolType,
195 eventReceiverAddressInfo, heartbeatTimer, request);
196 if (rc != PLDM_SUCCESS)
197 {
198 requester.markFree(eid, instanceId);
199 std::cerr << "Failed to encode_set_event_receiver_req, rc = "
200 << std::hex << std::showbase << rc << std::endl;
201 return;
202 }
203
204 auto processSetEventReceiverResponse = [](mctp_eid_t /*eid*/,
205 const pldm_msg* response,
206 size_t respMsgLen) {
207 if (response == nullptr || !respMsgLen)
208 {
209 std::cerr << "Failed to receive response for "
210 "setEventReceiver command \n";
211 return;
212 }
213
214 uint8_t completionCode{};
215 auto rc = decode_set_event_receiver_resp(response, respMsgLen,
216 &completionCode);
217 if (rc || completionCode)
218 {
219 std::cerr << "Failed to decode setEventReceiver command response,"
220 << " rc=" << rc << "cc=" << (uint8_t)completionCode
221 << "\n";
222 pldm::utils::reportError(
223 "xyz.openbmc_project.bmc.pldm.InternalFailure");
224 }
225 };
226 rc = handler->registerRequest(
227 eid, instanceId, PLDM_PLATFORM, PLDM_SET_EVENT_RECEIVER,
228 std::move(requestMsg), std::move(processSetEventReceiverResponse));
229
230 if (rc != PLDM_SUCCESS)
231 {
232 std::cerr << "Failed to send the setEventReceiver request"
233 << "\n";
234 }
Sagar Srinivas7f760b32021-05-12 07:46:56 -0500235
236 if (oemPlatformHandler)
237 {
238 oemPlatformHandler->countSetEventReceiver();
239 oemPlatformHandler->checkAndDisableWatchDog();
240 }
Sagar Srinivasa6a8ccd2021-04-01 07:58:33 -0500241}
242
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600243Response Handler::getTID(const pldm_msg* request, size_t /*payloadLength*/)
John Wang5c4f80d2019-07-29 11:12:18 +0800244{
245 // assigned 1 to the bmc as the PLDM terminus
246 uint8_t tid = 1;
247
248 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_TID_RESP_BYTES, 0);
249 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
George Liufb8611d2019-12-06 10:14:15 +0800250 auto rc = encode_get_tid_resp(request->hdr.instance_id, PLDM_SUCCESS, tid,
251 responsePtr);
252 if (rc != PLDM_SUCCESS)
253 {
254 return ccOnlyResponse(request, rc);
255 }
John Wang5c4f80d2019-07-29 11:12:18 +0800256
Sagar Srinivasa6a8ccd2021-04-01 07:58:33 -0500257 survEvent = std::make_unique<sdeventplus::source::Defer>(
258 event, std::bind_front(&Handler::processSetEventReceiver, this));
259
John Wang5c4f80d2019-07-29 11:12:18 +0800260 return response;
261}
262
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600263} // namespace base
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600264} // namespace responder
265} // namespace pldm