blob: be9f90e1bf146e3de92ab96fb0db2c8236775e8c [file] [log] [blame]
Chris Cain5d66a0a2022-02-09 08:52:10 -06001#include "occ_status.hpp"
2
Andrew Geissler32016d12017-06-20 15:46:52 -05003#include <phosphor-logging/log.hpp>
Gunnar Mills94df8c92018-09-14 14:50:03 -05004#include <powercap.hpp>
George Liub5ca1012021-09-10 12:53:11 +08005
6#include <cassert>
Chris Caine2d0a432022-03-28 11:08:49 -05007#include <filesystem>
Patrick Williams48002492024-02-13 21:43:32 -06008#include <format>
Andrew Geissler32016d12017-06-20 15:46:52 -05009
10namespace open_power
11{
12namespace occ
13{
14namespace powercap
15{
16
Gunnar Mills94df8c92018-09-14 14:50:03 -050017constexpr auto PCAP_PATH = "/xyz/openbmc_project/control/host0/power_cap";
Andrew Geissler52cf26a2017-07-06 12:56:32 -050018constexpr auto PCAP_INTERFACE = "xyz.openbmc_project.Control.Power.Cap";
19
Andrew Geissler52cf26a2017-07-06 12:56:32 -050020constexpr auto POWER_CAP_PROP = "PowerCap";
21constexpr auto POWER_CAP_ENABLE_PROP = "PowerCapEnable";
Chris Cain613dc902022-04-08 09:56:22 -050022constexpr auto POWER_CAP_SOFT_MIN = "MinSoftPowerCapValue";
Chris Cain5d66a0a2022-02-09 08:52:10 -060023constexpr auto POWER_CAP_HARD_MIN = "MinPowerCapValue";
24constexpr auto POWER_CAP_MAX = "MaxPowerCapValue";
Andrew Geissler52cf26a2017-07-06 12:56:32 -050025
Andrew Geissler32016d12017-06-20 15:46:52 -050026using namespace phosphor::logging;
George Liubcef3b42021-09-10 12:39:02 +080027namespace fs = std::filesystem;
Andrew Geissler32016d12017-06-20 15:46:52 -050028
Chris Cain5d66a0a2022-02-09 08:52:10 -060029void PowerCap::updatePcapBounds()
30{
31 // Build the hwmon string to write the power cap bounds
32 fs::path minName = getPcapFilename(std::regex{"power\\d+_cap_min$"});
Chris Cain613dc902022-04-08 09:56:22 -050033 fs::path softMinName =
34 getPcapFilename(std::regex{"power\\d+_cap_min_soft$"});
Chris Cain5d66a0a2022-02-09 08:52:10 -060035 fs::path maxName = getPcapFilename(std::regex{"power\\d+_cap_max$"});
36
Chris Cain81c83432022-06-27 08:21:52 -050037 // Read the current cap bounds from dbus
38 uint32_t capSoftMin, capHardMin, capMax;
39 readDbusPcapLimits(capSoftMin, capHardMin, capMax);
Chris Cain613dc902022-04-08 09:56:22 -050040
Chris Cain81c83432022-06-27 08:21:52 -050041 // Read the power cap bounds from sysfs files (from OCC)
42 uint64_t cap;
Chris Cain613dc902022-04-08 09:56:22 -050043 std::ifstream softMinFile(softMinName, std::ios::in);
44 if (softMinFile)
45 {
46 softMinFile >> cap;
47 softMinFile.close();
Chris Cain81c83432022-06-27 08:21:52 -050048 // Convert to input/AC Power in Watts (round up)
Chris Cain613dc902022-04-08 09:56:22 -050049 capSoftMin = ((cap / (PS_DERATING_FACTOR / 100.0) / 1000000) + 0.9);
50 }
51 else
52 {
53 log<level::ERR>(
Patrick Williams48002492024-02-13 21:43:32 -060054 std::format(
Chris Cain613dc902022-04-08 09:56:22 -050055 "updatePcapBounds: unable to find pcap_min_soft file: {} (errno={})",
56 pcapBasePathname.c_str(), errno)
57 .c_str());
58 }
59
Chris Cain5d66a0a2022-02-09 08:52:10 -060060 std::ifstream minFile(minName, std::ios::in);
61 if (minFile)
62 {
63 minFile >> cap;
64 minFile.close();
Chris Cain81c83432022-06-27 08:21:52 -050065 // Convert to input/AC Power in Watts (round up)
Chris Cain8676e032022-03-24 15:06:23 -050066 capHardMin = ((cap / (PS_DERATING_FACTOR / 100.0) / 1000000) + 0.9);
Chris Cain5d66a0a2022-02-09 08:52:10 -060067 }
68 else
69 {
70 log<level::ERR>(
Patrick Williams48002492024-02-13 21:43:32 -060071 std::format(
Chris Cain5d66a0a2022-02-09 08:52:10 -060072 "updatePcapBounds: unable to find cap_min file: {} (errno={})",
73 pcapBasePathname.c_str(), errno)
74 .c_str());
75 }
Chris Cain613dc902022-04-08 09:56:22 -050076
Chris Cain5d66a0a2022-02-09 08:52:10 -060077 std::ifstream maxFile(maxName, std::ios::in);
78 if (maxFile)
79 {
80 maxFile >> cap;
81 maxFile.close();
Chris Cain81c83432022-06-27 08:21:52 -050082 // Convert to input/AC Power in Watts (truncate remainder)
Chris Cain8676e032022-03-24 15:06:23 -050083 capMax = cap / (PS_DERATING_FACTOR / 100.0) / 1000000;
Chris Cain5d66a0a2022-02-09 08:52:10 -060084 }
85 else
86 {
87 log<level::ERR>(
Patrick Williams48002492024-02-13 21:43:32 -060088 std::format(
Chris Cain5d66a0a2022-02-09 08:52:10 -060089 "updatePcapBounds: unable to find cap_max file: {} (errno={})",
90 pcapBasePathname.c_str(), errno)
91 .c_str());
92 }
93
Chris Cain81c83432022-06-27 08:21:52 -050094 // Save the power cap bounds to dbus
95 updateDbusPcapLimits(capSoftMin, capHardMin, capMax);
Chris Cain40501a22022-03-14 17:33:27 -050096
Chris Cain81c83432022-06-27 08:21:52 -050097 // Validate user power cap (if enabled) is within the bounds
Chris Cain40501a22022-03-14 17:33:27 -050098 const uint32_t dbusUserCap = getPcap();
Chris Cain81c83432022-06-27 08:21:52 -050099 const bool pcapEnabled = getPcapEnabled();
100 if (pcapEnabled && (dbusUserCap != 0))
Chris Cain40501a22022-03-14 17:33:27 -0500101 {
Chris Cain81c83432022-06-27 08:21:52 -0500102 const uint32_t hwmonUserCap = readUserCapHwmon();
103 if ((dbusUserCap >= capSoftMin) && (dbusUserCap <= capMax))
104 {
105 // Validate dbus and hwmon user caps match
106 if ((hwmonUserCap != 0) && (dbusUserCap != hwmonUserCap))
107 {
108 // User power cap is enabled, but does not match dbus
109 log<level::ERR>(
Patrick Williams48002492024-02-13 21:43:32 -0600110 std::format(
Chris Cain81c83432022-06-27 08:21:52 -0500111 "updatePcapBounds: user powercap mismatch (hwmon:{}W, bdus:{}W) - using dbus",
112 hwmonUserCap, dbusUserCap)
113 .c_str());
114 auto occInput = getOccInput(dbusUserCap, pcapEnabled);
115 writeOcc(occInput);
116 }
117 }
118 else
119 {
120 // User power cap is outside of current bounds
121 uint32_t newCap = capMax;
122 if (dbusUserCap < capSoftMin)
123 {
124 newCap = capSoftMin;
125 }
126 log<level::ERR>(
Patrick Williams48002492024-02-13 21:43:32 -0600127 std::format(
Chris Cain81c83432022-06-27 08:21:52 -0500128 "updatePcapBounds: user powercap {}W is outside bounds "
129 "(soft min:{}, min:{}, max:{})",
130 dbusUserCap, capSoftMin, capHardMin, capMax)
131 .c_str());
132 try
133 {
134 log<level::INFO>(
Patrick Williams48002492024-02-13 21:43:32 -0600135 std::format(
Chris Cain81c83432022-06-27 08:21:52 -0500136 "updatePcapBounds: Updating user powercap from {} to {}W",
137 hwmonUserCap, newCap)
138 .c_str());
139 utils::setProperty(PCAP_PATH, PCAP_INTERFACE, POWER_CAP_PROP,
140 newCap);
141 auto occInput = getOccInput(newCap, pcapEnabled);
142 writeOcc(occInput);
143 }
Patrick Williamsaf408082022-07-22 19:26:54 -0500144 catch (const sdbusplus::exception_t& e)
Chris Cain81c83432022-06-27 08:21:52 -0500145 {
146 log<level::ERR>(
Patrick Williams48002492024-02-13 21:43:32 -0600147 std::format(
Chris Cain81c83432022-06-27 08:21:52 -0500148 "updatePcapBounds: Failed to update user powercap due to ",
149 e.what())
150 .c_str());
151 }
152 }
Chris Cain40501a22022-03-14 17:33:27 -0500153 }
Chris Cain5d66a0a2022-02-09 08:52:10 -0600154}
155
Chris Cain81c83432022-06-27 08:21:52 -0500156// Get value of power cap to send to the OCC (output/DC power)
Andrew Geissler4cea4d22017-07-10 15:13:33 -0500157uint32_t PowerCap::getOccInput(uint32_t pcap, bool pcapEnabled)
158{
159 if (!pcapEnabled)
160 {
161 // Pcap disabled, return 0 to indicate disabled
162 return 0;
163 }
164
165 // If pcap is not disabled then just return the pcap with the derating
Chris Cain81c83432022-06-27 08:21:52 -0500166 // factor applied (output/DC power).
Gunnar Mills94df8c92018-09-14 14:50:03 -0500167 return ((static_cast<uint64_t>(pcap) * PS_DERATING_FACTOR) / 100);
Andrew Geissler4cea4d22017-07-10 15:13:33 -0500168}
169
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500170uint32_t PowerCap::getPcap()
171{
George Liuf3b75142021-06-10 11:22:50 +0800172 utils::PropertyValue pcap{};
173 try
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500174 {
George Liuf3b75142021-06-10 11:22:50 +0800175 pcap = utils::getProperty(PCAP_PATH, PCAP_INTERFACE, POWER_CAP_PROP);
176
177 return std::get<uint32_t>(pcap);
178 }
Patrick Williamsaf408082022-07-22 19:26:54 -0500179 catch (const sdbusplus::exception_t& e)
George Liuf3b75142021-06-10 11:22:50 +0800180 {
181 log<level::ERR>("Failed to get PowerCap property",
182 entry("ERROR=%s", e.what()),
183 entry("PATH=%s", PCAP_PATH));
184
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500185 return 0;
186 }
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500187}
188
189bool PowerCap::getPcapEnabled()
190{
George Liuf3b75142021-06-10 11:22:50 +0800191 utils::PropertyValue pcapEnabled{};
192 try
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500193 {
George Liuf3b75142021-06-10 11:22:50 +0800194 pcapEnabled = utils::getProperty(PCAP_PATH, PCAP_INTERFACE,
195 POWER_CAP_ENABLE_PROP);
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500196
George Liuf3b75142021-06-10 11:22:50 +0800197 return std::get<bool>(pcapEnabled);
198 }
Patrick Williamsaf408082022-07-22 19:26:54 -0500199 catch (const sdbusplus::exception_t& e)
George Liuf3b75142021-06-10 11:22:50 +0800200 {
201 log<level::ERR>("Failed to get PowerCapEnable property",
202 entry("ERROR=%s", e.what()),
203 entry("PATH=%s", PCAP_PATH));
204
205 return false;
206 }
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500207}
Andrew Geissler32016d12017-06-20 15:46:52 -0500208
Chris Cain5d66a0a2022-02-09 08:52:10 -0600209fs::path PowerCap::getPcapFilename(const std::regex& expr)
Matt Spinlereaaf3b22019-07-16 10:29:27 -0500210{
Chris Cain5d66a0a2022-02-09 08:52:10 -0600211 if (pcapBasePathname.empty())
212 {
Chris Cain5d66a0a2022-02-09 08:52:10 -0600213 pcapBasePathname = occStatus.getHwmonPath();
Chris Cain5d66a0a2022-02-09 08:52:10 -0600214 }
Chris Caine2d0a432022-03-28 11:08:49 -0500215
216 if (fs::exists(pcapBasePathname))
Matt Spinlereaaf3b22019-07-16 10:29:27 -0500217 {
Chris Caine2d0a432022-03-28 11:08:49 -0500218 // Search for pcap file based on the supplied expr
219 for (auto& file : fs::directory_iterator(pcapBasePathname))
Matt Spinlereaaf3b22019-07-16 10:29:27 -0500220 {
Chris Caine2d0a432022-03-28 11:08:49 -0500221 if (std::regex_search(file.path().string(), expr))
222 {
223 // Found match
224 return file;
225 }
Matt Spinlereaaf3b22019-07-16 10:29:27 -0500226 }
227 }
Chris Caine2d0a432022-03-28 11:08:49 -0500228 else
229 {
Patrick Williams48002492024-02-13 21:43:32 -0600230 log<level::ERR>(std::format("Power Cap base filename not found: {}",
Chris Caine2d0a432022-03-28 11:08:49 -0500231 pcapBasePathname.c_str())
232 .c_str());
233 }
234
Chris Cain5d66a0a2022-02-09 08:52:10 -0600235 // return empty path
236 return fs::path{};
Matt Spinlereaaf3b22019-07-16 10:29:27 -0500237}
238
Chris Cain81c83432022-06-27 08:21:52 -0500239// Write the user power cap to sysfs (output/DC power)
Chris Cain40501a22022-03-14 17:33:27 -0500240// This will trigger the driver to send the cap to the OCC
Andrew Geissler6ac874e2017-07-10 15:54:58 -0500241void PowerCap::writeOcc(uint32_t pcapValue)
242{
Chris Caind4c19a02022-04-22 15:46:13 -0500243 if (!occStatus.occActive())
244 {
245 // OCC not running, skip update
246 return;
247 }
248
Chris Cain5d66a0a2022-02-09 08:52:10 -0600249 // Build the hwmon string to write the user power cap
250 fs::path fileName = getPcapFilename(std::regex{"power\\d+_cap_user$"});
251 if (fileName.empty())
Matt Spinlereaaf3b22019-07-16 10:29:27 -0500252 {
Chris Cainb6535e82022-01-21 08:24:13 -0600253 log<level::ERR>(
Patrick Williams48002492024-02-13 21:43:32 -0600254 std::format("Could not find a power cap file to write to: {})",
Chris Cain5d66a0a2022-02-09 08:52:10 -0600255 pcapBasePathname.c_str())
Chris Cainb6535e82022-01-21 08:24:13 -0600256 .c_str());
Matt Spinlereaaf3b22019-07-16 10:29:27 -0500257 return;
258 }
Matt Spinlereaaf3b22019-07-16 10:29:27 -0500259
260 uint64_t microWatts = pcapValue * 1000000ull;
261
262 auto pcapString{std::to_string(microWatts)};
Andrew Geissler6ac874e2017-07-10 15:54:58 -0500263
Andrew Geissler6ac874e2017-07-10 15:54:58 -0500264 // Open the hwmon file and write the power cap
Chris Cain5d66a0a2022-02-09 08:52:10 -0600265 std::ofstream file(fileName, std::ios::out);
266 if (file)
267 {
Patrick Williams48002492024-02-13 21:43:32 -0600268 log<level::INFO>(std::format("Writing {}uW to {}", pcapString.c_str(),
Chris Cain5d66a0a2022-02-09 08:52:10 -0600269 fileName.c_str())
270 .c_str());
271 file << pcapString;
272 file.close();
273 }
274 else
275 {
Patrick Williams48002492024-02-13 21:43:32 -0600276 log<level::ERR>(std::format("Failed writing {}uW to {} (errno={})",
Chris Cain5d66a0a2022-02-09 08:52:10 -0600277 microWatts, fileName.c_str(), errno)
278 .c_str());
279 }
280
Andrew Geissler6ac874e2017-07-10 15:54:58 -0500281 return;
282}
283
Chris Cain81c83432022-06-27 08:21:52 -0500284// Read the current user power cap from sysfs as input/AC power
Chris Cain40501a22022-03-14 17:33:27 -0500285uint32_t PowerCap::readUserCapHwmon()
286{
287 uint32_t userCap = 0;
288
289 // Get the sysfs filename for the user power cap
290 fs::path userCapName = getPcapFilename(std::regex{"power\\d+_cap_user$"});
291 if (userCapName.empty())
292 {
293 log<level::ERR>(
Patrick Williams48002492024-02-13 21:43:32 -0600294 std::format(
Chris Cain40501a22022-03-14 17:33:27 -0500295 "readUserCapHwmon: Could not find a power cap file to read: {})",
296 pcapBasePathname.c_str())
297 .c_str());
298 return 0;
299 }
300
301 // Open the sysfs file and read the power cap
Chris Cain40501a22022-03-14 17:33:27 -0500302 std::ifstream file(userCapName, std::ios::in);
303 if (file)
304 {
Chris Caine2d0a432022-03-28 11:08:49 -0500305 uint64_t cap;
Chris Cain40501a22022-03-14 17:33:27 -0500306 file >> cap;
307 file.close();
Chris Cain81c83432022-06-27 08:21:52 -0500308 // Convert to input/AC Power in Watts
309 userCap = (cap / (PS_DERATING_FACTOR / 100.0) / 1000000);
Chris Cain40501a22022-03-14 17:33:27 -0500310 }
311 else
312 {
313 log<level::ERR>(
Patrick Williams48002492024-02-13 21:43:32 -0600314 std::format("readUserCapHwmon: Failed reading {} (errno={})",
Chris Cain40501a22022-03-14 17:33:27 -0500315 userCapName.c_str(), errno)
316 .c_str());
317 }
318
319 return userCap;
320}
321
Patrick Williamsaf408082022-07-22 19:26:54 -0500322void PowerCap::pcapChanged(sdbusplus::message_t& msg)
Andrew Geissler32016d12017-06-20 15:46:52 -0500323{
Andrew Geissler32016d12017-06-20 15:46:52 -0500324 if (!occStatus.occActive())
325 {
Chris Cain5d66a0a2022-02-09 08:52:10 -0600326 // Nothing to do
Andrew Geissler32016d12017-06-20 15:46:52 -0500327 return;
328 }
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500329
330 uint32_t pcap = 0;
331 bool pcapEnabled = false;
332
333 std::string msgSensor;
Patrick Williamse0962702020-05-13 17:50:22 -0500334 std::map<std::string, std::variant<uint32_t, bool>> msgData;
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500335 msg.read(msgSensor, msgData);
336
Chris Cain5d66a0a2022-02-09 08:52:10 -0600337 bool changeFound = false;
338 for (const auto& [prop, value] : msgData)
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500339 {
Chris Cain5d66a0a2022-02-09 08:52:10 -0600340 if (prop == POWER_CAP_PROP)
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500341 {
Chris Cain5d66a0a2022-02-09 08:52:10 -0600342 pcap = std::get<uint32_t>(value);
343 pcapEnabled = getPcapEnabled();
344 changeFound = true;
345 }
346 else if (prop == POWER_CAP_ENABLE_PROP)
347 {
348 pcapEnabled = std::get<bool>(value);
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500349 pcap = getPcap();
Chris Cain5d66a0a2022-02-09 08:52:10 -0600350 changeFound = true;
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500351 }
352 else
353 {
Chris Cain5d66a0a2022-02-09 08:52:10 -0600354 // Ignore other properties
355 log<level::DEBUG>(
Patrick Williams48002492024-02-13 21:43:32 -0600356 std::format(
Chris Cain5d66a0a2022-02-09 08:52:10 -0600357 "pcapChanged: Unknown power cap property changed {} to {}",
358 prop.c_str(), std::get<uint32_t>(value))
359 .c_str());
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500360 }
361 }
362
Chris Cain81c83432022-06-27 08:21:52 -0500363 // Validate the cap is within supported range
364 uint32_t capSoftMin, capHardMin, capMax;
365 readDbusPcapLimits(capSoftMin, capHardMin, capMax);
366 if (((pcap > 0) && (pcap < capSoftMin)) || ((pcap == 0) && (pcapEnabled)))
367 {
368 log<level::ERR>(
Patrick Williams48002492024-02-13 21:43:32 -0600369 std::format(
Chris Cain81c83432022-06-27 08:21:52 -0500370 "pcapChanged: Power cap of {}W is lower than allowed (soft min:{}, min:{}) - using soft min",
371 pcap, capSoftMin, capHardMin)
372 .c_str());
373 pcap = capSoftMin;
374 utils::setProperty(PCAP_PATH, PCAP_INTERFACE, POWER_CAP_PROP, pcap);
375 }
376 else if (pcap > capMax)
377 {
378 log<level::ERR>(
Patrick Williams48002492024-02-13 21:43:32 -0600379 std::format(
Chris Cain81c83432022-06-27 08:21:52 -0500380 "pcapChanged: Power cap of {}W is higher than allowed (max:{}) - using max",
381 pcap, capSoftMin, capHardMin)
382 .c_str());
383 pcap = capMax;
384 utils::setProperty(PCAP_PATH, PCAP_INTERFACE, POWER_CAP_PROP, pcap);
385 }
386
Chris Cain5d66a0a2022-02-09 08:52:10 -0600387 if (changeFound)
388 {
389 log<level::INFO>(
Patrick Williams48002492024-02-13 21:43:32 -0600390 std::format(
Chris Cain5d66a0a2022-02-09 08:52:10 -0600391 "Power Cap Property Change (cap={}W (input), enabled={})", pcap,
392 pcapEnabled ? 'y' : 'n')
393 .c_str());
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500394
Chris Cain5d66a0a2022-02-09 08:52:10 -0600395 // Determine desired action to write to occ
Chris Cain5d66a0a2022-02-09 08:52:10 -0600396 auto occInput = getOccInput(pcap, pcapEnabled);
Chris Cain5d66a0a2022-02-09 08:52:10 -0600397 // Write action to occ
398 writeOcc(occInput);
399 }
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500400
401 return;
Andrew Geissler32016d12017-06-20 15:46:52 -0500402}
403
Chris Cain5d66a0a2022-02-09 08:52:10 -0600404// Update the Power Cap bounds on DBus
Chris Cain81c83432022-06-27 08:21:52 -0500405bool PowerCap::updateDbusPcapLimits(uint32_t softMin, uint32_t hardMin,
406 uint32_t max)
Chris Cain5d66a0a2022-02-09 08:52:10 -0600407{
408 bool complete = true;
409
410 try
411 {
Chris Cain613dc902022-04-08 09:56:22 -0500412 utils::setProperty(PCAP_PATH, PCAP_INTERFACE, POWER_CAP_SOFT_MIN,
413 softMin);
414 }
Patrick Williamsaf408082022-07-22 19:26:54 -0500415 catch (const sdbusplus::exception_t& e)
Chris Cain613dc902022-04-08 09:56:22 -0500416 {
417 log<level::ERR>(
Patrick Williams48002492024-02-13 21:43:32 -0600418 std::format(
Chris Cain81c83432022-06-27 08:21:52 -0500419 "updateDbusPcapLimits: Failed to set SOFT PCAP to {}W due to {}",
Chris Cain613dc902022-04-08 09:56:22 -0500420 softMin, e.what())
421 .c_str());
422 complete = false;
423 }
424
425 try
426 {
Chris Cain5d66a0a2022-02-09 08:52:10 -0600427 utils::setProperty(PCAP_PATH, PCAP_INTERFACE, POWER_CAP_HARD_MIN,
428 hardMin);
429 }
Patrick Williamsaf408082022-07-22 19:26:54 -0500430 catch (const sdbusplus::exception_t& e)
Chris Cain5d66a0a2022-02-09 08:52:10 -0600431 {
432 log<level::ERR>(
Patrick Williams48002492024-02-13 21:43:32 -0600433 std::format(
Chris Cain81c83432022-06-27 08:21:52 -0500434 "updateDbusPcapLimits: Failed to set HARD PCAP to {}W due to {}",
Chris Cain5d66a0a2022-02-09 08:52:10 -0600435 hardMin, e.what())
436 .c_str());
437 complete = false;
438 }
439
440 try
441 {
442 utils::setProperty(PCAP_PATH, PCAP_INTERFACE, POWER_CAP_MAX, max);
443 }
Patrick Williamsaf408082022-07-22 19:26:54 -0500444 catch (const sdbusplus::exception_t& e)
Chris Cain5d66a0a2022-02-09 08:52:10 -0600445 {
446 log<level::ERR>(
Patrick Williams48002492024-02-13 21:43:32 -0600447 std::format(
Chris Cain81c83432022-06-27 08:21:52 -0500448 "updateDbusPcapLimits: Failed to set MAX PCAP to {}W due to {}",
449 max, e.what())
Chris Cain5d66a0a2022-02-09 08:52:10 -0600450 .c_str());
451 complete = false;
452 }
453
454 return complete;
455}
Chris Cain81c83432022-06-27 08:21:52 -0500456
457// Read the Power Cap bounds from DBus
458bool PowerCap::readDbusPcapLimits(uint32_t& softMin, uint32_t& hardMin,
459 uint32_t& max)
460{
461 bool complete = true;
462 utils::PropertyValue prop{};
463
464 try
465 {
Patrick Williamsa49c9872023-05-10 07:50:35 -0500466 prop = utils::getProperty(PCAP_PATH, PCAP_INTERFACE,
467 POWER_CAP_SOFT_MIN);
Chris Cain81c83432022-06-27 08:21:52 -0500468 softMin = std::get<uint32_t>(prop);
469 }
Patrick Williamsaf408082022-07-22 19:26:54 -0500470 catch (const sdbusplus::exception_t& e)
Chris Cain81c83432022-06-27 08:21:52 -0500471 {
472 log<level::ERR>(
Patrick Williams48002492024-02-13 21:43:32 -0600473 std::format("readDbusPcapLimits: Failed to get SOFT PCAP due to {}",
Chris Cain81c83432022-06-27 08:21:52 -0500474 e.what())
475 .c_str());
476 softMin = 0;
477 complete = false;
478 }
479
480 try
481 {
Patrick Williamsa49c9872023-05-10 07:50:35 -0500482 prop = utils::getProperty(PCAP_PATH, PCAP_INTERFACE,
483 POWER_CAP_HARD_MIN);
Chris Cain81c83432022-06-27 08:21:52 -0500484 hardMin = std::get<uint32_t>(prop);
485 }
Patrick Williamsaf408082022-07-22 19:26:54 -0500486 catch (const sdbusplus::exception_t& e)
Chris Cain81c83432022-06-27 08:21:52 -0500487 {
488 log<level::ERR>(
Patrick Williams48002492024-02-13 21:43:32 -0600489 std::format("readDbusPcapLimits: Failed to get HARD PCAP due to {}",
Chris Cain81c83432022-06-27 08:21:52 -0500490 e.what())
491 .c_str());
492 hardMin = 0;
493 complete = false;
494 }
495
496 try
497 {
498 prop = utils::getProperty(PCAP_PATH, PCAP_INTERFACE, POWER_CAP_MAX);
499 max = std::get<uint32_t>(prop);
500 }
Patrick Williamsaf408082022-07-22 19:26:54 -0500501 catch (const sdbusplus::exception_t& e)
Chris Cain81c83432022-06-27 08:21:52 -0500502 {
503 log<level::ERR>(
Patrick Williams48002492024-02-13 21:43:32 -0600504 std::format("readDbusPcapLimits: Failed to get MAX PCAP due to {}",
Chris Cain81c83432022-06-27 08:21:52 -0500505 e.what())
506 .c_str());
507 max = INT_MAX;
508 complete = false;
509 }
510
511 return complete;
512}
513
Gunnar Mills94df8c92018-09-14 14:50:03 -0500514} // namespace powercap
Andrew Geissler32016d12017-06-20 15:46:52 -0500515
516} // namespace occ
517
Gunnar Mills94df8c92018-09-14 14:50:03 -0500518} // namespace open_power