blob: fa340b70c29e3cc3c3015402dd33e6ca9c7d75bb [file] [log] [blame]
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +05301#pragma once
2
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +05303#include "occ_pass_through.hpp"
Vishwanatha Subbanna307d80b2017-06-28 15:56:09 +05304#include "occ_status.hpp"
Tom Joseph815f9f52020-07-27 12:12:13 +05305#ifdef PLDM
6#include "pldm.hpp"
Eddie Jamescbad2192021-10-07 09:39:39 -05007
8#include <libphal.H>
Tom Joseph815f9f52020-07-27 12:12:13 +05309#endif
George Liuf3b75142021-06-10 11:22:50 +080010#include "utils.hpp"
Chris Cain78e86012021-03-04 16:15:31 -060011#ifdef POWER10
12#include "powermode.hpp"
13#endif
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +053014
Gunnar Mills94df8c92018-09-14 14:50:03 -050015#include <sdbusplus/bus.hpp>
Chris Caina8857c52021-01-27 11:53:05 -060016#include <sdeventplus/event.hpp>
17#include <sdeventplus/utility/timer.hpp>
George Liub5ca1012021-09-10 12:53:11 +080018
19#include <cstring>
20#include <functional>
Gunnar Mills94df8c92018-09-14 14:50:03 -050021#include <vector>
22
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +053023namespace sdbusRule = sdbusplus::bus::match::rules;
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +053024namespace open_power
25{
26namespace occ
27{
28
Chicago Duanbb895cb2021-06-18 19:37:16 +080029#ifdef READ_OCC_SENSORS
30enum occFruType
31{
32 processorCore = 0,
33 internalMemCtlr = 1,
34 dimm = 2,
35 memCtrlAndDimm = 3,
36 VRMVdd = 6,
37 PMIC = 7,
Matt Spinlerace67d82021-10-18 13:41:57 -050038 memCtlrExSensor = 8,
39 processorIoRing = 9
Chicago Duanbb895cb2021-06-18 19:37:16 +080040};
41#endif
42
Chris Caina8857c52021-01-27 11:53:05 -060043/** @brief Default time, in seconds, between OCC poll commands */
Matt Spinler37923462021-09-24 11:38:05 -050044#ifndef POWER10
Chicago Duanbb895cb2021-06-18 19:37:16 +080045constexpr unsigned int defaultPollingInterval = 1;
Matt Spinler37923462021-09-24 11:38:05 -050046#else
47constexpr unsigned int defaultPollingInterval = 5;
48#endif
Chris Caina8857c52021-01-27 11:53:05 -060049
Chris Cain17257672021-10-22 13:41:03 -050050constexpr auto AMBIENT_PATH =
51 "/xyz/openbmc_project/sensors/temperature/Ambient_Virtual_Temp";
52constexpr auto AMBIENT_INTERFACE = "xyz.openbmc_project.Sensor.Value";
53constexpr auto AMBIENT_PROP = "Value";
54constexpr auto ALTITUDE_PATH = "/xyz/openbmc_project/sensors/altitude/Altitude";
55constexpr auto ALTITUDE_INTERFACE = "xyz.openbmc_project.Sensor.Value";
56constexpr auto ALTITUDE_PROP = "Value";
57
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +053058/** @class Manager
59 * @brief Builds and manages OCC objects
60 */
61struct Manager
62{
Gunnar Mills94df8c92018-09-14 14:50:03 -050063 public:
64 Manager() = delete;
65 Manager(const Manager&) = delete;
66 Manager& operator=(const Manager&) = delete;
67 Manager(Manager&&) = delete;
68 Manager& operator=(Manager&&) = delete;
69 ~Manager() = default;
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +053070
Gunnar Mills94df8c92018-09-14 14:50:03 -050071 /** @brief Adds OCC pass-through and status objects on the bus
72 * when corresponding CPU inventory is created.
73 *
Gunnar Mills94df8c92018-09-14 14:50:03 -050074 * @param[in] event - Unique ptr reference to sd_event
75 */
George Liuf3a4a692021-12-28 13:59:51 +080076 explicit Manager(EventPtr& event) :
George Liuf3b75142021-06-10 11:22:50 +080077 event(event), pollInterval(defaultPollingInterval),
Chris Caina8857c52021-01-27 11:53:05 -060078 sdpEvent(sdeventplus::Event::get_default()),
79 _pollTimer(
80 std::make_unique<
81 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>>(
Chris Cain17257672021-10-22 13:41:03 -050082 sdpEvent, std::bind(&Manager::pollerTimerExpired, this))),
83 ambientPropChanged(
84 utils::getBus(),
85 sdbusRule::member("PropertiesChanged") +
86 sdbusRule::path(AMBIENT_PATH) +
87 sdbusRule::argN(0, AMBIENT_INTERFACE) +
88 sdbusRule::interface("org.freedesktop.DBus.Properties"),
89 std::bind(&Manager::ambientCallback, this, std::placeholders::_1))
Tom Joseph815f9f52020-07-27 12:12:13 +053090#ifdef PLDM
91 ,
92 pldmHandle(std::make_unique<pldm::Interface>(
George Liuf3b75142021-06-10 11:22:50 +080093 std::bind(std::mem_fn(&Manager::updateOCCActive), this,
Eddie Jamescbad2192021-10-07 09:39:39 -050094 std::placeholders::_1, std::placeholders::_2),
95 std::bind(std::mem_fn(&Manager::sbeHRESETResult), this,
George Liuf3b75142021-06-10 11:22:50 +080096 std::placeholders::_1, std::placeholders::_2)))
Tom Joseph815f9f52020-07-27 12:12:13 +053097#endif
Matt Spinlerd267cec2021-09-01 14:49:19 -050098#ifdef POWER10
99 ,
100 discoverTimer(
101 std::make_unique<
102 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>>(
Chris Caina7b74dc2021-11-10 17:03:43 -0600103 sdpEvent, std::bind(&Manager::findAndCreateObjects, this))),
104 waitForAllOccsTimer(
105 std::make_unique<
106 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>>(
107 sdpEvent, std::bind(&Manager::occsNotAllRunning, this)))
Matt Spinlerd267cec2021-09-01 14:49:19 -0500108#endif
Gunnar Mills94df8c92018-09-14 14:50:03 -0500109 {
Lei YU0ab90ca2017-07-13 17:02:23 +0800110#ifdef I2C_OCC
Gunnar Mills94df8c92018-09-14 14:50:03 -0500111 // I2C OCC status objects are initialized directly
112 initStatusObjects();
Lei YU0ab90ca2017-07-13 17:02:23 +0800113#else
Gunnar Mills94df8c92018-09-14 14:50:03 -0500114 findAndCreateObjects();
Lei YU0ab90ca2017-07-13 17:02:23 +0800115#endif
Chris Cain17257672021-10-22 13:41:03 -0500116 readAltitude();
Gunnar Mills94df8c92018-09-14 14:50:03 -0500117 }
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +0530118
Chris Caina8857c52021-01-27 11:53:05 -0600119 /** @brief Return the number of bound OCCs */
Gunnar Mills94df8c92018-09-14 14:50:03 -0500120 inline auto getNumOCCs() const
121 {
122 return activeCount;
123 }
Edward A. James636577f2017-10-06 10:53:55 -0500124
Eddie Jamescbad2192021-10-07 09:39:39 -0500125#ifdef PLDM
126 /** @brief Called by a Device to report that the SBE timed out
127 * and appropriate action should be taken
128 *
129 * @param[in] instance - the OCC instance id
130 */
131 void sbeTimeout(unsigned int instance);
132#endif
133
Chris Cain17257672021-10-22 13:41:03 -0500134 /** @brief Return the latest ambient and altitude readings
135 *
136 * @param[out] ambientValid - true if ambientTemp is valid
137 * @param[out] ambient - ambient temperature in degrees C
138 * @param[out] altitude - altitude in meters
139 */
140 void getAmbientData(bool& ambientValid, uint8_t& ambientTemp,
141 uint16_t& altitude) const;
142
Gunnar Mills94df8c92018-09-14 14:50:03 -0500143 private:
Matt Spinlerd267cec2021-09-01 14:49:19 -0500144 /** @brief Creates the OCC D-Bus objects.
Gunnar Mills94df8c92018-09-14 14:50:03 -0500145 */
146 void findAndCreateObjects();
Vishwanatha Subbannadfc7ec72017-09-07 18:18:01 +0530147
Gunnar Mills94df8c92018-09-14 14:50:03 -0500148 /** @brief Callback that responds to cpu creation in the inventory -
149 * by creating the needed objects.
150 *
151 * @param[in] msg - bus message
152 *
153 * @returns 0 to indicate success
154 */
155 int cpuCreated(sdbusplus::message::message& msg);
Deepak Kodihalli5f031f32017-07-26 08:25:59 -0500156
Gunnar Mills94df8c92018-09-14 14:50:03 -0500157 /** @brief Create child OCC objects.
158 *
159 * @param[in] occ - the occ name, such as occ0.
160 */
161 void createObjects(const std::string& occ);
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +0530162
Gunnar Mills94df8c92018-09-14 14:50:03 -0500163 /** @brief Callback handler invoked by Status object when the OccActive
164 * property is changed. This is needed to make sure that the
165 * error detection is started only after all the OCCs are bound.
166 * Similarly, when one of the OCC gets its OccActive property
167 * un-set, then the OCC error detection needs to be stopped on
168 * all the OCCs
169 *
170 * @param[in] status - OccActive status
171 */
172 void statusCallBack(bool status);
Vishwanatha Subbanna2dc9b1a2017-08-18 18:29:41 +0530173
Gunnar Mills94df8c92018-09-14 14:50:03 -0500174 /** @brief Sends a Heartbeat command to host control command handler */
175 void sendHeartBeat();
Vishwanatha Subbanna2dc9b1a2017-08-18 18:29:41 +0530176
Gunnar Mills94df8c92018-09-14 14:50:03 -0500177 /** @brief reference to sd_event wrapped in unique_ptr */
178 EventPtr& event;
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530179
Gunnar Mills94df8c92018-09-14 14:50:03 -0500180 /** @brief OCC pass-through objects */
181 std::vector<std::unique_ptr<PassThrough>> passThroughObjects;
Vishwanatha Subbanna307d80b2017-06-28 15:56:09 +0530182
Gunnar Mills94df8c92018-09-14 14:50:03 -0500183 /** @brief OCC Status objects */
184 std::vector<std::unique_ptr<Status>> statusObjects;
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +0530185
Chris Cain78e86012021-03-04 16:15:31 -0600186#ifdef POWER10
187 /** @brief Power mode monitor and notification object */
188 std::unique_ptr<open_power::occ::powermode::PowerMode> pmode;
189#endif
190
Gunnar Mills94df8c92018-09-14 14:50:03 -0500191 /** @brief sbdbusplus match objects */
192 std::vector<sdbusplus::bus::match_t> cpuMatches;
Vishwanatha Subbanna2dc9b1a2017-08-18 18:29:41 +0530193
Gunnar Mills94df8c92018-09-14 14:50:03 -0500194 /** @brief Number of OCCs that are bound */
195 uint8_t activeCount = 0;
Lei YU0ab90ca2017-07-13 17:02:23 +0800196
Chris Caina8857c52021-01-27 11:53:05 -0600197 /** @brief Number of seconds between poll commands */
198 uint8_t pollInterval;
199
Chris Cain17257672021-10-22 13:41:03 -0500200 /** @brief Ambient temperature of the system in degrees C */
201 uint8_t ambient = 0xFF; // default: not available
202
203 /** @brief Altitude of the system in meters */
204 uint16_t altitude = 0xFFFF; // default: not available
205
Chris Caina8857c52021-01-27 11:53:05 -0600206 /** @brief Poll timer event */
207 sdeventplus::Event sdpEvent;
208
209 /**
210 * @brief The timer to be used once the OCC goes active. When it expires,
211 * a POLL command will be sent to the OCC and then timer restarted.
212 */
213 std::unique_ptr<
214 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>>
215 _pollTimer;
216
Chris Cain17257672021-10-22 13:41:03 -0500217 /** @brief Subscribe to ambient temperature changed events */
218 sdbusplus::bus::match_t ambientPropChanged;
219
Lei YU0ab90ca2017-07-13 17:02:23 +0800220#ifdef I2C_OCC
Gunnar Mills94df8c92018-09-14 14:50:03 -0500221 /** @brief Init Status objects for I2C OCC devices
222 *
223 * It iterates in /sys/bus/i2c/devices, finds all occ hwmon devices
224 * and creates status objects.
225 */
226 void initStatusObjects();
Lei YU0ab90ca2017-07-13 17:02:23 +0800227#endif
Tom Joseph815f9f52020-07-27 12:12:13 +0530228
229#ifdef PLDM
230 /** @brief Callback handler invoked by the PLDM event handler when state of
231 * the OCC is toggled by the host. The caller passes the instance
232 * of the OCC and state of the OCC.
233 *
234 * @param[in] instance - instance of the OCC
235 * @param[in] status - true when the OCC goes active and false when the OCC
236 * goes inactive
237 *
238 * @return true if setting the state of OCC is successful and false if it
239 * fails.
240 */
241 bool updateOCCActive(instanceID instance, bool status);
242
Eddie Jamescbad2192021-10-07 09:39:39 -0500243 /** @brief Callback handler invoked by PLDM sensor change when
244 * the HRESET succeeds or fails.
245 *
246 * @param[in] instance - the SBE instance id
247 * @param[in] success - true if the HRESET succeeded, otherwise false
248 */
249 void sbeHRESETResult(instanceID instance, bool success);
250
251 /** @brief Helper function to check whether an SBE dump should be collected
252 * now.
253 *
254 * @param[in] instance - the SBE instance id
255 *
256 * @return true if an SBE dump should be collected and false if not
257 */
258 bool sbeCanDump(unsigned int instance);
259
260 /** @brief Helper function to set the SBE state through PDBG/PHAL
261 *
262 * @param[in] instance - instance of the SBE
263 * @param[in] state - the state to which the SBE should be set
264 *
265 */
266 void setSBEState(unsigned int instance, enum sbe_state state);
267
268 /** @brief Helper function to get the SBE instance PDBG processor target
269 *
270 * @param[in] instance - the SBE instance id
271 *
272 * @return a pointer to the PDBG target
273 */
274 struct pdbg_target* getPdbgTarget(unsigned int instance);
275
276 /** @brief Whether pdbg_targets_init has been called */
277 bool pdbgInitialized = false;
278
Tom Joseph815f9f52020-07-27 12:12:13 +0530279 std::unique_ptr<pldm::Interface> pldmHandle = nullptr;
280#endif
Chris Caina8857c52021-01-27 11:53:05 -0600281
Matt Spinlerd267cec2021-09-01 14:49:19 -0500282#ifdef POWER10
283 /**
284 * @brief Timer used when discovering OCCs in /dev.
285 */
286 std::unique_ptr<
287 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>>
288 discoverTimer;
289
290 /**
291 * @brief Used when discovering /dev/occ objects to know if
292 * any were added since the last check.
293 */
294 std::vector<int> prevOCCSearch;
Chris Caina7b74dc2021-11-10 17:03:43 -0600295
296 /**
297 * @brief Timer used when waiting for OCCs to go active.
298 */
299 std::unique_ptr<
300 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>>
301 waitForAllOccsTimer;
302
303 /** @brief Called when code times out waiting for all OCCs to be running or
304 * after the app is restarted (Status does not callback into
305 * Manager).
306 */
307 void occsNotAllRunning();
Matt Spinlerd267cec2021-09-01 14:49:19 -0500308#endif
309
Chris Caina8857c52021-01-27 11:53:05 -0600310 /**
311 * @brief Called when poll timer expires and forces a POLL command to the
312 * OCC. The poll timer will then be restarted.
313 * */
314 void pollerTimerExpired();
Chicago Duanbb895cb2021-06-18 19:37:16 +0800315
Matt Spinlerd267cec2021-09-01 14:49:19 -0500316 /**
317 * @brief Finds the OCC devices in /dev
318 *
319 * @return The IDs of the OCCs - 0, 1, etc.
320 */
321 std::vector<int> findOCCsInDev();
322
Chicago Duanbb895cb2021-06-18 19:37:16 +0800323#ifdef READ_OCC_SENSORS
324 /**
325 * @brief Gets the occ sensor values.
Chris Cain5d66a0a2022-02-09 08:52:10 -0600326 * @param[in] occ - pointer to OCCs Status object
Chicago Duanbb895cb2021-06-18 19:37:16 +0800327 * */
Chris Cain5d66a0a2022-02-09 08:52:10 -0600328 void getSensorValues(std::unique_ptr<Status>& occ);
Chicago Duanbb895cb2021-06-18 19:37:16 +0800329
330 /**
331 * @brief Trigger OCC driver to read the temperature sensors.
332 * @param[in] path - path of the OCC sensors.
333 * @param[in] id - Id of the OCC.
334 * */
335 void readTempSensors(const fs::path& path, uint32_t id);
336
337 /**
338 * @brief Trigger OCC driver to read the power sensors.
339 * @param[in] path - path of the OCC sensors.
340 * @param[in] id - Id of the OCC.
341 * */
342 void readPowerSensors(const fs::path& path, uint32_t id);
343
344 /**
345 * @brief Set all sensor values of this OCC to NaN.
346 * @param[in] id - Id of the OCC.
347 * */
348 void setSensorValueToNaN(uint32_t id);
349
350 /** @brief Store the existing OCC sensors on D-BUS */
351 std::map<std::string, uint32_t> existingSensors;
352
353 /** @brief Get FunctionID from the `powerX_label` file.
354 * @param[in] value - the value of the `powerX_label` file.
355 * @returns FunctionID of the power sensors.
356 */
357 std::optional<std::string>
358 getPowerLabelFunctionID(const std::string& value);
359
360 /** @brief The power sensor names map */
361 const std::map<std::string, std::string> powerSensorName = {
362 {"system", "total_power"}, {"1", "p0_mem_power"},
363 {"2", "p1_mem_power"}, {"3", "p2_mem_power"},
364 {"4", "p3_mem_power"}, {"5", "p0_power"},
365 {"6", "p1_power"}, {"7", "p2_power"},
366 {"8", "p3_power"}, {"9", "p0_cache_power"},
367 {"10", "p1_cache_power"}, {"11", "p2_cache_power"},
368 {"12", "p3_cache_power"}, {"13", "io_a_power"},
369 {"14", "io_b_power"}, {"15", "io_c_power"},
370 {"16", "fans_a_power"}, {"17", "fans_b_power"},
371 {"18", "storage_a_power"}, {"19", "storage_b_power"},
372 {"23", "mem_cache_power"}, {"25", "p0_mem_0_power"},
373 {"26", "p0_mem_1_power"}, {"27", "p0_mem_2_power"}};
374
375 /** @brief The dimm temperature sensor names map */
376 const std::map<uint32_t, std::string> dimmTempSensorName = {
377 {internalMemCtlr, "_intmb_temp"},
378 {dimm, "_dram_temp"},
379 {memCtrlAndDimm, "_dram_extmb_temp"},
380 {PMIC, "_pmic_temp"},
381 {memCtlrExSensor, "_extmb_temp"}};
382#endif
Chris Cain17257672021-10-22 13:41:03 -0500383
384 /** @brief Read the altitude from DBus */
385 void readAltitude();
386
387 /** @brief Callback function when ambient temperature changes
388 *
389 * @param[in] msg - Data associated with subscribed signal
390 */
391 void ambientCallback(sdbusplus::message::message& msg);
Chris Caina7b74dc2021-11-10 17:03:43 -0600392
393 /** @brief Confirm that a single OCC master was found and start presence
394 * monitoring
395 */
396 void validateOccMaster();
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +0530397};
398
399} // namespace occ
400} // namespace open_power