blob: 85677844a4d427f6e01f9b873742f0ee4987f0b3 [file] [log] [blame]
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +05301#include "config.h"
Gunnar Mills94df8c92018-09-14 14:50:03 -05002
3#include "occ_pass_through.hpp"
4
Gunnar Mills94df8c92018-09-14 14:50:03 -05005#include <errno.h>
6#include <fcntl.h>
7#include <unistd.h>
8
Gunnar Mills94df8c92018-09-14 14:50:03 -05009#include <org/open_power/OCC/Device/error.hpp>
Patrick Williamsd8aab2a2023-04-21 11:15:54 -050010#include <phosphor-logging/elog-errors.hpp>
Gunnar Mills94df8c92018-09-14 14:50:03 -050011#include <phosphor-logging/elog.hpp>
12#include <phosphor-logging/log.hpp>
George Liub5ca1012021-09-10 12:53:11 +080013
14#include <algorithm>
Patrick Williams48002492024-02-13 21:43:32 -060015#include <format>
George Liub5ca1012021-09-10 12:53:11 +080016#include <memory>
Gunnar Mills94df8c92018-09-14 14:50:03 -050017#include <string>
Chris Caina8857c52021-01-27 11:53:05 -060018
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050019namespace open_power
20{
21namespace occ
22{
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050023
Chris Cain36f9cde2021-11-22 11:18:21 -060024using namespace phosphor::logging;
25using namespace sdbusplus::org::open_power::OCC::Device::Error;
26
27PassThrough::PassThrough(
28 const char* path
29#ifdef POWER10
30 ,
31 std::unique_ptr<open_power::occ::powermode::PowerMode>& powerModeRef
32#endif
33 ) :
Patrick Williamsd7542c82024-08-16 15:20:28 -040034 Iface(utils::getBus(), path), path(path),
Chris Cain36f9cde2021-11-22 11:18:21 -060035#ifdef POWER10
36 pmode(powerModeRef),
37#endif
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +053038 devicePath(OCC_DEV_PATH + std::to_string((this->path.back() - '0') + 1)),
Chris Caina8857c52021-01-27 11:53:05 -060039 occInstance(this->path.back() - '0'),
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +053040 activeStatusSignal(
George Liuf3b75142021-06-10 11:22:50 +080041 utils::getBus(),
42 sdbusRule::propertiesChanged(path, "org.open_power.OCC.Status"),
Gunnar Mills94df8c92018-09-14 14:50:03 -050043 std::bind(std::mem_fn(&PassThrough::activeStatusEvent), this,
Chris Caina8857c52021-01-27 11:53:05 -060044 std::placeholders::_1)),
George Liuf3b75142021-06-10 11:22:50 +080045 occCmd(occInstance, path)
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050046{
Vishwanatha Subbanna38b08d72017-04-14 18:12:14 +053047 // Nothing to do.
48}
49
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050050std::vector<int32_t> PassThrough::send(std::vector<int32_t> command)
51{
Gunnar Mills94df8c92018-09-14 14:50:03 -050052 std::vector<int32_t> response{};
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053053
Vishwanatha Subbanna7d700e22017-05-19 19:58:01 +053054 // OCC only understands [bytes] so need array of bytes. Doing this
55 // because rest-server currently treats all int* as 32 bit integer.
Chris Caina8857c52021-01-27 11:53:05 -060056 std::vector<uint8_t> cmdInBytes, rsp;
Vishwanatha Subbanna7d700e22017-05-19 19:58:01 +053057 cmdInBytes.resize(command.size());
58
59 // Populate uint8_t version of vector.
60 std::transform(command.begin(), command.end(), cmdInBytes.begin(),
Gunnar Mills94df8c92018-09-14 14:50:03 -050061 [](decltype(cmdInBytes)::value_type x) { return x; });
Vishwanatha Subbanna7d700e22017-05-19 19:58:01 +053062
Chris Caina8857c52021-01-27 11:53:05 -060063 rsp = send(cmdInBytes);
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053064
Chris Caina8857c52021-01-27 11:53:05 -060065 response.resize(rsp.size());
66 std::transform(rsp.begin(), rsp.end(), response.begin(),
67 [](decltype(response)::value_type x) { return x; });
68
69 return response;
70}
71
72std::vector<uint8_t> PassThrough::send(std::vector<uint8_t> command)
73{
Chris Caina8857c52021-01-27 11:53:05 -060074 std::vector<uint8_t> response{};
75
Chris Caind4c19a02022-04-22 15:46:13 -050076 if (!occActive)
77 {
78 log<level::ERR>(
Patrick Williams48002492024-02-13 21:43:32 -060079 std::format(
Chris Caind4c19a02022-04-22 15:46:13 -050080 "PassThrough::send() - OCC{} not active, command not sent",
81 occInstance)
82 .c_str());
83 return response;
84 }
85
Chris Cain358d3962024-08-23 15:29:38 -050086 if (command.size() >= 3)
87 {
88 const uint16_t dataLen = command[1] << 8 | command[2];
89 std::string dataString = "";
90 if (command.size() > 3)
91 {
92 // Trace first 4 bytes of command data
93 size_t index = 3;
94 dataString = "0x";
95 for (; (index < 7) && (index < command.size()); ++index)
96 {
97 dataString += std::format("{:02X}", command[index]);
98 }
99 if (index < command.size())
100 {
101 dataString += "...";
102 }
103 }
104 log<level::INFO>(
105 std::format(
106 "PassThrough::send() Sending 0x{:02X} command to OCC{} (data len={}, data={})",
107 command.front(), occInstance, dataLen, dataString)
108 .c_str());
109 }
110 else
111 {
112 log<level::INFO>(
113 std::format("PassThrough::send() Sending 0x{:02X} command to OCC{}",
114 command.front(), occInstance)
115 .c_str());
116 }
Chris Caina8857c52021-01-27 11:53:05 -0600117 CmdStatus status = occCmd.send(command, response);
118 if (status == CmdStatus::SUCCESS)
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +0530119 {
Chris Caina8857c52021-01-27 11:53:05 -0600120 if (response.size() >= 5)
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +0530121 {
George Liub5ca1012021-09-10 12:53:11 +0800122 log<level::DEBUG>(
Patrick Williams48002492024-02-13 21:43:32 -0600123 std::format("PassThrough::send() response had {} bytes",
George Liub5ca1012021-09-10 12:53:11 +0800124 response.size())
125 .c_str());
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +0530126 }
127 else
128 {
Chris Caina8857c52021-01-27 11:53:05 -0600129 log<level::ERR>("PassThrough::send() Invalid OCC response");
130 dump_hex(response);
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +0530131 }
132 }
Chris Caina8857c52021-01-27 11:53:05 -0600133 else
134 {
Chris Cainc567dc82022-04-01 15:09:17 -0500135 log<level::ERR>(
Patrick Williams48002492024-02-13 21:43:32 -0600136 std::format(
Chris Cainc567dc82022-04-01 15:09:17 -0500137 "PassThrough::send(): OCC command failed with status {}",
138 uint32_t(status))
139 .c_str());
Chris Caina8857c52021-01-27 11:53:05 -0600140 }
Eddie James4f4712d2018-06-21 15:57:02 -0500141
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +0530142 return response;
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -0500143}
144
Chris Cain36f9cde2021-11-22 11:18:21 -0600145bool PassThrough::setMode(const uint8_t mode, const uint16_t modeData)
146{
147#ifdef POWER10
148 SysPwrMode newMode = SysPwrMode(mode);
149
Chris Cain30040d92024-06-19 16:50:34 -0500150 if (!pmode)
151 {
152 log<level::ERR>("PassThrough::setMode: PowerMode is not defined!");
153 return false;
154 }
155
156 if (!pmode->isValidMode(SysPwrMode(mode)))
Chris Cain36f9cde2021-11-22 11:18:21 -0600157 {
158 log<level::ERR>(
Patrick Williams48002492024-02-13 21:43:32 -0600159 std::format(
Chris Cain36f9cde2021-11-22 11:18:21 -0600160 "PassThrough::setMode() Unsupported mode {} requested (0x{:04X})",
161 newMode, modeData)
162 .c_str());
163 return false;
164 }
165
166 if (((newMode == SysPwrMode::FFO) || (newMode == SysPwrMode::SFP)) &&
167 (modeData == 0))
168 {
169 log<level::ERR>(
Patrick Williams48002492024-02-13 21:43:32 -0600170 std::format(
Chris Cain36f9cde2021-11-22 11:18:21 -0600171 "PassThrough::setMode() Mode {} requires non-zero frequency point.",
172 newMode)
173 .c_str());
174 return false;
175 }
176
177 log<level::INFO>(
Patrick Williams48002492024-02-13 21:43:32 -0600178 std::format("PassThrough::setMode() Setting Power Mode {} (data: {})",
Chris Cain36f9cde2021-11-22 11:18:21 -0600179 newMode, modeData)
180 .c_str());
181 return pmode->setMode(newMode, modeData);
182#else
183 log<level::DEBUG>(
Patrick Williams48002492024-02-13 21:43:32 -0600184 std::format(
Chris Cain36f9cde2021-11-22 11:18:21 -0600185 "PassThrough::setMode() No support to setting Power Mode {} (data: {})",
186 mode, modeData)
187 .c_str());
188 return false;
189#endif
190}
191
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530192// Called at OCC Status change signal
Patrick Williamsaf408082022-07-22 19:26:54 -0500193void PassThrough::activeStatusEvent(sdbusplus::message_t& msg)
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530194{
195 std::string statusInterface;
Patrick Williamse0962702020-05-13 17:50:22 -0500196 std::map<std::string, std::variant<bool>> msgData;
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530197 msg.read(statusInterface, msgData);
198
199 auto propertyMap = msgData.find("OccActive");
200 if (propertyMap != msgData.end())
201 {
202 // Extract the OccActive property
Patrick Williams305ff8b2020-05-13 11:17:39 -0500203 if (std::get<bool>(propertyMap->second))
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530204 {
Eddie James4f4712d2018-06-21 15:57:02 -0500205 occActive = true;
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530206 }
207 else
208 {
Eddie James4f4712d2018-06-21 15:57:02 -0500209 occActive = false;
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530210 }
211 }
212 return;
213}
214
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -0500215} // namespace occ
216} // namespace open_power