blob: 61e9ad388a10c2ef3d9da72e7f98a15ce45446d7 [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>
Chris Cain37abe9b2024-10-31 17:20:31 -050010#include <phosphor-logging/lg2.hpp>
George Liub5ca1012021-09-10 12:53:11 +080011
12#include <algorithm>
13#include <memory>
Gunnar Mills94df8c92018-09-14 14:50:03 -050014#include <string>
Chris Caina8857c52021-01-27 11:53:05 -060015
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050016namespace open_power
17{
18namespace occ
19{
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050020
Chris Cain36f9cde2021-11-22 11:18:21 -060021using namespace phosphor::logging;
22using namespace sdbusplus::org::open_power::OCC::Device::Error;
23
24PassThrough::PassThrough(
25 const char* path
26#ifdef POWER10
27 ,
28 std::unique_ptr<open_power::occ::powermode::PowerMode>& powerModeRef
29#endif
30 ) :
Patrick Williamsd7542c82024-08-16 15:20:28 -040031 Iface(utils::getBus(), path), path(path),
Chris Cain36f9cde2021-11-22 11:18:21 -060032#ifdef POWER10
33 pmode(powerModeRef),
34#endif
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +053035 devicePath(OCC_DEV_PATH + std::to_string((this->path.back() - '0') + 1)),
Chris Caina8857c52021-01-27 11:53:05 -060036 occInstance(this->path.back() - '0'),
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +053037 activeStatusSignal(
George Liuf3b75142021-06-10 11:22:50 +080038 utils::getBus(),
39 sdbusRule::propertiesChanged(path, "org.open_power.OCC.Status"),
Gunnar Mills94df8c92018-09-14 14:50:03 -050040 std::bind(std::mem_fn(&PassThrough::activeStatusEvent), this,
Chris Caina8857c52021-01-27 11:53:05 -060041 std::placeholders::_1)),
George Liuf3b75142021-06-10 11:22:50 +080042 occCmd(occInstance, path)
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050043{
Vishwanatha Subbanna38b08d72017-04-14 18:12:14 +053044 // Nothing to do.
45}
46
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050047std::vector<int32_t> PassThrough::send(std::vector<int32_t> command)
48{
Gunnar Mills94df8c92018-09-14 14:50:03 -050049 std::vector<int32_t> response{};
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053050
Vishwanatha Subbanna7d700e22017-05-19 19:58:01 +053051 // OCC only understands [bytes] so need array of bytes. Doing this
52 // because rest-server currently treats all int* as 32 bit integer.
Chris Caina8857c52021-01-27 11:53:05 -060053 std::vector<uint8_t> cmdInBytes, rsp;
Vishwanatha Subbanna7d700e22017-05-19 19:58:01 +053054 cmdInBytes.resize(command.size());
55
56 // Populate uint8_t version of vector.
57 std::transform(command.begin(), command.end(), cmdInBytes.begin(),
Gunnar Mills94df8c92018-09-14 14:50:03 -050058 [](decltype(cmdInBytes)::value_type x) { return x; });
Vishwanatha Subbanna7d700e22017-05-19 19:58:01 +053059
Chris Caina8857c52021-01-27 11:53:05 -060060 rsp = send(cmdInBytes);
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053061
Chris Caina8857c52021-01-27 11:53:05 -060062 response.resize(rsp.size());
63 std::transform(rsp.begin(), rsp.end(), response.begin(),
64 [](decltype(response)::value_type x) { return x; });
65
66 return response;
67}
68
69std::vector<uint8_t> PassThrough::send(std::vector<uint8_t> command)
70{
Chris Caina8857c52021-01-27 11:53:05 -060071 std::vector<uint8_t> response{};
72
Chris Caind4c19a02022-04-22 15:46:13 -050073 if (!occActive)
74 {
Chris Cain37abe9b2024-10-31 17:20:31 -050075 lg2::error(
76 "PassThrough::send() - OCC{INST} not active, command not sent",
77 "INST", occInstance);
Chris Caind4c19a02022-04-22 15:46:13 -050078 return response;
79 }
80
Chris Cain358d3962024-08-23 15:29:38 -050081 if (command.size() >= 3)
82 {
83 const uint16_t dataLen = command[1] << 8 | command[2];
84 std::string dataString = "";
85 if (command.size() > 3)
86 {
87 // Trace first 4 bytes of command data
88 size_t index = 3;
89 dataString = "0x";
90 for (; (index < 7) && (index < command.size()); ++index)
91 {
92 dataString += std::format("{:02X}", command[index]);
93 }
94 if (index < command.size())
95 {
96 dataString += "...";
97 }
98 }
Chris Cain37abe9b2024-10-31 17:20:31 -050099 lg2::info(
100 "PassThrough::send() Sending {CMD} command to OCC{INST} (data len={LEN}, data={DATA})",
101 "CMD", lg2::hex, command.front(), "INST", occInstance, "LEN",
102 dataLen, "DATA", dataString);
Chris Cain358d3962024-08-23 15:29:38 -0500103 }
104 else
105 {
Chris Cain37abe9b2024-10-31 17:20:31 -0500106 lg2::info("PassThrough::send() Sending {CMD} command to OCC{INST}",
107 "CMD", command.front(), "INST", occInstance);
Chris Cain358d3962024-08-23 15:29:38 -0500108 }
Chris Caina8857c52021-01-27 11:53:05 -0600109 CmdStatus status = occCmd.send(command, response);
110 if (status == CmdStatus::SUCCESS)
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +0530111 {
Chris Caina8857c52021-01-27 11:53:05 -0600112 if (response.size() >= 5)
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +0530113 {
Chris Cain37abe9b2024-10-31 17:20:31 -0500114 lg2::debug("PassThrough::send() response had {LEN} bytes", "LEN",
115 response.size());
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +0530116 }
117 else
118 {
Chris Cain37abe9b2024-10-31 17:20:31 -0500119 lg2::error("PassThrough::send() Invalid OCC response");
Chris Caina8857c52021-01-27 11:53:05 -0600120 dump_hex(response);
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +0530121 }
122 }
Chris Caina8857c52021-01-27 11:53:05 -0600123 else
124 {
Chris Cain37abe9b2024-10-31 17:20:31 -0500125 lg2::error(
126 "PassThrough::send(): OCC command failed with status {STATUS}",
127 "STATUS", status);
Chris Caina8857c52021-01-27 11:53:05 -0600128 }
Eddie James4f4712d2018-06-21 15:57:02 -0500129
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +0530130 return response;
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -0500131}
132
Chris Cain36f9cde2021-11-22 11:18:21 -0600133bool PassThrough::setMode(const uint8_t mode, const uint16_t modeData)
134{
135#ifdef POWER10
136 SysPwrMode newMode = SysPwrMode(mode);
137
Chris Cain30040d92024-06-19 16:50:34 -0500138 if (!pmode)
139 {
Chris Cain37abe9b2024-10-31 17:20:31 -0500140 lg2::error("PassThrough::setMode: PowerMode is not defined!");
Chris Cain30040d92024-06-19 16:50:34 -0500141 return false;
142 }
143
144 if (!pmode->isValidMode(SysPwrMode(mode)))
Chris Cain36f9cde2021-11-22 11:18:21 -0600145 {
Chris Cain37abe9b2024-10-31 17:20:31 -0500146 lg2::error(
147 "PassThrough::setMode() Unsupported mode {MODE} requested ({DATA})",
148 "MODE", newMode, "DATA", modeData);
Chris Cain36f9cde2021-11-22 11:18:21 -0600149 return false;
150 }
151
152 if (((newMode == SysPwrMode::FFO) || (newMode == SysPwrMode::SFP)) &&
153 (modeData == 0))
154 {
Chris Cain37abe9b2024-10-31 17:20:31 -0500155 lg2::error(
156 "PassThrough::setMode() Mode {MODE} requires non-zero frequency point.",
157 "MODE", newMode);
Chris Cain36f9cde2021-11-22 11:18:21 -0600158 return false;
159 }
160
Chris Cain37abe9b2024-10-31 17:20:31 -0500161 lg2::info("PassThrough::setMode() Setting Power Mode {MODE} (data: {DATA})",
162 "MODE", uint8_t(newMode), "DATA", modeData);
Chris Cain36f9cde2021-11-22 11:18:21 -0600163 return pmode->setMode(newMode, modeData);
164#else
Chris Cain37abe9b2024-10-31 17:20:31 -0500165 lg2::debug(
166 "PassThrough::setMode() No support to setting Power Mode {MODE} (data: {DATA})",
167 "MODE", mode, "DATA", modeData);
Chris Cain36f9cde2021-11-22 11:18:21 -0600168 return false;
169#endif
170}
171
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530172// Called at OCC Status change signal
Patrick Williamsaf408082022-07-22 19:26:54 -0500173void PassThrough::activeStatusEvent(sdbusplus::message_t& msg)
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530174{
175 std::string statusInterface;
Patrick Williamse0962702020-05-13 17:50:22 -0500176 std::map<std::string, std::variant<bool>> msgData;
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530177 msg.read(statusInterface, msgData);
178
179 auto propertyMap = msgData.find("OccActive");
180 if (propertyMap != msgData.end())
181 {
182 // Extract the OccActive property
Patrick Williams305ff8b2020-05-13 11:17:39 -0500183 if (std::get<bool>(propertyMap->second))
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530184 {
Eddie James4f4712d2018-06-21 15:57:02 -0500185 occActive = true;
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530186 }
187 else
188 {
Eddie James4f4712d2018-06-21 15:57:02 -0500189 occActive = false;
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530190 }
191 }
192 return;
193}
194
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -0500195} // namespace occ
196} // namespace open_power