blob: 873ecfc8ad00f172046097e5341df0c5bdc1a532 [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 Jamesaced3092022-04-22 16:19:30 -050054 devPath(path),
55 instance(instance), statusObject(status), managerObject(manager),
Eddie Jamescbad2192021-10-07 09:39:39 -050056 error(event, path / "occ_error",
57 std::bind(std::mem_fn(&Device::errorCallback), this,
58 std::placeholders::_1)),
59 timeout(event,
60 path /
61 fs::path("../../sbefifo" + std::to_string(instance + 1)) /
62 "timeout",
63#ifdef PLDM
64 std::bind(std::mem_fn(&Device::timeoutCallback), this,
65 std::placeholders::_1)
66#else
67 nullptr
68#endif
69 ),
Eddie James2f9f9bb2021-09-20 14:26:31 -050070 ffdc(event, path / "ffdc", instance),
Eddie Jamescbad2192021-10-07 09:39:39 -050071 presence(event, path / "occs_present", manager,
72 std::bind(std::mem_fn(&Device::errorCallback), this,
73 std::placeholders::_1)),
Gunnar Mills94df8c92018-09-14 14:50:03 -050074 throttleProcTemp(
Eddie James774f9af2019-03-19 20:58:53 +000075 event, path / "occ_dvfs_overtemp",
Gunnar Mills94df8c92018-09-14 14:50:03 -050076 std::bind(std::mem_fn(&Device::throttleProcTempCallback), this,
77 std::placeholders::_1)),
78 throttleProcPower(
Eddie James774f9af2019-03-19 20:58:53 +000079 event, path / "occ_dvfs_power",
Gunnar Mills94df8c92018-09-14 14:50:03 -050080 std::bind(std::mem_fn(&Device::throttleProcPowerCallback), this,
81 std::placeholders::_1)),
Eddie James774f9af2019-03-19 20:58:53 +000082 throttleMemTemp(event, path / "occ_mem_throttle",
Gunnar Mills94df8c92018-09-14 14:50:03 -050083 std::bind(std::mem_fn(&Device::throttleMemTempCallback),
84 this, std::placeholders::_1))
Sheldon Baileyea2b22e2022-04-04 12:24:46 -050085#ifdef POWER10
86 ,
87 pmode(powerModeRef)
88#endif
Gunnar Mills94df8c92018-09-14 14:50:03 -050089 {
90 // Nothing to do here
91 }
92
Eddie Jamesaced3092022-04-22 16:19:30 -050093 /** @brief Sets the device active or inactive
Gunnar Mills94df8c92018-09-14 14:50:03 -050094 *
Eddie Jamesaced3092022-04-22 16:19:30 -050095 * @param[in] active - Indicates whether or not to set the device active
Gunnar Mills94df8c92018-09-14 14:50:03 -050096 */
Eddie Jamesaced3092022-04-22 16:19:30 -050097 void setActive(bool active);
Gunnar Mills94df8c92018-09-14 14:50:03 -050098
Eddie James774f9af2019-03-19 20:58:53 +000099 /** @brief Starts to monitor for errors
100 *
101 * @param[in] poll - Indicates whether or not the error file should
102 * actually be polled for changes. Disabling polling is
103 * necessary for error files that don't support the poll
104 * file operation.
105 */
106 inline void addErrorWatch(bool poll = true)
Gunnar Mills94df8c92018-09-14 14:50:03 -0500107 {
Eddie James774f9af2019-03-19 20:58:53 +0000108 try
109 {
110 throttleProcTemp.addWatch(poll);
111 }
112 catch (const OpenFailure& e)
113 {
114 // try the old kernel version
115 throttleProcTemp.setFile(devPath / "occ_dvfs_ot");
116 throttleProcTemp.addWatch(poll);
117 }
118
Sheldon Baileyea2b22e2022-04-04 12:24:46 -0500119#ifdef POWER10
120 if (master())
121 {
122 pmode->addIpsWatch(poll);
123 }
124#endif
125
Eddie James774f9af2019-03-19 20:58:53 +0000126 throttleProcPower.addWatch(poll);
127 throttleMemTemp.addWatch(poll);
Eddie James2f9f9bb2021-09-20 14:26:31 -0500128
129 try
130 {
131 ffdc.addWatch(poll);
132 }
133 catch (const OpenFailure& e)
134 {
135 // nothing to do if there is no FFDC file
136 }
137
Eddie Jamescbad2192021-10-07 09:39:39 -0500138 try
139 {
140 timeout.addWatch(poll);
141 }
142 catch (const std::exception& e)
143 {
144 // nothing to do if there is no SBE timeout file
145 }
146
Eddie James774f9af2019-03-19 20:58:53 +0000147 error.addWatch(poll);
Gunnar Mills94df8c92018-09-14 14:50:03 -0500148 }
149
150 /** @brief stops monitoring for errors */
151 inline void removeErrorWatch()
152 {
153 // we can always safely remove watch even if we don't add it
154 presence.removeWatch();
Eddie James2f9f9bb2021-09-20 14:26:31 -0500155 ffdc.removeWatch();
Gunnar Mills94df8c92018-09-14 14:50:03 -0500156 error.removeWatch();
Eddie Jamescbad2192021-10-07 09:39:39 -0500157 timeout.removeWatch();
Gunnar Mills94df8c92018-09-14 14:50:03 -0500158 throttleMemTemp.removeWatch();
159 throttleProcPower.removeWatch();
160 throttleProcTemp.removeWatch();
Sheldon Baileyea2b22e2022-04-04 12:24:46 -0500161#ifdef POWER10
162 if (master())
163 {
164 pmode->removeIpsWatch();
165 }
166#endif
Gunnar Mills94df8c92018-09-14 14:50:03 -0500167 }
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
Eddie Jamesaced3092022-04-22 16:19:30 -0500185 /** @brief Returns true if the device is active */
186 bool active() const;
187
Chris Cain78e86012021-03-04 16:15:31 -0600188 /** @brief Returns true if device represents the master OCC */
189 bool master() const;
190
Gunnar Mills94df8c92018-09-14 14:50:03 -0500191 private:
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 /** Store the associated Status instance */
199 Status& statusObject;
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530200
Eddie Jamescbad2192021-10-07 09:39:39 -0500201 /** Store the parent Manager instance */
202 Manager& managerObject;
203
Gunnar Mills94df8c92018-09-14 14:50:03 -0500204 /** Abstraction of error monitoring */
205 Error error;
Eddie Jamesdae2d942017-12-20 10:50:03 -0600206
Eddie Jamescbad2192021-10-07 09:39:39 -0500207 /** Abstraction of SBE timeout monitoring */
208 Error timeout;
209
Eddie James2f9f9bb2021-09-20 14:26:31 -0500210 /** SBE FFDC monitoring */
211 FFDC ffdc;
212
Gunnar Mills94df8c92018-09-14 14:50:03 -0500213 /** Abstraction of OCC presence monitoring */
214 Presence presence;
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530215
Gunnar Mills94df8c92018-09-14 14:50:03 -0500216 /** Error instances for watching for throttling events */
217 Error throttleProcTemp;
218 Error throttleProcPower;
219 Error throttleMemTemp;
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530220
Sheldon Baileyea2b22e2022-04-04 12:24:46 -0500221#ifdef POWER10
222 /** @brief OCC PowerMode object */
223 std::unique_ptr<powermode::PowerMode>& pmode;
224#endif
225
Eddie Jamesaced3092022-04-22 16:19:30 -0500226 /** @brief file reader to read a binary string ("1" or "0")
227 *
228 * @param[in] fileName - Name of file to be read
229 * @return - The value returned by reading the file
230 */
231 bool readBinary(const std::string& fileName) const;
232
Gunnar Mills94df8c92018-09-14 14:50:03 -0500233 /** @brief file writer to achieve bind and unbind
234 *
235 * @param[in] filename - Name of file to be written
236 * @param[in] data - Data to be written to
237 * @return - None
238 */
239 void write(const fs::path& fileName, const std::string& data)
240 {
241 // If there is an error, move the exception all the way up
242 std::ofstream file(fileName, std::ios::out);
243 file << data;
244 file.close();
245 return;
246 }
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530247
Eddie Jamescbad2192021-10-07 09:39:39 -0500248 /** @brief callback for OCC error and presence monitoring
249 *
250 * @param[in] error - True if an error is reported, false otherwise
251 */
252 void errorCallback(bool error);
253
254#ifdef PLDM
255 /** @brief callback for SBE timeout monitoring
256 *
257 * @param[in] error - True if an error is reported, false otherwise
258 */
259 void timeoutCallback(bool error);
260#endif
261
Gunnar Mills94df8c92018-09-14 14:50:03 -0500262 /** @brief callback for the proc temp throttle event
263 *
264 * @param[in] error - True if an error is reported, false otherwise
265 */
266 void throttleProcTempCallback(bool error);
Eddie James482e31f2017-09-14 13:17:17 -0500267
Gunnar Mills94df8c92018-09-14 14:50:03 -0500268 /** @brief callback for the proc power throttle event
269 *
270 * @param[in] error - True if an error is reported, false otherwise
271 */
272 void throttleProcPowerCallback(bool error);
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530273
Gunnar Mills94df8c92018-09-14 14:50:03 -0500274 /** @brief callback for the proc temp throttle event
275 *
276 * @param[in] error - True if an error is reported, false otherwise
277 */
278 void throttleMemTempCallback(bool error);
Chris Cain5d66a0a2022-02-09 08:52:10 -0600279
280 /** @brief Get the pathname for a file based on a regular expression
281 *
282 * @param[in] basePath - The path where the files will be checked
283 * @param[in] expr - Regular expression describing the target file
284 *
285 * @return path to the file or empty path if not found
286 */
Chris Caine2d0a432022-03-28 11:08:49 -0500287 fs::path getFilenameByRegex(fs::path basePath,
288 const std::regex& expr) const;
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530289};
290
291} // namespace occ
292} // namespace open_power