summaryrefslogtreecommitdiff
path: root/fs/cbfs
diff options
context:
space:
mode:
authorGabe Black <gabeblack@chromium.org>2011-07-27 22:15:03 -0700
committerSimon Glass <sjg@chromium.org>2011-08-29 10:59:18 -0700
commit41558b3e202319fc32634a5ac81aeb258caa3dd6 (patch)
treedd04efcb6a63b6d2b525c5ba94becdc2fc404cd4 /fs/cbfs
parent5136f6ff6f002f7ad9c481e62b3ca7c4ce2edcf4 (diff)
Refactor the CBFS driver so that it's easier to use programmatically
This change refactors the implementation of the CBFS driver so that it can be used effectively both from the command line and programmatically from within u-boot. BUG=chrome-os-partner:4993 TEST=Built and booted on Alex. Verified that the CBFS commands still behaved correctly. Change-Id: I97720828e282261f69479979d7d0c2c7d193c53f Signed-off-by: Gabe Black <gabeblack@google.com> Reviewed-on: http://gerrit.chromium.org/gerrit/4916 Reviewed-by: Gabe Black <gabeblack@chromium.org> Tested-by: Gabe Black <gabeblack@chromium.org>
Diffstat (limited to 'fs/cbfs')
-rw-r--r--fs/cbfs/cbfs.c287
1 files changed, 145 insertions, 142 deletions
diff --git a/fs/cbfs/cbfs.c b/fs/cbfs/cbfs.c
index d1b03c7e1a..f25689e1c4 100644
--- a/fs/cbfs/cbfs.c
+++ b/fs/cbfs/cbfs.c
@@ -20,32 +20,30 @@
* MA 02111-1307 USA
*/
-#include <common.h>
-#include <config.h>
#include <cbfs.h>
#include <malloc.h>
#include <asm/byteorder.h>
-#define CBFS_TYPE_STAGE 0x10
-#define CBFS_TYPE_PAYLOAD 0x20
-#define CBFS_TYPE_OPTIONROM 0x30
-#define CBFS_TYPE_BOOTSPLASH 0x40
-#define CBFS_TYPE_RAW 0x50
-#define CBFS_TYPE_VSA 0x51
-#define CBFS_TYPE_MBI 0x52
-#define CBFS_TYPE_MICROCODE 0x53
-#define CBFS_COMPONENT_CMOS_DEFAULT 0xaa
-#define CBFS_COMPONENT_CMOS_LAYOUT 0x01aa
-
-typedef struct CbfsHeader {
- u32 magic;
- u32 version;
- u32 romSize;
- u32 bootBlockSize;
- u32 align;
- u32 offset;
- u32 pad[2];
-} __attribute__((packed)) CbfsHeader;
+CbfsResult 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";
+ }
+}
typedef struct CbfsFileHeader {
u8 magic[8];
@@ -56,10 +54,13 @@ typedef struct CbfsFileHeader {
} __attribute__((packed)) CbfsFileHeader;
typedef struct CbfsCacheNode {
- CbfsFileHeader header;
struct CbfsCacheNode *next;
+ u32 type;
void *data;
+ u32 dataLength;
char *name;
+ u32 nameLength;
+ u32 checksum;
} __attribute__((packed)) CbfsCacheNode;
@@ -71,7 +72,8 @@ static int initialized;
static struct CbfsHeader header;
static CbfsCacheNode *fileCache;
-static void swap_header(CbfsHeader *dest, CbfsHeader *src)
+static void
+swap_header(CbfsHeader *dest, CbfsHeader *src)
{
dest->magic = be32_to_cpu(src->magic);
dest->version = be32_to_cpu(src->version);
@@ -81,7 +83,8 @@ static void swap_header(CbfsHeader *dest, CbfsHeader *src)
dest->offset = be32_to_cpu(src->offset);
}
-static void swap_file_header(CbfsFileHeader *dest, CbfsFileHeader *src)
+static void
+swap_file_header(CbfsFileHeader *dest, CbfsFileHeader *src)
{
memcpy(&dest->magic, &src->magic, sizeof(dest->magic));
dest->len = be32_to_cpu(src->len);
@@ -90,19 +93,12 @@ static void swap_file_header(CbfsFileHeader *dest, CbfsFileHeader *src)
dest->offset = be32_to_cpu(src->offset);
}
-static int init_check(void)
-{
- if (!initialized) {
- printf("CBFS not initialized.\n");
- return 1;
- }
- return 0;
-}
-
-static int file_cbfs_fill_cache(u8 *start, u32 size, u32 align)
+static void
+file_cbfs_fill_cache(u8 *start, u32 size, u32 align)
{
CbfsCacheNode *cacheNode;
CbfsCacheNode *newNode;
+ CbfsFileHeader header;
CbfsCacheNode **cacheTail = &fileCache;
/* Clear out old information. */
@@ -129,35 +125,40 @@ static int file_cbfs_fill_cache(u8 *start, u32 size, u32 align)
}
newNode = (CbfsCacheNode *)malloc(sizeof(CbfsCacheNode));
- swap_file_header(&newNode->header, fileHeader);
- if (newNode->header.offset < sizeof(CbfsFileHeader) ||
- newNode->header.offset > newNode->header.len) {
- printf("Bad file in CBFS.\n");
- return 1;
+ swap_file_header(&header, fileHeader);
+ if (header.offset < sizeof(CbfsFileHeader) ||
+ header.offset > header.len) {
+ file_cbfs_result = CBFS_BAD_FILE;
+ return;
}
newNode->next = NULL;
- newNode->data = start + newNode->header.offset;
- nameLen = newNode->header.offset - sizeof(CbfsFileHeader);
+ newNode->type = header.type;
+ newNode->data = start + header.offset;
+ newNode->dataLength = header.len;
+ nameLen = header.offset - sizeof(CbfsFileHeader);
/* Add a byte for a NULL terminator. */
newNode->name = (char *)malloc(nameLen + 1);
strncpy(newNode->name,
((char *)fileHeader) + sizeof(CbfsFileHeader),
nameLen);
newNode->name[nameLen] = 0;
+ newNode->nameLength = nameLen;
+ newNode->checksum = header.checksum;
*cacheTail = newNode;
cacheTail = &newNode->next;
- step = newNode->header.len;
+ step = header.len;
if (step % align)
step = step + align - step % align;
size -= step;
start += step;
}
- return 0;
+ file_cbfs_result = CBFS_SUCCESS;
}
-int file_cbfs_init(uintptr_t endOfRom)
+void
+file_cbfs_init(uintptr_t endOfRom)
{
CbfsHeader *headerInRom;
u8 *startOfRom;
@@ -168,129 +169,131 @@ int file_cbfs_init(uintptr_t endOfRom)
if (header.magic != goodMagic || header.offset >
header.romSize - header.bootBlockSize) {
- printf("Bad CBFS header.\n");
- return 1;
+ file_cbfs_result = CBFS_BAD_HEADER;
+ return;
}
startOfRom = (u8 *)(endOfRom + 1 - header.romSize);
- if (file_cbfs_fill_cache(startOfRom + header.offset,
- header.romSize, header.align)) {
- return 1;
+ file_cbfs_fill_cache(startOfRom + header.offset,
+ header.romSize, header.align);
+ if (file_cbfs_result == CBFS_SUCCESS)
+ initialized = 1;
+}
+
+const CbfsHeader *
+file_cbfs_get_header(void)
+{
+ if (initialized) {
+ file_cbfs_result = CBFS_SUCCESS;
+ return &header;
+ } else {
+ file_cbfs_result = CBFS_NOT_INITIALIZED;
+ return NULL;
+ }
+}
+
+CbfsFile
+file_cbfs_get_first(void)
+{
+ if (!initialized) {
+ file_cbfs_result = CBFS_NOT_INITIALIZED;
+ return NULL;
+ } else {
+ file_cbfs_result = CBFS_SUCCESS;
+ return fileCache;
+ }
+}
+
+void
+file_cbfs_get_next(CbfsFile *file)
+{
+ if (!initialized) {
+ file_cbfs_result = CBFS_NOT_INITIALIZED;
+ file = NULL;
+ return;
}
- initialized = 1;
- return 0;
+ if (*file)
+ *file = (*file)->next;
+ file_cbfs_result = CBFS_SUCCESS;
}
-long file_cbfs_read(const char *filename, void *buffer, unsigned long maxsize)
+CbfsFile
+file_cbfs_find(const char *name)
{
struct CbfsCacheNode *cacheNode = fileCache;
- u32 size;
- if (init_check())
- return 1;
+ if (!initialized) {
+ file_cbfs_result = CBFS_NOT_INITIALIZED;
+ return NULL;
+ }
while (cacheNode) {
- if (!strcmp(filename, cacheNode->name))
+ if (!strcmp(name, cacheNode->name))
break;
cacheNode = cacheNode->next;
}
if (!cacheNode) {
- printf("File %s not found.\n", filename);
- return -1;
+ file_cbfs_result = CBFS_FILE_NOT_FOUND;
+ } else {
+ file_cbfs_result = CBFS_SUCCESS;
}
+ return cacheNode;
+}
- printf("reading %s\n", filename);
-
- size = cacheNode->header.len;
- if (maxsize && size > maxsize)
- size = maxsize;
-
- memcpy(buffer, cacheNode->data, size);
-
- return size;
+const char *
+file_cbfs_name(CbfsFile file)
+{
+ if (!initialized) {
+ file_cbfs_result = CBFS_NOT_INITIALIZED;
+ return NULL;
+ } else {
+ file_cbfs_result = CBFS_SUCCESS;
+ return file->name;
+ }
}
-int file_cbfs_ls(void)
+u32
+file_cbfs_size(CbfsFile file)
{
- struct CbfsCacheNode *cacheNode = fileCache;
- int files = 0;
+ if (!initialized) {
+ file_cbfs_result = CBFS_NOT_INITIALIZED;
+ return 0;
+ } else {
+ file_cbfs_result = CBFS_SUCCESS;
+ return file->dataLength;
+ }
+}
- if (init_check())
- return 1;
+u32
+file_cbfs_type(CbfsFile file)
+{
+ if (!initialized) {
+ file_cbfs_result = CBFS_NOT_INITIALIZED;
+ return 0;
+ } else {
+ file_cbfs_result = CBFS_SUCCESS;
+ return file->type;
+ }
+}
- printf(" size type name\n");
- printf("------------------------------------------\n");
- while (cacheNode) {
- char *typeName = NULL;
- printf(" %8d", cacheNode->header.len);
+long
+file_cbfs_read(CbfsFile file, void *buffer, unsigned long maxsize)
+{
+ u32 size;
- switch (cacheNode->header.type) {
- case CBFS_TYPE_STAGE:
- typeName = "stage";
- break;
- case CBFS_TYPE_PAYLOAD:
- typeName = "payload";
- break;
- case CBFS_TYPE_OPTIONROM:
- typeName = "option rom";
- break;
- case CBFS_TYPE_BOOTSPLASH:
- typeName = "boot splash";
- break;
- case CBFS_TYPE_RAW:
- typeName = "raw";
- break;
- case CBFS_TYPE_VSA:
- typeName = "vsa";
- break;
- case CBFS_TYPE_MBI:
- typeName = "mbi";
- break;
- case CBFS_TYPE_MICROCODE:
- typeName = "microcode";
- break;
- case CBFS_COMPONENT_CMOS_DEFAULT:
- typeName = "cmos default";
- break;
- case CBFS_COMPONENT_CMOS_LAYOUT:
- typeName = "cmos layout";
- break;
- case -1UL:
- typeName = "null";
- break;
- }
- if (typeName)
- printf(" %16s", typeName);
- else
- printf(" %16d", cacheNode->header.type);
-
- if (cacheNode->name[0])
- printf(" %s\n", cacheNode->name);
- else
- printf(" %s\n", "(empty)");
- cacheNode = cacheNode->next;
- files++;
+ if (!initialized) {
+ file_cbfs_result = CBFS_NOT_INITIALIZED;
+ return -CBFS_NOT_INITIALIZED;
}
- printf("\n%d file(s)\n\n", files);
- return 0;
-}
+ size = file->dataLength;
+ if (maxsize && size > maxsize)
+ size = maxsize;
-int file_cbfs_fsinfo(void)
-{
- if (init_check())
- return 1;
-
- printf("\n");
- printf("CBFS version: %#x\n", header.version);
- printf("ROM size: %#x\n", header.romSize);
- printf("Boot block size: %#x\n", header.bootBlockSize);
- printf("CBFS size: %#x\n",
- header.romSize - header.bootBlockSize - header.offset);
- printf("Alignment: %d\n", header.align);
- printf("Offset: %#x\n", header.offset);
- printf("\n");
- return 0;
+ memcpy(buffer, file->data, size);
+
+ file_cbfs_result = CBFS_SUCCESS;
+ return size;
}