| Vishwanatha Subbanna | 3e5422e | 2017-08-10 18:25:26 +0530 | [diff] [blame] | 1 | #include "config.h" | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 2 |  | 
|  | 3 | #include "occ_pass_through.hpp" | 
|  | 4 |  | 
|  | 5 | #include "elog-errors.hpp" | 
|  | 6 |  | 
|  | 7 | #include <errno.h> | 
|  | 8 | #include <fcntl.h> | 
| Chris Cain | a8857c5 | 2021-01-27 11:53:05 -0600 | [diff] [blame] | 9 | #include <fmt/core.h> | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 10 | #include <unistd.h> | 
|  | 11 |  | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 12 | #include <org/open_power/OCC/Device/error.hpp> | 
|  | 13 | #include <phosphor-logging/elog.hpp> | 
|  | 14 | #include <phosphor-logging/log.hpp> | 
| George Liu | b5ca101 | 2021-09-10 12:53:11 +0800 | [diff] [blame] | 15 |  | 
|  | 16 | #include <algorithm> | 
|  | 17 | #include <memory> | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 18 | #include <string> | 
| Chris Cain | a8857c5 | 2021-01-27 11:53:05 -0600 | [diff] [blame] | 19 |  | 
| Deepak Kodihalli | 6b492fb | 2017-03-18 01:09:28 -0500 | [diff] [blame] | 20 | namespace open_power | 
|  | 21 | { | 
|  | 22 | namespace occ | 
|  | 23 | { | 
| Deepak Kodihalli | 6b492fb | 2017-03-18 01:09:28 -0500 | [diff] [blame] | 24 |  | 
| Chris Cain | 36f9cde | 2021-11-22 11:18:21 -0600 | [diff] [blame] | 25 | using namespace phosphor::logging; | 
|  | 26 | using namespace sdbusplus::org::open_power::OCC::Device::Error; | 
|  | 27 |  | 
|  | 28 | PassThrough::PassThrough( | 
|  | 29 | const char* path | 
|  | 30 | #ifdef POWER10 | 
|  | 31 | , | 
|  | 32 | std::unique_ptr<open_power::occ::powermode::PowerMode>& powerModeRef | 
|  | 33 | #endif | 
|  | 34 | ) : | 
|  | 35 | Iface(utils::getBus(), path), | 
|  | 36 | path(path), | 
|  | 37 | #ifdef POWER10 | 
|  | 38 | pmode(powerModeRef), | 
|  | 39 | #endif | 
| Vishwanatha Subbanna | 3e5422e | 2017-08-10 18:25:26 +0530 | [diff] [blame] | 40 | devicePath(OCC_DEV_PATH + std::to_string((this->path.back() - '0') + 1)), | 
| Chris Cain | a8857c5 | 2021-01-27 11:53:05 -0600 | [diff] [blame] | 41 | occInstance(this->path.back() - '0'), | 
| Vishwanatha Subbanna | 3e5422e | 2017-08-10 18:25:26 +0530 | [diff] [blame] | 42 | activeStatusSignal( | 
| George Liu | f3b7514 | 2021-06-10 11:22:50 +0800 | [diff] [blame] | 43 | utils::getBus(), | 
|  | 44 | sdbusRule::propertiesChanged(path, "org.open_power.OCC.Status"), | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 45 | std::bind(std::mem_fn(&PassThrough::activeStatusEvent), this, | 
| Chris Cain | a8857c5 | 2021-01-27 11:53:05 -0600 | [diff] [blame] | 46 | std::placeholders::_1)), | 
| George Liu | f3b7514 | 2021-06-10 11:22:50 +0800 | [diff] [blame] | 47 | occCmd(occInstance, path) | 
| Deepak Kodihalli | 6b492fb | 2017-03-18 01:09:28 -0500 | [diff] [blame] | 48 | { | 
| Vishwanatha Subbanna | 38b08d7 | 2017-04-14 18:12:14 +0530 | [diff] [blame] | 49 | // Nothing to do. | 
|  | 50 | } | 
|  | 51 |  | 
| Deepak Kodihalli | 6b492fb | 2017-03-18 01:09:28 -0500 | [diff] [blame] | 52 | std::vector<int32_t> PassThrough::send(std::vector<int32_t> command) | 
|  | 53 | { | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 54 | std::vector<int32_t> response{}; | 
| Vishwanatha Subbanna | 67d50ad | 2017-04-17 23:21:52 +0530 | [diff] [blame] | 55 |  | 
| Vishwanatha Subbanna | 7d700e2 | 2017-05-19 19:58:01 +0530 | [diff] [blame] | 56 | // OCC only understands [bytes] so need array of bytes. Doing this | 
|  | 57 | // because rest-server currently treats all int* as 32 bit integer. | 
| Chris Cain | a8857c5 | 2021-01-27 11:53:05 -0600 | [diff] [blame] | 58 | std::vector<uint8_t> cmdInBytes, rsp; | 
| Vishwanatha Subbanna | 7d700e2 | 2017-05-19 19:58:01 +0530 | [diff] [blame] | 59 | cmdInBytes.resize(command.size()); | 
|  | 60 |  | 
|  | 61 | // Populate uint8_t version of vector. | 
|  | 62 | std::transform(command.begin(), command.end(), cmdInBytes.begin(), | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 63 | [](decltype(cmdInBytes)::value_type x) { return x; }); | 
| Vishwanatha Subbanna | 7d700e2 | 2017-05-19 19:58:01 +0530 | [diff] [blame] | 64 |  | 
| Chris Cain | a8857c5 | 2021-01-27 11:53:05 -0600 | [diff] [blame] | 65 | rsp = send(cmdInBytes); | 
| Vishwanatha Subbanna | 67d50ad | 2017-04-17 23:21:52 +0530 | [diff] [blame] | 66 |  | 
| Chris Cain | a8857c5 | 2021-01-27 11:53:05 -0600 | [diff] [blame] | 67 | response.resize(rsp.size()); | 
|  | 68 | std::transform(rsp.begin(), rsp.end(), response.begin(), | 
|  | 69 | [](decltype(response)::value_type x) { return x; }); | 
|  | 70 |  | 
|  | 71 | return response; | 
|  | 72 | } | 
|  | 73 |  | 
|  | 74 | std::vector<uint8_t> PassThrough::send(std::vector<uint8_t> command) | 
|  | 75 | { | 
| Chris Cain | a8857c5 | 2021-01-27 11:53:05 -0600 | [diff] [blame] | 76 | std::vector<uint8_t> response{}; | 
|  | 77 |  | 
|  | 78 | log<level::DEBUG>( | 
|  | 79 | fmt::format("PassThrough::send() Sending 0x{:02X} command to OCC{}", | 
|  | 80 | command.front(), occInstance) | 
|  | 81 | .c_str()); | 
|  | 82 | CmdStatus status = occCmd.send(command, response); | 
|  | 83 | if (status == CmdStatus::SUCCESS) | 
| Vishwanatha Subbanna | 67d50ad | 2017-04-17 23:21:52 +0530 | [diff] [blame] | 84 | { | 
| Chris Cain | a8857c5 | 2021-01-27 11:53:05 -0600 | [diff] [blame] | 85 | if (response.size() >= 5) | 
| Vishwanatha Subbanna | 67d50ad | 2017-04-17 23:21:52 +0530 | [diff] [blame] | 86 | { | 
| George Liu | b5ca101 | 2021-09-10 12:53:11 +0800 | [diff] [blame] | 87 | log<level::DEBUG>( | 
|  | 88 | fmt::format("PassThrough::send() response had {} bytes", | 
|  | 89 | response.size()) | 
|  | 90 | .c_str()); | 
| Vishwanatha Subbanna | 67d50ad | 2017-04-17 23:21:52 +0530 | [diff] [blame] | 91 | } | 
|  | 92 | else | 
|  | 93 | { | 
| Chris Cain | a8857c5 | 2021-01-27 11:53:05 -0600 | [diff] [blame] | 94 | log<level::ERR>("PassThrough::send() Invalid OCC response"); | 
|  | 95 | dump_hex(response); | 
| Vishwanatha Subbanna | 67d50ad | 2017-04-17 23:21:52 +0530 | [diff] [blame] | 96 | } | 
|  | 97 | } | 
| Chris Cain | a8857c5 | 2021-01-27 11:53:05 -0600 | [diff] [blame] | 98 | else | 
|  | 99 | { | 
|  | 100 | if (status == CmdStatus::OPEN_FAILURE) | 
|  | 101 | { | 
|  | 102 | log<level::WARNING>("PassThrough::send() - OCC not active yet"); | 
|  | 103 | } | 
|  | 104 | else | 
|  | 105 | { | 
|  | 106 | log<level::ERR>("PassThrough::send() - OCC command failed!"); | 
|  | 107 | } | 
|  | 108 | } | 
| Eddie James | 4f4712d | 2018-06-21 15:57:02 -0500 | [diff] [blame] | 109 |  | 
| Vishwanatha Subbanna | 67d50ad | 2017-04-17 23:21:52 +0530 | [diff] [blame] | 110 | return response; | 
| Deepak Kodihalli | 6b492fb | 2017-03-18 01:09:28 -0500 | [diff] [blame] | 111 | } | 
|  | 112 |  | 
| Chris Cain | 36f9cde | 2021-11-22 11:18:21 -0600 | [diff] [blame] | 113 | bool PassThrough::setMode(const uint8_t mode, const uint16_t modeData) | 
|  | 114 | { | 
|  | 115 | #ifdef POWER10 | 
|  | 116 | SysPwrMode newMode = SysPwrMode(mode); | 
|  | 117 |  | 
|  | 118 | if ((!VALID_POWER_MODE_SETTING(newMode)) && | 
|  | 119 | (!VALID_OEM_POWER_MODE_SETTING(newMode))) | 
|  | 120 | { | 
|  | 121 | log<level::ERR>( | 
|  | 122 | fmt::format( | 
|  | 123 | "PassThrough::setMode() Unsupported mode {} requested (0x{:04X})", | 
|  | 124 | newMode, modeData) | 
|  | 125 | .c_str()); | 
|  | 126 | return false; | 
|  | 127 | } | 
|  | 128 |  | 
|  | 129 | if (((newMode == SysPwrMode::FFO) || (newMode == SysPwrMode::SFP)) && | 
|  | 130 | (modeData == 0)) | 
|  | 131 | { | 
|  | 132 | log<level::ERR>( | 
|  | 133 | fmt::format( | 
|  | 134 | "PassThrough::setMode() Mode {} requires non-zero frequency point.", | 
|  | 135 | newMode) | 
|  | 136 | .c_str()); | 
|  | 137 | return false; | 
|  | 138 | } | 
|  | 139 |  | 
|  | 140 | log<level::INFO>( | 
|  | 141 | fmt::format("PassThrough::setMode() Setting Power Mode {} (data: {})", | 
|  | 142 | newMode, modeData) | 
|  | 143 | .c_str()); | 
|  | 144 | return pmode->setMode(newMode, modeData); | 
|  | 145 | #else | 
|  | 146 | log<level::DEBUG>( | 
|  | 147 | fmt::format( | 
|  | 148 | "PassThrough::setMode() No support to setting Power Mode {} (data: {})", | 
|  | 149 | mode, modeData) | 
|  | 150 | .c_str()); | 
|  | 151 | return false; | 
|  | 152 | #endif | 
|  | 153 | } | 
|  | 154 |  | 
| Vishwanatha Subbanna | 3e5422e | 2017-08-10 18:25:26 +0530 | [diff] [blame] | 155 | // Called at OCC Status change signal | 
|  | 156 | void PassThrough::activeStatusEvent(sdbusplus::message::message& msg) | 
|  | 157 | { | 
|  | 158 | std::string statusInterface; | 
| Patrick Williams | e096270 | 2020-05-13 17:50:22 -0500 | [diff] [blame] | 159 | std::map<std::string, std::variant<bool>> msgData; | 
| Vishwanatha Subbanna | 3e5422e | 2017-08-10 18:25:26 +0530 | [diff] [blame] | 160 | msg.read(statusInterface, msgData); | 
|  | 161 |  | 
|  | 162 | auto propertyMap = msgData.find("OccActive"); | 
|  | 163 | if (propertyMap != msgData.end()) | 
|  | 164 | { | 
|  | 165 | // Extract the OccActive property | 
| Patrick Williams | 305ff8b | 2020-05-13 11:17:39 -0500 | [diff] [blame] | 166 | if (std::get<bool>(propertyMap->second)) | 
| Vishwanatha Subbanna | 3e5422e | 2017-08-10 18:25:26 +0530 | [diff] [blame] | 167 | { | 
| Eddie James | 4f4712d | 2018-06-21 15:57:02 -0500 | [diff] [blame] | 168 | occActive = true; | 
| Vishwanatha Subbanna | 3e5422e | 2017-08-10 18:25:26 +0530 | [diff] [blame] | 169 | } | 
|  | 170 | else | 
|  | 171 | { | 
| Eddie James | 4f4712d | 2018-06-21 15:57:02 -0500 | [diff] [blame] | 172 | occActive = false; | 
| Vishwanatha Subbanna | 3e5422e | 2017-08-10 18:25:26 +0530 | [diff] [blame] | 173 | } | 
|  | 174 | } | 
|  | 175 | return; | 
|  | 176 | } | 
|  | 177 |  | 
| Deepak Kodihalli | 6b492fb | 2017-03-18 01:09:28 -0500 | [diff] [blame] | 178 | } // namespace occ | 
|  | 179 | } // namespace open_power |