f7e8d88149ed71c15fbae71ff5436fd79e8a4de1
[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 extern struct coreinfo_module cpuinfo_module;
26 extern struct coreinfo_module pci_module;
27 extern struct coreinfo_module coreboot_module;
28 extern struct coreinfo_module nvram_module;
29 extern struct coreinfo_module bootlog_module;
30 extern struct coreinfo_module lar_module;
31
32 struct coreinfo_module *system_modules[] = {
33 #ifdef CONFIG_MODULE_CPUINFO
34         &cpuinfo_module,
35 #endif
36 #ifdef CONFIG_MODULE_PCI
37         &pci_module,
38 #endif
39 #ifdef CONFIG_MODULE_NVRAM
40         &nvram_module,
41 #endif
42 };
43
44 struct coreinfo_module *coreboot_modules[] = {
45 #ifdef CONFIG_MODULE_COREBOOT
46         &coreboot_module,
47 #endif
48 #ifdef CONFIG_MODULE_BOOTLOG
49         &bootlog_module,
50 #endif
51 #ifdef CONFIG_MODULE_LAR
52         &lar_module
53 #endif
54 };
55
56 struct coreinfo_cat {
57         char name[15];
58         int cur;
59         int count;
60         struct coreinfo_module **modules;
61 } categories[] = {
62         {
63                 .name = "System",
64                 .modules = system_modules,
65                 .count = ARRAY_SIZE(system_modules),
66         },
67         {
68                 .name = "Coreboot",
69                 .modules = coreboot_modules,
70                 .count = ARRAY_SIZE(coreboot_modules),
71         }
72 };
73
74
75 static WINDOW *modwin;
76 static WINDOW *menuwin;
77
78 static int curwin;
79
80 void print_module_title(WINDOW *win, const char *title)
81 {
82         int i;
83
84         wattrset(win, COLOR_PAIR(2));
85         mvwprintw(win, 0, 1, title);
86
87         wmove(win, 1, 1);
88
89         for (i = 0; i < 78; i++)
90                 waddch(win, '\304');
91 }
92
93 static void print_submenu(struct coreinfo_cat *cat)
94 {
95         int i, j;
96         char menu[80];
97         char *ptr = menu;
98
99         wmove(menuwin, 0, 0);
100
101         for (j = 0; j < SCREEN_X; j++)
102                 waddch(menuwin, ' ');
103
104         if (!cat->count)
105                 return;
106
107         for (i = 0; i < cat->count; i++)
108                 ptr += sprintf(ptr, "[%c: %s] ", 'A' + i, cat->modules[i]->name);
109
110         mvwprintw(menuwin, 0, 0, menu);
111 }
112
113 #ifdef CONFIG_SHOW_DATE_TIME
114 static void print_time_and_date(void)
115 {
116         struct tm tm;
117
118         while(nvram_updating())
119                 mdelay(10);
120
121         rtc_read_clock(&tm);
122
123         mvwprintw(menuwin, 0, 57, "%02d/%02d/%04d - %02d:%02d:%02d",
124                 tm.tm_mon, tm.tm_mday, 1900+tm.tm_year, tm.tm_hour,
125                 tm.tm_min, tm.tm_sec);
126 }
127 #endif
128
129 static void print_menu(void)
130 {
131         int i, j;
132         char menu[80];
133         char *ptr = menu;
134
135         wmove(menuwin, 1, 0);
136
137         for (j = 0; j < SCREEN_X; j++)
138                 waddch(menuwin, ' ');
139
140         for (i = 0; i < ARRAY_SIZE(categories); i++) {
141                 if (categories[i].count == 0)
142                         continue;
143
144                 ptr += sprintf(ptr, "F%d: %s ", i + 1, categories[i].name);
145         }
146
147         mvwprintw(menuwin, 1, 0, menu);
148
149 #ifdef CONFIG_SHOW_DATE_TIME
150         print_time_and_date();
151 #endif
152 }
153
154 static void center(int row, const char *str)
155 {
156         int len = strlen(str);
157         int j;
158
159         wmove(stdscr, row, 0);
160
161         for (j = 0; j < SCREEN_X; j++)
162                 waddch(stdscr, ' ');
163
164         mvprintw(row, (SCREEN_X - len) / 2, str);
165 }
166
167 /* FIXME: Currently unused. */
168 #if 0
169 static void header(int row, const char *str)
170 {
171         char buf[SCREEN_X];
172         char *ptr = buf;
173         int i;
174         int len = strlen(str) + 4;
175
176         for (i = 0; i < (SCREEN_X - len) / 2; i++)
177                 ptr += sprintf(ptr, "=");
178
179         ptr += sprintf(ptr, "[ %s ]", str);
180
181
182
183         for (i = ((SCREEN_X - len) / 2) + len; i < SCREEN_X; i++)
184                 ptr += sprintf(ptr, "=");
185
186         mvprintw(row, 0, buf);
187 }
188 #endif
189
190 static void redraw_module(struct coreinfo_cat *cat)
191 {
192         if (cat->count == 0)
193                 return;
194
195         wclear(modwin);
196         cat->modules[cat->cur]->redraw(modwin);
197         wrefresh(modwin);
198 }
199
200 static void handle_category_key(struct coreinfo_cat *cat, int key)
201 {
202         if (key >= 'a' && key <= 'z') {
203                 int index = key - 'a';
204
205                 if (index < cat->count) {
206
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, "coreinfo v0.1");
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
260                 handle_category_key(&categories[curwin], key);
261         }
262 }
263
264 int main(void)
265 {
266         int i, j;
267
268         curses_enable_serial(0);
269         curses_enable_vga(1);
270
271         initscr();
272
273         init_pair(1, COLOR_WHITE, COLOR_GREEN);
274         init_pair(2, COLOR_BLACK, COLOR_WHITE);
275         init_pair(3, COLOR_WHITE, COLOR_WHITE);
276
277         modwin = newwin(SCREEN_Y - 3, SCREEN_X, 1, 0);
278         menuwin = newwin(2, SCREEN_X, SCREEN_Y - 2, 0);
279
280         wattrset(stdscr, COLOR_PAIR(1) | A_BOLD);
281         wattrset(modwin, COLOR_PAIR(2));
282         wattrset(menuwin, COLOR_PAIR(1) | A_BOLD);
283
284         for (i = 0; i < SCREEN_Y - 1; i++) {
285                 wmove(modwin, i - 1, 0);
286
287                 for (j = 0; j < SCREEN_X; j++)
288                         waddch(modwin, ' ');
289         }
290
291         wrefresh(modwin);
292
293         for (i = 0; i < ARRAY_SIZE(categories); i++) {
294                 for(j = 0; j < categories[i].count; j++)
295                         categories[i].modules[j]->init();
296
297         }
298
299         loop();
300
301         return 0;
302 }