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