3f49f53ef2418f1407809d58d67b3cfbac9a22f1
[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 nvram_module;
31 extern struct coreinfo_module bootlog_module;
32 extern struct coreinfo_module ramdump_module;
33 extern struct coreinfo_module lar_module;
34
35 struct coreinfo_module *system_modules[] = {
36 #ifdef CONFIG_MODULE_CPUINFO
37         &cpuinfo_module,
38 #endif
39 #ifdef CONFIG_MODULE_PCI
40         &pci_module,
41 #endif
42 #ifdef CONFIG_MODULE_NVRAM
43         &nvram_module,
44 #endif
45 #ifdef CONFIG_MODULE_RAMDUMP
46         &ramdump_module,
47 #endif
48 };
49
50 struct coreinfo_module *coreboot_modules[] = {
51 #ifdef CONFIG_MODULE_COREBOOT
52         &coreboot_module,
53 #endif
54 #ifdef CONFIG_MODULE_BOOTLOG
55         &bootlog_module,
56 #endif
57 #ifdef CONFIG_MODULE_LAR
58         &lar_module
59 #endif
60 };
61
62 struct coreinfo_cat {
63         char name[15];
64         int cur;
65         int count;
66         struct coreinfo_module **modules;
67 } categories[] = {
68         {
69                 .name = "System",
70                 .modules = system_modules,
71                 .count = ARRAY_SIZE(system_modules),
72         },
73         {
74                 .name = "Coreboot",
75                 .modules = coreboot_modules,
76                 .count = ARRAY_SIZE(coreboot_modules),
77         }
78 };
79
80
81 static WINDOW *modwin;
82 static WINDOW *menuwin;
83
84 static int curwin;
85
86 void print_module_title(WINDOW *win, const char *title)
87 {
88         int i;
89
90         wattrset(win, COLOR_PAIR(2));
91         mvwprintw(win, 0, 1, title);
92
93         wmove(win, 1, 1);
94
95         for (i = 0; i < 78; i++)
96                 waddch(win, '\304');
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, cat->modules[i]->name);
115
116         mvwprintw(menuwin, 0, 0, menu);
117 }
118
119 #ifdef CONFIG_SHOW_DATE_TIME
120 static void print_time_and_date(void)
121 {
122         struct tm tm;
123
124         while(nvram_updating())
125                 mdelay(10);
126
127         rtc_read_clock(&tm);
128
129         mvwprintw(menuwin, 0, 57, "%02d/%02d/%04d - %02d:%02d:%02d",
130                 tm.tm_mon, tm.tm_mday, 1900+tm.tm_year, tm.tm_hour,
131                 tm.tm_min, tm.tm_sec);
132 }
133 #endif
134
135 static void print_menu(void)
136 {
137         int i, j;
138         char menu[80];
139         char *ptr = menu;
140
141         wmove(menuwin, 1, 0);
142
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 len = strlen(str);
163         int j;
164
165         wmove(stdscr, row, 0);
166
167         for (j = 0; j < SCREEN_X; j++)
168                 waddch(stdscr, ' ');
169
170         mvprintw(row, (SCREEN_X - len) / 2, str);
171 }
172
173 /* FIXME: Currently unused. */
174 #if 0
175 static void header(int row, const char *str)
176 {
177         char buf[SCREEN_X];
178         char *ptr = buf;
179         int i;
180         int len = strlen(str) + 4;
181
182         for (i = 0; i < (SCREEN_X - len) / 2; i++)
183                 ptr += sprintf(ptr, "=");
184
185         ptr += sprintf(ptr, "[ %s ]", str);
186
187
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
211                 if (index < cat->count) {
212
213                 cat->cur = index;
214                         redraw_module(cat);
215                         return;
216                 }
217         }
218
219         if (cat->count && cat->modules[cat->cur]->handle) {
220                 if (cat->modules[cat->cur]->handle(key))
221                         redraw_module(cat);
222         }
223 }
224
225 static void loop(void)
226 {
227         int key;
228
229         center(0, "coreinfo v0.1");
230         refresh();
231
232         print_menu();
233         print_submenu(&categories[curwin]);
234         redraw_module(&categories[curwin]);
235
236         halfdelay(10);
237
238         while (1) {
239 #ifdef CONFIG_SHOW_DATE_TIME
240                 print_time_and_date();
241                 wrefresh(menuwin);
242 #endif
243
244                 key = getch();
245
246                 if (key == ERR)
247                         continue;
248
249                 if (key >= KEY_F(1) && key <= KEY_F(9)) {
250                         unsigned char ch = key - KEY_F(1);
251
252                         if (ch <= ARRAY_SIZE(categories)) {
253                                 if (ch == ARRAY_SIZE(categories))
254                                         continue;
255                                 if (categories[ch].count == 0)
256                                         continue;
257
258                                 curwin = ch;
259                                 print_submenu(&categories[curwin]);
260                                 redraw_module(&categories[curwin]);
261                                 continue;
262                         }
263                 }
264
265                 if (key == KEY_ESC)
266                         return;
267
268                 handle_category_key(&categories[curwin], key);
269         }
270 }
271
272 int main(void)
273 {
274         int i, j;
275
276         initscr();
277
278         init_pair(1, COLOR_WHITE, COLOR_GREEN);
279         init_pair(2, COLOR_BLACK, COLOR_WHITE);
280         init_pair(3, COLOR_WHITE, COLOR_WHITE);
281
282         modwin = newwin(SCREEN_Y - 3, SCREEN_X, 1, 0);
283         menuwin = newwin(2, SCREEN_X, SCREEN_Y - 2, 0);
284
285         wattrset(stdscr, COLOR_PAIR(1) | A_BOLD);
286         wattrset(modwin, COLOR_PAIR(2));
287         wattrset(menuwin, COLOR_PAIR(1) | A_BOLD);
288
289         for (i = 0; i < SCREEN_Y - 1; i++) {
290                 wmove(modwin, i - 1, 0);
291
292                 for (j = 0; j < SCREEN_X; j++)
293                         waddch(modwin, ' ');
294         }
295
296         wrefresh(modwin);
297
298         for (i = 0; i < ARRAY_SIZE(categories); i++) {
299                 for(j = 0; j < categories[i].count; j++)
300                         categories[i].modules[j]->init();
301
302         }
303
304         loop();
305
306         return 0;
307 }
308
309 PAYLOAD_INFO(name,"coreinfo");
310 PAYLOAD_INFO(listname,"System Information");
311 PAYLOAD_INFO(desc,"Display information about the system");