summaryrefslogtreecommitdiff
path: root/src/commonlib/bsd/include
diff options
context:
space:
mode:
authorJulius Werner <jwerner@chromium.org>2019-12-11 15:47:42 -0800
committerJulius Werner <jwerner@chromium.org>2020-01-28 06:36:13 +0000
commit98eeb961353d187a26085a07889bd0414cdaa910 (patch)
treeb97e2edbdb5033a93095044be96c809271bd0be8 /src/commonlib/bsd/include
parente4d6c033fe91cf777a95531669622f7829e6b44d (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')
-rw-r--r--src/commonlib/bsd/include/commonlib/bsd/cb_err.h42
-rw-r--r--src/commonlib/bsd/include/commonlib/bsd/cbfs_serialized.h190
-rw-r--r--src/commonlib/bsd/include/commonlib/bsd/compiler.h53
-rw-r--r--src/commonlib/bsd/include/commonlib/bsd/compression.h21
-rw-r--r--src/commonlib/bsd/include/commonlib/bsd/fmap_serialized.h41
-rw-r--r--src/commonlib/bsd/include/commonlib/bsd/helpers.h89
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 */