blob: 907f2cb4d8148d5d7aa584779be0085a160f1511 [file] [log] [blame]
Sampa Misraaea5dde2020-08-31 08:33:47 -05001#pragma once
Varsha Kaverappabb585b22020-09-10 06:15:42 -05002
Manojkiran Edaa31ceb92021-07-22 09:19:02 +05303#include "collect_slot_vpd.hpp"
4#include "common/utils.hpp"
Sampa Misraaea5dde2020-08-31 08:33:47 -05005#include "inband_code_update.hpp"
6#include "libpldmresponder/oem_handler.hpp"
Varsha Kaverappabb585b22020-09-10 06:15:42 -05007#include "libpldmresponder/pdr_utils.hpp"
Sampa Misraaea5dde2020-08-31 08:33:47 -05008#include "libpldmresponder/platform.hpp"
Sampa Misrac0c79482021-06-02 08:01:54 -05009#include "requester/handler.hpp"
Sampa Misraaea5dde2020-08-31 08:33:47 -050010
George Liuc453e162022-12-21 17:16:23 +080011#include <libpldm/entity.h>
Andrew Jeffery21f128d2024-01-15 15:34:26 +103012#include <libpldm/oem/ibm/state_set.h>
George Liuc453e162022-12-21 17:16:23 +080013#include <libpldm/platform.h>
George Liuc453e162022-12-21 17:16:23 +080014
Sagar Srinivas18145f72022-04-11 07:38:26 -050015#include <sdbusplus/bus/match.hpp>
16#include <sdeventplus/event.hpp>
17#include <sdeventplus/utility/timer.hpp>
18
Christian Geddes7f9523c2021-08-03 13:44:38 -050019typedef ibm_oem_pldm_state_set_firmware_update_state_values CodeUpdateState;
20
Sampa Misraaea5dde2020-08-31 08:33:47 -050021namespace pldm
22{
Sampa Misraaea5dde2020-08-31 08:33:47 -050023namespace responder
24{
Manojkiran Edaa31ceb92021-07-22 09:19:02 +053025using ObjectPath = std::string;
26using AssociatedEntityMap = std::map<ObjectPath, pldm_entity>;
Sampa Misraaea5dde2020-08-31 08:33:47 -050027namespace oem_ibm_platform
28{
Sagar Srinivas78a225a2020-08-27 00:52:20 -050029constexpr uint16_t ENTITY_INSTANCE_0 = 0;
30constexpr uint16_t ENTITY_INSTANCE_1 = 1;
31
Sagar Srinivas3687e2b2023-04-10 05:08:28 -050032constexpr uint32_t BMC_PDR_START_RANGE = 0x00000000;
33constexpr uint32_t BMC_PDR_END_RANGE = 0x00FFFFFF;
34constexpr uint32_t HOST_PDR_START_RANGE = 0x01000000;
35constexpr uint32_t HOST_PDR_END_RANGE = 0x01FFFFFF;
36
Sagar Srinivas18145f72022-04-11 07:38:26 -050037const pldm::pdr::TerminusID HYPERVISOR_TID = 208;
38
39static constexpr uint8_t HEARTBEAT_TIMEOUT_DELTA = 10;
40
Sagar Srinivas7f760b32021-05-12 07:46:56 -050041enum SetEventReceiverCount
42{
43 SET_EVENT_RECEIVER_SENT = 0x2,
44};
45
Sampa Misraaea5dde2020-08-31 08:33:47 -050046class Handler : public oem_platform::Handler
47{
48 public:
49 Handler(const pldm::utils::DBusHandler* dBusIntf,
Manojkiran Edaa31ceb92021-07-22 09:19:02 +053050 pldm::responder::CodeUpdate* codeUpdate,
51 pldm::responder::SlotHandler* slotHandler, int mctp_fd,
Andrew Jefferya330b2f2023-05-04 14:55:37 +093052 uint8_t mctp_eid, pldm::InstanceIdDb& instanceIdDb,
Brad Bishop5079ac42021-08-19 18:35:06 -040053 sdeventplus::Event& event,
Sampa Misrac0c79482021-06-02 08:01:54 -050054 pldm::requester::Handler<pldm::requester::Request>* handler) :
Patrick Williams16c2a0a2024-08-16 15:20:59 -040055 oem_platform::Handler(dBusIntf), codeUpdate(codeUpdate),
Manojkiran Edaa31ceb92021-07-22 09:19:02 +053056 slotHandler(slotHandler), platformHandler(nullptr), mctp_fd(mctp_fd),
57 mctp_eid(mctp_eid), instanceIdDb(instanceIdDb), event(event),
58 handler(handler),
Sagar Srinivas18145f72022-04-11 07:38:26 -050059 timer(event, std::bind(std::mem_fn(&Handler::setSurvTimer), this,
60 HYPERVISOR_TID, false)),
61 hostTransitioningToOff(true)
Sampa Misraaea5dde2020-08-31 08:33:47 -050062 {
63 codeUpdate->setVersions();
Sagar Srinivas7f760b32021-05-12 07:46:56 -050064 setEventReceiverCnt = 0;
65
66 using namespace sdbusplus::bus::match::rules;
Patrick Williams84b790c2022-07-22 19:26:56 -050067 hostOffMatch = std::make_unique<sdbusplus::bus::match_t>(
Sagar Srinivas7f760b32021-05-12 07:46:56 -050068 pldm::utils::DBusHandler::getBus(),
69 propertiesChanged("/xyz/openbmc_project/state/host0",
70 "xyz.openbmc_project.State.Host"),
Patrick Williams84b790c2022-07-22 19:26:56 -050071 [this](sdbusplus::message_t& msg) {
Patrick Williams16c2a0a2024-08-16 15:20:59 -040072 pldm::utils::DbusChangedProps props{};
73 std::string intf;
74 msg.read(intf, props);
75 const auto itr = props.find("CurrentHostState");
76 if (itr != props.end())
Sagar Srinivas7f760b32021-05-12 07:46:56 -050077 {
Patrick Williams16c2a0a2024-08-16 15:20:59 -040078 pldm::utils::PropertyValue value = itr->second;
79 auto propVal = std::get<std::string>(value);
80 if (propVal ==
81 "xyz.openbmc_project.State.Host.HostState.Off")
82 {
83 hostOff = true;
84 setEventReceiverCnt = 0;
85 disableWatchDogTimer();
86 startStopTimer(false);
87 }
88 else if (propVal ==
89 "xyz.openbmc_project.State.Host.HostState.Running")
90 {
91 hostOff = false;
92 hostTransitioningToOff = false;
93 }
94 else if (
95 propVal ==
96 "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
97 {
98 hostTransitioningToOff = true;
99 }
Sagar Srinivas7f760b32021-05-12 07:46:56 -0500100 }
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400101 });
Pavithra Barithaya0fd6a092024-05-31 08:24:27 -0500102
Patrick Williams4f152f92024-06-18 02:38:34 -0500103 powerStateOffMatch = std::make_unique<sdbusplus::bus::match_t>(
Pavithra Barithaya0fd6a092024-05-31 08:24:27 -0500104 pldm::utils::DBusHandler::getBus(),
105 propertiesChanged("/xyz/openbmc_project/state/chassis0",
106 "xyz.openbmc_project.State.Chassis"),
Andrew Jefferya933c092024-07-25 20:51:47 +0930107 [](sdbusplus::message_t& msg) {
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400108 pldm::utils::DbusChangedProps props{};
109 std::string intf;
110 msg.read(intf, props);
111 const auto itr = props.find("CurrentPowerState");
112 if (itr != props.end())
Pavithra Barithaya0fd6a092024-05-31 08:24:27 -0500113 {
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400114 pldm::utils::PropertyValue value = itr->second;
115 auto propVal = std::get<std::string>(value);
116 if (propVal ==
117 "xyz.openbmc_project.State.Chassis.PowerState.Off")
Pavithra Barithaya0fd6a092024-05-31 08:24:27 -0500118 {
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400119 static constexpr auto searchpath =
120 "/xyz/openbmc_project/inventory/system/chassis/motherboard";
121 int depth = 0;
122 std::vector<std::string> powerInterface = {
123 "xyz.openbmc_project.State.Decorator.PowerState"};
124 pldm::utils::GetSubTreeResponse response =
125 pldm::utils::DBusHandler().getSubtree(
126 searchpath, depth, powerInterface);
127 for (const auto& [objPath, serviceMap] : response)
Pavithra Barithaya0fd6a092024-05-31 08:24:27 -0500128 {
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400129 pldm::utils::DBusMapping dbusMapping{
130 objPath,
131 "xyz.openbmc_project.State.Decorator.PowerState",
132 "PowerState", "string"};
133 value =
134 "xyz.openbmc_project.State.Decorator.PowerState.State.Off";
135 try
136 {
137 pldm::utils::DBusHandler().setDbusProperty(
138 dbusMapping, value);
139 }
140 catch (const std::exception& e)
141 {
142 error(
143 "Unable to set the slot power state to Off error - {ERROR}",
144 "ERROR", e);
145 }
Pavithra Barithaya0fd6a092024-05-31 08:24:27 -0500146 }
147 }
148 }
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400149 });
Sampa Misraaea5dde2020-08-31 08:33:47 -0500150 }
151
152 int getOemStateSensorReadingsHandler(
Kamalkumar Patel7d427f12024-05-16 03:44:00 -0500153 pldm::pdr::EntityType entityType,
154 pldm::pdr::EntityInstance entityInstance,
Manojkiran Edaa31ceb92021-07-22 09:19:02 +0530155 pldm::pdr::ContainerID containerId, pldm::pdr::StateSetId stateSetId,
156 pldm::pdr::CompositeCount compSensorCnt, uint16_t sensorId,
Sampa Misraaea5dde2020-08-31 08:33:47 -0500157 std::vector<get_sensor_state_field>& stateField);
158
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500159 int oemSetStateEffecterStatesHandler(
Varsha Kaverappa3fbd39e2020-09-28 01:40:22 -0500160 uint16_t entityType, uint16_t entityInstance, uint16_t stateSetId,
161 uint8_t compEffecterCnt,
162 std::vector<set_effecter_state_field>& stateField, uint16_t effecterId);
Sampa Misraaea5dde2020-08-31 08:33:47 -0500163
164 /** @brief Method to set the platform handler in the
165 * oem_ibm_handler class
166 * @param[in] handler - pointer to PLDM platform handler
167 */
168 void setPlatformHandler(pldm::responder::platform::Handler* handler);
169
Sagar Srinivas78a225a2020-08-27 00:52:20 -0500170 /** @brief Method to fetch the effecter ID of the code update PDRs
171 *
172 * @return platformHandler->getNextEffecterId() - returns the
173 * effecter ID from the platform handler
174 */
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530175 virtual uint16_t getNextEffecterId()
Sagar Srinivas78a225a2020-08-27 00:52:20 -0500176 {
177 return platformHandler->getNextEffecterId();
178 }
179
180 /** @brief Method to fetch the sensor ID of the code update PDRs
181 *
182 * @return platformHandler->getNextSensorId() - returns the
183 * Sensor ID from the platform handler
184 */
Manojkiran Eda6b1d8832021-03-27 11:25:06 +0530185 virtual uint16_t getNextSensorId()
Sagar Srinivas78a225a2020-08-27 00:52:20 -0500186 {
187 return platformHandler->getNextSensorId();
188 }
189
Manojkiran Edaa31ceb92021-07-22 09:19:02 +0530190 /** @brief Get std::map associated with the entity
191 * key: object path
192 * value: pldm_entity
193 *
194 * @return std::map<ObjectPath, pldm_entity>
195 */
196 virtual const AssociatedEntityMap& getAssociateEntityMap()
197 {
198 return platformHandler->getAssociateEntityMap();
199 }
200
Sagar Srinivas78a225a2020-08-27 00:52:20 -0500201 /** @brief Method to Generate the OEM PDRs
202 *
203 * @param[in] repo - instance of concrete implementation of Repo
204 */
205 void buildOEMPDR(pdr_utils::Repo& repo);
206
Varsha Kaverappabb585b22020-09-10 06:15:42 -0500207 /** @brief Method to send code update event to host
208 * @param[in] sensorId - sendor ID
209 * @param[in] sensorEventClass - event class of sensor
210 * @param[in] sensorOffset - sensor offset
211 * @param[in] eventState - new code update event state
212 * @param[in] prevEventState - previous code update event state
213 * @return none
214 */
215 void sendStateSensorEvent(uint16_t sensorId,
216 enum sensor_event_class_states sensorEventClass,
217 uint8_t sensorOffset, uint8_t eventState,
218 uint8_t prevEventState);
219
220 /** @brief Method to send encoded request msg of code update event to host
221 * @param[in] requestMsg - encoded request msg
Sampa Misrac0c79482021-06-02 08:01:54 -0500222 * @param[in] instanceId - instance id of the message
Varsha Kaverappabb585b22020-09-10 06:15:42 -0500223 * @return PLDM status code
224 */
Sampa Misrac0c79482021-06-02 08:01:54 -0500225 int sendEventToHost(std::vector<uint8_t>& requestMsg, uint8_t instanceId);
Varsha Kaverappabb585b22020-09-10 06:15:42 -0500226
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500227 /** @brief _processEndUpdate processes the actual work that needs
228 * to be carried out after EndUpdate effecter is set. This is done async
229 * after sending response for EndUpdate set effecter
230 * @param[in] source - sdeventplus event source
231 */
232 void _processEndUpdate(sdeventplus::source::EventBase& source);
233
234 /** @brief _processStartUpdate processes the actual work that needs
235 * to be carried out after StartUpdate effecter is set. This is done async
236 * after sending response for StartUpdate set effecter
237 * @param[in] source - sdeventplus event source
238 */
239 void _processStartUpdate(sdeventplus::source::EventBase& source);
240
Sagar Srinivas9a64b4a2021-02-09 07:55:38 -0600241 /** @brief _processSystemReboot processes the actual work that needs to be
242 * carried out after the System Power State effecter is set to reboot
243 * the system
244 * @param[in] source - sdeventplus event source
245 */
246 void _processSystemReboot(sdeventplus::source::EventBase& source);
247
Sagar Srinivas7f760b32021-05-12 07:46:56 -0500248 /*keeps track how many times setEventReceiver is sent */
249 void countSetEventReceiver()
250 {
251 setEventReceiverCnt++;
252 }
253
254 /* disables watchdog if running and Host is up */
255 void checkAndDisableWatchDog();
256
Sagar Srinivas79669c92021-04-28 15:43:30 -0500257 /** @brief To check if the watchdog app is running
258 *
259 * @return the running status of watchdog app
260 */
261 bool watchDogRunning();
262
263 /** @brief Method to reset the Watchdog timer on receiving platform Event
264 * Message for heartbeat elapsed time from Hostboot
265 */
266 void resetWatchDogTimer();
267
Sagar Srinivas7f760b32021-05-12 07:46:56 -0500268 /** @brief To disable to the watchdog timer on host poweron completion*/
269 void disableWatchDogTimer();
270
Pavithra Barithaya99854a72021-09-29 06:58:11 -0500271 /** @brief to check the BMC state*/
272 int checkBMCState();
273
Kamalkumar Patel15ce5a12024-05-07 11:45:11 -0500274 /** @brief update the dbus object paths */
275 void updateOemDbusPaths(std::string& dbusPath);
276
Sagar Srinivas3687e2b2023-04-10 05:08:28 -0500277 /** @brief Method to fetch the last BMC record from the PDR repo
278 *
279 * @param[in] repo - pointer to BMC's primary PDR repo
280 *
281 * @return the last BMC record from the repo
282 */
283 const pldm_pdr_record* fetchLastBMCRecord(const pldm_pdr* repo);
284
285 /** @brief Method to check if the record handle passed is in remote PDR
286 * record handle range
287 *
288 * @param[in] record_handle - record handle of the PDR
289 *
290 * @return true if record handle passed is in host PDR record handle range
291 */
292 bool checkRecordHandleInRange(const uint32_t& record_handle);
293
Sagar Srinivas90314a32023-10-17 10:38:03 -0500294 /** *brief Method to call the setEventReceiver command*/
295 void processSetEventReceiver();
296
297 /** @brief Method to call the setEventReceiver through the platform
298 * handler
299 */
300 virtual void setEventReceiver()
301 {
302 platformHandler->setEventReceiver();
303 }
304
Sagar Srinivas18145f72022-04-11 07:38:26 -0500305 /** @brief Method to Enable/Disable timer to see if remote terminus sends
306 * the surveillance ping and logs informational error if remote terminus
307 * fails to send the surveillance pings
308 *
309 * @param[in] tid - TID of the remote terminus
310 * @param[in] value - true or false, to indicate if the timer is
311 * running or not
312 */
313 void setSurvTimer(uint8_t tid, bool value);
314
Sampa Misraaea5dde2020-08-31 08:33:47 -0500315 ~Handler() = default;
316
317 pldm::responder::CodeUpdate* codeUpdate; //!< pointer to CodeUpdate object
Manojkiran Edaa31ceb92021-07-22 09:19:02 +0530318
319 pldm::responder::SlotHandler*
320 slotHandler; //!< pointer to SlotHandler object
321
Sampa Misraaea5dde2020-08-31 08:33:47 -0500322 pldm::responder::platform::Handler*
323 platformHandler; //!< pointer to PLDM platform handler
Varsha Kaverappabb585b22020-09-10 06:15:42 -0500324
325 /** @brief fd of MCTP communications socket */
326 int mctp_fd;
327
328 /** @brief MCTP EID of host firmware */
329 uint8_t mctp_eid;
330
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930331 /** @brief reference to an InstanceIdDb object, used to obtain a PLDM
332 * instance id. */
333 pldm::InstanceIdDb& instanceIdDb;
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500334 /** @brief sdeventplus event source */
335 std::unique_ptr<sdeventplus::source::Defer> assembleImageEvent;
336 std::unique_ptr<sdeventplus::source::Defer> startUpdateEvent;
Sagar Srinivas9a64b4a2021-02-09 07:55:38 -0600337 std::unique_ptr<sdeventplus::source::Defer> systemRebootEvent;
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500338
Manojkiran Edaa31ceb92021-07-22 09:19:02 +0530339 /** @brief Effecterid to dbus object path map
340 */
341 std::unordered_map<uint16_t, std::string> effecterIdToDbusMap;
342
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500343 /** @brief reference of main event loop of pldmd, primarily used to schedule
344 * work
345 */
346 sdeventplus::Event& event;
Sagar Srinivas9a64b4a2021-02-09 07:55:38 -0600347
348 private:
Sagar Srinivas18145f72022-04-11 07:38:26 -0500349 /** @brief Method to reset or stop the surveillance timer
350 *
351 * @param[in] value - true or false, to indicate if the timer
352 * should be reset or turned off
353 */
354 void startStopTimer(bool value);
355
Sagar Srinivas9a64b4a2021-02-09 07:55:38 -0600356 /** @brief D-Bus property changed signal match for CurrentPowerState*/
Patrick Williams84b790c2022-07-22 19:26:56 -0500357 std::unique_ptr<sdbusplus::bus::match_t> chassisOffMatch;
Sampa Misrac0c79482021-06-02 08:01:54 -0500358
359 /** @brief PLDM request handler */
360 pldm::requester::Handler<pldm::requester::Request>* handler;
Sagar Srinivas7f760b32021-05-12 07:46:56 -0500361
362 /** @brief D-Bus property changed signal match */
Patrick Williams84b790c2022-07-22 19:26:56 -0500363 std::unique_ptr<sdbusplus::bus::match_t> hostOffMatch;
Sagar Srinivas7f760b32021-05-12 07:46:56 -0500364
Pavithra Barithaya0fd6a092024-05-31 08:24:27 -0500365 /** @brief D-Bus property changed signal match */
366 std::unique_ptr<sdbusplus::bus::match_t> powerStateOffMatch;
367
Sagar Srinivas18145f72022-04-11 07:38:26 -0500368 /** @brief Timer used for monitoring surveillance pings from host */
369 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> timer;
370
Sagar Srinivas7f760b32021-05-12 07:46:56 -0500371 bool hostOff = true;
372
Sagar Srinivas18145f72022-04-11 07:38:26 -0500373 bool hostTransitioningToOff;
374
Sagar Srinivas7f760b32021-05-12 07:46:56 -0500375 int setEventReceiverCnt = 0;
Sampa Misraaea5dde2020-08-31 08:33:47 -0500376};
377
Varsha Kaverappabb585b22020-09-10 06:15:42 -0500378/** @brief Method to encode code update event msg
379 * @param[in] eventType - type of event
380 * @param[in] eventDataVec - vector of event data to be sent to host
381 * @param[in/out] requestMsg - request msg to be encoded
382 * @param[in] instanceId - instance ID
383 * @return PLDM status code
384 */
385int encodeEventMsg(uint8_t eventType, const std::vector<uint8_t>& eventDataVec,
386 std::vector<uint8_t>& requestMsg, uint8_t instanceId);
387
Sampa Misraaea5dde2020-08-31 08:33:47 -0500388} // namespace oem_ibm_platform
389
390} // namespace responder
391
392} // namespace pldm