blob: 3b633b0e116a52247191ec3054a5c27961081cdb [file] [log] [blame]
Vijay Khemkaa2d52f12019-03-27 14:54:00 -07001/*
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
Vijay Khemkaa2d52f12019-03-27 14:54:00 -070018#include <fcntl.h>
Vijay Khemka63c99be2020-05-27 19:14:35 -070019#include <ipmid/api.h>
20#include <sys/stat.h>
Vijay Khemkaa2d52f12019-03-27 14:54:00 -070021#include <unistd.h>
Vijay Khemka63c99be2020-05-27 19:14:35 -070022
23#include <appcommands.hpp>
Vijay Khemkaa2d52f12019-03-27 14:54:00 -070024#include <commandutils.hpp>
Patrick Williams2405ae92023-05-10 07:50:09 -050025#include <ipmid/api-types.hpp>
26#include <ipmid/api.hpp>
Vijay Khemka63c99be2020-05-27 19:14:35 -070027#include <nlohmann/json.hpp>
Vijay Khemkaa2d52f12019-03-27 14:54:00 -070028#include <phosphor-logging/log.hpp>
29#include <sdbusplus/message/types.hpp>
Vijay Khemka63c99be2020-05-27 19:14:35 -070030
Kevin Tunge4e18ca2025-06-05 10:21:23 +080031#include <format>
Vijay Khemka63c99be2020-05-27 19:14:35 -070032#include <fstream>
33#include <iomanip>
34#include <iostream>
35#include <sstream>
Vijay Khemkaa2d52f12019-03-27 14:54:00 -070036
37namespace ipmi
38{
39
40static void registerAPPFunctions() __attribute__((constructor));
41static constexpr size_t GUID_SIZE = 16;
42// TODO Make offset and location runtime configurable to ensure we
43// can make each define their own locations.
44static constexpr off_t OFFSET_SYS_GUID = 0x17F0;
Vijay Khemka63c99be2020-05-27 19:14:35 -070045static constexpr const char* FRU_EEPROM = "/sys/bus/i2c/devices/6-0054/eeprom";
Vijay Khemka666a4d92019-04-03 11:27:24 -070046
47// TODO: Need to store this info after identifying proper storage
Vijay Khemkaa2d52f12019-03-27 14:54:00 -070048static uint8_t globEna = 0x09;
Vijay Khemka666a4d92019-04-03 11:27:24 -070049static SysInfoParam sysInfoParams;
Vijay Khemka802ccb12019-08-27 15:03:44 -070050nlohmann::json appData __attribute__((init_priority(101)));
Vijay Khemkaa2d52f12019-03-27 14:54:00 -070051
George Liu2f454992025-07-02 16:43:57 +080052// Custom completion codes can be defined in individual modules for command
53// specific errors in the 0x80-0xBE range
54constexpr ipmi::Cc ccSystemInfoParameterNotSupported = 0x80;
55
Manikandan Elumalai5f8e3432020-12-02 03:46:55 +053056int sendBicCmd(uint8_t, uint8_t, uint8_t, std::vector<uint8_t>&,
57 std::vector<uint8_t>&);
58
Bonnie Loe9baaff2022-11-08 16:36:21 +080059static inline auto responseSystemInfoParamterNotSupportCommand()
60{
George Liu2f454992025-07-02 16:43:57 +080061 return response(ccSystemInfoParameterNotSupported);
Bonnie Loe9baaff2022-11-08 16:36:21 +080062}
63
Vijay Khemka63c99be2020-05-27 19:14:35 -070064void printGUID(uint8_t* guid, off_t offset)
Vijay Khemkaa2d52f12019-03-27 14:54:00 -070065{
66 std::cout << "Read GUID from offset : " << offset << " :\n";
Willy Tue39f9392022-06-15 13:24:20 -070067 for (size_t i = 0; i < GUID_SIZE; i++)
Vijay Khemkaa2d52f12019-03-27 14:54:00 -070068 {
69 int data = guid[i];
70 std::cout << std::hex << data << " ";
71 }
72 std::cout << std::endl;
73}
74
Vijay Khemka63c99be2020-05-27 19:14:35 -070075int getGUID(off_t offset, uint8_t* guid)
Vijay Khemkaa2d52f12019-03-27 14:54:00 -070076{
77 int fd = -1;
78 ssize_t bytes_rd;
79 int ret = 0;
cchouxb2ae88b2023-09-13 00:35:36 +080080 std::string eepromPath = FRU_EEPROM;
81
82 // find the eeprom path of MB FRU
83 auto device = getMbFruDevice();
84 if (device)
85 {
86 auto [bus, address] = *device;
87 std::stringstream ss;
88 ss << "/sys/bus/i2c/devices/" << static_cast<int>(bus) << "-"
89 << std::setw(4) << std::setfill('0') << std::hex
90 << static_cast<int>(address) << "/eeprom";
91 eepromPath = ss.str();
92 }
Vijay Khemkaa2d52f12019-03-27 14:54:00 -070093
94 errno = 0;
95
96 // Check if file is present
cchouxb2ae88b2023-09-13 00:35:36 +080097 if (access(eepromPath.c_str(), F_OK) == -1)
Vijay Khemkaa2d52f12019-03-27 14:54:00 -070098 {
cchouxb2ae88b2023-09-13 00:35:36 +080099 std::cerr << "Unable to access: " << eepromPath << std::endl;
Vijay Khemkaa2d52f12019-03-27 14:54:00 -0700100 return errno;
101 }
102
103 // Open the file
cchouxb2ae88b2023-09-13 00:35:36 +0800104 fd = open(eepromPath.c_str(), O_RDONLY);
Vijay Khemkaa2d52f12019-03-27 14:54:00 -0700105 if (fd == -1)
106 {
cchouxb2ae88b2023-09-13 00:35:36 +0800107 std::cerr << "Unable to open: " << eepromPath << std::endl;
Vijay Khemkaa2d52f12019-03-27 14:54:00 -0700108 return errno;
109 }
110
111 // seek to the offset
112 lseek(fd, offset, SEEK_SET);
113
114 // Read bytes from location
115 bytes_rd = read(fd, guid, GUID_SIZE);
116 if (bytes_rd != GUID_SIZE)
117 {
118 phosphor::logging::log<phosphor::logging::level::ERR>(
119 "GUID read data from EEPROM failed");
120 ret = errno;
121 }
122 else
123 {
124 printGUID(guid, offset);
125 }
126 close(fd);
127 return ret;
128}
129
Vijay Khemka63c99be2020-05-27 19:14:35 -0700130int getSystemGUID(uint8_t* guid)
Vijay Khemkaa2d52f12019-03-27 14:54:00 -0700131{
132 return getGUID(OFFSET_SYS_GUID, guid);
133}
134
Vijay Khemkaa2d52f12019-03-27 14:54:00 -0700135//----------------------------------------------------------------------
Vijay Khemka666a4d92019-04-03 11:27:24 -0700136// Get Self Test Results (IPMI/Section 20.4) (CMD_APP_GET_SELFTEST_RESULTS)
137//----------------------------------------------------------------------
Willy Tue39f9392022-06-15 13:24:20 -0700138ipmi_ret_t ipmiAppGetSTResults(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t,
139 ipmi_response_t response,
140 ipmi_data_len_t data_len, ipmi_context_t)
Vijay Khemka666a4d92019-04-03 11:27:24 -0700141{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700142 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemka666a4d92019-04-03 11:27:24 -0700143
144 // TODO: Following data needs to be updated based on self-test results
145 *res++ = 0x55; // Self-Test result
146 *res++ = 0x00; // Extra error info in case of failure
147
148 *data_len = 2;
149
George Liu2f454992025-07-02 16:43:57 +0800150 return ipmi::ccSuccess;
Vijay Khemka666a4d92019-04-03 11:27:24 -0700151}
152
153//----------------------------------------------------------------------
154// Manufacturing Test On (IPMI/Section 20.5) (CMD_APP_MFR_TEST_ON)
155//----------------------------------------------------------------------
Willy Tue39f9392022-06-15 13:24:20 -0700156ipmi_ret_t ipmiAppMfrTestOn(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t request,
157 ipmi_response_t, ipmi_data_len_t data_len,
158 ipmi_context_t)
Vijay Khemka666a4d92019-04-03 11:27:24 -0700159{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700160 uint8_t* req = reinterpret_cast<uint8_t*>(request);
Vijay Khemka666a4d92019-04-03 11:27:24 -0700161 std::string mfrTest = "sled-cycle";
George Liu2f454992025-07-02 16:43:57 +0800162 ipmi_ret_t rc = ipmi::ccSuccess;
Vijay Khemka666a4d92019-04-03 11:27:24 -0700163
164 if (!memcmp(req, mfrTest.data(), mfrTest.length()) &&
165 (*data_len == mfrTest.length()))
166 {
167 /* sled-cycle the BMC */
Patrick Williams35208452022-06-24 06:12:15 -0500168 auto ret = system("/usr/sbin/power-util sled-cycle");
169 if (ret)
170 {
George Liu2f454992025-07-02 16:43:57 +0800171 rc = ipmi::ccUnspecifiedError;
Patrick Williams35208452022-06-24 06:12:15 -0500172 }
Vijay Khemka666a4d92019-04-03 11:27:24 -0700173 }
174 else
175 {
George Liu2f454992025-07-02 16:43:57 +0800176 rc = ccSystemInfoParameterNotSupported;
Vijay Khemka666a4d92019-04-03 11:27:24 -0700177 }
178
179 *data_len = 0;
180
Patrick Williams35208452022-06-24 06:12:15 -0500181 return rc;
Vijay Khemka666a4d92019-04-03 11:27:24 -0700182}
183
184//----------------------------------------------------------------------
Vijay Khemkaa2d52f12019-03-27 14:54:00 -0700185// Set Global Enables (CMD_APP_SET_GLOBAL_ENABLES)
186//----------------------------------------------------------------------
Willy Tue39f9392022-06-15 13:24:20 -0700187ipmi_ret_t ipmiAppSetGlobalEnables(ipmi_netfn_t, ipmi_cmd_t,
188 ipmi_request_t request, ipmi_response_t,
189 ipmi_data_len_t data_len, ipmi_context_t)
Vijay Khemkaa2d52f12019-03-27 14:54:00 -0700190{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700191 uint8_t* req = reinterpret_cast<uint8_t*>(request);
Vijay Khemkaa2d52f12019-03-27 14:54:00 -0700192
193 globEna = *req;
194 *data_len = 0;
195
George Liu2f454992025-07-02 16:43:57 +0800196 return ipmi::ccSuccess;
Vijay Khemkaa2d52f12019-03-27 14:54:00 -0700197}
198
199//----------------------------------------------------------------------
200// Get Global Enables (CMD_APP_GET_GLOBAL_ENABLES)
201//----------------------------------------------------------------------
Willy Tue39f9392022-06-15 13:24:20 -0700202ipmi_ret_t ipmiAppGetGlobalEnables(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t,
Vijay Khemkaa2d52f12019-03-27 14:54:00 -0700203 ipmi_response_t response,
Willy Tue39f9392022-06-15 13:24:20 -0700204 ipmi_data_len_t data_len, ipmi_context_t)
Vijay Khemkaa2d52f12019-03-27 14:54:00 -0700205{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700206 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemkaa2d52f12019-03-27 14:54:00 -0700207
208 *data_len = 1;
209 *res++ = globEna;
210
George Liu2f454992025-07-02 16:43:57 +0800211 return ipmi::ccSuccess;
Vijay Khemkaa2d52f12019-03-27 14:54:00 -0700212}
213
214//----------------------------------------------------------------------
Vijay Khemka666a4d92019-04-03 11:27:24 -0700215// Clear Message flags (IPMI/Section 22.3) (CMD_APP_CLEAR_MESSAGE_FLAGS)
216//----------------------------------------------------------------------
Willy Tue39f9392022-06-15 13:24:20 -0700217ipmi_ret_t ipmiAppClearMsgFlags(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t,
218 ipmi_response_t, ipmi_data_len_t data_len,
219 ipmi_context_t)
Vijay Khemka666a4d92019-04-03 11:27:24 -0700220{
221 // Do Nothing and just return success
222 *data_len = 0;
223
George Liu2f454992025-07-02 16:43:57 +0800224 return ipmi::ccSuccess;
Vijay Khemka666a4d92019-04-03 11:27:24 -0700225}
226
227//----------------------------------------------------------------------
Vijay Khemkaa2d52f12019-03-27 14:54:00 -0700228// Get System GUID (CMD_APP_GET_SYS_GUID)
229//----------------------------------------------------------------------
Manikandan Elumalai5f8e3432020-12-02 03:46:55 +0530230#if BIC_ENABLED
Patrick Williams1caf0482025-02-01 08:21:34 -0500231ipmi::RspType<std::vector<uint8_t>> ipmiAppGetSysGUID(
232 ipmi::Context::ptr ctx, std::vector<uint8_t> reqData)
Manikandan Elumalai5f8e3432020-12-02 03:46:55 +0530233
234{
235 std::vector<uint8_t> respData;
236
237 uint8_t bicAddr = (uint8_t)ctx->hostIdx << 2;
238
239 if (sendBicCmd(ctx->netFn, ctx->cmd, bicAddr, reqData, respData))
240 return ipmi::responseUnspecifiedError();
241
242 return ipmi::responseSuccess(respData);
243}
244
245#else
Willy Tue39f9392022-06-15 13:24:20 -0700246ipmi_ret_t ipmiAppGetSysGUID(ipmi_netfn_t, ipmi_cmd_t, ipmi_request_t,
247 ipmi_response_t response, ipmi_data_len_t data_len,
248 ipmi_context_t)
Vijay Khemkaa2d52f12019-03-27 14:54:00 -0700249{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700250 uint8_t* res = reinterpret_cast<uint8_t*>(response);
Vijay Khemkaa2d52f12019-03-27 14:54:00 -0700251 if (getSystemGUID(res))
252 {
George Liu2f454992025-07-02 16:43:57 +0800253 return ipmi::ccUnspecifiedError;
Vijay Khemkaa2d52f12019-03-27 14:54:00 -0700254 }
255 *data_len = GUID_SIZE;
George Liu2f454992025-07-02 16:43:57 +0800256 return ipmi::ccSuccess;
Vijay Khemkaa2d52f12019-03-27 14:54:00 -0700257}
258
Manikandan Elumalai5f8e3432020-12-02 03:46:55 +0530259#endif
260
Vijay Khemka666a4d92019-04-03 11:27:24 -0700261//----------------------------------------------------------------------
262// Platform specific functions for storing app data
263//----------------------------------------------------------------------
264
265void flush_app_data()
266{
Vijay Khemka802ccb12019-08-27 15:03:44 -0700267 std::ofstream file(JSON_APP_DATA_FILE);
Vijay Khemka666a4d92019-04-03 11:27:24 -0700268 file << appData;
Vijay Khemka802ccb12019-08-27 15:03:44 -0700269 file.close();
Vijay Khemka666a4d92019-04-03 11:27:24 -0700270 return;
271}
272
Kevin Tunge4e18ca2025-06-05 10:21:23 +0800273static int platSetSysFWVer(uint8_t* ver, const size_t hostId)
Vijay Khemka666a4d92019-04-03 11:27:24 -0700274{
275 std::stringstream ss;
276 int i;
277
278 /* TODO: implement byte 1: Set selector
279 * byte 2: encodeing, currently only supported
280 * ASCII which is value 0, UTF and unicode are
281 * not supported yet.
282 */
283 if (ver[1] & 0x0f)
284 return -1;
285
286 for (i = 3; i < 3 + ver[2]; i++)
287 {
288 ss << (char)ver[i];
289 }
290
Kevin Tunge4e18ca2025-06-05 10:21:23 +0800291 /* Save to legacy sysfw version file for backward compatibility */
292 appData[KEY_SYSFW_VER + std::to_string(hostId)] = ss.str();
Vijay Khemka666a4d92019-04-03 11:27:24 -0700293 flush_app_data();
294
Kevin Tunge4e18ca2025-06-05 10:21:23 +0800295 auto sysfwVersionFile = std::format(SYSFW_VER_FILE, hostId);
296 std::ofstream file(sysfwVersionFile);
297
298 if (!file)
299 {
300 phosphor::logging::log<phosphor::logging::level::ERR>(
301 "Failed to open system firmware version file for writing",
302 phosphor::logging::entry("FILE=%s", sysfwVersionFile.c_str()));
303 return -1;
304 }
305
306 file << ss.str();
307 file.close();
308
Vijay Khemka666a4d92019-04-03 11:27:24 -0700309 return 0;
310}
311
Kevin Tunge4e18ca2025-06-05 10:21:23 +0800312static int platGetSysFWVer(std::vector<uint8_t>& respData, const size_t hostId)
Vijay Khemka666a4d92019-04-03 11:27:24 -0700313{
Kevin Tunge4e18ca2025-06-05 10:21:23 +0800314 constexpr size_t headerSize = 3; // selector + encoding + version size
Vijay Khemka666a4d92019-04-03 11:27:24 -0700315
Kevin Tunge4e18ca2025-06-05 10:21:23 +0800316 std::string sysfwVersionFile = std::format(SYSFW_VER_FILE, hostId);
317 std::ifstream file(sysfwVersionFile);
318
319 if (!file)
Bonnie Loe9baaff2022-11-08 16:36:21 +0800320 {
Kevin Tunge4e18ca2025-06-05 10:21:23 +0800321 phosphor::logging::log<phosphor::logging::level::ERR>(
322 "Failed to open system firmware version file for reading",
323 phosphor::logging::entry("FILE=%s", sysfwVersionFile.c_str()));
Bonnie Loe9baaff2022-11-08 16:36:21 +0800324 return -1;
325 }
Bonnie Loe9baaff2022-11-08 16:36:21 +0800326
Kevin Tunge4e18ca2025-06-05 10:21:23 +0800327 std::string version;
328 std::getline(file, version);
329 file.close();
Vijay Khemka666a4d92019-04-03 11:27:24 -0700330
Kevin Tunge4e18ca2025-06-05 10:21:23 +0800331 // Truncate if longer than allowed
332 if (version.size() > SIZE_SYSFW_VER - headerSize)
333 {
334 version.resize(SIZE_SYSFW_VER - headerSize);
335 }
Bonnie Loe9baaff2022-11-08 16:36:21 +0800336
Kevin Tunge4e18ca2025-06-05 10:21:23 +0800337 respData.push_back(0); // Byte 1: set selector not supported
338 respData.push_back(0); // Byte 2: only ASCII supported
339 respData.push_back(version.size()); // Byte 3: length of version
340
341 for (auto c : version)
Bonnie Loe9baaff2022-11-08 16:36:21 +0800342 {
343 respData.push_back(c);
344 }
345
346 // Remaining byte fill to 0
Kevin Tunge4e18ca2025-06-05 10:21:23 +0800347 for (size_t i = 0; i < SIZE_SYSFW_VER - (version.size() + headerSize); i++)
Bonnie Loe9baaff2022-11-08 16:36:21 +0800348 {
349 respData.push_back(0);
350 }
Vijay Khemka666a4d92019-04-03 11:27:24 -0700351
Kevin Tunge4e18ca2025-06-05 10:21:23 +0800352 return (version.size() + headerSize);
Vijay Khemka666a4d92019-04-03 11:27:24 -0700353}
354
355//----------------------------------------------------------------------
356// Set Sys Info Params (IPMI/Sec 22.14a) (CMD_APP_SET_SYS_INFO_PARAMS)
357//----------------------------------------------------------------------
Patrick Williams1caf0482025-02-01 08:21:34 -0500358ipmi::RspType<uint8_t> ipmiAppSetSysInfoParams(ipmi::Context::ptr ctx,
359 std::vector<uint8_t> req)
Vijay Khemka666a4d92019-04-03 11:27:24 -0700360{
Vijay Khemka666a4d92019-04-03 11:27:24 -0700361 uint8_t param = req[0];
Bonnie Loe9baaff2022-11-08 16:36:21 +0800362 uint8_t req_len = req.size();
363 std::optional<size_t> hostId = findHost(ctx->hostIdx);
Vijay Khemka666a4d92019-04-03 11:27:24 -0700364
Bonnie Loe9baaff2022-11-08 16:36:21 +0800365 if (!hostId)
366 {
367 phosphor::logging::log<phosphor::logging::level::ERR>(
368 "Invalid Host Id received");
369 return ipmi::responseInvalidCommand();
370 }
Vijay Khemka666a4d92019-04-03 11:27:24 -0700371
372 switch (param)
373 {
374 case SYS_INFO_PARAM_SET_IN_PROG:
375 sysInfoParams.set_in_prog = req[1];
376 break;
377 case SYS_INFO_PARAM_SYSFW_VER:
Bonnie Loe9baaff2022-11-08 16:36:21 +0800378 {
Vijay Khemka666a4d92019-04-03 11:27:24 -0700379 memcpy(sysInfoParams.sysfw_ver, &req[1], SIZE_SYSFW_VER);
Kevin Tunge4e18ca2025-06-05 10:21:23 +0800380 if (platSetSysFWVer(sysInfoParams.sysfw_ver, *hostId))
Bonnie Loe9baaff2022-11-08 16:36:21 +0800381 return ipmi::responseSystemInfoParamterNotSupportCommand();
Vijay Khemka666a4d92019-04-03 11:27:24 -0700382 break;
Bonnie Loe9baaff2022-11-08 16:36:21 +0800383 }
Vijay Khemka666a4d92019-04-03 11:27:24 -0700384 case SYS_INFO_PARAM_SYS_NAME:
385 memcpy(sysInfoParams.sys_name, &req[1], SIZE_SYS_NAME);
386 break;
387 case SYS_INFO_PARAM_PRI_OS_NAME:
388 memcpy(sysInfoParams.pri_os_name, &req[1], SIZE_OS_NAME);
389 break;
390 case SYS_INFO_PARAM_PRESENT_OS_NAME:
391 memcpy(sysInfoParams.present_os_name, &req[1], SIZE_OS_NAME);
392 break;
393 case SYS_INFO_PARAM_PRESENT_OS_VER:
394 memcpy(sysInfoParams.present_os_ver, &req[1], SIZE_OS_VER);
395 break;
396 case SYS_INFO_PARAM_BMC_URL:
397 memcpy(sysInfoParams.bmc_url, &req[1], SIZE_BMC_URL);
398 break;
399 case SYS_INFO_PARAM_OS_HV_URL:
400 memcpy(sysInfoParams.os_hv_url, &req[1], SIZE_OS_HV_URL);
401 break;
402 case SYS_INFO_PARAM_BIOS_CURRENT_BOOT_LIST:
403 memcpy(sysInfoParams.bios_current_boot_list, &req[1], req_len);
404 appData[KEY_BIOS_BOOT_LEN] = req_len;
405 flush_app_data();
406 break;
407 case SYS_INFO_PARAM_BIOS_FIXED_BOOT_DEVICE:
408 if (SIZE_BIOS_FIXED_BOOT_DEVICE != req_len)
409 break;
410 memcpy(sysInfoParams.bios_fixed_boot_device, &req[1],
411 SIZE_BIOS_FIXED_BOOT_DEVICE);
412 break;
413 case SYS_INFO_PARAM_BIOS_RSTR_DFLT_SETTING:
414 if (SIZE_BIOS_RSTR_DFLT_SETTING != req_len)
415 break;
416 memcpy(sysInfoParams.bios_rstr_dflt_setting, &req[1],
417 SIZE_BIOS_RSTR_DFLT_SETTING);
418 break;
419 case SYS_INFO_PARAM_LAST_BOOT_TIME:
420 if (SIZE_LAST_BOOT_TIME != req_len)
421 break;
422 memcpy(sysInfoParams.last_boot_time, &req[1], SIZE_LAST_BOOT_TIME);
423 break;
424 default:
Bonnie Loe9baaff2022-11-08 16:36:21 +0800425 return ipmi::responseSystemInfoParamterNotSupportCommand();
Vijay Khemka666a4d92019-04-03 11:27:24 -0700426 break;
427 }
428
Bonnie Loe9baaff2022-11-08 16:36:21 +0800429 return ipmi::responseSuccess();
Vijay Khemka666a4d92019-04-03 11:27:24 -0700430}
431
432//----------------------------------------------------------------------
433// Get Sys Info Params (IPMI/Sec 22.14b) (CMD_APP_GET_SYS_INFO_PARAMS)
434//----------------------------------------------------------------------
Patrick Williams010dee02024-08-16 15:19:44 -0400435ipmi::RspType<std::vector<uint8_t>> ipmiAppGetSysInfoParams(
436 ipmi::Context::ptr ctx, uint8_t, uint8_t param, uint8_t, uint8_t)
Vijay Khemka666a4d92019-04-03 11:27:24 -0700437{
Willy Tue39f9392022-06-15 13:24:20 -0700438 int len;
Bonnie Loe9baaff2022-11-08 16:36:21 +0800439 std::vector<uint8_t> respData;
440 respData.push_back(1); // Parameter revision
Vijay Khemka666a4d92019-04-03 11:27:24 -0700441
Bonnie Loe9baaff2022-11-08 16:36:21 +0800442 std::optional<size_t> hostId = findHost(ctx->hostIdx);
443
444 if (!hostId)
445 {
446 phosphor::logging::log<phosphor::logging::level::ERR>(
447 "Invalid Host Id received");
448 return ipmi::responseInvalidCommand();
449 }
Vijay Khemka666a4d92019-04-03 11:27:24 -0700450
451 switch (param)
452 {
453 case SYS_INFO_PARAM_SET_IN_PROG:
Bonnie Loe9baaff2022-11-08 16:36:21 +0800454 respData.push_back(sysInfoParams.set_in_prog);
Vijay Khemka666a4d92019-04-03 11:27:24 -0700455 break;
456 case SYS_INFO_PARAM_SYSFW_VER:
Bonnie Loe9baaff2022-11-08 16:36:21 +0800457 {
Kevin Tunge4e18ca2025-06-05 10:21:23 +0800458 if ((platGetSysFWVer(respData, *hostId)) < 0)
Bonnie Loe9baaff2022-11-08 16:36:21 +0800459 return ipmi::responseSystemInfoParamterNotSupportCommand();
Vijay Khemka666a4d92019-04-03 11:27:24 -0700460 break;
Bonnie Loe9baaff2022-11-08 16:36:21 +0800461 }
Vijay Khemka666a4d92019-04-03 11:27:24 -0700462 case SYS_INFO_PARAM_SYS_NAME:
Bonnie Loe9baaff2022-11-08 16:36:21 +0800463 respData.insert(respData.end(), std::begin(sysInfoParams.sys_name),
464 std::end(sysInfoParams.sys_name));
Vijay Khemka666a4d92019-04-03 11:27:24 -0700465 break;
466 case SYS_INFO_PARAM_PRI_OS_NAME:
Bonnie Loe9baaff2022-11-08 16:36:21 +0800467 respData.insert(respData.end(),
468 std::begin(sysInfoParams.pri_os_name),
469 std::end(sysInfoParams.pri_os_name));
Vijay Khemka666a4d92019-04-03 11:27:24 -0700470 break;
471 case SYS_INFO_PARAM_PRESENT_OS_NAME:
Bonnie Loe9baaff2022-11-08 16:36:21 +0800472 respData.insert(respData.end(),
473 std::begin(sysInfoParams.present_os_name),
474 std::end(sysInfoParams.present_os_name));
Vijay Khemka666a4d92019-04-03 11:27:24 -0700475 break;
476 case SYS_INFO_PARAM_PRESENT_OS_VER:
Bonnie Loe9baaff2022-11-08 16:36:21 +0800477 respData.insert(respData.end(),
478 std::begin(sysInfoParams.present_os_ver),
479 std::end(sysInfoParams.present_os_ver));
Vijay Khemka666a4d92019-04-03 11:27:24 -0700480 break;
481 case SYS_INFO_PARAM_BMC_URL:
Bonnie Loe9baaff2022-11-08 16:36:21 +0800482 respData.insert(respData.end(), std::begin(sysInfoParams.bmc_url),
483 std::end(sysInfoParams.bmc_url));
Vijay Khemka666a4d92019-04-03 11:27:24 -0700484 break;
485 case SYS_INFO_PARAM_OS_HV_URL:
Bonnie Loe9baaff2022-11-08 16:36:21 +0800486 respData.insert(respData.end(), std::begin(sysInfoParams.os_hv_url),
487 std::end(sysInfoParams.os_hv_url));
Vijay Khemka666a4d92019-04-03 11:27:24 -0700488 break;
489 case SYS_INFO_PARAM_BIOS_CURRENT_BOOT_LIST:
490 len = appData[KEY_BIOS_BOOT_LEN].get<uint8_t>();
Patrick Williams010dee02024-08-16 15:19:44 -0400491 respData.insert(
492 respData.end(),
493 std::begin(sysInfoParams.bios_current_boot_list),
494 std::begin(sysInfoParams.bios_current_boot_list) + len);
Vijay Khemka666a4d92019-04-03 11:27:24 -0700495 break;
496 case SYS_INFO_PARAM_BIOS_FIXED_BOOT_DEVICE:
Bonnie Loe9baaff2022-11-08 16:36:21 +0800497 respData.insert(respData.end(),
498 std::begin(sysInfoParams.bios_fixed_boot_device),
499 std::end(sysInfoParams.bios_fixed_boot_device));
Vijay Khemka666a4d92019-04-03 11:27:24 -0700500 break;
501 case SYS_INFO_PARAM_BIOS_RSTR_DFLT_SETTING:
Bonnie Loe9baaff2022-11-08 16:36:21 +0800502 respData.insert(respData.end(),
503 std::begin(sysInfoParams.bios_rstr_dflt_setting),
504 std::end(sysInfoParams.bios_rstr_dflt_setting));
Vijay Khemka666a4d92019-04-03 11:27:24 -0700505 break;
506 case SYS_INFO_PARAM_LAST_BOOT_TIME:
Bonnie Loe9baaff2022-11-08 16:36:21 +0800507 respData.insert(respData.end(),
508 std::begin(sysInfoParams.last_boot_time),
509 std::end(sysInfoParams.last_boot_time));
Vijay Khemka666a4d92019-04-03 11:27:24 -0700510 break;
511 default:
Bonnie Loe9baaff2022-11-08 16:36:21 +0800512 return ipmi::responseSystemInfoParamterNotSupportCommand();
Vijay Khemka666a4d92019-04-03 11:27:24 -0700513 break;
514 }
Bonnie Loe9baaff2022-11-08 16:36:21 +0800515
516 return ipmi::responseSuccess(respData);
Vijay Khemka666a4d92019-04-03 11:27:24 -0700517}
518
Vijay Khemkaa2d52f12019-03-27 14:54:00 -0700519void registerAPPFunctions()
520{
Vijay Khemka666a4d92019-04-03 11:27:24 -0700521 /* Get App data stored in json file */
Vijay Khemka802ccb12019-08-27 15:03:44 -0700522 std::ifstream file(JSON_APP_DATA_FILE);
Vijay Khemka666a4d92019-04-03 11:27:24 -0700523 if (file)
Vijay Khemka802ccb12019-08-27 15:03:44 -0700524 {
Vijay Khemka666a4d92019-04-03 11:27:24 -0700525 file >> appData;
Vijay Khemka802ccb12019-08-27 15:03:44 -0700526 file.close();
527 }
Vijay Khemka666a4d92019-04-03 11:27:24 -0700528
George Liu0821a2e2025-04-03 10:12:10 +0800529 ipmiPrintAndRegister(ipmi::netFnApp, CMD_APP_GET_SELFTEST_RESULTS, NULL,
Vijay Khemka666a4d92019-04-03 11:27:24 -0700530 ipmiAppGetSTResults,
531 PRIVILEGE_USER); // Get Self Test Results
George Liu0821a2e2025-04-03 10:12:10 +0800532 ipmiPrintAndRegister(ipmi::netFnApp, CMD_APP_MFR_TEST_ON, NULL,
Vijay Khemka666a4d92019-04-03 11:27:24 -0700533 ipmiAppMfrTestOn,
534 PRIVILEGE_USER); // Manufacturing Test On
George Liu0821a2e2025-04-03 10:12:10 +0800535 ipmiPrintAndRegister(ipmi::netFnApp, CMD_APP_SET_GLOBAL_ENABLES, NULL,
Vijay Khemkaa2d52f12019-03-27 14:54:00 -0700536 ipmiAppSetGlobalEnables,
Vijay Khemka666a4d92019-04-03 11:27:24 -0700537 PRIVILEGE_USER); // Set Global Enables
George Liu0821a2e2025-04-03 10:12:10 +0800538 ipmiPrintAndRegister(ipmi::netFnApp, CMD_APP_GET_GLOBAL_ENABLES, NULL,
Vijay Khemkaa2d52f12019-03-27 14:54:00 -0700539 ipmiAppGetGlobalEnables,
540 PRIVILEGE_USER); // Get Global Enables
George Liu0821a2e2025-04-03 10:12:10 +0800541 ipmiPrintAndRegister(ipmi::netFnApp, CMD_APP_CLEAR_MESSAGE_FLAGS, NULL,
Vijay Khemka666a4d92019-04-03 11:27:24 -0700542 ipmiAppClearMsgFlags,
543 PRIVILEGE_USER); // Clear Message flags
Manikandan Elumalai5f8e3432020-12-02 03:46:55 +0530544#if BIC_ENABLED
545 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
546 ipmi::app::cmdGetSystemGuid, ipmi::Privilege::User,
547 ipmiAppGetSysGUID);
548#else
George Liu0821a2e2025-04-03 10:12:10 +0800549 ipmiPrintAndRegister(ipmi::netFnApp, CMD_APP_GET_SYS_GUID, NULL,
Vijay Khemkaa2d52f12019-03-27 14:54:00 -0700550 ipmiAppGetSysGUID,
551 PRIVILEGE_USER); // Get System GUID
Manikandan Elumalai5f8e3432020-12-02 03:46:55 +0530552#endif
Bonnie Loe9baaff2022-11-08 16:36:21 +0800553 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
554 ipmi::app::cmdSetSystemInfoParameters,
555 ipmi::Privilege::User, ipmiAppSetSysInfoParams);
556
557 ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
558 ipmi::app::cmdGetSystemInfoParameters,
559 ipmi::Privilege::User, ipmiAppGetSysInfoParams);
Vijay Khemkaa2d52f12019-03-27 14:54:00 -0700560 return;
561}
562
563} // namespace ipmi