diff options
Diffstat (limited to 'lib')
101 files changed, 2901 insertions, 1619 deletions
diff --git a/lib/Kconfig b/lib/Kconfig index 189e6eb31aa..5f282ecb543 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -403,7 +403,7 @@ config TRACE_EARLY_CALL_DEPTH_LIMIT config TRACE_EARLY_ADDR hex "Address of early trace buffer in U-Boot" depends on TRACE_EARLY - default 0x00100000 + default 0x00200000 help Sets the address of the early trace buffer in U-Boot. This memory must be accessible before relocation. @@ -439,9 +439,6 @@ config TPM depends on DM imply DM_RNG select SHA1 - select SHA256 - select SHA384 - select SHA512 help This enables support for TPMs which can be used to provide security features for your board. The TPM can be connected via LPC or I2C @@ -449,6 +446,9 @@ config TPM command to interactive the TPM. Driver model support is provided for the low-level TPM interface, but only one TPM is supported at a time by the TPM library. + For size reasons only SHA1 is selected which is supported on TPM1.2. + If you want a fully functional TPM enable all hashing algorithms. + If you enabled measured boot all hashing algorithms are selected. config SPL_TPM bool "Trusted Platform Module (TPM) Support in SPL" @@ -1102,48 +1102,25 @@ config LMB bool "Enable the logical memory blocks library (lmb)" default y if ARC || ARM || M68K || MICROBLAZE || MIPS || \ NIOS2 || PPC || RISCV || SANDBOX || SH || X86 || XTENSA + select ARCH_MISC_INIT if PPC help - Support the library logical memory blocks. - -config LMB_USE_MAX_REGIONS - bool "Use a common number of memory and reserved regions in lmb lib" - default y - help - Define the number of supported memory regions in the library logical - memory blocks. - This feature allow to reduce the lmb library size by using compiler - optimization when LMB_MEMORY_REGIONS == LMB_RESERVED_REGIONS. - -config LMB_MAX_REGIONS - int "Number of memory and reserved regions in lmb lib" - depends on LMB_USE_MAX_REGIONS - default 16 - help - Define the number of supported regions, memory and reserved, in the - library logical memory blocks. - -config LMB_MEMORY_REGIONS - int "Number of memory regions in lmb lib" - depends on !LMB_USE_MAX_REGIONS - default 8 - help - Define the number of supported memory regions in the library logical - memory blocks. - The minimal value is CONFIG_NR_DRAM_BANKS. + Support the library logical memory blocks. This will require + a malloc() implementation for defining the data structures + needed for maintaining the LMB memory map. -config LMB_RESERVED_REGIONS - int "Number of reserved regions in lmb lib" - depends on !LMB_USE_MAX_REGIONS - default 8 +config SPL_LMB + bool "Enable LMB module for SPL" + depends on SPL && SPL_FRAMEWORK && SPL_SYS_MALLOC help - Define the number of supported reserved regions in the library logical - memory blocks. + Enable support for Logical Memory Block library routines in + SPL. This will require a malloc() implementation for defining + the data structures needed for maintaining the LMB memory map. config PHANDLE_CHECK_SEQ bool "Enable phandle check while getting sequence number" help When there are multiple device tree nodes with same name, - enable this config option to distinguish them using + enable this config option to distinguish them using phandles in fdtdec_get_alias_seq() function. endmenu diff --git a/lib/Makefile b/lib/Makefile index 2a76acf100d..d300249f57c 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -61,6 +61,8 @@ ifeq ($(CONFIG_$(SPL_TPL_)TPM),y) obj-$(CONFIG_TPM) += tpm_api.o obj-$(CONFIG_TPM_V1) += tpm-v1.o obj-$(CONFIG_TPM_V2) += tpm-v2.o +obj-$(CONFIG_EFI_TCG2_PROTOCOL) += tpm_tcg2.o +obj-$(CONFIG_MEASURED_BOOT) += tpm_tcg2.o endif obj-$(CONFIG_$(SPL_TPL_)CRC8) += crc8.o @@ -116,7 +118,7 @@ obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += fdtdec.o fdtdec_common.o obj-y += hang.o obj-y += linux_compat.o obj-y += linux_string.o -obj-$(CONFIG_LMB) += lmb.o +obj-$(CONFIG_$(SPL_TPL_)LMB) += lmb.o obj-y += membuff.o obj-$(CONFIG_REGEX) += slre.o obj-y += string.o @@ -145,6 +147,7 @@ endif obj-$(CONFIG_$(SPL_)OID_REGISTRY) += oid_registry.o obj-y += abuf.o +obj-y += alist.o obj-y += date.o obj-y += rtc-lib.o obj-$(CONFIG_LIB_ELF) += elf.o diff --git a/lib/acpi/acpi_table.c b/lib/acpi/acpi_table.c index c16ead6a6ec..6dbfdb22dec 100644 --- a/lib/acpi/acpi_table.c +++ b/lib/acpi/acpi_table.c @@ -117,6 +117,7 @@ void acpi_fill_header(struct acpi_table_header *header, char *signature) memcpy(header->oem_table_id, OEM_TABLE_ID, 8); header->oem_revision = OEM_REVISION; memcpy(header->creator_id, ASLC_ID, 4); + header->creator_revision = ASL_REVISION; } void acpi_align(struct acpi_ctx *ctx) @@ -219,7 +220,6 @@ void acpi_create_dbg2(struct acpi_dbg2_header *dbg2, header->revision = acpi_get_table_revision(ACPITAB_DBG2); acpi_fill_header(header, "DBG2"); - header->creator_revision = ASL_REVISION; /* One debug device defined */ dbg2->devices_offset = sizeof(struct acpi_dbg2_header); diff --git a/lib/acpi/ssdt.c b/lib/acpi/ssdt.c index e032e266b3c..df1d739d117 100644 --- a/lib/acpi/ssdt.c +++ b/lib/acpi/ssdt.c @@ -23,7 +23,6 @@ int acpi_write_ssdt(struct acpi_ctx *ctx, const struct acpi_writer *entry) acpi_fill_header(ssdt, "SSDT"); ssdt->revision = acpi_get_table_revision(ACPITAB_SSDT); - ssdt->creator_revision = 1; ssdt->length = sizeof(struct acpi_table_header); acpi_inc(ctx, sizeof(struct acpi_table_header)); diff --git a/lib/alist.c b/lib/alist.c new file mode 100644 index 00000000000..b7928cad520 --- /dev/null +++ b/lib/alist.c @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Handles a contiguous list of pointers which be allocated and freed + * + * Copyright 2023 Google LLC + * Written by Simon Glass <sjg@chromium.org> + */ + +#include <alist.h> +#include <display_options.h> +#include <malloc.h> +#include <stdio.h> +#include <string.h> + +enum { + ALIST_INITIAL_SIZE = 4, /* default size of unsized list */ +}; + +bool alist_init(struct alist *lst, uint obj_size, uint start_size) +{ + /* Avoid realloc for the initial size to help malloc_simple */ + memset(lst, '\0', sizeof(struct alist)); + if (start_size) { + lst->data = calloc(obj_size, start_size); + if (!lst->data) { + lst->flags = ALISTF_FAIL; + return false; + } + lst->alloc = start_size; + } + lst->obj_size = obj_size; + + return true; +} + +void alist_uninit(struct alist *lst) +{ + free(lst->data); + + /* Clear fields to avoid any confusion */ + memset(lst, '\0', sizeof(struct alist)); +} + +/** + * alist_expand_to() - Expand a list to the given size + * + * @lst: List to modify + * @inc_by: Amount to expand to + * Return: true if OK, false if out of memory + */ +static bool alist_expand_to(struct alist *lst, uint new_alloc) +{ + void *new_data; + + if (lst->flags & ALISTF_FAIL) + return false; + + /* avoid using realloc() since it increases code size */ + new_data = malloc(lst->obj_size * new_alloc); + if (!new_data) { + lst->flags |= ALISTF_FAIL; + return false; + } + + memcpy(new_data, lst->data, lst->obj_size * lst->alloc); + free(lst->data); + + memset(new_data + lst->obj_size * lst->alloc, '\0', + lst->obj_size * (new_alloc - lst->alloc)); + lst->alloc = new_alloc; + lst->data = new_data; + + return true; +} + +bool alist_expand_by(struct alist *lst, uint inc_by) +{ + return alist_expand_to(lst, lst->alloc + inc_by); +} + +/** + * alist_expand_min() - Expand to at least the provided size + * + * Expands to the lowest power of two which can incorporate the new size + * + * @lst: alist to expand + * @min_alloc: Minimum new allocated size; if 0 then ALIST_INITIAL_SIZE is used + * Return: true if OK, false if out of memory + */ +static bool alist_expand_min(struct alist *lst, uint min_alloc) +{ + uint new_alloc; + + for (new_alloc = lst->alloc ?: ALIST_INITIAL_SIZE; + new_alloc < min_alloc;) + new_alloc *= 2; + + return alist_expand_to(lst, new_alloc); +} + +const void *alist_get_ptr(const struct alist *lst, uint index) +{ + if (index >= lst->count) + return NULL; + + return lst->data + index * lst->obj_size; +} + +void *alist_ensure_ptr(struct alist *lst, uint index) +{ + uint minsize = index + 1; + void *ptr; + + if (index >= lst->alloc && !alist_expand_min(lst, minsize)) + return NULL; + + ptr = lst->data + index * lst->obj_size; + if (minsize >= lst->count) + lst->count = minsize; + + return ptr; +} + +void *alist_add_placeholder(struct alist *lst) +{ + return alist_ensure_ptr(lst, lst->count); +} + +void *alist_add_ptr(struct alist *lst, void *obj) +{ + void *ptr; + + ptr = alist_add_placeholder(lst); + if (!ptr) + return NULL; + memcpy(ptr, obj, lst->obj_size); + + return ptr; +} + +void *alist_uninit_move_ptr(struct alist *alist, size_t *countp) +{ + void *ptr; + + if (countp) + *countp = alist->count; + if (!alist->count) { + alist_uninit(alist); + return NULL; + } + + ptr = alist->data; + + /* Clear everything out so there is no record of the data */ + alist_init(alist, alist->obj_size, 0); + + return ptr; +} diff --git a/lib/asm-offsets.c b/lib/asm-offsets.c index 4e2dbda9a71..b6bbcbf76ca 100644 --- a/lib/asm-offsets.c +++ b/lib/asm-offsets.c @@ -44,7 +44,9 @@ int main(void) DEFINE(GD_NEW_GD, offsetof(struct global_data, new_gd)); +#if CONFIG_IS_ENABLED(ENV_SUPPORT) DEFINE(GD_ENV_ADDR, offsetof(struct global_data, env_addr)); +#endif return 0; } diff --git a/lib/blake2/blake2b.c b/lib/blake2/blake2b.c index 686138ef24b..9cd6232aa54 100644 --- a/lib/blake2/blake2b.c +++ b/lib/blake2/blake2b.c @@ -51,7 +51,6 @@ static const uint8_t blake2b_sigma[12][16] = { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } }; - static void blake2b_set_lastnode( blake2b_state *S ) { S->f[1] = (uint64_t)-1; @@ -100,8 +99,6 @@ int blake2b_init_param( blake2b_state *S, const blake2b_param *P ) return 0; } - - int blake2b_init( blake2b_state *S, size_t outlen ) { blake2b_param P[1]; @@ -123,7 +120,6 @@ int blake2b_init( blake2b_state *S, size_t outlen ) return blake2b_init_param( S, P ); } - int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen ) { blake2b_param P[1]; diff --git a/lib/bzip2/bzlib.c b/lib/bzip2/bzlib.c index f7318b7886e..39a480e25f9 100644 --- a/lib/bzip2/bzlib.c +++ b/lib/bzip2/bzlib.c @@ -87,7 +87,6 @@ /*--- Compression stuff ---*/ /*---------------------------------------------------*/ - /*---------------------------------------------------*/ #ifndef BZ_NO_STDIO void BZ2_bz__AssertH__fail ( int errcode ) @@ -137,7 +136,6 @@ void BZ2_bz__AssertH__fail ( int errcode ) } #endif - /*---------------------------------------------------*/ static int bz_config_ok ( void ) @@ -148,7 +146,6 @@ int bz_config_ok ( void ) return 1; } - /*---------------------------------------------------*/ static void* default_bzalloc ( void* opaque, Int32 items, Int32 size ) @@ -177,7 +174,6 @@ void prepare_new_block ( EState* s ) s->blockNo++; } - /*---------------------------------------------------*/ static void init_RL ( EState* s ) @@ -186,7 +182,6 @@ void init_RL ( EState* s ) s->state_in_len = 0; } - static Bool isempty_RL ( EState* s ) { @@ -261,7 +256,6 @@ int BZ_API(BZ2_bzCompressInit) return BZ_OK; } - /*---------------------------------------------------*/ static void add_pair_to_block ( EState* s ) @@ -297,7 +291,6 @@ void add_pair_to_block ( EState* s ) } } - /*---------------------------------------------------*/ static void flush_RL ( EState* s ) @@ -306,7 +299,6 @@ void flush_RL ( EState* s ) init_RL ( s ); } - /*---------------------------------------------------*/ #define ADD_CHAR_TO_BLOCK(zs,zchh0) \ { \ @@ -334,7 +326,6 @@ void flush_RL ( EState* s ) } \ } - /*---------------------------------------------------*/ static Bool copy_input_until_stop ( EState* s ) @@ -379,7 +370,6 @@ Bool copy_input_until_stop ( EState* s ) return progress_in; } - /*---------------------------------------------------*/ static Bool copy_output_until_stop ( EState* s ) @@ -406,7 +396,6 @@ Bool copy_output_until_stop ( EState* s ) return progress_out; } - /*---------------------------------------------------*/ static Bool handle_compress ( bz_stream* strm ) @@ -453,7 +442,6 @@ Bool handle_compress ( bz_stream* strm ) return progress_in || progress_out; } - /*---------------------------------------------------*/ int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action ) { @@ -514,7 +502,6 @@ int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action ) return BZ_OK; /*--not reached--*/ } - /*---------------------------------------------------*/ int BZ_API(BZ2_bzCompressEnd) ( bz_stream *strm ) { @@ -578,7 +565,6 @@ int BZ_API(BZ2_bzDecompressInit) return BZ_OK; } - /*---------------------------------------------------*/ static void unRLE_obuf_to_output_FAST ( DState* s ) @@ -604,7 +590,6 @@ void unRLE_obuf_to_output_FAST ( DState* s ) /* can a new run be started? */ if (s->nblock_used == s->save_nblock+1) return; - s->state_out_len = 1; s->state_out_ch = s->k0; BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; @@ -720,7 +705,6 @@ void unRLE_obuf_to_output_FAST ( DState* s ) } } - /*---------------------------------------------------*/ __inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab ) { @@ -735,7 +719,6 @@ __inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab ) return nb; } - /*---------------------------------------------------*/ static void unRLE_obuf_to_output_SMALL ( DState* s ) @@ -761,7 +744,6 @@ void unRLE_obuf_to_output_SMALL ( DState* s ) /* can a new run be started? */ if (s->nblock_used == s->save_nblock+1) return; - s->state_out_len = 1; s->state_out_ch = s->k0; BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; @@ -831,7 +813,6 @@ void unRLE_obuf_to_output_SMALL ( DState* s ) } } - /*---------------------------------------------------*/ int BZ_API(BZ2_bzDecompress) ( bz_stream *strm ) { @@ -886,7 +867,6 @@ int BZ_API(BZ2_bzDecompress) ( bz_stream *strm ) return 0; /*NOTREACHED*/ } - /*---------------------------------------------------*/ int BZ_API(BZ2_bzDecompressEnd) ( bz_stream *strm ) { @@ -906,7 +886,6 @@ int BZ_API(BZ2_bzDecompressEnd) ( bz_stream *strm ) return BZ_OK; } - #ifndef BZ_NO_STDIO /*---------------------------------------------------*/ /*--- File I/O stuff ---*/ @@ -930,7 +909,6 @@ typedef } bzFile; - /*---------------------------------------------*/ static Bool myfeof ( FILE* f ) { @@ -940,7 +918,6 @@ static Bool myfeof ( FILE* f ) return False; } - /*---------------------------------------------------*/ BZFILE* BZ_API(BZ2_bzWriteOpen) ( int* bzerror, @@ -987,7 +964,6 @@ BZFILE* BZ_API(BZ2_bzWriteOpen) return bzf; } - /*---------------------------------------------------*/ void BZ_API(BZ2_bzWrite) ( int* bzerror, @@ -1032,7 +1008,6 @@ void BZ_API(BZ2_bzWrite) } } - /*---------------------------------------------------*/ void BZ_API(BZ2_bzWriteClose) ( int* bzerror, @@ -1045,7 +1020,6 @@ void BZ_API(BZ2_bzWriteClose) nbytes_in, NULL, nbytes_out, NULL ); } - void BZ_API(BZ2_bzWriteClose64) ( int* bzerror, BZFILE* b, @@ -1110,7 +1084,6 @@ void BZ_API(BZ2_bzWriteClose64) free ( bzf ); } - /*---------------------------------------------------*/ BZFILE* BZ_API(BZ2_bzReadOpen) ( int* bzerror, @@ -1166,7 +1139,6 @@ BZFILE* BZ_API(BZ2_bzReadOpen) return bzf; } - /*---------------------------------------------------*/ void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b ) { @@ -1184,7 +1156,6 @@ void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b ) free ( bzf ); } - /*---------------------------------------------------*/ int BZ_API(BZ2_bzRead) ( int* bzerror, @@ -1244,7 +1215,6 @@ int BZ_API(BZ2_bzRead) return 0; /*not reached*/ } - /*---------------------------------------------------*/ void BZ_API(BZ2_bzReadGetUnused) ( int* bzerror, @@ -1266,7 +1236,6 @@ void BZ_API(BZ2_bzReadGetUnused) } #endif - /*---------------------------------------------------*/ /*--- Misc convenience stuff ---*/ /*---------------------------------------------------*/ @@ -1372,7 +1341,6 @@ int BZ_API(BZ2_bzBuffToBuffDecompress) return ret; } - /*---------------------------------------------------*/ /*-- Code contributed by Yoshioka Tsuneo @@ -1394,7 +1362,6 @@ const char * BZ_API(BZ2_bzlibVersion)(void) return BZ_VERSION; } - #ifndef BZ_NO_STDIO /*---------------------------------------------------*/ @@ -1476,7 +1443,6 @@ BZFILE * bzopen_or_bzdopen return bzfp; } - /*---------------------------------------------------*/ /*-- open file for read or write. @@ -1490,7 +1456,6 @@ BZFILE * BZ_API(BZ2_bzopen) return bzopen_or_bzdopen(path,-1,mode,/*bzopen*/0); } - /*---------------------------------------------------*/ BZFILE * BZ_API(BZ2_bzdopen) ( int fd, @@ -1499,7 +1464,6 @@ BZFILE * BZ_API(BZ2_bzdopen) return bzopen_or_bzdopen(NULL,fd,mode,/*bzdopen*/1); } - /*---------------------------------------------------*/ int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len ) { @@ -1513,7 +1477,6 @@ int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len ) } } - /*---------------------------------------------------*/ int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len ) { @@ -1527,7 +1490,6 @@ int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len ) } } - /*---------------------------------------------------*/ int BZ_API(BZ2_bzflush) (BZFILE *b) { @@ -1535,7 +1497,6 @@ int BZ_API(BZ2_bzflush) (BZFILE *b) return 0; } - /*---------------------------------------------------*/ void BZ_API(BZ2_bzclose) (BZFILE* b) { @@ -1556,7 +1517,6 @@ void BZ_API(BZ2_bzclose) (BZFILE* b) } } - /*---------------------------------------------------*/ /*-- return last error code @@ -1580,7 +1540,6 @@ static char *bzerrorstrings[] = { ,"???" /* for future */ }; - const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum) { int err = ((bzFile *)b)->lastErr; diff --git a/lib/bzip2/bzlib_blocksort.c b/lib/bzip2/bzlib_blocksort.c index 36cf8436592..2408ee90c18 100644 --- a/lib/bzip2/bzlib_blocksort.c +++ b/lib/bzip2/bzlib_blocksort.c @@ -99,7 +99,6 @@ void fallbackSimpleSort ( UInt32* fmap, } } - /*---------------------------------------------*/ #define fswap(zz1, zz2) \ { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; } @@ -115,7 +114,6 @@ void fallbackSimpleSort ( UInt32* fmap, } \ } - #define fmin(a,b) ((a) < (b)) ? (a) : (b) #define fpush(lz,hz) { stackLo[sp] = lz; \ @@ -129,7 +127,6 @@ void fallbackSimpleSort ( UInt32* fmap, #define FALLBACK_QSORT_SMALL_THRESH 10 #define FALLBACK_QSORT_STACK_SIZE 100 - static void fallbackQSort3 ( UInt32* fmap, UInt32* eclass, @@ -228,7 +225,6 @@ void fallbackQSort3 ( UInt32* fmap, #undef FALLBACK_QSORT_SMALL_THRESH #undef FALLBACK_QSORT_STACK_SIZE - /*---------------------------------------------*/ /* Pre: nblock > 0 @@ -375,7 +371,6 @@ void fallbackSort ( UInt32* fmap, #undef WORD_BH #undef UNALIGNED_BH - /*---------------------------------------------*/ /*--- The main, O(N^2 log(N)) sorting ---*/ /*--- algorithm. Faster for "normal" ---*/ @@ -509,7 +504,6 @@ Bool mainGtU ( UInt32 i1, return False; } - /*---------------------------------------------*/ /*-- Knuth's increments seem to work better @@ -595,7 +589,6 @@ void mainSimpleSort ( UInt32* ptr, } } - /*---------------------------------------------*/ /*-- The following is an implementation of @@ -644,7 +637,6 @@ UChar mmed3 ( UChar a, UChar b, UChar c ) hz = stackHi[sp]; \ dz = stackD [sp]; } - #define mnextsize(az) (nextHi[az]-nextLo[az]) #define mnextswap(az,bz) \ @@ -653,7 +645,6 @@ UChar mmed3 ( UChar a, UChar b, UChar c ) tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \ tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; } - #define MAIN_QSORT_SMALL_THRESH 20 #define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT) #define MAIN_QSORT_STACK_SIZE 100 @@ -768,7 +759,6 @@ void mainQSort3 ( UInt32* ptr, #undef MAIN_QSORT_DEPTH_THRESH #undef MAIN_QSORT_STACK_SIZE - /*---------------------------------------------*/ /* Pre: nblock > N_OVERSHOOT @@ -1055,7 +1045,6 @@ void mainSort ( UInt32* ptr, #undef SETMASK #undef CLEARMASK - /*---------------------------------------------*/ /* Pre: nblock > 0 @@ -1129,7 +1118,6 @@ void BZ2_blockSort ( EState* s ) AssertH( s->origPtr != -1, 1003 ); } - /*-------------------------------------------------------------*/ /*--- end blocksort.c ---*/ /*-------------------------------------------------------------*/ diff --git a/lib/bzip2/bzlib_compress.c b/lib/bzip2/bzlib_compress.c index 68d948b427a..d9400ca758c 100644 --- a/lib/bzip2/bzlib_compress.c +++ b/lib/bzip2/bzlib_compress.c @@ -80,7 +80,6 @@ void BZ2_bsInitWrite ( EState* s ) s->bsBuff = 0; } - /*---------------------------------------------------*/ static void bsFinishWrite ( EState* s ) @@ -93,7 +92,6 @@ void bsFinishWrite ( EState* s ) } } - /*---------------------------------------------------*/ #define bsNEEDW(nz) \ { \ @@ -106,7 +104,6 @@ void bsFinishWrite ( EState* s ) } \ } - /*---------------------------------------------------*/ static __inline__ @@ -117,7 +114,6 @@ void bsW ( EState* s, Int32 n, UInt32 v ) s->bsLive += n; } - /*---------------------------------------------------*/ static void bsPutUInt32 ( EState* s, UInt32 u ) @@ -128,7 +124,6 @@ void bsPutUInt32 ( EState* s, UInt32 u ) bsW ( s, 8, u & 0xffL ); } - /*---------------------------------------------------*/ static void bsPutUChar ( EState* s, UChar c ) @@ -136,7 +131,6 @@ void bsPutUChar ( EState* s, UChar c ) bsW( s, 8, (UInt32)c ); } - /*---------------------------------------------------*/ /*--- The back end proper ---*/ /*---------------------------------------------------*/ @@ -154,7 +148,6 @@ void makeMaps_e ( EState* s ) } } - /*---------------------------------------------------*/ static void generateMTFValues ( EState* s ) @@ -270,7 +263,6 @@ void generateMTFValues ( EState* s ) s->nMTF = wr; } - /*---------------------------------------------------*/ #define BZ_LESSER_ICOST 0 #define BZ_GREATER_ICOST 15 @@ -293,7 +285,6 @@ void sendMTFValues ( EState* s ) Made global to keep stack frame size small. --*/ - UInt16 cost[BZ_N_GROUPS]; Int32 fave[BZ_N_GROUPS]; @@ -492,13 +483,11 @@ void sendMTFValues ( EState* s ) alphaSize, 17 /*20*/ ); } - AssertH( nGroups < 8, 3002 ); AssertH( nSelectors < 32768 && nSelectors <= (2 + (900000 / BZ_G_SIZE)), 3003 ); - /*--- Compute MTF values for the selectors. ---*/ { UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp; @@ -628,7 +617,6 @@ void sendMTFValues ( EState* s ) } } - gs = ge+1; selCtr++; } @@ -638,7 +626,6 @@ void sendMTFValues ( EState* s ) VPrintf1( "codes %d\n", s->numZ-nBytes ); } - /*---------------------------------------------------*/ void BZ2_compressBlock ( EState* s, Bool is_last_block ) { @@ -693,7 +680,6 @@ void BZ2_compressBlock ( EState* s, Bool is_last_block ) sendMTFValues ( s ); } - /*-- If this is the last block, add the stream trailer. --*/ if (is_last_block) { @@ -707,7 +693,6 @@ void BZ2_compressBlock ( EState* s, Bool is_last_block ) } } - /*-------------------------------------------------------------*/ /*--- end compress.c ---*/ /*-------------------------------------------------------------*/ diff --git a/lib/bzip2/bzlib_crctable.c b/lib/bzip2/bzlib_crctable.c index 325b96643ef..2da2d655007 100644 --- a/lib/bzip2/bzlib_crctable.c +++ b/lib/bzip2/bzlib_crctable.c @@ -59,7 +59,6 @@ For more information on these sources, see the manual. --*/ - #include "bzlib_private.h" /*-- @@ -139,7 +138,6 @@ UInt32 BZ2_crc32Table[256] = { 0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L }; - /*-------------------------------------------------------------*/ /*--- end crctable.c ---*/ /*-------------------------------------------------------------*/ diff --git a/lib/bzip2/bzlib_decompress.c b/lib/bzip2/bzlib_decompress.c index e56ab6674b0..53695c13bfc 100644 --- a/lib/bzip2/bzlib_decompress.c +++ b/lib/bzip2/bzlib_decompress.c @@ -60,10 +60,8 @@ For more information on these sources, see the manual. --*/ - #include "bzlib_private.h" - /*---------------------------------------------------*/ static void makeMaps_d ( DState* s ) @@ -77,7 +75,6 @@ void makeMaps_d ( DState* s ) } } - /*---------------------------------------------------*/ #define RETURN(rrr) \ { retVal = rrr; goto save_state_and_return; }; @@ -143,7 +140,6 @@ void makeMaps_d ( DState* s ) lval = gPerm[zvec - gBase[zn]]; \ } - /*---------------------------------------------------*/ Int32 BZ2_decompress ( DState* s ) { @@ -605,7 +601,6 @@ Int32 BZ2_decompress ( DState* s ) RETURN(BZ_OK); - endhdr_2: GET_UCHAR(BZ_X_ENDHDR_2, uc); @@ -667,7 +662,6 @@ Int32 BZ2_decompress ( DState* s ) return retVal; } - /*-------------------------------------------------------------*/ /*--- end decompress.c ---*/ /*-------------------------------------------------------------*/ diff --git a/lib/bzip2/bzlib_huffman.c b/lib/bzip2/bzlib_huffman.c index 801b8ec39a0..904783d7cb1 100644 --- a/lib/bzip2/bzlib_huffman.c +++ b/lib/bzip2/bzlib_huffman.c @@ -59,7 +59,6 @@ For more information on these sources, see the manual. --*/ - #include "bzlib_private.h" /*---------------------------------------------------*/ @@ -99,7 +98,6 @@ heap[zz] = tmp; \ } - /*---------------------------------------------------*/ void BZ2_hbMakeCodeLengths ( UChar *len, Int32 *freq, @@ -171,7 +169,6 @@ void BZ2_hbMakeCodeLengths ( UChar *len, } } - /*---------------------------------------------------*/ void BZ2_hbAssignCodes ( Int32 *code, UChar *length, @@ -189,7 +186,6 @@ void BZ2_hbAssignCodes ( Int32 *code, } } - /*---------------------------------------------------*/ void BZ2_hbCreateDecodeTables ( Int32 *limit, Int32 *base, @@ -223,7 +219,6 @@ void BZ2_hbCreateDecodeTables ( Int32 *limit, base[i] = ((limit[i-1] + 1) << 1) - base[i]; } - /*-------------------------------------------------------------*/ /*--- end huffman.c ---*/ /*-------------------------------------------------------------*/ diff --git a/lib/bzip2/bzlib_private.h b/lib/bzip2/bzlib_private.h index 87d8f945258..b69eadc96a1 100644 --- a/lib/bzip2/bzlib_private.h +++ b/lib/bzip2/bzlib_private.h @@ -62,7 +62,6 @@ For more information on these sources, see the manual. --*/ - #ifndef _BZLIB_PRIVATE_H #define _BZLIB_PRIVATE_H @@ -76,7 +75,6 @@ #include <string.h> #endif - /*-- General stuff. --*/ #define BZ_VERSION "1.0.2, 30-Dec-2001" @@ -135,11 +133,9 @@ extern void bz_internal_error ( int errcode ); #define VPrintf5(zf,za1,za2,za3,za4,za5) /* */ #endif - #define BZALLOC(nnn) (strm->bzalloc)(strm->opaque,(nnn),1) #define BZFREE(ppp) (strm->bzfree)(strm->opaque,(ppp)) - /*-- Header bytes. --*/ #define BZ_HDR_B 0x42 /* 'B' */ @@ -161,7 +157,6 @@ extern void bz_internal_error ( int errcode ); #define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE)) - /*-- Stuff for randomising repetitive blocks. --*/ extern Int32 BZ2_rNums[512]; @@ -184,7 +179,6 @@ extern Int32 BZ2_rNums[512]; } \ s->rNToGo--; - /*-- Stuff for doing CRCs. --*/ extern UInt32 BZ2_crc32Table[256]; @@ -206,7 +200,6 @@ extern UInt32 BZ2_crc32Table[256]; ((UChar)cha)]; \ } - /*-- States and modes for compression. --*/ #define BZ_M_IDLE 1 @@ -222,7 +215,6 @@ extern UInt32 BZ2_crc32Table[256]; #define BZ_N_SHELL 18 #define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2) - /*-- Structure holding all the compression-side stuff. --*/ typedef @@ -297,7 +289,6 @@ typedef } EState; - /*-- externs for compression. --*/ extern void @@ -315,7 +306,6 @@ BZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 ); extern void BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 ); - /*-- states for decompression. --*/ #define BZ_X_IDLE 1 @@ -363,13 +353,11 @@ BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 ); #define BZ_X_CCRC_3 49 #define BZ_X_CCRC_4 50 - /*-- Constants for the fast MTF decoder. --*/ #define MTFA_SIZE 4096 #define MTFL_SIZE 16 - /*-- Structure holding all the decompression-side stuff. --*/ typedef @@ -465,7 +453,6 @@ typedef } DState; - /*-- Macros for decompression. --*/ #define BZ_GET_FAST(cccc) \ @@ -499,7 +486,6 @@ typedef cccc = BZ2_indexIntoF ( s->tPos, s->cftab ); \ s->tPos = GET_LL(s->tPos); - /*-- externs for decompression. --*/ extern Int32 @@ -512,10 +498,8 @@ extern void BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*, Int32, Int32, Int32 ); - #endif - /*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/ #ifdef BZ_NO_STDIO @@ -524,7 +508,6 @@ BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*, #endif #endif - /*-------------------------------------------------------------*/ /*--- end bzlib_private.h ---*/ /*-------------------------------------------------------------*/ diff --git a/lib/bzip2/bzlib_randtable.c b/lib/bzip2/bzlib_randtable.c index c3dc7e41817..b2969266fc2 100644 --- a/lib/bzip2/bzlib_randtable.c +++ b/lib/bzip2/bzlib_randtable.c @@ -59,10 +59,8 @@ For more information on these sources, see the manual. --*/ - #include "bzlib_private.h" - /*---------------------------------------------*/ Int32 BZ2_rNums[512] = { 619, 720, 127, 481, 931, 816, 813, 233, 566, 247, @@ -119,7 +117,6 @@ Int32 BZ2_rNums[512] = { 936, 638 }; - /*-------------------------------------------------------------*/ /*--- end randtable.c ---*/ /*-------------------------------------------------------------*/ diff --git a/lib/circbuf.c b/lib/circbuf.c index 2e161ae8d8b..461c240f788 100644 --- a/lib/circbuf.c +++ b/lib/circbuf.c @@ -9,7 +9,6 @@ #include <circbuf.h> - int buf_init (circbuf_t * buf, unsigned int size) { assert (buf != NULL); diff --git a/lib/crc7.c b/lib/crc7.c index e635c9c2d67..938e258febe 100644 --- a/lib/crc7.c +++ b/lib/crc7.c @@ -8,7 +8,6 @@ #include <linux/types.h> #include <linux/crc7.h> - /* Table for CRC-7 (polynomial x^7 + x^3 + 1) */ const u8 crc7_syndrome_table[256] = { 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, diff --git a/lib/crypt/crypt-sha256.c b/lib/crypt/crypt-sha256.c index 335c8880d81..824e24e190b 100644 --- a/lib/crypt/crypt-sha256.c +++ b/lib/crypt/crypt-sha256.c @@ -72,7 +72,6 @@ struct sha256_buffer static_assert (sizeof (struct sha256_buffer) <= ALG_SPECIFIC_SIZE, "ALG_SPECIFIC_SIZE is too small for SHA256"); - /* Use this instead of including errno.h */ static int errno; diff --git a/lib/crypt/crypt-sha512.c b/lib/crypt/crypt-sha512.c index 8c8e6dd3dea..24d1345a223 100644 --- a/lib/crypt/crypt-sha512.c +++ b/lib/crypt/crypt-sha512.c @@ -72,7 +72,6 @@ struct sha512_buffer static_assert (sizeof (struct sha512_buffer) <= ALG_SPECIFIC_SIZE, "ALG_SPECIFIC_SIZE is too small for SHA512"); - /* Use this instead of including errno.h */ static int errno; diff --git a/lib/crypto/Kconfig b/lib/crypto/Kconfig index 6e0656ad1c5..742f6d9d4ed 100644 --- a/lib/crypto/Kconfig +++ b/lib/crypto/Kconfig @@ -1,6 +1,6 @@ menuconfig ASYMMETRIC_KEY_TYPE bool "Asymmetric (public-key cryptographic) key Support" - depends on FIT_SIGNATURE + depends on FIT_SIGNATURE || RSA_VERIFY_WITH_PKEY help This option provides support for a key type that holds the data for the asymmetric keys used for public key cryptographic operations such diff --git a/lib/dhry/dhry.h b/lib/dhry/dhry.h index 892c9ed73b8..bd95540eeb2 100644 --- a/lib/dhry/dhry.h +++ b/lib/dhry/dhry.h @@ -365,7 +365,6 @@ *************************************************************************** */ - /* Compiler and system dependent definitions: */ #ifndef TIME @@ -432,7 +431,6 @@ typedef struct record } variant; } Rec_Type, *Rec_Pointer; - /* * dhry() - run dhrystone for a given number of iterations * diff --git a/lib/dhry/dhry_1.c b/lib/dhry/dhry_1.c index 252cd14a656..275a89942ea 100644 --- a/lib/dhry/dhry_1.c +++ b/lib/dhry/dhry_1.c @@ -102,7 +102,6 @@ void Proc_3 (Rec_Pointer *Ptr_Ref_Par); void Proc_4 (void); void Proc_5 (void); - extern Boolean Func_2(Str_30, Str_30); extern void Proc_6(Enumeration, Enumeration *); extern void Proc_7(One_Fifty, One_Fifty, One_Fifty *); @@ -323,7 +322,6 @@ void dhry(int Number_Of_Runs) #endif /* SELF_TIMED */ } - void Proc_1 (REG Rec_Pointer Ptr_Val_Par) /* executed once */ { @@ -354,7 +352,6 @@ void Proc_1 (REG Rec_Pointer Ptr_Val_Par) structassign (*Ptr_Val_Par, *Ptr_Val_Par->Ptr_Comp); } /* Proc_1 */ - void Proc_2 (One_Fifty *Int_Par_Ref) /* executed once */ /* *Int_Par_Ref == 1, becomes 4 */ @@ -376,7 +373,6 @@ void Proc_2 (One_Fifty *Int_Par_Ref) while (Enum_Loc != Ident_1); /* true */ } /* Proc_2 */ - void Proc_3 (Rec_Pointer *Ptr_Ref_Par) /* executed once */ /* Ptr_Ref_Par becomes Ptr_Glob */ @@ -387,7 +383,6 @@ void Proc_3 (Rec_Pointer *Ptr_Ref_Par) Proc_7 (10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp); } /* Proc_3 */ - void Proc_4 (void) /* without parameters */ /* executed once */ { @@ -406,7 +401,6 @@ void Proc_5 (void) /* without parameters */ Bool_Glob = false; } /* Proc_5 */ - /* Procedure for the assignment of structures, */ /* if the C compiler doesn't support this feature */ #ifdef NOSTRUCTASSIGN diff --git a/lib/dhry/dhry_2.c b/lib/dhry/dhry_2.c index a74197d884d..8f18f4ed423 100644 --- a/lib/dhry/dhry_2.c +++ b/lib/dhry/dhry_2.c @@ -106,7 +106,6 @@ One_Fifty *Int_Par_Ref; *Int_Par_Ref = Int_2_Par_Val + Int_Loc; } /* Proc_7 */ - void Proc_8 (Arr_1_Par_Ref, Arr_2_Par_Ref, Int_1_Par_Val, Int_2_Par_Val) /*********************************************************************/ /* executed once */ @@ -131,7 +130,6 @@ int Int_2_Par_Val; Int_Glob = 5; } /* Proc_8 */ - Enumeration Func_1 (Capital_Letter Ch_1_Par_Val, Capital_Letter Ch_2_Par_Val) /*************************************************/ /* executed three times */ @@ -154,8 +152,6 @@ Enumeration Func_1 (Capital_Letter Ch_1_Par_Val, Capital_Letter Ch_2_Par_Val) } } /* Func_1 */ - - Boolean Func_2 (Str_1_Par_Ref, Str_2_Par_Ref) /*************************************************/ /* executed once */ @@ -198,7 +194,6 @@ Str_30 Str_2_Par_Ref; } /* if Ch_Loc */ } /* Func_2 */ - Boolean Func_3 (Enum_Par_Val) /***************************/ /* executed once */ diff --git a/lib/display_options.c b/lib/display_options.c index d6b93553dcb..d5df53ab15f 100644 --- a/lib/display_options.c +++ b/lib/display_options.c @@ -12,6 +12,7 @@ #include <linux/ctype.h> #include <linux/kernel.h> #include <asm/io.h> +#include <stdio.h> #include <vsprintf.h> char *display_options_get_banner_priv(bool newlines, const char *build_tag, diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 430bb7f0f7d..6ffefa9103f 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -10,9 +10,9 @@ config EFI_LOADER depends on !EFI_STUB || !X86_64 || EFI_STUB_64BIT # We need EFI_STUB_32BIT to be set on x86_32 with EFI_STUB depends on !EFI_STUB || !X86 || X86_64 || EFI_STUB_32BIT - depends on BLK depends on !EFI_APP default y if !ARM || SYS_CPU = armv7 || SYS_CPU = armv8 + select BLK select CHARSET # We need to send DM events, dynamically, in the EFI block driver select DM_EVENT @@ -67,7 +67,7 @@ config EFI_RT_VOLATILE_STORE depends on EFI_VARIABLE_FILE_STORE help When EFI variables are stored on file we don't allow SetVariableRT, - since the OS doesn't know how to write that file. At he same time + since the OS doesn't know how to write that file. At the same time we copy runtime variables in DRAM and support GetVariableRT Enable this option to allow SetVariableRT on the RAM backend of @@ -220,6 +220,7 @@ config EFI_CAPSULE_ON_DISK config EFI_IGNORE_OSINDICATIONS bool "Ignore OsIndications for CapsuleUpdate on-disk" depends on EFI_CAPSULE_ON_DISK + default y if !EFI_RT_VOLATILE_STORE help There are boards where U-Boot does not support SetVariable at runtime. Select this option if you want to use the capsule-on-disk feature @@ -298,13 +299,15 @@ config EFI_CAPSULE_MAX Select the max capsule index value used for capsule report variables. This value is used to create CapsuleMax variable. -config EFI_CAPSULE_ESL_FILE - string "Path to the EFI Signature List File" +config EFI_CAPSULE_CRT_FILE + string "Path to the EFI capsule public key certificate" depends on EFI_CAPSULE_AUTHENTICATE help - Provides the path to the EFI Signature List file which will - be embedded in the platform's device tree and used for - capsule authentication at the time of capsule update. + Provides the path to the EFI capsule public key certificate that + corresponds to the capsule signing key. This certificate will be used + to generate the EFI capsule ESL (signature list file) that gets + embedded in the platform's device tree and used for capsule + authentication at the time of capsule update. config EFI_DEVICE_PATH_TO_TEXT bool "Device path to text protocol" @@ -361,7 +364,6 @@ endif config EFI_LOADER_BOUNCE_BUFFER bool "EFI Applications use bounce buffers for DMA operations" - depends on ARM64 help Some hardware does not support DMA to full 64bit addresses. For this hardware we can create a bounce buffer so that payloads don't have to @@ -484,6 +486,7 @@ config EFI_ECPT config EFI_EBBR_2_1_CONFORMANCE bool "Add the EBBRv2.1 conformance entry to the ECPT table" + depends on BOOTMETH_EFI_BOOTMGR depends on EFI_ECPT depends on EFI_LOADER_HII depends on EFI_RISCV_BOOT_PROTOCOL || !RISCV diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index 034e366967f..2af6f2066b5 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -59,6 +59,7 @@ obj-y += efi_device_path.o obj-$(CONFIG_EFI_DEVICE_PATH_TO_TEXT) += efi_device_path_to_text.o obj-$(CONFIG_EFI_DEVICE_PATH_UTIL) += efi_device_path_utilities.o obj-y += efi_dt_fixup.o +obj-y += efi_fdt.o obj-y += efi_file.o obj-$(CONFIG_EFI_LOADER_HII) += efi_hii.o obj-y += efi_image_loader.o diff --git a/lib/efi_loader/capsule_esl.dtsi.in b/lib/efi_loader/capsule_esl.dtsi.in index 61a9f2b25e9..bc7db836faa 100644 --- a/lib/efi_loader/capsule_esl.dtsi.in +++ b/lib/efi_loader/capsule_esl.dtsi.in @@ -1,9 +1,9 @@ // SPDX-License-Identifier: GPL-2.0+ -/** +/* * Devicetree file with the public key EFI Signature List(ESL) * node. This file is used to generate the dtsi file to be * included into the DTB. -*/ + */ / { signature { capsule-key = /incbin/("ESL_BIN_FILE"); diff --git a/lib/efi_loader/dtbdump.c b/lib/efi_loader/dtbdump.c index 5f39cf22da7..9f1d8fb82cb 100644 --- a/lib/efi_loader/dtbdump.c +++ b/lib/efi_loader/dtbdump.c @@ -41,6 +41,53 @@ static void print(u16 *string) } /** + * print_char() - print character + * + * 0x00 is replaced by '", "'. + * + * @c: - character + */ +static void print_char(unsigned char c) +{ + u16 out[2] = u"?"; + + if (!c) { + print(u"\", \""); + return; + } + + if (c > 0x1f && c < 0x80) + out[0] = c; + + print(out); +} + +/** + * print_hex_digit() - print hexadecimal digit + * + * @digit: digit to print + */ +static void print_hex_digit(unsigned char digit) +{ + if (digit < 10) + digit += '0'; + else + digit += 'a' - 10; + print_char(digit); +} + +/** + * printx() - print hexadecimal byte + * + * @val: value to print + */ +static void printx(unsigned char val) +{ + print_hex_digit(val >> 4); + print_hex_digit(val & 0xf); +} + +/** * error() - print error string * * @string: error text @@ -227,6 +274,7 @@ bool starts_with(u16 *string, u16 *keyword) */ void do_help(void) { + error(u"dump - print device-tree\r\n"); error(u"load <dtb> - load device-tree from file\r\n"); error(u"save <dtb> - save device-tree to file\r\n"); error(u"exit - exit the shell\r\n"); @@ -490,6 +538,217 @@ efi_status_t do_save(u16 *filename) } /** + * indent() - print a number of tabstops + * + * @level: indentation level + */ +static void indent(u32 level) +{ + for (; level; --level) + print(u"\t"); +} + +/** + * is_string_value() - determine if property is a string + * + * If a property is a string, an x-string, or a u32 cannot be deducted + * from the device-tree. Therefore a heuristic is used. + * + * @str: pointer to device-tree property + * @len: length of the device-tree property + * Return: 1 for string, 0 otherwise + */ +static int is_string_value(const unsigned char *str, u32 len) +{ + int nonzero_flag = 0; + + /* Zero length or not ending with 0x00 */ + if (!len || str[len - 1]) + return 0; + + for (u32 i = 0; i < len; ++i) { + if (!str[i]) { + /* Zero length string or two consecutive 0x00 */ + if (!nonzero_flag) + return 0; + + nonzero_flag = 0; + + continue; + } + /* Non-printable */ + if (str[i] < 0x20 || str[i] >= 0x80) + return 0; + + nonzero_flag = 1; + } + + return 1; +} + +/** + * print_property() - print device-tree property + * + * If a property is a string, an x-string, or a u32 cannot be deducted + * from the device-tree. Therefore a heuristic is used. + * + * @str: property value + * @len: length of property value + */ +static void print_property(const unsigned char *val, u32 len) +{ + if (is_string_value(val, len)) { + /* string */ + print(u"\""); + for (int i = 0; i < len - 1; ++i) + print_char(val[i]); + print(u"\""); + } else if (len & 0x3) { + /* byte string */ + print(u"["); + for (int i = 0; i < len; ++i) { + if (i) + print(u" "); + printx(val[i]); + } + print(u"]\""); + } else { + /* cell list */ + print(u"<"); + for (u32 i = 0; i < len; ++i) { + if ((i & 0x3) == 0) { + if (i > 0) + print(u" "); + print(u"0x"); + } + printx(val[i]); + } + print(u">"); + } +} + +/** + * print_mem_res_block() - print memory reservation block + * + * @rsvblk: memory reservation block + */ +static void print_mem_res_block(const struct fdt_reserve_entry *rsvblk) +{ + for (; rsvblk->address || rsvblk->size; ++rsvblk) { + const unsigned char *val; + + print(u"/memreserve/ 0x"); + val = (const unsigned char *)&rsvblk->address; + for (u32 i = 0; i < sizeof(u64); ++i) + printx(val[i]); + print(u" 0x"); + val = (const unsigned char *)&rsvblk->size; + for (u32 i = 0; i < sizeof(u64); ++i) + printx(val[i]); + print(u";\r\n"); + } +} + +/** + * do_dump() - print device-tree + */ +static efi_status_t do_dump(void) +{ + const unsigned char *fdt; + struct fdt_header *header; + const u32 *end; + const u32 *pos; + const char *strings; + u32 level = 0; + + fdt = get_dtb(systable); + if (!fdt) { + error(u"DTB not found\r\n"); + return EFI_NOT_FOUND; + } + + header = (struct fdt_header *)fdt; + if (f2h(header->magic) != FDT_MAGIC) { + error(u"Wrong device tree magic\r\n"); + error(u"Not a device-tree\r\n"); + return EFI_LOAD_ERROR; + } + + pos = (u32 *)(fdt + f2h(header->off_dt_struct)); + end = &pos[f2h(header->totalsize) >> 2]; + strings = fdt + f2h(header->off_dt_strings); + + print(u"/dts-v1/;\r\n"); + + print_mem_res_block((const struct fdt_reserve_entry *) + (fdt + f2h(header->off_mem_rsvmap))); + + print(u"/"); + for (; pos < end;) { + switch (f2h(pos[0])) { + case FDT_BEGIN_NODE: { + const char *c = (char *)&pos[1]; + size_t i; + + indent(level); + for (i = 0; c[i]; ++i) + print_char(c[i]); + print(u" {\n\r"); + + ++level; + pos = &pos[2 + (i >> 2)]; + break; + } + case FDT_PROP: { + struct fdt_property *prop = (struct fdt_property *)pos; + const unsigned char *label = &strings[f2h(prop->nameoff)]; + u32 len = f2h(prop->len); + const unsigned char *str = (unsigned char *)&pos[3]; + + indent(level); + for (int i = 0; label[i]; ++i) + print_char(label[i]); + + if (len) { + print(u" = "); + print_property(str, len); + } + print(u";\r\n"); + + pos = &pos[3 + ((f2h(prop->len) + 3) >> 2)]; + break; + } + case FDT_NOP: + ++pos; + break; + case FDT_END_NODE: + if (!level) { + error(u"Extraneous end node\r\n"); + return EFI_LOAD_ERROR; + } + + --level; + indent(level); + print(u"};\n\r"); + ++pos; + break; + case FDT_END: + if (level) { + error(u"Missing end node\r\n"); + return EFI_LOAD_ERROR; + } + return EFI_SUCCESS; + default: + error(u"Invalid device tree token\r\n"); + return EFI_LOAD_ERROR; + } + } + error(u"Overrun\r\n"); + + return EFI_LOAD_ERROR; +} + +/** * efi_main() - entry point of the EFI application. * * @handle: handle of the loaded image @@ -524,6 +783,8 @@ efi_status_t EFIAPI efi_main(efi_handle_t image_handle, pos = skip_whitespace(command); if (starts_with(pos, u"exit")) break; + else if (starts_with(pos, u"dump")) + do_dump(); else if (starts_with(pos, u"load ")) do_load(pos + 5); else if (starts_with(pos, u"save ")) diff --git a/lib/efi_loader/efi_bootbin.c b/lib/efi_loader/efi_bootbin.c index b7910f78fb6..a87006b3c0e 100644 --- a/lib/efi_loader/efi_bootbin.c +++ b/lib/efi_loader/efi_bootbin.c @@ -150,7 +150,7 @@ efi_status_t efi_run_image(void *source_buffer, efi_uintn_t source_size) msg_path = file_path; } else { file_path = efi_dp_concat(bootefi_device_path, - bootefi_image_path, false); + bootefi_image_path, 0); msg_path = bootefi_image_path; log_debug("Loaded from disk\n"); } diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c index 7da3139f917..589d3996b68 100644 --- a/lib/efi_loader/efi_bootmgr.c +++ b/lib/efi_loader/efi_bootmgr.c @@ -130,7 +130,7 @@ static efi_status_t try_load_from_file_path(efi_handle_t *fs_handles, if (!dp) continue; - dp = efi_dp_concat(dp, fp, false); + dp = efi_dp_concat(dp, fp, 0); if (!dp) continue; @@ -1186,6 +1186,59 @@ out: } /** + * load_fdt_from_load_option - load device-tree from load option + * + * @fdt: pointer to loaded device-tree or NULL + * Return: status code + */ +static efi_status_t load_fdt_from_load_option(void **fdt) +{ + struct efi_device_path *dp = NULL; + struct efi_file_handle *f = NULL; + efi_uintn_t filesize; + efi_status_t ret; + + *fdt = NULL; + + dp = efi_get_dp_from_boot(&efi_guid_fdt); + if (!dp) + return EFI_SUCCESS; + + /* Open file */ + f = efi_file_from_path(dp); + if (!f) { + log_err("Can't find %pD specified in Boot####\n", dp); + ret = EFI_NOT_FOUND; + goto out; + } + + /* Get file size */ + ret = efi_file_size(f, &filesize); + if (ret != EFI_SUCCESS) + goto out; + + *fdt = calloc(1, filesize); + if (!*fdt) { + log_err("Out of memory\n"); + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + ret = EFI_CALL(f->read(f, &filesize, *fdt)); + if (ret != EFI_SUCCESS) { + log_err("Can't read fdt\n"); + free(*fdt); + *fdt = NULL; + } + +out: + efi_free_pool(dp); + if (f) + EFI_CALL(f->close(f)); + + return ret; +} + +/** * efi_bootmgr_run() - execute EFI boot manager * @fdt: Flat device tree * @@ -1200,6 +1253,8 @@ efi_status_t efi_bootmgr_run(void *fdt) efi_handle_t handle; void *load_options; efi_status_t ret; + void *fdt_lo, *fdt_distro = NULL; + efi_uintn_t fdt_size; /* Initialize EFI drivers */ ret = efi_init_obj_list(); @@ -1215,7 +1270,31 @@ efi_status_t efi_bootmgr_run(void *fdt) return ret; } + if (!IS_ENABLED(CONFIG_GENERATE_ACPI_TABLE)) { + ret = load_fdt_from_load_option(&fdt_lo); + if (ret != EFI_SUCCESS) + return ret; + if (fdt_lo) + fdt = fdt_lo; + if (!fdt) { + efi_load_distro_fdt(handle, &fdt_distro, &fdt_size); + fdt = fdt_distro; + } + } + + /* + * Needed in ACPI case to create reservations based on + * control device-tree. + */ ret = efi_install_fdt(fdt); + + if (!IS_ENABLED(CONFIG_GENERATE_ACPI_TABLE)) { + free(fdt_lo); + if (fdt_distro) + efi_free_pages((uintptr_t)fdt_distro, + efi_size_in_pages(fdt_size)); + } + if (ret != EFI_SUCCESS) { if (EFI_CALL(efi_unload_image(handle)) == EFI_SUCCESS) free(load_options); diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 1951291747c..4f52284b4c6 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -1816,7 +1816,7 @@ efi_status_t efi_setup_loaded_image(struct efi_device_path *device_path, if (device_path) { info->device_handle = efi_dp_find_obj(device_path, NULL, NULL); - dp = efi_dp_concat(device_path, file_path, false); + dp = efi_dp_concat(device_path, file_path, 0); if (!dp) { ret = EFI_OUT_OF_RESOURCES; goto failure; @@ -1996,7 +1996,6 @@ error: * @size: size of the loaded image * Return: status code */ -static efi_status_t efi_load_image_from_path(bool boot_policy, struct efi_device_path *file_path, void **buffer, efi_uintn_t *size) @@ -2510,16 +2509,12 @@ static efi_status_t EFIAPI efi_protocols_per_handle( return EFI_EXIT(EFI_INVALID_PARAMETER); *protocol_buffer = NULL; - *protocol_buffer_count = 0; efiobj = efi_search_obj(handle); if (!efiobj) return EFI_EXIT(EFI_INVALID_PARAMETER); - /* Count protocols */ - list_for_each(protocol_handle, &efiobj->protocols) { - ++*protocol_buffer_count; - } + *protocol_buffer_count = list_count_nodes(&efiobj->protocols); /* Copy GUIDs */ if (*protocol_buffer_count) { diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c index de0d49ebebd..635088f25a1 100644 --- a/lib/efi_loader/efi_capsule.c +++ b/lib/efi_loader/efi_capsule.c @@ -480,6 +480,11 @@ static __maybe_unused efi_status_t fwu_empty_capsule_process( if (ret != EFI_SUCCESS) log_err("Unable to set the Accept bit for the image %pUs\n", image_guid); + + status = fwu_state_machine_updates(0, active_idx); + if (status < 0) + ret = EFI_DEVICE_ERROR; + } return ret; @@ -521,11 +526,10 @@ static __maybe_unused efi_status_t fwu_post_update_process(bool fw_accept_os) log_err("Failed to update FWU metadata index values\n"); } else { log_debug("Successfully updated the active_index\n"); - if (fw_accept_os) { - status = fwu_trial_state_ctr_start(); - if (status < 0) - ret = EFI_DEVICE_ERROR; - } + status = fwu_state_machine_updates(fw_accept_os ? 1 : 0, + update_index); + if (status < 0) + ret = EFI_DEVICE_ERROR; } return ret; @@ -568,7 +572,6 @@ static efi_status_t efi_capsule_update_firmware( return EFI_INVALID_PARAMETER; } - /* Obtain the update_index from the platform */ status = fwu_plat_get_update_index(&update_index); if (status < 0) { diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c index 03dece51aea..c944c10b216 100644 --- a/lib/efi_loader/efi_console.c +++ b/lib/efi_loader/efi_console.c @@ -1176,7 +1176,6 @@ out: return EFI_EXIT(ret); } - /** * efi_cin_reset() - drain the input buffer * diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c index aec224d8466..0f684590f22 100644 --- a/lib/efi_loader/efi_device_path.c +++ b/lib/efi_loader/efi_device_path.c @@ -276,10 +276,11 @@ struct efi_device_path *efi_dp_dup(const struct efi_device_path *dp) * * @dp1: First device path * @dp2: Second device path - * @split_end_node: If true the two device paths will be concatenated and - * separated by an end node (DEVICE_PATH_SUB_TYPE_END). - * If false the second device path will be concatenated to the - * first one as-is. + * @split_end_node: + * * 0 to concatenate + * * 1 to concatenate with end node added as separator + * * size of dp1 excluding last end node to concatenate with end node as + * separator in case dp1 contains an end node * * Return: * concatenated device path or NULL. Caller must free the returned value @@ -287,7 +288,7 @@ struct efi_device_path *efi_dp_dup(const struct efi_device_path *dp) struct efi_device_path *efi_dp_concat(const struct efi_device_path *dp1, const struct efi_device_path *dp2, - bool split_end_node) + size_t split_end_node) { struct efi_device_path *ret; size_t end_size; @@ -301,10 +302,15 @@ efi_device_path *efi_dp_concat(const struct efi_device_path *dp1, ret = efi_dp_dup(dp1); } else { /* both dp1 and dp2 are non-null */ - unsigned sz1 = efi_dp_size(dp1); - unsigned sz2 = efi_dp_size(dp2); + size_t sz1; + size_t sz2 = efi_dp_size(dp2); void *p; + if (split_end_node < sizeof(struct efi_device_path)) + sz1 = efi_dp_size(dp1); + else + sz1 = split_end_node; + if (split_end_node) end_size = 2 * sizeof(END); else @@ -1127,17 +1133,18 @@ ssize_t efi_dp_check_length(const struct efi_device_path *dp, } /** - * efi_dp_from_lo() - Get the instance of a VenMedia node in a - * multi-instance device path that matches - * a specific GUID. This kind of device paths - * is found in Boot#### options describing an - * initrd location + * efi_dp_from_lo() - get device-path from load option * - * @lo: EFI_LOAD_OPTION containing a valid device path - * @guid: guid to search for + * The load options in U-Boot may contain multiple concatenated device-paths. + * The first device-path indicates the EFI binary to execute. Subsequent + * device-paths start with a VenMedia node where the GUID identifies the + * function (initrd or fdt). + * + * @lo: EFI load option containing a valid device path + * @guid: GUID identifying device-path or NULL for the EFI binary * * Return: - * device path including the VenMedia node or NULL. + * device path excluding the matched VenMedia node or NULL. * Caller must free the returned value. */ struct @@ -1148,6 +1155,9 @@ efi_device_path *efi_dp_from_lo(struct efi_load_option *lo, struct efi_device_path_vendor *vendor; int lo_len = lo->file_path_length; + if (!guid) + return efi_dp_dup(fp); + for (; lo_len >= sizeof(struct efi_device_path); lo_len -= fp->length, fp = (void *)fp + fp->length) { if (lo_len < 0 || efi_dp_check_length(fp, lo_len) < 0) diff --git a/lib/efi_loader/efi_device_path_utilities.c b/lib/efi_loader/efi_device_path_utilities.c index c95dbfa9b5f..ac250bbfcc9 100644 --- a/lib/efi_loader/efi_device_path_utilities.c +++ b/lib/efi_loader/efi_device_path_utilities.c @@ -76,7 +76,7 @@ static struct efi_device_path * EFIAPI append_device_path( const struct efi_device_path *src2) { EFI_ENTRY("%pD, %pD", src1, src2); - return EFI_EXIT(efi_dp_concat(src1, src2, false)); + return EFI_EXIT(efi_dp_concat(src1, src2, 0)); } /* diff --git a/lib/efi_loader/efi_dt_fixup.c b/lib/efi_loader/efi_dt_fixup.c index 9886e6897cd..9d017804eea 100644 --- a/lib/efi_loader/efi_dt_fixup.c +++ b/lib/efi_loader/efi_dt_fixup.c @@ -172,7 +172,7 @@ efi_dt_fixup(struct efi_dt_fixup_protocol *this, void *dtb, } fdt_set_totalsize(dtb, *buffer_size); - if (image_setup_libfdt(&img, dtb, NULL)) { + if (image_setup_libfdt(&img, dtb, false)) { log_err("failed to process device tree\n"); ret = EFI_INVALID_PARAMETER; goto out; diff --git a/lib/efi_loader/efi_fdt.c b/lib/efi_loader/efi_fdt.c new file mode 100644 index 00000000000..f882622fdad --- /dev/null +++ b/lib/efi_loader/efi_fdt.c @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Bootmethod for distro boot via EFI + * + * Copyright 2021 Google LLC + * Written by Simon Glass <sjg@chromium.org> + */ + +#include <efi_loader.h> +#include <env.h> +#include <errno.h> +#include <log.h> +#include <string.h> +#include <vsprintf.h> + +/** + * efi_get_distro_fdt_name() - get the filename for reading the .dtb file + * + * @fname: buffer for filename + * @size: buffer size + * @seq: sequence number, to cycle through options (0=first) + * + * Returns: + * 0 on success, + * -ENOENT if the "fdtfile" env var does not exist, + * -EINVAL if there are no more options, + * -EALREADY if the control FDT should be used + */ +int efi_get_distro_fdt_name(char *fname, int size, int seq) +{ + const char *fdt_fname; + const char *prefix; + + /* select the prefix */ + switch (seq) { + case 0: + /* this is the default */ + prefix = "/dtb"; + break; + case 1: + prefix = ""; + break; + case 2: + prefix = "/dtb/current"; + break; + case 3: + prefix = "/dtbs"; + break; + default: + return log_msg_ret("pref", -EINVAL); + } + + fdt_fname = env_get("fdtfile"); + if (fdt_fname) { + snprintf(fname, size, "%s/%s", prefix, fdt_fname); + log_debug("Using device tree: %s\n", fname); + } else if (IS_ENABLED(CONFIG_OF_HAS_PRIOR_STAGE)) { + strcpy(fname, "<prior>"); + return log_msg_ret("pref", -EALREADY); + /* Use this fallback only for 32-bit ARM */ + } else if (IS_ENABLED(CONFIG_ARM) && !IS_ENABLED(CONFIG_ARM64)) { + const char *soc = env_get("soc"); + const char *board = env_get("board"); + const char *boardver = env_get("boardver"); + + /* cf the code in label_boot() which seems very complex */ + snprintf(fname, size, "%s/%s%s%s%s.dtb", prefix, + soc ? soc : "", soc ? "-" : "", board ? board : "", + boardver ? boardver : ""); + log_debug("Using default device tree: %s\n", fname); + } else { + return log_msg_ret("env", -ENOENT); + } + + return 0; +} + +/** + * efi_load_distro_fdt() - load distro device-tree + * + * @handle: handle of loaded image + * @fdt: on return device-tree, must be freed via efi_free_pages() + * @fdt_size: buffer size + */ +void efi_load_distro_fdt(efi_handle_t handle, void **fdt, efi_uintn_t *fdt_size) +{ + struct efi_device_path *dp; + efi_status_t ret; + struct efi_handler *handler; + struct efi_loaded_image *loaded_image; + efi_handle_t device; + + *fdt = NULL; + + /* Get boot device from loaded image protocol */ + ret = efi_search_protocol(handle, &efi_guid_loaded_image, &handler); + if (ret != EFI_SUCCESS) + return; + loaded_image = handler->protocol_interface; + device = loaded_image->device_handle; + + /* Get device path of boot device */ + ret = efi_search_protocol(device, &efi_guid_device_path, &handler); + if (ret != EFI_SUCCESS) + return; + dp = handler->protocol_interface; + + /* Try the various available names */ + for (int seq = 0; ; ++seq) { + struct efi_device_path *file; + char buf[255]; + + if (efi_get_distro_fdt_name(buf, sizeof(buf), seq)) + break; + file = efi_dp_from_file(dp, buf); + if (!file) + break; + ret = efi_load_image_from_path(true, file, fdt, fdt_size); + efi_free_pool(file); + if (ret == EFI_SUCCESS) { + log_debug("Fdt %pD loaded\n", file); + break; + } + } +} diff --git a/lib/efi_loader/efi_helper.c b/lib/efi_loader/efi_helper.c index 73d0279e843..96f847652ec 100644 --- a/lib/efi_loader/efi_helper.c +++ b/lib/efi_loader/efi_helper.c @@ -74,6 +74,7 @@ out: */ struct efi_device_path *efi_get_dp_from_boot(const efi_guid_t *guid) { + struct efi_device_path *file_path = NULL; struct efi_load_option lo; void *var_value; efi_uintn_t size; @@ -92,11 +93,55 @@ struct efi_device_path *efi_get_dp_from_boot(const efi_guid_t *guid) if (ret != EFI_SUCCESS) goto err; - return efi_dp_from_lo(&lo, guid); + file_path = efi_dp_from_lo(&lo, guid); err: free(var_value); - return NULL; + return file_path; +} + +/** + * efi_load_option_dp_join() - join device-paths for load option + * + * @dp: in: binary device-path, out: joined device-path + * @dp_size: size of joined device-path + * @initrd_dp: initrd device-path or NULL + * @fdt_dp: device-tree device-path or NULL + * Return: status_code + */ +efi_status_t efi_load_option_dp_join(struct efi_device_path **dp, + size_t *dp_size, + struct efi_device_path *initrd_dp, + struct efi_device_path *fdt_dp) +{ + if (!dp) + return EFI_INVALID_PARAMETER; + + *dp_size = efi_dp_size(*dp); + + if (initrd_dp) { + struct efi_device_path *tmp_dp = *dp; + + *dp = efi_dp_concat(tmp_dp, initrd_dp, *dp_size); + efi_free_pool(tmp_dp); + if (!*dp) + return EFI_OUT_OF_RESOURCES; + *dp_size += efi_dp_size(initrd_dp) + sizeof(END); + } + + if (fdt_dp) { + struct efi_device_path *tmp_dp = *dp; + + *dp = efi_dp_concat(tmp_dp, fdt_dp, *dp_size); + efi_free_pool(tmp_dp); + if (!*dp) + return EFI_OUT_OF_RESOURCES; + *dp_size += efi_dp_size(fdt_dp) + sizeof(END); + } + + *dp_size += sizeof(END); + + return EFI_SUCCESS; } const struct guid_to_hash_map { @@ -469,7 +514,7 @@ efi_status_t efi_install_fdt(void *fdt) return EFI_OUT_OF_RESOURCES; } - if (image_setup_libfdt(&img, fdt, NULL)) { + if (image_setup_libfdt(&img, fdt, false)) { log_err("ERROR: failed to process device tree\n"); return EFI_LOAD_ERROR; } diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c index 60424360328..0ddf69a0918 100644 --- a/lib/efi_loader/efi_image_loader.c +++ b/lib/efi_loader/efi_image_loader.c @@ -173,11 +173,6 @@ static efi_status_t efi_loader_relocate(const IMAGE_BASE_RELOCATION *rel, return EFI_SUCCESS; } -void __weak invalidate_icache_all(void) -{ - /* If the system doesn't support icache_all flush, cross our fingers */ -} - /** * efi_set_code_and_data_type() - determine the memory types to be used for code * and data. @@ -743,7 +738,6 @@ static bool efi_image_authenticate(void *efi, size_t efi_size) log_debug("Message digest doesn't match\n"); } - /* last resort try the image sha256 hash in db */ if (!ret && efi_signature_lookup_digest(regs, db, false)) ret = true; @@ -766,7 +760,6 @@ static bool efi_image_authenticate(void *efi, size_t efi_size) } #endif /* CONFIG_EFI_SECURE_BOOT */ - /** * efi_check_pe() - check if a memory buffer contains a PE-COFF image * @@ -986,7 +979,13 @@ efi_status_t efi_load_pe(struct efi_loaded_image_obj *handle, /* Flush cache */ flush_cache((ulong)efi_reloc, ALIGN(virt_size, EFI_CACHELINE_SIZE)); - invalidate_icache_all(); + + /* + * If on x86 a write affects a prefetched instruction, + * the prefetch queue is invalidated. + */ + if (!CONFIG_IS_ENABLED(X86)) + invalidate_icache_all(); /* Populate the loaded image interface bits */ loaded_image_info->image_base = efi_reloc; diff --git a/lib/efi_loader/efi_load_initrd.c b/lib/efi_loader/efi_load_initrd.c index d91135436c4..23508431c83 100644 --- a/lib/efi_loader/efi_load_initrd.c +++ b/lib/efi_loader/efi_load_initrd.c @@ -24,7 +24,7 @@ static const struct efi_load_file_protocol efi_lf2_protocol = { * Device path defined by Linux to identify the handle providing the * EFI_LOAD_FILE2_PROTOCOL used for loading the initial ramdisk. */ -static const struct efi_initrd_dp dp_lf2_handle = { +static const struct efi_lo_dp_prefix dp_lf2_handle = { .vendor = { { DEVICE_PATH_TYPE_MEDIA_DEVICE, diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c index 12cf23fa3fa..c6f1dd09456 100644 --- a/lib/efi_loader/efi_memory.c +++ b/lib/efi_loader/efi_memory.c @@ -127,7 +127,7 @@ static uint64_t desc_get_end(struct efi_mem_desc *desc) */ static void efi_mem_sort(void) { - struct list_head *lhandle; + struct efi_mem_list *lmem; struct efi_mem_list *prevmem = NULL; bool merge_again = true; @@ -136,19 +136,18 @@ static void efi_mem_sort(void) /* Now merge entries that can be merged */ while (merge_again) { merge_again = false; - list_for_each(lhandle, &efi_mem) { - struct efi_mem_list *lmem; - struct efi_mem_desc *prev = &prevmem->desc; + list_for_each_entry(lmem, &efi_mem, link) { + struct efi_mem_desc *prev; struct efi_mem_desc *cur; uint64_t pages; - lmem = list_entry(lhandle, struct efi_mem_list, link); if (!prevmem) { prevmem = lmem; continue; } cur = &lmem->desc; + prev = &prevmem->desc; if ((desc_get_end(cur) == prev->physical_start) && (prev->type == cur->type) && @@ -268,7 +267,7 @@ static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, int memory_type, bool overlap_only_ram) { - struct list_head *lhandle; + struct efi_mem_list *lmem; struct efi_mem_list *newlist; bool carve_again; uint64_t carved_pages = 0; @@ -308,11 +307,9 @@ static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, /* Add our new map */ do { carve_again = false; - list_for_each(lhandle, &efi_mem) { - struct efi_mem_list *lmem; + list_for_each_entry(lmem, &efi_mem, link) { s64 r; - lmem = list_entry(lhandle, struct efi_mem_list, link); r = efi_mem_carve_out(lmem, &newlist->desc, overlap_only_ram); switch (r) { @@ -444,7 +441,7 @@ static efi_status_t efi_check_allocated(u64 addr, bool must_be_allocated) */ static uint64_t efi_find_free_memory(uint64_t len, uint64_t max_addr) { - struct list_head *lhandle; + struct efi_mem_list *lmem; /* * Prealign input max address, so we simplify our matching @@ -452,9 +449,7 @@ static uint64_t efi_find_free_memory(uint64_t len, uint64_t max_addr) */ max_addr &= ~EFI_PAGE_MASK; - list_for_each(lhandle, &efi_mem) { - struct efi_mem_list *lmem = list_entry(lhandle, - struct efi_mem_list, link); + list_for_each_entry(lmem, &efi_mem, link) { struct efi_mem_desc *desc = &lmem->desc; uint64_t desc_len = desc->num_pages << EFI_PAGE_SHIFT; uint64_t desc_end = desc->physical_start + desc_len; @@ -742,9 +737,9 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size, efi_uintn_t *descriptor_size, uint32_t *descriptor_version) { + size_t map_entries; efi_uintn_t map_size = 0; - int map_entries = 0; - struct list_head *lhandle; + struct efi_mem_list *lmem; efi_uintn_t provided_map_size; if (!memory_map_size) @@ -752,8 +747,7 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size, provided_map_size = *memory_map_size; - list_for_each(lhandle, &efi_mem) - map_entries++; + map_entries = list_count_nodes(&efi_mem); map_size = map_entries * sizeof(struct efi_mem_desc); @@ -774,10 +768,7 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size, /* Copy list into array */ /* Return the list in ascending order */ memory_map = &memory_map[map_entries - 1]; - list_for_each(lhandle, &efi_mem) { - struct efi_mem_list *lmem; - - lmem = list_entry(lhandle, struct efi_mem_list, link); + list_for_each_entry(lmem, &efi_mem, link) { *memory_map = lmem->desc; memory_map--; } diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c index 011bcd04836..05369c47b01 100644 --- a/lib/efi_loader/efi_runtime.c +++ b/lib/efi_loader/efi_runtime.c @@ -783,7 +783,12 @@ void efi_runtime_relocate(ulong offset, struct efi_mem_desc *map) lastoff = offset; #endif - invalidate_icache_all(); + /* + * If on x86 a write affects a prefetched instruction, + * the prefetch queue is invalidated. + */ + if (!CONFIG_IS_ENABLED(X86)) + invalidate_icache_all(); } /** diff --git a/lib/efi_loader/efi_signature.c b/lib/efi_loader/efi_signature.c index f338e732759..184eac8cddb 100644 --- a/lib/efi_loader/efi_signature.c +++ b/lib/efi_loader/efi_signature.c @@ -17,7 +17,6 @@ #include <linux/oid_registry.h> #include <u-boot/hash-checksum.h> #include <u-boot/rsa.h> -#include <u-boot/sha256.h> const efi_guid_t efi_guid_sha256 = EFI_CERT_SHA256_GUID; const efi_guid_t efi_guid_cert_rsa2048 = EFI_CERT_RSA2048_GUID; diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c index b07e0099c27..45f451ef6b6 100644 --- a/lib/efi_loader/efi_tcg2.c +++ b/lib/efi_loader/efi_tcg2.c @@ -16,12 +16,8 @@ #include <malloc.h> #include <smbios.h> #include <version_string.h> -#include <tpm-v2.h> #include <tpm_api.h> #include <u-boot/hash-checksum.h> -#include <u-boot/sha1.h> -#include <u-boot/sha256.h> -#include <u-boot/sha512.h> #include <linux/unaligned/be_byteshift.h> #include <linux/unaligned/le_byteshift.h> #include <linux/unaligned/generic.h> @@ -257,8 +253,8 @@ efi_tcg2_get_capability(struct efi_tcg2_protocol *this, capability->protocol_version.major = 1; capability->protocol_version.minor = 1; - efi_ret = tcg2_platform_get_tpm2(&dev); - if (efi_ret != EFI_SUCCESS) { + ret = tcg2_platform_get_tpm2(&dev); + if (ret) { capability->supported_event_logs = 0; capability->hash_algorithm_bitmap = 0; capability->tpm_present_flag = false; @@ -280,7 +276,7 @@ efi_tcg2_get_capability(struct efi_tcg2_protocol *this, /* Supported and active PCRs */ capability->hash_algorithm_bitmap = 0; capability->active_pcr_banks = 0; - ret = tpm2_get_pcr_info(dev, &capability->hash_algorithm_bitmap, + ret = tcg2_get_pcr_info(dev, &capability->hash_algorithm_bitmap, &capability->active_pcr_banks, &capability->number_of_pcr_banks); if (ret) { @@ -353,8 +349,7 @@ efi_tcg2_get_eventlog(struct efi_tcg2_protocol *this, goto out; } - ret = tcg2_platform_get_tpm2(&dev); - if (ret != EFI_SUCCESS) { + if (tcg2_platform_get_tpm2(&dev)) { event_log_location = NULL; event_log_last_entry = NULL; *event_log_truncated = false; @@ -389,7 +384,7 @@ static efi_status_t tcg2_hash_pe_image(void *efi, u64 efi_size, void *new_efi = NULL; u8 hash[TPM2_SHA512_DIGEST_SIZE]; struct udevice *dev; - efi_status_t ret; + efi_status_t ret = EFI_SUCCESS; u32 active; int i; @@ -404,20 +399,21 @@ static efi_status_t tcg2_hash_pe_image(void *efi, u64 efi_size, goto out; } - ret = tcg2_platform_get_tpm2(&dev); - if (ret != EFI_SUCCESS) + if (tcg2_platform_get_tpm2(&dev)) { + ret = EFI_DEVICE_ERROR; goto out; + } - ret = tcg2_get_active_pcr_banks(dev, &active); - if (ret != EFI_SUCCESS) { + if (tcg2_get_active_pcr_banks(dev, &active)) { + ret = EFI_DEVICE_ERROR; goto out; } digest_list->count = 0; - for (i = 0; i < ARRAY_SIZE(tpm2_supported_algorithms); i++) { - u16 hash_alg = tpm2_supported_algorithms[i]; + for (i = 0; i < ARRAY_SIZE(hash_algo_list); i++) { + u16 hash_alg = hash_algo_list[i].hash_alg; - if (!(active & tpm2_algorithm_to_mask(hash_alg))) + if (!(active & hash_algo_list[i].hash_mask)) continue; switch (hash_alg) { case TPM2_ALG_SHA1: @@ -473,12 +469,12 @@ efi_status_t tcg2_measure_pe_image(void *efi, u64 efi_size, IMAGE_DOS_HEADER *dos; IMAGE_NT_HEADERS32 *nt; struct efi_handler *handler; + int rc; if (!is_tcg2_protocol_installed()) return EFI_SUCCESS; - ret = tcg2_platform_get_tpm2(&dev); - if (ret != EFI_SUCCESS) + if (tcg2_platform_get_tpm2(&dev)) return EFI_SECURITY_VIOLATION; switch (handle->image_type) { @@ -502,9 +498,9 @@ efi_status_t tcg2_measure_pe_image(void *efi, u64 efi_size, if (ret != EFI_SUCCESS) return ret; - ret = tcg2_pcr_extend(dev, pcr_index, &digest_list); - if (ret != EFI_SUCCESS) - return ret; + rc = tcg2_pcr_extend(dev, pcr_index, &digest_list); + if (rc) + return EFI_DEVICE_ERROR; ret = efi_search_protocol(&handle->header, &efi_guid_loaded_image_device_path, &handler); @@ -574,9 +570,10 @@ efi_tcg2_hash_log_extend_event(struct efi_tcg2_protocol *this, u64 flags, struct efi_tcg2_event *efi_tcg_event) { struct udevice *dev; - efi_status_t ret; + efi_status_t ret = EFI_SUCCESS; u32 event_type, pcr_index, event_size; struct tpml_digest_values digest_list; + int rc = 0; EFI_ENTRY("%p, %llu, %llu, %llu, %p", this, flags, data_to_hash, data_to_hash_len, efi_tcg_event); @@ -586,9 +583,10 @@ efi_tcg2_hash_log_extend_event(struct efi_tcg2_protocol *this, u64 flags, goto out; } - ret = tcg2_platform_get_tpm2(&dev); - if (ret != EFI_SUCCESS) + if (tcg2_platform_get_tpm2(&dev)) { + ret = EFI_DEVICE_ERROR; goto out; + } if (efi_tcg_event->size < efi_tcg_event->header.header_size + sizeof(u32)) { @@ -621,8 +619,10 @@ efi_tcg2_hash_log_extend_event(struct efi_tcg2_protocol *this, u64 flags, ret = tcg2_hash_pe_image((void *)(uintptr_t)data_to_hash, data_to_hash_len, &digest_list); } else { - ret = tcg2_create_digest(dev, (u8 *)(uintptr_t)data_to_hash, - data_to_hash_len, &digest_list); + rc = tcg2_create_digest(dev, (u8 *)(uintptr_t)data_to_hash, + data_to_hash_len, &digest_list); + if (rc) + ret = EFI_DEVICE_ERROR; } if (ret != EFI_SUCCESS) @@ -631,9 +631,11 @@ efi_tcg2_hash_log_extend_event(struct efi_tcg2_protocol *this, u64 flags, pcr_index = efi_tcg_event->header.pcr_index; event_type = efi_tcg_event->header.event_type; - ret = tcg2_pcr_extend(dev, pcr_index, &digest_list); - if (ret != EFI_SUCCESS) + rc = tcg2_pcr_extend(dev, pcr_index, &digest_list); + if (rc) { + ret = EFI_DEVICE_ERROR; goto out; + } if (flags & EFI_TCG2_EXTEND_ONLY) { if (event_log.truncated) @@ -672,7 +674,7 @@ efi_tcg2_submit_command(struct efi_tcg2_protocol *this, u8 *output_param_block) { struct udevice *dev; - efi_status_t ret; + efi_status_t ret = EFI_SUCCESS; u32 rc; size_t resp_buf_size = output_param_block_size; @@ -684,9 +686,10 @@ efi_tcg2_submit_command(struct efi_tcg2_protocol *this, goto out; } - ret = tcg2_platform_get_tpm2(&dev); - if (ret != EFI_SUCCESS) + if (tcg2_platform_get_tpm2(&dev)) { + ret = EFI_DEVICE_ERROR; goto out; + } rc = tpm2_submit_command(dev, input_param_block, output_param_block, &resp_buf_size); @@ -714,19 +717,25 @@ efi_tcg2_get_active_pcr_banks(struct efi_tcg2_protocol *this, u32 *active_pcr_banks) { struct udevice *dev; - efi_status_t ret; + efi_status_t ret = EFI_INVALID_PARAMETER; EFI_ENTRY("%p, %p", this, active_pcr_banks); - if (!this || !active_pcr_banks) { - ret = EFI_INVALID_PARAMETER; + if (!this || !active_pcr_banks) goto out; - } - ret = tcg2_platform_get_tpm2(&dev); - if (ret != EFI_SUCCESS) + + if (tcg2_platform_get_tpm2(&dev)) + goto out; + + /* + * EFI_INVALID_PARAMETER does not convey the problem type. + * but that's what currently the spec specifies. + * EFI_DEVICE_ERROR would be better + */ + if (tcg2_get_active_pcr_banks(dev, active_pcr_banks)) goto out; - ret = tcg2_get_active_pcr_banks(dev, active_pcr_banks); + ret = EFI_SUCCESS; out: return EFI_EXIT(ret); @@ -852,14 +861,15 @@ static efi_status_t measure_event(struct udevice *dev, u32 pcr_index, u32 event_type, u32 size, u8 event[]) { struct tpml_digest_values digest_list; - efi_status_t ret; + efi_status_t ret = EFI_DEVICE_ERROR; + int rc; - ret = tcg2_create_digest(dev, event, size, &digest_list); - if (ret != EFI_SUCCESS) + rc = tcg2_create_digest(dev, event, size, &digest_list); + if (rc) goto out; - ret = tcg2_pcr_extend(dev, pcr_index, &digest_list); - if (ret != EFI_SUCCESS) + rc = tcg2_pcr_extend(dev, pcr_index, &digest_list); + if (rc) goto out; ret = tcg2_agile_log_append(pcr_index, event_type, &digest_list, @@ -901,10 +911,10 @@ static efi_status_t efi_init_event_log(void) struct tcg2_event_log elog; struct udevice *dev; efi_status_t ret; + int rc; - ret = tcg2_platform_get_tpm2(&dev); - if (ret != EFI_SUCCESS) - return ret; + if (tcg2_platform_get_tpm2(&dev)) + return EFI_DEVICE_ERROR; ret = efi_allocate_pool(EFI_BOOT_SERVICES_DATA, TPM2_EVENT_LOG_SIZE, (void **)&event_log.buffer); @@ -933,9 +943,11 @@ static efi_status_t efi_init_event_log(void) */ elog.log = event_log.buffer; elog.log_size = TPM2_EVENT_LOG_SIZE; - ret = tcg2_log_prepare_buffer(dev, &elog, false); - if (ret != EFI_SUCCESS) + rc = tcg2_log_prepare_buffer(dev, &elog, false); + if (rc) { + ret = (rc == -ENOBUFS) ? EFI_BUFFER_TOO_SMALL : EFI_DEVICE_ERROR; goto free_pool; + } event_log.pos = elog.log_position; @@ -1306,8 +1318,7 @@ efi_status_t efi_tcg2_measure_dtb(void *dtb) if (!is_tcg2_protocol_installed()) return EFI_SUCCESS; - ret = tcg2_platform_get_tpm2(&dev); - if (ret != EFI_SUCCESS) + if (tcg2_platform_get_tpm2(&dev)) return EFI_SECURITY_VIOLATION; rsvmap_size = size_of_rsvmap(dtb); @@ -1331,7 +1342,7 @@ efi_status_t efi_tcg2_measure_dtb(void *dtb) sha256_update(&hash_ctx, (u8 *)dtb + fdt_off_mem_rsvmap(dtb), rsvmap_size); sha256_finish(&hash_ctx, blob->data + blob->blob_description_size); - ret = measure_event(dev, 0, EV_POST_CODE, event_size, (u8 *)blob); + ret = measure_event(dev, 1, EV_POST_CODE, event_size, (u8 *)blob); free(blob); return ret; @@ -1356,8 +1367,7 @@ efi_status_t efi_tcg2_measure_efi_app_invocation(struct efi_loaded_image_obj *ha if (tcg2_efi_app_invoked) return EFI_SUCCESS; - ret = tcg2_platform_get_tpm2(&dev); - if (ret != EFI_SUCCESS) + if (tcg2_platform_get_tpm2(&dev)) return EFI_SECURITY_VIOLATION; ret = tcg2_measure_boot_variable(dev); @@ -1406,9 +1416,8 @@ efi_status_t efi_tcg2_measure_efi_app_exit(void) if (!is_tcg2_protocol_installed()) return EFI_SUCCESS; - ret = tcg2_platform_get_tpm2(&dev); - if (ret != EFI_SUCCESS) - return ret; + if (tcg2_platform_get_tpm2(&dev)) + return EFI_SECURITY_VIOLATION; ret = measure_event(dev, 4, EV_EFI_ACTION, strlen(EFI_RETURNING_FROM_EFI_APPLICATION), @@ -1437,9 +1446,10 @@ efi_tcg2_notify_exit_boot_services(struct efi_event *event, void *context) goto out; } - ret = tcg2_platform_get_tpm2(&dev); - if (ret != EFI_SUCCESS) + if (tcg2_platform_get_tpm2(&dev)) { + ret = EFI_SECURITY_VIOLATION; goto out; + } ret = measure_event(dev, 5, EV_EFI_ACTION, strlen(EFI_EXIT_BOOT_SERVICES_INVOCATION), @@ -1469,9 +1479,8 @@ efi_status_t efi_tcg2_notify_exit_boot_services_failed(void) if (!is_tcg2_protocol_installed()) return EFI_SUCCESS; - ret = tcg2_platform_get_tpm2(&dev); - if (ret != EFI_SUCCESS) - goto out; + if (tcg2_platform_get_tpm2(&dev)) + return EFI_SECURITY_VIOLATION; ret = measure_event(dev, 5, EV_EFI_ACTION, strlen(EFI_EXIT_BOOT_SERVICES_INVOCATION), @@ -1551,8 +1560,7 @@ efi_status_t efi_tcg2_do_initial_measurement(void) if (!is_tcg2_protocol_installed()) return EFI_SUCCESS; - ret = tcg2_platform_get_tpm2(&dev); - if (ret != EFI_SUCCESS) + if (tcg2_platform_get_tpm2(&dev)) return EFI_SECURITY_VIOLATION; ret = tcg2_measure_secure_boot_variable(dev); @@ -1577,8 +1585,7 @@ efi_status_t efi_tcg2_register(void) struct efi_event *event; u32 err; - ret = tcg2_platform_get_tpm2(&dev); - if (ret != EFI_SUCCESS) { + if (tcg2_platform_get_tpm2(&dev)) { log_warning("Missing TPMv2 device for EFI_TCG_PROTOCOL\n"); return EFI_SUCCESS; } @@ -1586,6 +1593,7 @@ efi_status_t efi_tcg2_register(void) /* initialize the TPM as early as possible. */ err = tpm_auto_start(dev); if (err) { + ret = EFI_DEVICE_ERROR; log_err("TPM startup failed\n"); goto fail; } diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c index 1cc02acb3b2..e888c52efe3 100644 --- a/lib/efi_loader/efi_variable.c +++ b/lib/efi_loader/efi_variable.c @@ -288,7 +288,6 @@ efi_status_t efi_set_variable_int(const u16 *variable_name, /* check if a variable exists */ var = efi_var_mem_find(vendor, variable_name, NULL); append = !!(attributes & EFI_VARIABLE_APPEND_WRITE); - attributes &= ~EFI_VARIABLE_APPEND_WRITE; delete = !append && (!data_size || !attributes); /* check attributes */ @@ -304,7 +303,7 @@ efi_status_t efi_set_variable_int(const u16 *variable_name, /* attributes won't be changed */ if (!delete && - ((ro_check && var->attr != attributes) || + ((ro_check && var->attr != (attributes & ~EFI_VARIABLE_APPEND_WRITE)) || (!ro_check && ((var->attr & ~EFI_VARIABLE_READ_ONLY) != (attributes & ~EFI_VARIABLE_READ_ONLY))))) { return EFI_INVALID_PARAMETER; @@ -378,7 +377,8 @@ efi_status_t efi_set_variable_int(const u16 *variable_name, for (; *old_data; ++old_data) ; ++old_data; - ret = efi_var_mem_ins(variable_name, vendor, attributes, + ret = efi_var_mem_ins(variable_name, vendor, + attributes & ~EFI_VARIABLE_APPEND_WRITE, var->length, old_data, data_size, data, time); } else { @@ -604,6 +604,5 @@ efi_status_t efi_init_variables(void) log_err("Invalid EFI variable seed\n"); } - return efi_init_secure_state(); } diff --git a/lib/efi_loader/initrddump.c b/lib/efi_loader/initrddump.c index 0004b6b042b..615119043d1 100644 --- a/lib/efi_loader/initrddump.c +++ b/lib/efi_loader/initrddump.c @@ -33,7 +33,7 @@ static bool nocolor; * Device path defined by Linux to identify the handle providing the * EFI_LOAD_FILE2_PROTOCOL used for loading the initial ramdisk. */ -static const struct efi_initrd_dp initrd_dp = { +static const struct efi_lo_dp_prefix initrd_dp = { .vendor = { { DEVICE_PATH_TYPE_MEDIA_DEVICE, diff --git a/lib/efi_selftest/efi_selftest_controllers.c b/lib/efi_selftest/efi_selftest_controllers.c index 02f19574f83..9f23117449c 100644 --- a/lib/efi_selftest/efi_selftest_controllers.c +++ b/lib/efi_selftest/efi_selftest_controllers.c @@ -447,7 +447,6 @@ static int execute(void) return EFI_ST_FAILURE; } - return EFI_ST_SUCCESS; } diff --git a/lib/efi_selftest/efi_selftest_ecpt.c b/lib/efi_selftest/efi_selftest_ecpt.c index 09c5e96c5e1..47316598e61 100644 --- a/lib/efi_selftest/efi_selftest_ecpt.c +++ b/lib/efi_selftest/efi_selftest_ecpt.c @@ -68,7 +68,6 @@ static int execute(void) return EFI_ST_SUCCESS; } - EFI_UNIT_TEST(ecpt) = { .name = "conformance profile table", .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, diff --git a/lib/efi_selftest/efi_selftest_fdt.c b/lib/efi_selftest/efi_selftest_fdt.c index aa3b13ae3ab..a4b0cef20e4 100644 --- a/lib/efi_selftest/efi_selftest_fdt.c +++ b/lib/efi_selftest/efi_selftest_fdt.c @@ -227,6 +227,13 @@ static int execute(void) return EFI_ST_FAILURE; } } + if (IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL_MEASURE_DTB)) { + str = get_property(u"kaslr-seed", u"chosen"); + if (str) { + efi_st_error("kaslr-seed with measured fdt\n"); + return EFI_ST_FAILURE; + } + } if (IS_ENABLED(CONFIG_RISCV)) { u32 fdt_hartid; diff --git a/lib/efi_selftest/efi_selftest_load_file.c b/lib/efi_selftest/efi_selftest_load_file.c index 14df7611727..4e77a7cbac2 100644 --- a/lib/efi_selftest/efi_selftest_load_file.c +++ b/lib/efi_selftest/efi_selftest_load_file.c @@ -233,7 +233,6 @@ static efi_status_t EFIAPI load_file(struct efi_load_file_protocol *this, return EFI_SUCCESS; } - /* * load_file2() - LoadFile() service of a EFI_LOAD_FILE2_PROTOCOL * diff --git a/lib/elf.c b/lib/elf.c index 9a794f9cba8..e767a42a3b3 100644 --- a/lib/elf.c +++ b/lib/elf.c @@ -7,6 +7,7 @@ #include <cpu_func.h> #include <elf.h> #include <env.h> +#include <errno.h> #include <net.h> #include <vxworks.h> #ifdef CONFIG_X86 @@ -15,6 +16,59 @@ #include <linux/linkage.h> #endif +/** + * bootelf_exec() - start the ELF image execution. + * + * @entry: address of entry point of ELF. + * + * May by used to allow ports to override the default behavior. + */ +unsigned long bootelf_exec(ulong (*entry)(int, char * const[]), + int argc, char *const argv[]) +{ + return entry(argc, argv); +} + +/** + * bootelf() - Boot ELF from memory. + * + * @addr: Loading address of ELF in memory. + * @flags: Bits like ELF_PHDR to control boot details. + * @argc: May be used to pass command line arguments (maybe unused). + * Necessary for backward compatibility with the CLI command. + * If unused, must be 0. + * @argv: see @argc. If unused, must be NULL. + * Return: Number returned by ELF application. + * + * Sets errno = ENOEXEC if the ELF image is not valid. + */ +unsigned long bootelf(unsigned long addr, Bootelf_flags flags, + int argc, char *const argv[]) +{ + unsigned long entry_addr; + char *args[] = {"", NULL}; + + errno = 0; + + if (!valid_elf_image(addr)) { + errno = ENOEXEC; + return 1; + } + + entry_addr = flags.phdr ? load_elf_image_phdr(addr) + : load_elf_image_shdr(addr); + + if (!flags.autostart) + return 0; + + if (!argc && !argv) { + argc = 1; + argv = args; + } + + return bootelf_exec((void *)entry_addr, argc, argv); +} + /* * A very simple ELF64 loader, assumes the image is valid, returns the * entry point address. @@ -32,10 +86,14 @@ unsigned long load_elf64_image_phdr(unsigned long addr) phdr = (Elf64_Phdr *)(addr + (ulong)ehdr->e_phoff); /* Load each program header */ - for (i = 0; i < ehdr->e_phnum; ++i) { + for (i = 0; i < ehdr->e_phnum; ++i, ++phdr) { void *dst = (void *)(ulong)phdr->p_paddr; void *src = (void *)addr + phdr->p_offset; + /* Only load PT_LOAD program header */ + if (phdr->p_type != PT_LOAD) + continue; + debug("Loading phdr %i to 0x%p (%lu bytes)\n", i, dst, (ulong)phdr->p_filesz); if (phdr->p_filesz) @@ -45,7 +103,6 @@ unsigned long load_elf64_image_phdr(unsigned long addr) phdr->p_memsz - phdr->p_filesz); flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN), roundup(phdr->p_memsz, ARCH_DMA_MINALIGN)); - ++phdr; } if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags & @@ -147,10 +204,14 @@ unsigned long load_elf_image_phdr(unsigned long addr) phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff); /* Load each program header */ - for (i = 0; i < ehdr->e_phnum; ++i) { + for (i = 0; i < ehdr->e_phnum; ++i, ++phdr) { void *dst = (void *)(uintptr_t)phdr->p_paddr; void *src = (void *)addr + phdr->p_offset; + /* Only load PT_LOAD program header */ + if (phdr->p_type != PT_LOAD) + continue; + debug("Loading phdr %i to 0x%p (%i bytes)\n", i, dst, phdr->p_filesz); if (phdr->p_filesz) @@ -160,7 +221,6 @@ unsigned long load_elf_image_phdr(unsigned long addr) phdr->p_memsz - phdr->p_filesz); flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN), roundup(phdr->p_memsz, ARCH_DMA_MINALIGN)); - ++phdr; } return ehdr->e_entry; diff --git a/lib/fdtdec.c b/lib/fdtdec.c index b2c59ab3818..5edc8dd2f9f 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1182,7 +1182,6 @@ static int uncompress_blob(const void *src, ulong sz_src, void **dstp) if (!gzip && !lzo) return -EBADMSG; - if (CONFIG_IS_ENABLED(MULTI_DTB_FIT_DYN_ALLOC)) { dst = malloc(sz_out); if (!dst) { @@ -1669,8 +1668,16 @@ int fdtdec_setup(void) { int ret = -ENOENT; - /* If allowing a bloblist, check that first */ - if (CONFIG_IS_ENABLED(BLOBLIST)) { + /* + * If allowing a bloblist, check that first. There was discussion about + * adding an OF_BLOBLIST Kconfig, but this was rejected. + * + * The necessary test is whether the previous phase passed a bloblist, + * not whether this phase creates one. + */ + if (CONFIG_IS_ENABLED(BLOBLIST) && + (spl_prev_phase() != PHASE_TPL || + !IS_ENABLED(CONFIG_TPL_BLOBLIST))) { ret = bloblist_maybe_init(); if (!ret) { gd->fdt_blob = bloblist_find(BLOBLISTT_CONTROL_FDT, 0); @@ -1678,6 +1685,7 @@ int fdtdec_setup(void) gd->fdt_src = FDTSRC_BLOBLIST; log_debug("Devicetree is in bloblist at %p\n", gd->fdt_blob); + ret = 0; } else { log_debug("No FDT found in bloblist\n"); ret = -ENOENT; diff --git a/lib/fwu_updates/Kconfig b/lib/fwu_updates/Kconfig index d35247d0e5d..51b7fbbefd3 100644 --- a/lib/fwu_updates/Kconfig +++ b/lib/fwu_updates/Kconfig @@ -31,4 +31,18 @@ config FWU_TRIAL_STATE_CNT the platform is allowed to boot in Trial State after an update. +config FWU_MDATA_V1 + bool "Enable support FWU Metadata version 1" + help + The FWU specification supports two versions of the + metadata structure. This option enables support for FWU + Metadata version 1 access. + +config FWU_MDATA_V2 + bool "Enable support FWU Metadata version 2" + help + The FWU specification supports two versions of the + metadata structure. This option enables support for FWU + Metadata version 2 access. + endif diff --git a/lib/fwu_updates/Makefile b/lib/fwu_updates/Makefile index c9e3c06b489..3681bef46cd 100644 --- a/lib/fwu_updates/Makefile +++ b/lib/fwu_updates/Makefile @@ -6,3 +6,5 @@ obj-$(CONFIG_FWU_MULTI_BANK_UPDATE) += fwu.o obj-$(CONFIG_FWU_MDATA_GPT_BLK) += fwu_gpt.o obj-$(CONFIG_FWU_MDATA_MTD) += fwu_mtd.o +obj-$(CONFIG_FWU_MDATA_V1) += fwu_v1.o +obj-$(CONFIG_FWU_MDATA_V2) += fwu_v2.o diff --git a/lib/fwu_updates/fwu.c b/lib/fwu_updates/fwu.c index 86518108c2d..c7fc8987beb 100644 --- a/lib/fwu_updates/fwu.c +++ b/lib/fwu_updates/fwu.c @@ -10,6 +10,7 @@ #include <event.h> #include <fwu.h> #include <fwu_mdata.h> +#include <log.h> #include <malloc.h> #include <linux/errno.h> @@ -17,7 +18,7 @@ #include <u-boot/crc.h> -static struct fwu_mdata g_mdata; /* = {0} makes uninit crc32 always invalid */ +struct fwu_data g_fwu_data; static struct udevice *g_dev; static u8 in_trial; static u8 boottime_check; @@ -27,12 +28,6 @@ enum { IMAGE_ACCEPT_CLEAR, }; -enum { - PRIMARY_PART = 1, - SECONDARY_PART, - BOTH_PARTS, -}; - static int trial_counter_update(u16 *trial_state_ctr) { bool delete; @@ -106,23 +101,9 @@ out: return ret; } -static int in_trial_state(struct fwu_mdata *mdata) +static u32 in_trial_state(void) { - u32 i, active_bank; - struct fwu_image_entry *img_entry; - struct fwu_image_bank_info *img_bank_info; - - active_bank = mdata->active_index; - img_entry = &mdata->img_entry[0]; - for (i = 0; i < CONFIG_FWU_NUM_IMAGES_PER_BANK; i++) { - img_bank_info = &img_entry[i].img_bank_info[active_bank]; - if (!img_bank_info->accepted) { - log_info("System booting in Trial State\n"); - return 1; - } - } - - return 0; + return g_fwu_data.trial_state; } static int fwu_get_image_type_id(u8 image_index, efi_guid_t *image_type_id) @@ -141,17 +122,70 @@ static int fwu_get_image_type_id(u8 image_index, efi_guid_t *image_type_id) return -ENOENT; } +static int mdata_crc_check(struct fwu_mdata *mdata) +{ + int ret; + u32 calc_crc32; + uint32_t mdata_size; + void *buf = &mdata->version; + + ret = fwu_get_mdata_size(&mdata_size); + if (ret) + return ret; + + calc_crc32 = crc32(0, buf, mdata_size - sizeof(u32)); + return calc_crc32 == mdata->crc32 ? 0 : -EINVAL; +} + +static void fwu_data_crc_update(uint32_t crc32) +{ + g_fwu_data.crc32 = crc32; +} + +/** + * fwu_get_data() - Return the version agnostic FWU structure + * + * Return the pointer to the version agnostic FWU structure. + * + * Return: Pointer to the FWU data structure + */ +struct fwu_data *fwu_get_data(void) +{ + return &g_fwu_data; +} + +static void fwu_populate_mdata_bank_index(struct fwu_data *fwu_data) +{ + struct fwu_mdata *mdata = fwu_data->fwu_mdata; + + mdata->active_index = fwu_data->active_index; + mdata->previous_active_index = fwu_data->previous_active_index; +} + +/** + * fwu_get_dev() - Return the FWU metadata device + * + * Return the pointer to the FWU metadata device. + * + * Return: Pointer to the FWU metadata dev + */ +struct udevice *fwu_get_dev(void) +{ + return g_dev; +} + /** * fwu_sync_mdata() - Update given meta-data partition(s) with the copy provided - * @mdata: FWU metadata structure + * @data: FWU Data structure * @part: Bitmask of FWU metadata partitions to be written to * * Return: 0 if OK, -ve on error */ -static int fwu_sync_mdata(struct fwu_mdata *mdata, int part) +int fwu_sync_mdata(struct fwu_mdata *mdata, int part) { - void *buf = &mdata->version; int err; + uint mdata_size; + void *buf = &mdata->version; if (part == BOTH_PARTS) { err = fwu_sync_mdata(mdata, SECONDARY_PART); @@ -160,32 +194,53 @@ static int fwu_sync_mdata(struct fwu_mdata *mdata, int part) part = PRIMARY_PART; } + err = fwu_get_mdata_size(&mdata_size); + if (err) + return err; + /* * Calculate the crc32 for the updated FWU metadata * and put the updated value in the FWU metadata crc32 * field */ - mdata->crc32 = crc32(0, buf, sizeof(*mdata) - sizeof(u32)); + mdata->crc32 = crc32(0, buf, mdata_size - sizeof(u32)); + fwu_data_crc_update(mdata->crc32); - err = fwu_write_mdata(g_dev, mdata, part == PRIMARY_PART); + err = fwu_write_mdata(g_dev, mdata, part == PRIMARY_PART, mdata_size); if (err) { log_err("Unable to write %s mdata\n", part == PRIMARY_PART ? "primary" : "secondary"); return err; } - /* update the cached copy of meta-data */ - memcpy(&g_mdata, mdata, sizeof(struct fwu_mdata)); - return 0; } -static inline int mdata_crc_check(struct fwu_mdata *mdata) +/** + * fwu_mdata_copies_allocate() - Allocate memory for metadata + * @mdata_size: Size of the metadata structure + * + * Allocate memory for storing both the copies of the FWU metadata. The + * copies are then used as a cache for storing FWU metadata contents. + * + * Return: 0 if OK, -ve on error + */ +int fwu_mdata_copies_allocate(u32 mdata_size) { - void *buf = &mdata->version; - u32 calc_crc32 = crc32(0, buf, sizeof(*mdata) - sizeof(u32)); + if (g_fwu_data.fwu_mdata) + return 0; - return calc_crc32 == mdata->crc32 ? 0 : -EINVAL; + /* + * Allocate the total memory that would be needed for both + * the copies. + */ + g_fwu_data.fwu_mdata = calloc(2, mdata_size); + if (!g_fwu_data.fwu_mdata) { + log_err("Unable to allocate space for FWU metadata\n"); + return -ENOMEM; + } + + return 0; } /** @@ -201,21 +256,32 @@ static inline int mdata_crc_check(struct fwu_mdata *mdata) int fwu_get_mdata(struct fwu_mdata *mdata) { int err; + uint32_t mdata_size; bool parts_ok[2] = { false }; - struct fwu_mdata s, *parts_mdata[2]; + struct fwu_mdata *parts_mdata[2]; - parts_mdata[0] = &g_mdata; - parts_mdata[1] = &s; + err = fwu_get_mdata_size(&mdata_size); + if (err) + return err; + + parts_mdata[0] = g_fwu_data.fwu_mdata; + if (!parts_mdata[0]) { + log_err("Memory not allocated for the FWU Metadata copies\n"); + return -ENOMEM; + } + + parts_mdata[1] = (struct fwu_mdata *)((char *)parts_mdata[0] + + mdata_size); /* if mdata already read and ready */ err = mdata_crc_check(parts_mdata[0]); if (!err) goto ret_mdata; - /* else read, verify and, if needed, fix mdata */ + /* else read, verify and, if needed, fix mdata */ for (int i = 0; i < 2; i++) { parts_ok[i] = false; - err = fwu_read_mdata(g_dev, parts_mdata[i], !i); + err = fwu_read_mdata(g_dev, parts_mdata[i], !i, mdata_size); if (!err) { err = mdata_crc_check(parts_mdata[i]); if (!err) @@ -230,7 +296,7 @@ int fwu_get_mdata(struct fwu_mdata *mdata) * Before returning, check that both the * FWU metadata copies are the same. */ - err = memcmp(parts_mdata[0], parts_mdata[1], sizeof(struct fwu_mdata)); + err = memcmp(parts_mdata[0], parts_mdata[1], mdata_size); if (!err) goto ret_mdata; @@ -247,7 +313,7 @@ int fwu_get_mdata(struct fwu_mdata *mdata) if (parts_ok[i]) continue; - memcpy(parts_mdata[i], parts_mdata[1 - i], sizeof(struct fwu_mdata)); + memcpy(parts_mdata[i], parts_mdata[1 - i], mdata_size); err = fwu_sync_mdata(parts_mdata[i], i ? SECONDARY_PART : PRIMARY_PART); if (err) { log_debug("mdata : %s write failed\n", i ? "secondary" : "primary"); @@ -257,7 +323,7 @@ int fwu_get_mdata(struct fwu_mdata *mdata) ret_mdata: if (!err && mdata) - memcpy(mdata, parts_mdata[0], sizeof(struct fwu_mdata)); + memcpy(mdata, parts_mdata[0], mdata_size); return err; } @@ -275,13 +341,13 @@ ret_mdata: int fwu_get_active_index(uint *active_idx) { int ret = 0; - struct fwu_mdata *mdata = &g_mdata; + struct fwu_data *data = &g_fwu_data; /* * Found the FWU metadata partition, now read the active_index * value */ - *active_idx = mdata->active_index; + *active_idx = data->active_index; if (*active_idx >= CONFIG_FWU_NUM_BANKS) { log_debug("Active index value read is incorrect\n"); ret = -EINVAL; @@ -302,7 +368,7 @@ int fwu_get_active_index(uint *active_idx) int fwu_set_active_index(uint active_idx) { int ret; - struct fwu_mdata *mdata = &g_mdata; + struct fwu_data *data = &g_fwu_data; if (active_idx >= CONFIG_FWU_NUM_BANKS) { log_debug("Invalid active index value\n"); @@ -313,14 +379,16 @@ int fwu_set_active_index(uint active_idx) * Update the active index and previous_active_index fields * in the FWU metadata */ - mdata->previous_active_index = mdata->active_index; - mdata->active_index = active_idx; + data->previous_active_index = data->active_index; + data->active_index = active_idx; + + fwu_populate_mdata_bank_index(data); /* * Now write this updated FWU metadata to both the * FWU metadata partitions */ - ret = fwu_sync_mdata(mdata, BOTH_PARTS); + ret = fwu_sync_mdata(data->fwu_mdata, BOTH_PARTS); if (ret) { log_debug("Failed to update FWU metadata partitions\n"); ret = -EIO; @@ -346,7 +414,7 @@ int fwu_get_dfu_alt_num(u8 image_index, u8 *alt_num) int ret, i; uint update_bank; efi_guid_t *image_guid, image_type_id; - struct fwu_mdata *mdata = &g_mdata; + struct fwu_data *data = &g_fwu_data; struct fwu_image_entry *img_entry; struct fwu_image_bank_info *img_bank_info; @@ -365,15 +433,15 @@ int fwu_get_dfu_alt_num(u8 image_index, u8 *alt_num) ret = -EINVAL; /* - * The FWU metadata has been read. Now get the image_uuid for the + * The FWU metadata has been read. Now get the image_guid for the * image with the update_bank. */ for (i = 0; i < CONFIG_FWU_NUM_IMAGES_PER_BANK; i++) { if (!guidcmp(&image_type_id, - &mdata->img_entry[i].image_type_uuid)) { - img_entry = &mdata->img_entry[i]; + &data->fwu_images[i].image_type_guid)) { + img_entry = &data->fwu_images[i]; img_bank_info = &img_entry->img_bank_info[update_bank]; - image_guid = &img_bank_info->image_uuid; + image_guid = &img_bank_info->image_guid; ret = fwu_plat_get_alt_num(g_dev, image_guid, alt_num); if (ret) log_debug("alt_num not found for partition with GUID %pUs\n", @@ -407,21 +475,23 @@ int fwu_revert_boot_index(void) { int ret; u32 cur_active_index; - struct fwu_mdata *mdata = &g_mdata; + struct fwu_data *data = &g_fwu_data; /* * Swap the active index and previous_active_index fields * in the FWU metadata */ - cur_active_index = mdata->active_index; - mdata->active_index = mdata->previous_active_index; - mdata->previous_active_index = cur_active_index; + cur_active_index = data->active_index; + data->active_index = data->previous_active_index; + data->previous_active_index = cur_active_index; + + fwu_populate_mdata_bank_index(data); /* * Now write this updated FWU metadata to both the * FWU metadata partitions */ - ret = fwu_sync_mdata(mdata, BOTH_PARTS); + ret = fwu_sync_mdata(data->fwu_mdata, BOTH_PARTS); if (ret) { log_debug("Failed to update FWU metadata partitions\n"); ret = -EIO; @@ -448,20 +518,21 @@ int fwu_revert_boot_index(void) static int fwu_clrset_image_accept(efi_guid_t *img_type_id, u32 bank, u8 action) { int ret, i; - struct fwu_mdata *mdata = &g_mdata; + struct fwu_data *data = &g_fwu_data; struct fwu_image_entry *img_entry; struct fwu_image_bank_info *img_bank_info; - img_entry = &mdata->img_entry[0]; + img_entry = &data->fwu_images[0]; for (i = 0; i < CONFIG_FWU_NUM_IMAGES_PER_BANK; i++) { - if (!guidcmp(&img_entry[i].image_type_uuid, img_type_id)) { + if (!guidcmp(&img_entry[i].image_type_guid, img_type_id)) { img_bank_info = &img_entry[i].img_bank_info[bank]; if (action == IMAGE_ACCEPT_SET) img_bank_info->accepted |= FWU_IMAGE_ACCEPTED; else img_bank_info->accepted = 0; - ret = fwu_sync_mdata(mdata, BOTH_PARTS); + fwu_populate_mdata_image_info(data); + ret = fwu_sync_mdata(data->fwu_mdata, BOTH_PARTS); goto out; } } @@ -627,9 +698,9 @@ static int fwu_boottime_checks(void) return 0; } - ret = fwu_get_mdata(NULL); + ret = fwu_init(); if (ret) { - log_debug("Unable to read meta-data\n"); + log_debug("fwu_init() failed\n"); return ret; } @@ -665,7 +736,7 @@ static int fwu_boottime_checks(void) if (efi_init_obj_list() != EFI_SUCCESS) return 0; - in_trial = in_trial_state(&g_mdata); + in_trial = in_trial_state(); if (!in_trial || (ret = fwu_trial_count_update()) > 0) ret = trial_counter_update(NULL); diff --git a/lib/fwu_updates/fwu_mtd.c b/lib/fwu_updates/fwu_mtd.c index 69cd3d7001f..c14203b9dd3 100644 --- a/lib/fwu_updates/fwu_mtd.c +++ b/lib/fwu_updates/fwu_mtd.c @@ -11,20 +11,25 @@ #include <malloc.h> #include <mtd.h> #include <uuid.h> -#include <vsprintf.h> +#include <stdio.h> #include <dm/ofnode.h> -struct fwu_mtd_image_info -fwu_mtd_images[CONFIG_FWU_NUM_BANKS * CONFIG_FWU_NUM_IMAGES_PER_BANK]; - static struct fwu_mtd_image_info *mtd_img_by_uuid(const char *uuidbuf) { - int num_images = ARRAY_SIZE(fwu_mtd_images); + int num_images; + struct fwu_mdata_mtd_priv *mtd_priv = dev_get_priv(fwu_get_dev()); + struct fwu_mtd_image_info *image_info = mtd_priv->fwu_mtd_images; + + if (!image_info) + return NULL; + + num_images = CONFIG_FWU_NUM_BANKS * + CONFIG_FWU_NUM_IMAGES_PER_BANK; for (int i = 0; i < num_images; i++) - if (!strcmp(uuidbuf, fwu_mtd_images[i].uuidbuf)) - return &fwu_mtd_images[i]; + if (!strcmp(uuidbuf, image_info[i].uuidbuf)) + return &image_info[i]; return NULL; } @@ -55,10 +60,7 @@ int fwu_mtd_get_alt_num(efi_guid_t *image_id, u8 *alt_num, if (ret) return -ENOENT; - nalt = 0; - list_for_each_entry(dfu, &dfu_list, list) - nalt++; - + nalt = list_count_nodes(&dfu_list); if (!nalt) { log_warning("No entities in dfu_alt_info\n"); dfu_free_entities(); @@ -107,7 +109,7 @@ __weak int fwu_plat_get_alt_num(struct udevice *dev, efi_guid_t *image_id, return fwu_mtd_get_alt_num(image_id, alt_num, "nor1"); } -static int gen_image_alt_info(char *buf, size_t len, int sidx, +static int gen_image_alt_info(char *buf, size_t len, struct fwu_image_entry *img, struct mtd_info *mtd) { char *p = buf, *end = buf + len; @@ -131,7 +133,7 @@ static int gen_image_alt_info(char *buf, size_t len, int sidx, /* Query a partition by image UUID */ bank = &img->img_bank_info[i]; - uuid_bin_to_str(bank->image_uuid.b, uuidbuf, UUID_STR_FORMAT_STD); + uuid_bin_to_str(bank->image_guid.b, uuidbuf, UUID_STR_FORMAT_STD); mtd_img_info = mtd_img_by_uuid(uuidbuf); if (!mtd_img_info) { @@ -158,18 +160,13 @@ static int gen_image_alt_info(char *buf, size_t len, int sidx, int fwu_gen_alt_info_from_mtd(char *buf, size_t len, struct mtd_info *mtd) { - struct fwu_mdata mdata; int i, l, ret; - - ret = fwu_get_mdata(&mdata); - if (ret < 0) { - log_err("Failed to get the FWU mdata.\n"); - return ret; - } + struct fwu_data *data = fwu_get_data(); + struct fwu_image_entry *img_entry; for (i = 0; i < CONFIG_FWU_NUM_IMAGES_PER_BANK; i++) { - ret = gen_image_alt_info(buf, len, i * CONFIG_FWU_NUM_BANKS, - &mdata.img_entry[i], mtd); + img_entry = &data->fwu_images[i]; + ret = gen_image_alt_info(buf, len, img_entry, mtd); if (ret) break; diff --git a/lib/fwu_updates/fwu_v1.c b/lib/fwu_updates/fwu_v1.c new file mode 100644 index 00000000000..efb8d515008 --- /dev/null +++ b/lib/fwu_updates/fwu_v1.c @@ -0,0 +1,167 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2024, Linaro Limited + */ + +#include <fwu.h> +#include <fwu_mdata.h> + +#include <linux/types.h> + +#define FWU_MDATA_VERSION 0x1U + +static uint32_t fwu_check_trial_state(struct fwu_mdata *mdata, uint32_t bank) +{ + u32 i; + struct fwu_image_entry *img_entry; + struct fwu_image_bank_info *img_bank_info; + + img_entry = &mdata->img_entry[0]; + for (i = 0; i < CONFIG_FWU_NUM_IMAGES_PER_BANK; i++) { + img_bank_info = &img_entry[i].img_bank_info[bank]; + if (!img_bank_info->accepted) { + return 1; + } + } + + return 0; +} + +static void fwu_data_init(void) +{ + size_t image_info_size; + void *dst_img_info, *src_img_info; + struct fwu_data *data = fwu_get_data(); + struct fwu_mdata *mdata = data->fwu_mdata; + + data->crc32 = mdata->crc32; + data->version = mdata->version; + data->active_index = mdata->active_index; + data->previous_active_index = mdata->previous_active_index; + + data->metadata_size = sizeof(struct fwu_mdata); + data->num_banks = CONFIG_FWU_NUM_BANKS; + data->num_images = CONFIG_FWU_NUM_IMAGES_PER_BANK; + fwu_plat_get_bootidx(&data->boot_index); + data->trial_state = fwu_check_trial_state(mdata, data->boot_index); + + src_img_info = &mdata->img_entry[0]; + dst_img_info = &data->fwu_images[0]; + image_info_size = sizeof(data->fwu_images); + + memcpy(dst_img_info, src_img_info, image_info_size); +} + +static int fwu_trial_state_update(bool trial_state) +{ + int ret; + struct fwu_data *data = fwu_get_data(); + + if (trial_state) { + ret = fwu_trial_state_ctr_start(); + if (ret) + return ret; + } + + data->trial_state = trial_state; + + return 0; +} + +/** + * fwu_populate_mdata_image_info() - Populate the image information + * of the metadata + * @data: Version agnostic FWU metadata information + * + * Populate the image information in the FWU metadata by copying it + * from the version agnostic structure. This is done before the + * metadata gets written to the storage media. + * + * Return: None + */ +void fwu_populate_mdata_image_info(struct fwu_data *data) +{ + size_t image_info_size; + void *dst_img_info, *src_img_info; + struct fwu_mdata *mdata = data->fwu_mdata; + + image_info_size = sizeof(data->fwu_images); + dst_img_info = &mdata->img_entry[0]; + src_img_info = &data->fwu_images[0]; + + memcpy(dst_img_info, src_img_info, image_info_size); +} + +/** + * fwu_state_machine_updates() - Update FWU state of the platform + * @trial_state: Is platform transitioning into Trial State + * @update_index: Bank number to which images have been updated + * + * On successful completion of updates, transition the platform to + * either Trial State or Regular State. + * + * To transition the platform to Trial State, start the + * TrialStateCtr counter, followed by setting the value of bank_state + * field of the metadata to Valid state(applicable only in version 2 + * of metadata). + * + * In case, the platform is to transition directly to Regular State, + * update the bank_state field of the metadata to Accepted + * state(applicable only in version 2 of metadata). + * + * Return: 0 if OK, -ve on error + */ +int fwu_state_machine_updates(bool trial_state, + __maybe_unused uint32_t update_index) +{ + return fwu_trial_state_update(trial_state); +} + +/** + * fwu_get_mdata_size() - Get the FWU metadata size + * @mdata_size: Size of the metadata structure + * + * Get the size of the FWU metadata. + * + * Return: 0 if OK, -ve on error + */ +int fwu_get_mdata_size(uint32_t *mdata_size) +{ + *mdata_size = sizeof(struct fwu_mdata); + + return 0; +} + +/** + * fwu_init() - FWU specific initialisations + * + * Carry out some FWU specific initialisations including allocation + * of memory for the metadata copies, and reading the FWU metadata + * copies into the allocated memory. The metadata fields are then + * copied into a version agnostic structure. + * + * Return: 0 if OK, -ve on error + */ +int fwu_init(void) +{ + int ret; + uint32_t mdata_size; + + fwu_get_mdata_size(&mdata_size); + + ret = fwu_mdata_copies_allocate(mdata_size); + if (ret) + return ret; + + /* + * Now read the entire structure, both copies, and + * validate that the copies. + */ + ret = fwu_get_mdata(NULL); + if (ret) + return ret; + + fwu_data_init(); + + return 0; +} diff --git a/lib/fwu_updates/fwu_v2.c b/lib/fwu_updates/fwu_v2.c new file mode 100644 index 00000000000..108bc9bb4ac --- /dev/null +++ b/lib/fwu_updates/fwu_v2.c @@ -0,0 +1,260 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2024, Linaro Limited + */ + +#include <fwu.h> +#include <fwu_mdata.h> +#include <log.h> + +#include <linux/types.h> + +#define FWU_MDATA_VERSION 0x2U + +static inline struct fwu_fw_store_desc *fwu_get_fw_desc(struct fwu_mdata *mdata) +{ + return (struct fwu_fw_store_desc *)((u8 *)mdata + sizeof(*mdata)); +} + +static uint32_t fwu_check_trial_state(struct fwu_mdata *mdata, uint32_t bank) +{ + return mdata->bank_state[bank] == FWU_BANK_VALID ? 1 : 0; +} + +static void fwu_data_init(void) +{ + int i; + size_t image_info_size; + void *dst_img_info, *src_img_info; + struct fwu_data *data = fwu_get_data(); + struct fwu_mdata *mdata = data->fwu_mdata; + + data->crc32 = mdata->crc32; + data->version = mdata->version; + data->active_index = mdata->active_index; + data->previous_active_index = mdata->previous_active_index; + data->metadata_size = mdata->metadata_size; + fwu_plat_get_bootidx(&data->boot_index); + data->trial_state = fwu_check_trial_state(mdata, data->boot_index); + + data->num_banks = fwu_get_fw_desc(mdata)->num_banks; + data->num_images = fwu_get_fw_desc(mdata)->num_images; + + for (i = 0; i < 4; i++) { + data->bank_state[i] = mdata->bank_state[i]; + } + + image_info_size = sizeof(data->fwu_images); + src_img_info = &fwu_get_fw_desc(mdata)->img_entry[0]; + dst_img_info = &data->fwu_images[0]; + + memcpy(dst_img_info, src_img_info, image_info_size); +} + +static int fwu_mdata_sanity_checks(void) +{ + uint8_t num_banks; + uint16_t num_images; + struct fwu_data *data = fwu_get_data(); + struct fwu_mdata *mdata = data->fwu_mdata; + + if (mdata->version != FWU_MDATA_VERSION) { + log_err("FWU metadata version %u. Expected value of %u\n", + mdata->version, FWU_MDATA_VERSION); + return -EINVAL; + } + + if (!mdata->desc_offset) { + log_err("No image information provided with the Metadata. "); + log_err("Image information expected in the metadata\n"); + return -EINVAL; + } + + if (mdata->desc_offset != 0x20) { + log_err("Descriptor Offset(0x%x) in the FWU Metadata not equal to 0x20\n", + mdata->desc_offset); + return -EINVAL; + } + + num_banks = fwu_get_fw_desc(mdata)->num_banks; + num_images = fwu_get_fw_desc(mdata)->num_images; + + if (num_banks != CONFIG_FWU_NUM_BANKS) { + log_err("Number of Banks(%u) in FWU Metadata different from the configured value(%d)", + num_banks, CONFIG_FWU_NUM_BANKS); + return -EINVAL; + } + + if (num_images != CONFIG_FWU_NUM_IMAGES_PER_BANK) { + log_err("Number of Images(%u) in FWU Metadata different from the configured value(%d)", + num_images, CONFIG_FWU_NUM_IMAGES_PER_BANK); + return -EINVAL; + } + + return 0; +} + +static int fwu_bank_state_update(bool trial_state, uint32_t bank) +{ + int ret; + struct fwu_data *data = fwu_get_data(); + struct fwu_mdata *mdata = data->fwu_mdata; + + mdata->bank_state[bank] = data->bank_state[bank] = trial_state ? + FWU_BANK_VALID : FWU_BANK_ACCEPTED; + + ret = fwu_sync_mdata(mdata, BOTH_PARTS); + if (ret) + log_err("Unable to set bank_state for bank %u\n", bank); + else + data->trial_state = trial_state; + + return ret; +} + +static int fwu_trial_state_start(uint update_index) +{ + int ret; + + ret = fwu_trial_state_ctr_start(); + if (ret) + return ret; + + ret = fwu_bank_state_update(1, update_index); + if (ret) + return ret; + + return 0; +} + +/** + * fwu_populate_mdata_image_info() - Populate the image information + * of the metadata + * @data: Version agnostic FWU metadata information + * + * Populate the image information in the FWU metadata by copying it + * from the version agnostic structure. This is done before the + * metadata gets written to the storage media. + * + * Return: None + */ +void fwu_populate_mdata_image_info(struct fwu_data *data) +{ + size_t image_info_size; + struct fwu_mdata *mdata = data->fwu_mdata; + void *dst_img_info, *src_img_info; + + image_info_size = sizeof(data->fwu_images); + dst_img_info = &fwu_get_fw_desc(mdata)->img_entry[0]; + src_img_info = &data->fwu_images[0]; + + memcpy(dst_img_info, src_img_info, image_info_size); +} + +/** + * fwu_state_machine_updates() - Update FWU state of the platform + * @trial_state: Is platform transitioning into Trial State + * @update_index: Bank number to which images have been updated + * + * On successful completion of updates, transition the platform to + * either Trial State or Regular State. + * + * To transition the platform to Trial State, start the + * TrialStateCtr counter, followed by setting the value of bank_state + * field of the metadata to Valid state(applicable only in version 2 + * of metadata). + * + * In case, the platform is to transition directly to Regular State, + * update the bank_state field of the metadata to Accepted + * state(applicable only in version 2 of metadata). + * + * Return: 0 if OK, -ve on error + */ +int fwu_state_machine_updates(bool trial_state, uint32_t update_index) +{ + return trial_state ? fwu_trial_state_start(update_index) : + fwu_bank_state_update(0, update_index); +} + +/** + * fwu_get_mdata_size() - Get the FWU metadata size + * @mdata_size: Size of the metadata structure + * + * Get the size of the FWU metadata from the structure. This is later used + * to allocate memory for the structure. + * + * Return: 0 if OK, -ve on error + */ +int fwu_get_mdata_size(uint32_t *mdata_size) +{ + int ret = 0; + struct fwu_mdata mdata = { 0 }; + struct fwu_data *data = fwu_get_data(); + struct udevice *fwu_dev = fwu_get_dev(); + + if (data->metadata_size) { + *mdata_size = data->metadata_size; + return 0; + } + + ret = fwu_read_mdata(fwu_dev, &mdata, 1, + sizeof(struct fwu_mdata)); + if (ret) { + log_err("FWU metadata read failed\n"); + return ret; + } + + *mdata_size = mdata.metadata_size; + if (!*mdata_size) + return -EINVAL; + + return 0; +} + +/** + * fwu_init() - FWU specific initialisations + * + * Carry out some FWU specific initialisations including allocation + * of memory for the metadata copies, and reading the FWU metadata + * copies into the allocated memory. The metadata fields are then + * copied into a version agnostic structure. + * + * Return: 0 if OK, -ve on error + */ +int fwu_init(void) +{ + int ret; + struct fwu_mdata mdata = { 0 }; + struct udevice *fwu_dev = fwu_get_dev(); + + /* + * First we read only the top level structure + * and get the size of the complete structure. + */ + ret = fwu_read_mdata(fwu_dev, &mdata, 1, + sizeof(struct fwu_mdata)); + if (ret) { + log_err("FWU metadata read failed\n"); + return ret; + } + + ret = fwu_mdata_copies_allocate(mdata.metadata_size); + if (ret) + return ret; + + /* + * Now read the entire structure, both copies, and + * validate that the copies. + */ + ret = fwu_get_mdata(NULL); + if (ret) + return ret; + + ret = fwu_mdata_sanity_checks(); + if (ret) + return ret; + + fwu_data_init(); + + return 0; +} diff --git a/lib/hashtable.c b/lib/hashtable.c index a0060f6a0d6..9613adc5540 100644 --- a/lib/hashtable.c +++ b/lib/hashtable.c @@ -58,7 +58,6 @@ struct env_entry_node { struct env_entry entry; }; - static void _hdelete(const char *key, struct hsearch_data *htab, struct env_entry *ep, int idx); @@ -127,7 +126,6 @@ int hcreate_r(size_t nel, struct hsearch_data *htab) return 1; } - /* * hdestroy() */ @@ -428,7 +426,6 @@ int hsearch_r(struct env_entry item, enum env_action action, return 0; } - /* * hdelete() */ @@ -718,7 +715,6 @@ ssize_t hexport_r(struct hsearch_data *htab, const char sep, int flag, } #endif - /* * himport() */ diff --git a/lib/hexdump.c b/lib/hexdump.c index 33e3e6e5182..2bc508ff504 100644 --- a/lib/hexdump.c +++ b/lib/hexdump.c @@ -10,7 +10,7 @@ #include <hexdump.h> #include <mapmem.h> -#include <vsprintf.h> +#include <stdio.h> #include <linux/ctype.h> #include <linux/compat.h> #include <linux/log2.h> diff --git a/lib/initcall.c b/lib/initcall.c index c8e2b0f6a38..2686b9aed5c 100644 --- a/lib/initcall.c +++ b/lib/initcall.c @@ -49,13 +49,14 @@ static int initcall_is_event(init_fnc_t func) */ int initcall_run_list(const init_fnc_t init_sequence[]) { - ulong reloc_ofs = calc_reloc_ofs(); + ulong reloc_ofs; const init_fnc_t *ptr; enum event_t type; init_fnc_t func; int ret = 0; for (ptr = init_sequence; func = *ptr, func; ptr++) { + reloc_ofs = calc_reloc_ofs(); type = initcall_is_event(func); if (type) { @@ -84,7 +85,8 @@ int initcall_run_list(const init_fnc_t init_sequence[]) sprintf(buf, "event %d/%s", type, event_type_name(type)); } else { - sprintf(buf, "call %p", func); + sprintf(buf, "call %p", + (char *)func - reloc_ofs); } printf("initcall failed at %s (err=%dE)\n", buf, ret); diff --git a/lib/libavb/avb_sha.h b/lib/libavb/avb_sha.h index f5d02e09f22..fdd92fbe22d 100644 --- a/lib/libavb/avb_sha.h +++ b/lib/libavb/avb_sha.h @@ -24,7 +24,6 @@ extern "C" { /* Block size in bytes of a SHA-256 digest. */ #define AVB_SHA256_BLOCK_SIZE 64 - /* Block size in bytes of a SHA-512 digest. */ #define AVB_SHA512_BLOCK_SIZE 128 diff --git a/lib/lmb.c b/lib/lmb.c index 44f98205310..3ed570fb29b 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -6,50 +6,72 @@ * Copyright (C) 2001 Peter Bergner. */ +#include <alist.h> #include <efi_loader.h> #include <image.h> #include <mapmem.h> #include <lmb.h> #include <log.h> #include <malloc.h> +#include <spl.h> #include <asm/global_data.h> #include <asm/sections.h> +#include <linux/kernel.h> +#include <linux/sizes.h> DECLARE_GLOBAL_DATA_PTR; #define LMB_ALLOC_ANYWHERE 0 +#define LMB_ALIST_INITIAL_SIZE 4 -static void lmb_dump_region(struct lmb_region *rgn, char *name) +static struct lmb lmb; + +static void lmb_print_region_flags(enum lmb_flags flags) +{ + u64 bitpos; + const char *flag_str[] = { "none", "no-map", "no-overwrite" }; + + do { + bitpos = flags ? fls(flags) - 1 : 0; + printf("%s", flag_str[bitpos]); + flags &= ~(1ull << bitpos); + puts(flags ? ", " : "\n"); + } while (flags); +} + +static void lmb_dump_region(struct alist *lmb_rgn_lst, char *name) { + struct lmb_region *rgn = lmb_rgn_lst->data; unsigned long long base, size, end; enum lmb_flags flags; int i; - printf(" %s.cnt = 0x%lx / max = 0x%lx\n", name, rgn->cnt, rgn->max); + printf(" %s.count = 0x%x\n", name, lmb_rgn_lst->count); - for (i = 0; i < rgn->cnt; i++) { - base = rgn->region[i].base; - size = rgn->region[i].size; + for (i = 0; i < lmb_rgn_lst->count; i++) { + base = rgn[i].base; + size = rgn[i].size; end = base + size - 1; - flags = rgn->region[i].flags; + flags = rgn[i].flags; - printf(" %s[%d]\t[0x%llx-0x%llx], 0x%08llx bytes flags: %x\n", - name, i, base, end, size, flags); + printf(" %s[%d]\t[0x%llx-0x%llx], 0x%08llx bytes flags: ", + name, i, base, end, size); + lmb_print_region_flags(flags); } } -void lmb_dump_all_force(struct lmb *lmb) +void lmb_dump_all_force(void) { printf("lmb_dump_all:\n"); - lmb_dump_region(&lmb->memory, "memory"); - lmb_dump_region(&lmb->reserved, "reserved"); + lmb_dump_region(&lmb.free_mem, "memory"); + lmb_dump_region(&lmb.used_mem, "reserved"); } -void lmb_dump_all(struct lmb *lmb) +void lmb_dump_all(void) { #ifdef DEBUG - lmb_dump_all_force(lmb); + lmb_dump_all_force(); #endif } @@ -73,111 +95,71 @@ static long lmb_addrs_adjacent(phys_addr_t base1, phys_size_t size1, return 0; } -static long lmb_regions_overlap(struct lmb_region *rgn, unsigned long r1, +static long lmb_regions_overlap(struct alist *lmb_rgn_lst, unsigned long r1, unsigned long r2) { - phys_addr_t base1 = rgn->region[r1].base; - phys_size_t size1 = rgn->region[r1].size; - phys_addr_t base2 = rgn->region[r2].base; - phys_size_t size2 = rgn->region[r2].size; + struct lmb_region *rgn = lmb_rgn_lst->data; + + phys_addr_t base1 = rgn[r1].base; + phys_size_t size1 = rgn[r1].size; + phys_addr_t base2 = rgn[r2].base; + phys_size_t size2 = rgn[r2].size; return lmb_addrs_overlap(base1, size1, base2, size2); } -static long lmb_regions_adjacent(struct lmb_region *rgn, unsigned long r1, + +static long lmb_regions_adjacent(struct alist *lmb_rgn_lst, unsigned long r1, unsigned long r2) { - phys_addr_t base1 = rgn->region[r1].base; - phys_size_t size1 = rgn->region[r1].size; - phys_addr_t base2 = rgn->region[r2].base; - phys_size_t size2 = rgn->region[r2].size; + struct lmb_region *rgn = lmb_rgn_lst->data; + + phys_addr_t base1 = rgn[r1].base; + phys_size_t size1 = rgn[r1].size; + phys_addr_t base2 = rgn[r2].base; + phys_size_t size2 = rgn[r2].size; return lmb_addrs_adjacent(base1, size1, base2, size2); } -static void lmb_remove_region(struct lmb_region *rgn, unsigned long r) +static void lmb_remove_region(struct alist *lmb_rgn_lst, unsigned long r) { unsigned long i; + struct lmb_region *rgn = lmb_rgn_lst->data; - for (i = r; i < rgn->cnt - 1; i++) { - rgn->region[i].base = rgn->region[i + 1].base; - rgn->region[i].size = rgn->region[i + 1].size; - rgn->region[i].flags = rgn->region[i + 1].flags; + for (i = r; i < lmb_rgn_lst->count - 1; i++) { + rgn[i].base = rgn[i + 1].base; + rgn[i].size = rgn[i + 1].size; + rgn[i].flags = rgn[i + 1].flags; } - rgn->cnt--; + lmb_rgn_lst->count--; } /* Assumption: base addr of region 1 < base addr of region 2 */ -static void lmb_coalesce_regions(struct lmb_region *rgn, unsigned long r1, +static void lmb_coalesce_regions(struct alist *lmb_rgn_lst, unsigned long r1, unsigned long r2) { - rgn->region[r1].size += rgn->region[r2].size; - lmb_remove_region(rgn, r2); + struct lmb_region *rgn = lmb_rgn_lst->data; + + rgn[r1].size += rgn[r2].size; + lmb_remove_region(lmb_rgn_lst, r2); } /*Assumption : base addr of region 1 < base addr of region 2*/ -static void lmb_fix_over_lap_regions(struct lmb_region *rgn, unsigned long r1, - unsigned long r2) +static void lmb_fix_over_lap_regions(struct alist *lmb_rgn_lst, + unsigned long r1, unsigned long r2) { - phys_addr_t base1 = rgn->region[r1].base; - phys_size_t size1 = rgn->region[r1].size; - phys_addr_t base2 = rgn->region[r2].base; - phys_size_t size2 = rgn->region[r2].size; + struct lmb_region *rgn = lmb_rgn_lst->data; + + phys_addr_t base1 = rgn[r1].base; + phys_size_t size1 = rgn[r1].size; + phys_addr_t base2 = rgn[r2].base; + phys_size_t size2 = rgn[r2].size; if (base1 + size1 > base2 + size2) { printf("This will not be a case any time\n"); return; } - rgn->region[r1].size = base2 + size2 - base1; - lmb_remove_region(rgn, r2); -} - -void lmb_init(struct lmb *lmb) -{ -#if IS_ENABLED(CONFIG_LMB_USE_MAX_REGIONS) - lmb->memory.max = CONFIG_LMB_MAX_REGIONS; - lmb->reserved.max = CONFIG_LMB_MAX_REGIONS; -#else - lmb->memory.max = CONFIG_LMB_MEMORY_REGIONS; - lmb->reserved.max = CONFIG_LMB_RESERVED_REGIONS; - lmb->memory.region = lmb->memory_regions; - lmb->reserved.region = lmb->reserved_regions; -#endif - lmb->memory.cnt = 0; - lmb->reserved.cnt = 0; -} - -void arch_lmb_reserve_generic(struct lmb *lmb, ulong sp, ulong end, ulong align) -{ - ulong bank_end; - int bank; - - /* - * Reserve memory from aligned address below the bottom of U-Boot stack - * until end of U-Boot area using LMB to prevent U-Boot from overwriting - * that memory. - */ - debug("## Current stack ends at 0x%08lx ", sp); - - /* adjust sp by 4K to be safe */ - sp -= align; - for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) { - if (!gd->bd->bi_dram[bank].size || - sp < gd->bd->bi_dram[bank].start) - continue; - /* Watch out for RAM at end of address space! */ - bank_end = gd->bd->bi_dram[bank].start + - gd->bd->bi_dram[bank].size - 1; - if (sp > bank_end) - continue; - if (bank_end > end) - bank_end = end - 1; - - lmb_reserve(lmb, sp, bank_end - sp + 1); - - if (gd->flags & GD_FLG_SKIP_RELOC) - lmb_reserve(lmb, (phys_addr_t)(uintptr_t)_start, gd->mon_len); - - break; - } + rgn[r1].size = base2 + size2 - base1; + lmb_remove_region(lmb_rgn_lst, r2); } /** @@ -186,10 +168,9 @@ void arch_lmb_reserve_generic(struct lmb *lmb, ulong sp, ulong end, ulong align) * Add reservations for all EFI memory areas that are not * EFI_CONVENTIONAL_MEMORY. * - * @lmb: lmb environment * Return: 0 on success, 1 on failure */ -static __maybe_unused int efi_lmb_reserve(struct lmb *lmb) +static __maybe_unused int efi_lmb_reserve(void) { struct efi_mem_desc *memmap = NULL, *map; efi_uintn_t i, map_size = 0; @@ -201,8 +182,7 @@ static __maybe_unused int efi_lmb_reserve(struct lmb *lmb) for (i = 0, map = memmap; i < map_size / sizeof(*map); ++map, ++i) { if (map->type != EFI_CONVENTIONAL_MEMORY) { - lmb_reserve_flags(lmb, - map_to_sysmem((void *)(uintptr_t) + lmb_reserve_flags(map_to_sysmem((void *)(uintptr_t) map->physical_start), map->num_pages * EFI_PAGE_SIZE, map->type == EFI_RESERVED_MEMORY_TYPE @@ -214,64 +194,199 @@ static __maybe_unused int efi_lmb_reserve(struct lmb *lmb) return 0; } -static void lmb_reserve_common(struct lmb *lmb, void *fdt_blob) +static void lmb_reserve_uboot_region(void) +{ + int bank; + ulong end, bank_end; + phys_addr_t rsv_start; + + rsv_start = gd->start_addr_sp - CONFIG_STACK_SIZE; + end = gd->ram_top; + + /* + * Reserve memory from aligned address below the bottom of U-Boot stack + * until end of RAM area to prevent LMB from overwriting that memory. + */ + debug("## Current stack ends at 0x%08lx ", (ulong)rsv_start); + + /* adjust sp by 16K to be safe */ + rsv_start -= SZ_16K; + for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) { + if (!gd->bd->bi_dram[bank].size || + rsv_start < gd->bd->bi_dram[bank].start) + continue; + /* Watch out for RAM at end of address space! */ + bank_end = gd->bd->bi_dram[bank].start + + gd->bd->bi_dram[bank].size - 1; + if (rsv_start > bank_end) + continue; + if (bank_end > end) + bank_end = end - 1; + + lmb_reserve_flags(rsv_start, bank_end - rsv_start + 1, + LMB_NOOVERWRITE); + + if (gd->flags & GD_FLG_SKIP_RELOC) + lmb_reserve_flags((phys_addr_t)(uintptr_t)_start, + gd->mon_len, LMB_NOOVERWRITE); + + break; + } +} + +static void lmb_reserve_common(void *fdt_blob) { - arch_lmb_reserve(lmb); - board_lmb_reserve(lmb); + lmb_reserve_uboot_region(); if (CONFIG_IS_ENABLED(OF_LIBFDT) && fdt_blob) - boot_fdt_add_mem_rsv_regions(lmb, fdt_blob); + boot_fdt_add_mem_rsv_regions(fdt_blob); if (CONFIG_IS_ENABLED(EFI_LOADER)) - efi_lmb_reserve(lmb); + efi_lmb_reserve(); +} + +static __maybe_unused void lmb_reserve_common_spl(void) +{ + phys_addr_t rsv_start; + phys_size_t rsv_size; + + /* + * Assume a SPL stack of 16KB. This must be + * more than enough for the SPL stage. + */ + if (IS_ENABLED(CONFIG_SPL_STACK_R_ADDR)) { + rsv_start = gd->start_addr_sp - 16384; + rsv_size = 16384; + lmb_reserve_flags(rsv_start, rsv_size, LMB_NOOVERWRITE); + } + + if (IS_ENABLED(CONFIG_SPL_SEPARATE_BSS)) { + /* Reserve the bss region */ + rsv_start = (phys_addr_t)(uintptr_t)__bss_start; + rsv_size = (phys_addr_t)(uintptr_t)__bss_end - + (phys_addr_t)(uintptr_t)__bss_start; + lmb_reserve_flags(rsv_start, rsv_size, LMB_NOOVERWRITE); + } } -/* Initialize the struct, add memory and call arch/board reserve functions */ -void lmb_init_and_reserve(struct lmb *lmb, struct bd_info *bd, void *fdt_blob) +/** + * lmb_add_memory() - Add memory range for LMB allocations + * + * Add the entire available memory range to the pool of memory that + * can be used by the LMB module for allocations. + * + * Return: None + */ +void lmb_add_memory(void) { int i; + phys_size_t size; + phys_addr_t rgn_top; + u64 ram_top = gd->ram_top; + struct bd_info *bd = gd->bd; - lmb_init(lmb); + /* Assume a 4GB ram_top if not defined */ + if (!ram_top) + ram_top = 0x100000000ULL; for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { - if (bd->bi_dram[i].size) { - lmb_add(lmb, bd->bi_dram[i].start, - bd->bi_dram[i].size); + size = bd->bi_dram[i].size; + if (size) { + if (bd->bi_dram[i].start > ram_top) + continue; + + rgn_top = bd->bi_dram[i].start + + bd->bi_dram[i].size; + + if (rgn_top > ram_top) + size -= rgn_top - ram_top; + + lmb_add(bd->bi_dram[i].start, size); } } - - lmb_reserve_common(lmb, fdt_blob); } -/* Initialize the struct, add memory and call arch/board reserve functions */ -void lmb_init_and_reserve_range(struct lmb *lmb, phys_addr_t base, - phys_size_t size, void *fdt_blob) +static long lmb_resize_regions(struct alist *lmb_rgn_lst, + unsigned long idx_start, + phys_addr_t base, phys_size_t size) { - lmb_init(lmb); - lmb_add(lmb, base, size); - lmb_reserve_common(lmb, fdt_blob); + phys_size_t rgnsize; + unsigned long rgn_cnt, idx, idx_end; + phys_addr_t rgnbase, rgnend; + phys_addr_t mergebase, mergeend; + struct lmb_region *rgn = lmb_rgn_lst->data; + + rgn_cnt = 0; + idx = idx_start; + idx_end = idx_start; + + /* + * First thing to do is to identify how many regions + * the requested region overlaps. + * If the flags match, combine all these overlapping + * regions into a single region, and remove the merged + * regions. + */ + while (idx <= lmb_rgn_lst->count - 1) { + rgnbase = rgn[idx].base; + rgnsize = rgn[idx].size; + + if (lmb_addrs_overlap(base, size, rgnbase, + rgnsize)) { + if (rgn[idx].flags != LMB_NONE) + return -1; + rgn_cnt++; + idx_end = idx; + } + idx++; + } + + /* The merged region's base and size */ + rgnbase = rgn[idx_start].base; + mergebase = min(base, rgnbase); + rgnend = rgn[idx_end].base + rgn[idx_end].size; + mergeend = max(rgnend, (base + size)); + + rgn[idx_start].base = mergebase; + rgn[idx_start].size = mergeend - mergebase; + + /* Now remove the merged regions */ + while (--rgn_cnt) + lmb_remove_region(lmb_rgn_lst, idx_start + 1); + + return 0; } -/* This routine called with relocation disabled. */ -static long lmb_add_region_flags(struct lmb_region *rgn, phys_addr_t base, +/** + * lmb_add_region_flags() - Add an lmb region to the given list + * @lmb_rgn_lst: LMB list to which region is to be added(free/used) + * @base: Start address of the region + * @size: Size of the region to be added + * @flags: Attributes of the LMB region + * + * Add a region of memory to the list. If the region does not exist, add + * it to the list. Depending on the attributes of the region to be added, + * the function might resize an already existing region or coalesce two + * adjacent regions. + * + * + * Returns: 0 if the region addition successful, -1 on failure + */ +static long lmb_add_region_flags(struct alist *lmb_rgn_lst, phys_addr_t base, phys_size_t size, enum lmb_flags flags) { unsigned long coalesced = 0; - long adjacent, i; + long ret, i; + struct lmb_region *rgn = lmb_rgn_lst->data; - if (rgn->cnt == 0) { - rgn->region[0].base = base; - rgn->region[0].size = size; - rgn->region[0].flags = flags; - rgn->cnt = 1; - return 0; - } + if (alist_err(lmb_rgn_lst)) + return -1; /* First try and coalesce this LMB with another. */ - for (i = 0; i < rgn->cnt; i++) { - phys_addr_t rgnbase = rgn->region[i].base; - phys_size_t rgnsize = rgn->region[i].size; - phys_size_t rgnflags = rgn->region[i].flags; + for (i = 0; i < lmb_rgn_lst->count; i++) { + phys_addr_t rgnbase = rgn[i].base; + phys_size_t rgnsize = rgn[i].size; + phys_size_t rgnflags = rgn[i].flags; phys_addr_t end = base + size - 1; phys_addr_t rgnend = rgnbase + rgnsize - 1; if (rgnbase <= base && end <= rgnend) { @@ -282,119 +397,127 @@ static long lmb_add_region_flags(struct lmb_region *rgn, phys_addr_t base, return -1; /* regions with new flags */ } - adjacent = lmb_addrs_adjacent(base, size, rgnbase, rgnsize); - if (adjacent > 0) { + ret = lmb_addrs_adjacent(base, size, rgnbase, rgnsize); + if (ret > 0) { if (flags != rgnflags) break; - rgn->region[i].base -= size; - rgn->region[i].size += size; + rgn[i].base -= size; + rgn[i].size += size; coalesced++; break; - } else if (adjacent < 0) { + } else if (ret < 0) { if (flags != rgnflags) break; - rgn->region[i].size += size; + rgn[i].size += size; coalesced++; break; } else if (lmb_addrs_overlap(base, size, rgnbase, rgnsize)) { - /* regions overlap */ - return -1; + if (flags == LMB_NONE) { + ret = lmb_resize_regions(lmb_rgn_lst, i, base, + size); + if (ret < 0) + return -1; + + coalesced++; + break; + } else { + return -1; + } } } - if (i < rgn->cnt - 1 && rgn->region[i].flags == rgn->region[i + 1].flags) { - if (lmb_regions_adjacent(rgn, i, i + 1)) { - lmb_coalesce_regions(rgn, i, i + 1); - coalesced++; - } else if (lmb_regions_overlap(rgn, i, i + 1)) { - /* fix overlapping area */ - lmb_fix_over_lap_regions(rgn, i, i + 1); - coalesced++; + if (lmb_rgn_lst->count && i < lmb_rgn_lst->count - 1) { + rgn = lmb_rgn_lst->data; + if (rgn[i].flags == rgn[i + 1].flags) { + if (lmb_regions_adjacent(lmb_rgn_lst, i, i + 1)) { + lmb_coalesce_regions(lmb_rgn_lst, i, i + 1); + coalesced++; + } else if (lmb_regions_overlap(lmb_rgn_lst, i, i + 1)) { + /* fix overlapping area */ + lmb_fix_over_lap_regions(lmb_rgn_lst, i, i + 1); + coalesced++; + } } } if (coalesced) return coalesced; - if (rgn->cnt >= rgn->max) + + if (alist_full(lmb_rgn_lst) && + !alist_expand_by(lmb_rgn_lst, lmb_rgn_lst->alloc)) return -1; + rgn = lmb_rgn_lst->data; /* Couldn't coalesce the LMB, so add it to the sorted table. */ - for (i = rgn->cnt-1; i >= 0; i--) { - if (base < rgn->region[i].base) { - rgn->region[i + 1].base = rgn->region[i].base; - rgn->region[i + 1].size = rgn->region[i].size; - rgn->region[i + 1].flags = rgn->region[i].flags; + for (i = lmb_rgn_lst->count; i >= 0; i--) { + if (i && base < rgn[i - 1].base) { + rgn[i] = rgn[i - 1]; } else { - rgn->region[i + 1].base = base; - rgn->region[i + 1].size = size; - rgn->region[i + 1].flags = flags; + rgn[i].base = base; + rgn[i].size = size; + rgn[i].flags = flags; break; } } - if (base < rgn->region[0].base) { - rgn->region[0].base = base; - rgn->region[0].size = size; - rgn->region[0].flags = flags; - } - - rgn->cnt++; + lmb_rgn_lst->count++; return 0; } -static long lmb_add_region(struct lmb_region *rgn, phys_addr_t base, +static long lmb_add_region(struct alist *lmb_rgn_lst, phys_addr_t base, phys_size_t size) { - return lmb_add_region_flags(rgn, base, size, LMB_NONE); + return lmb_add_region_flags(lmb_rgn_lst, base, size, LMB_NONE); } /* This routine may be called with relocation disabled. */ -long lmb_add(struct lmb *lmb, phys_addr_t base, phys_size_t size) +long lmb_add(phys_addr_t base, phys_size_t size) { - struct lmb_region *_rgn = &(lmb->memory); + struct alist *lmb_rgn_lst = &lmb.free_mem; - return lmb_add_region(_rgn, base, size); + return lmb_add_region(lmb_rgn_lst, base, size); } -long lmb_free(struct lmb *lmb, phys_addr_t base, phys_size_t size) +long lmb_free(phys_addr_t base, phys_size_t size) { - struct lmb_region *rgn = &(lmb->reserved); + struct lmb_region *rgn; + struct alist *lmb_rgn_lst = &lmb.used_mem; phys_addr_t rgnbegin, rgnend; phys_addr_t end = base + size - 1; int i; rgnbegin = rgnend = 0; /* supress gcc warnings */ - + rgn = lmb_rgn_lst->data; /* Find the region where (base, size) belongs to */ - for (i = 0; i < rgn->cnt; i++) { - rgnbegin = rgn->region[i].base; - rgnend = rgnbegin + rgn->region[i].size - 1; + for (i = 0; i < lmb_rgn_lst->count; i++) { + rgnbegin = rgn[i].base; + rgnend = rgnbegin + rgn[i].size - 1; if ((rgnbegin <= base) && (end <= rgnend)) break; } /* Didn't find the region */ - if (i == rgn->cnt) + if (i == lmb_rgn_lst->count) return -1; /* Check to see if we are removing entire region */ if ((rgnbegin == base) && (rgnend == end)) { - lmb_remove_region(rgn, i); + lmb_remove_region(lmb_rgn_lst, i); return 0; } /* Check to see if region is matching at the front */ if (rgnbegin == base) { - rgn->region[i].base = end + 1; - rgn->region[i].size -= size; + rgn[i].base = end + 1; + rgn[i].size -= size; return 0; } /* Check to see if the region is matching at the end */ if (rgnend == end) { - rgn->region[i].size -= size; + rgn[i].size -= size; return 0; } @@ -402,55 +525,37 @@ long lmb_free(struct lmb *lmb, phys_addr_t base, phys_size_t size) * We need to split the entry - adjust the current one to the * beginging of the hole and add the region after hole. */ - rgn->region[i].size = base - rgn->region[i].base; - return lmb_add_region_flags(rgn, end + 1, rgnend - end, - rgn->region[i].flags); + rgn[i].size = base - rgn[i].base; + return lmb_add_region_flags(lmb_rgn_lst, end + 1, rgnend - end, + rgn[i].flags); } -long lmb_reserve_flags(struct lmb *lmb, phys_addr_t base, phys_size_t size, - enum lmb_flags flags) +long lmb_reserve_flags(phys_addr_t base, phys_size_t size, enum lmb_flags flags) { - struct lmb_region *_rgn = &(lmb->reserved); + struct alist *lmb_rgn_lst = &lmb.used_mem; - return lmb_add_region_flags(_rgn, base, size, flags); + return lmb_add_region_flags(lmb_rgn_lst, base, size, flags); } -long lmb_reserve(struct lmb *lmb, phys_addr_t base, phys_size_t size) +long lmb_reserve(phys_addr_t base, phys_size_t size) { - return lmb_reserve_flags(lmb, base, size, LMB_NONE); + return lmb_reserve_flags(base, size, LMB_NONE); } -static long lmb_overlaps_region(struct lmb_region *rgn, phys_addr_t base, +static long lmb_overlaps_region(struct alist *lmb_rgn_lst, phys_addr_t base, phys_size_t size) { unsigned long i; + struct lmb_region *rgn = lmb_rgn_lst->data; - for (i = 0; i < rgn->cnt; i++) { - phys_addr_t rgnbase = rgn->region[i].base; - phys_size_t rgnsize = rgn->region[i].size; + for (i = 0; i < lmb_rgn_lst->count; i++) { + phys_addr_t rgnbase = rgn[i].base; + phys_size_t rgnsize = rgn[i].size; if (lmb_addrs_overlap(base, size, rgnbase, rgnsize)) break; } - return (i < rgn->cnt) ? i : -1; -} - -phys_addr_t lmb_alloc(struct lmb *lmb, phys_size_t size, ulong align) -{ - return lmb_alloc_base(lmb, size, align, LMB_ALLOC_ANYWHERE); -} - -phys_addr_t lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phys_addr_t max_addr) -{ - phys_addr_t alloc; - - alloc = __lmb_alloc_base(lmb, size, align, max_addr); - - if (alloc == 0) - printf("ERROR: Failed to allocate 0x%lx bytes below 0x%lx.\n", - (ulong)size, (ulong)max_addr); - - return alloc; + return (i < lmb_rgn_lst->count) ? i : -1; } static phys_addr_t lmb_align_down(phys_addr_t addr, phys_size_t size) @@ -458,15 +563,18 @@ static phys_addr_t lmb_align_down(phys_addr_t addr, phys_size_t size) return addr & ~(size - 1); } -phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phys_addr_t max_addr) +static phys_addr_t __lmb_alloc_base(phys_size_t size, ulong align, + phys_addr_t max_addr, enum lmb_flags flags) { long i, rgn; phys_addr_t base = 0; phys_addr_t res_base; + struct lmb_region *lmb_used = lmb.used_mem.data; + struct lmb_region *lmb_memory = lmb.free_mem.data; - for (i = lmb->memory.cnt - 1; i >= 0; i--) { - phys_addr_t lmbbase = lmb->memory.region[i].base; - phys_size_t lmbsize = lmb->memory.region[i].size; + for (i = lmb.free_mem.count - 1; i >= 0; i--) { + phys_addr_t lmbbase = lmb_memory[i].base; + phys_size_t lmbsize = lmb_memory[i].size; if (lmbsize < size) continue; @@ -482,15 +590,16 @@ phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phy continue; while (base && lmbbase <= base) { - rgn = lmb_overlaps_region(&lmb->reserved, base, size); + rgn = lmb_overlaps_region(&lmb.used_mem, base, size); if (rgn < 0) { /* This area isn't reserved, take it */ - if (lmb_add_region(&lmb->reserved, base, - size) < 0) + if (lmb_add_region_flags(&lmb.used_mem, base, + size, flags) < 0) return 0; return base; } - res_base = lmb->reserved.region[rgn].base; + + res_base = lmb_used[rgn].base; if (res_base < size) break; base = lmb_align_down(res_base - size, align); @@ -499,83 +608,177 @@ phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phy return 0; } -/* - * Try to allocate a specific address range: must be in defined memory but not - * reserved - */ -phys_addr_t lmb_alloc_addr(struct lmb *lmb, phys_addr_t base, phys_size_t size) +phys_addr_t lmb_alloc(phys_size_t size, ulong align) +{ + return lmb_alloc_base(size, align, LMB_ALLOC_ANYWHERE); +} + +phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr) +{ + phys_addr_t alloc; + + alloc = __lmb_alloc_base(size, align, max_addr, LMB_NONE); + + if (alloc == 0) + printf("ERROR: Failed to allocate 0x%lx bytes below 0x%lx.\n", + (ulong)size, (ulong)max_addr); + + return alloc; +} + +static phys_addr_t __lmb_alloc_addr(phys_addr_t base, phys_size_t size, + enum lmb_flags flags) { long rgn; + struct lmb_region *lmb_memory = lmb.free_mem.data; /* Check if the requested address is in one of the memory regions */ - rgn = lmb_overlaps_region(&lmb->memory, base, size); + rgn = lmb_overlaps_region(&lmb.free_mem, base, size); if (rgn >= 0) { /* * Check if the requested end address is in the same memory * region we found. */ - if (lmb_addrs_overlap(lmb->memory.region[rgn].base, - lmb->memory.region[rgn].size, + if (lmb_addrs_overlap(lmb_memory[rgn].base, + lmb_memory[rgn].size, base + size - 1, 1)) { /* ok, reserve the memory */ - if (lmb_reserve(lmb, base, size) >= 0) + if (lmb_reserve_flags(base, size, flags) >= 0) return base; } } + return 0; } +/* + * Try to allocate a specific address range: must be in defined memory but not + * reserved + */ +phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) +{ + return __lmb_alloc_addr(base, size, LMB_NONE); +} + /* Return number of bytes from a given address that are free */ -phys_size_t lmb_get_free_size(struct lmb *lmb, phys_addr_t addr) +phys_size_t lmb_get_free_size(phys_addr_t addr) { int i; long rgn; + struct lmb_region *lmb_used = lmb.used_mem.data; + struct lmb_region *lmb_memory = lmb.free_mem.data; /* check if the requested address is in the memory regions */ - rgn = lmb_overlaps_region(&lmb->memory, addr, 1); + rgn = lmb_overlaps_region(&lmb.free_mem, addr, 1); if (rgn >= 0) { - for (i = 0; i < lmb->reserved.cnt; i++) { - if (addr < lmb->reserved.region[i].base) { + for (i = 0; i < lmb.used_mem.count; i++) { + if (addr < lmb_used[i].base) { /* first reserved range > requested address */ - return lmb->reserved.region[i].base - addr; + return lmb_used[i].base - addr; } - if (lmb->reserved.region[i].base + - lmb->reserved.region[i].size > addr) { + if (lmb_used[i].base + + lmb_used[i].size > addr) { /* requested addr is in this reserved range */ return 0; } } /* if we come here: no reserved ranges above requested addr */ - return lmb->memory.region[lmb->memory.cnt - 1].base + - lmb->memory.region[lmb->memory.cnt - 1].size - addr; + return lmb_memory[lmb.free_mem.count - 1].base + + lmb_memory[lmb.free_mem.count - 1].size - addr; } return 0; } -int lmb_is_reserved_flags(struct lmb *lmb, phys_addr_t addr, int flags) +int lmb_is_reserved_flags(phys_addr_t addr, int flags) { int i; + struct lmb_region *lmb_used = lmb.used_mem.data; - for (i = 0; i < lmb->reserved.cnt; i++) { - phys_addr_t upper = lmb->reserved.region[i].base + - lmb->reserved.region[i].size - 1; - if ((addr >= lmb->reserved.region[i].base) && (addr <= upper)) - return (lmb->reserved.region[i].flags & flags) == flags; + for (i = 0; i < lmb.used_mem.count; i++) { + phys_addr_t upper = lmb_used[i].base + + lmb_used[i].size - 1; + if (addr >= lmb_used[i].base && addr <= upper) + return (lmb_used[i].flags & flags) == flags; } return 0; } -int lmb_is_reserved(struct lmb *lmb, phys_addr_t addr) +static int lmb_setup(void) { - return lmb_is_reserved_flags(lmb, addr, LMB_NONE); + bool ret; + + ret = alist_init(&lmb.free_mem, sizeof(struct lmb_region), + (uint)LMB_ALIST_INITIAL_SIZE); + if (!ret) { + log_debug("Unable to initialise the list for LMB free memory\n"); + return -ENOMEM; + } + + ret = alist_init(&lmb.used_mem, sizeof(struct lmb_region), + (uint)LMB_ALIST_INITIAL_SIZE); + if (!ret) { + log_debug("Unable to initialise the list for LMB used memory\n"); + return -ENOMEM; + } + + return 0; } -__weak void board_lmb_reserve(struct lmb *lmb) +/** + * lmb_init() - Initialise the LMB module + * + * Initialise the LMB lists needed for keeping the memory map. There + * are two lists, in form of alloced list data structure. One for the + * available memory, and one for the used memory. Initialise the two + * lists as part of board init. Add memory to the available memory + * list and reserve common areas by adding them to the used memory + * list. + * + * Return: 0 on success, -ve on error + */ +int lmb_init(void) { - /* please define platform specific board_lmb_reserve() */ + int ret; + + ret = lmb_setup(); + if (ret) { + log_info("Unable to init LMB\n"); + return ret; + } + + lmb_add_memory(); + + /* Reserve the U-Boot image region once U-Boot has relocated */ + if (spl_phase() == PHASE_SPL) + lmb_reserve_common_spl(); + else if (spl_phase() == PHASE_BOARD_R) + lmb_reserve_common((void *)gd->fdt_blob); + + return 0; +} + +#if CONFIG_IS_ENABLED(UNIT_TEST) +struct lmb *lmb_get(void) +{ + return &lmb; +} + +int lmb_push(struct lmb *store) +{ + int ret; + + *store = lmb; + ret = lmb_setup(); + if (ret) + return ret; + + return 0; } -__weak void arch_lmb_reserve(struct lmb *lmb) +void lmb_pop(struct lmb *store) { - /* please define platform specific arch_lmb_reserve() */ + alist_uninit(&lmb.free_mem); + alist_uninit(&lmb.used_mem); + lmb = *store; } +#endif /* UNIT_TEST */ diff --git a/lib/lz4.c b/lib/lz4.c index d365dc727cf..63955a0b178 100644 --- a/lib/lz4.c +++ b/lib/lz4.c @@ -71,7 +71,6 @@ static void LZ4_wildCopy(void* dstPtr, const void* srcPtr, void* dstEnd) do { LZ4_copy8(d,s); d+=8; s+=8; } while (d<e); } - /************************************** * Common Constants **************************************/ diff --git a/lib/lzma/LzmaDec.c b/lib/lzma/LzmaDec.c index 1da3f0a14a7..954380af52a 100644 --- a/lib/lzma/LzmaDec.c +++ b/lib/lzma/LzmaDec.c @@ -58,7 +58,6 @@ #define TREE_DECODE_CHECK(probs, limit, i) \ { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; } - #define kNumPosBitsMax 4 #define kNumPosStatesMax (1 << kNumPosBitsMax) @@ -76,7 +75,6 @@ #define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) #define kNumLenProbs (LenHigh + kLenNumHighSymbols) - #define kNumStates 12 #define kNumLitStates 7 @@ -689,7 +687,6 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS return res; } - static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data) { p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]); diff --git a/lib/lzma/LzmaDec.h b/lib/lzma/LzmaDec.h index 63aa505e8ca..14b247b802b 100644 --- a/lib/lzma/LzmaDec.h +++ b/lib/lzma/LzmaDec.h @@ -16,7 +16,6 @@ #define CLzmaProb UInt16 #endif - /* ---------- LZMA Properties ---------- */ #define LZMA_PROPS_SIZE 5 @@ -35,7 +34,6 @@ Returns: SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); - /* ---------- LZMA Decoder state ---------- */ /* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case. @@ -104,7 +102,6 @@ typedef enum /* ELzmaStatus is used only as output value for function call */ - /* ---------- Interfaces ---------- */ /* There are 3 levels of interfaces: @@ -114,7 +111,6 @@ typedef enum You can select any of these interfaces, but don't mix functions from different groups for same object. */ - /* There are two variants to allocate state for Dictionary Interface: 1) LzmaDec_Allocate / LzmaDec_Free 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs @@ -177,7 +173,6 @@ Returns: SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); - /* ---------- Buffer Interface ---------- */ /* It's zlib-like interface. @@ -194,7 +189,6 @@ finishMode: SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); - /* ---------- One Call Interface ---------- */ /* LzmaDecode diff --git a/lib/lzma/Types.h b/lib/lzma/Types.h index 04f894a8ca9..6f7e735c1f6 100644 --- a/lib/lzma/Types.h +++ b/lib/lzma/Types.h @@ -84,7 +84,6 @@ typedef int Bool; #define True 1 #define False 0 - #ifdef _MSC_VER #if _MSC_VER >= 1300 @@ -103,7 +102,6 @@ typedef int Bool; #endif - /* The following interfaces use first parameter as pointer to structure */ typedef struct diff --git a/lib/lzo/lzo1x_decompress.c b/lib/lzo/lzo1x_decompress.c index 5d70fa41337..03027e5dc3b 100644 --- a/lib/lzo/lzo1x_decompress.c +++ b/lib/lzo/lzo1x_decompress.c @@ -31,7 +31,6 @@ static const unsigned char lzop_magic[] = { #define HEADER_HAS_FILTER 0x00000800L - bool lzop_is_valid_header(const unsigned char *src) { int i; diff --git a/lib/md5.c b/lib/md5.c index faf3f78ab1e..584463d55ca 100644 --- a/lib/md5.c +++ b/lib/md5.c @@ -55,7 +55,7 @@ byteReverse(unsigned char *buf, unsigned longs) * initialization constants. */ void -MD5Init(struct MD5Context *ctx) +MD5Init(MD5Context *ctx) { ctx->buf[0] = 0x67452301; ctx->buf[1] = 0xefcdab89; @@ -71,7 +71,7 @@ MD5Init(struct MD5Context *ctx) * of bytes. */ void -MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len) +MD5Update(MD5Context *ctx, unsigned char const *buf, unsigned int len) { register __u32 t; @@ -120,7 +120,7 @@ MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len) * 1 0* (64-bit count of bits processed, MSB-first) */ void -MD5Final(unsigned char digest[16], struct MD5Context *ctx) +MD5Final(unsigned char digest[16], MD5Context *ctx) { unsigned int count; unsigned char *p; @@ -269,14 +269,13 @@ MD5Transform(__u32 buf[4], __u32 const in[16]) void md5 (unsigned char *input, int len, unsigned char output[16]) { - struct MD5Context context; + MD5Context context; MD5Init(&context); MD5Update(&context, input, len); MD5Final(output, &context); } - /* * Calculate and store in 'output' the MD5 digest of 'len' bytes at 'input'. * 'output' must have enough space to hold 16 bytes. If 'chunk' Trigger the @@ -286,7 +285,7 @@ void md5_wd(const unsigned char *input, unsigned int len, unsigned char output[16], unsigned int chunk_sz) { - struct MD5Context context; + MD5Context context; #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) const unsigned char *end, *curr; int chunk; diff --git a/lib/smbios.c b/lib/smbios.c index b190b010f30..7c24ea129eb 100644 --- a/lib/smbios.c +++ b/lib/smbios.c @@ -5,6 +5,8 @@ * Adapted from coreboot src/arch/x86/smbios.c */ +#define LOG_CATEGORY LOGC_BOARD + #include <dm.h> #include <env.h> #include <linux/stringify.h> @@ -20,6 +22,7 @@ #include <cpu.h> #include <dm/uclass-internal.h> #endif +#include <linux/sizes.h> /* Safeguard for checking that U_BOOT_VERSION_NUM macros are compatible with U_BOOT_DMI */ #if U_BOOT_VERSION_NUM < 2000 || U_BOOT_VERSION_NUM > 2099 || \ @@ -346,7 +349,13 @@ static int smbios_write_type0(ulong *current, int handle, #endif t->bios_release_date = smbios_add_prop(ctx, NULL, U_BOOT_DMI_DATE); #ifdef CONFIG_ROM_SIZE - t->bios_rom_size = (CONFIG_ROM_SIZE / 65536) - 1; + if (CONFIG_ROM_SIZE < SZ_16M) { + t->bios_rom_size = (CONFIG_ROM_SIZE / 65536) - 1; + } else { + /* CONFIG_ROM_SIZE < 8 GiB */ + t->bios_rom_size = 0xff; + t->extended_bios_rom_size = CONFIG_ROM_SIZE >> 20; + } #endif t->bios_characteristics = BIOS_CHARACTERISTICS_PCI_SUPPORTED | BIOS_CHARACTERISTICS_SELECTABLE_BOOT | @@ -383,8 +392,12 @@ static int smbios_write_type1(ulong *current, int handle, memset(t, 0, sizeof(struct smbios_type1)); fill_smbios_header(t, SMBIOS_SYSTEM_INFORMATION, len, handle); smbios_set_eos(ctx, t->eos); - t->manufacturer = smbios_add_prop(ctx, "manufacturer", NULL); - t->product_name = smbios_add_prop(ctx, "product", NULL); + t->manufacturer = smbios_add_prop_si(ctx, "manufacturer", + SYSINFO_ID_SMBIOS_SYSTEM_MANUFACTURER, + NULL); + t->product_name = smbios_add_prop_si(ctx, "product", + SYSINFO_ID_SMBIOS_SYSTEM_PRODUCT, + NULL); t->version = smbios_add_prop_si(ctx, "version", SYSINFO_ID_SMBIOS_SYSTEM_VERSION, NULL); @@ -392,11 +405,15 @@ static int smbios_write_type1(ulong *current, int handle, t->serial_number = smbios_add_prop(ctx, NULL, serial_str); strncpy((char *)t->uuid, serial_str, sizeof(t->uuid)); } else { - t->serial_number = smbios_add_prop(ctx, "serial", NULL); + t->serial_number = smbios_add_prop_si(ctx, "serial", + SYSINFO_ID_SMBIOS_SYSTEM_SERIAL, + NULL); } t->wakeup_type = SMBIOS_WAKEUP_TYPE_UNKNOWN; - t->sku_number = smbios_add_prop(ctx, "sku", NULL); - t->family = smbios_add_prop(ctx, "family", NULL); + t->sku_number = smbios_add_prop_si(ctx, "sku", + SYSINFO_ID_SMBIOS_SYSTEM_SKU, NULL); + t->family = smbios_add_prop_si(ctx, "family", + SYSINFO_ID_SMBIOS_SYSTEM_FAMILY, NULL); len = t->length + smbios_string_table_len(ctx); *current += len; @@ -415,12 +432,22 @@ static int smbios_write_type2(ulong *current, int handle, memset(t, 0, sizeof(struct smbios_type2)); fill_smbios_header(t, SMBIOS_BOARD_INFORMATION, len, handle); smbios_set_eos(ctx, t->eos); - t->manufacturer = smbios_add_prop(ctx, "manufacturer", NULL); - t->product_name = smbios_add_prop(ctx, "product", NULL); + t->manufacturer = smbios_add_prop_si(ctx, "manufacturer", + SYSINFO_ID_SMBIOS_BASEBOARD_MANUFACTURER, + NULL); + t->product_name = smbios_add_prop_si(ctx, "product", + SYSINFO_ID_SMBIOS_BASEBOARD_PRODUCT, + NULL); t->version = smbios_add_prop_si(ctx, "version", SYSINFO_ID_SMBIOS_BASEBOARD_VERSION, NULL); - t->asset_tag_number = smbios_add_prop(ctx, "asset-tag", NULL); + + t->serial_number = smbios_add_prop_si(ctx, "serial", + SYSINFO_ID_SMBIOS_BASEBOARD_SERIAL, + NULL); + t->asset_tag_number = smbios_add_prop_si(ctx, "asset-tag", + SYSINFO_ID_SMBIOS_BASEBOARD_ASSET_TAG, + NULL); t->feature_flags = SMBIOS_BOARD_FEATURE_HOSTING; t->board_type = SMBIOS_BOARD_MOTHERBOARD; t->chassis_handle = handle + 1; @@ -571,10 +598,20 @@ ulong write_smbios_table(ulong addr) int i; ctx.node = ofnode_null(); - if (IS_ENABLED(CONFIG_OF_CONTROL)) { + if (IS_ENABLED(CONFIG_OF_CONTROL) && CONFIG_IS_ENABLED(SYSINFO)) { uclass_first_device(UCLASS_SYSINFO, &ctx.dev); - if (ctx.dev) + if (ctx.dev) { + int ret; + parent_node = dev_read_subnode(ctx.dev, "smbios"); + ret = sysinfo_detect(ctx.dev); + + /* + * ignore the error since many boards don't implement + * this and we can still use the info in the devicetree + */ + ret = log_msg_ret("sys", ret); + } } else { ctx.dev = NULL; } diff --git a/lib/string.c b/lib/string.c index f2c61471288..feae9519f2f 100644 --- a/lib/string.c +++ b/lib/string.c @@ -22,7 +22,6 @@ #include <linux/ctype.h> #include <malloc.h> - /** * strncasecmp - Case insensitive, length-limited string comparison * @s1: One string diff --git a/lib/strto.c b/lib/strto.c index 5157332d6c1..f83ac67c666 100644 --- a/lib/strto.c +++ b/lib/strto.c @@ -236,12 +236,14 @@ const char **str_to_list(const char *instr) return NULL; /* count the number of space-separated strings */ - for (count = *str != '\0', p = str; *p; p++) { + for (count = 0, p = str; *p; p++) { if (*p == ' ') { count++; *p = '\0'; } } + if (p != str && p[-1]) + count++; /* allocate the pointer array, allowing for a NULL terminator */ ptr = calloc(count + 1, sizeof(char *)); diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c index 68eaaa639f8..59e6cbafafa 100644 --- a/lib/tpm-v2.c +++ b/lib/tpm-v2.c @@ -10,6 +10,7 @@ #include <tpm_api.h> #include <tpm-common.h> #include <tpm-v2.h> +#include <tpm_tcg2.h> #include <u-boot/sha1.h> #include <u-boot/sha256.h> #include <u-boot/sha512.h> @@ -22,683 +23,6 @@ #include "tpm-utils.h" -const enum tpm2_algorithms tpm2_supported_algorithms[4] = { - TPM2_ALG_SHA1, - TPM2_ALG_SHA256, - TPM2_ALG_SHA384, - TPM2_ALG_SHA512, -}; - -int tcg2_get_active_pcr_banks(struct udevice *dev, u32 *active_pcr_banks) -{ - u32 supported = 0; - u32 pcr_banks = 0; - u32 active = 0; - int rc; - - rc = tpm2_get_pcr_info(dev, &supported, &active, &pcr_banks); - if (rc) - return rc; - - *active_pcr_banks = active; - - return 0; -} - -u32 tcg2_event_get_size(struct tpml_digest_values *digest_list) -{ - u32 len; - size_t i; - - len = offsetof(struct tcg_pcr_event2, digests); - len += offsetof(struct tpml_digest_values, digests); - for (i = 0; i < digest_list->count; ++i) { - u16 l = tpm2_algorithm_to_len(digest_list->digests[i].hash_alg); - - if (!l) - continue; - - len += l + offsetof(struct tpmt_ha, digest); - } - len += sizeof(u32); - - return len; -} - -int tcg2_create_digest(struct udevice *dev, const u8 *input, u32 length, - struct tpml_digest_values *digest_list) -{ - u8 final[sizeof(union tpmu_ha)]; - sha256_context ctx_256; - sha512_context ctx_512; - sha1_context ctx; - u32 active; - size_t i; - u32 len; - int rc; - - rc = tcg2_get_active_pcr_banks(dev, &active); - if (rc) - return rc; - - digest_list->count = 0; - for (i = 0; i < ARRAY_SIZE(tpm2_supported_algorithms); ++i) { - u32 mask = - tpm2_algorithm_to_mask(tpm2_supported_algorithms[i]); - - if (!(active & mask)) - continue; - - switch (tpm2_supported_algorithms[i]) { - case TPM2_ALG_SHA1: - sha1_starts(&ctx); - sha1_update(&ctx, input, length); - sha1_finish(&ctx, final); - len = TPM2_SHA1_DIGEST_SIZE; - break; - case TPM2_ALG_SHA256: - sha256_starts(&ctx_256); - sha256_update(&ctx_256, input, length); - sha256_finish(&ctx_256, final); - len = TPM2_SHA256_DIGEST_SIZE; - break; - case TPM2_ALG_SHA384: - sha384_starts(&ctx_512); - sha384_update(&ctx_512, input, length); - sha384_finish(&ctx_512, final); - len = TPM2_SHA384_DIGEST_SIZE; - break; - case TPM2_ALG_SHA512: - sha512_starts(&ctx_512); - sha512_update(&ctx_512, input, length); - sha512_finish(&ctx_512, final); - len = TPM2_SHA512_DIGEST_SIZE; - break; - default: - printf("%s: unsupported algorithm %x\n", __func__, - tpm2_supported_algorithms[i]); - continue; - } - - digest_list->digests[digest_list->count].hash_alg = - tpm2_supported_algorithms[i]; - memcpy(&digest_list->digests[digest_list->count].digest, final, - len); - digest_list->count++; - } - - return 0; -} - -void tcg2_log_append(u32 pcr_index, u32 event_type, - struct tpml_digest_values *digest_list, u32 size, - const u8 *event, u8 *log) -{ - size_t len; - size_t pos; - u32 i; - - pos = offsetof(struct tcg_pcr_event2, pcr_index); - put_unaligned_le32(pcr_index, log); - pos = offsetof(struct tcg_pcr_event2, event_type); - put_unaligned_le32(event_type, log + pos); - pos = offsetof(struct tcg_pcr_event2, digests) + - offsetof(struct tpml_digest_values, count); - put_unaligned_le32(digest_list->count, log + pos); - - pos = offsetof(struct tcg_pcr_event2, digests) + - offsetof(struct tpml_digest_values, digests); - for (i = 0; i < digest_list->count; ++i) { - u16 hash_alg = digest_list->digests[i].hash_alg; - - len = tpm2_algorithm_to_len(hash_alg); - if (!len) - continue; - - pos += offsetof(struct tpmt_ha, hash_alg); - put_unaligned_le16(hash_alg, log + pos); - pos += offsetof(struct tpmt_ha, digest); - memcpy(log + pos, (u8 *)&digest_list->digests[i].digest, len); - pos += len; - } - - put_unaligned_le32(size, log + pos); - pos += sizeof(u32); - memcpy(log + pos, event, size); -} - -static int tcg2_log_append_check(struct tcg2_event_log *elog, u32 pcr_index, - u32 event_type, - struct tpml_digest_values *digest_list, - u32 size, const u8 *event) -{ - u32 event_size; - u8 *log; - - event_size = size + tcg2_event_get_size(digest_list); - if (elog->log_position + event_size > elog->log_size) { - printf("%s: log too large: %u + %u > %u\n", __func__, - elog->log_position, event_size, elog->log_size); - return -ENOBUFS; - } - - log = elog->log + elog->log_position; - elog->log_position += event_size; - - tcg2_log_append(pcr_index, event_type, digest_list, size, event, log); - - return 0; -} - -static int tcg2_log_init(struct udevice *dev, struct tcg2_event_log *elog) -{ - struct tcg_efi_spec_id_event *ev; - struct tcg_pcr_event *log; - u32 event_size; - u32 count = 0; - u32 log_size; - u32 active; - u32 mask; - size_t i; - u16 len; - int rc; - - rc = tcg2_get_active_pcr_banks(dev, &active); - if (rc) - return rc; - - event_size = offsetof(struct tcg_efi_spec_id_event, digest_sizes); - for (i = 0; i < ARRAY_SIZE(tpm2_supported_algorithms); ++i) { - mask = tpm2_algorithm_to_mask(tpm2_supported_algorithms[i]); - - if (!(active & mask)) - continue; - - switch (tpm2_supported_algorithms[i]) { - case TPM2_ALG_SHA1: - case TPM2_ALG_SHA256: - case TPM2_ALG_SHA384: - case TPM2_ALG_SHA512: - count++; - break; - default: - continue; - } - } - - event_size += 1 + - (sizeof(struct tcg_efi_spec_id_event_algorithm_size) * count); - log_size = offsetof(struct tcg_pcr_event, event) + event_size; - - if (log_size > elog->log_size) { - printf("%s: log too large: %u > %u\n", __func__, log_size, - elog->log_size); - return -ENOBUFS; - } - - log = (struct tcg_pcr_event *)elog->log; - put_unaligned_le32(0, &log->pcr_index); - put_unaligned_le32(EV_NO_ACTION, &log->event_type); - memset(&log->digest, 0, sizeof(log->digest)); - put_unaligned_le32(event_size, &log->event_size); - - ev = (struct tcg_efi_spec_id_event *)log->event; - strlcpy((char *)ev->signature, TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03, - sizeof(ev->signature)); - put_unaligned_le32(0, &ev->platform_class); - ev->spec_version_minor = TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2; - ev->spec_version_major = TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2; - ev->spec_errata = TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_ERRATA_TPM2; - ev->uintn_size = sizeof(size_t) / sizeof(u32); - put_unaligned_le32(count, &ev->number_of_algorithms); - - count = 0; - for (i = 0; i < ARRAY_SIZE(tpm2_supported_algorithms); ++i) { - mask = tpm2_algorithm_to_mask(tpm2_supported_algorithms[i]); - - if (!(active & mask)) - continue; - - len = tpm2_algorithm_to_len(tpm2_supported_algorithms[i]); - if (!len) - continue; - - put_unaligned_le16(tpm2_supported_algorithms[i], - &ev->digest_sizes[count].algorithm_id); - put_unaligned_le16(len, &ev->digest_sizes[count].digest_size); - count++; - } - - *((u8 *)ev + (event_size - 1)) = 0; - elog->log_position = log_size; - - return 0; -} - -static int tcg2_replay_eventlog(struct tcg2_event_log *elog, - struct udevice *dev, - struct tpml_digest_values *digest_list, - u32 log_position) -{ - const u32 offset = offsetof(struct tcg_pcr_event2, digests) + - offsetof(struct tpml_digest_values, digests); - u32 event_size; - u32 count; - u16 algo; - u32 pcr; - u32 pos; - u16 len; - u8 *log; - int rc; - u32 i; - - while (log_position + offset < elog->log_size) { - log = elog->log + log_position; - - pos = offsetof(struct tcg_pcr_event2, pcr_index); - pcr = get_unaligned_le32(log + pos); - pos = offsetof(struct tcg_pcr_event2, event_type); - if (!get_unaligned_le32(log + pos)) - return 0; - - pos = offsetof(struct tcg_pcr_event2, digests) + - offsetof(struct tpml_digest_values, count); - count = get_unaligned_le32(log + pos); - if (count > ARRAY_SIZE(tpm2_supported_algorithms) || - (digest_list->count && digest_list->count != count)) - return 0; - - pos = offsetof(struct tcg_pcr_event2, digests) + - offsetof(struct tpml_digest_values, digests); - for (i = 0; i < count; ++i) { - pos += offsetof(struct tpmt_ha, hash_alg); - if (log_position + pos + sizeof(u16) >= elog->log_size) - return 0; - - algo = get_unaligned_le16(log + pos); - pos += offsetof(struct tpmt_ha, digest); - switch (algo) { - case TPM2_ALG_SHA1: - case TPM2_ALG_SHA256: - case TPM2_ALG_SHA384: - case TPM2_ALG_SHA512: - len = tpm2_algorithm_to_len(algo); - break; - default: - return 0; - } - - if (digest_list->count) { - if (algo != digest_list->digests[i].hash_alg || - log_position + pos + len >= elog->log_size) - return 0; - - memcpy(digest_list->digests[i].digest.sha512, - log + pos, len); - } - - pos += len; - } - - if (log_position + pos + sizeof(u32) >= elog->log_size) - return 0; - - event_size = get_unaligned_le32(log + pos); - pos += event_size + sizeof(u32); - if (log_position + pos > elog->log_size) - return 0; - - if (digest_list->count) { - rc = tcg2_pcr_extend(dev, pcr, digest_list); - if (rc) - return rc; - } - - log_position += pos; - } - - elog->log_position = log_position; - elog->found = true; - return 0; -} - -static int tcg2_log_parse(struct udevice *dev, struct tcg2_event_log *elog) -{ - struct tpml_digest_values digest_list; - struct tcg_efi_spec_id_event *event; - struct tcg_pcr_event *log; - u32 log_active; - u32 calc_size; - u32 active; - u32 count; - u32 evsz; - u32 mask; - u16 algo; - u16 len; - int rc; - u32 i; - u16 j; - - if (elog->log_size <= offsetof(struct tcg_pcr_event, event)) - return 0; - - log = (struct tcg_pcr_event *)elog->log; - if (get_unaligned_le32(&log->pcr_index) != 0 || - get_unaligned_le32(&log->event_type) != EV_NO_ACTION) - return 0; - - for (i = 0; i < sizeof(log->digest); i++) { - if (log->digest[i]) - return 0; - } - - evsz = get_unaligned_le32(&log->event_size); - if (evsz < offsetof(struct tcg_efi_spec_id_event, digest_sizes) || - evsz + offsetof(struct tcg_pcr_event, event) > elog->log_size) - return 0; - - event = (struct tcg_efi_spec_id_event *)log->event; - if (memcmp(event->signature, TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03, - sizeof(TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03))) - return 0; - - if (event->spec_version_minor != TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2 || - event->spec_version_major != TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2) - return 0; - - count = get_unaligned_le32(&event->number_of_algorithms); - if (count > ARRAY_SIZE(tpm2_supported_algorithms)) - return 0; - - calc_size = offsetof(struct tcg_efi_spec_id_event, digest_sizes) + - (sizeof(struct tcg_efi_spec_id_event_algorithm_size) * count) + - 1; - if (evsz != calc_size) - return 0; - - rc = tcg2_get_active_pcr_banks(dev, &active); - if (rc) - return rc; - - digest_list.count = 0; - log_active = 0; - - for (i = 0; i < count; ++i) { - algo = get_unaligned_le16(&event->digest_sizes[i].algorithm_id); - mask = tpm2_algorithm_to_mask(algo); - - if (!(active & mask)) - return 0; - - switch (algo) { - case TPM2_ALG_SHA1: - case TPM2_ALG_SHA256: - case TPM2_ALG_SHA384: - case TPM2_ALG_SHA512: - len = get_unaligned_le16(&event->digest_sizes[i].digest_size); - if (tpm2_algorithm_to_len(algo) != len) - return 0; - digest_list.digests[digest_list.count++].hash_alg = algo; - break; - default: - return 0; - } - - log_active |= mask; - } - - /* Ensure the previous firmware extended all the PCRs. */ - if (log_active != active) - return 0; - - /* Read PCR0 to check if previous firmware extended the PCRs or not. */ - rc = tcg2_pcr_read(dev, 0, &digest_list); - if (rc) - return rc; - - for (i = 0; i < digest_list.count; ++i) { - len = tpm2_algorithm_to_len(digest_list.digests[i].hash_alg); - for (j = 0; j < len; ++j) { - if (digest_list.digests[i].digest.sha512[j]) - break; - } - - /* PCR is non-zero; it has been extended, so skip extending. */ - if (j != len) { - digest_list.count = 0; - break; - } - } - - return tcg2_replay_eventlog(elog, dev, &digest_list, - offsetof(struct tcg_pcr_event, event) + - evsz); -} - -int tcg2_pcr_extend(struct udevice *dev, u32 pcr_index, - struct tpml_digest_values *digest_list) -{ - u32 rc; - u32 i; - - for (i = 0; i < digest_list->count; i++) { - u32 alg = digest_list->digests[i].hash_alg; - - rc = tpm2_pcr_extend(dev, pcr_index, alg, - (u8 *)&digest_list->digests[i].digest, - tpm2_algorithm_to_len(alg)); - if (rc) { - printf("%s: error pcr:%u alg:%08x\n", __func__, - pcr_index, alg); - return rc; - } - } - - return 0; -} - -int tcg2_pcr_read(struct udevice *dev, u32 pcr_index, - struct tpml_digest_values *digest_list) -{ - struct tpm_chip_priv *priv; - u32 rc; - u32 i; - - priv = dev_get_uclass_priv(dev); - if (!priv) - return -ENODEV; - - for (i = 0; i < digest_list->count; i++) { - u32 alg = digest_list->digests[i].hash_alg; - u8 *digest = (u8 *)&digest_list->digests[i].digest; - - rc = tpm2_pcr_read(dev, pcr_index, priv->pcr_select_min, alg, - digest, tpm2_algorithm_to_len(alg), NULL); - if (rc) { - printf("%s: error pcr:%u alg:%08x\n", __func__, - pcr_index, alg); - return rc; - } - } - - return 0; -} - -int tcg2_measure_data(struct udevice *dev, struct tcg2_event_log *elog, - u32 pcr_index, u32 size, const u8 *data, u32 event_type, - u32 event_size, const u8 *event) -{ - struct tpml_digest_values digest_list; - int rc; - - if (data) - rc = tcg2_create_digest(dev, data, size, &digest_list); - else - rc = tcg2_create_digest(dev, event, event_size, &digest_list); - if (rc) - return rc; - - rc = tcg2_pcr_extend(dev, pcr_index, &digest_list); - if (rc) - return rc; - - return tcg2_log_append_check(elog, pcr_index, event_type, &digest_list, - event_size, event); -} - -int tcg2_log_prepare_buffer(struct udevice *dev, struct tcg2_event_log *elog, - bool ignore_existing_log) -{ - struct tcg2_event_log log; - int rc; - - elog->log_position = 0; - elog->found = false; - - rc = tcg2_platform_get_log(dev, (void **)&log.log, &log.log_size); - if (!rc) { - log.log_position = 0; - log.found = false; - - if (!ignore_existing_log) { - rc = tcg2_log_parse(dev, &log); - if (rc) - return rc; - } - - if (elog->log_size) { - if (log.found) { - if (elog->log_size < log.log_position) - return -ENOSPC; - - /* - * Copy the discovered log into the user buffer - * if there's enough space. - */ - memcpy(elog->log, log.log, log.log_position); - } - - unmap_physmem(log.log, MAP_NOCACHE); - } else { - elog->log = log.log; - elog->log_size = log.log_size; - } - - elog->log_position = log.log_position; - elog->found = log.found; - } - - /* - * Initialize the log buffer if no log was discovered and the buffer is - * valid. User's can pass in their own buffer as a fallback if no - * memory region is found. - */ - if (!elog->found && elog->log_size) - rc = tcg2_log_init(dev, elog); - - return rc; -} - -int tcg2_measurement_init(struct udevice **dev, struct tcg2_event_log *elog, - bool ignore_existing_log) -{ - int rc; - - rc = tcg2_platform_get_tpm2(dev); - if (rc) - return rc; - - rc = tpm_auto_start(*dev); - if (rc) - return rc; - - rc = tcg2_log_prepare_buffer(*dev, elog, ignore_existing_log); - if (rc) { - tcg2_measurement_term(*dev, elog, true); - return rc; - } - - rc = tcg2_measure_event(*dev, elog, 0, EV_S_CRTM_VERSION, - strlen(version_string) + 1, - (u8 *)version_string); - if (rc) { - tcg2_measurement_term(*dev, elog, true); - return rc; - } - - return 0; -} - -void tcg2_measurement_term(struct udevice *dev, struct tcg2_event_log *elog, - bool error) -{ - u32 event = error ? 0x1 : 0xffffffff; - int i; - - for (i = 0; i < 8; ++i) - tcg2_measure_event(dev, elog, i, EV_SEPARATOR, sizeof(event), - (const u8 *)&event); - - if (elog->log) - unmap_physmem(elog->log, MAP_NOCACHE); -} - -__weak int tcg2_platform_get_log(struct udevice *dev, void **addr, u32 *size) -{ - const __be32 *addr_prop; - const __be32 *size_prop; - int asize; - int ssize; - - *addr = NULL; - *size = 0; - - addr_prop = dev_read_prop(dev, "tpm_event_log_addr", &asize); - if (!addr_prop) - addr_prop = dev_read_prop(dev, "linux,sml-base", &asize); - - size_prop = dev_read_prop(dev, "tpm_event_log_size", &ssize); - if (!size_prop) - size_prop = dev_read_prop(dev, "linux,sml-size", &ssize); - - if (addr_prop && size_prop) { - u64 a = of_read_number(addr_prop, asize / sizeof(__be32)); - u64 s = of_read_number(size_prop, ssize / sizeof(__be32)); - - *addr = map_physmem(a, s, MAP_NOCACHE); - *size = (u32)s; - } else { - struct ofnode_phandle_args args; - phys_addr_t a; - fdt_size_t s; - - if (dev_read_phandle_with_args(dev, "memory-region", NULL, 0, - 0, &args)) - return -ENODEV; - - a = ofnode_get_addr_size(args.node, "reg", &s); - if (a == FDT_ADDR_T_NONE) - return -ENOMEM; - - *addr = map_physmem(a, s, MAP_NOCACHE); - *size = (u32)s; - } - - return 0; -} - -__weak int tcg2_platform_get_tpm2(struct udevice **dev) -{ - for_each_tpm_device(*dev) { - if (tpm_get_version(*dev) == TPM_V2) - return 0; - } - - return -ENODEV; -} - -__weak void tcg2_platform_startup_error(struct udevice *dev, int rc) {} - u32 tpm2_startup(struct udevice *dev, enum tpm2_startup_types mode) { const u8 command_v2[12] = { @@ -872,6 +196,11 @@ u32 tpm2_pcr_extend(struct udevice *dev, u32 index, u32 algorithm, if (!digest) return -EINVAL; + + if (!tpm2_allow_extend(dev)) { + log_err("Cannot extend PCRs if all the TPM enabled algorithms are not supported\n"); + return -EINVAL; + } /* * Fill the command structure starting from the first buffer: * - the digest @@ -1071,48 +400,25 @@ static int tpm2_get_num_pcr(struct udevice *dev, u32 *num_pcr) return 0; } -static bool tpm2_is_active_pcr(struct tpms_pcr_selection *selection) -{ - int i; - - /* - * check the pcr_select. If at least one of the PCRs supports the - * algorithm add it on the active ones - */ - for (i = 0; i < selection->size_of_select; i++) { - if (selection->pcr_select[i]) - return true; - } - - return false; -} - -int tpm2_get_pcr_info(struct udevice *dev, u32 *supported_pcr, u32 *active_pcr, - u32 *pcr_banks) +int tpm2_get_pcr_info(struct udevice *dev, struct tpml_pcr_selection *pcrs) { u8 response[(sizeof(struct tpms_capability_data) - offsetof(struct tpms_capability_data, data))]; - struct tpml_pcr_selection pcrs; u32 num_pcr; size_t i; u32 ret; - *supported_pcr = 0; - *active_pcr = 0; - *pcr_banks = 0; - memset(response, 0, sizeof(response)); ret = tpm2_get_capability(dev, TPM2_CAP_PCRS, 0, response, 1); if (ret) return ret; - pcrs.count = get_unaligned_be32(response); + pcrs->count = get_unaligned_be32(response); /* - * We only support 5 algorithms for now so check against that + * We only support 4 algorithms for now so check against that * instead of TPM2_NUM_PCR_BANKS */ - if (pcrs.count > ARRAY_SIZE(tpm2_supported_algorithms) || - pcrs.count < 1) { - printf("%s: too many pcrs: %u\n", __func__, pcrs.count); + if (pcrs->count > 4 || pcrs->count < 1) { + printf("%s: too many pcrs: %u\n", __func__, pcrs->count); return -EMSGSIZE; } @@ -1120,7 +426,7 @@ int tpm2_get_pcr_info(struct udevice *dev, u32 *supported_pcr, u32 *active_pcr, if (ret) return ret; - for (i = 0; i < pcrs.count; i++) { + for (i = 0; i < pcrs->count; i++) { /* * Definition of TPMS_PCR_SELECTION Structure * hash: u16 @@ -1140,35 +446,20 @@ int tpm2_get_pcr_info(struct udevice *dev, u32 *supported_pcr, u32 *active_pcr, hash_offset + offsetof(struct tpms_pcr_selection, pcr_select); - pcrs.selection[i].hash = + pcrs->selection[i].hash = get_unaligned_be16(response + hash_offset); - pcrs.selection[i].size_of_select = + pcrs->selection[i].size_of_select = __get_unaligned_be(response + size_select_offset); - if (pcrs.selection[i].size_of_select > TPM2_PCR_SELECT_MAX) { + if (pcrs->selection[i].size_of_select > TPM2_PCR_SELECT_MAX) { printf("%s: pcrs selection too large: %u\n", __func__, - pcrs.selection[i].size_of_select); + pcrs->selection[i].size_of_select); return -ENOBUFS; } /* copy the array of pcr_select */ - memcpy(pcrs.selection[i].pcr_select, response + pcr_select_offset, - pcrs.selection[i].size_of_select); - } - - for (i = 0; i < pcrs.count; i++) { - u32 hash_mask = tpm2_algorithm_to_mask(pcrs.selection[i].hash); - - if (hash_mask) { - *supported_pcr |= hash_mask; - if (tpm2_is_active_pcr(&pcrs.selection[i])) - *active_pcr |= hash_mask; - } else { - printf("%s: unknown algorithm %x\n", __func__, - pcrs.selection[i].hash); - } + memcpy(pcrs->selection[i].pcr_select, response + pcr_select_offset, + pcrs->selection[i].size_of_select); } - *pcr_banks = pcrs.count; - return 0; } @@ -1555,3 +846,71 @@ u32 tpm2_enable_nvcommits(struct udevice *dev, uint vendor_cmd, return 0; } + +bool tpm2_is_active_pcr(struct tpms_pcr_selection *selection) +{ + int i; + + for (i = 0; i < selection->size_of_select; i++) { + if (selection->pcr_select[i]) + return true; + } + + return false; +} + +enum tpm2_algorithms tpm2_name_to_algorithm(const char *name) +{ + size_t i; + + for (i = 0; i < ARRAY_SIZE(hash_algo_list); ++i) { + if (!strcasecmp(name, hash_algo_list[i].hash_name)) + return hash_algo_list[i].hash_alg; + } + printf("%s: unsupported algorithm %s\n", __func__, name); + + return -EINVAL; +} + +const char *tpm2_algorithm_name(enum tpm2_algorithms algo) +{ + size_t i; + + for (i = 0; i < ARRAY_SIZE(hash_algo_list); ++i) { + if (hash_algo_list[i].hash_alg == algo) + return hash_algo_list[i].hash_name; + } + + return ""; +} + +u16 tpm2_algorithm_to_len(enum tpm2_algorithms algo) +{ + size_t i; + + for (i = 0; i < ARRAY_SIZE(hash_algo_list); ++i) { + if (hash_algo_list[i].hash_alg == algo) + return hash_algo_list[i].hash_len; + } + + return 0; +} + +bool tpm2_allow_extend(struct udevice *dev) +{ + struct tpml_pcr_selection pcrs; + size_t i; + int rc; + + rc = tpm2_get_pcr_info(dev, &pcrs); + if (rc) + return false; + + for (i = 0; i < pcrs.count; i++) { + if (tpm2_is_active_pcr(&pcrs.selection[i]) && + !tpm2_algorithm_to_len(pcrs.selection[i].hash)) + return false; + } + + return true; +} diff --git a/lib/tpm_tcg2.c b/lib/tpm_tcg2.c new file mode 100644 index 00000000000..7f868cc8837 --- /dev/null +++ b/lib/tpm_tcg2.c @@ -0,0 +1,731 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2023 Linaro Limited + */ + +#include <dm.h> +#include <dm/of_access.h> +#include <tpm_api.h> +#include <tpm-common.h> +#include <tpm-v2.h> +#include <tpm_tcg2.h> +#include <u-boot/sha1.h> +#include <u-boot/sha256.h> +#include <u-boot/sha512.h> +#include <version_string.h> +#include <asm/io.h> +#include <linux/bitops.h> +#include <linux/unaligned/be_byteshift.h> +#include <linux/unaligned/generic.h> +#include <linux/unaligned/le_byteshift.h> +#include "tpm-utils.h" + +int tcg2_get_pcr_info(struct udevice *dev, u32 *supported_pcr, u32 *active_pcr, + u32 *pcr_banks) +{ + u8 response[(sizeof(struct tpms_capability_data) - + offsetof(struct tpms_capability_data, data))]; + struct tpml_pcr_selection pcrs; + size_t i; + u32 ret; + + *supported_pcr = 0; + *active_pcr = 0; + *pcr_banks = 0; + memset(response, 0, sizeof(response)); + + ret = tpm2_get_pcr_info(dev, &pcrs); + if (ret) + return ret; + + for (i = 0; i < pcrs.count; i++) { + u32 hash_mask = tcg2_algorithm_to_mask(pcrs.selection[i].hash); + + if (hash_mask) { + *supported_pcr |= hash_mask; + if (tpm2_is_active_pcr(&pcrs.selection[i])) + *active_pcr |= hash_mask; + } else { + printf("%s: unknown algorithm %x\n", __func__, + pcrs.selection[i].hash); + } + } + + *pcr_banks = pcrs.count; + + return 0; +} + +int tcg2_get_active_pcr_banks(struct udevice *dev, u32 *active_pcr_banks) +{ + u32 supported = 0; + u32 pcr_banks = 0; + u32 active = 0; + int rc; + + rc = tcg2_get_pcr_info(dev, &supported, &active, &pcr_banks); + if (rc) + return rc; + + *active_pcr_banks = active; + + return 0; +} + +u32 tcg2_event_get_size(struct tpml_digest_values *digest_list) +{ + u32 len; + size_t i; + + len = offsetof(struct tcg_pcr_event2, digests); + len += offsetof(struct tpml_digest_values, digests); + for (i = 0; i < digest_list->count; ++i) { + u16 l = tpm2_algorithm_to_len(digest_list->digests[i].hash_alg); + + if (!l) + continue; + + len += l + offsetof(struct tpmt_ha, digest); + } + len += sizeof(u32); + + return len; +} + +int tcg2_create_digest(struct udevice *dev, const u8 *input, u32 length, + struct tpml_digest_values *digest_list) +{ + u8 final[sizeof(union tpmu_ha)]; + sha256_context ctx_256; + sha512_context ctx_512; + sha1_context ctx; + u32 active; + size_t i; + u32 len; + int rc; + + rc = tcg2_get_active_pcr_banks(dev, &active); + if (rc) + return rc; + + digest_list->count = 0; + for (i = 0; i < ARRAY_SIZE(hash_algo_list); ++i) { + if (!(active & hash_algo_list[i].hash_mask)) + continue; + + switch (hash_algo_list[i].hash_alg) { + case TPM2_ALG_SHA1: + sha1_starts(&ctx); + sha1_update(&ctx, input, length); + sha1_finish(&ctx, final); + len = TPM2_SHA1_DIGEST_SIZE; + break; + case TPM2_ALG_SHA256: + sha256_starts(&ctx_256); + sha256_update(&ctx_256, input, length); + sha256_finish(&ctx_256, final); + len = TPM2_SHA256_DIGEST_SIZE; + break; + case TPM2_ALG_SHA384: + sha384_starts(&ctx_512); + sha384_update(&ctx_512, input, length); + sha384_finish(&ctx_512, final); + len = TPM2_SHA384_DIGEST_SIZE; + break; + case TPM2_ALG_SHA512: + sha512_starts(&ctx_512); + sha512_update(&ctx_512, input, length); + sha512_finish(&ctx_512, final); + len = TPM2_SHA512_DIGEST_SIZE; + break; + default: + printf("%s: unsupported algorithm %x\n", __func__, + hash_algo_list[i].hash_alg); + continue; + } + + digest_list->digests[digest_list->count].hash_alg = + hash_algo_list[i].hash_alg; + memcpy(&digest_list->digests[digest_list->count].digest, final, + len); + digest_list->count++; + } + + return 0; +} + +void tcg2_log_append(u32 pcr_index, u32 event_type, + struct tpml_digest_values *digest_list, u32 size, + const u8 *event, u8 *log) +{ + size_t len; + size_t pos; + u32 i; + + pos = offsetof(struct tcg_pcr_event2, pcr_index); + put_unaligned_le32(pcr_index, log); + pos = offsetof(struct tcg_pcr_event2, event_type); + put_unaligned_le32(event_type, log + pos); + pos = offsetof(struct tcg_pcr_event2, digests) + + offsetof(struct tpml_digest_values, count); + put_unaligned_le32(digest_list->count, log + pos); + + pos = offsetof(struct tcg_pcr_event2, digests) + + offsetof(struct tpml_digest_values, digests); + for (i = 0; i < digest_list->count; ++i) { + u16 hash_alg = digest_list->digests[i].hash_alg; + + len = tpm2_algorithm_to_len(hash_alg); + if (!len) + continue; + + pos += offsetof(struct tpmt_ha, hash_alg); + put_unaligned_le16(hash_alg, log + pos); + pos += offsetof(struct tpmt_ha, digest); + memcpy(log + pos, (u8 *)&digest_list->digests[i].digest, len); + pos += len; + } + + put_unaligned_le32(size, log + pos); + pos += sizeof(u32); + memcpy(log + pos, event, size); +} + +static int tcg2_log_append_check(struct tcg2_event_log *elog, u32 pcr_index, + u32 event_type, + struct tpml_digest_values *digest_list, + u32 size, const u8 *event) +{ + u32 event_size; + u8 *log; + + event_size = size + tcg2_event_get_size(digest_list); + if (elog->log_position + event_size > elog->log_size) { + printf("%s: log too large: %u + %u > %u\n", __func__, + elog->log_position, event_size, elog->log_size); + return -ENOBUFS; + } + + log = elog->log + elog->log_position; + elog->log_position += event_size; + + tcg2_log_append(pcr_index, event_type, digest_list, size, event, log); + + return 0; +} + +static int tcg2_log_init(struct udevice *dev, struct tcg2_event_log *elog) +{ + struct tcg_efi_spec_id_event *ev; + struct tcg_pcr_event *log; + u32 event_size; + u32 count = 0; + u32 log_size; + u32 active; + size_t i; + u16 len; + int rc; + + rc = tcg2_get_active_pcr_banks(dev, &active); + if (rc) + return rc; + + event_size = offsetof(struct tcg_efi_spec_id_event, digest_sizes); + for (i = 0; i < ARRAY_SIZE(hash_algo_list); ++i) { + if (!(active & hash_algo_list[i].hash_mask)) + continue; + + switch (hash_algo_list[i].hash_alg) { + case TPM2_ALG_SHA1: + case TPM2_ALG_SHA256: + case TPM2_ALG_SHA384: + case TPM2_ALG_SHA512: + count++; + break; + default: + continue; + } + } + + event_size += 1 + + (sizeof(struct tcg_efi_spec_id_event_algorithm_size) * count); + log_size = offsetof(struct tcg_pcr_event, event) + event_size; + + if (log_size > elog->log_size) { + printf("%s: log too large: %u > %u\n", __func__, log_size, + elog->log_size); + return -ENOBUFS; + } + + log = (struct tcg_pcr_event *)elog->log; + put_unaligned_le32(0, &log->pcr_index); + put_unaligned_le32(EV_NO_ACTION, &log->event_type); + memset(&log->digest, 0, sizeof(log->digest)); + put_unaligned_le32(event_size, &log->event_size); + + ev = (struct tcg_efi_spec_id_event *)log->event; + strlcpy((char *)ev->signature, TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03, + sizeof(ev->signature)); + put_unaligned_le32(0, &ev->platform_class); + ev->spec_version_minor = TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2; + ev->spec_version_major = TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2; + ev->spec_errata = TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_ERRATA_TPM2; + ev->uintn_size = sizeof(size_t) / sizeof(u32); + put_unaligned_le32(count, &ev->number_of_algorithms); + + count = 0; + for (i = 0; i < ARRAY_SIZE(hash_algo_list); ++i) { + if (!(active & hash_algo_list[i].hash_mask)) + continue; + + len = hash_algo_list[i].hash_len; + if (!len) + continue; + + put_unaligned_le16(hash_algo_list[i].hash_alg, + &ev->digest_sizes[count].algorithm_id); + put_unaligned_le16(len, &ev->digest_sizes[count].digest_size); + count++; + } + + *((u8 *)ev + (event_size - 1)) = 0; + elog->log_position = log_size; + + return 0; +} + +static int tcg2_replay_eventlog(struct tcg2_event_log *elog, + struct udevice *dev, + struct tpml_digest_values *digest_list, + u32 log_position) +{ + const u32 offset = offsetof(struct tcg_pcr_event2, digests) + + offsetof(struct tpml_digest_values, digests); + u32 event_size; + u32 count; + u16 algo; + u32 pcr; + u32 pos; + u16 len; + u8 *log; + int rc; + u32 i; + + while (log_position + offset < elog->log_size) { + log = elog->log + log_position; + + pos = offsetof(struct tcg_pcr_event2, pcr_index); + pcr = get_unaligned_le32(log + pos); + pos = offsetof(struct tcg_pcr_event2, event_type); + if (!get_unaligned_le32(log + pos)) + return 0; + + pos = offsetof(struct tcg_pcr_event2, digests) + + offsetof(struct tpml_digest_values, count); + count = get_unaligned_le32(log + pos); + if (count > ARRAY_SIZE(hash_algo_list) || + (digest_list->count && digest_list->count != count)) + return 0; + + pos = offsetof(struct tcg_pcr_event2, digests) + + offsetof(struct tpml_digest_values, digests); + for (i = 0; i < count; ++i) { + pos += offsetof(struct tpmt_ha, hash_alg); + if (log_position + pos + sizeof(u16) >= elog->log_size) + return 0; + + algo = get_unaligned_le16(log + pos); + pos += offsetof(struct tpmt_ha, digest); + switch (algo) { + case TPM2_ALG_SHA1: + case TPM2_ALG_SHA256: + case TPM2_ALG_SHA384: + case TPM2_ALG_SHA512: + len = tpm2_algorithm_to_len(algo); + break; + default: + return 0; + } + + if (digest_list->count) { + if (algo != digest_list->digests[i].hash_alg || + log_position + pos + len >= elog->log_size) + return 0; + + memcpy(digest_list->digests[i].digest.sha512, + log + pos, len); + } + + pos += len; + } + + if (log_position + pos + sizeof(u32) >= elog->log_size) + return 0; + + event_size = get_unaligned_le32(log + pos); + pos += event_size + sizeof(u32); + if (log_position + pos > elog->log_size) + return 0; + + if (digest_list->count) { + rc = tcg2_pcr_extend(dev, pcr, digest_list); + if (rc) + return rc; + } + + log_position += pos; + } + + elog->log_position = log_position; + elog->found = true; + return 0; +} + +static int tcg2_log_parse(struct udevice *dev, struct tcg2_event_log *elog) +{ + struct tpml_digest_values digest_list; + struct tcg_efi_spec_id_event *event; + struct tcg_pcr_event *log; + u32 log_active; + u32 calc_size; + u32 active; + u32 count; + u32 evsz; + u32 mask; + u16 algo; + u16 len; + int rc; + u32 i; + u16 j; + + if (elog->log_size <= offsetof(struct tcg_pcr_event, event)) + return 0; + + log = (struct tcg_pcr_event *)elog->log; + if (get_unaligned_le32(&log->pcr_index) != 0 || + get_unaligned_le32(&log->event_type) != EV_NO_ACTION) + return 0; + + for (i = 0; i < sizeof(log->digest); i++) { + if (log->digest[i]) + return 0; + } + + evsz = get_unaligned_le32(&log->event_size); + if (evsz < offsetof(struct tcg_efi_spec_id_event, digest_sizes) || + evsz + offsetof(struct tcg_pcr_event, event) > elog->log_size) + return 0; + + event = (struct tcg_efi_spec_id_event *)log->event; + if (memcmp(event->signature, TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03, + sizeof(TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03))) + return 0; + + if (event->spec_version_minor != TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2 || + event->spec_version_major != TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2) + return 0; + + count = get_unaligned_le32(&event->number_of_algorithms); + if (count > ARRAY_SIZE(hash_algo_list)) + return 0; + + calc_size = offsetof(struct tcg_efi_spec_id_event, digest_sizes) + + (sizeof(struct tcg_efi_spec_id_event_algorithm_size) * count) + + 1; + if (evsz != calc_size) + return 0; + + rc = tcg2_get_active_pcr_banks(dev, &active); + if (rc) + return rc; + + digest_list.count = 0; + log_active = 0; + + for (i = 0; i < count; ++i) { + algo = get_unaligned_le16(&event->digest_sizes[i].algorithm_id); + mask = tcg2_algorithm_to_mask(algo); + + if (!(active & mask)) + return 0; + + switch (algo) { + case TPM2_ALG_SHA1: + case TPM2_ALG_SHA256: + case TPM2_ALG_SHA384: + case TPM2_ALG_SHA512: + len = get_unaligned_le16(&event->digest_sizes[i].digest_size); + if (tpm2_algorithm_to_len(algo) != len) + return 0; + digest_list.digests[digest_list.count++].hash_alg = algo; + break; + default: + return 0; + } + + log_active |= mask; + } + + /* Ensure the previous firmware extended all the PCRs. */ + if (log_active != active) + return 0; + + /* Read PCR0 to check if previous firmware extended the PCRs or not. */ + rc = tcg2_pcr_read(dev, 0, &digest_list); + if (rc) + return rc; + + for (i = 0; i < digest_list.count; ++i) { + len = tpm2_algorithm_to_len(digest_list.digests[i].hash_alg); + for (j = 0; j < len; ++j) { + if (digest_list.digests[i].digest.sha512[j]) + break; + } + + /* PCR is non-zero; it has been extended, so skip extending. */ + if (j != len) { + digest_list.count = 0; + break; + } + } + + return tcg2_replay_eventlog(elog, dev, &digest_list, + offsetof(struct tcg_pcr_event, event) + + evsz); +} + +int tcg2_pcr_extend(struct udevice *dev, u32 pcr_index, + struct tpml_digest_values *digest_list) +{ + u32 rc; + u32 i; + + for (i = 0; i < digest_list->count; i++) { + u32 alg = digest_list->digests[i].hash_alg; + + rc = tpm2_pcr_extend(dev, pcr_index, alg, + (u8 *)&digest_list->digests[i].digest, + tpm2_algorithm_to_len(alg)); + if (rc) { + printf("%s: error pcr:%u alg:%08x\n", __func__, + pcr_index, alg); + return rc; + } + } + + return 0; +} + +int tcg2_pcr_read(struct udevice *dev, u32 pcr_index, + struct tpml_digest_values *digest_list) +{ + struct tpm_chip_priv *priv; + u32 rc; + u32 i; + + priv = dev_get_uclass_priv(dev); + if (!priv) + return -ENODEV; + + for (i = 0; i < digest_list->count; i++) { + u32 alg = digest_list->digests[i].hash_alg; + u8 *digest = (u8 *)&digest_list->digests[i].digest; + + rc = tpm2_pcr_read(dev, pcr_index, priv->pcr_select_min, alg, + digest, tpm2_algorithm_to_len(alg), NULL); + if (rc) { + printf("%s: error pcr:%u alg:%08x\n", __func__, + pcr_index, alg); + return rc; + } + } + + return 0; +} + +int tcg2_measure_data(struct udevice *dev, struct tcg2_event_log *elog, + u32 pcr_index, u32 size, const u8 *data, u32 event_type, + u32 event_size, const u8 *event) +{ + struct tpml_digest_values digest_list; + int rc; + + if (data) + rc = tcg2_create_digest(dev, data, size, &digest_list); + else + rc = tcg2_create_digest(dev, event, event_size, &digest_list); + if (rc) + return rc; + + rc = tcg2_pcr_extend(dev, pcr_index, &digest_list); + if (rc) + return rc; + + return tcg2_log_append_check(elog, pcr_index, event_type, &digest_list, + event_size, event); +} + +int tcg2_log_prepare_buffer(struct udevice *dev, struct tcg2_event_log *elog, + bool ignore_existing_log) +{ + struct tcg2_event_log log; + int rc; + + elog->log_position = 0; + elog->found = false; + + rc = tcg2_platform_get_log(dev, (void **)&log.log, &log.log_size); + if (!rc) { + log.log_position = 0; + log.found = false; + + if (!ignore_existing_log) { + rc = tcg2_log_parse(dev, &log); + if (rc) + return rc; + } + + if (elog->log_size) { + if (log.found) { + if (elog->log_size < log.log_position) + return -ENOBUFS; + + /* + * Copy the discovered log into the user buffer + * if there's enough space. + */ + memcpy(elog->log, log.log, log.log_position); + } + + unmap_physmem(log.log, MAP_NOCACHE); + } else { + elog->log = log.log; + elog->log_size = log.log_size; + } + + elog->log_position = log.log_position; + elog->found = log.found; + } + + /* + * Initialize the log buffer if no log was discovered and the buffer is + * valid. User's can pass in their own buffer as a fallback if no + * memory region is found. + */ + if (!elog->found && elog->log_size) + rc = tcg2_log_init(dev, elog); + + return rc; +} + +int tcg2_measurement_init(struct udevice **dev, struct tcg2_event_log *elog, + bool ignore_existing_log) +{ + int rc; + + rc = tcg2_platform_get_tpm2(dev); + if (rc) + return rc; + + rc = tpm_auto_start(*dev); + if (rc) + return rc; + + rc = tcg2_log_prepare_buffer(*dev, elog, ignore_existing_log); + if (rc) { + tcg2_measurement_term(*dev, elog, true); + return rc; + } + + rc = tcg2_measure_event(*dev, elog, 0, EV_S_CRTM_VERSION, + strlen(version_string) + 1, + (u8 *)version_string); + if (rc) { + tcg2_measurement_term(*dev, elog, true); + return rc; + } + + return 0; +} + +void tcg2_measurement_term(struct udevice *dev, struct tcg2_event_log *elog, + bool error) +{ + u32 event = error ? 0x1 : 0xffffffff; + int i; + + for (i = 0; i < 8; ++i) + tcg2_measure_event(dev, elog, i, EV_SEPARATOR, sizeof(event), + (const u8 *)&event); + + if (elog->log) + unmap_physmem(elog->log, MAP_NOCACHE); +} + +__weak int tcg2_platform_get_log(struct udevice *dev, void **addr, u32 *size) +{ + const __be32 *addr_prop; + const __be32 *size_prop; + int asize; + int ssize; + + *addr = NULL; + *size = 0; + + addr_prop = dev_read_prop(dev, "tpm_event_log_addr", &asize); + if (!addr_prop) + addr_prop = dev_read_prop(dev, "linux,sml-base", &asize); + + size_prop = dev_read_prop(dev, "tpm_event_log_size", &ssize); + if (!size_prop) + size_prop = dev_read_prop(dev, "linux,sml-size", &ssize); + + if (addr_prop && size_prop) { + u64 a = of_read_number(addr_prop, asize / sizeof(__be32)); + u64 s = of_read_number(size_prop, ssize / sizeof(__be32)); + + *addr = map_physmem(a, s, MAP_NOCACHE); + *size = (u32)s; + } else { + struct ofnode_phandle_args args; + phys_addr_t a; + fdt_size_t s; + + if (dev_read_phandle_with_args(dev, "memory-region", NULL, 0, + 0, &args)) + return -ENODEV; + + a = ofnode_get_addr_size(args.node, "reg", &s); + if (a == FDT_ADDR_T_NONE) + return -ENOMEM; + + *addr = map_physmem(a, s, MAP_NOCACHE); + *size = (u32)s; + } + + return 0; +} + +__weak int tcg2_platform_get_tpm2(struct udevice **dev) +{ + for_each_tpm_device(*dev) { + if (tpm_get_version(*dev) == TPM_V2) + return 0; + } + + return -ENODEV; +} + +u32 tcg2_algorithm_to_mask(enum tpm2_algorithms algo) +{ + size_t i; + + for (i = 0; i < ARRAY_SIZE(hash_algo_list); i++) { + if (hash_algo_list[i].hash_alg == algo) + return hash_algo_list[i].hash_mask; + } + + return 0; +} + +__weak void tcg2_platform_startup_error(struct udevice *dev, int rc) {} diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 27ea9c907a3..cfd1f1914ed 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -19,6 +19,7 @@ #include <hexdump.h> #include <stdarg.h> #include <uuid.h> +#include <stdio.h> #include <vsprintf.h> #include <linux/ctype.h> #include <linux/err.h> diff --git a/lib/zlib/deflate.c b/lib/zlib/deflate.c index 7e1ed4f9b20..af7542cc9a8 100644 --- a/lib/zlib/deflate.c +++ b/lib/zlib/deflate.c @@ -164,7 +164,6 @@ struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ */ #define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask) - /* =========================================================================== * Insert string str in the dictionary and set match_head to the previous head * of the hash chain (the most recent string with same hash key). Return @@ -966,7 +965,6 @@ int ZEXPORT deflateCopy (dest, source) deflate_state *ds; deflate_state *ss; - if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { return Z_STREAM_ERROR; } diff --git a/lib/zlib/deflate.h b/lib/zlib/deflate.h index 4c53b94af0b..b4a4634ec78 100644 --- a/lib/zlib/deflate.h +++ b/lib/zlib/deflate.h @@ -57,7 +57,6 @@ #define FINISH_STATE 666 /* Stream status */ - /* Data structure describing a single value and its code string. */ typedef struct ct_data_s { union { @@ -269,7 +268,6 @@ typedef struct internal_state { */ #define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} - #define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) /* Minimum amount of lookahead, except at the end of the input file. * See deflate.c for comments about the MIN_MATCH+1. diff --git a/lib/zlib/inffast.c b/lib/zlib/inffast.c index 5e2a65ad4d2..b5a0adcce69 100644 --- a/lib/zlib/inffast.c +++ b/lib/zlib/inffast.c @@ -236,18 +236,47 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ } } else { + unsigned short *sout; + unsigned long loops; + from = out - dist; /* copy direct from output */ - do { /* minimum length is three */ - *out++ = *from++; - *out++ = *from++; - *out++ = *from++; - len -= 3; - } while (len > 2); - if (len) { - *out++ = *from++; - if (len > 1) - *out++ = *from++; - } + /* minimum length is three */ + /* Align out addr */ + if (!((long)(out - 1) & 1)) { + *out++ = *from++; + len--; + } + sout = (unsigned short *)out; + if (dist > 2 ) { + unsigned short *sfrom; + + sfrom = (unsigned short *)from; + loops = len >> 1; + do + *sout++ = get_unaligned(sfrom++); + while (--loops); + out = (unsigned char *)sout; + from = (unsigned char *)sfrom; + } else { /* dist == 1 or dist == 2 */ + unsigned short pat16; + + pat16 = *(sout - 1); + if (dist == 1) +#if defined(__BIG_ENDIAN) + pat16 = (pat16 & 0xff) | ((pat16 & 0xff ) << 8); +#elif defined(__LITTLE_ENDIAN) + pat16 = (pat16 & 0xff00) | ((pat16 & 0xff00 ) >> 8); +#else +#error __BIG_ENDIAN nor __LITTLE_ENDIAN is defined +#endif + loops = len >> 1; + do + *sout++ = pat16; + while (--loops); + out = (unsigned char *)sout; + } + if (len & 1) + *out++ = *from++; } } else if ((op & 64) == 0) { /* 2nd level distance code */ diff --git a/lib/zlib/trees.c b/lib/zlib/trees.c index e040617686a..569d44351e5 100644 --- a/lib/zlib/trees.c +++ b/lib/zlib/trees.c @@ -231,7 +231,6 @@ local void send_bits(s, value, length) } #endif /* DEBUG */ - /* the arguments must not have side effects */ /* =========================================================================== @@ -431,7 +430,6 @@ local void init_block(s) #define SMALLEST 1 /* Index within the heap array of least frequent node in the Huffman tree */ - /* =========================================================================== * Remove the smallest element from the heap and recreate the heap with * one less element. Updates heap and heap_len. diff --git a/lib/zlib/zlib.h b/lib/zlib/zlib.h index 560e7be97d3..f9b2f69ac02 100644 --- a/lib/zlib/zlib.h +++ b/lib/zlib/zlib.h @@ -10,7 +10,6 @@ /* avoid conflicts */ #undef OFF #undef ASMINF -#undef POSTINC #undef NO_GZIP #define GUNZIP #undef STDC diff --git a/lib/zlib/zutil.h b/lib/zlib/zutil.h index e63bf68653f..c0c04196a02 100644 --- a/lib/zlib/zutil.h +++ b/lib/zlib/zutil.h @@ -114,7 +114,6 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # define Tracecv(c,x) #endif - voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); void zcfree OF((voidpf opaque, voidpf ptr, unsigned size)); diff --git a/lib/zstd/common/bitstream.h b/lib/zstd/common/bitstream.h index feef3a1b1d6..ee36de1cd1a 100644 --- a/lib/zstd/common/bitstream.h +++ b/lib/zstd/common/bitstream.h @@ -28,7 +28,6 @@ #include "debug.h" /* assert(), DEBUGLOG(), RAWLOG() */ #include "error_private.h" /* error codes and messages */ - /*========================================= * Target specific =========================================*/ @@ -37,7 +36,6 @@ #define STREAM_ACCUMULATOR_MIN_64 57 #define STREAM_ACCUMULATOR_MIN ((U32)(MEM_32bits() ? STREAM_ACCUMULATOR_MIN_32 : STREAM_ACCUMULATOR_MIN_64)) - /*-****************************************** * bitStream encoding API (write forward) ********************************************/ @@ -75,7 +73,6 @@ MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC); * If data couldn't fit into `dstBuffer`, it will return a 0 ( == not storable) */ - /*-******************************************** * bitStream decoding API (read backward) **********************************************/ @@ -98,7 +95,6 @@ MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits); MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD); MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* bitD); - /* Start by invoking BIT_initDStream(). * A chunk of the bitStream is then stored into a local register. * Local register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (size_t). @@ -109,7 +105,6 @@ MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* bitD); * Checking if DStream has reached its end can be performed with BIT_endOfDStream(). */ - /*-**************************************** * unsafe API ******************************************/ @@ -122,8 +117,6 @@ MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC); MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits); /* faster, but works only if nbBits >= 1 */ - - /*-************************************************************** * Internal functions ****************************************************************/ @@ -245,7 +238,6 @@ MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC) return (bitC->ptr - bitC->startPtr) + (bitC->bitPos > 0); } - /*-******************************************************** * bitStream decoding **********************************************************/ @@ -442,5 +434,4 @@ MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* DStream) return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer)*8)); } - #endif /* BITSTREAM_H_MODULE */ diff --git a/lib/zstd/common/compiler.h b/lib/zstd/common/compiler.h index c42d39faf9b..a7345658602 100644 --- a/lib/zstd/common/compiler.h +++ b/lib/zstd/common/compiler.h @@ -70,7 +70,6 @@ /* force no inlining */ #define FORCE_NOINLINE static __attribute__((__noinline__)) - /* target attribute */ #define TARGET_ATTRIBUTE(target) __attribute__((__target__(target))) @@ -135,7 +134,6 @@ /*Like DYNAMIC_BMI2 but for compile time determination of BMI2 support*/ - /* compile time determination of SIMD support */ /* C-language Attributes are added in C23. */ @@ -179,6 +177,4 @@ * Sanitizer *****************************************************************/ - - #endif /* ZSTD_COMPILER_H */ diff --git a/lib/zstd/common/cpu.h b/lib/zstd/common/cpu.h index 0db7b42407e..becf832a95a 100644 --- a/lib/zstd/common/cpu.h +++ b/lib/zstd/common/cpu.h @@ -18,7 +18,6 @@ #include "mem.h" - typedef struct { U32 f1c; U32 f1d; diff --git a/lib/zstd/common/debug.c b/lib/zstd/common/debug.c index bb863c9ea61..49254cc6722 100644 --- a/lib/zstd/common/debug.c +++ b/lib/zstd/common/debug.c @@ -12,7 +12,6 @@ * You may select, at your option, one of the above-listed licenses. ****************************************************************** */ - /* * This module only hosts one global variable * which can be used to dynamically influence the verbosity of traces, diff --git a/lib/zstd/common/debug.h b/lib/zstd/common/debug.h index 7f43dd3c063..ad6e60d609e 100644 --- a/lib/zstd/common/debug.h +++ b/lib/zstd/common/debug.h @@ -12,7 +12,6 @@ * You may select, at your option, one of the above-listed licenses. ****************************************************************** */ - /* * The purpose of this header is to enable debug functions. * They regroup assert(), DEBUGLOG() and RAWLOG() for run-time, @@ -32,14 +31,11 @@ #ifndef DEBUG_H_12987983217 #define DEBUG_H_12987983217 - - /* static assert is triggered at compile time, leaving no runtime artefact. * static assert only works with compile-time constants. * Also, this variant can only be used inside a function. */ #define DEBUG_STATIC_ASSERT(c) (void)sizeof(char[(c) ? 1 : -1]) - /* DEBUGLEVEL is expected to be defined externally, * typically through compiler command line. * Value must be a number. */ @@ -47,7 +43,6 @@ # define DEBUGLEVEL 0 #endif - /* recommended values for DEBUGLEVEL : * 0 : release mode, no debug, all run-time checks disabled * 1 : enables assert() only, no display @@ -87,6 +82,4 @@ extern int g_debuglevel; /* the variable is only declared, # define DEBUGLOG(l, ...) {} /* disabled */ #endif - - #endif /* DEBUG_H_12987983217 */ diff --git a/lib/zstd/common/entropy_common.c b/lib/zstd/common/entropy_common.c index fef67056f05..0f421839ed4 100644 --- a/lib/zstd/common/entropy_common.c +++ b/lib/zstd/common/entropy_common.c @@ -22,11 +22,9 @@ #define HUF_STATIC_LINKING_ONLY /* HUF_TABLELOG_ABSOLUTEMAX */ #include "huf.h" - /*=== Version ===*/ unsigned FSE_versionNumber(void) { return FSE_VERSION_NUMBER; } - /*=== Error Management ===*/ unsigned FSE_isError(size_t code) { return ERR_isError(code); } const char* FSE_getErrorName(size_t code) { return ERR_getErrorName(code); } @@ -34,7 +32,6 @@ const char* FSE_getErrorName(size_t code) { return ERR_getErrorName(code); } unsigned HUF_isError(size_t code) { return ERR_isError(code); } const char* HUF_getErrorName(size_t code) { return ERR_getErrorName(code); } - /*-************************************************************** * FSE NCount encoding-decoding ****************************************************************/ @@ -240,7 +237,6 @@ size_t FSE_readNCount( return FSE_readNCount_bmi2(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize, /* bmi2 */ 0); } - /*! HUF_readStats() : Read compact Huffman tree, saved by HUF_writeCTable(). `huffWeight` is destination buffer. diff --git a/lib/zstd/common/error_private.h b/lib/zstd/common/error_private.h index ca5101e542f..886d2757df4 100644 --- a/lib/zstd/common/error_private.h +++ b/lib/zstd/common/error_private.h @@ -13,8 +13,6 @@ #ifndef ERROR_H_MODULE #define ERROR_H_MODULE - - /* **************************************** * Dependencies ******************************************/ @@ -23,20 +21,17 @@ #include "debug.h" #include "zstd_deps.h" /* size_t */ - /* **************************************** * Compiler-specific ******************************************/ #define ERR_STATIC static __attribute__((unused)) - /*-**************************************** * Customization (error_public.h) ******************************************/ typedef ZSTD_ErrorCode ERR_enum; #define PREFIX(name) ZSTD_error_##name - /*-**************************************** * Error codes handling ******************************************/ @@ -52,7 +47,6 @@ ERR_STATIC ERR_enum ERR_getErrorCode(size_t code) { if (!ERR_isError(code)) retu #define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return e #define CHECK_F(f) { CHECK_V_F(_var_err__, f); } - /*-**************************************** * Error Strings ******************************************/ @@ -141,5 +135,4 @@ void _force_has_format_string(const char *format, ...) { } \ } while(0); - #endif /* ERROR_H_MODULE */ diff --git a/lib/zstd/common/fse.h b/lib/zstd/common/fse.h index 4507043b228..78b3ff14b93 100644 --- a/lib/zstd/common/fse.h +++ b/lib/zstd/common/fse.h @@ -12,17 +12,14 @@ * You may select, at your option, one of the above-listed licenses. ****************************************************************** */ - #ifndef FSE_H #define FSE_H - /*-***************************************** * Dependencies ******************************************/ #include "zstd_deps.h" /* size_t, ptrdiff_t */ - /*-***************************************** * FSE_PUBLIC_API : control library symbols visibility ******************************************/ @@ -49,7 +46,6 @@ #define FSE_VERSION_NUMBER (FSE_VERSION_MAJOR *100*100 + FSE_VERSION_MINOR *100 + FSE_VERSION_RELEASE) FSE_PUBLIC_API unsigned FSE_versionNumber(void); /*< library version number; to be used when checking dll version */ - /*-**************************************** * FSE simple functions ******************************************/ @@ -77,7 +73,6 @@ FSE_PUBLIC_API size_t FSE_compress(void* dst, size_t dstCapacity, FSE_PUBLIC_API size_t FSE_decompress(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize); - /*-***************************************** * Tool functions ******************************************/ @@ -87,7 +82,6 @@ FSE_PUBLIC_API size_t FSE_compressBound(size_t size); /* maximum compresse FSE_PUBLIC_API unsigned FSE_isError(size_t code); /* tells if a return value is an error code */ FSE_PUBLIC_API const char* FSE_getErrorName(size_t code); /* provides error code string (useful for debugging) */ - /*-***************************************** * FSE advanced functions ******************************************/ @@ -101,7 +95,6 @@ FSE_PUBLIC_API const char* FSE_getErrorName(size_t code); /* provides error co */ FSE_PUBLIC_API size_t FSE_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog); - /*-***************************************** * FSE detailed API ******************************************/ @@ -219,7 +212,6 @@ If it returns '0', compressed data could not fit into 'dst'. If there is an error, the function will return an ErrorCode (which can be tested using FSE_isError()). */ - /* *** DECOMPRESSION *** */ /*! FSE_readNCount(): @@ -292,7 +284,6 @@ If there is an error, the function will return an error code, which can be teste /* *** Dependency *** */ #include "bitstream.h" - /* ***************************************** * Static allocation *******************************************/ @@ -309,7 +300,6 @@ If there is an error, the function will return an error code, which can be teste #define FSE_CTABLE_SIZE(maxTableLog, maxSymbolValue) (FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) * sizeof(FSE_CTable)) #define FSE_DTABLE_SIZE(maxTableLog) (FSE_DTABLE_SIZE_U32(maxTableLog) * sizeof(FSE_DTable)) - /* ***************************************** * FSE advanced API ***************************************** */ @@ -397,7 +387,6 @@ FSE_CTable ct; // Provided by FSE_buildCTable() BIT_CStream_t bitStream; // bitStream tracking structure FSE_CState_t state; // State tracking structure (can have several) - The first thing to do is to init bitStream and state. size_t errorCode = BIT_initCStream(&bitStream, dstBuffer, maxDstSize); FSE_initCState(&state, ct); @@ -427,7 +416,6 @@ If there is an error, it returns an errorCode (which can be tested using FSE_isE size_t size = BIT_closeCStream(&bitStream); */ - /* ***************************************** * FSE symbol decompression API *******************************************/ @@ -436,7 +424,6 @@ typedef struct { const void* table; /* precise table may vary, depending on U16 */ } FSE_DState_t; - static void FSE_initDState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD, const FSE_DTable* dt); static unsigned char FSE_decodeSymbol(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD); @@ -492,14 +479,12 @@ Check also the states. There might be some symbols left there, if some high prob FSE_endOfDState(&DState); */ - /* ***************************************** * FSE unsafe API *******************************************/ static unsigned char FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD); /* faster, but works only if nbBits is always >= 1 (otherwise, result will be corrupted) */ - /* ***************************************** * Implementation of inlined functions *******************************************/ @@ -519,7 +504,6 @@ MEM_STATIC void FSE_initCState(FSE_CState_t* statePtr, const FSE_CTable* ct) statePtr->stateLog = tableLog; } - /*! FSE_initCState2() : * Same as FSE_initCState(), but the first symbol to include (which will be the last to be read) * uses the smallest state value possible, saving the cost of this symbol */ @@ -549,7 +533,6 @@ MEM_STATIC void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* statePt BIT_flushBits(bitC); } - /* FSE_getMaxNbBits() : * Approximate maximum cost of a symbol, in bits. * Fractional get rounded up (i.e : a symbol with a normalized frequency of 3 gives the same result as a frequency of 2) @@ -582,7 +565,6 @@ MEM_STATIC U32 FSE_bitCost(const void* symbolTTPtr, U32 tableLog, U32 symbolValu } } - /* ====== Decompression ====== */ typedef struct { @@ -649,8 +631,6 @@ MEM_STATIC unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr) return DStatePtr->state == 0; } - - #ifndef FSE_COMMONDEFS_ONLY /* ************************************************************** @@ -685,10 +665,8 @@ MEM_STATIC unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr) #define FSE_FUNCTION_EXTENSION #define FSE_DECODE_TYPE FSE_decode_t - #endif /* !FSE_COMMONDEFS_ONLY */ - /* *************************************************************** * Constants *****************************************************************/ @@ -705,7 +683,5 @@ MEM_STATIC unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr) #define FSE_TABLESTEP(tableSize) (((tableSize)>>1) + ((tableSize)>>3) + 3) - #endif /* FSE_STATIC_LINKING_ONLY */ - diff --git a/lib/zstd/common/fse_decompress.c b/lib/zstd/common/fse_decompress.c index a0d06095be8..5aa75db413a 100644 --- a/lib/zstd/common/fse_decompress.c +++ b/lib/zstd/common/fse_decompress.c @@ -12,7 +12,6 @@ * You may select, at your option, one of the above-listed licenses. ****************************************************************** */ - /* ************************************************************** * Includes ****************************************************************/ @@ -25,14 +24,12 @@ #define ZSTD_DEPS_NEED_MALLOC #include "zstd_deps.h" - /* ************************************************************** * Error Management ****************************************************************/ #define FSE_isError ERR_isError #define FSE_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c) /* use only *after* variable declarations */ - /* ************************************************************** * Templates ****************************************************************/ @@ -55,7 +52,6 @@ #define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y) #define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y) - /* Function templates */ FSE_DTable* FSE_createDTable (unsigned tableLog) { @@ -178,7 +174,6 @@ size_t FSE_buildDTable_wksp(FSE_DTable* dt, const short* normalizedCounter, unsi return FSE_buildDTable_internal(dt, normalizedCounter, maxSymbolValue, tableLog, workSpace, wkspSize); } - #ifndef FSE_COMMONDEFS_ONLY /*-******************************************************* @@ -201,7 +196,6 @@ size_t FSE_buildDTable_rle (FSE_DTable* dt, BYTE symbolValue) return 0; } - size_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits) { void* ptr = dt; @@ -290,7 +284,6 @@ FORCE_INLINE_TEMPLATE size_t FSE_decompress_usingDTable_generic( return op-ostart; } - size_t FSE_decompress_usingDTable(void* dst, size_t originalSize, const void* cSrc, size_t cSrcSize, const FSE_DTable* dt) @@ -304,7 +297,6 @@ size_t FSE_decompress_usingDTable(void* dst, size_t originalSize, return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 0); } - size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize) { return FSE_decompress_wksp_bmi2(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize, /* bmi2 */ 0); @@ -315,7 +307,6 @@ typedef struct { FSE_DTable dtable[1]; /* Dynamically sized */ } FSE_DecompressWksp; - FORCE_INLINE_TEMPLATE size_t FSE_decompress_wksp_body( void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, @@ -382,9 +373,6 @@ size_t FSE_decompress_wksp_bmi2(void* dst, size_t dstCapacity, const void* cSrc, return FSE_decompress_wksp_body_default(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize); } - typedef FSE_DTable DTable_max_t[FSE_DTABLE_SIZE_U32(FSE_MAX_TABLELOG)]; - - #endif /* FSE_COMMONDEFS_ONLY */ diff --git a/lib/zstd/common/huf.h b/lib/zstd/common/huf.h index 5042ff87030..b2678b8153e 100644 --- a/lib/zstd/common/huf.h +++ b/lib/zstd/common/huf.h @@ -12,14 +12,12 @@ * You may select, at your option, one of the above-listed licenses. ****************************************************************** */ - #ifndef HUF_H_298734234 #define HUF_H_298734234 /* *** Dependencies *** */ #include "zstd_deps.h" /* size_t */ - /* *** library symbols visibility *** */ /* Note : when linking with -fvisibility=hidden on gcc, or by default on Visual, * HUF symbols remain "private" (internal symbols for library only). @@ -34,7 +32,6 @@ # define HUF_PUBLIC_API #endif - /* ========================== */ /* *** simple functions *** */ /* ========================== */ @@ -64,7 +61,6 @@ HUF_PUBLIC_API size_t HUF_compress(void* dst, size_t dstCapacity, HUF_PUBLIC_API size_t HUF_decompress(void* dst, size_t originalSize, const void* cSrc, size_t cSrcSize); - /* *** Tool functions *** */ #define HUF_BLOCKSIZE_MAX (128 * 1024) /*< maximum input size for a single block compressed with HUF_compress */ HUF_PUBLIC_API size_t HUF_compressBound(size_t size); /*< maximum compressed size (worst case) */ @@ -73,7 +69,6 @@ HUF_PUBLIC_API size_t HUF_compressBound(size_t size); /*< maximum compressed s HUF_PUBLIC_API unsigned HUF_isError(size_t code); /*< tells if a return value is an error code */ HUF_PUBLIC_API const char* HUF_getErrorName(size_t code); /*< provides error code string (useful for debugging) */ - /* *** Advanced function *** */ /* HUF_compress2() : @@ -111,7 +106,6 @@ HUF_PUBLIC_API size_t HUF_compress4X_wksp (void* dst, size_t dstCapacity, #define FSE_STATIC_LINKING_ONLY #include "fse.h" - /* *** Constants *** */ #define HUF_TABLELOG_MAX 12 /* max runtime value of tableLog (due to static allocation); can be modified up to HUF_TABLELOG_ABSOLUTEMAX */ #define HUF_TABLELOG_DEFAULT 11 /* default tableLog value when none specified */ @@ -122,7 +116,6 @@ HUF_PUBLIC_API size_t HUF_compress4X_wksp (void* dst, size_t dstCapacity, # error "HUF_TABLELOG_MAX is too large !" #endif - /* **************************************** * Static allocation ******************************************/ @@ -147,7 +140,6 @@ typedef U32 HUF_DTable; #define HUF_CREATE_STATIC_DTABLEX2(DTable, maxTableLog) \ HUF_DTable DTable[HUF_DTABLE_SIZE(maxTableLog)] = { ((U32)(maxTableLog) * 0x01000001) } - /* **************************************** * Advanced decompression functions ******************************************/ @@ -166,7 +158,6 @@ size_t HUF_decompress4X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /*< double-symbols decoder */ #endif - /* **************************************** * HUF detailed API * ****************************************/ @@ -293,7 +284,6 @@ size_t HUF_decompress4X1_usingDTable(void* dst, size_t maxDstSize, const void* c size_t HUF_decompress4X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); #endif - /* ====================== */ /* single stream variants */ /* ====================== */ diff --git a/lib/zstd/common/portability_macros.h b/lib/zstd/common/portability_macros.h index 0e3b2c0a527..b1cb945f275 100644 --- a/lib/zstd/common/portability_macros.h +++ b/lib/zstd/common/portability_macros.h @@ -20,7 +20,6 @@ * */ - /* compat. with non-clang compilers */ #ifndef __has_attribute #define __has_attribute(x) 0 diff --git a/lib/zstd/common/zstd_common.c b/lib/zstd/common/zstd_common.c index 3d7e35b309b..17df097dcd5 100644 --- a/lib/zstd/common/zstd_common.c +++ b/lib/zstd/common/zstd_common.c @@ -8,8 +8,6 @@ * You may select, at your option, one of the above-listed licenses. */ - - /*-************************************* * Dependencies ***************************************/ @@ -18,7 +16,6 @@ #include "error_private.h" #include "zstd_internal.h" - /*-**************************************** * Version ******************************************/ @@ -26,7 +23,6 @@ unsigned ZSTD_versionNumber(void) { return ZSTD_VERSION_NUMBER; } const char* ZSTD_versionString(void) { return ZSTD_VERSION_STRING; } - /*-**************************************** * ZSTD Error Management ******************************************/ @@ -48,8 +44,6 @@ ZSTD_ErrorCode ZSTD_getErrorCode(size_t code) { return ERR_getErrorCode(code); } * provides error code string from enum */ const char* ZSTD_getErrorString(ZSTD_ErrorCode code) { return ERR_getErrorString(code); } - - /*=************************************************************** * Custom allocator ****************************************************************/ diff --git a/lib/zstd/common/zstd_internal.h b/lib/zstd/common/zstd_internal.h index 93305d9b41b..c575c1fe8f4 100644 --- a/lib/zstd/common/zstd_internal.h +++ b/lib/zstd/common/zstd_internal.h @@ -33,14 +33,12 @@ #include <linux/xxhash.h> /* XXH_reset, update, digest */ #define ZSTD_TRACE 0 - /* ---- static assert (debug) --- */ #define ZSTD_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c) #define ZSTD_isError ERR_isError /* for inlining */ #define FSE_isError ERR_isError #define HUF_isError ERR_isError - /*-************************************* * shared macros ***************************************/ @@ -50,7 +48,6 @@ #define MAX(a,b) ((a)>(b) ? (a) : (b)) #define BOUNDED(min,val,max) (MAX(min,MIN(val,max))) - /*-************************************* * Common constants ***************************************/ @@ -155,7 +152,6 @@ static UNUSED_ATTR const S16 OF_defaultNorm[DefaultMaxOff+1] = { #define OF_DEFAULTNORMLOG 5 /* for static allocation */ static UNUSED_ATTR const U32 OF_defaultNormLog = OF_DEFAULTNORMLOG; - /*-******************************************* * Shared functions to include for inlining *********************************************/ @@ -269,7 +265,6 @@ typedef enum { ZSTD_bm_stable = 1 /* ZSTD_inBuffer/ZSTD_outBuffer is stable */ } ZSTD_bufferMode_e; - /*-******************************************* * Private declarations *********************************************/ @@ -349,7 +344,6 @@ void* ZSTD_customMalloc(size_t size, ZSTD_customMem customMem); void* ZSTD_customCalloc(size_t size, ZSTD_customMem customMem); void ZSTD_customFree(void* ptr, ZSTD_customMem customMem); - MEM_STATIC U32 ZSTD_highbit32(U32 val) /* compress, dictBuilder, decodeCorpus */ { assert(val != 0); @@ -404,14 +398,12 @@ MEM_STATIC unsigned ZSTD_countTrailingZeros(size_t val) } } - /* ZSTD_invalidateRepCodes() : * ensures next compression will not use repcodes from previous block. * Note : only works with regular variant; * do not use with extDict variant ! */ void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx); /* zstdmt, adaptive_compression (shouldn't get this definition from here) */ - typedef struct { blockType_e blockType; U32 lastBlock; @@ -439,5 +431,4 @@ MEM_STATIC int ZSTD_cpuSupportsBmi2(void) return ZSTD_cpuid_bmi1(cpuid) && ZSTD_cpuid_bmi2(cpuid); } - #endif /* ZSTD_CCOMMON_H_MODULE */ diff --git a/lib/zstd/decompress/huf_decompress.c b/lib/zstd/decompress/huf_decompress.c index 89b269a641c..e2d473ad4e8 100644 --- a/lib/zstd/decompress/huf_decompress.c +++ b/lib/zstd/decompress/huf_decompress.c @@ -69,14 +69,12 @@ ****************************************************************/ #define HUF_isError ERR_isError - /* ************************************************************** * Byte alignment for workSpace management ****************************************************************/ #define HUF_ALIGN(x, a) HUF_ALIGN_MASK((x), (a) - 1) #define HUF_ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask)) - /* ************************************************************** * BMI2 Variant Wrappers ****************************************************************/ @@ -121,7 +119,6 @@ #endif - /*-***************************/ /* generic DTableDesc */ /*-***************************/ @@ -268,7 +265,6 @@ static size_t HUF_initRemainingDStream(BIT_DStream_t* bit, HUF_DecompressAsmArgs } #endif - #ifndef HUF_FORCE_DECOMPRESS_X2 /*-***************************/ @@ -329,7 +325,6 @@ typedef struct { BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1]; } HUF_ReadDTableX1_Workspace; - size_t HUF_readDTableX1_wksp(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize) { return HUF_readDTableX1_wksp_bmi2(DTable, src, srcSize, workSpace, wkspSize, /* bmi2 */ 0); @@ -353,7 +348,6 @@ size_t HUF_readDTableX1_wksp_bmi2(HUF_DTable* DTable, const void* src, size_t sr iSize = HUF_readStats_wksp(wksp->huffWeight, HUF_SYMBOLVALUE_MAX + 1, wksp->rankVal, &nbSymbols, &tableLog, src, srcSize, wksp->statsWksp, sizeof(wksp->statsWksp), bmi2); if (HUF_isError(iSize)) return iSize; - /* Table header */ { DTableDesc dtd = HUF_getDTableDesc(DTable); U32 const maxTableLog = dtd.maxTableLog + 1; @@ -745,7 +739,6 @@ static size_t HUF_decompress4X1_usingDTable_internal(void* dst, size_t dstSize, #endif } - size_t HUF_decompress1X1_usingDTable( void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, @@ -770,7 +763,6 @@ size_t HUF_decompress1X1_DCtx_wksp(HUF_DTable* DCtx, void* dst, size_t dstSize, return HUF_decompress1X1_usingDTable_internal(dst, dstSize, ip, cSrcSize, DCtx, /* bmi2 */ 0); } - size_t HUF_decompress4X1_usingDTable( void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, @@ -802,10 +794,8 @@ size_t HUF_decompress4X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, return HUF_decompress4X1_DCtx_wksp_bmi2(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, 0); } - #endif /* HUF_FORCE_DECOMPRESS_X2 */ - #ifndef HUF_FORCE_DECOMPRESS_X1 /* *************************/ @@ -1130,7 +1120,6 @@ size_t HUF_readDTableX2_wksp_bmi2(HUF_DTable* DTable, return iSize; } - FORCE_INLINE_TEMPLATE U32 HUF_decodeSymbolX2(void* op, BIT_DStream_t* DStream, const HUF_DEltX2* dt, const U32 dtLog) { @@ -1477,7 +1466,6 @@ size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable* DCtx, void* dst, size_t dstSize, return HUF_decompress1X2_usingDTable_internal(dst, dstSize, ip, cSrcSize, DCtx, /* bmi2 */ 0); } - size_t HUF_decompress4X2_usingDTable( void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, @@ -1510,10 +1498,8 @@ size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, return HUF_decompress4X2_DCtx_wksp_bmi2(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, /* bmi2 */ 0); } - #endif /* HUF_FORCE_DECOMPRESS_X1 */ - /* ***********************************/ /* Universal decompression selectors */ /* ***********************************/ @@ -1556,7 +1542,6 @@ size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize, #endif } - #if !defined(HUF_FORCE_DECOMPRESS_X1) && !defined(HUF_FORCE_DECOMPRESS_X2) typedef struct { U32 tableTime; U32 decode256Time; } algo_time_t; static const algo_time_t algoTime[16 /* Quantization */][2 /* single, double */] = @@ -1610,7 +1595,6 @@ U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize) #endif } - size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, @@ -1667,7 +1651,6 @@ size_t HUF_decompress1X_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, } } - size_t HUF_decompress1X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int bmi2) { DTableDesc const dtd = HUF_getDTableDesc(DTable); diff --git a/lib/zstd/decompress/zstd_ddict.c b/lib/zstd/decompress/zstd_ddict.c index dbbc7919de5..db6aa722966 100644 --- a/lib/zstd/decompress/zstd_ddict.c +++ b/lib/zstd/decompress/zstd_ddict.c @@ -24,9 +24,6 @@ #include "zstd_decompress_internal.h" #include "zstd_ddict.h" - - - /*-******************************************************* * Types *********************************************************/ @@ -82,7 +79,6 @@ void ZSTD_copyDDictParameters(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict) } } - static size_t ZSTD_loadEntropy_intoDDict(ZSTD_DDict* ddict, ZSTD_dictContentType_e dictContentType) @@ -113,7 +109,6 @@ ZSTD_loadEntropy_intoDDict(ZSTD_DDict* ddict, return 0; } - static size_t ZSTD_initDDict_internal(ZSTD_DDict* ddict, const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, @@ -180,7 +175,6 @@ ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, size_t dictSize return ZSTD_createDDict_advanced(dictBuffer, dictSize, ZSTD_dlm_byRef, ZSTD_dct_auto, allocator); } - const ZSTD_DDict* ZSTD_initStaticDDict( void* sBuffer, size_t sBufferSize, const void* dict, size_t dictSize, @@ -205,7 +199,6 @@ const ZSTD_DDict* ZSTD_initStaticDDict( return ddict; } - size_t ZSTD_freeDDict(ZSTD_DDict* ddict) { if (ddict==NULL) return 0; /* support free on NULL */ diff --git a/lib/zstd/decompress/zstd_ddict.h b/lib/zstd/decompress/zstd_ddict.h index 8c1a79d666f..2ad60da2c4f 100644 --- a/lib/zstd/decompress/zstd_ddict.h +++ b/lib/zstd/decompress/zstd_ddict.h @@ -8,7 +8,6 @@ * You may select, at your option, one of the above-listed licenses. */ - #ifndef ZSTD_DDICT_H #define ZSTD_DDICT_H @@ -18,7 +17,6 @@ #include "../common/zstd_deps.h" /* size_t */ #include <linux/zstd.h> /* ZSTD_DDict, and several public functions */ - /*-******************************************************* * Interface *********************************************************/ @@ -39,6 +37,4 @@ size_t ZSTD_DDict_dictSize(const ZSTD_DDict* ddict); void ZSTD_copyDDictParameters(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict); - - #endif /* ZSTD_DDICT_H */ diff --git a/lib/zstd/decompress/zstd_decompress.c b/lib/zstd/decompress/zstd_decompress.c index b9b935a9f5c..6537824629c 100644 --- a/lib/zstd/decompress/zstd_decompress.c +++ b/lib/zstd/decompress/zstd_decompress.c @@ -8,7 +8,6 @@ * You may select, at your option, one of the above-listed licenses. */ - /* *************************************************************** * Tuning parameters *****************************************************************/ @@ -48,7 +47,6 @@ # define ZSTD_NO_FORWARD_PROGRESS_MAX 16 #endif - /*-******************************************************* * Dependencies *********************************************************/ @@ -64,9 +62,6 @@ #include "zstd_ddict.h" /* ZSTD_DDictDictContent */ #include "zstd_decompress_block.h" /* ZSTD_decompressBlock_internal */ - - - /* *********************************** * Multiple DDicts Hashset internals * *************************************/ @@ -220,7 +215,6 @@ size_t ZSTD_sizeof_DCtx (const ZSTD_DCtx* dctx) size_t ZSTD_estimateDCtxSize(void) { return sizeof(ZSTD_DCtx); } - static size_t ZSTD_startingInputLength(ZSTD_format_e format) { size_t const startingInputLength = ZSTD_FRAMEHEADERSIZE_PREFIX(format); @@ -353,7 +347,6 @@ static void ZSTD_DCtx_selectFrameDDict(ZSTD_DCtx* dctx) { } } - /*-************************************************************* * Frame header decoding ***************************************************************/ @@ -415,7 +408,6 @@ size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize) return ZSTD_frameHeaderSize_internal(src, srcSize, ZSTD_f_zstd1); } - /* ZSTD_getFrameHeader_advanced() : * decode Frame Header, or require larger `srcSize`. * note : only works for formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless @@ -639,7 +631,6 @@ unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize) return (ret >= ZSTD_CONTENTSIZE_ERROR) ? 0 : ret; } - /* ZSTD_decodeFrameHeader() : * `headerSize` must be the size provided by ZSTD_frameHeaderSize(). * If multiple DDict references are enabled, also will choose the correct DDict to use. @@ -681,7 +672,6 @@ static ZSTD_frameSizeInfo ZSTD_findFrameSizeInfo(const void* src, size_t srcSize ZSTD_frameSizeInfo frameSizeInfo; ZSTD_memset(&frameSizeInfo, 0, sizeof(ZSTD_frameSizeInfo)); - if ((srcSize >= ZSTD_SKIPPABLEHEADERSIZE) && (MEM_readLE32(src) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) { frameSizeInfo.compressedSize = readSkippableFrameSize(src, srcSize); @@ -773,7 +763,6 @@ unsigned long long ZSTD_decompressBound(const void* src, size_t srcSize) return bound; } - /*-************************************************************* * Frame decoding ***************************************************************/ @@ -788,7 +777,6 @@ size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, size_t blockSiz return blockSize; } - static size_t ZSTD_copyRawBlock(void* dst, size_t dstCapacity, const void* src, size_t srcSize) { @@ -823,7 +811,6 @@ static void ZSTD_DCtx_trace_end(ZSTD_DCtx const* dctx, U64 uncompressedSize, U64 (void)streaming; } - /*! ZSTD_decompressFrame() : * @dctx must be properly initialized * will update *srcPtr and *srcSizePtr, @@ -935,7 +922,6 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx, while (srcSize >= ZSTD_startingInputLength(dctx->format)) { - { U32 const magicNumber = MEM_readLE32(src); DEBUGLOG(4, "reading magic number %08X (expecting %08X)", (unsigned)magicNumber, ZSTD_MAGICNUMBER); @@ -994,7 +980,6 @@ size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx, return ZSTD_decompressMultiFrame(dctx, dst, dstCapacity, src, srcSize, dict, dictSize, NULL); } - static ZSTD_DDict const* ZSTD_getDDict(ZSTD_DCtx* dctx) { switch (dctx->dictUses) { @@ -1017,7 +1002,6 @@ size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const return ZSTD_decompress_usingDDict(dctx, dst, dstCapacity, src, srcSize, ZSTD_getDDict(dctx)); } - size_t ZSTD_decompress(void* dst, size_t dstCapacity, const void* src, size_t srcSize) { #if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE>=1) @@ -1034,7 +1018,6 @@ size_t ZSTD_decompress(void* dst, size_t dstCapacity, const void* src, size_t sr #endif } - /*-************************************** * Advanced Streaming Decompression API * Bufferless and synchronous @@ -1247,7 +1230,6 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c } } - static size_t ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSize) { dctx->dictEnd = dctx->previousDstEnd; @@ -1407,7 +1389,6 @@ size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t return 0; } - /* ====== ZSTD_DDict ====== */ size_t ZSTD_decompressBegin_usingDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict) @@ -1461,7 +1442,6 @@ unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize) return zfp.dictID; } - /*! ZSTD_decompress_usingDDict() : * Decompression using a pre-digested Dictionary * Use dictionary without significant overhead. */ @@ -1476,7 +1456,6 @@ size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx, ddict); } - /*===================================== * Streaming decompression *====================================*/ @@ -1502,7 +1481,6 @@ size_t ZSTD_freeDStream(ZSTD_DStream* zds) return ZSTD_freeDCtx(zds); } - /* *** Initialization *** */ size_t ZSTD_DStreamInSize(void) { return ZSTD_BLOCKSIZE_MAX + ZSTD_blockHeaderSize; } @@ -1546,7 +1524,6 @@ size_t ZSTD_DCtx_refPrefix(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSiz return ZSTD_DCtx_refPrefix_advanced(dctx, prefix, prefixSize, ZSTD_dct_rawContent); } - /* ZSTD_initDStream_usingDict() : * return : expected size, aka ZSTD_startingInputLength(). * this function cannot fail */ @@ -1584,7 +1561,6 @@ size_t ZSTD_resetDStream(ZSTD_DStream* dctx) return ZSTD_startingInputLength(dctx->format); } - size_t ZSTD_DCtx_refDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict) { RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong, ""); @@ -1745,7 +1721,6 @@ size_t ZSTD_DCtx_reset(ZSTD_DCtx* dctx, ZSTD_ResetDirective reset) return 0; } - size_t ZSTD_sizeof_DStream(const ZSTD_DStream* dctx) { return ZSTD_sizeof_DCtx(dctx); @@ -1783,7 +1758,6 @@ size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize) return ZSTD_estimateDStreamSize((size_t)zfh.windowSize); } - /* ***** Decompression ***** */ static int ZSTD_DCtx_isOverflow(ZSTD_DStream* zds, size_t const neededInBuffSize, size_t const neededOutBuffSize) diff --git a/lib/zstd/decompress/zstd_decompress_block.c b/lib/zstd/decompress/zstd_decompress_block.c index c1913b8e7c8..6e46a1bc524 100644 --- a/lib/zstd/decompress/zstd_decompress_block.c +++ b/lib/zstd/decompress/zstd_decompress_block.c @@ -40,13 +40,11 @@ #error "Cannot force the use of the short and the long ZSTD_decompressSequences variants!" #endif - /*_******************************************************* * Memory operations **********************************************************/ static void ZSTD_copy4(void* dst, const void* src) { ZSTD_memcpy(dst, src, 4); } - /*-************************************************************* * Block decoding ***************************************************************/ @@ -379,7 +377,6 @@ static const ZSTD_seqSymbol OF_defaultDTable[(1<<OF_DEFAULTNORMLOG)+1] = { { 0, 25, 5,33554429}, { 0, 24, 5,16777213}, }; /* OF_defaultDTable */ - /* Default FSE distribution table for Match Lengths */ static const ZSTD_seqSymbol ML_defaultDTable[(1<<ML_DEFAULTNORMLOG)+1] = { { 1, 1, 1, ML_DEFAULTNORMLOG}, /* header : fastMode, tableLog */ @@ -418,7 +415,6 @@ static const ZSTD_seqSymbol ML_defaultDTable[(1<<ML_DEFAULTNORMLOG)+1] = { { 0, 11, 6, 2051}, { 0, 10, 6, 1027}, }; /* ML_defaultDTable */ - static void ZSTD_buildSeqTable_rle(ZSTD_seqSymbol* dt, U32 baseValue, U8 nbAddBits) { void* ptr = dt; @@ -435,7 +431,6 @@ static void ZSTD_buildSeqTable_rle(ZSTD_seqSymbol* dt, U32 baseValue, U8 nbAddBi cell->baseValue = baseValue; } - /* ZSTD_buildFSETable() : * generate FSE decoding table for one symbol (ll, ml or off) * cannot fail if input is valid => @@ -454,7 +449,6 @@ void ZSTD_buildFSETable_body(ZSTD_seqSymbol* dt, BYTE* spread = (BYTE*)(symbolNext + MaxSeq + 1); U32 highThreshold = tableSize - 1; - /* Sanity Checks */ assert(maxSymbolValue <= MaxSeq); assert(tableLog <= MaxFSELog); @@ -598,7 +592,6 @@ void ZSTD_buildFSETable(ZSTD_seqSymbol* dt, baseValue, nbAdditionalBits, tableLog, wksp, wkspSize); } - /*! ZSTD_buildSeqTable() : * @return : nb bytes read from src, * or an error code if it fails */ @@ -729,7 +722,6 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr, return ip-istart; } - typedef struct { size_t litLength; size_t matchLength; @@ -915,7 +907,6 @@ size_t ZSTD_execSequenceEndSplitLitBuffer(BYTE* op, const BYTE* const iLitEnd = *litPtr + sequence.litLength; const BYTE* match = oLitEnd - sequence.offset; - /* bounds checks : careful of address space overflow in 32-bit mode */ RETURN_ERROR_IF(sequenceLength > (size_t)(oend - op), dstSize_tooSmall, "last match must fit within dstBuffer"); RETURN_ERROR_IF(sequence.litLength > (size_t)(litLimit - *litPtr), corruption_detected, "try to read beyond literal buffer"); @@ -1133,7 +1124,6 @@ size_t ZSTD_execSequenceSplitLitBuffer(BYTE* op, return sequenceLength; } - static void ZSTD_initFseState(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, const ZSTD_seqSymbol* dt) { @@ -1316,7 +1306,6 @@ MEM_STATIC void ZSTD_assertValidSequence( #ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG - FORCE_INLINE_TEMPLATE size_t DONT_VECTORIZE ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx, @@ -1841,8 +1830,6 @@ ZSTD_decompressSequencesLong_default(ZSTD_DCtx* dctx, } #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */ - - #if DYNAMIC_BMI2 #ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG @@ -1920,7 +1907,6 @@ ZSTD_decompressSequencesSplitLitBuffer(ZSTD_DCtx* dctx, void* dst, size_t maxDst } #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */ - #ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT /* ZSTD_decompressSequencesLong() : * decompression function triggered when a minimum share of offsets is considered "long", @@ -1944,8 +1930,6 @@ ZSTD_decompressSequencesLong(ZSTD_DCtx* dctx, } #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */ - - #if !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) && \ !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG) /* ZSTD_getLongOffsetsShare() : @@ -2048,7 +2032,6 @@ ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx, } } - void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst, size_t dstSize) { if (dst != dctx->previousDstEnd && dstSize > 0) { /* not contiguous */ @@ -2059,7 +2042,6 @@ void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst, size_t dstSize) } } - size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize) diff --git a/lib/zstd/decompress/zstd_decompress_block.h b/lib/zstd/decompress/zstd_decompress_block.h index 3d2d57a5d25..b8e912c6fd8 100644 --- a/lib/zstd/decompress/zstd_decompress_block.h +++ b/lib/zstd/decompress/zstd_decompress_block.h @@ -8,7 +8,6 @@ * You may select, at your option, one of the above-listed licenses. */ - #ifndef ZSTD_DEC_BLOCK_H #define ZSTD_DEC_BLOCK_H @@ -20,7 +19,6 @@ #include "../common/zstd_internal.h" /* blockProperties_t, and some public functions */ #include "zstd_decompress_internal.h" /* ZSTD_seqSymbol */ - /* === Prototypes === */ /* note: prototypes already published within `zstd.h` : @@ -32,7 +30,6 @@ * ZSTD_decodeSeqHeaders() */ - /* Streaming state is used to inform allocation of the literal buffer */ typedef enum { not_streaming = 0, @@ -64,5 +61,4 @@ void ZSTD_buildFSETable(ZSTD_seqSymbol* dt, unsigned tableLog, void* wksp, size_t wkspSize, int bmi2); - #endif /* ZSTD_DEC_BLOCK_H */ diff --git a/lib/zstd/decompress/zstd_decompress_internal.h b/lib/zstd/decompress/zstd_decompress_internal.h index 98102edb6a8..e165cbe9f59 100644 --- a/lib/zstd/decompress/zstd_decompress_internal.h +++ b/lib/zstd/decompress/zstd_decompress_internal.h @@ -8,22 +8,18 @@ * You may select, at your option, one of the above-listed licenses. */ - /* zstd_decompress_internal: * objects and definitions shared within lib/decompress modules */ #ifndef ZSTD_DECOMPRESS_INTERNAL_H #define ZSTD_DECOMPRESS_INTERNAL_H - /*-******************************************************* * Dependencies *********************************************************/ #include "../common/mem.h" /* BYTE, U16, U32 */ #include "../common/zstd_internal.h" /* constants : MaxLL, MaxML, MaxOff, LLFSELog, etc. */ - - /*-******************************************************* * Constants *********************************************************/ @@ -55,7 +51,6 @@ static UNUSED_ATTR const U32 ML_base[MaxML+1] = { 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803, 0x1003, 0x2003, 0x4003, 0x8003, 0x10003 }; - /*-******************************************************* * Decompression types *********************************************************/ @@ -224,5 +219,4 @@ size_t ZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy, * This function cannot fail. */ void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst, size_t dstSize); - #endif /* ZSTD_DECOMPRESS_INTERNAL_H */ |