blob: 13907e1e71031790322b7e7f196399c4657ace96 [file] [log] [blame]
Kumar Thangavel41ad4ff2020-06-11 10:31:07 +05301/*
2 * Copyright (c) 2018 Intel Corporation.
3 * Copyright (c) 2018-present Facebook.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#include <ipmid/api.hpp>
19#include <ipmid/api-types.hpp>
20
21#include <commandutils.hpp>
22#include <biccommands.hpp>
23#include <phosphor-logging/log.hpp>
24
25#include <vector>
Kumar Thangavelad049242020-08-31 22:27:33 +053026#include <variant>
Kumar Thangavel41ad4ff2020-06-11 10:31:07 +053027#include <iostream>
28
29namespace ipmi
30{
31
32using namespace phosphor::logging;
33
Patrick Williams58c1ca22021-04-22 12:29:35 -050034#ifdef BIC_ENABLED
Kumar Thangavel41ad4ff2020-06-11 10:31:07 +053035static void registerBICFunctions() __attribute__((constructor));
Patrick Williams58c1ca22021-04-22 12:29:35 -050036#endif
Kumar Thangavel41ad4ff2020-06-11 10:31:07 +053037
38extern message::Response::ptr executeIpmiCommand(message::Request::ptr);
39
Bonnie Lo25b79bf2022-12-16 15:41:48 +080040int sendBicCmd(uint8_t, uint8_t, uint8_t, std::vector<uint8_t>&,
41 std::vector<uint8_t>&);
42
Kumar Thangavel41ad4ff2020-06-11 10:31:07 +053043//----------------------------------------------------------------------
44// ipmiOemBicHandler (IPMI/Section - ) (CMD_OEM_BIC_INFO)
45// This Function will handle BIC request for netfn=0x38 and cmd=1
46// send the response back to the sender.
47//----------------------------------------------------------------------
48
Bonnie Lo25b79bf2022-12-16 15:41:48 +080049ipmi::RspType<IanaType, uint8_t, uint2_t, uint6_t, uint8_t, uint8_t,
50 ipmi::message::Payload>
51 ipmiOemBicHandler(ipmi::Context::ptr ctx, IanaType reqIana,
Kumar Thangavel41ad4ff2020-06-11 10:31:07 +053052 uint8_t interface, uint2_t lun, uint6_t netFnReq,
Patrick Williams485f9b32021-09-03 16:14:47 -050053 uint8_t cmdReq, SecureBuffer data)
Kumar Thangavel41ad4ff2020-06-11 10:31:07 +053054{
55
56 ipmi::message::Response::ptr res;
57
58 // Updating the correct netfn and cmd in the ipmi Context
59 ctx->netFn = ((uint8_t)netFnReq);
60 ctx->cmd = cmdReq;
61
62 // creating ipmi message request for calling executeIpmiCommand function
Patrick Williams485f9b32021-09-03 16:14:47 -050063 auto req = std::make_shared<ipmi::message::Request>(ctx, std::move(data));
Kumar Thangavel41ad4ff2020-06-11 10:31:07 +053064
65 // Calling executeIpmiCommand request function
66 res = ipmi::executeIpmiCommand(req);
67
68 // sending the response with headers and payload
Bonnie Lo25b79bf2022-12-16 15:41:48 +080069 return ipmi::responseSuccess(reqIana, interface, lun, ++netFnReq, cmdReq,
Kumar Thangavel41ad4ff2020-06-11 10:31:07 +053070 res->cc, res->payload);
71}
72
Kumar Thangavelad049242020-08-31 22:27:33 +053073//----------------------------------------------------------------------
74// ipmiOemPostCodeHandler (CMD_OEM_BIC_POST_BUFFER_INFO)
75// This Function will handle BIC incomming postcode from multi-host for
76// netfn=0x38 and cmd=0x08 send the response back to the sender.
77//----------------------------------------------------------------------
78
Bonnie Lo25b79bf2022-12-16 15:41:48 +080079ipmi::RspType<IanaType> ipmiOemPostCodeHandler(ipmi::Context::ptr ctx,
80 IanaType reqIana,
81 uint8_t dataLen,
82 std::vector<uint8_t> data)
Kumar Thangavelad049242020-08-31 22:27:33 +053083{
84 // creating bus connection
85 auto conn = getSdBus();
86
Bonnie Lod8ef7b32022-10-24 16:42:42 +080087 using postcode_t = std::tuple<uint64_t, std::vector<uint8_t>>;
Manojkiran Edac723d6a2021-03-11 14:53:32 +053088
Bonnie Lod8ef7b32022-10-24 16:42:42 +080089 std::string dbusObjStr = dbusObj + std::to_string((ctx->hostIdx + 1));
90
91 for (unsigned int index = 0; index < dataLen; index++)
92 {
93 uint64_t primaryPostCode = static_cast<uint64_t>(data[index]);
Kumar Thangavel0fcfbee2021-04-16 12:38:20 +053094 auto postCode = postcode_t(primaryPostCode, {});
Kumar Thangavelad049242020-08-31 22:27:33 +053095
Bonnie Lod8ef7b32022-10-24 16:42:42 +080096 try
97 {
98 auto method = conn->new_method_call(
99 "xyz.openbmc_project.State.Boot.Raw", dbusObjStr.c_str(),
100 "org.freedesktop.DBus.Properties", "Set");
Kumar Thangavelad049242020-08-31 22:27:33 +0530101
Bonnie Lod8ef7b32022-10-24 16:42:42 +0800102 // Adding paramters to method call
103 method.append(dbusService, "Value",
104 std::variant<postcode_t>(postCode));
Kumar Thangavelad049242020-08-31 22:27:33 +0530105
Bonnie Lod8ef7b32022-10-24 16:42:42 +0800106 // Invoke method call function
107 auto reply = conn->call(method);
108 }
Kumar Thangavelad049242020-08-31 22:27:33 +0530109
Bonnie Lod8ef7b32022-10-24 16:42:42 +0800110 catch (std::exception& e)
111 {
112 phosphor::logging::log<phosphor::logging::level::ERR>(
113 "post code handler error\n");
Kumar Thangavelad049242020-08-31 22:27:33 +0530114
Bonnie Lod8ef7b32022-10-24 16:42:42 +0800115 // sending the Error response
116 return ipmi::responseResponseError();
117 }
Kumar Thangavelad049242020-08-31 22:27:33 +0530118 }
Kumar Thangavelad049242020-08-31 22:27:33 +0530119
Bonnie Lo25b79bf2022-12-16 15:41:48 +0800120 return ipmi::responseSuccess(reqIana);
121}
122
123//----------------------------------------------------------------------
124// ipmiOemGetBicGpioState (CMD_OEM_GET_BIC_GPIO_STATE)
125// This Function will handle BIC GPIO stats for
126// netfn=0x38 and cmd=0x03 send the response back to the sender.
127//----------------------------------------------------------------------
128
129ipmi::RspType<IanaType, std::vector<uint8_t>>
130 ipmiOemGetBicGpioState(ipmi::Context::ptr ctx, std::vector<uint8_t> reqIana)
131{
132 std::vector<uint8_t> respData;
133
134 if (std::equal(reqIana.begin(), reqIana.end(), iana.begin()) == false)
135 {
136 phosphor::logging::log<phosphor::logging::level::ERR>(
137 "Invalid IANA number");
138 return ipmi::responseInvalidFieldRequest();
139 }
140
141 uint8_t bicAddr = (uint8_t)ctx->hostIdx << 2;
142
143 if (sendBicCmd(ctx->netFn, ctx->cmd, bicAddr, reqIana, respData))
144 {
145 return ipmi::responseUnspecifiedError();
146 }
147
148 std::vector<uint8_t> gpioState;
149 IanaType respIana;
150
151 auto r =
152 std::ranges::copy_n(respData.begin(), iana.size(), respIana.begin()).in;
153 std::copy(r, respData.end(), std::back_inserter(gpioState));
154
155 return ipmi::responseSuccess(respIana, gpioState);
Kumar Thangavelad049242020-08-31 22:27:33 +0530156}
157
Bonnie Lo41027b92022-12-16 16:21:08 +0800158//----------------------------------------------------------------------
159// ipmiOemSetHostPowerState (CMD_OEM_SET_HOST_POWER_STATE)
160// This Function will handle BIC incomming IPMI request for
161// setting host current state for netfn=0x38 and cmd=0x0C
162// send the response back to the sender.
163//----------------------------------------------------------------------
164
165ipmi::RspType<IanaType> ipmiOemSetHostPowerState(ipmi::Context::ptr ctx,
166 IanaType reqIana,
167 uint8_t status)
168{
169 std::string targetUnit;
170
171 switch (static_cast<HostPowerState>(status))
172 {
173 case HostPowerState::HOST_POWER_ON:
174 targetUnit = "obmc-host-startmin@.target";
175 break;
176 case HostPowerState::HOST_POWER_OFF:
177 targetUnit = "obmc-host-stop@.target";
178 break;
179 default:
180 phosphor::logging::log<phosphor::logging::level::ERR>(
181 "IPMI ipmiOemHostPowerStatus power status error");
182 return ipmi::responseUnspecifiedError();
183 }
184
185 int mousePos = targetUnit.find('@');
186 targetUnit.insert(mousePos + 1, std::to_string(ctx->hostIdx + 1));
187
188 auto conn = getSdBus();
189 auto method = conn->new_method_call(systemdService, systemdObjPath,
190 systemdInterface, "StartUnit");
191 method.append(targetUnit);
192 method.append("replace");
193
194 try
195 {
196 conn->call_noreply(method);
197 }
198 catch (const sdbusplus::exception::SdBusError& e)
199 {
200 phosphor::logging::log<phosphor::logging::level::ERR>(
201 "IPMI ipmiOemHostPowerStatus Failed in call method",
202 phosphor::logging::entry("ERROR=%s", e.what()));
203 return ipmi::responseUnspecifiedError();
204 }
205
206 return ipmi::responseSuccess(reqIana);
207}
208
Willy Tue39f9392022-06-15 13:24:20 -0700209[[maybe_unused]] static void registerBICFunctions(void)
Kumar Thangavel41ad4ff2020-06-11 10:31:07 +0530210{
211
212 phosphor::logging::log<phosphor::logging::level::INFO>(
213 "Registering BIC commands");
214
215 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnOemFive,
Bonnie Lo25b79bf2022-12-16 15:41:48 +0800216 static_cast<Cmd>(fb_bic_cmds::CMD_OEM_BIC_INFO),
217 ipmi::Privilege::User, ipmiOemBicHandler);
218 ipmi::registerHandler(
219 ipmi::prioOpenBmcBase, ipmi::netFnOemFive,
220 static_cast<Cmd>(fb_bic_cmds::CMD_OEM_SEND_POST_BUFFER_TO_BMC),
221 ipmi::Privilege::User, ipmiOemPostCodeHandler);
222 ipmi::registerHandler(
223 ipmi::prioOemBase, ipmi::netFnOemFive,
224 static_cast<Cmd>(fb_bic_cmds::CMD_OEM_GET_BIC_GPIO_STATE),
225 ipmi::Privilege::User, ipmiOemGetBicGpioState);
Bonnie Lo41027b92022-12-16 16:21:08 +0800226 ipmi::registerHandler(
227 ipmi::prioOpenBmcBase, ipmi::netFnOemFive,
228 static_cast<Cmd>(fb_bic_cmds::CMD_OEM_SET_HOST_POWER_STATE),
229 ipmi::Privilege::User, ipmiOemSetHostPowerState);
Kumar Thangavel41ad4ff2020-06-11 10:31:07 +0530230 return;
231}
232
233} // namespace ipmi