mb/google/nissa/var/rull: when using pcie wifi7, turn off CNVI BT
[coreboot2.git] / payloads / coreinfo / cbfs_module.c
blobc8fa7e2eb233b8007c330d48d09e4efa7ae6b84f
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include "coreinfo.h"
4 #include "endian.h"
6 #if CONFIG(MODULE_CBFS)
8 #define FILES_VISIBLE 19
10 #define HEADER_MAGIC 0x4F524243
11 #define HEADER_ADDR 0xfffffffc
12 #define LARCHIVE_MAGIC 0x455649484352414cLL /* "LARCHIVE" */
14 #define COMPONENT_DELETED 0x00
15 #define COMPONENT_BOOTBLOCK 0x01
16 #define COMPONENT_CBFSHEADER 0x02
17 #define COMPONENT_STAGE 0x10
18 #define COMPONENT_SELF 0x20
19 #define COMPONENT_FIT 0x21
20 #define COMPONENT_OPTIONROM 0x30
21 #define COMPONENT_RAW 0x50
22 #define COMPONENT_MICROCODE 0x53
23 #define COMPONENT_CMOS_LAYOUT 0x1aa
24 #define COMPONENT_NULL 0xffffffff
26 struct cbheader {
27 u32 magic;
28 u32 version;
29 u32 romsize;
30 u32 bootblocksize;
31 u32 align;
32 u32 offset;
33 u32 architecture;
34 u32 pad[];
35 } __packed;
37 struct cbfile {
38 u64 magic;
39 u32 len;
40 u32 type;
41 u32 checksum;
42 u32 offset;
43 char filename[];
44 } __packed;
46 static int filecount = 0, selected = 0, start_row = 0;
47 static char **filenames;
48 static struct cbheader *header = NULL;
50 static struct cbfile *getfile(struct cbfile *f)
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;
59 f = (struct cbfile *)((u8 *)f + ntohl(header->align));
63 static struct cbfile *firstfile(void)
65 return getfile((void *)(0 - ntohl(header->romsize) +
66 ntohl(header->offset)));
69 static struct cbfile *nextfile(struct cbfile *f)
71 f = (struct cbfile *)((u8 *)f + ALIGN_UP(ntohl(f->len) + ntohl(f->offset),
72 ntohl(header->align)));
73 return getfile(f);
76 static struct cbfile *findfile(const char *filename)
78 struct cbfile *f;
79 for (f = firstfile(); f; f = nextfile(f)) {
80 if (strcmp(filename, f->filename) == 0)
81 return f;
83 return NULL;
86 static int cbfs_module_init(void)
88 struct cbfile *f;
89 int index = 0;
91 header = *(void **)HEADER_ADDR;
92 if (header->magic != ntohl(HEADER_MAGIC)) {
93 header = NULL;
94 return 0;
97 for (f = firstfile(); f; f = nextfile(f))
98 filecount++;
100 filenames = malloc(filecount * sizeof(char *));
101 if (filenames == NULL)
102 return 0;
104 for (f = firstfile(); f; f = nextfile(f))
105 filenames[index++] = strdup((const char *)f->filename);
107 return 0;
110 static int cbfs_module_redraw(WINDOW * win)
112 struct cbfile *f;
113 int i, row, frow;
115 print_module_title(win, "CBFS Listing");
117 if (!header) {
118 mvwprintw(win, 11, 61 / 2, "Bad or missing CBFS header");
119 return 0;
122 /* Draw a line down the middle. */
123 for (i = 2; i < 21; i++)
124 mvwaddch(win, i, 30, ACS_VLINE);
126 /* Draw the names down the left side. */
127 for (frow = 0; frow < FILES_VISIBLE; frow++) {
128 row = 2 + frow;
129 i = start_row + frow;
130 if (i >= filecount)
131 break;
132 if (i == selected)
133 wattrset(win, COLOR_PAIR(3) | A_BOLD);
134 else
135 wattrset(win, COLOR_PAIR(2));
137 if (strlen(filenames[i]) == 0) {
138 if (findfile(filenames[i])->type == COMPONENT_NULL)
139 mvwprintw(win, row, 1, "<free space>");
140 else
141 mvwprintw(win, row, 1, "<unnamed>");
142 } else {
143 mvwprintw(win, row, 1, "%.25s", filenames[i]);
145 /* show scroll arrows */
146 if (frow == 0 && start_row > 0) {
147 wattrset(win, COLOR_PAIR(2));
148 mvwaddch(win, row, 28, ACS_UARROW);
150 if (frow == FILES_VISIBLE - 1 && i != filecount - 1) {
151 wattrset(win, COLOR_PAIR(2));
152 mvwaddch(win, row, 28, ACS_DARROW);
156 f = findfile(filenames[selected]);
157 if (!f) {
158 mvwprintw(win, 11, 32, "ERROR: CBFS component not found");
159 return 0;
162 wattrset(win, COLOR_PAIR(2));
164 /* Draw the file information */
165 row = 2;
166 /* mvwprintw(win, row++, 32, "Offset: 0x%x", f->offset); *//* FIXME */
167 mvwprintw(win, row, 32, "Type: ");
168 switch (ntohl(f->type)) {
169 case COMPONENT_BOOTBLOCK:
170 mvwprintw(win, row++, 38, "bootblock");
171 break;
172 case COMPONENT_CBFSHEADER:
173 mvwprintw(win, row++, 38, "CBFS header");
174 break;
175 case COMPONENT_STAGE:
176 mvwprintw(win, row++, 38, "stage");
177 break;
178 case COMPONENT_SELF:
179 mvwprintw(win, row++, 38, "simple ELF");
180 break;
181 case COMPONENT_FIT:
182 mvwprintw(win, row++, 38, "FIT");
183 break;
184 case COMPONENT_OPTIONROM:
185 mvwprintw(win, row++, 38, "optionrom");
186 break;
187 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;
196 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;
206 mvwprintw(win, row++, 32, "Size: %d", ntohl(f->len));
207 mvwprintw(win, row++, 32, "Checksum: 0x%x", ntohl(f->checksum));
209 return 0;
212 static int cbfs_module_handle(int key)
214 int ret = 0;
216 if (filecount == 0)
217 return 0;
219 switch (key) {
220 case KEY_DOWN:
221 if (selected + 1 < filecount) {
222 selected++;
223 if (selected >= start_row + FILES_VISIBLE - 1)
224 start_row = selected - (FILES_VISIBLE - 1);
225 ret = 1;
227 break;
228 case KEY_UP:
229 if (selected > 0) {
230 selected--;
231 if (selected < start_row)
232 start_row = selected;
233 ret = 1;
235 break;
238 return ret;
241 struct coreinfo_module cbfs_module = {
242 .name = "CBFS",
243 .init = cbfs_module_init,
244 .redraw = cbfs_module_redraw,
245 .handle = cbfs_module_handle
248 #else
250 struct coreinfo_module cbfs_module = {
253 #endif