From 941c1fd52a96fd3e238d1798127a137e4c4eb659 Mon Sep 17 00:00:00 2001 From: Uwe Hermann Date: Tue, 7 Jul 2009 15:10:13 +0000 Subject: Add initial support for a CBFS module for coreinfo. Currently it prints a list of components in CBFS and their size/type. There's a bunch of additional output that could be printed, but that's for another patch. Signed-off-by: Uwe Hermann Acked-by: Myles Watson git-svn-id: svn://svn.coreboot.org/coreboot/trunk@4404 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1 --- payloads/coreinfo/Kconfig | 10 +- payloads/coreinfo/Makefile | 2 +- payloads/coreinfo/cbfs_module.c | 221 ++++++++++++++++++++++++++++++++++++++++ payloads/coreinfo/coreinfo.c | 6 +- 4 files changed, 235 insertions(+), 4 deletions(-) create mode 100644 payloads/coreinfo/cbfs_module.c diff --git a/payloads/coreinfo/Kconfig b/payloads/coreinfo/Kconfig index 26ff6ad719..461cd24999 100644 --- a/payloads/coreinfo/Kconfig +++ b/payloads/coreinfo/Kconfig @@ -34,7 +34,7 @@ config SHOW_DATE_TIME Show the current date and time in the lower-right corner of the coreinfo menu. - This option will increase the ELF file size by ca. 256 bytes. + This option will increase the ELF file size by ca. 250 bytes. config PAYLOAD_INFO_NAME string "Payload name" @@ -74,7 +74,7 @@ config MODULE_MULTIBOOT bool "Enable the multiboot module" default y help - This option will increase the ELF file size by ca. 1792 bytes. + This option will increase the ELF file size by ca. 1790 bytes. config MODULE_CPUINFO bool "Enable the cpuinfo module" @@ -106,5 +106,11 @@ config MODULE_LAR bool "Enable the coreboot LAR module" default y +config MODULE_CBFS + bool "Enable the coreboot CBFS module" + default y + help + This option will increase the ELF file size by ca. 1440 bytes. + endmenu diff --git a/payloads/coreinfo/Makefile b/payloads/coreinfo/Makefile index ed5ee288d8..59af713962 100644 --- a/payloads/coreinfo/Makefile +++ b/payloads/coreinfo/Makefile @@ -53,7 +53,7 @@ INCLUDES = -Ibuild CFLAGS := -Wall -Werror -Os $(INCLUDES) OBJECTS = cpuinfo_module.o cpuid.S.o pci_module.o coreboot_module.o \ nvram_module.o bootlog_module.o ramdump_module.o lar_module.o \ - multiboot_module.o coreinfo.o + multiboot_module.o cbfs_module.o coreinfo.o OBJS = $(patsubst %,$(obj)/%,$(OBJECTS)) TARGET = $(obj)/coreinfo.elf diff --git a/payloads/coreinfo/cbfs_module.c b/payloads/coreinfo/cbfs_module.c new file mode 100644 index 0000000000..274356dd2e --- /dev/null +++ b/payloads/coreinfo/cbfs_module.c @@ -0,0 +1,221 @@ +/* + * This file is part of the coreinfo project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "coreinfo.h" +#include "arch/endian.h" + +#ifdef CONFIG_MODULE_CBFS + +#define ALIGN(_v, _a) (((_v) + ((_a) - 1)) & ~((_a) - 1)) + +#define HEADER_MAGIC 0x4F524243 +#define HEADER_ADDR 0xfffffffc +#define LARCHIVE_MAGIC 0x455649484352414cLL /* "LARCHIVE" */ + +#define COMPONENT_DELETED 0x00 +#define COMPONENT_STAGE 0x10 +#define COMPONENT_PAYLOAD 0x20 +#define COMPONENT_OPTIONROM 0x30 +#define COMPONENT_NULL 0xffffffff + +struct cbheader { + u32 magic; + u32 version; + u32 romsize; + u32 bootblocksize; + u32 align; + u32 offset; + u32 pad[2]; +} __attribute__ ((packed)); + +struct cbfile { + u64 magic; + u32 len; + u32 type; + u32 checksum; + u32 offset; + char filename[0]; +} __attribute__ ((packed)); + +static int filecount = 0, selected = 0; +static char **filenames; +static struct cbheader *header = NULL; + +static struct cbfile *getfile(struct cbfile *f) +{ + while (1) { + if (f < (struct cbfile *)(0xffffffff - ntohl(header->romsize))) + return NULL; + if (f->magic == 0) + return NULL; + if (f->magic == LARCHIVE_MAGIC) + return f; + f = (void *)f + ntohl(header->align); + } +} + +static struct cbfile *firstfile(void) +{ + return getfile((void *)(0 - ntohl(header->romsize) + + ntohl(header->offset))); +} + +static struct cbfile *nextfile(struct cbfile *f) +{ + f = (void *)f + ALIGN(ntohl(f->len) + ntohl(f->offset), + ntohl(header->align)); + return getfile(f); +} + +static struct cbfile *findfile(const char *filename) +{ + struct cbfile *f; + for (f = firstfile(); f; f = nextfile(f)) { + if (strcmp(filename, f->filename) == 0) + return f; + } + return NULL; +} + +static int cbfs_module_init(void) +{ + struct cbfile *f; + int index = 0; + + header = *(void **)HEADER_ADDR; + if (header->magic != ntohl(HEADER_MAGIC)) { + header = NULL; + return 0; + } + + for (f = firstfile(); f; f = nextfile(f)) + filecount++; + + filenames = malloc(filecount * sizeof(char *)); + if (filenames == NULL) + return 0; + + for (f = firstfile(); f; f = nextfile(f)) + filenames[index++] = strdup((const char *)f->filename); + + return 0; +} + +static int cbfs_module_redraw(WINDOW * win) +{ + struct cbfile *f; + int i, row = 2; + + print_module_title(win, "CBFS Listing"); + + if (!header) { + mvwprintw(win, 11, 61 / 2, "Bad or missing CBFS header"); + return 0; + } + + /* Draw a line down the middle. */ + for (i = 2; i < 21; i++) + mvwaddch(win, i, 30, ACS_VLINE); + + /* Draw the names down the left side. */ + for (i = 0; i < filecount; i++) { + if (i == selected) + wattrset(win, COLOR_PAIR(3) | A_BOLD); + else + wattrset(win, COLOR_PAIR(2)); + if (i == filecount - 1) + mvwprintw(win, 2 + i, 1, ""); + else + mvwprintw(win, 2 + i, 1, "%.25s", filenames[i]); + } + + f = findfile(filenames[selected]); + if (!f) { + mvwprintw(win, 11, 32, "ERROR: CBFS component not found"); + return 0; + } + + wattrset(win, COLOR_PAIR(2)); + + /* mvwprintw(win, row++, 32, "Offset: 0x%x", f->offset); *//* FIXME */ + mvwprintw(win, row, 32, "Type: "); + switch (ntohl(f->type)) { + case COMPONENT_STAGE: + mvwprintw(win, row++, 38, "stage"); + break; + case COMPONENT_PAYLOAD: + mvwprintw(win, row++, 38, "payload"); + break; + case COMPONENT_OPTIONROM: + mvwprintw(win, row++, 38, "optionrom"); + break; + case COMPONENT_NULL: + mvwprintw(win, row++, 38, "free"); + break; + case COMPONENT_DELETED: + mvwprintw(win, row++, 38, "deleted"); + break; + default: + mvwprintw(win, row++, 38, "Unknown (0x%x)", ntohl(f->type)); + break; + } + mvwprintw(win, row++, 32, "Size: %d", ntohl(f->len)); + mvwprintw(win, row++, 32, "Checksum: 0x%x", ntohl(f->checksum)); + + return 0; +} + +static int cbfs_module_handle(int key) +{ + int ret = 0; + + if (filecount == 0) + return 0; + + switch (key) { + case KEY_DOWN: + if (selected + 1 < filecount) { + selected++; + ret = 1; + } + break; + case KEY_UP: + if (selected > 0) { + selected--; + ret = 1; + } + break; + } + + return ret; +} + +struct coreinfo_module cbfs_module = { + .name = "CBFS", + .init = cbfs_module_init, + .redraw = cbfs_module_redraw, + .handle = cbfs_module_handle +}; + +#else + +struct coreinfo_module cbfs_module = { +}; + +#endif diff --git a/payloads/coreinfo/coreinfo.c b/payloads/coreinfo/coreinfo.c index befe988c2d..846cf77c18 100644 --- a/payloads/coreinfo/coreinfo.c +++ b/payloads/coreinfo/coreinfo.c @@ -32,6 +32,7 @@ extern struct coreinfo_module nvram_module; extern struct coreinfo_module bootlog_module; extern struct coreinfo_module ramdump_module; extern struct coreinfo_module lar_module; +extern struct coreinfo_module cbfs_module; struct coreinfo_module *system_modules[] = { #ifdef CONFIG_MODULE_CPUINFO @@ -59,7 +60,10 @@ struct coreinfo_module *firmware_modules[] = { &bootlog_module, #endif #ifdef CONFIG_MODULE_LAR - &lar_module + &lar_module, +#endif +#ifdef CONFIG_MODULE_CBFS + &cbfs_module, #endif }; -- cgit v1.2.3