[PATCH] coreinfo: Add multiboot parsing support
[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
36 struct coreinfo_module *system_modules[] = {
37 #ifdef CONFIG_MODULE_CPUINFO
38         &cpuinfo_module,
39 #endif
40 #ifdef CONFIG_MODULE_PCI
41         &pci_module,
42 #endif
43 #ifdef CONFIG_MODULE_NVRAM
44         &nvram_module,
45 #endif
46 #ifdef CONFIG_MODULE_RAMDUMP
47         &ramdump_module,
48 #endif
49 };
50
51 struct coreinfo_module *firmware_modules[] = {
52 #ifdef CONFIG_MODULE_COREBOOT
53         &coreboot_module,
54 #endif
55 #ifdef CONFIG_MODULE_MULTIBOOT
56         &multiboot_module,
57 #endif
58 #ifdef CONFIG_MODULE_BOOTLOG
59         &bootlog_module,
60 #endif
61 #ifdef CONFIG_MODULE_LAR
62         &lar_module
63 #endif
64 };
65
66 struct coreinfo_cat {
67         char name[15];
68         int cur;
69         int count;
70         struct coreinfo_module **modules;
71 } categories[] = {
72         {
73                 .name = "System",
74                 .modules = system_modules,
75                 .count = ARRAY_SIZE(system_modules),
76         },
77         {
78                 .name = "Firmware",
79                 .modules = firmware_modules,
80                 .count = ARRAY_SIZE(firmware_modules),
81         }
82 };
83
84 static WINDOW *modwin, *menuwin;
85 static int curwin;
86
87 void print_module_title(WINDOW *win, const char *title)
88 {
89         int i;
90
91         wattrset(win, COLOR_PAIR(2));
92         mvwprintw(win, 0, 1, title);
93
94         wmove(win, 1, 1);
95         for (i = 0; i < 78; i++)
96                 waddch(win, ACS_HLINE);
97 }
98
99 static void print_submenu(struct coreinfo_cat *cat)
100 {
101         int i, j;
102         char menu[80];
103         char *ptr = menu;
104
105         wmove(menuwin, 0, 0);
106
107         for (j = 0; j < SCREEN_X; j++)
108                 waddch(menuwin, ' ');
109
110         if (!cat->count)
111                 return;
112
113         for (i = 0; i < cat->count; i++)
114                 ptr += sprintf(ptr, "[%c: %s] ", 'A' + i,
115                                cat->modules[i]->name);
116
117         mvwprintw(menuwin, 0, 0, menu);
118 }
119
120 #ifdef CONFIG_SHOW_DATE_TIME
121 static void print_time_and_date(void)
122 {
123         struct tm tm;
124
125         while (nvram_updating())
126                 mdelay(10);
127
128         rtc_read_clock(&tm);
129
130         mvwprintw(menuwin, 0, 57, "%02d/%02d/%04d - %02d:%02d:%02d",
131                   tm.tm_mon, tm.tm_mday, 1900 + tm.tm_year, tm.tm_hour,
132                   tm.tm_min, tm.tm_sec);
133 }
134 #endif
135
136 static void print_menu(void)
137 {
138         int i, j;
139         char menu[80];
140         char *ptr = menu;
141
142         wmove(menuwin, 1, 0);
143         for (j = 0; j < SCREEN_X; j++)
144                 waddch(menuwin, ' ');
145
146         for (i = 0; i < ARRAY_SIZE(categories); i++) {
147                 if (categories[i].count == 0)
148                         continue;
149
150                 ptr += sprintf(ptr, "F%d: %s ", i + 1, categories[i].name);
151         }
152
153         mvwprintw(menuwin, 1, 0, menu);
154
155 #ifdef CONFIG_SHOW_DATE_TIME
156         print_time_and_date();
157 #endif
158 }
159
160 static void center(int row, const char *str)
161 {
162         int j, len = strlen(str);
163
164         wmove(stdscr, row, 0);
165         for (j = 0; j < SCREEN_X; j++)
166                 waddch(stdscr, ' ');
167
168         mvprintw(row, (SCREEN_X - len) / 2, str);
169 }
170
171 /* FIXME: Currently unused. */
172 #if 0
173 static void header(int row, const char *str)
174 {
175         char buf[SCREEN_X];
176         char *ptr = buf;
177         int i;
178         int len = strlen(str) + 4;
179
180         for (i = 0; i < (SCREEN_X - len) / 2; i++)
181                 ptr += sprintf(ptr, "=");
182
183         ptr += sprintf(ptr, "[ %s ]", str);
184
185         for (i = ((SCREEN_X - len) / 2) + len; i < SCREEN_X; i++)
186                 ptr += sprintf(ptr, "=");
187
188         mvprintw(row, 0, buf);
189 }
190 #endif
191
192 static void redraw_module(struct coreinfo_cat *cat)
193 {
194         if (cat->count == 0)
195                 return;
196
197         wclear(modwin);
198         cat->modules[cat->cur]->redraw(modwin);
199         wrefresh(modwin);
200 }
201
202 static void handle_category_key(struct coreinfo_cat *cat, int key)
203 {
204         if (key >= 'a' && key <= 'z') {
205                 int index = key - 'a';
206                 if (index < cat->count) {
207                         cat->cur = index;
208                         redraw_module(cat);
209                         return;
210                 }
211         }
212
213         if (cat->count && cat->modules[cat->cur]->handle) {
214                 if (cat->modules[cat->cur]->handle(key))
215                         redraw_module(cat);
216         }
217 }
218
219 static void loop(void)
220 {
221         int key;
222
223         center(0, CONFIG_PAYLOAD_INFO_NAME " " CONFIG_PAYLOAD_INFO_VERSION);
224         refresh();
225
226         print_menu();
227         print_submenu(&categories[curwin]);
228         redraw_module(&categories[curwin]);
229
230         halfdelay(10);
231
232         while (1) {
233 #ifdef CONFIG_SHOW_DATE_TIME
234                 print_time_and_date();
235                 wrefresh(menuwin);
236 #endif
237
238                 key = getch();
239
240                 if (key == ERR)
241                         continue;
242
243                 if (key >= KEY_F(1) && key <= KEY_F(9)) {
244                         unsigned char ch = key - KEY_F(1);
245
246                         if (ch <= ARRAY_SIZE(categories)) {
247                                 if (ch == ARRAY_SIZE(categories))
248                                         continue;
249                                 if (categories[ch].count == 0)
250                                         continue;
251
252                                 curwin = ch;
253                                 print_submenu(&categories[curwin]);
254                                 redraw_module(&categories[curwin]);
255                                 continue;
256                         }
257                 }
258
259                 if (key == KEY_ESC)
260                         return;
261
262                 handle_category_key(&categories[curwin], key);
263         }
264 }
265
266 int main(void)
267 {
268         int i, j;
269
270         initscr();
271
272         init_pair(1, COLOR_WHITE, COLOR_GREEN);
273         init_pair(2, COLOR_BLACK, COLOR_WHITE);
274         init_pair(3, COLOR_WHITE, COLOR_WHITE);
275
276         modwin = newwin(SCREEN_Y - 3, SCREEN_X, 1, 0);
277         menuwin = newwin(2, SCREEN_X, SCREEN_Y - 2, 0);
278
279         wattrset(stdscr, COLOR_PAIR(1) | A_BOLD);
280         wattrset(modwin, COLOR_PAIR(2));
281         wattrset(menuwin, COLOR_PAIR(1) | A_BOLD);
282
283         werase(modwin);
284
285         for (i = 0; i < ARRAY_SIZE(categories); i++) {
286                 for (j = 0; j < categories[i].count; j++)
287                         categories[i].modules[j]->init();
288         }
289
290         loop();
291
292         return 0;
293 }
294
295 PAYLOAD_INFO(name, CONFIG_PAYLOAD_INFO_NAME);
296 PAYLOAD_INFO(listname, CONFIG_PAYLOAD_INFO_LISTNAME);
297 PAYLOAD_INFO(desc, CONFIG_PAYLOAD_INFO_DESC);