blob: e6e8cbb0b3746e2cd2c7292e1b99b4e63be06031 [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 <cstring>
15#include <functional>
16#include <sdbusplus/bus.hpp>
Chris Caina8857c52021-01-27 11:53:05 -060017#include <sdeventplus/event.hpp>
18#include <sdeventplus/utility/timer.hpp>
Gunnar Mills94df8c92018-09-14 14:50:03 -050019#include <vector>
20
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +053021namespace sdbusRule = sdbusplus::bus::match::rules;
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +053022namespace open_power
23{
24namespace occ
25{
26
Chicago Duanbb895cb2021-06-18 19:37:16 +080027#ifdef READ_OCC_SENSORS
28enum occFruType
29{
30 processorCore = 0,
31 internalMemCtlr = 1,
32 dimm = 2,
33 memCtrlAndDimm = 3,
34 VRMVdd = 6,
35 PMIC = 7,
36 memCtlrExSensor = 8
37};
38#endif
39
Chris Caina8857c52021-01-27 11:53:05 -060040/** @brief Default time, in seconds, between OCC poll commands */
Chicago Duanbb895cb2021-06-18 19:37:16 +080041constexpr unsigned int defaultPollingInterval = 1;
Chris Caina8857c52021-01-27 11:53:05 -060042
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +053043/** @class Manager
44 * @brief Builds and manages OCC objects
45 */
46struct Manager
47{
Gunnar Mills94df8c92018-09-14 14:50:03 -050048 public:
49 Manager() = delete;
50 Manager(const Manager&) = delete;
51 Manager& operator=(const Manager&) = delete;
52 Manager(Manager&&) = delete;
53 Manager& operator=(Manager&&) = delete;
54 ~Manager() = default;
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +053055
Gunnar Mills94df8c92018-09-14 14:50:03 -050056 /** @brief Adds OCC pass-through and status objects on the bus
57 * when corresponding CPU inventory is created.
58 *
Gunnar Mills94df8c92018-09-14 14:50:03 -050059 * @param[in] event - Unique ptr reference to sd_event
60 */
George Liuf3b75142021-06-10 11:22:50 +080061 Manager(EventPtr& event) :
62 event(event), pollInterval(defaultPollingInterval),
Chris Caina8857c52021-01-27 11:53:05 -060063 sdpEvent(sdeventplus::Event::get_default()),
64 _pollTimer(
65 std::make_unique<
66 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>>(
67 sdpEvent, std::bind(&Manager::pollerTimerExpired, this)))
Tom Joseph815f9f52020-07-27 12:12:13 +053068#ifdef PLDM
69 ,
70 pldmHandle(std::make_unique<pldm::Interface>(
George Liuf3b75142021-06-10 11:22:50 +080071 std::bind(std::mem_fn(&Manager::updateOCCActive), this,
72 std::placeholders::_1, std::placeholders::_2)))
Tom Joseph815f9f52020-07-27 12:12:13 +053073#endif
74
Gunnar Mills94df8c92018-09-14 14:50:03 -050075 {
Lei YU0ab90ca2017-07-13 17:02:23 +080076#ifdef I2C_OCC
Gunnar Mills94df8c92018-09-14 14:50:03 -050077 // I2C OCC status objects are initialized directly
78 initStatusObjects();
Lei YU0ab90ca2017-07-13 17:02:23 +080079#else
Gunnar Mills94df8c92018-09-14 14:50:03 -050080 findAndCreateObjects();
Lei YU0ab90ca2017-07-13 17:02:23 +080081#endif
Gunnar Mills94df8c92018-09-14 14:50:03 -050082 }
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +053083
Chris Caina8857c52021-01-27 11:53:05 -060084 /** @brief Return the number of bound OCCs */
Gunnar Mills94df8c92018-09-14 14:50:03 -050085 inline auto getNumOCCs() const
86 {
87 return activeCount;
88 }
Edward A. James636577f2017-10-06 10:53:55 -050089
Gunnar Mills94df8c92018-09-14 14:50:03 -050090 private:
91 /** @brief Checks if the CPU inventory is present and if so, creates
92 * the occ D-Bus objects. Else, registers a handler to be
93 * called when inventory is created.
94 */
95 void findAndCreateObjects();
Vishwanatha Subbannadfc7ec72017-09-07 18:18:01 +053096
Gunnar Mills94df8c92018-09-14 14:50:03 -050097 /** @brief Callback that responds to cpu creation in the inventory -
98 * by creating the needed objects.
99 *
100 * @param[in] msg - bus message
101 *
102 * @returns 0 to indicate success
103 */
104 int cpuCreated(sdbusplus::message::message& msg);
Deepak Kodihalli5f031f32017-07-26 08:25:59 -0500105
Gunnar Mills94df8c92018-09-14 14:50:03 -0500106 /** @brief Create child OCC objects.
107 *
108 * @param[in] occ - the occ name, such as occ0.
109 */
110 void createObjects(const std::string& occ);
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +0530111
Gunnar Mills94df8c92018-09-14 14:50:03 -0500112 /** @brief Callback handler invoked by Status object when the OccActive
113 * property is changed. This is needed to make sure that the
114 * error detection is started only after all the OCCs are bound.
115 * Similarly, when one of the OCC gets its OccActive property
116 * un-set, then the OCC error detection needs to be stopped on
117 * all the OCCs
118 *
119 * @param[in] status - OccActive status
120 */
121 void statusCallBack(bool status);
Vishwanatha Subbanna2dc9b1a2017-08-18 18:29:41 +0530122
Gunnar Mills94df8c92018-09-14 14:50:03 -0500123 /** @brief Sends a Heartbeat command to host control command handler */
124 void sendHeartBeat();
Vishwanatha Subbanna2dc9b1a2017-08-18 18:29:41 +0530125
Gunnar Mills94df8c92018-09-14 14:50:03 -0500126 /** @brief reference to sd_event wrapped in unique_ptr */
127 EventPtr& event;
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530128
Gunnar Mills94df8c92018-09-14 14:50:03 -0500129 /** @brief OCC pass-through objects */
130 std::vector<std::unique_ptr<PassThrough>> passThroughObjects;
Vishwanatha Subbanna307d80b2017-06-28 15:56:09 +0530131
Gunnar Mills94df8c92018-09-14 14:50:03 -0500132 /** @brief OCC Status objects */
133 std::vector<std::unique_ptr<Status>> statusObjects;
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +0530134
Gunnar Mills94df8c92018-09-14 14:50:03 -0500135 /** @brief Power cap monitor and occ notification object */
136 std::unique_ptr<open_power::occ::powercap::PowerCap> pcap;
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500137
Chris Cain78e86012021-03-04 16:15:31 -0600138#ifdef POWER10
139 /** @brief Power mode monitor and notification object */
140 std::unique_ptr<open_power::occ::powermode::PowerMode> pmode;
141#endif
142
Gunnar Mills94df8c92018-09-14 14:50:03 -0500143 /** @brief sbdbusplus match objects */
144 std::vector<sdbusplus::bus::match_t> cpuMatches;
Vishwanatha Subbanna2dc9b1a2017-08-18 18:29:41 +0530145
Gunnar Mills94df8c92018-09-14 14:50:03 -0500146 /** @brief Number of OCCs that are bound */
147 uint8_t activeCount = 0;
Lei YU0ab90ca2017-07-13 17:02:23 +0800148
Chris Caina8857c52021-01-27 11:53:05 -0600149 /** @brief Number of seconds between poll commands */
150 uint8_t pollInterval;
151
152 /** @brief Poll timer event */
153 sdeventplus::Event sdpEvent;
154
155 /**
156 * @brief The timer to be used once the OCC goes active. When it expires,
157 * a POLL command will be sent to the OCC and then timer restarted.
158 */
159 std::unique_ptr<
160 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>>
161 _pollTimer;
162
Lei YU0ab90ca2017-07-13 17:02:23 +0800163#ifdef I2C_OCC
Gunnar Mills94df8c92018-09-14 14:50:03 -0500164 /** @brief Init Status objects for I2C OCC devices
165 *
166 * It iterates in /sys/bus/i2c/devices, finds all occ hwmon devices
167 * and creates status objects.
168 */
169 void initStatusObjects();
Lei YU0ab90ca2017-07-13 17:02:23 +0800170#endif
Tom Joseph815f9f52020-07-27 12:12:13 +0530171
172#ifdef PLDM
173 /** @brief Callback handler invoked by the PLDM event handler when state of
174 * the OCC is toggled by the host. The caller passes the instance
175 * of the OCC and state of the OCC.
176 *
177 * @param[in] instance - instance of the OCC
178 * @param[in] status - true when the OCC goes active and false when the OCC
179 * goes inactive
180 *
181 * @return true if setting the state of OCC is successful and false if it
182 * fails.
183 */
184 bool updateOCCActive(instanceID instance, bool status);
185
186 std::unique_ptr<pldm::Interface> pldmHandle = nullptr;
187#endif
Chris Caina8857c52021-01-27 11:53:05 -0600188
189 /**
190 * @brief Called when poll timer expires and forces a POLL command to the
191 * OCC. The poll timer will then be restarted.
192 * */
193 void pollerTimerExpired();
Chicago Duanbb895cb2021-06-18 19:37:16 +0800194
195#ifdef READ_OCC_SENSORS
196 /**
197 * @brief Gets the occ sensor values.
198 * @param[in] id - Id of the OCC.
199 * @param[in] masterOcc - Is this OCC the master OCC.
200 * */
201 void getSensorValues(uint32_t id, bool masterOcc);
202
203 /**
204 * @brief Trigger OCC driver to read the temperature sensors.
205 * @param[in] path - path of the OCC sensors.
206 * @param[in] id - Id of the OCC.
207 * */
208 void readTempSensors(const fs::path& path, uint32_t id);
209
210 /**
211 * @brief Trigger OCC driver to read the power sensors.
212 * @param[in] path - path of the OCC sensors.
213 * @param[in] id - Id of the OCC.
214 * */
215 void readPowerSensors(const fs::path& path, uint32_t id);
216
217 /**
218 * @brief Set all sensor values of this OCC to NaN.
219 * @param[in] id - Id of the OCC.
220 * */
221 void setSensorValueToNaN(uint32_t id);
222
223 /** @brief Store the existing OCC sensors on D-BUS */
224 std::map<std::string, uint32_t> existingSensors;
225
226 /** @brief Get FunctionID from the `powerX_label` file.
227 * @param[in] value - the value of the `powerX_label` file.
228 * @returns FunctionID of the power sensors.
229 */
230 std::optional<std::string>
231 getPowerLabelFunctionID(const std::string& value);
232
233 /** @brief The power sensor names map */
234 const std::map<std::string, std::string> powerSensorName = {
235 {"system", "total_power"}, {"1", "p0_mem_power"},
236 {"2", "p1_mem_power"}, {"3", "p2_mem_power"},
237 {"4", "p3_mem_power"}, {"5", "p0_power"},
238 {"6", "p1_power"}, {"7", "p2_power"},
239 {"8", "p3_power"}, {"9", "p0_cache_power"},
240 {"10", "p1_cache_power"}, {"11", "p2_cache_power"},
241 {"12", "p3_cache_power"}, {"13", "io_a_power"},
242 {"14", "io_b_power"}, {"15", "io_c_power"},
243 {"16", "fans_a_power"}, {"17", "fans_b_power"},
244 {"18", "storage_a_power"}, {"19", "storage_b_power"},
245 {"23", "mem_cache_power"}, {"25", "p0_mem_0_power"},
246 {"26", "p0_mem_1_power"}, {"27", "p0_mem_2_power"}};
247
248 /** @brief The dimm temperature sensor names map */
249 const std::map<uint32_t, std::string> dimmTempSensorName = {
250 {internalMemCtlr, "_intmb_temp"},
251 {dimm, "_dram_temp"},
252 {memCtrlAndDimm, "_dram_extmb_temp"},
253 {PMIC, "_pmic_temp"},
254 {memCtlrExSensor, "_extmb_temp"}};
255#endif
Vishwanatha Subbanna2180b2d2017-06-28 14:05:57 +0530256};
257
258} // namespace occ
259} // namespace open_power