blob: 68343989353717099e849f2c5a6c923bb2397482 [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>
Chris Caina8857c52021-01-27 11:53:05 -06007#include <fmt/core.h>
Gunnar Mills94df8c92018-09-14 14:50:03 -05008#include <unistd.h>
9
Gunnar Mills94df8c92018-09-14 14:50:03 -050010#include <org/open_power/OCC/Device/error.hpp>
Patrick Williamsd8aab2a2023-04-21 11:15:54 -050011#include <phosphor-logging/elog-errors.hpp>
Gunnar Mills94df8c92018-09-14 14:50:03 -050012#include <phosphor-logging/elog.hpp>
13#include <phosphor-logging/log.hpp>
George Liub5ca1012021-09-10 12:53:11 +080014
15#include <algorithm>
16#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 ) :
34 Iface(utils::getBus(), path),
35 path(path),
36#ifdef POWER10
37 pmode(powerModeRef),
38#endif
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +053039 devicePath(OCC_DEV_PATH + std::to_string((this->path.back() - '0') + 1)),
Chris Caina8857c52021-01-27 11:53:05 -060040 occInstance(this->path.back() - '0'),
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +053041 activeStatusSignal(
George Liuf3b75142021-06-10 11:22:50 +080042 utils::getBus(),
43 sdbusRule::propertiesChanged(path, "org.open_power.OCC.Status"),
Gunnar Mills94df8c92018-09-14 14:50:03 -050044 std::bind(std::mem_fn(&PassThrough::activeStatusEvent), this,
Chris Caina8857c52021-01-27 11:53:05 -060045 std::placeholders::_1)),
George Liuf3b75142021-06-10 11:22:50 +080046 occCmd(occInstance, path)
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050047{
Vishwanatha Subbanna38b08d72017-04-14 18:12:14 +053048 // Nothing to do.
49}
50
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050051std::vector<int32_t> PassThrough::send(std::vector<int32_t> command)
52{
Gunnar Mills94df8c92018-09-14 14:50:03 -050053 std::vector<int32_t> response{};
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053054
Vishwanatha Subbanna7d700e22017-05-19 19:58:01 +053055 // OCC only understands [bytes] so need array of bytes. Doing this
56 // because rest-server currently treats all int* as 32 bit integer.
Chris Caina8857c52021-01-27 11:53:05 -060057 std::vector<uint8_t> cmdInBytes, rsp;
Vishwanatha Subbanna7d700e22017-05-19 19:58:01 +053058 cmdInBytes.resize(command.size());
59
60 // Populate uint8_t version of vector.
61 std::transform(command.begin(), command.end(), cmdInBytes.begin(),
Gunnar Mills94df8c92018-09-14 14:50:03 -050062 [](decltype(cmdInBytes)::value_type x) { return x; });
Vishwanatha Subbanna7d700e22017-05-19 19:58:01 +053063
Chris Caina8857c52021-01-27 11:53:05 -060064 rsp = send(cmdInBytes);
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053065
Chris Caina8857c52021-01-27 11:53:05 -060066 response.resize(rsp.size());
67 std::transform(rsp.begin(), rsp.end(), response.begin(),
68 [](decltype(response)::value_type x) { return x; });
69
70 return response;
71}
72
73std::vector<uint8_t> PassThrough::send(std::vector<uint8_t> command)
74{
Chris Caina8857c52021-01-27 11:53:05 -060075 std::vector<uint8_t> response{};
76
Chris Caind4c19a02022-04-22 15:46:13 -050077 if (!occActive)
78 {
79 log<level::ERR>(
80 fmt::format(
81 "PassThrough::send() - OCC{} not active, command not sent",
82 occInstance)
83 .c_str());
84 return response;
85 }
86
Chris Cain40501a22022-03-14 17:33:27 -050087 log<level::INFO>(
Chris Caina8857c52021-01-27 11:53:05 -060088 fmt::format("PassThrough::send() Sending 0x{:02X} command to OCC{}",
89 command.front(), occInstance)
90 .c_str());
91 CmdStatus status = occCmd.send(command, response);
92 if (status == CmdStatus::SUCCESS)
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053093 {
Chris Caina8857c52021-01-27 11:53:05 -060094 if (response.size() >= 5)
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053095 {
George Liub5ca1012021-09-10 12:53:11 +080096 log<level::DEBUG>(
97 fmt::format("PassThrough::send() response had {} bytes",
98 response.size())
99 .c_str());
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +0530100 }
101 else
102 {
Chris Caina8857c52021-01-27 11:53:05 -0600103 log<level::ERR>("PassThrough::send() Invalid OCC response");
104 dump_hex(response);
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +0530105 }
106 }
Chris Caina8857c52021-01-27 11:53:05 -0600107 else
108 {
Chris Cainc567dc82022-04-01 15:09:17 -0500109 log<level::ERR>(
110 fmt::format(
111 "PassThrough::send(): OCC command failed with status {}",
112 uint32_t(status))
113 .c_str());
Chris Caina8857c52021-01-27 11:53:05 -0600114 }
Eddie James4f4712d2018-06-21 15:57:02 -0500115
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +0530116 return response;
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -0500117}
118
Chris Cain36f9cde2021-11-22 11:18:21 -0600119bool PassThrough::setMode(const uint8_t mode, const uint16_t modeData)
120{
121#ifdef POWER10
122 SysPwrMode newMode = SysPwrMode(mode);
123
124 if ((!VALID_POWER_MODE_SETTING(newMode)) &&
125 (!VALID_OEM_POWER_MODE_SETTING(newMode)))
126 {
127 log<level::ERR>(
128 fmt::format(
129 "PassThrough::setMode() Unsupported mode {} requested (0x{:04X})",
130 newMode, modeData)
131 .c_str());
132 return false;
133 }
134
135 if (((newMode == SysPwrMode::FFO) || (newMode == SysPwrMode::SFP)) &&
136 (modeData == 0))
137 {
138 log<level::ERR>(
139 fmt::format(
140 "PassThrough::setMode() Mode {} requires non-zero frequency point.",
141 newMode)
142 .c_str());
143 return false;
144 }
145
Chris Cain6fa848a2022-01-24 14:54:38 -0600146 if (!pmode)
147 {
148 log<level::ERR>("PassThrough::setMode: PowerMode is not defined!");
149 return false;
150 }
151
Chris Cain36f9cde2021-11-22 11:18:21 -0600152 log<level::INFO>(
153 fmt::format("PassThrough::setMode() Setting Power Mode {} (data: {})",
154 newMode, modeData)
155 .c_str());
156 return pmode->setMode(newMode, modeData);
157#else
158 log<level::DEBUG>(
159 fmt::format(
160 "PassThrough::setMode() No support to setting Power Mode {} (data: {})",
161 mode, modeData)
162 .c_str());
163 return false;
164#endif
165}
166
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530167// Called at OCC Status change signal
Patrick Williamsaf408082022-07-22 19:26:54 -0500168void PassThrough::activeStatusEvent(sdbusplus::message_t& msg)
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530169{
170 std::string statusInterface;
Patrick Williamse0962702020-05-13 17:50:22 -0500171 std::map<std::string, std::variant<bool>> msgData;
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530172 msg.read(statusInterface, msgData);
173
174 auto propertyMap = msgData.find("OccActive");
175 if (propertyMap != msgData.end())
176 {
177 // Extract the OccActive property
Patrick Williams305ff8b2020-05-13 11:17:39 -0500178 if (std::get<bool>(propertyMap->second))
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530179 {
Eddie James4f4712d2018-06-21 15:57:02 -0500180 occActive = true;
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530181 }
182 else
183 {
Eddie James4f4712d2018-06-21 15:57:02 -0500184 occActive = false;
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530185 }
186 }
187 return;
188}
189
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -0500190} // namespace occ
191} // namespace open_power