blob: e5030ec2fc5a2f39de675b438ca81faf95197f86 [file] [log] [blame]
Sagar Srinivasa6a8ccd2021-04-01 07:58:33 -05001#include "config.h"
2
Deepak Kodihalli1b24f972019-02-01 04:09:13 -06003#include "base.hpp"
George Liuc453e162022-12-21 17:16:23 +08004
Sagar Srinivasa6a8ccd2021-04-01 07:58:33 -05005#include "common/utils.hpp"
6#include "libpldmresponder/pdr.hpp"
Deepak Kodihalli1b24f972019-02-01 04:09:13 -06007
George Liuc453e162022-12-21 17:16:23 +08008#include <libpldm/base.h>
9#include <libpldm/bios.h>
10#include <libpldm/fru.h>
11#include <libpldm/platform.h>
12#include <libpldm/pldm.h>
13
Deepak Kodihalli1b24f972019-02-01 04:09:13 -060014#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
George Liuc453e162022-12-21 17:16:23 +080022#include <libpldm/file_io.h>
23#include <libpldm/host.h>
Sridevi Ramesh45e52542020-04-03 07:54:18 -050024#endif
25
Deepak Kodihalli1b24f972019-02-01 04:09:13 -060026namespace pldm
27{
Deepak Kodihallibc669f12019-11-28 08:52:07 -060028using Type = uint8_t;
29
Deepak Kodihalli1b24f972019-02-01 04:09:13 -060030namespace responder
31{
Deepak Kodihalli1b24f972019-02-01 04:09:13 -060032using Cmd = std::vector<uint8_t>;
33
34static const std::map<Type, Cmd> capabilities{
Zahed Hossain5e4e3832019-07-05 03:43:18 -050035 {PLDM_BASE,
John Wang5c4f80d2019-07-29 11:12:18 +080036 {PLDM_GET_TID, PLDM_GET_PLDM_VERSION, PLDM_GET_PLDM_TYPES,
37 PLDM_GET_PLDM_COMMANDS}},
Sridevi Ramesh8fb11c92021-06-08 08:45:01 -050038 {PLDM_PLATFORM,
39 {PLDM_GET_PDR, PLDM_SET_STATE_EFFECTER_STATES, PLDM_SET_EVENT_RECEIVER,
40 PLDM_GET_SENSOR_READING, PLDM_GET_STATE_SENSOR_READINGS,
41 PLDM_SET_NUMERIC_EFFECTER_VALUE, PLDM_GET_NUMERIC_EFFECTER_VALUE,
42 PLDM_PLATFORM_EVENT_MESSAGE}},
John Wang8721ed62019-12-05 14:44:43 +080043 {PLDM_BIOS,
Sridevi Rameshf58d9a52020-02-14 00:30:58 -060044 {PLDM_GET_DATE_TIME, PLDM_SET_DATE_TIME, PLDM_GET_BIOS_TABLE,
Xiaochao Mad3cf57e2019-12-31 14:22:38 +080045 PLDM_GET_BIOS_ATTRIBUTE_CURRENT_VALUE_BY_HANDLE,
Sridevi Ramesh8fb11c92021-06-08 08:45:01 -050046 PLDM_SET_BIOS_ATTRIBUTE_CURRENT_VALUE, PLDM_SET_BIOS_TABLE}},
John Wang5bdde3a2020-06-16 15:02:33 +080047 {PLDM_FRU,
48 {PLDM_GET_FRU_RECORD_TABLE_METADATA, PLDM_GET_FRU_RECORD_TABLE,
49 PLDM_GET_FRU_RECORD_BY_OPTION}},
Sridevi Ramesh45e52542020-04-03 07:54:18 -050050#ifdef OEM_IBM
51 {PLDM_OEM,
52 {PLDM_HOST_GET_ALERT_STATUS, PLDM_GET_FILE_TABLE, PLDM_READ_FILE,
53 PLDM_WRITE_FILE, PLDM_READ_FILE_INTO_MEMORY, PLDM_WRITE_FILE_FROM_MEMORY,
54 PLDM_READ_FILE_BY_TYPE_INTO_MEMORY, PLDM_WRITE_FILE_BY_TYPE_FROM_MEMORY,
55 PLDM_NEW_FILE_AVAILABLE, PLDM_READ_FILE_BY_TYPE, PLDM_WRITE_FILE_BY_TYPE,
56 PLDM_FILE_ACK}},
57#endif
58};
Deepak Kodihalli1b24f972019-02-01 04:09:13 -060059
Deepak Kodihalli97e0bd52019-02-21 03:54:22 -060060static const std::map<Type, ver32_t> versions{
Manojkiran Edacb454672022-06-29 11:05:42 +053061 {PLDM_BASE, {0x00, 0xf0, 0xf0, 0xf1}},
62 {PLDM_PLATFORM, {0x00, 0xf0, 0xf2, 0xf1}},
63 {PLDM_BIOS, {0x00, 0xf0, 0xf0, 0xf1}},
64 {PLDM_FRU, {0x00, 0xf0, 0xf0, 0xf1}},
Sridevi Ramesh45e52542020-04-03 07:54:18 -050065#ifdef OEM_IBM
Manojkiran Edacb454672022-06-29 11:05:42 +053066 {PLDM_OEM, {0x00, 0xf0, 0xf0, 0xf1}},
Sridevi Ramesh45e52542020-04-03 07:54:18 -050067#endif
Sampa Misra432e1872019-02-13 03:49:43 -060068};
69
Jinu Joy Thomasf666db12019-05-29 05:22:31 -050070namespace base
71{
Deepak Kodihallibc669f12019-11-28 08:52:07 -060072Response Handler::getPLDMTypes(const pldm_msg* request,
73 size_t /*payloadLength*/)
Deepak Kodihalli1b24f972019-02-01 04:09:13 -060074{
75 // DSP0240 has this as a bitfield8[N], where N = 0 to 7
Deepak Kodihalli97e0bd52019-02-21 03:54:22 -060076 std::array<bitfield8_t, 8> types{};
Deepak Kodihalli1b24f972019-02-01 04:09:13 -060077 for (const auto& type : capabilities)
78 {
79 auto index = type.first / 8;
80 // <Type Number> = <Array Index> * 8 + <bit position>
81 auto bit = type.first - (index * 8);
Deepak Kodihalli97e0bd52019-02-21 03:54:22 -060082 types[index].byte |= 1 << bit;
Deepak Kodihalli1b24f972019-02-01 04:09:13 -060083 }
84
vkaverapa6575b82019-04-03 05:33:52 -050085 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_TYPES_RESP_BYTES, 0);
86 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
George Liufb8611d2019-12-06 10:14:15 +080087 auto rc = encode_get_types_resp(request->hdr.instance_id, PLDM_SUCCESS,
88 types.data(), responsePtr);
89 if (rc != PLDM_SUCCESS)
90 {
91 return CmdHandler::ccOnlyResponse(request, rc);
92 }
vkaverapa6575b82019-04-03 05:33:52 -050093
94 return response;
Deepak Kodihalli1b24f972019-02-01 04:09:13 -060095}
96
Deepak Kodihallibc669f12019-11-28 08:52:07 -060097Response Handler::getPLDMCommands(const pldm_msg* request, size_t payloadLength)
Deepak Kodihalli1b24f972019-02-01 04:09:13 -060098{
Deepak Kodihalli97e0bd52019-02-21 03:54:22 -060099 ver32_t version{};
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600100 Type type;
101
vkaverapa6575b82019-04-03 05:33:52 -0500102 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_COMMANDS_RESP_BYTES, 0);
103 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600104
Zahed Hossain223a73d2019-07-04 12:46:18 -0500105 auto rc = decode_get_commands_req(request, payloadLength, &type, &version);
vkaverapa6575b82019-04-03 05:33:52 -0500106
107 if (rc != PLDM_SUCCESS)
108 {
George Liufb8611d2019-12-06 10:14:15 +0800109 return CmdHandler::ccOnlyResponse(request, rc);
vkaverapa6575b82019-04-03 05:33:52 -0500110 }
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600111
112 // DSP0240 has this as a bitfield8[N], where N = 0 to 31
Deepak Kodihalli97e0bd52019-02-21 03:54:22 -0600113 std::array<bitfield8_t, 32> cmds{};
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600114 if (capabilities.find(type) == capabilities.end())
115 {
George Liufb8611d2019-12-06 10:14:15 +0800116 return CmdHandler::ccOnlyResponse(request,
117 PLDM_ERROR_INVALID_PLDM_TYPE);
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600118 }
119
120 for (const auto& cmd : capabilities.at(type))
121 {
122 auto index = cmd / 8;
123 // <Type Number> = <Array Index> * 8 + <bit position>
124 auto bit = cmd - (index * 8);
Deepak Kodihalli97e0bd52019-02-21 03:54:22 -0600125 cmds[index].byte |= 1 << bit;
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600126 }
127
George Liufb8611d2019-12-06 10:14:15 +0800128 rc = encode_get_commands_resp(request->hdr.instance_id, PLDM_SUCCESS,
129 cmds.data(), responsePtr);
130 if (rc != PLDM_SUCCESS)
131 {
132 return ccOnlyResponse(request, rc);
133 }
vkaverapa6575b82019-04-03 05:33:52 -0500134
135 return response;
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600136}
137
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600138Response Handler::getPLDMVersion(const pldm_msg* request, size_t payloadLength)
Sampa Misra432e1872019-02-13 03:49:43 -0600139{
140 uint32_t transferHandle;
141 Type type;
142 uint8_t transferFlag;
143
vkaverapa6575b82019-04-03 05:33:52 -0500144 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_VERSION_RESP_BYTES, 0);
145 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
Sampa Misra432e1872019-02-13 03:49:43 -0600146
Zahed Hossain223a73d2019-07-04 12:46:18 -0500147 uint8_t rc = decode_get_version_req(request, payloadLength, &transferHandle,
148 &transferFlag, &type);
vkaverapa6575b82019-04-03 05:33:52 -0500149
150 if (rc != PLDM_SUCCESS)
151 {
George Liufb8611d2019-12-06 10:14:15 +0800152 return CmdHandler::ccOnlyResponse(request, rc);
vkaverapa6575b82019-04-03 05:33:52 -0500153 }
Sampa Misra432e1872019-02-13 03:49:43 -0600154
Deepak Kodihalli97e0bd52019-02-21 03:54:22 -0600155 ver32_t version{};
Sampa Misra432e1872019-02-13 03:49:43 -0600156 auto search = versions.find(type);
157
158 if (search == versions.end())
159 {
George Liufb8611d2019-12-06 10:14:15 +0800160 return CmdHandler::ccOnlyResponse(request,
161 PLDM_ERROR_INVALID_PLDM_TYPE);
Sampa Misra432e1872019-02-13 03:49:43 -0600162 }
163
164 memcpy(&version, &(search->second), sizeof(version));
George Liufb8611d2019-12-06 10:14:15 +0800165 rc = encode_get_version_resp(request->hdr.instance_id, PLDM_SUCCESS, 0,
166 PLDM_START_AND_END, &version,
167 sizeof(pldm_version), responsePtr);
168 if (rc != PLDM_SUCCESS)
169 {
170 return ccOnlyResponse(request, rc);
171 }
vkaverapa6575b82019-04-03 05:33:52 -0500172
173 return response;
Sampa Misra432e1872019-02-13 03:49:43 -0600174}
175
Sagar Srinivasa6a8ccd2021-04-01 07:58:33 -0500176void Handler::processSetEventReceiver(
177 sdeventplus::source::EventBase& /*source */)
178{
179 survEvent.reset();
180 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
181 PLDM_SET_EVENT_RECEIVER_REQ_BYTES);
182 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
183 auto instanceId = requester.getInstanceId(eid);
184 uint8_t eventMessageGlobalEnable =
185 PLDM_EVENT_MESSAGE_GLOBAL_ENABLE_ASYNC_KEEP_ALIVE;
186 uint8_t transportProtocolType = PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP;
187 uint8_t eventReceiverAddressInfo = pldm::responder::pdr::BmcMctpEid;
188 uint16_t heartbeatTimer = HEARTBEAT_TIMEOUT;
189
190 auto rc = encode_set_event_receiver_req(
191 instanceId, eventMessageGlobalEnable, transportProtocolType,
192 eventReceiverAddressInfo, heartbeatTimer, request);
193 if (rc != PLDM_SUCCESS)
194 {
195 requester.markFree(eid, instanceId);
196 std::cerr << "Failed to encode_set_event_receiver_req, rc = "
197 << std::hex << std::showbase << rc << std::endl;
198 return;
199 }
200
201 auto processSetEventReceiverResponse = [](mctp_eid_t /*eid*/,
202 const pldm_msg* response,
203 size_t respMsgLen) {
204 if (response == nullptr || !respMsgLen)
205 {
206 std::cerr << "Failed to receive response for "
207 "setEventReceiver command \n";
208 return;
209 }
210
211 uint8_t completionCode{};
212 auto rc = decode_set_event_receiver_resp(response, respMsgLen,
213 &completionCode);
214 if (rc || completionCode)
215 {
216 std::cerr << "Failed to decode setEventReceiver command response,"
Manojkiran Eda0a725f82021-10-23 06:02:26 +0530217 << " rc=" << rc << "cc=" << (unsigned)completionCode
Sagar Srinivasa6a8ccd2021-04-01 07:58:33 -0500218 << "\n";
219 pldm::utils::reportError(
220 "xyz.openbmc_project.bmc.pldm.InternalFailure");
221 }
222 };
223 rc = handler->registerRequest(
224 eid, instanceId, PLDM_PLATFORM, PLDM_SET_EVENT_RECEIVER,
225 std::move(requestMsg), std::move(processSetEventReceiverResponse));
226
227 if (rc != PLDM_SUCCESS)
228 {
229 std::cerr << "Failed to send the setEventReceiver request"
230 << "\n";
231 }
Sagar Srinivas7f760b32021-05-12 07:46:56 -0500232
233 if (oemPlatformHandler)
234 {
235 oemPlatformHandler->countSetEventReceiver();
236 oemPlatformHandler->checkAndDisableWatchDog();
237 }
Sagar Srinivasa6a8ccd2021-04-01 07:58:33 -0500238}
239
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600240Response Handler::getTID(const pldm_msg* request, size_t /*payloadLength*/)
John Wang5c4f80d2019-07-29 11:12:18 +0800241{
John Wang5c4f80d2019-07-29 11:12:18 +0800242 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_TID_RESP_BYTES, 0);
243 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
ArchanaKakani6c39c7a2022-12-05 04:36:35 -0600244 auto rc = encode_get_tid_resp(request->hdr.instance_id, PLDM_SUCCESS,
245 TERMINUS_ID, responsePtr);
George Liufb8611d2019-12-06 10:14:15 +0800246 if (rc != PLDM_SUCCESS)
247 {
248 return ccOnlyResponse(request, rc);
249 }
John Wang5c4f80d2019-07-29 11:12:18 +0800250
Sagar Srinivasa6a8ccd2021-04-01 07:58:33 -0500251 survEvent = std::make_unique<sdeventplus::source::Defer>(
252 event, std::bind_front(&Handler::processSetEventReceiver, this));
253
John Wang5c4f80d2019-07-29 11:12:18 +0800254 return response;
255}
256
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600257} // namespace base
Deepak Kodihalli1b24f972019-02-01 04:09:13 -0600258} // namespace responder
259} // namespace pldm