diff options
Diffstat (limited to 'qemu/roms/u-boot/fs/cbfs/cbfs.c')
-rw-r--r-- | qemu/roms/u-boot/fs/cbfs/cbfs.c | 323 |
1 files changed, 0 insertions, 323 deletions
diff --git a/qemu/roms/u-boot/fs/cbfs/cbfs.c b/qemu/roms/u-boot/fs/cbfs/cbfs.c deleted file mode 100644 index c81b61106..000000000 --- a/qemu/roms/u-boot/fs/cbfs/cbfs.c +++ /dev/null @@ -1,323 +0,0 @@ -/* - * Copyright (c) 2011 The Chromium OS Authors. All rights reserved. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#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; -} |