Clone a tag rather than SeaBIOS stable branch HEAD
[coreboot.git] / payloads / coreinfo / bootlog_module.c
1 /*
2  * This file is part of the coreinfo project.
3  *
4  * Copyright (C) 2008 Uwe Hermann <uwe@hermann-uwe.de>
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 #ifdef CONFIG_MODULE_BOOTLOG
23
24 #define CONFIG_COREBOOT_PRINTK_BUFFER_ADDR 0x90000
25 #define CONFIG_COREBOOT_PRINTK_BUFFER_SIZE 65536
26
27 static char *buf;
28 static s32 cursor = 0;
29 static s32 cursor_max;
30
31 static int bootlog_module_init(void)
32 {
33         int i;
34         volatile unsigned long *ptr =
35                 (void *)(CONFIG_COREBOOT_PRINTK_BUFFER_ADDR + 16); /* FIXME */
36
37         buf = malloc(CONFIG_COREBOOT_PRINTK_BUFFER_SIZE);
38         if (!buf) {
39                 /* TODO */
40         }
41
42         memcpy(buf, (char *)ptr, CONFIG_COREBOOT_PRINTK_BUFFER_SIZE);
43
44         cursor_max = CONFIG_COREBOOT_PRINTK_BUFFER_SIZE;
45         for (i = 0; i < 20; i++) {
46                 do {
47                         cursor_max--;
48                 } while (*(buf + cursor_max) != '\n');
49         }
50         cursor_max++;   /* Stay _behind_ the newline. */
51
52         /* TODO: Maybe a _cleanup hook where we call free()? */
53
54         return 0;
55 }
56
57 static int bootlog_module_redraw(WINDOW *win)
58 {
59         int x = 0, y = 0;
60         char *tmp = buf + cursor;
61
62         print_module_title(win, "Coreboot Bootlog");
63
64         /* FIXME: Handle lines longer than 80 characters. */
65         while (y <= 18) {
66                 mvwaddch(win, y + 2, x, isprint(*tmp) ? *tmp : ' ');
67                 x++;
68                 tmp++;
69                 if (*tmp == '\n') {
70                         y++;
71                         x = 0;
72                         tmp++;          /* Skip the newline. */
73                 }
74         }
75
76         return 0;
77 }
78
79 /* TODO: Simplify code. */
80 static int bootlog_module_handle(int key)
81 {
82         int i;
83
84         switch (key) {
85         case KEY_DOWN:
86                 if (cursor == cursor_max)
87                         return 0;
88                 while (*(buf + cursor) != '\n')
89                         cursor++;
90                 cursor++;       /* Skip the newline. */
91                 break;
92         case KEY_UP:
93                 if (cursor == 0)
94                         return 0;
95                 cursor--;       /* Skip the newline. */
96                 do {
97                         cursor--;
98                 } while (*(buf + cursor) != '\n');
99                 cursor++;       /* Stay _behind_ the newline. */
100                 break;
101         case KEY_NPAGE:
102                 if (cursor == cursor_max)
103                         return 0;
104                 for (i = 0; i < 20; i++) {
105                         while (*(buf + cursor) != '\n')
106                                 cursor++;
107                         cursor++;       /* Skip the newline. */
108                 }
109                 break;
110         case KEY_PPAGE:
111                 if (cursor == 0)
112                         return 0;
113                 for (i = 0; i < 20; i++) {
114                         do {
115                                 cursor--;
116                         } while (*(buf + cursor) != '\n');
117                 }
118                 cursor++;       /* Stay _behind_ the newline. */
119                 break;
120         }
121
122         if (cursor > cursor_max)
123                 cursor = cursor_max;
124
125         if (cursor < 0)
126                 cursor = 0;
127
128         return 1;
129 }
130
131 struct coreinfo_module bootlog_module = {
132         .name = "Bootlog",
133         .init = bootlog_module_init,
134         .redraw = bootlog_module_redraw,
135         .handle = bootlog_module_handle,
136 };
137
138 #else
139
140 struct coreinfo_module bootlog_module = {
141 };
142
143 #endif