13e5422edSVishwanatha Subbanna #include "config.h" 294df8c90SGunnar Mills 394df8c90SGunnar Mills #include "occ_pass_through.hpp" 494df8c90SGunnar Mills 594df8c90SGunnar Mills #include <errno.h> 694df8c90SGunnar Mills #include <fcntl.h> 7a8857c50SChris Cain #include <fmt/core.h> 894df8c90SGunnar Mills #include <unistd.h> 994df8c90SGunnar Mills 1094df8c90SGunnar Mills #include <org/open_power/OCC/Device/error.hpp> 11*d8aab2a9SPatrick Williams #include <phosphor-logging/elog-errors.hpp> 1294df8c90SGunnar Mills #include <phosphor-logging/elog.hpp> 1394df8c90SGunnar Mills #include <phosphor-logging/log.hpp> 14b5ca1015SGeorge Liu 15b5ca1015SGeorge Liu #include <algorithm> 16b5ca1015SGeorge Liu #include <memory> 1794df8c90SGunnar Mills #include <string> 18a8857c50SChris Cain 196b492fbfSDeepak Kodihalli namespace open_power 206b492fbfSDeepak Kodihalli { 216b492fbfSDeepak Kodihalli namespace occ 226b492fbfSDeepak Kodihalli { 236b492fbfSDeepak Kodihalli 2436f9cdedSChris Cain using namespace phosphor::logging; 2536f9cdedSChris Cain using namespace sdbusplus::org::open_power::OCC::Device::Error; 2636f9cdedSChris Cain 2736f9cdedSChris Cain PassThrough::PassThrough( 2836f9cdedSChris Cain const char* path 2936f9cdedSChris Cain #ifdef POWER10 3036f9cdedSChris Cain , 3136f9cdedSChris Cain std::unique_ptr<open_power::occ::powermode::PowerMode>& powerModeRef 3236f9cdedSChris Cain #endif 3336f9cdedSChris Cain ) : 3436f9cdedSChris Cain Iface(utils::getBus(), path), 3536f9cdedSChris Cain path(path), 3636f9cdedSChris Cain #ifdef POWER10 3736f9cdedSChris Cain pmode(powerModeRef), 3836f9cdedSChris Cain #endif 393e5422edSVishwanatha Subbanna devicePath(OCC_DEV_PATH + std::to_string((this->path.back() - '0') + 1)), 40a8857c50SChris Cain occInstance(this->path.back() - '0'), 413e5422edSVishwanatha Subbanna activeStatusSignal( 42f3b7514eSGeorge Liu utils::getBus(), 43f3b7514eSGeorge Liu sdbusRule::propertiesChanged(path, "org.open_power.OCC.Status"), 4494df8c90SGunnar Mills std::bind(std::mem_fn(&PassThrough::activeStatusEvent), this, 45a8857c50SChris Cain std::placeholders::_1)), 46f3b7514eSGeorge Liu occCmd(occInstance, path) 476b492fbfSDeepak Kodihalli { 4838b08d79SVishwanatha Subbanna // Nothing to do. 4938b08d79SVishwanatha Subbanna } 5038b08d79SVishwanatha Subbanna 516b492fbfSDeepak Kodihalli std::vector<int32_t> PassThrough::send(std::vector<int32_t> command) 526b492fbfSDeepak Kodihalli { 5367d50ad6SVishwanatha Subbanna std::vector<int32_t> response{}; 5467d50ad6SVishwanatha Subbanna 557d700e26SVishwanatha Subbanna // OCC only understands [bytes] so need array of bytes. Doing this 567d700e26SVishwanatha Subbanna // because rest-server currently treats all int* as 32 bit integer. 57a8857c50SChris Cain std::vector<uint8_t> cmdInBytes, rsp; 587d700e26SVishwanatha Subbanna cmdInBytes.resize(command.size()); 597d700e26SVishwanatha Subbanna 607d700e26SVishwanatha Subbanna // Populate uint8_t version of vector. 617d700e26SVishwanatha Subbanna std::transform(command.begin(), command.end(), cmdInBytes.begin(), 627d700e26SVishwanatha Subbanna [](decltype(cmdInBytes)::value_type x) { return x; }); 637d700e26SVishwanatha Subbanna 64a8857c50SChris Cain rsp = send(cmdInBytes); 65a8857c50SChris Cain 66a8857c50SChris Cain response.resize(rsp.size()); 67a8857c50SChris Cain std::transform(rsp.begin(), rsp.end(), response.begin(), 68a8857c50SChris Cain [](decltype(response)::value_type x) { return x; }); 69a8857c50SChris Cain 70a8857c50SChris Cain return response; 716b492fbfSDeepak Kodihalli } 726b492fbfSDeepak Kodihalli 73a8857c50SChris Cain std::vector<uint8_t> PassThrough::send(std::vector<uint8_t> command) 7467d50ad6SVishwanatha Subbanna { 75a8857c50SChris Cain std::vector<uint8_t> response{}; 76a8857c50SChris Cain 77d4c19a07SChris Cain if (!occActive) 78d4c19a07SChris Cain { 79d4c19a07SChris Cain log<level::ERR>( 80d4c19a07SChris Cain fmt::format( 81d4c19a07SChris Cain "PassThrough::send() - OCC{} not active, command not sent", 82d4c19a07SChris Cain occInstance) 83d4c19a07SChris Cain .c_str()); 84d4c19a07SChris Cain return response; 85d4c19a07SChris Cain } 86d4c19a07SChris Cain 8740501a23SChris Cain log<level::INFO>( 88a8857c50SChris Cain fmt::format("PassThrough::send() Sending 0x{:02X} command to OCC{}", 89a8857c50SChris Cain command.front(), occInstance) 90a8857c50SChris Cain .c_str()); 91a8857c50SChris Cain CmdStatus status = occCmd.send(command, response); 92a8857c50SChris Cain if (status == CmdStatus::SUCCESS) 9367d50ad6SVishwanatha Subbanna { 94a8857c50SChris Cain if (response.size() >= 5) 9567d50ad6SVishwanatha Subbanna { 96b5ca1015SGeorge Liu log<level::DEBUG>( 97b5ca1015SGeorge Liu fmt::format("PassThrough::send() response had {} bytes", 98a8857c50SChris Cain response.size()) 99a8857c50SChris Cain .c_str()); 10067d50ad6SVishwanatha Subbanna } 10167d50ad6SVishwanatha Subbanna else 10267d50ad6SVishwanatha Subbanna { 103a8857c50SChris Cain log<level::ERR>("PassThrough::send() Invalid OCC response"); 104a8857c50SChris Cain dump_hex(response); 10567d50ad6SVishwanatha Subbanna } 10667d50ad6SVishwanatha Subbanna } 107a8857c50SChris Cain else 108a8857c50SChris Cain { 109c567dc8dSChris Cain log<level::ERR>( 110c567dc8dSChris Cain fmt::format( 111c567dc8dSChris Cain "PassThrough::send(): OCC command failed with status {}", 112c567dc8dSChris Cain uint32_t(status)) 113c567dc8dSChris Cain .c_str()); 114a8857c50SChris Cain } 1154f4712d8SEddie James 11667d50ad6SVishwanatha Subbanna return response; 11767d50ad6SVishwanatha Subbanna } 11867d50ad6SVishwanatha Subbanna 11936f9cdedSChris Cain bool PassThrough::setMode(const uint8_t mode, const uint16_t modeData) 12036f9cdedSChris Cain { 12136f9cdedSChris Cain #ifdef POWER10 12236f9cdedSChris Cain SysPwrMode newMode = SysPwrMode(mode); 12336f9cdedSChris Cain 12436f9cdedSChris Cain if ((!VALID_POWER_MODE_SETTING(newMode)) && 12536f9cdedSChris Cain (!VALID_OEM_POWER_MODE_SETTING(newMode))) 12636f9cdedSChris Cain { 12736f9cdedSChris Cain log<level::ERR>( 12836f9cdedSChris Cain fmt::format( 12936f9cdedSChris Cain "PassThrough::setMode() Unsupported mode {} requested (0x{:04X})", 13036f9cdedSChris Cain newMode, modeData) 13136f9cdedSChris Cain .c_str()); 13236f9cdedSChris Cain return false; 13336f9cdedSChris Cain } 13436f9cdedSChris Cain 13536f9cdedSChris Cain if (((newMode == SysPwrMode::FFO) || (newMode == SysPwrMode::SFP)) && 13636f9cdedSChris Cain (modeData == 0)) 13736f9cdedSChris Cain { 13836f9cdedSChris Cain log<level::ERR>( 13936f9cdedSChris Cain fmt::format( 14036f9cdedSChris Cain "PassThrough::setMode() Mode {} requires non-zero frequency point.", 14136f9cdedSChris Cain newMode) 14236f9cdedSChris Cain .c_str()); 14336f9cdedSChris Cain return false; 14436f9cdedSChris Cain } 14536f9cdedSChris Cain 1466fa848a9SChris Cain if (!pmode) 1476fa848a9SChris Cain { 1486fa848a9SChris Cain log<level::ERR>("PassThrough::setMode: PowerMode is not defined!"); 1496fa848a9SChris Cain return false; 1506fa848a9SChris Cain } 1516fa848a9SChris Cain 15236f9cdedSChris Cain log<level::INFO>( 15336f9cdedSChris Cain fmt::format("PassThrough::setMode() Setting Power Mode {} (data: {})", 15436f9cdedSChris Cain newMode, modeData) 15536f9cdedSChris Cain .c_str()); 15636f9cdedSChris Cain return pmode->setMode(newMode, modeData); 15736f9cdedSChris Cain #else 15836f9cdedSChris Cain log<level::DEBUG>( 15936f9cdedSChris Cain fmt::format( 16036f9cdedSChris Cain "PassThrough::setMode() No support to setting Power Mode {} (data: {})", 16136f9cdedSChris Cain mode, modeData) 16236f9cdedSChris Cain .c_str()); 16336f9cdedSChris Cain return false; 16436f9cdedSChris Cain #endif 16536f9cdedSChris Cain } 16636f9cdedSChris Cain 1673e5422edSVishwanatha Subbanna // Called at OCC Status change signal 168af40808fSPatrick Williams void PassThrough::activeStatusEvent(sdbusplus::message_t& msg) 1693e5422edSVishwanatha Subbanna { 1703e5422edSVishwanatha Subbanna std::string statusInterface; 171e0962703SPatrick Williams std::map<std::string, std::variant<bool>> msgData; 1723e5422edSVishwanatha Subbanna msg.read(statusInterface, msgData); 1733e5422edSVishwanatha Subbanna 1743e5422edSVishwanatha Subbanna auto propertyMap = msgData.find("OccActive"); 1753e5422edSVishwanatha Subbanna if (propertyMap != msgData.end()) 1763e5422edSVishwanatha Subbanna { 1773e5422edSVishwanatha Subbanna // Extract the OccActive property 178305ff8b1SPatrick Williams if (std::get<bool>(propertyMap->second)) 1793e5422edSVishwanatha Subbanna { 1804f4712d8SEddie James occActive = true; 1813e5422edSVishwanatha Subbanna } 1823e5422edSVishwanatha Subbanna else 1833e5422edSVishwanatha Subbanna { 1844f4712d8SEddie James occActive = false; 1853e5422edSVishwanatha Subbanna } 1863e5422edSVishwanatha Subbanna } 1873e5422edSVishwanatha Subbanna return; 1883e5422edSVishwanatha Subbanna } 1893e5422edSVishwanatha Subbanna 1906b492fbfSDeepak Kodihalli } // namespace occ 1916b492fbfSDeepak Kodihalli } // namespace open_power 192