blob: 93c90e7da90214bf024386a32b78fde44d1955e7 [file] [log] [blame]
Jacob Garber07201d72020-09-08 12:25:44 -06001/* SPDX-License-Identifier: GPL-2.0-only */
Uwe Hermann941c1fd2009-07-07 15:10:13 +00002
3#include "coreinfo.h"
Gabe Black0af03d22012-03-19 03:06:46 -07004#include "endian.h"
Uwe Hermann941c1fd2009-07-07 15:10:13 +00005
Julius Wernereab2a292019-03-05 16:55:15 -08006#if CONFIG(MODULE_CBFS)
Uwe Hermann941c1fd2009-07-07 15:10:13 +00007
Ben Gardnerd770bad2016-04-29 12:45:43 -05008#define FILES_VISIBLE 19
9
Uwe Hermann941c1fd2009-07-07 15:10:13 +000010#define HEADER_MAGIC 0x4F524243
11#define HEADER_ADDR 0xfffffffc
12#define LARCHIVE_MAGIC 0x455649484352414cLL /* "LARCHIVE" */
13
14#define COMPONENT_DELETED 0x00
Jonathan Neuschäfer53685042016-03-10 05:37:27 +010015#define COMPONENT_BOOTBLOCK 0x01
16#define COMPONENT_CBFSHEADER 0x02
Uwe Hermann941c1fd2009-07-07 15:10:13 +000017#define COMPONENT_STAGE 0x10
Patrick Rudolph4f5bed52018-05-02 09:44:08 +020018#define COMPONENT_SELF 0x20
Patrick Rudolph7ee05ed2018-04-26 09:35:13 +020019#define COMPONENT_FIT 0x21
Uwe Hermann941c1fd2009-07-07 15:10:13 +000020#define COMPONENT_OPTIONROM 0x30
Jonathan Neuschäfer53685042016-03-10 05:37:27 +010021#define COMPONENT_RAW 0x50
22#define COMPONENT_MICROCODE 0x53
23#define COMPONENT_CMOS_LAYOUT 0x1aa
Uwe Hermann941c1fd2009-07-07 15:10:13 +000024#define COMPONENT_NULL 0xffffffff
25
26struct cbheader {
27 u32 magic;
28 u32 version;
29 u32 romsize;
30 u32 bootblocksize;
31 u32 align;
32 u32 offset;
David Hendricks90ca3b62012-11-16 14:48:22 -080033 u32 architecture;
34 u32 pad[1];
Stefan Reinauer6a001132017-07-13 02:20:27 +020035} __packed;
Uwe Hermann941c1fd2009-07-07 15:10:13 +000036
37struct cbfile {
38 u64 magic;
39 u32 len;
40 u32 type;
41 u32 checksum;
42 u32 offset;
43 char filename[0];
Stefan Reinauer6a001132017-07-13 02:20:27 +020044} __packed;
Uwe Hermann941c1fd2009-07-07 15:10:13 +000045
Ben Gardnerd770bad2016-04-29 12:45:43 -050046static int filecount = 0, selected = 0, start_row = 0;
Uwe Hermann941c1fd2009-07-07 15:10:13 +000047static char **filenames;
48static struct cbheader *header = NULL;
49
50static struct cbfile *getfile(struct cbfile *f)
51{
52 while (1) {
53 if (f < (struct cbfile *)(0xffffffff - ntohl(header->romsize)))
54 return NULL;
55 if (f->magic == 0)
56 return NULL;
57 if (f->magic == LARCHIVE_MAGIC)
58 return f;
Richard Spiegelb93796d2018-10-29 08:01:53 -070059 f = (struct cbfile *)((u8 *)f + ntohl(header->align));
Uwe Hermann941c1fd2009-07-07 15:10:13 +000060 }
61}
62
63static struct cbfile *firstfile(void)
64{
65 return getfile((void *)(0 - ntohl(header->romsize) +
66 ntohl(header->offset)));
67}
68
69static struct cbfile *nextfile(struct cbfile *f)
70{
Elyes Haouasd6b6b222022-10-10 12:34:21 +020071 f = (struct cbfile *)((u8 *)f + ALIGN_UP(ntohl(f->len) + ntohl(f->offset),
Richard Spiegelb93796d2018-10-29 08:01:53 -070072 ntohl(header->align)));
Uwe Hermann941c1fd2009-07-07 15:10:13 +000073 return getfile(f);
74}
75
76static struct cbfile *findfile(const char *filename)
77{
78 struct cbfile *f;
79 for (f = firstfile(); f; f = nextfile(f)) {
80 if (strcmp(filename, f->filename) == 0)
81 return f;
82 }
83 return NULL;
84}
85
86static int cbfs_module_init(void)
87{
88 struct cbfile *f;
89 int index = 0;
90
91 header = *(void **)HEADER_ADDR;
92 if (header->magic != ntohl(HEADER_MAGIC)) {
93 header = NULL;
94 return 0;
95 }
96
97 for (f = firstfile(); f; f = nextfile(f))
98 filecount++;
99
100 filenames = malloc(filecount * sizeof(char *));
101 if (filenames == NULL)
102 return 0;
103
104 for (f = firstfile(); f; f = nextfile(f))
105 filenames[index++] = strdup((const char *)f->filename);
106
107 return 0;
108}
109
110static int cbfs_module_redraw(WINDOW * win)
111{
112 struct cbfile *f;
Ben Gardnerd770bad2016-04-29 12:45:43 -0500113 int i, row, frow;
Uwe Hermann941c1fd2009-07-07 15:10:13 +0000114
115 print_module_title(win, "CBFS Listing");
116
117 if (!header) {
118 mvwprintw(win, 11, 61 / 2, "Bad or missing CBFS header");
119 return 0;
120 }
121
122 /* Draw a line down the middle. */
123 for (i = 2; i < 21; i++)
124 mvwaddch(win, i, 30, ACS_VLINE);
125
126 /* Draw the names down the left side. */
Ben Gardnerd770bad2016-04-29 12:45:43 -0500127 for (frow = 0; frow < FILES_VISIBLE; frow++) {
128 row = 2 + frow;
129 i = start_row + frow;
130 if (i >= filecount)
131 break;
Uwe Hermann941c1fd2009-07-07 15:10:13 +0000132 if (i == selected)
133 wattrset(win, COLOR_PAIR(3) | A_BOLD);
134 else
135 wattrset(win, COLOR_PAIR(2));
Jonathan Neuschäfer1aca8b82016-03-10 04:32:46 +0100136
137 if (strlen(filenames[i]) == 0) {
138 if (findfile(filenames[i])->type == COMPONENT_NULL)
Ben Gardnerd770bad2016-04-29 12:45:43 -0500139 mvwprintw(win, row, 1, "<free space>");
Jonathan Neuschäfer1aca8b82016-03-10 04:32:46 +0100140 else
Ben Gardnerd770bad2016-04-29 12:45:43 -0500141 mvwprintw(win, row, 1, "<unnamed>");
Jonathan Neuschäfer1aca8b82016-03-10 04:32:46 +0100142 } else {
Ben Gardnerd770bad2016-04-29 12:45:43 -0500143 mvwprintw(win, row, 1, "%.25s", filenames[i]);
144 }
145 /* show scroll arrows */
146 if (frow == 0 && start_row > 0) {
147 wattrset(win, COLOR_PAIR(2));
148 mvwaddch(win, row, 28, ACS_UARROW);
149 }
150 if (frow == FILES_VISIBLE - 1 && i != filecount - 1) {
151 wattrset(win, COLOR_PAIR(2));
152 mvwaddch(win, row, 28, ACS_DARROW);
Jonathan Neuschäfer1aca8b82016-03-10 04:32:46 +0100153 }
Uwe Hermann941c1fd2009-07-07 15:10:13 +0000154 }
155
156 f = findfile(filenames[selected]);
157 if (!f) {
158 mvwprintw(win, 11, 32, "ERROR: CBFS component not found");
159 return 0;
160 }
161
162 wattrset(win, COLOR_PAIR(2));
163
Ben Gardnerd770bad2016-04-29 12:45:43 -0500164 /* Draw the file information */
165 row = 2;
Uwe Hermann941c1fd2009-07-07 15:10:13 +0000166 /* mvwprintw(win, row++, 32, "Offset: 0x%x", f->offset); *//* FIXME */
167 mvwprintw(win, row, 32, "Type: ");
168 switch (ntohl(f->type)) {
Jonathan Neuschäfer53685042016-03-10 05:37:27 +0100169 case COMPONENT_BOOTBLOCK:
170 mvwprintw(win, row++, 38, "bootblock");
171 break;
172 case COMPONENT_CBFSHEADER:
173 mvwprintw(win, row++, 38, "CBFS header");
174 break;
Uwe Hermann941c1fd2009-07-07 15:10:13 +0000175 case COMPONENT_STAGE:
176 mvwprintw(win, row++, 38, "stage");
177 break;
Patrick Rudolph4f5bed52018-05-02 09:44:08 +0200178 case COMPONENT_SELF:
Ronald G. Minnichc6d13492018-05-15 18:05:07 -0700179 mvwprintw(win, row++, 38, "simple ELF");
Uwe Hermann941c1fd2009-07-07 15:10:13 +0000180 break;
Patrick Rudolph7ee05ed2018-04-26 09:35:13 +0200181 case COMPONENT_FIT:
182 mvwprintw(win, row++, 38, "FIT");
183 break;
Uwe Hermann941c1fd2009-07-07 15:10:13 +0000184 case COMPONENT_OPTIONROM:
185 mvwprintw(win, row++, 38, "optionrom");
186 break;
Jonathan Neuschäfer53685042016-03-10 05:37:27 +0100187 case COMPONENT_RAW:
188 mvwprintw(win, row++, 38, "raw");
189 break;
190 case COMPONENT_MICROCODE:
191 mvwprintw(win, row++, 38, "microcode");
192 break;
193 case COMPONENT_CMOS_LAYOUT:
194 mvwprintw(win, row++, 38, "cmos layout");
195 break;
Uwe Hermann941c1fd2009-07-07 15:10:13 +0000196 case COMPONENT_NULL:
197 mvwprintw(win, row++, 38, "free");
198 break;
199 case COMPONENT_DELETED:
200 mvwprintw(win, row++, 38, "deleted");
201 break;
202 default:
203 mvwprintw(win, row++, 38, "Unknown (0x%x)", ntohl(f->type));
204 break;
205 }
206 mvwprintw(win, row++, 32, "Size: %d", ntohl(f->len));
207 mvwprintw(win, row++, 32, "Checksum: 0x%x", ntohl(f->checksum));
208
209 return 0;
210}
211
212static int cbfs_module_handle(int key)
213{
214 int ret = 0;
215
216 if (filecount == 0)
217 return 0;
218
219 switch (key) {
220 case KEY_DOWN:
221 if (selected + 1 < filecount) {
222 selected++;
Ben Gardnerd770bad2016-04-29 12:45:43 -0500223 if (selected >= start_row + FILES_VISIBLE - 1)
224 start_row = selected - (FILES_VISIBLE - 1);
Uwe Hermann941c1fd2009-07-07 15:10:13 +0000225 ret = 1;
226 }
227 break;
228 case KEY_UP:
229 if (selected > 0) {
230 selected--;
Ben Gardnerd770bad2016-04-29 12:45:43 -0500231 if (selected < start_row)
232 start_row = selected;
Uwe Hermann941c1fd2009-07-07 15:10:13 +0000233 ret = 1;
234 }
235 break;
236 }
237
238 return ret;
239}
240
241struct coreinfo_module cbfs_module = {
242 .name = "CBFS",
243 .init = cbfs_module_init,
244 .redraw = cbfs_module_redraw,
245 .handle = cbfs_module_handle
246};
247
248#else
249
250struct coreinfo_module cbfs_module = {
251};
252
253#endif