Clone a tag rather than SeaBIOS stable branch HEAD
[coreboot.git] / payloads / coreinfo / coreinfo.c
1 /*
2  * This file is part of the coreinfo project.
3  *
4  * Copyright (C) 2008 Advanced Micro Devices, Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; version 2 of the License.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
18  */
19
20 #include "coreinfo.h"
21
22 #define SCREEN_Y 25
23 #define SCREEN_X 80
24
25 #define KEY_ESC 27
26
27 extern struct coreinfo_module cpuinfo_module;
28 extern struct coreinfo_module pci_module;
29 extern struct coreinfo_module coreboot_module;
30 extern struct coreinfo_module multiboot_module;
31 extern struct coreinfo_module nvram_module;
32 extern struct coreinfo_module bootlog_module;
33 extern struct coreinfo_module ramdump_module;
34 extern struct coreinfo_module lar_module;
35 extern struct coreinfo_module cbfs_module;
36
37 struct coreinfo_module *system_modules[] = {
38 #ifdef CONFIG_MODULE_CPUINFO
39         &cpuinfo_module,
40 #endif
41 #ifdef CONFIG_MODULE_PCI
42         &pci_module,
43 #endif
44 #ifdef CONFIG_MODULE_NVRAM
45         &nvram_module,
46 #endif
47 #ifdef CONFIG_MODULE_RAMDUMP
48         &ramdump_module,
49 #endif
50 };
51
52 struct coreinfo_module *firmware_modules[] = {
53 #ifdef CONFIG_MODULE_COREBOOT
54         &coreboot_module,
55 #endif
56 #ifdef CONFIG_MODULE_MULTIBOOT
57         &multiboot_module,
58 #endif
59 #ifdef CONFIG_MODULE_BOOTLOG
60         &bootlog_module,
61 #endif
62 #ifdef CONFIG_MODULE_LAR
63         &lar_module,
64 #endif
65 #ifdef CONFIG_MODULE_CBFS
66         &cbfs_module,
67 #endif
68 };
69
70 struct coreinfo_cat {
71         char name[15];
72         int cur;
73         int count;
74         struct coreinfo_module **modules;
75 } categories[] = {
76         {
77                 .name = "System",
78                 .modules = system_modules,
79                 .count = ARRAY_SIZE(system_modules),
80         },
81         {
82                 .name = "Firmware",
83                 .modules = firmware_modules,
84                 .count = ARRAY_SIZE(firmware_modules),
85         }
86 };
87
88 static WINDOW *modwin, *menuwin;
89 static int curwin;
90
91 void print_module_title(WINDOW *win, const char *title)
92 {
93         int i;
94
95         wattrset(win, COLOR_PAIR(2));
96         mvwprintw(win, 0, 1, title);
97
98         wmove(win, 1, 1);
99         for (i = 0; i < 78; i++)
100                 waddch(win, ACS_HLINE);
101 }
102
103 static void print_submenu(struct coreinfo_cat *cat)
104 {
105         int i, j;
106         char menu[80];
107         char *ptr = menu;
108
109         wmove(menuwin, 0, 0);
110
111         for (j = 0; j < SCREEN_X; j++)
112                 waddch(menuwin, ' ');
113
114         if (!cat->count)
115                 return;
116
117         for (i = 0; i < cat->count; i++)
118                 ptr += sprintf(ptr, "[%c: %s] ", 'A' + i,
119                                cat->modules[i]->name);
120
121         mvwprintw(menuwin, 0, 0, menu);
122 }
123
124 #ifdef CONFIG_SHOW_DATE_TIME
125 static void print_time_and_date(void)
126 {
127         struct tm tm;
128
129         while (nvram_updating())
130                 mdelay(10);
131
132         rtc_read_clock(&tm);
133
134         mvwprintw(menuwin, 0, 57, "%02d/%02d/%04d - %02d:%02d:%02d",
135                   tm.tm_mon, tm.tm_mday, 1900 + tm.tm_year, tm.tm_hour,
136                   tm.tm_min, tm.tm_sec);
137 }
138 #endif
139
140 static void print_menu(void)
141 {
142         int i, j;
143         char menu[80];
144         char *ptr = menu;
145
146         wmove(menuwin, 1, 0);
147         for (j = 0; j < SCREEN_X; j++)
148                 waddch(menuwin, ' ');
149
150         for (i = 0; i < ARRAY_SIZE(categories); i++) {
151                 if (categories[i].count == 0)
152                         continue;
153
154                 ptr += sprintf(ptr, "F%d: %s ", i + 1, categories[i].name);
155         }
156
157         mvwprintw(menuwin, 1, 0, menu);
158
159 #ifdef CONFIG_SHOW_DATE_TIME
160         print_time_and_date();
161 #endif
162 }
163
164 static void center(int row, const char *str)
165 {
166         int j, len = strlen(str);
167
168         wmove(stdscr, row, 0);
169         for (j = 0; j < SCREEN_X; j++)
170                 waddch(stdscr, ' ');
171
172         mvprintw(row, (SCREEN_X - len) / 2, str);
173 }
174
175 /* FIXME: Currently unused. */
176 #if 0
177 static void header(int row, const char *str)
178 {
179         char buf[SCREEN_X];
180         char *ptr = buf;
181         int i;
182         int len = strlen(str) + 4;
183
184         for (i = 0; i < (SCREEN_X - len) / 2; i++)
185                 ptr += sprintf(ptr, "=");
186
187         ptr += sprintf(ptr, "[ %s ]", str);
188
189         for (i = ((SCREEN_X - len) / 2) + len; i < SCREEN_X; i++)
190                 ptr += sprintf(ptr, "=");
191
192         mvprintw(row, 0, buf);
193 }
194 #endif
195
196 static void redraw_module(struct coreinfo_cat *cat)
197 {
198         if (cat->count == 0)
199                 return;
200
201         wclear(modwin);
202         cat->modules[cat->cur]->redraw(modwin);
203         wrefresh(modwin);
204 }
205
206 static void handle_category_key(struct coreinfo_cat *cat, int key)
207 {
208         if (key >= 'a' && key <= 'z') {
209                 int index = key - 'a';
210                 if (index < cat->count) {
211                         cat->cur = index;
212                         redraw_module(cat);
213                         return;
214                 }
215         }
216
217         if (cat->count && cat->modules[cat->cur]->handle) {
218                 if (cat->modules[cat->cur]->handle(key))
219                         redraw_module(cat);
220         }
221 }
222
223 static void loop(void)
224 {
225         int key;
226
227         center(0, CONFIG_PAYLOAD_INFO_NAME " " CONFIG_PAYLOAD_INFO_VERSION);
228         refresh();
229
230         print_menu();
231         print_submenu(&categories[curwin]);
232         redraw_module(&categories[curwin]);
233
234         halfdelay(10);
235
236         while (1) {
237 #ifdef CONFIG_SHOW_DATE_TIME
238                 print_time_and_date();
239                 wrefresh(menuwin);
240 #endif
241
242                 key = getch();
243
244                 if (key == ERR)
245                         continue;
246
247                 if (key >= KEY_F(1) && key <= KEY_F(9)) {
248                         unsigned char ch = key - KEY_F(1);
249
250                         if (ch <= ARRAY_SIZE(categories)) {
251                                 if (ch == ARRAY_SIZE(categories))
252                                         continue;
253                                 if (categories[ch].count == 0)
254                                         continue;
255
256                                 curwin = ch;
257                                 print_submenu(&categories[curwin]);
258                                 redraw_module(&categories[curwin]);
259                                 continue;
260                         }
261                 }
262
263                 if (key == KEY_ESC)
264                         return;
265
266                 handle_category_key(&categories[curwin], key);
267         }
268 }
269
270 int main(void)
271 {
272         int i, j;
273
274         initscr();
275
276         init_pair(1, COLOR_WHITE, COLOR_GREEN);
277         init_pair(2, COLOR_BLACK, COLOR_WHITE);
278         init_pair(3, COLOR_WHITE, COLOR_WHITE);
279
280         modwin = newwin(SCREEN_Y - 3, SCREEN_X, 1, 0);
281         menuwin = newwin(2, SCREEN_X, SCREEN_Y - 2, 0);
282
283         wattrset(stdscr, COLOR_PAIR(1) | A_BOLD);
284         wattrset(modwin, COLOR_PAIR(2));
285         wattrset(menuwin, COLOR_PAIR(1) | A_BOLD);
286
287         werase(modwin);
288
289         for (i = 0; i < ARRAY_SIZE(categories); i++) {
290                 for (j = 0; j < categories[i].count; j++)
291                         categories[i].modules[j]->init();
292         }
293
294         loop();
295
296         return 0;
297 }
298
299 PAYLOAD_INFO(name, CONFIG_PAYLOAD_INFO_NAME);
300 PAYLOAD_INFO(listname, CONFIG_PAYLOAD_INFO_LISTNAME);
301 PAYLOAD_INFO(desc, CONFIG_PAYLOAD_INFO_DESC);