blob: afc9513d9ae5785ba27663d04e7849d51fe7165f [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
5#include "elog-errors.hpp"
6
7#include <errno.h>
8#include <fcntl.h>
Chris Caina8857c52021-01-27 11:53:05 -06009#include <fmt/core.h>
Gunnar Mills94df8c92018-09-14 14:50:03 -050010#include <unistd.h>
11
Gunnar Mills94df8c92018-09-14 14:50:03 -050012#include <org/open_power/OCC/Device/error.hpp>
13#include <phosphor-logging/elog.hpp>
14#include <phosphor-logging/log.hpp>
George Liub5ca1012021-09-10 12:53:11 +080015
16#include <algorithm>
17#include <memory>
Gunnar Mills94df8c92018-09-14 14:50:03 -050018#include <string>
Chris Caina8857c52021-01-27 11:53:05 -060019
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050020namespace open_power
21{
22namespace occ
23{
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050024
Chris Cain36f9cde2021-11-22 11:18:21 -060025using namespace phosphor::logging;
26using namespace sdbusplus::org::open_power::OCC::Device::Error;
27
28PassThrough::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 Subbanna3e5422e2017-08-10 18:25:26 +053040 devicePath(OCC_DEV_PATH + std::to_string((this->path.back() - '0') + 1)),
Chris Caina8857c52021-01-27 11:53:05 -060041 occInstance(this->path.back() - '0'),
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +053042 activeStatusSignal(
George Liuf3b75142021-06-10 11:22:50 +080043 utils::getBus(),
44 sdbusRule::propertiesChanged(path, "org.open_power.OCC.Status"),
Gunnar Mills94df8c92018-09-14 14:50:03 -050045 std::bind(std::mem_fn(&PassThrough::activeStatusEvent), this,
Chris Caina8857c52021-01-27 11:53:05 -060046 std::placeholders::_1)),
George Liuf3b75142021-06-10 11:22:50 +080047 occCmd(occInstance, path)
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050048{
Vishwanatha Subbanna38b08d72017-04-14 18:12:14 +053049 // Nothing to do.
50}
51
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050052std::vector<int32_t> PassThrough::send(std::vector<int32_t> command)
53{
Gunnar Mills94df8c92018-09-14 14:50:03 -050054 std::vector<int32_t> response{};
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053055
Vishwanatha Subbanna7d700e22017-05-19 19:58:01 +053056 // OCC only understands [bytes] so need array of bytes. Doing this
57 // because rest-server currently treats all int* as 32 bit integer.
Chris Caina8857c52021-01-27 11:53:05 -060058 std::vector<uint8_t> cmdInBytes, rsp;
Vishwanatha Subbanna7d700e22017-05-19 19:58:01 +053059 cmdInBytes.resize(command.size());
60
61 // Populate uint8_t version of vector.
62 std::transform(command.begin(), command.end(), cmdInBytes.begin(),
Gunnar Mills94df8c92018-09-14 14:50:03 -050063 [](decltype(cmdInBytes)::value_type x) { return x; });
Vishwanatha Subbanna7d700e22017-05-19 19:58:01 +053064
Chris Caina8857c52021-01-27 11:53:05 -060065 rsp = send(cmdInBytes);
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053066
Chris Caina8857c52021-01-27 11:53:05 -060067 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
74std::vector<uint8_t> PassThrough::send(std::vector<uint8_t> command)
75{
Chris Caina8857c52021-01-27 11:53:05 -060076 std::vector<uint8_t> response{};
77
Chris Caind4c19a02022-04-22 15:46:13 -050078 if (!occActive)
79 {
80 log<level::ERR>(
81 fmt::format(
82 "PassThrough::send() - OCC{} not active, command not sent",
83 occInstance)
84 .c_str());
85 return response;
86 }
87
Chris Cain40501a22022-03-14 17:33:27 -050088 log<level::INFO>(
Chris Caina8857c52021-01-27 11:53:05 -060089 fmt::format("PassThrough::send() Sending 0x{:02X} command to OCC{}",
90 command.front(), occInstance)
91 .c_str());
92 CmdStatus status = occCmd.send(command, response);
93 if (status == CmdStatus::SUCCESS)
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053094 {
Chris Caina8857c52021-01-27 11:53:05 -060095 if (response.size() >= 5)
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053096 {
George Liub5ca1012021-09-10 12:53:11 +080097 log<level::DEBUG>(
98 fmt::format("PassThrough::send() response had {} bytes",
99 response.size())
100 .c_str());
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +0530101 }
102 else
103 {
Chris Caina8857c52021-01-27 11:53:05 -0600104 log<level::ERR>("PassThrough::send() Invalid OCC response");
105 dump_hex(response);
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +0530106 }
107 }
Chris Caina8857c52021-01-27 11:53:05 -0600108 else
109 {
Chris Cainc567dc82022-04-01 15:09:17 -0500110 log<level::ERR>(
111 fmt::format(
112 "PassThrough::send(): OCC command failed with status {}",
113 uint32_t(status))
114 .c_str());
Chris Caina8857c52021-01-27 11:53:05 -0600115 }
Eddie James4f4712d2018-06-21 15:57:02 -0500116
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +0530117 return response;
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -0500118}
119
Chris Cain36f9cde2021-11-22 11:18:21 -0600120bool PassThrough::setMode(const uint8_t mode, const uint16_t modeData)
121{
122#ifdef POWER10
123 SysPwrMode newMode = SysPwrMode(mode);
124
125 if ((!VALID_POWER_MODE_SETTING(newMode)) &&
126 (!VALID_OEM_POWER_MODE_SETTING(newMode)))
127 {
128 log<level::ERR>(
129 fmt::format(
130 "PassThrough::setMode() Unsupported mode {} requested (0x{:04X})",
131 newMode, modeData)
132 .c_str());
133 return false;
134 }
135
136 if (((newMode == SysPwrMode::FFO) || (newMode == SysPwrMode::SFP)) &&
137 (modeData == 0))
138 {
139 log<level::ERR>(
140 fmt::format(
141 "PassThrough::setMode() Mode {} requires non-zero frequency point.",
142 newMode)
143 .c_str());
144 return false;
145 }
146
Chris Cain6fa848a2022-01-24 14:54:38 -0600147 if (!pmode)
148 {
149 log<level::ERR>("PassThrough::setMode: PowerMode is not defined!");
150 return false;
151 }
152
Chris Cain36f9cde2021-11-22 11:18:21 -0600153 log<level::INFO>(
154 fmt::format("PassThrough::setMode() Setting Power Mode {} (data: {})",
155 newMode, modeData)
156 .c_str());
157 return pmode->setMode(newMode, modeData);
158#else
159 log<level::DEBUG>(
160 fmt::format(
161 "PassThrough::setMode() No support to setting Power Mode {} (data: {})",
162 mode, modeData)
163 .c_str());
164 return false;
165#endif
166}
167
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530168// Called at OCC Status change signal
Patrick Williamsaf408082022-07-22 19:26:54 -0500169void PassThrough::activeStatusEvent(sdbusplus::message_t& msg)
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530170{
171 std::string statusInterface;
Patrick Williamse0962702020-05-13 17:50:22 -0500172 std::map<std::string, std::variant<bool>> msgData;
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530173 msg.read(statusInterface, msgData);
174
175 auto propertyMap = msgData.find("OccActive");
176 if (propertyMap != msgData.end())
177 {
178 // Extract the OccActive property
Patrick Williams305ff8b2020-05-13 11:17:39 -0500179 if (std::get<bool>(propertyMap->second))
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530180 {
Eddie James4f4712d2018-06-21 15:57:02 -0500181 occActive = true;
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530182 }
183 else
184 {
Eddie James4f4712d2018-06-21 15:57:02 -0500185 occActive = false;
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530186 }
187 }
188 return;
189}
190
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -0500191} // namespace occ
192} // namespace open_power