blob: b6049570ad11df43d7031221a5cc34942d6f12be [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
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +053050size_t getSelectorPosition();
Vijay Khemkae7d23d02019-03-08 13:13:40 -080051static void registerOEMFunctions() __attribute__((constructor));
52sdbusplus::bus::bus dbus(ipmid_get_sd_bus_connection()); // from ipmid/api.h
53static constexpr size_t maxFRUStringLength = 0x3F;
Manikandan Elumalai5f8e3432020-12-02 03:46:55 +053054constexpr uint8_t cmdSetSystemGuid = 0xEF;
Vijay Khemkae7d23d02019-03-08 13:13:40 -080055
Vijay Khemka63c99be2020-05-27 19:14:35 -070056int plat_udbg_get_post_desc(uint8_t, uint8_t*, uint8_t, uint8_t*, uint8_t*,
57 uint8_t*);
58int plat_udbg_get_gpio_desc(uint8_t, uint8_t*, uint8_t*, uint8_t*, uint8_t*,
59 uint8_t*);
60ipmi_ret_t plat_udbg_get_frame_data(uint8_t, uint8_t, uint8_t*, uint8_t*,
61 uint8_t*);
62ipmi_ret_t plat_udbg_control_panel(uint8_t, uint8_t, uint8_t, uint8_t*,
63 uint8_t*);
64int sendMeCmd(uint8_t, uint8_t, std::vector<uint8_t>&, std::vector<uint8_t>&);
Vijay Khemkadd14c0f2020-03-18 14:48:13 -070065
Manikandan Elumalai5f8e3432020-12-02 03:46:55 +053066int sendBicCmd(uint8_t, uint8_t, uint8_t, std::vector<uint8_t>&,
67 std::vector<uint8_t>&);
68
Vijay Khemkafeaa9812019-08-27 15:08:08 -070069nlohmann::json oemData __attribute__((init_priority(101)));
Vijay Khemka1b6fae32019-03-25 17:43:01 -070070
Vijay Khemkaf2246ce2020-05-27 14:26:35 -070071static constexpr size_t GUID_SIZE = 16;
72// TODO Make offset and location runtime configurable to ensure we
73// can make each define their own locations.
74static constexpr off_t OFFSET_SYS_GUID = 0x17F0;
75static constexpr const char* FRU_EEPROM = "/sys/bus/i2c/devices/6-0054/eeprom";
76
Vijay Khemka1b6fae32019-03-25 17:43:01 -070077enum class LanParam : uint8_t
78{
79 INPROGRESS = 0,
80 AUTHSUPPORT = 1,
81 AUTHENABLES = 2,
82 IP = 3,
83 IPSRC = 4,
84 MAC = 5,
85 SUBNET = 6,
86 GATEWAY = 12,
87 VLAN = 20,
88 CIPHER_SUITE_COUNT = 22,
89 CIPHER_SUITE_ENTRIES = 23,
90 IPV6 = 59,
91};
92
Vijay Khemkaa7231892019-10-11 11:35:05 -070093namespace network
94{
95
96constexpr auto ROOT = "/xyz/openbmc_project/network";
97constexpr auto SERVICE = "xyz.openbmc_project.Network";
98constexpr auto IPV4_TYPE = "ipv4";
99constexpr auto IPV6_TYPE = "ipv6";
100constexpr auto IPV4_PREFIX = "169.254";
101constexpr auto IPV6_PREFIX = "fe80";
102constexpr auto IP_INTERFACE = "xyz.openbmc_project.Network.IP";
103constexpr auto MAC_INTERFACE = "xyz.openbmc_project.Network.MACAddress";
104
Vijay Khemka63c99be2020-05-27 19:14:35 -0700105bool isLinkLocalIP(const std::string& address)
Vijay Khemkaa7231892019-10-11 11:35:05 -0700106{
107 return address.find(IPV4_PREFIX) == 0 || address.find(IPV6_PREFIX) == 0;
108}
109
Vijay Khemka63c99be2020-05-27 19:14:35 -0700110DbusObjectInfo getIPObject(sdbusplus::bus::bus& bus,
111 const std::string& interface,
112 const std::string& serviceRoot,
113 const std::string& match)
Vijay Khemkaa7231892019-10-11 11:35:05 -0700114{
115 auto objectTree = getAllDbusObjects(bus, serviceRoot, interface, match);
116
117 if (objectTree.empty())
118 {
119 log<level::ERR>("No Object has implemented the IP interface",
120 entry("INTERFACE=%s", interface.c_str()));
121 }
122
123 DbusObjectInfo objectInfo;
124
Vijay Khemka63c99be2020-05-27 19:14:35 -0700125 for (auto& object : objectTree)
Vijay Khemkaa7231892019-10-11 11:35:05 -0700126 {
127 auto variant =
128 ipmi::getDbusProperty(bus, object.second.begin()->first,
129 object.first, IP_INTERFACE, "Address");
130
131 objectInfo = std::make_pair(object.first, object.second.begin()->first);
132
133 // if LinkLocalIP found look for Non-LinkLocalIP
134 if (isLinkLocalIP(std::get<std::string>(variant)))
135 {
136 continue;
137 }
138 else
139 {
140 break;
141 }
142 }
143 return objectInfo;
144}
145
146} // namespace network
147
Jayashree-Df0cf6652020-11-30 11:03:30 +0530148namespace boot
149{
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530150using BootSource =
151 sdbusplus::xyz::openbmc_project::Control::Boot::server::Source::Sources;
152using BootMode =
153 sdbusplus::xyz::openbmc_project::Control::Boot::server::Mode::Modes;
154using BootType =
155 sdbusplus::xyz::openbmc_project::Control::Boot::server::Type::Types;
Jayashree-Df0cf6652020-11-30 11:03:30 +0530156
Jayashree-Df0cf6652020-11-30 11:03:30 +0530157using IpmiValue = uint8_t;
158
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530159std::map<IpmiValue, BootSource> sourceIpmiToDbus = {
160 {0x0f, BootSource::Default}, {0x00, BootSource::RemovableMedia},
161 {0x01, BootSource::Network}, {0x02, BootSource::Disk},
162 {0x03, BootSource::ExternalMedia}, {0x09, BootSource::Network}};
Jayashree-Df0cf6652020-11-30 11:03:30 +0530163
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530164std::map<IpmiValue, BootMode> modeIpmiToDbus = {{0x06, BootMode::Setup},
165 {0x00, BootMode::Regular}};
Jayashree-Df0cf6652020-11-30 11:03:30 +0530166
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530167std::map<IpmiValue, BootType> typeIpmiToDbus = {{0x00, BootType::Legacy},
168 {0x01, BootType::EFI}};
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530169
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530170std::map<std::optional<BootSource>, IpmiValue> sourceDbusToIpmi = {
171 {BootSource::Default, 0x0f},
172 {BootSource::RemovableMedia, 0x00},
173 {BootSource::Network, 0x01},
174 {BootSource::Disk, 0x02},
175 {BootSource::ExternalMedia, 0x03}};
Jayashree-Df0cf6652020-11-30 11:03:30 +0530176
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530177std::map<std::optional<BootMode>, IpmiValue> modeDbusToIpmi = {
178 {BootMode::Setup, 0x06}, {BootMode::Regular, 0x00}};
Jayashree-Df0cf6652020-11-30 11:03:30 +0530179
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530180std::map<std::optional<BootType>, IpmiValue> typeDbusToIpmi = {
181 {BootType::Legacy, 0x00}, {BootType::EFI, 0x01}};
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530182
Jayashree-Df0cf6652020-11-30 11:03:30 +0530183static constexpr auto bootModeIntf = "xyz.openbmc_project.Control.Boot.Mode";
184static constexpr auto bootSourceIntf =
185 "xyz.openbmc_project.Control.Boot.Source";
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530186static constexpr auto bootTypeIntf = "xyz.openbmc_project.Control.Boot.Type";
Jayashree-Df0cf6652020-11-30 11:03:30 +0530187static constexpr auto bootSourceProp = "BootSource";
188static constexpr auto bootModeProp = "BootMode";
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530189static constexpr auto bootTypeProp = "BootType";
Jayashree-Df0cf6652020-11-30 11:03:30 +0530190
191auto instances(std::string s)
192{
193 std::string delimiter = " ";
194 size_t pos = 0;
195 std::string token;
196 std::vector<std::string> host;
197
198 while ((pos = s.find(delimiter)) != std::string::npos)
199 {
200 token = s.substr(0, pos);
201 host.push_back(token);
202 s.erase(0, pos + delimiter.length());
203 }
204 host.push_back(s);
205
206 return host;
207}
208
209std::optional<size_t> findHost(size_t id)
210{
211 std::string str = INSTANCES;
212 size_t hostId;
213
214 if (INSTANCES == "0")
215 {
216 hostId = id;
217 }
218 else
219 {
220 static const auto hosts = instances(str);
221 std::string num = std::to_string(id + 1);
222 auto instance = std::lower_bound(hosts.begin(), hosts.end(), num);
223
224 if ((instance == hosts.end()) || (*instance != num))
225 {
226 return std::nullopt;
227 }
228 hostId = id + 1;
229 }
230
231 return hostId;
232}
233
234std::tuple<std::string, std::string> objPath(size_t id)
235{
236 std::string hostName = "host" + std::to_string(id);
237 std::string bootObjPath =
238 "/xyz/openbmc_project/control/" + hostName + "/boot";
239 return std::make_tuple(std::move(bootObjPath), std::move(hostName));
240}
241
242} // namespace boot
243
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700244//----------------------------------------------------------------------
245// Helper functions for storing oem data
246//----------------------------------------------------------------------
247
248void flushOemData()
249{
250 std::ofstream file(JSON_OEM_DATA_FILE);
251 file << oemData;
Vijay Khemkafeaa9812019-08-27 15:08:08 -0700252 file.close();
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700253 return;
254}
255
Vijay Khemka63c99be2020-05-27 19:14:35 -0700256std::string bytesToStr(uint8_t* byte, int len)
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700257{
258 std::stringstream ss;
259 int i;
260
261 ss << std::hex;
262 for (i = 0; i < len; i++)
263 {
264 ss << std::setw(2) << std::setfill('0') << (int)byte[i];
265 }
266
267 return ss.str();
268}
269
Vijay Khemka63c99be2020-05-27 19:14:35 -0700270int strToBytes(std::string& str, uint8_t* data)
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700271{
272 std::string sstr;
Willy Tue39f9392022-06-15 13:24:20 -0700273 size_t i;
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700274
275 for (i = 0; i < (str.length()) / 2; i++)
276 {
277 sstr = str.substr(i * 2, 2);
278 data[i] = (uint8_t)std::strtol(sstr.c_str(), NULL, 16);
279 }
280 return i;
281}
282
Vijay Khemka63c99be2020-05-27 19:14:35 -0700283ipmi_ret_t getNetworkData(uint8_t lan_param, char* data)
Vijay Khemka1b6fae32019-03-25 17:43:01 -0700284{
285 ipmi_ret_t rc = IPMI_CC_OK;
286 sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
287
288 const std::string ethdevice = "eth0";
289
290 switch (static_cast<LanParam>(lan_param))
291 {
Vijay Khemkad1194022020-05-27 18:58:33 -0700292 case LanParam::IP:
293 {
Vijay Khemkaa7231892019-10-11 11:35:05 -0700294 auto ethIP = ethdevice + "/" + ipmi::network::IPV4_TYPE;
Vijay Khemka1b6fae32019-03-25 17:43:01 -0700295 std::string ipaddress;
Vijay Khemkaa7231892019-10-11 11:35:05 -0700296 auto ipObjectInfo = ipmi::network::getIPObject(
Vijay Khemka1b6fae32019-03-25 17:43:01 -0700297 bus, ipmi::network::IP_INTERFACE, ipmi::network::ROOT, ethIP);
298
299 auto properties = ipmi::getAllDbusProperties(
300 bus, ipObjectInfo.second, ipObjectInfo.first,
301 ipmi::network::IP_INTERFACE);
302
Patrick Williamsef0efbc2020-05-13 11:26:51 -0500303 ipaddress = std::get<std::string>(properties["Address"]);
Vijay Khemka1b6fae32019-03-25 17:43:01 -0700304
305 std::strcpy(data, ipaddress.c_str());
306 }
307 break;
308
Vijay Khemkad1194022020-05-27 18:58:33 -0700309 case LanParam::IPV6:
310 {
Vijay Khemkaa7231892019-10-11 11:35:05 -0700311 auto ethIP = ethdevice + "/" + ipmi::network::IPV6_TYPE;
Vijay Khemka1b6fae32019-03-25 17:43:01 -0700312 std::string ipaddress;
Vijay Khemkaa7231892019-10-11 11:35:05 -0700313 auto ipObjectInfo = ipmi::network::getIPObject(
Vijay Khemka1b6fae32019-03-25 17:43:01 -0700314 bus, ipmi::network::IP_INTERFACE, ipmi::network::ROOT, ethIP);
315
316 auto properties = ipmi::getAllDbusProperties(
317 bus, ipObjectInfo.second, ipObjectInfo.first,
318 ipmi::network::IP_INTERFACE);
319
Patrick Williamsef0efbc2020-05-13 11:26:51 -0500320 ipaddress = std::get<std::string>(properties["Address"]);
Vijay Khemka1b6fae32019-03-25 17:43:01 -0700321
322 std::strcpy(data, ipaddress.c_str());
323 }
324 break;
325
Vijay Khemkad1194022020-05-27 18:58:33 -0700326 case LanParam::MAC:
327 {
Vijay Khemka1b6fae32019-03-25 17:43:01 -0700328 std::string macAddress;
329 auto macObjectInfo =
330 ipmi::getDbusObject(bus, ipmi::network::MAC_INTERFACE,
331 ipmi::network::ROOT, ethdevice);
332
333 auto variant = ipmi::getDbusProperty(
334 bus, macObjectInfo.second, macObjectInfo.first,
335 ipmi::network::MAC_INTERFACE, "MACAddress");
336
Patrick Williamsef0efbc2020-05-13 11:26:51 -0500337 macAddress = std::get<std::string>(variant);
Vijay Khemka1b6fae32019-03-25 17:43:01 -0700338
339 sscanf(macAddress.c_str(), ipmi::network::MAC_ADDRESS_FORMAT,
340 (data), (data + 1), (data + 2), (data + 3), (data + 4),
341 (data + 5));
342 std::strcpy(data, macAddress.c_str());
343 }
344 break;
345
346 default:
347 rc = IPMI_CC_PARM_OUT_OF_RANGE;
348 }
349 return rc;
350}
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800351
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +0530352bool isMultiHostPlatform()
353{
354 bool platform;
355 if (INSTANCES == "0")
356 {
357 platform = false;
358 }
359 else
360 {
361 platform = true;
362 }
363 return platform;
364}
365
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800366// return code: 0 successful
Vijay Khemka63c99be2020-05-27 19:14:35 -0700367int8_t getFruData(std::string& data, std::string& name)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800368{
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530369 size_t pos;
370 static constexpr const auto depth = 0;
371 std::vector<std::string> paths;
372 std::string machinePath;
373 std::string baseBoard = "Baseboard";
374
375 bool platform = isMultiHostPlatform();
376 if (platform == true)
377 {
378 pos = getSelectorPosition();
379 }
380
381 sd_bus* bus = NULL;
382 int ret = sd_bus_default_system(&bus);
383 if (ret < 0)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800384 {
385 phosphor::logging::log<phosphor::logging::level::ERR>(
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530386 "Failed to connect to system bus",
387 phosphor::logging::entry("ERRNO=0x%X", -ret));
388 sd_bus_unref(bus);
389 return -1;
390 }
391 sdbusplus::bus::bus dbus(bus);
392 auto mapperCall = dbus.new_method_call("xyz.openbmc_project.ObjectMapper",
393 "/xyz/openbmc_project/object_mapper",
394 "xyz.openbmc_project.ObjectMapper",
395 "GetSubTreePaths");
396 static constexpr std::array<const char*, 1> interface = {
397 "xyz.openbmc_project.Inventory.Decorator.Asset"};
398 mapperCall.append("/xyz/openbmc_project/inventory/", depth, interface);
399
400 try
401 {
402 auto reply = dbus.call(mapperCall);
403 reply.read(paths);
404 }
405 catch (sdbusplus::exception_t& e)
406 {
407 phosphor::logging::log<phosphor::logging::level::ERR>(e.what());
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800408 return -1;
409 }
410
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530411 for (const auto& path : paths)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800412 {
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530413 if (platform == true)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800414 {
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530415 if (pos == BMC_POS)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800416 {
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530417 machinePath = baseBoard;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800418 }
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530419 else
420 {
421 machinePath = "_" + std::to_string(pos);
422 }
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800423 }
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530424 else
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800425 {
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530426 machinePath = baseBoard;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800427 }
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530428
429 auto found = path.find(machinePath);
430 if (found == -1)
431 {
432 continue;
433 }
434
435 std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
436 std::string service = getService(
437 *dbus, "xyz.openbmc_project.Inventory.Decorator.Asset", path);
438
439 auto Value = ipmi::getDbusProperty(
440 *dbus, service, path,
441 "xyz.openbmc_project.Inventory.Decorator.Asset", name);
442
443 data = std::get<std::string>(Value);
444 return 0;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800445 }
446 return -1;
447}
448
449typedef struct
450{
451 uint8_t cur_power_state;
452 uint8_t last_power_event;
453 uint8_t misc_power_state;
454 uint8_t front_panel_button_cap_status;
455} ipmi_get_chassis_status_t;
456
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800457//----------------------------------------------------------------------
458// Get Debug Frame Info
459//----------------------------------------------------------------------
Willy Tue39f9392022-06-15 13:24:20 -0700460ipmi_ret_t ipmiOemDbgGetFrameInfo(ipmi_netfn_t, ipmi_cmd_t,
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800461 ipmi_request_t request,
462 ipmi_response_t response,
Willy Tue39f9392022-06-15 13:24:20 -0700463 ipmi_data_len_t data_len, ipmi_context_t)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800464{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700465 uint8_t* req = reinterpret_cast<uint8_t*>(request);
466 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800467 uint8_t num_frames = 3;
468
469 std::memcpy(res, req, SIZE_IANA_ID); // IANA ID
470 res[SIZE_IANA_ID] = num_frames;
471 *data_len = SIZE_IANA_ID + 1;
472
473 return IPMI_CC_OK;
474}
475
476//----------------------------------------------------------------------
477// Get Debug Updated Frames
478//----------------------------------------------------------------------
Willy Tue39f9392022-06-15 13:24:20 -0700479ipmi_ret_t ipmiOemDbgGetUpdFrames(ipmi_netfn_t, ipmi_cmd_t,
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800480 ipmi_request_t request,
481 ipmi_response_t response,
Willy Tue39f9392022-06-15 13:24:20 -0700482 ipmi_data_len_t data_len, ipmi_context_t)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800483{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700484 uint8_t* req = reinterpret_cast<uint8_t*>(request);
485 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800486 uint8_t num_updates = 3;
487 *data_len = 4;
488
489 std::memcpy(res, req, SIZE_IANA_ID); // IANA ID
490 res[SIZE_IANA_ID] = num_updates;
491 *data_len = SIZE_IANA_ID + num_updates + 1;
492 res[SIZE_IANA_ID + 1] = 1; // info page update
493 res[SIZE_IANA_ID + 2] = 2; // cri sel update
494 res[SIZE_IANA_ID + 3] = 3; // cri sensor update
495
496 return IPMI_CC_OK;
497}
498
499//----------------------------------------------------------------------
500// Get Debug POST Description
501//----------------------------------------------------------------------
Willy Tue39f9392022-06-15 13:24:20 -0700502ipmi_ret_t ipmiOemDbgGetPostDesc(ipmi_netfn_t, ipmi_cmd_t,
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800503 ipmi_request_t request,
504 ipmi_response_t response,
Willy Tue39f9392022-06-15 13:24:20 -0700505 ipmi_data_len_t data_len, ipmi_context_t)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800506{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700507 uint8_t* req = reinterpret_cast<uint8_t*>(request);
508 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800509 uint8_t index = 0;
510 uint8_t next = 0;
511 uint8_t end = 0;
512 uint8_t phase = 0;
Vijay Khemkacc0d6d92019-08-27 14:51:17 -0700513 uint8_t descLen = 0;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800514 int ret;
515
516 index = req[3];
517 phase = req[4];
518
Vijay Khemkacc0d6d92019-08-27 14:51:17 -0700519 ret = plat_udbg_get_post_desc(index, &next, phase, &end, &descLen, &res[8]);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800520 if (ret)
521 {
522 memcpy(res, req, SIZE_IANA_ID); // IANA ID
523 *data_len = SIZE_IANA_ID;
524 return IPMI_CC_UNSPECIFIED_ERROR;
525 }
526
527 memcpy(res, req, SIZE_IANA_ID); // IANA ID
528 res[3] = index;
529 res[4] = next;
530 res[5] = phase;
531 res[6] = end;
Vijay Khemkacc0d6d92019-08-27 14:51:17 -0700532 res[7] = descLen;
533 *data_len = SIZE_IANA_ID + 5 + descLen;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800534
535 return IPMI_CC_OK;
536}
537
538//----------------------------------------------------------------------
539// Get Debug GPIO Description
540//----------------------------------------------------------------------
Willy Tue39f9392022-06-15 13:24:20 -0700541ipmi_ret_t ipmiOemDbgGetGpioDesc(ipmi_netfn_t, ipmi_cmd_t,
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800542 ipmi_request_t request,
543 ipmi_response_t response,
Willy Tue39f9392022-06-15 13:24:20 -0700544 ipmi_data_len_t data_len, ipmi_context_t)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800545{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700546 uint8_t* req = reinterpret_cast<uint8_t*>(request);
547 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800548
Vijay Khemka38183d62019-08-28 16:19:33 -0700549 uint8_t index = 0;
550 uint8_t next = 0;
551 uint8_t level = 0;
552 uint8_t pinDef = 0;
553 uint8_t descLen = 0;
554 int ret;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800555
Vijay Khemka38183d62019-08-28 16:19:33 -0700556 index = req[3];
557
558 ret = plat_udbg_get_gpio_desc(index, &next, &level, &pinDef, &descLen,
559 &res[8]);
560 if (ret)
561 {
562 memcpy(res, req, SIZE_IANA_ID); // IANA ID
563 *data_len = SIZE_IANA_ID;
564 return IPMI_CC_UNSPECIFIED_ERROR;
565 }
566
567 memcpy(res, req, SIZE_IANA_ID); // IANA ID
568 res[3] = index;
569 res[4] = next;
570 res[5] = level;
571 res[6] = pinDef;
572 res[7] = descLen;
573 *data_len = SIZE_IANA_ID + 5 + descLen;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800574
575 return IPMI_CC_OK;
576}
577
578//----------------------------------------------------------------------
579// Get Debug Frame Data
580//----------------------------------------------------------------------
Willy Tue39f9392022-06-15 13:24:20 -0700581ipmi_ret_t ipmiOemDbgGetFrameData(ipmi_netfn_t, ipmi_cmd_t,
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800582 ipmi_request_t request,
583 ipmi_response_t response,
Willy Tue39f9392022-06-15 13:24:20 -0700584 ipmi_data_len_t data_len, ipmi_context_t)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800585{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700586 uint8_t* req = reinterpret_cast<uint8_t*>(request);
587 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800588 uint8_t frame;
589 uint8_t page;
590 uint8_t next;
591 uint8_t count;
592 int ret;
593
594 frame = req[3];
595 page = req[4];
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800596
597 ret = plat_udbg_get_frame_data(frame, page, &next, &count, &res[7]);
598 if (ret)
599 {
600 memcpy(res, req, SIZE_IANA_ID); // IANA ID
601 *data_len = SIZE_IANA_ID;
602 return IPMI_CC_UNSPECIFIED_ERROR;
603 }
604
605 memcpy(res, req, SIZE_IANA_ID); // IANA ID
606 res[3] = frame;
607 res[4] = page;
608 res[5] = next;
609 res[6] = count;
610 *data_len = SIZE_IANA_ID + 4 + count;
611
612 return IPMI_CC_OK;
613}
614
615//----------------------------------------------------------------------
616// Get Debug Control Panel
617//----------------------------------------------------------------------
Willy Tue39f9392022-06-15 13:24:20 -0700618ipmi_ret_t ipmiOemDbgGetCtrlPanel(ipmi_netfn_t, ipmi_cmd_t,
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800619 ipmi_request_t request,
620 ipmi_response_t response,
Willy Tue39f9392022-06-15 13:24:20 -0700621 ipmi_data_len_t data_len, ipmi_context_t)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800622{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700623 uint8_t* req = reinterpret_cast<uint8_t*>(request);
624 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800625
626 uint8_t panel;
627 uint8_t operation;
628 uint8_t item;
629 uint8_t count;
630 ipmi_ret_t ret;
631
632 panel = req[3];
633 operation = req[4];
634 item = req[5];
635
636 ret = plat_udbg_control_panel(panel, operation, item, &count, &res[3]);
637
638 std::memcpy(res, req, SIZE_IANA_ID); // IANA ID
639 *data_len = SIZE_IANA_ID + count;
640
641 return ret;
642}
643
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800644//----------------------------------------------------------------------
645// Set Dimm Info (CMD_OEM_SET_DIMM_INFO)
646//----------------------------------------------------------------------
Willy Tue39f9392022-06-15 13:24:20 -0700647ipmi_ret_t ipmiOemSetDimmInfo(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t request,
648 ipmi_response_t, ipmi_data_len_t data_len,
649 ipmi_context_t)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800650{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700651 uint8_t* req = reinterpret_cast<uint8_t*>(request);
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700652
653 uint8_t index = req[0];
654 uint8_t type = req[1];
655 uint16_t speed;
656 uint32_t size;
657
658 memcpy(&speed, &req[2], 2);
659 memcpy(&size, &req[4], 4);
660
661 std::stringstream ss;
662 ss << std::hex;
663 ss << std::setw(2) << std::setfill('0') << (int)index;
664
665 oemData[KEY_SYS_CONFIG][ss.str()][KEY_DIMM_INDEX] = index;
666 oemData[KEY_SYS_CONFIG][ss.str()][KEY_DIMM_TYPE] = type;
667 oemData[KEY_SYS_CONFIG][ss.str()][KEY_DIMM_SPEED] = speed;
668 oemData[KEY_SYS_CONFIG][ss.str()][KEY_DIMM_SIZE] = size;
669
670 flushOemData();
671
672 *data_len = 0;
673
674 return IPMI_CC_OK;
675}
676
677//----------------------------------------------------------------------
678// Get Board ID (CMD_OEM_GET_BOARD_ID)
679//----------------------------------------------------------------------
Willy Tue39f9392022-06-15 13:24:20 -0700680ipmi_ret_t ipmiOemGetBoardID(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t,
681 ipmi_response_t, ipmi_data_len_t data_len,
682 ipmi_context_t)
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700683{
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700684 /* TODO: Needs to implement this after GPIO implementation */
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800685 *data_len = 0;
686
687 return IPMI_CC_OK;
688}
689
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800690/* Helper functions to set boot order */
Jayashree-Df0cf6652020-11-30 11:03:30 +0530691void setBootOrder(std::string bootObjPath, uint8_t* data,
692 std::string bootOrderKey)
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800693{
Jayashree-Df0cf6652020-11-30 11:03:30 +0530694 std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
695
696 // SETTING BOOT MODE PROPERTY
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530697 uint8_t bootModeBit = data[0] & 0x06;
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530698 auto bootValue = ipmi::boot::modeIpmiToDbus.at(bootModeBit);
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530699
Jayashree-Df0cf6652020-11-30 11:03:30 +0530700 std::string bootOption =
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530701 sdbusplus::message::convert_to_string<boot::BootMode>(bootValue);
Jayashree-Df0cf6652020-11-30 11:03:30 +0530702
703 std::string service =
704 getService(*dbus, ipmi::boot::bootModeIntf, bootObjPath);
705 setDbusProperty(*dbus, service, bootObjPath, ipmi::boot::bootModeIntf,
706 ipmi::boot::bootModeProp, bootOption);
707
708 // SETTING BOOT SOURCE PROPERTY
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530709 auto bootOrder = ipmi::boot::sourceIpmiToDbus.at(data[1]);
Jayashree-Df0cf6652020-11-30 11:03:30 +0530710 std::string bootSource =
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530711 sdbusplus::message::convert_to_string<boot::BootSource>(bootOrder);
Jayashree-Df0cf6652020-11-30 11:03:30 +0530712
713 service = getService(*dbus, ipmi::boot::bootSourceIntf, bootObjPath);
714 setDbusProperty(*dbus, service, bootObjPath, ipmi::boot::bootSourceIntf,
715 ipmi::boot::bootSourceProp, bootSource);
716
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530717 // SETTING BOOT TYPE PROPERTY
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530718 uint8_t bootTypeBit = data[0] & 0x01;
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530719 auto bootTypeVal = ipmi::boot::typeIpmiToDbus.at(bootTypeBit);
720
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530721 std::string bootType =
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530722 sdbusplus::message::convert_to_string<boot::BootType>(bootTypeVal);
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530723
724 service = getService(*dbus, ipmi::boot::bootTypeIntf, bootObjPath);
725
726 setDbusProperty(*dbus, service, bootObjPath, ipmi::boot::bootTypeIntf,
727 ipmi::boot::bootTypeProp, bootType);
728
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800729 nlohmann::json bootMode;
730 uint8_t mode = data[0];
731 int i;
732
733 bootMode["UEFI"] = (mode & BOOT_MODE_UEFI ? true : false);
734 bootMode["CMOS_CLR"] = (mode & BOOT_MODE_CMOS_CLR ? true : false);
735 bootMode["FORCE_BOOT"] = (mode & BOOT_MODE_FORCE_BOOT ? true : false);
736 bootMode["BOOT_FLAG"] = (mode & BOOT_MODE_BOOT_FLAG ? true : false);
Jayashree-Df0cf6652020-11-30 11:03:30 +0530737 oemData[bootOrderKey][KEY_BOOT_MODE] = bootMode;
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800738
739 /* Initialize boot sequence array */
Jayashree-Df0cf6652020-11-30 11:03:30 +0530740 oemData[bootOrderKey][KEY_BOOT_SEQ] = {};
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800741 for (i = 1; i < SIZE_BOOT_ORDER; i++)
742 {
743 if (data[i] >= BOOT_SEQ_ARRAY_SIZE)
Jayashree-Df0cf6652020-11-30 11:03:30 +0530744 oemData[bootOrderKey][KEY_BOOT_SEQ][i - 1] = "NA";
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800745 else
Jayashree-Df0cf6652020-11-30 11:03:30 +0530746 oemData[bootOrderKey][KEY_BOOT_SEQ][i - 1] = bootSeq[data[i]];
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800747 }
748
749 flushOemData();
750}
751
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800752//----------------------------------------------------------------------
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700753// Set Boot Order (CMD_OEM_SET_BOOT_ORDER)
754//----------------------------------------------------------------------
Jayashree-Df0cf6652020-11-30 11:03:30 +0530755ipmi::RspType<std::vector<uint8_t>>
756 ipmiOemSetBootOrder(ipmi::Context::ptr ctx, std::vector<uint8_t> data)
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700757{
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700758
Jayashree-Df0cf6652020-11-30 11:03:30 +0530759 uint8_t bootSeq[SIZE_BOOT_ORDER];
760 size_t len = data.size();
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700761
762 if (len != SIZE_BOOT_ORDER)
763 {
764 phosphor::logging::log<phosphor::logging::level::ERR>(
765 "Invalid Boot order length received");
Jayashree-Df0cf6652020-11-30 11:03:30 +0530766 return ipmi::responseReqDataLenInvalid();
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700767 }
768
Jayashree-Df0cf6652020-11-30 11:03:30 +0530769 std::copy(std::begin(data), std::end(data), bootSeq);
770 std::optional<size_t> hostId = ipmi::boot::findHost(ctx->hostIdx);
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700771
Jayashree-Df0cf6652020-11-30 11:03:30 +0530772 if (!hostId)
773 {
774 phosphor::logging::log<phosphor::logging::level::ERR>(
775 "Invalid Host Id received");
776 return ipmi::responseInvalidCommand();
777 }
778 auto [bootObjPath, hostName] = ipmi::boot::objPath(*hostId);
779
780 setBootOrder(bootObjPath, bootSeq, hostName);
781
782 return ipmi::responseSuccess(data);
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700783}
784
785//----------------------------------------------------------------------
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800786// Get Boot Order (CMD_OEM_GET_BOOT_ORDER)
787//----------------------------------------------------------------------
Jayashree-Df0cf6652020-11-30 11:03:30 +0530788ipmi::RspType<uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t>
789 ipmiOemGetBootOrder(ipmi::Context::ptr ctx)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800790{
Jayashree-Df0cf6652020-11-30 11:03:30 +0530791 uint8_t bootSeq[SIZE_BOOT_ORDER];
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700792 uint8_t mode = 0;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800793
Jayashree-Df0cf6652020-11-30 11:03:30 +0530794 std::optional<size_t> hostId = ipmi::boot::findHost(ctx->hostIdx);
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700795
Jayashree-Df0cf6652020-11-30 11:03:30 +0530796 if (!hostId)
797 {
798 phosphor::logging::log<phosphor::logging::level::ERR>(
799 "Invalid Host Id received");
800 return ipmi::responseInvalidCommand();
801 }
802 auto [bootObjPath, hostName] = ipmi::boot::objPath(*hostId);
803
Jayashree-Df0cf6652020-11-30 11:03:30 +0530804 std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
805
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530806 // GETTING PROPERTY OF MODE INTERFACE
807
Jayashree-Df0cf6652020-11-30 11:03:30 +0530808 std::string service =
809 getService(*dbus, ipmi::boot::bootModeIntf, bootObjPath);
810 Value variant =
811 getDbusProperty(*dbus, service, bootObjPath, ipmi::boot::bootModeIntf,
812 ipmi::boot::bootModeProp);
813
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530814 auto bootMode = sdbusplus::message::convert_from_string<boot::BootMode>(
Jayashree-Df0cf6652020-11-30 11:03:30 +0530815 std::get<std::string>(variant));
816
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530817 uint8_t bootOption = ipmi::boot::modeDbusToIpmi.at(bootMode);
Jayashree-Df0cf6652020-11-30 11:03:30 +0530818
819 // GETTING PROPERTY OF SOURCE INTERFACE
820
821 service = getService(*dbus, ipmi::boot::bootSourceIntf, bootObjPath);
822 variant =
823 getDbusProperty(*dbus, service, bootObjPath, ipmi::boot::bootSourceIntf,
824 ipmi::boot::bootSourceProp);
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530825
826 auto bootSource = sdbusplus::message::convert_from_string<boot::BootSource>(
Jayashree-Df0cf6652020-11-30 11:03:30 +0530827 std::get<std::string>(variant));
828
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530829 uint8_t bootOrder = ipmi::boot::sourceDbusToIpmi.at(bootSource);
830
831 // GETTING PROPERTY OF TYPE INTERFACE
832
833 service = getService(*dbus, ipmi::boot::bootTypeIntf, bootObjPath);
834 variant =
835 getDbusProperty(*dbus, service, bootObjPath, ipmi::boot::bootTypeIntf,
836 ipmi::boot::bootTypeProp);
Jayashree Dhanapal77ee4892022-04-08 16:53:51 +0530837
838 auto bootType = sdbusplus::message::convert_from_string<boot::BootType>(
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530839 std::get<std::string>(variant));
840
841 uint8_t bootTypeVal = ipmi::boot::typeDbusToIpmi.at(bootType);
842
843 uint8_t bootVal = bootOption | bootTypeVal;
Jayashree-Df0cf6652020-11-30 11:03:30 +0530844
845 if (oemData.find(hostName) == oemData.end())
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800846 {
847 /* Return default boot order 0100090203ff */
848 uint8_t defaultBoot[SIZE_BOOT_ORDER] = {
Willy Tue39f9392022-06-15 13:24:20 -0700849 BOOT_MODE_UEFI,
850 static_cast<uint8_t>(bootMap["USB_DEV"]),
851 static_cast<uint8_t>(bootMap["NET_IPV6"]),
852 static_cast<uint8_t>(bootMap["SATA_HDD"]),
853 static_cast<uint8_t>(bootMap["SATA_CD"]),
854 0xff};
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700855
Jayashree-Df0cf6652020-11-30 11:03:30 +0530856 memcpy(bootSeq, defaultBoot, SIZE_BOOT_ORDER);
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800857 phosphor::logging::log<phosphor::logging::level::INFO>(
858 "Set default boot order");
Jayashree-Df0cf6652020-11-30 11:03:30 +0530859 setBootOrder(bootObjPath, defaultBoot, hostName);
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800860 }
861 else
862 {
Jayashree-Df0cf6652020-11-30 11:03:30 +0530863 nlohmann::json bootMode = oemData[hostName][KEY_BOOT_MODE];
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800864 if (bootMode["UEFI"])
865 mode |= BOOT_MODE_UEFI;
866 if (bootMode["CMOS_CLR"])
867 mode |= BOOT_MODE_CMOS_CLR;
868 if (bootMode["BOOT_FLAG"])
869 mode |= BOOT_MODE_BOOT_FLAG;
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700870
Jayashree-Df0cf6652020-11-30 11:03:30 +0530871 bootSeq[0] = mode;
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800872
Jayashree-Df0cf6652020-11-30 11:03:30 +0530873 for (int i = 1; i < SIZE_BOOT_ORDER; i++)
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800874 {
Jayashree-Df0cf6652020-11-30 11:03:30 +0530875 std::string seqStr = oemData[hostName][KEY_BOOT_SEQ][i - 1];
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800876 if (bootMap.find(seqStr) != bootMap.end())
Jayashree-Df0cf6652020-11-30 11:03:30 +0530877 bootSeq[i] = bootMap[seqStr];
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800878 else
Jayashree-Df0cf6652020-11-30 11:03:30 +0530879 bootSeq[i] = 0xff;
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800880 }
881 }
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800882
Jayashree Dhanapal778147d2022-03-30 16:48:53 +0530883 return ipmi::responseSuccess(bootVal, bootOrder, bootSeq[2], bootSeq[3],
Jayashree-Df0cf6652020-11-30 11:03:30 +0530884 bootSeq[4], bootSeq[5]);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800885}
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800886// Set Machine Config Info (CMD_OEM_SET_MACHINE_CONFIG_INFO)
887//----------------------------------------------------------------------
Willy Tue39f9392022-06-15 13:24:20 -0700888ipmi_ret_t ipmiOemSetMachineCfgInfo(ipmi_netfn_t, ipmi_cmd_t,
889 ipmi_request_t request, ipmi_response_t,
890 ipmi_data_len_t data_len, ipmi_context_t)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800891{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700892 machineConfigInfo_t* req = reinterpret_cast<machineConfigInfo_t*>(request);
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700893 uint8_t len = *data_len;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800894
895 *data_len = 0;
896
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700897 if (len < sizeof(machineConfigInfo_t))
898 {
899 phosphor::logging::log<phosphor::logging::level::ERR>(
900 "Invalid machine configuration length received");
901 return IPMI_CC_REQ_DATA_LEN_INVALID;
902 }
903
Vijay Khemka63c99be2020-05-27 19:14:35 -0700904 if (req->chassis_type >= sizeof(chassisType) / sizeof(uint8_t*))
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700905 oemData[KEY_MC_CONFIG][KEY_MC_CHAS_TYPE] = "UNKNOWN";
906 else
907 oemData[KEY_MC_CONFIG][KEY_MC_CHAS_TYPE] =
908 chassisType[req->chassis_type];
909
Vijay Khemka63c99be2020-05-27 19:14:35 -0700910 if (req->mb_type >= sizeof(mbType) / sizeof(uint8_t*))
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700911 oemData[KEY_MC_CONFIG][KEY_MC_MB_TYPE] = "UNKNOWN";
912 else
913 oemData[KEY_MC_CONFIG][KEY_MC_MB_TYPE] = mbType[req->mb_type];
914
915 oemData[KEY_MC_CONFIG][KEY_MC_PROC_CNT] = req->proc_cnt;
916 oemData[KEY_MC_CONFIG][KEY_MC_MEM_CNT] = req->mem_cnt;
917 oemData[KEY_MC_CONFIG][KEY_MC_HDD35_CNT] = req->hdd35_cnt;
918 oemData[KEY_MC_CONFIG][KEY_MC_HDD25_CNT] = req->hdd25_cnt;
919
Vijay Khemka63c99be2020-05-27 19:14:35 -0700920 if (req->riser_type >= sizeof(riserType) / sizeof(uint8_t*))
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700921 oemData[KEY_MC_CONFIG][KEY_MC_RSR_TYPE] = "UNKNOWN";
922 else
923 oemData[KEY_MC_CONFIG][KEY_MC_RSR_TYPE] = riserType[req->riser_type];
924
925 oemData[KEY_MC_CONFIG][KEY_MC_PCIE_LOC] = {};
926 int i = 0;
927 if (req->pcie_card_loc & BIT_0)
928 oemData[KEY_MC_CONFIG][KEY_MC_PCIE_LOC][i++] = "SLOT1";
929 if (req->pcie_card_loc & BIT_1)
930 oemData[KEY_MC_CONFIG][KEY_MC_PCIE_LOC][i++] = "SLOT2";
931 if (req->pcie_card_loc & BIT_2)
932 oemData[KEY_MC_CONFIG][KEY_MC_PCIE_LOC][i++] = "SLOT3";
933 if (req->pcie_card_loc & BIT_3)
934 oemData[KEY_MC_CONFIG][KEY_MC_PCIE_LOC][i++] = "SLOT4";
935
Vijay Khemka63c99be2020-05-27 19:14:35 -0700936 if (req->slot1_pcie_type >= sizeof(pcieType) / sizeof(uint8_t*))
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700937 oemData[KEY_MC_CONFIG][KEY_MC_SLOT1_TYPE] = "UNKNOWN";
938 else
939 oemData[KEY_MC_CONFIG][KEY_MC_SLOT1_TYPE] =
940 pcieType[req->slot1_pcie_type];
941
Vijay Khemka63c99be2020-05-27 19:14:35 -0700942 if (req->slot2_pcie_type >= sizeof(pcieType) / sizeof(uint8_t*))
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700943 oemData[KEY_MC_CONFIG][KEY_MC_SLOT2_TYPE] = "UNKNOWN";
944 else
945 oemData[KEY_MC_CONFIG][KEY_MC_SLOT2_TYPE] =
946 pcieType[req->slot2_pcie_type];
947
Vijay Khemka63c99be2020-05-27 19:14:35 -0700948 if (req->slot3_pcie_type >= sizeof(pcieType) / sizeof(uint8_t*))
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700949 oemData[KEY_MC_CONFIG][KEY_MC_SLOT3_TYPE] = "UNKNOWN";
950 else
951 oemData[KEY_MC_CONFIG][KEY_MC_SLOT3_TYPE] =
952 pcieType[req->slot3_pcie_type];
953
Vijay Khemka63c99be2020-05-27 19:14:35 -0700954 if (req->slot4_pcie_type >= sizeof(pcieType) / sizeof(uint8_t*))
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700955 oemData[KEY_MC_CONFIG][KEY_MC_SLOT4_TYPE] = "UNKNOWN";
956 else
957 oemData[KEY_MC_CONFIG][KEY_MC_SLOT4_TYPE] =
958 pcieType[req->slot4_pcie_type];
959
960 oemData[KEY_MC_CONFIG][KEY_MC_AEP_CNT] = req->aep_mem_cnt;
961
962 flushOemData();
963
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800964 return IPMI_CC_OK;
965}
966
967//----------------------------------------------------------------------
968// Set POST start (CMD_OEM_SET_POST_START)
969//----------------------------------------------------------------------
Willy Tue39f9392022-06-15 13:24:20 -0700970ipmi_ret_t ipmiOemSetPostStart(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t,
971 ipmi_response_t, ipmi_data_len_t data_len,
972 ipmi_context_t)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800973{
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800974 phosphor::logging::log<phosphor::logging::level::INFO>("POST Start Event");
975
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700976 /* Do nothing, return success */
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800977 *data_len = 0;
978 return IPMI_CC_OK;
979}
980
981//----------------------------------------------------------------------
982// Set POST End (CMD_OEM_SET_POST_END)
983//----------------------------------------------------------------------
Willy Tue39f9392022-06-15 13:24:20 -0700984ipmi_ret_t ipmiOemSetPostEnd(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t,
985 ipmi_response_t, ipmi_data_len_t data_len,
986 ipmi_context_t)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800987{
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700988 struct timespec ts;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800989
990 phosphor::logging::log<phosphor::logging::level::INFO>("POST End Event");
991
992 *data_len = 0;
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700993
994 // Timestamp post end time.
995 clock_gettime(CLOCK_REALTIME, &ts);
996 oemData[KEY_TS_SLED] = ts.tv_sec;
997 flushOemData();
998
999 // Sync time with system
1000 // TODO: Add code for syncing time
1001
1002 return IPMI_CC_OK;
1003}
1004
1005//----------------------------------------------------------------------
1006// Set PPIN Info (CMD_OEM_SET_PPIN_INFO)
1007//----------------------------------------------------------------------
1008// Inform BMC about PPIN data of 8 bytes for each CPU
1009//
1010// Request:
1011// Byte 1:8 – CPU0 PPIN data
1012// Optional:
1013// Byte 9:16 – CPU1 PPIN data
1014//
1015// Response:
1016// Byte 1 – Completion Code
Willy Tue39f9392022-06-15 13:24:20 -07001017ipmi_ret_t ipmiOemSetPPINInfo(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t request,
1018 ipmi_response_t, ipmi_data_len_t data_len,
1019 ipmi_context_t)
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001020{
Vijay Khemka63c99be2020-05-27 19:14:35 -07001021 uint8_t* req = reinterpret_cast<uint8_t*>(request);
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001022 std::string ppinStr;
1023 int len;
1024
1025 if (*data_len > SIZE_CPU_PPIN * 2)
1026 len = SIZE_CPU_PPIN * 2;
1027 else
1028 len = *data_len;
1029 *data_len = 0;
1030
1031 ppinStr = bytesToStr(req, len);
1032 oemData[KEY_PPIN_INFO] = ppinStr.c_str();
1033 flushOemData();
1034
1035 return IPMI_CC_OK;
1036}
1037
1038//----------------------------------------------------------------------
1039// Set ADR Trigger (CMD_OEM_SET_ADR_TRIGGER)
1040//----------------------------------------------------------------------
Willy Tue39f9392022-06-15 13:24:20 -07001041ipmi_ret_t ipmiOemSetAdrTrigger(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t,
1042 ipmi_response_t, ipmi_data_len_t data_len,
1043 ipmi_context_t)
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001044{
1045 /* Do nothing, return success */
1046 *data_len = 0;
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001047 return IPMI_CC_OK;
1048}
1049
Vijay Khemkaf2246ce2020-05-27 14:26:35 -07001050// Helper function to set guid at offset in EEPROM
Willy Tue39f9392022-06-15 13:24:20 -07001051[[maybe_unused]] static int setGUID(off_t offset, uint8_t* guid)
Vijay Khemkaf2246ce2020-05-27 14:26:35 -07001052{
1053 int fd = -1;
1054 ssize_t len;
1055 int ret = 0;
1056
1057 errno = 0;
1058
1059 // Check if file is present
1060 if (access(FRU_EEPROM, F_OK) == -1)
1061 {
1062 std::cerr << "Unable to access: " << FRU_EEPROM << std::endl;
1063 return errno;
1064 }
1065
1066 // Open the file
1067 fd = open(FRU_EEPROM, O_WRONLY);
1068 if (fd == -1)
1069 {
1070 std::cerr << "Unable to open: " << FRU_EEPROM << std::endl;
1071 return errno;
1072 }
1073
1074 // seek to the offset
1075 lseek(fd, offset, SEEK_SET);
1076
1077 // Write bytes to location
1078 len = write(fd, guid, GUID_SIZE);
1079 if (len != GUID_SIZE)
1080 {
1081 phosphor::logging::log<phosphor::logging::level::ERR>(
1082 "GUID write data to EEPROM failed");
1083 ret = errno;
1084 }
1085
1086 close(fd);
1087 return ret;
1088}
1089
1090//----------------------------------------------------------------------
1091// Set System GUID (CMD_OEM_SET_SYSTEM_GUID)
1092//----------------------------------------------------------------------
Manikandan Elumalai5f8e3432020-12-02 03:46:55 +05301093#if BIC_ENABLED
Willy Tue39f9392022-06-15 13:24:20 -07001094ipmi::RspType<> ipmiOemSetSystemGuid(ipmi::Context::ptr ctx, uint8_t,
Manikandan Elumalai5f8e3432020-12-02 03:46:55 +05301095 std::vector<uint8_t> reqData)
1096{
1097 std::vector<uint8_t> respData;
1098
1099 if (reqData.size() != GUID_SIZE) // 16bytes
1100 {
1101
1102 return ipmi::responseReqDataLenInvalid();
1103 }
1104
Manikandan Elumalai5f8e3432020-12-02 03:46:55 +05301105 uint8_t bicAddr = (uint8_t)ctx->hostIdx << 2;
1106
1107 if (sendBicCmd(ctx->netFn, ctx->cmd, bicAddr, reqData, respData))
1108 return ipmi::responseUnspecifiedError();
1109
1110 return ipmi::responseSuccess();
1111}
1112
1113#else
Vijay Khemkaf2246ce2020-05-27 14:26:35 -07001114ipmi_ret_t ipmiOemSetSystemGuid(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
1115 ipmi_request_t request,
1116 ipmi_response_t response,
1117 ipmi_data_len_t data_len,
1118 ipmi_context_t context)
1119{
1120 uint8_t* req = reinterpret_cast<uint8_t*>(request);
1121
1122 if (*data_len != GUID_SIZE) // 16bytes
1123 {
1124 *data_len = 0;
1125 return IPMI_CC_REQ_DATA_LEN_INVALID;
1126 }
1127
1128 *data_len = 0;
1129
1130 if (setGUID(OFFSET_SYS_GUID, req))
1131 {
1132 return IPMI_CC_UNSPECIFIED_ERROR;
1133 }
1134 return IPMI_CC_OK;
1135}
Manikandan Elumalai5f8e3432020-12-02 03:46:55 +05301136#endif
Vijay Khemkaf2246ce2020-05-27 14:26:35 -07001137
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001138//----------------------------------------------------------------------
1139// Set Bios Flash Info (CMD_OEM_SET_BIOS_FLASH_INFO)
1140//----------------------------------------------------------------------
Willy Tue39f9392022-06-15 13:24:20 -07001141ipmi_ret_t ipmiOemSetBiosFlashInfo(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t,
1142 ipmi_response_t, ipmi_data_len_t data_len,
1143 ipmi_context_t)
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001144{
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001145 /* Do nothing, return success */
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001146 *data_len = 0;
1147 return IPMI_CC_OK;
1148}
1149
1150//----------------------------------------------------------------------
1151// Set PPR (CMD_OEM_SET_PPR)
1152//----------------------------------------------------------------------
Willy Tue39f9392022-06-15 13:24:20 -07001153ipmi_ret_t ipmiOemSetPpr(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t request,
1154 ipmi_response_t, ipmi_data_len_t data_len,
1155 ipmi_context_t)
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001156{
Vijay Khemka63c99be2020-05-27 19:14:35 -07001157 uint8_t* req = reinterpret_cast<uint8_t*>(request);
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001158 uint8_t pprCnt, pprAct, pprIndex;
1159 uint8_t selParam = req[0];
1160 uint8_t len = *data_len;
1161 std::stringstream ss;
1162 std::string str;
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001163
1164 *data_len = 0;
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001165
1166 switch (selParam)
1167 {
1168 case PPR_ACTION:
1169 if (oemData[KEY_PPR].find(KEY_PPR_ROW_COUNT) ==
1170 oemData[KEY_PPR].end())
1171 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
1172
1173 pprCnt = oemData[KEY_PPR][KEY_PPR_ROW_COUNT];
1174 if (pprCnt == 0)
1175 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
1176
1177 pprAct = req[1];
1178 /* Check if ppr is enabled or disabled */
1179 if (!(pprAct & 0x80))
1180 pprAct = 0;
1181
1182 oemData[KEY_PPR][KEY_PPR_ACTION] = pprAct;
1183 break;
1184 case PPR_ROW_COUNT:
1185 if (req[1] > 100)
1186 return IPMI_CC_PARM_OUT_OF_RANGE;
1187
1188 oemData[KEY_PPR][KEY_PPR_ROW_COUNT] = req[1];
1189 break;
1190 case PPR_ROW_ADDR:
1191 pprIndex = req[1];
1192 if (pprIndex > 100)
1193 return IPMI_CC_PARM_OUT_OF_RANGE;
1194
1195 if (len < PPR_ROW_ADDR_LEN + 1)
1196 {
1197 phosphor::logging::log<phosphor::logging::level::ERR>(
1198 "Invalid PPR Row Address length received");
1199 return IPMI_CC_REQ_DATA_LEN_INVALID;
1200 }
1201
1202 ss << std::hex;
1203 ss << std::setw(2) << std::setfill('0') << (int)pprIndex;
1204
1205 oemData[KEY_PPR][ss.str()][KEY_PPR_INDEX] = pprIndex;
1206
1207 str = bytesToStr(&req[1], PPR_ROW_ADDR_LEN);
1208 oemData[KEY_PPR][ss.str()][KEY_PPR_ROW_ADDR] = str.c_str();
1209 break;
1210 case PPR_HISTORY_DATA:
1211 pprIndex = req[1];
1212 if (pprIndex > 100)
1213 return IPMI_CC_PARM_OUT_OF_RANGE;
1214
1215 if (len < PPR_HST_DATA_LEN + 1)
1216 {
1217 phosphor::logging::log<phosphor::logging::level::ERR>(
1218 "Invalid PPR history data length received");
1219 return IPMI_CC_REQ_DATA_LEN_INVALID;
1220 }
1221
1222 ss << std::hex;
1223 ss << std::setw(2) << std::setfill('0') << (int)pprIndex;
1224
1225 oemData[KEY_PPR][ss.str()][KEY_PPR_INDEX] = pprIndex;
1226
1227 str = bytesToStr(&req[1], PPR_HST_DATA_LEN);
1228 oemData[KEY_PPR][ss.str()][KEY_PPR_HST_DATA] = str.c_str();
1229 break;
1230 default:
1231 return IPMI_CC_PARM_OUT_OF_RANGE;
1232 break;
1233 }
1234
1235 flushOemData();
1236
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001237 return IPMI_CC_OK;
1238}
1239
1240//----------------------------------------------------------------------
1241// Get PPR (CMD_OEM_GET_PPR)
1242//----------------------------------------------------------------------
Willy Tue39f9392022-06-15 13:24:20 -07001243ipmi_ret_t ipmiOemGetPpr(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t request,
1244 ipmi_response_t response, ipmi_data_len_t data_len,
1245 ipmi_context_t)
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001246{
Vijay Khemka63c99be2020-05-27 19:14:35 -07001247 uint8_t* req = reinterpret_cast<uint8_t*>(request);
1248 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001249 uint8_t pprCnt, pprIndex;
1250 uint8_t selParam = req[0];
1251 std::stringstream ss;
1252 std::string str;
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001253
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001254 /* Any failure will return zero length data */
1255 *data_len = 0;
1256
1257 switch (selParam)
1258 {
1259 case PPR_ACTION:
1260 res[0] = 0;
1261 *data_len = 1;
1262
1263 if (oemData[KEY_PPR].find(KEY_PPR_ROW_COUNT) !=
1264 oemData[KEY_PPR].end())
1265 {
1266 pprCnt = oemData[KEY_PPR][KEY_PPR_ROW_COUNT];
1267 if (pprCnt != 0)
1268 {
1269 if (oemData[KEY_PPR].find(KEY_PPR_ACTION) !=
1270 oemData[KEY_PPR].end())
1271 {
1272 res[0] = oemData[KEY_PPR][KEY_PPR_ACTION];
1273 }
1274 }
1275 }
1276 break;
1277 case PPR_ROW_COUNT:
1278 res[0] = 0;
1279 *data_len = 1;
1280 if (oemData[KEY_PPR].find(KEY_PPR_ROW_COUNT) !=
1281 oemData[KEY_PPR].end())
1282 res[0] = oemData[KEY_PPR][KEY_PPR_ROW_COUNT];
1283 break;
1284 case PPR_ROW_ADDR:
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_ROW_ADDR) ==
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_ROW_ADDR];
1300 *data_len = strToBytes(str, res);
1301 break;
1302 case PPR_HISTORY_DATA:
1303 pprIndex = req[1];
1304 if (pprIndex > 100)
1305 return IPMI_CC_PARM_OUT_OF_RANGE;
1306
1307 ss << std::hex;
1308 ss << std::setw(2) << std::setfill('0') << (int)pprIndex;
1309
1310 if (oemData[KEY_PPR].find(ss.str()) == oemData[KEY_PPR].end())
1311 return IPMI_CC_PARM_OUT_OF_RANGE;
1312
1313 if (oemData[KEY_PPR][ss.str()].find(KEY_PPR_HST_DATA) ==
1314 oemData[KEY_PPR][ss.str()].end())
1315 return IPMI_CC_PARM_OUT_OF_RANGE;
1316
1317 str = oemData[KEY_PPR][ss.str()][KEY_PPR_HST_DATA];
1318 *data_len = strToBytes(str, res);
1319 break;
1320 default:
1321 return IPMI_CC_PARM_OUT_OF_RANGE;
1322 break;
1323 }
1324
1325 return IPMI_CC_OK;
1326}
1327
1328/* FB OEM QC Commands */
1329
1330//----------------------------------------------------------------------
1331// Set Proc Info (CMD_OEM_Q_SET_PROC_INFO)
1332//----------------------------------------------------------------------
1333//"Request:
1334// Byte 1:3 – Manufacturer ID – XXYYZZ h, LSB first
1335// Byte 4 – Processor Index, 0 base
1336// Byte 5 – Parameter Selector
1337// Byte 6..N – Configuration parameter data (see below for Parameters
1338// of Processor Information)
1339// Response:
1340// Byte 1 – Completion code
1341//
1342// Parameter#1: (Processor Product Name)
1343//
1344// Byte 1..48 –Product name(ASCII code)
1345// Ex. Intel(R) Xeon(R) CPU E5-2685 v3 @ 2.60GHz
1346//
1347// Param#2: Processor Basic Information
1348// Byte 1 – Core Number
1349// Byte 2 – Thread Number (LSB)
1350// Byte 3 – Thread Number (MSB)
1351// Byte 4 – Processor frequency in MHz (LSB)
1352// Byte 5 – Processor frequency in MHz (MSB)
1353// Byte 6..7 – Revision
1354//
Willy Tue39f9392022-06-15 13:24:20 -07001355ipmi_ret_t ipmiOemQSetProcInfo(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t request,
1356 ipmi_response_t, ipmi_data_len_t data_len,
1357 ipmi_context_t)
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001358{
Vijay Khemka63c99be2020-05-27 19:14:35 -07001359 qProcInfo_t* req = reinterpret_cast<qProcInfo_t*>(request);
1360 uint8_t numParam = sizeof(cpuInfoKey) / sizeof(uint8_t*);
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001361 std::stringstream ss;
1362 std::string str;
1363 uint8_t len = *data_len;
1364
1365 *data_len = 0;
1366
1367 /* check for requested data params */
1368 if (len < 5 || req->paramSel < 1 || req->paramSel >= numParam)
1369 {
1370 phosphor::logging::log<phosphor::logging::level::ERR>(
1371 "Invalid parameter received");
1372 return IPMI_CC_PARM_OUT_OF_RANGE;
1373 }
1374
1375 len = len - 5; // Get Actual data length
1376
1377 ss << std::hex;
1378 ss << std::setw(2) << std::setfill('0') << (int)req->procIndex;
1379 oemData[KEY_Q_PROC_INFO][ss.str()][KEY_PROC_INDEX] = req->procIndex;
1380
1381 str = bytesToStr(req->data, len);
1382 oemData[KEY_Q_PROC_INFO][ss.str()][cpuInfoKey[req->paramSel]] = str.c_str();
1383 flushOemData();
1384
1385 return IPMI_CC_OK;
1386}
1387
1388//----------------------------------------------------------------------
1389// Get Proc Info (CMD_OEM_Q_GET_PROC_INFO)
1390//----------------------------------------------------------------------
1391// Request:
1392// Byte 1:3 – Manufacturer ID – XXYYZZ h, LSB first
1393// Byte 4 – Processor Index, 0 base
1394// Byte 5 – Parameter Selector
1395// Response:
1396// Byte 1 – Completion code
1397// Byte 2..N – Configuration Parameter Data (see below for Parameters
1398// of Processor Information)
1399//
1400// Parameter#1: (Processor Product Name)
1401//
1402// Byte 1..48 –Product name(ASCII code)
1403// Ex. Intel(R) Xeon(R) CPU E5-2685 v3 @ 2.60GHz
1404//
1405// Param#2: Processor Basic Information
1406// Byte 1 – Core Number
1407// Byte 2 – Thread Number (LSB)
1408// Byte 3 – Thread Number (MSB)
1409// Byte 4 – Processor frequency in MHz (LSB)
1410// Byte 5 – Processor frequency in MHz (MSB)
1411// Byte 6..7 – Revision
1412//
Willy Tue39f9392022-06-15 13:24:20 -07001413ipmi_ret_t ipmiOemQGetProcInfo(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t request,
1414 ipmi_response_t response,
1415 ipmi_data_len_t data_len, ipmi_context_t)
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001416{
Vijay Khemka63c99be2020-05-27 19:14:35 -07001417 qProcInfo_t* req = reinterpret_cast<qProcInfo_t*>(request);
1418 uint8_t numParam = sizeof(cpuInfoKey) / sizeof(uint8_t*);
1419 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001420 std::stringstream ss;
1421 std::string str;
1422
1423 *data_len = 0;
1424
1425 /* check for requested data params */
1426 if (req->paramSel < 1 || req->paramSel >= numParam)
1427 {
1428 phosphor::logging::log<phosphor::logging::level::ERR>(
1429 "Invalid parameter received");
1430 return IPMI_CC_PARM_OUT_OF_RANGE;
1431 }
1432
1433 ss << std::hex;
1434 ss << std::setw(2) << std::setfill('0') << (int)req->procIndex;
1435
1436 if (oemData[KEY_Q_PROC_INFO].find(ss.str()) ==
1437 oemData[KEY_Q_PROC_INFO].end())
1438 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
1439
1440 if (oemData[KEY_Q_PROC_INFO][ss.str()].find(cpuInfoKey[req->paramSel]) ==
1441 oemData[KEY_Q_PROC_INFO][ss.str()].end())
1442 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
1443
1444 str = oemData[KEY_Q_PROC_INFO][ss.str()][cpuInfoKey[req->paramSel]];
1445 *data_len = strToBytes(str, res);
1446
1447 return IPMI_CC_OK;
1448}
1449
1450//----------------------------------------------------------------------
1451// Set Dimm Info (CMD_OEM_Q_SET_DIMM_INFO)
1452//----------------------------------------------------------------------
1453// Request:
1454// Byte 1:3 – Manufacturer ID – XXYYZZh, LSB first
1455// Byte 4 – DIMM Index, 0 base
1456// Byte 5 – Parameter Selector
1457// Byte 6..N – Configuration parameter data (see below for Parameters
1458// of DIMM Information)
1459// Response:
1460// Byte 1 – Completion code
1461//
1462// Param#1 (DIMM Location):
1463// Byte 1 – DIMM Present
1464// Byte 1 – DIMM Present
1465// 01h – Present
1466// FFh – Not Present
1467// Byte 2 – Node Number, 0 base
1468// Byte 3 – Channel Number , 0 base
1469// Byte 4 – DIMM Number , 0 base
1470//
1471// Param#2 (DIMM Type):
1472// Byte 1 – DIMM Type
1473// Bit [7:6]
1474// For DDR3
1475// 00 – Normal Voltage (1.5V)
1476// 01 – Ultra Low Voltage (1.25V)
1477// 10 – Low Voltage (1.35V)
1478// 11 – Reserved
1479// For DDR4
1480// 00 – Reserved
1481// 01 – Reserved
1482// 10 – Reserved
1483// 11 – Normal Voltage (1.2V)
1484// Bit [5:0]
1485// 0x00 – SDRAM
1486// 0x01 – DDR-1 RAM
1487// 0x02 – Rambus
1488// 0x03 – DDR-2 RAM
1489// 0x04 – FBDIMM
1490// 0x05 – DDR-3 RAM
1491// 0x06 – DDR-4 RAM
1492//
1493// Param#3 (DIMM Speed):
1494// Byte 1..2 – DIMM speed in MHz, LSB
1495// Byte 3..6 – DIMM size in Mbytes, LSB
1496//
1497// Param#4 (Module Part Number):
1498// Byte 1..20 –Module Part Number (JEDEC Standard No. 21-C)
1499//
1500// Param#5 (Module Serial Number):
1501// Byte 1..4 –Module Serial Number (JEDEC Standard No. 21-C)
1502//
1503// Param#6 (Module Manufacturer ID):
1504// Byte 1 - Module Manufacturer ID, LSB
1505// Byte 2 - Module Manufacturer ID, MSB
1506//
Willy Tue39f9392022-06-15 13:24:20 -07001507ipmi_ret_t ipmiOemQSetDimmInfo(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t request,
1508 ipmi_response_t, ipmi_data_len_t data_len,
1509 ipmi_context_t)
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001510{
Vijay Khemka63c99be2020-05-27 19:14:35 -07001511 qDimmInfo_t* req = reinterpret_cast<qDimmInfo_t*>(request);
1512 uint8_t numParam = sizeof(dimmInfoKey) / sizeof(uint8_t*);
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001513 std::stringstream ss;
1514 std::string str;
1515 uint8_t len = *data_len;
1516
1517 *data_len = 0;
1518
1519 /* check for requested data params */
1520 if (len < 5 || req->paramSel < 1 || req->paramSel >= numParam)
1521 {
1522 phosphor::logging::log<phosphor::logging::level::ERR>(
1523 "Invalid parameter received");
1524 return IPMI_CC_PARM_OUT_OF_RANGE;
1525 }
1526
1527 len = len - 5; // Get Actual data length
1528
1529 ss << std::hex;
1530 ss << std::setw(2) << std::setfill('0') << (int)req->dimmIndex;
1531 oemData[KEY_Q_DIMM_INFO][ss.str()][KEY_DIMM_INDEX] = req->dimmIndex;
1532
1533 str = bytesToStr(req->data, len);
1534 oemData[KEY_Q_DIMM_INFO][ss.str()][dimmInfoKey[req->paramSel]] =
1535 str.c_str();
1536 flushOemData();
1537
1538 return IPMI_CC_OK;
1539}
1540
1541//----------------------------------------------------------------------
1542// Get Dimm Info (CMD_OEM_Q_GET_DIMM_INFO)
1543//----------------------------------------------------------------------
1544// Request:
1545// Byte 1:3 – Manufacturer ID – XXYYZZh, LSB first
1546// Byte 4 – DIMM Index, 0 base
1547// Byte 5 – Parameter Selector
1548// Byte 6..N – Configuration parameter data (see below for Parameters
1549// of DIMM Information)
1550// Response:
1551// Byte 1 – Completion code
1552// Byte 2..N – Configuration Parameter Data (see Table_1213h Parameters
1553// of DIMM Information)
1554//
1555// Param#1 (DIMM Location):
1556// Byte 1 – DIMM Present
1557// Byte 1 – DIMM Present
1558// 01h – Present
1559// FFh – Not Present
1560// Byte 2 – Node Number, 0 base
1561// Byte 3 – Channel Number , 0 base
1562// Byte 4 – DIMM Number , 0 base
1563//
1564// Param#2 (DIMM Type):
1565// Byte 1 – DIMM Type
1566// Bit [7:6]
1567// For DDR3
1568// 00 – Normal Voltage (1.5V)
1569// 01 – Ultra Low Voltage (1.25V)
1570// 10 – Low Voltage (1.35V)
1571// 11 – Reserved
1572// For DDR4
1573// 00 – Reserved
1574// 01 – Reserved
1575// 10 – Reserved
1576// 11 – Normal Voltage (1.2V)
1577// Bit [5:0]
1578// 0x00 – SDRAM
1579// 0x01 – DDR-1 RAM
1580// 0x02 – Rambus
1581// 0x03 – DDR-2 RAM
1582// 0x04 – FBDIMM
1583// 0x05 – DDR-3 RAM
1584// 0x06 – DDR-4 RAM
1585//
1586// Param#3 (DIMM Speed):
1587// Byte 1..2 – DIMM speed in MHz, LSB
1588// Byte 3..6 – DIMM size in Mbytes, LSB
1589//
1590// Param#4 (Module Part Number):
1591// Byte 1..20 –Module Part Number (JEDEC Standard No. 21-C)
1592//
1593// Param#5 (Module Serial Number):
1594// Byte 1..4 –Module Serial Number (JEDEC Standard No. 21-C)
1595//
1596// Param#6 (Module Manufacturer ID):
1597// Byte 1 - Module Manufacturer ID, LSB
1598// Byte 2 - Module Manufacturer ID, MSB
1599//
Willy Tue39f9392022-06-15 13:24:20 -07001600ipmi_ret_t ipmiOemQGetDimmInfo(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t request,
1601 ipmi_response_t response,
1602 ipmi_data_len_t data_len, ipmi_context_t)
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001603{
Vijay Khemka63c99be2020-05-27 19:14:35 -07001604 qDimmInfo_t* req = reinterpret_cast<qDimmInfo_t*>(request);
1605 uint8_t numParam = sizeof(dimmInfoKey) / sizeof(uint8_t*);
1606 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001607 std::stringstream ss;
1608 std::string str;
1609
1610 *data_len = 0;
1611
1612 /* check for requested data params */
1613 if (req->paramSel < 1 || req->paramSel >= numParam)
1614 {
1615 phosphor::logging::log<phosphor::logging::level::ERR>(
1616 "Invalid parameter received");
1617 return IPMI_CC_PARM_OUT_OF_RANGE;
1618 }
1619
1620 ss << std::hex;
1621 ss << std::setw(2) << std::setfill('0') << (int)req->dimmIndex;
1622
1623 if (oemData[KEY_Q_DIMM_INFO].find(ss.str()) ==
1624 oemData[KEY_Q_DIMM_INFO].end())
1625 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
1626
1627 if (oemData[KEY_Q_DIMM_INFO][ss.str()].find(dimmInfoKey[req->paramSel]) ==
1628 oemData[KEY_Q_DIMM_INFO][ss.str()].end())
1629 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
1630
1631 str = oemData[KEY_Q_DIMM_INFO][ss.str()][dimmInfoKey[req->paramSel]];
1632 *data_len = strToBytes(str, res);
1633
1634 return IPMI_CC_OK;
1635}
1636
1637//----------------------------------------------------------------------
1638// Set Drive Info (CMD_OEM_Q_SET_DRIVE_INFO)
1639//----------------------------------------------------------------------
1640// BIOS issue this command to provide HDD information to BMC.
1641//
1642// BIOS just can get information by standard ATA / SMART command for
1643// OB SATA controller.
1644// BIOS can get
1645// 1. Serial Number
1646// 2. Model Name
1647// 3. HDD FW Version
1648// 4. HDD Capacity
1649// 5. HDD WWN
1650//
1651// Use Get HDD info Param #5 to know the MAX HDD info index.
1652//
1653// Request:
1654// Byte 1:3 – Quanta Manufacturer ID – 001C4Ch, LSB first
1655// Byte 4 –
1656// [7:4] Reserved
1657// [3:0] HDD Controller Type
1658// 0x00 – BIOS
1659// 0x01 – Expander
1660// 0x02 – LSI
1661// Byte 5 – HDD Info Index, 0 base
1662// Byte 6 – Parameter Selector
1663// Byte 7..N – Configuration parameter data (see Table_1415h Parameters of HDD
1664// Information)
1665//
1666// Response:
1667// Byte 1 – Completion Code
1668//
1669// Param#0 (HDD Location):
1670// Byte 1 – Controller
1671// [7:3] Device Number
1672// [2:0] Function Number
1673// For Intel C610 series (Wellsburg)
1674// D31:F2 (0xFA) – SATA control 1
1675// D31:F5 (0xFD) – SATA control 2
1676// D17:F4 (0x8C) – sSata control
1677// Byte 2 – Port Number
1678// Byte 3 – Location (0xFF: No HDD Present)
1679// BIOS default set Byte 3 to 0xFF, if No HDD Present. And then skip send param
1680// #1~4, #6, #7 to BMC (still send param #5) BIOS default set Byte 3 to 0, if
1681// the HDD present. BMC or other people who know the HDD location has
1682// responsibility for update Location info
1683//
1684// Param#1 (Serial Number):
1685// Bytes 1..33: HDD Serial Number
1686//
1687// Param#2 (Model Name):
1688// Byte 1..33 – HDD Model Name
1689//
1690// Param#3 (HDD FW Version):
1691// Byte 1..17 –HDD FW version
1692//
1693// Param#4 (Capacity):
1694// Byte 1..4 –HDD Block Size, LSB
1695// Byte 5..12 - HDD Block Number, LSB
1696// HDD Capacity = HDD Block size * HDD BLock number (Unit Byte)
1697//
1698// Param#5 (Max HDD Quantity):
1699// Byte 1 - Max HDD Quantity
1700// Max supported port numbers in this PCH
1701//
1702// Param#6 (HDD Type)
1703// Byte 1 – HDD Type
1704// 0h – Reserved
1705// 1h – SAS
1706// 2h – SATA
1707// 3h – PCIE SSD (NVME)
1708//
1709// Param#7 (HDD WWN)
1710// Data 1...8: HDD World Wide Name, LSB
1711//
Willy Tue39f9392022-06-15 13:24:20 -07001712ipmi_ret_t ipmiOemQSetDriveInfo(ipmi_netfn_t, ipmi_cmd_t,
1713 ipmi_request_t request, ipmi_response_t,
1714 ipmi_data_len_t data_len, ipmi_context_t)
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001715{
Vijay Khemka63c99be2020-05-27 19:14:35 -07001716 qDriveInfo_t* req = reinterpret_cast<qDriveInfo_t*>(request);
1717 uint8_t numParam = sizeof(driveInfoKey) / sizeof(uint8_t*);
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001718 uint8_t ctrlType = req->hddCtrlType & 0x0f;
1719 std::stringstream ss;
1720 std::string str;
1721 uint8_t len = *data_len;
1722
1723 *data_len = 0;
1724
1725 /* check for requested data params */
1726 if (len < 6 || req->paramSel < 1 || req->paramSel >= numParam ||
1727 ctrlType > 2)
1728 {
1729 phosphor::logging::log<phosphor::logging::level::ERR>(
1730 "Invalid parameter received");
1731 return IPMI_CC_PARM_OUT_OF_RANGE;
1732 }
1733
1734 len = len - 6; // Get Actual data length
1735
1736 ss << std::hex;
1737 ss << std::setw(2) << std::setfill('0') << (int)req->hddIndex;
1738 oemData[KEY_Q_DRIVE_INFO][KEY_HDD_CTRL_TYPE] = req->hddCtrlType;
1739 oemData[KEY_Q_DRIVE_INFO][ctrlTypeKey[ctrlType]][ss.str()][KEY_HDD_INDEX] =
1740 req->hddIndex;
1741
1742 str = bytesToStr(req->data, len);
1743 oemData[KEY_Q_DRIVE_INFO][ctrlTypeKey[ctrlType]][ss.str()]
1744 [driveInfoKey[req->paramSel]] = str.c_str();
1745 flushOemData();
1746
1747 return IPMI_CC_OK;
1748}
1749
1750//----------------------------------------------------------------------
1751// Get Drive Info (CMD_OEM_Q_GET_DRIVE_INFO)
1752//----------------------------------------------------------------------
1753// BMC needs to check HDD presented or not first. If NOT presented, return
1754// completion code 0xD5.
1755//
1756// Request:
1757// Byte 1:3 – Quanta Manufacturer ID – 001C4Ch, LSB first
1758// Byte 4 –
1759//[7:4] Reserved
1760//[3:0] HDD Controller Type
1761// 0x00 – BIOS
1762// 0x01 – Expander
1763// 0x02 – LSI
1764// Byte 5 – HDD Index, 0 base
1765// Byte 6 – Parameter Selector (See Above Set HDD Information)
1766// Response:
1767// Byte 1 – Completion Code
1768// 0xD5 – Not support in current status (HDD Not Present)
1769// Byte 2..N – Configuration parameter data (see Table_1415h Parameters of HDD
1770// Information)
1771//
Willy Tue39f9392022-06-15 13:24:20 -07001772ipmi_ret_t ipmiOemQGetDriveInfo(ipmi_netfn_t, ipmi_cmd_t,
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001773 ipmi_request_t request,
1774 ipmi_response_t response,
Willy Tue39f9392022-06-15 13:24:20 -07001775 ipmi_data_len_t data_len, ipmi_context_t)
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001776{
Vijay Khemka63c99be2020-05-27 19:14:35 -07001777 qDriveInfo_t* req = reinterpret_cast<qDriveInfo_t*>(request);
1778 uint8_t numParam = sizeof(driveInfoKey) / sizeof(uint8_t*);
1779 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001780 uint8_t ctrlType = req->hddCtrlType & 0x0f;
1781 std::stringstream ss;
1782 std::string str;
1783
1784 *data_len = 0;
1785
1786 /* check for requested data params */
1787 if (req->paramSel < 1 || req->paramSel >= numParam || ctrlType > 2)
1788 {
1789 phosphor::logging::log<phosphor::logging::level::ERR>(
1790 "Invalid parameter received");
1791 return IPMI_CC_PARM_OUT_OF_RANGE;
1792 }
1793
1794 if (oemData[KEY_Q_DRIVE_INFO].find(ctrlTypeKey[ctrlType]) ==
1795 oemData[KEY_Q_DRIVE_INFO].end())
1796 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
1797
1798 ss << std::hex;
1799 ss << std::setw(2) << std::setfill('0') << (int)req->hddIndex;
1800
1801 if (oemData[KEY_Q_DRIVE_INFO][ctrlTypeKey[ctrlType]].find(ss.str()) ==
1802 oemData[KEY_Q_DRIVE_INFO].end())
1803 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
1804
1805 if (oemData[KEY_Q_DRIVE_INFO][ctrlTypeKey[ctrlType]][ss.str()].find(
1806 dimmInfoKey[req->paramSel]) ==
1807 oemData[KEY_Q_DRIVE_INFO][ss.str()].end())
1808 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
1809
1810 str = oemData[KEY_Q_DRIVE_INFO][ctrlTypeKey[ctrlType]][ss.str()]
1811 [dimmInfoKey[req->paramSel]];
1812 *data_len = strToBytes(str, res);
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001813
1814 return IPMI_CC_OK;
1815}
1816
Vijay Khemkadd14c0f2020-03-18 14:48:13 -07001817/* Helper function for sending DCMI commands to ME and getting response back */
1818ipmi::RspType<std::vector<uint8_t>> sendDCMICmd(uint8_t cmd,
Vijay Khemka63c99be2020-05-27 19:14:35 -07001819 std::vector<uint8_t>& cmdData)
Vijay Khemkadd14c0f2020-03-18 14:48:13 -07001820{
1821 std::vector<uint8_t> respData;
1822
1823 /* Add group id as first byte to request for ME command */
1824 cmdData.insert(cmdData.begin(), groupDCMI);
1825
1826 if (sendMeCmd(ipmi::netFnGroup, cmd, cmdData, respData))
1827 return ipmi::responseUnspecifiedError();
1828
1829 /* Remove group id as first byte as it will be added by IPMID */
1830 respData.erase(respData.begin());
1831
1832 return ipmi::responseSuccess(std::move(respData));
1833}
1834
1835/* DCMI Command handellers. */
1836
1837ipmi::RspType<std::vector<uint8_t>>
1838 ipmiOemDCMIGetPowerReading(std::vector<uint8_t> reqData)
1839{
1840 return sendDCMICmd(ipmi::dcmi::cmdGetPowerReading, reqData);
1841}
1842
1843ipmi::RspType<std::vector<uint8_t>>
1844 ipmiOemDCMIGetPowerLimit(std::vector<uint8_t> reqData)
1845{
1846 return sendDCMICmd(ipmi::dcmi::cmdGetPowerLimit, reqData);
1847}
1848
1849ipmi::RspType<std::vector<uint8_t>>
1850 ipmiOemDCMISetPowerLimit(std::vector<uint8_t> reqData)
1851{
1852 return sendDCMICmd(ipmi::dcmi::cmdSetPowerLimit, reqData);
1853}
1854
1855ipmi::RspType<std::vector<uint8_t>>
1856 ipmiOemDCMIApplyPowerLimit(std::vector<uint8_t> reqData)
1857{
1858 return sendDCMICmd(ipmi::dcmi::cmdActDeactivatePwrLimit, reqData);
1859}
1860
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001861static void registerOEMFunctions(void)
1862{
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001863 /* Get OEM data from json file */
1864 std::ifstream file(JSON_OEM_DATA_FILE);
1865 if (file)
Vijay Khemkafeaa9812019-08-27 15:08:08 -07001866 {
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001867 file >> oemData;
Vijay Khemkafeaa9812019-08-27 15:08:08 -07001868 file.close();
1869 }
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001870
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001871 phosphor::logging::log<phosphor::logging::level::INFO>(
1872 "Registering OEM commands");
Vijay Khemka7c0aea42020-03-05 13:31:53 -08001873
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001874 ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, CMD_OEM_USB_DBG_GET_FRAME_INFO,
1875 NULL, ipmiOemDbgGetFrameInfo,
1876 PRIVILEGE_USER); // get debug frame info
1877 ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ,
1878 CMD_OEM_USB_DBG_GET_UPDATED_FRAMES, NULL,
1879 ipmiOemDbgGetUpdFrames,
1880 PRIVILEGE_USER); // get debug updated frames
1881 ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, CMD_OEM_USB_DBG_GET_POST_DESC,
1882 NULL, ipmiOemDbgGetPostDesc,
1883 PRIVILEGE_USER); // get debug post description
1884 ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, CMD_OEM_USB_DBG_GET_GPIO_DESC,
1885 NULL, ipmiOemDbgGetGpioDesc,
1886 PRIVILEGE_USER); // get debug gpio description
1887 ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, CMD_OEM_USB_DBG_GET_FRAME_DATA,
1888 NULL, ipmiOemDbgGetFrameData,
1889 PRIVILEGE_USER); // get debug frame data
1890 ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, CMD_OEM_USB_DBG_CTRL_PANEL,
1891 NULL, ipmiOemDbgGetCtrlPanel,
1892 PRIVILEGE_USER); // get debug control panel
1893 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_DIMM_INFO, NULL,
1894 ipmiOemSetDimmInfo,
1895 PRIVILEGE_USER); // Set Dimm Info
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001896 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_GET_BOARD_ID, NULL,
1897 ipmiOemGetBoardID,
1898 PRIVILEGE_USER); // Get Board ID
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001899 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_MACHINE_CONFIG_INFO, NULL,
1900 ipmiOemSetMachineCfgInfo,
1901 PRIVILEGE_USER); // Set Machine Config Info
1902 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_POST_START, NULL,
1903 ipmiOemSetPostStart,
1904 PRIVILEGE_USER); // Set POST start
1905 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_POST_END, NULL,
1906 ipmiOemSetPostEnd,
1907 PRIVILEGE_USER); // Set POST End
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001908 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_PPIN_INFO, NULL,
1909 ipmiOemSetPPINInfo,
1910 PRIVILEGE_USER); // Set PPIN Info
Manikandan Elumalai5f8e3432020-12-02 03:46:55 +05301911#if BIC_ENABLED
1912
1913 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnOemOne,
1914 ipmi::cmdSetSystemGuid, ipmi::Privilege::User,
1915 ipmiOemSetSystemGuid);
1916#else
1917
Vijay Khemkaf2246ce2020-05-27 14:26:35 -07001918 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_SYSTEM_GUID, NULL,
1919 ipmiOemSetSystemGuid,
1920 PRIVILEGE_USER); // Set System GUID
Manikandan Elumalai5f8e3432020-12-02 03:46:55 +05301921#endif
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001922 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_ADR_TRIGGER, NULL,
1923 ipmiOemSetAdrTrigger,
1924 PRIVILEGE_USER); // Set ADR Trigger
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001925 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_BIOS_FLASH_INFO, NULL,
1926 ipmiOemSetBiosFlashInfo,
1927 PRIVILEGE_USER); // Set Bios Flash Info
1928 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_PPR, NULL, ipmiOemSetPpr,
1929 PRIVILEGE_USER); // Set PPR
1930 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_GET_PPR, NULL, ipmiOemGetPpr,
1931 PRIVILEGE_USER); // Get PPR
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001932 /* FB OEM QC Commands */
1933 ipmiPrintAndRegister(NETFUN_FB_OEM_QC, CMD_OEM_Q_SET_PROC_INFO, NULL,
1934 ipmiOemQSetProcInfo,
1935 PRIVILEGE_USER); // Set Proc Info
1936 ipmiPrintAndRegister(NETFUN_FB_OEM_QC, CMD_OEM_Q_GET_PROC_INFO, NULL,
1937 ipmiOemQGetProcInfo,
1938 PRIVILEGE_USER); // Get Proc Info
1939 ipmiPrintAndRegister(NETFUN_FB_OEM_QC, CMD_OEM_Q_SET_DIMM_INFO, NULL,
1940 ipmiOemQSetDimmInfo,
1941 PRIVILEGE_USER); // Set Dimm Info
1942 ipmiPrintAndRegister(NETFUN_FB_OEM_QC, CMD_OEM_Q_GET_DIMM_INFO, NULL,
1943 ipmiOemQGetDimmInfo,
1944 PRIVILEGE_USER); // Get Dimm Info
1945 ipmiPrintAndRegister(NETFUN_FB_OEM_QC, CMD_OEM_Q_SET_DRIVE_INFO, NULL,
1946 ipmiOemQSetDriveInfo,
1947 PRIVILEGE_USER); // Set Drive Info
1948 ipmiPrintAndRegister(NETFUN_FB_OEM_QC, CMD_OEM_Q_GET_DRIVE_INFO, NULL,
1949 ipmiOemQGetDriveInfo,
1950 PRIVILEGE_USER); // Get Drive Info
Vijay Khemkadd14c0f2020-03-18 14:48:13 -07001951
1952 /* FB OEM DCMI Commands as per DCMI spec 1.5 Section 6 */
1953 ipmi::registerGroupHandler(ipmi::prioOpenBmcBase, groupDCMI,
1954 ipmi::dcmi::cmdGetPowerReading,
1955 ipmi::Privilege::User,
1956 ipmiOemDCMIGetPowerReading); // Get Power Reading
1957
1958 ipmi::registerGroupHandler(ipmi::prioOpenBmcBase, groupDCMI,
1959 ipmi::dcmi::cmdGetPowerLimit,
1960 ipmi::Privilege::User,
1961 ipmiOemDCMIGetPowerLimit); // Get Power Limit
1962
1963 ipmi::registerGroupHandler(ipmi::prioOpenBmcBase, groupDCMI,
1964 ipmi::dcmi::cmdSetPowerLimit,
1965 ipmi::Privilege::Operator,
1966 ipmiOemDCMISetPowerLimit); // Set Power Limit
1967
1968 ipmi::registerGroupHandler(ipmi::prioOpenBmcBase, groupDCMI,
1969 ipmi::dcmi::cmdActDeactivatePwrLimit,
1970 ipmi::Privilege::Operator,
1971 ipmiOemDCMIApplyPowerLimit); // Apply Power Limit
1972
Jayashree-Df0cf6652020-11-30 11:03:30 +05301973 /* FB OEM BOOT ORDER COMMANDS */
1974 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnOemOne,
1975 CMD_OEM_GET_BOOT_ORDER, ipmi::Privilege::User,
1976 ipmiOemGetBootOrder); // Get Boot Order
1977
1978 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnOemOne,
1979 CMD_OEM_SET_BOOT_ORDER, ipmi::Privilege::User,
1980 ipmiOemSetBootOrder); // Set Boot Order
1981
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001982 return;
1983}
1984
1985} // namespace ipmi