blob: 97bdcebfb1b4110e33dbcebb35576d9fb8378901 [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"
9
George Liub5ca1012021-09-10 12:53:11 +080010#include <org/open_power/OCC/Device/error.hpp>
11
George Liubcef3b42021-09-10 12:39:02 +080012#include <filesystem>
Gunnar Mills94df8c92018-09-14 14:50:03 -050013#include <fstream>
Chris Cain5d66a0a2022-02-09 08:52:10 -060014#include <regex>
Gunnar Mills94df8c92018-09-14 14:50:03 -050015
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +053016namespace open_power
17{
18namespace occ
19{
20
Edward A. James636577f2017-10-06 10:53:55 -050021class Manager;
Eddie James482e31f2017-09-14 13:17:17 -050022class Status;
George Liubcef3b42021-09-10 12:39:02 +080023namespace fs = std::filesystem;
Eddie James774f9af2019-03-19 20:58:53 +000024using namespace sdbusplus::org::open_power::OCC::Device::Error;
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +053025
26/** @class Device
27 * @brief Binds and unbinds the OCC driver upon request
28 */
29class Device
30{
Gunnar Mills94df8c92018-09-14 14:50:03 -050031 public:
32 Device() = delete;
33 ~Device() = default;
34 Device(const Device&) = delete;
35 Device& operator=(const Device&) = delete;
36 Device(Device&&) = default;
37 Device& operator=(Device&&) = default;
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +053038
Gunnar Mills94df8c92018-09-14 14:50:03 -050039 /** @brief Constructs the Device object
40 *
41 * @param[in] event - Unique ptr reference to sd_event
Eddie James774f9af2019-03-19 20:58:53 +000042 * @param[in] path - Path to the OCC instance
Gunnar Mills94df8c92018-09-14 14:50:03 -050043 * @param[in] manager - OCC manager instance
Eddie James2f9f9bb2021-09-20 14:26:31 -050044 * @param[in] status - Status instance
45 * @param[in] instance - OCC instance number
Gunnar Mills94df8c92018-09-14 14:50:03 -050046 */
Eddie Jamescbad2192021-10-07 09:39:39 -050047 Device(EventPtr& event, const fs::path& path, Manager& manager,
48 Status& status, unsigned int instance = 0) :
Eddie James774f9af2019-03-19 20:58:53 +000049 config(getPathBack(path)),
Eddie Jamescbad2192021-10-07 09:39:39 -050050 devPath(path), instance(instance), statusObject(status),
51 managerObject(manager),
52 error(event, path / "occ_error",
53 std::bind(std::mem_fn(&Device::errorCallback), this,
54 std::placeholders::_1)),
55 timeout(event,
56 path /
57 fs::path("../../sbefifo" + std::to_string(instance + 1)) /
58 "timeout",
59#ifdef PLDM
60 std::bind(std::mem_fn(&Device::timeoutCallback), this,
61 std::placeholders::_1)
62#else
63 nullptr
64#endif
65 ),
Eddie James2f9f9bb2021-09-20 14:26:31 -050066 ffdc(event, path / "ffdc", instance),
Eddie Jamescbad2192021-10-07 09:39:39 -050067 presence(event, path / "occs_present", manager,
68 std::bind(std::mem_fn(&Device::errorCallback), this,
69 std::placeholders::_1)),
Gunnar Mills94df8c92018-09-14 14:50:03 -050070 throttleProcTemp(
Eddie James774f9af2019-03-19 20:58:53 +000071 event, path / "occ_dvfs_overtemp",
Gunnar Mills94df8c92018-09-14 14:50:03 -050072 std::bind(std::mem_fn(&Device::throttleProcTempCallback), this,
73 std::placeholders::_1)),
74 throttleProcPower(
Eddie James774f9af2019-03-19 20:58:53 +000075 event, path / "occ_dvfs_power",
Gunnar Mills94df8c92018-09-14 14:50:03 -050076 std::bind(std::mem_fn(&Device::throttleProcPowerCallback), this,
77 std::placeholders::_1)),
Eddie James774f9af2019-03-19 20:58:53 +000078 throttleMemTemp(event, path / "occ_mem_throttle",
Gunnar Mills94df8c92018-09-14 14:50:03 -050079 std::bind(std::mem_fn(&Device::throttleMemTempCallback),
80 this, std::placeholders::_1))
81 {
82 // Nothing to do here
83 }
84
85 /** @brief Binds device to the OCC driver */
86 inline void bind()
87 {
88 // Bind the device
89 return write(bindPath, config);
90 }
91
92 /** @brief Un-binds device from the OCC driver */
93 inline void unBind()
94 {
95 // Unbind the device
96 return write(unBindPath, config);
97 }
98
99 /** @brief Returns if device is already bound.
100 *
101 * On device bind, a soft link by the name $config
102 * gets created in OCC_HWMON_PATH and gets removed
103 * on unbind
104 *
105 * @return true if bound, else false
106 */
107 inline bool bound() const
108 {
109 return fs::exists(OCC_HWMON_PATH + config);
110 }
111
Eddie James774f9af2019-03-19 20:58:53 +0000112 /** @brief Starts to monitor for errors
113 *
114 * @param[in] poll - Indicates whether or not the error file should
115 * actually be polled for changes. Disabling polling is
116 * necessary for error files that don't support the poll
117 * file operation.
118 */
119 inline void addErrorWatch(bool poll = true)
Gunnar Mills94df8c92018-09-14 14:50:03 -0500120 {
Eddie James774f9af2019-03-19 20:58:53 +0000121 try
122 {
123 throttleProcTemp.addWatch(poll);
124 }
125 catch (const OpenFailure& e)
126 {
127 // try the old kernel version
128 throttleProcTemp.setFile(devPath / "occ_dvfs_ot");
129 throttleProcTemp.addWatch(poll);
130 }
131
132 throttleProcPower.addWatch(poll);
133 throttleMemTemp.addWatch(poll);
Eddie James2f9f9bb2021-09-20 14:26:31 -0500134
135 try
136 {
137 ffdc.addWatch(poll);
138 }
139 catch (const OpenFailure& e)
140 {
141 // nothing to do if there is no FFDC file
142 }
143
Eddie Jamescbad2192021-10-07 09:39:39 -0500144 try
145 {
146 timeout.addWatch(poll);
147 }
148 catch (const std::exception& e)
149 {
150 // nothing to do if there is no SBE timeout file
151 }
152
Eddie James774f9af2019-03-19 20:58:53 +0000153 error.addWatch(poll);
Gunnar Mills94df8c92018-09-14 14:50:03 -0500154 }
155
156 /** @brief stops monitoring for errors */
157 inline void removeErrorWatch()
158 {
159 // we can always safely remove watch even if we don't add it
160 presence.removeWatch();
Eddie James2f9f9bb2021-09-20 14:26:31 -0500161 ffdc.removeWatch();
Gunnar Mills94df8c92018-09-14 14:50:03 -0500162 error.removeWatch();
Eddie Jamescbad2192021-10-07 09:39:39 -0500163 timeout.removeWatch();
Gunnar Mills94df8c92018-09-14 14:50:03 -0500164 throttleMemTemp.removeWatch();
165 throttleProcPower.removeWatch();
166 throttleProcTemp.removeWatch();
167 }
168
169 /** @brief Starts to watch how many OCCs are present on the master */
170 inline void addPresenceWatchMaster()
171 {
172 if (master())
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530173 {
Gunnar Mills94df8c92018-09-14 14:50:03 -0500174 presence.addWatch();
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530175 }
Gunnar Mills94df8c92018-09-14 14:50:03 -0500176 }
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530177
Eddie James774f9af2019-03-19 20:58:53 +0000178 /** @brief helper function to get the last part of the path
179 *
180 * @param[in] path - Path to parse
181 * @return - Last directory name in the path
182 */
183 static std::string getPathBack(const fs::path& path);
184
Chris Cain78e86012021-03-04 16:15:31 -0600185 /** @brief Returns true if device represents the master OCC */
186 bool master() const;
187
Gunnar Mills94df8c92018-09-14 14:50:03 -0500188 private:
189 /** @brief Config value to be used to do bind and unbind */
190 const std::string config;
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530191
Eddie James774f9af2019-03-19 20:58:53 +0000192 /** @brief This directory contains the error files */
193 const fs::path devPath;
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530194
Eddie Jamescbad2192021-10-07 09:39:39 -0500195 /** @brief OCC instance ID */
196 const unsigned int instance;
197
Gunnar Mills94df8c92018-09-14 14:50:03 -0500198 /** @brief To bind the device to the OCC driver, do:
199 *
200 * Write occ<#>-dev0 to: /sys/bus/platform/drivers/occ-hwmon/bind
201 */
202 static fs::path bindPath;
Vishwanatha Subbannab57f1512017-09-04 15:06:20 +0530203
Gunnar Mills94df8c92018-09-14 14:50:03 -0500204 /** @brief To un-bind the device from the OCC driver, do:
205 * Write occ<#>-dev0 to: /sys/bus/platform/drivers/occ-hwmon/unbind
206 */
207 static fs::path unBindPath;
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530208
Gunnar Mills94df8c92018-09-14 14:50:03 -0500209 /** Store the associated Status instance */
210 Status& statusObject;
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530211
Eddie Jamescbad2192021-10-07 09:39:39 -0500212 /** Store the parent Manager instance */
213 Manager& managerObject;
214
Gunnar Mills94df8c92018-09-14 14:50:03 -0500215 /** Abstraction of error monitoring */
216 Error error;
Eddie Jamesdae2d942017-12-20 10:50:03 -0600217
Eddie Jamescbad2192021-10-07 09:39:39 -0500218 /** Abstraction of SBE timeout monitoring */
219 Error timeout;
220
Eddie James2f9f9bb2021-09-20 14:26:31 -0500221 /** SBE FFDC monitoring */
222 FFDC ffdc;
223
Gunnar Mills94df8c92018-09-14 14:50:03 -0500224 /** Abstraction of OCC presence monitoring */
225 Presence presence;
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530226
Gunnar Mills94df8c92018-09-14 14:50:03 -0500227 /** Error instances for watching for throttling events */
228 Error throttleProcTemp;
229 Error throttleProcPower;
230 Error throttleMemTemp;
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530231
Gunnar Mills94df8c92018-09-14 14:50:03 -0500232 /** @brief file writer to achieve bind and unbind
233 *
234 * @param[in] filename - Name of file to be written
235 * @param[in] data - Data to be written to
236 * @return - None
237 */
238 void write(const fs::path& fileName, const std::string& data)
239 {
240 // If there is an error, move the exception all the way up
241 std::ofstream file(fileName, std::ios::out);
242 file << data;
243 file.close();
244 return;
245 }
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530246
Eddie Jamescbad2192021-10-07 09:39:39 -0500247 /** @brief callback for OCC error and presence monitoring
248 *
249 * @param[in] error - True if an error is reported, false otherwise
250 */
251 void errorCallback(bool error);
252
253#ifdef PLDM
254 /** @brief callback for SBE timeout monitoring
255 *
256 * @param[in] error - True if an error is reported, false otherwise
257 */
258 void timeoutCallback(bool error);
259#endif
260
Gunnar Mills94df8c92018-09-14 14:50:03 -0500261 /** @brief callback for the proc temp throttle event
262 *
263 * @param[in] error - True if an error is reported, false otherwise
264 */
265 void throttleProcTempCallback(bool error);
Eddie James482e31f2017-09-14 13:17:17 -0500266
Gunnar Mills94df8c92018-09-14 14:50:03 -0500267 /** @brief callback for the proc power throttle event
268 *
269 * @param[in] error - True if an error is reported, false otherwise
270 */
271 void throttleProcPowerCallback(bool error);
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530272
Gunnar Mills94df8c92018-09-14 14:50:03 -0500273 /** @brief callback for the proc temp throttle event
274 *
275 * @param[in] error - True if an error is reported, false otherwise
276 */
277 void throttleMemTempCallback(bool error);
Chris Cain5d66a0a2022-02-09 08:52:10 -0600278
279 /** @brief Get the pathname for a file based on a regular expression
280 *
281 * @param[in] basePath - The path where the files will be checked
282 * @param[in] expr - Regular expression describing the target file
283 *
284 * @return path to the file or empty path if not found
285 */
286 fs::path getFilenameByRegex(fs::path basePath, const std::regex& expr) const
287 {
288 for (auto& file : fs::directory_iterator(basePath))
289 {
290 if (std::regex_search(file.path().string(), expr))
291 {
292 return file;
293 }
294 }
295 return fs::path{};
296 }
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530297};
298
299} // namespace occ
300} // namespace open_power