|  | #include <fmt/core.h> | 
|  |  | 
|  | #include <phosphor-logging/log.hpp> | 
|  | #include <powermode.hpp> | 
|  | #include <xyz/openbmc_project/Control/Power/Mode/server.hpp> | 
|  |  | 
|  | #include <cassert> | 
|  | #include <regex> | 
|  |  | 
|  | namespace open_power | 
|  | { | 
|  | namespace occ | 
|  | { | 
|  | namespace powermode | 
|  | { | 
|  |  | 
|  | using namespace phosphor::logging; | 
|  | using Mode = sdbusplus::xyz::openbmc_project::Control::Power::server::Mode; | 
|  |  | 
|  | void PowerMode::modeChanged(sdbusplus::message::message& msg) | 
|  | { | 
|  | if (!occStatus.occActive()) | 
|  | { | 
|  | // Nothing to do | 
|  | return; | 
|  | } | 
|  |  | 
|  | SysPwrMode pmode = SysPwrMode::NO_CHANGE; | 
|  |  | 
|  | std::map<std::string, std::variant<std::string>> properties{}; | 
|  | std::string interface; | 
|  | std::string propVal; | 
|  | msg.read(interface, properties); | 
|  | const auto modeEntry = properties.find(POWER_MODE_PROP); | 
|  | if (modeEntry != properties.end()) | 
|  | { | 
|  | auto modeEntryValue = modeEntry->second; | 
|  | propVal = std::get<std::string>(modeEntryValue); | 
|  | pmode = convertStringToMode(propVal); | 
|  |  | 
|  | if (pmode != SysPwrMode::NO_CHANGE) | 
|  | { | 
|  | log<level::INFO>( | 
|  | fmt::format("Power Mode Change Requested: {}", propVal) | 
|  | .c_str()); | 
|  |  | 
|  | // Trigger mode change to OCC | 
|  | occStatus.sendModeChange(); | 
|  | } | 
|  | } | 
|  |  | 
|  | return; | 
|  | } | 
|  |  | 
|  | // Convert PowerMode string to OCC SysPwrMode | 
|  | SysPwrMode convertStringToMode(const std::string& i_modeString) | 
|  | { | 
|  | SysPwrMode pmode = SysPwrMode::NO_CHANGE; | 
|  |  | 
|  | Mode::PowerMode mode = Mode::convertPowerModeFromString(i_modeString); | 
|  | if (mode == Mode::PowerMode::MaximumPerformance) | 
|  | { | 
|  | pmode = SysPwrMode::MAX_PERF; | 
|  | } | 
|  | else if (mode == Mode::PowerMode::PowerSaving) | 
|  | { | 
|  | pmode = SysPwrMode::POWER_SAVING; | 
|  | } | 
|  | else if (mode == Mode::PowerMode::Static) | 
|  | { | 
|  | pmode = SysPwrMode::DISABLE; | 
|  | } | 
|  | else | 
|  | { | 
|  | log<level::ERR>( | 
|  | fmt::format("convertStringToMode: Invalid Power Mode specified: {}", | 
|  | i_modeString) | 
|  | .c_str()); | 
|  | } | 
|  |  | 
|  | return pmode; | 
|  | } | 
|  |  | 
|  | void PowerIPS::ipsChanged(sdbusplus::message::message& msg) | 
|  | { | 
|  | if (!occStatus.occActive()) | 
|  | { | 
|  | // Nothing to do | 
|  | return; | 
|  | } | 
|  |  | 
|  | bool parmsChanged = false; | 
|  | std::string interface; | 
|  | std::map<std::string, std::variant<bool, uint8_t, uint64_t>> | 
|  | ipsProperties{}; | 
|  | msg.read(interface, ipsProperties); | 
|  |  | 
|  | auto ipsEntry = ipsProperties.find(IPS_ENABLED_PROP); | 
|  | if (ipsEntry != ipsProperties.end()) | 
|  | { | 
|  | const auto ipsEnabled = std::get<bool>(ipsEntry->second); | 
|  | log<level::INFO>( | 
|  | fmt::format("Idle Power Saver change: Enabled={}", ipsEnabled) | 
|  | .c_str()); | 
|  | parmsChanged = true; | 
|  | } | 
|  | ipsEntry = ipsProperties.find(IPS_ENTER_UTIL); | 
|  | if (ipsEntry != ipsProperties.end()) | 
|  | { | 
|  | const auto enterUtil = std::get<uint8_t>(ipsEntry->second); | 
|  | log<level::INFO>( | 
|  | fmt::format("Idle Power Saver change: Enter Util={}%", enterUtil) | 
|  | .c_str()); | 
|  | parmsChanged = true; | 
|  | } | 
|  | ipsEntry = ipsProperties.find(IPS_ENTER_TIME); | 
|  | if (ipsEntry != ipsProperties.end()) | 
|  | { | 
|  | std::chrono::milliseconds ms(std::get<uint64_t>(ipsEntry->second)); | 
|  | const auto enterTime = | 
|  | std::chrono::duration_cast<std::chrono::seconds>(ms).count(); | 
|  | log<level::INFO>( | 
|  | fmt::format("Idle Power Saver change: Enter Time={}sec", enterTime) | 
|  | .c_str()); | 
|  | parmsChanged = true; | 
|  | } | 
|  | ipsEntry = ipsProperties.find(IPS_EXIT_UTIL); | 
|  | if (ipsEntry != ipsProperties.end()) | 
|  | { | 
|  | const auto exitUtil = std::get<uint8_t>(ipsEntry->second); | 
|  | log<level::INFO>( | 
|  | fmt::format("Idle Power Saver change: Exit Util={}%", exitUtil) | 
|  | .c_str()); | 
|  | parmsChanged = true; | 
|  | } | 
|  | ipsEntry = ipsProperties.find(IPS_EXIT_TIME); | 
|  | if (ipsEntry != ipsProperties.end()) | 
|  | { | 
|  | std::chrono::milliseconds ms(std::get<uint64_t>(ipsEntry->second)); | 
|  | const auto exitTime = | 
|  | std::chrono::duration_cast<std::chrono::seconds>(ms).count(); | 
|  | log<level::INFO>( | 
|  | fmt::format("Idle Power Saver change: Exit Time={}sec", exitTime) | 
|  | .c_str()); | 
|  | parmsChanged = true; | 
|  | } | 
|  |  | 
|  | if (parmsChanged) | 
|  | { | 
|  | // Trigger mode change to OCC | 
|  | occStatus.sendIpsData(); | 
|  | } | 
|  |  | 
|  | return; | 
|  | } | 
|  |  | 
|  | } // namespace powermode | 
|  |  | 
|  | } // namespace occ | 
|  |  | 
|  | } // namespace open_power |