xref: /openbmc/openpower-occ-control/occ_device.hpp (revision 16a5adb204d261be727c67c4ea3b64a0965303e0)
1 #pragma once
2 
3 #include "config.h"
4 
5 #include "occ_errors.hpp"
6 #include "occ_events.hpp"
7 #include "occ_ffdc.hpp"
8 #include "occ_presence.hpp"
9 #include "powermode.hpp"
10 
11 #include <org/open_power/OCC/Device/error.hpp>
12 
13 #include <filesystem>
14 #include <fstream>
15 #include <regex>
16 
17 namespace open_power
18 {
19 namespace occ
20 {
21 
22 class Manager;
23 class Status;
24 namespace fs = std::filesystem;
25 using namespace sdbusplus::org::open_power::OCC::Device::Error;
26 
27 /** @class Device
28  *  @brief Binds and unbinds the OCC driver upon request
29  */
30 class Device
31 {
32   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;
39 
40     /** @brief Constructs the Device object
41      *
42      *  @param[in] event    - Unique ptr reference to sd_event
43      *  @param[in] path     - Path to the OCC instance
44      *  @param[in] manager  - OCC manager instance
45      *  @param[in] status   - Status instance
46      *  @param[in] instance - OCC instance number
47      */
Device(EventPtr & event,const fs::path & path,Manager & manager,Status & status,std::unique_ptr<powermode::PowerMode> & powerModeRef,unsigned int instance=0)48     Device(EventPtr& event, const fs::path& path, Manager& manager,
49            Status& status,
50 
51            std::unique_ptr<powermode::PowerMode>& powerModeRef,
52 
53            unsigned int instance = 0) :
54         devPath(path), instance(instance), statusObject(status),
55         managerObject(manager),
56         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                 std::bind(std::mem_fn(&Device::timeoutCallback), this,
64                           std::placeholders::_1)),
65         ffdc(event, path / "ffdc", instance),
66         presence(event, path / "occs_present", manager,
67                  std::bind(std::mem_fn(&Device::errorCallback), this,
68                            std::placeholders::_1)),
69         throttleProcTemp(
70             event, path / "occ_dvfs_overtemp",
71             std::bind(std::mem_fn(&Device::throttleProcTempCallback), this,
72                       std::placeholders::_1)),
73         throttleProcPower(
74             event, path / "occ_dvfs_power",
75             std::bind(std::mem_fn(&Device::throttleProcPowerCallback), this,
76                       std::placeholders::_1)),
77         throttleMemTemp(event, path / "occ_mem_throttle",
78                         std::bind(std::mem_fn(&Device::throttleMemTempCallback),
79                                   this, std::placeholders::_1)),
80         pmode(powerModeRef)
81     {
82         // Nothing to do here
83     }
84 
85     /** @brief Sets the device active or inactive
86      *
87      * @param[in] active - Indicates whether or not to set the device active
88      */
89     void setActive(bool active);
90 
91     /** @brief Starts to monitor for errors
92      *
93      *  @param[in] poll - Indicates whether or not the error file should
94      *                    actually be polled for changes. Disabling polling is
95      *                    necessary for error files that don't support the poll
96      *                    file operation.
97      */
addErrorWatch(bool poll=true)98     inline void addErrorWatch(bool poll = true)
99     {
100         throttleProcTemp.addWatch(poll);
101 
102         if (master())
103         {
104             pmode->addIpsWatch(poll);
105         }
106 
107         throttleProcPower.addWatch(poll);
108         throttleMemTemp.addWatch(poll);
109 
110         try
111         {
112             ffdc.addWatch(poll);
113         }
114         catch (const OpenFailure& e)
115         {
116             // nothing to do if there is no FFDC file
117         }
118 
119         try
120         {
121             timeout.addWatch(poll);
122         }
123         catch (const std::exception& e)
124         {
125             // nothing to do if there is no SBE timeout file
126         }
127 
128         error.addWatch(poll);
129     }
130 
131     /** @brief stops monitoring for errors */
removeErrorWatch()132     inline void removeErrorWatch()
133     {
134         // we can always safely remove watch even if we don't add it
135         presence.removeWatch();
136         ffdc.removeWatch();
137         error.removeWatch();
138         timeout.removeWatch();
139         throttleMemTemp.removeWatch();
140         throttleProcPower.removeWatch();
141         throttleProcTemp.removeWatch();
142 
143         if (master())
144         {
145             pmode->removeIpsWatch();
146         }
147     }
148 
149     /** @brief Starts to watch how many OCCs are present on the master */
addPresenceWatchMaster()150     inline void addPresenceWatchMaster()
151     {
152         if (master())
153         {
154             presence.addWatch();
155         }
156     }
157 
158     /** @brief helper function to get the last part of the path
159      *
160      * @param[in] path - Path to parse
161      * @return         - Last directory name in the path
162      */
163     static std::string getPathBack(const fs::path& path);
164 
165     /** @brief Returns true if the device is active */
166     bool active() const;
167 
168     /** @brief Returns true if device represents the master OCC */
169     bool master() const;
170 
171   private:
172     /** @brief This directory contains the error files */
173     const fs::path devPath;
174 
175     /** @brief OCC instance ID */
176     const unsigned int instance;
177 
178     /**  Store the associated Status instance */
179     Status& statusObject;
180 
181     /** Store the parent Manager instance */
182     Manager& managerObject;
183 
184     /** Abstraction of error monitoring */
185     Error error;
186 
187     /** Abstraction of SBE timeout monitoring */
188     Error timeout;
189 
190     /** SBE FFDC monitoring */
191     FFDC ffdc;
192 
193     /** Abstraction of OCC presence monitoring */
194     Presence presence;
195 
196     /** Error instances for watching for throttling events */
197     Error throttleProcTemp;
198     Error throttleProcPower;
199     Error throttleMemTemp;
200 
201     /** @brief OCC PowerMode object */
202     std::unique_ptr<powermode::PowerMode>& pmode;
203 
204     /** @brief file reader to read a binary string ("1" or "0")
205      *
206      * @param[in] fileName - Name of file to be read
207      * @return             - The value returned by reading the file
208      */
209     bool readBinary(const std::string& fileName) const;
210 
211     /** @brief file writer to achieve bind and unbind
212      *
213      *  @param[in] filename - Name of file to be written
214      *  @param[in] data     - Data to be written to
215      *  @return             - None
216      */
write(const fs::path & fileName,const std::string & data)217     void write(const fs::path& fileName, const std::string& data)
218     {
219         // If there is an error, move the exception all the way up
220         std::ofstream file(fileName, std::ios::out);
221         file << data;
222         file.close();
223         return;
224     }
225 
226     /** @brief callback for OCC error monitoring
227      *
228      * @param[in] error - Errno stored in the error file, 0 if no error
229      */
230     void errorCallback(int error);
231 
232     /** @brief callback for OCC presence monitoring
233      *
234      * @param[in] occsPresent - The number of OCCs indicated in the poll
235      * response
236      */
237     void presenceCallback(int occsPresent);
238 
239     /** @brief callback for SBE timeout monitoring
240      *
241      * @param[in] error - True if an error is reported, false otherwise
242      */
243     void timeoutCallback(int error);
244 
245     /** @brief callback for the proc temp throttle event
246      *
247      *  @param[in] error - True if an error is reported, false otherwise
248      */
249     void throttleProcTempCallback(int error);
250 
251     /** @brief callback for the proc power throttle event
252      *
253      *  @param[in] error - True if an error is reported, false otherwise
254      */
255     void throttleProcPowerCallback(int error);
256 
257     /** @brief callback for the proc temp throttle event
258      *
259      *  @param[in] error - True if an error is reported, false otherwise
260      */
261     void throttleMemTempCallback(int error);
262 
263     /** @brief Get the pathname for a file based on a regular expression
264      *
265      *  @param[in] basePath - The path where the files will be checked
266      *  @param[in] expr - Regular expression describing the target file
267      *
268      *  @return path to the file or empty path if not found
269      */
270     fs::path getFilenameByRegex(fs::path basePath,
271                                 const std::regex& expr) const;
272 };
273 
274 } // namespace occ
275 } // namespace open_power
276