blob: ca0dc0e0fbc93ca2ad0918cf99aa34ca4e9ba9f4 [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"
Vijay Khemkae7d23d02019-03-08 13:13:40 -080019
Vijay Khemka63c99be2020-05-27 19:14:35 -070020#include <ipmid/api.hpp>
Vijay Khemka1b6fae32019-03-25 17:43:01 -070021#include <ipmid/utils.hpp>
Vijay Khemka63c99be2020-05-27 19:14:35 -070022#include <commandutils.hpp>
23#include <nlohmann/json.hpp>
24#include <oemcommands.hpp>
Vijay Khemkae7d23d02019-03-08 13:13:40 -080025#include <phosphor-logging/log.hpp>
26#include <sdbusplus/bus.hpp>
Vijay Khemka63c99be2020-05-27 19:14:35 -070027
28#include <array>
29#include <cstring>
30#include <fstream>
31#include <iomanip>
32#include <iostream>
33#include <sstream>
Vijay Khemkae7d23d02019-03-08 13:13:40 -080034#include <string>
35#include <vector>
36
37#define SIZE_IANA_ID 3
38
39namespace ipmi
40{
Vijay Khemkaa7231892019-10-11 11:35:05 -070041
42using namespace phosphor::logging;
43
Vijay Khemkae7d23d02019-03-08 13:13:40 -080044static void registerOEMFunctions() __attribute__((constructor));
45sdbusplus::bus::bus dbus(ipmid_get_sd_bus_connection()); // from ipmid/api.h
46static constexpr size_t maxFRUStringLength = 0x3F;
47
Vijay Khemka63c99be2020-05-27 19:14:35 -070048int plat_udbg_get_post_desc(uint8_t, uint8_t*, uint8_t, uint8_t*, uint8_t*,
49 uint8_t*);
50int plat_udbg_get_gpio_desc(uint8_t, uint8_t*, uint8_t*, uint8_t*, uint8_t*,
51 uint8_t*);
52ipmi_ret_t plat_udbg_get_frame_data(uint8_t, uint8_t, uint8_t*, uint8_t*,
53 uint8_t*);
54ipmi_ret_t plat_udbg_control_panel(uint8_t, uint8_t, uint8_t, uint8_t*,
55 uint8_t*);
56int sendMeCmd(uint8_t, uint8_t, std::vector<uint8_t>&, std::vector<uint8_t>&);
Vijay Khemkadd14c0f2020-03-18 14:48:13 -070057
Vijay Khemkafeaa9812019-08-27 15:08:08 -070058nlohmann::json oemData __attribute__((init_priority(101)));
Vijay Khemka1b6fae32019-03-25 17:43:01 -070059
60enum class LanParam : uint8_t
61{
62 INPROGRESS = 0,
63 AUTHSUPPORT = 1,
64 AUTHENABLES = 2,
65 IP = 3,
66 IPSRC = 4,
67 MAC = 5,
68 SUBNET = 6,
69 GATEWAY = 12,
70 VLAN = 20,
71 CIPHER_SUITE_COUNT = 22,
72 CIPHER_SUITE_ENTRIES = 23,
73 IPV6 = 59,
74};
75
Vijay Khemkaa7231892019-10-11 11:35:05 -070076namespace network
77{
78
79constexpr auto ROOT = "/xyz/openbmc_project/network";
80constexpr auto SERVICE = "xyz.openbmc_project.Network";
81constexpr auto IPV4_TYPE = "ipv4";
82constexpr auto IPV6_TYPE = "ipv6";
83constexpr auto IPV4_PREFIX = "169.254";
84constexpr auto IPV6_PREFIX = "fe80";
85constexpr auto IP_INTERFACE = "xyz.openbmc_project.Network.IP";
86constexpr auto MAC_INTERFACE = "xyz.openbmc_project.Network.MACAddress";
87
Vijay Khemka63c99be2020-05-27 19:14:35 -070088bool isLinkLocalIP(const std::string& address)
Vijay Khemkaa7231892019-10-11 11:35:05 -070089{
90 return address.find(IPV4_PREFIX) == 0 || address.find(IPV6_PREFIX) == 0;
91}
92
Vijay Khemka63c99be2020-05-27 19:14:35 -070093DbusObjectInfo getIPObject(sdbusplus::bus::bus& bus,
94 const std::string& interface,
95 const std::string& serviceRoot,
96 const std::string& match)
Vijay Khemkaa7231892019-10-11 11:35:05 -070097{
98 auto objectTree = getAllDbusObjects(bus, serviceRoot, interface, match);
99
100 if (objectTree.empty())
101 {
102 log<level::ERR>("No Object has implemented the IP interface",
103 entry("INTERFACE=%s", interface.c_str()));
104 }
105
106 DbusObjectInfo objectInfo;
107
Vijay Khemka63c99be2020-05-27 19:14:35 -0700108 for (auto& object : objectTree)
Vijay Khemkaa7231892019-10-11 11:35:05 -0700109 {
110 auto variant =
111 ipmi::getDbusProperty(bus, object.second.begin()->first,
112 object.first, IP_INTERFACE, "Address");
113
114 objectInfo = std::make_pair(object.first, object.second.begin()->first);
115
116 // if LinkLocalIP found look for Non-LinkLocalIP
117 if (isLinkLocalIP(std::get<std::string>(variant)))
118 {
119 continue;
120 }
121 else
122 {
123 break;
124 }
125 }
126 return objectInfo;
127}
128
129} // namespace network
130
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700131//----------------------------------------------------------------------
132// Helper functions for storing oem data
133//----------------------------------------------------------------------
134
135void flushOemData()
136{
137 std::ofstream file(JSON_OEM_DATA_FILE);
138 file << oemData;
Vijay Khemkafeaa9812019-08-27 15:08:08 -0700139 file.close();
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700140 return;
141}
142
Vijay Khemka63c99be2020-05-27 19:14:35 -0700143std::string bytesToStr(uint8_t* byte, int len)
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700144{
145 std::stringstream ss;
146 int i;
147
148 ss << std::hex;
149 for (i = 0; i < len; i++)
150 {
151 ss << std::setw(2) << std::setfill('0') << (int)byte[i];
152 }
153
154 return ss.str();
155}
156
Vijay Khemka63c99be2020-05-27 19:14:35 -0700157int strToBytes(std::string& str, uint8_t* data)
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700158{
159 std::string sstr;
160 int i;
161
162 for (i = 0; i < (str.length()) / 2; i++)
163 {
164 sstr = str.substr(i * 2, 2);
165 data[i] = (uint8_t)std::strtol(sstr.c_str(), NULL, 16);
166 }
167 return i;
168}
169
Vijay Khemka63c99be2020-05-27 19:14:35 -0700170ipmi_ret_t getNetworkData(uint8_t lan_param, char* data)
Vijay Khemka1b6fae32019-03-25 17:43:01 -0700171{
172 ipmi_ret_t rc = IPMI_CC_OK;
173 sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
174
175 const std::string ethdevice = "eth0";
176
177 switch (static_cast<LanParam>(lan_param))
178 {
Vijay Khemka63c99be2020-05-27 19:14:35 -0700179 case LanParam::IP: {
Vijay Khemkaa7231892019-10-11 11:35:05 -0700180 auto ethIP = ethdevice + "/" + ipmi::network::IPV4_TYPE;
Vijay Khemka1b6fae32019-03-25 17:43:01 -0700181 std::string ipaddress;
Vijay Khemkaa7231892019-10-11 11:35:05 -0700182 auto ipObjectInfo = ipmi::network::getIPObject(
Vijay Khemka1b6fae32019-03-25 17:43:01 -0700183 bus, ipmi::network::IP_INTERFACE, ipmi::network::ROOT, ethIP);
184
185 auto properties = ipmi::getAllDbusProperties(
186 bus, ipObjectInfo.second, ipObjectInfo.first,
187 ipmi::network::IP_INTERFACE);
188
Patrick Williamsef0efbc2020-05-13 11:26:51 -0500189 ipaddress = std::get<std::string>(properties["Address"]);
Vijay Khemka1b6fae32019-03-25 17:43:01 -0700190
191 std::strcpy(data, ipaddress.c_str());
192 }
193 break;
194
Vijay Khemka63c99be2020-05-27 19:14:35 -0700195 case LanParam::IPV6: {
Vijay Khemkaa7231892019-10-11 11:35:05 -0700196 auto ethIP = ethdevice + "/" + ipmi::network::IPV6_TYPE;
Vijay Khemka1b6fae32019-03-25 17:43:01 -0700197 std::string ipaddress;
Vijay Khemkaa7231892019-10-11 11:35:05 -0700198 auto ipObjectInfo = ipmi::network::getIPObject(
Vijay Khemka1b6fae32019-03-25 17:43:01 -0700199 bus, ipmi::network::IP_INTERFACE, ipmi::network::ROOT, ethIP);
200
201 auto properties = ipmi::getAllDbusProperties(
202 bus, ipObjectInfo.second, ipObjectInfo.first,
203 ipmi::network::IP_INTERFACE);
204
Patrick Williamsef0efbc2020-05-13 11:26:51 -0500205 ipaddress = std::get<std::string>(properties["Address"]);
Vijay Khemka1b6fae32019-03-25 17:43:01 -0700206
207 std::strcpy(data, ipaddress.c_str());
208 }
209 break;
210
Vijay Khemka63c99be2020-05-27 19:14:35 -0700211 case LanParam::MAC: {
Vijay Khemka1b6fae32019-03-25 17:43:01 -0700212 std::string macAddress;
213 auto macObjectInfo =
214 ipmi::getDbusObject(bus, ipmi::network::MAC_INTERFACE,
215 ipmi::network::ROOT, ethdevice);
216
217 auto variant = ipmi::getDbusProperty(
218 bus, macObjectInfo.second, macObjectInfo.first,
219 ipmi::network::MAC_INTERFACE, "MACAddress");
220
Patrick Williamsef0efbc2020-05-13 11:26:51 -0500221 macAddress = std::get<std::string>(variant);
Vijay Khemka1b6fae32019-03-25 17:43:01 -0700222
223 sscanf(macAddress.c_str(), ipmi::network::MAC_ADDRESS_FORMAT,
224 (data), (data + 1), (data + 2), (data + 3), (data + 4),
225 (data + 5));
226 std::strcpy(data, macAddress.c_str());
227 }
228 break;
229
230 default:
231 rc = IPMI_CC_PARM_OUT_OF_RANGE;
232 }
233 return rc;
234}
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800235
236// return code: 0 successful
Vijay Khemka63c99be2020-05-27 19:14:35 -0700237int8_t getFruData(std::string& data, std::string& name)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800238{
239 std::string objpath = "/xyz/openbmc_project/FruDevice";
240 std::string intf = "xyz.openbmc_project.FruDeviceManager";
241 std::string service = getService(dbus, intf, objpath);
242 ObjectValueTree valueTree = getManagedObjects(dbus, service, "/");
243 if (valueTree.empty())
244 {
245 phosphor::logging::log<phosphor::logging::level::ERR>(
246 "No object implements interface",
247 phosphor::logging::entry("INTF=%s", intf.c_str()));
248 return -1;
249 }
250
Vijay Khemka63c99be2020-05-27 19:14:35 -0700251 for (const auto& item : valueTree)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800252 {
253 auto interface = item.second.find("xyz.openbmc_project.FruDevice");
254 if (interface == item.second.end())
255 {
256 continue;
257 }
258
259 auto property = interface->second.find(name.c_str());
260 if (property == interface->second.end())
261 {
262 continue;
263 }
264
265 try
266 {
267 Value variant = property->second;
Vijay Khemka63c99be2020-05-27 19:14:35 -0700268 std::string& result = std::get<std::string>(variant);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800269 if (result.size() > maxFRUStringLength)
270 {
271 phosphor::logging::log<phosphor::logging::level::ERR>(
272 "FRU serial number exceed maximum length");
273 return -1;
274 }
275 data = result;
276 return 0;
277 }
Vijay Khemka63c99be2020-05-27 19:14:35 -0700278 catch (std::bad_variant_access& e)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800279 {
280 phosphor::logging::log<phosphor::logging::level::ERR>(e.what());
281 return -1;
282 }
283 }
284 return -1;
285}
286
287typedef struct
288{
289 uint8_t cur_power_state;
290 uint8_t last_power_event;
291 uint8_t misc_power_state;
292 uint8_t front_panel_button_cap_status;
293} ipmi_get_chassis_status_t;
294
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800295//----------------------------------------------------------------------
296// Get Debug Frame Info
297//----------------------------------------------------------------------
298ipmi_ret_t ipmiOemDbgGetFrameInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
299 ipmi_request_t request,
300 ipmi_response_t response,
301 ipmi_data_len_t data_len,
302 ipmi_context_t context)
303{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700304 uint8_t* req = reinterpret_cast<uint8_t*>(request);
305 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800306 uint8_t num_frames = 3;
307
308 std::memcpy(res, req, SIZE_IANA_ID); // IANA ID
309 res[SIZE_IANA_ID] = num_frames;
310 *data_len = SIZE_IANA_ID + 1;
311
312 return IPMI_CC_OK;
313}
314
315//----------------------------------------------------------------------
316// Get Debug Updated Frames
317//----------------------------------------------------------------------
318ipmi_ret_t ipmiOemDbgGetUpdFrames(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
319 ipmi_request_t request,
320 ipmi_response_t response,
321 ipmi_data_len_t data_len,
322 ipmi_context_t context)
323{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700324 uint8_t* req = reinterpret_cast<uint8_t*>(request);
325 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800326 uint8_t num_updates = 3;
327 *data_len = 4;
328
329 std::memcpy(res, req, SIZE_IANA_ID); // IANA ID
330 res[SIZE_IANA_ID] = num_updates;
331 *data_len = SIZE_IANA_ID + num_updates + 1;
332 res[SIZE_IANA_ID + 1] = 1; // info page update
333 res[SIZE_IANA_ID + 2] = 2; // cri sel update
334 res[SIZE_IANA_ID + 3] = 3; // cri sensor update
335
336 return IPMI_CC_OK;
337}
338
339//----------------------------------------------------------------------
340// Get Debug POST Description
341//----------------------------------------------------------------------
342ipmi_ret_t ipmiOemDbgGetPostDesc(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
343 ipmi_request_t request,
344 ipmi_response_t response,
345 ipmi_data_len_t data_len,
346 ipmi_context_t context)
347{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700348 uint8_t* req = reinterpret_cast<uint8_t*>(request);
349 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800350 uint8_t index = 0;
351 uint8_t next = 0;
352 uint8_t end = 0;
353 uint8_t phase = 0;
Vijay Khemkacc0d6d92019-08-27 14:51:17 -0700354 uint8_t descLen = 0;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800355 int ret;
356
357 index = req[3];
358 phase = req[4];
359
Vijay Khemkacc0d6d92019-08-27 14:51:17 -0700360 ret = plat_udbg_get_post_desc(index, &next, phase, &end, &descLen, &res[8]);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800361 if (ret)
362 {
363 memcpy(res, req, SIZE_IANA_ID); // IANA ID
364 *data_len = SIZE_IANA_ID;
365 return IPMI_CC_UNSPECIFIED_ERROR;
366 }
367
368 memcpy(res, req, SIZE_IANA_ID); // IANA ID
369 res[3] = index;
370 res[4] = next;
371 res[5] = phase;
372 res[6] = end;
Vijay Khemkacc0d6d92019-08-27 14:51:17 -0700373 res[7] = descLen;
374 *data_len = SIZE_IANA_ID + 5 + descLen;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800375
376 return IPMI_CC_OK;
377}
378
379//----------------------------------------------------------------------
380// Get Debug GPIO Description
381//----------------------------------------------------------------------
382ipmi_ret_t ipmiOemDbgGetGpioDesc(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
383 ipmi_request_t request,
384 ipmi_response_t response,
385 ipmi_data_len_t data_len,
386 ipmi_context_t context)
387{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700388 uint8_t* req = reinterpret_cast<uint8_t*>(request);
389 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800390
Vijay Khemka38183d62019-08-28 16:19:33 -0700391 uint8_t index = 0;
392 uint8_t next = 0;
393 uint8_t level = 0;
394 uint8_t pinDef = 0;
395 uint8_t descLen = 0;
396 int ret;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800397
Vijay Khemka38183d62019-08-28 16:19:33 -0700398 index = req[3];
399
400 ret = plat_udbg_get_gpio_desc(index, &next, &level, &pinDef, &descLen,
401 &res[8]);
402 if (ret)
403 {
404 memcpy(res, req, SIZE_IANA_ID); // IANA ID
405 *data_len = SIZE_IANA_ID;
406 return IPMI_CC_UNSPECIFIED_ERROR;
407 }
408
409 memcpy(res, req, SIZE_IANA_ID); // IANA ID
410 res[3] = index;
411 res[4] = next;
412 res[5] = level;
413 res[6] = pinDef;
414 res[7] = descLen;
415 *data_len = SIZE_IANA_ID + 5 + descLen;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800416
417 return IPMI_CC_OK;
418}
419
420//----------------------------------------------------------------------
421// Get Debug Frame Data
422//----------------------------------------------------------------------
423ipmi_ret_t ipmiOemDbgGetFrameData(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
424 ipmi_request_t request,
425 ipmi_response_t response,
426 ipmi_data_len_t data_len,
427 ipmi_context_t context)
428{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700429 uint8_t* req = reinterpret_cast<uint8_t*>(request);
430 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800431 uint8_t frame;
432 uint8_t page;
433 uint8_t next;
434 uint8_t count;
435 int ret;
436
437 frame = req[3];
438 page = req[4];
439 int fr = frame;
440 int pg = page;
441
442 ret = plat_udbg_get_frame_data(frame, page, &next, &count, &res[7]);
443 if (ret)
444 {
445 memcpy(res, req, SIZE_IANA_ID); // IANA ID
446 *data_len = SIZE_IANA_ID;
447 return IPMI_CC_UNSPECIFIED_ERROR;
448 }
449
450 memcpy(res, req, SIZE_IANA_ID); // IANA ID
451 res[3] = frame;
452 res[4] = page;
453 res[5] = next;
454 res[6] = count;
455 *data_len = SIZE_IANA_ID + 4 + count;
456
457 return IPMI_CC_OK;
458}
459
460//----------------------------------------------------------------------
461// Get Debug Control Panel
462//----------------------------------------------------------------------
463ipmi_ret_t ipmiOemDbgGetCtrlPanel(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
464 ipmi_request_t request,
465 ipmi_response_t response,
466 ipmi_data_len_t data_len,
467 ipmi_context_t context)
468{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700469 uint8_t* req = reinterpret_cast<uint8_t*>(request);
470 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800471
472 uint8_t panel;
473 uint8_t operation;
474 uint8_t item;
475 uint8_t count;
476 ipmi_ret_t ret;
477
478 panel = req[3];
479 operation = req[4];
480 item = req[5];
481
482 ret = plat_udbg_control_panel(panel, operation, item, &count, &res[3]);
483
484 std::memcpy(res, req, SIZE_IANA_ID); // IANA ID
485 *data_len = SIZE_IANA_ID + count;
486
487 return ret;
488}
489
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800490//----------------------------------------------------------------------
491// Set Dimm Info (CMD_OEM_SET_DIMM_INFO)
492//----------------------------------------------------------------------
493ipmi_ret_t ipmiOemSetDimmInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
494 ipmi_request_t request, ipmi_response_t response,
495 ipmi_data_len_t data_len, ipmi_context_t context)
496{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700497 uint8_t* req = reinterpret_cast<uint8_t*>(request);
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700498
499 uint8_t index = req[0];
500 uint8_t type = req[1];
501 uint16_t speed;
502 uint32_t size;
503
504 memcpy(&speed, &req[2], 2);
505 memcpy(&size, &req[4], 4);
506
507 std::stringstream ss;
508 ss << std::hex;
509 ss << std::setw(2) << std::setfill('0') << (int)index;
510
511 oemData[KEY_SYS_CONFIG][ss.str()][KEY_DIMM_INDEX] = index;
512 oemData[KEY_SYS_CONFIG][ss.str()][KEY_DIMM_TYPE] = type;
513 oemData[KEY_SYS_CONFIG][ss.str()][KEY_DIMM_SPEED] = speed;
514 oemData[KEY_SYS_CONFIG][ss.str()][KEY_DIMM_SIZE] = size;
515
516 flushOemData();
517
518 *data_len = 0;
519
520 return IPMI_CC_OK;
521}
522
523//----------------------------------------------------------------------
524// Get Board ID (CMD_OEM_GET_BOARD_ID)
525//----------------------------------------------------------------------
526ipmi_ret_t ipmiOemGetBoardID(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
527 ipmi_request_t request, ipmi_response_t response,
528 ipmi_data_len_t data_len, ipmi_context_t context)
529{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700530 uint8_t* req = reinterpret_cast<uint8_t*>(request);
531 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800532
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700533 /* TODO: Needs to implement this after GPIO implementation */
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800534 *data_len = 0;
535
536 return IPMI_CC_OK;
537}
538
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800539/* Helper functions to set boot order */
Vijay Khemka63c99be2020-05-27 19:14:35 -0700540void setBootOrder(uint8_t* data)
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800541{
542 nlohmann::json bootMode;
543 uint8_t mode = data[0];
544 int i;
545
546 bootMode["UEFI"] = (mode & BOOT_MODE_UEFI ? true : false);
547 bootMode["CMOS_CLR"] = (mode & BOOT_MODE_CMOS_CLR ? true : false);
548 bootMode["FORCE_BOOT"] = (mode & BOOT_MODE_FORCE_BOOT ? true : false);
549 bootMode["BOOT_FLAG"] = (mode & BOOT_MODE_BOOT_FLAG ? true : false);
550 oemData[KEY_BOOT_ORDER][KEY_BOOT_MODE] = bootMode;
551
552 /* Initialize boot sequence array */
553 oemData[KEY_BOOT_ORDER][KEY_BOOT_SEQ] = {};
554 for (i = 1; i < SIZE_BOOT_ORDER; i++)
555 {
556 if (data[i] >= BOOT_SEQ_ARRAY_SIZE)
557 oemData[KEY_BOOT_ORDER][KEY_BOOT_SEQ][i - 1] = "NA";
558 else
559 oemData[KEY_BOOT_ORDER][KEY_BOOT_SEQ][i - 1] = bootSeq[data[i]];
560 }
561
562 flushOemData();
563}
564
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800565//----------------------------------------------------------------------
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700566// Set Boot Order (CMD_OEM_SET_BOOT_ORDER)
567//----------------------------------------------------------------------
568ipmi_ret_t ipmiOemSetBootOrder(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
569 ipmi_request_t request, ipmi_response_t response,
570 ipmi_data_len_t data_len, ipmi_context_t context)
571{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700572 uint8_t* req = reinterpret_cast<uint8_t*>(request);
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700573 uint8_t len = *data_len;
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700574
575 *data_len = 0;
576
577 if (len != SIZE_BOOT_ORDER)
578 {
579 phosphor::logging::log<phosphor::logging::level::ERR>(
580 "Invalid Boot order length received");
581 return IPMI_CC_REQ_DATA_LEN_INVALID;
582 }
583
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800584 setBootOrder(req);
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700585
586 return IPMI_CC_OK;
587}
588
589//----------------------------------------------------------------------
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800590// Get Boot Order (CMD_OEM_GET_BOOT_ORDER)
591//----------------------------------------------------------------------
592ipmi_ret_t ipmiOemGetBootOrder(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
593 ipmi_request_t request, ipmi_response_t response,
594 ipmi_data_len_t data_len, ipmi_context_t context)
595{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700596 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700597 uint8_t mode = 0;
598 int i;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800599
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700600 *data_len = SIZE_BOOT_ORDER;
601
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800602 if (oemData.find(KEY_BOOT_ORDER) == oemData.end())
603 {
604 /* Return default boot order 0100090203ff */
605 uint8_t defaultBoot[SIZE_BOOT_ORDER] = {
606 BOOT_MODE_UEFI, bootMap["USB_DEV"], bootMap["NET_IPV6"],
607 bootMap["SATA_HDD"], bootMap["SATA_CD"], 0xff};
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700608
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800609 memcpy(res, defaultBoot, SIZE_BOOT_ORDER);
610 phosphor::logging::log<phosphor::logging::level::INFO>(
611 "Set default boot order");
612 setBootOrder(defaultBoot);
613 }
614 else
615 {
616 nlohmann::json bootMode = oemData[KEY_BOOT_ORDER][KEY_BOOT_MODE];
617 if (bootMode["UEFI"])
618 mode |= BOOT_MODE_UEFI;
619 if (bootMode["CMOS_CLR"])
620 mode |= BOOT_MODE_CMOS_CLR;
621 if (bootMode["BOOT_FLAG"])
622 mode |= BOOT_MODE_BOOT_FLAG;
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700623
Vijay Khemka877d5dd2019-12-16 14:46:21 -0800624 res[0] = mode;
625
626 for (i = 1; i < SIZE_BOOT_ORDER; i++)
627 {
628 std::string seqStr = oemData[KEY_BOOT_ORDER][KEY_BOOT_SEQ][i - 1];
629 if (bootMap.find(seqStr) != bootMap.end())
630 res[i] = bootMap[seqStr];
631 else
632 res[i] = 0xff;
633 }
634 }
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800635
636 return IPMI_CC_OK;
637}
638
639//----------------------------------------------------------------------
640// Set Machine Config Info (CMD_OEM_SET_MACHINE_CONFIG_INFO)
641//----------------------------------------------------------------------
642ipmi_ret_t ipmiOemSetMachineCfgInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
643 ipmi_request_t request,
644 ipmi_response_t response,
645 ipmi_data_len_t data_len,
646 ipmi_context_t context)
647{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700648 machineConfigInfo_t* req = reinterpret_cast<machineConfigInfo_t*>(request);
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700649 uint8_t len = *data_len;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800650
651 *data_len = 0;
652
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700653 if (len < sizeof(machineConfigInfo_t))
654 {
655 phosphor::logging::log<phosphor::logging::level::ERR>(
656 "Invalid machine configuration length received");
657 return IPMI_CC_REQ_DATA_LEN_INVALID;
658 }
659
Vijay Khemka63c99be2020-05-27 19:14:35 -0700660 if (req->chassis_type >= sizeof(chassisType) / sizeof(uint8_t*))
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700661 oemData[KEY_MC_CONFIG][KEY_MC_CHAS_TYPE] = "UNKNOWN";
662 else
663 oemData[KEY_MC_CONFIG][KEY_MC_CHAS_TYPE] =
664 chassisType[req->chassis_type];
665
Vijay Khemka63c99be2020-05-27 19:14:35 -0700666 if (req->mb_type >= sizeof(mbType) / sizeof(uint8_t*))
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700667 oemData[KEY_MC_CONFIG][KEY_MC_MB_TYPE] = "UNKNOWN";
668 else
669 oemData[KEY_MC_CONFIG][KEY_MC_MB_TYPE] = mbType[req->mb_type];
670
671 oemData[KEY_MC_CONFIG][KEY_MC_PROC_CNT] = req->proc_cnt;
672 oemData[KEY_MC_CONFIG][KEY_MC_MEM_CNT] = req->mem_cnt;
673 oemData[KEY_MC_CONFIG][KEY_MC_HDD35_CNT] = req->hdd35_cnt;
674 oemData[KEY_MC_CONFIG][KEY_MC_HDD25_CNT] = req->hdd25_cnt;
675
Vijay Khemka63c99be2020-05-27 19:14:35 -0700676 if (req->riser_type >= sizeof(riserType) / sizeof(uint8_t*))
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700677 oemData[KEY_MC_CONFIG][KEY_MC_RSR_TYPE] = "UNKNOWN";
678 else
679 oemData[KEY_MC_CONFIG][KEY_MC_RSR_TYPE] = riserType[req->riser_type];
680
681 oemData[KEY_MC_CONFIG][KEY_MC_PCIE_LOC] = {};
682 int i = 0;
683 if (req->pcie_card_loc & BIT_0)
684 oemData[KEY_MC_CONFIG][KEY_MC_PCIE_LOC][i++] = "SLOT1";
685 if (req->pcie_card_loc & BIT_1)
686 oemData[KEY_MC_CONFIG][KEY_MC_PCIE_LOC][i++] = "SLOT2";
687 if (req->pcie_card_loc & BIT_2)
688 oemData[KEY_MC_CONFIG][KEY_MC_PCIE_LOC][i++] = "SLOT3";
689 if (req->pcie_card_loc & BIT_3)
690 oemData[KEY_MC_CONFIG][KEY_MC_PCIE_LOC][i++] = "SLOT4";
691
Vijay Khemka63c99be2020-05-27 19:14:35 -0700692 if (req->slot1_pcie_type >= sizeof(pcieType) / sizeof(uint8_t*))
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700693 oemData[KEY_MC_CONFIG][KEY_MC_SLOT1_TYPE] = "UNKNOWN";
694 else
695 oemData[KEY_MC_CONFIG][KEY_MC_SLOT1_TYPE] =
696 pcieType[req->slot1_pcie_type];
697
Vijay Khemka63c99be2020-05-27 19:14:35 -0700698 if (req->slot2_pcie_type >= sizeof(pcieType) / sizeof(uint8_t*))
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700699 oemData[KEY_MC_CONFIG][KEY_MC_SLOT2_TYPE] = "UNKNOWN";
700 else
701 oemData[KEY_MC_CONFIG][KEY_MC_SLOT2_TYPE] =
702 pcieType[req->slot2_pcie_type];
703
Vijay Khemka63c99be2020-05-27 19:14:35 -0700704 if (req->slot3_pcie_type >= sizeof(pcieType) / sizeof(uint8_t*))
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700705 oemData[KEY_MC_CONFIG][KEY_MC_SLOT3_TYPE] = "UNKNOWN";
706 else
707 oemData[KEY_MC_CONFIG][KEY_MC_SLOT3_TYPE] =
708 pcieType[req->slot3_pcie_type];
709
Vijay Khemka63c99be2020-05-27 19:14:35 -0700710 if (req->slot4_pcie_type >= sizeof(pcieType) / sizeof(uint8_t*))
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700711 oemData[KEY_MC_CONFIG][KEY_MC_SLOT4_TYPE] = "UNKNOWN";
712 else
713 oemData[KEY_MC_CONFIG][KEY_MC_SLOT4_TYPE] =
714 pcieType[req->slot4_pcie_type];
715
716 oemData[KEY_MC_CONFIG][KEY_MC_AEP_CNT] = req->aep_mem_cnt;
717
718 flushOemData();
719
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800720 return IPMI_CC_OK;
721}
722
723//----------------------------------------------------------------------
724// Set POST start (CMD_OEM_SET_POST_START)
725//----------------------------------------------------------------------
726ipmi_ret_t ipmiOemSetPostStart(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
727 ipmi_request_t request, ipmi_response_t response,
728 ipmi_data_len_t data_len, ipmi_context_t context)
729{
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800730 phosphor::logging::log<phosphor::logging::level::INFO>("POST Start Event");
731
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700732 /* Do nothing, return success */
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800733 *data_len = 0;
734 return IPMI_CC_OK;
735}
736
737//----------------------------------------------------------------------
738// Set POST End (CMD_OEM_SET_POST_END)
739//----------------------------------------------------------------------
740ipmi_ret_t ipmiOemSetPostEnd(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
741 ipmi_request_t request, ipmi_response_t response,
742 ipmi_data_len_t data_len, ipmi_context_t context)
743{
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700744 struct timespec ts;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800745
746 phosphor::logging::log<phosphor::logging::level::INFO>("POST End Event");
747
748 *data_len = 0;
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700749
750 // Timestamp post end time.
751 clock_gettime(CLOCK_REALTIME, &ts);
752 oemData[KEY_TS_SLED] = ts.tv_sec;
753 flushOemData();
754
755 // Sync time with system
756 // TODO: Add code for syncing time
757
758 return IPMI_CC_OK;
759}
760
761//----------------------------------------------------------------------
762// Set PPIN Info (CMD_OEM_SET_PPIN_INFO)
763//----------------------------------------------------------------------
764// Inform BMC about PPIN data of 8 bytes for each CPU
765//
766// Request:
767// Byte 1:8 – CPU0 PPIN data
768// Optional:
769// Byte 9:16 – CPU1 PPIN data
770//
771// Response:
772// Byte 1 – Completion Code
773ipmi_ret_t ipmiOemSetPPINInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
774 ipmi_request_t request, ipmi_response_t response,
775 ipmi_data_len_t data_len, ipmi_context_t context)
776{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700777 uint8_t* req = reinterpret_cast<uint8_t*>(request);
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700778 std::string ppinStr;
779 int len;
780
781 if (*data_len > SIZE_CPU_PPIN * 2)
782 len = SIZE_CPU_PPIN * 2;
783 else
784 len = *data_len;
785 *data_len = 0;
786
787 ppinStr = bytesToStr(req, len);
788 oemData[KEY_PPIN_INFO] = ppinStr.c_str();
789 flushOemData();
790
791 return IPMI_CC_OK;
792}
793
794//----------------------------------------------------------------------
795// Set ADR Trigger (CMD_OEM_SET_ADR_TRIGGER)
796//----------------------------------------------------------------------
797ipmi_ret_t ipmiOemSetAdrTrigger(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
798 ipmi_request_t request,
799 ipmi_response_t response,
800 ipmi_data_len_t data_len,
801 ipmi_context_t context)
802{
803 /* Do nothing, return success */
804 *data_len = 0;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800805 return IPMI_CC_OK;
806}
807
808//----------------------------------------------------------------------
809// Set Bios Flash Info (CMD_OEM_SET_BIOS_FLASH_INFO)
810//----------------------------------------------------------------------
811ipmi_ret_t ipmiOemSetBiosFlashInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
812 ipmi_request_t request,
813 ipmi_response_t response,
814 ipmi_data_len_t data_len,
815 ipmi_context_t context)
816{
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700817 /* Do nothing, return success */
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800818 *data_len = 0;
819 return IPMI_CC_OK;
820}
821
822//----------------------------------------------------------------------
823// Set PPR (CMD_OEM_SET_PPR)
824//----------------------------------------------------------------------
825ipmi_ret_t ipmiOemSetPpr(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
826 ipmi_request_t request, ipmi_response_t response,
827 ipmi_data_len_t data_len, ipmi_context_t context)
828{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700829 uint8_t* req = reinterpret_cast<uint8_t*>(request);
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700830 uint8_t pprCnt, pprAct, pprIndex;
831 uint8_t selParam = req[0];
832 uint8_t len = *data_len;
833 std::stringstream ss;
834 std::string str;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800835
836 *data_len = 0;
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700837
838 switch (selParam)
839 {
840 case PPR_ACTION:
841 if (oemData[KEY_PPR].find(KEY_PPR_ROW_COUNT) ==
842 oemData[KEY_PPR].end())
843 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
844
845 pprCnt = oemData[KEY_PPR][KEY_PPR_ROW_COUNT];
846 if (pprCnt == 0)
847 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
848
849 pprAct = req[1];
850 /* Check if ppr is enabled or disabled */
851 if (!(pprAct & 0x80))
852 pprAct = 0;
853
854 oemData[KEY_PPR][KEY_PPR_ACTION] = pprAct;
855 break;
856 case PPR_ROW_COUNT:
857 if (req[1] > 100)
858 return IPMI_CC_PARM_OUT_OF_RANGE;
859
860 oemData[KEY_PPR][KEY_PPR_ROW_COUNT] = req[1];
861 break;
862 case PPR_ROW_ADDR:
863 pprIndex = req[1];
864 if (pprIndex > 100)
865 return IPMI_CC_PARM_OUT_OF_RANGE;
866
867 if (len < PPR_ROW_ADDR_LEN + 1)
868 {
869 phosphor::logging::log<phosphor::logging::level::ERR>(
870 "Invalid PPR Row Address length received");
871 return IPMI_CC_REQ_DATA_LEN_INVALID;
872 }
873
874 ss << std::hex;
875 ss << std::setw(2) << std::setfill('0') << (int)pprIndex;
876
877 oemData[KEY_PPR][ss.str()][KEY_PPR_INDEX] = pprIndex;
878
879 str = bytesToStr(&req[1], PPR_ROW_ADDR_LEN);
880 oemData[KEY_PPR][ss.str()][KEY_PPR_ROW_ADDR] = str.c_str();
881 break;
882 case PPR_HISTORY_DATA:
883 pprIndex = req[1];
884 if (pprIndex > 100)
885 return IPMI_CC_PARM_OUT_OF_RANGE;
886
887 if (len < PPR_HST_DATA_LEN + 1)
888 {
889 phosphor::logging::log<phosphor::logging::level::ERR>(
890 "Invalid PPR history data length received");
891 return IPMI_CC_REQ_DATA_LEN_INVALID;
892 }
893
894 ss << std::hex;
895 ss << std::setw(2) << std::setfill('0') << (int)pprIndex;
896
897 oemData[KEY_PPR][ss.str()][KEY_PPR_INDEX] = pprIndex;
898
899 str = bytesToStr(&req[1], PPR_HST_DATA_LEN);
900 oemData[KEY_PPR][ss.str()][KEY_PPR_HST_DATA] = str.c_str();
901 break;
902 default:
903 return IPMI_CC_PARM_OUT_OF_RANGE;
904 break;
905 }
906
907 flushOemData();
908
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800909 return IPMI_CC_OK;
910}
911
912//----------------------------------------------------------------------
913// Get PPR (CMD_OEM_GET_PPR)
914//----------------------------------------------------------------------
915ipmi_ret_t ipmiOemGetPpr(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
916 ipmi_request_t request, ipmi_response_t response,
917 ipmi_data_len_t data_len, ipmi_context_t context)
918{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700919 uint8_t* req = reinterpret_cast<uint8_t*>(request);
920 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700921 uint8_t pprCnt, pprIndex;
922 uint8_t selParam = req[0];
923 std::stringstream ss;
924 std::string str;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800925
Vijay Khemka1d4a0692019-04-09 15:20:28 -0700926 /* Any failure will return zero length data */
927 *data_len = 0;
928
929 switch (selParam)
930 {
931 case PPR_ACTION:
932 res[0] = 0;
933 *data_len = 1;
934
935 if (oemData[KEY_PPR].find(KEY_PPR_ROW_COUNT) !=
936 oemData[KEY_PPR].end())
937 {
938 pprCnt = oemData[KEY_PPR][KEY_PPR_ROW_COUNT];
939 if (pprCnt != 0)
940 {
941 if (oemData[KEY_PPR].find(KEY_PPR_ACTION) !=
942 oemData[KEY_PPR].end())
943 {
944 res[0] = oemData[KEY_PPR][KEY_PPR_ACTION];
945 }
946 }
947 }
948 break;
949 case PPR_ROW_COUNT:
950 res[0] = 0;
951 *data_len = 1;
952 if (oemData[KEY_PPR].find(KEY_PPR_ROW_COUNT) !=
953 oemData[KEY_PPR].end())
954 res[0] = oemData[KEY_PPR][KEY_PPR_ROW_COUNT];
955 break;
956 case PPR_ROW_ADDR:
957 pprIndex = req[1];
958 if (pprIndex > 100)
959 return IPMI_CC_PARM_OUT_OF_RANGE;
960
961 ss << std::hex;
962 ss << std::setw(2) << std::setfill('0') << (int)pprIndex;
963
964 if (oemData[KEY_PPR].find(ss.str()) == oemData[KEY_PPR].end())
965 return IPMI_CC_PARM_OUT_OF_RANGE;
966
967 if (oemData[KEY_PPR][ss.str()].find(KEY_PPR_ROW_ADDR) ==
968 oemData[KEY_PPR][ss.str()].end())
969 return IPMI_CC_PARM_OUT_OF_RANGE;
970
971 str = oemData[KEY_PPR][ss.str()][KEY_PPR_ROW_ADDR];
972 *data_len = strToBytes(str, res);
973 break;
974 case PPR_HISTORY_DATA:
975 pprIndex = req[1];
976 if (pprIndex > 100)
977 return IPMI_CC_PARM_OUT_OF_RANGE;
978
979 ss << std::hex;
980 ss << std::setw(2) << std::setfill('0') << (int)pprIndex;
981
982 if (oemData[KEY_PPR].find(ss.str()) == oemData[KEY_PPR].end())
983 return IPMI_CC_PARM_OUT_OF_RANGE;
984
985 if (oemData[KEY_PPR][ss.str()].find(KEY_PPR_HST_DATA) ==
986 oemData[KEY_PPR][ss.str()].end())
987 return IPMI_CC_PARM_OUT_OF_RANGE;
988
989 str = oemData[KEY_PPR][ss.str()][KEY_PPR_HST_DATA];
990 *data_len = strToBytes(str, res);
991 break;
992 default:
993 return IPMI_CC_PARM_OUT_OF_RANGE;
994 break;
995 }
996
997 return IPMI_CC_OK;
998}
999
1000/* FB OEM QC Commands */
1001
1002//----------------------------------------------------------------------
1003// Set Proc Info (CMD_OEM_Q_SET_PROC_INFO)
1004//----------------------------------------------------------------------
1005//"Request:
1006// Byte 1:3 – Manufacturer ID – XXYYZZ h, LSB first
1007// Byte 4 – Processor Index, 0 base
1008// Byte 5 – Parameter Selector
1009// Byte 6..N – Configuration parameter data (see below for Parameters
1010// of Processor Information)
1011// Response:
1012// Byte 1 – Completion code
1013//
1014// Parameter#1: (Processor Product Name)
1015//
1016// Byte 1..48 –Product name(ASCII code)
1017// Ex. Intel(R) Xeon(R) CPU E5-2685 v3 @ 2.60GHz
1018//
1019// Param#2: Processor Basic Information
1020// Byte 1 – Core Number
1021// Byte 2 – Thread Number (LSB)
1022// Byte 3 – Thread Number (MSB)
1023// Byte 4 – Processor frequency in MHz (LSB)
1024// Byte 5 – Processor frequency in MHz (MSB)
1025// Byte 6..7 – Revision
1026//
1027ipmi_ret_t ipmiOemQSetProcInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
1028 ipmi_request_t request, ipmi_response_t response,
1029 ipmi_data_len_t data_len, ipmi_context_t context)
1030{
Vijay Khemka63c99be2020-05-27 19:14:35 -07001031 qProcInfo_t* req = reinterpret_cast<qProcInfo_t*>(request);
1032 uint8_t numParam = sizeof(cpuInfoKey) / sizeof(uint8_t*);
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001033 std::stringstream ss;
1034 std::string str;
1035 uint8_t len = *data_len;
1036
1037 *data_len = 0;
1038
1039 /* check for requested data params */
1040 if (len < 5 || req->paramSel < 1 || req->paramSel >= numParam)
1041 {
1042 phosphor::logging::log<phosphor::logging::level::ERR>(
1043 "Invalid parameter received");
1044 return IPMI_CC_PARM_OUT_OF_RANGE;
1045 }
1046
1047 len = len - 5; // Get Actual data length
1048
1049 ss << std::hex;
1050 ss << std::setw(2) << std::setfill('0') << (int)req->procIndex;
1051 oemData[KEY_Q_PROC_INFO][ss.str()][KEY_PROC_INDEX] = req->procIndex;
1052
1053 str = bytesToStr(req->data, len);
1054 oemData[KEY_Q_PROC_INFO][ss.str()][cpuInfoKey[req->paramSel]] = str.c_str();
1055 flushOemData();
1056
1057 return IPMI_CC_OK;
1058}
1059
1060//----------------------------------------------------------------------
1061// Get Proc Info (CMD_OEM_Q_GET_PROC_INFO)
1062//----------------------------------------------------------------------
1063// Request:
1064// Byte 1:3 – Manufacturer ID – XXYYZZ h, LSB first
1065// Byte 4 – Processor Index, 0 base
1066// Byte 5 – Parameter Selector
1067// Response:
1068// Byte 1 – Completion code
1069// Byte 2..N – Configuration Parameter Data (see below for Parameters
1070// of Processor Information)
1071//
1072// Parameter#1: (Processor Product Name)
1073//
1074// Byte 1..48 –Product name(ASCII code)
1075// Ex. Intel(R) Xeon(R) CPU E5-2685 v3 @ 2.60GHz
1076//
1077// Param#2: Processor Basic Information
1078// Byte 1 – Core Number
1079// Byte 2 – Thread Number (LSB)
1080// Byte 3 – Thread Number (MSB)
1081// Byte 4 – Processor frequency in MHz (LSB)
1082// Byte 5 – Processor frequency in MHz (MSB)
1083// Byte 6..7 – Revision
1084//
1085ipmi_ret_t ipmiOemQGetProcInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
1086 ipmi_request_t request, ipmi_response_t response,
1087 ipmi_data_len_t data_len, ipmi_context_t context)
1088{
Vijay Khemka63c99be2020-05-27 19:14:35 -07001089 qProcInfo_t* req = reinterpret_cast<qProcInfo_t*>(request);
1090 uint8_t numParam = sizeof(cpuInfoKey) / sizeof(uint8_t*);
1091 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001092 std::stringstream ss;
1093 std::string str;
1094
1095 *data_len = 0;
1096
1097 /* check for requested data params */
1098 if (req->paramSel < 1 || req->paramSel >= numParam)
1099 {
1100 phosphor::logging::log<phosphor::logging::level::ERR>(
1101 "Invalid parameter received");
1102 return IPMI_CC_PARM_OUT_OF_RANGE;
1103 }
1104
1105 ss << std::hex;
1106 ss << std::setw(2) << std::setfill('0') << (int)req->procIndex;
1107
1108 if (oemData[KEY_Q_PROC_INFO].find(ss.str()) ==
1109 oemData[KEY_Q_PROC_INFO].end())
1110 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
1111
1112 if (oemData[KEY_Q_PROC_INFO][ss.str()].find(cpuInfoKey[req->paramSel]) ==
1113 oemData[KEY_Q_PROC_INFO][ss.str()].end())
1114 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
1115
1116 str = oemData[KEY_Q_PROC_INFO][ss.str()][cpuInfoKey[req->paramSel]];
1117 *data_len = strToBytes(str, res);
1118
1119 return IPMI_CC_OK;
1120}
1121
1122//----------------------------------------------------------------------
1123// Set Dimm Info (CMD_OEM_Q_SET_DIMM_INFO)
1124//----------------------------------------------------------------------
1125// Request:
1126// Byte 1:3 – Manufacturer ID – XXYYZZh, LSB first
1127// Byte 4 – DIMM Index, 0 base
1128// Byte 5 – Parameter Selector
1129// Byte 6..N – Configuration parameter data (see below for Parameters
1130// of DIMM Information)
1131// Response:
1132// Byte 1 – Completion code
1133//
1134// Param#1 (DIMM Location):
1135// Byte 1 – DIMM Present
1136// Byte 1 – DIMM Present
1137// 01h – Present
1138// FFh – Not Present
1139// Byte 2 – Node Number, 0 base
1140// Byte 3 – Channel Number , 0 base
1141// Byte 4 – DIMM Number , 0 base
1142//
1143// Param#2 (DIMM Type):
1144// Byte 1 – DIMM Type
1145// Bit [7:6]
1146// For DDR3
1147// 00 – Normal Voltage (1.5V)
1148// 01 – Ultra Low Voltage (1.25V)
1149// 10 – Low Voltage (1.35V)
1150// 11 – Reserved
1151// For DDR4
1152// 00 – Reserved
1153// 01 – Reserved
1154// 10 – Reserved
1155// 11 – Normal Voltage (1.2V)
1156// Bit [5:0]
1157// 0x00 – SDRAM
1158// 0x01 – DDR-1 RAM
1159// 0x02 – Rambus
1160// 0x03 – DDR-2 RAM
1161// 0x04 – FBDIMM
1162// 0x05 – DDR-3 RAM
1163// 0x06 – DDR-4 RAM
1164//
1165// Param#3 (DIMM Speed):
1166// Byte 1..2 – DIMM speed in MHz, LSB
1167// Byte 3..6 – DIMM size in Mbytes, LSB
1168//
1169// Param#4 (Module Part Number):
1170// Byte 1..20 –Module Part Number (JEDEC Standard No. 21-C)
1171//
1172// Param#5 (Module Serial Number):
1173// Byte 1..4 –Module Serial Number (JEDEC Standard No. 21-C)
1174//
1175// Param#6 (Module Manufacturer ID):
1176// Byte 1 - Module Manufacturer ID, LSB
1177// Byte 2 - Module Manufacturer ID, MSB
1178//
1179ipmi_ret_t ipmiOemQSetDimmInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
1180 ipmi_request_t request, ipmi_response_t response,
1181 ipmi_data_len_t data_len, ipmi_context_t context)
1182{
Vijay Khemka63c99be2020-05-27 19:14:35 -07001183 qDimmInfo_t* req = reinterpret_cast<qDimmInfo_t*>(request);
1184 uint8_t numParam = sizeof(dimmInfoKey) / sizeof(uint8_t*);
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001185 std::stringstream ss;
1186 std::string str;
1187 uint8_t len = *data_len;
1188
1189 *data_len = 0;
1190
1191 /* check for requested data params */
1192 if (len < 5 || req->paramSel < 1 || req->paramSel >= numParam)
1193 {
1194 phosphor::logging::log<phosphor::logging::level::ERR>(
1195 "Invalid parameter received");
1196 return IPMI_CC_PARM_OUT_OF_RANGE;
1197 }
1198
1199 len = len - 5; // Get Actual data length
1200
1201 ss << std::hex;
1202 ss << std::setw(2) << std::setfill('0') << (int)req->dimmIndex;
1203 oemData[KEY_Q_DIMM_INFO][ss.str()][KEY_DIMM_INDEX] = req->dimmIndex;
1204
1205 str = bytesToStr(req->data, len);
1206 oemData[KEY_Q_DIMM_INFO][ss.str()][dimmInfoKey[req->paramSel]] =
1207 str.c_str();
1208 flushOemData();
1209
1210 return IPMI_CC_OK;
1211}
1212
1213//----------------------------------------------------------------------
1214// Get Dimm Info (CMD_OEM_Q_GET_DIMM_INFO)
1215//----------------------------------------------------------------------
1216// Request:
1217// Byte 1:3 – Manufacturer ID – XXYYZZh, LSB first
1218// Byte 4 – DIMM Index, 0 base
1219// Byte 5 – Parameter Selector
1220// Byte 6..N – Configuration parameter data (see below for Parameters
1221// of DIMM Information)
1222// Response:
1223// Byte 1 – Completion code
1224// Byte 2..N – Configuration Parameter Data (see Table_1213h Parameters
1225// of DIMM Information)
1226//
1227// Param#1 (DIMM Location):
1228// Byte 1 – DIMM Present
1229// Byte 1 – DIMM Present
1230// 01h – Present
1231// FFh – Not Present
1232// Byte 2 – Node Number, 0 base
1233// Byte 3 – Channel Number , 0 base
1234// Byte 4 – DIMM Number , 0 base
1235//
1236// Param#2 (DIMM Type):
1237// Byte 1 – DIMM Type
1238// Bit [7:6]
1239// For DDR3
1240// 00 – Normal Voltage (1.5V)
1241// 01 – Ultra Low Voltage (1.25V)
1242// 10 – Low Voltage (1.35V)
1243// 11 – Reserved
1244// For DDR4
1245// 00 – Reserved
1246// 01 – Reserved
1247// 10 – Reserved
1248// 11 – Normal Voltage (1.2V)
1249// Bit [5:0]
1250// 0x00 – SDRAM
1251// 0x01 – DDR-1 RAM
1252// 0x02 – Rambus
1253// 0x03 – DDR-2 RAM
1254// 0x04 – FBDIMM
1255// 0x05 – DDR-3 RAM
1256// 0x06 – DDR-4 RAM
1257//
1258// Param#3 (DIMM Speed):
1259// Byte 1..2 – DIMM speed in MHz, LSB
1260// Byte 3..6 – DIMM size in Mbytes, LSB
1261//
1262// Param#4 (Module Part Number):
1263// Byte 1..20 –Module Part Number (JEDEC Standard No. 21-C)
1264//
1265// Param#5 (Module Serial Number):
1266// Byte 1..4 –Module Serial Number (JEDEC Standard No. 21-C)
1267//
1268// Param#6 (Module Manufacturer ID):
1269// Byte 1 - Module Manufacturer ID, LSB
1270// Byte 2 - Module Manufacturer ID, MSB
1271//
1272ipmi_ret_t ipmiOemQGetDimmInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
1273 ipmi_request_t request, ipmi_response_t response,
1274 ipmi_data_len_t data_len, ipmi_context_t context)
1275{
Vijay Khemka63c99be2020-05-27 19:14:35 -07001276 qDimmInfo_t* req = reinterpret_cast<qDimmInfo_t*>(request);
1277 uint8_t numParam = sizeof(dimmInfoKey) / sizeof(uint8_t*);
1278 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001279 std::stringstream ss;
1280 std::string str;
1281
1282 *data_len = 0;
1283
1284 /* check for requested data params */
1285 if (req->paramSel < 1 || req->paramSel >= numParam)
1286 {
1287 phosphor::logging::log<phosphor::logging::level::ERR>(
1288 "Invalid parameter received");
1289 return IPMI_CC_PARM_OUT_OF_RANGE;
1290 }
1291
1292 ss << std::hex;
1293 ss << std::setw(2) << std::setfill('0') << (int)req->dimmIndex;
1294
1295 if (oemData[KEY_Q_DIMM_INFO].find(ss.str()) ==
1296 oemData[KEY_Q_DIMM_INFO].end())
1297 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
1298
1299 if (oemData[KEY_Q_DIMM_INFO][ss.str()].find(dimmInfoKey[req->paramSel]) ==
1300 oemData[KEY_Q_DIMM_INFO][ss.str()].end())
1301 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
1302
1303 str = oemData[KEY_Q_DIMM_INFO][ss.str()][dimmInfoKey[req->paramSel]];
1304 *data_len = strToBytes(str, res);
1305
1306 return IPMI_CC_OK;
1307}
1308
1309//----------------------------------------------------------------------
1310// Set Drive Info (CMD_OEM_Q_SET_DRIVE_INFO)
1311//----------------------------------------------------------------------
1312// BIOS issue this command to provide HDD information to BMC.
1313//
1314// BIOS just can get information by standard ATA / SMART command for
1315// OB SATA controller.
1316// BIOS can get
1317// 1. Serial Number
1318// 2. Model Name
1319// 3. HDD FW Version
1320// 4. HDD Capacity
1321// 5. HDD WWN
1322//
1323// Use Get HDD info Param #5 to know the MAX HDD info index.
1324//
1325// Request:
1326// Byte 1:3 – Quanta Manufacturer ID – 001C4Ch, LSB first
1327// Byte 4 –
1328// [7:4] Reserved
1329// [3:0] HDD Controller Type
1330// 0x00 – BIOS
1331// 0x01 – Expander
1332// 0x02 – LSI
1333// Byte 5 – HDD Info Index, 0 base
1334// Byte 6 – Parameter Selector
1335// Byte 7..N – Configuration parameter data (see Table_1415h Parameters of HDD
1336// Information)
1337//
1338// Response:
1339// Byte 1 – Completion Code
1340//
1341// Param#0 (HDD Location):
1342// Byte 1 – Controller
1343// [7:3] Device Number
1344// [2:0] Function Number
1345// For Intel C610 series (Wellsburg)
1346// D31:F2 (0xFA) – SATA control 1
1347// D31:F5 (0xFD) – SATA control 2
1348// D17:F4 (0x8C) – sSata control
1349// Byte 2 – Port Number
1350// Byte 3 – Location (0xFF: No HDD Present)
1351// BIOS default set Byte 3 to 0xFF, if No HDD Present. And then skip send param
1352// #1~4, #6, #7 to BMC (still send param #5) BIOS default set Byte 3 to 0, if
1353// the HDD present. BMC or other people who know the HDD location has
1354// responsibility for update Location info
1355//
1356// Param#1 (Serial Number):
1357// Bytes 1..33: HDD Serial Number
1358//
1359// Param#2 (Model Name):
1360// Byte 1..33 – HDD Model Name
1361//
1362// Param#3 (HDD FW Version):
1363// Byte 1..17 –HDD FW version
1364//
1365// Param#4 (Capacity):
1366// Byte 1..4 –HDD Block Size, LSB
1367// Byte 5..12 - HDD Block Number, LSB
1368// HDD Capacity = HDD Block size * HDD BLock number (Unit Byte)
1369//
1370// Param#5 (Max HDD Quantity):
1371// Byte 1 - Max HDD Quantity
1372// Max supported port numbers in this PCH
1373//
1374// Param#6 (HDD Type)
1375// Byte 1 – HDD Type
1376// 0h – Reserved
1377// 1h – SAS
1378// 2h – SATA
1379// 3h – PCIE SSD (NVME)
1380//
1381// Param#7 (HDD WWN)
1382// Data 1...8: HDD World Wide Name, LSB
1383//
1384ipmi_ret_t ipmiOemQSetDriveInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
1385 ipmi_request_t request,
1386 ipmi_response_t response,
1387 ipmi_data_len_t data_len,
1388 ipmi_context_t context)
1389{
Vijay Khemka63c99be2020-05-27 19:14:35 -07001390 qDriveInfo_t* req = reinterpret_cast<qDriveInfo_t*>(request);
1391 uint8_t numParam = sizeof(driveInfoKey) / sizeof(uint8_t*);
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001392 uint8_t ctrlType = req->hddCtrlType & 0x0f;
1393 std::stringstream ss;
1394 std::string str;
1395 uint8_t len = *data_len;
1396
1397 *data_len = 0;
1398
1399 /* check for requested data params */
1400 if (len < 6 || req->paramSel < 1 || req->paramSel >= numParam ||
1401 ctrlType > 2)
1402 {
1403 phosphor::logging::log<phosphor::logging::level::ERR>(
1404 "Invalid parameter received");
1405 return IPMI_CC_PARM_OUT_OF_RANGE;
1406 }
1407
1408 len = len - 6; // Get Actual data length
1409
1410 ss << std::hex;
1411 ss << std::setw(2) << std::setfill('0') << (int)req->hddIndex;
1412 oemData[KEY_Q_DRIVE_INFO][KEY_HDD_CTRL_TYPE] = req->hddCtrlType;
1413 oemData[KEY_Q_DRIVE_INFO][ctrlTypeKey[ctrlType]][ss.str()][KEY_HDD_INDEX] =
1414 req->hddIndex;
1415
1416 str = bytesToStr(req->data, len);
1417 oemData[KEY_Q_DRIVE_INFO][ctrlTypeKey[ctrlType]][ss.str()]
1418 [driveInfoKey[req->paramSel]] = str.c_str();
1419 flushOemData();
1420
1421 return IPMI_CC_OK;
1422}
1423
1424//----------------------------------------------------------------------
1425// Get Drive Info (CMD_OEM_Q_GET_DRIVE_INFO)
1426//----------------------------------------------------------------------
1427// BMC needs to check HDD presented or not first. If NOT presented, return
1428// completion code 0xD5.
1429//
1430// Request:
1431// Byte 1:3 – Quanta Manufacturer ID – 001C4Ch, LSB first
1432// Byte 4 –
1433//[7:4] Reserved
1434//[3:0] HDD Controller Type
1435// 0x00 – BIOS
1436// 0x01 – Expander
1437// 0x02 – LSI
1438// Byte 5 – HDD Index, 0 base
1439// Byte 6 – Parameter Selector (See Above Set HDD Information)
1440// Response:
1441// Byte 1 – Completion Code
1442// 0xD5 – Not support in current status (HDD Not Present)
1443// Byte 2..N – Configuration parameter data (see Table_1415h Parameters of HDD
1444// Information)
1445//
1446ipmi_ret_t ipmiOemQGetDriveInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
1447 ipmi_request_t request,
1448 ipmi_response_t response,
1449 ipmi_data_len_t data_len,
1450 ipmi_context_t context)
1451{
Vijay Khemka63c99be2020-05-27 19:14:35 -07001452 qDriveInfo_t* req = reinterpret_cast<qDriveInfo_t*>(request);
1453 uint8_t numParam = sizeof(driveInfoKey) / sizeof(uint8_t*);
1454 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001455 uint8_t ctrlType = req->hddCtrlType & 0x0f;
1456 std::stringstream ss;
1457 std::string str;
1458
1459 *data_len = 0;
1460
1461 /* check for requested data params */
1462 if (req->paramSel < 1 || req->paramSel >= numParam || ctrlType > 2)
1463 {
1464 phosphor::logging::log<phosphor::logging::level::ERR>(
1465 "Invalid parameter received");
1466 return IPMI_CC_PARM_OUT_OF_RANGE;
1467 }
1468
1469 if (oemData[KEY_Q_DRIVE_INFO].find(ctrlTypeKey[ctrlType]) ==
1470 oemData[KEY_Q_DRIVE_INFO].end())
1471 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
1472
1473 ss << std::hex;
1474 ss << std::setw(2) << std::setfill('0') << (int)req->hddIndex;
1475
1476 if (oemData[KEY_Q_DRIVE_INFO][ctrlTypeKey[ctrlType]].find(ss.str()) ==
1477 oemData[KEY_Q_DRIVE_INFO].end())
1478 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
1479
1480 if (oemData[KEY_Q_DRIVE_INFO][ctrlTypeKey[ctrlType]][ss.str()].find(
1481 dimmInfoKey[req->paramSel]) ==
1482 oemData[KEY_Q_DRIVE_INFO][ss.str()].end())
1483 return CC_PARAM_NOT_SUPP_IN_CURR_STATE;
1484
1485 str = oemData[KEY_Q_DRIVE_INFO][ctrlTypeKey[ctrlType]][ss.str()]
1486 [dimmInfoKey[req->paramSel]];
1487 *data_len = strToBytes(str, res);
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001488
1489 return IPMI_CC_OK;
1490}
1491
Vijay Khemkadd14c0f2020-03-18 14:48:13 -07001492/* Helper function for sending DCMI commands to ME and getting response back */
1493ipmi::RspType<std::vector<uint8_t>> sendDCMICmd(uint8_t cmd,
Vijay Khemka63c99be2020-05-27 19:14:35 -07001494 std::vector<uint8_t>& cmdData)
Vijay Khemkadd14c0f2020-03-18 14:48:13 -07001495{
1496 std::vector<uint8_t> respData;
1497
1498 /* Add group id as first byte to request for ME command */
1499 cmdData.insert(cmdData.begin(), groupDCMI);
1500
1501 if (sendMeCmd(ipmi::netFnGroup, cmd, cmdData, respData))
1502 return ipmi::responseUnspecifiedError();
1503
1504 /* Remove group id as first byte as it will be added by IPMID */
1505 respData.erase(respData.begin());
1506
1507 return ipmi::responseSuccess(std::move(respData));
1508}
1509
1510/* DCMI Command handellers. */
1511
1512ipmi::RspType<std::vector<uint8_t>>
1513 ipmiOemDCMIGetPowerReading(std::vector<uint8_t> reqData)
1514{
1515 return sendDCMICmd(ipmi::dcmi::cmdGetPowerReading, reqData);
1516}
1517
1518ipmi::RspType<std::vector<uint8_t>>
1519 ipmiOemDCMIGetPowerLimit(std::vector<uint8_t> reqData)
1520{
1521 return sendDCMICmd(ipmi::dcmi::cmdGetPowerLimit, reqData);
1522}
1523
1524ipmi::RspType<std::vector<uint8_t>>
1525 ipmiOemDCMISetPowerLimit(std::vector<uint8_t> reqData)
1526{
1527 return sendDCMICmd(ipmi::dcmi::cmdSetPowerLimit, reqData);
1528}
1529
1530ipmi::RspType<std::vector<uint8_t>>
1531 ipmiOemDCMIApplyPowerLimit(std::vector<uint8_t> reqData)
1532{
1533 return sendDCMICmd(ipmi::dcmi::cmdActDeactivatePwrLimit, reqData);
1534}
1535
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001536static void registerOEMFunctions(void)
1537{
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001538 /* Get OEM data from json file */
1539 std::ifstream file(JSON_OEM_DATA_FILE);
1540 if (file)
Vijay Khemkafeaa9812019-08-27 15:08:08 -07001541 {
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001542 file >> oemData;
Vijay Khemkafeaa9812019-08-27 15:08:08 -07001543 file.close();
1544 }
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001545
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001546 phosphor::logging::log<phosphor::logging::level::INFO>(
1547 "Registering OEM commands");
Vijay Khemka7c0aea42020-03-05 13:31:53 -08001548
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001549 ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, CMD_OEM_USB_DBG_GET_FRAME_INFO,
1550 NULL, ipmiOemDbgGetFrameInfo,
1551 PRIVILEGE_USER); // get debug frame info
1552 ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ,
1553 CMD_OEM_USB_DBG_GET_UPDATED_FRAMES, NULL,
1554 ipmiOemDbgGetUpdFrames,
1555 PRIVILEGE_USER); // get debug updated frames
1556 ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, CMD_OEM_USB_DBG_GET_POST_DESC,
1557 NULL, ipmiOemDbgGetPostDesc,
1558 PRIVILEGE_USER); // get debug post description
1559 ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, CMD_OEM_USB_DBG_GET_GPIO_DESC,
1560 NULL, ipmiOemDbgGetGpioDesc,
1561 PRIVILEGE_USER); // get debug gpio description
1562 ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, CMD_OEM_USB_DBG_GET_FRAME_DATA,
1563 NULL, ipmiOemDbgGetFrameData,
1564 PRIVILEGE_USER); // get debug frame data
1565 ipmiPrintAndRegister(NETFN_OEM_USB_DBG_REQ, CMD_OEM_USB_DBG_CTRL_PANEL,
1566 NULL, ipmiOemDbgGetCtrlPanel,
1567 PRIVILEGE_USER); // get debug control panel
1568 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_DIMM_INFO, NULL,
1569 ipmiOemSetDimmInfo,
1570 PRIVILEGE_USER); // Set Dimm Info
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001571 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_GET_BOARD_ID, NULL,
1572 ipmiOemGetBoardID,
1573 PRIVILEGE_USER); // Get Board ID
1574 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_BOOT_ORDER, NULL,
1575 ipmiOemSetBootOrder,
1576 PRIVILEGE_USER); // Set Boot Order
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001577 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_GET_BOOT_ORDER, NULL,
1578 ipmiOemGetBootOrder,
1579 PRIVILEGE_USER); // Get Boot Order
1580 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_MACHINE_CONFIG_INFO, NULL,
1581 ipmiOemSetMachineCfgInfo,
1582 PRIVILEGE_USER); // Set Machine Config Info
1583 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_POST_START, NULL,
1584 ipmiOemSetPostStart,
1585 PRIVILEGE_USER); // Set POST start
1586 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_POST_END, NULL,
1587 ipmiOemSetPostEnd,
1588 PRIVILEGE_USER); // Set POST End
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001589 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_PPIN_INFO, NULL,
1590 ipmiOemSetPPINInfo,
1591 PRIVILEGE_USER); // Set PPIN Info
1592 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_ADR_TRIGGER, NULL,
1593 ipmiOemSetAdrTrigger,
1594 PRIVILEGE_USER); // Set ADR Trigger
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001595 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_BIOS_FLASH_INFO, NULL,
1596 ipmiOemSetBiosFlashInfo,
1597 PRIVILEGE_USER); // Set Bios Flash Info
1598 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_PPR, NULL, ipmiOemSetPpr,
1599 PRIVILEGE_USER); // Set PPR
1600 ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_GET_PPR, NULL, ipmiOemGetPpr,
1601 PRIVILEGE_USER); // Get PPR
Vijay Khemka1d4a0692019-04-09 15:20:28 -07001602 /* FB OEM QC Commands */
1603 ipmiPrintAndRegister(NETFUN_FB_OEM_QC, CMD_OEM_Q_SET_PROC_INFO, NULL,
1604 ipmiOemQSetProcInfo,
1605 PRIVILEGE_USER); // Set Proc Info
1606 ipmiPrintAndRegister(NETFUN_FB_OEM_QC, CMD_OEM_Q_GET_PROC_INFO, NULL,
1607 ipmiOemQGetProcInfo,
1608 PRIVILEGE_USER); // Get Proc Info
1609 ipmiPrintAndRegister(NETFUN_FB_OEM_QC, CMD_OEM_Q_SET_DIMM_INFO, NULL,
1610 ipmiOemQSetDimmInfo,
1611 PRIVILEGE_USER); // Set Dimm Info
1612 ipmiPrintAndRegister(NETFUN_FB_OEM_QC, CMD_OEM_Q_GET_DIMM_INFO, NULL,
1613 ipmiOemQGetDimmInfo,
1614 PRIVILEGE_USER); // Get Dimm Info
1615 ipmiPrintAndRegister(NETFUN_FB_OEM_QC, CMD_OEM_Q_SET_DRIVE_INFO, NULL,
1616 ipmiOemQSetDriveInfo,
1617 PRIVILEGE_USER); // Set Drive Info
1618 ipmiPrintAndRegister(NETFUN_FB_OEM_QC, CMD_OEM_Q_GET_DRIVE_INFO, NULL,
1619 ipmiOemQGetDriveInfo,
1620 PRIVILEGE_USER); // Get Drive Info
Vijay Khemkadd14c0f2020-03-18 14:48:13 -07001621
1622 /* FB OEM DCMI Commands as per DCMI spec 1.5 Section 6 */
1623 ipmi::registerGroupHandler(ipmi::prioOpenBmcBase, groupDCMI,
1624 ipmi::dcmi::cmdGetPowerReading,
1625 ipmi::Privilege::User,
1626 ipmiOemDCMIGetPowerReading); // Get Power Reading
1627
1628 ipmi::registerGroupHandler(ipmi::prioOpenBmcBase, groupDCMI,
1629 ipmi::dcmi::cmdGetPowerLimit,
1630 ipmi::Privilege::User,
1631 ipmiOemDCMIGetPowerLimit); // Get Power Limit
1632
1633 ipmi::registerGroupHandler(ipmi::prioOpenBmcBase, groupDCMI,
1634 ipmi::dcmi::cmdSetPowerLimit,
1635 ipmi::Privilege::Operator,
1636 ipmiOemDCMISetPowerLimit); // Set Power Limit
1637
1638 ipmi::registerGroupHandler(ipmi::prioOpenBmcBase, groupDCMI,
1639 ipmi::dcmi::cmdActDeactivatePwrLimit,
1640 ipmi::Privilege::Operator,
1641 ipmiOemDCMIApplyPowerLimit); // Apply Power Limit
1642
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001643 return;
1644}
1645
1646} // namespace ipmi