diff options
| -rw-r--r-- | Makefile | 3 | ||||
| -rw-r--r-- | README | 7 | ||||
| -rw-r--r-- | common/Makefile | 1 | ||||
| -rw-r--r-- | common/cmd_cbfs.c | 214 | ||||
| -rw-r--r-- | fs/Makefile | 1 | ||||
| -rw-r--r-- | fs/cbfs/Makefile | 43 | ||||
| -rw-r--r-- | fs/cbfs/cbfs.c | 339 | ||||
| -rw-r--r-- | include/cbfs.h | 181 | 
8 files changed, 788 insertions, 1 deletions
| @@ -260,7 +260,8 @@ LIBS-y += drivers/net/npe/libnpe.o  endif  LIBS-$(CONFIG_OF_EMBED) += dts/libdts.o  LIBS-y += arch/$(ARCH)/lib/lib$(ARCH).o -LIBS-y += fs/cramfs/libcramfs.o \ +LIBS-y += fs/cbfs/libcbfs.o \ +	fs/cramfs/libcramfs.o \  	fs/ext4/libext4fs.o \  	fs/fat/libfat.o \  	fs/fdos/libfdos.o \ @@ -1316,6 +1316,13 @@ The following options need to be configured:  		This will also enable the command "fatwrite" enabling the  		user to write files to FAT. +CBFS (Coreboot Filesystem) support +		CONFIG_CMD_CBFS + +		Define this to enable support for reading from a Coreboot +		filesystem. Available commands are cbfsinit, cbfsinfo, cbfsls +		and cbfsload. +  - Keyboard Support:  		CONFIG_ISA_KEYBOARD diff --git a/common/Makefile b/common/Makefile index fdfead79c..281f4f1e1 100644 --- a/common/Makefile +++ b/common/Makefile @@ -70,6 +70,7 @@ COBJS-$(CONFIG_CMD_BMP) += cmd_bmp.o  COBJS-$(CONFIG_CMD_BOOTLDR) += cmd_bootldr.o  COBJS-$(CONFIG_CMD_BOOTSTAGE) += cmd_bootstage.o  COBJS-$(CONFIG_CMD_CACHE) += cmd_cache.o +COBJS-$(CONFIG_CMD_CBFS) += cmd_cbfs.o  COBJS-$(CONFIG_CMD_CONSOLE) += cmd_console.o  COBJS-$(CONFIG_CMD_CPLBINFO) += cmd_cplbinfo.o  COBJS-$(CONFIG_DATAFLASH_MMC_SELECT) += cmd_dataflash_mmc_mux.o diff --git a/common/cmd_cbfs.c b/common/cmd_cbfs.c new file mode 100644 index 000000000..3b6cfd879 --- /dev/null +++ b/common/cmd_cbfs.c @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. All rights reserved. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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; either version 2 of + * the License, or (at your option) any later version. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * CBFS commands + */ +#include <common.h> +#include <command.h> +#include <cbfs.h> + +int do_cbfs_init(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ +	uintptr_t end_of_rom = 0xffffffff; +	char *ep; + +	if (argc > 2) { +		printf("usage: cbfsls [end of rom]>\n"); +		return 0; +	} +	if (argc == 2) { +		end_of_rom = (int)simple_strtoul(argv[1], &ep, 16); +		if (*ep) { +			puts("\n** Invalid end of ROM **\n"); +			return 1; +		} +	} +	file_cbfs_init(end_of_rom); +	if (file_cbfs_result != CBFS_SUCCESS) { +		printf("%s.\n", file_cbfs_error()); +		return 1; +	} +	return 0; +} + +U_BOOT_CMD( +	cbfsinit,	2,	0,	do_cbfs_init, +	"initialize the cbfs driver", +	"[end of rom]\n" +	"    - Initialize the cbfs driver. The optional 'end of rom'\n" +	"      parameter specifies where the end of the ROM is that the\n" +	"      CBFS is in. It defaults to 0xFFFFFFFF\n" +); + +int do_cbfs_fsload(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ +	const struct cbfs_cachenode *file; +	unsigned long offset; +	unsigned long count; +	char buf[12]; +	long size; + +	if (argc < 3) { +		printf("usage: cbfsload <addr> <filename> [bytes]\n"); +		return 1; +	} + +	/* parse offset and count */ +	offset = simple_strtoul(argv[1], NULL, 16); +	if (argc == 4) +		count = simple_strtoul(argv[3], NULL, 16); +	else +		count = 0; + +	file = file_cbfs_find(argv[2]); +	if (!file) { +		if (file_cbfs_result == CBFS_FILE_NOT_FOUND) +			printf("%s: %s\n", file_cbfs_error(), argv[2]); +		else +			printf("%s.\n", file_cbfs_error()); +		return 1; +	} + +	printf("reading %s\n", file_cbfs_name(file)); + +	size = file_cbfs_read(file, (void *)offset, count); + +	printf("\n%ld bytes read\n", size); + +	sprintf(buf, "%lX", size); +	setenv("filesize", buf); + +	return 0; +} + +U_BOOT_CMD( +	cbfsload,	4,	0,	do_cbfs_fsload, +	"load binary file from a cbfs filesystem", +	"<addr> <filename> [bytes]\n" +	"    - load binary file 'filename' from the cbfs to address 'addr'\n" +); + +int do_cbfs_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ +	const struct cbfs_cachenode *file = file_cbfs_get_first(); +	int files = 0; + +	if (!file) { +		printf("%s.\n", file_cbfs_error()); +		return 1; +	} + +	printf("     size              type  name\n"); +	printf("------------------------------------------\n"); +	while (file) { +		u32 type = file_cbfs_type(file); +		char *type_name = NULL; +		const char *filename = file_cbfs_name(file); + +		printf(" %8d", file_cbfs_size(file)); + +		switch (type) { +		case CBFS_TYPE_STAGE: +			type_name = "stage"; +			break; +		case CBFS_TYPE_PAYLOAD: +			type_name = "payload"; +			break; +		case CBFS_TYPE_OPTIONROM: +			type_name = "option rom"; +			break; +		case CBFS_TYPE_BOOTSPLASH: +			type_name = "boot splash"; +			break; +		case CBFS_TYPE_RAW: +			type_name = "raw"; +			break; +		case CBFS_TYPE_VSA: +			type_name = "vsa"; +			break; +		case CBFS_TYPE_MBI: +			type_name = "mbi"; +			break; +		case CBFS_TYPE_MICROCODE: +			type_name = "microcode"; +			break; +		case CBFS_COMPONENT_CMOS_DEFAULT: +			type_name = "cmos default"; +			break; +		case CBFS_COMPONENT_CMOS_LAYOUT: +			type_name = "cmos layout"; +			break; +		case -1UL: +			type_name = "null"; +			break; +		} +		if (type_name) +			printf("  %16s", type_name); +		else +			printf("  %16d", type); + +		if (filename[0]) +			printf("  %s\n", filename); +		else +			printf("  %s\n", "(empty)"); +		file_cbfs_get_next(&file); +		files++; +	} + +	printf("\n%d file(s)\n\n", files); +	return 0; +} + +U_BOOT_CMD( +	cbfsls,	1,	1,	do_cbfs_ls, +	"list files", +	"    - list the files in the cbfs\n" +); + +int do_cbfs_fsinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ +	const struct cbfs_header *header = file_cbfs_get_header(); + +	if (!header) { +		printf("%s.\n", file_cbfs_error()); +		return 1; +	} + +	printf("\n"); +	printf("CBFS version: %#x\n", header->version); +	printf("ROM size: %#x\n", header->rom_size); +	printf("Boot block size: %#x\n", header->boot_block_size); +	printf("CBFS size: %#x\n", +		header->rom_size - header->boot_block_size - header->offset); +	printf("Alignment: %d\n", header->align); +	printf("Offset: %#x\n", header->offset); +	printf("\n"); + +	return 0; +} + +U_BOOT_CMD( +	cbfsinfo,	1,	1,	do_cbfs_fsinfo, +	"print information about filesystem", +	"    - print information about the cbfs filesystem\n" +); diff --git a/fs/Makefile b/fs/Makefile index 901e1894b..b4db60623 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -22,6 +22,7 @@  #  # +subdirs-$(CONFIG_CMD_CBFS) += cbfs  subdirs-$(CONFIG_CMD_CRAMFS) := cramfs  subdirs-$(CONFIG_CMD_EXT4) += ext4  ifndef CONFIG_CMD_EXT4 diff --git a/fs/cbfs/Makefile b/fs/cbfs/Makefile new file mode 100644 index 000000000..2be8a6880 --- /dev/null +++ b/fs/cbfs/Makefile @@ -0,0 +1,43 @@ +# +# See file CREDITS for list of people who contributed to this +# project. +# +# 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; either version 2 of +# the License, or (at your option) any later version. +# +# 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., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB	= $(obj)libcbfs.o + +COBJS-$(CONFIG_CMD_CBFS)	:= cbfs.o + +SRCS	:= $(COBJS-y:.o=.c) +OBJS	:= $(addprefix $(obj),$(COBJS-y)) + +all:	$(LIB) + +$(LIB):	$(obj).depend $(OBJS) +	$(call cmd_link_o_target, $(OBJS)) + + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/fs/cbfs/cbfs.c b/fs/cbfs/cbfs.c new file mode 100644 index 000000000..cae6d56db --- /dev/null +++ b/fs/cbfs/cbfs.c @@ -0,0 +1,339 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. All rights reserved. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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; either version 2 of + * the License, or (at your option) any later version. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <cbfs.h> +#include <malloc.h> +#include <asm/byteorder.h> + +enum cbfs_result file_cbfs_result; + +const char *file_cbfs_error(void) +{ +	switch (file_cbfs_result) { +	case CBFS_SUCCESS: +		return "Success"; +	case CBFS_NOT_INITIALIZED: +		return "CBFS not initialized"; +	case CBFS_BAD_HEADER: +		return "Bad CBFS header"; +	case CBFS_BAD_FILE: +		return "Bad CBFS file"; +	case CBFS_FILE_NOT_FOUND: +		return "File not found"; +	default: +		return "Unknown"; +	} +} + + +static const u32 good_magic = 0x4f524243; +static const u8 good_file_magic[] = "LARCHIVE"; + + +static int initialized; +static struct cbfs_header cbfs_header; +static struct cbfs_cachenode *file_cache; + +/* Do endian conversion on the CBFS header structure. */ +static void swap_header(struct cbfs_header *dest, struct cbfs_header *src) +{ +	dest->magic = be32_to_cpu(src->magic); +	dest->version = be32_to_cpu(src->version); +	dest->rom_size = be32_to_cpu(src->rom_size); +	dest->boot_block_size = be32_to_cpu(src->boot_block_size); +	dest->align = be32_to_cpu(src->align); +	dest->offset = be32_to_cpu(src->offset); +} + +/* Do endian conversion on a CBFS file header. */ +static void swap_file_header(struct cbfs_fileheader *dest, +			     const struct cbfs_fileheader *src) +{ +	memcpy(&dest->magic, &src->magic, sizeof(dest->magic)); +	dest->len = be32_to_cpu(src->len); +	dest->type = be32_to_cpu(src->type); +	dest->checksum = be32_to_cpu(src->checksum); +	dest->offset = be32_to_cpu(src->offset); +} + +/* + * Given a starting position in memory, scan forward, bounded by a size, and + * find the next valid CBFS file. No memory is allocated by this function. The + * caller is responsible for allocating space for the new file structure. + * + * @param start		The location in memory to start from. + * @param size		The size of the memory region to search. + * @param align		The alignment boundaries to check on. + * @param newNode	A pointer to the file structure to load. + * @param used		A pointer to the count of of bytes scanned through, + *			including the file if one is found. + * + * @return 1 if a file is found, 0 if one isn't. + */ +static int file_cbfs_next_file(u8 *start, u32 size, u32 align, +			       struct cbfs_cachenode *newNode, u32 *used) +{ +	struct cbfs_fileheader header; + +	*used = 0; + +	while (size >= align) { +		const struct cbfs_fileheader *fileHeader = +			(const struct cbfs_fileheader *)start; +		u32 name_len; +		u32 step; + +		/* Check if there's a file here. */ +		if (memcmp(good_file_magic, &(fileHeader->magic), +				sizeof(fileHeader->magic))) { +			*used += align; +			size -= align; +			start += align; +			continue; +		} + +		swap_file_header(&header, fileHeader); +		if (header.offset < sizeof(const struct cbfs_cachenode *) || +				header.offset > header.len) { +			file_cbfs_result = CBFS_BAD_FILE; +			return -1; +		} +		newNode->next = NULL; +		newNode->type = header.type; +		newNode->data = start + header.offset; +		newNode->data_length = header.len; +		name_len = header.offset - sizeof(struct cbfs_cachenode *); +		newNode->name = (char *)fileHeader + +				sizeof(struct cbfs_cachenode *); +		newNode->name_length = name_len; +		newNode->checksum = header.checksum; + +		step = header.len; +		if (step % align) +			step = step + align - step % align; + +		*used += step; +		return 1; +	} +	return 0; +} + +/* Look through a CBFS instance and copy file metadata into regular memory. */ +static void file_cbfs_fill_cache(u8 *start, u32 size, u32 align) +{ +	struct cbfs_cachenode *cache_node; +	struct cbfs_cachenode *newNode; +	struct cbfs_cachenode **cache_tail = &file_cache; + +	/* Clear out old information. */ +	cache_node = file_cache; +	while (cache_node) { +		struct cbfs_cachenode *oldNode = cache_node; +		cache_node = cache_node->next; +		free(oldNode); +	} +	file_cache = NULL; + +	while (size >= align) { +		int result; +		u32 used; + +		newNode = (struct cbfs_cachenode *) +				malloc(sizeof(struct cbfs_cachenode)); +		result = file_cbfs_next_file(start, size, align, +			newNode, &used); + +		if (result < 0) { +			free(newNode); +			return; +		} else if (result == 0) { +			free(newNode); +			break; +		} +		*cache_tail = newNode; +		cache_tail = &newNode->next; + +		size -= used; +		start += used; +	} +	file_cbfs_result = CBFS_SUCCESS; +} + +/* Get the CBFS header out of the ROM and do endian conversion. */ +static int file_cbfs_load_header(uintptr_t end_of_rom, +				 struct cbfs_header *header) +{ +	struct cbfs_header *header_in_rom; + +	header_in_rom = (struct cbfs_header *)(uintptr_t) +			*(u32 *)(end_of_rom - 3); +	swap_header(header, header_in_rom); + +	if (header->magic != good_magic || header->offset > +			header->rom_size - header->boot_block_size) { +		file_cbfs_result = CBFS_BAD_HEADER; +		return 1; +	} +	return 0; +} + +void file_cbfs_init(uintptr_t end_of_rom) +{ +	u8 *start_of_rom; +	initialized = 0; + +	if (file_cbfs_load_header(end_of_rom, &cbfs_header)) +		return; + +	start_of_rom = (u8 *)(end_of_rom + 1 - cbfs_header.rom_size); + +	file_cbfs_fill_cache(start_of_rom + cbfs_header.offset, +			     cbfs_header.rom_size, cbfs_header.align); +	if (file_cbfs_result == CBFS_SUCCESS) +		initialized = 1; +} + +const struct cbfs_header *file_cbfs_get_header(void) +{ +	if (initialized) { +		file_cbfs_result = CBFS_SUCCESS; +		return &cbfs_header; +	} else { +		file_cbfs_result = CBFS_NOT_INITIALIZED; +		return NULL; +	} +} + +const struct cbfs_cachenode *file_cbfs_get_first(void) +{ +	if (!initialized) { +		file_cbfs_result = CBFS_NOT_INITIALIZED; +		return NULL; +	} else { +		file_cbfs_result = CBFS_SUCCESS; +		return file_cache; +	} +} + +void file_cbfs_get_next(const struct cbfs_cachenode **file) +{ +	if (!initialized) { +		file_cbfs_result = CBFS_NOT_INITIALIZED; +		file = NULL; +		return; +	} + +	if (*file) +		*file = (*file)->next; +	file_cbfs_result = CBFS_SUCCESS; +} + +const struct cbfs_cachenode *file_cbfs_find(const char *name) +{ +	struct cbfs_cachenode *cache_node = file_cache; + +	if (!initialized) { +		file_cbfs_result = CBFS_NOT_INITIALIZED; +		return NULL; +	} + +	while (cache_node) { +		if (!strcmp(name, cache_node->name)) +			break; +		cache_node = cache_node->next; +	} +	if (!cache_node) +		file_cbfs_result = CBFS_FILE_NOT_FOUND; +	else +		file_cbfs_result = CBFS_SUCCESS; + +	return cache_node; +} + +const struct cbfs_cachenode *file_cbfs_find_uncached(uintptr_t end_of_rom, +						     const char *name) +{ +	u8 *start; +	u32 size; +	u32 align; +	static struct cbfs_cachenode node; + +	if (file_cbfs_load_header(end_of_rom, &cbfs_header)) +		return NULL; + +	start = (u8 *)(end_of_rom + 1 - cbfs_header.rom_size); +	size = cbfs_header.rom_size; +	align = cbfs_header.align; + +	while (size >= align) { +		int result; +		u32 used; + +		result = file_cbfs_next_file(start, size, align, &node, &used); + +		if (result < 0) +			return NULL; +		else if (result == 0) +			break; + +		if (!strcmp(name, node.name)) +			return &node; + +		size -= used; +		start += used; +	} +	file_cbfs_result = CBFS_FILE_NOT_FOUND; +	return NULL; +} + +const char *file_cbfs_name(const struct cbfs_cachenode *file) +{ +	file_cbfs_result = CBFS_SUCCESS; +	return file->name; +} + +u32 file_cbfs_size(const struct cbfs_cachenode *file) +{ +	file_cbfs_result = CBFS_SUCCESS; +	return file->data_length; +} + +u32 file_cbfs_type(const struct cbfs_cachenode *file) +{ +	file_cbfs_result = CBFS_SUCCESS; +	return file->type; +} + +long file_cbfs_read(const struct cbfs_cachenode *file, void *buffer, +		    unsigned long maxsize) +{ +	u32 size; + +	size = file->data_length; +	if (maxsize && size > maxsize) +		size = maxsize; + +	memcpy(buffer, file->data, size); + +	file_cbfs_result = CBFS_SUCCESS; +	return size; +} diff --git a/include/cbfs.h b/include/cbfs.h new file mode 100644 index 000000000..6ea3f3511 --- /dev/null +++ b/include/cbfs.h @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. All rights reserved. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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; either version 2 of + * the License, or (at your option) any later version. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __CBFS_H +#define __CBFS_H + +#include <compiler.h> +#include <linux/compiler.h> + +enum cbfs_result { +	CBFS_SUCCESS = 0, +	CBFS_NOT_INITIALIZED, +	CBFS_BAD_HEADER, +	CBFS_BAD_FILE, +	CBFS_FILE_NOT_FOUND +}; + +enum cbfs_filetype { +	CBFS_TYPE_STAGE = 0x10, +	CBFS_TYPE_PAYLOAD = 0x20, +	CBFS_TYPE_OPTIONROM = 0x30, +	CBFS_TYPE_BOOTSPLASH = 0x40, +	CBFS_TYPE_RAW = 0x50, +	CBFS_TYPE_VSA = 0x51, +	CBFS_TYPE_MBI = 0x52, +	CBFS_TYPE_MICROCODE = 0x53, +	CBFS_COMPONENT_CMOS_DEFAULT = 0xaa, +	CBFS_COMPONENT_CMOS_LAYOUT = 0x01aa +}; + +struct cbfs_header { +	u32 magic; +	u32 version; +	u32 rom_size; +	u32 boot_block_size; +	u32 align; +	u32 offset; +	u32 pad[2]; +} __packed; + +struct cbfs_fileheader { +	u8 magic[8]; +	u32 len; +	u32 type; +	u32 checksum; +	u32 offset; +} __packed; + +struct cbfs_cachenode { +	struct cbfs_cachenode *next; +	u32 type; +	void *data; +	u32 data_length; +	char *name; +	u32 name_length; +	u32 checksum; +} __packed; + +extern enum cbfs_result file_cbfs_result; + +/* + * Return a string describing the most recent error condition. + * + * @return A pointer to the constant string. + */ +const char *file_cbfs_error(void); + +/* + * Initialize the CBFS driver and load metadata into RAM. + * + * @param end_of_rom	Points to the end of the ROM the CBFS should be read + *                      from. + */ +void file_cbfs_init(uintptr_t end_of_rom); + +/* + * Get the header structure for the current CBFS. + * + * @return A pointer to the constant structure, or NULL if there is none. + */ +const struct cbfs_header *file_cbfs_get_header(void); + +/* + * Get a handle for the first file in CBFS. + * + * @return A handle for the first file in CBFS, NULL on error. + */ +const struct cbfs_cachenode *file_cbfs_get_first(void); + +/* + * Get a handle to the file after this one in CBFS. + * + * @param file		A pointer to the handle to advance. + */ +void file_cbfs_get_next(const struct cbfs_cachenode **file); + +/* + * Find a file with a particular name in CBFS. + * + * @param name		The name to search for. + * + * @return A handle to the file, or NULL on error. + */ +const struct cbfs_cachenode *file_cbfs_find(const char *name); + + +/***************************************************************************/ +/* All of the functions below can be used without first initializing CBFS. */ +/***************************************************************************/ + +/* + * Find a file with a particular name in CBFS without using the heap. + * + * @param end_of_rom	Points to the end of the ROM the CBFS should be read + *                      from. + * @param name		The name to search for. + * + * @return A handle to the file, or NULL on error. + */ +const struct cbfs_cachenode *file_cbfs_find_uncached(uintptr_t end_of_rom, +						     const char *name); + +/* + * Get the name of a file in CBFS. + * + * @param file		The handle to the file. + * + * @return The name of the file, NULL on error. + */ +const char *file_cbfs_name(const struct cbfs_cachenode *file); + +/* + * Get the size of a file in CBFS. + * + * @param file		The handle to the file. + * + * @return The size of the file, zero on error. + */ +u32 file_cbfs_size(const struct cbfs_cachenode *file); + +/* + * Get the type of a file in CBFS. + * + * @param file		The handle to the file. + * + * @return The type of the file, zero on error. + */ +u32 file_cbfs_type(const struct cbfs_cachenode *file); + +/* + * Read a file from CBFS into RAM + * + * @param file		A handle to the file to read. + * @param buffer	Where to read it into memory. + * + * @return If positive or zero, the number of characters read. If negative, an + *         error occurred. + */ +long file_cbfs_read(const struct cbfs_cachenode *file, void *buffer, +		    unsigned long maxsize); + +#endif /* __CBFS_H */ |