blob: abcfc831e99e0fa82f87d000a155471ec19f7cef [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;
272 int i;
273
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//----------------------------------------------------------------------
427ipmi_ret_t ipmiOemDbgGetFrameInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
428 ipmi_request_t request,
429 ipmi_response_t response,
430 ipmi_data_len_t data_len,
431 ipmi_context_t context)
432{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700433 uint8_t* req = reinterpret_cast<uint8_t*>(request);
434 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800435 uint8_t num_frames = 3;
436
437 std::memcpy(res, req, SIZE_IANA_ID); // IANA ID
438 res[SIZE_IANA_ID] = num_frames;
439 *data_len = SIZE_IANA_ID + 1;
440
441 return IPMI_CC_OK;
442}
443
444//----------------------------------------------------------------------
445// Get Debug Updated Frames
446//----------------------------------------------------------------------
447ipmi_ret_t ipmiOemDbgGetUpdFrames(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
448 ipmi_request_t request,
449 ipmi_response_t response,
450 ipmi_data_len_t data_len,
451 ipmi_context_t context)
452{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700453 uint8_t* req = reinterpret_cast<uint8_t*>(request);
454 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800455 uint8_t num_updates = 3;
456 *data_len = 4;
457
458 std::memcpy(res, req, SIZE_IANA_ID); // IANA ID
459 res[SIZE_IANA_ID] = num_updates;
460 *data_len = SIZE_IANA_ID + num_updates + 1;
461 res[SIZE_IANA_ID + 1] = 1; // info page update
462 res[SIZE_IANA_ID + 2] = 2; // cri sel update
463 res[SIZE_IANA_ID + 3] = 3; // cri sensor update
464
465 return IPMI_CC_OK;
466}
467
468//----------------------------------------------------------------------
469// Get Debug POST Description
470//----------------------------------------------------------------------
471ipmi_ret_t ipmiOemDbgGetPostDesc(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
472 ipmi_request_t request,
473 ipmi_response_t response,
474 ipmi_data_len_t data_len,
475 ipmi_context_t context)
476{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700477 uint8_t* req = reinterpret_cast<uint8_t*>(request);
478 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800479 uint8_t index = 0;
480 uint8_t next = 0;
481 uint8_t end = 0;
482 uint8_t phase = 0;
Vijay Khemkacc0d6d92019-08-27 14:51:17 -0700483 uint8_t descLen = 0;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800484 int ret;
485
486 index = req[3];
487 phase = req[4];
488
Vijay Khemkacc0d6d92019-08-27 14:51:17 -0700489 ret = plat_udbg_get_post_desc(index, &next, phase, &end, &descLen, &res[8]);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800490 if (ret)
491 {
492 memcpy(res, req, SIZE_IANA_ID); // IANA ID
493 *data_len = SIZE_IANA_ID;
494 return IPMI_CC_UNSPECIFIED_ERROR;
495 }
496
497 memcpy(res, req, SIZE_IANA_ID); // IANA ID
498 res[3] = index;
499 res[4] = next;
500 res[5] = phase;
501 res[6] = end;
Vijay Khemkacc0d6d92019-08-27 14:51:17 -0700502 res[7] = descLen;
503 *data_len = SIZE_IANA_ID + 5 + descLen;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800504
505 return IPMI_CC_OK;
506}
507
508//----------------------------------------------------------------------
509// Get Debug GPIO Description
510//----------------------------------------------------------------------
511ipmi_ret_t ipmiOemDbgGetGpioDesc(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
512 ipmi_request_t request,
513 ipmi_response_t response,
514 ipmi_data_len_t data_len,
515 ipmi_context_t context)
516{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700517 uint8_t* req = reinterpret_cast<uint8_t*>(request);
518 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800519
Vijay Khemka38183d62019-08-28 16:19:33 -0700520 uint8_t index = 0;
521 uint8_t next = 0;
522 uint8_t level = 0;
523 uint8_t pinDef = 0;
524 uint8_t descLen = 0;
525 int ret;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800526
Vijay Khemka38183d62019-08-28 16:19:33 -0700527 index = req[3];
528
529 ret = plat_udbg_get_gpio_desc(index, &next, &level, &pinDef, &descLen,
530 &res[8]);
531 if (ret)
532 {
533 memcpy(res, req, SIZE_IANA_ID); // IANA ID
534 *data_len = SIZE_IANA_ID;
535 return IPMI_CC_UNSPECIFIED_ERROR;
536 }
537
538 memcpy(res, req, SIZE_IANA_ID); // IANA ID
539 res[3] = index;
540 res[4] = next;
541 res[5] = level;
542 res[6] = pinDef;
543 res[7] = descLen;
544 *data_len = SIZE_IANA_ID + 5 + descLen;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800545
546 return IPMI_CC_OK;
547}
548
549//----------------------------------------------------------------------
550// Get Debug Frame Data
551//----------------------------------------------------------------------
552ipmi_ret_t ipmiOemDbgGetFrameData(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
553 ipmi_request_t request,
554 ipmi_response_t response,
555 ipmi_data_len_t data_len,
556 ipmi_context_t context)
557{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700558 uint8_t* req = reinterpret_cast<uint8_t*>(request);
559 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800560 uint8_t frame;
561 uint8_t page;
562 uint8_t next;
563 uint8_t count;
564 int ret;
565
566 frame = req[3];
567 page = req[4];
568 int fr = frame;
569 int pg = page;
570
571 ret = plat_udbg_get_frame_data(frame, page, &next, &count, &res[7]);
572 if (ret)
573 {
574 memcpy(res, req, SIZE_IANA_ID); // IANA ID
575 *data_len = SIZE_IANA_ID;
576 return IPMI_CC_UNSPECIFIED_ERROR;
577 }
578
579 memcpy(res, req, SIZE_IANA_ID); // IANA ID
580 res[3] = frame;
581 res[4] = page;
582 res[5] = next;
583 res[6] = count;
584 *data_len = SIZE_IANA_ID + 4 + count;
585
586 return IPMI_CC_OK;
587}
588
589//----------------------------------------------------------------------
590// Get Debug Control Panel
591//----------------------------------------------------------------------
592ipmi_ret_t ipmiOemDbgGetCtrlPanel(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
593 ipmi_request_t request,
594 ipmi_response_t response,
595 ipmi_data_len_t data_len,
596 ipmi_context_t context)
597{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700598 uint8_t* req = reinterpret_cast<uint8_t*>(request);
599 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800600
601 uint8_t panel;
602 uint8_t operation;
603 uint8_t item;
604 uint8_t count;
605 ipmi_ret_t ret;
606
607 panel = req[3];
608 operation = req[4];
609 item = req[5];
610
611 ret = plat_udbg_control_panel(panel, operation, item, &count, &res[3]);
612
613 std::memcpy(res, req, SIZE_IANA_ID); // IANA ID
614 *data_len = SIZE_IANA_ID + count;
615
616 return ret;
617}
618
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800619//----------------------------------------------------------------------
620// Set Dimm Info (CMD_OEM_SET_DIMM_INFO)
621//----------------------------------------------------------------------
622ipmi_ret_t ipmiOemSetDimmInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
623 ipmi_request_t request, ipmi_response_t response,
624 ipmi_data_len_t data_len, ipmi_context_t context)
625{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700626 uint8_t* req = reinterpret_cast<uint8_t*>(request);
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700627
628 uint8_t index = req[0];
629 uint8_t type = req[1];
630 uint16_t speed;
631 uint32_t size;
632
633 memcpy(&speed, &req[2], 2);
634 memcpy(&size, &req[4], 4);
635
636 std::stringstream ss;
637 ss << std::hex;
638 ss << std::setw(2) << std::setfill('0') << (int)index;
639
640 oemData[KEY_SYS_CONFIG][ss.str()][KEY_DIMM_INDEX] = index;
641 oemData[KEY_SYS_CONFIG][ss.str()][KEY_DIMM_TYPE] = type;
642 oemData[KEY_SYS_CONFIG][ss.str()][KEY_DIMM_SPEED] = speed;
643 oemData[KEY_SYS_CONFIG][ss.str()][KEY_DIMM_SIZE] = size;
644
645 flushOemData();
646
647 *data_len = 0;
648
649 return IPMI_CC_OK;
650}
651
652//----------------------------------------------------------------------
653// Get Board ID (CMD_OEM_GET_BOARD_ID)
654//----------------------------------------------------------------------
655ipmi_ret_t ipmiOemGetBoardID(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
656 ipmi_request_t request, ipmi_response_t response,
657 ipmi_data_len_t data_len, ipmi_context_t context)
658{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700659 uint8_t* req = reinterpret_cast<uint8_t*>(request);
660 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800661
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700662 /* TODO: Needs to implement this after GPIO implementation */
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800663 *data_len = 0;
664
665 return IPMI_CC_OK;
666}
667
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800668/* Helper functions to set boot order */
Jayashree-Df0cf6652020-11-30 11:03:30 +0530669void setBootOrder(std::string bootObjPath, uint8_t* data,
670 std::string bootOrderKey)
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800671{
Jayashree-Df0cf6652020-11-30 11:03:30 +0530672 std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
673
674 // SETTING BOOT MODE PROPERTY
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530675 uint8_t bootModeBit = data[0] & 0x06;
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530676 auto bootValue = ipmi::boot::modeIpmiToDbus.at(bootModeBit);
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530677
Jayashree-Df0cf6652020-11-30 11:03:30 +0530678 std::string bootOption =
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530679 sdbusplus::message::convert_to_string<boot::BootMode>(bootValue);
Jayashree-Df0cf6652020-11-30 11:03:30 +0530680
681 std::string service =
682 getService(*dbus, ipmi::boot::bootModeIntf, bootObjPath);
683 setDbusProperty(*dbus, service, bootObjPath, ipmi::boot::bootModeIntf,
684 ipmi::boot::bootModeProp, bootOption);
685
686 // SETTING BOOT SOURCE PROPERTY
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530687 auto bootOrder = ipmi::boot::sourceIpmiToDbus.at(data[1]);
Jayashree-Df0cf6652020-11-30 11:03:30 +0530688 std::string bootSource =
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530689 sdbusplus::message::convert_to_string<boot::BootSource>(bootOrder);
Jayashree-Df0cf6652020-11-30 11:03:30 +0530690
691 service = getService(*dbus, ipmi::boot::bootSourceIntf, bootObjPath);
692 setDbusProperty(*dbus, service, bootObjPath, ipmi::boot::bootSourceIntf,
693 ipmi::boot::bootSourceProp, bootSource);
694
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530695 // SETTING BOOT TYPE PROPERTY
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530696 uint8_t bootTypeBit = data[0] & 0x01;
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530697 auto bootTypeVal = ipmi::boot::typeIpmiToDbus.at(bootTypeBit);
698
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530699 std::string bootType =
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530700 sdbusplus::message::convert_to_string<boot::BootType>(bootTypeVal);
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530701
702 service = getService(*dbus, ipmi::boot::bootTypeIntf, bootObjPath);
703
704 setDbusProperty(*dbus, service, bootObjPath, ipmi::boot::bootTypeIntf,
705 ipmi::boot::bootTypeProp, bootType);
706
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800707 nlohmann::json bootMode;
708 uint8_t mode = data[0];
709 int i;
710
711 bootMode["UEFI"] = (mode & BOOT_MODE_UEFI ? true : false);
712 bootMode["CMOS_CLR"] = (mode & BOOT_MODE_CMOS_CLR ? true : false);
713 bootMode["FORCE_BOOT"] = (mode & BOOT_MODE_FORCE_BOOT ? true : false);
714 bootMode["BOOT_FLAG"] = (mode & BOOT_MODE_BOOT_FLAG ? true : false);
Jayashree-Df0cf6652020-11-30 11:03:30 +0530715 oemData[bootOrderKey][KEY_BOOT_MODE] = bootMode;
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800716
717 /* Initialize boot sequence array */
Jayashree-Df0cf6652020-11-30 11:03:30 +0530718 oemData[bootOrderKey][KEY_BOOT_SEQ] = {};
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800719 for (i = 1; i < SIZE_BOOT_ORDER; i++)
720 {
721 if (data[i] >= BOOT_SEQ_ARRAY_SIZE)
Jayashree-Df0cf6652020-11-30 11:03:30 +0530722 oemData[bootOrderKey][KEY_BOOT_SEQ][i - 1] = "NA";
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800723 else
Jayashree-Df0cf6652020-11-30 11:03:30 +0530724 oemData[bootOrderKey][KEY_BOOT_SEQ][i - 1] = bootSeq[data[i]];
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800725 }
726
727 flushOemData();
728}
729
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800730//----------------------------------------------------------------------
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700731// Set Boot Order (CMD_OEM_SET_BOOT_ORDER)
732//----------------------------------------------------------------------
Jayashree-Df0cf6652020-11-30 11:03:30 +0530733ipmi::RspType<std::vector<uint8_t>>
734 ipmiOemSetBootOrder(ipmi::Context::ptr ctx, std::vector<uint8_t> data)
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700735{
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700736
Jayashree-Df0cf6652020-11-30 11:03:30 +0530737 uint8_t bootSeq[SIZE_BOOT_ORDER];
738 size_t len = data.size();
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700739
740 if (len != SIZE_BOOT_ORDER)
741 {
742 phosphor::logging::log<phosphor::logging::level::ERR>(
743 "Invalid Boot order length received");
Jayashree-Df0cf6652020-11-30 11:03:30 +0530744 return ipmi::responseReqDataLenInvalid();
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700745 }
746
Jayashree-Df0cf6652020-11-30 11:03:30 +0530747 std::copy(std::begin(data), std::end(data), bootSeq);
748 std::optional<size_t> hostId = ipmi::boot::findHost(ctx->hostIdx);
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700749
Jayashree-Df0cf6652020-11-30 11:03:30 +0530750 if (!hostId)
751 {
752 phosphor::logging::log<phosphor::logging::level::ERR>(
753 "Invalid Host Id received");
754 return ipmi::responseInvalidCommand();
755 }
756 auto [bootObjPath, hostName] = ipmi::boot::objPath(*hostId);
757
758 setBootOrder(bootObjPath, bootSeq, hostName);
759
760 return ipmi::responseSuccess(data);
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700761}
762
763//----------------------------------------------------------------------
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800764// Get Boot Order (CMD_OEM_GET_BOOT_ORDER)
765//----------------------------------------------------------------------
Jayashree-Df0cf6652020-11-30 11:03:30 +0530766ipmi::RspType<uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t>
767 ipmiOemGetBootOrder(ipmi::Context::ptr ctx)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800768{
Jayashree-Df0cf6652020-11-30 11:03:30 +0530769 uint8_t bootSeq[SIZE_BOOT_ORDER];
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700770 uint8_t mode = 0;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800771
Jayashree-Df0cf6652020-11-30 11:03:30 +0530772 std::optional<size_t> hostId = ipmi::boot::findHost(ctx->hostIdx);
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700773
Jayashree-Df0cf6652020-11-30 11:03:30 +0530774 if (!hostId)
775 {
776 phosphor::logging::log<phosphor::logging::level::ERR>(
777 "Invalid Host Id received");
778 return ipmi::responseInvalidCommand();
779 }
780 auto [bootObjPath, hostName] = ipmi::boot::objPath(*hostId);
781
Jayashree-Df0cf6652020-11-30 11:03:30 +0530782 std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
783
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530784 // GETTING PROPERTY OF MODE INTERFACE
785
Jayashree-Df0cf6652020-11-30 11:03:30 +0530786 std::string service =
787 getService(*dbus, ipmi::boot::bootModeIntf, bootObjPath);
788 Value variant =
789 getDbusProperty(*dbus, service, bootObjPath, ipmi::boot::bootModeIntf,
790 ipmi::boot::bootModeProp);
791
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530792 auto bootMode = sdbusplus::message::convert_from_string<boot::BootMode>(
Jayashree-Df0cf6652020-11-30 11:03:30 +0530793 std::get<std::string>(variant));
794
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530795 uint8_t bootOption = ipmi::boot::modeDbusToIpmi.at(bootMode);
Jayashree-Df0cf6652020-11-30 11:03:30 +0530796
797 // GETTING PROPERTY OF SOURCE INTERFACE
798
799 service = getService(*dbus, ipmi::boot::bootSourceIntf, bootObjPath);
800 variant =
801 getDbusProperty(*dbus, service, bootObjPath, ipmi::boot::bootSourceIntf,
802 ipmi::boot::bootSourceProp);
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530803
804 auto bootSource = sdbusplus::message::convert_from_string<boot::BootSource>(
Jayashree-Df0cf6652020-11-30 11:03:30 +0530805 std::get<std::string>(variant));
806
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530807 uint8_t bootOrder = ipmi::boot::sourceDbusToIpmi.at(bootSource);
808
809 // GETTING PROPERTY OF TYPE INTERFACE
810
811 service = getService(*dbus, ipmi::boot::bootTypeIntf, bootObjPath);
812 variant =
813 getDbusProperty(*dbus, service, bootObjPath, ipmi::boot::bootTypeIntf,
814 ipmi::boot::bootTypeProp);
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530815
816 auto bootType = sdbusplus::message::convert_from_string<boot::BootType>(
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530817 std::get<std::string>(variant));
818
819 uint8_t bootTypeVal = ipmi::boot::typeDbusToIpmi.at(bootType);
820
821 uint8_t bootVal = bootOption | bootTypeVal;
Jayashree-Df0cf6652020-11-30 11:03:30 +0530822
823 if (oemData.find(hostName) == oemData.end())
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800824 {
825 /* Return default boot order 0100090203ff */
826 uint8_t defaultBoot[SIZE_BOOT_ORDER] = {
827 BOOT_MODE_UEFI, bootMap["USB_DEV"], bootMap["NET_IPV6"],
828 bootMap["SATA_HDD"], bootMap["SATA_CD"], 0xff};
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700829
Jayashree-Df0cf6652020-11-30 11:03:30 +0530830 memcpy(bootSeq, defaultBoot, SIZE_BOOT_ORDER);
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800831 phosphor::logging::log<phosphor::logging::level::INFO>(
832 "Set default boot order");
Jayashree-Df0cf6652020-11-30 11:03:30 +0530833 setBootOrder(bootObjPath, defaultBoot, hostName);
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800834 }
835 else
836 {
Jayashree-Df0cf6652020-11-30 11:03:30 +0530837 nlohmann::json bootMode = oemData[hostName][KEY_BOOT_MODE];
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800838 if (bootMode["UEFI"])
839 mode |= BOOT_MODE_UEFI;
840 if (bootMode["CMOS_CLR"])
841 mode |= BOOT_MODE_CMOS_CLR;
842 if (bootMode["BOOT_FLAG"])
843 mode |= BOOT_MODE_BOOT_FLAG;
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700844
Jayashree-Df0cf6652020-11-30 11:03:30 +0530845 bootSeq[0] = mode;
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800846
Jayashree-Df0cf6652020-11-30 11:03:30 +0530847 for (int i = 1; i < SIZE_BOOT_ORDER; i++)
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800848 {
Jayashree-Df0cf6652020-11-30 11:03:30 +0530849 std::string seqStr = oemData[hostName][KEY_BOOT_SEQ][i - 1];
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800850 if (bootMap.find(seqStr) != bootMap.end())
Jayashree-Df0cf6652020-11-30 11:03:30 +0530851 bootSeq[i] = bootMap[seqStr];
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800852 else
Jayashree-Df0cf6652020-11-30 11:03:30 +0530853 bootSeq[i] = 0xff;
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800854 }
855 }
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800856
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530857 return ipmi::responseSuccess(bootVal, bootOrder, bootSeq[2], bootSeq[3],
Jayashree-Df0cf6652020-11-30 11:03:30 +0530858 bootSeq[4], bootSeq[5]);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800859}
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800860// Set Machine Config Info (CMD_OEM_SET_MACHINE_CONFIG_INFO)
861//----------------------------------------------------------------------
862ipmi_ret_t ipmiOemSetMachineCfgInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
863 ipmi_request_t request,
864 ipmi_response_t response,
865 ipmi_data_len_t data_len,
866 ipmi_context_t context)
867{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700868 machineConfigInfo_t* req = reinterpret_cast<machineConfigInfo_t*>(request);
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700869 uint8_t len = *data_len;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800870
871 *data_len = 0;
872
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700873 if (len < sizeof(machineConfigInfo_t))
874 {
875 phosphor::logging::log<phosphor::logging::level::ERR>(
876 "Invalid machine configuration length received");
877 return IPMI_CC_REQ_DATA_LEN_INVALID;
878 }
879
Vijay Khemka63c99be2020-05-27 19:14:35 -0700880 if (req->chassis_type >= sizeof(chassisType) / sizeof(uint8_t*))
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700881 oemData[KEY_MC_CONFIG][KEY_MC_CHAS_TYPE] = "UNKNOWN";
882 else
883 oemData[KEY_MC_CONFIG][KEY_MC_CHAS_TYPE] =
884 chassisType[req->chassis_type];
885
Vijay Khemka63c99be2020-05-27 19:14:35 -0700886 if (req->mb_type >= sizeof(mbType) / sizeof(uint8_t*))
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700887 oemData[KEY_MC_CONFIG][KEY_MC_MB_TYPE] = "UNKNOWN";
888 else
889 oemData[KEY_MC_CONFIG][KEY_MC_MB_TYPE] = mbType[req->mb_type];
890
891 oemData[KEY_MC_CONFIG][KEY_MC_PROC_CNT] = req->proc_cnt;
892 oemData[KEY_MC_CONFIG][KEY_MC_MEM_CNT] = req->mem_cnt;
893 oemData[KEY_MC_CONFIG][KEY_MC_HDD35_CNT] = req->hdd35_cnt;
894 oemData[KEY_MC_CONFIG][KEY_MC_HDD25_CNT] = req->hdd25_cnt;
895
Vijay Khemka63c99be2020-05-27 19:14:35 -0700896 if (req->riser_type >= sizeof(riserType) / sizeof(uint8_t*))
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700897 oemData[KEY_MC_CONFIG][KEY_MC_RSR_TYPE] = "UNKNOWN";
898 else
899 oemData[KEY_MC_CONFIG][KEY_MC_RSR_TYPE] = riserType[req->riser_type];
900
901 oemData[KEY_MC_CONFIG][KEY_MC_PCIE_LOC] = {};
902 int i = 0;
903 if (req->pcie_card_loc & BIT_0)
904 oemData[KEY_MC_CONFIG][KEY_MC_PCIE_LOC][i++] = "SLOT1";
905 if (req->pcie_card_loc & BIT_1)
906 oemData[KEY_MC_CONFIG][KEY_MC_PCIE_LOC][i++] = "SLOT2";
907 if (req->pcie_card_loc & BIT_2)
908 oemData[KEY_MC_CONFIG][KEY_MC_PCIE_LOC][i++] = "SLOT3";
909 if (req->pcie_card_loc & BIT_3)
910 oemData[KEY_MC_CONFIG][KEY_MC_PCIE_LOC][i++] = "SLOT4";
911
Vijay Khemka63c99be2020-05-27 19:14:35 -0700912 if (req->slot1_pcie_type >= sizeof(pcieType) / sizeof(uint8_t*))
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700913 oemData[KEY_MC_CONFIG][KEY_MC_SLOT1_TYPE] = "UNKNOWN";
914 else
915 oemData[KEY_MC_CONFIG][KEY_MC_SLOT1_TYPE] =
916 pcieType[req->slot1_pcie_type];
917
Vijay Khemka63c99be2020-05-27 19:14:35 -0700918 if (req->slot2_pcie_type >= sizeof(pcieType) / sizeof(uint8_t*))
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700919 oemData[KEY_MC_CONFIG][KEY_MC_SLOT2_TYPE] = "UNKNOWN";
920 else
921 oemData[KEY_MC_CONFIG][KEY_MC_SLOT2_TYPE] =
922 pcieType[req->slot2_pcie_type];
923
Vijay Khemka63c99be2020-05-27 19:14:35 -0700924 if (req->slot3_pcie_type >= sizeof(pcieType) / sizeof(uint8_t*))
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700925 oemData[KEY_MC_CONFIG][KEY_MC_SLOT3_TYPE] = "UNKNOWN";
926 else
927 oemData[KEY_MC_CONFIG][KEY_MC_SLOT3_TYPE] =
928 pcieType[req->slot3_pcie_type];
929
Vijay Khemka63c99be2020-05-27 19:14:35 -0700930 if (req->slot4_pcie_type >= sizeof(pcieType) / sizeof(uint8_t*))
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700931 oemData[KEY_MC_CONFIG][KEY_MC_SLOT4_TYPE] = "UNKNOWN";
932 else
933 oemData[KEY_MC_CONFIG][KEY_MC_SLOT4_TYPE] =
934 pcieType[req->slot4_pcie_type];
935
936 oemData[KEY_MC_CONFIG][KEY_MC_AEP_CNT] = req->aep_mem_cnt;
937
938 flushOemData();
939
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800940 return IPMI_CC_OK;
941}
942
943//----------------------------------------------------------------------
944// Set POST start (CMD_OEM_SET_POST_START)
945//----------------------------------------------------------------------
946ipmi_ret_t ipmiOemSetPostStart(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
947 ipmi_request_t request, ipmi_response_t response,
948 ipmi_data_len_t data_len, ipmi_context_t context)
949{
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800950 phosphor::logging::log<phosphor::logging::level::INFO>("POST Start Event");
951
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700952 /* Do nothing, return success */
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800953 *data_len = 0;
954 return IPMI_CC_OK;
955}
956
957//----------------------------------------------------------------------
958// Set POST End (CMD_OEM_SET_POST_END)
959//----------------------------------------------------------------------
960ipmi_ret_t ipmiOemSetPostEnd(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
961 ipmi_request_t request, ipmi_response_t response,
962 ipmi_data_len_t data_len, ipmi_context_t context)
963{
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700964 struct timespec ts;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800965
966 phosphor::logging::log<phosphor::logging::level::INFO>("POST End Event");
967
968 *data_len = 0;
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700969
970 // Timestamp post end time.
971 clock_gettime(CLOCK_REALTIME, &ts);
972 oemData[KEY_TS_SLED] = ts.tv_sec;
973 flushOemData();
974
975 // Sync time with system
976 // TODO: Add code for syncing time
977
978 return IPMI_CC_OK;
979}
980
981//----------------------------------------------------------------------
982// Set PPIN Info (CMD_OEM_SET_PPIN_INFO)
983//----------------------------------------------------------------------
984// Inform BMC about PPIN data of 8 bytes for each CPU
985//
986// Request:
987// Byte 1:8 – CPU0 PPIN data
988// Optional:
989// Byte 9:16 – CPU1 PPIN data
990//
991// Response:
992// Byte 1 – Completion Code
993ipmi_ret_t ipmiOemSetPPINInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
994 ipmi_request_t request, ipmi_response_t response,
995 ipmi_data_len_t data_len, ipmi_context_t context)
996{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700997 uint8_t* req = reinterpret_cast<uint8_t*>(request);
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700998 std::string ppinStr;
999 int len;
1000
1001 if (*data_len > SIZE_CPU_PPIN * 2)
1002 len = SIZE_CPU_PPIN * 2;
1003 else
1004 len = *data_len;
1005 *data_len = 0;
1006
1007 ppinStr = bytesToStr(req, len);
1008 oemData[KEY_PPIN_INFO] = ppinStr.c_str();
1009 flushOemData();
1010
1011 return IPMI_CC_OK;
1012}
1013
1014//----------------------------------------------------------------------
1015// Set ADR Trigger (CMD_OEM_SET_ADR_TRIGGER)
1016//----------------------------------------------------------------------
1017ipmi_ret_t ipmiOemSetAdrTrigger(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
1018 ipmi_request_t request,
1019 ipmi_response_t response,
1020 ipmi_data_len_t data_len,
1021 ipmi_context_t context)
1022{
1023 /* Do nothing, return success */
1024 *data_len = 0;
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001025 return IPMI_CC_OK;
1026}
1027
Vijay Khemkaf2246ce2020-05-27 14:26:35 -07001028// Helper function to set guid at offset in EEPROM
1029static int setGUID(off_t offset, uint8_t* guid)
1030{
1031 int fd = -1;
1032 ssize_t len;
1033 int ret = 0;
1034
1035 errno = 0;
1036
1037 // Check if file is present
1038 if (access(FRU_EEPROM, F_OK) == -1)
1039 {
1040 std::cerr << "Unable to access: " << FRU_EEPROM << std::endl;
1041 return errno;
1042 }
1043
1044 // Open the file
1045 fd = open(FRU_EEPROM, O_WRONLY);
1046 if (fd == -1)
1047 {
1048 std::cerr << "Unable to open: " << FRU_EEPROM << std::endl;
1049 return errno;
1050 }
1051
1052 // seek to the offset
1053 lseek(fd, offset, SEEK_SET);
1054
1055 // Write bytes to location
1056 len = write(fd, guid, GUID_SIZE);
1057 if (len != GUID_SIZE)
1058 {
1059 phosphor::logging::log<phosphor::logging::level::ERR>(
1060 "GUID write data to EEPROM failed");
1061 ret = errno;
1062 }
1063
1064 close(fd);
1065 return ret;
1066}
1067
1068//----------------------------------------------------------------------
1069// Set System GUID (CMD_OEM_SET_SYSTEM_GUID)
1070//----------------------------------------------------------------------
Manikandan Elumalai5f8e3432020-12-02 03:46:55 +05301071#if BIC_ENABLED
1072ipmi::RspType<> ipmiOemSetSystemGuid(ipmi::Context::ptr ctx, uint8_t cmdReq,
1073 std::vector<uint8_t> reqData)
1074{
1075 std::vector<uint8_t> respData;
1076
1077 if (reqData.size() != GUID_SIZE) // 16bytes
1078 {
1079
1080 return ipmi::responseReqDataLenInvalid();
1081 }
1082
1083 auto ptrReqData = reqData.insert(reqData.begin(), reqData.size());
1084
1085 uint8_t bicAddr = (uint8_t)ctx->hostIdx << 2;
1086
1087 if (sendBicCmd(ctx->netFn, ctx->cmd, bicAddr, reqData, respData))
1088 return ipmi::responseUnspecifiedError();
1089
1090 return ipmi::responseSuccess();
1091}
1092
1093#else
Vijay Khemkaf2246ce2020-05-27 14:26:35 -07001094ipmi_ret_t ipmiOemSetSystemGuid(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
1095 ipmi_request_t request,
1096 ipmi_response_t response,
1097 ipmi_data_len_t data_len,
1098 ipmi_context_t context)
1099{
1100 uint8_t* req = reinterpret_cast<uint8_t*>(request);
1101
1102 if (*data_len != GUID_SIZE) // 16bytes
1103 {
1104 *data_len = 0;
1105 return IPMI_CC_REQ_DATA_LEN_INVALID;
1106 }
1107
1108 *data_len = 0;
1109
1110 if (setGUID(OFFSET_SYS_GUID, req))
1111 {
1112 return IPMI_CC_UNSPECIFIED_ERROR;
1113 }
1114 return IPMI_CC_OK;
1115}
Manikandan Elumalai5f8e3432020-12-02 03:46:55 +05301116#endif
Vijay Khemkaf2246ce2020-05-27 14:26:35 -07001117
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001118//----------------------------------------------------------------------
1119// Set Bios Flash Info (CMD_OEM_SET_BIOS_FLASH_INFO)
1120//----------------------------------------------------------------------
1121ipmi_ret_t ipmiOemSetBiosFlashInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
1122 ipmi_request_t request,
1123 ipmi_response_t response,
1124 ipmi_data_len_t data_len,
1125 ipmi_context_t context)
1126{
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001127 /* Do nothing, return success */
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001128 *data_len = 0;
1129 return IPMI_CC_OK;
1130}
1131
1132//----------------------------------------------------------------------
1133// Set PPR (CMD_OEM_SET_PPR)
1134//----------------------------------------------------------------------
1135ipmi_ret_t ipmiOemSetPpr(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
1136 ipmi_request_t request, ipmi_response_t response,
1137 ipmi_data_len_t data_len, ipmi_context_t context)
1138{
Vijay Khemka63c99be2020-05-27 19:14:35 -07001139 uint8_t* req = reinterpret_cast<uint8_t*>(request);
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001140 uint8_t pprCnt, pprAct, pprIndex;
1141 uint8_t selParam = req[0];
1142 uint8_t len = *data_len;
1143 std::stringstream ss;
1144 std::string str;
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001145
1146 *data_len = 0;
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001147
1148 switch (selParam)
1149 {
1150 case PPR_ACTION:
1151 if (oemData[KEY_PPR].find(KEY_PPR_ROW_COUNT) ==
1152 oemData[KEY_PPR].end())
1153 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
1154
1155 pprCnt = oemData[KEY_PPR][KEY_PPR_ROW_COUNT];
1156 if (pprCnt == 0)
1157 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
1158
1159 pprAct = req[1];
1160 /* Check if ppr is enabled or disabled */
1161 if (!(pprAct & 0x80))
1162 pprAct = 0;
1163
1164 oemData[KEY_PPR][KEY_PPR_ACTION] = pprAct;
1165 break;
1166 case PPR_ROW_COUNT:
1167 if (req[1] > 100)
1168 return IPMI_CC_PARM_OUT_OF_RANGE;
1169
1170 oemData[KEY_PPR][KEY_PPR_ROW_COUNT] = req[1];
1171 break;
1172 case PPR_ROW_ADDR:
1173 pprIndex = req[1];
1174 if (pprIndex > 100)
1175 return IPMI_CC_PARM_OUT_OF_RANGE;
1176
1177 if (len < PPR_ROW_ADDR_LEN + 1)
1178 {
1179 phosphor::logging::log<phosphor::logging::level::ERR>(
1180 "Invalid PPR Row Address length received");
1181 return IPMI_CC_REQ_DATA_LEN_INVALID;
1182 }
1183
1184 ss << std::hex;
1185 ss << std::setw(2) << std::setfill('0') << (int)pprIndex;
1186
1187 oemData[KEY_PPR][ss.str()][KEY_PPR_INDEX] = pprIndex;
1188
1189 str = bytesToStr(&req[1], PPR_ROW_ADDR_LEN);
1190 oemData[KEY_PPR][ss.str()][KEY_PPR_ROW_ADDR] = str.c_str();
1191 break;
1192 case PPR_HISTORY_DATA:
1193 pprIndex = req[1];
1194 if (pprIndex > 100)
1195 return IPMI_CC_PARM_OUT_OF_RANGE;
1196
1197 if (len < PPR_HST_DATA_LEN + 1)
1198 {
1199 phosphor::logging::log<phosphor::logging::level::ERR>(
1200 "Invalid PPR history data length received");
1201 return IPMI_CC_REQ_DATA_LEN_INVALID;
1202 }
1203
1204 ss << std::hex;
1205 ss << std::setw(2) << std::setfill('0') << (int)pprIndex;
1206
1207 oemData[KEY_PPR][ss.str()][KEY_PPR_INDEX] = pprIndex;
1208
1209 str = bytesToStr(&req[1], PPR_HST_DATA_LEN);
1210 oemData[KEY_PPR][ss.str()][KEY_PPR_HST_DATA] = str.c_str();
1211 break;
1212 default:
1213 return IPMI_CC_PARM_OUT_OF_RANGE;
1214 break;
1215 }
1216
1217 flushOemData();
1218
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001219 return IPMI_CC_OK;
1220}
1221
1222//----------------------------------------------------------------------
1223// Get PPR (CMD_OEM_GET_PPR)
1224//----------------------------------------------------------------------
1225ipmi_ret_t ipmiOemGetPpr(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
1226 ipmi_request_t request, ipmi_response_t response,
1227 ipmi_data_len_t data_len, ipmi_context_t context)
1228{
Vijay Khemka63c99be2020-05-27 19:14:35 -07001229 uint8_t* req = reinterpret_cast<uint8_t*>(request);
1230 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001231 uint8_t pprCnt, pprIndex;
1232 uint8_t selParam = req[0];
1233 std::stringstream ss;
1234 std::string str;
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001235
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001236 /* Any failure will return zero length data */
1237 *data_len = 0;
1238
1239 switch (selParam)
1240 {
1241 case PPR_ACTION:
1242 res[0] = 0;
1243 *data_len = 1;
1244
1245 if (oemData[KEY_PPR].find(KEY_PPR_ROW_COUNT) !=
1246 oemData[KEY_PPR].end())
1247 {
1248 pprCnt = oemData[KEY_PPR][KEY_PPR_ROW_COUNT];
1249 if (pprCnt != 0)
1250 {
1251 if (oemData[KEY_PPR].find(KEY_PPR_ACTION) !=
1252 oemData[KEY_PPR].end())
1253 {
1254 res[0] = oemData[KEY_PPR][KEY_PPR_ACTION];
1255 }
1256 }
1257 }
1258 break;
1259 case PPR_ROW_COUNT:
1260 res[0] = 0;
1261 *data_len = 1;
1262 if (oemData[KEY_PPR].find(KEY_PPR_ROW_COUNT) !=
1263 oemData[KEY_PPR].end())
1264 res[0] = oemData[KEY_PPR][KEY_PPR_ROW_COUNT];
1265 break;
1266 case PPR_ROW_ADDR:
1267 pprIndex = req[1];
1268 if (pprIndex > 100)
1269 return IPMI_CC_PARM_OUT_OF_RANGE;
1270
1271 ss << std::hex;
1272 ss << std::setw(2) << std::setfill('0') << (int)pprIndex;
1273
1274 if (oemData[KEY_PPR].find(ss.str()) == oemData[KEY_PPR].end())
1275 return IPMI_CC_PARM_OUT_OF_RANGE;
1276
1277 if (oemData[KEY_PPR][ss.str()].find(KEY_PPR_ROW_ADDR) ==
1278 oemData[KEY_PPR][ss.str()].end())
1279 return IPMI_CC_PARM_OUT_OF_RANGE;
1280
1281 str = oemData[KEY_PPR][ss.str()][KEY_PPR_ROW_ADDR];
1282 *data_len = strToBytes(str, res);
1283 break;
1284 case PPR_HISTORY_DATA:
1285 pprIndex = req[1];
1286 if (pprIndex > 100)
1287 return IPMI_CC_PARM_OUT_OF_RANGE;
1288
1289 ss << std::hex;
1290 ss << std::setw(2) << std::setfill('0') << (int)pprIndex;
1291
1292 if (oemData[KEY_PPR].find(ss.str()) == oemData[KEY_PPR].end())
1293 return IPMI_CC_PARM_OUT_OF_RANGE;
1294
1295 if (oemData[KEY_PPR][ss.str()].find(KEY_PPR_HST_DATA) ==
1296 oemData[KEY_PPR][ss.str()].end())
1297 return IPMI_CC_PARM_OUT_OF_RANGE;
1298
1299 str = oemData[KEY_PPR][ss.str()][KEY_PPR_HST_DATA];
1300 *data_len = strToBytes(str, res);
1301 break;
1302 default:
1303 return IPMI_CC_PARM_OUT_OF_RANGE;
1304 break;
1305 }
1306
1307 return IPMI_CC_OK;
1308}
1309
1310/* FB OEM QC Commands */
1311
1312//----------------------------------------------------------------------
1313// Set Proc Info (CMD_OEM_Q_SET_PROC_INFO)
1314//----------------------------------------------------------------------
1315//"Request:
1316// Byte 1:3 – Manufacturer ID – XXYYZZ h, LSB first
1317// Byte 4 – Processor Index, 0 base
1318// Byte 5 – Parameter Selector
1319// Byte 6..N – Configuration parameter data (see below for Parameters
1320// of Processor Information)
1321// Response:
1322// Byte 1 – Completion code
1323//
1324// Parameter#1: (Processor Product Name)
1325//
1326// Byte 1..48 –Product name(ASCII code)
1327// Ex. Intel(R) Xeon(R) CPU E5-2685 v3 @ 2.60GHz
1328//
1329// Param#2: Processor Basic Information
1330// Byte 1 – Core Number
1331// Byte 2 – Thread Number (LSB)
1332// Byte 3 – Thread Number (MSB)
1333// Byte 4 – Processor frequency in MHz (LSB)
1334// Byte 5 – Processor frequency in MHz (MSB)
1335// Byte 6..7 – Revision
1336//
1337ipmi_ret_t ipmiOemQSetProcInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
1338 ipmi_request_t request, ipmi_response_t response,
1339 ipmi_data_len_t data_len, ipmi_context_t context)
1340{
Vijay Khemka63c99be2020-05-27 19:14:35 -07001341 qProcInfo_t* req = reinterpret_cast<qProcInfo_t*>(request);
1342 uint8_t numParam = sizeof(cpuInfoKey) / sizeof(uint8_t*);
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001343 std::stringstream ss;
1344 std::string str;
1345 uint8_t len = *data_len;
1346
1347 *data_len = 0;
1348
1349 /* check for requested data params */
1350 if (len < 5 || req->paramSel < 1 || req->paramSel >= numParam)
1351 {
1352 phosphor::logging::log<phosphor::logging::level::ERR>(
1353 "Invalid parameter received");
1354 return IPMI_CC_PARM_OUT_OF_RANGE;
1355 }
1356
1357 len = len - 5; // Get Actual data length
1358
1359 ss << std::hex;
1360 ss << std::setw(2) << std::setfill('0') << (int)req->procIndex;
1361 oemData[KEY_Q_PROC_INFO][ss.str()][KEY_PROC_INDEX] = req->procIndex;
1362
1363 str = bytesToStr(req->data, len);
1364 oemData[KEY_Q_PROC_INFO][ss.str()][cpuInfoKey[req->paramSel]] = str.c_str();
1365 flushOemData();
1366
1367 return IPMI_CC_OK;
1368}
1369
1370//----------------------------------------------------------------------
1371// Get Proc Info (CMD_OEM_Q_GET_PROC_INFO)
1372//----------------------------------------------------------------------
1373// Request:
1374// Byte 1:3 – Manufacturer ID – XXYYZZ h, LSB first
1375// Byte 4 – Processor Index, 0 base
1376// Byte 5 – Parameter Selector
1377// Response:
1378// Byte 1 – Completion code
1379// Byte 2..N – Configuration Parameter Data (see below for Parameters
1380// of Processor Information)
1381//
1382// Parameter#1: (Processor Product Name)
1383//
1384// Byte 1..48 –Product name(ASCII code)
1385// Ex. Intel(R) Xeon(R) CPU E5-2685 v3 @ 2.60GHz
1386//
1387// Param#2: Processor Basic Information
1388// Byte 1 – Core Number
1389// Byte 2 – Thread Number (LSB)
1390// Byte 3 – Thread Number (MSB)
1391// Byte 4 – Processor frequency in MHz (LSB)
1392// Byte 5 – Processor frequency in MHz (MSB)
1393// Byte 6..7 – Revision
1394//
1395ipmi_ret_t ipmiOemQGetProcInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
1396 ipmi_request_t request, ipmi_response_t response,
1397 ipmi_data_len_t data_len, ipmi_context_t context)
1398{
Vijay Khemka63c99be2020-05-27 19:14:35 -07001399 qProcInfo_t* req = reinterpret_cast<qProcInfo_t*>(request);
1400 uint8_t numParam = sizeof(cpuInfoKey) / sizeof(uint8_t*);
1401 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001402 std::stringstream ss;
1403 std::string str;
1404
1405 *data_len = 0;
1406
1407 /* check for requested data params */
1408 if (req->paramSel < 1 || req->paramSel >= numParam)
1409 {
1410 phosphor::logging::log<phosphor::logging::level::ERR>(
1411 "Invalid parameter received");
1412 return IPMI_CC_PARM_OUT_OF_RANGE;
1413 }
1414
1415 ss << std::hex;
1416 ss << std::setw(2) << std::setfill('0') << (int)req->procIndex;
1417
1418 if (oemData[KEY_Q_PROC_INFO].find(ss.str()) ==
1419 oemData[KEY_Q_PROC_INFO].end())
1420 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
1421
1422 if (oemData[KEY_Q_PROC_INFO][ss.str()].find(cpuInfoKey[req->paramSel]) ==
1423 oemData[KEY_Q_PROC_INFO][ss.str()].end())
1424 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
1425
1426 str = oemData[KEY_Q_PROC_INFO][ss.str()][cpuInfoKey[req->paramSel]];
1427 *data_len = strToBytes(str, res);
1428
1429 return IPMI_CC_OK;
1430}
1431
1432//----------------------------------------------------------------------
1433// Set Dimm Info (CMD_OEM_Q_SET_DIMM_INFO)
1434//----------------------------------------------------------------------
1435// Request:
1436// Byte 1:3 – Manufacturer ID – XXYYZZh, LSB first
1437// Byte 4 – DIMM Index, 0 base
1438// Byte 5 – Parameter Selector
1439// Byte 6..N – Configuration parameter data (see below for Parameters
1440// of DIMM Information)
1441// Response:
1442// Byte 1 – Completion code
1443//
1444// Param#1 (DIMM Location):
1445// Byte 1 – DIMM Present
1446// Byte 1 – DIMM Present
1447// 01h – Present
1448// FFh – Not Present
1449// Byte 2 – Node Number, 0 base
1450// Byte 3 – Channel Number , 0 base
1451// Byte 4 – DIMM Number , 0 base
1452//
1453// Param#2 (DIMM Type):
1454// Byte 1 – DIMM Type
1455// Bit [7:6]
1456// For DDR3
1457// 00 – Normal Voltage (1.5V)
1458// 01 – Ultra Low Voltage (1.25V)
1459// 10 – Low Voltage (1.35V)
1460// 11 – Reserved
1461// For DDR4
1462// 00 – Reserved
1463// 01 – Reserved
1464// 10 – Reserved
1465// 11 – Normal Voltage (1.2V)
1466// Bit [5:0]
1467// 0x00 – SDRAM
1468// 0x01 – DDR-1 RAM
1469// 0x02 – Rambus
1470// 0x03 – DDR-2 RAM
1471// 0x04 – FBDIMM
1472// 0x05 – DDR-3 RAM
1473// 0x06 – DDR-4 RAM
1474//
1475// Param#3 (DIMM Speed):
1476// Byte 1..2 – DIMM speed in MHz, LSB
1477// Byte 3..6 – DIMM size in Mbytes, LSB
1478//
1479// Param#4 (Module Part Number):
1480// Byte 1..20 –Module Part Number (JEDEC Standard No. 21-C)
1481//
1482// Param#5 (Module Serial Number):
1483// Byte 1..4 –Module Serial Number (JEDEC Standard No. 21-C)
1484//
1485// Param#6 (Module Manufacturer ID):
1486// Byte 1 - Module Manufacturer ID, LSB
1487// Byte 2 - Module Manufacturer ID, MSB
1488//
1489ipmi_ret_t ipmiOemQSetDimmInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
1490 ipmi_request_t request, ipmi_response_t response,
1491 ipmi_data_len_t data_len, ipmi_context_t context)
1492{
Vijay Khemka63c99be2020-05-27 19:14:35 -07001493 qDimmInfo_t* req = reinterpret_cast<qDimmInfo_t*>(request);
1494 uint8_t numParam = sizeof(dimmInfoKey) / sizeof(uint8_t*);
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001495 std::stringstream ss;
1496 std::string str;
1497 uint8_t len = *data_len;
1498
1499 *data_len = 0;
1500
1501 /* check for requested data params */
1502 if (len < 5 || req->paramSel < 1 || req->paramSel >= numParam)
1503 {
1504 phosphor::logging::log<phosphor::logging::level::ERR>(
1505 "Invalid parameter received");
1506 return IPMI_CC_PARM_OUT_OF_RANGE;
1507 }
1508
1509 len = len - 5; // Get Actual data length
1510
1511 ss << std::hex;
1512 ss << std::setw(2) << std::setfill('0') << (int)req->dimmIndex;
1513 oemData[KEY_Q_DIMM_INFO][ss.str()][KEY_DIMM_INDEX] = req->dimmIndex;
1514
1515 str = bytesToStr(req->data, len);
1516 oemData[KEY_Q_DIMM_INFO][ss.str()][dimmInfoKey[req->paramSel]] =
1517 str.c_str();
1518 flushOemData();
1519
1520 return IPMI_CC_OK;
1521}
1522
1523//----------------------------------------------------------------------
1524// Get Dimm Info (CMD_OEM_Q_GET_DIMM_INFO)
1525//----------------------------------------------------------------------
1526// Request:
1527// Byte 1:3 – Manufacturer ID – XXYYZZh, LSB first
1528// Byte 4 – DIMM Index, 0 base
1529// Byte 5 – Parameter Selector
1530// Byte 6..N – Configuration parameter data (see below for Parameters
1531// of DIMM Information)
1532// Response:
1533// Byte 1 – Completion code
1534// Byte 2..N – Configuration Parameter Data (see Table_1213h Parameters
1535// of DIMM Information)
1536//
1537// Param#1 (DIMM Location):
1538// Byte 1 – DIMM Present
1539// Byte 1 – DIMM Present
1540// 01h – Present
1541// FFh – Not Present
1542// Byte 2 – Node Number, 0 base
1543// Byte 3 – Channel Number , 0 base
1544// Byte 4 – DIMM Number , 0 base
1545//
1546// Param#2 (DIMM Type):
1547// Byte 1 – DIMM Type
1548// Bit [7:6]
1549// For DDR3
1550// 00 – Normal Voltage (1.5V)
1551// 01 – Ultra Low Voltage (1.25V)
1552// 10 – Low Voltage (1.35V)
1553// 11 – Reserved
1554// For DDR4
1555// 00 – Reserved
1556// 01 – Reserved
1557// 10 – Reserved
1558// 11 – Normal Voltage (1.2V)
1559// Bit [5:0]
1560// 0x00 – SDRAM
1561// 0x01 – DDR-1 RAM
1562// 0x02 – Rambus
1563// 0x03 – DDR-2 RAM
1564// 0x04 – FBDIMM
1565// 0x05 – DDR-3 RAM
1566// 0x06 – DDR-4 RAM
1567//
1568// Param#3 (DIMM Speed):
1569// Byte 1..2 – DIMM speed in MHz, LSB
1570// Byte 3..6 – DIMM size in Mbytes, LSB
1571//
1572// Param#4 (Module Part Number):
1573// Byte 1..20 –Module Part Number (JEDEC Standard No. 21-C)
1574//
1575// Param#5 (Module Serial Number):
1576// Byte 1..4 –Module Serial Number (JEDEC Standard No. 21-C)
1577//
1578// Param#6 (Module Manufacturer ID):
1579// Byte 1 - Module Manufacturer ID, LSB
1580// Byte 2 - Module Manufacturer ID, MSB
1581//
1582ipmi_ret_t ipmiOemQGetDimmInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
1583 ipmi_request_t request, ipmi_response_t response,
1584 ipmi_data_len_t data_len, ipmi_context_t context)
1585{
Vijay Khemka63c99be2020-05-27 19:14:35 -07001586 qDimmInfo_t* req = reinterpret_cast<qDimmInfo_t*>(request);
1587 uint8_t numParam = sizeof(dimmInfoKey) / sizeof(uint8_t*);
1588 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001589 std::stringstream ss;
1590 std::string str;
1591
1592 *data_len = 0;
1593
1594 /* check for requested data params */
1595 if (req->paramSel < 1 || req->paramSel >= numParam)
1596 {
1597 phosphor::logging::log<phosphor::logging::level::ERR>(
1598 "Invalid parameter received");
1599 return IPMI_CC_PARM_OUT_OF_RANGE;
1600 }
1601
1602 ss << std::hex;
1603 ss << std::setw(2) << std::setfill('0') << (int)req->dimmIndex;
1604
1605 if (oemData[KEY_Q_DIMM_INFO].find(ss.str()) ==
1606 oemData[KEY_Q_DIMM_INFO].end())
1607 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
1608
1609 if (oemData[KEY_Q_DIMM_INFO][ss.str()].find(dimmInfoKey[req->paramSel]) ==
1610 oemData[KEY_Q_DIMM_INFO][ss.str()].end())
1611 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
1612
1613 str = oemData[KEY_Q_DIMM_INFO][ss.str()][dimmInfoKey[req->paramSel]];
1614 *data_len = strToBytes(str, res);
1615
1616 return IPMI_CC_OK;
1617}
1618
1619//----------------------------------------------------------------------
1620// Set Drive Info (CMD_OEM_Q_SET_DRIVE_INFO)
1621//----------------------------------------------------------------------
1622// BIOS issue this command to provide HDD information to BMC.
1623//
1624// BIOS just can get information by standard ATA / SMART command for
1625// OB SATA controller.
1626// BIOS can get
1627// 1. Serial Number
1628// 2. Model Name
1629// 3. HDD FW Version
1630// 4. HDD Capacity
1631// 5. HDD WWN
1632//
1633// Use Get HDD info Param #5 to know the MAX HDD info index.
1634//
1635// Request:
1636// Byte 1:3 – Quanta Manufacturer ID – 001C4Ch, LSB first
1637// Byte 4 –
1638// [7:4] Reserved
1639// [3:0] HDD Controller Type
1640// 0x00 – BIOS
1641// 0x01 – Expander
1642// 0x02 – LSI
1643// Byte 5 – HDD Info Index, 0 base
1644// Byte 6 – Parameter Selector
1645// Byte 7..N – Configuration parameter data (see Table_1415h Parameters of HDD
1646// Information)
1647//
1648// Response:
1649// Byte 1 – Completion Code
1650//
1651// Param#0 (HDD Location):
1652// Byte 1 – Controller
1653// [7:3] Device Number
1654// [2:0] Function Number
1655// For Intel C610 series (Wellsburg)
1656// D31:F2 (0xFA) – SATA control 1
1657// D31:F5 (0xFD) – SATA control 2
1658// D17:F4 (0x8C) – sSata control
1659// Byte 2 – Port Number
1660// Byte 3 – Location (0xFF: No HDD Present)
1661// BIOS default set Byte 3 to 0xFF, if No HDD Present. And then skip send param
1662// #1~4, #6, #7 to BMC (still send param #5) BIOS default set Byte 3 to 0, if
1663// the HDD present. BMC or other people who know the HDD location has
1664// responsibility for update Location info
1665//
1666// Param#1 (Serial Number):
1667// Bytes 1..33: HDD Serial Number
1668//
1669// Param#2 (Model Name):
1670// Byte 1..33 – HDD Model Name
1671//
1672// Param#3 (HDD FW Version):
1673// Byte 1..17 –HDD FW version
1674//
1675// Param#4 (Capacity):
1676// Byte 1..4 –HDD Block Size, LSB
1677// Byte 5..12 - HDD Block Number, LSB
1678// HDD Capacity = HDD Block size * HDD BLock number (Unit Byte)
1679//
1680// Param#5 (Max HDD Quantity):
1681// Byte 1 - Max HDD Quantity
1682// Max supported port numbers in this PCH
1683//
1684// Param#6 (HDD Type)
1685// Byte 1 – HDD Type
1686// 0h – Reserved
1687// 1h – SAS
1688// 2h – SATA
1689// 3h – PCIE SSD (NVME)
1690//
1691// Param#7 (HDD WWN)
1692// Data 1...8: HDD World Wide Name, LSB
1693//
1694ipmi_ret_t ipmiOemQSetDriveInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
1695 ipmi_request_t request,
1696 ipmi_response_t response,
1697 ipmi_data_len_t data_len,
1698 ipmi_context_t context)
1699{
Vijay Khemka63c99be2020-05-27 19:14:35 -07001700 qDriveInfo_t* req = reinterpret_cast<qDriveInfo_t*>(request);
1701 uint8_t numParam = sizeof(driveInfoKey) / sizeof(uint8_t*);
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001702 uint8_t ctrlType = req->hddCtrlType & 0x0f;
1703 std::stringstream ss;
1704 std::string str;
1705 uint8_t len = *data_len;
1706
1707 *data_len = 0;
1708
1709 /* check for requested data params */
1710 if (len < 6 || req->paramSel < 1 || req->paramSel >= numParam ||
1711 ctrlType > 2)
1712 {
1713 phosphor::logging::log<phosphor::logging::level::ERR>(
1714 "Invalid parameter received");
1715 return IPMI_CC_PARM_OUT_OF_RANGE;
1716 }
1717
1718 len = len - 6; // Get Actual data length
1719
1720 ss << std::hex;
1721 ss << std::setw(2) << std::setfill('0') << (int)req->hddIndex;
1722 oemData[KEY_Q_DRIVE_INFO][KEY_HDD_CTRL_TYPE] = req->hddCtrlType;
1723 oemData[KEY_Q_DRIVE_INFO][ctrlTypeKey[ctrlType]][ss.str()][KEY_HDD_INDEX] =
1724 req->hddIndex;
1725
1726 str = bytesToStr(req->data, len);
1727 oemData[KEY_Q_DRIVE_INFO][ctrlTypeKey[ctrlType]][ss.str()]
1728 [driveInfoKey[req->paramSel]] = str.c_str();
1729 flushOemData();
1730
1731 return IPMI_CC_OK;
1732}
1733
1734//----------------------------------------------------------------------
1735// Get Drive Info (CMD_OEM_Q_GET_DRIVE_INFO)
1736//----------------------------------------------------------------------
1737// BMC needs to check HDD presented or not first. If NOT presented, return
1738// completion code 0xD5.
1739//
1740// Request:
1741// Byte 1:3 – Quanta Manufacturer ID – 001C4Ch, LSB first
1742// Byte 4 –
1743//[7:4] Reserved
1744//[3:0] HDD Controller Type
1745// 0x00 – BIOS
1746// 0x01 – Expander
1747// 0x02 – LSI
1748// Byte 5 – HDD Index, 0 base
1749// Byte 6 – Parameter Selector (See Above Set HDD Information)
1750// Response:
1751// Byte 1 – Completion Code
1752// 0xD5 – Not support in current status (HDD Not Present)
1753// Byte 2..N – Configuration parameter data (see Table_1415h Parameters of HDD
1754// Information)
1755//
1756ipmi_ret_t ipmiOemQGetDriveInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
1757 ipmi_request_t request,
1758 ipmi_response_t response,
1759 ipmi_data_len_t data_len,
1760 ipmi_context_t context)
1761{
Vijay Khemka63c99be2020-05-27 19:14:35 -07001762 qDriveInfo_t* req = reinterpret_cast<qDriveInfo_t*>(request);
1763 uint8_t numParam = sizeof(driveInfoKey) / sizeof(uint8_t*);
1764 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001765 uint8_t ctrlType = req->hddCtrlType & 0x0f;
1766 std::stringstream ss;
1767 std::string str;
1768
1769 *data_len = 0;
1770
1771 /* check for requested data params */
1772 if (req->paramSel < 1 || req->paramSel >= numParam || ctrlType > 2)
1773 {
1774 phosphor::logging::log<phosphor::logging::level::ERR>(
1775 "Invalid parameter received");
1776 return IPMI_CC_PARM_OUT_OF_RANGE;
1777 }
1778
1779 if (oemData[KEY_Q_DRIVE_INFO].find(ctrlTypeKey[ctrlType]) ==
1780 oemData[KEY_Q_DRIVE_INFO].end())
1781 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
1782
1783 ss << std::hex;
1784 ss << std::setw(2) << std::setfill('0') << (int)req->hddIndex;
1785
1786 if (oemData[KEY_Q_DRIVE_INFO][ctrlTypeKey[ctrlType]].find(ss.str()) ==
1787 oemData[KEY_Q_DRIVE_INFO].end())
1788 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
1789
1790 if (oemData[KEY_Q_DRIVE_INFO][ctrlTypeKey[ctrlType]][ss.str()].find(
1791 dimmInfoKey[req->paramSel]) ==
1792 oemData[KEY_Q_DRIVE_INFO][ss.str()].end())
1793 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
1794
1795 str = oemData[KEY_Q_DRIVE_INFO][ctrlTypeKey[ctrlType]][ss.str()]
1796 [dimmInfoKey[req->paramSel]];
1797 *data_len = strToBytes(str, res);
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001798
1799 return IPMI_CC_OK;
1800}
1801
Vijay Khemkadd14c0f2020-03-18 14:48:13 -07001802/* Helper function for sending DCMI commands to ME and getting response back */
1803ipmi::RspType<std::vector<uint8_t>> sendDCMICmd(uint8_t cmd,
Vijay Khemka63c99be2020-05-27 19:14:35 -07001804 std::vector<uint8_t>& cmdData)
Vijay Khemkadd14c0f2020-03-18 14:48:13 -07001805{
1806 std::vector<uint8_t> respData;
1807
1808 /* Add group id as first byte to request for ME command */
1809 cmdData.insert(cmdData.begin(), groupDCMI);
1810
1811 if (sendMeCmd(ipmi::netFnGroup, cmd, cmdData, respData))
1812 return ipmi::responseUnspecifiedError();
1813
1814 /* Remove group id as first byte as it will be added by IPMID */
1815 respData.erase(respData.begin());
1816
1817 return ipmi::responseSuccess(std::move(respData));
1818}
1819
1820/* DCMI Command handellers. */
1821
1822ipmi::RspType<std::vector<uint8_t>>
1823 ipmiOemDCMIGetPowerReading(std::vector<uint8_t> reqData)
1824{
1825 return sendDCMICmd(ipmi::dcmi::cmdGetPowerReading, reqData);
1826}
1827
1828ipmi::RspType<std::vector<uint8_t>>
1829 ipmiOemDCMIGetPowerLimit(std::vector<uint8_t> reqData)
1830{
1831 return sendDCMICmd(ipmi::dcmi::cmdGetPowerLimit, reqData);
1832}
1833
1834ipmi::RspType<std::vector<uint8_t>>
1835 ipmiOemDCMISetPowerLimit(std::vector<uint8_t> reqData)
1836{
1837 return sendDCMICmd(ipmi::dcmi::cmdSetPowerLimit, reqData);
1838}
1839
1840ipmi::RspType<std::vector<uint8_t>>
1841 ipmiOemDCMIApplyPowerLimit(std::vector<uint8_t> reqData)
1842{
1843 return sendDCMICmd(ipmi::dcmi::cmdActDeactivatePwrLimit, reqData);
1844}
1845
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001846static void registerOEMFunctions(void)
1847{
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001848 /* Get OEM data from json file */
1849 std::ifstream file(JSON_OEM_DATA_FILE);
1850 if (file)
Vijay Khemkafeaa9812019-08-27 15:08:08 -07001851 {
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001852 file >> oemData;
Vijay Khemkafeaa9812019-08-27 15:08:08 -07001853 file.close();
1854 }
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001855
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001856 phosphor::logging::log<phosphor::logging::level::INFO>(
1857 "Registering OEM commands");
Vijay Khemka7c0aea42020-03-05 13:31:53 -08001858
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001859 ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, CMD_OEM_USB_DBG_GET_FRAME_INFO,
1860 NULL, ipmiOemDbgGetFrameInfo,
1861 PRIVILEGE_USER); // get debug frame info
1862 ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ,
1863 CMD_OEM_USB_DBG_GET_UPDATED_FRAMES, NULL,
1864 ipmiOemDbgGetUpdFrames,
1865 PRIVILEGE_USER); // get debug updated frames
1866 ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, CMD_OEM_USB_DBG_GET_POST_DESC,
1867 NULL, ipmiOemDbgGetPostDesc,
1868 PRIVILEGE_USER); // get debug post description
1869 ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, CMD_OEM_USB_DBG_GET_GPIO_DESC,
1870 NULL, ipmiOemDbgGetGpioDesc,
1871 PRIVILEGE_USER); // get debug gpio description
1872 ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, CMD_OEM_USB_DBG_GET_FRAME_DATA,
1873 NULL, ipmiOemDbgGetFrameData,
1874 PRIVILEGE_USER); // get debug frame data
1875 ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, CMD_OEM_USB_DBG_CTRL_PANEL,
1876 NULL, ipmiOemDbgGetCtrlPanel,
1877 PRIVILEGE_USER); // get debug control panel
1878 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_DIMM_INFO, NULL,
1879 ipmiOemSetDimmInfo,
1880 PRIVILEGE_USER); // Set Dimm Info
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001881 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_GET_BOARD_ID, NULL,
1882 ipmiOemGetBoardID,
1883 PRIVILEGE_USER); // Get Board ID
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001884 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_MACHINE_CONFIG_INFO, NULL,
1885 ipmiOemSetMachineCfgInfo,
1886 PRIVILEGE_USER); // Set Machine Config Info
1887 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_POST_START, NULL,
1888 ipmiOemSetPostStart,
1889 PRIVILEGE_USER); // Set POST start
1890 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_POST_END, NULL,
1891 ipmiOemSetPostEnd,
1892 PRIVILEGE_USER); // Set POST End
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001893 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_PPIN_INFO, NULL,
1894 ipmiOemSetPPINInfo,
1895 PRIVILEGE_USER); // Set PPIN Info
Manikandan Elumalai5f8e3432020-12-02 03:46:55 +05301896#if BIC_ENABLED
1897
1898 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnOemOne,
1899 ipmi::cmdSetSystemGuid, ipmi::Privilege::User,
1900 ipmiOemSetSystemGuid);
1901#else
1902
Vijay Khemkaf2246ce2020-05-27 14:26:35 -07001903 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_SYSTEM_GUID, NULL,
1904 ipmiOemSetSystemGuid,
1905 PRIVILEGE_USER); // Set System GUID
Manikandan Elumalai5f8e3432020-12-02 03:46:55 +05301906#endif
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001907 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_ADR_TRIGGER, NULL,
1908 ipmiOemSetAdrTrigger,
1909 PRIVILEGE_USER); // Set ADR Trigger
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001910 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_BIOS_FLASH_INFO, NULL,
1911 ipmiOemSetBiosFlashInfo,
1912 PRIVILEGE_USER); // Set Bios Flash Info
1913 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_PPR, NULL, ipmiOemSetPpr,
1914 PRIVILEGE_USER); // Set PPR
1915 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_GET_PPR, NULL, ipmiOemGetPpr,
1916 PRIVILEGE_USER); // Get PPR
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001917 /* FB OEM QC Commands */
1918 ipmiPrintAndRegister(NETFUN_FB_OEM_QC, CMD_OEM_Q_SET_PROC_INFO, NULL,
1919 ipmiOemQSetProcInfo,
1920 PRIVILEGE_USER); // Set Proc Info
1921 ipmiPrintAndRegister(NETFUN_FB_OEM_QC, CMD_OEM_Q_GET_PROC_INFO, NULL,
1922 ipmiOemQGetProcInfo,
1923 PRIVILEGE_USER); // Get Proc Info
1924 ipmiPrintAndRegister(NETFUN_FB_OEM_QC, CMD_OEM_Q_SET_DIMM_INFO, NULL,
1925 ipmiOemQSetDimmInfo,
1926 PRIVILEGE_USER); // Set Dimm Info
1927 ipmiPrintAndRegister(NETFUN_FB_OEM_QC, CMD_OEM_Q_GET_DIMM_INFO, NULL,
1928 ipmiOemQGetDimmInfo,
1929 PRIVILEGE_USER); // Get Dimm Info
1930 ipmiPrintAndRegister(NETFUN_FB_OEM_QC, CMD_OEM_Q_SET_DRIVE_INFO, NULL,
1931 ipmiOemQSetDriveInfo,
1932 PRIVILEGE_USER); // Set Drive Info
1933 ipmiPrintAndRegister(NETFUN_FB_OEM_QC, CMD_OEM_Q_GET_DRIVE_INFO, NULL,
1934 ipmiOemQGetDriveInfo,
1935 PRIVILEGE_USER); // Get Drive Info
Vijay Khemkadd14c0f2020-03-18 14:48:13 -07001936
1937 /* FB OEM DCMI Commands as per DCMI spec 1.5 Section 6 */
1938 ipmi::registerGroupHandler(ipmi::prioOpenBmcBase, groupDCMI,
1939 ipmi::dcmi::cmdGetPowerReading,
1940 ipmi::Privilege::User,
1941 ipmiOemDCMIGetPowerReading); // Get Power Reading
1942
1943 ipmi::registerGroupHandler(ipmi::prioOpenBmcBase, groupDCMI,
1944 ipmi::dcmi::cmdGetPowerLimit,
1945 ipmi::Privilege::User,
1946 ipmiOemDCMIGetPowerLimit); // Get Power Limit
1947
1948 ipmi::registerGroupHandler(ipmi::prioOpenBmcBase, groupDCMI,
1949 ipmi::dcmi::cmdSetPowerLimit,
1950 ipmi::Privilege::Operator,
1951 ipmiOemDCMISetPowerLimit); // Set Power Limit
1952
1953 ipmi::registerGroupHandler(ipmi::prioOpenBmcBase, groupDCMI,
1954 ipmi::dcmi::cmdActDeactivatePwrLimit,
1955 ipmi::Privilege::Operator,
1956 ipmiOemDCMIApplyPowerLimit); // Apply Power Limit
1957
Jayashree-Df0cf6652020-11-30 11:03:30 +05301958 /* FB OEM BOOT ORDER COMMANDS */
1959 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnOemOne,
1960 CMD_OEM_GET_BOOT_ORDER, ipmi::Privilege::User,
1961 ipmiOemGetBootOrder); // Get Boot Order
1962
1963 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnOemOne,
1964 CMD_OEM_SET_BOOT_ORDER, ipmi::Privilege::User,
1965 ipmiOemSetBootOrder); // Set Boot Order
1966
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001967 return;
1968}
1969
1970} // namespace ipmi