blob: dbb3cf69fbbc48fc88038470d733a979e7e0a910 [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 */
Chicago Duanbb895cb2021-06-18 19:37:16 +080042constexpr unsigned int defaultPollingInterval = 1;
Chris Caina8857c52021-01-27 11:53:05 -060043
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +053044/** @class Manager
45 * @brief Builds and manages OCC objects
46 */
47struct Manager
48{
Gunnar Mills94df8c92018-09-14 14:50:03 -050049 public:
50 Manager() = delete;
51 Manager(const Manager&) = delete;
52 Manager& operator=(const Manager&) = delete;
53 Manager(Manager&&) = delete;
54 Manager& operator=(Manager&&) = delete;
55 ~Manager() = default;
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +053056
Gunnar Mills94df8c92018-09-14 14:50:03 -050057 /** @brief Adds OCC pass-through and status objects on the bus
58 * when corresponding CPU inventory is created.
59 *
Gunnar Mills94df8c92018-09-14 14:50:03 -050060 * @param[in] event - Unique ptr reference to sd_event
61 */
George Liuf3b75142021-06-10 11:22:50 +080062 Manager(EventPtr& event) :
63 event(event), pollInterval(defaultPollingInterval),
Chris Caina8857c52021-01-27 11:53:05 -060064 sdpEvent(sdeventplus::Event::get_default()),
65 _pollTimer(
66 std::make_unique<
67 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>>(
68 sdpEvent, std::bind(&Manager::pollerTimerExpired, this)))
Tom Joseph815f9f52020-07-27 12:12:13 +053069#ifdef PLDM
70 ,
71 pldmHandle(std::make_unique<pldm::Interface>(
George Liuf3b75142021-06-10 11:22:50 +080072 std::bind(std::mem_fn(&Manager::updateOCCActive), this,
73 std::placeholders::_1, std::placeholders::_2)))
Tom Joseph815f9f52020-07-27 12:12:13 +053074#endif
Matt Spinlerd267cec2021-09-01 14:49:19 -050075#ifdef POWER10
76 ,
77 discoverTimer(
78 std::make_unique<
79 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>>(
80 sdpEvent, std::bind(&Manager::findAndCreateObjects, this)))
81#endif
Gunnar Mills94df8c92018-09-14 14:50:03 -050082 {
Lei YU0ab90ca2017-07-13 17:02:23 +080083#ifdef I2C_OCC
Gunnar Mills94df8c92018-09-14 14:50:03 -050084 // I2C OCC status objects are initialized directly
85 initStatusObjects();
Lei YU0ab90ca2017-07-13 17:02:23 +080086#else
Gunnar Mills94df8c92018-09-14 14:50:03 -050087 findAndCreateObjects();
Lei YU0ab90ca2017-07-13 17:02:23 +080088#endif
Gunnar Mills94df8c92018-09-14 14:50:03 -050089 }
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +053090
Chris Caina8857c52021-01-27 11:53:05 -060091 /** @brief Return the number of bound OCCs */
Gunnar Mills94df8c92018-09-14 14:50:03 -050092 inline auto getNumOCCs() const
93 {
94 return activeCount;
95 }
Edward A. James636577f2017-10-06 10:53:55 -050096
Gunnar Mills94df8c92018-09-14 14:50:03 -050097 private:
Matt Spinlerd267cec2021-09-01 14:49:19 -050098 /** @brief Creates the OCC D-Bus objects.
Gunnar Mills94df8c92018-09-14 14:50:03 -050099 */
100 void findAndCreateObjects();
Vishwanatha Subbannadfc7ec72017-09-07 18:18:01 +0530101
Gunnar Mills94df8c92018-09-14 14:50:03 -0500102 /** @brief Callback that responds to cpu creation in the inventory -
103 * by creating the needed objects.
104 *
105 * @param[in] msg - bus message
106 *
107 * @returns 0 to indicate success
108 */
109 int cpuCreated(sdbusplus::message::message& msg);
Deepak Kodihalli5f031f32017-07-26 08:25:59 -0500110
Gunnar Mills94df8c92018-09-14 14:50:03 -0500111 /** @brief Create child OCC objects.
112 *
113 * @param[in] occ - the occ name, such as occ0.
114 */
115 void createObjects(const std::string& occ);
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +0530116
Gunnar Mills94df8c92018-09-14 14:50:03 -0500117 /** @brief Callback handler invoked by Status object when the OccActive
118 * property is changed. This is needed to make sure that the
119 * error detection is started only after all the OCCs are bound.
120 * Similarly, when one of the OCC gets its OccActive property
121 * un-set, then the OCC error detection needs to be stopped on
122 * all the OCCs
123 *
124 * @param[in] status - OccActive status
125 */
126 void statusCallBack(bool status);
Vishwanatha Subbanna2dc9b1a2017-08-18 18:29:41 +0530127
Gunnar Mills94df8c92018-09-14 14:50:03 -0500128 /** @brief Sends a Heartbeat command to host control command handler */
129 void sendHeartBeat();
Vishwanatha Subbanna2dc9b1a2017-08-18 18:29:41 +0530130
Gunnar Mills94df8c92018-09-14 14:50:03 -0500131 /** @brief reference to sd_event wrapped in unique_ptr */
132 EventPtr& event;
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530133
Gunnar Mills94df8c92018-09-14 14:50:03 -0500134 /** @brief OCC pass-through objects */
135 std::vector<std::unique_ptr<PassThrough>> passThroughObjects;
Vishwanatha Subbanna307d80b2017-06-28 15:56:09 +0530136
Gunnar Mills94df8c92018-09-14 14:50:03 -0500137 /** @brief OCC Status objects */
138 std::vector<std::unique_ptr<Status>> statusObjects;
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +0530139
Gunnar Mills94df8c92018-09-14 14:50:03 -0500140 /** @brief Power cap monitor and occ notification object */
141 std::unique_ptr<open_power::occ::powercap::PowerCap> pcap;
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500142
Chris Cain78e86012021-03-04 16:15:31 -0600143#ifdef POWER10
144 /** @brief Power mode monitor and notification object */
145 std::unique_ptr<open_power::occ::powermode::PowerMode> pmode;
146#endif
147
Gunnar Mills94df8c92018-09-14 14:50:03 -0500148 /** @brief sbdbusplus match objects */
149 std::vector<sdbusplus::bus::match_t> cpuMatches;
Vishwanatha Subbanna2dc9b1a2017-08-18 18:29:41 +0530150
Gunnar Mills94df8c92018-09-14 14:50:03 -0500151 /** @brief Number of OCCs that are bound */
152 uint8_t activeCount = 0;
Lei YU0ab90ca2017-07-13 17:02:23 +0800153
Chris Caina8857c52021-01-27 11:53:05 -0600154 /** @brief Number of seconds between poll commands */
155 uint8_t pollInterval;
156
157 /** @brief Poll timer event */
158 sdeventplus::Event sdpEvent;
159
160 /**
161 * @brief The timer to be used once the OCC goes active. When it expires,
162 * a POLL command will be sent to the OCC and then timer restarted.
163 */
164 std::unique_ptr<
165 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>>
166 _pollTimer;
167
Lei YU0ab90ca2017-07-13 17:02:23 +0800168#ifdef I2C_OCC
Gunnar Mills94df8c92018-09-14 14:50:03 -0500169 /** @brief Init Status objects for I2C OCC devices
170 *
171 * It iterates in /sys/bus/i2c/devices, finds all occ hwmon devices
172 * and creates status objects.
173 */
174 void initStatusObjects();
Lei YU0ab90ca2017-07-13 17:02:23 +0800175#endif
Tom Joseph815f9f52020-07-27 12:12:13 +0530176
177#ifdef PLDM
178 /** @brief Callback handler invoked by the PLDM event handler when state of
179 * the OCC is toggled by the host. The caller passes the instance
180 * of the OCC and state of the OCC.
181 *
182 * @param[in] instance - instance of the OCC
183 * @param[in] status - true when the OCC goes active and false when the OCC
184 * goes inactive
185 *
186 * @return true if setting the state of OCC is successful and false if it
187 * fails.
188 */
189 bool updateOCCActive(instanceID instance, bool status);
190
191 std::unique_ptr<pldm::Interface> pldmHandle = nullptr;
192#endif
Chris Caina8857c52021-01-27 11:53:05 -0600193
Matt Spinlerd267cec2021-09-01 14:49:19 -0500194#ifdef POWER10
195 /**
196 * @brief Timer used when discovering OCCs in /dev.
197 */
198 std::unique_ptr<
199 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>>
200 discoverTimer;
201
202 /**
203 * @brief Used when discovering /dev/occ objects to know if
204 * any were added since the last check.
205 */
206 std::vector<int> prevOCCSearch;
207#endif
208
Chris Caina8857c52021-01-27 11:53:05 -0600209 /**
210 * @brief Called when poll timer expires and forces a POLL command to the
211 * OCC. The poll timer will then be restarted.
212 * */
213 void pollerTimerExpired();
Chicago Duanbb895cb2021-06-18 19:37:16 +0800214
Matt Spinlerd267cec2021-09-01 14:49:19 -0500215 /**
216 * @brief Finds the OCC devices in /dev
217 *
218 * @return The IDs of the OCCs - 0, 1, etc.
219 */
220 std::vector<int> findOCCsInDev();
221
Chicago Duanbb895cb2021-06-18 19:37:16 +0800222#ifdef READ_OCC_SENSORS
223 /**
224 * @brief Gets the occ sensor values.
225 * @param[in] id - Id of the OCC.
226 * @param[in] masterOcc - Is this OCC the master OCC.
227 * */
228 void getSensorValues(uint32_t id, bool masterOcc);
229
230 /**
231 * @brief Trigger OCC driver to read the temperature sensors.
232 * @param[in] path - path of the OCC sensors.
233 * @param[in] id - Id of the OCC.
234 * */
235 void readTempSensors(const fs::path& path, uint32_t id);
236
237 /**
238 * @brief Trigger OCC driver to read the power sensors.
239 * @param[in] path - path of the OCC sensors.
240 * @param[in] id - Id of the OCC.
241 * */
242 void readPowerSensors(const fs::path& path, uint32_t id);
243
244 /**
245 * @brief Set all sensor values of this OCC to NaN.
246 * @param[in] id - Id of the OCC.
247 * */
248 void setSensorValueToNaN(uint32_t id);
249
250 /** @brief Store the existing OCC sensors on D-BUS */
251 std::map<std::string, uint32_t> existingSensors;
252
253 /** @brief Get FunctionID from the `powerX_label` file.
254 * @param[in] value - the value of the `powerX_label` file.
255 * @returns FunctionID of the power sensors.
256 */
257 std::optional<std::string>
258 getPowerLabelFunctionID(const std::string& value);
259
260 /** @brief The power sensor names map */
261 const std::map<std::string, std::string> powerSensorName = {
262 {"system", "total_power"}, {"1", "p0_mem_power"},
263 {"2", "p1_mem_power"}, {"3", "p2_mem_power"},
264 {"4", "p3_mem_power"}, {"5", "p0_power"},
265 {"6", "p1_power"}, {"7", "p2_power"},
266 {"8", "p3_power"}, {"9", "p0_cache_power"},
267 {"10", "p1_cache_power"}, {"11", "p2_cache_power"},
268 {"12", "p3_cache_power"}, {"13", "io_a_power"},
269 {"14", "io_b_power"}, {"15", "io_c_power"},
270 {"16", "fans_a_power"}, {"17", "fans_b_power"},
271 {"18", "storage_a_power"}, {"19", "storage_b_power"},
272 {"23", "mem_cache_power"}, {"25", "p0_mem_0_power"},
273 {"26", "p0_mem_1_power"}, {"27", "p0_mem_2_power"}};
274
275 /** @brief The dimm temperature sensor names map */
276 const std::map<uint32_t, std::string> dimmTempSensorName = {
277 {internalMemCtlr, "_intmb_temp"},
278 {dimm, "_dram_temp"},
279 {memCtrlAndDimm, "_dram_extmb_temp"},
280 {PMIC, "_pmic_temp"},
281 {memCtlrExSensor, "_extmb_temp"}};
282#endif
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +0530283};
284
285} // namespace occ
286} // namespace open_power