libpayload: Remove legacy CBFS API
It's been several years already since we announced the deprecation of the legacy CBFS API for payloads. It's time to remove it completely. Change-Id: I0ed157ac2d1376b8dff4537af9a63731064b45f6 Signed-off-by: Julius Werner <jwerner@chromium.org> Reviewed-on: https://review.coreboot.org/c/coreboot/+/80650 Reviewed-by: Nico Huber <nico.h@gmx.de> Reviewed-by: Jakub Czapiga <czapiga@google.com> Reviewed-by: Arthur Heymans <arthur@aheymans.xyz> Reviewed-by: Lean Sheng Tan <sheng.tan@9elements.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Maximilian Brune <maximilian.brune@9elements.com>
This commit is contained in:
@ -43,8 +43,6 @@ libc-$(CONFIG_LP_GPL) += memcpy.S memset.S memmove.S
|
|||||||
|
|
||||||
libgdb-y += gdb.c
|
libgdb-y += gdb.c
|
||||||
|
|
||||||
libcbfs-$(CONFIG_LP_CBFS) += dummy_media.c
|
|
||||||
|
|
||||||
# Add other classes here when you put assembly files into them!
|
# Add other classes here when you put assembly files into them!
|
||||||
head.o-S-ccopts += $(arm_asm_flags)
|
head.o-S-ccopts += $(arm_asm_flags)
|
||||||
libc-S-ccopts += $(arm_asm_flags)
|
libc-S-ccopts += $(arm_asm_flags)
|
||||||
|
@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* Copyright (C) 2013 Google, Inc.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* 3. The name of the author may not be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
* SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
#define LIBPAYLOAD
|
|
||||||
|
|
||||||
#include <cbfs.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/* The generic cbfs code relies on the libpayload_init_default_cbfs_media
|
|
||||||
* symbol. Therefore, provide an implementation that just throws an error. */
|
|
||||||
|
|
||||||
int libpayload_init_default_cbfs_media(struct cbfs_media *media);
|
|
||||||
|
|
||||||
__attribute__((weak)) int libpayload_init_default_cbfs_media(
|
|
||||||
struct cbfs_media *media)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
@ -38,7 +38,6 @@ libc-y += exception_asm.S exception.c
|
|||||||
libc-y += cache.c cpu.S
|
libc-y += cache.c cpu.S
|
||||||
libc-y += selfboot.c
|
libc-y += selfboot.c
|
||||||
libc-y += mmu.c
|
libc-y += mmu.c
|
||||||
libcbfs-$(CONFIG_LP_CBFS) += dummy_media.c
|
|
||||||
|
|
||||||
libgdb-y += gdb.c
|
libgdb-y += gdb.c
|
||||||
|
|
||||||
|
@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* Copyright (C) 2013 Google, Inc.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* 3. The name of the author may not be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
* SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
#define LIBPAYLOAD
|
|
||||||
|
|
||||||
#include <cbfs.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/* The generic cbfs code relies on the libpayload_init_default_cbfs_media
|
|
||||||
* symbol. Therefore, provide an implementation that just throws an error. */
|
|
||||||
|
|
||||||
int libpayload_init_default_cbfs_media(struct cbfs_media *media);
|
|
||||||
|
|
||||||
__attribute__((weak)) int libpayload_init_default_cbfs_media(
|
|
||||||
struct cbfs_media *media)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
@ -4,6 +4,4 @@ head.o-y += head.c
|
|||||||
|
|
||||||
libc-y += virtual.c
|
libc-y += virtual.c
|
||||||
|
|
||||||
libcbfs-$(CONFIG_LP_CBFS) += mock_media.c
|
|
||||||
|
|
||||||
CFLAGS += -Wno-address-of-packed-member
|
CFLAGS += -Wno-address-of-packed-member
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
||||||
|
|
||||||
#include <cbfs.h>
|
|
||||||
|
|
||||||
int libpayload_init_default_cbfs_media(struct cbfs_media *media);
|
|
||||||
|
|
||||||
__attribute__((weak)) int libpayload_init_default_cbfs_media(struct cbfs_media *media)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
@ -43,7 +43,6 @@ libc-$(CONFIG_LP_GPL) += string.c
|
|||||||
|
|
||||||
libgdb-y += gdb.c
|
libgdb-y += gdb.c
|
||||||
|
|
||||||
libcbfs-$(CONFIG_LP_CBFS) += rom_media.c
|
|
||||||
libcbfs-$(CONFIG_LP_CBFS) += boot_media.c
|
libcbfs-$(CONFIG_LP_CBFS) += boot_media.c
|
||||||
|
|
||||||
# Multiboot support is configurable
|
# Multiboot support is configurable
|
||||||
|
@ -1,110 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* Copyright (C) 2013 Google, Inc.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* 3. The name of the author may not be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
* SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
#define LIBPAYLOAD
|
|
||||||
|
|
||||||
#include <cbfs.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#ifdef LIBPAYLOAD
|
|
||||||
# define printk(x...)
|
|
||||||
# define init_default_cbfs_media libpayload_init_default_cbfs_media
|
|
||||||
extern int libpayload_init_default_cbfs_media(struct cbfs_media *media);
|
|
||||||
#else
|
|
||||||
# include <console/console.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Implementation of memory-mapped ROM media source on X86.
|
|
||||||
|
|
||||||
static int x86_rom_open(struct cbfs_media *media) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *x86_rom_map(struct cbfs_media *media, size_t offset, size_t count) {
|
|
||||||
void *ptr;
|
|
||||||
// Some address (ex, pointer to master header) may be given in memory
|
|
||||||
// mapped location. To workaround that, we handle >0xf0000000 as real
|
|
||||||
// memory pointer.
|
|
||||||
|
|
||||||
if ((uint32_t)offset > (uint32_t)0xf0000000)
|
|
||||||
ptr = (void*)offset;
|
|
||||||
else
|
|
||||||
ptr = (void*)(0 - (uint32_t)media->context + offset);
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *x86_rom_unmap(struct cbfs_media *media, const void *address) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t x86_rom_read(struct cbfs_media *media, void *dest, size_t offset,
|
|
||||||
size_t count) {
|
|
||||||
void *ptr = x86_rom_map(media, offset, count);
|
|
||||||
memcpy(dest, ptr, count);
|
|
||||||
x86_rom_unmap(media, ptr);
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int x86_rom_close(struct cbfs_media *media) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int init_x86rom_cbfs_media(struct cbfs_media *media);
|
|
||||||
int init_x86rom_cbfs_media(struct cbfs_media *media) {
|
|
||||||
// On X86, we always keep a reference of pointer to CBFS header in
|
|
||||||
// 0xfffffffc, and the pointer is still a memory-mapped address.
|
|
||||||
// Since the CBFS core always use ROM offset, we need to figure out
|
|
||||||
// header->romsize even before media is initialized.
|
|
||||||
struct cbfs_header *header = (struct cbfs_header*)
|
|
||||||
*(uint32_t*)(0xfffffffc);
|
|
||||||
if (CBFS_HEADER_MAGIC != ntohl(header->magic)) {
|
|
||||||
#if CONFIG(LP_ROM_SIZE)
|
|
||||||
printk(BIOS_ERR, "Invalid CBFS master header at %p\n", header);
|
|
||||||
media->context = (void*)CONFIG_LP_ROM_SIZE;
|
|
||||||
#else
|
|
||||||
return -1;
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
uint32_t romsize = ntohl(header->romsize);
|
|
||||||
media->context = (void*)romsize;
|
|
||||||
#if CONFIG(LP_ROM_SIZE)
|
|
||||||
if (CONFIG_LP_ROM_SIZE != romsize)
|
|
||||||
printk(BIOS_WARNING, "rom size unmatch (%d/%d)\n",
|
|
||||||
CONFIG_LP_ROM_SIZE, romsize);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
media->open = x86_rom_open;
|
|
||||||
media->close = x86_rom_close;
|
|
||||||
media->map = x86_rom_map;
|
|
||||||
media->unmap = x86_rom_unmap;
|
|
||||||
media->read = x86_rom_read;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int init_default_cbfs_media(struct cbfs_media *media) {
|
|
||||||
return init_x86rom_cbfs_media(media);
|
|
||||||
}
|
|
@ -139,8 +139,4 @@ static inline bool cbfs_ro_file_exists(const char *name)
|
|||||||
return _cbfs_boot_lookup(name, true, &mdata) >= 0;
|
return _cbfs_boot_lookup(name, true, &mdata) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Legacy API. Designated for removal in the future. */
|
|
||||||
#include <cbfs_legacy.h>
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,134 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* Copyright (C) 2008 Jordan Crouse <jordan@cosmicpenguin.net>
|
|
||||||
* Copyright (C) 2012 Google, Inc.
|
|
||||||
*
|
|
||||||
* This file is dual-licensed. You can choose between:
|
|
||||||
* - The GNU GPL, version 2, as published by the Free Software Foundation
|
|
||||||
* - The revised BSD license (without advertising clause)
|
|
||||||
*
|
|
||||||
* ---------------------------------------------------------------------------
|
|
||||||
* 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.
|
|
||||||
* ---------------------------------------------------------------------------
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* 3. The name of the author may not be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
* SUCH DAMAGE.
|
|
||||||
* ---------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _CBFS_CORE_H_
|
|
||||||
#define _CBFS_CORE_H_
|
|
||||||
|
|
||||||
#include <commonlib/bsd/cbfs_serialized.h>
|
|
||||||
#include <endian.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#define CBFS_HEADER_INVALID_ADDRESS ((void*)(0xffffffff))
|
|
||||||
|
|
||||||
struct cbfs_stage {
|
|
||||||
uint32_t compression; /** Compression type */
|
|
||||||
uint64_t entry; /** entry point */
|
|
||||||
uint64_t load; /** Where to load in memory */
|
|
||||||
uint32_t len; /** length of data to load */
|
|
||||||
uint32_t memlen; /** total length of object in memory */
|
|
||||||
} __packed;
|
|
||||||
|
|
||||||
#define CBFS_MEDIA_INVALID_MAP_ADDRESS ((void*)(0xffffffff))
|
|
||||||
#define CBFS_DEFAULT_MEDIA ((void*)(0x0))
|
|
||||||
|
|
||||||
/* Media for CBFS to load files. */
|
|
||||||
struct cbfs_media {
|
|
||||||
|
|
||||||
/* implementation dependent context, to hold resource references */
|
|
||||||
void *context;
|
|
||||||
|
|
||||||
/* opens media and returns 0 on success, -1 on failure */
|
|
||||||
int (*open)(struct cbfs_media *media);
|
|
||||||
|
|
||||||
/* returns number of bytes read from media into dest, starting from
|
|
||||||
* offset for count of bytes */
|
|
||||||
size_t (*read)(struct cbfs_media *media, void *dest, size_t offset,
|
|
||||||
size_t count);
|
|
||||||
|
|
||||||
/* returns a pointer to memory with count of bytes from media source
|
|
||||||
* starting from offset, or CBFS_MEDIA_INVALID_MAP_ADDRESS on failure.
|
|
||||||
* Note: mapped data can't be free unless unmap is called, even if you
|
|
||||||
* do close first. */
|
|
||||||
void * (*map)(struct cbfs_media *media, size_t offset, size_t count);
|
|
||||||
|
|
||||||
/* returns NULL and releases the memory by address, which was allocated
|
|
||||||
* by map */
|
|
||||||
void * (*unmap)(struct cbfs_media *media, const void *address);
|
|
||||||
|
|
||||||
/* closes media and returns 0 on success, -1 on failure. */
|
|
||||||
int (*close)(struct cbfs_media *media);
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns pointer to a copy of the file content or NULL on error.
|
|
||||||
* If the file is compressed, data will be decompressed.
|
|
||||||
* The caller owns the returned memory.
|
|
||||||
*/
|
|
||||||
void *cbfs_get_file_content(struct cbfs_media *media, const char *name,
|
|
||||||
int type, size_t *sz);
|
|
||||||
|
|
||||||
/* Returns decompressed size on success, 0 on failure. */
|
|
||||||
size_t cbfs_decompress(int algo, const void *src, size_t srcn, void *dst,
|
|
||||||
size_t dstn);
|
|
||||||
|
|
||||||
/* returns a pointer to CBFS master header, or CBFS_HEADER_INVALID_ADDRESS
|
|
||||||
* on failure */
|
|
||||||
const struct cbfs_header *cbfs_get_header(struct cbfs_media *media);
|
|
||||||
|
|
||||||
/* Persistent handle to a CBFS file that has not yet been fully mapped. */
|
|
||||||
struct cbfs_handle {
|
|
||||||
struct cbfs_media media; /* copy of original media object */
|
|
||||||
u32 type; /* CBFS file type */
|
|
||||||
u32 media_offset; /* offset from beginning of media */
|
|
||||||
u32 attribute_offset; /* relative offset of attributes */
|
|
||||||
u32 content_offset; /* relative offset of contents */
|
|
||||||
u32 content_size; /* length of file contents in bytes */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Returns handle to CBFS file, or NULL on error. Does not yet map contents.
|
|
||||||
* Caller is responsible to free() returned handle after use. */
|
|
||||||
struct cbfs_handle *cbfs_get_handle(struct cbfs_media *media, const char *name);
|
|
||||||
|
|
||||||
/* Given a cbfs_handle and an attribute tag, return a mapping for the first
|
|
||||||
* instance of the attribute or NULL if none found. */
|
|
||||||
void *cbfs_get_attr(struct cbfs_handle *handle, uint32_t tag);
|
|
||||||
|
|
||||||
/* Given a cbfs_handle, returns the (decompressed) file contents in a buffer,
|
|
||||||
* or NULL on error. If |size| is passed, will store amount of bytes read there.
|
|
||||||
* If |limit| is not 0, will only return up to that many bytes. */
|
|
||||||
void *cbfs_get_contents(struct cbfs_handle *handle, size_t *size, size_t limit);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,82 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* Copyright (C) 2008 Jordan Crouse <jordan@cosmicpenguin.net>
|
|
||||||
* Copyright (C) 2013 Google, Inc.
|
|
||||||
*
|
|
||||||
* This file is dual-licensed. You can choose between:
|
|
||||||
* - The GNU GPL, version 2, as published by the Free Software Foundation
|
|
||||||
* - The revised BSD license (without advertising clause)
|
|
||||||
*
|
|
||||||
* ---------------------------------------------------------------------------
|
|
||||||
* 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.
|
|
||||||
* ---------------------------------------------------------------------------
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* 3. The name of the author may not be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
* SUCH DAMAGE.
|
|
||||||
* ---------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _CBFS_LEGACY_H_
|
|
||||||
#define _CBFS_LEGACY_H_
|
|
||||||
|
|
||||||
#include <cbfs_core.h>
|
|
||||||
|
|
||||||
/* legacy APIs */
|
|
||||||
const struct cbfs_header *get_cbfs_header(void);
|
|
||||||
struct cbfs_file *cbfs_find(const char *name);
|
|
||||||
void *cbfs_find_file(const char *name, int type);
|
|
||||||
|
|
||||||
int cbfs_execute_stage(struct cbfs_media *media, const char *name);
|
|
||||||
void *cbfs_load_optionrom(struct cbfs_media *media, uint16_t vendor,
|
|
||||||
uint16_t device);
|
|
||||||
void *cbfs_load_payload(struct cbfs_media *media, const char *name);
|
|
||||||
void *cbfs_load_stage(struct cbfs_media *media, const char *name);
|
|
||||||
|
|
||||||
/* Simple buffer for streaming media. */
|
|
||||||
struct cbfs_simple_buffer {
|
|
||||||
char *buffer;
|
|
||||||
size_t allocated;
|
|
||||||
size_t size;
|
|
||||||
size_t last_allocate;
|
|
||||||
};
|
|
||||||
|
|
||||||
void *cbfs_simple_buffer_map(struct cbfs_simple_buffer *buffer,
|
|
||||||
struct cbfs_media *media,
|
|
||||||
size_t offset, size_t count);
|
|
||||||
|
|
||||||
void *cbfs_simple_buffer_unmap(struct cbfs_simple_buffer *buffer,
|
|
||||||
const void *address);
|
|
||||||
|
|
||||||
// Utility functions
|
|
||||||
int run_address(void *f);
|
|
||||||
|
|
||||||
/* Defined in individual arch / board implementation. */
|
|
||||||
int init_default_cbfs_media(struct cbfs_media *media);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* Copyright (C) 2013 Google, Inc.
|
|
||||||
*
|
|
||||||
* This file is dual-licensed. You can choose between:
|
|
||||||
* - The GNU GPL, version 2, as published by the Free Software Foundation
|
|
||||||
* - The revised BSD license (without advertising clause)
|
|
||||||
*
|
|
||||||
* ---------------------------------------------------------------------------
|
|
||||||
* 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.
|
|
||||||
* ---------------------------------------------------------------------------
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* 3. The name of the author may not be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
* SUCH DAMAGE.
|
|
||||||
* ---------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _CBFS_RAM_H_
|
|
||||||
#define _CBFS_RAM_H_
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
struct cbfs_media;
|
|
||||||
|
|
||||||
/* The following functions return 0 for success. None-zero on error. */
|
|
||||||
int init_cbfs_ram_media(struct cbfs_media *media, void *start, size_t size);
|
|
||||||
int setup_cbfs_from_ram(void *start, uint32_t size);
|
|
||||||
int setup_cbfs_from_flash(void);
|
|
||||||
|
|
||||||
#endif /* _CBFS_RAM_H_ */
|
|
@ -537,8 +537,4 @@ int getline(char *buffer, int len);
|
|||||||
/* Defined in arch/${ARCH}/selfboot.c */
|
/* Defined in arch/${ARCH}/selfboot.c */
|
||||||
void selfboot(void *entry);
|
void selfboot(void *entry);
|
||||||
|
|
||||||
/* look for area "name" in "fmap", setting offset and size to describe it.
|
|
||||||
Returns 0 on success, < 0 on error. */
|
|
||||||
int fmap_region_by_name(const uint32_t fmap_offset, const char * const name,
|
|
||||||
uint32_t * const offset, uint32_t * const size);
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -78,56 +78,3 @@ enum cb_err fmap_locate_area(const char *name, size_t *offset, size_t *size)
|
|||||||
|
|
||||||
return fmap_find_area(_fmap_cache, name, offset, size);
|
return fmap_find_area(_fmap_cache, name, offset, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************************************
|
|
||||||
* LEGACY CODE *
|
|
||||||
**********************************************************************************************/
|
|
||||||
|
|
||||||
int fmap_region_by_name(const uint32_t fmap_offset, const char * const name,
|
|
||||||
uint32_t * const offset, uint32_t * const size)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
struct fmap *fmap;
|
|
||||||
struct fmap fmap_head;
|
|
||||||
struct cbfs_media default_media;
|
|
||||||
struct cbfs_media *media = &default_media;
|
|
||||||
|
|
||||||
if (init_default_cbfs_media(media) != 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
media->open(media);
|
|
||||||
|
|
||||||
if (!media->read(media, &fmap_head, fmap_offset, sizeof(fmap_head)))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (memcmp(fmap_head.signature, FMAP_SIGNATURE, sizeof(fmap_head.signature))) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int fmap_size = sizeof(*fmap) +
|
|
||||||
fmap_head.nareas * sizeof(struct fmap_area);
|
|
||||||
|
|
||||||
fmap = malloc(fmap_size);
|
|
||||||
if (!fmap)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (!media->read(media, fmap, fmap_offset, fmap_size))
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
media->close(media);
|
|
||||||
|
|
||||||
for (i = 0; i < fmap->nareas; i++) {
|
|
||||||
if (strcmp((const char *)fmap->areas[i].name, name) != 0)
|
|
||||||
continue;
|
|
||||||
if (offset)
|
|
||||||
*offset = fmap->areas[i].offset;
|
|
||||||
if (size)
|
|
||||||
*size = fmap->areas[i].size;
|
|
||||||
free(fmap);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
err:
|
|
||||||
free(fmap);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
@ -27,8 +27,6 @@
|
|||||||
##
|
##
|
||||||
|
|
||||||
libcbfs-$(CONFIG_LP_CBFS) += cbfs.c
|
libcbfs-$(CONFIG_LP_CBFS) += cbfs.c
|
||||||
libcbfs-$(CONFIG_LP_CBFS) += ram_media.c
|
|
||||||
libcbfs-$(CONFIG_LP_CBFS) += cbfs_legacy.c
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_LP_CBFS),y)
|
ifeq ($(CONFIG_LP_CBFS),y)
|
||||||
libcbfs-srcs += $(coreboottop)/src/commonlib/bsd/cbfs_private.c
|
libcbfs-srcs += $(coreboottop)/src/commonlib/bsd/cbfs_private.c
|
||||||
|
@ -1,363 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* Copyright (C) 2011 secunet Security Networks AG
|
|
||||||
* Copyright (C) 2013 Google, Inc.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* 3. The name of the author may not be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
* SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* The CBFS core requires a couple of #defines or functions to adapt it to the
|
|
||||||
* target environment:
|
|
||||||
*
|
|
||||||
* CBFS_CORE_WITH_LZMA (must be #define)
|
|
||||||
* if defined, ulzma() must exist for decompression of data streams
|
|
||||||
*
|
|
||||||
* CBFS_CORE_WITH_LZ4 (must be #define)
|
|
||||||
* if defined, ulz4f() must exist for decompression of data streams
|
|
||||||
*
|
|
||||||
* ERROR(x...)
|
|
||||||
* print an error message x (in printf format)
|
|
||||||
*
|
|
||||||
* LOG(x...)
|
|
||||||
* print a message x (in printf format)
|
|
||||||
*
|
|
||||||
* DEBUG(x...)
|
|
||||||
* print a debug message x (in printf format)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <libpayload.h>
|
|
||||||
#include <cbfs.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sysinfo.h>
|
|
||||||
|
|
||||||
/* returns a pointer to CBFS master header, or CBFS_HEADER_INVALID_ADDRESS
|
|
||||||
* on failure */
|
|
||||||
const struct cbfs_header *cbfs_get_header(struct cbfs_media *media)
|
|
||||||
{
|
|
||||||
int32_t rel_offset;
|
|
||||||
const struct cbfs_header *header;
|
|
||||||
struct cbfs_media default_media;
|
|
||||||
|
|
||||||
if (media == CBFS_DEFAULT_MEDIA) {
|
|
||||||
media = &default_media;
|
|
||||||
if (init_default_cbfs_media(media) != 0) {
|
|
||||||
ERROR("Failed to initialize default media.\n");
|
|
||||||
return CBFS_HEADER_INVALID_ADDRESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
media->open(media);
|
|
||||||
|
|
||||||
if (!media->read(media, &rel_offset, (size_t)(0 - sizeof(int32_t)),
|
|
||||||
sizeof(int32_t))) {
|
|
||||||
ERROR("Could not read CBFS master header offset!\n");
|
|
||||||
return CBFS_HEADER_INVALID_ADDRESS;
|
|
||||||
}
|
|
||||||
header = media->map(media, (size_t)rel_offset, sizeof(*header));
|
|
||||||
DEBUG("CBFS header at %#zx (-%#zx from end of image).\n",
|
|
||||||
(size_t)rel_offset, (size_t)-rel_offset);
|
|
||||||
media->close(media);
|
|
||||||
|
|
||||||
if (header == CBFS_MEDIA_INVALID_MAP_ADDRESS) {
|
|
||||||
ERROR("Failed to load CBFS header from %#zx(-%#zx)\n",
|
|
||||||
(size_t)rel_offset, (size_t)-rel_offset);
|
|
||||||
return CBFS_HEADER_INVALID_ADDRESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CBFS_HEADER_MAGIC != ntohl(header->magic)) {
|
|
||||||
ERROR("Could not find valid CBFS master header at %#zx(-%#zx): "
|
|
||||||
"magic %#.8x vs %#.8x.\n", (size_t)rel_offset,
|
|
||||||
(size_t)-rel_offset, CBFS_HEADER_MAGIC,
|
|
||||||
ntohl(header->magic));
|
|
||||||
if (header->magic == 0xffffffff) {
|
|
||||||
ERROR("Maybe ROM is not mapped properly?\n");
|
|
||||||
}
|
|
||||||
return CBFS_HEADER_INVALID_ADDRESS;
|
|
||||||
}
|
|
||||||
return header;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int get_cbfs_range(uint32_t *offset, uint32_t *cbfs_end,
|
|
||||||
struct cbfs_media *media)
|
|
||||||
{
|
|
||||||
const struct cbfs_header *header;
|
|
||||||
|
|
||||||
if (media == CBFS_DEFAULT_MEDIA &&
|
|
||||||
lib_sysinfo.cbfs_offset && lib_sysinfo.cbfs_size) {
|
|
||||||
*offset = lib_sysinfo.cbfs_offset;
|
|
||||||
*cbfs_end = *offset + lib_sysinfo.cbfs_size;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* read offset and size from cbfs master header */
|
|
||||||
DEBUG("Read CBFS offset & size from master header\n");
|
|
||||||
header = cbfs_get_header(media);
|
|
||||||
if (header == CBFS_HEADER_INVALID_ADDRESS)
|
|
||||||
return -1;
|
|
||||||
// Logical offset (for source media) of first file.
|
|
||||||
*offset = ntohl(header->offset);
|
|
||||||
*cbfs_end = ntohl(header->romsize);
|
|
||||||
#if CONFIG(LP_ARCH_X86)
|
|
||||||
// resolve actual length of ROM used for CBFS components
|
|
||||||
// the bootblock size was not taken into account
|
|
||||||
*cbfs_end -= ntohl(header->bootblocksize);
|
|
||||||
|
|
||||||
// fine tune the length to handle alignment positioning.
|
|
||||||
// using (bootblock size) % align, to derive the
|
|
||||||
// number of bytes the bootblock is off from the alignment size.
|
|
||||||
if ((ntohl(header->bootblocksize) % CBFS_ALIGNMENT))
|
|
||||||
*cbfs_end -= (CBFS_ALIGNMENT -
|
|
||||||
(ntohl(header->bootblocksize) % CBFS_ALIGNMENT));
|
|
||||||
else
|
|
||||||
*cbfs_end -= 1;
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* public API starts here*/
|
|
||||||
struct cbfs_handle *cbfs_get_handle(struct cbfs_media *media, const char *name)
|
|
||||||
{
|
|
||||||
const char *vardata;
|
|
||||||
uint32_t offset, cbfs_end, vardata_len;
|
|
||||||
struct cbfs_file file;
|
|
||||||
struct cbfs_handle *handle = malloc(sizeof(*handle));
|
|
||||||
|
|
||||||
if (!handle)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (get_cbfs_range(&offset, &cbfs_end, media)) {
|
|
||||||
ERROR("Failed to find cbfs range\n");
|
|
||||||
free(handle);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (media == CBFS_DEFAULT_MEDIA) {
|
|
||||||
media = &handle->media;
|
|
||||||
if (init_default_cbfs_media(media) != 0) {
|
|
||||||
ERROR("Failed to initialize default media.\n");
|
|
||||||
free(handle);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
memcpy(&handle->media, media, sizeof(*media));
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG("CBFS location: 0x%x~0x%x\n", offset, cbfs_end);
|
|
||||||
DEBUG("Looking for '%s' starting from 0x%x.\n", name, offset);
|
|
||||||
|
|
||||||
media->open(media);
|
|
||||||
while (offset < cbfs_end &&
|
|
||||||
media->read(media, &file, offset, sizeof(file)) == sizeof(file)) {
|
|
||||||
if (memcmp(CBFS_FILE_MAGIC, file.magic,
|
|
||||||
sizeof(file.magic)) != 0) {
|
|
||||||
uint32_t new_align = CBFS_ALIGNMENT;
|
|
||||||
if (offset % CBFS_ALIGNMENT)
|
|
||||||
new_align += CBFS_ALIGNMENT -
|
|
||||||
(offset % CBFS_ALIGNMENT);
|
|
||||||
ERROR("ERROR: No file header found at 0x%xx - "
|
|
||||||
"try next aligned address: 0x%x.\n", offset,
|
|
||||||
offset + new_align);
|
|
||||||
offset += new_align;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
vardata_len = ntohl(file.offset) - sizeof(file);
|
|
||||||
DEBUG(" - load entry 0x%x variable data (%d bytes)...\n",
|
|
||||||
offset, vardata_len);
|
|
||||||
|
|
||||||
// load file name (arbitrary length).
|
|
||||||
vardata = (const char*)media->map(
|
|
||||||
media, offset + sizeof(file), vardata_len);
|
|
||||||
if (vardata == CBFS_MEDIA_INVALID_MAP_ADDRESS) {
|
|
||||||
ERROR("ERROR: Failed to get filename: 0x%x.\n", offset);
|
|
||||||
} else if (strcmp(vardata, name) == 0) {
|
|
||||||
int file_offset = ntohl(file.offset),
|
|
||||||
file_len = ntohl(file.len);
|
|
||||||
DEBUG("Found file (offset=0x%x, len=%d).\n",
|
|
||||||
offset + file_offset, file_len);
|
|
||||||
media->unmap(media, vardata);
|
|
||||||
media->close(media);
|
|
||||||
handle->type = ntohl(file.type);
|
|
||||||
handle->media_offset = offset;
|
|
||||||
handle->content_offset = file_offset;
|
|
||||||
handle->content_size = file_len;
|
|
||||||
handle->attribute_offset =
|
|
||||||
ntohl(file.attributes_offset);
|
|
||||||
return handle;
|
|
||||||
} else {
|
|
||||||
DEBUG(" (unmatched file @0x%x: %s)\n", offset,
|
|
||||||
vardata);
|
|
||||||
media->unmap(media, vardata);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move to next file.
|
|
||||||
uint32_t next_offset = offset + ntohl(file.len) + ntohl(file.offset);
|
|
||||||
if (next_offset % CBFS_ALIGNMENT)
|
|
||||||
next_offset += CBFS_ALIGNMENT - (next_offset % CBFS_ALIGNMENT);
|
|
||||||
// Check that offset is strictly monotonic to prevent infinite loop
|
|
||||||
if (next_offset <= offset) {
|
|
||||||
ERROR("ERROR: corrupted CBFS file header at 0x%x.\n", offset);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
offset = next_offset;
|
|
||||||
}
|
|
||||||
media->close(media);
|
|
||||||
LOG("WARNING: '%s' not found.\n", name);
|
|
||||||
free(handle);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *cbfs_get_contents(struct cbfs_handle *handle, size_t *size, size_t limit)
|
|
||||||
{
|
|
||||||
struct cbfs_media *m = &handle->media;
|
|
||||||
size_t on_media_size = handle->content_size;
|
|
||||||
int algo = CBFS_COMPRESS_NONE;
|
|
||||||
void *ret = NULL;
|
|
||||||
size_t dummy_size;
|
|
||||||
|
|
||||||
if (!size)
|
|
||||||
size = &dummy_size;
|
|
||||||
|
|
||||||
struct cbfs_file_attr_compression *comp =
|
|
||||||
cbfs_get_attr(handle, CBFS_FILE_ATTR_TAG_COMPRESSION);
|
|
||||||
if (comp) {
|
|
||||||
algo = ntohl(comp->compression);
|
|
||||||
DEBUG("File '%s' is compressed (alg=%d)\n", name, algo);
|
|
||||||
*size = ntohl(comp->decompressed_size);
|
|
||||||
/* TODO: Implement partial decompression with |limit| */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (algo == CBFS_COMPRESS_NONE) {
|
|
||||||
if (limit != 0 && limit < on_media_size)
|
|
||||||
on_media_size = limit;
|
|
||||||
*size = on_media_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *data = m->map(m, handle->media_offset + handle->content_offset,
|
|
||||||
on_media_size);
|
|
||||||
if (data == CBFS_MEDIA_INVALID_MAP_ADDRESS)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
ret = malloc(*size);
|
|
||||||
if (ret != NULL) {
|
|
||||||
size_t final_size = cbfs_decompress(algo, data, on_media_size,
|
|
||||||
ret, *size);
|
|
||||||
if (final_size != *size) {
|
|
||||||
ERROR("Expect %zu bytes but got %zu bytes after "
|
|
||||||
"decompression.\n", *size, final_size);
|
|
||||||
free(ret);
|
|
||||||
ret = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m->unmap(m, data);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *cbfs_get_file_content(struct cbfs_media *media, const char *name,
|
|
||||||
int type, size_t *sz)
|
|
||||||
{
|
|
||||||
void *ret = NULL;
|
|
||||||
struct cbfs_handle *handle = cbfs_get_handle(media, name);
|
|
||||||
|
|
||||||
if (!handle)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (handle->type == type)
|
|
||||||
ret = cbfs_get_contents(handle, sz, 0);
|
|
||||||
else
|
|
||||||
ERROR("File '%s' is of type %x, but we requested %x.\n", name,
|
|
||||||
handle->type, type);
|
|
||||||
|
|
||||||
free(handle);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *cbfs_get_attr(struct cbfs_handle *handle, uint32_t tag)
|
|
||||||
{
|
|
||||||
struct cbfs_media *m = &handle->media;
|
|
||||||
uint32_t offset = handle->media_offset + handle->attribute_offset;
|
|
||||||
uint32_t end = handle->media_offset + handle->content_offset;
|
|
||||||
struct cbfs_file_attribute attr;
|
|
||||||
void *ret;
|
|
||||||
|
|
||||||
/* attribute_offset should be 0 when there is no attribute, but all
|
|
||||||
* values that point into the cbfs_file header are invalid, too. */
|
|
||||||
if (handle->attribute_offset <= sizeof(struct cbfs_file))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
m->open(m);
|
|
||||||
while (offset + sizeof(attr) <= end) {
|
|
||||||
if (m->read(m, &attr, offset, sizeof(attr)) != sizeof(attr)) {
|
|
||||||
ERROR("Failed to read attribute header %#x\n", offset);
|
|
||||||
m->close(m);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (ntohl(attr.tag) != tag) {
|
|
||||||
uint32_t next_offset = offset + ntohl(attr.len);
|
|
||||||
// Check that offset is strictly monotonic to prevent infinite loop
|
|
||||||
if (next_offset <= offset) {
|
|
||||||
ERROR("ERROR: corrupted CBFS attribute at 0x%x.\n", offset);
|
|
||||||
m->close(m);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
offset = next_offset;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
ret = m->map(m, offset, ntohl(attr.len));
|
|
||||||
if (ret == CBFS_MEDIA_INVALID_MAP_ADDRESS) {
|
|
||||||
ERROR("Failed to map attribute at %#x\n", offset);
|
|
||||||
m->close(m);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
m->close(m);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t cbfs_decompress(int algo, const void *src, size_t srcn, void *dst,
|
|
||||||
size_t dstn)
|
|
||||||
{
|
|
||||||
size_t len;
|
|
||||||
switch (algo) {
|
|
||||||
case CBFS_COMPRESS_NONE:
|
|
||||||
len = MIN(srcn, dstn);
|
|
||||||
memcpy(dst, src, len);
|
|
||||||
return len;
|
|
||||||
#ifdef CBFS_CORE_WITH_LZMA
|
|
||||||
case CBFS_COMPRESS_LZMA:
|
|
||||||
return ulzman(src, srcn, dst, dstn);
|
|
||||||
#endif
|
|
||||||
#ifdef CBFS_CORE_WITH_LZ4
|
|
||||||
case CBFS_COMPRESS_LZ4:
|
|
||||||
return ulz4fn(src, srcn, dst, dstn);
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
ERROR("tried to decompress %zu bytes with algorithm "
|
|
||||||
"#%x, but that algorithm id is unsupported.\n",
|
|
||||||
srcn, algo);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,243 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* Copyright (C) 2011 secunet Security Networks AG
|
|
||||||
* Copyright (C) 2013 Google, Inc.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* 3. The name of the author may not be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
* SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
#define LIBPAYLOAD
|
|
||||||
|
|
||||||
#ifdef LIBPAYLOAD
|
|
||||||
# include <libpayload-config.h>
|
|
||||||
# if CONFIG(LP_LZMA)
|
|
||||||
# include <lzma.h>
|
|
||||||
# define CBFS_CORE_WITH_LZMA
|
|
||||||
# endif
|
|
||||||
# if CONFIG(LP_LZ4)
|
|
||||||
# include <lz4.h>
|
|
||||||
# define CBFS_CORE_WITH_LZ4
|
|
||||||
# endif
|
|
||||||
# define CBFS_MINI_BUILD
|
|
||||||
#elif defined(__SMM__)
|
|
||||||
# define CBFS_MINI_BUILD
|
|
||||||
#else
|
|
||||||
# define CBFS_CORE_WITH_LZMA
|
|
||||||
# define CBFS_CORE_WITH_LZ4
|
|
||||||
# include <lib.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <cbfs.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#ifdef LIBPAYLOAD
|
|
||||||
# include <stdio.h>
|
|
||||||
# define DEBUG(x...)
|
|
||||||
# define LOG(x...)
|
|
||||||
# define ERROR(x...) printf(x)
|
|
||||||
#else
|
|
||||||
# include <console/console.h>
|
|
||||||
# define ERROR(x...) printk(BIOS_ERR, "CBFS: " x)
|
|
||||||
# define LOG(x...) printk(BIOS_INFO, "CBFS: " x)
|
|
||||||
# if CONFIG_LP_DEBUG_CBFS
|
|
||||||
# define DEBUG(x...) printk(BIOS_SPEW, "CBFS: " x)
|
|
||||||
# else
|
|
||||||
# define DEBUG(x...)
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "cbfs_core.c"
|
|
||||||
|
|
||||||
#ifndef __SMM__
|
|
||||||
static inline int tohex4(unsigned int c)
|
|
||||||
{
|
|
||||||
return (c <= 9) ? (c + '0') : (c - 10 + 'a');
|
|
||||||
}
|
|
||||||
|
|
||||||
static void tohex16(unsigned int val, char* dest)
|
|
||||||
{
|
|
||||||
dest[0] = tohex4(val>>12);
|
|
||||||
dest[1] = tohex4((val>>8) & 0xf);
|
|
||||||
dest[2] = tohex4((val>>4) & 0xf);
|
|
||||||
dest[3] = tohex4(val & 0xf);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *cbfs_load_optionrom(struct cbfs_media *media, uint16_t vendor,
|
|
||||||
uint16_t device)
|
|
||||||
{
|
|
||||||
char name[17] = "pciXXXX,XXXX.rom";
|
|
||||||
|
|
||||||
tohex16(vendor, name+3);
|
|
||||||
tohex16(device, name+8);
|
|
||||||
|
|
||||||
return cbfs_get_file_content(media, name, CBFS_TYPE_OPTIONROM, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void * cbfs_load_stage(struct cbfs_media *media, const char *name)
|
|
||||||
{
|
|
||||||
struct cbfs_stage *stage = (struct cbfs_stage *)
|
|
||||||
cbfs_get_file_content(media, name, CBFS_TYPE_STAGE, NULL);
|
|
||||||
/* this is a mess. There is no ntohll. */
|
|
||||||
/* for now, assume compatible byte order until we solve this. */
|
|
||||||
uintptr_t entry;
|
|
||||||
uint32_t final_size;
|
|
||||||
|
|
||||||
if (stage == NULL)
|
|
||||||
return (void *) -1;
|
|
||||||
|
|
||||||
LOG("loading stage %s @ %p (%d bytes), entry @ 0x%llx\n",
|
|
||||||
name,
|
|
||||||
(void*)(uintptr_t) stage->load, stage->memlen,
|
|
||||||
stage->entry);
|
|
||||||
|
|
||||||
final_size = cbfs_decompress(stage->compression,
|
|
||||||
((unsigned char *) stage) +
|
|
||||||
sizeof(struct cbfs_stage),
|
|
||||||
stage->len,
|
|
||||||
(void *) (uintptr_t) stage->load,
|
|
||||||
stage->memlen);
|
|
||||||
if (!final_size) {
|
|
||||||
entry = -1;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset((void *)((uintptr_t)stage->load + final_size), 0,
|
|
||||||
stage->memlen - final_size);
|
|
||||||
|
|
||||||
DEBUG("stage loaded.\n");
|
|
||||||
|
|
||||||
entry = stage->entry;
|
|
||||||
// entry = ntohll(stage->entry);
|
|
||||||
|
|
||||||
out:
|
|
||||||
free(stage);
|
|
||||||
return (void *) entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cbfs_execute_stage(struct cbfs_media *media, const char *name)
|
|
||||||
{
|
|
||||||
struct cbfs_stage *stage = (struct cbfs_stage *)
|
|
||||||
cbfs_get_file_content(media, name, CBFS_TYPE_STAGE, NULL);
|
|
||||||
|
|
||||||
if (stage == NULL)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (ntohl(stage->compression) != CBFS_COMPRESS_NONE) {
|
|
||||||
LOG("Unable to run %s: Compressed file"
|
|
||||||
"Not supported for in-place execution\n", name);
|
|
||||||
free(stage);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG("run @ %p\n", (void *) (uintptr_t)ntohll(stage->entry));
|
|
||||||
int result = run_address((void *)(uintptr_t)ntohll(stage->entry));
|
|
||||||
free(stage);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *cbfs_load_payload(struct cbfs_media *media, const char *name)
|
|
||||||
{
|
|
||||||
return (struct cbfs_payload *)cbfs_get_file_content(
|
|
||||||
media, name, CBFS_TYPE_SELF, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct cbfs_file *cbfs_find(const char *name) {
|
|
||||||
struct cbfs_handle *handle = cbfs_get_handle(CBFS_DEFAULT_MEDIA, name);
|
|
||||||
struct cbfs_media *m = &handle->media;
|
|
||||||
void *ret;
|
|
||||||
|
|
||||||
if (!handle)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
ret = m->map(m, handle->media_offset,
|
|
||||||
handle->content_offset + handle->content_size);
|
|
||||||
if (ret == CBFS_MEDIA_INVALID_MAP_ADDRESS) {
|
|
||||||
free(handle);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(handle);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *cbfs_find_file(const char *name, int type) {
|
|
||||||
return cbfs_get_file_content(CBFS_DEFAULT_MEDIA, name, type, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
const struct cbfs_header *get_cbfs_header(void) {
|
|
||||||
return cbfs_get_header(CBFS_DEFAULT_MEDIA);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Simple buffer */
|
|
||||||
|
|
||||||
void *cbfs_simple_buffer_map(struct cbfs_simple_buffer *buffer,
|
|
||||||
struct cbfs_media *media,
|
|
||||||
size_t offset, size_t count) {
|
|
||||||
void *address = buffer->buffer + buffer->allocated;
|
|
||||||
DEBUG("simple_buffer_map(offset=%zu, count=%zu): "
|
|
||||||
"allocated=%zu, size=%zu, last_allocate=%zu\n",
|
|
||||||
offset, count, buffer->allocated, buffer->size,
|
|
||||||
buffer->last_allocate);
|
|
||||||
if (buffer->allocated + count >= buffer->size)
|
|
||||||
return CBFS_MEDIA_INVALID_MAP_ADDRESS;
|
|
||||||
if (media->read(media, address, offset, count) != count) {
|
|
||||||
ERROR("simple_buffer: fail to read %zd bytes from 0x%zx\n",
|
|
||||||
count, offset);
|
|
||||||
return CBFS_MEDIA_INVALID_MAP_ADDRESS;
|
|
||||||
}
|
|
||||||
buffer->allocated += count;
|
|
||||||
buffer->last_allocate = count;
|
|
||||||
return address;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *cbfs_simple_buffer_unmap(struct cbfs_simple_buffer *buffer,
|
|
||||||
const void *address) {
|
|
||||||
// TODO Add simple buffer management so we can free more than last
|
|
||||||
// allocated one.
|
|
||||||
DEBUG("simple_buffer_unmap(address=%p): "
|
|
||||||
"allocated=%zu, size=%zu, last_allocate=%zu\n",
|
|
||||||
address, buffer->allocated, buffer->size,
|
|
||||||
buffer->last_allocate);
|
|
||||||
if ((buffer->buffer + buffer->allocated - buffer->last_allocate) ==
|
|
||||||
address) {
|
|
||||||
buffer->allocated -= buffer->last_allocate;
|
|
||||||
buffer->last_allocate = 0;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* run_address is passed the address of a function taking no parameters and
|
|
||||||
* jumps to it, returning the result.
|
|
||||||
* @param f the address to call as a function.
|
|
||||||
* @return value returned by the function.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int run_address(void *f)
|
|
||||||
{
|
|
||||||
int (*v) (void);
|
|
||||||
v = f;
|
|
||||||
return v();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,117 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* Copyright (C) 2013 Google, Inc.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* 3. The name of the author may not be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
* SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
#include <cbfs.h>
|
|
||||||
#include <cbfs_ram.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
// Implementation of a media source based on given memory buffer.
|
|
||||||
struct ram_media {
|
|
||||||
char *start;
|
|
||||||
size_t size;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int ram_open(struct cbfs_media *media) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *ram_map(struct cbfs_media *media, size_t offset, size_t count) {
|
|
||||||
struct ram_media *m = (struct ram_media*)media->context;
|
|
||||||
/* assume addressing from top of image in this case */
|
|
||||||
if (offset > 0xf0000000) {
|
|
||||||
offset = m->size + offset;
|
|
||||||
}
|
|
||||||
if (offset + count > m->size) {
|
|
||||||
printf("ERROR: ram_map: request out of range (0x%zx+0x%zx)\n",
|
|
||||||
offset, count);
|
|
||||||
return CBFS_MEDIA_INVALID_MAP_ADDRESS;
|
|
||||||
}
|
|
||||||
return (void*)(m->start + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *ram_unmap(struct cbfs_media *media, const void *address) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t ram_read(struct cbfs_media *media, void *dest, size_t offset,
|
|
||||||
size_t count) {
|
|
||||||
void *ptr = ram_map(media, offset, count);
|
|
||||||
if (ptr == CBFS_MEDIA_INVALID_MAP_ADDRESS)
|
|
||||||
return 0;
|
|
||||||
memcpy(dest, ptr, count);
|
|
||||||
ram_unmap(media, ptr);
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ram_close(struct cbfs_media *media) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int init_cbfs_ram_media(struct cbfs_media *media, void *start, size_t size) {
|
|
||||||
// TODO Find a way to release unused media. Maybe adding media->destroy.
|
|
||||||
struct ram_media *m = (struct ram_media*)malloc(sizeof(*m));
|
|
||||||
m->start = start;
|
|
||||||
m->size = size;
|
|
||||||
media->context = (void*)m;
|
|
||||||
media->open = ram_open;
|
|
||||||
media->close = ram_close;
|
|
||||||
media->map = ram_map;
|
|
||||||
media->unmap = ram_unmap;
|
|
||||||
media->read = ram_read;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Legacy setup_cbfs_from_*.
|
|
||||||
static int is_default_cbfs_media_initialized;
|
|
||||||
static struct cbfs_media default_cbfs_media;
|
|
||||||
|
|
||||||
int setup_cbfs_from_ram(void *start, uint32_t size) {
|
|
||||||
int result = init_cbfs_ram_media(&default_cbfs_media, start, size);
|
|
||||||
if (result == 0)
|
|
||||||
is_default_cbfs_media_initialized = 1;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern int libpayload_init_default_cbfs_media(struct cbfs_media *media);
|
|
||||||
int setup_cbfs_from_flash(void) {
|
|
||||||
int result = libpayload_init_default_cbfs_media(&default_cbfs_media);
|
|
||||||
if (result == 0)
|
|
||||||
is_default_cbfs_media_initialized = 1;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int init_default_cbfs_media(struct cbfs_media *media) {
|
|
||||||
int result = 0;
|
|
||||||
if (is_default_cbfs_media_initialized != 1) {
|
|
||||||
result = setup_cbfs_from_flash();
|
|
||||||
}
|
|
||||||
if (result == 0)
|
|
||||||
memcpy(media, &default_cbfs_media, sizeof(*media));
|
|
||||||
return result;
|
|
||||||
}
|
|
Reference in New Issue
Block a user