blob: b5749c337794075b5f50bed013e3ccf42b16eab2 [file] [log] [blame]
Sampa Misraaea5dde2020-08-31 08:33:47 -05001#pragma once
Varsha Kaverappabb585b22020-09-10 06:15:42 -05002
Sampa Misraaea5dde2020-08-31 08:33:47 -05003#include "inband_code_update.hpp"
4#include "libpldmresponder/oem_handler.hpp"
Varsha Kaverappabb585b22020-09-10 06:15:42 -05005#include "libpldmresponder/pdr_utils.hpp"
Sampa Misraaea5dde2020-08-31 08:33:47 -05006#include "libpldmresponder/platform.hpp"
Sampa Misrac0c79482021-06-02 08:01:54 -05007#include "requester/handler.hpp"
Sampa Misraaea5dde2020-08-31 08:33:47 -05008
George Liuc453e162022-12-21 17:16:23 +08009#include <libpldm/entity.h>
Andrew Jeffery21f128d2024-01-15 15:34:26 +103010#include <libpldm/oem/ibm/state_set.h>
George Liuc453e162022-12-21 17:16:23 +080011#include <libpldm/platform.h>
George Liuc453e162022-12-21 17:16:23 +080012
Sagar Srinivas18145f72022-04-11 07:38:26 -050013#include <sdbusplus/bus/match.hpp>
14#include <sdeventplus/event.hpp>
15#include <sdeventplus/utility/timer.hpp>
16
Christian Geddes7f9523c2021-08-03 13:44:38 -050017typedef ibm_oem_pldm_state_set_firmware_update_state_values CodeUpdateState;
18
Sampa Misraaea5dde2020-08-31 08:33:47 -050019namespace pldm
20{
Sampa Misraaea5dde2020-08-31 08:33:47 -050021namespace responder
22{
Sampa Misraaea5dde2020-08-31 08:33:47 -050023namespace oem_ibm_platform
24{
Sagar Srinivas78a225a2020-08-27 00:52:20 -050025constexpr uint16_t ENTITY_INSTANCE_0 = 0;
26constexpr uint16_t ENTITY_INSTANCE_1 = 1;
27
Sagar Srinivas3687e2b2023-04-10 05:08:28 -050028constexpr uint32_t BMC_PDR_START_RANGE = 0x00000000;
29constexpr uint32_t BMC_PDR_END_RANGE = 0x00FFFFFF;
30constexpr uint32_t HOST_PDR_START_RANGE = 0x01000000;
31constexpr uint32_t HOST_PDR_END_RANGE = 0x01FFFFFF;
32
Sagar Srinivas18145f72022-04-11 07:38:26 -050033const pldm::pdr::TerminusID HYPERVISOR_TID = 208;
34
35static constexpr uint8_t HEARTBEAT_TIMEOUT_DELTA = 10;
36
Sagar Srinivas7f760b32021-05-12 07:46:56 -050037enum SetEventReceiverCount
38{
39 SET_EVENT_RECEIVER_SENT = 0x2,
40};
41
Sampa Misraaea5dde2020-08-31 08:33:47 -050042class Handler : public oem_platform::Handler
43{
44 public:
45 Handler(const pldm::utils::DBusHandler* dBusIntf,
Varsha Kaverappabb585b22020-09-10 06:15:42 -050046 pldm::responder::CodeUpdate* codeUpdate, int mctp_fd,
Andrew Jefferya330b2f2023-05-04 14:55:37 +093047 uint8_t mctp_eid, pldm::InstanceIdDb& instanceIdDb,
Brad Bishop5079ac42021-08-19 18:35:06 -040048 sdeventplus::Event& event,
Sampa Misrac0c79482021-06-02 08:01:54 -050049 pldm::requester::Handler<pldm::requester::Request>* handler) :
Patrick Williams16c2a0a2024-08-16 15:20:59 -040050 oem_platform::Handler(dBusIntf), codeUpdate(codeUpdate),
51 platformHandler(nullptr), mctp_fd(mctp_fd), mctp_eid(mctp_eid),
52 instanceIdDb(instanceIdDb), event(event), handler(handler),
Sagar Srinivas18145f72022-04-11 07:38:26 -050053 timer(event, std::bind(std::mem_fn(&Handler::setSurvTimer), this,
54 HYPERVISOR_TID, false)),
55 hostTransitioningToOff(true)
Sampa Misraaea5dde2020-08-31 08:33:47 -050056 {
57 codeUpdate->setVersions();
Sagar Srinivas7f760b32021-05-12 07:46:56 -050058 setEventReceiverCnt = 0;
59
60 using namespace sdbusplus::bus::match::rules;
Patrick Williams84b790c2022-07-22 19:26:56 -050061 hostOffMatch = std::make_unique<sdbusplus::bus::match_t>(
Sagar Srinivas7f760b32021-05-12 07:46:56 -050062 pldm::utils::DBusHandler::getBus(),
63 propertiesChanged("/xyz/openbmc_project/state/host0",
64 "xyz.openbmc_project.State.Host"),
Patrick Williams84b790c2022-07-22 19:26:56 -050065 [this](sdbusplus::message_t& msg) {
Patrick Williams16c2a0a2024-08-16 15:20:59 -040066 pldm::utils::DbusChangedProps props{};
67 std::string intf;
68 msg.read(intf, props);
69 const auto itr = props.find("CurrentHostState");
70 if (itr != props.end())
Sagar Srinivas7f760b32021-05-12 07:46:56 -050071 {
Patrick Williams16c2a0a2024-08-16 15:20:59 -040072 pldm::utils::PropertyValue value = itr->second;
73 auto propVal = std::get<std::string>(value);
74 if (propVal ==
75 "xyz.openbmc_project.State.Host.HostState.Off")
76 {
77 hostOff = true;
78 setEventReceiverCnt = 0;
79 disableWatchDogTimer();
80 startStopTimer(false);
81 }
82 else if (propVal ==
83 "xyz.openbmc_project.State.Host.HostState.Running")
84 {
85 hostOff = false;
86 hostTransitioningToOff = false;
87 }
88 else if (
89 propVal ==
90 "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
91 {
92 hostTransitioningToOff = true;
93 }
Sagar Srinivas7f760b32021-05-12 07:46:56 -050094 }
Patrick Williams16c2a0a2024-08-16 15:20:59 -040095 });
Pavithra Barithaya0fd6a092024-05-31 08:24:27 -050096
Patrick Williams4f152f92024-06-18 02:38:34 -050097 powerStateOffMatch = std::make_unique<sdbusplus::bus::match_t>(
Pavithra Barithaya0fd6a092024-05-31 08:24:27 -050098 pldm::utils::DBusHandler::getBus(),
99 propertiesChanged("/xyz/openbmc_project/state/chassis0",
100 "xyz.openbmc_project.State.Chassis"),
Andrew Jefferya933c092024-07-25 20:51:47 +0930101 [](sdbusplus::message_t& msg) {
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400102 pldm::utils::DbusChangedProps props{};
103 std::string intf;
104 msg.read(intf, props);
105 const auto itr = props.find("CurrentPowerState");
106 if (itr != props.end())
Pavithra Barithaya0fd6a092024-05-31 08:24:27 -0500107 {
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400108 pldm::utils::PropertyValue value = itr->second;
109 auto propVal = std::get<std::string>(value);
110 if (propVal ==
111 "xyz.openbmc_project.State.Chassis.PowerState.Off")
Pavithra Barithaya0fd6a092024-05-31 08:24:27 -0500112 {
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400113 static constexpr auto searchpath =
114 "/xyz/openbmc_project/inventory/system/chassis/motherboard";
115 int depth = 0;
116 std::vector<std::string> powerInterface = {
117 "xyz.openbmc_project.State.Decorator.PowerState"};
118 pldm::utils::GetSubTreeResponse response =
119 pldm::utils::DBusHandler().getSubtree(
120 searchpath, depth, powerInterface);
121 for (const auto& [objPath, serviceMap] : response)
Pavithra Barithaya0fd6a092024-05-31 08:24:27 -0500122 {
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400123 pldm::utils::DBusMapping dbusMapping{
124 objPath,
125 "xyz.openbmc_project.State.Decorator.PowerState",
126 "PowerState", "string"};
127 value =
128 "xyz.openbmc_project.State.Decorator.PowerState.State.Off";
129 try
130 {
131 pldm::utils::DBusHandler().setDbusProperty(
132 dbusMapping, value);
133 }
134 catch (const std::exception& e)
135 {
136 error(
137 "Unable to set the slot power state to Off error - {ERROR}",
138 "ERROR", e);
139 }
Pavithra Barithaya0fd6a092024-05-31 08:24:27 -0500140 }
141 }
142 }
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400143 });
Sampa Misraaea5dde2020-08-31 08:33:47 -0500144 }
145
146 int getOemStateSensorReadingsHandler(
Kamalkumar Patel7d427f12024-05-16 03:44:00 -0500147 pldm::pdr::EntityType entityType,
148 pldm::pdr::EntityInstance entityInstance,
Brad Bishop5079ac42021-08-19 18:35:06 -0400149 pldm::pdr::StateSetId stateSetId,
150 pldm::pdr::CompositeCount compSensorCnt,
Sampa Misraaea5dde2020-08-31 08:33:47 -0500151 std::vector<get_sensor_state_field>& stateField);
152
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500153 int oemSetStateEffecterStatesHandler(
Varsha Kaverappa3fbd39e2020-09-28 01:40:22 -0500154 uint16_t entityType, uint16_t entityInstance, uint16_t stateSetId,
155 uint8_t compEffecterCnt,
156 std::vector<set_effecter_state_field>& stateField, uint16_t effecterId);
Sampa Misraaea5dde2020-08-31 08:33:47 -0500157
158 /** @brief Method to set the platform handler in the
159 * oem_ibm_handler class
160 * @param[in] handler - pointer to PLDM platform handler
161 */
162 void setPlatformHandler(pldm::responder::platform::Handler* handler);
163
Sagar Srinivas78a225a2020-08-27 00:52:20 -0500164 /** @brief Method to fetch the effecter ID of the code update PDRs
165 *
166 * @return platformHandler->getNextEffecterId() - returns the
167 * effecter ID from the platform handler
168 */
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530169 virtual uint16_t getNextEffecterId()
Sagar Srinivas78a225a2020-08-27 00:52:20 -0500170 {
171 return platformHandler->getNextEffecterId();
172 }
173
174 /** @brief Method to fetch the sensor ID of the code update PDRs
175 *
176 * @return platformHandler->getNextSensorId() - returns the
177 * Sensor ID from the platform handler
178 */
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530179 virtual uint16_t getNextSensorId()
Sagar Srinivas78a225a2020-08-27 00:52:20 -0500180 {
181 return platformHandler->getNextSensorId();
182 }
183
184 /** @brief Method to Generate the OEM PDRs
185 *
186 * @param[in] repo - instance of concrete implementation of Repo
187 */
188 void buildOEMPDR(pdr_utils::Repo& repo);
189
Varsha Kaverappabb585b22020-09-10 06:15:42 -0500190 /** @brief Method to send code update event to host
191 * @param[in] sensorId - sendor ID
192 * @param[in] sensorEventClass - event class of sensor
193 * @param[in] sensorOffset - sensor offset
194 * @param[in] eventState - new code update event state
195 * @param[in] prevEventState - previous code update event state
196 * @return none
197 */
198 void sendStateSensorEvent(uint16_t sensorId,
199 enum sensor_event_class_states sensorEventClass,
200 uint8_t sensorOffset, uint8_t eventState,
201 uint8_t prevEventState);
202
203 /** @brief Method to send encoded request msg of code update event to host
204 * @param[in] requestMsg - encoded request msg
Sampa Misrac0c79482021-06-02 08:01:54 -0500205 * @param[in] instanceId - instance id of the message
Varsha Kaverappabb585b22020-09-10 06:15:42 -0500206 * @return PLDM status code
207 */
Sampa Misrac0c79482021-06-02 08:01:54 -0500208 int sendEventToHost(std::vector<uint8_t>& requestMsg, uint8_t instanceId);
Varsha Kaverappabb585b22020-09-10 06:15:42 -0500209
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500210 /** @brief _processEndUpdate processes the actual work that needs
211 * to be carried out after EndUpdate effecter is set. This is done async
212 * after sending response for EndUpdate set effecter
213 * @param[in] source - sdeventplus event source
214 */
215 void _processEndUpdate(sdeventplus::source::EventBase& source);
216
217 /** @brief _processStartUpdate processes the actual work that needs
218 * to be carried out after StartUpdate effecter is set. This is done async
219 * after sending response for StartUpdate set effecter
220 * @param[in] source - sdeventplus event source
221 */
222 void _processStartUpdate(sdeventplus::source::EventBase& source);
223
Sagar Srinivas9a64b4a2021-02-09 07:55:38 -0600224 /** @brief _processSystemReboot processes the actual work that needs to be
225 * carried out after the System Power State effecter is set to reboot
226 * the system
227 * @param[in] source - sdeventplus event source
228 */
229 void _processSystemReboot(sdeventplus::source::EventBase& source);
230
Sagar Srinivas7f760b32021-05-12 07:46:56 -0500231 /*keeps track how many times setEventReceiver is sent */
232 void countSetEventReceiver()
233 {
234 setEventReceiverCnt++;
235 }
236
237 /* disables watchdog if running and Host is up */
238 void checkAndDisableWatchDog();
239
Sagar Srinivas79669c92021-04-28 15:43:30 -0500240 /** @brief To check if the watchdog app is running
241 *
242 * @return the running status of watchdog app
243 */
244 bool watchDogRunning();
245
246 /** @brief Method to reset the Watchdog timer on receiving platform Event
247 * Message for heartbeat elapsed time from Hostboot
248 */
249 void resetWatchDogTimer();
250
Sagar Srinivas7f760b32021-05-12 07:46:56 -0500251 /** @brief To disable to the watchdog timer on host poweron completion*/
252 void disableWatchDogTimer();
253
Pavithra Barithaya99854a72021-09-29 06:58:11 -0500254 /** @brief to check the BMC state*/
255 int checkBMCState();
256
Kamalkumar Patel15ce5a12024-05-07 11:45:11 -0500257 /** @brief update the dbus object paths */
258 void updateOemDbusPaths(std::string& dbusPath);
259
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500260 /** @brief Method to fetch the last BMC record from the PDR repo
261 *
262 * @param[in] repo - pointer to BMC's primary PDR repo
263 *
264 * @return the last BMC record from the repo
265 */
266 const pldm_pdr_record* fetchLastBMCRecord(const pldm_pdr* repo);
267
268 /** @brief Method to check if the record handle passed is in remote PDR
269 * record handle range
270 *
271 * @param[in] record_handle - record handle of the PDR
272 *
273 * @return true if record handle passed is in host PDR record handle range
274 */
275 bool checkRecordHandleInRange(const uint32_t& record_handle);
276
Sagar Srinivas90314a32023-10-17 10:38:03 -0500277 /** *brief Method to call the setEventReceiver command*/
278 void processSetEventReceiver();
279
280 /** @brief Method to call the setEventReceiver through the platform
281 * handler
282 */
283 virtual void setEventReceiver()
284 {
285 platformHandler->setEventReceiver();
286 }
287
Sagar Srinivas18145f72022-04-11 07:38:26 -0500288 /** @brief Method to Enable/Disable timer to see if remote terminus sends
289 * the surveillance ping and logs informational error if remote terminus
290 * fails to send the surveillance pings
291 *
292 * @param[in] tid - TID of the remote terminus
293 * @param[in] value - true or false, to indicate if the timer is
294 * running or not
295 */
296 void setSurvTimer(uint8_t tid, bool value);
297
Sampa Misraaea5dde2020-08-31 08:33:47 -0500298 ~Handler() = default;
299
300 pldm::responder::CodeUpdate* codeUpdate; //!< pointer to CodeUpdate object
301 pldm::responder::platform::Handler*
302 platformHandler; //!< pointer to PLDM platform handler
Varsha Kaverappabb585b22020-09-10 06:15:42 -0500303
304 /** @brief fd of MCTP communications socket */
305 int mctp_fd;
306
307 /** @brief MCTP EID of host firmware */
308 uint8_t mctp_eid;
309
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930310 /** @brief reference to an InstanceIdDb object, used to obtain a PLDM
311 * instance id. */
312 pldm::InstanceIdDb& instanceIdDb;
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500313 /** @brief sdeventplus event source */
314 std::unique_ptr<sdeventplus::source::Defer> assembleImageEvent;
315 std::unique_ptr<sdeventplus::source::Defer> startUpdateEvent;
Sagar Srinivas9a64b4a2021-02-09 07:55:38 -0600316 std::unique_ptr<sdeventplus::source::Defer> systemRebootEvent;
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500317
318 /** @brief reference of main event loop of pldmd, primarily used to schedule
319 * work
320 */
321 sdeventplus::Event& event;
Sagar Srinivas9a64b4a2021-02-09 07:55:38 -0600322
323 private:
Sagar Srinivas18145f72022-04-11 07:38:26 -0500324 /** @brief Method to reset or stop the surveillance timer
325 *
326 * @param[in] value - true or false, to indicate if the timer
327 * should be reset or turned off
328 */
329 void startStopTimer(bool value);
330
Sagar Srinivas9a64b4a2021-02-09 07:55:38 -0600331 /** @brief D-Bus property changed signal match for CurrentPowerState*/
Patrick Williams84b790c2022-07-22 19:26:56 -0500332 std::unique_ptr<sdbusplus::bus::match_t> chassisOffMatch;
Sampa Misrac0c79482021-06-02 08:01:54 -0500333
334 /** @brief PLDM request handler */
335 pldm::requester::Handler<pldm::requester::Request>* handler;
Sagar Srinivas7f760b32021-05-12 07:46:56 -0500336
337 /** @brief D-Bus property changed signal match */
Patrick Williams84b790c2022-07-22 19:26:56 -0500338 std::unique_ptr<sdbusplus::bus::match_t> hostOffMatch;
Sagar Srinivas7f760b32021-05-12 07:46:56 -0500339
Pavithra Barithaya0fd6a092024-05-31 08:24:27 -0500340 /** @brief D-Bus property changed signal match */
341 std::unique_ptr<sdbusplus::bus::match_t> powerStateOffMatch;
342
Sagar Srinivas18145f72022-04-11 07:38:26 -0500343 /** @brief Timer used for monitoring surveillance pings from host */
344 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> timer;
345
Sagar Srinivas7f760b32021-05-12 07:46:56 -0500346 bool hostOff = true;
347
Sagar Srinivas18145f72022-04-11 07:38:26 -0500348 bool hostTransitioningToOff;
349
Sagar Srinivas7f760b32021-05-12 07:46:56 -0500350 int setEventReceiverCnt = 0;
Sampa Misraaea5dde2020-08-31 08:33:47 -0500351};
352
Varsha Kaverappabb585b22020-09-10 06:15:42 -0500353/** @brief Method to encode code update event msg
354 * @param[in] eventType - type of event
355 * @param[in] eventDataVec - vector of event data to be sent to host
356 * @param[in/out] requestMsg - request msg to be encoded
357 * @param[in] instanceId - instance ID
358 * @return PLDM status code
359 */
360int encodeEventMsg(uint8_t eventType, const std::vector<uint8_t>& eventDataVec,
361 std::vector<uint8_t>& requestMsg, uint8_t instanceId);
362
Sampa Misraaea5dde2020-08-31 08:33:47 -0500363} // namespace oem_ibm_platform
364
365} // namespace responder
366
367} // namespace pldm