blob: efa013606b24bc3680903f8af7342c2461c9348f [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
17#include <host-ipmid/ipmid-api.h>
18#include <stdbool.h>
19#include <stdio.h>
20#include <sys/stat.h>
21
22#include <fstream>
23#include <iostream>
24
25namespace ipmi
26{
27
28#define ETH_INTF_NAME "eth0"
29
30#define ESCAPE "\x1B"
31#define ESC_BAT ESCAPE "B"
32#define ESC_MCU_BL_VER ESCAPE "U"
33#define ESC_MCU_RUN_VER ESCAPE "R"
34#define ESC_ALT ESCAPE "[5;7m"
35#define ESC_RST ESCAPE "[m"
36
37#define LINE_DELIMITER '\x1F'
38
39#define FRAME_BUFF_SIZE 4096
40#define FRAME_PAGE_BUF_SIZE 256
41#define FRU_ALL 0
42#define MAX_VALUE_LEN 64
43
44/* Used for systems which do not specifically have a
45 * phase, and we want to ignore the phase provided by the
46 * debug card */
47#define PHASE_ANY 0xff
48
49ipmi_ret_t getNetworkData(uint8_t lan_param, char *data);
50int8_t getFruData(std::string &serial, std::string &name);
51
52typedef struct _post_desc
53{
54 uint8_t code;
55 char desc[32];
56} post_desc_t;
57
58typedef struct _post_phase_desc
59{
60 int phase;
61 post_desc_t *post_tbl;
62 size_t post_tbl_cnt;
63} post_phase_desc_t;
64
65typedef struct _gpio_desc
66{
67 uint8_t pin;
68 uint8_t level;
69 uint8_t def;
70 char desc[32];
71} gpio_desc_t;
72
73typedef struct _sensor_desc
74{
75 char name[16];
76 uint8_t sensor_num;
77 char unit[5];
78 uint8_t fru;
79 uint8_t disp_prec;
80} sensor_desc_t;
81
82struct frame
83{
84 char title[32];
85 size_t max_size;
86 size_t max_page;
87 char *buf;
88 uint16_t idx_head, idx_tail;
89 uint8_t line_per_page;
90 uint8_t line_width;
91 uint16_t lines, pages;
92 uint8_t esc_sts;
93 uint8_t overwrite;
94 time_t mtime;
95 frame() : buf(NULL), pages(0), mtime(0)
96 {
97 }
98 int init(size_t size);
99 int append(const char *string, int indent);
100 int insert(const char *string, int indent);
101 int getPage(int page, char *page_buf, size_t page_buf_size);
102 int isFull();
103 int isEscSeq(char chr);
104 int parse(char *buf, size_t buf_size, const char *input, int indent);
105};
106
107struct frame frame_info;
108struct frame frame_sel;
109struct frame frame_snr;
110
111enum ENUM_PANEL
112{
113 PANEL_MAIN = 1,
114 PANEL_BOOT_ORDER = 2,
115 PANEL_POWER_POLICY = 3,
116};
117
118struct ctrl_panel
119{
120 uint8_t parent;
121 uint8_t item_num;
122 char item_str[8][32];
123 uint8_t (*select)(uint8_t item);
124};
125
126static uint8_t panel_main(uint8_t item);
127static uint8_t panel_boot_order(uint8_t item);
128static uint8_t panel_power_policy(uint8_t item);
129
130static struct ctrl_panel panels[] = {
131 {/* dummy entry for making other to 1-based */},
132 {
133 .parent = PANEL_MAIN,
134 .item_num = 2,
135 .item_str =
136 {
137 "User Setting",
138 ">Boot Order",
139 ">Power Policy",
140 },
141 .select = panel_main,
142 },
143 {
144 .parent = PANEL_MAIN,
145 .item_num = 0,
146 .item_str =
147 {
148 "Boot Order",
149 },
150 .select = panel_boot_order,
151 },
152 {
153 .parent = PANEL_MAIN,
154 .item_num = 0,
155 .item_str =
156 {
157 "Power Policy",
158 },
159 .select = panel_power_policy,
160 },
161};
162
163static int panelNum = (sizeof(panels) / sizeof(struct ctrl_panel)) - 1;
164
165/* Returns the FRU the hand-switch is switched to. If it is switched to BMC
166 * it returns FRU_ALL. Note, if in err, it returns FRU_ALL */
167static uint8_t plat_get_fru_sel()
168{
169 // For Tiogapass it just return 1, can modify to support more platform
170 return 1;
171}
172
173// return 0 on seccuess
174int frame::init(size_t size)
175{
176 // Reset status
177 idx_head = idx_tail = 0;
178 lines = 0;
179 esc_sts = 0;
180 pages = 1;
181
182 if (buf != NULL && max_size == size)
183 {
184 // reinit
185 return 0;
186 }
187
188 if (buf != NULL && max_size != size)
189 {
190 delete[] buf;
191 }
192 // Initialize Configuration
193 title[0] = '\0';
194 buf = new char[size];
195 max_size = size;
196 max_page = size;
197 line_per_page = 7;
198 line_width = 16;
199 overwrite = 0;
200
201 if (buf)
202 return 0;
203 else
204 return -1;
205}
206
207// return 0 on seccuess
208int frame::append(const char *string, int indent)
209{
210 const size_t buf_size = 64;
211 char lbuf[buf_size];
212 char *ptr;
213 int ret;
214
215 ret = parse(lbuf, buf_size, string, indent);
216
217 if (ret < 0)
218 return ret;
219
220 int len = strlen(string);
221 for (ptr = lbuf; *ptr != '\0'; ptr++)
222 {
223 if (isFull())
224 {
225 if (overwrite)
226 {
227 if (buf[idx_head] == LINE_DELIMITER)
228 lines--;
229 idx_head = (idx_head + 1) % max_size;
230 }
231 else
232 return -1;
233 }
234
235 buf[idx_tail] = *ptr;
236 if (*ptr == LINE_DELIMITER)
237 lines++;
238
239 idx_tail = (idx_tail + 1) % max_size;
240 }
241
242 pages = (lines / line_per_page) + ((lines % line_per_page) ? 1 : 0);
243
244 if (pages > max_page)
245 pages = max_page;
246
247 return 0;
248}
249
250// return 0 on seccuess
251int frame::insert(const char *string, int indent)
252{
253 const size_t buf_size = 128;
254 char lbuf[buf_size];
255 char *ptr;
256 int ret;
257 int i;
258
259 ret = parse(lbuf, buf_size, string, indent);
260
261 if (ret < 0)
262 return ret;
263
264 for (i = strlen(lbuf) - 1; i >= 0; i--)
265 {
266 ptr = &lbuf[i];
267 if (isFull())
268 {
269 if (overwrite)
270 {
271 idx_tail = (idx_tail + max_size - 1) % max_size;
272 if (buf[idx_tail] == LINE_DELIMITER)
273 lines--;
274 }
275 else
276 return -1;
277 }
278
279 idx_head = (idx_head + max_size - 1) % max_size;
280
281 buf[idx_head] = *ptr;
282 if (*ptr == LINE_DELIMITER)
283 lines++;
284 }
285
286 pages = (lines / line_per_page) + ((lines % line_per_page) ? 1 : 0);
287
288 if (pages > max_page)
289 pages = max_page;
290
291 return 0;
292}
293
294// return page size
295int frame::getPage(int page, char *page_buf, size_t page_buf_size)
296{
297 int ret;
298 uint16_t line = 0;
299 uint16_t idx, len;
300
301 if (buf == NULL)
302 return -1;
303
304 // 1-based page
305 if (page > pages || page < 1)
306 return -1;
307
308 if (page_buf == NULL || page_buf_size < 0)
309 return -1;
310
311 ret = snprintf(page_buf, 17, "%-10s %02d/%02d", title, page, pages);
312 len = strlen(page_buf);
313 if (ret < 0)
314 return -1;
315
316 line = 0;
317 idx = idx_head;
318 while (line < ((page - 1) * line_per_page) && idx != idx_tail)
319 {
320 if (buf[idx] == LINE_DELIMITER)
321 line++;
322 idx = (idx + 1) % max_size;
323 }
324
325 while (line < ((page)*line_per_page) && idx != idx_tail)
326 {
327 if (buf[idx] == LINE_DELIMITER)
328 {
329 line++;
330 }
331 else
332 {
333 page_buf[len++] = buf[idx];
334 if (len == (page_buf_size - 1))
335 {
336 break;
337 }
338 }
339 idx = (idx + 1) % max_size;
340 }
341
342 return len;
343}
344
345// return 1 for frame buffer full
346int frame::isFull()
347{
348 if (buf == NULL)
349 return -1;
350
351 if ((idx_tail + 1) % max_size == idx_head)
352 return 1;
353 else
354 return 0;
355}
356
357// return 1 for Escape Sequence
358int frame::isEscSeq(char chr)
359{
360 uint8_t curr_sts = esc_sts;
361
362 if (esc_sts == 0 && (chr == 0x1b))
363 esc_sts = 1; // Escape Sequence
364 else if (esc_sts == 1 && (chr == 0x5b))
365 esc_sts = 2; // Control Sequence Introducer(CSI)
366 else if (esc_sts == 1 && (chr != 0x5b))
367 esc_sts = 0;
368 else if (esc_sts == 2 && (chr >= 0x40 && chr <= 0x7e))
369 esc_sts = 0;
370
371 if (curr_sts || esc_sts)
372 return 1;
373 else
374 return 0;
375}
376
377// return 0 on success
378int frame::parse(char *lbuf, size_t buf_size, const char *input, int indent)
379{
380 uint8_t pos, esc;
381 int i;
382 const char *in, *end;
383
384 if (buf == NULL || input == NULL)
385 return -1;
386
387 if (indent >= line_width || indent < 0)
388 return -1;
389
390 in = input;
391 end = in + strlen(input);
392 pos = 0; // line position
393 esc = 0; // escape state
394 i = 0; // buf index
395 while (in != end)
396 {
397 if (i >= buf_size)
398 break;
399
400 if (pos < indent)
401 {
402 // fill indent
403 lbuf[i++] = ' ';
404 pos++;
405 continue;
406 }
407
408 esc = isEscSeq(*in);
409
410 if (!esc && pos == line_width)
411 {
412 lbuf[i++] = LINE_DELIMITER;
413 pos = 0;
414 continue;
415 }
416
417 if (!esc)
418 pos++;
419
420 // fill input data
421 lbuf[i++] = *(in++);
422 }
423
424 // padding
425 while (pos <= line_width)
426 {
427 if (i >= buf_size)
428 break;
429 if (pos < line_width)
430 lbuf[i++] = ' ';
431 else
432 lbuf[i++] = LINE_DELIMITER;
433 pos++;
434 }
435
436 // full
437 if (i >= buf_size)
438 return -1;
439
440 lbuf[i++] = '\0';
441
442 return 0;
443}
444
445static int chk_cri_sel_update(uint8_t *cri_sel_up)
446{
447 FILE *fp;
448 struct stat file_stat;
449 uint8_t pos = plat_get_fru_sel();
450 static uint8_t pre_pos = 0xff;
451
452 fp = fopen("/mnt/data/cri_sel", "r");
453 if (fp)
454 {
455 if ((stat("/mnt/data/cri_sel", &file_stat) == 0) &&
456 (file_stat.st_mtime != frame_sel.mtime || pre_pos != pos))
457 {
458 *cri_sel_up = 1;
459 }
460 else
461 {
462 *cri_sel_up = 0;
463 }
464 fclose(fp);
465 }
466 else
467 {
468 if (frame_sel.buf == NULL || frame_sel.lines != 0 || pre_pos != pos)
469 {
470 *cri_sel_up = 1;
471 }
472 else
473 {
474 *cri_sel_up = 0;
475 }
476 }
477 pre_pos = pos;
478 return 0;
479}
480
481int plat_udbg_get_frame_info(uint8_t *num)
482{
483 *num = 3;
484 return 0;
485}
486
487int plat_udbg_get_updated_frames(uint8_t *count, uint8_t *buffer)
488{
489 uint8_t cri_sel_up = 0;
490 uint8_t info_page_up = 1;
491
492 *count = 0;
493
494 // info page update
495 if (info_page_up == 1)
496 {
497 buffer[*count] = 1;
498 *count += 1;
499 }
500
501 // cri sel update
502 chk_cri_sel_update(&cri_sel_up);
503 if (cri_sel_up == 1)
504 {
505 buffer[*count] = 2;
506 *count += 1;
507 }
508
509 // cri sensor update
510 buffer[*count] = 3;
511 *count += 1;
512
513 return 0;
514}
515
516int plat_udbg_get_post_desc(uint8_t index, uint8_t *next, uint8_t phase,
517 uint8_t *end, uint8_t *length, uint8_t *buffer)
518{
519 int target, pdesc_size;
520 post_phase_desc_t *post_phase;
521 size_t post_phase_desc_cnt, i;
522 post_desc_t *ptr = NULL;
523 post_desc_t *next_phase = NULL;
524 uint8_t pos = plat_get_fru_sel();
525
526 /* Temporary return sample */
527 *next = 0xff;
528 *end = 0x00;
529 memcpy(buffer, "Hello Post", 10);
530 *length = 10;
531 return 0;
532}
533
534/* Need to implement this */
535int plat_udbg_get_gpio_desc(uint8_t index, uint8_t *next, uint8_t *level,
536 uint8_t *def, uint8_t *count, uint8_t *buffer)
537{
538 return 0;
539}
540
541static int udbg_get_cri_sel(uint8_t frame, uint8_t page, uint8_t *next,
542 uint8_t *count, uint8_t *buffer)
543{
544 int len;
545 int ret;
546 char line_buff[FRAME_PAGE_BUF_SIZE], *fptr;
547 const char *ptr;
548 FILE *fp;
549 struct stat file_stat;
550 uint8_t pos = plat_get_fru_sel();
551 static uint8_t pre_pos = FRU_ALL;
552 bool pos_changed = pre_pos != pos;
553
554 pre_pos = pos;
555
556 /* Revisit this */
557 fp = fopen("/mnt/data/cri_sel", "r");
558 if (fp)
559 {
560 if ((stat("/mnt/data/cri_sel", &file_stat) == 0) &&
561 (file_stat.st_mtime != frame_sel.mtime || pos_changed))
562 {
563 // initialize and clear frame
564 frame_sel.init(FRAME_BUFF_SIZE);
565 frame_sel.overwrite = 1;
566 frame_sel.max_page = 20;
567 frame_sel.mtime = file_stat.st_mtime;
568 snprintf(frame_sel.title, 32, "Cri SEL");
569
570 while (fgets(line_buff, FRAME_PAGE_BUF_SIZE, fp))
571 {
572 // Remove newline
573 line_buff[strlen(line_buff) - 1] = '\0';
574 ptr = line_buff;
575 // Find message
576 ptr = strstr(ptr, "local0.err");
577 if (ptr == NULL)
578 {
579 continue;
580 }
581
582 if ((ptr = strrchr(ptr, ':')) == NULL)
583 {
584 continue;
585 }
586 len = strlen(ptr);
587 if (len > 2)
588 {
589 // to skip log string ": "
590 ptr += 2;
591 }
592 // Write new message
593 frame_sel.insert(ptr, 0);
594 }
595 }
596 fclose(fp);
597 }
598 else
599 {
600 // Title only
601 frame_sel.init(FRAME_BUFF_SIZE);
602 snprintf(frame_sel.title, 32, "Cri SEL");
603 frame_sel.mtime = 0;
604 }
605
606 if (page > frame_sel.pages)
607 {
608 return -1;
609 }
610
611 ret = frame_sel.getPage(page, (char *)buffer, FRAME_PAGE_BUF_SIZE);
612 if (ret < 0)
613 {
614 *count = 0;
615 return -1;
616 }
617 *count = (uint8_t)ret;
618
619 if (page < frame_sel.pages)
620 *next = page + 1;
621 else
622 *next = 0xFF; // Set the value of next to 0xFF to indicate this is the
623 // last page
624
625 return 0;
626}
627
628static int udbg_get_cri_sensor(uint8_t frame, uint8_t page, uint8_t *next,
629 uint8_t *count, uint8_t *buffer)
630{
631 char str[32], temp_val[16], temp_thresh[8], print_format[32];
632 int i, ret;
633 float fvalue;
634 sensor_desc_t *cri_sensor = NULL;
635 size_t sensor_count = 0;
636 uint8_t pos = plat_get_fru_sel();
637 uint8_t fru;
638
639 if (page == 1)
640 {
641 // Only update frame data while getting page 1
642
643 // initialize and clear frame
644 frame_snr.init(FRAME_BUFF_SIZE);
645 snprintf(frame_snr.title, 32, "CriSensor");
646 frame_snr.append(str, 0);
647 } // End of update frame
648
649 if (page > frame_snr.pages)
650 {
651 return -1;
652 }
653
654 ret = frame_snr.getPage(page, (char *)buffer, FRAME_PAGE_BUF_SIZE);
655 if (ret < 0)
656 {
657 *count = 0;
658 return -1;
659 }
660 *count = (uint8_t)ret;
661
662 if (page < frame_snr.pages)
663 *next = page + 1;
664 else
665 *next = 0xFF; // Set the value of next to 0xFF to indicate this is the
666 // last page
667
668 return 0;
669}
670
671static int udbg_get_info_page(uint8_t frame, uint8_t page, uint8_t *next,
672 uint8_t *count, uint8_t *buffer)
673{
674 char line_buff[1000], *pres_dev = line_buff;
675 uint8_t pos = plat_get_fru_sel();
676 const char *delim = "\n";
677 int ret;
678 std::string serialName = "BOARD_SERIAL_NUMBER";
679 std::string partName = "BOARD_PART_NUMBER";
680 std::string verDel = "VERSION=";
681 std::string verPath = "/etc/os-release";
682
683 if (page == 1)
684 {
685 // Only update frame data while getting page 1
686
687 // initialize and clear frame
688 frame_info.init(FRAME_BUFF_SIZE);
689 snprintf(frame_info.title, 32, "SYS_Info");
690
691 // FRU TBD:
692 std::string data;
693 frame_info.append("SN:", 0);
694 if (getFruData(data, serialName) != 0)
695 {
696 data = "Not Found";
697 }
698 frame_info.append(data.c_str(), 1);
699 frame_info.append("PN:", 0);
700 if (getFruData(data, partName) != 0)
701 {
702 data = "Not Found";
703 }
704 frame_info.append(data.c_str(), 1);
705
706 // LAN
707 getNetworkData(3, line_buff);
708 frame_info.append("BMC_IP:", 0);
709 frame_info.append(line_buff, 1);
710 getNetworkData(59, line_buff);
711 frame_info.append("BMC_IPv6:", 0);
712 frame_info.append(line_buff, 1);
713
714 // BMC ver
715 std::ifstream file(verPath);
716 if (file)
717 {
718 std::string line;
719 while (std::getline(file, line))
720 {
721 if (line.find(verDel) != std::string::npos)
722 {
723 std::string bmcVer = line.substr(verDel.size());
724 frame_info.append("BMC_FW_ver:", 0);
725 frame_info.append(bmcVer.c_str(), 1);
726 break;
727 }
728 }
729 }
730
731 /* TBD: BIOS ver, ME status and Board ID needs implementation */
732 // BIOS ver
733
734 // ME status
735
736 // Board ID
737
738 // Battery - Use Escape sequence
739 frame_info.append("Battery:", 0);
740 frame_info.append(ESC_BAT " ", 1);
741 // frame_info.append(&frame_info, esc_bat, 1);
742
743 // MCU Version - Use Escape sequence
744 frame_info.append("MCUbl_ver:", 0);
745 frame_info.append(ESC_MCU_BL_VER, 1);
746 frame_info.append("MCU_ver:", 0);
747 frame_info.append(ESC_MCU_RUN_VER, 1);
748
749 // TBD:
750 // Sys config present device
751
752 } // End of update frame
753
754 if (page > frame_info.pages)
755 {
756 return -1;
757 }
758
759 ret = frame_info.getPage(page, (char *)buffer, FRAME_PAGE_BUF_SIZE);
760 if (ret < 0)
761 {
762 *count = 0;
763 return -1;
764 }
765 *count = (uint8_t)ret;
766
767 if (page < frame_info.pages)
768 *next = page + 1;
769 else
770 *next = 0xFF; // Set the value of next to 0xFF to indicate this is the
771 // last page
772
773 return 0;
774}
775
776int plat_udbg_get_frame_data(uint8_t frame, uint8_t page, uint8_t *next,
777 uint8_t *count, uint8_t *buffer)
778{
779 switch (frame)
780 {
781 case 1: // info_page
782 return udbg_get_info_page(frame, page, next, count, buffer);
783 case 2: // critical SEL
784 return udbg_get_cri_sel(frame, page, next, count, buffer);
785 case 3: // critical Sensor
786 return udbg_get_cri_sensor(frame, page, next, count, buffer);
787 default:
788 return -1;
789 }
790}
791
792static uint8_t panel_main(uint8_t item)
793{
794 // Update item list when select item 0
795 switch (item)
796 {
797 case 1:
798 return panels[PANEL_BOOT_ORDER].select(0);
799 case 2:
800 return panels[PANEL_POWER_POLICY].select(0);
801 default:
802 return PANEL_MAIN;
803 }
804}
805
806static uint8_t panel_boot_order(uint8_t item)
807{
808 int i;
809 unsigned char buff[MAX_VALUE_LEN], pickup, len;
810 uint8_t pos = plat_get_fru_sel();
811
812 /* To be implemented */
813 /*
814 if (pos != FRU_ALL && pal_get_boot_order(pos, buff, buff, &len) == 0)
815 {
816 if (item > 0 && item < SIZE_BOOT_ORDER)
817 {
818 pickup = buff[item];
819 while (item > 1)
820 {
821 buff[item] = buff[item -1];
822 item--;
823 }
824 buff[item] = pickup;
825 buff[0] |= 0x80;
826 pal_set_boot_order(pos, buff, buff, &len);
827
828 // refresh items
829 return panels[PANEL_BOOT_ORDER].select(0);
830 }
831
832 // '*': boot flags valid, BIOS has not yet read
833 snprintf(panels[PANEL_BOOT_ORDER].item_str[0], 32,
834 "Boot Order%c", (buff[0] & 0x80)?'*':'\0');
835
836 for (i = 1; i < SIZE_BOOT_ORDER; i++)
837 {
838 switch (buff[i])
839 {
840 case 0x0:
841 snprintf(panels[PANEL_BOOT_ORDER].item_str[i], 32,
842 " USB device");
843 break;
844 case 0x1:
845 snprintf(panels[PANEL_BOOT_ORDER].item_str[i], 32,
846 " Network v4");
847 break;
848 case (0x1 | 0x8):
849 snprintf(panels[PANEL_BOOT_ORDER].item_str[i], 32,
850 " Network v6");
851 break;
852 case 0x2:
853 snprintf(panels[PANEL_BOOT_ORDER].item_str[i], 32,
854 " SATA HDD");
855 break;
856 case 0x3:
857 snprintf(panels[PANEL_BOOT_ORDER].item_str[i], 32,
858 " SATA-CDROM");
859 break;
860 case 0x4:
861 snprintf(panels[PANEL_BOOT_ORDER].item_str[i], 32,
862 " Other");
863 break;
864 default:
865 panels[PANEL_BOOT_ORDER].item_str[i][0] = '\0';
866 break;
867 }
868 }
869
870 // remove empty items
871 for (i--; (strlen(panels[PANEL_BOOT_ORDER].item_str[i]) == 0) && (i > 0); i--)
872 ;
873
874 panels[PANEL_BOOT_ORDER].item_num = i;
875 } else
876 {
877 panels[PANEL_BOOT_ORDER].item_num = 0;
878 }
879 */
880 return PANEL_BOOT_ORDER;
881}
882
883static uint8_t panel_power_policy(uint8_t item)
884{
885 uint8_t buff[32] = {0};
886 uint8_t res_len;
887 uint8_t pos = plat_get_fru_sel();
888 uint8_t policy;
889 // uint8_t pwr_policy_item_map[3] = {POWER_CFG_ON, POWER_CFG_LPS,
890 // POWER_CFG_OFF};
891
892 /* To be cleaned */
893 /*
894 if (pos != FRU_ALL) {
895 if (item > 0 && item <= sizeof(pwr_policy_item_map)) {
896 policy = pwr_policy_item_map[item - 1];
897 pal_set_power_restore_policy(pos, &policy, NULL);
898 }
899 pal_get_chassis_status(pos, NULL, buff, &res_len);
900 policy = (((uint8_t)buff[0]) >> 5) & 0x7;
901 snprintf(panels[PANEL_POWER_POLICY].item_str[1], 32,
902 "%cPower On", policy == POWER_CFG_ON ? '*' : ' ');
903 snprintf(panels[PANEL_POWER_POLICY].item_str[2], 32,
904 "%cLast State", policy == POWER_CFG_LPS ? '*' : ' ');
905 snprintf(panels[PANEL_POWER_POLICY].item_str[3], 32,
906 "%cPower Off", policy == POWER_CFG_OFF ? '*' : ' ');
907 panels[PANEL_POWER_POLICY].item_num = 3;
908 } else {
909 panels[PANEL_POWER_POLICY].item_num = 0;
910 }
911 */
912 return PANEL_POWER_POLICY;
913}
914
915int plat_udbg_control_panel(uint8_t panel, uint8_t operation, uint8_t item,
916 uint8_t *count, uint8_t *buffer)
917{
918 if (panel > panelNum || panel < PANEL_MAIN)
919 return IPMI_CC_PARM_OUT_OF_RANGE;
920
921 // No more item; End of item list
922 if (item > panels[panel].item_num)
923 return IPMI_CC_PARM_OUT_OF_RANGE;
924
925 switch (operation)
926 {
927 case 0: // Get Description
928 break;
929 case 1: // Select item
930 panel = panels[panel].select(item);
931 item = 0;
932 break;
933 case 2: // Back
934 panel = panels[panel].parent;
935 item = 0;
936 break;
937 default:
938 return IPMI_CC_PARM_OUT_OF_RANGE;
939 }
940
941 buffer[0] = panel;
942 buffer[1] = item;
943 buffer[2] = strlen(panels[panel].item_str[item]);
944 if (buffer[2] > 0 && (buffer[2] + 3) < FRAME_PAGE_BUF_SIZE)
945 {
946 memcpy(&buffer[3], panels[panel].item_str[item], buffer[2]);
947 }
948 *count = buffer[2] + 3;
949 return IPMI_CC_OK;
950}
951
952} // end of namespace ipmi