From 63e54275f684da6f6db8289561726adab5254b39 Mon Sep 17 00:00:00 2001 From: Jakub Czapiga Date: Mon, 15 Nov 2021 08:36:07 +0000 Subject: libpayload: Implement new CBFS access API This commit adds new CBFS API, which is based on the one available in the main coreboot source tree. Libpayload implementation supports RO/RW file lookups and file contents verification. Change-Id: I00da0658dbac0cddf92ad55611def947932d23c7 Signed-off-by: Jakub Czapiga Reviewed-on: https://review.coreboot.org/c/coreboot/+/59497 Tested-by: build bot (Jenkins) Reviewed-by: Julius Werner --- payloads/libpayload/include/cbfs.h | 180 ++++++++++++++++++------------ payloads/libpayload/include/cbfs_core.h | 154 +------------------------ payloads/libpayload/include/cbfs_glue.h | 46 ++++++++ payloads/libpayload/include/cbfs_legacy.h | 83 ++++++++++++++ 4 files changed, 241 insertions(+), 222 deletions(-) create mode 100644 payloads/libpayload/include/cbfs_glue.h create mode 100644 payloads/libpayload/include/cbfs_legacy.h (limited to 'payloads/libpayload/include') diff --git a/payloads/libpayload/include/cbfs.h b/payloads/libpayload/include/cbfs.h index ab23b02e0377..8adadb737e9e 100644 --- a/payloads/libpayload/include/cbfs.h +++ b/payloads/libpayload/include/cbfs.h @@ -1,82 +1,124 @@ -/* - * - * Copyright (C) 2008 Jordan Crouse - * 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. - * --------------------------------------------------------------------------- - */ +/* SPDX-License-Identifier: BSD-3-Clause */ #ifndef _CBFS_H_ #define _CBFS_H_ -#include +#include +#include +#include +#include -/* 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); +/********************************************************************************************** + * CBFS FILE ACCESS APIs * + **********************************************************************************************/ -/* Simple buffer for streaming media. */ -struct cbfs_simple_buffer { - char *buffer; - size_t allocated; - size_t size; - size_t last_allocate; -}; +/* For documentation look in src/include/cbfs.h file in the main coreboot source tree. */ -void *cbfs_simple_buffer_map(struct cbfs_simple_buffer *buffer, - struct cbfs_media *media, - size_t offset, size_t count); +static inline size_t cbfs_load(const char *name, void *buf, size_t size); +static inline size_t cbfs_ro_load(const char *name, void *buf, size_t size); -void *cbfs_simple_buffer_unmap(struct cbfs_simple_buffer *buffer, - const void *address); +static inline void *cbfs_map(const char *name, size_t *size_out); +static inline void *cbfs_ro_map(const char *name, size_t *size_out); -// Utility functions -int run_address(void *f); +void cbfs_unmap(void *mapping); -/* Defined in individual arch / board implementation. */ -int init_default_cbfs_media(struct cbfs_media *media); +static inline size_t cbfs_get_size(const char *name); +static inline size_t cbfs_ro_get_size(const char *name); + +static inline enum cbfs_type cbfs_get_type(const char *name); +static inline enum cbfs_type cbfs_ro_get_type(const char *name); + +static inline bool cbfs_file_exists(const char *name); +static inline bool cbfs_ro_file_exists(const char *name); + +/********************************************************************************************** + * INTERNAL HELPERS FOR INLINES, DO NOT USE. * + **********************************************************************************************/ +ssize_t _cbfs_boot_lookup(const char *name, bool force_ro, union cbfs_mdata *mdata); + +void *_cbfs_load(const char *name, void *buf, size_t *size_inout, bool force_ro); + +/********************************************************************************************** + * INLINE IMPLEMENTATIONS * + **********************************************************************************************/ + +static inline void *cbfs_map(const char *name, size_t *size_out) +{ + return _cbfs_load(name, NULL, size_out, false); +} + +static inline void *cbfs_ro_map(const char *name, size_t *size_out) +{ + return _cbfs_load(name, NULL, size_out, true); +} + +static inline size_t cbfs_load(const char *name, void *buf, size_t size) +{ + if (_cbfs_load(name, buf, &size, false)) + return size; + else + return 0; +} + +static inline size_t cbfs_ro_load(const char *name, void *buf, size_t size) +{ + if (_cbfs_load(name, buf, &size, true)) + return size; + else + return 0; +} + +static inline size_t cbfs_get_size(const char *name) +{ + union cbfs_mdata mdata; + if (_cbfs_boot_lookup(name, false, &mdata) < 0) + return 0; + else + return be32toh(mdata.h.len); +} + +static inline size_t cbfs_ro_get_size(const char *name) +{ + union cbfs_mdata mdata; + if (_cbfs_boot_lookup(name, true, &mdata) < 0) + return 0; + else + return be32toh(mdata.h.len); +} + +static inline enum cbfs_type cbfs_get_type(const char *name) +{ + union cbfs_mdata mdata; + if (_cbfs_boot_lookup(name, false, &mdata) < 0) + return CBFS_TYPE_NULL; + else + return be32toh(mdata.h.type); +} + +static inline enum cbfs_type cbfs_ro_get_type(const char *name) +{ + union cbfs_mdata mdata; + if (_cbfs_boot_lookup(name, true, &mdata) < 0) + return CBFS_TYPE_NULL; + else + return be32toh(mdata.h.type); +} + +static inline bool cbfs_file_exists(const char *name) +{ + union cbfs_mdata mdata; + return _cbfs_boot_lookup(name, false, &mdata) >= 0; +} + +static inline bool cbfs_ro_file_exists(const char *name) +{ + union cbfs_mdata mdata; + return _cbfs_boot_lookup(name, true, &mdata) >= 0; +} + + +/* Legacy API. Designated for removal in the future. */ +#include #endif diff --git a/payloads/libpayload/include/cbfs_core.h b/payloads/libpayload/include/cbfs_core.h index fc4caa44177c..4a638d971a49 100644 --- a/payloads/libpayload/include/cbfs_core.h +++ b/payloads/libpayload/include/cbfs_core.h @@ -45,139 +45,14 @@ #ifndef _CBFS_CORE_H_ #define _CBFS_CORE_H_ +#include #include #include #include #include -/** These are standard values for the known compression - alogrithms that coreboot knows about for stages and - payloads. Of course, other CBFS users can use whatever - values they want, as long as they understand them. */ - -#define CBFS_COMPRESS_NONE 0 -#define CBFS_COMPRESS_LZMA 1 -#define CBFS_COMPRESS_LZ4 2 - -/** These are standard component types for well known - components (i.e - those that coreboot needs to consume. - Users are welcome to use any other value for their - components */ - -#define CBFS_TYPE_STAGE 0x10 -#define CBFS_TYPE_SELF 0x20 -#define CBFS_TYPE_FIT 0x21 -#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_TYPE_STRUCT 0x70 -#define CBFS_COMPONENT_CMOS_DEFAULT 0xaa -#define CBFS_COMPONENT_CMOS_LAYOUT 0x01aa - -#define CBFS_HEADER_MAGIC 0x4F524243 -#define CBFS_HEADER_VERSION1 0x31313131 -#define CBFS_HEADER_VERSION2 0x31313132 -#define CBFS_HEADER_VERSION CBFS_HEADER_VERSION2 - #define CBFS_HEADER_INVALID_ADDRESS ((void*)(0xffffffff)) -/* this is the master cbfs header - it must be located somewhere available - * to bootblock (to load romstage). The last 4 bytes in the image contain its - * relative offset from the end of the image (as a 32-bit signed integer). */ - -struct cbfs_header { - uint32_t magic; - uint32_t version; - uint32_t romsize; - uint32_t bootblocksize; - uint32_t align; /* fixed to 64 bytes */ - uint32_t offset; - uint32_t architecture; - uint32_t pad[1]; -} __packed; - -/* this used to be flexible, but wasn't ever set to something different. */ -#define CBFS_ALIGNMENT 64 - -/* "Unknown" refers to CBFS headers version 1, - * before the architecture was defined (i.e., x86 only). - */ -#define CBFS_ARCHITECTURE_UNKNOWN 0xFFFFFFFF -#define CBFS_ARCHITECTURE_X86 0x00000001 -#define CBFS_ARCHITECTURE_ARM 0x00000010 -#define CBFS_ARCHITECTURE_ARM64 0x00000011 - -/** This is a component header - every entry in the CBFS - will have this header. - - This is how the component is arranged in the ROM: - - -------------- <- 0 - component header - -------------- <- sizeof(struct component) - component name - -------------- <- offset - data - ... - -------------- <- offset + len -*/ - -#define CBFS_FILE_MAGIC "LARCHIVE" - -struct cbfs_file { - char magic[8]; - uint32_t len; - uint32_t type; - uint32_t attributes_offset; - uint32_t offset; - char filename[]; -} __packed; - -/* Depending on how the header was initialized, it may be backed with 0x00 or - * 0xff. Support both. */ -#define CBFS_FILE_ATTR_TAG_UNUSED 0 -#define CBFS_FILE_ATTR_TAG_UNUSED2 0xffffffff -#define CBFS_FILE_ATTR_TAG_COMPRESSION 0x42435a4c -#define CBFS_FILE_ATTR_TAG_HASH 0x68736148 -#define CBFS_FILE_ATTR_TAG_IBB 0x32494242 /* Initial BootBlock */ - -/* The common fields of extended cbfs file attributes. - Attributes are expected to start with tag/len, then append their - specific fields. */ -struct cbfs_file_attribute { - uint32_t tag; - /* len covers the whole structure, incl. tag and len */ - uint32_t len; - uint8_t data[0]; -} __packed; - -struct cbfs_file_attr_compression { - uint32_t tag; - uint32_t len; - /* whole file compression format. 0 if no compression. */ - uint32_t compression; - uint32_t decompressed_size; -} __packed; - -struct cbfs_file_attr_hash { - uint32_t tag; - uint32_t len; - uint32_t hash_type; - /* hash_data is len - sizeof(struct) bytes */ - uint8_t hash_data[]; -} __packed; - -/*** Component sub-headers ***/ - -/* Following are component sub-headers for the "standard" - component types */ - -/** This is the sub-header for stage components. Stages are - loaded by coreboot during the normal boot process */ - struct cbfs_stage { uint32_t compression; /** Compression type */ uint64_t entry; /** entry point */ @@ -186,33 +61,6 @@ struct cbfs_stage { uint32_t memlen; /** total length of object in memory */ } __packed; -/** this is the sub-header for payload components. Payloads - are loaded by coreboot at the end of the boot process */ - -struct cbfs_payload_segment { - uint32_t type; - uint32_t compression; - uint32_t offset; - uint64_t load_addr; - uint32_t len; - uint32_t mem_len; -} __packed; - -struct cbfs_payload { - struct cbfs_payload_segment segments; -}; - -#define PAYLOAD_SEGMENT_CODE 0x45444F43 -#define PAYLOAD_SEGMENT_DATA 0x41544144 -#define PAYLOAD_SEGMENT_BSS 0x20535342 -#define PAYLOAD_SEGMENT_PARAMS 0x41524150 -#define PAYLOAD_SEGMENT_ENTRY 0x52544E45 - -struct cbfs_optionrom { - uint32_t compression; - uint32_t len; -} __packed; - #define CBFS_MEDIA_INVALID_MAP_ADDRESS ((void*)(0xffffffff)) #define CBFS_DEFAULT_MEDIA ((void*)(0x0)) diff --git a/payloads/libpayload/include/cbfs_glue.h b/payloads/libpayload/include/cbfs_glue.h new file mode 100644 index 000000000000..00d0ea943aba --- /dev/null +++ b/payloads/libpayload/include/cbfs_glue.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ + +#ifndef _CBFS_CBFS_GLUE_H +#define _CBFS_CBFS_GLUE_H + +#include +#include +#include + +#define CBFS_ENABLE_HASHING CONFIG(LP_CBFS_VERIFICATION) + +#define ERROR(...) printf("CBFS ERROR: " __VA_ARGS__) +#define LOG(...) printf("CBFS: " __VA_ARGS__) +#define DEBUG(...) \ + do { \ + if (CONFIG(LP_DEBUG_CBFS)) \ + printf("CBFS DEBUG: " __VA_ARGS__); \ + } while (0) + +struct cbfs_dev { + size_t offset; + size_t size; +}; + +struct cbfs_boot_device { + struct cbfs_dev dev; + void *mcache; + size_t mcache_size; +}; + +typedef const struct cbfs_dev *cbfs_dev_t; + +static inline ssize_t cbfs_dev_read(cbfs_dev_t dev, void *buffer, size_t offset, size_t size) +{ + if (offset + size < offset || offset + size > dev->size) + return CB_ERR_ARG; + + return boot_device_read(buffer, dev->offset + offset, size); +} + +static inline size_t cbfs_dev_size(cbfs_dev_t dev) +{ + return dev->size; +} + +#endif /* _CBFS_CBFS_GLUE_H */ diff --git a/payloads/libpayload/include/cbfs_legacy.h b/payloads/libpayload/include/cbfs_legacy.h new file mode 100644 index 000000000000..c1b896cea443 --- /dev/null +++ b/payloads/libpayload/include/cbfs_legacy.h @@ -0,0 +1,83 @@ +/* + * + * Copyright (C) 2008 Jordan Crouse + * 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 +#include + +/* 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 -- cgit v1.2.3