13e5422edSVishwanatha Subbanna #include "config.h" 294df8c90SGunnar Mills 394df8c90SGunnar Mills #include "occ_pass_through.hpp" 494df8c90SGunnar Mills 594df8c90SGunnar Mills #include "elog-errors.hpp" 694df8c90SGunnar Mills 794df8c90SGunnar Mills #include <errno.h> 894df8c90SGunnar Mills #include <fcntl.h> 9a8857c50SChris Cain #include <fmt/core.h> 1094df8c90SGunnar Mills #include <unistd.h> 1194df8c90SGunnar Mills 1294df8c90SGunnar Mills #include <org/open_power/OCC/Device/error.hpp> 1394df8c90SGunnar Mills #include <phosphor-logging/elog.hpp> 1494df8c90SGunnar Mills #include <phosphor-logging/log.hpp> 15b5ca1015SGeorge Liu 16b5ca1015SGeorge Liu #include <algorithm> 17b5ca1015SGeorge Liu #include <memory> 1894df8c90SGunnar Mills #include <string> 19a8857c50SChris Cain 206b492fbfSDeepak Kodihalli namespace open_power 216b492fbfSDeepak Kodihalli { 226b492fbfSDeepak Kodihalli namespace occ 236b492fbfSDeepak Kodihalli { 246b492fbfSDeepak Kodihalli 25*36f9cdedSChris Cain using namespace phosphor::logging; 26*36f9cdedSChris Cain using namespace sdbusplus::org::open_power::OCC::Device::Error; 27*36f9cdedSChris Cain 28*36f9cdedSChris Cain PassThrough::PassThrough( 29*36f9cdedSChris Cain const char* path 30*36f9cdedSChris Cain #ifdef POWER10 31*36f9cdedSChris Cain , 32*36f9cdedSChris Cain std::unique_ptr<open_power::occ::powermode::PowerMode>& powerModeRef 33*36f9cdedSChris Cain #endif 34*36f9cdedSChris Cain ) : 35*36f9cdedSChris Cain Iface(utils::getBus(), path), 36*36f9cdedSChris Cain path(path), 37*36f9cdedSChris Cain #ifdef POWER10 38*36f9cdedSChris Cain pmode(powerModeRef), 39*36f9cdedSChris Cain #endif 403e5422edSVishwanatha Subbanna devicePath(OCC_DEV_PATH + std::to_string((this->path.back() - '0') + 1)), 41a8857c50SChris Cain occInstance(this->path.back() - '0'), 423e5422edSVishwanatha Subbanna activeStatusSignal( 43f3b7514eSGeorge Liu utils::getBus(), 44f3b7514eSGeorge Liu sdbusRule::propertiesChanged(path, "org.open_power.OCC.Status"), 4594df8c90SGunnar Mills std::bind(std::mem_fn(&PassThrough::activeStatusEvent), this, 46a8857c50SChris Cain std::placeholders::_1)), 47f3b7514eSGeorge Liu occCmd(occInstance, path) 486b492fbfSDeepak Kodihalli { 4938b08d79SVishwanatha Subbanna // Nothing to do. 5038b08d79SVishwanatha Subbanna } 5138b08d79SVishwanatha Subbanna 526b492fbfSDeepak Kodihalli std::vector<int32_t> PassThrough::send(std::vector<int32_t> command) 536b492fbfSDeepak Kodihalli { 5467d50ad6SVishwanatha Subbanna std::vector<int32_t> response{}; 5567d50ad6SVishwanatha Subbanna 567d700e26SVishwanatha Subbanna // OCC only understands [bytes] so need array of bytes. Doing this 577d700e26SVishwanatha Subbanna // because rest-server currently treats all int* as 32 bit integer. 58a8857c50SChris Cain std::vector<uint8_t> cmdInBytes, rsp; 597d700e26SVishwanatha Subbanna cmdInBytes.resize(command.size()); 607d700e26SVishwanatha Subbanna 617d700e26SVishwanatha Subbanna // Populate uint8_t version of vector. 627d700e26SVishwanatha Subbanna std::transform(command.begin(), command.end(), cmdInBytes.begin(), 637d700e26SVishwanatha Subbanna [](decltype(cmdInBytes)::value_type x) { return x; }); 647d700e26SVishwanatha Subbanna 65a8857c50SChris Cain rsp = send(cmdInBytes); 66a8857c50SChris Cain 67a8857c50SChris Cain response.resize(rsp.size()); 68a8857c50SChris Cain std::transform(rsp.begin(), rsp.end(), response.begin(), 69a8857c50SChris Cain [](decltype(response)::value_type x) { return x; }); 70a8857c50SChris Cain 71a8857c50SChris Cain return response; 726b492fbfSDeepak Kodihalli } 736b492fbfSDeepak Kodihalli 74a8857c50SChris Cain std::vector<uint8_t> PassThrough::send(std::vector<uint8_t> command) 7567d50ad6SVishwanatha Subbanna { 76a8857c50SChris Cain std::vector<uint8_t> response{}; 77a8857c50SChris Cain 78a8857c50SChris Cain log<level::DEBUG>( 79a8857c50SChris Cain fmt::format("PassThrough::send() Sending 0x{:02X} command to OCC{}", 80a8857c50SChris Cain command.front(), occInstance) 81a8857c50SChris Cain .c_str()); 82a8857c50SChris Cain CmdStatus status = occCmd.send(command, response); 83a8857c50SChris Cain if (status == CmdStatus::SUCCESS) 8467d50ad6SVishwanatha Subbanna { 85a8857c50SChris Cain if (response.size() >= 5) 8667d50ad6SVishwanatha Subbanna { 87b5ca1015SGeorge Liu log<level::DEBUG>( 88b5ca1015SGeorge Liu fmt::format("PassThrough::send() response had {} bytes", 89a8857c50SChris Cain response.size()) 90a8857c50SChris Cain .c_str()); 9167d50ad6SVishwanatha Subbanna } 9267d50ad6SVishwanatha Subbanna else 9367d50ad6SVishwanatha Subbanna { 94a8857c50SChris Cain log<level::ERR>("PassThrough::send() Invalid OCC response"); 95a8857c50SChris Cain dump_hex(response); 9667d50ad6SVishwanatha Subbanna } 9767d50ad6SVishwanatha Subbanna } 98a8857c50SChris Cain else 99a8857c50SChris Cain { 100a8857c50SChris Cain if (status == CmdStatus::OPEN_FAILURE) 101a8857c50SChris Cain { 102a8857c50SChris Cain log<level::WARNING>("PassThrough::send() - OCC not active yet"); 103a8857c50SChris Cain } 104a8857c50SChris Cain else 105a8857c50SChris Cain { 106a8857c50SChris Cain log<level::ERR>("PassThrough::send() - OCC command failed!"); 107a8857c50SChris Cain } 108a8857c50SChris Cain } 1094f4712d8SEddie James 11067d50ad6SVishwanatha Subbanna return response; 11167d50ad6SVishwanatha Subbanna } 11267d50ad6SVishwanatha Subbanna 113*36f9cdedSChris Cain bool PassThrough::setMode(const uint8_t mode, const uint16_t modeData) 114*36f9cdedSChris Cain { 115*36f9cdedSChris Cain #ifdef POWER10 116*36f9cdedSChris Cain SysPwrMode newMode = SysPwrMode(mode); 117*36f9cdedSChris Cain 118*36f9cdedSChris Cain if ((!VALID_POWER_MODE_SETTING(newMode)) && 119*36f9cdedSChris Cain (!VALID_OEM_POWER_MODE_SETTING(newMode))) 120*36f9cdedSChris Cain { 121*36f9cdedSChris Cain log<level::ERR>( 122*36f9cdedSChris Cain fmt::format( 123*36f9cdedSChris Cain "PassThrough::setMode() Unsupported mode {} requested (0x{:04X})", 124*36f9cdedSChris Cain newMode, modeData) 125*36f9cdedSChris Cain .c_str()); 126*36f9cdedSChris Cain return false; 127*36f9cdedSChris Cain } 128*36f9cdedSChris Cain 129*36f9cdedSChris Cain if (((newMode == SysPwrMode::FFO) || (newMode == SysPwrMode::SFP)) && 130*36f9cdedSChris Cain (modeData == 0)) 131*36f9cdedSChris Cain { 132*36f9cdedSChris Cain log<level::ERR>( 133*36f9cdedSChris Cain fmt::format( 134*36f9cdedSChris Cain "PassThrough::setMode() Mode {} requires non-zero frequency point.", 135*36f9cdedSChris Cain newMode) 136*36f9cdedSChris Cain .c_str()); 137*36f9cdedSChris Cain return false; 138*36f9cdedSChris Cain } 139*36f9cdedSChris Cain 140*36f9cdedSChris Cain log<level::INFO>( 141*36f9cdedSChris Cain fmt::format("PassThrough::setMode() Setting Power Mode {} (data: {})", 142*36f9cdedSChris Cain newMode, modeData) 143*36f9cdedSChris Cain .c_str()); 144*36f9cdedSChris Cain return pmode->setMode(newMode, modeData); 145*36f9cdedSChris Cain #else 146*36f9cdedSChris Cain log<level::DEBUG>( 147*36f9cdedSChris Cain fmt::format( 148*36f9cdedSChris Cain "PassThrough::setMode() No support to setting Power Mode {} (data: {})", 149*36f9cdedSChris Cain mode, modeData) 150*36f9cdedSChris Cain .c_str()); 151*36f9cdedSChris Cain return false; 152*36f9cdedSChris Cain #endif 153*36f9cdedSChris Cain } 154*36f9cdedSChris Cain 1553e5422edSVishwanatha Subbanna // Called at OCC Status change signal 1563e5422edSVishwanatha Subbanna void PassThrough::activeStatusEvent(sdbusplus::message::message& msg) 1573e5422edSVishwanatha Subbanna { 1583e5422edSVishwanatha Subbanna std::string statusInterface; 159e0962703SPatrick Williams std::map<std::string, std::variant<bool>> msgData; 1603e5422edSVishwanatha Subbanna msg.read(statusInterface, msgData); 1613e5422edSVishwanatha Subbanna 1623e5422edSVishwanatha Subbanna auto propertyMap = msgData.find("OccActive"); 1633e5422edSVishwanatha Subbanna if (propertyMap != msgData.end()) 1643e5422edSVishwanatha Subbanna { 1653e5422edSVishwanatha Subbanna // Extract the OccActive property 166305ff8b1SPatrick Williams if (std::get<bool>(propertyMap->second)) 1673e5422edSVishwanatha Subbanna { 1684f4712d8SEddie James occActive = true; 1693e5422edSVishwanatha Subbanna } 1703e5422edSVishwanatha Subbanna else 1713e5422edSVishwanatha Subbanna { 1724f4712d8SEddie James occActive = false; 1733e5422edSVishwanatha Subbanna } 1743e5422edSVishwanatha Subbanna } 1753e5422edSVishwanatha Subbanna return; 1763e5422edSVishwanatha Subbanna } 1773e5422edSVishwanatha Subbanna 1786b492fbfSDeepak Kodihalli } // namespace occ 1796b492fbfSDeepak Kodihalli } // namespace open_power 180