blob: 43cc32f049d94412f6d707bda5f510d9e9fd5228 [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;
150#endif
151
Gunnar Mills94df8c92018-09-14 14:50:03 -0500152 /** @brief sbdbusplus match objects */
153 std::vector<sdbusplus::bus::match_t> cpuMatches;
Vishwanatha Subbanna2dc9b1a2017-08-18 18:29:41 +0530154
Gunnar Mills94df8c92018-09-14 14:50:03 -0500155 /** @brief Number of OCCs that are bound */
156 uint8_t activeCount = 0;
Lei YU0ab90ca2017-07-13 17:02:23 +0800157
Chris Caina8857c52021-01-27 11:53:05 -0600158 /** @brief Number of seconds between poll commands */
159 uint8_t pollInterval;
160
161 /** @brief Poll timer event */
162 sdeventplus::Event sdpEvent;
163
164 /**
165 * @brief The timer to be used once the OCC goes active. When it expires,
166 * a POLL command will be sent to the OCC and then timer restarted.
167 */
168 std::unique_ptr<
169 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>>
170 _pollTimer;
171
Lei YU0ab90ca2017-07-13 17:02:23 +0800172#ifdef I2C_OCC
Gunnar Mills94df8c92018-09-14 14:50:03 -0500173 /** @brief Init Status objects for I2C OCC devices
174 *
175 * It iterates in /sys/bus/i2c/devices, finds all occ hwmon devices
176 * and creates status objects.
177 */
178 void initStatusObjects();
Lei YU0ab90ca2017-07-13 17:02:23 +0800179#endif
Tom Joseph815f9f52020-07-27 12:12:13 +0530180
181#ifdef PLDM
182 /** @brief Callback handler invoked by the PLDM event handler when state of
183 * the OCC is toggled by the host. The caller passes the instance
184 * of the OCC and state of the OCC.
185 *
186 * @param[in] instance - instance of the OCC
187 * @param[in] status - true when the OCC goes active and false when the OCC
188 * goes inactive
189 *
190 * @return true if setting the state of OCC is successful and false if it
191 * fails.
192 */
193 bool updateOCCActive(instanceID instance, bool status);
194
195 std::unique_ptr<pldm::Interface> pldmHandle = nullptr;
196#endif
Chris Caina8857c52021-01-27 11:53:05 -0600197
Matt Spinlerd267cec2021-09-01 14:49:19 -0500198#ifdef POWER10
199 /**
200 * @brief Timer used when discovering OCCs in /dev.
201 */
202 std::unique_ptr<
203 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>>
204 discoverTimer;
205
206 /**
207 * @brief Used when discovering /dev/occ objects to know if
208 * any were added since the last check.
209 */
210 std::vector<int> prevOCCSearch;
211#endif
212
Chris Caina8857c52021-01-27 11:53:05 -0600213 /**
214 * @brief Called when poll timer expires and forces a POLL command to the
215 * OCC. The poll timer will then be restarted.
216 * */
217 void pollerTimerExpired();
Chicago Duanbb895cb2021-06-18 19:37:16 +0800218
Matt Spinlerd267cec2021-09-01 14:49:19 -0500219 /**
220 * @brief Finds the OCC devices in /dev
221 *
222 * @return The IDs of the OCCs - 0, 1, etc.
223 */
224 std::vector<int> findOCCsInDev();
225
Chicago Duanbb895cb2021-06-18 19:37:16 +0800226#ifdef READ_OCC_SENSORS
227 /**
228 * @brief Gets the occ sensor values.
229 * @param[in] id - Id of the OCC.
230 * @param[in] masterOcc - Is this OCC the master OCC.
231 * */
232 void getSensorValues(uint32_t id, bool masterOcc);
233
234 /**
235 * @brief Trigger OCC driver to read the temperature sensors.
236 * @param[in] path - path of the OCC sensors.
237 * @param[in] id - Id of the OCC.
238 * */
239 void readTempSensors(const fs::path& path, uint32_t id);
240
241 /**
242 * @brief Trigger OCC driver to read the power sensors.
243 * @param[in] path - path of the OCC sensors.
244 * @param[in] id - Id of the OCC.
245 * */
246 void readPowerSensors(const fs::path& path, uint32_t id);
247
248 /**
249 * @brief Set all sensor values of this OCC to NaN.
250 * @param[in] id - Id of the OCC.
251 * */
252 void setSensorValueToNaN(uint32_t id);
253
254 /** @brief Store the existing OCC sensors on D-BUS */
255 std::map<std::string, uint32_t> existingSensors;
256
257 /** @brief Get FunctionID from the `powerX_label` file.
258 * @param[in] value - the value of the `powerX_label` file.
259 * @returns FunctionID of the power sensors.
260 */
261 std::optional<std::string>
262 getPowerLabelFunctionID(const std::string& value);
263
264 /** @brief The power sensor names map */
265 const std::map<std::string, std::string> powerSensorName = {
266 {"system", "total_power"}, {"1", "p0_mem_power"},
267 {"2", "p1_mem_power"}, {"3", "p2_mem_power"},
268 {"4", "p3_mem_power"}, {"5", "p0_power"},
269 {"6", "p1_power"}, {"7", "p2_power"},
270 {"8", "p3_power"}, {"9", "p0_cache_power"},
271 {"10", "p1_cache_power"}, {"11", "p2_cache_power"},
272 {"12", "p3_cache_power"}, {"13", "io_a_power"},
273 {"14", "io_b_power"}, {"15", "io_c_power"},
274 {"16", "fans_a_power"}, {"17", "fans_b_power"},
275 {"18", "storage_a_power"}, {"19", "storage_b_power"},
276 {"23", "mem_cache_power"}, {"25", "p0_mem_0_power"},
277 {"26", "p0_mem_1_power"}, {"27", "p0_mem_2_power"}};
278
279 /** @brief The dimm temperature sensor names map */
280 const std::map<uint32_t, std::string> dimmTempSensorName = {
281 {internalMemCtlr, "_intmb_temp"},
282 {dimm, "_dram_temp"},
283 {memCtrlAndDimm, "_dram_extmb_temp"},
284 {PMIC, "_pmic_temp"},
285 {memCtlrExSensor, "_extmb_temp"}};
286#endif
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +0530287};
288
289} // namespace occ
290} // namespace open_power