blob: 5b66bf5a7d98133c8ca3f13c5c9120db28e5ac9b [file] [log] [blame]
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +05301#pragma once
2
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +05303#include "config.h"
Lei YU0ab90ca2017-07-13 17:02:23 +08004
Gunnar Mills94df8c92018-09-14 14:50:03 -05005#include "occ_errors.hpp"
6#include "occ_events.hpp"
Eddie James2f9f9bb2021-09-20 14:26:31 -05007#include "occ_ffdc.hpp"
Gunnar Mills94df8c92018-09-14 14:50:03 -05008#include "occ_presence.hpp"
Sheldon Baileyea2b22e2022-04-04 12:24:46 -05009#include "powermode.hpp"
Gunnar Mills94df8c92018-09-14 14:50:03 -050010
George Liub5ca1012021-09-10 12:53:11 +080011#include <org/open_power/OCC/Device/error.hpp>
12
George Liubcef3b42021-09-10 12:39:02 +080013#include <filesystem>
Gunnar Mills94df8c92018-09-14 14:50:03 -050014#include <fstream>
Chris Cain5d66a0a2022-02-09 08:52:10 -060015#include <regex>
Gunnar Mills94df8c92018-09-14 14:50:03 -050016
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +053017namespace open_power
18{
19namespace occ
20{
21
Edward A. James636577f2017-10-06 10:53:55 -050022class Manager;
Eddie James482e31f2017-09-14 13:17:17 -050023class Status;
George Liubcef3b42021-09-10 12:39:02 +080024namespace fs = std::filesystem;
Eddie James774f9af2019-03-19 20:58:53 +000025using namespace sdbusplus::org::open_power::OCC::Device::Error;
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +053026
27/** @class Device
28 * @brief Binds and unbinds the OCC driver upon request
29 */
30class Device
31{
Gunnar Mills94df8c92018-09-14 14:50:03 -050032 public:
33 Device() = delete;
34 ~Device() = default;
35 Device(const Device&) = delete;
36 Device& operator=(const Device&) = delete;
37 Device(Device&&) = default;
38 Device& operator=(Device&&) = default;
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +053039
Gunnar Mills94df8c92018-09-14 14:50:03 -050040 /** @brief Constructs the Device object
41 *
42 * @param[in] event - Unique ptr reference to sd_event
Eddie James774f9af2019-03-19 20:58:53 +000043 * @param[in] path - Path to the OCC instance
Gunnar Mills94df8c92018-09-14 14:50:03 -050044 * @param[in] manager - OCC manager instance
Eddie James2f9f9bb2021-09-20 14:26:31 -050045 * @param[in] status - Status instance
46 * @param[in] instance - OCC instance number
Gunnar Mills94df8c92018-09-14 14:50:03 -050047 */
Eddie Jamescbad2192021-10-07 09:39:39 -050048 Device(EventPtr& event, const fs::path& path, Manager& manager,
Sheldon Baileyea2b22e2022-04-04 12:24:46 -050049 Status& status,
50#ifdef POWER10
51 std::unique_ptr<powermode::PowerMode>& powerModeRef,
52#endif
53 unsigned int instance = 0) :
Eddie James774f9af2019-03-19 20:58:53 +000054 config(getPathBack(path)),
Eddie Jamescbad2192021-10-07 09:39:39 -050055 devPath(path), instance(instance), statusObject(status),
56 managerObject(manager),
57 error(event, path / "occ_error",
58 std::bind(std::mem_fn(&Device::errorCallback), this,
59 std::placeholders::_1)),
60 timeout(event,
61 path /
62 fs::path("../../sbefifo" + std::to_string(instance + 1)) /
63 "timeout",
64#ifdef PLDM
65 std::bind(std::mem_fn(&Device::timeoutCallback), this,
66 std::placeholders::_1)
67#else
68 nullptr
69#endif
70 ),
Eddie James2f9f9bb2021-09-20 14:26:31 -050071 ffdc(event, path / "ffdc", instance),
Eddie Jamescbad2192021-10-07 09:39:39 -050072 presence(event, path / "occs_present", manager,
73 std::bind(std::mem_fn(&Device::errorCallback), this,
74 std::placeholders::_1)),
Gunnar Mills94df8c92018-09-14 14:50:03 -050075 throttleProcTemp(
Eddie James774f9af2019-03-19 20:58:53 +000076 event, path / "occ_dvfs_overtemp",
Gunnar Mills94df8c92018-09-14 14:50:03 -050077 std::bind(std::mem_fn(&Device::throttleProcTempCallback), this,
78 std::placeholders::_1)),
79 throttleProcPower(
Eddie James774f9af2019-03-19 20:58:53 +000080 event, path / "occ_dvfs_power",
Gunnar Mills94df8c92018-09-14 14:50:03 -050081 std::bind(std::mem_fn(&Device::throttleProcPowerCallback), this,
82 std::placeholders::_1)),
Eddie James774f9af2019-03-19 20:58:53 +000083 throttleMemTemp(event, path / "occ_mem_throttle",
Gunnar Mills94df8c92018-09-14 14:50:03 -050084 std::bind(std::mem_fn(&Device::throttleMemTempCallback),
85 this, std::placeholders::_1))
Sheldon Baileyea2b22e2022-04-04 12:24:46 -050086#ifdef POWER10
87 ,
88 pmode(powerModeRef)
89#endif
Gunnar Mills94df8c92018-09-14 14:50:03 -050090 {
91 // Nothing to do here
92 }
93
94 /** @brief Binds device to the OCC driver */
95 inline void bind()
96 {
97 // Bind the device
98 return write(bindPath, config);
99 }
100
101 /** @brief Un-binds device from the OCC driver */
102 inline void unBind()
103 {
104 // Unbind the device
105 return write(unBindPath, config);
106 }
107
108 /** @brief Returns if device is already bound.
109 *
110 * On device bind, a soft link by the name $config
111 * gets created in OCC_HWMON_PATH and gets removed
112 * on unbind
113 *
114 * @return true if bound, else false
115 */
116 inline bool bound() const
117 {
118 return fs::exists(OCC_HWMON_PATH + config);
119 }
120
Eddie James774f9af2019-03-19 20:58:53 +0000121 /** @brief Starts to monitor for errors
122 *
123 * @param[in] poll - Indicates whether or not the error file should
124 * actually be polled for changes. Disabling polling is
125 * necessary for error files that don't support the poll
126 * file operation.
127 */
128 inline void addErrorWatch(bool poll = true)
Gunnar Mills94df8c92018-09-14 14:50:03 -0500129 {
Eddie James774f9af2019-03-19 20:58:53 +0000130 try
131 {
132 throttleProcTemp.addWatch(poll);
133 }
134 catch (const OpenFailure& e)
135 {
136 // try the old kernel version
137 throttleProcTemp.setFile(devPath / "occ_dvfs_ot");
138 throttleProcTemp.addWatch(poll);
139 }
140
Sheldon Baileyea2b22e2022-04-04 12:24:46 -0500141#ifdef POWER10
142 if (master())
143 {
144 pmode->addIpsWatch(poll);
145 }
146#endif
147
Eddie James774f9af2019-03-19 20:58:53 +0000148 throttleProcPower.addWatch(poll);
149 throttleMemTemp.addWatch(poll);
Eddie James2f9f9bb2021-09-20 14:26:31 -0500150
151 try
152 {
153 ffdc.addWatch(poll);
154 }
155 catch (const OpenFailure& e)
156 {
157 // nothing to do if there is no FFDC file
158 }
159
Eddie Jamescbad2192021-10-07 09:39:39 -0500160 try
161 {
162 timeout.addWatch(poll);
163 }
164 catch (const std::exception& e)
165 {
166 // nothing to do if there is no SBE timeout file
167 }
168
Eddie James774f9af2019-03-19 20:58:53 +0000169 error.addWatch(poll);
Gunnar Mills94df8c92018-09-14 14:50:03 -0500170 }
171
172 /** @brief stops monitoring for errors */
173 inline void removeErrorWatch()
174 {
175 // we can always safely remove watch even if we don't add it
176 presence.removeWatch();
Eddie James2f9f9bb2021-09-20 14:26:31 -0500177 ffdc.removeWatch();
Gunnar Mills94df8c92018-09-14 14:50:03 -0500178 error.removeWatch();
Eddie Jamescbad2192021-10-07 09:39:39 -0500179 timeout.removeWatch();
Gunnar Mills94df8c92018-09-14 14:50:03 -0500180 throttleMemTemp.removeWatch();
181 throttleProcPower.removeWatch();
182 throttleProcTemp.removeWatch();
Sheldon Baileyea2b22e2022-04-04 12:24:46 -0500183#ifdef POWER10
184 if (master())
185 {
186 pmode->removeIpsWatch();
187 }
188#endif
Gunnar Mills94df8c92018-09-14 14:50:03 -0500189 }
190
191 /** @brief Starts to watch how many OCCs are present on the master */
192 inline void addPresenceWatchMaster()
193 {
194 if (master())
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530195 {
Gunnar Mills94df8c92018-09-14 14:50:03 -0500196 presence.addWatch();
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530197 }
Gunnar Mills94df8c92018-09-14 14:50:03 -0500198 }
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530199
Eddie James774f9af2019-03-19 20:58:53 +0000200 /** @brief helper function to get the last part of the path
201 *
202 * @param[in] path - Path to parse
203 * @return - Last directory name in the path
204 */
205 static std::string getPathBack(const fs::path& path);
206
Chris Cain78e86012021-03-04 16:15:31 -0600207 /** @brief Returns true if device represents the master OCC */
208 bool master() const;
209
Gunnar Mills94df8c92018-09-14 14:50:03 -0500210 private:
211 /** @brief Config value to be used to do bind and unbind */
212 const std::string config;
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530213
Eddie James774f9af2019-03-19 20:58:53 +0000214 /** @brief This directory contains the error files */
215 const fs::path devPath;
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530216
Eddie Jamescbad2192021-10-07 09:39:39 -0500217 /** @brief OCC instance ID */
218 const unsigned int instance;
219
Gunnar Mills94df8c92018-09-14 14:50:03 -0500220 /** @brief To bind the device to the OCC driver, do:
221 *
222 * Write occ<#>-dev0 to: /sys/bus/platform/drivers/occ-hwmon/bind
223 */
224 static fs::path bindPath;
Vishwanatha Subbannab57f1512017-09-04 15:06:20 +0530225
Gunnar Mills94df8c92018-09-14 14:50:03 -0500226 /** @brief To un-bind the device from the OCC driver, do:
227 * Write occ<#>-dev0 to: /sys/bus/platform/drivers/occ-hwmon/unbind
228 */
229 static fs::path unBindPath;
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530230
Gunnar Mills94df8c92018-09-14 14:50:03 -0500231 /** Store the associated Status instance */
232 Status& statusObject;
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530233
Eddie Jamescbad2192021-10-07 09:39:39 -0500234 /** Store the parent Manager instance */
235 Manager& managerObject;
236
Gunnar Mills94df8c92018-09-14 14:50:03 -0500237 /** Abstraction of error monitoring */
238 Error error;
Eddie Jamesdae2d942017-12-20 10:50:03 -0600239
Eddie Jamescbad2192021-10-07 09:39:39 -0500240 /** Abstraction of SBE timeout monitoring */
241 Error timeout;
242
Eddie James2f9f9bb2021-09-20 14:26:31 -0500243 /** SBE FFDC monitoring */
244 FFDC ffdc;
245
Gunnar Mills94df8c92018-09-14 14:50:03 -0500246 /** Abstraction of OCC presence monitoring */
247 Presence presence;
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530248
Gunnar Mills94df8c92018-09-14 14:50:03 -0500249 /** Error instances for watching for throttling events */
250 Error throttleProcTemp;
251 Error throttleProcPower;
252 Error throttleMemTemp;
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530253
Sheldon Baileyea2b22e2022-04-04 12:24:46 -0500254#ifdef POWER10
255 /** @brief OCC PowerMode object */
256 std::unique_ptr<powermode::PowerMode>& pmode;
257#endif
258
Gunnar Mills94df8c92018-09-14 14:50:03 -0500259 /** @brief file writer to achieve bind and unbind
260 *
261 * @param[in] filename - Name of file to be written
262 * @param[in] data - Data to be written to
263 * @return - None
264 */
265 void write(const fs::path& fileName, const std::string& data)
266 {
267 // If there is an error, move the exception all the way up
268 std::ofstream file(fileName, std::ios::out);
269 file << data;
270 file.close();
271 return;
272 }
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530273
Eddie Jamescbad2192021-10-07 09:39:39 -0500274 /** @brief callback for OCC error and presence monitoring
275 *
276 * @param[in] error - True if an error is reported, false otherwise
277 */
278 void errorCallback(bool error);
279
280#ifdef PLDM
281 /** @brief callback for SBE timeout monitoring
282 *
283 * @param[in] error - True if an error is reported, false otherwise
284 */
285 void timeoutCallback(bool error);
286#endif
287
Gunnar Mills94df8c92018-09-14 14:50:03 -0500288 /** @brief callback for the proc temp throttle event
289 *
290 * @param[in] error - True if an error is reported, false otherwise
291 */
292 void throttleProcTempCallback(bool error);
Eddie James482e31f2017-09-14 13:17:17 -0500293
Gunnar Mills94df8c92018-09-14 14:50:03 -0500294 /** @brief callback for the proc power throttle event
295 *
296 * @param[in] error - True if an error is reported, false otherwise
297 */
298 void throttleProcPowerCallback(bool error);
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530299
Gunnar Mills94df8c92018-09-14 14:50:03 -0500300 /** @brief callback for the proc temp throttle event
301 *
302 * @param[in] error - True if an error is reported, false otherwise
303 */
304 void throttleMemTempCallback(bool error);
Chris Cain5d66a0a2022-02-09 08:52:10 -0600305
306 /** @brief Get the pathname for a file based on a regular expression
307 *
308 * @param[in] basePath - The path where the files will be checked
309 * @param[in] expr - Regular expression describing the target file
310 *
311 * @return path to the file or empty path if not found
312 */
Chris Caine2d0a432022-03-28 11:08:49 -0500313 fs::path getFilenameByRegex(fs::path basePath,
314 const std::regex& expr) const;
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530315};
316
317} // namespace occ
318} // namespace open_power