xref: /openbmc/fb-ipmi-oem/src/oemcommands.cpp (revision e7d23d0ed77ffc40529d20ae7faf96aff4d00b30)
1*e7d23d0eSVijay Khemka /*
2*e7d23d0eSVijay Khemka  * Copyright (c)  2018 Intel Corporation.
3*e7d23d0eSVijay Khemka  * Copyright (c)  2018-present Facebook.
4*e7d23d0eSVijay Khemka  *
5*e7d23d0eSVijay Khemka  * Licensed under the Apache License, Version 2.0 (the "License");
6*e7d23d0eSVijay Khemka  * you may not use this file except in compliance with the License.
7*e7d23d0eSVijay Khemka  * You may obtain a copy of the License at
8*e7d23d0eSVijay Khemka  *
9*e7d23d0eSVijay Khemka  *      http://www.apache.org/licenses/LICENSE-2.0
10*e7d23d0eSVijay Khemka  *
11*e7d23d0eSVijay Khemka  * Unless required by applicable law or agreed to in writing, software
12*e7d23d0eSVijay Khemka  * distributed under the License is distributed on an "AS IS" BASIS,
13*e7d23d0eSVijay Khemka  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*e7d23d0eSVijay Khemka  * See the License for the specific language governing permissions and
15*e7d23d0eSVijay Khemka  * limitations under the License.
16*e7d23d0eSVijay Khemka  */
17*e7d23d0eSVijay Khemka 
18*e7d23d0eSVijay Khemka #include "xyz/openbmc_project/Common/error.hpp"
19*e7d23d0eSVijay Khemka #include <ipmid/api.h>
20*e7d23d0eSVijay Khemka 
21*e7d23d0eSVijay Khemka #include <array>
22*e7d23d0eSVijay Khemka #include <commandutils.hpp>
23*e7d23d0eSVijay Khemka #include <cstring>
24*e7d23d0eSVijay Khemka #include <iostream>
25*e7d23d0eSVijay Khemka #include <oemcommands.hpp>
26*e7d23d0eSVijay Khemka #include <phosphor-ipmi-host/utils.hpp>
27*e7d23d0eSVijay Khemka #include <phosphor-logging/log.hpp>
28*e7d23d0eSVijay Khemka #include <sdbusplus/bus.hpp>
29*e7d23d0eSVijay Khemka #include <string>
30*e7d23d0eSVijay Khemka #include <vector>
31*e7d23d0eSVijay Khemka 
32*e7d23d0eSVijay Khemka #define SIZE_IANA_ID 3
33*e7d23d0eSVijay Khemka 
34*e7d23d0eSVijay Khemka namespace ipmi
35*e7d23d0eSVijay Khemka {
36*e7d23d0eSVijay Khemka static void registerOEMFunctions() __attribute__((constructor));
37*e7d23d0eSVijay Khemka sdbusplus::bus::bus dbus(ipmid_get_sd_bus_connection()); // from ipmid/api.h
38*e7d23d0eSVijay Khemka static constexpr size_t maxFRUStringLength = 0x3F;
39*e7d23d0eSVijay Khemka 
40*e7d23d0eSVijay Khemka ipmi_ret_t plat_udbg_get_post_desc(uint8_t, uint8_t *, uint8_t, uint8_t *,
41*e7d23d0eSVijay Khemka                                    uint8_t *, uint8_t *);
42*e7d23d0eSVijay Khemka ipmi_ret_t plat_udbg_get_frame_data(uint8_t, uint8_t, uint8_t *, uint8_t *,
43*e7d23d0eSVijay Khemka                                     uint8_t *);
44*e7d23d0eSVijay Khemka ipmi_ret_t plat_udbg_control_panel(uint8_t, uint8_t, uint8_t, uint8_t *,
45*e7d23d0eSVijay Khemka                                    uint8_t *);
46*e7d23d0eSVijay Khemka 
47*e7d23d0eSVijay Khemka // return code: 0 successful
48*e7d23d0eSVijay Khemka int8_t getFruData(std::string &data, std::string &name)
49*e7d23d0eSVijay Khemka {
50*e7d23d0eSVijay Khemka     std::string objpath = "/xyz/openbmc_project/FruDevice";
51*e7d23d0eSVijay Khemka     std::string intf = "xyz.openbmc_project.FruDeviceManager";
52*e7d23d0eSVijay Khemka     std::string service = getService(dbus, intf, objpath);
53*e7d23d0eSVijay Khemka     ObjectValueTree valueTree = getManagedObjects(dbus, service, "/");
54*e7d23d0eSVijay Khemka     if (valueTree.empty())
55*e7d23d0eSVijay Khemka     {
56*e7d23d0eSVijay Khemka         phosphor::logging::log<phosphor::logging::level::ERR>(
57*e7d23d0eSVijay Khemka             "No object implements interface",
58*e7d23d0eSVijay Khemka             phosphor::logging::entry("INTF=%s", intf.c_str()));
59*e7d23d0eSVijay Khemka         return -1;
60*e7d23d0eSVijay Khemka     }
61*e7d23d0eSVijay Khemka 
62*e7d23d0eSVijay Khemka     for (const auto &item : valueTree)
63*e7d23d0eSVijay Khemka     {
64*e7d23d0eSVijay Khemka         auto interface = item.second.find("xyz.openbmc_project.FruDevice");
65*e7d23d0eSVijay Khemka         if (interface == item.second.end())
66*e7d23d0eSVijay Khemka         {
67*e7d23d0eSVijay Khemka             continue;
68*e7d23d0eSVijay Khemka         }
69*e7d23d0eSVijay Khemka 
70*e7d23d0eSVijay Khemka         auto property = interface->second.find(name.c_str());
71*e7d23d0eSVijay Khemka         if (property == interface->second.end())
72*e7d23d0eSVijay Khemka         {
73*e7d23d0eSVijay Khemka             continue;
74*e7d23d0eSVijay Khemka         }
75*e7d23d0eSVijay Khemka 
76*e7d23d0eSVijay Khemka         try
77*e7d23d0eSVijay Khemka         {
78*e7d23d0eSVijay Khemka             Value variant = property->second;
79*e7d23d0eSVijay Khemka             std::string &result =
80*e7d23d0eSVijay Khemka                 sdbusplus::message::variant_ns::get<std::string>(variant);
81*e7d23d0eSVijay Khemka             if (result.size() > maxFRUStringLength)
82*e7d23d0eSVijay Khemka             {
83*e7d23d0eSVijay Khemka                 phosphor::logging::log<phosphor::logging::level::ERR>(
84*e7d23d0eSVijay Khemka                     "FRU serial number exceed maximum length");
85*e7d23d0eSVijay Khemka                 return -1;
86*e7d23d0eSVijay Khemka             }
87*e7d23d0eSVijay Khemka             data = result;
88*e7d23d0eSVijay Khemka             return 0;
89*e7d23d0eSVijay Khemka         }
90*e7d23d0eSVijay Khemka         catch (sdbusplus::message::variant_ns::bad_variant_access &e)
91*e7d23d0eSVijay Khemka         {
92*e7d23d0eSVijay Khemka             phosphor::logging::log<phosphor::logging::level::ERR>(e.what());
93*e7d23d0eSVijay Khemka             return -1;
94*e7d23d0eSVijay Khemka         }
95*e7d23d0eSVijay Khemka     }
96*e7d23d0eSVijay Khemka     return -1;
97*e7d23d0eSVijay Khemka }
98*e7d23d0eSVijay Khemka 
99*e7d23d0eSVijay Khemka typedef struct
100*e7d23d0eSVijay Khemka {
101*e7d23d0eSVijay Khemka     uint8_t cur_power_state;
102*e7d23d0eSVijay Khemka     uint8_t last_power_event;
103*e7d23d0eSVijay Khemka     uint8_t misc_power_state;
104*e7d23d0eSVijay Khemka     uint8_t front_panel_button_cap_status;
105*e7d23d0eSVijay Khemka } ipmi_get_chassis_status_t;
106*e7d23d0eSVijay Khemka 
107*e7d23d0eSVijay Khemka // Todo: Needs to update this as per power policy when integrated
108*e7d23d0eSVijay Khemka //----------------------------------------------------------------------
109*e7d23d0eSVijay Khemka // Get Chassis Status commands
110*e7d23d0eSVijay Khemka //----------------------------------------------------------------------
111*e7d23d0eSVijay Khemka ipmi_ret_t ipmiGetChassisStatus(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
112*e7d23d0eSVijay Khemka                                 ipmi_request_t request,
113*e7d23d0eSVijay Khemka                                 ipmi_response_t response,
114*e7d23d0eSVijay Khemka                                 ipmi_data_len_t data_len,
115*e7d23d0eSVijay Khemka                                 ipmi_context_t context)
116*e7d23d0eSVijay Khemka {
117*e7d23d0eSVijay Khemka     ipmi_get_chassis_status_t chassis_status;
118*e7d23d0eSVijay Khemka     uint8_t s = 2;
119*e7d23d0eSVijay Khemka 
120*e7d23d0eSVijay Khemka     *data_len = 4;
121*e7d23d0eSVijay Khemka 
122*e7d23d0eSVijay Khemka     // Current Power State
123*e7d23d0eSVijay Khemka     // [7] reserved
124*e7d23d0eSVijay Khemka     // [6..5] power restore policy
125*e7d23d0eSVijay Khemka     //          00b = chassis stays powered off after AC/mains returns
126*e7d23d0eSVijay Khemka     //          01b = after AC returns, power is restored to the state that was
127*e7d23d0eSVijay Khemka     //          in effect when AC/mains was lost.
128*e7d23d0eSVijay Khemka     //          10b = chassis always powers up after AC/mains returns
129*e7d23d0eSVijay Khemka     //          11b = unknow
130*e7d23d0eSVijay Khemka     //        Set to 00b, by observing the hardware behavior.
131*e7d23d0eSVijay Khemka     //        Do we need to define a dbus property to identify the restore
132*e7d23d0eSVijay Khemka     //        policy?
133*e7d23d0eSVijay Khemka 
134*e7d23d0eSVijay Khemka     // [4] power control fault
135*e7d23d0eSVijay Khemka     //       1b = controller attempted to turn system power on or off, but
136*e7d23d0eSVijay Khemka     //       system did not enter desired state.
137*e7d23d0eSVijay Khemka     //       Set to 0b, since We don't support it..
138*e7d23d0eSVijay Khemka 
139*e7d23d0eSVijay Khemka     // [3] power fault
140*e7d23d0eSVijay Khemka     //       1b = fault detected in main power subsystem.
141*e7d23d0eSVijay Khemka     //       set to 0b. for we don't support it.
142*e7d23d0eSVijay Khemka 
143*e7d23d0eSVijay Khemka     // [2] 1b = interlock (chassis is presently shut down because a chassis
144*e7d23d0eSVijay Khemka     //       panel interlock switch is active). (IPMI 1.5)
145*e7d23d0eSVijay Khemka     //       set to 0b,  for we don't support it.
146*e7d23d0eSVijay Khemka 
147*e7d23d0eSVijay Khemka     // [1] power overload
148*e7d23d0eSVijay Khemka     //      1b = system shutdown because of power overload condition.
149*e7d23d0eSVijay Khemka     //       set to 0b,  for we don't support it.
150*e7d23d0eSVijay Khemka 
151*e7d23d0eSVijay Khemka     // [0] power is on
152*e7d23d0eSVijay Khemka     //       1b = system power is on
153*e7d23d0eSVijay Khemka     //       0b = system power is off(soft-off S4/S5, or mechanical off)
154*e7d23d0eSVijay Khemka 
155*e7d23d0eSVijay Khemka     chassis_status.cur_power_state = ((s & 0x3) << 5) | (1 & 0x1);
156*e7d23d0eSVijay Khemka 
157*e7d23d0eSVijay Khemka     // Last Power Event
158*e7d23d0eSVijay Khemka     // [7..5] – reserved
159*e7d23d0eSVijay Khemka     // [4] – 1b = last ‘Power is on’ state was entered via IPMI command
160*e7d23d0eSVijay Khemka     // [3] – 1b = last power down caused by power fault
161*e7d23d0eSVijay Khemka     // [2] – 1b = last power down caused by a power interlock being activated
162*e7d23d0eSVijay Khemka     // [1] – 1b = last power down caused by a Power overload
163*e7d23d0eSVijay Khemka     // [0] – 1b = AC failed
164*e7d23d0eSVijay Khemka     // set to 0x0,  for we don't support these fields.
165*e7d23d0eSVijay Khemka 
166*e7d23d0eSVijay Khemka     chassis_status.last_power_event = 0;
167*e7d23d0eSVijay Khemka 
168*e7d23d0eSVijay Khemka     // Misc. Chassis State
169*e7d23d0eSVijay Khemka     // [7] – reserved
170*e7d23d0eSVijay Khemka     // [6] – 1b = Chassis Identify command and state info supported (Optional)
171*e7d23d0eSVijay Khemka     //       0b = Chassis Identify command support unspecified via this command.
172*e7d23d0eSVijay Khemka     //       (The Get Command Support command , if implemented, would still
173*e7d23d0eSVijay Khemka     //       indicate support for the Chassis Identify command)
174*e7d23d0eSVijay Khemka     // [5..4] – Chassis Identify State. Mandatory when bit[6] =1b, reserved
175*e7d23d0eSVijay Khemka     // (return
176*e7d23d0eSVijay Khemka     //          as 00b) otherwise. Returns the present chassis identify state.
177*e7d23d0eSVijay Khemka     //           Refer to the Chassis Identify command for more info.
178*e7d23d0eSVijay Khemka     //         00b = chassis identify state = Off
179*e7d23d0eSVijay Khemka     //         01b = chassis identify state = Temporary(timed) On
180*e7d23d0eSVijay Khemka     //         10b = chassis identify state = Indefinite On
181*e7d23d0eSVijay Khemka     //         11b = reserved
182*e7d23d0eSVijay Khemka     // [3] – 1b = Cooling/fan fault detected
183*e7d23d0eSVijay Khemka     // [2] – 1b = Drive Fault
184*e7d23d0eSVijay Khemka     // [1] – 1b = Front Panel Lockout active (power off and reset via chassis
185*e7d23d0eSVijay Khemka     //       push-buttons disabled.)
186*e7d23d0eSVijay Khemka     // [0] – 1b = Chassis Intrusion active
187*e7d23d0eSVijay Khemka     //  set to 0,  for we don't support them.
188*e7d23d0eSVijay Khemka     chassis_status.misc_power_state = 0x40;
189*e7d23d0eSVijay Khemka 
190*e7d23d0eSVijay Khemka     //  Front Panel Button Capabilities and disable/enable status(Optional)
191*e7d23d0eSVijay Khemka     //  set to 0,  for we don't support them.
192*e7d23d0eSVijay Khemka     chassis_status.front_panel_button_cap_status = 0;
193*e7d23d0eSVijay Khemka 
194*e7d23d0eSVijay Khemka     // Pack the actual response
195*e7d23d0eSVijay Khemka     std::memcpy(response, &chassis_status, *data_len);
196*e7d23d0eSVijay Khemka 
197*e7d23d0eSVijay Khemka     return IPMI_CC_OK;
198*e7d23d0eSVijay Khemka }
199*e7d23d0eSVijay Khemka 
200*e7d23d0eSVijay Khemka //----------------------------------------------------------------------
201*e7d23d0eSVijay Khemka // Get Debug Frame Info
202*e7d23d0eSVijay Khemka //----------------------------------------------------------------------
203*e7d23d0eSVijay Khemka ipmi_ret_t ipmiOemDbgGetFrameInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
204*e7d23d0eSVijay Khemka                                   ipmi_request_t request,
205*e7d23d0eSVijay Khemka                                   ipmi_response_t response,
206*e7d23d0eSVijay Khemka                                   ipmi_data_len_t data_len,
207*e7d23d0eSVijay Khemka                                   ipmi_context_t context)
208*e7d23d0eSVijay Khemka {
209*e7d23d0eSVijay Khemka     uint8_t *req = reinterpret_cast<uint8_t *>(request);
210*e7d23d0eSVijay Khemka     uint8_t *res = reinterpret_cast<uint8_t *>(response);
211*e7d23d0eSVijay Khemka     uint8_t num_frames = 3;
212*e7d23d0eSVijay Khemka 
213*e7d23d0eSVijay Khemka     std::memcpy(res, req, SIZE_IANA_ID); // IANA ID
214*e7d23d0eSVijay Khemka     res[SIZE_IANA_ID] = num_frames;
215*e7d23d0eSVijay Khemka     *data_len = SIZE_IANA_ID + 1;
216*e7d23d0eSVijay Khemka 
217*e7d23d0eSVijay Khemka     return IPMI_CC_OK;
218*e7d23d0eSVijay Khemka }
219*e7d23d0eSVijay Khemka 
220*e7d23d0eSVijay Khemka //----------------------------------------------------------------------
221*e7d23d0eSVijay Khemka // Get Debug Updated Frames
222*e7d23d0eSVijay Khemka //----------------------------------------------------------------------
223*e7d23d0eSVijay Khemka ipmi_ret_t ipmiOemDbgGetUpdFrames(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
224*e7d23d0eSVijay Khemka                                   ipmi_request_t request,
225*e7d23d0eSVijay Khemka                                   ipmi_response_t response,
226*e7d23d0eSVijay Khemka                                   ipmi_data_len_t data_len,
227*e7d23d0eSVijay Khemka                                   ipmi_context_t context)
228*e7d23d0eSVijay Khemka {
229*e7d23d0eSVijay Khemka     uint8_t *req = reinterpret_cast<uint8_t *>(request);
230*e7d23d0eSVijay Khemka     uint8_t *res = reinterpret_cast<uint8_t *>(response);
231*e7d23d0eSVijay Khemka     uint8_t num_updates = 3;
232*e7d23d0eSVijay Khemka     *data_len = 4;
233*e7d23d0eSVijay Khemka 
234*e7d23d0eSVijay Khemka     std::memcpy(res, req, SIZE_IANA_ID); // IANA ID
235*e7d23d0eSVijay Khemka     res[SIZE_IANA_ID] = num_updates;
236*e7d23d0eSVijay Khemka     *data_len = SIZE_IANA_ID + num_updates + 1;
237*e7d23d0eSVijay Khemka     res[SIZE_IANA_ID + 1] = 1; // info page update
238*e7d23d0eSVijay Khemka     res[SIZE_IANA_ID + 2] = 2; // cri sel update
239*e7d23d0eSVijay Khemka     res[SIZE_IANA_ID + 3] = 3; // cri sensor update
240*e7d23d0eSVijay Khemka 
241*e7d23d0eSVijay Khemka     return IPMI_CC_OK;
242*e7d23d0eSVijay Khemka }
243*e7d23d0eSVijay Khemka 
244*e7d23d0eSVijay Khemka //----------------------------------------------------------------------
245*e7d23d0eSVijay Khemka // Get Debug POST Description
246*e7d23d0eSVijay Khemka //----------------------------------------------------------------------
247*e7d23d0eSVijay Khemka ipmi_ret_t ipmiOemDbgGetPostDesc(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
248*e7d23d0eSVijay Khemka                                  ipmi_request_t request,
249*e7d23d0eSVijay Khemka                                  ipmi_response_t response,
250*e7d23d0eSVijay Khemka                                  ipmi_data_len_t data_len,
251*e7d23d0eSVijay Khemka                                  ipmi_context_t context)
252*e7d23d0eSVijay Khemka {
253*e7d23d0eSVijay Khemka     uint8_t *req = reinterpret_cast<uint8_t *>(request);
254*e7d23d0eSVijay Khemka     uint8_t *res = reinterpret_cast<uint8_t *>(response);
255*e7d23d0eSVijay Khemka     uint8_t index = 0;
256*e7d23d0eSVijay Khemka     uint8_t next = 0;
257*e7d23d0eSVijay Khemka     uint8_t end = 0;
258*e7d23d0eSVijay Khemka     uint8_t phase = 0;
259*e7d23d0eSVijay Khemka     uint8_t count = 0;
260*e7d23d0eSVijay Khemka     int ret;
261*e7d23d0eSVijay Khemka 
262*e7d23d0eSVijay Khemka     index = req[3];
263*e7d23d0eSVijay Khemka     phase = req[4];
264*e7d23d0eSVijay Khemka 
265*e7d23d0eSVijay Khemka     phosphor::logging::log<phosphor::logging::level::INFO>(
266*e7d23d0eSVijay Khemka         "Get POST Description Event");
267*e7d23d0eSVijay Khemka 
268*e7d23d0eSVijay Khemka     ret = plat_udbg_get_post_desc(index, &next, phase, &end, &count, &res[8]);
269*e7d23d0eSVijay Khemka     if (ret)
270*e7d23d0eSVijay Khemka     {
271*e7d23d0eSVijay Khemka         memcpy(res, req, SIZE_IANA_ID); // IANA ID
272*e7d23d0eSVijay Khemka         *data_len = SIZE_IANA_ID;
273*e7d23d0eSVijay Khemka         return IPMI_CC_UNSPECIFIED_ERROR;
274*e7d23d0eSVijay Khemka     }
275*e7d23d0eSVijay Khemka 
276*e7d23d0eSVijay Khemka     memcpy(res, req, SIZE_IANA_ID); // IANA ID
277*e7d23d0eSVijay Khemka     res[3] = index;
278*e7d23d0eSVijay Khemka     res[4] = next;
279*e7d23d0eSVijay Khemka     res[5] = phase;
280*e7d23d0eSVijay Khemka     res[6] = end;
281*e7d23d0eSVijay Khemka     res[7] = count;
282*e7d23d0eSVijay Khemka     *data_len = SIZE_IANA_ID + 5 + count;
283*e7d23d0eSVijay Khemka 
284*e7d23d0eSVijay Khemka     return IPMI_CC_OK;
285*e7d23d0eSVijay Khemka }
286*e7d23d0eSVijay Khemka 
287*e7d23d0eSVijay Khemka //----------------------------------------------------------------------
288*e7d23d0eSVijay Khemka // Get Debug GPIO Description
289*e7d23d0eSVijay Khemka //----------------------------------------------------------------------
290*e7d23d0eSVijay Khemka ipmi_ret_t ipmiOemDbgGetGpioDesc(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
291*e7d23d0eSVijay Khemka                                  ipmi_request_t request,
292*e7d23d0eSVijay Khemka                                  ipmi_response_t response,
293*e7d23d0eSVijay Khemka                                  ipmi_data_len_t data_len,
294*e7d23d0eSVijay Khemka                                  ipmi_context_t context)
295*e7d23d0eSVijay Khemka {
296*e7d23d0eSVijay Khemka     uint8_t *req = reinterpret_cast<uint8_t *>(request);
297*e7d23d0eSVijay Khemka     uint8_t *res = reinterpret_cast<uint8_t *>(response);
298*e7d23d0eSVijay Khemka 
299*e7d23d0eSVijay Khemka     phosphor::logging::log<phosphor::logging::level::INFO>(
300*e7d23d0eSVijay Khemka         "Get GPIO Description Event");
301*e7d23d0eSVijay Khemka 
302*e7d23d0eSVijay Khemka     std::memcpy(res, req, SIZE_IANA_ID + 1); // IANA ID
303*e7d23d0eSVijay Khemka     *data_len = SIZE_IANA_ID + 1;
304*e7d23d0eSVijay Khemka 
305*e7d23d0eSVijay Khemka     return IPMI_CC_OK;
306*e7d23d0eSVijay Khemka }
307*e7d23d0eSVijay Khemka 
308*e7d23d0eSVijay Khemka //----------------------------------------------------------------------
309*e7d23d0eSVijay Khemka // Get Debug Frame Data
310*e7d23d0eSVijay Khemka //----------------------------------------------------------------------
311*e7d23d0eSVijay Khemka ipmi_ret_t ipmiOemDbgGetFrameData(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
312*e7d23d0eSVijay Khemka                                   ipmi_request_t request,
313*e7d23d0eSVijay Khemka                                   ipmi_response_t response,
314*e7d23d0eSVijay Khemka                                   ipmi_data_len_t data_len,
315*e7d23d0eSVijay Khemka                                   ipmi_context_t context)
316*e7d23d0eSVijay Khemka {
317*e7d23d0eSVijay Khemka     uint8_t *req = reinterpret_cast<uint8_t *>(request);
318*e7d23d0eSVijay Khemka     uint8_t *res = reinterpret_cast<uint8_t *>(response);
319*e7d23d0eSVijay Khemka     uint8_t frame;
320*e7d23d0eSVijay Khemka     uint8_t page;
321*e7d23d0eSVijay Khemka     uint8_t next;
322*e7d23d0eSVijay Khemka     uint8_t count;
323*e7d23d0eSVijay Khemka     int ret;
324*e7d23d0eSVijay Khemka 
325*e7d23d0eSVijay Khemka     frame = req[3];
326*e7d23d0eSVijay Khemka     page = req[4];
327*e7d23d0eSVijay Khemka     int fr = frame;
328*e7d23d0eSVijay Khemka     int pg = page;
329*e7d23d0eSVijay Khemka 
330*e7d23d0eSVijay Khemka     ret = plat_udbg_get_frame_data(frame, page, &next, &count, &res[7]);
331*e7d23d0eSVijay Khemka     if (ret)
332*e7d23d0eSVijay Khemka     {
333*e7d23d0eSVijay Khemka         memcpy(res, req, SIZE_IANA_ID); // IANA ID
334*e7d23d0eSVijay Khemka         *data_len = SIZE_IANA_ID;
335*e7d23d0eSVijay Khemka         return IPMI_CC_UNSPECIFIED_ERROR;
336*e7d23d0eSVijay Khemka     }
337*e7d23d0eSVijay Khemka 
338*e7d23d0eSVijay Khemka     memcpy(res, req, SIZE_IANA_ID); // IANA ID
339*e7d23d0eSVijay Khemka     res[3] = frame;
340*e7d23d0eSVijay Khemka     res[4] = page;
341*e7d23d0eSVijay Khemka     res[5] = next;
342*e7d23d0eSVijay Khemka     res[6] = count;
343*e7d23d0eSVijay Khemka     *data_len = SIZE_IANA_ID + 4 + count;
344*e7d23d0eSVijay Khemka 
345*e7d23d0eSVijay Khemka     return IPMI_CC_OK;
346*e7d23d0eSVijay Khemka }
347*e7d23d0eSVijay Khemka 
348*e7d23d0eSVijay Khemka //----------------------------------------------------------------------
349*e7d23d0eSVijay Khemka // Get Debug Control Panel
350*e7d23d0eSVijay Khemka //----------------------------------------------------------------------
351*e7d23d0eSVijay Khemka ipmi_ret_t ipmiOemDbgGetCtrlPanel(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
352*e7d23d0eSVijay Khemka                                   ipmi_request_t request,
353*e7d23d0eSVijay Khemka                                   ipmi_response_t response,
354*e7d23d0eSVijay Khemka                                   ipmi_data_len_t data_len,
355*e7d23d0eSVijay Khemka                                   ipmi_context_t context)
356*e7d23d0eSVijay Khemka {
357*e7d23d0eSVijay Khemka     uint8_t *req = reinterpret_cast<uint8_t *>(request);
358*e7d23d0eSVijay Khemka     uint8_t *res = reinterpret_cast<uint8_t *>(response);
359*e7d23d0eSVijay Khemka 
360*e7d23d0eSVijay Khemka     uint8_t panel;
361*e7d23d0eSVijay Khemka     uint8_t operation;
362*e7d23d0eSVijay Khemka     uint8_t item;
363*e7d23d0eSVijay Khemka     uint8_t count;
364*e7d23d0eSVijay Khemka     ipmi_ret_t ret;
365*e7d23d0eSVijay Khemka 
366*e7d23d0eSVijay Khemka     panel = req[3];
367*e7d23d0eSVijay Khemka     operation = req[4];
368*e7d23d0eSVijay Khemka     item = req[5];
369*e7d23d0eSVijay Khemka 
370*e7d23d0eSVijay Khemka     ret = plat_udbg_control_panel(panel, operation, item, &count, &res[3]);
371*e7d23d0eSVijay Khemka 
372*e7d23d0eSVijay Khemka     std::memcpy(res, req, SIZE_IANA_ID); // IANA ID
373*e7d23d0eSVijay Khemka     *data_len = SIZE_IANA_ID + count;
374*e7d23d0eSVijay Khemka 
375*e7d23d0eSVijay Khemka     return ret;
376*e7d23d0eSVijay Khemka }
377*e7d23d0eSVijay Khemka 
378*e7d23d0eSVijay Khemka // Todo: Need to implement all below functions for oem commands
379*e7d23d0eSVijay Khemka //----------------------------------------------------------------------
380*e7d23d0eSVijay Khemka // Set Dimm Info (CMD_OEM_SET_DIMM_INFO)
381*e7d23d0eSVijay Khemka //----------------------------------------------------------------------
382*e7d23d0eSVijay Khemka ipmi_ret_t ipmiOemSetDimmInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
383*e7d23d0eSVijay Khemka                               ipmi_request_t request, ipmi_response_t response,
384*e7d23d0eSVijay Khemka                               ipmi_data_len_t data_len, ipmi_context_t context)
385*e7d23d0eSVijay Khemka {
386*e7d23d0eSVijay Khemka     uint8_t *req = reinterpret_cast<uint8_t *>(request);
387*e7d23d0eSVijay Khemka     uint8_t *res = reinterpret_cast<uint8_t *>(response);
388*e7d23d0eSVijay Khemka 
389*e7d23d0eSVijay Khemka     std::memcpy(res, req, SIZE_IANA_ID + 1); // IANA ID
390*e7d23d0eSVijay Khemka     *data_len = SIZE_IANA_ID + 1;
391*e7d23d0eSVijay Khemka     *data_len = 0;
392*e7d23d0eSVijay Khemka 
393*e7d23d0eSVijay Khemka     return IPMI_CC_OK;
394*e7d23d0eSVijay Khemka }
395*e7d23d0eSVijay Khemka 
396*e7d23d0eSVijay Khemka //----------------------------------------------------------------------
397*e7d23d0eSVijay Khemka // Get Boot Order (CMD_OEM_GET_BOOT_ORDER)
398*e7d23d0eSVijay Khemka //----------------------------------------------------------------------
399*e7d23d0eSVijay Khemka ipmi_ret_t ipmiOemGetBootOrder(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
400*e7d23d0eSVijay Khemka                                ipmi_request_t request, ipmi_response_t response,
401*e7d23d0eSVijay Khemka                                ipmi_data_len_t data_len, ipmi_context_t context)
402*e7d23d0eSVijay Khemka {
403*e7d23d0eSVijay Khemka     uint8_t *req = reinterpret_cast<uint8_t *>(request);
404*e7d23d0eSVijay Khemka     uint8_t *res = reinterpret_cast<uint8_t *>(response);
405*e7d23d0eSVijay Khemka 
406*e7d23d0eSVijay Khemka     *res++ = 0x01;
407*e7d23d0eSVijay Khemka     *res++ = 0x00;
408*e7d23d0eSVijay Khemka     *res++ = 0x09;
409*e7d23d0eSVijay Khemka     *res++ = 0x02;
410*e7d23d0eSVijay Khemka     *res++ = 0x03;
411*e7d23d0eSVijay Khemka     *res++ = 0xff;
412*e7d23d0eSVijay Khemka     *data_len = 6;
413*e7d23d0eSVijay Khemka 
414*e7d23d0eSVijay Khemka     return IPMI_CC_OK;
415*e7d23d0eSVijay Khemka }
416*e7d23d0eSVijay Khemka 
417*e7d23d0eSVijay Khemka //----------------------------------------------------------------------
418*e7d23d0eSVijay Khemka // Set Machine Config Info (CMD_OEM_SET_MACHINE_CONFIG_INFO)
419*e7d23d0eSVijay Khemka //----------------------------------------------------------------------
420*e7d23d0eSVijay Khemka ipmi_ret_t ipmiOemSetMachineCfgInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
421*e7d23d0eSVijay Khemka                                     ipmi_request_t request,
422*e7d23d0eSVijay Khemka                                     ipmi_response_t response,
423*e7d23d0eSVijay Khemka                                     ipmi_data_len_t data_len,
424*e7d23d0eSVijay Khemka                                     ipmi_context_t context)
425*e7d23d0eSVijay Khemka {
426*e7d23d0eSVijay Khemka     uint8_t *req = reinterpret_cast<uint8_t *>(request);
427*e7d23d0eSVijay Khemka     uint8_t *res = reinterpret_cast<uint8_t *>(response);
428*e7d23d0eSVijay Khemka 
429*e7d23d0eSVijay Khemka     *data_len = 0;
430*e7d23d0eSVijay Khemka 
431*e7d23d0eSVijay Khemka     return IPMI_CC_OK;
432*e7d23d0eSVijay Khemka }
433*e7d23d0eSVijay Khemka 
434*e7d23d0eSVijay Khemka //----------------------------------------------------------------------
435*e7d23d0eSVijay Khemka // Set POST start (CMD_OEM_SET_POST_START)
436*e7d23d0eSVijay Khemka //----------------------------------------------------------------------
437*e7d23d0eSVijay Khemka ipmi_ret_t ipmiOemSetPostStart(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
438*e7d23d0eSVijay Khemka                                ipmi_request_t request, ipmi_response_t response,
439*e7d23d0eSVijay Khemka                                ipmi_data_len_t data_len, ipmi_context_t context)
440*e7d23d0eSVijay Khemka {
441*e7d23d0eSVijay Khemka     uint8_t *req = reinterpret_cast<uint8_t *>(request);
442*e7d23d0eSVijay Khemka     uint8_t *res = reinterpret_cast<uint8_t *>(response);
443*e7d23d0eSVijay Khemka 
444*e7d23d0eSVijay Khemka     phosphor::logging::log<phosphor::logging::level::INFO>("POST Start Event");
445*e7d23d0eSVijay Khemka 
446*e7d23d0eSVijay Khemka     *data_len = 0;
447*e7d23d0eSVijay Khemka     return IPMI_CC_OK;
448*e7d23d0eSVijay Khemka }
449*e7d23d0eSVijay Khemka 
450*e7d23d0eSVijay Khemka //----------------------------------------------------------------------
451*e7d23d0eSVijay Khemka // Set POST End (CMD_OEM_SET_POST_END)
452*e7d23d0eSVijay Khemka //----------------------------------------------------------------------
453*e7d23d0eSVijay Khemka ipmi_ret_t ipmiOemSetPostEnd(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
454*e7d23d0eSVijay Khemka                              ipmi_request_t request, ipmi_response_t response,
455*e7d23d0eSVijay Khemka                              ipmi_data_len_t data_len, ipmi_context_t context)
456*e7d23d0eSVijay Khemka {
457*e7d23d0eSVijay Khemka     uint8_t *req = reinterpret_cast<uint8_t *>(request);
458*e7d23d0eSVijay Khemka     uint8_t *res = reinterpret_cast<uint8_t *>(response);
459*e7d23d0eSVijay Khemka 
460*e7d23d0eSVijay Khemka     phosphor::logging::log<phosphor::logging::level::INFO>("POST End Event");
461*e7d23d0eSVijay Khemka 
462*e7d23d0eSVijay Khemka     *data_len = 0;
463*e7d23d0eSVijay Khemka     return IPMI_CC_OK;
464*e7d23d0eSVijay Khemka }
465*e7d23d0eSVijay Khemka 
466*e7d23d0eSVijay Khemka //----------------------------------------------------------------------
467*e7d23d0eSVijay Khemka // Set Bios Flash Info (CMD_OEM_SET_BIOS_FLASH_INFO)
468*e7d23d0eSVijay Khemka //----------------------------------------------------------------------
469*e7d23d0eSVijay Khemka ipmi_ret_t ipmiOemSetBiosFlashInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
470*e7d23d0eSVijay Khemka                                    ipmi_request_t request,
471*e7d23d0eSVijay Khemka                                    ipmi_response_t response,
472*e7d23d0eSVijay Khemka                                    ipmi_data_len_t data_len,
473*e7d23d0eSVijay Khemka                                    ipmi_context_t context)
474*e7d23d0eSVijay Khemka {
475*e7d23d0eSVijay Khemka     uint8_t *req = reinterpret_cast<uint8_t *>(request);
476*e7d23d0eSVijay Khemka     uint8_t *res = reinterpret_cast<uint8_t *>(response);
477*e7d23d0eSVijay Khemka 
478*e7d23d0eSVijay Khemka     *data_len = 0;
479*e7d23d0eSVijay Khemka     return IPMI_CC_OK;
480*e7d23d0eSVijay Khemka }
481*e7d23d0eSVijay Khemka 
482*e7d23d0eSVijay Khemka //----------------------------------------------------------------------
483*e7d23d0eSVijay Khemka // Set PPR (CMD_OEM_SET_PPR)
484*e7d23d0eSVijay Khemka //----------------------------------------------------------------------
485*e7d23d0eSVijay Khemka ipmi_ret_t ipmiOemSetPpr(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
486*e7d23d0eSVijay Khemka                          ipmi_request_t request, ipmi_response_t response,
487*e7d23d0eSVijay Khemka                          ipmi_data_len_t data_len, ipmi_context_t context)
488*e7d23d0eSVijay Khemka {
489*e7d23d0eSVijay Khemka     uint8_t *req = reinterpret_cast<uint8_t *>(request);
490*e7d23d0eSVijay Khemka     uint8_t *res = reinterpret_cast<uint8_t *>(response);
491*e7d23d0eSVijay Khemka 
492*e7d23d0eSVijay Khemka     *data_len = 0;
493*e7d23d0eSVijay Khemka     return IPMI_CC_OK;
494*e7d23d0eSVijay Khemka }
495*e7d23d0eSVijay Khemka 
496*e7d23d0eSVijay Khemka //----------------------------------------------------------------------
497*e7d23d0eSVijay Khemka // Get PPR (CMD_OEM_GET_PPR)
498*e7d23d0eSVijay Khemka //----------------------------------------------------------------------
499*e7d23d0eSVijay Khemka ipmi_ret_t ipmiOemGetPpr(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
500*e7d23d0eSVijay Khemka                          ipmi_request_t request, ipmi_response_t response,
501*e7d23d0eSVijay Khemka                          ipmi_data_len_t data_len, ipmi_context_t context)
502*e7d23d0eSVijay Khemka {
503*e7d23d0eSVijay Khemka     uint8_t *req = reinterpret_cast<uint8_t *>(request);
504*e7d23d0eSVijay Khemka     uint8_t *res = reinterpret_cast<uint8_t *>(response);
505*e7d23d0eSVijay Khemka 
506*e7d23d0eSVijay Khemka     res[0] = 0x00;
507*e7d23d0eSVijay Khemka     *data_len = 1;
508*e7d23d0eSVijay Khemka 
509*e7d23d0eSVijay Khemka     return IPMI_CC_OK;
510*e7d23d0eSVijay Khemka }
511*e7d23d0eSVijay Khemka 
512*e7d23d0eSVijay Khemka static void registerOEMFunctions(void)
513*e7d23d0eSVijay Khemka {
514*e7d23d0eSVijay Khemka     phosphor::logging::log<phosphor::logging::level::INFO>(
515*e7d23d0eSVijay Khemka         "Registering OEM commands");
516*e7d23d0eSVijay Khemka     ipmiPrintAndRegister(NETFUN_CHASSIS, 1, NULL, ipmiGetChassisStatus,
517*e7d23d0eSVijay Khemka                          PRIVILEGE_USER); // get chassis status
518*e7d23d0eSVijay Khemka     ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, CMD_OEM_USB_DBG_GET_FRAME_INFO,
519*e7d23d0eSVijay Khemka                          NULL, ipmiOemDbgGetFrameInfo,
520*e7d23d0eSVijay Khemka                          PRIVILEGE_USER); // get debug frame info
521*e7d23d0eSVijay Khemka     ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ,
522*e7d23d0eSVijay Khemka                          CMD_OEM_USB_DBG_GET_UPDATED_FRAMES, NULL,
523*e7d23d0eSVijay Khemka                          ipmiOemDbgGetUpdFrames,
524*e7d23d0eSVijay Khemka                          PRIVILEGE_USER); // get debug updated frames
525*e7d23d0eSVijay Khemka     ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, CMD_OEM_USB_DBG_GET_POST_DESC,
526*e7d23d0eSVijay Khemka                          NULL, ipmiOemDbgGetPostDesc,
527*e7d23d0eSVijay Khemka                          PRIVILEGE_USER); // get debug post description
528*e7d23d0eSVijay Khemka     ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, CMD_OEM_USB_DBG_GET_GPIO_DESC,
529*e7d23d0eSVijay Khemka                          NULL, ipmiOemDbgGetGpioDesc,
530*e7d23d0eSVijay Khemka                          PRIVILEGE_USER); // get debug gpio description
531*e7d23d0eSVijay Khemka     ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, CMD_OEM_USB_DBG_GET_FRAME_DATA,
532*e7d23d0eSVijay Khemka                          NULL, ipmiOemDbgGetFrameData,
533*e7d23d0eSVijay Khemka                          PRIVILEGE_USER); // get debug frame data
534*e7d23d0eSVijay Khemka     ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, CMD_OEM_USB_DBG_CTRL_PANEL,
535*e7d23d0eSVijay Khemka                          NULL, ipmiOemDbgGetCtrlPanel,
536*e7d23d0eSVijay Khemka                          PRIVILEGE_USER); // get debug control panel
537*e7d23d0eSVijay Khemka     ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_DIMM_INFO, NULL,
538*e7d23d0eSVijay Khemka                          ipmiOemSetDimmInfo,
539*e7d23d0eSVijay Khemka                          PRIVILEGE_USER); // Set Dimm Info
540*e7d23d0eSVijay Khemka     ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_GET_BOOT_ORDER, NULL,
541*e7d23d0eSVijay Khemka                          ipmiOemGetBootOrder,
542*e7d23d0eSVijay Khemka                          PRIVILEGE_USER); // Get Boot Order
543*e7d23d0eSVijay Khemka     ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_MACHINE_CONFIG_INFO, NULL,
544*e7d23d0eSVijay Khemka                          ipmiOemSetMachineCfgInfo,
545*e7d23d0eSVijay Khemka                          PRIVILEGE_USER); // Set Machine Config Info
546*e7d23d0eSVijay Khemka     ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_POST_START, NULL,
547*e7d23d0eSVijay Khemka                          ipmiOemSetPostStart,
548*e7d23d0eSVijay Khemka                          PRIVILEGE_USER); // Set POST start
549*e7d23d0eSVijay Khemka     ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_POST_END, NULL,
550*e7d23d0eSVijay Khemka                          ipmiOemSetPostEnd,
551*e7d23d0eSVijay Khemka                          PRIVILEGE_USER); // Set POST End
552*e7d23d0eSVijay Khemka     ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_BIOS_FLASH_INFO, NULL,
553*e7d23d0eSVijay Khemka                          ipmiOemSetBiosFlashInfo,
554*e7d23d0eSVijay Khemka                          PRIVILEGE_USER); // Set Bios Flash Info
555*e7d23d0eSVijay Khemka     ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_PPR, NULL, ipmiOemSetPpr,
556*e7d23d0eSVijay Khemka                          PRIVILEGE_USER); // Set PPR
557*e7d23d0eSVijay Khemka     ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_GET_PPR, NULL, ipmiOemGetPpr,
558*e7d23d0eSVijay Khemka                          PRIVILEGE_USER); // Get PPR
559*e7d23d0eSVijay Khemka     return;
560*e7d23d0eSVijay Khemka }
561*e7d23d0eSVijay Khemka 
562*e7d23d0eSVijay Khemka } // namespace ipmi
563