blob: e6e7a18023c92e5af01b54aed77660debce2239f [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
Vishwanatha Subbannadfc7ec72017-09-07 18:18:01 +053010#include "powercap.hpp"
George Liuf3b75142021-06-10 11:22:50 +080011#include "utils.hpp"
Chris Cain78e86012021-03-04 16:15:31 -060012#ifdef POWER10
13#include "powermode.hpp"
14#endif
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +053015
Gunnar Mills94df8c92018-09-14 14:50:03 -050016#include <sdbusplus/bus.hpp>
Chris Caina8857c52021-01-27 11:53:05 -060017#include <sdeventplus/event.hpp>
18#include <sdeventplus/utility/timer.hpp>
George Liub5ca1012021-09-10 12:53:11 +080019
20#include <cstring>
21#include <functional>
Gunnar Mills94df8c92018-09-14 14:50:03 -050022#include <vector>
23
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +053024namespace sdbusRule = sdbusplus::bus::match::rules;
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +053025namespace open_power
26{
27namespace occ
28{
29
Chicago Duanbb895cb2021-06-18 19:37:16 +080030#ifdef READ_OCC_SENSORS
31enum occFruType
32{
33 processorCore = 0,
34 internalMemCtlr = 1,
35 dimm = 2,
36 memCtrlAndDimm = 3,
37 VRMVdd = 6,
38 PMIC = 7,
39 memCtlrExSensor = 8
40};
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
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +053050/** @class Manager
51 * @brief Builds and manages OCC objects
52 */
53struct Manager
54{
Gunnar Mills94df8c92018-09-14 14:50:03 -050055 public:
56 Manager() = delete;
57 Manager(const Manager&) = delete;
58 Manager& operator=(const Manager&) = delete;
59 Manager(Manager&&) = delete;
60 Manager& operator=(Manager&&) = delete;
61 ~Manager() = default;
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +053062
Gunnar Mills94df8c92018-09-14 14:50:03 -050063 /** @brief Adds OCC pass-through and status objects on the bus
64 * when corresponding CPU inventory is created.
65 *
Gunnar Mills94df8c92018-09-14 14:50:03 -050066 * @param[in] event - Unique ptr reference to sd_event
67 */
George Liuf3b75142021-06-10 11:22:50 +080068 Manager(EventPtr& event) :
69 event(event), pollInterval(defaultPollingInterval),
Chris Caina8857c52021-01-27 11:53:05 -060070 sdpEvent(sdeventplus::Event::get_default()),
71 _pollTimer(
72 std::make_unique<
73 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>>(
74 sdpEvent, std::bind(&Manager::pollerTimerExpired, this)))
Tom Joseph815f9f52020-07-27 12:12:13 +053075#ifdef PLDM
76 ,
77 pldmHandle(std::make_unique<pldm::Interface>(
George Liuf3b75142021-06-10 11:22:50 +080078 std::bind(std::mem_fn(&Manager::updateOCCActive), this,
Eddie Jamescbad2192021-10-07 09:39:39 -050079 std::placeholders::_1, std::placeholders::_2),
80 std::bind(std::mem_fn(&Manager::sbeHRESETResult), this,
George Liuf3b75142021-06-10 11:22:50 +080081 std::placeholders::_1, std::placeholders::_2)))
Tom Joseph815f9f52020-07-27 12:12:13 +053082#endif
Matt Spinlerd267cec2021-09-01 14:49:19 -050083#ifdef POWER10
84 ,
85 discoverTimer(
86 std::make_unique<
87 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>>(
88 sdpEvent, std::bind(&Manager::findAndCreateObjects, this)))
89#endif
Gunnar Mills94df8c92018-09-14 14:50:03 -050090 {
Lei YU0ab90ca2017-07-13 17:02:23 +080091#ifdef I2C_OCC
Gunnar Mills94df8c92018-09-14 14:50:03 -050092 // I2C OCC status objects are initialized directly
93 initStatusObjects();
Lei YU0ab90ca2017-07-13 17:02:23 +080094#else
Gunnar Mills94df8c92018-09-14 14:50:03 -050095 findAndCreateObjects();
Lei YU0ab90ca2017-07-13 17:02:23 +080096#endif
Gunnar Mills94df8c92018-09-14 14:50:03 -050097 }
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +053098
Chris Caina8857c52021-01-27 11:53:05 -060099 /** @brief Return the number of bound OCCs */
Gunnar Mills94df8c92018-09-14 14:50:03 -0500100 inline auto getNumOCCs() const
101 {
102 return activeCount;
103 }
Edward A. James636577f2017-10-06 10:53:55 -0500104
Eddie Jamescbad2192021-10-07 09:39:39 -0500105#ifdef PLDM
106 /** @brief Called by a Device to report that the SBE timed out
107 * and appropriate action should be taken
108 *
109 * @param[in] instance - the OCC instance id
110 */
111 void sbeTimeout(unsigned int instance);
112#endif
113
Gunnar Mills94df8c92018-09-14 14:50:03 -0500114 private:
Matt Spinlerd267cec2021-09-01 14:49:19 -0500115 /** @brief Creates the OCC D-Bus objects.
Gunnar Mills94df8c92018-09-14 14:50:03 -0500116 */
117 void findAndCreateObjects();
Vishwanatha Subbannadfc7ec72017-09-07 18:18:01 +0530118
Gunnar Mills94df8c92018-09-14 14:50:03 -0500119 /** @brief Callback that responds to cpu creation in the inventory -
120 * by creating the needed objects.
121 *
122 * @param[in] msg - bus message
123 *
124 * @returns 0 to indicate success
125 */
126 int cpuCreated(sdbusplus::message::message& msg);
Deepak Kodihalli5f031f32017-07-26 08:25:59 -0500127
Gunnar Mills94df8c92018-09-14 14:50:03 -0500128 /** @brief Create child OCC objects.
129 *
130 * @param[in] occ - the occ name, such as occ0.
131 */
132 void createObjects(const std::string& occ);
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +0530133
Gunnar Mills94df8c92018-09-14 14:50:03 -0500134 /** @brief Callback handler invoked by Status object when the OccActive
135 * property is changed. This is needed to make sure that the
136 * error detection is started only after all the OCCs are bound.
137 * Similarly, when one of the OCC gets its OccActive property
138 * un-set, then the OCC error detection needs to be stopped on
139 * all the OCCs
140 *
141 * @param[in] status - OccActive status
142 */
143 void statusCallBack(bool status);
Vishwanatha Subbanna2dc9b1a2017-08-18 18:29:41 +0530144
Gunnar Mills94df8c92018-09-14 14:50:03 -0500145 /** @brief Sends a Heartbeat command to host control command handler */
146 void sendHeartBeat();
Vishwanatha Subbanna2dc9b1a2017-08-18 18:29:41 +0530147
Gunnar Mills94df8c92018-09-14 14:50:03 -0500148 /** @brief reference to sd_event wrapped in unique_ptr */
149 EventPtr& event;
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530150
Gunnar Mills94df8c92018-09-14 14:50:03 -0500151 /** @brief OCC pass-through objects */
152 std::vector<std::unique_ptr<PassThrough>> passThroughObjects;
Vishwanatha Subbanna307d80b2017-06-28 15:56:09 +0530153
Gunnar Mills94df8c92018-09-14 14:50:03 -0500154 /** @brief OCC Status objects */
155 std::vector<std::unique_ptr<Status>> statusObjects;
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +0530156
Gunnar Mills94df8c92018-09-14 14:50:03 -0500157 /** @brief Power cap monitor and occ notification object */
158 std::unique_ptr<open_power::occ::powercap::PowerCap> pcap;
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500159
Chris Cain78e86012021-03-04 16:15:31 -0600160#ifdef POWER10
161 /** @brief Power mode monitor and notification object */
162 std::unique_ptr<open_power::occ::powermode::PowerMode> pmode;
Chris Cain1d51da22021-09-21 14:13:41 -0500163
164 /** @brief Idle Power Saver monitor and notification object */
165 std::unique_ptr<open_power::occ::powermode::PowerIPS> pips;
Chris Cain78e86012021-03-04 16:15:31 -0600166#endif
167
Gunnar Mills94df8c92018-09-14 14:50:03 -0500168 /** @brief sbdbusplus match objects */
169 std::vector<sdbusplus::bus::match_t> cpuMatches;
Vishwanatha Subbanna2dc9b1a2017-08-18 18:29:41 +0530170
Gunnar Mills94df8c92018-09-14 14:50:03 -0500171 /** @brief Number of OCCs that are bound */
172 uint8_t activeCount = 0;
Lei YU0ab90ca2017-07-13 17:02:23 +0800173
Chris Caina8857c52021-01-27 11:53:05 -0600174 /** @brief Number of seconds between poll commands */
175 uint8_t pollInterval;
176
177 /** @brief Poll timer event */
178 sdeventplus::Event sdpEvent;
179
180 /**
181 * @brief The timer to be used once the OCC goes active. When it expires,
182 * a POLL command will be sent to the OCC and then timer restarted.
183 */
184 std::unique_ptr<
185 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>>
186 _pollTimer;
187
Lei YU0ab90ca2017-07-13 17:02:23 +0800188#ifdef I2C_OCC
Gunnar Mills94df8c92018-09-14 14:50:03 -0500189 /** @brief Init Status objects for I2C OCC devices
190 *
191 * It iterates in /sys/bus/i2c/devices, finds all occ hwmon devices
192 * and creates status objects.
193 */
194 void initStatusObjects();
Lei YU0ab90ca2017-07-13 17:02:23 +0800195#endif
Tom Joseph815f9f52020-07-27 12:12:13 +0530196
197#ifdef PLDM
198 /** @brief Callback handler invoked by the PLDM event handler when state of
199 * the OCC is toggled by the host. The caller passes the instance
200 * of the OCC and state of the OCC.
201 *
202 * @param[in] instance - instance of the OCC
203 * @param[in] status - true when the OCC goes active and false when the OCC
204 * goes inactive
205 *
206 * @return true if setting the state of OCC is successful and false if it
207 * fails.
208 */
209 bool updateOCCActive(instanceID instance, bool status);
210
Eddie Jamescbad2192021-10-07 09:39:39 -0500211 /** @brief Callback handler invoked by PLDM sensor change when
212 * the HRESET succeeds or fails.
213 *
214 * @param[in] instance - the SBE instance id
215 * @param[in] success - true if the HRESET succeeded, otherwise false
216 */
217 void sbeHRESETResult(instanceID instance, bool success);
218
219 /** @brief Helper function to check whether an SBE dump should be collected
220 * now.
221 *
222 * @param[in] instance - the SBE instance id
223 *
224 * @return true if an SBE dump should be collected and false if not
225 */
226 bool sbeCanDump(unsigned int instance);
227
228 /** @brief Helper function to set the SBE state through PDBG/PHAL
229 *
230 * @param[in] instance - instance of the SBE
231 * @param[in] state - the state to which the SBE should be set
232 *
233 */
234 void setSBEState(unsigned int instance, enum sbe_state state);
235
236 /** @brief Helper function to get the SBE instance PDBG processor target
237 *
238 * @param[in] instance - the SBE instance id
239 *
240 * @return a pointer to the PDBG target
241 */
242 struct pdbg_target* getPdbgTarget(unsigned int instance);
243
244 /** @brief Whether pdbg_targets_init has been called */
245 bool pdbgInitialized = false;
246
Tom Joseph815f9f52020-07-27 12:12:13 +0530247 std::unique_ptr<pldm::Interface> pldmHandle = nullptr;
248#endif
Chris Caina8857c52021-01-27 11:53:05 -0600249
Matt Spinlerd267cec2021-09-01 14:49:19 -0500250#ifdef POWER10
251 /**
252 * @brief Timer used when discovering OCCs in /dev.
253 */
254 std::unique_ptr<
255 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>>
256 discoverTimer;
257
258 /**
259 * @brief Used when discovering /dev/occ objects to know if
260 * any were added since the last check.
261 */
262 std::vector<int> prevOCCSearch;
263#endif
264
Chris Caina8857c52021-01-27 11:53:05 -0600265 /**
266 * @brief Called when poll timer expires and forces a POLL command to the
267 * OCC. The poll timer will then be restarted.
268 * */
269 void pollerTimerExpired();
Chicago Duanbb895cb2021-06-18 19:37:16 +0800270
Matt Spinlerd267cec2021-09-01 14:49:19 -0500271 /**
272 * @brief Finds the OCC devices in /dev
273 *
274 * @return The IDs of the OCCs - 0, 1, etc.
275 */
276 std::vector<int> findOCCsInDev();
277
Chicago Duanbb895cb2021-06-18 19:37:16 +0800278#ifdef READ_OCC_SENSORS
279 /**
280 * @brief Gets the occ sensor values.
281 * @param[in] id - Id of the OCC.
282 * @param[in] masterOcc - Is this OCC the master OCC.
283 * */
284 void getSensorValues(uint32_t id, bool masterOcc);
285
286 /**
287 * @brief Trigger OCC driver to read the temperature sensors.
288 * @param[in] path - path of the OCC sensors.
289 * @param[in] id - Id of the OCC.
290 * */
291 void readTempSensors(const fs::path& path, uint32_t id);
292
293 /**
294 * @brief Trigger OCC driver to read the power sensors.
295 * @param[in] path - path of the OCC sensors.
296 * @param[in] id - Id of the OCC.
297 * */
298 void readPowerSensors(const fs::path& path, uint32_t id);
299
300 /**
301 * @brief Set all sensor values of this OCC to NaN.
302 * @param[in] id - Id of the OCC.
303 * */
304 void setSensorValueToNaN(uint32_t id);
305
306 /** @brief Store the existing OCC sensors on D-BUS */
307 std::map<std::string, uint32_t> existingSensors;
308
309 /** @brief Get FunctionID from the `powerX_label` file.
310 * @param[in] value - the value of the `powerX_label` file.
311 * @returns FunctionID of the power sensors.
312 */
313 std::optional<std::string>
314 getPowerLabelFunctionID(const std::string& value);
315
316 /** @brief The power sensor names map */
317 const std::map<std::string, std::string> powerSensorName = {
318 {"system", "total_power"}, {"1", "p0_mem_power"},
319 {"2", "p1_mem_power"}, {"3", "p2_mem_power"},
320 {"4", "p3_mem_power"}, {"5", "p0_power"},
321 {"6", "p1_power"}, {"7", "p2_power"},
322 {"8", "p3_power"}, {"9", "p0_cache_power"},
323 {"10", "p1_cache_power"}, {"11", "p2_cache_power"},
324 {"12", "p3_cache_power"}, {"13", "io_a_power"},
325 {"14", "io_b_power"}, {"15", "io_c_power"},
326 {"16", "fans_a_power"}, {"17", "fans_b_power"},
327 {"18", "storage_a_power"}, {"19", "storage_b_power"},
328 {"23", "mem_cache_power"}, {"25", "p0_mem_0_power"},
329 {"26", "p0_mem_1_power"}, {"27", "p0_mem_2_power"}};
330
331 /** @brief The dimm temperature sensor names map */
332 const std::map<uint32_t, std::string> dimmTempSensorName = {
333 {internalMemCtlr, "_intmb_temp"},
334 {dimm, "_dram_temp"},
335 {memCtrlAndDimm, "_dram_extmb_temp"},
336 {PMIC, "_pmic_temp"},
337 {memCtlrExSensor, "_extmb_temp"}};
338#endif
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +0530339};
340
341} // namespace occ
342} // namespace open_power