1 /* SPDX-License-Identifier: GPL-2.0-only */
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
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
)
53 if (f
< (struct cbfile
*)(0xffffffff - ntohl(header
->romsize
)))
57 if (f
->magic
== LARCHIVE_MAGIC
)
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
)));
76 static struct cbfile
*findfile(const char *filename
)
79 for (f
= firstfile(); f
; f
= nextfile(f
)) {
80 if (strcmp(filename
, f
->filename
) == 0)
86 static int cbfs_module_init(void)
91 header
= *(void **)HEADER_ADDR
;
92 if (header
->magic
!= ntohl(HEADER_MAGIC
)) {
97 for (f
= firstfile(); f
; f
= nextfile(f
))
100 filenames
= malloc(filecount
* sizeof(char *));
101 if (filenames
== NULL
)
104 for (f
= firstfile(); f
; f
= nextfile(f
))
105 filenames
[index
++] = strdup((const char *)f
->filename
);
110 static int cbfs_module_redraw(WINDOW
* win
)
115 print_module_title(win
, "CBFS Listing");
118 mvwprintw(win
, 11, 61 / 2, "Bad or missing CBFS header");
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
++) {
129 i
= start_row
+ frow
;
133 wattrset(win
, COLOR_PAIR(3) | A_BOLD
);
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>");
141 mvwprintw(win
, row
, 1, "<unnamed>");
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
]);
158 mvwprintw(win
, 11, 32, "ERROR: CBFS component not found");
162 wattrset(win
, COLOR_PAIR(2));
164 /* Draw the file information */
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");
172 case COMPONENT_CBFSHEADER
:
173 mvwprintw(win
, row
++, 38, "CBFS header");
175 case COMPONENT_STAGE
:
176 mvwprintw(win
, row
++, 38, "stage");
179 mvwprintw(win
, row
++, 38, "simple ELF");
182 mvwprintw(win
, row
++, 38, "FIT");
184 case COMPONENT_OPTIONROM
:
185 mvwprintw(win
, row
++, 38, "optionrom");
188 mvwprintw(win
, row
++, 38, "raw");
190 case COMPONENT_MICROCODE
:
191 mvwprintw(win
, row
++, 38, "microcode");
193 case COMPONENT_CMOS_LAYOUT
:
194 mvwprintw(win
, row
++, 38, "cmos layout");
197 mvwprintw(win
, row
++, 38, "free");
199 case COMPONENT_DELETED
:
200 mvwprintw(win
, row
++, 38, "deleted");
203 mvwprintw(win
, row
++, 38, "Unknown (0x%x)", ntohl(f
->type
));
206 mvwprintw(win
, row
++, 32, "Size: %d", ntohl(f
->len
));
207 mvwprintw(win
, row
++, 32, "Checksum: 0x%x", ntohl(f
->checksum
));
212 static int cbfs_module_handle(int key
)
221 if (selected
+ 1 < filecount
) {
223 if (selected
>= start_row
+ FILES_VISIBLE
- 1)
224 start_row
= selected
- (FILES_VISIBLE
- 1);
231 if (selected
< start_row
)
232 start_row
= selected
;
241 struct coreinfo_module cbfs_module
= {
243 .init
= cbfs_module_init
,
244 .redraw
= cbfs_module_redraw
,
245 .handle
= cbfs_module_handle
250 struct coreinfo_module cbfs_module
= {