330 lines
6.5 KiB
C
330 lines
6.5 KiB
C
/*
|
|
* This file is part of the coreinfo project.
|
|
*
|
|
* Copyright (C) 2008 Advanced Micro Devices, Inc.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; version 2 of the License.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*/
|
|
|
|
#include "coreinfo.h"
|
|
|
|
#define KEY_ESC 27
|
|
|
|
extern struct coreinfo_module cpuinfo_module;
|
|
extern struct coreinfo_module pci_module;
|
|
extern struct coreinfo_module coreboot_module;
|
|
extern struct coreinfo_module multiboot_module;
|
|
extern struct coreinfo_module nvram_module;
|
|
extern struct coreinfo_module bootlog_module;
|
|
extern struct coreinfo_module ramdump_module;
|
|
extern struct coreinfo_module cbfs_module;
|
|
|
|
struct coreinfo_module *system_modules[] = {
|
|
#if IS_ENABLED(CONFIG_MODULE_CPUINFO)
|
|
&cpuinfo_module,
|
|
#endif
|
|
#if IS_ENABLED(CONFIG_MODULE_PCI)
|
|
&pci_module,
|
|
#endif
|
|
#if IS_ENABLED(CONFIG_MODULE_NVRAM)
|
|
&nvram_module,
|
|
#endif
|
|
#if IS_ENABLED(CONFIG_MODULE_RAMDUMP)
|
|
&ramdump_module,
|
|
#endif
|
|
};
|
|
|
|
struct coreinfo_module *firmware_modules[] = {
|
|
#if IS_ENABLED(CONFIG_MODULE_COREBOOT)
|
|
&coreboot_module,
|
|
#endif
|
|
#if IS_ENABLED(CONFIG_MODULE_MULTIBOOT)
|
|
&multiboot_module,
|
|
#endif
|
|
#if IS_ENABLED(CONFIG_MODULE_BOOTLOG)
|
|
&bootlog_module,
|
|
#endif
|
|
#if IS_ENABLED(CONFIG_MODULE_CBFS)
|
|
&cbfs_module,
|
|
#endif
|
|
};
|
|
|
|
struct coreinfo_cat {
|
|
char name[15];
|
|
int cur;
|
|
int count;
|
|
struct coreinfo_module **modules;
|
|
} categories[] = {
|
|
{
|
|
.name = "System",
|
|
.modules = system_modules,
|
|
.count = ARRAY_SIZE(system_modules),
|
|
},
|
|
{
|
|
.name = "Firmware",
|
|
.modules = firmware_modules,
|
|
.count = ARRAY_SIZE(firmware_modules),
|
|
}
|
|
};
|
|
|
|
static WINDOW *modwin, *menuwin;
|
|
static int curwin;
|
|
|
|
void print_module_title(WINDOW *win, const char *title)
|
|
{
|
|
int i;
|
|
|
|
wattrset(win, COLOR_PAIR(2));
|
|
mvwprintw(win, 0, 1, title);
|
|
|
|
wmove(win, 1, 1);
|
|
for (i = 0; i < 78; i++)
|
|
waddch(win, ACS_HLINE);
|
|
}
|
|
|
|
static void print_submenu(struct coreinfo_cat *cat)
|
|
{
|
|
int i, j;
|
|
char menu[80];
|
|
char *ptr = menu;
|
|
|
|
wmove(menuwin, 0, 0);
|
|
|
|
for (j = 0; j < SCREEN_X; j++)
|
|
waddch(menuwin, ' ');
|
|
|
|
if (!cat->count)
|
|
return;
|
|
|
|
for (i = 0; i < cat->count; i++)
|
|
ptr += sprintf(ptr, "[%c: %s] ", 'A' + i,
|
|
cat->modules[i]->name);
|
|
|
|
mvwprintw(menuwin, 0, 0, menu);
|
|
}
|
|
|
|
#if IS_ENABLED(CONFIG_SHOW_DATE_TIME)
|
|
static void print_time_and_date(void)
|
|
{
|
|
struct tm tm;
|
|
|
|
while (nvram_updating())
|
|
mdelay(10);
|
|
|
|
rtc_read_clock(&tm);
|
|
|
|
mvwprintw(menuwin, 1, 57, "%02d/%02d/%04d - %02d:%02d:%02d",
|
|
tm.tm_mon + 1, tm.tm_mday, 1900 + tm.tm_year, tm.tm_hour,
|
|
tm.tm_min, tm.tm_sec);
|
|
}
|
|
#endif
|
|
|
|
static void print_menu(void)
|
|
{
|
|
int i, j;
|
|
char menu[80];
|
|
char *ptr = menu;
|
|
|
|
wmove(menuwin, 1, 0);
|
|
for (j = 0; j < SCREEN_X; j++)
|
|
waddch(menuwin, ' ');
|
|
|
|
for (i = 0; i < ARRAY_SIZE(categories); i++) {
|
|
if (categories[i].count == 0)
|
|
continue;
|
|
|
|
ptr += sprintf(ptr, "F%d: %s ", i + 1, categories[i].name);
|
|
}
|
|
|
|
mvwprintw(menuwin, 1, 0, menu);
|
|
|
|
#if IS_ENABLED(CONFIG_SHOW_DATE_TIME)
|
|
print_time_and_date();
|
|
#endif
|
|
}
|
|
|
|
static void center(int row, const char *str)
|
|
{
|
|
int j, len = strlen(str);
|
|
|
|
wmove(stdscr, row, 0);
|
|
for (j = 0; j < SCREEN_X; j++)
|
|
waddch(stdscr, ' ');
|
|
|
|
mvprintw(row, (SCREEN_X - len) / 2, str);
|
|
}
|
|
|
|
/* FIXME: Currently unused. */
|
|
#if 0
|
|
static void header(int row, const char *str)
|
|
{
|
|
char buf[SCREEN_X];
|
|
char *ptr = buf;
|
|
int i;
|
|
int len = strlen(str) + 4;
|
|
|
|
for (i = 0; i < (SCREEN_X - len) / 2; i++)
|
|
ptr += sprintf(ptr, "=");
|
|
|
|
ptr += sprintf(ptr, "[ %s ]", str);
|
|
|
|
for (i = ((SCREEN_X - len) / 2) + len; i < SCREEN_X; i++)
|
|
ptr += sprintf(ptr, "=");
|
|
|
|
mvprintw(row, 0, buf);
|
|
}
|
|
#endif
|
|
|
|
static void redraw_module(struct coreinfo_cat *cat)
|
|
{
|
|
if (cat->count == 0)
|
|
return;
|
|
|
|
wclear(modwin);
|
|
cat->modules[cat->cur]->redraw(modwin);
|
|
wrefresh(modwin);
|
|
}
|
|
|
|
static void handle_category_key(struct coreinfo_cat *cat, int key)
|
|
{
|
|
if (key >= 'a' && key <= 'z') {
|
|
int index = key - 'a';
|
|
if (index < cat->count) {
|
|
cat->cur = index;
|
|
redraw_module(cat);
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (cat->count && cat->modules[cat->cur]->handle) {
|
|
if (cat->modules[cat->cur]->handle(key))
|
|
redraw_module(cat);
|
|
}
|
|
}
|
|
|
|
static void print_no_modules_selected(void)
|
|
{
|
|
int height = getmaxy(stdscr), i;
|
|
|
|
for (i = 0; i < ARRAY_SIZE(categories); i++)
|
|
if (categories[i].count > 0)
|
|
return;
|
|
|
|
color_set(2, NULL); // White on black
|
|
center(height / 2, "No modules selected");
|
|
}
|
|
|
|
static int first_nonempty_category(void)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < ARRAY_SIZE(categories); i++)
|
|
if (categories[i].count > 0)
|
|
return i;
|
|
return 0;
|
|
}
|
|
|
|
static void loop(void)
|
|
{
|
|
int key;
|
|
|
|
center(0, CONFIG_PAYLOAD_INFO_NAME " " CONFIG_PAYLOAD_INFO_VERSION);
|
|
print_no_modules_selected();
|
|
refresh();
|
|
|
|
curwin = first_nonempty_category();
|
|
print_menu();
|
|
print_submenu(&categories[curwin]);
|
|
redraw_module(&categories[curwin]);
|
|
|
|
halfdelay(10);
|
|
|
|
while (1) {
|
|
int ch = -1;
|
|
|
|
#if IS_ENABLED(CONFIG_SHOW_DATE_TIME)
|
|
print_time_and_date();
|
|
wrefresh(menuwin);
|
|
#endif
|
|
|
|
key = getch();
|
|
|
|
if (key == ERR)
|
|
continue;
|
|
|
|
if (key >= KEY_F(1) && key <= KEY_F(9))
|
|
ch = key - KEY_F(1);
|
|
if (key >= '1' && key <= '9')
|
|
ch = key - '1';
|
|
|
|
if (ch >= 0 && ch <= ARRAY_SIZE(categories)) {
|
|
if (ch == ARRAY_SIZE(categories))
|
|
continue;
|
|
if (categories[ch].count == 0)
|
|
continue;
|
|
|
|
curwin = ch;
|
|
print_submenu(&categories[curwin]);
|
|
redraw_module(&categories[curwin]);
|
|
continue;
|
|
}
|
|
|
|
if (key == KEY_ESC)
|
|
return;
|
|
|
|
handle_category_key(&categories[curwin], key);
|
|
}
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
int i, j;
|
|
|
|
#if IS_ENABLED(CONFIG_LP_USB)
|
|
usb_initialize();
|
|
#endif
|
|
|
|
initscr();
|
|
|
|
start_color();
|
|
init_pair(1, COLOR_WHITE, COLOR_GREEN);
|
|
init_pair(2, COLOR_WHITE, COLOR_BLACK);
|
|
init_pair(3, COLOR_BLACK, COLOR_WHITE);
|
|
|
|
modwin = newwin(SCREEN_Y - 3, SCREEN_X, 1, 0);
|
|
menuwin = newwin(2, SCREEN_X, SCREEN_Y - 2, 0);
|
|
|
|
wattrset(stdscr, COLOR_PAIR(1) | A_BOLD);
|
|
wattrset(modwin, COLOR_PAIR(2));
|
|
wattrset(menuwin, COLOR_PAIR(1) | A_BOLD);
|
|
|
|
werase(modwin);
|
|
|
|
for (i = 0; i < ARRAY_SIZE(categories); i++) {
|
|
for (j = 0; j < categories[i].count; j++)
|
|
categories[i].modules[j]->init();
|
|
}
|
|
|
|
noecho(); /* don't let curses echo keyboard chars */
|
|
keypad(stdscr, TRUE); /* allow KEY_F(n) keys to be seen */
|
|
curs_set(0); /* Hide blinking cursor */
|
|
|
|
loop();
|
|
|
|
/* reboot */
|
|
outb(0x6, 0xcf9);
|
|
halt();
|
|
return 0;
|
|
}
|
|
|
|
PAYLOAD_INFO(name, CONFIG_PAYLOAD_INFO_NAME);
|
|
PAYLOAD_INFO(listname, CONFIG_PAYLOAD_INFO_LISTNAME);
|
|
PAYLOAD_INFO(desc, CONFIG_PAYLOAD_INFO_DESC);
|