diff options
author | Julius Werner <jwerner@chromium.org> | 2019-12-11 15:47:42 -0800 |
---|---|---|
committer | Julius Werner <jwerner@chromium.org> | 2020-01-28 06:36:13 +0000 |
commit | 98eeb961353d187a26085a07889bd0414cdaa910 (patch) | |
tree | b97e2edbdb5033a93095044be96c809271bd0be8 /src/commonlib/bsd/include | |
parent | e4d6c033fe91cf777a95531669622f7829e6b44d (diff) |
commonlib: Add commonlib/bsd
This patch creates a new commonlib/bsd subdirectory with a similar
purpose to the existing commonlib, with the difference that all files
under this subdirectory shall be licensed under the BSD-3-Clause license
(or compatible permissive license). The goal is to allow more code to be
shared with libpayload in the future.
Initially, I'm going to move a few files there that have already been
BSD-licensed in the existing commonlib. I am also exracting most
contents of the often-needed <commonlib/helpers.h> as long as they have
either been written by me (and are hereby relicensed) or have an
existing equivalent in BSD-licensed libpayload code. I am also
relicensing <commonlib/compression.h> (written by me) and
<commonlib/compiler.h> (same stuff exists in libpayload).
Finally, I am extracting the cb_err error code definitions from
<types.h> into a new BSD-licensed header so that future commonlib/bsd
code can build upon a common set of error values. I am making the
assumption here that the enum constants and the half-sentence fragments
of documentation next to them by themselves do not meet the threshold of
copyrightability.
Change-Id: I316cea70930f131e8e93d4218542ddb5ae4b63a2
Signed-off-by: Julius Werner <jwerner@chromium.org>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/38420
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Rudolph <siro@das-labor.org>
Diffstat (limited to 'src/commonlib/bsd/include')
6 files changed, 436 insertions, 0 deletions
diff --git a/src/commonlib/bsd/include/commonlib/bsd/cb_err.h b/src/commonlib/bsd/include/commonlib/bsd/cb_err.h new file mode 100644 index 0000000000..ab419a7709 --- /dev/null +++ b/src/commonlib/bsd/include/commonlib/bsd/cb_err.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-or-later */ + +#ifndef _COMMONLIB_BSD_CB_ERR_H_ +#define _COMMONLIB_BSD_CB_ERR_H_ + +#include <stdint.h> + +/** + * coreboot error codes + * + * Common error definitions that can be used for any function. All error values + * should be negative -- when useful, positive values can also be used to denote + * success. Allocate a new group or errors every 100 values. + */ +enum cb_err { + CB_SUCCESS = 0, /**< Call completed successfully */ + CB_ERR = -1, /**< Generic error code */ + CB_ERR_ARG = -2, /**< Invalid argument */ + + /* NVRAM/CMOS errors */ + CB_CMOS_OTABLE_DISABLED = -100, /**< Option table disabled */ + CB_CMOS_LAYOUT_NOT_FOUND = -101, /**< Layout file not found */ + CB_CMOS_OPTION_NOT_FOUND = -102, /**< Option string not found */ + CB_CMOS_ACCESS_ERROR = -103, /**< CMOS access error */ + CB_CMOS_CHECKSUM_INVALID = -104, /**< CMOS checksum is invalid */ + + /* Keyboard test failures */ + CB_KBD_CONTROLLER_FAILURE = -200, + CB_KBD_INTERFACE_FAILURE = -201, + + /* I2C controller failures */ + CB_I2C_NO_DEVICE = -300, /**< Device is not responding */ + CB_I2C_BUSY = -301, /**< Device tells it's busy */ + CB_I2C_PROTOCOL_ERROR = -302, /**< Data lost or spurious slave + device response, try again? */ + CB_I2C_TIMEOUT = -303, /**< Transmission timed out */ +}; + +/* Don't typedef the enum directly, so the size is unambiguous for serialization. */ +typedef int32_t cb_err_t; + +#endif /* _COMMONLIB_BSD_CB_ERR_H_ */ diff --git a/src/commonlib/bsd/include/commonlib/bsd/cbfs_serialized.h b/src/commonlib/bsd/include/commonlib/bsd/cbfs_serialized.h new file mode 100644 index 0000000000..d2fc6267ad --- /dev/null +++ b/src/commonlib/bsd/include/commonlib/bsd/cbfs_serialized.h @@ -0,0 +1,190 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +#ifndef _CBFS_SERIALIZED_H_ +#define _CBFS_SERIALIZED_H_ + +#include <stdint.h> + +/** These are standard values for the known compression + algorithms 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_DELETED 0x00000000 +#define CBFS_TYPE_DELETED2 0xffffffff +#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_FSP 0x60 +#define CBFS_TYPE_MRC 0x61 +#define CBFS_TYPE_MMA 0x62 +#define CBFS_TYPE_EFI 0x63 +#define CBFS_TYPE_STRUCT 0x70 +#define CBFS_COMPONENT_CMOS_DEFAULT 0xaa +#define CBFS_TYPE_SPD 0xab +#define CBFS_TYPE_MRC_CACHE 0xac +#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 + +/* 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 + +/** 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; +} __packed; + +/* 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; + +/* 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_POSITION 0x42435350 /* PSCB */ +#define CBFS_FILE_ATTR_TAG_ALIGNMENT 0x42434c41 /* ALCB */ +#define CBFS_FILE_ATTR_TAG_IBB 0x32494242 /* Initial BootBlock */ + +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; + +struct cbfs_file_attr_position { + uint32_t tag; + uint32_t len; + uint32_t position; +} __packed; + +struct cbfs_file_attr_align { + uint32_t tag; + uint32_t len; + uint32_t alignment; +} __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 */ + 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; + +/** 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 0x434F4445 +#define PAYLOAD_SEGMENT_DATA 0x44415441 +#define PAYLOAD_SEGMENT_BSS 0x42535320 +#define PAYLOAD_SEGMENT_PARAMS 0x50415241 +#define PAYLOAD_SEGMENT_ENTRY 0x454E5452 + +struct cbfs_optionrom { + uint32_t compression; + uint32_t len; +} __packed; + +#endif /* _CBFS_SERIALIZED_H_ */ diff --git a/src/commonlib/bsd/include/commonlib/bsd/compiler.h b/src/commonlib/bsd/include/commonlib/bsd/compiler.h new file mode 100644 index 0000000000..ee2ff88d10 --- /dev/null +++ b/src/commonlib/bsd/include/commonlib/bsd/compiler.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +#ifndef _COMMONLIB_BSD_COMPILER_H_ +#define _COMMONLIB_BSD_COMPILER_H_ + +#ifndef __packed +#if defined(__WIN32) || defined(__WIN64) +#define __packed __attribute__((gcc_struct, packed)) +#else +#define __packed __attribute__((packed)) +#endif +#endif + +#ifndef __aligned +#define __aligned(x) __attribute__((aligned(x))) +#endif + +#ifndef __always_unused +#define __always_unused __attribute__((unused)) +#endif + +#ifndef __must_check +#define __must_check __attribute__((warn_unused_result)) +#endif + +#ifndef __weak +#define __weak __attribute__((weak)) +#endif + +#ifndef __noreturn +#define __noreturn __attribute__((noreturn)) +#endif + +#ifndef __always_inline +#define __always_inline inline __attribute__((always_inline)) +#endif + +/* This evaluates to the type of the first expression, unless that is constant + in which case it evalutates to the type of the second. This is useful when + assigning macro parameters to temporary variables, because that would + normally circumvent the special loosened type promotion rules for integer + literals. By using this macro, the promotion can happen at the time the + literal is assigned to the temporary variable. If the literal doesn't fit in + the chosen type, -Werror=overflow will catch it, so this should be safe. */ +#define __TYPEOF_UNLESS_CONST(expr, fallback_expr) __typeof__( \ + __builtin_choose_expr(__builtin_constant_p(expr), fallback_expr, expr)) + +/* This creates a unique local variable name for use in macros. */ +#define __TMPNAME_3(i) __tmpname_##i +#define __TMPNAME_2(i) __TMPNAME_3(i) +#define __TMPNAME __TMPNAME_2(__COUNTER__) + +#endif diff --git a/src/commonlib/bsd/include/commonlib/bsd/compression.h b/src/commonlib/bsd/include/commonlib/bsd/compression.h new file mode 100644 index 0000000000..873e7e4e15 --- /dev/null +++ b/src/commonlib/bsd/include/commonlib/bsd/compression.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +#ifndef _COMMONLIB_COMPRESSION_H_ +#define _COMMONLIB_COMPRESSION_H_ + +#include <stddef.h> + +/* Decompresses an LZ4F image (multiple LZ4 blocks with frame header) from src + * to dst, ensuring that it doesn't read more than srcn bytes and doesn't write + * more than dstn. Buffer sizes must stay below 2GB. Can decompress files loaded + * to the end of a buffer in-place, as long as buffer is larger than the final + * output size. (Usually just a few bytes, but may be up to (8 + dstn/255) in + * worst case. Will reliably return an error if buffer was too small.) + * Returns amount of decompressed bytes, or 0 on error. + */ +size_t ulz4fn(const void *src, size_t srcn, void *dst, size_t dstn); + +/* Same as ulz4fn() but does not perform any bounds checks. */ +size_t ulz4f(const void *src, void *dst); + +#endif /* _COMMONLIB_COMPRESSION_H_ */ diff --git a/src/commonlib/bsd/include/commonlib/bsd/fmap_serialized.h b/src/commonlib/bsd/include/commonlib/bsd/fmap_serialized.h new file mode 100644 index 0000000000..3d328c45b8 --- /dev/null +++ b/src/commonlib/bsd/include/commonlib/bsd/fmap_serialized.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +#ifndef FLASHMAP_SERIALIZED_H__ +#define FLASHMAP_SERIALIZED_H__ + +#include <stdint.h> + +#define FMAP_SIGNATURE "__FMAP__" +#define FMAP_VER_MAJOR 1 /* this header's FMAP minor version */ +#define FMAP_VER_MINOR 1 /* this header's FMAP minor version */ +#define FMAP_STRLEN 32 /* maximum length for strings, */ + /* including null-terminator */ + +enum fmap_flags { + FMAP_AREA_STATIC = 1 << 0, + FMAP_AREA_COMPRESSED = 1 << 1, + FMAP_AREA_RO = 1 << 2, + FMAP_AREA_PRESERVE = 1 << 3, +}; + +/* Mapping of volatile and static regions in firmware binary */ +struct fmap_area { + uint32_t offset; /* offset relative to base */ + uint32_t size; /* size in bytes */ + uint8_t name[FMAP_STRLEN]; /* descriptive name */ + uint16_t flags; /* flags for this area */ +} __packed; + +struct fmap { + uint8_t signature[8]; /* "__FMAP__" (0x5F5F464D41505F5F) */ + uint8_t ver_major; /* major version */ + uint8_t ver_minor; /* minor version */ + uint64_t base; /* address of the firmware binary */ + uint32_t size; /* size of firmware binary in bytes */ + uint8_t name[FMAP_STRLEN]; /* name of this firmware binary */ + uint16_t nareas; /* number of areas described by + fmap_areas[] below */ + struct fmap_area areas[]; +} __packed; + +#endif /* FLASHMAP_SERIALIZED_H__ */ diff --git a/src/commonlib/bsd/include/commonlib/bsd/helpers.h b/src/commonlib/bsd/include/commonlib/bsd/helpers.h new file mode 100644 index 0000000000..a305df0cd5 --- /dev/null +++ b/src/commonlib/bsd/include/commonlib/bsd/helpers.h @@ -0,0 +1,89 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +#ifndef COMMONLIB_BSD_HELPERS_H +#define COMMONLIB_BSD_HELPERS_H + +#ifndef __ASSEMBLER__ +#include <commonlib/bsd/compiler.h> +#include <stddef.h> +#endif + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +#endif + +#define ALIGN(x, a) __ALIGN_MASK(x, (__typeof__(x))(a)-1UL) +#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask)) +#define ALIGN_UP(x, a) ALIGN((x), (a)) +#define ALIGN_DOWN(x, a) ((x) & ~((__typeof__(x))(a)-1UL)) +#define IS_ALIGNED(x, a) (((x) & ((__typeof__(x))(a)-1UL)) == 0) + +/* Double-evaluation unsafe min/max, for bitfields and outside of functions */ +#define __CMP_UNSAFE(a, b, op) ((a) op (b) ? (a) : (b)) +#define MIN_UNSAFE(a, b) __CMP_UNSAFE(a, b, <) +#define MAX_UNSAFE(a, b) __CMP_UNSAFE(a, b, >) + +#define __CMP_SAFE(a, b, op, var_a, var_b) ({ \ + __TYPEOF_UNLESS_CONST(a, b) var_a = (a); \ + __TYPEOF_UNLESS_CONST(b, a) var_b = (b); \ + var_a op var_b ? var_a : var_b; \ +}) + +#define __CMP(a, b, op) __builtin_choose_expr( \ + __builtin_constant_p(a) && __builtin_constant_p(b), \ + __CMP_UNSAFE(a, b, op), __CMP_SAFE(a, b, op, __TMPNAME, __TMPNAME)) + +#ifndef MIN +#define MIN(a, b) __CMP(a, b, <) +#endif +#ifndef MAX +#define MAX(a, b) __CMP(a, b, >) +#endif + +#ifndef ABS +#define ABS(a) ({ \ + __typeof__(a) _abs_local_a = (a); \ + (_abs_local_a < 0) ? (-_abs_local_a) : _abs_local_a; \ +}) +#endif + +#define IS_POWER_OF_2(x) ({ \ + __typeof__(x) _power_local_x = (x); \ + (_power_local_x & (_power_local_x - 1)) == 0; \ +}) + +#define DIV_ROUND_UP(x, y) ({ \ + __typeof__(x) _div_local_x = (x); \ + __typeof__(y) _div_local_y = (y); \ + (_div_local_x + _div_local_y - 1) / _div_local_y; \ +}) + +#define SWAP(a, b) do { \ + __typeof__(&(a)) _swap_local_a = &(a); \ + __typeof__(&(b)) _swap_local_b = &(b); \ + __typeof__(a) _swap_local_tmp = *_swap_local_a; \ + *_swap_local_a = *_swap_local_b; \ + *_swap_local_b = _swap_local_tmp; \ +} while (0) + +/* Standard units. */ +#define KiB (1<<10) +#define MiB (1<<20) +#define GiB (1<<30) + +#define KHz (1000) +#define MHz (1000 * KHz) +#define GHz (1000 * MHz) + +#ifndef offsetof +#define offsetof(TYPE, MEMBER) __builtin_offsetof(TYPE, MEMBER) +#endif + +#define check_member(structure, member, offset) _Static_assert( \ + offsetof(struct structure, member) == offset, \ + "`struct " #structure "` offset for `" #member "` is not " #offset) + +/* Calculate size of structure member. */ +#define member_size(type, member) (sizeof(((type *)0)->member)) + +#endif /* COMMONLIB_BSD_HELPERS_H */ |