15d66a0aaSChris Cain #include "occ_status.hpp"
25d66a0aaSChris Cain
332016d18SAndrew Geissler #include <phosphor-logging/log.hpp>
494df8c90SGunnar Mills #include <powercap.hpp>
5b5ca1015SGeorge Liu
6b5ca1015SGeorge Liu #include <cassert>
7e2d0a43cSChris Cain #include <filesystem>
848002498SPatrick Williams #include <format>
932016d18SAndrew Geissler
1032016d18SAndrew Geissler namespace open_power
1132016d18SAndrew Geissler {
1232016d18SAndrew Geissler namespace occ
1332016d18SAndrew Geissler {
1432016d18SAndrew Geissler namespace powercap
1532016d18SAndrew Geissler {
1632016d18SAndrew Geissler
1752cf26a8SAndrew Geissler constexpr auto PCAP_PATH = "/xyz/openbmc_project/control/host0/power_cap";
1852cf26a8SAndrew Geissler constexpr auto PCAP_INTERFACE = "xyz.openbmc_project.Control.Power.Cap";
1952cf26a8SAndrew Geissler
2052cf26a8SAndrew Geissler constexpr auto POWER_CAP_PROP = "PowerCap";
2152cf26a8SAndrew Geissler constexpr auto POWER_CAP_ENABLE_PROP = "PowerCapEnable";
22613dc90dSChris Cain constexpr auto POWER_CAP_SOFT_MIN = "MinSoftPowerCapValue";
235d66a0aaSChris Cain constexpr auto POWER_CAP_HARD_MIN = "MinPowerCapValue";
245d66a0aaSChris Cain constexpr auto POWER_CAP_MAX = "MaxPowerCapValue";
2552cf26a8SAndrew Geissler
2632016d18SAndrew Geissler using namespace phosphor::logging;
27bcef3b48SGeorge Liu namespace fs = std::filesystem;
2832016d18SAndrew Geissler
updatePcapBounds()295d66a0aaSChris Cain void PowerCap::updatePcapBounds()
305d66a0aaSChris Cain {
315d66a0aaSChris Cain // Build the hwmon string to write the power cap bounds
325d66a0aaSChris Cain fs::path minName = getPcapFilename(std::regex{"power\\d+_cap_min$"});
33613dc90dSChris Cain fs::path softMinName =
34613dc90dSChris Cain getPcapFilename(std::regex{"power\\d+_cap_min_soft$"});
355d66a0aaSChris Cain fs::path maxName = getPcapFilename(std::regex{"power\\d+_cap_max$"});
365d66a0aaSChris Cain
3781c83430SChris Cain // Read the current cap bounds from dbus
3881c83430SChris Cain uint32_t capSoftMin, capHardMin, capMax;
3981c83430SChris Cain readDbusPcapLimits(capSoftMin, capHardMin, capMax);
40613dc90dSChris Cain
4181c83430SChris Cain // Read the power cap bounds from sysfs files (from OCC)
4281c83430SChris Cain uint64_t cap;
43613dc90dSChris Cain std::ifstream softMinFile(softMinName, std::ios::in);
44613dc90dSChris Cain if (softMinFile)
45613dc90dSChris Cain {
46613dc90dSChris Cain softMinFile >> cap;
47613dc90dSChris Cain softMinFile.close();
4881c83430SChris Cain // Convert to input/AC Power in Watts (round up)
49613dc90dSChris Cain capSoftMin = ((cap / (PS_DERATING_FACTOR / 100.0) / 1000000) + 0.9);
50613dc90dSChris Cain }
51613dc90dSChris Cain else
52613dc90dSChris Cain {
53613dc90dSChris Cain log<level::ERR>(
5448002498SPatrick Williams std::format(
55613dc90dSChris Cain "updatePcapBounds: unable to find pcap_min_soft file: {} (errno={})",
56613dc90dSChris Cain pcapBasePathname.c_str(), errno)
57613dc90dSChris Cain .c_str());
58613dc90dSChris Cain }
59613dc90dSChris Cain
605d66a0aaSChris Cain std::ifstream minFile(minName, std::ios::in);
615d66a0aaSChris Cain if (minFile)
625d66a0aaSChris Cain {
635d66a0aaSChris Cain minFile >> cap;
645d66a0aaSChris Cain minFile.close();
6581c83430SChris Cain // Convert to input/AC Power in Watts (round up)
668676e037SChris Cain capHardMin = ((cap / (PS_DERATING_FACTOR / 100.0) / 1000000) + 0.9);
675d66a0aaSChris Cain }
685d66a0aaSChris Cain else
695d66a0aaSChris Cain {
705d66a0aaSChris Cain log<level::ERR>(
7148002498SPatrick Williams std::format(
725d66a0aaSChris Cain "updatePcapBounds: unable to find cap_min file: {} (errno={})",
735d66a0aaSChris Cain pcapBasePathname.c_str(), errno)
745d66a0aaSChris Cain .c_str());
755d66a0aaSChris Cain }
76613dc90dSChris Cain
775d66a0aaSChris Cain std::ifstream maxFile(maxName, std::ios::in);
785d66a0aaSChris Cain if (maxFile)
795d66a0aaSChris Cain {
805d66a0aaSChris Cain maxFile >> cap;
815d66a0aaSChris Cain maxFile.close();
8281c83430SChris Cain // Convert to input/AC Power in Watts (truncate remainder)
838676e037SChris Cain capMax = cap / (PS_DERATING_FACTOR / 100.0) / 1000000;
845d66a0aaSChris Cain }
855d66a0aaSChris Cain else
865d66a0aaSChris Cain {
875d66a0aaSChris Cain log<level::ERR>(
8848002498SPatrick Williams std::format(
895d66a0aaSChris Cain "updatePcapBounds: unable to find cap_max file: {} (errno={})",
905d66a0aaSChris Cain pcapBasePathname.c_str(), errno)
915d66a0aaSChris Cain .c_str());
925d66a0aaSChris Cain }
935d66a0aaSChris Cain
9481c83430SChris Cain // Save the power cap bounds to dbus
9581c83430SChris Cain updateDbusPcapLimits(capSoftMin, capHardMin, capMax);
9640501a23SChris Cain
9781c83430SChris Cain // Validate user power cap (if enabled) is within the bounds
9840501a23SChris Cain const uint32_t dbusUserCap = getPcap();
9981c83430SChris Cain const bool pcapEnabled = getPcapEnabled();
10081c83430SChris Cain if (pcapEnabled && (dbusUserCap != 0))
10181c83430SChris Cain {
10240501a23SChris Cain const uint32_t hwmonUserCap = readUserCapHwmon();
10381c83430SChris Cain if ((dbusUserCap >= capSoftMin) && (dbusUserCap <= capMax))
10481c83430SChris Cain {
10581c83430SChris Cain // Validate dbus and hwmon user caps match
10640501a23SChris Cain if ((hwmonUserCap != 0) && (dbusUserCap != hwmonUserCap))
10740501a23SChris Cain {
10840501a23SChris Cain // User power cap is enabled, but does not match dbus
10940501a23SChris Cain log<level::ERR>(
11048002498SPatrick Williams std::format(
11140501a23SChris Cain "updatePcapBounds: user powercap mismatch (hwmon:{}W, bdus:{}W) - using dbus",
11240501a23SChris Cain hwmonUserCap, dbusUserCap)
11340501a23SChris Cain .c_str());
11481c83430SChris Cain auto occInput = getOccInput(dbusUserCap, pcapEnabled);
11581c83430SChris Cain writeOcc(occInput);
11681c83430SChris Cain }
11781c83430SChris Cain }
11881c83430SChris Cain else
11981c83430SChris Cain {
12081c83430SChris Cain // User power cap is outside of current bounds
12181c83430SChris Cain uint32_t newCap = capMax;
12281c83430SChris Cain if (dbusUserCap < capSoftMin)
12381c83430SChris Cain {
12481c83430SChris Cain newCap = capSoftMin;
12581c83430SChris Cain }
12681c83430SChris Cain log<level::ERR>(
12748002498SPatrick Williams std::format(
12881c83430SChris Cain "updatePcapBounds: user powercap {}W is outside bounds "
12981c83430SChris Cain "(soft min:{}, min:{}, max:{})",
13081c83430SChris Cain dbusUserCap, capSoftMin, capHardMin, capMax)
13181c83430SChris Cain .c_str());
13281c83430SChris Cain try
13381c83430SChris Cain {
13481c83430SChris Cain log<level::INFO>(
13548002498SPatrick Williams std::format(
13681c83430SChris Cain "updatePcapBounds: Updating user powercap from {} to {}W",
13781c83430SChris Cain hwmonUserCap, newCap)
13881c83430SChris Cain .c_str());
13981c83430SChris Cain utils::setProperty(PCAP_PATH, PCAP_INTERFACE, POWER_CAP_PROP,
14081c83430SChris Cain newCap);
14181c83430SChris Cain auto occInput = getOccInput(newCap, pcapEnabled);
14281c83430SChris Cain writeOcc(occInput);
14381c83430SChris Cain }
144af40808fSPatrick Williams catch (const sdbusplus::exception_t& e)
14581c83430SChris Cain {
14681c83430SChris Cain log<level::ERR>(
14748002498SPatrick Williams std::format(
14881c83430SChris Cain "updatePcapBounds: Failed to update user powercap due to ",
14981c83430SChris Cain e.what())
15081c83430SChris Cain .c_str());
15181c83430SChris Cain }
15281c83430SChris Cain }
15340501a23SChris Cain }
1545d66a0aaSChris Cain }
1555d66a0aaSChris Cain
15681c83430SChris Cain // Get value of power cap to send to the OCC (output/DC power)
getOccInput(uint32_t pcap,bool pcapEnabled)1574cea4d2bSAndrew Geissler uint32_t PowerCap::getOccInput(uint32_t pcap, bool pcapEnabled)
1584cea4d2bSAndrew Geissler {
1594cea4d2bSAndrew Geissler if (!pcapEnabled)
1604cea4d2bSAndrew Geissler {
1614cea4d2bSAndrew Geissler // Pcap disabled, return 0 to indicate disabled
1624cea4d2bSAndrew Geissler return 0;
1634cea4d2bSAndrew Geissler }
1644cea4d2bSAndrew Geissler
1654cea4d2bSAndrew Geissler // If pcap is not disabled then just return the pcap with the derating
16681c83430SChris Cain // factor applied (output/DC power).
1674cea4d2bSAndrew Geissler return ((static_cast<uint64_t>(pcap) * PS_DERATING_FACTOR) / 100);
1684cea4d2bSAndrew Geissler }
1694cea4d2bSAndrew Geissler
getPcap()17052cf26a8SAndrew Geissler uint32_t PowerCap::getPcap()
17152cf26a8SAndrew Geissler {
172f3b7514eSGeorge Liu utils::PropertyValue pcap{};
173f3b7514eSGeorge Liu try
17452cf26a8SAndrew Geissler {
175f3b7514eSGeorge Liu pcap = utils::getProperty(PCAP_PATH, PCAP_INTERFACE, POWER_CAP_PROP);
17652cf26a8SAndrew Geissler
177305ff8b1SPatrick Williams return std::get<uint32_t>(pcap);
17852cf26a8SAndrew Geissler }
179af40808fSPatrick Williams catch (const sdbusplus::exception_t& e)
180f3b7514eSGeorge Liu {
181f3b7514eSGeorge Liu log<level::ERR>("Failed to get PowerCap property",
182f3b7514eSGeorge Liu entry("ERROR=%s", e.what()),
183f3b7514eSGeorge Liu entry("PATH=%s", PCAP_PATH));
184f3b7514eSGeorge Liu
185f3b7514eSGeorge Liu return 0;
186f3b7514eSGeorge Liu }
187f3b7514eSGeorge Liu }
18852cf26a8SAndrew Geissler
getPcapEnabled()18952cf26a8SAndrew Geissler bool PowerCap::getPcapEnabled()
19052cf26a8SAndrew Geissler {
191f3b7514eSGeorge Liu utils::PropertyValue pcapEnabled{};
192f3b7514eSGeorge Liu try
19352cf26a8SAndrew Geissler {
194f3b7514eSGeorge Liu pcapEnabled = utils::getProperty(PCAP_PATH, PCAP_INTERFACE,
195f3b7514eSGeorge Liu POWER_CAP_ENABLE_PROP);
19652cf26a8SAndrew Geissler
197305ff8b1SPatrick Williams return std::get<bool>(pcapEnabled);
19852cf26a8SAndrew Geissler }
199af40808fSPatrick Williams catch (const sdbusplus::exception_t& e)
200f3b7514eSGeorge Liu {
201f3b7514eSGeorge Liu log<level::ERR>("Failed to get PowerCapEnable property",
202f3b7514eSGeorge Liu entry("ERROR=%s", e.what()),
203f3b7514eSGeorge Liu entry("PATH=%s", PCAP_PATH));
204f3b7514eSGeorge Liu
205f3b7514eSGeorge Liu return false;
206f3b7514eSGeorge Liu }
207f3b7514eSGeorge Liu }
20832016d18SAndrew Geissler
getPcapFilename(const std::regex & expr)2095d66a0aaSChris Cain fs::path PowerCap::getPcapFilename(const std::regex& expr)
210eaaf3b28SMatt Spinler {
2115d66a0aaSChris Cain if (pcapBasePathname.empty())
2125d66a0aaSChris Cain {
2135d66a0aaSChris Cain pcapBasePathname = occStatus.getHwmonPath();
214e2d0a43cSChris Cain }
215e2d0a43cSChris Cain
216e2d0a43cSChris Cain if (fs::exists(pcapBasePathname))
2175d66a0aaSChris Cain {
218e2d0a43cSChris Cain // Search for pcap file based on the supplied expr
2195d66a0aaSChris Cain for (auto& file : fs::directory_iterator(pcapBasePathname))
220eaaf3b28SMatt Spinler {
221eaaf3b28SMatt Spinler if (std::regex_search(file.path().string(), expr))
222eaaf3b28SMatt Spinler {
223e2d0a43cSChris Cain // Found match
2245d66a0aaSChris Cain return file;
225eaaf3b28SMatt Spinler }
226eaaf3b28SMatt Spinler }
227e2d0a43cSChris Cain }
228e2d0a43cSChris Cain else
229e2d0a43cSChris Cain {
23048002498SPatrick Williams log<level::ERR>(std::format("Power Cap base filename not found: {}",
231e2d0a43cSChris Cain pcapBasePathname.c_str())
232e2d0a43cSChris Cain .c_str());
233e2d0a43cSChris Cain }
234e2d0a43cSChris Cain
2355d66a0aaSChris Cain // return empty path
2365d66a0aaSChris Cain return fs::path{};
237eaaf3b28SMatt Spinler }
238eaaf3b28SMatt Spinler
23981c83430SChris Cain // Write the user power cap to sysfs (output/DC power)
24040501a23SChris Cain // This will trigger the driver to send the cap to the OCC
writeOcc(uint32_t pcapValue)2416ac874e1SAndrew Geissler void PowerCap::writeOcc(uint32_t pcapValue)
2426ac874e1SAndrew Geissler {
243d4c19a07SChris Cain if (!occStatus.occActive())
244d4c19a07SChris Cain {
245d4c19a07SChris Cain // OCC not running, skip update
246d4c19a07SChris Cain return;
247d4c19a07SChris Cain }
248d4c19a07SChris Cain
2495d66a0aaSChris Cain // Build the hwmon string to write the user power cap
2505d66a0aaSChris Cain fs::path fileName = getPcapFilename(std::regex{"power\\d+_cap_user$"});
2515d66a0aaSChris Cain if (fileName.empty())
252eaaf3b28SMatt Spinler {
253b6535e89SChris Cain log<level::ERR>(
25448002498SPatrick Williams std::format("Could not find a power cap file to write to: {})",
2555d66a0aaSChris Cain pcapBasePathname.c_str())
256b6535e89SChris Cain .c_str());
257eaaf3b28SMatt Spinler return;
258eaaf3b28SMatt Spinler }
259eaaf3b28SMatt Spinler
260eaaf3b28SMatt Spinler uint64_t microWatts = pcapValue * 1000000ull;
261eaaf3b28SMatt Spinler
262eaaf3b28SMatt Spinler auto pcapString{std::to_string(microWatts)};
2636ac874e1SAndrew Geissler
2646ac874e1SAndrew Geissler // Open the hwmon file and write the power cap
2655d66a0aaSChris Cain std::ofstream file(fileName, std::ios::out);
2665d66a0aaSChris Cain if (file)
2675d66a0aaSChris Cain {
26848002498SPatrick Williams log<level::INFO>(std::format("Writing {}uW to {}", pcapString.c_str(),
2695d66a0aaSChris Cain fileName.c_str())
2705d66a0aaSChris Cain .c_str());
2716ac874e1SAndrew Geissler file << pcapString;
2726ac874e1SAndrew Geissler file.close();
2735d66a0aaSChris Cain }
2745d66a0aaSChris Cain else
2755d66a0aaSChris Cain {
27648002498SPatrick Williams log<level::ERR>(std::format("Failed writing {}uW to {} (errno={})",
2775d66a0aaSChris Cain microWatts, fileName.c_str(), errno)
2785d66a0aaSChris Cain .c_str());
2795d66a0aaSChris Cain }
2805d66a0aaSChris Cain
2816ac874e1SAndrew Geissler return;
2826ac874e1SAndrew Geissler }
2836ac874e1SAndrew Geissler
28481c83430SChris Cain // Read the current user power cap from sysfs as input/AC power
readUserCapHwmon()28540501a23SChris Cain uint32_t PowerCap::readUserCapHwmon()
28640501a23SChris Cain {
28740501a23SChris Cain uint32_t userCap = 0;
28840501a23SChris Cain
28940501a23SChris Cain // Get the sysfs filename for the user power cap
29040501a23SChris Cain fs::path userCapName = getPcapFilename(std::regex{"power\\d+_cap_user$"});
29140501a23SChris Cain if (userCapName.empty())
29240501a23SChris Cain {
29340501a23SChris Cain log<level::ERR>(
29448002498SPatrick Williams std::format(
29540501a23SChris Cain "readUserCapHwmon: Could not find a power cap file to read: {})",
29640501a23SChris Cain pcapBasePathname.c_str())
29740501a23SChris Cain .c_str());
29840501a23SChris Cain return 0;
29940501a23SChris Cain }
30040501a23SChris Cain
30140501a23SChris Cain // Open the sysfs file and read the power cap
30240501a23SChris Cain std::ifstream file(userCapName, std::ios::in);
30340501a23SChris Cain if (file)
30440501a23SChris Cain {
305e2d0a43cSChris Cain uint64_t cap;
30640501a23SChris Cain file >> cap;
30740501a23SChris Cain file.close();
30881c83430SChris Cain // Convert to input/AC Power in Watts
30981c83430SChris Cain userCap = (cap / (PS_DERATING_FACTOR / 100.0) / 1000000);
31040501a23SChris Cain }
31140501a23SChris Cain else
31240501a23SChris Cain {
31340501a23SChris Cain log<level::ERR>(
31448002498SPatrick Williams std::format("readUserCapHwmon: Failed reading {} (errno={})",
31540501a23SChris Cain userCapName.c_str(), errno)
31640501a23SChris Cain .c_str());
31740501a23SChris Cain }
31840501a23SChris Cain
31940501a23SChris Cain return userCap;
32040501a23SChris Cain }
32140501a23SChris Cain
pcapChanged(sdbusplus::message_t & msg)322af40808fSPatrick Williams void PowerCap::pcapChanged(sdbusplus::message_t& msg)
32332016d18SAndrew Geissler {
32432016d18SAndrew Geissler if (!occStatus.occActive())
32532016d18SAndrew Geissler {
32632016d18SAndrew Geissler // Nothing to do
32732016d18SAndrew Geissler return;
32832016d18SAndrew Geissler }
32952cf26a8SAndrew Geissler
33052cf26a8SAndrew Geissler uint32_t pcap = 0;
33152cf26a8SAndrew Geissler bool pcapEnabled = false;
33252cf26a8SAndrew Geissler
33352cf26a8SAndrew Geissler std::string msgSensor;
334e0962703SPatrick Williams std::map<std::string, std::variant<uint32_t, bool>> msgData;
33552cf26a8SAndrew Geissler msg.read(msgSensor, msgData);
33652cf26a8SAndrew Geissler
3375d66a0aaSChris Cain bool changeFound = false;
3385d66a0aaSChris Cain for (const auto& [prop, value] : msgData)
33952cf26a8SAndrew Geissler {
3405d66a0aaSChris Cain if (prop == POWER_CAP_PROP)
3415d66a0aaSChris Cain {
3425d66a0aaSChris Cain pcap = std::get<uint32_t>(value);
34352cf26a8SAndrew Geissler pcapEnabled = getPcapEnabled();
3445d66a0aaSChris Cain changeFound = true;
34552cf26a8SAndrew Geissler }
3465d66a0aaSChris Cain else if (prop == POWER_CAP_ENABLE_PROP)
34752cf26a8SAndrew Geissler {
3485d66a0aaSChris Cain pcapEnabled = std::get<bool>(value);
34952cf26a8SAndrew Geissler pcap = getPcap();
3505d66a0aaSChris Cain changeFound = true;
35152cf26a8SAndrew Geissler }
35252cf26a8SAndrew Geissler else
35352cf26a8SAndrew Geissler {
3545d66a0aaSChris Cain // Ignore other properties
3555d66a0aaSChris Cain log<level::DEBUG>(
35648002498SPatrick Williams std::format(
3575d66a0aaSChris Cain "pcapChanged: Unknown power cap property changed {} to {}",
3585d66a0aaSChris Cain prop.c_str(), std::get<uint32_t>(value))
3595d66a0aaSChris Cain .c_str());
36052cf26a8SAndrew Geissler }
36152cf26a8SAndrew Geissler }
36252cf26a8SAndrew Geissler
36381c83430SChris Cain // Validate the cap is within supported range
36481c83430SChris Cain uint32_t capSoftMin, capHardMin, capMax;
36581c83430SChris Cain readDbusPcapLimits(capSoftMin, capHardMin, capMax);
36681c83430SChris Cain if (((pcap > 0) && (pcap < capSoftMin)) || ((pcap == 0) && (pcapEnabled)))
36781c83430SChris Cain {
36881c83430SChris Cain log<level::ERR>(
36948002498SPatrick Williams std::format(
37081c83430SChris Cain "pcapChanged: Power cap of {}W is lower than allowed (soft min:{}, min:{}) - using soft min",
37181c83430SChris Cain pcap, capSoftMin, capHardMin)
37281c83430SChris Cain .c_str());
37381c83430SChris Cain pcap = capSoftMin;
37481c83430SChris Cain utils::setProperty(PCAP_PATH, PCAP_INTERFACE, POWER_CAP_PROP, pcap);
37581c83430SChris Cain }
37681c83430SChris Cain else if (pcap > capMax)
37781c83430SChris Cain {
37881c83430SChris Cain log<level::ERR>(
37948002498SPatrick Williams std::format(
38081c83430SChris Cain "pcapChanged: Power cap of {}W is higher than allowed (max:{}) - using max",
38181c83430SChris Cain pcap, capSoftMin, capHardMin)
38281c83430SChris Cain .c_str());
38381c83430SChris Cain pcap = capMax;
38481c83430SChris Cain utils::setProperty(PCAP_PATH, PCAP_INTERFACE, POWER_CAP_PROP, pcap);
38581c83430SChris Cain }
38681c83430SChris Cain
3875d66a0aaSChris Cain if (changeFound)
3885d66a0aaSChris Cain {
389b6535e89SChris Cain log<level::INFO>(
39048002498SPatrick Williams std::format(
3915d66a0aaSChris Cain "Power Cap Property Change (cap={}W (input), enabled={})", pcap,
3925d66a0aaSChris Cain pcapEnabled ? 'y' : 'n')
393b6535e89SChris Cain .c_str());
39452cf26a8SAndrew Geissler
39552cf26a8SAndrew Geissler // Determine desired action to write to occ
3964cea4d2bSAndrew Geissler auto occInput = getOccInput(pcap, pcapEnabled);
39752cf26a8SAndrew Geissler // Write action to occ
3986ac874e1SAndrew Geissler writeOcc(occInput);
3995d66a0aaSChris Cain }
40052cf26a8SAndrew Geissler
40152cf26a8SAndrew Geissler return;
40232016d18SAndrew Geissler }
40332016d18SAndrew Geissler
4045d66a0aaSChris Cain // Update the Power Cap bounds on DBus
updateDbusPcapLimits(uint32_t softMin,uint32_t hardMin,uint32_t max)40581c83430SChris Cain bool PowerCap::updateDbusPcapLimits(uint32_t softMin, uint32_t hardMin,
40681c83430SChris Cain uint32_t max)
4075d66a0aaSChris Cain {
4085d66a0aaSChris Cain bool complete = true;
4095d66a0aaSChris Cain
4105d66a0aaSChris Cain try
4115d66a0aaSChris Cain {
412613dc90dSChris Cain utils::setProperty(PCAP_PATH, PCAP_INTERFACE, POWER_CAP_SOFT_MIN,
413613dc90dSChris Cain softMin);
414613dc90dSChris Cain }
415af40808fSPatrick Williams catch (const sdbusplus::exception_t& e)
416613dc90dSChris Cain {
417613dc90dSChris Cain log<level::ERR>(
41848002498SPatrick Williams std::format(
41981c83430SChris Cain "updateDbusPcapLimits: Failed to set SOFT PCAP to {}W due to {}",
420613dc90dSChris Cain softMin, e.what())
421613dc90dSChris Cain .c_str());
422613dc90dSChris Cain complete = false;
423613dc90dSChris Cain }
424613dc90dSChris Cain
425613dc90dSChris Cain try
426613dc90dSChris Cain {
4275d66a0aaSChris Cain utils::setProperty(PCAP_PATH, PCAP_INTERFACE, POWER_CAP_HARD_MIN,
4285d66a0aaSChris Cain hardMin);
4295d66a0aaSChris Cain }
430af40808fSPatrick Williams catch (const sdbusplus::exception_t& e)
4315d66a0aaSChris Cain {
4325d66a0aaSChris Cain log<level::ERR>(
43348002498SPatrick Williams std::format(
43481c83430SChris Cain "updateDbusPcapLimits: Failed to set HARD PCAP to {}W due to {}",
4355d66a0aaSChris Cain hardMin, e.what())
4365d66a0aaSChris Cain .c_str());
4375d66a0aaSChris Cain complete = false;
4385d66a0aaSChris Cain }
4395d66a0aaSChris Cain
4405d66a0aaSChris Cain try
4415d66a0aaSChris Cain {
4425d66a0aaSChris Cain utils::setProperty(PCAP_PATH, PCAP_INTERFACE, POWER_CAP_MAX, max);
4435d66a0aaSChris Cain }
444af40808fSPatrick Williams catch (const sdbusplus::exception_t& e)
4455d66a0aaSChris Cain {
4465d66a0aaSChris Cain log<level::ERR>(
44748002498SPatrick Williams std::format(
44881c83430SChris Cain "updateDbusPcapLimits: Failed to set MAX PCAP to {}W due to {}",
44981c83430SChris Cain max, e.what())
4505d66a0aaSChris Cain .c_str());
4515d66a0aaSChris Cain complete = false;
4525d66a0aaSChris Cain }
4535d66a0aaSChris Cain
4545d66a0aaSChris Cain return complete;
4555d66a0aaSChris Cain }
45681c83430SChris Cain
45781c83430SChris Cain // Read the Power Cap bounds from DBus
readDbusPcapLimits(uint32_t & softMin,uint32_t & hardMin,uint32_t & max)45881c83430SChris Cain bool PowerCap::readDbusPcapLimits(uint32_t& softMin, uint32_t& hardMin,
45981c83430SChris Cain uint32_t& max)
46081c83430SChris Cain {
46181c83430SChris Cain bool complete = true;
46281c83430SChris Cain utils::PropertyValue prop{};
46381c83430SChris Cain
46481c83430SChris Cain try
46581c83430SChris Cain {
466*d7542c83SPatrick Williams prop =
467*d7542c83SPatrick Williams utils::getProperty(PCAP_PATH, PCAP_INTERFACE, POWER_CAP_SOFT_MIN);
46881c83430SChris Cain softMin = std::get<uint32_t>(prop);
46981c83430SChris Cain }
470af40808fSPatrick Williams catch (const sdbusplus::exception_t& e)
47181c83430SChris Cain {
47281c83430SChris Cain log<level::ERR>(
47348002498SPatrick Williams std::format("readDbusPcapLimits: Failed to get SOFT PCAP due to {}",
47481c83430SChris Cain e.what())
47581c83430SChris Cain .c_str());
47681c83430SChris Cain softMin = 0;
47781c83430SChris Cain complete = false;
47881c83430SChris Cain }
47981c83430SChris Cain
48081c83430SChris Cain try
48181c83430SChris Cain {
482*d7542c83SPatrick Williams prop =
483*d7542c83SPatrick Williams utils::getProperty(PCAP_PATH, PCAP_INTERFACE, POWER_CAP_HARD_MIN);
48481c83430SChris Cain hardMin = std::get<uint32_t>(prop);
48581c83430SChris Cain }
486af40808fSPatrick Williams catch (const sdbusplus::exception_t& e)
48781c83430SChris Cain {
48881c83430SChris Cain log<level::ERR>(
48948002498SPatrick Williams std::format("readDbusPcapLimits: Failed to get HARD PCAP due to {}",
49081c83430SChris Cain e.what())
49181c83430SChris Cain .c_str());
49281c83430SChris Cain hardMin = 0;
49381c83430SChris Cain complete = false;
49481c83430SChris Cain }
49581c83430SChris Cain
49681c83430SChris Cain try
49781c83430SChris Cain {
49881c83430SChris Cain prop = utils::getProperty(PCAP_PATH, PCAP_INTERFACE, POWER_CAP_MAX);
49981c83430SChris Cain max = std::get<uint32_t>(prop);
50081c83430SChris Cain }
501af40808fSPatrick Williams catch (const sdbusplus::exception_t& e)
50281c83430SChris Cain {
50381c83430SChris Cain log<level::ERR>(
50448002498SPatrick Williams std::format("readDbusPcapLimits: Failed to get MAX PCAP due to {}",
50581c83430SChris Cain e.what())
50681c83430SChris Cain .c_str());
50781c83430SChris Cain max = INT_MAX;
50881c83430SChris Cain complete = false;
50981c83430SChris Cain }
51081c83430SChris Cain
51181c83430SChris Cain return complete;
51281c83430SChris Cain }
51381c83430SChris Cain
51494df8c90SGunnar Mills } // namespace powercap
51532016d18SAndrew Geissler
51632016d18SAndrew Geissler } // namespace occ
51732016d18SAndrew Geissler
51894df8c90SGunnar Mills } // namespace open_power
519