blob: a97a998926e41f03d0f7eb3425aed02557237fa4 [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
Karthikeyan Pasupathi813f2932022-04-06 14:10:48 +053017#include <usb-dbg.hpp>
Jayashree Dhanapal4ec80562022-06-28 15:41:47 +053018#include <commandutils.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);
24int8_t getFruData(std::string& serial, std::string& name);
Karthikeyan Pasupathi10ff3d82022-04-06 16:27:25 +053025int8_t sysConfig(std::vector<std::string>& data, size_t pos);
Karthikeyan Pasupathid532fec2022-07-14 14:43:42 +053026int8_t procInfo(std::string& result, size_t pos);
Vijay Khemkae7d23d02019-03-08 13:13:40 -080027
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +053028bool isMultiHostPlatform();
29
30/* Declare Host Selector interface and path */
31namespace selector
32{
33const std::string path = "/xyz/openbmc_project/Chassis/Buttons/HostSelector";
34const std::string interface =
Potin Laicff150e2022-09-19 09:34:57 +080035 "xyz.openbmc_project.Chassis.Buttons.HostSelector";
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +053036} // namespace selector
37
Vijay Khemka427b2762019-12-12 12:49:25 -080038/* Declare storage functions used here */
39namespace storage
40{
Vijay Khemka63c99be2020-05-27 19:14:35 -070041int getSensorValue(std::string&, double&);
42int getSensorUnit(std::string&, std::string&);
Vijay Khemka58bd5d82019-12-13 11:05:56 -080043} // namespace storage
Vijay Khemka427b2762019-12-12 12:49:25 -080044
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +053045void getMaxHostPosition(size_t& maxPosition)
Potin Laif24c78e2022-10-27 17:13:14 +080046{
47 try
48 {
49 std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
50 std::string service =
51 getService(*dbus, ipmi::selector::interface, ipmi::selector::path);
52 Value variant =
53 getDbusProperty(*dbus, service, ipmi::selector::path,
54 ipmi::selector::interface, "MaxPosition");
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +053055 maxPosition = std::get<size_t>(variant);
Potin Laif24c78e2022-10-27 17:13:14 +080056 }
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +053057 catch (const std::exception& e)
Potin Laif24c78e2022-10-27 17:13:14 +080058 {
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +053059 lg2::error("Unable to get max host position - {MAXPOSITION}",
60 "MAXPOSITION", maxPosition);
61 throw e;
Potin Laif24c78e2022-10-27 17:13:14 +080062 }
Potin Laif24c78e2022-10-27 17:13:14 +080063}
64
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +053065void getSelectorPosition(size_t& hostPosition)
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +053066{
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +053067 try
68 {
69 std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
70 std::string service =
71 getService(*dbus, ipmi::selector::interface, ipmi::selector::path);
72 Value variant = getDbusProperty(*dbus, service, ipmi::selector::path,
73 ipmi::selector::interface, "Position");
74 hostPosition = std::get<size_t>(variant);
75 }
76 catch (const std::exception& e)
77 {
78 lg2::error("Unable to get host position - {POSITION}", "POSITION",
79 hostPosition);
80 throw e;
81 }
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +053082}
83
Vijay Khemkae7d23d02019-03-08 13:13:40 -080084static int panelNum = (sizeof(panels) / sizeof(struct ctrl_panel)) - 1;
85
86/* Returns the FRU the hand-switch is switched to. If it is switched to BMC
87 * it returns FRU_ALL. Note, if in err, it returns FRU_ALL */
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +053088static size_t plat_get_fru_sel()
Vijay Khemkae7d23d02019-03-08 13:13:40 -080089{
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +053090 size_t position;
91 bool platform = isMultiHostPlatform();
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +053092 if (platform == true)
93 {
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +053094 getSelectorPosition(position);
95 if (position == BMC_POSITION)
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +053096 {
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +053097 return FRU_ALL;
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +053098 }
99 }
100 else
101 {
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +0530102 /* For Tiogapass it just return 1,
103 * can modify to support more platform */
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +0530104 position = 1;
105 }
106 return position;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800107}
108
109// return 0 on seccuess
110int frame::init(size_t size)
111{
112 // Reset status
113 idx_head = idx_tail = 0;
114 lines = 0;
115 esc_sts = 0;
116 pages = 1;
117
118 if (buf != NULL && max_size == size)
119 {
120 // reinit
121 return 0;
122 }
123
124 if (buf != NULL && max_size != size)
125 {
126 delete[] buf;
127 }
128 // Initialize Configuration
129 title[0] = '\0';
130 buf = new char[size];
131 max_size = size;
132 max_page = size;
133 line_per_page = 7;
134 line_width = 16;
135 overwrite = 0;
136
137 if (buf)
138 return 0;
139 else
140 return -1;
141}
142
143// return 0 on seccuess
Vijay Khemka63c99be2020-05-27 19:14:35 -0700144int frame::append(const char* string, int indent)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800145{
Karthikeyan Pasupathi10ff3d82022-04-06 16:27:25 +0530146 const size_t buf_size = 128;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800147 char lbuf[buf_size];
Vijay Khemka63c99be2020-05-27 19:14:35 -0700148 char* ptr;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800149 int ret;
150
151 ret = parse(lbuf, buf_size, string, indent);
152
153 if (ret < 0)
154 return ret;
155
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800156 for (ptr = lbuf; *ptr != '\0'; ptr++)
157 {
158 if (isFull())
159 {
160 if (overwrite)
161 {
162 if (buf[idx_head] == LINE_DELIMITER)
163 lines--;
164 idx_head = (idx_head + 1) % max_size;
165 }
166 else
167 return -1;
168 }
169
170 buf[idx_tail] = *ptr;
171 if (*ptr == LINE_DELIMITER)
172 lines++;
173
174 idx_tail = (idx_tail + 1) % max_size;
175 }
176
177 pages = (lines / line_per_page) + ((lines % line_per_page) ? 1 : 0);
178
179 if (pages > max_page)
180 pages = max_page;
181
182 return 0;
183}
184
185// return 0 on seccuess
Vijay Khemka63c99be2020-05-27 19:14:35 -0700186int frame::insert(const char* string, int indent)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800187{
188 const size_t buf_size = 128;
189 char lbuf[buf_size];
Vijay Khemka63c99be2020-05-27 19:14:35 -0700190 char* ptr;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800191 int ret;
192 int i;
193
194 ret = parse(lbuf, buf_size, string, indent);
195
196 if (ret < 0)
197 return ret;
198
199 for (i = strlen(lbuf) - 1; i >= 0; i--)
200 {
201 ptr = &lbuf[i];
202 if (isFull())
203 {
204 if (overwrite)
205 {
206 idx_tail = (idx_tail + max_size - 1) % max_size;
207 if (buf[idx_tail] == LINE_DELIMITER)
208 lines--;
209 }
210 else
211 return -1;
212 }
213
214 idx_head = (idx_head + max_size - 1) % max_size;
215
216 buf[idx_head] = *ptr;
217 if (*ptr == LINE_DELIMITER)
218 lines++;
219 }
220
221 pages = (lines / line_per_page) + ((lines % line_per_page) ? 1 : 0);
222
223 if (pages > max_page)
224 pages = max_page;
225
226 return 0;
227}
228
229// return page size
Vijay Khemka63c99be2020-05-27 19:14:35 -0700230int frame::getPage(int page, char* page_buf, size_t page_buf_size)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800231{
232 int ret;
233 uint16_t line = 0;
234 uint16_t idx, len;
235
236 if (buf == NULL)
237 return -1;
238
239 // 1-based page
240 if (page > pages || page < 1)
241 return -1;
242
Willy Tue39f9392022-06-15 13:24:20 -0700243 if (page_buf == NULL || page_buf_size == 0)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800244 return -1;
245
246 ret = snprintf(page_buf, 17, "%-10s %02d/%02d", title, page, pages);
247 len = strlen(page_buf);
248 if (ret < 0)
249 return -1;
250
251 line = 0;
252 idx = idx_head;
253 while (line < ((page - 1) * line_per_page) && idx != idx_tail)
254 {
255 if (buf[idx] == LINE_DELIMITER)
256 line++;
257 idx = (idx + 1) % max_size;
258 }
259
260 while (line < ((page)*line_per_page) && idx != idx_tail)
261 {
262 if (buf[idx] == LINE_DELIMITER)
263 {
264 line++;
265 }
266 else
267 {
268 page_buf[len++] = buf[idx];
269 if (len == (page_buf_size - 1))
270 {
271 break;
272 }
273 }
274 idx = (idx + 1) % max_size;
275 }
276
277 return len;
278}
279
280// return 1 for frame buffer full
281int frame::isFull()
282{
283 if (buf == NULL)
284 return -1;
285
286 if ((idx_tail + 1) % max_size == idx_head)
287 return 1;
288 else
289 return 0;
290}
291
292// return 1 for Escape Sequence
293int frame::isEscSeq(char chr)
294{
295 uint8_t curr_sts = esc_sts;
296
297 if (esc_sts == 0 && (chr == 0x1b))
298 esc_sts = 1; // Escape Sequence
299 else if (esc_sts == 1 && (chr == 0x5b))
300 esc_sts = 2; // Control Sequence Introducer(CSI)
301 else if (esc_sts == 1 && (chr != 0x5b))
302 esc_sts = 0;
303 else if (esc_sts == 2 && (chr >= 0x40 && chr <= 0x7e))
304 esc_sts = 0;
305
306 if (curr_sts || esc_sts)
307 return 1;
308 else
309 return 0;
310}
311
312// return 0 on success
Vijay Khemka63c99be2020-05-27 19:14:35 -0700313int frame::parse(char* lbuf, size_t buf_size, const char* input, int indent)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800314{
315 uint8_t pos, esc;
Willy Tue39f9392022-06-15 13:24:20 -0700316 size_t i;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800317 const char *in, *end;
318
319 if (buf == NULL || input == NULL)
320 return -1;
321
322 if (indent >= line_width || indent < 0)
323 return -1;
324
325 in = input;
326 end = in + strlen(input);
327 pos = 0; // line position
328 esc = 0; // escape state
329 i = 0; // buf index
330 while (in != end)
331 {
332 if (i >= buf_size)
333 break;
334
335 if (pos < indent)
336 {
337 // fill indent
338 lbuf[i++] = ' ';
339 pos++;
340 continue;
341 }
342
343 esc = isEscSeq(*in);
344
345 if (!esc && pos == line_width)
346 {
347 lbuf[i++] = LINE_DELIMITER;
348 pos = 0;
349 continue;
350 }
351
352 if (!esc)
353 pos++;
354
355 // fill input data
356 lbuf[i++] = *(in++);
357 }
358
359 // padding
360 while (pos <= line_width)
361 {
362 if (i >= buf_size)
363 break;
364 if (pos < line_width)
365 lbuf[i++] = ' ';
366 else
367 lbuf[i++] = LINE_DELIMITER;
368 pos++;
369 }
370
371 // full
372 if (i >= buf_size)
373 return -1;
374
375 lbuf[i++] = '\0';
376
377 return 0;
378}
379
Vijay Khemka63c99be2020-05-27 19:14:35 -0700380static int chk_cri_sel_update(uint8_t* cri_sel_up)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800381{
Vijay Khemka63c99be2020-05-27 19:14:35 -0700382 FILE* fp;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800383 struct stat file_stat;
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +0530384 size_t pos = plat_get_fru_sel();
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800385 static uint8_t pre_pos = 0xff;
386
387 fp = fopen("/mnt/data/cri_sel", "r");
388 if (fp)
389 {
390 if ((stat("/mnt/data/cri_sel", &file_stat) == 0) &&
391 (file_stat.st_mtime != frame_sel.mtime || pre_pos != pos))
392 {
393 *cri_sel_up = 1;
394 }
395 else
396 {
397 *cri_sel_up = 0;
398 }
399 fclose(fp);
400 }
401 else
402 {
403 if (frame_sel.buf == NULL || frame_sel.lines != 0 || pre_pos != pos)
404 {
405 *cri_sel_up = 1;
406 }
407 else
408 {
409 *cri_sel_up = 0;
410 }
411 }
412 pre_pos = pos;
413 return 0;
414}
415
Vijay Khemka63c99be2020-05-27 19:14:35 -0700416int plat_udbg_get_frame_info(uint8_t* num)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800417{
418 *num = 3;
419 return 0;
420}
421
Vijay Khemka63c99be2020-05-27 19:14:35 -0700422int plat_udbg_get_updated_frames(uint8_t* count, uint8_t* buffer)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800423{
424 uint8_t cri_sel_up = 0;
425 uint8_t info_page_up = 1;
426
427 *count = 0;
428
429 // info page update
430 if (info_page_up == 1)
431 {
432 buffer[*count] = 1;
433 *count += 1;
434 }
435
436 // cri sel update
437 chk_cri_sel_update(&cri_sel_up);
438 if (cri_sel_up == 1)
439 {
440 buffer[*count] = 2;
441 *count += 1;
442 }
443
444 // cri sensor update
445 buffer[*count] = 3;
446 *count += 1;
447
448 return 0;
449}
450
Vijay Khemka63c99be2020-05-27 19:14:35 -0700451int plat_udbg_get_post_desc(uint8_t index, uint8_t* next, uint8_t phase,
452 uint8_t* end, uint8_t* length, uint8_t* buffer)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800453{
Vijay Khemkacc0d6d92019-08-27 14:51:17 -0700454 nlohmann::json postObj;
455 std::string postCode;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800456
Vijay Khemkacc0d6d92019-08-27 14:51:17 -0700457 /* Get post description data stored in json file */
458 std::ifstream file(JSON_POST_DATA_FILE);
459 if (file)
460 {
461 file >> postObj;
462 file.close();
463 }
464 else
465 {
466 phosphor::logging::log<phosphor::logging::level::ERR>(
467 "Post code description file not found",
468 phosphor::logging::entry("POST_CODE_FILE=%s", JSON_POST_DATA_FILE));
469 return -1;
470 }
471
472 std::string phaseStr = "PhaseAny";
473 if (postObj.find(phaseStr) == postObj.end())
474 {
475 phaseStr = "Phase" + std::to_string(phase);
476 }
477
478 if (postObj.find(phaseStr) == postObj.end())
479 {
480 phosphor::logging::log<phosphor::logging::level::ERR>(
481 "Post code phase not available",
482 phosphor::logging::entry("PHASE=%d", phase));
483 return -1;
484 }
485
486 auto phaseObj = postObj[phaseStr];
487 int phaseSize = phaseObj.size();
488
489 for (int i = 0; i < phaseSize; i++)
490 {
491 postCode = phaseObj[i][0];
492 if (index == stoul(postCode, nullptr, 16))
493 {
494 std::string postDesc = phaseObj[i][1];
495 *length = postDesc.size();
496 memcpy(buffer, postDesc.data(), *length);
497 buffer[*length] = '\0';
498
499 if (phaseSize != i + 1)
500 {
501 postCode = phaseObj[i + 1][0];
502 *next = stoul(postCode, nullptr, 16);
503 *end = 0;
504 }
505 else
506 {
507 if (postObj.size() != phase)
508 {
509 std::string nextPhaseStr =
510 "Phase" + std::to_string(phase + 1);
511 postCode = postObj[nextPhaseStr][0][0];
512 *next = stoul(postCode, nullptr, 16);
513 *end = 0;
514 }
515 else
516 {
517 *next = 0xff;
518 *end = 1;
519 }
520 }
521
522 return 0;
523 }
524 }
525
526 phosphor::logging::log<phosphor::logging::level::ERR>(
527 "Post code description data not available",
528 phosphor::logging::entry("PHASE_CODE=%d_0x%x", phase, index));
529 return -1;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800530}
531
Vijay Khemka63c99be2020-05-27 19:14:35 -0700532int plat_udbg_get_gpio_desc(uint8_t index, uint8_t* next, uint8_t* level,
533 uint8_t* def, uint8_t* length, uint8_t* buffer)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800534{
Vijay Khemka38183d62019-08-28 16:19:33 -0700535 nlohmann::json gpioObj;
536 std::string gpioPin;
537
538 /* Get gpio data stored in json file */
539 std::ifstream file(JSON_GPIO_DATA_FILE);
540 if (file)
541 {
542 file >> gpioObj;
543 file.close();
544 }
545 else
546 {
547 phosphor::logging::log<phosphor::logging::level::ERR>(
548 "GPIO pin description file not found",
549 phosphor::logging::entry("GPIO_PIN_DETAILS_FILE=%s",
550 JSON_GPIO_DATA_FILE));
551 return -1;
552 }
553
554 if (gpioObj.find(DEBUG_GPIO_KEY) == gpioObj.end())
555 {
556 phosphor::logging::log<phosphor::logging::level::ERR>(
557 "GPIO pin details not available",
558 phosphor::logging::entry("GPIO_JSON_KEY=%d", DEBUG_GPIO_KEY));
559 return -1;
560 }
561
562 auto obj = gpioObj[DEBUG_GPIO_KEY];
563 int objSize = obj.size();
564
565 for (int i = 0; i < objSize; i++)
566 {
567 if (obj[i].size() != GPIO_ARRAY_SIZE)
568 {
569 phosphor::logging::log<phosphor::logging::level::ERR>(
570 "Size of gpio array is incorrect",
571 phosphor::logging::entry("EXPECTED_SIZE=%d", GPIO_ARRAY_SIZE));
572 return -1;
573 }
574
575 gpioPin = obj[i][GPIO_PIN_INDEX];
576 if (index == stoul(gpioPin, nullptr, 16))
577 {
578 if (objSize != i + 1)
579 {
580 gpioPin = obj[i + 1][GPIO_PIN_INDEX];
581 *next = stoul(gpioPin, nullptr, 16);
582 }
583 else
584 {
585 *next = 0xff;
586 }
587
588 *level = obj[i][GPIO_LEVEL_INDEX];
589 *def = obj[i][GPIO_DEF_INDEX];
590 std::string gpioDesc = obj[i][GPIO_DESC_INDEX];
591 *length = gpioDesc.size();
592 memcpy(buffer, gpioDesc.data(), *length);
593 buffer[*length] = '\0';
594
595 return 0;
596 }
597 }
598
599 phosphor::logging::log<phosphor::logging::level::ERR>(
600 "GPIO pin description data not available",
601 phosphor::logging::entry("GPIO_PIN=0x%x", index));
602 return -1;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800603}
604
Willy Tue39f9392022-06-15 13:24:20 -0700605static int udbg_get_cri_sel(uint8_t, uint8_t page, uint8_t* next,
Vijay Khemka63c99be2020-05-27 19:14:35 -0700606 uint8_t* count, uint8_t* buffer)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800607{
608 int len;
609 int ret;
Willy Tue39f9392022-06-15 13:24:20 -0700610 char line_buff[FRAME_PAGE_BUF_SIZE];
Vijay Khemka63c99be2020-05-27 19:14:35 -0700611 const char* ptr;
612 FILE* fp;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800613 struct stat file_stat;
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +0530614 size_t pos = plat_get_fru_sel();
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800615 static uint8_t pre_pos = FRU_ALL;
616 bool pos_changed = pre_pos != pos;
617
618 pre_pos = pos;
619
620 /* Revisit this */
621 fp = fopen("/mnt/data/cri_sel", "r");
622 if (fp)
623 {
624 if ((stat("/mnt/data/cri_sel", &file_stat) == 0) &&
625 (file_stat.st_mtime != frame_sel.mtime || pos_changed))
626 {
627 // initialize and clear frame
628 frame_sel.init(FRAME_BUFF_SIZE);
629 frame_sel.overwrite = 1;
630 frame_sel.max_page = 20;
631 frame_sel.mtime = file_stat.st_mtime;
632 snprintf(frame_sel.title, 32, "Cri SEL");
633
634 while (fgets(line_buff, FRAME_PAGE_BUF_SIZE, fp))
635 {
636 // Remove newline
637 line_buff[strlen(line_buff) - 1] = '\0';
638 ptr = line_buff;
639 // Find message
640 ptr = strstr(ptr, "local0.err");
641 if (ptr == NULL)
642 {
643 continue;
644 }
645
646 if ((ptr = strrchr(ptr, ':')) == NULL)
647 {
648 continue;
649 }
650 len = strlen(ptr);
651 if (len > 2)
652 {
653 // to skip log string ": "
654 ptr += 2;
655 }
656 // Write new message
657 frame_sel.insert(ptr, 0);
658 }
659 }
660 fclose(fp);
661 }
662 else
663 {
664 // Title only
665 frame_sel.init(FRAME_BUFF_SIZE);
666 snprintf(frame_sel.title, 32, "Cri SEL");
667 frame_sel.mtime = 0;
668 }
669
670 if (page > frame_sel.pages)
671 {
672 return -1;
673 }
674
Vijay Khemka63c99be2020-05-27 19:14:35 -0700675 ret = frame_sel.getPage(page, (char*)buffer, FRAME_PAGE_BUF_SIZE);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800676 if (ret < 0)
677 {
678 *count = 0;
679 return -1;
680 }
681 *count = (uint8_t)ret;
682
683 if (page < frame_sel.pages)
684 *next = page + 1;
685 else
686 *next = 0xFF; // Set the value of next to 0xFF to indicate this is the
687 // last page
688
689 return 0;
690}
691
Willy Tue39f9392022-06-15 13:24:20 -0700692static int udbg_get_cri_sensor(uint8_t, uint8_t page, uint8_t* next,
Vijay Khemka63c99be2020-05-27 19:14:35 -0700693 uint8_t* count, uint8_t* buffer)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800694{
Vijay Khemka427b2762019-12-12 12:49:25 -0800695 int ret;
696 double fvalue;
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +0530697 size_t pos = plat_get_fru_sel();
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800698
699 if (page == 1)
700 {
701 // Only update frame data while getting page 1
702
703 // initialize and clear frame
704 frame_snr.init(FRAME_BUFF_SIZE);
705 snprintf(frame_snr.title, 32, "CriSensor");
Vijay Khemka427b2762019-12-12 12:49:25 -0800706
707 nlohmann::json senObj;
708
709 /* Get critical sensor names stored in json file */
710 std::ifstream file(JSON_SENSOR_NAMES_FILE);
711 if (file)
712 {
713 file >> senObj;
714 file.close();
715 }
716 else
717 {
718 phosphor::logging::log<phosphor::logging::level::ERR>(
719 "Critical Sensor names file not found",
720 phosphor::logging::entry("CRI_SENSOR_NAMES_FILE=%s",
721 JSON_SENSOR_NAMES_FILE));
722 return -1;
723 }
724
725 /* Get sensors values for all critical sensors */
Vijay Khemka63c99be2020-05-27 19:14:35 -0700726 for (auto& j : senObj.items())
Vijay Khemka427b2762019-12-12 12:49:25 -0800727 {
728 std::string senName = j.key();
729 auto val = j.value();
730
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +0530731 if (senName[0] == '_')
732 {
733 senName = std::to_string(pos) + senName;
734 }
735
Vijay Khemka427b2762019-12-12 12:49:25 -0800736 if (ipmi::storage::getSensorValue(senName, fvalue) == 0)
737 {
738 std::stringstream ss;
Vijay Khemkaf43fad42019-12-26 11:47:58 -0800739 int prec = 0; // Default value
740
741 if (val.find("precision") != val.end())
742 prec = val["precision"];
743
744 ss << std::fixed << std::setprecision(prec) << fvalue;
Vijay Khemka427b2762019-12-12 12:49:25 -0800745
746 std::string senStr;
747 if (val.find("short_name") != val.end())
748 senStr = val["short_name"];
749 else
750 senStr = senName;
751
752 senStr += ss.str();
Vijay Khemka58bd5d82019-12-13 11:05:56 -0800753
754 /* Get unit string for sensor and append in output */
755 std::string unitStr;
756 if (ipmi::storage::getSensorUnit(senName, unitStr) == 0)
757 senStr += unitStr;
758
Vijay Khemka427b2762019-12-12 12:49:25 -0800759 frame_snr.append(senStr.c_str(), 0);
760 }
761 else
762 {
763 phosphor::logging::log<phosphor::logging::level::INFO>(
764 "Critical sensor not found",
765 phosphor::logging::entry("CRI_SENSOR_NAME=%s",
766 senName.c_str()));
767 }
768 }
769
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800770 } // End of update frame
771
772 if (page > frame_snr.pages)
773 {
774 return -1;
775 }
776
Vijay Khemka63c99be2020-05-27 19:14:35 -0700777 ret = frame_snr.getPage(page, (char*)buffer, FRAME_PAGE_BUF_SIZE);
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800778 if (ret < 0)
779 {
780 *count = 0;
781 return -1;
782 }
783 *count = (uint8_t)ret;
784
785 if (page < frame_snr.pages)
786 *next = page + 1;
787 else
788 *next = 0xFF; // Set the value of next to 0xFF to indicate this is the
789 // last page
790
791 return 0;
792}
793
Bonnie Loe9baaff2022-11-08 16:36:21 +0800794static int getBiosVer(std::string& ver, size_t hostPosition)
Vijay Khemka88884b82019-08-27 15:23:07 -0700795{
796 nlohmann::json appObj;
797
798 std::ifstream file(JSON_APP_DATA_FILE);
799 if (file)
800 {
801 file >> appObj;
802 file.close();
Bonnie Loe9baaff2022-11-08 16:36:21 +0800803 std::string version_key = KEY_SYSFW_VER + std::to_string(hostPosition);
804
805 if (appObj.find(version_key) != appObj.end())
Vijay Khemka88884b82019-08-27 15:23:07 -0700806 {
Bonnie Loe9baaff2022-11-08 16:36:21 +0800807 ver = appObj[version_key].get<std::string>();
Vijay Khemka88884b82019-08-27 15:23:07 -0700808 return 0;
809 }
810 }
811
812 return -1;
813}
814
Manikandan Elumalai5f8e3432020-12-02 03:46:55 +0530815int sendBicCmd(uint8_t netFn, uint8_t cmd, uint8_t bicAddr,
816 std::vector<uint8_t>& cmdData, std::vector<uint8_t>& respData)
817{
818 static constexpr uint8_t lun = 0;
819
820 auto bus = getSdBus();
821
822 auto method = bus->new_method_call("xyz.openbmc_project.Ipmi.Channel.Ipmb",
823 "/xyz/openbmc_project/Ipmi/Channel/Ipmb",
824 "org.openbmc.Ipmb", "sendRequest");
825 method.append(bicAddr, netFn, lun, cmd, cmdData);
826
827 auto reply = bus->call(method);
828 if (reply.is_method_error())
829 {
830 phosphor::logging::log<phosphor::logging::level::ERR>(
831 "Error reading from BIC");
832 return -1;
833 }
834
835 IpmbMethodType resp;
836 reply.read(resp);
837
838 respData =
839 std::move(std::get<std::remove_reference_t<decltype(respData)>>(resp));
840
841 return 0;
842}
843
Vijay Khemka63c99be2020-05-27 19:14:35 -0700844int sendMeCmd(uint8_t netFn, uint8_t cmd, std::vector<uint8_t>& cmdData,
845 std::vector<uint8_t>& respData)
Vijay Khemkadd14c0f2020-03-18 14:48:13 -0700846{
847 auto bus = getSdBus();
848
849 if (DEBUG)
850 {
851 std::cout << "ME NetFn:cmd " << (int)netFn << ":" << (int)cmd << "\n";
852 std::cout << "ME req data: ";
853 for (auto d : cmdData)
854 {
855 std::cout << d << " ";
856 }
857 std::cout << "\n";
858 }
859
860 auto method = bus->new_method_call("xyz.openbmc_project.Ipmi.Channel.Ipmb",
861 "/xyz/openbmc_project/Ipmi/Channel/Ipmb",
862 "org.openbmc.Ipmb", "sendRequest");
863 method.append(meAddress, netFn, lun, cmd, cmdData);
864
865 auto reply = bus->call(method);
866 if (reply.is_method_error())
867 {
868 phosphor::logging::log<phosphor::logging::level::ERR>(
869 "Error reading from ME");
870 return -1;
871 }
872
873 IpmbMethodType resp;
874 reply.read(resp);
875
876 respData =
877 std::move(std::get<std::remove_reference_t<decltype(respData)>>(resp));
878
879 if (DEBUG)
880 {
881 std::cout << "ME resp data: ";
882 for (auto d : respData)
883 {
884 std::cout << d << " ";
885 }
886 std::cout << "\n";
887 }
888
889 return 0;
890}
891
Potin Lai2ad53982022-10-27 17:02:51 +0800892#ifdef ME_SUPPORT
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530893static int getMeStatus(std::string& status, size_t pos)
Vijay Khemka317999d2020-01-02 13:43:42 -0800894{
895 uint8_t cmd = 0x01; // Get Device id command
896 uint8_t netFn = 0x06; // Netfn for APP
897 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
898 std::vector<uint8_t> cmdData;
899
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530900 uint8_t meAddr = meAddress;
901 bool platform = isMultiHostPlatform();
902 if (platform == true)
903 {
904 meAddr = ((pos - 1) << 2);
905 }
906
Vijay Khemka317999d2020-01-02 13:43:42 -0800907 auto method = bus->new_method_call("xyz.openbmc_project.Ipmi.Channel.Ipmb",
908 "/xyz/openbmc_project/Ipmi/Channel/Ipmb",
909 "org.openbmc.Ipmb", "sendRequest");
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530910 method.append(meAddr, netFn, lun, cmd, cmdData);
Vijay Khemka317999d2020-01-02 13:43:42 -0800911
912 auto reply = bus->call(method);
913 if (reply.is_method_error())
914 {
915 std::cerr << "Error reading from ME\n";
916 return -1;
917 }
918
919 IpmbMethodType resp;
920 reply.read(resp);
921
922 std::vector<uint8_t> data;
923 data = std::get<5>(resp);
924
925 if (DEBUG)
926 {
927 std::cout << "ME Get ID: ";
928 for (size_t d : data)
929 {
930 std::cout << d << " ";
931 }
932 std::cout << "\n";
933 }
934
935 if (data[2] & 0x80)
936 status = "recovery mode";
937 else
938 status = "operation mode";
939
940 return 0;
941}
Potin Lai2ad53982022-10-27 17:02:51 +0800942#endif
Vijay Khemka317999d2020-01-02 13:43:42 -0800943
Willy Tue39f9392022-06-15 13:24:20 -0700944static int udbg_get_info_page(uint8_t, uint8_t page, uint8_t* next,
Vijay Khemka63c99be2020-05-27 19:14:35 -0700945 uint8_t* count, uint8_t* buffer)
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800946{
Willy Tue39f9392022-06-15 13:24:20 -0700947 char line_buff[1000];
948 [[maybe_unused]] char* pres_dev = line_buff;
949 [[maybe_unused]] size_t pos = plat_get_fru_sel();
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800950 int ret;
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530951 std::string serialName = "SerialNumber";
952 std::string partName = "PartNumber";
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800953 std::string verDel = "VERSION=";
954 std::string verPath = "/etc/os-release";
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530955 size_t hostPosition;
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +0530956 size_t maxPosition;
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800957
958 if (page == 1)
959 {
960 // Only update frame data while getting page 1
961
962 // initialize and clear frame
963 frame_info.init(FRAME_BUFF_SIZE);
964 snprintf(frame_info.title, 32, "SYS_Info");
965
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530966 bool platform = isMultiHostPlatform();
967 if (platform == true)
968 {
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +0530969 hostPosition = plat_get_fru_sel();
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530970 }
971
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +0530972 getMaxHostPosition(maxPosition);
Jayashree Dhanapal4ec80562022-06-28 15:41:47 +0530973 if (hostPosition == BMC_POSITION || hostInstances == "0")
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530974 {
975 frame_info.append("FRU:spb", 0);
976 }
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +0530977 else if (hostPosition != BMC_POSITION && hostPosition <= maxPosition)
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +0530978 {
979 std::string data = "FRU:slot" + std::to_string(hostPosition);
980 frame_info.append(data.c_str(), 0);
981 }
982
983 // FRU
Vijay Khemkae7d23d02019-03-08 13:13:40 -0800984 std::string data;
985 frame_info.append("SN:", 0);
986 if (getFruData(data, serialName) != 0)
987 {
988 data = "Not Found";
989 }
990 frame_info.append(data.c_str(), 1);
991 frame_info.append("PN:", 0);
992 if (getFruData(data, partName) != 0)
993 {
994 data = "Not Found";
995 }
996 frame_info.append(data.c_str(), 1);
997
998 // LAN
999 getNetworkData(3, line_buff);
1000 frame_info.append("BMC_IP:", 0);
1001 frame_info.append(line_buff, 1);
1002 getNetworkData(59, line_buff);
1003 frame_info.append("BMC_IPv6:", 0);
1004 frame_info.append(line_buff, 1);
1005
1006 // BMC ver
1007 std::ifstream file(verPath);
1008 if (file)
1009 {
1010 std::string line;
1011 while (std::getline(file, line))
1012 {
1013 if (line.find(verDel) != std::string::npos)
1014 {
1015 std::string bmcVer = line.substr(verDel.size());
1016 frame_info.append("BMC_FW_ver:", 0);
1017 frame_info.append(bmcVer.c_str(), 1);
1018 break;
1019 }
1020 }
1021 }
1022
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +05301023 if (hostPosition != BMC_POSITION)
Vijay Khemka88884b82019-08-27 15:23:07 -07001024 {
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +05301025 // BIOS ver
1026 std::string biosVer;
Bonnie Loe9baaff2022-11-08 16:36:21 +08001027 if (getBiosVer(biosVer, hostPosition) == 0)
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +05301028 {
1029 frame_info.append("BIOS_FW_ver:", 0);
1030 frame_info.append(biosVer.c_str(), 1);
1031 }
Potin Lai2ad53982022-10-27 17:02:51 +08001032
1033#ifdef ME_SUPPORT
Karthikeyan Pasupathi98aabdb2022-04-06 17:18:51 +05301034 // ME status
1035 std::string meStatus;
1036 if (getMeStatus(meStatus, pos) != 0)
1037 {
1038 phosphor::logging::log<phosphor::logging::level::WARNING>(
1039 "Reading ME status failed");
1040 meStatus = "unknown";
1041 }
1042 frame_info.append("ME_status:", 0);
1043 frame_info.append(meStatus.c_str(), 1);
Potin Lai2ad53982022-10-27 17:02:51 +08001044#endif
Vijay Khemka88884b82019-08-27 15:23:07 -07001045 }
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001046
Vijay Khemka317999d2020-01-02 13:43:42 -08001047 /* TBD: Board ID needs implementation */
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001048 // Board ID
1049
1050 // Battery - Use Escape sequence
1051 frame_info.append("Battery:", 0);
1052 frame_info.append(ESC_BAT " ", 1);
1053 // frame_info.append(&frame_info, esc_bat, 1);
1054
1055 // MCU Version - Use Escape sequence
1056 frame_info.append("MCUbl_ver:", 0);
1057 frame_info.append(ESC_MCU_BL_VER, 1);
1058 frame_info.append("MCU_ver:", 0);
1059 frame_info.append(ESC_MCU_RUN_VER, 1);
1060
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001061 // Sys config present device
Karthikeyan Pasupathi10ff3d82022-04-06 16:27:25 +05301062 if (hostPosition != BMC_POSITION)
1063 {
1064 frame_info.append("Sys Conf. info:", 0);
1065
1066 // Dimm info
1067 std::vector<std::string> data;
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +05301068 if (sysConfig(data, pos) == 0)
Karthikeyan Pasupathi10ff3d82022-04-06 16:27:25 +05301069 {
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +05301070 for (auto& info : data)
1071 {
1072 frame_info.append(info.c_str(), 1);
1073 }
1074 }
1075 else
1076 {
1077 frame_info.append("Not Found", 1);
Karthikeyan Pasupathi10ff3d82022-04-06 16:27:25 +05301078 }
Karthikeyan Pasupathid532fec2022-07-14 14:43:42 +05301079
1080 // Processor info
1081 std::string result;
Karthikeyan Pasupathie1ff81f2022-11-21 17:54:46 +05301082 if (procInfo(result, pos) != 0)
1083 {
1084 result = "Not Found";
1085 }
Karthikeyan Pasupathid532fec2022-07-14 14:43:42 +05301086 frame_info.append(result.c_str(), 1);
Karthikeyan Pasupathi10ff3d82022-04-06 16:27:25 +05301087 }
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001088
1089 } // End of update frame
1090
1091 if (page > frame_info.pages)
1092 {
1093 return -1;
1094 }
1095
Vijay Khemka63c99be2020-05-27 19:14:35 -07001096 ret = frame_info.getPage(page, (char*)buffer, FRAME_PAGE_BUF_SIZE);
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001097 if (ret < 0)
1098 {
1099 *count = 0;
1100 return -1;
1101 }
1102 *count = (uint8_t)ret;
1103
1104 if (page < frame_info.pages)
1105 *next = page + 1;
1106 else
1107 *next = 0xFF; // Set the value of next to 0xFF to indicate this is the
1108 // last page
1109
1110 return 0;
1111}
1112
Vijay Khemka63c99be2020-05-27 19:14:35 -07001113int plat_udbg_get_frame_data(uint8_t frame, uint8_t page, uint8_t* next,
1114 uint8_t* count, uint8_t* buffer)
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001115{
1116 switch (frame)
1117 {
1118 case 1: // info_page
1119 return udbg_get_info_page(frame, page, next, count, buffer);
1120 case 2: // critical SEL
1121 return udbg_get_cri_sel(frame, page, next, count, buffer);
1122 case 3: // critical Sensor
1123 return udbg_get_cri_sensor(frame, page, next, count, buffer);
1124 default:
1125 return -1;
1126 }
1127}
1128
1129static uint8_t panel_main(uint8_t item)
1130{
1131 // Update item list when select item 0
1132 switch (item)
1133 {
1134 case 1:
1135 return panels[PANEL_BOOT_ORDER].select(0);
1136 case 2:
1137 return panels[PANEL_POWER_POLICY].select(0);
1138 default:
1139 return PANEL_MAIN;
1140 }
1141}
1142
Willy Tue39f9392022-06-15 13:24:20 -07001143static uint8_t panel_boot_order(uint8_t)
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001144{
Willy Tue39f9392022-06-15 13:24:20 -07001145 /* To be implemented */
1146#if 0
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001147 int i;
1148 unsigned char buff[MAX_VALUE_LEN], pickup, len;
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +05301149 size_t pos = plat_get_fru_sel();
Willy Tue39f9392022-06-15 13:24:20 -07001150 if (pos != FRU_ALL && pal_get_boot_order(pos, buff, buff, &len) == 0)
1151 {
1152 if (item > 0 && item < SIZE_BOOT_ORDER)
1153 {
1154 pickup = buff[item];
1155 while (item > 1)
1156 {
1157 buff[item] = buff[item - 1];
1158 item--;
1159 }
1160 buff[item] = pickup;
1161 buff[0] |= 0x80;
1162 pal_set_boot_order(pos, buff, buff, &len);
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001163
Willy Tue39f9392022-06-15 13:24:20 -07001164 // refresh items
1165 return panels[PANEL_BOOT_ORDER].select(0);
1166 }
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001167
Willy Tue39f9392022-06-15 13:24:20 -07001168 // '*': boot flags valid, BIOS has not yet read
1169 snprintf(panels[PANEL_BOOT_ORDER].item_str[0], 32, "Boot Order%c",
1170 (buff[0] & 0x80) ? '*' : '\0');
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001171
Willy Tue39f9392022-06-15 13:24:20 -07001172 for (i = 1; i < SIZE_BOOT_ORDER; i++)
1173 {
1174 switch (buff[i])
1175 {
1176 case 0x0:
1177 snprintf(panels[PANEL_BOOT_ORDER].item_str[i], 32,
1178 " USB device");
1179 break;
1180 case 0x1:
1181 snprintf(panels[PANEL_BOOT_ORDER].item_str[i], 32,
1182 " Network v4");
1183 break;
1184 case (0x1 | 0x8):
1185 snprintf(panels[PANEL_BOOT_ORDER].item_str[i], 32,
1186 " Network v6");
1187 break;
1188 case 0x2:
1189 snprintf(panels[PANEL_BOOT_ORDER].item_str[i], 32,
1190 " SATA HDD");
1191 break;
1192 case 0x3:
1193 snprintf(panels[PANEL_BOOT_ORDER].item_str[i], 32,
1194 " SATA-CDROM");
1195 break;
1196 case 0x4:
1197 snprintf(panels[PANEL_BOOT_ORDER].item_str[i], 32,
1198 " Other");
1199 break;
1200 default:
1201 panels[PANEL_BOOT_ORDER].item_str[i][0] = '\0';
1202 break;
1203 }
1204 }
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001205
Willy Tue39f9392022-06-15 13:24:20 -07001206 // remove empty items
1207 for (i--;
1208 (strlen(panels[PANEL_BOOT_ORDER].item_str[i]) == 0) && (i > 0);
1209 i--)
1210 ;
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001211
Willy Tue39f9392022-06-15 13:24:20 -07001212 panels[PANEL_BOOT_ORDER].item_num = i;
1213 }
1214 else
1215 {
1216 panels[PANEL_BOOT_ORDER].item_num = 0;
1217 }
1218#endif
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001219 return PANEL_BOOT_ORDER;
1220}
1221
Willy Tue39f9392022-06-15 13:24:20 -07001222static uint8_t panel_power_policy(uint8_t)
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001223{
Willy Tue39f9392022-06-15 13:24:20 -07001224/* To be cleaned */
1225#if 0
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001226 uint8_t buff[32] = {0};
1227 uint8_t res_len;
Karthikeyan Pasupathi39836ff2022-01-17 12:20:06 +05301228 size_t pos = plat_get_fru_sel();
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001229 uint8_t policy;
Willy Tue39f9392022-06-15 13:24:20 -07001230 uint8_t pwr_policy_item_map[3] = {POWER_CFG_ON, POWER_CFG_LPS,
1231 POWER_CFG_OFF};
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001232
Willy Tue39f9392022-06-15 13:24:20 -07001233 if (pos != FRU_ALL)
1234 {
1235 if (item > 0 && item <= sizeof(pwr_policy_item_map))
1236 {
1237 policy = pwr_policy_item_map[item - 1];
1238 pal_set_power_restore_policy(pos, &policy, NULL);
1239 }
1240 pal_get_chassis_status(pos, NULL, buff, &res_len);
1241 policy = (((uint8_t)buff[0]) >> 5) & 0x7;
1242 snprintf(panels[PANEL_POWER_POLICY].item_str[1], 32, "%cPower On",
1243 policy == POWER_CFG_ON ? '*' : ' ');
1244 snprintf(panels[PANEL_POWER_POLICY].item_str[2], 32, "%cLast State",
1245 policy == POWER_CFG_LPS ? '*' : ' ');
1246 snprintf(panels[PANEL_POWER_POLICY].item_str[3], 32, "%cPower Off",
1247 policy == POWER_CFG_OFF ? '*' : ' ');
1248 panels[PANEL_POWER_POLICY].item_num = 3;
1249 }
1250 else
1251 {
1252 panels[PANEL_POWER_POLICY].item_num = 0;
1253 }
1254#endif
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001255 return PANEL_POWER_POLICY;
1256}
1257
1258int plat_udbg_control_panel(uint8_t panel, uint8_t operation, uint8_t item,
Vijay Khemka63c99be2020-05-27 19:14:35 -07001259 uint8_t* count, uint8_t* buffer)
Vijay Khemkae7d23d02019-03-08 13:13:40 -08001260{
1261 if (panel > panelNum || panel < PANEL_MAIN)
1262 return IPMI_CC_PARM_OUT_OF_RANGE;
1263
1264 // No more item; End of item list
1265 if (item > panels[panel].item_num)
1266 return IPMI_CC_PARM_OUT_OF_RANGE;
1267
1268 switch (operation)
1269 {
1270 case 0: // Get Description
1271 break;
1272 case 1: // Select item
1273 panel = panels[panel].select(item);
1274 item = 0;
1275 break;
1276 case 2: // Back
1277 panel = panels[panel].parent;
1278 item = 0;
1279 break;
1280 default:
1281 return IPMI_CC_PARM_OUT_OF_RANGE;
1282 }
1283
1284 buffer[0] = panel;
1285 buffer[1] = item;
1286 buffer[2] = strlen(panels[panel].item_str[item]);
1287 if (buffer[2] > 0 && (buffer[2] + 3) < FRAME_PAGE_BUF_SIZE)
1288 {
1289 memcpy(&buffer[3], panels[panel].item_str[item], buffer[2]);
1290 }
1291 *count = buffer[2] + 3;
1292 return IPMI_CC_OK;
1293}
1294
1295} // end of namespace ipmi