blob: 573024c526e2e9a5384d0937adc38b071c78408e [file] [log] [blame]
Chris Cain5d66a0a2022-02-09 08:52:10 -06001#include "occ_status.hpp"
2
Chris Cain37abe9b2024-10-31 17:20:31 -05003#include <phosphor-logging/lg2.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>
Andrew Geissler32016d12017-06-20 15:46:52 -05008
9namespace open_power
10{
11namespace occ
12{
13namespace powercap
14{
15
Gunnar Mills94df8c92018-09-14 14:50:03 -050016constexpr auto PCAP_PATH = "/xyz/openbmc_project/control/host0/power_cap";
Andrew Geissler52cf26a2017-07-06 12:56:32 -050017constexpr auto PCAP_INTERFACE = "xyz.openbmc_project.Control.Power.Cap";
18
Andrew Geissler52cf26a2017-07-06 12:56:32 -050019constexpr auto POWER_CAP_PROP = "PowerCap";
20constexpr auto POWER_CAP_ENABLE_PROP = "PowerCapEnable";
21
George Liubcef3b42021-09-10 12:39:02 +080022namespace fs = std::filesystem;
Andrew Geissler32016d12017-06-20 15:46:52 -050023
Chris Caind6ced7c2022-10-17 17:11:07 -050024using CapLimits =
25 sdbusplus::xyz::openbmc_project::Control::Power::server::CapLimits;
26
27// Print the current values
28void OccPersistCapData::print()
29{
30 if (capData.initialized)
31 {
32 lg2::info(
33 "OccPersistCapData: Soft Min: {SOFT}, Hard Min: {HARD}, Max: {MAX}",
34 "SOFT", capData.softMin, "HARD", capData.hardMin, "MAX",
35 capData.max);
36 }
37}
38
39// Saves the power cap data in the filesystem.
40void OccPersistCapData::save()
41{
42 std::filesystem::path opath =
43 std::filesystem::path{OCC_CONTROL_PERSIST_PATH} / powerCapFilename;
44
45 if (!std::filesystem::exists(opath.parent_path()))
46 {
47 std::filesystem::create_directory(opath.parent_path());
48 }
49
50 try
51 {
52 std::ofstream stream{opath.c_str(), std::ios_base::binary};
53 stream.write((char*)&capData, sizeof(capData));
54 }
55 catch (const std::exception& e)
56 {
57 auto error = errno;
58 lg2::error(
59 "OccPersistCapData::save: failed to read {PATH}, errno={ERRNO}, err={ERR}",
60 "PATH", opath, "ERRNO", error, "ERR", e);
61 capData.initialized = false;
62 }
63}
64
65// Loads the power cap data from the filesystem
66void OccPersistCapData::load()
67{
68 std::filesystem::path ipath =
69 std::filesystem::path{OCC_CONTROL_PERSIST_PATH} / powerCapFilename;
70
71 if (!std::filesystem::exists(ipath))
72 {
73 capData.initialized = false;
74 return;
75 }
76
77 try
78 {
79 PowerCapData newCapData;
80 std::ifstream stream{ipath.c_str(), std::ios_base::binary};
81 stream.read((char*)&newCapData, sizeof(newCapData));
82 if (newCapData.version != PCAPDATA_FILE_VERSION)
83 {
84 lg2::warning(
85 "OccPersistCapData::load() file version was {VER} (expected {EXP})",
86 "VER", newCapData.version, "EXP", PCAPDATA_FILE_VERSION);
87 }
88 memcpy(&capData, &newCapData, sizeof(capData));
89 }
90 catch (const std::exception& e)
91 {
92 auto error = errno;
93 lg2::error(
94 "OccPersistCapData::load: failed to read {PATH}, errno={ERRNO}, err={ERR}",
95 "PATH", ipath, "ERRNO", error, "ERR", e);
96 capData.initialized = false;
97 }
98}
99
Chris Cain5d66a0a2022-02-09 08:52:10 -0600100void PowerCap::updatePcapBounds()
101{
102 // Build the hwmon string to write the power cap bounds
103 fs::path minName = getPcapFilename(std::regex{"power\\d+_cap_min$"});
Chris Cain613dc902022-04-08 09:56:22 -0500104 fs::path softMinName =
105 getPcapFilename(std::regex{"power\\d+_cap_min_soft$"});
Chris Cain5d66a0a2022-02-09 08:52:10 -0600106 fs::path maxName = getPcapFilename(std::regex{"power\\d+_cap_max$"});
107
Chris Caind6ced7c2022-10-17 17:11:07 -0500108 // Read the current limits from persistent data
Chris Cain81c83432022-06-27 08:21:52 -0500109 uint32_t capSoftMin, capHardMin, capMax;
Chris Caind6ced7c2022-10-17 17:11:07 -0500110 persistedData.getCapLimits(capSoftMin, capHardMin, capMax);
Chris Cain613dc902022-04-08 09:56:22 -0500111
Chris Cain81c83432022-06-27 08:21:52 -0500112 // Read the power cap bounds from sysfs files (from OCC)
113 uint64_t cap;
Chris Caind6ced7c2022-10-17 17:11:07 -0500114 bool parmsChanged = false;
Chris Cain613dc902022-04-08 09:56:22 -0500115 std::ifstream softMinFile(softMinName, std::ios::in);
116 if (softMinFile)
117 {
118 softMinFile >> cap;
119 softMinFile.close();
Chris Cain81c83432022-06-27 08:21:52 -0500120 // Convert to input/AC Power in Watts (round up)
Chris Cain613dc902022-04-08 09:56:22 -0500121 capSoftMin = ((cap / (PS_DERATING_FACTOR / 100.0) / 1000000) + 0.9);
Chris Caind6ced7c2022-10-17 17:11:07 -0500122 parmsChanged = true;
Chris Cain613dc902022-04-08 09:56:22 -0500123 }
124 else
125 {
Chris Cain37abe9b2024-10-31 17:20:31 -0500126 lg2::error(
127 "updatePcapBounds: unable to find pcap_min_soft file: {FILE} (errno={ERR})",
128 "FILE", pcapBasePathname, "ERR", errno);
Chris Cain613dc902022-04-08 09:56:22 -0500129 }
130
Chris Cain5d66a0a2022-02-09 08:52:10 -0600131 std::ifstream minFile(minName, std::ios::in);
132 if (minFile)
133 {
134 minFile >> cap;
135 minFile.close();
Chris Cain81c83432022-06-27 08:21:52 -0500136 // Convert to input/AC Power in Watts (round up)
Chris Cain8676e032022-03-24 15:06:23 -0500137 capHardMin = ((cap / (PS_DERATING_FACTOR / 100.0) / 1000000) + 0.9);
Chris Caind6ced7c2022-10-17 17:11:07 -0500138 parmsChanged = true;
Chris Cain5d66a0a2022-02-09 08:52:10 -0600139 }
140 else
141 {
Chris Cain37abe9b2024-10-31 17:20:31 -0500142 lg2::error(
143 "updatePcapBounds: unable to find cap_min file: {FILE} (errno={ERR})",
144 "FILE", pcapBasePathname, "ERR", errno);
Chris Cain5d66a0a2022-02-09 08:52:10 -0600145 }
Chris Cain613dc902022-04-08 09:56:22 -0500146
Chris Cain5d66a0a2022-02-09 08:52:10 -0600147 std::ifstream maxFile(maxName, std::ios::in);
148 if (maxFile)
149 {
150 maxFile >> cap;
151 maxFile.close();
Chris Cain81c83432022-06-27 08:21:52 -0500152 // Convert to input/AC Power in Watts (truncate remainder)
Chris Cain8676e032022-03-24 15:06:23 -0500153 capMax = cap / (PS_DERATING_FACTOR / 100.0) / 1000000;
Chris Caind6ced7c2022-10-17 17:11:07 -0500154 parmsChanged = true;
Chris Cain5d66a0a2022-02-09 08:52:10 -0600155 }
156 else
157 {
Chris Cain37abe9b2024-10-31 17:20:31 -0500158 lg2::error(
159 "updatePcapBounds: unable to find cap_max file: {FILE} (errno={ERR})",
160 "FILE", pcapBasePathname, "ERR", errno);
Chris Cain5d66a0a2022-02-09 08:52:10 -0600161 }
162
Chris Caind6ced7c2022-10-17 17:11:07 -0500163 if (parmsChanged)
164 {
165 // Save the power cap bounds to dbus
166 updateDbusPcapLimits(capSoftMin, capHardMin, capMax);
167 persistedData.updateCapLimits(capSoftMin, capHardMin, capMax);
168 }
Chris Cain40501a22022-03-14 17:33:27 -0500169
Chris Cain81c83432022-06-27 08:21:52 -0500170 // Validate user power cap (if enabled) is within the bounds
Chris Cain40501a22022-03-14 17:33:27 -0500171 const uint32_t dbusUserCap = getPcap();
Chris Cain81c83432022-06-27 08:21:52 -0500172 const bool pcapEnabled = getPcapEnabled();
173 if (pcapEnabled && (dbusUserCap != 0))
Chris Cain40501a22022-03-14 17:33:27 -0500174 {
Chris Cain81c83432022-06-27 08:21:52 -0500175 const uint32_t hwmonUserCap = readUserCapHwmon();
176 if ((dbusUserCap >= capSoftMin) && (dbusUserCap <= capMax))
177 {
178 // Validate dbus and hwmon user caps match
179 if ((hwmonUserCap != 0) && (dbusUserCap != hwmonUserCap))
180 {
181 // User power cap is enabled, but does not match dbus
Chris Cain37abe9b2024-10-31 17:20:31 -0500182 lg2::error(
183 "updatePcapBounds: user powercap mismatch (hwmon:{HCAP}W, bdus:{DCAP}W) - using dbus",
184 "HCAP", hwmonUserCap, "DCAP", dbusUserCap);
Chris Cain81c83432022-06-27 08:21:52 -0500185 auto occInput = getOccInput(dbusUserCap, pcapEnabled);
186 writeOcc(occInput);
187 }
188 }
189 else
190 {
191 // User power cap is outside of current bounds
192 uint32_t newCap = capMax;
193 if (dbusUserCap < capSoftMin)
194 {
195 newCap = capSoftMin;
196 }
Chris Cain37abe9b2024-10-31 17:20:31 -0500197 lg2::error(
198 "updatePcapBounds: user powercap {CAP}W is outside bounds "
199 "(soft min:{SMIN}, min:{MIN}, max:{MAX})",
200 "CAP", dbusUserCap, "SMIN", capSoftMin, "MIN", capHardMin,
201 "MAX", capMax);
Chris Cain81c83432022-06-27 08:21:52 -0500202 try
203 {
Chris Cain37abe9b2024-10-31 17:20:31 -0500204 lg2::info(
205 "updatePcapBounds: Updating user powercap from {OLD} to {NEW}W",
206 "OLD", hwmonUserCap, "NEW", newCap);
Chris Cain81c83432022-06-27 08:21:52 -0500207 utils::setProperty(PCAP_PATH, PCAP_INTERFACE, POWER_CAP_PROP,
208 newCap);
209 auto occInput = getOccInput(newCap, pcapEnabled);
210 writeOcc(occInput);
211 }
Patrick Williamsaf408082022-07-22 19:26:54 -0500212 catch (const sdbusplus::exception_t& e)
Chris Cain81c83432022-06-27 08:21:52 -0500213 {
Chris Cain37abe9b2024-10-31 17:20:31 -0500214 lg2::error(
215 "updatePcapBounds: Failed to update user powercap due to {ERR}",
216 "ERR", e.what());
Chris Cain81c83432022-06-27 08:21:52 -0500217 }
218 }
Chris Cain40501a22022-03-14 17:33:27 -0500219 }
Chris Cain5d66a0a2022-02-09 08:52:10 -0600220}
221
Chris Cain81c83432022-06-27 08:21:52 -0500222// Get value of power cap to send to the OCC (output/DC power)
Andrew Geissler4cea4d22017-07-10 15:13:33 -0500223uint32_t PowerCap::getOccInput(uint32_t pcap, bool pcapEnabled)
224{
225 if (!pcapEnabled)
226 {
227 // Pcap disabled, return 0 to indicate disabled
228 return 0;
229 }
230
231 // If pcap is not disabled then just return the pcap with the derating
Chris Cain81c83432022-06-27 08:21:52 -0500232 // factor applied (output/DC power).
Gunnar Mills94df8c92018-09-14 14:50:03 -0500233 return ((static_cast<uint64_t>(pcap) * PS_DERATING_FACTOR) / 100);
Andrew Geissler4cea4d22017-07-10 15:13:33 -0500234}
235
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500236uint32_t PowerCap::getPcap()
237{
George Liuf3b75142021-06-10 11:22:50 +0800238 utils::PropertyValue pcap{};
239 try
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500240 {
George Liuf3b75142021-06-10 11:22:50 +0800241 pcap = utils::getProperty(PCAP_PATH, PCAP_INTERFACE, POWER_CAP_PROP);
242
243 return std::get<uint32_t>(pcap);
244 }
Patrick Williamsaf408082022-07-22 19:26:54 -0500245 catch (const sdbusplus::exception_t& e)
George Liuf3b75142021-06-10 11:22:50 +0800246 {
Chris Cain37abe9b2024-10-31 17:20:31 -0500247 lg2::error("Failed to get PowerCap property: path={PATH}: {ERR}",
248 "PATH", PCAP_PATH, "ERR", e.what());
George Liuf3b75142021-06-10 11:22:50 +0800249
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500250 return 0;
251 }
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500252}
253
254bool PowerCap::getPcapEnabled()
255{
George Liuf3b75142021-06-10 11:22:50 +0800256 utils::PropertyValue pcapEnabled{};
257 try
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500258 {
George Liuf3b75142021-06-10 11:22:50 +0800259 pcapEnabled = utils::getProperty(PCAP_PATH, PCAP_INTERFACE,
260 POWER_CAP_ENABLE_PROP);
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500261
George Liuf3b75142021-06-10 11:22:50 +0800262 return std::get<bool>(pcapEnabled);
263 }
Patrick Williamsaf408082022-07-22 19:26:54 -0500264 catch (const sdbusplus::exception_t& e)
George Liuf3b75142021-06-10 11:22:50 +0800265 {
Chris Cain37abe9b2024-10-31 17:20:31 -0500266 lg2::error("Failed to get PowerCapEnable property: path={PATH}: {ERR}",
267 "PATH", PCAP_PATH, "ERR", e.what());
George Liuf3b75142021-06-10 11:22:50 +0800268
269 return false;
270 }
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500271}
Andrew Geissler32016d12017-06-20 15:46:52 -0500272
Chris Cain5d66a0a2022-02-09 08:52:10 -0600273fs::path PowerCap::getPcapFilename(const std::regex& expr)
Matt Spinlereaaf3b22019-07-16 10:29:27 -0500274{
Chris Cain5d66a0a2022-02-09 08:52:10 -0600275 if (pcapBasePathname.empty())
276 {
Chris Cain5d66a0a2022-02-09 08:52:10 -0600277 pcapBasePathname = occStatus.getHwmonPath();
Chris Cain5d66a0a2022-02-09 08:52:10 -0600278 }
Chris Caine2d0a432022-03-28 11:08:49 -0500279
280 if (fs::exists(pcapBasePathname))
Matt Spinlereaaf3b22019-07-16 10:29:27 -0500281 {
Chris Caine2d0a432022-03-28 11:08:49 -0500282 // Search for pcap file based on the supplied expr
283 for (auto& file : fs::directory_iterator(pcapBasePathname))
Matt Spinlereaaf3b22019-07-16 10:29:27 -0500284 {
Chris Caine2d0a432022-03-28 11:08:49 -0500285 if (std::regex_search(file.path().string(), expr))
286 {
287 // Found match
288 return file;
289 }
Matt Spinlereaaf3b22019-07-16 10:29:27 -0500290 }
291 }
Chris Caine2d0a432022-03-28 11:08:49 -0500292 else
293 {
Chris Cain37abe9b2024-10-31 17:20:31 -0500294 lg2::error("Power Cap base filename not found: {FILE}", "FILE",
295 pcapBasePathname);
Chris Caine2d0a432022-03-28 11:08:49 -0500296 }
297
Chris Cain5d66a0a2022-02-09 08:52:10 -0600298 // return empty path
299 return fs::path{};
Matt Spinlereaaf3b22019-07-16 10:29:27 -0500300}
301
Chris Cain81c83432022-06-27 08:21:52 -0500302// Write the user power cap to sysfs (output/DC power)
Chris Cain40501a22022-03-14 17:33:27 -0500303// This will trigger the driver to send the cap to the OCC
Andrew Geissler6ac874e2017-07-10 15:54:58 -0500304void PowerCap::writeOcc(uint32_t pcapValue)
305{
Chris Caind4c19a02022-04-22 15:46:13 -0500306 if (!occStatus.occActive())
307 {
308 // OCC not running, skip update
309 return;
310 }
311
Chris Cain5d66a0a2022-02-09 08:52:10 -0600312 // Build the hwmon string to write the user power cap
313 fs::path fileName = getPcapFilename(std::regex{"power\\d+_cap_user$"});
314 if (fileName.empty())
Matt Spinlereaaf3b22019-07-16 10:29:27 -0500315 {
Chris Cain37abe9b2024-10-31 17:20:31 -0500316 lg2::error("Could not find a power cap file to write to: {FILE})",
317 "FILE", pcapBasePathname);
Matt Spinlereaaf3b22019-07-16 10:29:27 -0500318 return;
319 }
Matt Spinlereaaf3b22019-07-16 10:29:27 -0500320
321 uint64_t microWatts = pcapValue * 1000000ull;
322
323 auto pcapString{std::to_string(microWatts)};
Andrew Geissler6ac874e2017-07-10 15:54:58 -0500324
Andrew Geissler6ac874e2017-07-10 15:54:58 -0500325 // Open the hwmon file and write the power cap
Chris Cain5d66a0a2022-02-09 08:52:10 -0600326 std::ofstream file(fileName, std::ios::out);
327 if (file)
328 {
Chris Cain37abe9b2024-10-31 17:20:31 -0500329 lg2::info("Writing {CAP}uW to {FILE}", "CAP", pcapString, "FILE",
330 fileName);
Chris Cain5d66a0a2022-02-09 08:52:10 -0600331 file << pcapString;
332 file.close();
333 }
334 else
335 {
Chris Cain37abe9b2024-10-31 17:20:31 -0500336 lg2::error("Failed writing {CAP}uW to {FILE} (errno={ERR})", "CAP",
337 microWatts, "FILE", fileName, "ERR", errno);
Chris Cain5d66a0a2022-02-09 08:52:10 -0600338 }
339
Andrew Geissler6ac874e2017-07-10 15:54:58 -0500340 return;
341}
342
Chris Cain81c83432022-06-27 08:21:52 -0500343// Read the current user power cap from sysfs as input/AC power
Chris Cain40501a22022-03-14 17:33:27 -0500344uint32_t PowerCap::readUserCapHwmon()
345{
346 uint32_t userCap = 0;
347
348 // Get the sysfs filename for the user power cap
349 fs::path userCapName = getPcapFilename(std::regex{"power\\d+_cap_user$"});
350 if (userCapName.empty())
351 {
Chris Cain37abe9b2024-10-31 17:20:31 -0500352 lg2::error(
353 "readUserCapHwmon: Could not find a power cap file to read: {FILE})",
354 "FILE", pcapBasePathname);
Chris Cain40501a22022-03-14 17:33:27 -0500355 return 0;
356 }
357
358 // Open the sysfs file and read the power cap
Chris Cain40501a22022-03-14 17:33:27 -0500359 std::ifstream file(userCapName, std::ios::in);
360 if (file)
361 {
Chris Caine2d0a432022-03-28 11:08:49 -0500362 uint64_t cap;
Chris Cain40501a22022-03-14 17:33:27 -0500363 file >> cap;
364 file.close();
Chris Cain81c83432022-06-27 08:21:52 -0500365 // Convert to input/AC Power in Watts
366 userCap = (cap / (PS_DERATING_FACTOR / 100.0) / 1000000);
Chris Cain40501a22022-03-14 17:33:27 -0500367 }
368 else
369 {
Chris Cain37abe9b2024-10-31 17:20:31 -0500370 lg2::error("readUserCapHwmon: Failed reading {FILE} (errno={ERR})",
371 "FILE", userCapName, "ERR", errno);
Chris Cain40501a22022-03-14 17:33:27 -0500372 }
373
374 return userCap;
375}
376
Patrick Williamsaf408082022-07-22 19:26:54 -0500377void PowerCap::pcapChanged(sdbusplus::message_t& msg)
Andrew Geissler32016d12017-06-20 15:46:52 -0500378{
Andrew Geissler32016d12017-06-20 15:46:52 -0500379 if (!occStatus.occActive())
380 {
Chris Cain5d66a0a2022-02-09 08:52:10 -0600381 // Nothing to do
Andrew Geissler32016d12017-06-20 15:46:52 -0500382 return;
383 }
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500384
385 uint32_t pcap = 0;
386 bool pcapEnabled = false;
387
388 std::string msgSensor;
Patrick Williamse0962702020-05-13 17:50:22 -0500389 std::map<std::string, std::variant<uint32_t, bool>> msgData;
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500390 msg.read(msgSensor, msgData);
391
Chris Cain5d66a0a2022-02-09 08:52:10 -0600392 bool changeFound = false;
393 for (const auto& [prop, value] : msgData)
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500394 {
Chris Cain5d66a0a2022-02-09 08:52:10 -0600395 if (prop == POWER_CAP_PROP)
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500396 {
Chris Cain5d66a0a2022-02-09 08:52:10 -0600397 pcap = std::get<uint32_t>(value);
398 pcapEnabled = getPcapEnabled();
399 changeFound = true;
400 }
401 else if (prop == POWER_CAP_ENABLE_PROP)
402 {
403 pcapEnabled = std::get<bool>(value);
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500404 pcap = getPcap();
Chris Cain5d66a0a2022-02-09 08:52:10 -0600405 changeFound = true;
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500406 }
407 else
408 {
Chris Cain5d66a0a2022-02-09 08:52:10 -0600409 // Ignore other properties
Chris Cain37abe9b2024-10-31 17:20:31 -0500410 lg2::debug(
411 "pcapChanged: Unknown power cap property changed {PROP} to {VAL}",
412 "PROP", prop, "VAL", std::get<uint32_t>(value));
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500413 }
414 }
415
Chris Cain81c83432022-06-27 08:21:52 -0500416 // Validate the cap is within supported range
417 uint32_t capSoftMin, capHardMin, capMax;
Chris Caind6ced7c2022-10-17 17:11:07 -0500418 persistedData.getCapLimits(capSoftMin, capHardMin, capMax);
Chris Cain81c83432022-06-27 08:21:52 -0500419 if (((pcap > 0) && (pcap < capSoftMin)) || ((pcap == 0) && (pcapEnabled)))
420 {
Chris Cain37abe9b2024-10-31 17:20:31 -0500421 lg2::error(
422 "pcapChanged: Power cap of {CAP}W is lower than allowed (soft min:{SMIN}, min:{MIN}) - using soft min",
423 "CAP", pcap, "SMIN", capSoftMin, "MIN", capHardMin);
Chris Cain81c83432022-06-27 08:21:52 -0500424 pcap = capSoftMin;
425 utils::setProperty(PCAP_PATH, PCAP_INTERFACE, POWER_CAP_PROP, pcap);
426 }
427 else if (pcap > capMax)
428 {
Chris Cain37abe9b2024-10-31 17:20:31 -0500429 lg2::error(
430 "pcapChanged: Power cap of {CAP}W is higher than allowed (max:{MAX}) - using max",
431 "CAP", pcap, "MAX", capMax);
Chris Cain81c83432022-06-27 08:21:52 -0500432 pcap = capMax;
433 utils::setProperty(PCAP_PATH, PCAP_INTERFACE, POWER_CAP_PROP, pcap);
434 }
435
Chris Cain5d66a0a2022-02-09 08:52:10 -0600436 if (changeFound)
437 {
Chris Cain37abe9b2024-10-31 17:20:31 -0500438 lg2::info(
439 "Power Cap Property Change (cap={CAP}W (input), enabled={ENABLE})",
440 "CAP", pcap, "ENABLE", pcapEnabled);
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500441
Chris Cain5d66a0a2022-02-09 08:52:10 -0600442 // Determine desired action to write to occ
Chris Cain5d66a0a2022-02-09 08:52:10 -0600443 auto occInput = getOccInput(pcap, pcapEnabled);
Chris Cain5d66a0a2022-02-09 08:52:10 -0600444 // Write action to occ
445 writeOcc(occInput);
446 }
Andrew Geissler52cf26a2017-07-06 12:56:32 -0500447
448 return;
Andrew Geissler32016d12017-06-20 15:46:52 -0500449}
450
Chris Cain5d66a0a2022-02-09 08:52:10 -0600451// Update the Power Cap bounds on DBus
Chris Caind6ced7c2022-10-17 17:11:07 -0500452void PowerCap::updateDbusPcapLimits(uint32_t softMin, uint32_t hardMin,
Chris Cain81c83432022-06-27 08:21:52 -0500453 uint32_t max)
Chris Cain5d66a0a2022-02-09 08:52:10 -0600454{
Chris Caind6ced7c2022-10-17 17:11:07 -0500455 CapLimits::minSoftPowerCapValue(softMin);
456 CapLimits::minPowerCapValue(hardMin);
457 CapLimits::maxPowerCapValue(max);
Chris Cain81c83432022-06-27 08:21:52 -0500458}
459
Gunnar Mills94df8c92018-09-14 14:50:03 -0500460} // namespace powercap
Andrew Geissler32016d12017-06-20 15:46:52 -0500461
462} // namespace occ
463
Gunnar Mills94df8c92018-09-14 14:50:03 -0500464} // namespace open_power