blob: 106604ed2ac89663e86a990da8d47c63e7513c5e [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>
14
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +053015namespace open_power
16{
17namespace occ
18{
19
Edward A. James636577f2017-10-06 10:53:55 -050020class Manager;
Eddie James482e31f2017-09-14 13:17:17 -050021class Status;
George Liubcef3b42021-09-10 12:39:02 +080022namespace fs = std::filesystem;
Eddie James774f9af2019-03-19 20:58:53 +000023using namespace sdbusplus::org::open_power::OCC::Device::Error;
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +053024
25/** @class Device
26 * @brief Binds and unbinds the OCC driver upon request
27 */
28class Device
29{
Gunnar Mills94df8c92018-09-14 14:50:03 -050030 public:
31 Device() = delete;
32 ~Device() = default;
33 Device(const Device&) = delete;
34 Device& operator=(const Device&) = delete;
35 Device(Device&&) = default;
36 Device& operator=(Device&&) = default;
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +053037
Gunnar Mills94df8c92018-09-14 14:50:03 -050038 /** @brief Constructs the Device object
39 *
40 * @param[in] event - Unique ptr reference to sd_event
Eddie James774f9af2019-03-19 20:58:53 +000041 * @param[in] path - Path to the OCC instance
Gunnar Mills94df8c92018-09-14 14:50:03 -050042 * @param[in] manager - OCC manager instance
Eddie James2f9f9bb2021-09-20 14:26:31 -050043 * @param[in] status - Status instance
44 * @param[in] instance - OCC instance number
Gunnar Mills94df8c92018-09-14 14:50:03 -050045 */
Eddie Jamescbad2192021-10-07 09:39:39 -050046 Device(EventPtr& event, const fs::path& path, Manager& manager,
47 Status& status, unsigned int instance = 0) :
Eddie James774f9af2019-03-19 20:58:53 +000048 config(getPathBack(path)),
Eddie Jamescbad2192021-10-07 09:39:39 -050049 devPath(path), instance(instance), statusObject(status),
50 managerObject(manager),
51 error(event, path / "occ_error",
52 std::bind(std::mem_fn(&Device::errorCallback), this,
53 std::placeholders::_1)),
54 timeout(event,
55 path /
56 fs::path("../../sbefifo" + std::to_string(instance + 1)) /
57 "timeout",
58#ifdef PLDM
59 std::bind(std::mem_fn(&Device::timeoutCallback), this,
60 std::placeholders::_1)
61#else
62 nullptr
63#endif
64 ),
Eddie James2f9f9bb2021-09-20 14:26:31 -050065 ffdc(event, path / "ffdc", instance),
Eddie Jamescbad2192021-10-07 09:39:39 -050066 presence(event, path / "occs_present", manager,
67 std::bind(std::mem_fn(&Device::errorCallback), this,
68 std::placeholders::_1)),
Gunnar Mills94df8c92018-09-14 14:50:03 -050069 throttleProcTemp(
Eddie James774f9af2019-03-19 20:58:53 +000070 event, path / "occ_dvfs_overtemp",
Gunnar Mills94df8c92018-09-14 14:50:03 -050071 std::bind(std::mem_fn(&Device::throttleProcTempCallback), this,
72 std::placeholders::_1)),
73 throttleProcPower(
Eddie James774f9af2019-03-19 20:58:53 +000074 event, path / "occ_dvfs_power",
Gunnar Mills94df8c92018-09-14 14:50:03 -050075 std::bind(std::mem_fn(&Device::throttleProcPowerCallback), this,
76 std::placeholders::_1)),
Eddie James774f9af2019-03-19 20:58:53 +000077 throttleMemTemp(event, path / "occ_mem_throttle",
Gunnar Mills94df8c92018-09-14 14:50:03 -050078 std::bind(std::mem_fn(&Device::throttleMemTempCallback),
79 this, std::placeholders::_1))
80 {
81 // Nothing to do here
82 }
83
84 /** @brief Binds device to the OCC driver */
85 inline void bind()
86 {
87 // Bind the device
88 return write(bindPath, config);
89 }
90
91 /** @brief Un-binds device from the OCC driver */
92 inline void unBind()
93 {
94 // Unbind the device
95 return write(unBindPath, config);
96 }
97
98 /** @brief Returns if device is already bound.
99 *
100 * On device bind, a soft link by the name $config
101 * gets created in OCC_HWMON_PATH and gets removed
102 * on unbind
103 *
104 * @return true if bound, else false
105 */
106 inline bool bound() const
107 {
108 return fs::exists(OCC_HWMON_PATH + config);
109 }
110
Eddie James774f9af2019-03-19 20:58:53 +0000111 /** @brief Starts to monitor for errors
112 *
113 * @param[in] poll - Indicates whether or not the error file should
114 * actually be polled for changes. Disabling polling is
115 * necessary for error files that don't support the poll
116 * file operation.
117 */
118 inline void addErrorWatch(bool poll = true)
Gunnar Mills94df8c92018-09-14 14:50:03 -0500119 {
Eddie James774f9af2019-03-19 20:58:53 +0000120 try
121 {
122 throttleProcTemp.addWatch(poll);
123 }
124 catch (const OpenFailure& e)
125 {
126 // try the old kernel version
127 throttleProcTemp.setFile(devPath / "occ_dvfs_ot");
128 throttleProcTemp.addWatch(poll);
129 }
130
131 throttleProcPower.addWatch(poll);
132 throttleMemTemp.addWatch(poll);
Eddie James2f9f9bb2021-09-20 14:26:31 -0500133
134 try
135 {
136 ffdc.addWatch(poll);
137 }
138 catch (const OpenFailure& e)
139 {
140 // nothing to do if there is no FFDC file
141 }
142
Eddie Jamescbad2192021-10-07 09:39:39 -0500143 try
144 {
145 timeout.addWatch(poll);
146 }
147 catch (const std::exception& e)
148 {
149 // nothing to do if there is no SBE timeout file
150 }
151
Eddie James774f9af2019-03-19 20:58:53 +0000152 error.addWatch(poll);
Gunnar Mills94df8c92018-09-14 14:50:03 -0500153 }
154
155 /** @brief stops monitoring for errors */
156 inline void removeErrorWatch()
157 {
158 // we can always safely remove watch even if we don't add it
159 presence.removeWatch();
Eddie James2f9f9bb2021-09-20 14:26:31 -0500160 ffdc.removeWatch();
Gunnar Mills94df8c92018-09-14 14:50:03 -0500161 error.removeWatch();
Eddie Jamescbad2192021-10-07 09:39:39 -0500162 timeout.removeWatch();
Gunnar Mills94df8c92018-09-14 14:50:03 -0500163 throttleMemTemp.removeWatch();
164 throttleProcPower.removeWatch();
165 throttleProcTemp.removeWatch();
166 }
167
168 /** @brief Starts to watch how many OCCs are present on the master */
169 inline void addPresenceWatchMaster()
170 {
171 if (master())
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530172 {
Gunnar Mills94df8c92018-09-14 14:50:03 -0500173 presence.addWatch();
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530174 }
Gunnar Mills94df8c92018-09-14 14:50:03 -0500175 }
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530176
Eddie James774f9af2019-03-19 20:58:53 +0000177 /** @brief helper function to get the last part of the path
178 *
179 * @param[in] path - Path to parse
180 * @return - Last directory name in the path
181 */
182 static std::string getPathBack(const fs::path& path);
183
Chris Cain78e86012021-03-04 16:15:31 -0600184 /** @brief Returns true if device represents the master OCC */
185 bool master() const;
186
Gunnar Mills94df8c92018-09-14 14:50:03 -0500187 private:
188 /** @brief Config value to be used to do bind and unbind */
189 const std::string config;
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530190
Eddie James774f9af2019-03-19 20:58:53 +0000191 /** @brief This directory contains the error files */
192 const fs::path devPath;
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530193
Eddie Jamescbad2192021-10-07 09:39:39 -0500194 /** @brief OCC instance ID */
195 const unsigned int instance;
196
Gunnar Mills94df8c92018-09-14 14:50:03 -0500197 /** @brief To bind the device to the OCC driver, do:
198 *
199 * Write occ<#>-dev0 to: /sys/bus/platform/drivers/occ-hwmon/bind
200 */
201 static fs::path bindPath;
Vishwanatha Subbannab57f1512017-09-04 15:06:20 +0530202
Gunnar Mills94df8c92018-09-14 14:50:03 -0500203 /** @brief To un-bind the device from the OCC driver, do:
204 * Write occ<#>-dev0 to: /sys/bus/platform/drivers/occ-hwmon/unbind
205 */
206 static fs::path unBindPath;
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530207
Gunnar Mills94df8c92018-09-14 14:50:03 -0500208 /** Store the associated Status instance */
209 Status& statusObject;
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530210
Eddie Jamescbad2192021-10-07 09:39:39 -0500211 /** Store the parent Manager instance */
212 Manager& managerObject;
213
Gunnar Mills94df8c92018-09-14 14:50:03 -0500214 /** Abstraction of error monitoring */
215 Error error;
Eddie Jamesdae2d942017-12-20 10:50:03 -0600216
Eddie Jamescbad2192021-10-07 09:39:39 -0500217 /** Abstraction of SBE timeout monitoring */
218 Error timeout;
219
Eddie James2f9f9bb2021-09-20 14:26:31 -0500220 /** SBE FFDC monitoring */
221 FFDC ffdc;
222
Gunnar Mills94df8c92018-09-14 14:50:03 -0500223 /** Abstraction of OCC presence monitoring */
224 Presence presence;
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530225
Gunnar Mills94df8c92018-09-14 14:50:03 -0500226 /** Error instances for watching for throttling events */
227 Error throttleProcTemp;
228 Error throttleProcPower;
229 Error throttleMemTemp;
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530230
Gunnar Mills94df8c92018-09-14 14:50:03 -0500231 /** @brief file writer to achieve bind and unbind
232 *
233 * @param[in] filename - Name of file to be written
234 * @param[in] data - Data to be written to
235 * @return - None
236 */
237 void write(const fs::path& fileName, const std::string& data)
238 {
239 // If there is an error, move the exception all the way up
240 std::ofstream file(fileName, std::ios::out);
241 file << data;
242 file.close();
243 return;
244 }
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530245
Eddie Jamescbad2192021-10-07 09:39:39 -0500246 /** @brief callback for OCC error and presence monitoring
247 *
248 * @param[in] error - True if an error is reported, false otherwise
249 */
250 void errorCallback(bool error);
251
252#ifdef PLDM
253 /** @brief callback for SBE timeout monitoring
254 *
255 * @param[in] error - True if an error is reported, false otherwise
256 */
257 void timeoutCallback(bool error);
258#endif
259
Gunnar Mills94df8c92018-09-14 14:50:03 -0500260 /** @brief callback for the proc temp throttle event
261 *
262 * @param[in] error - True if an error is reported, false otherwise
263 */
264 void throttleProcTempCallback(bool error);
Eddie James482e31f2017-09-14 13:17:17 -0500265
Gunnar Mills94df8c92018-09-14 14:50:03 -0500266 /** @brief callback for the proc power throttle event
267 *
268 * @param[in] error - True if an error is reported, false otherwise
269 */
270 void throttleProcPowerCallback(bool error);
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530271
Gunnar Mills94df8c92018-09-14 14:50:03 -0500272 /** @brief callback for the proc temp throttle event
273 *
274 * @param[in] error - True if an error is reported, false otherwise
275 */
276 void throttleMemTempCallback(bool error);
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530277};
278
279} // namespace occ
280} // namespace open_power