blob: 78fff8547e1a0ba8a368224483ca9b41bb539588 [file] [log] [blame]
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001/*
2 * Copyright (c) 2018-present Facebook. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Jayashree Dhanapal4ec80562022-06-28 15:41:47 +053017#include <commandutils.hpp>
Patrick Williams2405ae92023-05-10 07:50:09 -050018#include <usb-dbg.hpp>
Vijay Khemkae7d23d02019-03-08 13:13:40 -080019
20namespace ipmi
21{
22
Vijay Khemka63c99be2020-05-27 19:14:35 -070023ipmi_ret_t getNetworkData(uint8_t lan_param, char* data);
Daniel Hsud8d95a32024-05-27 16:05:25 +080024std::string getMotherBoardFruName();
Vijay Khemka63c99be2020-05-27 19:14:35 -070025int8_t getFruData(std::string& serial, std::string& name);
Karthikeyan Pasupathi10ff3d82022-04-06 16:27:25 +053026int8_t sysConfig(std::vector<std::string>& data, size_t pos);
Karthikeyan Pasupathid532fec2022-07-14 14:43:42 +053027int8_t procInfo(std::string& result, size_t pos);
Vijay Khemkae7d23d02019-03-08 13:13:40 -080028
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +053029bool isMultiHostPlatform();
30
31/* Declare Host Selector interface and path */
32namespace selector
33{
34const std::string path = "/xyz/openbmc_project/Chassis/Buttons/HostSelector";
35const std::string interface =
Potin Laicff150e2022-09-19 09:34:57 +080036 "xyz.openbmc_project.Chassis.Buttons.HostSelector";
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +053037} // namespace selector
38
Vijay Khemka427b2762019-12-12 12:49:25 -080039/* Declare storage functions used here */
40namespace storage
41{
Vijay Khemka63c99be2020-05-27 19:14:35 -070042int getSensorValue(std::string&, double&);
43int getSensorUnit(std::string&, std::string&);
Delphine CC Chiu2ca4aa02023-02-01 16:30:18 +080044int getSensorThreshold(std::string&, std::string&);
Vijay Khemka58bd5d82019-12-13 11:05:56 -080045} // namespace storage
Vijay Khemka427b2762019-12-12 12:49:25 -080046
Delphine CC Chiu7bb45922023-04-10 13:34:04 +080047namespace boot
48{
49std::tuple<std::string, std::string> objPath(size_t id);
50void setBootOrder(std::string bootObjPath, const std::vector<uint8_t>& bootSeq,
51 std::string hostName);
52void getBootOrder(std::string bootObjPath, std::vector<uint8_t>& bootSeq,
53 std::string hostName);
54} // namespace boot
55
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +053056void getMaxHostPosition(size_t& maxPosition)
Potin Laif24c78e2022-10-27 17:13:14 +080057{
58 try
59 {
60 std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
Patrick Williams010dee02024-08-16 15:19:44 -040061 std::string service =
62 getService(*dbus, ipmi::selector::interface, ipmi::selector::path);
63 Value variant =
64 getDbusProperty(*dbus, service, ipmi::selector::path,
65 ipmi::selector::interface, "MaxPosition");
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +053066 maxPosition = std::get<size_t>(variant);
Potin Laif24c78e2022-10-27 17:13:14 +080067 }
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +053068 catch (const std::exception& e)
Potin Laif24c78e2022-10-27 17:13:14 +080069 {
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +053070 lg2::error("Unable to get max host position - {MAXPOSITION}",
71 "MAXPOSITION", maxPosition);
72 throw e;
Potin Laif24c78e2022-10-27 17:13:14 +080073 }
Potin Laif24c78e2022-10-27 17:13:14 +080074}
75
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +053076void getSelectorPosition(size_t& hostPosition)
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +053077{
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +053078 try
79 {
80 std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
Patrick Williams010dee02024-08-16 15:19:44 -040081 std::string service =
82 getService(*dbus, ipmi::selector::interface, ipmi::selector::path);
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +053083 Value variant = getDbusProperty(*dbus, service, ipmi::selector::path,
84 ipmi::selector::interface, "Position");
85 hostPosition = std::get<size_t>(variant);
86 }
87 catch (const std::exception& e)
88 {
89 lg2::error("Unable to get host position - {POSITION}", "POSITION",
90 hostPosition);
91 throw e;
92 }
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +053093}
94
Vijay Khemkae7d23d02019-03-08 13:13:40 -080095static int panelNum = (sizeof(panels) / sizeof(struct ctrl_panel)) - 1;
96
97/* Returns the FRU the hand-switch is switched to. If it is switched to BMC
98 * it returns FRU_ALL. Note, if in err, it returns FRU_ALL */
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +053099static size_t plat_get_fru_sel()
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800100{
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +0530101 size_t position;
102 bool platform = isMultiHostPlatform();
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +0530103 if (platform == true)
104 {
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +0530105 getSelectorPosition(position);
106 if (position == BMC_POSITION)
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +0530107 {
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +0530108 return FRU_ALL;
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +0530109 }
110 }
111 else
112 {
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +0530113 /* For Tiogapass it just return 1,
114 * can modify to support more platform */
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +0530115 position = 1;
116 }
117 return position;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800118}
119
120// return 0 on seccuess
Patrick Williams13ce3792024-08-27 13:03:46 -0400121void frame::init(size_t size)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800122{
123 // Reset status
124 idx_head = idx_tail = 0;
125 lines = 0;
126 esc_sts = 0;
127 pages = 1;
128
Patrick Williams13ce3792024-08-27 13:03:46 -0400129 if (buf != nullptr && max_size == size)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800130 {
Patrick Williams13ce3792024-08-27 13:03:46 -0400131 return;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800132 }
133
Patrick Williams13ce3792024-08-27 13:03:46 -0400134 if (buf != nullptr && max_size != size)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800135 {
136 delete[] buf;
137 }
138 // Initialize Configuration
139 title[0] = '\0';
140 buf = new char[size];
141 max_size = size;
142 max_page = size;
143 line_per_page = 7;
144 line_width = 16;
Patrick Williams13ce3792024-08-27 13:03:46 -0400145 overwrite = false;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800146
Patrick Williams13ce3792024-08-27 13:03:46 -0400147 return;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800148}
149
150// return 0 on seccuess
Patrick Williams13ce3792024-08-27 13:03:46 -0400151void frame::append(const std::string& str, size_t indent)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800152{
Patrick Williams13ce3792024-08-27 13:03:46 -0400153 for (auto ch : parse(str, indent))
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800154 {
155 if (isFull())
156 {
157 if (overwrite)
158 {
159 if (buf[idx_head] == LINE_DELIMITER)
160 lines--;
161 idx_head = (idx_head + 1) % max_size;
162 }
163 else
Patrick Williams13ce3792024-08-27 13:03:46 -0400164 {
165 throw std::overflow_error("No room in buffer");
166 }
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800167 }
168
Patrick Williams13ce3792024-08-27 13:03:46 -0400169 buf[idx_tail] = ch;
170 if (ch == LINE_DELIMITER)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800171 lines++;
172
173 idx_tail = (idx_tail + 1) % max_size;
174 }
175
176 pages = (lines / line_per_page) + ((lines % line_per_page) ? 1 : 0);
177
178 if (pages > max_page)
179 pages = max_page;
180
Patrick Williams13ce3792024-08-27 13:03:46 -0400181 return;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800182}
183
184// return page size
Patrick Williams13ce3792024-08-27 13:03:46 -0400185int frame::getPage(size_t page, char* page_buf, size_t page_buf_size)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800186{
187 int ret;
188 uint16_t line = 0;
189 uint16_t idx, len;
190
Patrick Williams13ce3792024-08-27 13:03:46 -0400191 if (buf == nullptr)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800192 return -1;
193
194 // 1-based page
195 if (page > pages || page < 1)
196 return -1;
197
Patrick Williams13ce3792024-08-27 13:03:46 -0400198 if (page_buf == nullptr || page_buf_size == 0)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800199 return -1;
200
Patrick Williams13ce3792024-08-27 13:03:46 -0400201 ret = snprintf(page_buf, 17, "%-10s %02zd/%02zd", title, page, pages);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800202 len = strlen(page_buf);
203 if (ret < 0)
204 return -1;
205
206 line = 0;
207 idx = idx_head;
208 while (line < ((page - 1) * line_per_page) && idx != idx_tail)
209 {
210 if (buf[idx] == LINE_DELIMITER)
211 line++;
212 idx = (idx + 1) % max_size;
213 }
214
215 while (line < ((page)*line_per_page) && idx != idx_tail)
216 {
217 if (buf[idx] == LINE_DELIMITER)
218 {
219 line++;
220 }
221 else
222 {
223 page_buf[len++] = buf[idx];
224 if (len == (page_buf_size - 1))
225 {
226 break;
227 }
228 }
229 idx = (idx + 1) % max_size;
230 }
231
232 return len;
233}
234
Patrick Williams13ce3792024-08-27 13:03:46 -0400235bool frame::isFull() const
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800236{
Patrick Williams13ce3792024-08-27 13:03:46 -0400237 if (buf == nullptr)
238 return true;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800239
240 if ((idx_tail + 1) % max_size == idx_head)
Patrick Williams13ce3792024-08-27 13:03:46 -0400241 return true;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800242 else
Patrick Williams13ce3792024-08-27 13:03:46 -0400243 return false;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800244}
245
246// return 1 for Escape Sequence
Patrick Williams13ce3792024-08-27 13:03:46 -0400247bool frame::isEscSeq(char chr)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800248{
249 uint8_t curr_sts = esc_sts;
250
251 if (esc_sts == 0 && (chr == 0x1b))
252 esc_sts = 1; // Escape Sequence
253 else if (esc_sts == 1 && (chr == 0x5b))
254 esc_sts = 2; // Control Sequence Introducer(CSI)
255 else if (esc_sts == 1 && (chr != 0x5b))
256 esc_sts = 0;
257 else if (esc_sts == 2 && (chr >= 0x40 && chr <= 0x7e))
258 esc_sts = 0;
259
260 if (curr_sts || esc_sts)
Patrick Williams13ce3792024-08-27 13:03:46 -0400261 return true;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800262 else
Patrick Williams13ce3792024-08-27 13:03:46 -0400263 return false;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800264}
265
266// return 0 on success
Patrick Williams13ce3792024-08-27 13:03:46 -0400267auto frame::parse(const std::string& input, size_t indent) -> std::string
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800268{
Patrick Williams13ce3792024-08-27 13:03:46 -0400269 if (indent > line_width)
270 return {};
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800271
Patrick Williams13ce3792024-08-27 13:03:46 -0400272 std::string result;
273 size_t linepos = 0;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800274
Patrick Williams13ce3792024-08-27 13:03:46 -0400275 for (auto ch : input)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800276 {
Cosmo Chou6c02bfb2024-08-29 15:49:42 +0800277 if (linepos == 0)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800278 {
Patrick Williams13ce3792024-08-27 13:03:46 -0400279 result.append(indent, ' ');
280 linepos = indent;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800281 }
282
Patrick Williams13ce3792024-08-27 13:03:46 -0400283 // Insert character.
284 result.push_back(ch);
Cosmo Chou6c02bfb2024-08-29 15:49:42 +0800285
286 if (!isEscSeq(ch))
287 {
288 // Check if new line is needed.
289 if (++linepos == line_width)
290 {
291 result.push_back(LINE_DELIMITER);
292 linepos = 0;
293 }
294 }
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800295 }
296
Patrick Williams13ce3792024-08-27 13:03:46 -0400297 // Fill out remaining line.
298 result.append(line_width - linepos, ' ');
299 result.push_back(LINE_DELIMITER);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800300
Patrick Williams13ce3792024-08-27 13:03:46 -0400301 return result;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800302}
303
Vijay Khemka63c99be2020-05-27 19:14:35 -0700304static int chk_cri_sel_update(uint8_t* cri_sel_up)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800305{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700306 FILE* fp;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800307 struct stat file_stat;
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +0530308 size_t pos = plat_get_fru_sel();
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800309 static uint8_t pre_pos = 0xff;
310
311 fp = fopen("/mnt/data/cri_sel", "r");
312 if (fp)
313 {
314 if ((stat("/mnt/data/cri_sel", &file_stat) == 0) &&
315 (file_stat.st_mtime != frame_sel.mtime || pre_pos != pos))
316 {
317 *cri_sel_up = 1;
318 }
319 else
320 {
321 *cri_sel_up = 0;
322 }
323 fclose(fp);
324 }
325 else
326 {
Patrick Williams13ce3792024-08-27 13:03:46 -0400327 if (frame_sel.buf == nullptr || frame_sel.lines != 0 || pre_pos != pos)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800328 {
329 *cri_sel_up = 1;
330 }
331 else
332 {
333 *cri_sel_up = 0;
334 }
335 }
336 pre_pos = pos;
337 return 0;
338}
339
Vijay Khemka63c99be2020-05-27 19:14:35 -0700340int plat_udbg_get_frame_info(uint8_t* num)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800341{
342 *num = 3;
343 return 0;
344}
345
Vijay Khemka63c99be2020-05-27 19:14:35 -0700346int plat_udbg_get_updated_frames(uint8_t* count, uint8_t* buffer)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800347{
348 uint8_t cri_sel_up = 0;
349 uint8_t info_page_up = 1;
350
351 *count = 0;
352
353 // info page update
354 if (info_page_up == 1)
355 {
356 buffer[*count] = 1;
357 *count += 1;
358 }
359
360 // cri sel update
361 chk_cri_sel_update(&cri_sel_up);
362 if (cri_sel_up == 1)
363 {
364 buffer[*count] = 2;
365 *count += 1;
366 }
367
368 // cri sensor update
369 buffer[*count] = 3;
370 *count += 1;
371
372 return 0;
373}
374
Vijay Khemka63c99be2020-05-27 19:14:35 -0700375int plat_udbg_get_post_desc(uint8_t index, uint8_t* next, uint8_t phase,
376 uint8_t* end, uint8_t* length, uint8_t* buffer)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800377{
Vijay Khemkacc0d6d92019-08-27 14:51:17 -0700378 nlohmann::json postObj;
379 std::string postCode;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800380
Vijay Khemkacc0d6d92019-08-27 14:51:17 -0700381 /* Get post description data stored in json file */
382 std::ifstream file(JSON_POST_DATA_FILE);
383 if (file)
384 {
385 file >> postObj;
386 file.close();
387 }
388 else
389 {
390 phosphor::logging::log<phosphor::logging::level::ERR>(
391 "Post code description file not found",
392 phosphor::logging::entry("POST_CODE_FILE=%s", JSON_POST_DATA_FILE));
393 return -1;
394 }
395
396 std::string phaseStr = "PhaseAny";
397 if (postObj.find(phaseStr) == postObj.end())
398 {
399 phaseStr = "Phase" + std::to_string(phase);
400 }
401
402 if (postObj.find(phaseStr) == postObj.end())
403 {
404 phosphor::logging::log<phosphor::logging::level::ERR>(
405 "Post code phase not available",
406 phosphor::logging::entry("PHASE=%d", phase));
407 return -1;
408 }
409
410 auto phaseObj = postObj[phaseStr];
411 int phaseSize = phaseObj.size();
412
413 for (int i = 0; i < phaseSize; i++)
414 {
415 postCode = phaseObj[i][0];
416 if (index == stoul(postCode, nullptr, 16))
417 {
418 std::string postDesc = phaseObj[i][1];
419 *length = postDesc.size();
420 memcpy(buffer, postDesc.data(), *length);
421 buffer[*length] = '\0';
422
423 if (phaseSize != i + 1)
424 {
425 postCode = phaseObj[i + 1][0];
426 *next = stoul(postCode, nullptr, 16);
427 *end = 0;
428 }
429 else
430 {
431 if (postObj.size() != phase)
432 {
Patrick Williams010dee02024-08-16 15:19:44 -0400433 std::string nextPhaseStr =
434 "Phase" + std::to_string(phase + 1);
Vijay Khemkacc0d6d92019-08-27 14:51:17 -0700435 postCode = postObj[nextPhaseStr][0][0];
436 *next = stoul(postCode, nullptr, 16);
437 *end = 0;
438 }
439 else
440 {
441 *next = 0xff;
442 *end = 1;
443 }
444 }
445
446 return 0;
447 }
448 }
449
450 phosphor::logging::log<phosphor::logging::level::ERR>(
451 "Post code description data not available",
452 phosphor::logging::entry("PHASE_CODE=%d_0x%x", phase, index));
453 return -1;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800454}
455
Vijay Khemka63c99be2020-05-27 19:14:35 -0700456int plat_udbg_get_gpio_desc(uint8_t index, uint8_t* next, uint8_t* level,
457 uint8_t* def, uint8_t* length, uint8_t* buffer)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800458{
Vijay Khemka38183d62019-08-28 16:19:33 -0700459 nlohmann::json gpioObj;
460 std::string gpioPin;
461
462 /* Get gpio data stored in json file */
463 std::ifstream file(JSON_GPIO_DATA_FILE);
464 if (file)
465 {
466 file >> gpioObj;
467 file.close();
468 }
469 else
470 {
471 phosphor::logging::log<phosphor::logging::level::ERR>(
472 "GPIO pin description file not found",
473 phosphor::logging::entry("GPIO_PIN_DETAILS_FILE=%s",
474 JSON_GPIO_DATA_FILE));
475 return -1;
476 }
477
478 if (gpioObj.find(DEBUG_GPIO_KEY) == gpioObj.end())
479 {
480 phosphor::logging::log<phosphor::logging::level::ERR>(
481 "GPIO pin details not available",
482 phosphor::logging::entry("GPIO_JSON_KEY=%d", DEBUG_GPIO_KEY));
483 return -1;
484 }
485
486 auto obj = gpioObj[DEBUG_GPIO_KEY];
487 int objSize = obj.size();
488
489 for (int i = 0; i < objSize; i++)
490 {
491 if (obj[i].size() != GPIO_ARRAY_SIZE)
492 {
493 phosphor::logging::log<phosphor::logging::level::ERR>(
494 "Size of gpio array is incorrect",
495 phosphor::logging::entry("EXPECTED_SIZE=%d", GPIO_ARRAY_SIZE));
496 return -1;
497 }
498
499 gpioPin = obj[i][GPIO_PIN_INDEX];
500 if (index == stoul(gpioPin, nullptr, 16))
501 {
502 if (objSize != i + 1)
503 {
504 gpioPin = obj[i + 1][GPIO_PIN_INDEX];
505 *next = stoul(gpioPin, nullptr, 16);
506 }
507 else
508 {
509 *next = 0xff;
510 }
511
512 *level = obj[i][GPIO_LEVEL_INDEX];
513 *def = obj[i][GPIO_DEF_INDEX];
514 std::string gpioDesc = obj[i][GPIO_DESC_INDEX];
515 *length = gpioDesc.size();
516 memcpy(buffer, gpioDesc.data(), *length);
517 buffer[*length] = '\0';
518
519 return 0;
520 }
521 }
522
523 phosphor::logging::log<phosphor::logging::level::ERR>(
524 "GPIO pin description data not available",
525 phosphor::logging::entry("GPIO_PIN=0x%x", index));
526 return -1;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800527}
528
Bonnie Loe9baaff2022-11-08 16:36:21 +0800529static int getBiosVer(std::string& ver, size_t hostPosition)
Vijay Khemka88884b82019-08-27 15:23:07 -0700530{
531 nlohmann::json appObj;
532
533 std::ifstream file(JSON_APP_DATA_FILE);
534 if (file)
535 {
536 file >> appObj;
537 file.close();
Bonnie Loe9baaff2022-11-08 16:36:21 +0800538 std::string version_key = KEY_SYSFW_VER + std::to_string(hostPosition);
539
540 if (appObj.find(version_key) != appObj.end())
Vijay Khemka88884b82019-08-27 15:23:07 -0700541 {
Bonnie Loe9baaff2022-11-08 16:36:21 +0800542 ver = appObj[version_key].get<std::string>();
Vijay Khemka88884b82019-08-27 15:23:07 -0700543 return 0;
544 }
545 }
546
547 return -1;
548}
549
Manikandan Elumalai5f8e3432020-12-02 03:46:55 +0530550int sendBicCmd(uint8_t netFn, uint8_t cmd, uint8_t bicAddr,
551 std::vector<uint8_t>& cmdData, std::vector<uint8_t>& respData)
552{
553 static constexpr uint8_t lun = 0;
554
555 auto bus = getSdBus();
556
557 auto method = bus->new_method_call("xyz.openbmc_project.Ipmi.Channel.Ipmb",
558 "/xyz/openbmc_project/Ipmi/Channel/Ipmb",
559 "org.openbmc.Ipmb", "sendRequest");
560 method.append(bicAddr, netFn, lun, cmd, cmdData);
561
562 auto reply = bus->call(method);
563 if (reply.is_method_error())
564 {
565 phosphor::logging::log<phosphor::logging::level::ERR>(
566 "Error reading from BIC");
567 return -1;
568 }
569
570 IpmbMethodType resp;
571 reply.read(resp);
572
573 respData =
574 std::move(std::get<std::remove_reference_t<decltype(respData)>>(resp));
575
576 return 0;
577}
578
Vijay Khemka63c99be2020-05-27 19:14:35 -0700579int sendMeCmd(uint8_t netFn, uint8_t cmd, std::vector<uint8_t>& cmdData,
580 std::vector<uint8_t>& respData)
Vijay Khemkadd14c0f2020-03-18 14:48:13 -0700581{
582 auto bus = getSdBus();
583
584 if (DEBUG)
585 {
586 std::cout << "ME NetFn:cmd " << (int)netFn << ":" << (int)cmd << "\n";
587 std::cout << "ME req data: ";
588 for (auto d : cmdData)
589 {
590 std::cout << d << " ";
591 }
592 std::cout << "\n";
593 }
594
595 auto method = bus->new_method_call("xyz.openbmc_project.Ipmi.Channel.Ipmb",
596 "/xyz/openbmc_project/Ipmi/Channel/Ipmb",
597 "org.openbmc.Ipmb", "sendRequest");
598 method.append(meAddress, netFn, lun, cmd, cmdData);
599
600 auto reply = bus->call(method);
601 if (reply.is_method_error())
602 {
603 phosphor::logging::log<phosphor::logging::level::ERR>(
604 "Error reading from ME");
605 return -1;
606 }
607
608 IpmbMethodType resp;
609 reply.read(resp);
610
611 respData =
612 std::move(std::get<std::remove_reference_t<decltype(respData)>>(resp));
613
614 if (DEBUG)
615 {
616 std::cout << "ME resp data: ";
617 for (auto d : respData)
618 {
619 std::cout << d << " ";
620 }
621 std::cout << "\n";
622 }
623
624 return 0;
625}
626
Willy Tue39f9392022-06-15 13:24:20 -0700627static int udbg_get_info_page(uint8_t, uint8_t page, uint8_t* next,
Vijay Khemka63c99be2020-05-27 19:14:35 -0700628 uint8_t* count, uint8_t* buffer)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800629{
Willy Tue39f9392022-06-15 13:24:20 -0700630 char line_buff[1000];
631 [[maybe_unused]] char* pres_dev = line_buff;
632 [[maybe_unused]] size_t pos = plat_get_fru_sel();
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800633 int ret;
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530634 std::string serialName = "SerialNumber";
635 std::string partName = "PartNumber";
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800636 std::string verDel = "VERSION=";
637 std::string verPath = "/etc/os-release";
BonnieLo-wiwynn21a79232023-03-09 16:42:48 +0800638 size_t hostPosition = 0;
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +0530639 size_t maxPosition;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800640
641 if (page == 1)
642 {
643 // Only update frame data while getting page 1
644
645 // initialize and clear frame
Patrick Williams13ce3792024-08-27 13:03:46 -0400646 frame_info.init();
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800647 snprintf(frame_info.title, 32, "SYS_Info");
648
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530649 bool platform = isMultiHostPlatform();
650 if (platform == true)
651 {
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +0530652 hostPosition = plat_get_fru_sel();
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530653 }
654
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +0530655 getMaxHostPosition(maxPosition);
Jayashree Dhanapal4ec80562022-06-28 15:41:47 +0530656 if (hostPosition == BMC_POSITION || hostInstances == "0")
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530657 {
Daniel Hsud8d95a32024-05-27 16:05:25 +0800658 std::string data = "FRU:" + getMotherBoardFruName();
659 frame_info.append(data);
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530660 }
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +0530661 else if (hostPosition != BMC_POSITION && hostPosition <= maxPosition)
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530662 {
663 std::string data = "FRU:slot" + std::to_string(hostPosition);
Patrick Williams13ce3792024-08-27 13:03:46 -0400664 frame_info.append(data);
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530665 }
666
667 // FRU
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800668 std::string data;
Patrick Williams13ce3792024-08-27 13:03:46 -0400669 frame_info.append("SN:");
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800670 if (getFruData(data, serialName) != 0)
671 {
672 data = "Not Found";
673 }
Patrick Williams13ce3792024-08-27 13:03:46 -0400674 frame_info.append(data, 1);
675 frame_info.append("PN:");
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800676 if (getFruData(data, partName) != 0)
677 {
678 data = "Not Found";
679 }
Patrick Williams13ce3792024-08-27 13:03:46 -0400680 frame_info.append(data, 1);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800681
682 // LAN
683 getNetworkData(3, line_buff);
Patrick Williams13ce3792024-08-27 13:03:46 -0400684 frame_info.append("BMC_IP:");
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800685 frame_info.append(line_buff, 1);
686 getNetworkData(59, line_buff);
Patrick Williams13ce3792024-08-27 13:03:46 -0400687 frame_info.append("BMC_IPv6:");
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800688 frame_info.append(line_buff, 1);
689
690 // BMC ver
691 std::ifstream file(verPath);
692 if (file)
693 {
694 std::string line;
695 while (std::getline(file, line))
696 {
697 if (line.find(verDel) != std::string::npos)
698 {
699 std::string bmcVer = line.substr(verDel.size());
Patrick Williams13ce3792024-08-27 13:03:46 -0400700 frame_info.append("BMC_FW_ver:");
701 frame_info.append(bmcVer, 1);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800702 break;
703 }
704 }
705 }
706
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530707 if (hostPosition != BMC_POSITION)
Vijay Khemka88884b82019-08-27 15:23:07 -0700708 {
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530709 // BIOS ver
710 std::string biosVer;
Bonnie Loe9baaff2022-11-08 16:36:21 +0800711 if (getBiosVer(biosVer, hostPosition) == 0)
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530712 {
Patrick Williams13ce3792024-08-27 13:03:46 -0400713 frame_info.append("BIOS_FW_ver:");
714 frame_info.append(biosVer, 1);
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530715 }
Vijay Khemka88884b82019-08-27 15:23:07 -0700716 }
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800717
Vijay Khemka317999d2020-01-02 13:43:42 -0800718 /* TBD: Board ID needs implementation */
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800719 // Board ID
720
721 // Battery - Use Escape sequence
Patrick Williams13ce3792024-08-27 13:03:46 -0400722 frame_info.append("Battery:");
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800723 frame_info.append(ESC_BAT " ", 1);
724 // frame_info.append(&frame_info, esc_bat, 1);
725
726 // MCU Version - Use Escape sequence
Patrick Williams13ce3792024-08-27 13:03:46 -0400727 frame_info.append("MCUbl_ver:");
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800728 frame_info.append(ESC_MCU_BL_VER, 1);
Patrick Williams13ce3792024-08-27 13:03:46 -0400729 frame_info.append("MCU_ver:");
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800730 frame_info.append(ESC_MCU_RUN_VER, 1);
731
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800732 // Sys config present device
Karthikeyan Pasupathi10ff3d82022-04-06 16:27:25 +0530733 if (hostPosition != BMC_POSITION)
734 {
Patrick Williams13ce3792024-08-27 13:03:46 -0400735 frame_info.append("Sys Conf. info:");
Karthikeyan Pasupathi10ff3d82022-04-06 16:27:25 +0530736
737 // Dimm info
738 std::vector<std::string> data;
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +0530739 if (sysConfig(data, pos) == 0)
Karthikeyan Pasupathi10ff3d82022-04-06 16:27:25 +0530740 {
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +0530741 for (auto& info : data)
742 {
Patrick Williams13ce3792024-08-27 13:03:46 -0400743 frame_info.append(info, 1);
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +0530744 }
745 }
746 else
747 {
748 frame_info.append("Not Found", 1);
Karthikeyan Pasupathi10ff3d82022-04-06 16:27:25 +0530749 }
Karthikeyan Pasupathid532fec2022-07-14 14:43:42 +0530750
751 // Processor info
752 std::string result;
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +0530753 if (procInfo(result, pos) != 0)
754 {
755 result = "Not Found";
756 }
Patrick Williams13ce3792024-08-27 13:03:46 -0400757 frame_info.append(result, 1);
Karthikeyan Pasupathi10ff3d82022-04-06 16:27:25 +0530758 }
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800759
760 } // End of update frame
761
762 if (page > frame_info.pages)
763 {
764 return -1;
765 }
766
Vijay Khemka63c99be2020-05-27 19:14:35 -0700767 ret = frame_info.getPage(page, (char*)buffer, FRAME_PAGE_BUF_SIZE);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800768 if (ret < 0)
769 {
770 *count = 0;
771 return -1;
772 }
773 *count = (uint8_t)ret;
774
775 if (page < frame_info.pages)
776 *next = page + 1;
777 else
778 *next = 0xFF; // Set the value of next to 0xFF to indicate this is the
779 // last page
780
781 return 0;
782}
783
Peter Yinb340aa22024-07-08 16:07:55 +0800784static int udbg_get_postcode(uint8_t, uint8_t page, uint8_t* next,
785 uint8_t* count, uint8_t* buffer)
786{
Cosmo Chou5a6917d2024-09-05 23:29:11 +0800787 // up to 70 codes can be displayed on 10 pages
788 static constexpr size_t maxPostcodes = 70;
789
790 static constexpr const char* formatStr =
791 (postCodeSize == 4) ? "{:08X}"
792 : (postCodeSize == 8) ? "{:016X}"
793 : "{:02X}";
794
Peter Yinb340aa22024-07-08 16:07:55 +0800795 if (page == 1)
796 {
797 // Initialize and clear frame (example initialization)
Patrick Williams13ce3792024-08-27 13:03:46 -0400798 frame_postcode.init();
Cosmo Chou5a6917d2024-09-05 23:29:11 +0800799 snprintf(frame_postcode.title, 32, "POST CODE");
800 frame_postcode.max_page = 10;
Peter Yinb340aa22024-07-08 16:07:55 +0800801
802 // Synchronously get D-Bus connection
803 auto bus = sdbusplus::bus::new_default();
804
805 // Build D-Bus method call
806 auto method = bus.new_method_call(
807 "xyz.openbmc_project.State.Boot.PostCode0", // Target service name
808 "/xyz/openbmc_project/State/Boot/PostCode0", // Object path
809 "xyz.openbmc_project.State.Boot.PostCode", // Interface name
810 "GetPostCodes"); // Method name
811
812 method.append(uint16_t(1)); // Add method parameter, assuming it's page
813
814 try
815 {
816 auto reply = bus.call(method); // Send synchronous method call
817
818 // Read postcode value
819 std::vector<std::tuple<uint64_t, std::vector<uint8_t>>> postcodes;
820 reply.read(postcodes);
821
Cosmo Chou5a6917d2024-09-05 23:29:11 +0800822 // retrieve the latest postcodes
823 size_t numEntries = std::min(maxPostcodes, postcodes.size());
824 for (auto it = postcodes.rbegin();
825 it != postcodes.rbegin() + numEntries; ++it)
Peter Yinb340aa22024-07-08 16:07:55 +0800826 {
Cosmo Chou5a6917d2024-09-05 23:29:11 +0800827 const auto& [code, extra] = *it;
828 std::string result = std::format(formatStr, code);
Potin Lai3c9f5b62024-08-28 13:40:37 +0800829 for (const auto& byte : extra)
830 {
Cosmo Chou5a6917d2024-09-05 23:29:11 +0800831 result += std::format("{:02X}", byte);
Potin Lai3c9f5b62024-08-28 13:40:37 +0800832 }
Cosmo Chou5a6917d2024-09-05 23:29:11 +0800833
Patrick Williams13ce3792024-08-27 13:03:46 -0400834 frame_postcode.append(result);
Cosmo Chou5a6917d2024-09-05 23:29:11 +0800835 if (frame_postcode.lines >= maxPostcodes)
836 {
837 break;
838 }
Peter Yinb340aa22024-07-08 16:07:55 +0800839 }
840 }
841 catch (const std::exception& e)
842 {
843 // Handle exceptions
844 std::cerr << "Error retrieving postcodes: " << e.what()
845 << std::endl;
846 return -1;
847 }
848 }
849
850 if (page > frame_postcode.pages)
851 {
852 return -1;
853 }
854
855 int ret = frame_postcode.getPage(page, (char*)buffer, FRAME_PAGE_BUF_SIZE);
856 if (ret < 0)
857 {
858 *count = 0;
859 return -1;
860 }
861 *count = (uint8_t)ret;
862
863 if (page < frame_postcode.pages)
864 *next = page + 1;
865 else
866 *next = 0xFF; // Set next to 0xFF to indicate last page
867 return 0;
868}
869
Vijay Khemka63c99be2020-05-27 19:14:35 -0700870int plat_udbg_get_frame_data(uint8_t frame, uint8_t page, uint8_t* next,
871 uint8_t* count, uint8_t* buffer)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800872{
873 switch (frame)
874 {
875 case 1: // info_page
876 return udbg_get_info_page(frame, page, next, count, buffer);
Peter Yinb340aa22024-07-08 16:07:55 +0800877 case 2: // Extra Post Code
878 return udbg_get_postcode(frame, page, next, count, buffer);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800879 default:
880 return -1;
881 }
882}
883
Patrick Williamsa758d0a2024-08-27 08:35:55 -0400884static panel panel_main(size_t item)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800885{
886 // Update item list when select item 0
887 switch (item)
888 {
889 case 1:
Patrick Williamsa758d0a2024-08-27 08:35:55 -0400890 return panels[std::to_underlying(panel::BOOT_ORDER)].select(0);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800891 case 2:
Patrick Williamsa758d0a2024-08-27 08:35:55 -0400892 return panels[std::to_underlying(panel::POWER_POLICY)].select(0);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800893 default:
Patrick Williamsa758d0a2024-08-27 08:35:55 -0400894 return panel::MAIN;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800895 }
896}
897
Patrick Williamsa758d0a2024-08-27 08:35:55 -0400898static panel panel_boot_order(size_t selectedItemIndex)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800899{
Delphine CC Chiu7bb45922023-04-10 13:34:04 +0800900 static constexpr size_t sizeBootOrder = 6;
901 static constexpr size_t bootValid = 0x80;
902
903 std::vector<uint8_t> bootSeq;
904
Patrick Williamsa758d0a2024-08-27 08:35:55 -0400905 ctrl_panel& bootOrderPanel = panels[std::to_underlying(panel::BOOT_ORDER)];
Delphine CC Chiu7bb45922023-04-10 13:34:04 +0800906
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +0530907 size_t pos = plat_get_fru_sel();
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800908
Delphine CC Chiu7bb45922023-04-10 13:34:04 +0800909 if (pos == FRU_ALL)
910 {
911 bootOrderPanel.item_num = 0;
Patrick Williamsa758d0a2024-08-27 08:35:55 -0400912 return panel::BOOT_ORDER;
Delphine CC Chiu7bb45922023-04-10 13:34:04 +0800913 }
914
915 auto [bootObjPath, hostName] = ipmi::boot::objPath(pos);
916 ipmi::boot::getBootOrder(bootObjPath, bootSeq, hostName);
917
918 uint8_t& bootMode = bootSeq.front();
919
920 // One item is selected to set a new boot sequence.
921 // The selected item become the first boot order.
922 if (selectedItemIndex > 0 && selectedItemIndex < sizeBootOrder)
923 {
924 // Move the selected item to second element (the first one is boot mode)
925 std::rotate(bootSeq.begin() + 1, bootSeq.begin() + selectedItemIndex,
926 bootSeq.begin() + selectedItemIndex + 1);
927
928 bootMode |= bootValid;
929 try
930 {
931 ipmi::boot::setBootOrder(bootObjPath, bootSeq, hostName);
932 }
933 catch (const std::exception& e)
934 {
935 lg2::error("Fail to set boot order : {ERROR}", "ERROR", e);
Willy Tue39f9392022-06-15 13:24:20 -0700936 }
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800937
Delphine CC Chiu7bb45922023-04-10 13:34:04 +0800938 // refresh items
939 return bootOrderPanel.select(0);
940 }
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800941
Delphine CC Chiu7bb45922023-04-10 13:34:04 +0800942 // '*': boot flags valid, BIOS has not yet read
Patrick Williams010dee02024-08-16 15:19:44 -0400943 bootOrderPanel.item_str[0] =
944 std::string("Boot Order") + ((bootMode & bootValid) ? "*" : "");
Delphine CC Chiu7bb45922023-04-10 13:34:04 +0800945
946 static const std::unordered_map<uint8_t, const char*>
947 bootOrderMappingTable = {
948 {0x00, " USB device"}, {0x01, " Network v4"}, {0x02, " SATA HDD"},
949 {0x03, " SATA-CDROM"}, {0x04, " Other"}, {0x09, " Network v6"},
950 };
951
952 size_t validItem = 0;
953 for (size_t i = 1; i < sizeBootOrder; i++)
954 {
955 auto find = bootOrderMappingTable.find(bootSeq[i]);
956 if (find == bootOrderMappingTable.end())
Willy Tue39f9392022-06-15 13:24:20 -0700957 {
Delphine CC Chiu7bb45922023-04-10 13:34:04 +0800958 lg2::error("Unknown boot order : {BOOTORDER}", "BOOTORDER",
959 bootSeq[i]);
960 break;
Willy Tue39f9392022-06-15 13:24:20 -0700961 }
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800962
Delphine CC Chiu7bb45922023-04-10 13:34:04 +0800963 bootOrderPanel.item_str[i] = find->second;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800964
Delphine CC Chiu7bb45922023-04-10 13:34:04 +0800965 validItem++;
Willy Tue39f9392022-06-15 13:24:20 -0700966 }
Delphine CC Chiu7bb45922023-04-10 13:34:04 +0800967
968 bootOrderPanel.item_num = validItem;
Patrick Williamsa758d0a2024-08-27 08:35:55 -0400969 return panel::BOOT_ORDER;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800970}
971
Patrick Williamsa758d0a2024-08-27 08:35:55 -0400972static panel panel_power_policy(size_t)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800973{
Willy Tue39f9392022-06-15 13:24:20 -0700974/* To be cleaned */
975#if 0
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800976 uint8_t buff[32] = {0};
977 uint8_t res_len;
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +0530978 size_t pos = plat_get_fru_sel();
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800979 uint8_t policy;
Willy Tue39f9392022-06-15 13:24:20 -0700980 uint8_t pwr_policy_item_map[3] = {POWER_CFG_ON, POWER_CFG_LPS,
981 POWER_CFG_OFF};
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800982
Willy Tue39f9392022-06-15 13:24:20 -0700983 if (pos != FRU_ALL)
984 {
985 if (item > 0 && item <= sizeof(pwr_policy_item_map))
986 {
987 policy = pwr_policy_item_map[item - 1];
Patrick Williams13ce3792024-08-27 13:03:46 -0400988 pal_set_power_restore_policy(pos, &policy, nullptr);
Willy Tue39f9392022-06-15 13:24:20 -0700989 }
Patrick Williams13ce3792024-08-27 13:03:46 -0400990 pal_get_chassis_status(pos, nullptr, buff, &res_len);
Willy Tue39f9392022-06-15 13:24:20 -0700991 policy = (((uint8_t)buff[0]) >> 5) & 0x7;
992 snprintf(panels[PANEL_POWER_POLICY].item_str[1], 32, "%cPower On",
993 policy == POWER_CFG_ON ? '*' : ' ');
994 snprintf(panels[PANEL_POWER_POLICY].item_str[2], 32, "%cLast State",
995 policy == POWER_CFG_LPS ? '*' : ' ');
996 snprintf(panels[PANEL_POWER_POLICY].item_str[3], 32, "%cPower Off",
997 policy == POWER_CFG_OFF ? '*' : ' ');
998 panels[PANEL_POWER_POLICY].item_num = 3;
999 }
1000 else
1001 {
1002 panels[PANEL_POWER_POLICY].item_num = 0;
1003 }
1004#endif
Patrick Williamsa758d0a2024-08-27 08:35:55 -04001005 return panel::POWER_POLICY;
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001006}
1007
Patrick Williamsa758d0a2024-08-27 08:35:55 -04001008ipmi_ret_t plat_udbg_control_panel(uint8_t cur_panel, uint8_t operation,
Patrick Williams5e589482024-07-13 16:18:13 -05001009 uint8_t item, uint8_t* count,
1010 uint8_t* buffer)
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001011{
Patrick Williamsa758d0a2024-08-27 08:35:55 -04001012 if (cur_panel > panelNum || cur_panel < std::to_underlying(panel::MAIN))
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001013 return IPMI_CC_PARM_OUT_OF_RANGE;
1014
1015 // No more item; End of item list
Patrick Williamsa758d0a2024-08-27 08:35:55 -04001016 if (item > panels[cur_panel].item_num)
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001017 return IPMI_CC_PARM_OUT_OF_RANGE;
1018
1019 switch (operation)
1020 {
1021 case 0: // Get Description
1022 break;
1023 case 1: // Select item
Patrick Williamsa758d0a2024-08-27 08:35:55 -04001024 cur_panel = std::to_underlying(panels[cur_panel].select(item));
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001025 item = 0;
1026 break;
1027 case 2: // Back
Patrick Williamsa758d0a2024-08-27 08:35:55 -04001028 cur_panel = std::to_underlying(panels[cur_panel].parent);
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001029 item = 0;
1030 break;
1031 default:
1032 return IPMI_CC_PARM_OUT_OF_RANGE;
1033 }
1034
Patrick Williamsa758d0a2024-08-27 08:35:55 -04001035 buffer[0] = cur_panel;
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001036 buffer[1] = item;
Patrick Williamsa758d0a2024-08-27 08:35:55 -04001037 buffer[2] = std::size(panels[cur_panel].item_str[item]);
Delphine CC Chiu7bb45922023-04-10 13:34:04 +08001038
Patrick Williams13ce3792024-08-27 13:03:46 -04001039 if (buffer[2] > 0 && (buffer[2] + 3u) < FRAME_PAGE_BUF_SIZE)
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001040 {
Patrick Williamsa758d0a2024-08-27 08:35:55 -04001041 std::memcpy(&buffer[3], (panels[cur_panel].item_str[item]).c_str(),
Delphine CC Chiu7bb45922023-04-10 13:34:04 +08001042 buffer[2]);
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001043 }
1044 *count = buffer[2] + 3;
1045 return IPMI_CC_OK;
1046}
1047
1048} // end of namespace ipmi