blob: 48f58cb9d674fef021471316687b6ecf35a10996 [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(
Sheldon Bailey16a5adb2025-06-10 14:10:06 -050025 const char* path,
26 std::unique_ptr<open_power::occ::powermode::PowerMode>& powerModeRef) :
27 Iface(utils::getBus(), path), path(path), pmode(powerModeRef),
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +053028 devicePath(OCC_DEV_PATH + std::to_string((this->path.back() - '0') + 1)),
Chris Caina8857c52021-01-27 11:53:05 -060029 occInstance(this->path.back() - '0'),
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +053030 activeStatusSignal(
George Liuf3b75142021-06-10 11:22:50 +080031 utils::getBus(),
32 sdbusRule::propertiesChanged(path, "org.open_power.OCC.Status"),
Gunnar Mills94df8c92018-09-14 14:50:03 -050033 std::bind(std::mem_fn(&PassThrough::activeStatusEvent), this,
Chris Caina8857c52021-01-27 11:53:05 -060034 std::placeholders::_1)),
George Liuf3b75142021-06-10 11:22:50 +080035 occCmd(occInstance, path)
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050036{
Vishwanatha Subbanna38b08d72017-04-14 18:12:14 +053037 // Nothing to do.
38}
39
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050040std::vector<int32_t> PassThrough::send(std::vector<int32_t> command)
41{
Gunnar Mills94df8c92018-09-14 14:50:03 -050042 std::vector<int32_t> response{};
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053043
Vishwanatha Subbanna7d700e22017-05-19 19:58:01 +053044 // OCC only understands [bytes] so need array of bytes. Doing this
45 // because rest-server currently treats all int* as 32 bit integer.
Chris Caina8857c52021-01-27 11:53:05 -060046 std::vector<uint8_t> cmdInBytes, rsp;
Vishwanatha Subbanna7d700e22017-05-19 19:58:01 +053047 cmdInBytes.resize(command.size());
48
49 // Populate uint8_t version of vector.
50 std::transform(command.begin(), command.end(), cmdInBytes.begin(),
Gunnar Mills94df8c92018-09-14 14:50:03 -050051 [](decltype(cmdInBytes)::value_type x) { return x; });
Vishwanatha Subbanna7d700e22017-05-19 19:58:01 +053052
Chris Caina8857c52021-01-27 11:53:05 -060053 rsp = send(cmdInBytes);
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053054
Chris Caina8857c52021-01-27 11:53:05 -060055 response.resize(rsp.size());
56 std::transform(rsp.begin(), rsp.end(), response.begin(),
57 [](decltype(response)::value_type x) { return x; });
58
59 return response;
60}
61
62std::vector<uint8_t> PassThrough::send(std::vector<uint8_t> command)
63{
Chris Caina8857c52021-01-27 11:53:05 -060064 std::vector<uint8_t> response{};
65
Chris Caind4c19a02022-04-22 15:46:13 -050066 if (!occActive)
67 {
Chris Cain37abe9b2024-10-31 17:20:31 -050068 lg2::error(
69 "PassThrough::send() - OCC{INST} not active, command not sent",
70 "INST", occInstance);
Chris Caind4c19a02022-04-22 15:46:13 -050071 return response;
72 }
73
Chris Cain358d3962024-08-23 15:29:38 -050074 if (command.size() >= 3)
75 {
76 const uint16_t dataLen = command[1] << 8 | command[2];
77 std::string dataString = "";
78 if (command.size() > 3)
79 {
80 // Trace first 4 bytes of command data
81 size_t index = 3;
82 dataString = "0x";
83 for (; (index < 7) && (index < command.size()); ++index)
84 {
85 dataString += std::format("{:02X}", command[index]);
86 }
87 if (index < command.size())
88 {
89 dataString += "...";
90 }
91 }
Chris Cain37abe9b2024-10-31 17:20:31 -050092 lg2::info(
93 "PassThrough::send() Sending {CMD} command to OCC{INST} (data len={LEN}, data={DATA})",
94 "CMD", lg2::hex, command.front(), "INST", occInstance, "LEN",
95 dataLen, "DATA", dataString);
Chris Cain358d3962024-08-23 15:29:38 -050096 }
97 else
98 {
Chris Cain37abe9b2024-10-31 17:20:31 -050099 lg2::info("PassThrough::send() Sending {CMD} command to OCC{INST}",
100 "CMD", command.front(), "INST", occInstance);
Chris Cain358d3962024-08-23 15:29:38 -0500101 }
Chris Caina8857c52021-01-27 11:53:05 -0600102 CmdStatus status = occCmd.send(command, response);
103 if (status == CmdStatus::SUCCESS)
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +0530104 {
Chris Caina8857c52021-01-27 11:53:05 -0600105 if (response.size() >= 5)
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +0530106 {
Chris Cain37abe9b2024-10-31 17:20:31 -0500107 lg2::debug("PassThrough::send() response had {LEN} bytes", "LEN",
108 response.size());
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +0530109 }
110 else
111 {
Chris Cain37abe9b2024-10-31 17:20:31 -0500112 lg2::error("PassThrough::send() Invalid OCC response");
Chris Caina8857c52021-01-27 11:53:05 -0600113 dump_hex(response);
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +0530114 }
115 }
Chris Caina8857c52021-01-27 11:53:05 -0600116 else
117 {
Chris Cain37abe9b2024-10-31 17:20:31 -0500118 lg2::error(
119 "PassThrough::send(): OCC command failed with status {STATUS}",
120 "STATUS", status);
Chris Caina8857c52021-01-27 11:53:05 -0600121 }
Eddie James4f4712d2018-06-21 15:57:02 -0500122
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +0530123 return response;
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -0500124}
125
Chris Cain36f9cde2021-11-22 11:18:21 -0600126bool PassThrough::setMode(const uint8_t mode, const uint16_t modeData)
127{
Chris Cain36f9cde2021-11-22 11:18:21 -0600128 SysPwrMode newMode = SysPwrMode(mode);
129
Chris Cain30040d92024-06-19 16:50:34 -0500130 if (!pmode)
131 {
Chris Cain37abe9b2024-10-31 17:20:31 -0500132 lg2::error("PassThrough::setMode: PowerMode is not defined!");
Chris Cain30040d92024-06-19 16:50:34 -0500133 return false;
134 }
135
136 if (!pmode->isValidMode(SysPwrMode(mode)))
Chris Cain36f9cde2021-11-22 11:18:21 -0600137 {
Chris Cain37abe9b2024-10-31 17:20:31 -0500138 lg2::error(
139 "PassThrough::setMode() Unsupported mode {MODE} requested ({DATA})",
140 "MODE", newMode, "DATA", modeData);
Chris Cain36f9cde2021-11-22 11:18:21 -0600141 return false;
142 }
143
144 if (((newMode == SysPwrMode::FFO) || (newMode == SysPwrMode::SFP)) &&
145 (modeData == 0))
146 {
Chris Cain37abe9b2024-10-31 17:20:31 -0500147 lg2::error(
148 "PassThrough::setMode() Mode {MODE} requires non-zero frequency point.",
149 "MODE", newMode);
Chris Cain36f9cde2021-11-22 11:18:21 -0600150 return false;
151 }
152
Chris Cain37abe9b2024-10-31 17:20:31 -0500153 lg2::info("PassThrough::setMode() Setting Power Mode {MODE} (data: {DATA})",
154 "MODE", uint8_t(newMode), "DATA", modeData);
Chris Cain36f9cde2021-11-22 11:18:21 -0600155 return pmode->setMode(newMode, modeData);
Chris Cain36f9cde2021-11-22 11:18:21 -0600156}
157
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530158// Called at OCC Status change signal
Patrick Williamsaf408082022-07-22 19:26:54 -0500159void PassThrough::activeStatusEvent(sdbusplus::message_t& msg)
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530160{
161 std::string statusInterface;
Patrick Williamse0962702020-05-13 17:50:22 -0500162 std::map<std::string, std::variant<bool>> msgData;
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530163 msg.read(statusInterface, msgData);
164
165 auto propertyMap = msgData.find("OccActive");
166 if (propertyMap != msgData.end())
167 {
168 // Extract the OccActive property
Patrick Williams305ff8b2020-05-13 11:17:39 -0500169 if (std::get<bool>(propertyMap->second))
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530170 {
Eddie James4f4712d2018-06-21 15:57:02 -0500171 occActive = true;
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530172 }
173 else
174 {
Eddie James4f4712d2018-06-21 15:57:02 -0500175 occActive = false;
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530176 }
177 }
178 return;
179}
180
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -0500181} // namespace occ
182} // namespace open_power