blob: 55fcbf1cf80f080beda06fc57e7cfbfa4bbe7008 [file] [log] [blame]
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001/*
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 "xyz/openbmc_project/Common/error.hpp"
Jayashree-Df0cf6652020-11-30 11:03:30 +053019#include <xyz/openbmc_project/Control/Boot/Mode/server.hpp>
20#include <xyz/openbmc_project/Control/Boot/Source/server.hpp>
Jayashree Dhanapal778147d2022-03-30 16:48:53 +053021#include <xyz/openbmc_project/Control/Boot/Type/server.hpp>
Vijay Khemkae7d23d02019-03-08 13:13:40 -080022
Vijay Khemka63c99be2020-05-27 19:14:35 -070023#include <ipmid/api.hpp>
Vijay Khemka1b6fae32019-03-25 17:43:01 -070024#include <ipmid/utils.hpp>
Vijay Khemka63c99be2020-05-27 19:14:35 -070025#include <commandutils.hpp>
26#include <nlohmann/json.hpp>
27#include <oemcommands.hpp>
Vijay Khemkae7d23d02019-03-08 13:13:40 -080028#include <phosphor-logging/log.hpp>
29#include <sdbusplus/bus.hpp>
Vijay Khemka63c99be2020-05-27 19:14:35 -070030
Manikandan Elumalai5f8e3432020-12-02 03:46:55 +053031#include <ipmid/api.hpp>
32#include <ipmid/api-types.hpp>
33
Vijay Khemka63c99be2020-05-27 19:14:35 -070034#include <array>
35#include <cstring>
36#include <fstream>
37#include <iomanip>
38#include <iostream>
39#include <sstream>
Vijay Khemkae7d23d02019-03-08 13:13:40 -080040#include <string>
41#include <vector>
42
43#define SIZE_IANA_ID 3
44
45namespace ipmi
46{
Vijay Khemkaa7231892019-10-11 11:35:05 -070047
48using namespace phosphor::logging;
49
Vijay Khemkae7d23d02019-03-08 13:13:40 -080050static void registerOEMFunctions() __attribute__((constructor));
51sdbusplus::bus::bus dbus(ipmid_get_sd_bus_connection()); // from ipmid/api.h
52static constexpr size_t maxFRUStringLength = 0x3F;
Manikandan Elumalai5f8e3432020-12-02 03:46:55 +053053constexpr uint8_t cmdSetSystemGuid = 0xEF;
Vijay Khemkae7d23d02019-03-08 13:13:40 -080054
Vijay Khemka63c99be2020-05-27 19:14:35 -070055int plat_udbg_get_post_desc(uint8_t, uint8_t*, uint8_t, uint8_t*, uint8_t*,
56 uint8_t*);
57int plat_udbg_get_gpio_desc(uint8_t, uint8_t*, uint8_t*, uint8_t*, uint8_t*,
58 uint8_t*);
59ipmi_ret_t plat_udbg_get_frame_data(uint8_t, uint8_t, uint8_t*, uint8_t*,
60 uint8_t*);
61ipmi_ret_t plat_udbg_control_panel(uint8_t, uint8_t, uint8_t, uint8_t*,
62 uint8_t*);
63int sendMeCmd(uint8_t, uint8_t, std::vector<uint8_t>&, std::vector<uint8_t>&);
Vijay Khemkadd14c0f2020-03-18 14:48:13 -070064
Manikandan Elumalai5f8e3432020-12-02 03:46:55 +053065int sendBicCmd(uint8_t, uint8_t, uint8_t, std::vector<uint8_t>&,
66 std::vector<uint8_t>&);
67
Vijay Khemkafeaa9812019-08-27 15:08:08 -070068nlohmann::json oemData __attribute__((init_priority(101)));
Vijay Khemka1b6fae32019-03-25 17:43:01 -070069
Vijay Khemkaf2246ce2020-05-27 14:26:35 -070070static constexpr size_t GUID_SIZE = 16;
71// TODO Make offset and location runtime configurable to ensure we
72// can make each define their own locations.
73static constexpr off_t OFFSET_SYS_GUID = 0x17F0;
74static constexpr const char* FRU_EEPROM = "/sys/bus/i2c/devices/6-0054/eeprom";
75
Vijay Khemka1b6fae32019-03-25 17:43:01 -070076enum class LanParam : uint8_t
77{
78 INPROGRESS = 0,
79 AUTHSUPPORT = 1,
80 AUTHENABLES = 2,
81 IP = 3,
82 IPSRC = 4,
83 MAC = 5,
84 SUBNET = 6,
85 GATEWAY = 12,
86 VLAN = 20,
87 CIPHER_SUITE_COUNT = 22,
88 CIPHER_SUITE_ENTRIES = 23,
89 IPV6 = 59,
90};
91
Vijay Khemkaa7231892019-10-11 11:35:05 -070092namespace network
93{
94
95constexpr auto ROOT = "/xyz/openbmc_project/network";
96constexpr auto SERVICE = "xyz.openbmc_project.Network";
97constexpr auto IPV4_TYPE = "ipv4";
98constexpr auto IPV6_TYPE = "ipv6";
99constexpr auto IPV4_PREFIX = "169.254";
100constexpr auto IPV6_PREFIX = "fe80";
101constexpr auto IP_INTERFACE = "xyz.openbmc_project.Network.IP";
102constexpr auto MAC_INTERFACE = "xyz.openbmc_project.Network.MACAddress";
103
Vijay Khemka63c99be2020-05-27 19:14:35 -0700104bool isLinkLocalIP(const std::string& address)
Vijay Khemkaa7231892019-10-11 11:35:05 -0700105{
106 return address.find(IPV4_PREFIX) == 0 || address.find(IPV6_PREFIX) == 0;
107}
108
Vijay Khemka63c99be2020-05-27 19:14:35 -0700109DbusObjectInfo getIPObject(sdbusplus::bus::bus& bus,
110 const std::string& interface,
111 const std::string& serviceRoot,
112 const std::string& match)
Vijay Khemkaa7231892019-10-11 11:35:05 -0700113{
114 auto objectTree = getAllDbusObjects(bus, serviceRoot, interface, match);
115
116 if (objectTree.empty())
117 {
118 log<level::ERR>("No Object has implemented the IP interface",
119 entry("INTERFACE=%s", interface.c_str()));
120 }
121
122 DbusObjectInfo objectInfo;
123
Vijay Khemka63c99be2020-05-27 19:14:35 -0700124 for (auto& object : objectTree)
Vijay Khemkaa7231892019-10-11 11:35:05 -0700125 {
126 auto variant =
127 ipmi::getDbusProperty(bus, object.second.begin()->first,
128 object.first, IP_INTERFACE, "Address");
129
130 objectInfo = std::make_pair(object.first, object.second.begin()->first);
131
132 // if LinkLocalIP found look for Non-LinkLocalIP
133 if (isLinkLocalIP(std::get<std::string>(variant)))
134 {
135 continue;
136 }
137 else
138 {
139 break;
140 }
141 }
142 return objectInfo;
143}
144
145} // namespace network
146
Jayashree-Df0cf6652020-11-30 11:03:30 +0530147namespace boot
148{
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530149using BootSource =
150 sdbusplus::xyz::openbmc_project::Control::Boot::server::Source::Sources;
151using BootMode =
152 sdbusplus::xyz::openbmc_project::Control::Boot::server::Mode::Modes;
153using BootType =
154 sdbusplus::xyz::openbmc_project::Control::Boot::server::Type::Types;
Jayashree-Df0cf6652020-11-30 11:03:30 +0530155
Jayashree-Df0cf6652020-11-30 11:03:30 +0530156using IpmiValue = uint8_t;
157
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530158std::map<IpmiValue, BootSource> sourceIpmiToDbus = {
159 {0x0f, BootSource::Default}, {0x00, BootSource::RemovableMedia},
160 {0x01, BootSource::Network}, {0x02, BootSource::Disk},
161 {0x03, BootSource::ExternalMedia}, {0x09, BootSource::Network}};
Jayashree-Df0cf6652020-11-30 11:03:30 +0530162
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530163std::map<IpmiValue, BootMode> modeIpmiToDbus = {{0x06, BootMode::Setup},
164 {0x00, BootMode::Regular}};
Jayashree-Df0cf6652020-11-30 11:03:30 +0530165
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530166std::map<IpmiValue, BootType> typeIpmiToDbus = {{0x00, BootType::Legacy},
167 {0x01, BootType::EFI}};
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530168
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530169std::map<std::optional<BootSource>, IpmiValue> sourceDbusToIpmi = {
170 {BootSource::Default, 0x0f},
171 {BootSource::RemovableMedia, 0x00},
172 {BootSource::Network, 0x01},
173 {BootSource::Disk, 0x02},
174 {BootSource::ExternalMedia, 0x03}};
Jayashree-Df0cf6652020-11-30 11:03:30 +0530175
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530176std::map<std::optional<BootMode>, IpmiValue> modeDbusToIpmi = {
177 {BootMode::Setup, 0x06}, {BootMode::Regular, 0x00}};
Jayashree-Df0cf6652020-11-30 11:03:30 +0530178
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530179std::map<std::optional<BootType>, IpmiValue> typeDbusToIpmi = {
180 {BootType::Legacy, 0x00}, {BootType::EFI, 0x01}};
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530181
Jayashree-Df0cf6652020-11-30 11:03:30 +0530182static constexpr auto bootModeIntf = "xyz.openbmc_project.Control.Boot.Mode";
183static constexpr auto bootSourceIntf =
184 "xyz.openbmc_project.Control.Boot.Source";
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530185static constexpr auto bootTypeIntf = "xyz.openbmc_project.Control.Boot.Type";
Jayashree-Df0cf6652020-11-30 11:03:30 +0530186static constexpr auto bootSourceProp = "BootSource";
187static constexpr auto bootModeProp = "BootMode";
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530188static constexpr auto bootTypeProp = "BootType";
Jayashree-Df0cf6652020-11-30 11:03:30 +0530189
190auto instances(std::string s)
191{
192 std::string delimiter = " ";
193 size_t pos = 0;
194 std::string token;
195 std::vector<std::string> host;
196
197 while ((pos = s.find(delimiter)) != std::string::npos)
198 {
199 token = s.substr(0, pos);
200 host.push_back(token);
201 s.erase(0, pos + delimiter.length());
202 }
203 host.push_back(s);
204
205 return host;
206}
207
208std::optional<size_t> findHost(size_t id)
209{
210 std::string str = INSTANCES;
211 size_t hostId;
212
213 if (INSTANCES == "0")
214 {
215 hostId = id;
216 }
217 else
218 {
219 static const auto hosts = instances(str);
220 std::string num = std::to_string(id + 1);
221 auto instance = std::lower_bound(hosts.begin(), hosts.end(), num);
222
223 if ((instance == hosts.end()) || (*instance != num))
224 {
225 return std::nullopt;
226 }
227 hostId = id + 1;
228 }
229
230 return hostId;
231}
232
233std::tuple<std::string, std::string> objPath(size_t id)
234{
235 std::string hostName = "host" + std::to_string(id);
236 std::string bootObjPath =
237 "/xyz/openbmc_project/control/" + hostName + "/boot";
238 return std::make_tuple(std::move(bootObjPath), std::move(hostName));
239}
240
241} // namespace boot
242
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700243//----------------------------------------------------------------------
244// Helper functions for storing oem data
245//----------------------------------------------------------------------
246
247void flushOemData()
248{
249 std::ofstream file(JSON_OEM_DATA_FILE);
250 file << oemData;
Vijay Khemkafeaa9812019-08-27 15:08:08 -0700251 file.close();
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700252 return;
253}
254
Vijay Khemka63c99be2020-05-27 19:14:35 -0700255std::string bytesToStr(uint8_t* byte, int len)
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700256{
257 std::stringstream ss;
258 int i;
259
260 ss << std::hex;
261 for (i = 0; i < len; i++)
262 {
263 ss << std::setw(2) << std::setfill('0') << (int)byte[i];
264 }
265
266 return ss.str();
267}
268
Vijay Khemka63c99be2020-05-27 19:14:35 -0700269int strToBytes(std::string& str, uint8_t* data)
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700270{
271 std::string sstr;
Willy Tue39f9392022-06-15 13:24:20 -0700272 size_t i;
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700273
274 for (i = 0; i < (str.length()) / 2; i++)
275 {
276 sstr = str.substr(i * 2, 2);
277 data[i] = (uint8_t)std::strtol(sstr.c_str(), NULL, 16);
278 }
279 return i;
280}
281
Vijay Khemka63c99be2020-05-27 19:14:35 -0700282ipmi_ret_t getNetworkData(uint8_t lan_param, char* data)
Vijay Khemka1b6fae32019-03-25 17:43:01 -0700283{
284 ipmi_ret_t rc = IPMI_CC_OK;
285 sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
286
287 const std::string ethdevice = "eth0";
288
289 switch (static_cast<LanParam>(lan_param))
290 {
Vijay Khemkad1194022020-05-27 18:58:33 -0700291 case LanParam::IP:
292 {
Vijay Khemkaa7231892019-10-11 11:35:05 -0700293 auto ethIP = ethdevice + "/" + ipmi::network::IPV4_TYPE;
Vijay Khemka1b6fae32019-03-25 17:43:01 -0700294 std::string ipaddress;
Vijay Khemkaa7231892019-10-11 11:35:05 -0700295 auto ipObjectInfo = ipmi::network::getIPObject(
Vijay Khemka1b6fae32019-03-25 17:43:01 -0700296 bus, ipmi::network::IP_INTERFACE, ipmi::network::ROOT, ethIP);
297
298 auto properties = ipmi::getAllDbusProperties(
299 bus, ipObjectInfo.second, ipObjectInfo.first,
300 ipmi::network::IP_INTERFACE);
301
Patrick Williamsef0efbc2020-05-13 11:26:51 -0500302 ipaddress = std::get<std::string>(properties["Address"]);
Vijay Khemka1b6fae32019-03-25 17:43:01 -0700303
304 std::strcpy(data, ipaddress.c_str());
305 }
306 break;
307
Vijay Khemkad1194022020-05-27 18:58:33 -0700308 case LanParam::IPV6:
309 {
Vijay Khemkaa7231892019-10-11 11:35:05 -0700310 auto ethIP = ethdevice + "/" + ipmi::network::IPV6_TYPE;
Vijay Khemka1b6fae32019-03-25 17:43:01 -0700311 std::string ipaddress;
Vijay Khemkaa7231892019-10-11 11:35:05 -0700312 auto ipObjectInfo = ipmi::network::getIPObject(
Vijay Khemka1b6fae32019-03-25 17:43:01 -0700313 bus, ipmi::network::IP_INTERFACE, ipmi::network::ROOT, ethIP);
314
315 auto properties = ipmi::getAllDbusProperties(
316 bus, ipObjectInfo.second, ipObjectInfo.first,
317 ipmi::network::IP_INTERFACE);
318
Patrick Williamsef0efbc2020-05-13 11:26:51 -0500319 ipaddress = std::get<std::string>(properties["Address"]);
Vijay Khemka1b6fae32019-03-25 17:43:01 -0700320
321 std::strcpy(data, ipaddress.c_str());
322 }
323 break;
324
Vijay Khemkad1194022020-05-27 18:58:33 -0700325 case LanParam::MAC:
326 {
Vijay Khemka1b6fae32019-03-25 17:43:01 -0700327 std::string macAddress;
328 auto macObjectInfo =
329 ipmi::getDbusObject(bus, ipmi::network::MAC_INTERFACE,
330 ipmi::network::ROOT, ethdevice);
331
332 auto variant = ipmi::getDbusProperty(
333 bus, macObjectInfo.second, macObjectInfo.first,
334 ipmi::network::MAC_INTERFACE, "MACAddress");
335
Patrick Williamsef0efbc2020-05-13 11:26:51 -0500336 macAddress = std::get<std::string>(variant);
Vijay Khemka1b6fae32019-03-25 17:43:01 -0700337
338 sscanf(macAddress.c_str(), ipmi::network::MAC_ADDRESS_FORMAT,
339 (data), (data + 1), (data + 2), (data + 3), (data + 4),
340 (data + 5));
341 std::strcpy(data, macAddress.c_str());
342 }
343 break;
344
345 default:
346 rc = IPMI_CC_PARM_OUT_OF_RANGE;
347 }
348 return rc;
349}
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800350
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +0530351bool isMultiHostPlatform()
352{
353 bool platform;
354 if (INSTANCES == "0")
355 {
356 platform = false;
357 }
358 else
359 {
360 platform = true;
361 }
362 return platform;
363}
364
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800365// return code: 0 successful
Vijay Khemka63c99be2020-05-27 19:14:35 -0700366int8_t getFruData(std::string& data, std::string& name)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800367{
368 std::string objpath = "/xyz/openbmc_project/FruDevice";
369 std::string intf = "xyz.openbmc_project.FruDeviceManager";
370 std::string service = getService(dbus, intf, objpath);
371 ObjectValueTree valueTree = getManagedObjects(dbus, service, "/");
372 if (valueTree.empty())
373 {
374 phosphor::logging::log<phosphor::logging::level::ERR>(
375 "No object implements interface",
376 phosphor::logging::entry("INTF=%s", intf.c_str()));
377 return -1;
378 }
379
Vijay Khemka63c99be2020-05-27 19:14:35 -0700380 for (const auto& item : valueTree)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800381 {
382 auto interface = item.second.find("xyz.openbmc_project.FruDevice");
383 if (interface == item.second.end())
384 {
385 continue;
386 }
387
388 auto property = interface->second.find(name.c_str());
389 if (property == interface->second.end())
390 {
391 continue;
392 }
393
394 try
395 {
396 Value variant = property->second;
Vijay Khemka63c99be2020-05-27 19:14:35 -0700397 std::string& result = std::get<std::string>(variant);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800398 if (result.size() > maxFRUStringLength)
399 {
400 phosphor::logging::log<phosphor::logging::level::ERR>(
401 "FRU serial number exceed maximum length");
402 return -1;
403 }
404 data = result;
405 return 0;
406 }
Patrick Williams35d12542021-10-06 11:21:13 -0500407 catch (const std::bad_variant_access& e)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800408 {
409 phosphor::logging::log<phosphor::logging::level::ERR>(e.what());
410 return -1;
411 }
412 }
413 return -1;
414}
415
416typedef struct
417{
418 uint8_t cur_power_state;
419 uint8_t last_power_event;
420 uint8_t misc_power_state;
421 uint8_t front_panel_button_cap_status;
422} ipmi_get_chassis_status_t;
423
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800424//----------------------------------------------------------------------
425// Get Debug Frame Info
426//----------------------------------------------------------------------
Willy Tue39f9392022-06-15 13:24:20 -0700427ipmi_ret_t ipmiOemDbgGetFrameInfo(ipmi_netfn_t, ipmi_cmd_t,
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800428 ipmi_request_t request,
429 ipmi_response_t response,
Willy Tue39f9392022-06-15 13:24:20 -0700430 ipmi_data_len_t data_len, ipmi_context_t)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800431{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700432 uint8_t* req = reinterpret_cast<uint8_t*>(request);
433 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800434 uint8_t num_frames = 3;
435
436 std::memcpy(res, req, SIZE_IANA_ID); // IANA ID
437 res[SIZE_IANA_ID] = num_frames;
438 *data_len = SIZE_IANA_ID + 1;
439
440 return IPMI_CC_OK;
441}
442
443//----------------------------------------------------------------------
444// Get Debug Updated Frames
445//----------------------------------------------------------------------
Willy Tue39f9392022-06-15 13:24:20 -0700446ipmi_ret_t ipmiOemDbgGetUpdFrames(ipmi_netfn_t, ipmi_cmd_t,
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800447 ipmi_request_t request,
448 ipmi_response_t response,
Willy Tue39f9392022-06-15 13:24:20 -0700449 ipmi_data_len_t data_len, ipmi_context_t)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800450{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700451 uint8_t* req = reinterpret_cast<uint8_t*>(request);
452 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800453 uint8_t num_updates = 3;
454 *data_len = 4;
455
456 std::memcpy(res, req, SIZE_IANA_ID); // IANA ID
457 res[SIZE_IANA_ID] = num_updates;
458 *data_len = SIZE_IANA_ID + num_updates + 1;
459 res[SIZE_IANA_ID + 1] = 1; // info page update
460 res[SIZE_IANA_ID + 2] = 2; // cri sel update
461 res[SIZE_IANA_ID + 3] = 3; // cri sensor update
462
463 return IPMI_CC_OK;
464}
465
466//----------------------------------------------------------------------
467// Get Debug POST Description
468//----------------------------------------------------------------------
Willy Tue39f9392022-06-15 13:24:20 -0700469ipmi_ret_t ipmiOemDbgGetPostDesc(ipmi_netfn_t, ipmi_cmd_t,
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800470 ipmi_request_t request,
471 ipmi_response_t response,
Willy Tue39f9392022-06-15 13:24:20 -0700472 ipmi_data_len_t data_len, ipmi_context_t)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800473{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700474 uint8_t* req = reinterpret_cast<uint8_t*>(request);
475 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800476 uint8_t index = 0;
477 uint8_t next = 0;
478 uint8_t end = 0;
479 uint8_t phase = 0;
Vijay Khemkacc0d6d92019-08-27 14:51:17 -0700480 uint8_t descLen = 0;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800481 int ret;
482
483 index = req[3];
484 phase = req[4];
485
Vijay Khemkacc0d6d92019-08-27 14:51:17 -0700486 ret = plat_udbg_get_post_desc(index, &next, phase, &end, &descLen, &res[8]);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800487 if (ret)
488 {
489 memcpy(res, req, SIZE_IANA_ID); // IANA ID
490 *data_len = SIZE_IANA_ID;
491 return IPMI_CC_UNSPECIFIED_ERROR;
492 }
493
494 memcpy(res, req, SIZE_IANA_ID); // IANA ID
495 res[3] = index;
496 res[4] = next;
497 res[5] = phase;
498 res[6] = end;
Vijay Khemkacc0d6d92019-08-27 14:51:17 -0700499 res[7] = descLen;
500 *data_len = SIZE_IANA_ID + 5 + descLen;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800501
502 return IPMI_CC_OK;
503}
504
505//----------------------------------------------------------------------
506// Get Debug GPIO Description
507//----------------------------------------------------------------------
Willy Tue39f9392022-06-15 13:24:20 -0700508ipmi_ret_t ipmiOemDbgGetGpioDesc(ipmi_netfn_t, ipmi_cmd_t,
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800509 ipmi_request_t request,
510 ipmi_response_t response,
Willy Tue39f9392022-06-15 13:24:20 -0700511 ipmi_data_len_t data_len, ipmi_context_t)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800512{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700513 uint8_t* req = reinterpret_cast<uint8_t*>(request);
514 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800515
Vijay Khemka38183d62019-08-28 16:19:33 -0700516 uint8_t index = 0;
517 uint8_t next = 0;
518 uint8_t level = 0;
519 uint8_t pinDef = 0;
520 uint8_t descLen = 0;
521 int ret;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800522
Vijay Khemka38183d62019-08-28 16:19:33 -0700523 index = req[3];
524
525 ret = plat_udbg_get_gpio_desc(index, &next, &level, &pinDef, &descLen,
526 &res[8]);
527 if (ret)
528 {
529 memcpy(res, req, SIZE_IANA_ID); // IANA ID
530 *data_len = SIZE_IANA_ID;
531 return IPMI_CC_UNSPECIFIED_ERROR;
532 }
533
534 memcpy(res, req, SIZE_IANA_ID); // IANA ID
535 res[3] = index;
536 res[4] = next;
537 res[5] = level;
538 res[6] = pinDef;
539 res[7] = descLen;
540 *data_len = SIZE_IANA_ID + 5 + descLen;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800541
542 return IPMI_CC_OK;
543}
544
545//----------------------------------------------------------------------
546// Get Debug Frame Data
547//----------------------------------------------------------------------
Willy Tue39f9392022-06-15 13:24:20 -0700548ipmi_ret_t ipmiOemDbgGetFrameData(ipmi_netfn_t, ipmi_cmd_t,
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800549 ipmi_request_t request,
550 ipmi_response_t response,
Willy Tue39f9392022-06-15 13:24:20 -0700551 ipmi_data_len_t data_len, ipmi_context_t)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800552{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700553 uint8_t* req = reinterpret_cast<uint8_t*>(request);
554 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800555 uint8_t frame;
556 uint8_t page;
557 uint8_t next;
558 uint8_t count;
559 int ret;
560
561 frame = req[3];
562 page = req[4];
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800563
564 ret = plat_udbg_get_frame_data(frame, page, &next, &count, &res[7]);
565 if (ret)
566 {
567 memcpy(res, req, SIZE_IANA_ID); // IANA ID
568 *data_len = SIZE_IANA_ID;
569 return IPMI_CC_UNSPECIFIED_ERROR;
570 }
571
572 memcpy(res, req, SIZE_IANA_ID); // IANA ID
573 res[3] = frame;
574 res[4] = page;
575 res[5] = next;
576 res[6] = count;
577 *data_len = SIZE_IANA_ID + 4 + count;
578
579 return IPMI_CC_OK;
580}
581
582//----------------------------------------------------------------------
583// Get Debug Control Panel
584//----------------------------------------------------------------------
Willy Tue39f9392022-06-15 13:24:20 -0700585ipmi_ret_t ipmiOemDbgGetCtrlPanel(ipmi_netfn_t, ipmi_cmd_t,
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800586 ipmi_request_t request,
587 ipmi_response_t response,
Willy Tue39f9392022-06-15 13:24:20 -0700588 ipmi_data_len_t data_len, ipmi_context_t)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800589{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700590 uint8_t* req = reinterpret_cast<uint8_t*>(request);
591 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800592
593 uint8_t panel;
594 uint8_t operation;
595 uint8_t item;
596 uint8_t count;
597 ipmi_ret_t ret;
598
599 panel = req[3];
600 operation = req[4];
601 item = req[5];
602
603 ret = plat_udbg_control_panel(panel, operation, item, &count, &res[3]);
604
605 std::memcpy(res, req, SIZE_IANA_ID); // IANA ID
606 *data_len = SIZE_IANA_ID + count;
607
608 return ret;
609}
610
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800611//----------------------------------------------------------------------
612// Set Dimm Info (CMD_OEM_SET_DIMM_INFO)
613//----------------------------------------------------------------------
Willy Tue39f9392022-06-15 13:24:20 -0700614ipmi_ret_t ipmiOemSetDimmInfo(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t request,
615 ipmi_response_t, ipmi_data_len_t data_len,
616 ipmi_context_t)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800617{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700618 uint8_t* req = reinterpret_cast<uint8_t*>(request);
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700619
620 uint8_t index = req[0];
621 uint8_t type = req[1];
622 uint16_t speed;
623 uint32_t size;
624
625 memcpy(&speed, &req[2], 2);
626 memcpy(&size, &req[4], 4);
627
628 std::stringstream ss;
629 ss << std::hex;
630 ss << std::setw(2) << std::setfill('0') << (int)index;
631
632 oemData[KEY_SYS_CONFIG][ss.str()][KEY_DIMM_INDEX] = index;
633 oemData[KEY_SYS_CONFIG][ss.str()][KEY_DIMM_TYPE] = type;
634 oemData[KEY_SYS_CONFIG][ss.str()][KEY_DIMM_SPEED] = speed;
635 oemData[KEY_SYS_CONFIG][ss.str()][KEY_DIMM_SIZE] = size;
636
637 flushOemData();
638
639 *data_len = 0;
640
641 return IPMI_CC_OK;
642}
643
644//----------------------------------------------------------------------
645// Get Board ID (CMD_OEM_GET_BOARD_ID)
646//----------------------------------------------------------------------
Willy Tue39f9392022-06-15 13:24:20 -0700647ipmi_ret_t ipmiOemGetBoardID(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t,
648 ipmi_response_t, ipmi_data_len_t data_len,
649 ipmi_context_t)
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700650{
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700651 /* TODO: Needs to implement this after GPIO implementation */
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800652 *data_len = 0;
653
654 return IPMI_CC_OK;
655}
656
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800657/* Helper functions to set boot order */
Jayashree-Df0cf6652020-11-30 11:03:30 +0530658void setBootOrder(std::string bootObjPath, uint8_t* data,
659 std::string bootOrderKey)
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800660{
Jayashree-Df0cf6652020-11-30 11:03:30 +0530661 std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
662
663 // SETTING BOOT MODE PROPERTY
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530664 uint8_t bootModeBit = data[0] & 0x06;
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530665 auto bootValue = ipmi::boot::modeIpmiToDbus.at(bootModeBit);
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530666
Jayashree-Df0cf6652020-11-30 11:03:30 +0530667 std::string bootOption =
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530668 sdbusplus::message::convert_to_string<boot::BootMode>(bootValue);
Jayashree-Df0cf6652020-11-30 11:03:30 +0530669
670 std::string service =
671 getService(*dbus, ipmi::boot::bootModeIntf, bootObjPath);
672 setDbusProperty(*dbus, service, bootObjPath, ipmi::boot::bootModeIntf,
673 ipmi::boot::bootModeProp, bootOption);
674
675 // SETTING BOOT SOURCE PROPERTY
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530676 auto bootOrder = ipmi::boot::sourceIpmiToDbus.at(data[1]);
Jayashree-Df0cf6652020-11-30 11:03:30 +0530677 std::string bootSource =
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530678 sdbusplus::message::convert_to_string<boot::BootSource>(bootOrder);
Jayashree-Df0cf6652020-11-30 11:03:30 +0530679
680 service = getService(*dbus, ipmi::boot::bootSourceIntf, bootObjPath);
681 setDbusProperty(*dbus, service, bootObjPath, ipmi::boot::bootSourceIntf,
682 ipmi::boot::bootSourceProp, bootSource);
683
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530684 // SETTING BOOT TYPE PROPERTY
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530685 uint8_t bootTypeBit = data[0] & 0x01;
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530686 auto bootTypeVal = ipmi::boot::typeIpmiToDbus.at(bootTypeBit);
687
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530688 std::string bootType =
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530689 sdbusplus::message::convert_to_string<boot::BootType>(bootTypeVal);
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530690
691 service = getService(*dbus, ipmi::boot::bootTypeIntf, bootObjPath);
692
693 setDbusProperty(*dbus, service, bootObjPath, ipmi::boot::bootTypeIntf,
694 ipmi::boot::bootTypeProp, bootType);
695
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800696 nlohmann::json bootMode;
697 uint8_t mode = data[0];
698 int i;
699
700 bootMode["UEFI"] = (mode & BOOT_MODE_UEFI ? true : false);
701 bootMode["CMOS_CLR"] = (mode & BOOT_MODE_CMOS_CLR ? true : false);
702 bootMode["FORCE_BOOT"] = (mode & BOOT_MODE_FORCE_BOOT ? true : false);
703 bootMode["BOOT_FLAG"] = (mode & BOOT_MODE_BOOT_FLAG ? true : false);
Jayashree-Df0cf6652020-11-30 11:03:30 +0530704 oemData[bootOrderKey][KEY_BOOT_MODE] = bootMode;
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800705
706 /* Initialize boot sequence array */
Jayashree-Df0cf6652020-11-30 11:03:30 +0530707 oemData[bootOrderKey][KEY_BOOT_SEQ] = {};
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800708 for (i = 1; i < SIZE_BOOT_ORDER; i++)
709 {
710 if (data[i] >= BOOT_SEQ_ARRAY_SIZE)
Jayashree-Df0cf6652020-11-30 11:03:30 +0530711 oemData[bootOrderKey][KEY_BOOT_SEQ][i - 1] = "NA";
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800712 else
Jayashree-Df0cf6652020-11-30 11:03:30 +0530713 oemData[bootOrderKey][KEY_BOOT_SEQ][i - 1] = bootSeq[data[i]];
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800714 }
715
716 flushOemData();
717}
718
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800719//----------------------------------------------------------------------
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700720// Set Boot Order (CMD_OEM_SET_BOOT_ORDER)
721//----------------------------------------------------------------------
Jayashree-Df0cf6652020-11-30 11:03:30 +0530722ipmi::RspType<std::vector<uint8_t>>
723 ipmiOemSetBootOrder(ipmi::Context::ptr ctx, std::vector<uint8_t> data)
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700724{
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700725
Jayashree-Df0cf6652020-11-30 11:03:30 +0530726 uint8_t bootSeq[SIZE_BOOT_ORDER];
727 size_t len = data.size();
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700728
729 if (len != SIZE_BOOT_ORDER)
730 {
731 phosphor::logging::log<phosphor::logging::level::ERR>(
732 "Invalid Boot order length received");
Jayashree-Df0cf6652020-11-30 11:03:30 +0530733 return ipmi::responseReqDataLenInvalid();
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700734 }
735
Jayashree-Df0cf6652020-11-30 11:03:30 +0530736 std::copy(std::begin(data), std::end(data), bootSeq);
737 std::optional<size_t> hostId = ipmi::boot::findHost(ctx->hostIdx);
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700738
Jayashree-Df0cf6652020-11-30 11:03:30 +0530739 if (!hostId)
740 {
741 phosphor::logging::log<phosphor::logging::level::ERR>(
742 "Invalid Host Id received");
743 return ipmi::responseInvalidCommand();
744 }
745 auto [bootObjPath, hostName] = ipmi::boot::objPath(*hostId);
746
747 setBootOrder(bootObjPath, bootSeq, hostName);
748
749 return ipmi::responseSuccess(data);
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700750}
751
752//----------------------------------------------------------------------
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800753// Get Boot Order (CMD_OEM_GET_BOOT_ORDER)
754//----------------------------------------------------------------------
Jayashree-Df0cf6652020-11-30 11:03:30 +0530755ipmi::RspType<uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t>
756 ipmiOemGetBootOrder(ipmi::Context::ptr ctx)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800757{
Jayashree-Df0cf6652020-11-30 11:03:30 +0530758 uint8_t bootSeq[SIZE_BOOT_ORDER];
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700759 uint8_t mode = 0;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800760
Jayashree-Df0cf6652020-11-30 11:03:30 +0530761 std::optional<size_t> hostId = ipmi::boot::findHost(ctx->hostIdx);
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700762
Jayashree-Df0cf6652020-11-30 11:03:30 +0530763 if (!hostId)
764 {
765 phosphor::logging::log<phosphor::logging::level::ERR>(
766 "Invalid Host Id received");
767 return ipmi::responseInvalidCommand();
768 }
769 auto [bootObjPath, hostName] = ipmi::boot::objPath(*hostId);
770
Jayashree-Df0cf6652020-11-30 11:03:30 +0530771 std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
772
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530773 // GETTING PROPERTY OF MODE INTERFACE
774
Jayashree-Df0cf6652020-11-30 11:03:30 +0530775 std::string service =
776 getService(*dbus, ipmi::boot::bootModeIntf, bootObjPath);
777 Value variant =
778 getDbusProperty(*dbus, service, bootObjPath, ipmi::boot::bootModeIntf,
779 ipmi::boot::bootModeProp);
780
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530781 auto bootMode = sdbusplus::message::convert_from_string<boot::BootMode>(
Jayashree-Df0cf6652020-11-30 11:03:30 +0530782 std::get<std::string>(variant));
783
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530784 uint8_t bootOption = ipmi::boot::modeDbusToIpmi.at(bootMode);
Jayashree-Df0cf6652020-11-30 11:03:30 +0530785
786 // GETTING PROPERTY OF SOURCE INTERFACE
787
788 service = getService(*dbus, ipmi::boot::bootSourceIntf, bootObjPath);
789 variant =
790 getDbusProperty(*dbus, service, bootObjPath, ipmi::boot::bootSourceIntf,
791 ipmi::boot::bootSourceProp);
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530792
793 auto bootSource = sdbusplus::message::convert_from_string<boot::BootSource>(
Jayashree-Df0cf6652020-11-30 11:03:30 +0530794 std::get<std::string>(variant));
795
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530796 uint8_t bootOrder = ipmi::boot::sourceDbusToIpmi.at(bootSource);
797
798 // GETTING PROPERTY OF TYPE INTERFACE
799
800 service = getService(*dbus, ipmi::boot::bootTypeIntf, bootObjPath);
801 variant =
802 getDbusProperty(*dbus, service, bootObjPath, ipmi::boot::bootTypeIntf,
803 ipmi::boot::bootTypeProp);
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530804
805 auto bootType = sdbusplus::message::convert_from_string<boot::BootType>(
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530806 std::get<std::string>(variant));
807
808 uint8_t bootTypeVal = ipmi::boot::typeDbusToIpmi.at(bootType);
809
810 uint8_t bootVal = bootOption | bootTypeVal;
Jayashree-Df0cf6652020-11-30 11:03:30 +0530811
812 if (oemData.find(hostName) == oemData.end())
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800813 {
814 /* Return default boot order 0100090203ff */
815 uint8_t defaultBoot[SIZE_BOOT_ORDER] = {
Willy Tue39f9392022-06-15 13:24:20 -0700816 BOOT_MODE_UEFI,
817 static_cast<uint8_t>(bootMap["USB_DEV"]),
818 static_cast<uint8_t>(bootMap["NET_IPV6"]),
819 static_cast<uint8_t>(bootMap["SATA_HDD"]),
820 static_cast<uint8_t>(bootMap["SATA_CD"]),
821 0xff};
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700822
Jayashree-Df0cf6652020-11-30 11:03:30 +0530823 memcpy(bootSeq, defaultBoot, SIZE_BOOT_ORDER);
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800824 phosphor::logging::log<phosphor::logging::level::INFO>(
825 "Set default boot order");
Jayashree-Df0cf6652020-11-30 11:03:30 +0530826 setBootOrder(bootObjPath, defaultBoot, hostName);
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800827 }
828 else
829 {
Jayashree-Df0cf6652020-11-30 11:03:30 +0530830 nlohmann::json bootMode = oemData[hostName][KEY_BOOT_MODE];
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800831 if (bootMode["UEFI"])
832 mode |= BOOT_MODE_UEFI;
833 if (bootMode["CMOS_CLR"])
834 mode |= BOOT_MODE_CMOS_CLR;
835 if (bootMode["BOOT_FLAG"])
836 mode |= BOOT_MODE_BOOT_FLAG;
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700837
Jayashree-Df0cf6652020-11-30 11:03:30 +0530838 bootSeq[0] = mode;
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800839
Jayashree-Df0cf6652020-11-30 11:03:30 +0530840 for (int i = 1; i < SIZE_BOOT_ORDER; i++)
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800841 {
Jayashree-Df0cf6652020-11-30 11:03:30 +0530842 std::string seqStr = oemData[hostName][KEY_BOOT_SEQ][i - 1];
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800843 if (bootMap.find(seqStr) != bootMap.end())
Jayashree-Df0cf6652020-11-30 11:03:30 +0530844 bootSeq[i] = bootMap[seqStr];
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800845 else
Jayashree-Df0cf6652020-11-30 11:03:30 +0530846 bootSeq[i] = 0xff;
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800847 }
848 }
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800849
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530850 return ipmi::responseSuccess(bootVal, bootOrder, bootSeq[2], bootSeq[3],
Jayashree-Df0cf6652020-11-30 11:03:30 +0530851 bootSeq[4], bootSeq[5]);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800852}
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800853// Set Machine Config Info (CMD_OEM_SET_MACHINE_CONFIG_INFO)
854//----------------------------------------------------------------------
Willy Tue39f9392022-06-15 13:24:20 -0700855ipmi_ret_t ipmiOemSetMachineCfgInfo(ipmi_netfn_t, ipmi_cmd_t,
856 ipmi_request_t request, ipmi_response_t,
857 ipmi_data_len_t data_len, ipmi_context_t)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800858{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700859 machineConfigInfo_t* req = reinterpret_cast<machineConfigInfo_t*>(request);
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700860 uint8_t len = *data_len;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800861
862 *data_len = 0;
863
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700864 if (len < sizeof(machineConfigInfo_t))
865 {
866 phosphor::logging::log<phosphor::logging::level::ERR>(
867 "Invalid machine configuration length received");
868 return IPMI_CC_REQ_DATA_LEN_INVALID;
869 }
870
Vijay Khemka63c99be2020-05-27 19:14:35 -0700871 if (req->chassis_type >= sizeof(chassisType) / sizeof(uint8_t*))
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700872 oemData[KEY_MC_CONFIG][KEY_MC_CHAS_TYPE] = "UNKNOWN";
873 else
874 oemData[KEY_MC_CONFIG][KEY_MC_CHAS_TYPE] =
875 chassisType[req->chassis_type];
876
Vijay Khemka63c99be2020-05-27 19:14:35 -0700877 if (req->mb_type >= sizeof(mbType) / sizeof(uint8_t*))
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700878 oemData[KEY_MC_CONFIG][KEY_MC_MB_TYPE] = "UNKNOWN";
879 else
880 oemData[KEY_MC_CONFIG][KEY_MC_MB_TYPE] = mbType[req->mb_type];
881
882 oemData[KEY_MC_CONFIG][KEY_MC_PROC_CNT] = req->proc_cnt;
883 oemData[KEY_MC_CONFIG][KEY_MC_MEM_CNT] = req->mem_cnt;
884 oemData[KEY_MC_CONFIG][KEY_MC_HDD35_CNT] = req->hdd35_cnt;
885 oemData[KEY_MC_CONFIG][KEY_MC_HDD25_CNT] = req->hdd25_cnt;
886
Vijay Khemka63c99be2020-05-27 19:14:35 -0700887 if (req->riser_type >= sizeof(riserType) / sizeof(uint8_t*))
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700888 oemData[KEY_MC_CONFIG][KEY_MC_RSR_TYPE] = "UNKNOWN";
889 else
890 oemData[KEY_MC_CONFIG][KEY_MC_RSR_TYPE] = riserType[req->riser_type];
891
892 oemData[KEY_MC_CONFIG][KEY_MC_PCIE_LOC] = {};
893 int i = 0;
894 if (req->pcie_card_loc & BIT_0)
895 oemData[KEY_MC_CONFIG][KEY_MC_PCIE_LOC][i++] = "SLOT1";
896 if (req->pcie_card_loc & BIT_1)
897 oemData[KEY_MC_CONFIG][KEY_MC_PCIE_LOC][i++] = "SLOT2";
898 if (req->pcie_card_loc & BIT_2)
899 oemData[KEY_MC_CONFIG][KEY_MC_PCIE_LOC][i++] = "SLOT3";
900 if (req->pcie_card_loc & BIT_3)
901 oemData[KEY_MC_CONFIG][KEY_MC_PCIE_LOC][i++] = "SLOT4";
902
Vijay Khemka63c99be2020-05-27 19:14:35 -0700903 if (req->slot1_pcie_type >= sizeof(pcieType) / sizeof(uint8_t*))
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700904 oemData[KEY_MC_CONFIG][KEY_MC_SLOT1_TYPE] = "UNKNOWN";
905 else
906 oemData[KEY_MC_CONFIG][KEY_MC_SLOT1_TYPE] =
907 pcieType[req->slot1_pcie_type];
908
Vijay Khemka63c99be2020-05-27 19:14:35 -0700909 if (req->slot2_pcie_type >= sizeof(pcieType) / sizeof(uint8_t*))
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700910 oemData[KEY_MC_CONFIG][KEY_MC_SLOT2_TYPE] = "UNKNOWN";
911 else
912 oemData[KEY_MC_CONFIG][KEY_MC_SLOT2_TYPE] =
913 pcieType[req->slot2_pcie_type];
914
Vijay Khemka63c99be2020-05-27 19:14:35 -0700915 if (req->slot3_pcie_type >= sizeof(pcieType) / sizeof(uint8_t*))
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700916 oemData[KEY_MC_CONFIG][KEY_MC_SLOT3_TYPE] = "UNKNOWN";
917 else
918 oemData[KEY_MC_CONFIG][KEY_MC_SLOT3_TYPE] =
919 pcieType[req->slot3_pcie_type];
920
Vijay Khemka63c99be2020-05-27 19:14:35 -0700921 if (req->slot4_pcie_type >= sizeof(pcieType) / sizeof(uint8_t*))
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700922 oemData[KEY_MC_CONFIG][KEY_MC_SLOT4_TYPE] = "UNKNOWN";
923 else
924 oemData[KEY_MC_CONFIG][KEY_MC_SLOT4_TYPE] =
925 pcieType[req->slot4_pcie_type];
926
927 oemData[KEY_MC_CONFIG][KEY_MC_AEP_CNT] = req->aep_mem_cnt;
928
929 flushOemData();
930
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800931 return IPMI_CC_OK;
932}
933
934//----------------------------------------------------------------------
935// Set POST start (CMD_OEM_SET_POST_START)
936//----------------------------------------------------------------------
Willy Tue39f9392022-06-15 13:24:20 -0700937ipmi_ret_t ipmiOemSetPostStart(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t,
938 ipmi_response_t, ipmi_data_len_t data_len,
939 ipmi_context_t)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800940{
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800941 phosphor::logging::log<phosphor::logging::level::INFO>("POST Start Event");
942
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700943 /* Do nothing, return success */
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800944 *data_len = 0;
945 return IPMI_CC_OK;
946}
947
948//----------------------------------------------------------------------
949// Set POST End (CMD_OEM_SET_POST_END)
950//----------------------------------------------------------------------
Willy Tue39f9392022-06-15 13:24:20 -0700951ipmi_ret_t ipmiOemSetPostEnd(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t,
952 ipmi_response_t, ipmi_data_len_t data_len,
953 ipmi_context_t)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800954{
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700955 struct timespec ts;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800956
957 phosphor::logging::log<phosphor::logging::level::INFO>("POST End Event");
958
959 *data_len = 0;
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700960
961 // Timestamp post end time.
962 clock_gettime(CLOCK_REALTIME, &ts);
963 oemData[KEY_TS_SLED] = ts.tv_sec;
964 flushOemData();
965
966 // Sync time with system
967 // TODO: Add code for syncing time
968
969 return IPMI_CC_OK;
970}
971
972//----------------------------------------------------------------------
973// Set PPIN Info (CMD_OEM_SET_PPIN_INFO)
974//----------------------------------------------------------------------
975// Inform BMC about PPIN data of 8 bytes for each CPU
976//
977// Request:
978// Byte 1:8 – CPU0 PPIN data
979// Optional:
980// Byte 9:16 – CPU1 PPIN data
981//
982// Response:
983// Byte 1 – Completion Code
Willy Tue39f9392022-06-15 13:24:20 -0700984ipmi_ret_t ipmiOemSetPPINInfo(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t request,
985 ipmi_response_t, ipmi_data_len_t data_len,
986 ipmi_context_t)
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700987{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700988 uint8_t* req = reinterpret_cast<uint8_t*>(request);
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700989 std::string ppinStr;
990 int len;
991
992 if (*data_len > SIZE_CPU_PPIN * 2)
993 len = SIZE_CPU_PPIN * 2;
994 else
995 len = *data_len;
996 *data_len = 0;
997
998 ppinStr = bytesToStr(req, len);
999 oemData[KEY_PPIN_INFO] = ppinStr.c_str();
1000 flushOemData();
1001
1002 return IPMI_CC_OK;
1003}
1004
1005//----------------------------------------------------------------------
1006// Set ADR Trigger (CMD_OEM_SET_ADR_TRIGGER)
1007//----------------------------------------------------------------------
Willy Tue39f9392022-06-15 13:24:20 -07001008ipmi_ret_t ipmiOemSetAdrTrigger(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t,
1009 ipmi_response_t, ipmi_data_len_t data_len,
1010 ipmi_context_t)
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001011{
1012 /* Do nothing, return success */
1013 *data_len = 0;
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001014 return IPMI_CC_OK;
1015}
1016
Vijay Khemkaf2246ce2020-05-27 14:26:35 -07001017// Helper function to set guid at offset in EEPROM
Willy Tue39f9392022-06-15 13:24:20 -07001018[[maybe_unused]] static int setGUID(off_t offset, uint8_t* guid)
Vijay Khemkaf2246ce2020-05-27 14:26:35 -07001019{
1020 int fd = -1;
1021 ssize_t len;
1022 int ret = 0;
1023
1024 errno = 0;
1025
1026 // Check if file is present
1027 if (access(FRU_EEPROM, F_OK) == -1)
1028 {
1029 std::cerr << "Unable to access: " << FRU_EEPROM << std::endl;
1030 return errno;
1031 }
1032
1033 // Open the file
1034 fd = open(FRU_EEPROM, O_WRONLY);
1035 if (fd == -1)
1036 {
1037 std::cerr << "Unable to open: " << FRU_EEPROM << std::endl;
1038 return errno;
1039 }
1040
1041 // seek to the offset
1042 lseek(fd, offset, SEEK_SET);
1043
1044 // Write bytes to location
1045 len = write(fd, guid, GUID_SIZE);
1046 if (len != GUID_SIZE)
1047 {
1048 phosphor::logging::log<phosphor::logging::level::ERR>(
1049 "GUID write data to EEPROM failed");
1050 ret = errno;
1051 }
1052
1053 close(fd);
1054 return ret;
1055}
1056
1057//----------------------------------------------------------------------
1058// Set System GUID (CMD_OEM_SET_SYSTEM_GUID)
1059//----------------------------------------------------------------------
Manikandan Elumalai5f8e3432020-12-02 03:46:55 +05301060#if BIC_ENABLED
Willy Tue39f9392022-06-15 13:24:20 -07001061ipmi::RspType<> ipmiOemSetSystemGuid(ipmi::Context::ptr ctx, uint8_t,
Manikandan Elumalai5f8e3432020-12-02 03:46:55 +05301062 std::vector<uint8_t> reqData)
1063{
1064 std::vector<uint8_t> respData;
1065
1066 if (reqData.size() != GUID_SIZE) // 16bytes
1067 {
1068
1069 return ipmi::responseReqDataLenInvalid();
1070 }
1071
Manikandan Elumalai5f8e3432020-12-02 03:46:55 +05301072 uint8_t bicAddr = (uint8_t)ctx->hostIdx << 2;
1073
1074 if (sendBicCmd(ctx->netFn, ctx->cmd, bicAddr, reqData, respData))
1075 return ipmi::responseUnspecifiedError();
1076
1077 return ipmi::responseSuccess();
1078}
1079
1080#else
Vijay Khemkaf2246ce2020-05-27 14:26:35 -07001081ipmi_ret_t ipmiOemSetSystemGuid(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
1082 ipmi_request_t request,
1083 ipmi_response_t response,
1084 ipmi_data_len_t data_len,
1085 ipmi_context_t context)
1086{
1087 uint8_t* req = reinterpret_cast<uint8_t*>(request);
1088
1089 if (*data_len != GUID_SIZE) // 16bytes
1090 {
1091 *data_len = 0;
1092 return IPMI_CC_REQ_DATA_LEN_INVALID;
1093 }
1094
1095 *data_len = 0;
1096
1097 if (setGUID(OFFSET_SYS_GUID, req))
1098 {
1099 return IPMI_CC_UNSPECIFIED_ERROR;
1100 }
1101 return IPMI_CC_OK;
1102}
Manikandan Elumalai5f8e3432020-12-02 03:46:55 +05301103#endif
Vijay Khemkaf2246ce2020-05-27 14:26:35 -07001104
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001105//----------------------------------------------------------------------
1106// Set Bios Flash Info (CMD_OEM_SET_BIOS_FLASH_INFO)
1107//----------------------------------------------------------------------
Willy Tue39f9392022-06-15 13:24:20 -07001108ipmi_ret_t ipmiOemSetBiosFlashInfo(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t,
1109 ipmi_response_t, ipmi_data_len_t data_len,
1110 ipmi_context_t)
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001111{
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001112 /* Do nothing, return success */
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001113 *data_len = 0;
1114 return IPMI_CC_OK;
1115}
1116
1117//----------------------------------------------------------------------
1118// Set PPR (CMD_OEM_SET_PPR)
1119//----------------------------------------------------------------------
Willy Tue39f9392022-06-15 13:24:20 -07001120ipmi_ret_t ipmiOemSetPpr(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t request,
1121 ipmi_response_t, ipmi_data_len_t data_len,
1122 ipmi_context_t)
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001123{
Vijay Khemka63c99be2020-05-27 19:14:35 -07001124 uint8_t* req = reinterpret_cast<uint8_t*>(request);
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001125 uint8_t pprCnt, pprAct, pprIndex;
1126 uint8_t selParam = req[0];
1127 uint8_t len = *data_len;
1128 std::stringstream ss;
1129 std::string str;
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001130
1131 *data_len = 0;
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001132
1133 switch (selParam)
1134 {
1135 case PPR_ACTION:
1136 if (oemData[KEY_PPR].find(KEY_PPR_ROW_COUNT) ==
1137 oemData[KEY_PPR].end())
1138 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
1139
1140 pprCnt = oemData[KEY_PPR][KEY_PPR_ROW_COUNT];
1141 if (pprCnt == 0)
1142 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
1143
1144 pprAct = req[1];
1145 /* Check if ppr is enabled or disabled */
1146 if (!(pprAct & 0x80))
1147 pprAct = 0;
1148
1149 oemData[KEY_PPR][KEY_PPR_ACTION] = pprAct;
1150 break;
1151 case PPR_ROW_COUNT:
1152 if (req[1] > 100)
1153 return IPMI_CC_PARM_OUT_OF_RANGE;
1154
1155 oemData[KEY_PPR][KEY_PPR_ROW_COUNT] = req[1];
1156 break;
1157 case PPR_ROW_ADDR:
1158 pprIndex = req[1];
1159 if (pprIndex > 100)
1160 return IPMI_CC_PARM_OUT_OF_RANGE;
1161
1162 if (len < PPR_ROW_ADDR_LEN + 1)
1163 {
1164 phosphor::logging::log<phosphor::logging::level::ERR>(
1165 "Invalid PPR Row Address length received");
1166 return IPMI_CC_REQ_DATA_LEN_INVALID;
1167 }
1168
1169 ss << std::hex;
1170 ss << std::setw(2) << std::setfill('0') << (int)pprIndex;
1171
1172 oemData[KEY_PPR][ss.str()][KEY_PPR_INDEX] = pprIndex;
1173
1174 str = bytesToStr(&req[1], PPR_ROW_ADDR_LEN);
1175 oemData[KEY_PPR][ss.str()][KEY_PPR_ROW_ADDR] = str.c_str();
1176 break;
1177 case PPR_HISTORY_DATA:
1178 pprIndex = req[1];
1179 if (pprIndex > 100)
1180 return IPMI_CC_PARM_OUT_OF_RANGE;
1181
1182 if (len < PPR_HST_DATA_LEN + 1)
1183 {
1184 phosphor::logging::log<phosphor::logging::level::ERR>(
1185 "Invalid PPR history data length received");
1186 return IPMI_CC_REQ_DATA_LEN_INVALID;
1187 }
1188
1189 ss << std::hex;
1190 ss << std::setw(2) << std::setfill('0') << (int)pprIndex;
1191
1192 oemData[KEY_PPR][ss.str()][KEY_PPR_INDEX] = pprIndex;
1193
1194 str = bytesToStr(&req[1], PPR_HST_DATA_LEN);
1195 oemData[KEY_PPR][ss.str()][KEY_PPR_HST_DATA] = str.c_str();
1196 break;
1197 default:
1198 return IPMI_CC_PARM_OUT_OF_RANGE;
1199 break;
1200 }
1201
1202 flushOemData();
1203
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001204 return IPMI_CC_OK;
1205}
1206
1207//----------------------------------------------------------------------
1208// Get PPR (CMD_OEM_GET_PPR)
1209//----------------------------------------------------------------------
Willy Tue39f9392022-06-15 13:24:20 -07001210ipmi_ret_t ipmiOemGetPpr(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t request,
1211 ipmi_response_t response, ipmi_data_len_t data_len,
1212 ipmi_context_t)
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001213{
Vijay Khemka63c99be2020-05-27 19:14:35 -07001214 uint8_t* req = reinterpret_cast<uint8_t*>(request);
1215 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001216 uint8_t pprCnt, pprIndex;
1217 uint8_t selParam = req[0];
1218 std::stringstream ss;
1219 std::string str;
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001220
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001221 /* Any failure will return zero length data */
1222 *data_len = 0;
1223
1224 switch (selParam)
1225 {
1226 case PPR_ACTION:
1227 res[0] = 0;
1228 *data_len = 1;
1229
1230 if (oemData[KEY_PPR].find(KEY_PPR_ROW_COUNT) !=
1231 oemData[KEY_PPR].end())
1232 {
1233 pprCnt = oemData[KEY_PPR][KEY_PPR_ROW_COUNT];
1234 if (pprCnt != 0)
1235 {
1236 if (oemData[KEY_PPR].find(KEY_PPR_ACTION) !=
1237 oemData[KEY_PPR].end())
1238 {
1239 res[0] = oemData[KEY_PPR][KEY_PPR_ACTION];
1240 }
1241 }
1242 }
1243 break;
1244 case PPR_ROW_COUNT:
1245 res[0] = 0;
1246 *data_len = 1;
1247 if (oemData[KEY_PPR].find(KEY_PPR_ROW_COUNT) !=
1248 oemData[KEY_PPR].end())
1249 res[0] = oemData[KEY_PPR][KEY_PPR_ROW_COUNT];
1250 break;
1251 case PPR_ROW_ADDR:
1252 pprIndex = req[1];
1253 if (pprIndex > 100)
1254 return IPMI_CC_PARM_OUT_OF_RANGE;
1255
1256 ss << std::hex;
1257 ss << std::setw(2) << std::setfill('0') << (int)pprIndex;
1258
1259 if (oemData[KEY_PPR].find(ss.str()) == oemData[KEY_PPR].end())
1260 return IPMI_CC_PARM_OUT_OF_RANGE;
1261
1262 if (oemData[KEY_PPR][ss.str()].find(KEY_PPR_ROW_ADDR) ==
1263 oemData[KEY_PPR][ss.str()].end())
1264 return IPMI_CC_PARM_OUT_OF_RANGE;
1265
1266 str = oemData[KEY_PPR][ss.str()][KEY_PPR_ROW_ADDR];
1267 *data_len = strToBytes(str, res);
1268 break;
1269 case PPR_HISTORY_DATA:
1270 pprIndex = req[1];
1271 if (pprIndex > 100)
1272 return IPMI_CC_PARM_OUT_OF_RANGE;
1273
1274 ss << std::hex;
1275 ss << std::setw(2) << std::setfill('0') << (int)pprIndex;
1276
1277 if (oemData[KEY_PPR].find(ss.str()) == oemData[KEY_PPR].end())
1278 return IPMI_CC_PARM_OUT_OF_RANGE;
1279
1280 if (oemData[KEY_PPR][ss.str()].find(KEY_PPR_HST_DATA) ==
1281 oemData[KEY_PPR][ss.str()].end())
1282 return IPMI_CC_PARM_OUT_OF_RANGE;
1283
1284 str = oemData[KEY_PPR][ss.str()][KEY_PPR_HST_DATA];
1285 *data_len = strToBytes(str, res);
1286 break;
1287 default:
1288 return IPMI_CC_PARM_OUT_OF_RANGE;
1289 break;
1290 }
1291
1292 return IPMI_CC_OK;
1293}
1294
1295/* FB OEM QC Commands */
1296
1297//----------------------------------------------------------------------
1298// Set Proc Info (CMD_OEM_Q_SET_PROC_INFO)
1299//----------------------------------------------------------------------
1300//"Request:
1301// Byte 1:3 – Manufacturer ID – XXYYZZ h, LSB first
1302// Byte 4 – Processor Index, 0 base
1303// Byte 5 – Parameter Selector
1304// Byte 6..N – Configuration parameter data (see below for Parameters
1305// of Processor Information)
1306// Response:
1307// Byte 1 – Completion code
1308//
1309// Parameter#1: (Processor Product Name)
1310//
1311// Byte 1..48 –Product name(ASCII code)
1312// Ex. Intel(R) Xeon(R) CPU E5-2685 v3 @ 2.60GHz
1313//
1314// Param#2: Processor Basic Information
1315// Byte 1 – Core Number
1316// Byte 2 – Thread Number (LSB)
1317// Byte 3 – Thread Number (MSB)
1318// Byte 4 – Processor frequency in MHz (LSB)
1319// Byte 5 – Processor frequency in MHz (MSB)
1320// Byte 6..7 – Revision
1321//
Willy Tue39f9392022-06-15 13:24:20 -07001322ipmi_ret_t ipmiOemQSetProcInfo(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t request,
1323 ipmi_response_t, ipmi_data_len_t data_len,
1324 ipmi_context_t)
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001325{
Vijay Khemka63c99be2020-05-27 19:14:35 -07001326 qProcInfo_t* req = reinterpret_cast<qProcInfo_t*>(request);
1327 uint8_t numParam = sizeof(cpuInfoKey) / sizeof(uint8_t*);
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001328 std::stringstream ss;
1329 std::string str;
1330 uint8_t len = *data_len;
1331
1332 *data_len = 0;
1333
1334 /* check for requested data params */
1335 if (len < 5 || req->paramSel < 1 || req->paramSel >= numParam)
1336 {
1337 phosphor::logging::log<phosphor::logging::level::ERR>(
1338 "Invalid parameter received");
1339 return IPMI_CC_PARM_OUT_OF_RANGE;
1340 }
1341
1342 len = len - 5; // Get Actual data length
1343
1344 ss << std::hex;
1345 ss << std::setw(2) << std::setfill('0') << (int)req->procIndex;
1346 oemData[KEY_Q_PROC_INFO][ss.str()][KEY_PROC_INDEX] = req->procIndex;
1347
1348 str = bytesToStr(req->data, len);
1349 oemData[KEY_Q_PROC_INFO][ss.str()][cpuInfoKey[req->paramSel]] = str.c_str();
1350 flushOemData();
1351
1352 return IPMI_CC_OK;
1353}
1354
1355//----------------------------------------------------------------------
1356// Get Proc Info (CMD_OEM_Q_GET_PROC_INFO)
1357//----------------------------------------------------------------------
1358// Request:
1359// Byte 1:3 – Manufacturer ID – XXYYZZ h, LSB first
1360// Byte 4 – Processor Index, 0 base
1361// Byte 5 – Parameter Selector
1362// Response:
1363// Byte 1 – Completion code
1364// Byte 2..N – Configuration Parameter Data (see below for Parameters
1365// of Processor Information)
1366//
1367// Parameter#1: (Processor Product Name)
1368//
1369// Byte 1..48 –Product name(ASCII code)
1370// Ex. Intel(R) Xeon(R) CPU E5-2685 v3 @ 2.60GHz
1371//
1372// Param#2: Processor Basic Information
1373// Byte 1 – Core Number
1374// Byte 2 – Thread Number (LSB)
1375// Byte 3 – Thread Number (MSB)
1376// Byte 4 – Processor frequency in MHz (LSB)
1377// Byte 5 – Processor frequency in MHz (MSB)
1378// Byte 6..7 – Revision
1379//
Willy Tue39f9392022-06-15 13:24:20 -07001380ipmi_ret_t ipmiOemQGetProcInfo(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t request,
1381 ipmi_response_t response,
1382 ipmi_data_len_t data_len, ipmi_context_t)
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001383{
Vijay Khemka63c99be2020-05-27 19:14:35 -07001384 qProcInfo_t* req = reinterpret_cast<qProcInfo_t*>(request);
1385 uint8_t numParam = sizeof(cpuInfoKey) / sizeof(uint8_t*);
1386 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001387 std::stringstream ss;
1388 std::string str;
1389
1390 *data_len = 0;
1391
1392 /* check for requested data params */
1393 if (req->paramSel < 1 || req->paramSel >= numParam)
1394 {
1395 phosphor::logging::log<phosphor::logging::level::ERR>(
1396 "Invalid parameter received");
1397 return IPMI_CC_PARM_OUT_OF_RANGE;
1398 }
1399
1400 ss << std::hex;
1401 ss << std::setw(2) << std::setfill('0') << (int)req->procIndex;
1402
1403 if (oemData[KEY_Q_PROC_INFO].find(ss.str()) ==
1404 oemData[KEY_Q_PROC_INFO].end())
1405 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
1406
1407 if (oemData[KEY_Q_PROC_INFO][ss.str()].find(cpuInfoKey[req->paramSel]) ==
1408 oemData[KEY_Q_PROC_INFO][ss.str()].end())
1409 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
1410
1411 str = oemData[KEY_Q_PROC_INFO][ss.str()][cpuInfoKey[req->paramSel]];
1412 *data_len = strToBytes(str, res);
1413
1414 return IPMI_CC_OK;
1415}
1416
1417//----------------------------------------------------------------------
1418// Set Dimm Info (CMD_OEM_Q_SET_DIMM_INFO)
1419//----------------------------------------------------------------------
1420// Request:
1421// Byte 1:3 – Manufacturer ID – XXYYZZh, LSB first
1422// Byte 4 – DIMM Index, 0 base
1423// Byte 5 – Parameter Selector
1424// Byte 6..N – Configuration parameter data (see below for Parameters
1425// of DIMM Information)
1426// Response:
1427// Byte 1 – Completion code
1428//
1429// Param#1 (DIMM Location):
1430// Byte 1 – DIMM Present
1431// Byte 1 – DIMM Present
1432// 01h – Present
1433// FFh – Not Present
1434// Byte 2 – Node Number, 0 base
1435// Byte 3 – Channel Number , 0 base
1436// Byte 4 – DIMM Number , 0 base
1437//
1438// Param#2 (DIMM Type):
1439// Byte 1 – DIMM Type
1440// Bit [7:6]
1441// For DDR3
1442// 00 – Normal Voltage (1.5V)
1443// 01 – Ultra Low Voltage (1.25V)
1444// 10 – Low Voltage (1.35V)
1445// 11 – Reserved
1446// For DDR4
1447// 00 – Reserved
1448// 01 – Reserved
1449// 10 – Reserved
1450// 11 – Normal Voltage (1.2V)
1451// Bit [5:0]
1452// 0x00 – SDRAM
1453// 0x01 – DDR-1 RAM
1454// 0x02 – Rambus
1455// 0x03 – DDR-2 RAM
1456// 0x04 – FBDIMM
1457// 0x05 – DDR-3 RAM
1458// 0x06 – DDR-4 RAM
1459//
1460// Param#3 (DIMM Speed):
1461// Byte 1..2 – DIMM speed in MHz, LSB
1462// Byte 3..6 – DIMM size in Mbytes, LSB
1463//
1464// Param#4 (Module Part Number):
1465// Byte 1..20 –Module Part Number (JEDEC Standard No. 21-C)
1466//
1467// Param#5 (Module Serial Number):
1468// Byte 1..4 –Module Serial Number (JEDEC Standard No. 21-C)
1469//
1470// Param#6 (Module Manufacturer ID):
1471// Byte 1 - Module Manufacturer ID, LSB
1472// Byte 2 - Module Manufacturer ID, MSB
1473//
Willy Tue39f9392022-06-15 13:24:20 -07001474ipmi_ret_t ipmiOemQSetDimmInfo(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t request,
1475 ipmi_response_t, ipmi_data_len_t data_len,
1476 ipmi_context_t)
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001477{
Vijay Khemka63c99be2020-05-27 19:14:35 -07001478 qDimmInfo_t* req = reinterpret_cast<qDimmInfo_t*>(request);
1479 uint8_t numParam = sizeof(dimmInfoKey) / sizeof(uint8_t*);
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001480 std::stringstream ss;
1481 std::string str;
1482 uint8_t len = *data_len;
1483
1484 *data_len = 0;
1485
1486 /* check for requested data params */
1487 if (len < 5 || req->paramSel < 1 || req->paramSel >= numParam)
1488 {
1489 phosphor::logging::log<phosphor::logging::level::ERR>(
1490 "Invalid parameter received");
1491 return IPMI_CC_PARM_OUT_OF_RANGE;
1492 }
1493
1494 len = len - 5; // Get Actual data length
1495
1496 ss << std::hex;
1497 ss << std::setw(2) << std::setfill('0') << (int)req->dimmIndex;
1498 oemData[KEY_Q_DIMM_INFO][ss.str()][KEY_DIMM_INDEX] = req->dimmIndex;
1499
1500 str = bytesToStr(req->data, len);
1501 oemData[KEY_Q_DIMM_INFO][ss.str()][dimmInfoKey[req->paramSel]] =
1502 str.c_str();
1503 flushOemData();
1504
1505 return IPMI_CC_OK;
1506}
1507
1508//----------------------------------------------------------------------
1509// Get Dimm Info (CMD_OEM_Q_GET_DIMM_INFO)
1510//----------------------------------------------------------------------
1511// Request:
1512// Byte 1:3 – Manufacturer ID – XXYYZZh, LSB first
1513// Byte 4 – DIMM Index, 0 base
1514// Byte 5 – Parameter Selector
1515// Byte 6..N – Configuration parameter data (see below for Parameters
1516// of DIMM Information)
1517// Response:
1518// Byte 1 – Completion code
1519// Byte 2..N – Configuration Parameter Data (see Table_1213h Parameters
1520// of DIMM Information)
1521//
1522// Param#1 (DIMM Location):
1523// Byte 1 – DIMM Present
1524// Byte 1 – DIMM Present
1525// 01h – Present
1526// FFh – Not Present
1527// Byte 2 – Node Number, 0 base
1528// Byte 3 – Channel Number , 0 base
1529// Byte 4 – DIMM Number , 0 base
1530//
1531// Param#2 (DIMM Type):
1532// Byte 1 – DIMM Type
1533// Bit [7:6]
1534// For DDR3
1535// 00 – Normal Voltage (1.5V)
1536// 01 – Ultra Low Voltage (1.25V)
1537// 10 – Low Voltage (1.35V)
1538// 11 – Reserved
1539// For DDR4
1540// 00 – Reserved
1541// 01 – Reserved
1542// 10 – Reserved
1543// 11 – Normal Voltage (1.2V)
1544// Bit [5:0]
1545// 0x00 – SDRAM
1546// 0x01 – DDR-1 RAM
1547// 0x02 – Rambus
1548// 0x03 – DDR-2 RAM
1549// 0x04 – FBDIMM
1550// 0x05 – DDR-3 RAM
1551// 0x06 – DDR-4 RAM
1552//
1553// Param#3 (DIMM Speed):
1554// Byte 1..2 – DIMM speed in MHz, LSB
1555// Byte 3..6 – DIMM size in Mbytes, LSB
1556//
1557// Param#4 (Module Part Number):
1558// Byte 1..20 –Module Part Number (JEDEC Standard No. 21-C)
1559//
1560// Param#5 (Module Serial Number):
1561// Byte 1..4 –Module Serial Number (JEDEC Standard No. 21-C)
1562//
1563// Param#6 (Module Manufacturer ID):
1564// Byte 1 - Module Manufacturer ID, LSB
1565// Byte 2 - Module Manufacturer ID, MSB
1566//
Willy Tue39f9392022-06-15 13:24:20 -07001567ipmi_ret_t ipmiOemQGetDimmInfo(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t request,
1568 ipmi_response_t response,
1569 ipmi_data_len_t data_len, ipmi_context_t)
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001570{
Vijay Khemka63c99be2020-05-27 19:14:35 -07001571 qDimmInfo_t* req = reinterpret_cast<qDimmInfo_t*>(request);
1572 uint8_t numParam = sizeof(dimmInfoKey) / sizeof(uint8_t*);
1573 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001574 std::stringstream ss;
1575 std::string str;
1576
1577 *data_len = 0;
1578
1579 /* check for requested data params */
1580 if (req->paramSel < 1 || req->paramSel >= numParam)
1581 {
1582 phosphor::logging::log<phosphor::logging::level::ERR>(
1583 "Invalid parameter received");
1584 return IPMI_CC_PARM_OUT_OF_RANGE;
1585 }
1586
1587 ss << std::hex;
1588 ss << std::setw(2) << std::setfill('0') << (int)req->dimmIndex;
1589
1590 if (oemData[KEY_Q_DIMM_INFO].find(ss.str()) ==
1591 oemData[KEY_Q_DIMM_INFO].end())
1592 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
1593
1594 if (oemData[KEY_Q_DIMM_INFO][ss.str()].find(dimmInfoKey[req->paramSel]) ==
1595 oemData[KEY_Q_DIMM_INFO][ss.str()].end())
1596 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
1597
1598 str = oemData[KEY_Q_DIMM_INFO][ss.str()][dimmInfoKey[req->paramSel]];
1599 *data_len = strToBytes(str, res);
1600
1601 return IPMI_CC_OK;
1602}
1603
1604//----------------------------------------------------------------------
1605// Set Drive Info (CMD_OEM_Q_SET_DRIVE_INFO)
1606//----------------------------------------------------------------------
1607// BIOS issue this command to provide HDD information to BMC.
1608//
1609// BIOS just can get information by standard ATA / SMART command for
1610// OB SATA controller.
1611// BIOS can get
1612// 1. Serial Number
1613// 2. Model Name
1614// 3. HDD FW Version
1615// 4. HDD Capacity
1616// 5. HDD WWN
1617//
1618// Use Get HDD info Param #5 to know the MAX HDD info index.
1619//
1620// Request:
1621// Byte 1:3 – Quanta Manufacturer ID – 001C4Ch, LSB first
1622// Byte 4 –
1623// [7:4] Reserved
1624// [3:0] HDD Controller Type
1625// 0x00 – BIOS
1626// 0x01 – Expander
1627// 0x02 – LSI
1628// Byte 5 – HDD Info Index, 0 base
1629// Byte 6 – Parameter Selector
1630// Byte 7..N – Configuration parameter data (see Table_1415h Parameters of HDD
1631// Information)
1632//
1633// Response:
1634// Byte 1 – Completion Code
1635//
1636// Param#0 (HDD Location):
1637// Byte 1 – Controller
1638// [7:3] Device Number
1639// [2:0] Function Number
1640// For Intel C610 series (Wellsburg)
1641// D31:F2 (0xFA) – SATA control 1
1642// D31:F5 (0xFD) – SATA control 2
1643// D17:F4 (0x8C) – sSata control
1644// Byte 2 – Port Number
1645// Byte 3 – Location (0xFF: No HDD Present)
1646// BIOS default set Byte 3 to 0xFF, if No HDD Present. And then skip send param
1647// #1~4, #6, #7 to BMC (still send param #5) BIOS default set Byte 3 to 0, if
1648// the HDD present. BMC or other people who know the HDD location has
1649// responsibility for update Location info
1650//
1651// Param#1 (Serial Number):
1652// Bytes 1..33: HDD Serial Number
1653//
1654// Param#2 (Model Name):
1655// Byte 1..33 – HDD Model Name
1656//
1657// Param#3 (HDD FW Version):
1658// Byte 1..17 –HDD FW version
1659//
1660// Param#4 (Capacity):
1661// Byte 1..4 –HDD Block Size, LSB
1662// Byte 5..12 - HDD Block Number, LSB
1663// HDD Capacity = HDD Block size * HDD BLock number (Unit Byte)
1664//
1665// Param#5 (Max HDD Quantity):
1666// Byte 1 - Max HDD Quantity
1667// Max supported port numbers in this PCH
1668//
1669// Param#6 (HDD Type)
1670// Byte 1 – HDD Type
1671// 0h – Reserved
1672// 1h – SAS
1673// 2h – SATA
1674// 3h – PCIE SSD (NVME)
1675//
1676// Param#7 (HDD WWN)
1677// Data 1...8: HDD World Wide Name, LSB
1678//
Willy Tue39f9392022-06-15 13:24:20 -07001679ipmi_ret_t ipmiOemQSetDriveInfo(ipmi_netfn_t, ipmi_cmd_t,
1680 ipmi_request_t request, ipmi_response_t,
1681 ipmi_data_len_t data_len, ipmi_context_t)
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001682{
Vijay Khemka63c99be2020-05-27 19:14:35 -07001683 qDriveInfo_t* req = reinterpret_cast<qDriveInfo_t*>(request);
1684 uint8_t numParam = sizeof(driveInfoKey) / sizeof(uint8_t*);
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001685 uint8_t ctrlType = req->hddCtrlType & 0x0f;
1686 std::stringstream ss;
1687 std::string str;
1688 uint8_t len = *data_len;
1689
1690 *data_len = 0;
1691
1692 /* check for requested data params */
1693 if (len < 6 || req->paramSel < 1 || req->paramSel >= numParam ||
1694 ctrlType > 2)
1695 {
1696 phosphor::logging::log<phosphor::logging::level::ERR>(
1697 "Invalid parameter received");
1698 return IPMI_CC_PARM_OUT_OF_RANGE;
1699 }
1700
1701 len = len - 6; // Get Actual data length
1702
1703 ss << std::hex;
1704 ss << std::setw(2) << std::setfill('0') << (int)req->hddIndex;
1705 oemData[KEY_Q_DRIVE_INFO][KEY_HDD_CTRL_TYPE] = req->hddCtrlType;
1706 oemData[KEY_Q_DRIVE_INFO][ctrlTypeKey[ctrlType]][ss.str()][KEY_HDD_INDEX] =
1707 req->hddIndex;
1708
1709 str = bytesToStr(req->data, len);
1710 oemData[KEY_Q_DRIVE_INFO][ctrlTypeKey[ctrlType]][ss.str()]
1711 [driveInfoKey[req->paramSel]] = str.c_str();
1712 flushOemData();
1713
1714 return IPMI_CC_OK;
1715}
1716
1717//----------------------------------------------------------------------
1718// Get Drive Info (CMD_OEM_Q_GET_DRIVE_INFO)
1719//----------------------------------------------------------------------
1720// BMC needs to check HDD presented or not first. If NOT presented, return
1721// completion code 0xD5.
1722//
1723// Request:
1724// Byte 1:3 – Quanta Manufacturer ID – 001C4Ch, LSB first
1725// Byte 4 –
1726//[7:4] Reserved
1727//[3:0] HDD Controller Type
1728// 0x00 – BIOS
1729// 0x01 – Expander
1730// 0x02 – LSI
1731// Byte 5 – HDD Index, 0 base
1732// Byte 6 – Parameter Selector (See Above Set HDD Information)
1733// Response:
1734// Byte 1 – Completion Code
1735// 0xD5 – Not support in current status (HDD Not Present)
1736// Byte 2..N – Configuration parameter data (see Table_1415h Parameters of HDD
1737// Information)
1738//
Willy Tue39f9392022-06-15 13:24:20 -07001739ipmi_ret_t ipmiOemQGetDriveInfo(ipmi_netfn_t, ipmi_cmd_t,
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001740 ipmi_request_t request,
1741 ipmi_response_t response,
Willy Tue39f9392022-06-15 13:24:20 -07001742 ipmi_data_len_t data_len, ipmi_context_t)
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001743{
Vijay Khemka63c99be2020-05-27 19:14:35 -07001744 qDriveInfo_t* req = reinterpret_cast<qDriveInfo_t*>(request);
1745 uint8_t numParam = sizeof(driveInfoKey) / sizeof(uint8_t*);
1746 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001747 uint8_t ctrlType = req->hddCtrlType & 0x0f;
1748 std::stringstream ss;
1749 std::string str;
1750
1751 *data_len = 0;
1752
1753 /* check for requested data params */
1754 if (req->paramSel < 1 || req->paramSel >= numParam || ctrlType > 2)
1755 {
1756 phosphor::logging::log<phosphor::logging::level::ERR>(
1757 "Invalid parameter received");
1758 return IPMI_CC_PARM_OUT_OF_RANGE;
1759 }
1760
1761 if (oemData[KEY_Q_DRIVE_INFO].find(ctrlTypeKey[ctrlType]) ==
1762 oemData[KEY_Q_DRIVE_INFO].end())
1763 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
1764
1765 ss << std::hex;
1766 ss << std::setw(2) << std::setfill('0') << (int)req->hddIndex;
1767
1768 if (oemData[KEY_Q_DRIVE_INFO][ctrlTypeKey[ctrlType]].find(ss.str()) ==
1769 oemData[KEY_Q_DRIVE_INFO].end())
1770 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
1771
1772 if (oemData[KEY_Q_DRIVE_INFO][ctrlTypeKey[ctrlType]][ss.str()].find(
1773 dimmInfoKey[req->paramSel]) ==
1774 oemData[KEY_Q_DRIVE_INFO][ss.str()].end())
1775 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
1776
1777 str = oemData[KEY_Q_DRIVE_INFO][ctrlTypeKey[ctrlType]][ss.str()]
1778 [dimmInfoKey[req->paramSel]];
1779 *data_len = strToBytes(str, res);
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001780
1781 return IPMI_CC_OK;
1782}
1783
Vijay Khemkadd14c0f2020-03-18 14:48:13 -07001784/* Helper function for sending DCMI commands to ME and getting response back */
1785ipmi::RspType<std::vector<uint8_t>> sendDCMICmd(uint8_t cmd,
Vijay Khemka63c99be2020-05-27 19:14:35 -07001786 std::vector<uint8_t>& cmdData)
Vijay Khemkadd14c0f2020-03-18 14:48:13 -07001787{
1788 std::vector<uint8_t> respData;
1789
1790 /* Add group id as first byte to request for ME command */
1791 cmdData.insert(cmdData.begin(), groupDCMI);
1792
1793 if (sendMeCmd(ipmi::netFnGroup, cmd, cmdData, respData))
1794 return ipmi::responseUnspecifiedError();
1795
1796 /* Remove group id as first byte as it will be added by IPMID */
1797 respData.erase(respData.begin());
1798
1799 return ipmi::responseSuccess(std::move(respData));
1800}
1801
1802/* DCMI Command handellers. */
1803
1804ipmi::RspType<std::vector<uint8_t>>
1805 ipmiOemDCMIGetPowerReading(std::vector<uint8_t> reqData)
1806{
1807 return sendDCMICmd(ipmi::dcmi::cmdGetPowerReading, reqData);
1808}
1809
1810ipmi::RspType<std::vector<uint8_t>>
1811 ipmiOemDCMIGetPowerLimit(std::vector<uint8_t> reqData)
1812{
1813 return sendDCMICmd(ipmi::dcmi::cmdGetPowerLimit, reqData);
1814}
1815
1816ipmi::RspType<std::vector<uint8_t>>
1817 ipmiOemDCMISetPowerLimit(std::vector<uint8_t> reqData)
1818{
1819 return sendDCMICmd(ipmi::dcmi::cmdSetPowerLimit, reqData);
1820}
1821
1822ipmi::RspType<std::vector<uint8_t>>
1823 ipmiOemDCMIApplyPowerLimit(std::vector<uint8_t> reqData)
1824{
1825 return sendDCMICmd(ipmi::dcmi::cmdActDeactivatePwrLimit, reqData);
1826}
1827
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001828static void registerOEMFunctions(void)
1829{
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001830 /* Get OEM data from json file */
1831 std::ifstream file(JSON_OEM_DATA_FILE);
1832 if (file)
Vijay Khemkafeaa9812019-08-27 15:08:08 -07001833 {
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001834 file >> oemData;
Vijay Khemkafeaa9812019-08-27 15:08:08 -07001835 file.close();
1836 }
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001837
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001838 phosphor::logging::log<phosphor::logging::level::INFO>(
1839 "Registering OEM commands");
Vijay Khemka7c0aea42020-03-05 13:31:53 -08001840
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001841 ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, CMD_OEM_USB_DBG_GET_FRAME_INFO,
1842 NULL, ipmiOemDbgGetFrameInfo,
1843 PRIVILEGE_USER); // get debug frame info
1844 ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ,
1845 CMD_OEM_USB_DBG_GET_UPDATED_FRAMES, NULL,
1846 ipmiOemDbgGetUpdFrames,
1847 PRIVILEGE_USER); // get debug updated frames
1848 ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, CMD_OEM_USB_DBG_GET_POST_DESC,
1849 NULL, ipmiOemDbgGetPostDesc,
1850 PRIVILEGE_USER); // get debug post description
1851 ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, CMD_OEM_USB_DBG_GET_GPIO_DESC,
1852 NULL, ipmiOemDbgGetGpioDesc,
1853 PRIVILEGE_USER); // get debug gpio description
1854 ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, CMD_OEM_USB_DBG_GET_FRAME_DATA,
1855 NULL, ipmiOemDbgGetFrameData,
1856 PRIVILEGE_USER); // get debug frame data
1857 ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, CMD_OEM_USB_DBG_CTRL_PANEL,
1858 NULL, ipmiOemDbgGetCtrlPanel,
1859 PRIVILEGE_USER); // get debug control panel
1860 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_DIMM_INFO, NULL,
1861 ipmiOemSetDimmInfo,
1862 PRIVILEGE_USER); // Set Dimm Info
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001863 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_GET_BOARD_ID, NULL,
1864 ipmiOemGetBoardID,
1865 PRIVILEGE_USER); // Get Board ID
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001866 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_MACHINE_CONFIG_INFO, NULL,
1867 ipmiOemSetMachineCfgInfo,
1868 PRIVILEGE_USER); // Set Machine Config Info
1869 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_POST_START, NULL,
1870 ipmiOemSetPostStart,
1871 PRIVILEGE_USER); // Set POST start
1872 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_POST_END, NULL,
1873 ipmiOemSetPostEnd,
1874 PRIVILEGE_USER); // Set POST End
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001875 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_PPIN_INFO, NULL,
1876 ipmiOemSetPPINInfo,
1877 PRIVILEGE_USER); // Set PPIN Info
Manikandan Elumalai5f8e3432020-12-02 03:46:55 +05301878#if BIC_ENABLED
1879
1880 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnOemOne,
1881 ipmi::cmdSetSystemGuid, ipmi::Privilege::User,
1882 ipmiOemSetSystemGuid);
1883#else
1884
Vijay Khemkaf2246ce2020-05-27 14:26:35 -07001885 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_SYSTEM_GUID, NULL,
1886 ipmiOemSetSystemGuid,
1887 PRIVILEGE_USER); // Set System GUID
Manikandan Elumalai5f8e3432020-12-02 03:46:55 +05301888#endif
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001889 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_ADR_TRIGGER, NULL,
1890 ipmiOemSetAdrTrigger,
1891 PRIVILEGE_USER); // Set ADR Trigger
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001892 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_BIOS_FLASH_INFO, NULL,
1893 ipmiOemSetBiosFlashInfo,
1894 PRIVILEGE_USER); // Set Bios Flash Info
1895 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_PPR, NULL, ipmiOemSetPpr,
1896 PRIVILEGE_USER); // Set PPR
1897 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_GET_PPR, NULL, ipmiOemGetPpr,
1898 PRIVILEGE_USER); // Get PPR
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001899 /* FB OEM QC Commands */
1900 ipmiPrintAndRegister(NETFUN_FB_OEM_QC, CMD_OEM_Q_SET_PROC_INFO, NULL,
1901 ipmiOemQSetProcInfo,
1902 PRIVILEGE_USER); // Set Proc Info
1903 ipmiPrintAndRegister(NETFUN_FB_OEM_QC, CMD_OEM_Q_GET_PROC_INFO, NULL,
1904 ipmiOemQGetProcInfo,
1905 PRIVILEGE_USER); // Get Proc Info
1906 ipmiPrintAndRegister(NETFUN_FB_OEM_QC, CMD_OEM_Q_SET_DIMM_INFO, NULL,
1907 ipmiOemQSetDimmInfo,
1908 PRIVILEGE_USER); // Set Dimm Info
1909 ipmiPrintAndRegister(NETFUN_FB_OEM_QC, CMD_OEM_Q_GET_DIMM_INFO, NULL,
1910 ipmiOemQGetDimmInfo,
1911 PRIVILEGE_USER); // Get Dimm Info
1912 ipmiPrintAndRegister(NETFUN_FB_OEM_QC, CMD_OEM_Q_SET_DRIVE_INFO, NULL,
1913 ipmiOemQSetDriveInfo,
1914 PRIVILEGE_USER); // Set Drive Info
1915 ipmiPrintAndRegister(NETFUN_FB_OEM_QC, CMD_OEM_Q_GET_DRIVE_INFO, NULL,
1916 ipmiOemQGetDriveInfo,
1917 PRIVILEGE_USER); // Get Drive Info
Vijay Khemkadd14c0f2020-03-18 14:48:13 -07001918
1919 /* FB OEM DCMI Commands as per DCMI spec 1.5 Section 6 */
1920 ipmi::registerGroupHandler(ipmi::prioOpenBmcBase, groupDCMI,
1921 ipmi::dcmi::cmdGetPowerReading,
1922 ipmi::Privilege::User,
1923 ipmiOemDCMIGetPowerReading); // Get Power Reading
1924
1925 ipmi::registerGroupHandler(ipmi::prioOpenBmcBase, groupDCMI,
1926 ipmi::dcmi::cmdGetPowerLimit,
1927 ipmi::Privilege::User,
1928 ipmiOemDCMIGetPowerLimit); // Get Power Limit
1929
1930 ipmi::registerGroupHandler(ipmi::prioOpenBmcBase, groupDCMI,
1931 ipmi::dcmi::cmdSetPowerLimit,
1932 ipmi::Privilege::Operator,
1933 ipmiOemDCMISetPowerLimit); // Set Power Limit
1934
1935 ipmi::registerGroupHandler(ipmi::prioOpenBmcBase, groupDCMI,
1936 ipmi::dcmi::cmdActDeactivatePwrLimit,
1937 ipmi::Privilege::Operator,
1938 ipmiOemDCMIApplyPowerLimit); // Apply Power Limit
1939
Jayashree-Df0cf6652020-11-30 11:03:30 +05301940 /* FB OEM BOOT ORDER COMMANDS */
1941 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnOemOne,
1942 CMD_OEM_GET_BOOT_ORDER, ipmi::Privilege::User,
1943 ipmiOemGetBootOrder); // Get Boot Order
1944
1945 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnOemOne,
1946 CMD_OEM_SET_BOOT_ORDER, ipmi::Privilege::User,
1947 ipmiOemSetBootOrder); // Set Boot Order
1948
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001949 return;
1950}
1951
1952} // namespace ipmi