blob: 5b97abc8954f2f9a8c04ff95a0edd39d20f48110 [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"
7#endif
Vishwanatha Subbannadfc7ec72017-09-07 18:18:01 +05308#include "powercap.hpp"
George Liuf3b75142021-06-10 11:22:50 +08009#include "utils.hpp"
Chris Cain78e86012021-03-04 16:15:31 -060010#ifdef POWER10
11#include "powermode.hpp"
12#endif
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +053013
Gunnar Mills94df8c92018-09-14 14:50:03 -050014#include <sdbusplus/bus.hpp>
Chris Caina8857c52021-01-27 11:53:05 -060015#include <sdeventplus/event.hpp>
16#include <sdeventplus/utility/timer.hpp>
George Liub5ca1012021-09-10 12:53:11 +080017
18#include <cstring>
19#include <functional>
Gunnar Mills94df8c92018-09-14 14:50:03 -050020#include <vector>
21
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +053022namespace sdbusRule = sdbusplus::bus::match::rules;
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +053023namespace open_power
24{
25namespace occ
26{
27
Chicago Duanbb895cb2021-06-18 19:37:16 +080028#ifdef READ_OCC_SENSORS
29enum occFruType
30{
31 processorCore = 0,
32 internalMemCtlr = 1,
33 dimm = 2,
34 memCtrlAndDimm = 3,
35 VRMVdd = 6,
36 PMIC = 7,
37 memCtlrExSensor = 8
38};
39#endif
40
Chris Caina8857c52021-01-27 11:53:05 -060041/** @brief Default time, in seconds, between OCC poll commands */
Matt Spinler37923462021-09-24 11:38:05 -050042#ifndef POWER10
Chicago Duanbb895cb2021-06-18 19:37:16 +080043constexpr unsigned int defaultPollingInterval = 1;
Matt Spinler37923462021-09-24 11:38:05 -050044#else
45constexpr unsigned int defaultPollingInterval = 5;
46#endif
Chris Caina8857c52021-01-27 11:53:05 -060047
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +053048/** @class Manager
49 * @brief Builds and manages OCC objects
50 */
51struct Manager
52{
Gunnar Mills94df8c92018-09-14 14:50:03 -050053 public:
54 Manager() = delete;
55 Manager(const Manager&) = delete;
56 Manager& operator=(const Manager&) = delete;
57 Manager(Manager&&) = delete;
58 Manager& operator=(Manager&&) = delete;
59 ~Manager() = default;
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +053060
Gunnar Mills94df8c92018-09-14 14:50:03 -050061 /** @brief Adds OCC pass-through and status objects on the bus
62 * when corresponding CPU inventory is created.
63 *
Gunnar Mills94df8c92018-09-14 14:50:03 -050064 * @param[in] event - Unique ptr reference to sd_event
65 */
George Liuf3b75142021-06-10 11:22:50 +080066 Manager(EventPtr& event) :
67 event(event), pollInterval(defaultPollingInterval),
Chris Caina8857c52021-01-27 11:53:05 -060068 sdpEvent(sdeventplus::Event::get_default()),
69 _pollTimer(
70 std::make_unique<
71 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>>(
72 sdpEvent, std::bind(&Manager::pollerTimerExpired, this)))
Tom Joseph815f9f52020-07-27 12:12:13 +053073#ifdef PLDM
74 ,
75 pldmHandle(std::make_unique<pldm::Interface>(
George Liuf3b75142021-06-10 11:22:50 +080076 std::bind(std::mem_fn(&Manager::updateOCCActive), this,
77 std::placeholders::_1, std::placeholders::_2)))
Tom Joseph815f9f52020-07-27 12:12:13 +053078#endif
Matt Spinlerd267cec2021-09-01 14:49:19 -050079#ifdef POWER10
80 ,
81 discoverTimer(
82 std::make_unique<
83 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>>(
84 sdpEvent, std::bind(&Manager::findAndCreateObjects, this)))
85#endif
Gunnar Mills94df8c92018-09-14 14:50:03 -050086 {
Lei YU0ab90ca2017-07-13 17:02:23 +080087#ifdef I2C_OCC
Gunnar Mills94df8c92018-09-14 14:50:03 -050088 // I2C OCC status objects are initialized directly
89 initStatusObjects();
Lei YU0ab90ca2017-07-13 17:02:23 +080090#else
Gunnar Mills94df8c92018-09-14 14:50:03 -050091 findAndCreateObjects();
Lei YU0ab90ca2017-07-13 17:02:23 +080092#endif
Gunnar Mills94df8c92018-09-14 14:50:03 -050093 }
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +053094
Chris Caina8857c52021-01-27 11:53:05 -060095 /** @brief Return the number of bound OCCs */
Gunnar Mills94df8c92018-09-14 14:50:03 -050096 inline auto getNumOCCs() const
97 {
98 return activeCount;
99 }
Edward A. James636577f2017-10-06 10:53:55 -0500100
Gunnar Mills94df8c92018-09-14 14:50:03 -0500101 private:
Matt Spinlerd267cec2021-09-01 14:49:19 -0500102 /** @brief Creates the OCC D-Bus objects.
Gunnar Mills94df8c92018-09-14 14:50:03 -0500103 */
104 void findAndCreateObjects();
Vishwanatha Subbannadfc7ec72017-09-07 18:18:01 +0530105
Gunnar Mills94df8c92018-09-14 14:50:03 -0500106 /** @brief Callback that responds to cpu creation in the inventory -
107 * by creating the needed objects.
108 *
109 * @param[in] msg - bus message
110 *
111 * @returns 0 to indicate success
112 */
113 int cpuCreated(sdbusplus::message::message& msg);
Deepak Kodihalli5f031f32017-07-26 08:25:59 -0500114
Gunnar Mills94df8c92018-09-14 14:50:03 -0500115 /** @brief Create child OCC objects.
116 *
117 * @param[in] occ - the occ name, such as occ0.
118 */
119 void createObjects(const std::string& occ);
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +0530120
Gunnar Mills94df8c92018-09-14 14:50:03 -0500121 /** @brief Callback handler invoked by Status object when the OccActive
122 * property is changed. This is needed to make sure that the
123 * error detection is started only after all the OCCs are bound.
124 * Similarly, when one of the OCC gets its OccActive property
125 * un-set, then the OCC error detection needs to be stopped on
126 * all the OCCs
127 *
128 * @param[in] status - OccActive status
129 */
130 void statusCallBack(bool status);
Vishwanatha Subbanna2dc9b1a2017-08-18 18:29:41 +0530131
Gunnar Mills94df8c92018-09-14 14:50:03 -0500132 /** @brief Sends a Heartbeat command to host control command handler */
133 void sendHeartBeat();
Vishwanatha Subbanna2dc9b1a2017-08-18 18:29:41 +0530134
Gunnar Mills94df8c92018-09-14 14:50:03 -0500135 /** @brief reference to sd_event wrapped in unique_ptr */
136 EventPtr& event;
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530137
Gunnar Mills94df8c92018-09-14 14:50:03 -0500138 /** @brief OCC pass-through objects */
139 std::vector<std::unique_ptr<PassThrough>> passThroughObjects;
Vishwanatha Subbanna307d80b2017-06-28 15:56:09 +0530140
Gunnar Mills94df8c92018-09-14 14:50:03 -0500141 /** @brief OCC Status objects */
142 std::vector<std::unique_ptr<Status>> statusObjects;
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +0530143
Gunnar Mills94df8c92018-09-14 14:50:03 -0500144 /** @brief Power cap monitor and occ notification object */
145 std::unique_ptr<open_power::occ::powercap::PowerCap> pcap;
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500146
Chris Cain78e86012021-03-04 16:15:31 -0600147#ifdef POWER10
148 /** @brief Power mode monitor and notification object */
149 std::unique_ptr<open_power::occ::powermode::PowerMode> pmode;
Chris Cain1d51da22021-09-21 14:13:41 -0500150
151 /** @brief Idle Power Saver monitor and notification object */
152 std::unique_ptr<open_power::occ::powermode::PowerIPS> pips;
Chris Cain78e86012021-03-04 16:15:31 -0600153#endif
154
Gunnar Mills94df8c92018-09-14 14:50:03 -0500155 /** @brief sbdbusplus match objects */
156 std::vector<sdbusplus::bus::match_t> cpuMatches;
Vishwanatha Subbanna2dc9b1a2017-08-18 18:29:41 +0530157
Gunnar Mills94df8c92018-09-14 14:50:03 -0500158 /** @brief Number of OCCs that are bound */
159 uint8_t activeCount = 0;
Lei YU0ab90ca2017-07-13 17:02:23 +0800160
Chris Caina8857c52021-01-27 11:53:05 -0600161 /** @brief Number of seconds between poll commands */
162 uint8_t pollInterval;
163
164 /** @brief Poll timer event */
165 sdeventplus::Event sdpEvent;
166
167 /**
168 * @brief The timer to be used once the OCC goes active. When it expires,
169 * a POLL command will be sent to the OCC and then timer restarted.
170 */
171 std::unique_ptr<
172 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>>
173 _pollTimer;
174
Lei YU0ab90ca2017-07-13 17:02:23 +0800175#ifdef I2C_OCC
Gunnar Mills94df8c92018-09-14 14:50:03 -0500176 /** @brief Init Status objects for I2C OCC devices
177 *
178 * It iterates in /sys/bus/i2c/devices, finds all occ hwmon devices
179 * and creates status objects.
180 */
181 void initStatusObjects();
Lei YU0ab90ca2017-07-13 17:02:23 +0800182#endif
Tom Joseph815f9f52020-07-27 12:12:13 +0530183
184#ifdef PLDM
185 /** @brief Callback handler invoked by the PLDM event handler when state of
186 * the OCC is toggled by the host. The caller passes the instance
187 * of the OCC and state of the OCC.
188 *
189 * @param[in] instance - instance of the OCC
190 * @param[in] status - true when the OCC goes active and false when the OCC
191 * goes inactive
192 *
193 * @return true if setting the state of OCC is successful and false if it
194 * fails.
195 */
196 bool updateOCCActive(instanceID instance, bool status);
197
198 std::unique_ptr<pldm::Interface> pldmHandle = nullptr;
199#endif
Chris Caina8857c52021-01-27 11:53:05 -0600200
Matt Spinlerd267cec2021-09-01 14:49:19 -0500201#ifdef POWER10
202 /**
203 * @brief Timer used when discovering OCCs in /dev.
204 */
205 std::unique_ptr<
206 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>>
207 discoverTimer;
208
209 /**
210 * @brief Used when discovering /dev/occ objects to know if
211 * any were added since the last check.
212 */
213 std::vector<int> prevOCCSearch;
214#endif
215
Chris Caina8857c52021-01-27 11:53:05 -0600216 /**
217 * @brief Called when poll timer expires and forces a POLL command to the
218 * OCC. The poll timer will then be restarted.
219 * */
220 void pollerTimerExpired();
Chicago Duanbb895cb2021-06-18 19:37:16 +0800221
Matt Spinlerd267cec2021-09-01 14:49:19 -0500222 /**
223 * @brief Finds the OCC devices in /dev
224 *
225 * @return The IDs of the OCCs - 0, 1, etc.
226 */
227 std::vector<int> findOCCsInDev();
228
Chicago Duanbb895cb2021-06-18 19:37:16 +0800229#ifdef READ_OCC_SENSORS
230 /**
231 * @brief Gets the occ sensor values.
232 * @param[in] id - Id of the OCC.
233 * @param[in] masterOcc - Is this OCC the master OCC.
234 * */
235 void getSensorValues(uint32_t id, bool masterOcc);
236
237 /**
238 * @brief Trigger OCC driver to read the temperature sensors.
239 * @param[in] path - path of the OCC sensors.
240 * @param[in] id - Id of the OCC.
241 * */
242 void readTempSensors(const fs::path& path, uint32_t id);
243
244 /**
245 * @brief Trigger OCC driver to read the power sensors.
246 * @param[in] path - path of the OCC sensors.
247 * @param[in] id - Id of the OCC.
248 * */
249 void readPowerSensors(const fs::path& path, uint32_t id);
250
251 /**
252 * @brief Set all sensor values of this OCC to NaN.
253 * @param[in] id - Id of the OCC.
254 * */
255 void setSensorValueToNaN(uint32_t id);
256
257 /** @brief Store the existing OCC sensors on D-BUS */
258 std::map<std::string, uint32_t> existingSensors;
259
260 /** @brief Get FunctionID from the `powerX_label` file.
261 * @param[in] value - the value of the `powerX_label` file.
262 * @returns FunctionID of the power sensors.
263 */
264 std::optional<std::string>
265 getPowerLabelFunctionID(const std::string& value);
266
267 /** @brief The power sensor names map */
268 const std::map<std::string, std::string> powerSensorName = {
269 {"system", "total_power"}, {"1", "p0_mem_power"},
270 {"2", "p1_mem_power"}, {"3", "p2_mem_power"},
271 {"4", "p3_mem_power"}, {"5", "p0_power"},
272 {"6", "p1_power"}, {"7", "p2_power"},
273 {"8", "p3_power"}, {"9", "p0_cache_power"},
274 {"10", "p1_cache_power"}, {"11", "p2_cache_power"},
275 {"12", "p3_cache_power"}, {"13", "io_a_power"},
276 {"14", "io_b_power"}, {"15", "io_c_power"},
277 {"16", "fans_a_power"}, {"17", "fans_b_power"},
278 {"18", "storage_a_power"}, {"19", "storage_b_power"},
279 {"23", "mem_cache_power"}, {"25", "p0_mem_0_power"},
280 {"26", "p0_mem_1_power"}, {"27", "p0_mem_2_power"}};
281
282 /** @brief The dimm temperature sensor names map */
283 const std::map<uint32_t, std::string> dimmTempSensorName = {
284 {internalMemCtlr, "_intmb_temp"},
285 {dimm, "_dram_temp"},
286 {memCtrlAndDimm, "_dram_extmb_temp"},
287 {PMIC, "_pmic_temp"},
288 {memCtlrExSensor, "_extmb_temp"}};
289#endif
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +0530290};
291
292} // namespace occ
293} // namespace open_power