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