diff options
Diffstat (limited to 'lib')
44 files changed, 660 insertions, 352 deletions
diff --git a/lib/Kconfig b/lib/Kconfig index 17954461114..b2aecd8a49e 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -317,6 +317,7 @@ config SPL_ACPI config GENERATE_ACPI_TABLE bool "Generate an ACPI (Advanced Configuration and Power Interface) table" depends on ACPI + select BLOBLIST select QFW if QEMU help The Advanced Configuration and Power Interface (ACPI) specification @@ -1257,6 +1258,27 @@ config PHANDLE_CHECK_SEQ enable this config option to distinguish them using phandles in fdtdec_get_alias_seq() function. +config UTHREAD + bool "Enable thread support" + depends on HAVE_INITJMP + help + Implement a simple form of cooperative multi-tasking based on + context-switching via initjmp(), setjmp() and longjmp(). The + uthread_ interface enables the main thread of execution to create + one or more secondary threads and schedule them until they all have + returned. At any point a thread may suspend its execution and + schedule another thread, which allows for the efficient multiplexing + of leghthy operations. + +config UTHREAD_STACK_SIZE + int "Default uthread stack size" + depends on UTHREAD + default 32768 + help + The default stack size for uthreads. Each uthread has its own stack. + When the stack_sz argument to uthread_create() is zero then this + value is used. + endmenu source "lib/fwu_updates/Kconfig" diff --git a/lib/Makefile b/lib/Makefile index a30ce1595d5..18ae0cd87bf 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -43,7 +43,6 @@ endif obj-$(CONFIG_SMBIOS_PARSER) += smbios-parser.o obj-$(CONFIG_IMAGE_SPARSE) += image-sparse.o -obj-y += initcall.o obj-y += ldiv.o obj-$(CONFIG_XXHASH) += xxhash.o obj-y += net_utils.o @@ -71,7 +70,7 @@ obj-y += crypto/ obj-$(CONFIG_$(PHASE_)ACPI) += acpi/ obj-$(CONFIG_ECDSA) += ecdsa/ -obj-$(CONFIG_$(XPL_)RSA) += rsa/ +obj-$(CONFIG_$(PHASE_)RSA) += rsa/ obj-$(CONFIG_HASH) += hash-checksum.o obj-$(CONFIG_BLAKE2) += blake2/blake2b.o @@ -82,7 +81,7 @@ obj-$(CONFIG_$(PHASE_)SHA256_LEGACY) += sha256.o obj-$(CONFIG_$(PHASE_)SHA512_LEGACY) += sha512.o obj-$(CONFIG_CRYPT_PW) += crypt/ -obj-$(CONFIG_$(XPL_)ASN1_DECODER_LEGACY) += asn1_decoder.o +obj-$(CONFIG_$(PHASE_)ASN1_DECODER_LEGACY) += asn1_decoder.o obj-$(CONFIG_$(PHASE_)ZLIB) += zlib/ obj-$(CONFIG_$(PHASE_)ZSTD) += zstd/ @@ -91,14 +90,14 @@ obj-$(CONFIG_$(PHASE_)LZO) += lzo/ obj-$(CONFIG_$(PHASE_)LZMA) += lzma/ obj-$(CONFIG_$(PHASE_)LZ4) += lz4_wrapper.o -obj-$(CONFIG_$(XPL_)LIB_RATIONAL) += rational.o +obj-$(CONFIG_$(PHASE_)LIB_RATIONAL) += rational.o obj-$(CONFIG_LIBAVB) += libavb/ obj-$(CONFIG_$(PHASE_)OF_LIBFDT) += libfdt/ obj-$(CONFIG_$(PHASE_)OF_REAL) += fdtdec_common.o fdtdec.o -obj-$(CONFIG_$(XPL_)MBEDTLS_LIB) += mbedtls/ +obj-$(CONFIG_$(PHASE_)MBEDTLS_LIB) += mbedtls/ obj-$(CONFIG_NET_LWIP) += lwip/ @@ -125,7 +124,7 @@ obj-y += hang.o obj-y += linux_compat.o obj-y += linux_string.o obj-$(CONFIG_$(PHASE_)LMB) += lmb.o -obj-y += membuff.o +obj-y += membuf.o obj-$(CONFIG_REGEX) += slre.o obj-y += string.o obj-y += tables_csum.o @@ -150,7 +149,7 @@ else obj-y += vsprintf.o strto.o obj-$(CONFIG_SSCANF) += sscanf.o endif -obj-$(CONFIG_$(XPL_)OID_REGISTRY) += oid_registry.o +obj-$(CONFIG_$(PHASE_)OID_REGISTRY) += oid_registry.o obj-y += abuf.o obj-y += alist.o @@ -160,6 +159,8 @@ obj-$(CONFIG_LIB_ELF) += elf.o obj-$(CONFIG_$(PHASE_)SEMIHOSTING) += semihosting.o +obj-$(CONFIG_UTHREAD) += uthread.o + # # Build a fast OID lookup registry from include/linux/oid_registry.h # diff --git a/lib/acpi/Makefile b/lib/acpi/Makefile index dcca0c67268..64f06deaf11 100644 --- a/lib/acpi/Makefile +++ b/lib/acpi/Makefile @@ -5,10 +5,10 @@ obj-y += acpi.o ifdef CONFIG_$(PHASE_)GENERATE_ACPI_TABLE -obj-$(CONFIG_$(XPL_)ACPIGEN) += acpigen.o -obj-$(CONFIG_$(XPL_)ACPIGEN) += acpi_device.o -obj-$(CONFIG_$(XPL_)ACPIGEN) += acpi_dp.o -obj-$(CONFIG_$(XPL_)ACPIGEN) += acpi_table.o +obj-$(CONFIG_$(PHASE_)ACPIGEN) += acpigen.o +obj-$(CONFIG_$(PHASE_)ACPIGEN) += acpi_device.o +obj-$(CONFIG_$(PHASE_)ACPIGEN) += acpi_dp.o +obj-$(CONFIG_$(PHASE_)ACPIGEN) += acpi_table.o obj-y += acpi_writer.o # With QEMU the ACPI tables come from there, not from U-Boot diff --git a/lib/acpi/acpi.c b/lib/acpi/acpi.c index f4d5c1e25d0..596301a43fe 100644 --- a/lib/acpi/acpi.c +++ b/lib/acpi/acpi.c @@ -6,11 +6,18 @@ */ #include <mapmem.h> +#include <tables_csum.h> #include <acpi/acpi_table.h> #include <asm/global_data.h> DECLARE_GLOBAL_DATA_PTR; +void acpi_update_checksum(struct acpi_table_header *header) +{ + header->checksum = 0; + header->checksum = table_compute_checksum(header, header->length); +} + struct acpi_table_header *acpi_find_table(const char *sig) { struct acpi_rsdp *rsdp; diff --git a/lib/acpi/acpi_table.c b/lib/acpi/acpi_table.c index c0ed24984af..43b71182133 100644 --- a/lib/acpi/acpi_table.c +++ b/lib/acpi/acpi_table.c @@ -66,6 +66,7 @@ int acpi_create_dmar(struct acpi_dmar *dmar, enum dmar_flags flags) dmar->host_address_width = info.address_width - 1; dmar->flags = flags; + header->checksum = table_compute_checksum(dmar, header->length); return 0; } @@ -195,9 +196,7 @@ int acpi_add_table(struct acpi_ctx *ctx, void *table) (sizeof(u32) * (i + 1)); /* Re-calculate checksum */ - rsdt->header.checksum = 0; - rsdt->header.checksum = table_compute_checksum((u8 *)rsdt, - rsdt->header.length); + acpi_update_checksum(&rsdt->header); } if (ctx->xsdt) { @@ -228,9 +227,7 @@ int acpi_add_table(struct acpi_ctx *ctx, void *table) (sizeof(u64) * (i + 1)); /* Re-calculate checksum */ - xsdt->header.checksum = 0; - xsdt->header.checksum = table_compute_checksum((u8 *)xsdt, - xsdt->header.length); + acpi_update_checksum(&xsdt->header); } return 0; @@ -255,8 +252,8 @@ int acpi_write_fadt(struct acpi_ctx *ctx, const struct acpi_writer *entry) header->creator_revision = 1; fadt->minor_revision = 2; - fadt->x_firmware_ctrl = map_to_sysmem(ctx->facs); - fadt->x_dsdt = map_to_sysmem(ctx->dsdt); + fadt->x_firmware_ctrl = nomap_to_sysmem(ctx->facs); + fadt->x_dsdt = nomap_to_sysmem(ctx->dsdt); if (fadt->x_firmware_ctrl < 0x100000000ULL) fadt->firmware_ctrl = fadt->x_firmware_ctrl; @@ -268,7 +265,7 @@ int acpi_write_fadt(struct acpi_ctx *ctx, const struct acpi_writer *entry) acpi_fill_fadt(fadt); - header->checksum = table_compute_checksum(fadt, header->length); + acpi_update_checksum(header); return acpi_add_fadt(ctx, fadt); } @@ -303,7 +300,7 @@ int acpi_write_madt(struct acpi_ctx *ctx, const struct acpi_writer *entry) if (IS_ENABLED(CONFIG_ACPI_PARKING_PROTOCOL)) acpi_write_park(madt); - header->checksum = table_compute_checksum((void *)madt, header->length); + acpi_update_checksum(header); acpi_add_table(ctx, madt); ctx->current = (void *)madt + madt->header.length; @@ -374,7 +371,7 @@ void acpi_create_dbg2(struct acpi_dbg2_header *dbg2, /* Update structure lengths and checksum */ device->length = current - (uintptr_t)device; header->length = current - (uintptr_t)dbg2; - header->checksum = table_compute_checksum(dbg2, header->length); + acpi_update_checksum(header); } int acpi_write_dbg2_pci_uart(struct acpi_ctx *ctx, struct udevice *dev, @@ -549,7 +546,7 @@ static int acpi_write_spcr(struct acpi_ctx *ctx, const struct acpi_writer *entry spcr->baud_rate = 0; /* Fix checksum */ - header->checksum = table_compute_checksum((void *)spcr, header->length); + acpi_update_checksum(header); acpi_add_table(ctx, spcr); acpi_inc(ctx, spcr->header.length); @@ -615,6 +612,7 @@ int acpi_iort_add_named_component(struct acpi_ctx *ctx, node->length += strlen(device_name) + 1; comp = (struct acpi_iort_named_component *)node->node_data; + memset(comp, '\0', sizeof(struct acpi_iort_named_component)); comp->node_flags = node_flags; comp->memory_properties = memory_properties; @@ -635,6 +633,7 @@ int acpi_iort_add_rc(struct acpi_ctx *ctx, const struct acpi_iort_id_mapping *map) { struct acpi_iort_id_mapping *mapping; + struct acpi_iort_node *output_node; struct acpi_iort_node *node; struct acpi_iort_rc *rc; int offset; @@ -646,12 +645,18 @@ int acpi_iort_add_rc(struct acpi_ctx *ctx, node->type = ACPI_IORT_NODE_PCI_ROOT_COMPLEX; node->revision = 2; + node->mapping_count = num_mappings; + if (num_mappings) + node->mapping_offset = sizeof(struct acpi_iort_node) + + sizeof(struct acpi_iort_rc); node->length = sizeof(struct acpi_iort_node); node->length += sizeof(struct acpi_iort_rc); node->length += sizeof(struct acpi_iort_id_mapping) * num_mappings; rc = (struct acpi_iort_rc *)node->node_data; + memset(rc, '\0', sizeof(struct acpi_iort_rc)); + rc->mem_access_properties = mem_access_properties; rc->ats_attributes = ats_attributes; rc->pci_segment_number = pci_segment_number; @@ -659,6 +664,13 @@ int acpi_iort_add_rc(struct acpi_ctx *ctx, mapping = (struct acpi_iort_id_mapping *)(rc + 1); for (int i = 0; i < num_mappings; i++) { + /* Validate input */ + output_node = (struct acpi_iort_node *)ctx->tab_start + map[i].output_reference; + /* ID mappings can use SMMUs or ITS groups as output references */ + assert(output_node && ((output_node->type == ACPI_IORT_NODE_ITS_GROUP) || + (output_node->type == ACPI_IORT_NODE_SMMU) || + (output_node->type == ACPI_IORT_NODE_SMMU_V3))); + memcpy(mapping, &map[i], sizeof(struct acpi_iort_id_mapping)); mapping++; } @@ -683,6 +695,7 @@ int acpi_iort_add_smmu_v3(struct acpi_ctx *ctx, const struct acpi_iort_id_mapping *map) { struct acpi_iort_node *node; + struct acpi_iort_node *output_node; struct acpi_iort_smmu_v3 *smmu; struct acpi_iort_id_mapping *mapping; int offset; @@ -695,13 +708,16 @@ int acpi_iort_add_smmu_v3(struct acpi_ctx *ctx, node->type = ACPI_IORT_NODE_SMMU_V3; node->revision = 5; node->mapping_count = num_mappings; - node->mapping_offset = sizeof(struct acpi_iort_node) + sizeof(struct acpi_iort_smmu_v3); + if (num_mappings) + node->mapping_offset = sizeof(struct acpi_iort_node) + + sizeof(struct acpi_iort_smmu_v3); node->length = sizeof(struct acpi_iort_node); node->length += sizeof(struct acpi_iort_smmu_v3); node->length += sizeof(struct acpi_iort_id_mapping) * num_mappings; smmu = (struct acpi_iort_smmu_v3 *)node->node_data; + memset(smmu, '\0', sizeof(struct acpi_iort_smmu_v3)); smmu->base_address = base_address; smmu->flags = flags; @@ -716,6 +732,14 @@ int acpi_iort_add_smmu_v3(struct acpi_ctx *ctx, mapping = (struct acpi_iort_id_mapping *)(smmu + 1); for (int i = 0; i < num_mappings; i++) { + /* Validate input */ + output_node = (struct acpi_iort_node *)ctx->tab_start + map[i].output_reference; + /* + * ID mappings of an SMMUv3 node can only have ITS group nodes + * as output references. + */ + assert(output_node && output_node->type == ACPI_IORT_NODE_ITS_GROUP); + memcpy(mapping, &map[i], sizeof(struct acpi_iort_id_mapping)); mapping++; } @@ -759,7 +783,7 @@ static int acpi_write_iort(struct acpi_ctx *ctx, const struct acpi_writer *entry /* (Re)calculate length and checksum */ iort->header.length = ctx->current - (void *)iort; - iort->header.checksum = table_compute_checksum((void *)iort, iort->header.length); + acpi_update_checksum(&iort->header); log_debug("IORT at %p, length %x\n", iort, iort->header.length); /* Drop the table if it is empty */ diff --git a/lib/acpi/base.c b/lib/acpi/base.c index 8b6af2bc43a..5c755b14c16 100644 --- a/lib/acpi/base.c +++ b/lib/acpi/base.c @@ -50,8 +50,7 @@ static void acpi_write_rsdt(struct acpi_rsdt *rsdt) /* Entries are filled in later, we come with an empty set */ /* Fix checksum */ - header->checksum = table_compute_checksum(rsdt, - sizeof(struct acpi_rsdt)); + acpi_update_checksum(header); } static void acpi_write_xsdt(struct acpi_xsdt *xsdt) @@ -66,8 +65,7 @@ static void acpi_write_xsdt(struct acpi_xsdt *xsdt) /* Entries are filled in later, we come with an empty set */ /* Fix checksum */ - header->checksum = table_compute_checksum(xsdt, - sizeof(struct acpi_xsdt)); + acpi_update_checksum(header); } static int acpi_write_base(struct acpi_ctx *ctx, diff --git a/lib/acpi/csrt.c b/lib/acpi/csrt.c index 00927e53406..b863c644c07 100644 --- a/lib/acpi/csrt.c +++ b/lib/acpi/csrt.c @@ -40,7 +40,7 @@ int acpi_write_csrt(struct acpi_ctx *ctx, const struct acpi_writer *entry) /* (Re)calculate length and checksum */ header->length = (ulong)ctx->current - (ulong)csrt; - header->checksum = table_compute_checksum(csrt, header->length); + acpi_update_checksum(header); acpi_add_table(ctx, csrt); diff --git a/lib/acpi/mcfg.c b/lib/acpi/mcfg.c index 8b8a5bfafae..e21fe7ce123 100644 --- a/lib/acpi/mcfg.c +++ b/lib/acpi/mcfg.c @@ -57,7 +57,7 @@ int acpi_write_mcfg(struct acpi_ctx *ctx, const struct acpi_writer *entry) /* (Re)calculate length and checksum */ header->length = (ulong)ctx->current - (ulong)mcfg; - header->checksum = table_compute_checksum(mcfg, header->length); + acpi_update_checksum(header); acpi_add_table(ctx, mcfg); diff --git a/lib/acpi/ssdt.c b/lib/acpi/ssdt.c index df1d739d117..41e2d3c2f6c 100644 --- a/lib/acpi/ssdt.c +++ b/lib/acpi/ssdt.c @@ -35,7 +35,7 @@ int acpi_write_ssdt(struct acpi_ctx *ctx, const struct acpi_writer *entry) /* (Re)calculate length and checksum */ ssdt->length = ctx->current - (void *)ssdt; - ssdt->checksum = table_compute_checksum((void *)ssdt, ssdt->length); + acpi_update_checksum(ssdt); log_debug("SSDT at %p, length %x\n", ssdt, ssdt->length); /* Drop the table if it is empty */ diff --git a/lib/aes/Makefile b/lib/aes/Makefile index ad6228a7dad..41ebdd06044 100644 --- a/lib/aes/Makefile +++ b/lib/aes/Makefile @@ -2,4 +2,4 @@ # # Copyright (c) 2019, Softathome -obj-$(CONFIG_$(XPL_)FIT_CIPHER) += aes-decrypt.o +obj-$(CONFIG_$(PHASE_)FIT_CIPHER) += aes-decrypt.o diff --git a/lib/crypto/Makefile b/lib/crypto/Makefile index b729824df3c..ac2b9a7d72f 100644 --- a/lib/crypto/Makefile +++ b/lib/crypto/Makefile @@ -3,17 +3,17 @@ # Makefile for asymmetric cryptographic keys # -obj-$(CONFIG_$(XPL_)ASYMMETRIC_KEY_TYPE) += asymmetric_keys.o +obj-$(CONFIG_$(PHASE_)ASYMMETRIC_KEY_TYPE) += asymmetric_keys.o asymmetric_keys-y := asymmetric_type.o -obj-$(CONFIG_$(XPL_)ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key_helper.o -obj-$(CONFIG_$(XPL_)ASYMMETRIC_PUBLIC_KEY_LEGACY) += public_key.o +obj-$(CONFIG_$(PHASE_)ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key_helper.o +obj-$(CONFIG_$(PHASE_)ASYMMETRIC_PUBLIC_KEY_LEGACY) += public_key.o # # RSA public key parser # -obj-$(CONFIG_$(XPL_)RSA_PUBLIC_KEY_PARSER_LEGACY) += rsa_public_key.o +obj-$(CONFIG_$(PHASE_)RSA_PUBLIC_KEY_PARSER_LEGACY) += rsa_public_key.o rsa_public_key-y := \ rsapubkey.asn1.o \ rsa_helper.o @@ -31,9 +31,9 @@ endif # # X.509 Certificate handling # -obj-$(CONFIG_$(XPL_)X509_CERTIFICATE_PARSER) += x509_key_parser.o +obj-$(CONFIG_$(PHASE_)X509_CERTIFICATE_PARSER) += x509_key_parser.o x509_key_parser-y := x509_helper.o -x509_key_parser-$(CONFIG_$(XPL_)X509_CERTIFICATE_PARSER_LEGACY) += \ +x509_key_parser-$(CONFIG_$(PHASE_)X509_CERTIFICATE_PARSER_LEGACY) += \ x509.asn1.o \ x509_akid.asn1.o \ x509_cert_parser.o \ @@ -49,21 +49,21 @@ $(obj)/x509_akid.asn1.o: $(obj)/x509_akid.asn1.c $(obj)/x509_akid.asn1.h # # PKCS#7 message handling # -obj-$(CONFIG_$(XPL_)PKCS7_MESSAGE_PARSER) += pkcs7_message.o +obj-$(CONFIG_$(PHASE_)PKCS7_MESSAGE_PARSER) += pkcs7_message.o pkcs7_message-y := pkcs7_helper.o -pkcs7_message-$(CONFIG_$(SPL_)PKCS7_MESSAGE_PARSER_LEGACY) += \ +pkcs7_message-$(CONFIG_$(PHASE_)PKCS7_MESSAGE_PARSER_LEGACY) += \ pkcs7.asn1.o \ pkcs7_parser.o $(obj)/pkcs7_parser.o: $(obj)/pkcs7.asn1.h $(obj)/pkcs7.asn1.o: $(obj)/pkcs7.asn1.c $(obj)/pkcs7.asn1.h -obj-$(CONFIG_$(XPL_)PKCS7_VERIFY) += pkcs7_verify.o +obj-$(CONFIG_$(PHASE_)PKCS7_VERIFY) += pkcs7_verify.o # # Signed PE binary-wrapped key handling # -obj-$(CONFIG_$(XPL_)MSCODE_PARSER_LEGACY) += mscode.o +obj-$(CONFIG_$(PHASE_)MSCODE_PARSER_LEGACY) += mscode.o mscode-y := \ mscode_parser.o \ diff --git a/lib/ecdsa/Makefile b/lib/ecdsa/Makefile index 32b6183f6ff..9db9f7b17b9 100644 --- a/lib/ecdsa/Makefile +++ b/lib/ecdsa/Makefile @@ -1 +1 @@ -obj-$(CONFIG_$(XPL_)ECDSA_VERIFY) += ecdsa-verify.o +obj-$(CONFIG_$(PHASE_)ECDSA_VERIFY) += ecdsa-verify.o diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 6130af14337..7f02a83e2a2 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -305,7 +305,6 @@ config EFI_CAPSULE_FIRMWARE_FIT depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT select UPDATE_FIT select DFU - select SET_DFU_ALT_INFO select EFI_CAPSULE_FIRMWARE help Select this option if you want to enable firmware management protocol @@ -317,7 +316,6 @@ config EFI_CAPSULE_FIRMWARE_RAW depends on SANDBOX || (!SANDBOX && !EFI_CAPSULE_FIRMWARE_FIT) select DFU_WRITE_ALT select DFU - select SET_DFU_ALT_INFO select EFI_CAPSULE_FIRMWARE help Select this option if you want to enable firmware management protocol diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index 2a0b4172bd7..cf050e5385d 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -29,6 +29,7 @@ obj-y += efi_boottime.o obj-y += efi_helper.o obj-$(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) += efi_capsule.o obj-$(CONFIG_EFI_CAPSULE_FIRMWARE) += efi_firmware.o +obj-$(CONFIG_EFI_CAPSULE_AUTHENTICATE) += efi_capsule_key.o obj-y += efi_console.o obj-y += efi_device_path.o obj-$(CONFIG_EFI_DEVICE_PATH_TO_TEXT) += efi_device_path_to_text.o @@ -36,7 +37,7 @@ 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-$(CONFIG_EFI_LOADER_HII) += efi_hii.o efi_hii_config.o obj-y += efi_image_loader.o obj-y += efi_load_options.o obj-y += efi_memory.o @@ -73,6 +74,23 @@ obj-$(CONFIG_EFI_ECPT) += efi_conformance.o EFI_VAR_SEED_FILE := $(subst $\",,$(CONFIG_EFI_VAR_SEED_FILE)) $(obj)/efi_var_seed.o: $(srctree)/$(EFI_VAR_SEED_FILE) +ifeq ($(CONFIG_EFI_CAPSULE_AUTHENTICATE),y) +capsule_crt_path=($(subst $(quote),,$(CONFIG_EFI_CAPSULE_CRT_FILE))) +capsule_crt_full=$(srctree)/$(subst $(quote),,$(CONFIG_EFI_CAPSULE_CRT_FILE)) +quiet_cmd_capsule_esl_gen = CAPSULE_ESL_GEN $@ +cmd_capsule_esl_gen = cert-to-efi-sig-list $(capsule_crt_full) $@ +$(objtree)/capsule_esl_file: FORCE + @if [ ! -e "$(capsule_crt_full)" ]; then \ + echo "ERROR: path $(capsule_crt_full) is invalid." >&2; \ + echo "EFI CONFIG_EFI_CAPSULE_CRT_FILE must be specified when CONFIG_EFI_CAPSULE_AUTHENTICATE is enabled." >&2; \ + exit 1; \ + fi + $(call cmd,capsule_esl_gen) + +$(obj)/efi_capsule.o: $(objtree)/capsule_esl_file FORCE +asflags-y += -DCAPSULE_ESL_PATH=\"$(objtree)/capsule_esl_file\" +endif + # Set the C flags to add and remove for each app $(foreach f,$(apps-y),\ $(eval CFLAGS_$(f).o := $(CFLAGS_EFI) -Os -ffreestanding)\ diff --git a/lib/efi_loader/capsule_esl.dtsi.in b/lib/efi_loader/capsule_esl.dtsi.in deleted file mode 100644 index bc7db836faa..00000000000 --- a/lib/efi_loader/capsule_esl.dtsi.in +++ /dev/null @@ -1,11 +0,0 @@ -// 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/efi_acpi.c b/lib/efi_loader/efi_acpi.c index 4422b31ac6a..046986a7518 100644 --- a/lib/efi_loader/efi_acpi.c +++ b/lib/efi_loader/efi_acpi.c @@ -7,6 +7,7 @@ #define LOG_CATEGORY LOGC_EFI +#include <bloblist.h> #include <efi_loader.h> #include <log.h> #include <mapmem.h> @@ -34,25 +35,38 @@ efi_status_t efi_acpi_register(void) * add_u_boot_and_runtime(). At some point that function could create a * more detailed map. */ - if (IS_ENABLED(CONFIG_BLOBLIST_TABLES)) - return EFI_SUCCESS; - - /* Mark space used for tables */ - start = ALIGN_DOWN(gd->arch.table_start, EFI_PAGE_MASK); - end = ALIGN(gd->arch.table_end, EFI_PAGE_MASK); - ret = efi_add_memory_map(start, end - start, EFI_ACPI_RECLAIM_MEMORY); - if (ret != EFI_SUCCESS) - return ret; - if (gd->arch.table_start_high) { - start = ALIGN_DOWN(gd->arch.table_start_high, EFI_PAGE_MASK); - end = ALIGN(gd->arch.table_end_high, EFI_PAGE_MASK); + if (IS_ENABLED(CONFIG_BLOBLIST_TABLES)) { + int size; + void *tab = bloblist_get_blob(BLOBLISTT_ACPI_TABLES, &size); + + if (!tab) + return EFI_NOT_FOUND; + addr = map_to_sysmem(tab); + + ret = efi_add_memory_map(addr, size, + EFI_ACPI_RECLAIM_MEMORY); + if (ret != EFI_SUCCESS) + return ret; + } else { + /* Mark space used for tables */ + start = ALIGN_DOWN(gd->arch.table_start, EFI_PAGE_MASK); + end = ALIGN(gd->arch.table_end, EFI_PAGE_MASK); ret = efi_add_memory_map(start, end - start, EFI_ACPI_RECLAIM_MEMORY); if (ret != EFI_SUCCESS) return ret; - } + if (gd->arch.table_start_high) { + start = ALIGN_DOWN(gd->arch.table_start_high, + EFI_PAGE_MASK); + end = ALIGN(gd->arch.table_end_high, EFI_PAGE_MASK); + ret = efi_add_memory_map(start, end - start, + EFI_ACPI_RECLAIM_MEMORY); + if (ret != EFI_SUCCESS) + return ret; + } - addr = gd_acpi_start(); + addr = gd_acpi_start(); + } log_debug("EFI using ACPI tables at %lx\n", addr); /* And expose them to our EFI payload */ diff --git a/lib/efi_loader/efi_bootbin.c b/lib/efi_loader/efi_bootbin.c index deafb2ce1c2..d0f7da309ce 100644 --- a/lib/efi_loader/efi_bootbin.c +++ b/lib/efi_loader/efi_bootbin.c @@ -204,6 +204,8 @@ out: * @image: memory address of the UEFI image * @size: size of the UEFI image * @fdt: device-tree + * @initrd: initrd + * @initrd_sz: initrd size * @dp_dev: EFI device-path * @dp_img: EFI image-path * @@ -213,10 +215,12 @@ out: * Return: status code */ static efi_status_t efi_binary_run_dp(void *image, size_t size, void *fdt, + void *initrd, size_t initd_sz, struct efi_device_path *dp_dev, struct efi_device_path *dp_img) { efi_status_t ret; + struct efi_device_path *dp_initrd; /* Initialize EFI drivers */ ret = efi_init_obj_list(); @@ -230,6 +234,14 @@ static efi_status_t efi_binary_run_dp(void *image, size_t size, void *fdt, if (ret != EFI_SUCCESS) return ret; + dp_initrd = efi_dp_from_mem(EFI_LOADER_DATA, (uintptr_t)initrd, initd_sz); + if (!dp_initrd) + return EFI_OUT_OF_RESOURCES; + + ret = efi_initrd_register(dp_initrd); + if (ret != EFI_SUCCESS) + return ret; + return efi_run_image(image, size, dp_dev, dp_img); } @@ -239,13 +251,15 @@ static efi_status_t efi_binary_run_dp(void *image, size_t size, void *fdt, * @image: memory address of the UEFI image * @size: size of the UEFI image * @fdt: device-tree + * @initrd: initrd + * @initrd_sz: initrd size * * Execute an EFI binary image loaded at @image. * @size may be zero if the binary is loaded with U-Boot load command. * * Return: status code */ -efi_status_t efi_binary_run(void *image, size_t size, void *fdt) +efi_status_t efi_binary_run(void *image, size_t size, void *fdt, void *initrd, size_t initrd_sz) { efi_handle_t mem_handle = NULL; struct efi_device_path *file_path = NULL; @@ -269,11 +283,14 @@ efi_status_t efi_binary_run(void *image, size_t size, void *fdt) file_path, NULL); if (ret != EFI_SUCCESS) goto out; + + bootefi_device_path = file_path; + bootefi_image_path = NULL; } else { log_debug("Loaded from disk\n"); } - ret = efi_binary_run_dp(image, size, fdt, bootefi_device_path, + ret = efi_binary_run_dp(image, size, fdt, initrd, initrd_sz, bootefi_device_path, bootefi_image_path); out: if (mem_handle) { @@ -355,7 +372,7 @@ efi_status_t efi_bootflow_run(struct bootflow *bflow) log_debug("Booting with external fdt\n"); fdt = map_sysmem(bflow->fdt_addr, 0); } - ret = efi_binary_run_dp(bflow->buf, bflow->size, fdt, device, image); + ret = efi_binary_run_dp(bflow->buf, bflow->size, fdt, NULL, 0, device, image); return ret; } diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c index f9534ef85ed..c0df5cb9acd 100644 --- a/lib/efi_loader/efi_bootmgr.c +++ b/lib/efi_loader/efi_bootmgr.c @@ -685,12 +685,12 @@ static efi_status_t try_load_entry(u16 n, efi_handle_t *handle, /* try to register load file2 for initrd's */ if (IS_ENABLED(CONFIG_EFI_LOAD_FILE2_INITRD)) { - ret = efi_initrd_register(); + ret = efi_initrd_register(NULL); if (ret != EFI_SUCCESS) goto error; } - log_info("Booting: %ls\n", lo.label); + log_info("Booting: Label: %ls Device path: %pD\n", lo.label, lo.file_path); /* Ignore the optional data in auto-generated boot options */ if (size >= sizeof(efi_guid_t) && diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index c8d9a6037f7..dbebb37dc04 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -15,6 +15,7 @@ #include <irq_func.h> #include <log.h> #include <malloc.h> +#include <net-common.h> #include <pe.h> #include <time.h> #include <u-boot/crc.h> @@ -2231,6 +2232,8 @@ static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle, if (!efi_st_keep_devices) { bootm_disable_interrupts(); + if (IS_ENABLED(CONFIG_DM_ETH)) + eth_halt(); board_quiesce_devices(); dm_remove_devices_active(); } @@ -3192,7 +3195,7 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle, struct efi_loaded_image_obj *image_obj = (struct efi_loaded_image_obj *)image_handle; efi_status_t ret; - void *info; + struct efi_loaded_image *info; efi_handle_t parent_image = current_image; efi_status_t exit_status; jmp_buf exit_jmp; @@ -3210,7 +3213,7 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle, return EFI_EXIT(EFI_SECURITY_VIOLATION); ret = EFI_CALL(efi_open_protocol(image_handle, &efi_guid_loaded_image, - &info, NULL, NULL, + (void **)&info, NULL, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL)); if (ret != EFI_SUCCESS) return EFI_EXIT(EFI_INVALID_PARAMETER); @@ -3263,7 +3266,8 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle, current_image = image_handle; image_obj->header.type = EFI_OBJECT_TYPE_STARTED_IMAGE; - EFI_PRINT("Jumping into 0x%p\n", image_obj->entry); + EFI_PRINT("Starting image loaded at 0x%p, entry point 0x%p\n", + info->image_base, image_obj->entry); ret = EFI_CALL(image_obj->entry(image_handle, &systab)); /* diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c index f8a4a7c6ef4..1aa52ac7bb6 100644 --- a/lib/efi_loader/efi_capsule.c +++ b/lib/efi_loader/efi_capsule.c @@ -22,6 +22,7 @@ #include <asm/global_data.h> #include <u-boot/uuid.h> +#include <asm/sections.h> #include <crypto/pkcs7.h> #include <crypto/pkcs7_parser.h> #include <linux/err.h> @@ -284,33 +285,12 @@ out: } #if defined(CONFIG_EFI_CAPSULE_AUTHENTICATE) -int efi_get_public_key_data(void **pkey, efi_uintn_t *pkey_len) +static int efi_get_public_key_data(const void **pkey, efi_uintn_t *pkey_len) { - const void *fdt_blob = gd->fdt_blob; - const void *blob; - const char *cnode_name = "capsule-key"; - const char *snode_name = "signature"; - int sig_node; - int len; - - sig_node = fdt_subnode_offset(fdt_blob, 0, snode_name); - if (sig_node < 0) { - log_err("Unable to get signature node offset\n"); - - return -FDT_ERR_NOTFOUND; - } - - blob = fdt_getprop(fdt_blob, sig_node, cnode_name, &len); - - if (!blob || len < 0) { - log_err("Unable to get capsule-key value\n"); - *pkey = NULL; - *pkey_len = 0; - - return -FDT_ERR_NOTFOUND; - } + const void *blob = __efi_capsule_sig_begin; + const int len = __efi_capsule_sig_end - __efi_capsule_sig_begin; - *pkey = (void *)blob; + *pkey = blob; *pkey_len = len; return 0; @@ -321,7 +301,8 @@ efi_status_t efi_capsule_authenticate(const void *capsule, efi_uintn_t capsule_s { u8 *buf; int ret; - void *fdt_pkey, *pkey; + void *pkey; + const void *stored_pkey; efi_uintn_t pkey_len; uint64_t monotonic_count; struct efi_signature_store *truststore; @@ -373,7 +354,7 @@ efi_status_t efi_capsule_authenticate(const void *capsule, efi_uintn_t capsule_s goto out; } - ret = efi_get_public_key_data(&fdt_pkey, &pkey_len); + ret = efi_get_public_key_data(&stored_pkey, &pkey_len); if (ret < 0) goto out; @@ -381,7 +362,7 @@ efi_status_t efi_capsule_authenticate(const void *capsule, efi_uintn_t capsule_s if (!pkey) goto out; - memcpy(pkey, fdt_pkey, pkey_len); + memcpy(pkey, stored_pkey, pkey_len); truststore = efi_build_signature_store(pkey, pkey_len); if (!truststore) goto out; diff --git a/lib/efi_loader/efi_capsule_key.S b/lib/efi_loader/efi_capsule_key.S new file mode 100644 index 00000000000..80cefbe16ae --- /dev/null +++ b/lib/efi_loader/efi_capsule_key.S @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * .esl cert for capsule authentication + * + * Copyright (c) 2021, Ilias Apalodimas <ilias.apalodimas@linaro.org> + */ + +#include <config.h> + +.section .rodata.capsule_key.init,"a" +.balign 16 +.global __efi_capsule_sig_begin +__efi_capsule_sig_begin: +.incbin CAPSULE_ESL_PATH +__efi_capsule_sig_end: +.global __efi_capsule_sig_end +.balign 16 diff --git a/lib/efi_loader/efi_device_path_to_text.c b/lib/efi_loader/efi_device_path_to_text.c index f6889cb7399..452ec1b2e8b 100644 --- a/lib/efi_loader/efi_device_path_to_text.c +++ b/lib/efi_loader/efi_device_path_to_text.c @@ -181,10 +181,13 @@ static char *dp_msging(char *s, struct efi_device_path *dp) switch (idp->protocol) { case IPPROTO_TCP: s += sprintf(s, "TCP,"); + break; case IPPROTO_UDP: s += sprintf(s, "UDP,"); + break; default: s += sprintf(s, "0x%x,", idp->protocol); + break; } s += sprintf(s, idp->static_ip_address ? "Static" : "DHCP"); s += sprintf(s, ",%pI4", &idp->local_ip_address); diff --git a/lib/efi_loader/efi_dt_fixup.c b/lib/efi_loader/efi_dt_fixup.c index 26928cfc454..544e1aa9808 100644 --- a/lib/efi_loader/efi_dt_fixup.c +++ b/lib/efi_loader/efi_dt_fixup.c @@ -168,7 +168,7 @@ efi_dt_fixup(struct efi_dt_fixup_protocol *this, void *dtb, /* Check size */ required_size = fdt_off_dt_strings(dtb) + fdt_size_dt_strings(dtb) + - 0x3000; + CONFIG_SYS_FDT_PAD; total_size = fdt_totalsize(dtb); if (required_size < total_size) required_size = total_size; diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index 5a754c9cd03..d44dc09813e 100644 --- a/lib/efi_loader/efi_firmware.c +++ b/lib/efi_loader/efi_firmware.c @@ -56,11 +56,6 @@ struct fmp_state { u32 last_attempt_status; /* not used */ }; -__weak void set_dfu_alt_info(char *interface, char *devstr) -{ - env_set("dfu_alt_info", update_info.dfu_string); -} - /** * efi_firmware_get_image_type_id - get image_type_id * @image_index: image index @@ -649,8 +644,10 @@ efi_status_t EFIAPI efi_firmware_fit_set_image( efi_status_t (*progress)(efi_uintn_t completion), u16 **abort_reason) { + int ret; efi_status_t status; struct fmp_state state = { 0 }; + char *orig_dfu_env; EFI_ENTRY("%p %d %p %zu %p %p %p\n", this, image_index, image, image_size, vendor_code, progress, abort_reason); @@ -663,7 +660,28 @@ efi_status_t EFIAPI efi_firmware_fit_set_image( if (status != EFI_SUCCESS) return EFI_EXIT(status); - if (fit_update(image)) + orig_dfu_env = env_get("dfu_alt_info"); + if (orig_dfu_env) { + orig_dfu_env = strdup(orig_dfu_env); + if (!orig_dfu_env) { + log_err("strdup() failed!\n"); + return EFI_EXIT(EFI_OUT_OF_RESOURCES); + } + } + if (env_set("dfu_alt_info", update_info.dfu_string)) { + log_err("Unable to set env variable \"dfu_alt_info\"!\n"); + free(orig_dfu_env); + return EFI_EXIT(EFI_DEVICE_ERROR); + } + + ret = fit_update(image); + + if (env_set("dfu_alt_info", orig_dfu_env)) + log_warning("Unable to restore env variable \"dfu_alt_info\". Further DFU operations may fail!\n"); + + free(orig_dfu_env); + + if (ret) return EFI_EXIT(EFI_DEVICE_ERROR); efi_firmware_set_fmp_state_var(&state, image_index); @@ -717,6 +735,7 @@ efi_status_t EFIAPI efi_firmware_raw_set_image( u8 dfu_alt_num; efi_status_t status; struct fmp_state state = { 0 }; + char *orig_dfu_env; EFI_ENTRY("%p %d %p %zu %p %p %p\n", this, image_index, image, image_size, vendor_code, progress, abort_reason); @@ -747,8 +766,29 @@ efi_status_t EFIAPI efi_firmware_raw_set_image( } } - if (dfu_write_by_alt(dfu_alt_num, (void *)image, image_size, - NULL, NULL)) + orig_dfu_env = env_get("dfu_alt_info"); + if (orig_dfu_env) { + orig_dfu_env = strdup(orig_dfu_env); + if (!orig_dfu_env) { + log_err("strdup() failed!\n"); + return EFI_EXIT(EFI_OUT_OF_RESOURCES); + } + } + if (env_set("dfu_alt_info", update_info.dfu_string)) { + log_err("Unable to set env variable \"dfu_alt_info\"!\n"); + free(orig_dfu_env); + return EFI_EXIT(EFI_DEVICE_ERROR); + } + + ret = dfu_write_by_alt(dfu_alt_num, (void *)image, image_size, + NULL, NULL); + + if (env_set("dfu_alt_info", orig_dfu_env)) + log_warning("Unable to restore env variable \"dfu_alt_info\". Further DFU operations may fail!\n"); + + free(orig_dfu_env); + + if (ret) return EFI_EXIT(EFI_DEVICE_ERROR); efi_firmware_set_fmp_state_var(&state, image_index); diff --git a/lib/efi_loader/efi_helper.c b/lib/efi_loader/efi_helper.c index 8c32059edda..3936139ca41 100644 --- a/lib/efi_loader/efi_helper.c +++ b/lib/efi_loader/efi_helper.c @@ -485,7 +485,7 @@ static efi_status_t copy_fdt(void **fdtp) * needs to be expanded later. */ fdt = *fdtp; - fdt_pages = efi_size_in_pages(fdt_totalsize(fdt) + 0x3000); + fdt_pages = efi_size_in_pages(fdt_totalsize(fdt) + CONFIG_SYS_FDT_PAD); fdt_size = fdt_pages << EFI_PAGE_SHIFT; ret = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES, diff --git a/lib/efi_loader/efi_hii.c b/lib/efi_loader/efi_hii.c index 44235970a7c..330d7c5830b 100644 --- a/lib/efi_loader/efi_hii.c +++ b/lib/efi_loader/efi_hii.c @@ -343,6 +343,9 @@ static struct efi_hii_packagelist *new_packagelist(void) struct efi_hii_packagelist *hii; hii = malloc(sizeof(*hii)); + if (!hii) + return NULL; + list_add_tail(&hii->link, &efi_package_lists); hii->max_string_id = 0; INIT_LIST_HEAD(&hii->string_tables); diff --git a/lib/efi_loader/efi_hii_config.c b/lib/efi_loader/efi_hii_config.c index 37d8c6629e2..521481a86d8 100644 --- a/lib/efi_loader/efi_hii_config.c +++ b/lib/efi_loader/efi_hii_config.c @@ -4,10 +4,6 @@ * * Copyright (c) 2017 Leif Lindholm * Copyright (c) 2018 AKASHI Takahiro, Linaro Limited - * - * As this is still a non-working stub and the protocol is neither required - * by the EFI shell nor by the UEFI SCT this module has been removed from - * the Makefile. */ #define LOG_CATEGORY LOGC_EFI diff --git a/lib/efi_loader/efi_load_initrd.c b/lib/efi_loader/efi_load_initrd.c index fb8cc7bcbe3..b5d58943a80 100644 --- a/lib/efi_loader/efi_load_initrd.c +++ b/lib/efi_loader/efi_load_initrd.c @@ -42,6 +42,7 @@ static const struct efi_lo_dp_prefix dp_lf2_handle = { }; static efi_handle_t efi_initrd_handle; +static struct efi_device_path *efi_initrd_dp; /** * get_initrd_fp() - Get initrd device path from a FilePathList device path @@ -73,6 +74,41 @@ static efi_status_t get_initrd_fp(struct efi_device_path **initrd_fp) } /** + * efi_initrd_from_mem() - load initial RAM disk from memory + * + * This function copies the initrd from the memory mapped device + * path pointed to by efi_initrd_dp + * + * @buffer_size: size of allocated buffer + * @buffer: buffer to load the file + * + * Return: status code + */ +static efi_status_t efi_initrd_from_mem(efi_uintn_t *buffer_size, void *buffer) +{ + efi_status_t ret = EFI_NOT_FOUND; + efi_uintn_t bs; + struct efi_device_path_memory *mdp; + + mdp = (struct efi_device_path_memory *)efi_initrd_dp; + if (!mdp) + return ret; + + bs = mdp->end_address - mdp->start_address; + + if (!buffer || *buffer_size < bs) { + ret = EFI_BUFFER_TOO_SMALL; + *buffer_size = bs; + } else { + memcpy(buffer, (void *)(uintptr_t)mdp->start_address, bs); + *buffer_size = bs; + ret = EFI_SUCCESS; + } + + return ret; +} + +/** * efi_load_file2_initrd() - load initial RAM disk * * This function implements the LoadFile service of the EFI_LOAD_FILE2_PROTOCOL @@ -118,6 +154,9 @@ efi_load_file2_initrd(struct efi_load_file_protocol *this, goto out; } + if (efi_initrd_dp) + return EFI_EXIT(efi_initrd_from_mem(buffer_size, buffer)); + ret = get_initrd_fp(&initrd_fp); if (ret != EFI_SUCCESS) goto out; @@ -209,6 +248,9 @@ efi_status_t efi_initrd_deregister(void) NULL); efi_initrd_handle = NULL; + efi_free_pool(efi_initrd_dp); + efi_initrd_dp = NULL; + return ret; } @@ -234,24 +276,31 @@ static void EFIAPI efi_initrd_return_notify(struct efi_event *event, * This function creates a new handle and installs a Linux specific vendor * device path and an EFI_LOAD_FILE2_PROTOCOL. Linux uses the device path * to identify the handle and then calls the LoadFile service of the - * EFI_LOAD_FILE2_PROTOCOL to read the initial RAM disk. + * EFI_LOAD_FILE2_PROTOCOL to read the initial RAM disk. If dp_initrd is + * not provided, the initrd will be taken from the BootCurrent variable + * + * @dp_initrd: optional device path containing an initrd * * Return: status code */ -efi_status_t efi_initrd_register(void) +efi_status_t efi_initrd_register(struct efi_device_path *dp_initrd) { efi_status_t ret; struct efi_event *event; - /* - * Allow the user to continue if Boot#### file path is not set for - * an initrd - */ - ret = check_initrd(); - if (ret == EFI_INVALID_PARAMETER) - return EFI_SUCCESS; - if (ret != EFI_SUCCESS) - return ret; + if (dp_initrd) { + efi_initrd_dp = dp_initrd; + } else { + /* + * Allow the user to continue if Boot#### file path is not set for + * an initrd + */ + ret = check_initrd(); + if (ret == EFI_INVALID_PARAMETER) + return EFI_SUCCESS; + if (ret != EFI_SUCCESS) + return ret; + } ret = efi_install_multiple_protocol_interfaces(&efi_initrd_handle, /* initramfs */ diff --git a/lib/efi_loader/efi_root_node.c b/lib/efi_loader/efi_root_node.c index 74225edad29..e5246f65df2 100644 --- a/lib/efi_loader/efi_root_node.c +++ b/lib/efi_loader/efi_root_node.c @@ -80,6 +80,9 @@ efi_status_t efi_root_node_register(void) /* HII database protocol */ &efi_guid_hii_database_protocol, &efi_hii_database, + /* EFI HII Configuration Routing Protocol */ + &efi_guid_hii_config_routing_protocol, + &efi_hii_config_routing, #endif NULL); efi_root->type = EFI_OBJECT_TYPE_U_BOOT_FIRMWARE; diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile index 17fbfad116f..d78bf7d6191 100644 --- a/lib/efi_selftest/Makefile +++ b/lib/efi_selftest/Makefile @@ -51,6 +51,7 @@ efi_selftest_variables_runtime.o \ efi_selftest_watchdog.o obj-$(CONFIG_EFI_ECPT) += efi_selftest_ecpt.o +obj-$(CONFIG_ARM64) += efi_selftest_el.o obj-$(CONFIG_NETDEVICES) += efi_selftest_snp.o obj-$(CONFIG_EFI_HTTP_PROTOCOL) += efi_selftest_http.o obj-$(CONFIG_EFI_HTTP_PROTOCOL) += efi_selftest_ipconfig.o diff --git a/lib/efi_selftest/efi_selftest_el.c b/lib/efi_selftest/efi_selftest_el.c new file mode 100644 index 00000000000..f9941caf22d --- /dev/null +++ b/lib/efi_selftest/efi_selftest_el.c @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Check current exception level on ARMv8. + */ +#include <efi_loader.h> +#include <efi_selftest.h> + +/** + * current_exception_level() + * + * Return: current exception level, 0 - 3 + */ +static unsigned int current_exception_level(void) +{ + unsigned long el; + + asm volatile ( + "MRS %0, CurrentEL" + : "=r" (el) : : ); + + return (el >> 2) & 0x3; +} + +/** + * execute() - execute test + * + * Check that the exception level is not EL3. + */ +static int execute(void) +{ + unsigned int el = current_exception_level(); + + efi_st_printf("Exception level EL%u\n", el); + if (el != 1 && el != 2) { + efi_st_error("EL1 or EL2 expected"); + return EFI_ST_FAILURE; + } + + return EFI_ST_SUCCESS; +} + +EFI_UNIT_TEST(el) = { + .name = "exception level", + .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, + .execute = execute, +}; diff --git a/lib/efi_selftest/efi_selftest_hii.c b/lib/efi_selftest/efi_selftest_hii.c index c363df466dc..228dc296950 100644 --- a/lib/efi_selftest/efi_selftest_hii.c +++ b/lib/efi_selftest/efi_selftest_hii.c @@ -609,14 +609,12 @@ static int test_hii_database_get_package_list_handle(void) result = EFI_ST_SUCCESS; out: - if (handle) { - ret = hii_database_protocol->remove_package_list( - hii_database_protocol, handle); - if (ret != EFI_SUCCESS) { - efi_st_error("remove_package_list returned %u\n", - (unsigned int)ret); - return EFI_ST_FAILURE; - } + ret = hii_database_protocol->remove_package_list( + hii_database_protocol, handle); + if (ret != EFI_SUCCESS) { + efi_st_error("remove_package_list returned %u\n", + (unsigned int)ret); + return EFI_ST_FAILURE; } return result; @@ -711,14 +709,12 @@ static int test_hii_string_new_string(void) result = EFI_ST_SUCCESS; out: - if (handle) { - ret = hii_database_protocol->remove_package_list( - hii_database_protocol, handle); - if (ret != EFI_SUCCESS) { - efi_st_error("remove_package_list returned %u\n", - (unsigned int)ret); - return EFI_ST_FAILURE; - } + ret = hii_database_protocol->remove_package_list( + hii_database_protocol, handle); + if (ret != EFI_SUCCESS) { + efi_st_error("remove_package_list returned %u\n", + (unsigned int)ret); + return EFI_ST_FAILURE; } return result; @@ -792,14 +788,12 @@ static int test_hii_string_get_string(void) result = EFI_ST_SUCCESS; out: - if (handle) { - ret = hii_database_protocol->remove_package_list( - hii_database_protocol, handle); - if (ret != EFI_SUCCESS) { - efi_st_error("remove_package_list returned %u\n", - (unsigned int)ret); - return EFI_ST_FAILURE; - } + ret = hii_database_protocol->remove_package_list( + hii_database_protocol, handle); + if (ret != EFI_SUCCESS) { + efi_st_error("remove_package_list returned %u\n", + (unsigned int)ret); + return EFI_ST_FAILURE; } return result; @@ -851,14 +845,12 @@ static int test_hii_string_set_string(void) result = EFI_ST_SUCCESS; out: - if (handle) { - ret = hii_database_protocol->remove_package_list( - hii_database_protocol, handle); - if (ret != EFI_SUCCESS) { - efi_st_error("remove_package_list returned %u\n", - (unsigned int)ret); - return EFI_ST_FAILURE; - } + ret = hii_database_protocol->remove_package_list( + hii_database_protocol, handle); + if (ret != EFI_SUCCESS) { + efi_st_error("remove_package_list returned %u\n", + (unsigned int)ret); + return EFI_ST_FAILURE; } return result; @@ -918,14 +910,12 @@ static int test_hii_string_get_languages(void) result = EFI_ST_SUCCESS; out: - if (handle) { - ret = hii_database_protocol->remove_package_list( - hii_database_protocol, handle); - if (ret != EFI_SUCCESS) { - efi_st_error("remove_package_list returned %u\n", - (unsigned int)ret); - return EFI_ST_FAILURE; - } + ret = hii_database_protocol->remove_package_list( + hii_database_protocol, handle); + if (ret != EFI_SUCCESS) { + efi_st_error("remove_package_list returned %u\n", + (unsigned int)ret); + return EFI_ST_FAILURE; } return result; @@ -991,14 +981,12 @@ static int test_hii_string_get_secondary_languages(void) result = EFI_ST_SUCCESS; out: - if (handle) { - ret = hii_database_protocol->remove_package_list( - hii_database_protocol, handle); - if (ret != EFI_SUCCESS) { - efi_st_error("remove_package_list returned %u\n", - (unsigned int)ret); - return EFI_ST_FAILURE; - } + ret = hii_database_protocol->remove_package_list( + hii_database_protocol, handle); + if (ret != EFI_SUCCESS) { + efi_st_error("remove_package_list returned %u\n", + (unsigned int)ret); + return EFI_ST_FAILURE; } return result; diff --git a/lib/fdtdec.c b/lib/fdtdec.c index f09c9926a7a..c38738b48c7 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1708,7 +1708,7 @@ int fdtdec_setup(void) gd->fdt_src = FDTSRC_BLOBLIST; log_debug("Devicetree is in bloblist at %p\n", gd->fdt_blob); - ret = 0; + goto setup_fdt; } else { log_debug("No FDT found in bloblist\n"); ret = -ENOENT; @@ -1752,6 +1752,7 @@ int fdtdec_setup(void) } } +setup_fdt: if (CONFIG_IS_ENABLED(MULTI_DTB_FIT)) setup_multi_dtb_fit(); diff --git a/lib/initcall.c b/lib/initcall.c deleted file mode 100644 index 2686b9aed5c..00000000000 --- a/lib/initcall.c +++ /dev/null @@ -1,102 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (c) 2013 The Chromium OS Authors. - */ - -#include <efi.h> -#include <initcall.h> -#include <log.h> -#include <relocate.h> -#include <asm/global_data.h> - -DECLARE_GLOBAL_DATA_PTR; - -static ulong calc_reloc_ofs(void) -{ -#ifdef CONFIG_EFI_APP - return (ulong)image_base; -#endif - /* - * Sandbox is relocated by the OS, so symbols always appear at - * the relocated address. - */ - if (IS_ENABLED(CONFIG_SANDBOX) || (gd->flags & GD_FLG_RELOC)) - return gd->reloc_off; - - return 0; -} - -/** - * initcall_is_event() - Get the event number for an initcall - * - * func: Function pointer to check - * Return: Event number, if this is an event, else 0 - */ -static int initcall_is_event(init_fnc_t func) -{ - ulong val = (ulong)func; - - if ((val & INITCALL_IS_EVENT) == INITCALL_IS_EVENT) - return val & INITCALL_EVENT_TYPE; - - return 0; -} - -/* - * To enable debugging. add #define DEBUG at the top of the including file. - * - * To find a symbol, use grep on u-boot.map - */ -int initcall_run_list(const init_fnc_t init_sequence[]) -{ - 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) { - if (!CONFIG_IS_ENABLED(EVENT)) - continue; - debug("initcall: event %d/%s\n", type, - event_type_name(type)); - } else if (reloc_ofs) { - debug("initcall: %p (relocated to %p)\n", - (char *)func - reloc_ofs, (char *)func); - } else { - debug("initcall: %p\n", (char *)func - reloc_ofs); - } - - ret = type ? event_notify_null(type) : func(); - if (ret) - break; - } - - if (ret) { - if (CONFIG_IS_ENABLED(EVENT)) { - char buf[60]; - - /* don't worry about buf size as we are dying here */ - if (type) { - sprintf(buf, "event %d/%s", type, - event_type_name(type)); - } else { - sprintf(buf, "call %p", - (char *)func - reloc_ofs); - } - - printf("initcall failed at %s (err=%dE)\n", buf, ret); - } else { - printf("initcall failed at call %p (err=%d)\n", - (char *)func - reloc_ofs, ret); - } - - return ret; - } - - return 0; -} diff --git a/lib/lwip/Makefile b/lib/lwip/Makefile index fe2b64c9acc..e9e8caee93a 100644 --- a/lib/lwip/Makefile +++ b/lib/lwip/Makefile @@ -54,5 +54,5 @@ obj-y += \ lwip/src/core/udp.o \ lwip/src/netif/ethernet.o -obj-$(CONFIG_$(XPL_)MBEDTLS_LIB_TLS) += lwip/src/apps/altcp_tls/altcp_tls_mbedtls.o \ +obj-$(CONFIG_$(PHASE_)MBEDTLS_LIB_TLS) += lwip/src/apps/altcp_tls/altcp_tls_mbedtls.o \ lwip/src/apps/altcp_tls/altcp_tls_mbedtls_mem.o diff --git a/lib/mbedtls/Makefile b/lib/mbedtls/Makefile index 4bbe7ceec45..c5b445bd85c 100644 --- a/lib/mbedtls/Makefile +++ b/lib/mbedtls/Makefile @@ -6,19 +6,19 @@ MBEDTLS_LIB_DIR = external/mbedtls/library # shim layer for hash -obj-$(CONFIG_$(XPL_)MD5_MBEDTLS) += md5.o -obj-$(CONFIG_$(XPL_)SHA1_MBEDTLS) += sha1.o -obj-$(CONFIG_$(XPL_)SHA256_MBEDTLS) += sha256.o -obj-$(CONFIG_$(XPL_)SHA512_MBEDTLS) += sha512.o +obj-$(CONFIG_$(PHASE_)MD5_MBEDTLS) += md5.o +obj-$(CONFIG_$(PHASE_)SHA1_MBEDTLS) += sha1.o +obj-$(CONFIG_$(PHASE_)SHA256_MBEDTLS) += sha256.o +obj-$(CONFIG_$(PHASE_)SHA512_MBEDTLS) += sha512.o # x509 libraries -obj-$(CONFIG_$(XPL_)ASYMMETRIC_PUBLIC_KEY_MBEDTLS) += \ +obj-$(CONFIG_$(PHASE_)ASYMMETRIC_PUBLIC_KEY_MBEDTLS) += \ public_key.o -obj-$(CONFIG_$(XPL_)X509_CERTIFICATE_PARSER_MBEDTLS) += \ +obj-$(CONFIG_$(PHASE_)X509_CERTIFICATE_PARSER_MBEDTLS) += \ x509_cert_parser.o -obj-$(CONFIG_$(XPL_)PKCS7_MESSAGE_PARSER_MBEDTLS) += pkcs7_parser.o -obj-$(CONFIG_$(XPL_)MSCODE_PARSER_MBEDTLS) += mscode_parser.o -obj-$(CONFIG_$(XPL_)RSA_PUBLIC_KEY_PARSER_MBEDTLS) += rsa_helper.o +obj-$(CONFIG_$(PHASE_)PKCS7_MESSAGE_PARSER_MBEDTLS) += pkcs7_parser.o +obj-$(CONFIG_$(PHASE_)MSCODE_PARSER_MBEDTLS) += mscode_parser.o +obj-$(CONFIG_$(PHASE_)RSA_PUBLIC_KEY_PARSER_MBEDTLS) += rsa_helper.o # MbedTLS crypto library obj-$(CONFIG_$(XPL_)MBEDTLS_LIB) += mbedtls_lib_crypto.o @@ -27,35 +27,35 @@ mbedtls_lib_crypto-y := \ $(MBEDTLS_LIB_DIR)/constant_time.o \ $(MBEDTLS_LIB_DIR)/md.o -mbedtls_lib_crypto-$(CONFIG_$(XPL_)MD5_MBEDTLS) += $(MBEDTLS_LIB_DIR)/md5.o -mbedtls_lib_crypto-$(CONFIG_$(XPL_)SHA1_MBEDTLS) += $(MBEDTLS_LIB_DIR)/sha1.o -mbedtls_lib_crypto-$(CONFIG_$(XPL_)SHA256_MBEDTLS) += \ +mbedtls_lib_crypto-$(CONFIG_$(PHASE_)MD5_MBEDTLS) += $(MBEDTLS_LIB_DIR)/md5.o +mbedtls_lib_crypto-$(CONFIG_$(PHASE_)SHA1_MBEDTLS) += $(MBEDTLS_LIB_DIR)/sha1.o +mbedtls_lib_crypto-$(CONFIG_$(PHASE_)SHA256_MBEDTLS) += \ $(MBEDTLS_LIB_DIR)/sha256.o -mbedtls_lib_crypto-$(CONFIG_$(XPL_)SHA512_MBEDTLS) += \ +mbedtls_lib_crypto-$(CONFIG_$(PHASE_)SHA512_MBEDTLS) += \ $(MBEDTLS_LIB_DIR)/sha512.o -mbedtls_lib_crypto-$(CONFIG_$(XPL_)HKDF_MBEDTLS) += \ +mbedtls_lib_crypto-$(CONFIG_$(PHASE_)HKDF_MBEDTLS) += \ $(MBEDTLS_LIB_DIR)/hkdf.o # MbedTLS X509 library obj-$(CONFIG_$(XPL_)MBEDTLS_LIB_X509) += mbedtls_lib_x509.o mbedtls_lib_x509-y := $(MBEDTLS_LIB_DIR)/x509.o -mbedtls_lib_x509-$(CONFIG_$(XPL_)ASN1_DECODER_MBEDTLS) += \ +mbedtls_lib_x509-$(CONFIG_$(PHASE_)ASN1_DECODER_MBEDTLS) += \ $(MBEDTLS_LIB_DIR)/asn1parse.o \ $(MBEDTLS_LIB_DIR)/asn1write.o \ $(MBEDTLS_LIB_DIR)/oid.o -mbedtls_lib_x509-$(CONFIG_$(XPL_)RSA_PUBLIC_KEY_PARSER_MBEDTLS) += \ +mbedtls_lib_x509-$(CONFIG_$(PHASE_)RSA_PUBLIC_KEY_PARSER_MBEDTLS) += \ $(MBEDTLS_LIB_DIR)/bignum.o \ $(MBEDTLS_LIB_DIR)/bignum_core.o \ $(MBEDTLS_LIB_DIR)/rsa.o \ $(MBEDTLS_LIB_DIR)/rsa_alt_helpers.o -mbedtls_lib_x509-$(CONFIG_$(XPL_)ASYMMETRIC_PUBLIC_KEY_MBEDTLS) += \ +mbedtls_lib_x509-$(CONFIG_$(PHASE_)ASYMMETRIC_PUBLIC_KEY_MBEDTLS) += \ $(MBEDTLS_LIB_DIR)/pk.o \ $(MBEDTLS_LIB_DIR)/pk_wrap.o \ $(MBEDTLS_LIB_DIR)/pkparse.o -mbedtls_lib_x509-$(CONFIG_$(XPL_)X509_CERTIFICATE_PARSER_MBEDTLS) += \ +mbedtls_lib_x509-$(CONFIG_$(PHASE_)X509_CERTIFICATE_PARSER_MBEDTLS) += \ $(MBEDTLS_LIB_DIR)/x509_crl.o \ $(MBEDTLS_LIB_DIR)/x509_crt.o -mbedtls_lib_x509-$(CONFIG_$(XPL_)PKCS7_MESSAGE_PARSER_MBEDTLS) += \ +mbedtls_lib_x509-$(CONFIG_$(PHASE_)PKCS7_MESSAGE_PARSER_MBEDTLS) += \ $(MBEDTLS_LIB_DIR)/pkcs7.o #mbedTLS TLS support diff --git a/lib/mbedtls/pkcs7_parser.c b/lib/mbedtls/pkcs7_parser.c index ecfcc46edfa..bf8ee17b5b8 100644 --- a/lib/mbedtls/pkcs7_parser.c +++ b/lib/mbedtls/pkcs7_parser.c @@ -189,10 +189,6 @@ static int authattrs_parse(struct pkcs7_message *msg, void *aa, size_t aa_len, len)) { if (__test_and_set_bit(sinfo_has_smime_caps, &sinfo->aa_set)) return -EINVAL; - - if (msg->data_type != OID_msIndirectData && - msg->data_type != OID_data) - return -EINVAL; } else if (!MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_MICROSOFT_SPOPUSINFO, inner_p, len)) { if (__test_and_set_bit(sinfo_has_ms_opus_info, &sinfo->aa_set)) diff --git a/lib/membuff.c b/lib/membuf.c index b242a38ff1c..f38ff36cb0b 100644 --- a/lib/membuff.c +++ b/lib/membuf.c @@ -9,17 +9,17 @@ #include <errno.h> #include <log.h> #include <malloc.h> -#include "membuff.h" +#include "membuf.h" -void membuff_purge(struct membuff *mb) +void membuf_purge(struct membuf *mb) { /* set mb->head and mb->tail so the buffers look empty */ mb->head = mb->start; mb->tail = mb->start; } -static int membuff_putrawflex(struct membuff *mb, int maxlen, bool update, - char ***data, int *offsetp) +static int membuf_putrawflex(struct membuf *mb, int maxlen, bool update, + char ***data, int *offsetp) { int len; @@ -72,30 +72,30 @@ static int membuff_putrawflex(struct membuff *mb, int maxlen, bool update, return len; } -int membuff_putraw(struct membuff *mb, int maxlen, bool update, char **data) +int membuf_putraw(struct membuf *mb, int maxlen, bool update, char **data) { char **datap; int offset; int size; - size = membuff_putrawflex(mb, maxlen, update, &datap, &offset); + size = membuf_putrawflex(mb, maxlen, update, &datap, &offset); *data = *datap + offset; return size; } -bool membuff_putbyte(struct membuff *mb, int ch) +bool membuf_putbyte(struct membuf *mb, int ch) { char *data; - if (membuff_putraw(mb, 1, true, &data) != 1) + if (membuf_putraw(mb, 1, true, &data) != 1) return false; *data = ch; return true; } -int membuff_getraw(struct membuff *mb, int maxlen, bool update, char **data) +int membuf_getraw(struct membuf *mb, int maxlen, bool update, char **data) { int len; @@ -146,21 +146,21 @@ int membuff_getraw(struct membuff *mb, int maxlen, bool update, char **data) return len; } -int membuff_getbyte(struct membuff *mb) +int membuf_getbyte(struct membuf *mb) { char *data = 0; - return membuff_getraw(mb, 1, true, &data) != 1 ? -1 : *(uint8_t *)data; + return membuf_getraw(mb, 1, true, &data) != 1 ? -1 : *(uint8_t *)data; } -int membuff_peekbyte(struct membuff *mb) +int membuf_peekbyte(struct membuf *mb) { char *data = 0; - return membuff_getraw(mb, 1, false, &data) != 1 ? -1 : *(uint8_t *)data; + return membuf_getraw(mb, 1, false, &data) != 1 ? -1 : *(uint8_t *)data; } -int membuff_get(struct membuff *mb, char *buff, int maxlen) +int membuf_get(struct membuf *mb, char *buff, int maxlen) { char *data = 0, *buffptr = buff; int len = 1, i; @@ -171,7 +171,7 @@ int membuff_get(struct membuff *mb, char *buff, int maxlen) */ for (i = 0; len && i < 2; i++) { /* get a pointer to the data available */ - len = membuff_getraw(mb, maxlen, true, &data); + len = membuf_getraw(mb, maxlen, true, &data); /* copy it into the buffer */ memcpy(buffptr, data, len); @@ -183,14 +183,14 @@ int membuff_get(struct membuff *mb, char *buff, int maxlen) return buffptr - buff; } -int membuff_put(struct membuff *mb, const char *buff, int length) +int membuf_put(struct membuf *mb, const char *buff, int length) { char *data; int towrite, i, written; for (i = written = 0; i < 2; i++) { /* ask where some data can be written */ - towrite = membuff_putraw(mb, length, true, &data); + towrite = membuf_putraw(mb, length, true, &data); /* and write it, updating the bytes length */ memcpy(data, buff, towrite); @@ -203,14 +203,14 @@ int membuff_put(struct membuff *mb, const char *buff, int length) return written; } -bool membuff_isempty(struct membuff *mb) +bool membuf_isempty(struct membuf *mb) { return mb->head == mb->tail; } -int membuff_avail(struct membuff *mb) +int membuf_avail(struct membuf *mb) { - struct membuff copy; + struct membuf copy; int i, avail; char *data = 0; @@ -219,18 +219,18 @@ int membuff_avail(struct membuff *mb) /* now read everything out of the copied buffer */ for (i = avail = 0; i < 2; i++) - avail += membuff_getraw(©, -1, true, &data); + avail += membuf_getraw(©, -1, true, &data); /* and return how much we read */ return avail; } -int membuff_size(struct membuff *mb) +int membuf_size(struct membuf *mb) { return mb->end - mb->start; } -bool membuff_makecontig(struct membuff *mb) +bool membuf_makecontig(struct membuf *mb) { int topsize, botsize; @@ -281,13 +281,14 @@ bool membuff_makecontig(struct membuff *mb) return true; } -int membuff_free(struct membuff *mb) +int membuf_free(struct membuf *mb) { return mb->end == mb->start ? 0 : - (mb->end - mb->start) - 1 - membuff_avail(mb); + (mb->end - mb->start) - 1 - membuf_avail(mb); } -int membuff_readline(struct membuff *mb, char *str, int maxlen, int minch, bool must_fit) +int membuf_readline(struct membuf *mb, char *str, int maxlen, int minch, + bool must_fit) { int len; /* number of bytes read (!= string length) */ char *s, *end; @@ -322,7 +323,7 @@ int membuff_readline(struct membuff *mb, char *str, int maxlen, int minch, bool return len; } -int membuff_extend_by(struct membuff *mb, int by, int max) +int membuf_extend_by(struct membuf *mb, int by, int max) { int oldhead, oldtail; int size, orig; @@ -358,32 +359,32 @@ int membuff_extend_by(struct membuff *mb, int by, int max) return 0; } -void membuff_init(struct membuff *mb, char *buff, int size) +void membuf_init(struct membuf *mb, char *buff, int size) { mb->start = buff; mb->end = mb->start + size; - membuff_purge(mb); + membuf_purge(mb); } -int membuff_new(struct membuff *mb, int size) +int membuf_new(struct membuf *mb, int size) { mb->start = malloc(size); if (!mb->start) return -ENOMEM; - membuff_init(mb, mb->start, size); + membuf_init(mb, mb->start, size); return 0; } -void membuff_uninit(struct membuff *mb) +void membuf_uninit(struct membuf *mb) { mb->end = NULL; mb->start = NULL; - membuff_purge(mb); + membuf_purge(mb); } -void membuff_dispose(struct membuff *mb) +void membuf_dispose(struct membuf *mb) { - free(&mb->start); - membuff_uninit(mb); + free(mb->start); + membuf_uninit(mb); } diff --git a/lib/smbios.c b/lib/smbios.c index 7c9701a57f9..b8c2846277a 100644 --- a/lib/smbios.c +++ b/lib/smbios.c @@ -950,7 +950,7 @@ ulong write_smbios_table(ulong addr) ctx.subnode_name = NULL; if (method->subnode_name) { ctx.subnode_name = method->subnode_name; - if (IS_ENABLED(CONFIG_OF_CONTROL)) + if (ofnode_valid(parent_node)) ctx.node = ofnode_find_subnode(parent_node, method->subnode_name); } diff --git a/lib/time.c b/lib/time.c index d88edafb196..0e9b079f9cf 100644 --- a/lib/time.c +++ b/lib/time.c @@ -17,6 +17,7 @@ #include <asm/global_data.h> #include <asm/io.h> #include <linux/delay.h> +#include <uthread.h> #ifndef CFG_WD_PERIOD # define CFG_WD_PERIOD (10 * 1000 * 1000) /* 10 seconds default */ @@ -197,7 +198,13 @@ void udelay(unsigned long usec) do { schedule(); kv = usec > CFG_WD_PERIOD ? CFG_WD_PERIOD : usec; - __udelay(kv); + if (CONFIG_IS_ENABLED(UTHREAD)) { + ulong t0 = timer_get_us(); + while (timer_get_us() - t0 < kv) + uthread_schedule(); + } else { + __udelay(kv); + } usec -= kv; } while(usec); } diff --git a/lib/tiny-printf.c b/lib/tiny-printf.c index faf55d7f327..2a7a4d286c0 100644 --- a/lib/tiny-printf.c +++ b/lib/tiny-printf.c @@ -283,8 +283,9 @@ static int _vprintf(struct printf_info *info, const char *fmt, va_list va) break; } islong = true; - /* no break */ + fallthrough; case 'x': + case 'X': if (islong) { num = va_arg(va, unsigned long); div = 1UL << (sizeof(long) * 8 - 4); diff --git a/lib/uthread.c b/lib/uthread.c new file mode 100644 index 00000000000..062fca7d209 --- /dev/null +++ b/lib/uthread.c @@ -0,0 +1,165 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2021 Ahmad Fatoum, Pengutronix + * Copyright (C) 2025 Linaro Limited + * + * An implementation of cooperative multi-tasking inspired from barebox threads + * https://github.com/barebox/barebox/blob/master/common/bthread.c + */ + +#include <compiler.h> +#include <linux/errno.h> +#include <linux/kernel.h> +#include <linux/list.h> +#include <malloc.h> +#include <setjmp.h> +#include <stdint.h> +#include <uthread.h> + +static struct uthread main_thread = { + .list = LIST_HEAD_INIT(main_thread.list), +}; + +static struct uthread *current = &main_thread; + +/** + * uthread_trampoline() - Call the current thread's entry point then resume the + * main thread. + * + * This is a helper function which is used as the @func argument to the + * initjmp() function, and ultimately invoked via setjmp(). It does not return + * but instead longjmp()'s back to the main thread. + */ +static void __noreturn uthread_trampoline(void) +{ + struct uthread *curr = current; + + curr->fn(curr->arg); + curr->done = true; + current = &main_thread; + longjmp(current->ctx, 1); + /* Not reached */ + while (true) + ; +} + +/** + * uthread_free() - Free memory used by a uthread object. + */ +static void uthread_free(struct uthread *uthread) +{ + if (!uthread) + return; + free(uthread->stack); + free(uthread); +} + +int uthread_create(struct uthread *uthr, void (*fn)(void *), void *arg, + size_t stack_sz, unsigned int grp_id) +{ + bool user_allocated = false; + + if (!stack_sz) + stack_sz = CONFIG_UTHREAD_STACK_SIZE; + + if (uthr) { + user_allocated = true; + } else { + uthr = calloc(1, sizeof(*uthr)); + if (!uthr) + return -1; + } + + uthr->stack = memalign(16, stack_sz); + if (!uthr->stack) + goto err; + + uthr->fn = fn; + uthr->arg = arg; + uthr->grp_id = grp_id; + + list_add_tail(&uthr->list, ¤t->list); + + initjmp(uthr->ctx, uthread_trampoline, uthr->stack, stack_sz); + + return 0; +err: + if (!user_allocated) + free(uthr); + return -1; +} + +/** + * uthread_resume() - switch execution to a given thread + * + * @uthread: the thread object that should be resumed + */ +static void uthread_resume(struct uthread *uthread) +{ + if (!setjmp(current->ctx)) { + current = uthread; + longjmp(uthread->ctx, 1); + } +} + +bool uthread_schedule(void) +{ + struct uthread *next; + struct uthread *tmp; + + list_for_each_entry_safe(next, tmp, ¤t->list, list) { + if (!next->done) { + uthread_resume(next); + return true; + } + /* Found a 'done' thread, free its resources */ + list_del(&next->list); + uthread_free(next); + } + return false; +} + +unsigned int uthread_grp_new_id(void) +{ + static unsigned int id; + + return ++id; +} + +bool uthread_grp_done(unsigned int grp_id) +{ + struct uthread *next; + + list_for_each_entry(next, &main_thread.list, list) { + if (next->grp_id == grp_id && !next->done) + return false; + } + + return true; +} + +int uthread_mutex_lock(struct uthread_mutex *mutex) +{ + while (mutex->state == UTHREAD_MUTEX_LOCKED) + uthread_schedule(); + + mutex->state = UTHREAD_MUTEX_LOCKED; + return 0; +} + +int uthread_mutex_trylock(struct uthread_mutex *mutex) +{ + if (mutex->state == UTHREAD_MUTEX_UNLOCKED) { + mutex->state = UTHREAD_MUTEX_LOCKED; + return 0; + } + + return -EBUSY; +} + +int uthread_mutex_unlock(struct uthread_mutex *mutex) +{ + mutex->state = UTHREAD_MUTEX_UNLOCKED; + + return 0; +} diff --git a/lib/uuid.c b/lib/uuid.c index 75658778044..6abbcf27b1f 100644 --- a/lib/uuid.c +++ b/lib/uuid.c @@ -67,8 +67,11 @@ static const struct { efi_guid_t guid; } list_guid[] = { #ifndef USE_HOSTCC +#if defined(CONFIG_PARTITION_TYPE_GUID) || defined(CONFIG_CMD_EFIDEBUG) || \ + defined(CONFIG_EFI) + {"EFI System Partition", PARTITION_SYSTEM_GUID}, +#endif #ifdef CONFIG_PARTITION_TYPE_GUID - {"system", PARTITION_SYSTEM_GUID}, {"mbr", LEGACY_MBR_PARTITION_GUID}, {"msft", PARTITION_MSFT_RESERVED_GUID}, {"data", PARTITION_BASIC_DATA_GUID}, @@ -182,10 +185,6 @@ static const struct { { "TCG2", EFI_TCG2_PROTOCOL_GUID, - }, - { - "System Partition", - PARTITION_SYSTEM_GUID }, { "Firmware Management", diff --git a/lib/zlib/inflate.c b/lib/zlib/inflate.c index b4c72cc2c5c..2b7a464f74f 100644 --- a/lib/zlib/inflate.c +++ b/lib/zlib/inflate.c @@ -420,6 +420,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) if (state->flags & 0x0200) CRC2(state->check, hold); INITBITS(); state->mode = TIME; + fallthrough; case TIME: NEEDBITS(32); if (state->head != Z_NULL) @@ -427,6 +428,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) if (state->flags & 0x0200) CRC4(state->check, hold); INITBITS(); state->mode = OS; + fallthrough; case OS: NEEDBITS(16); if (state->head != Z_NULL) { @@ -436,6 +438,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) if (state->flags & 0x0200) CRC2(state->check, hold); INITBITS(); state->mode = EXLEN; + fallthrough; case EXLEN: if (state->flags & 0x0400) { NEEDBITS(16); @@ -448,6 +451,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) else if (state->head != Z_NULL) state->head->extra = Z_NULL; state->mode = EXTRA; + fallthrough; case EXTRA: if (state->flags & 0x0400) { copy = state->length; @@ -471,6 +475,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) } state->length = 0; state->mode = NAME; + fallthrough; case NAME: if (state->flags & 0x0800) { if (have == 0) goto inf_leave; @@ -492,6 +497,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) state->head->name = Z_NULL; state->length = 0; state->mode = COMMENT; + fallthrough; case COMMENT: if (state->flags & 0x1000) { if (have == 0) goto inf_leave; @@ -512,6 +518,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) else if (state->head != Z_NULL) state->head->comment = Z_NULL; state->mode = HCRC; + fallthrough; case HCRC: if (state->flags & 0x0200) { NEEDBITS(16); @@ -535,6 +542,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) strm->adler = state->check = REVERSE(hold); INITBITS(); state->mode = DICT; + fallthrough; case DICT: if (state->havedict == 0) { RESTORE(); @@ -542,9 +550,11 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) } strm->adler = state->check = adler32(0L, Z_NULL, 0); state->mode = TYPE; + fallthrough; case TYPE: schedule(); if (flush == Z_BLOCK) goto inf_leave; + fallthrough; case TYPEDO: if (state->last) { BYTEBITS(); @@ -590,6 +600,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) state->length)); INITBITS(); state->mode = COPY; + fallthrough; case COPY: copy = state->length; if (copy) { @@ -625,6 +636,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) Tracev((stderr, "inflate: table sizes ok\n")); state->have = 0; state->mode = LENLENS; + fallthrough; case LENLENS: while (state->have < state->ncode) { NEEDBITS(3); @@ -646,6 +658,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) Tracev((stderr, "inflate: code lengths ok\n")); state->have = 0; state->mode = CODELENS; + fallthrough; case CODELENS: while (state->have < state->nlen + state->ndist) { for (;;) { @@ -720,6 +733,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) } Tracev((stderr, "inflate: codes ok\n")); state->mode = LEN; + fallthrough; case LEN: schedule(); if (have >= 6 && left >= 258) { @@ -764,6 +778,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) } state->extra = (unsigned)(this.op) & 15; state->mode = LENEXT; + fallthrough; case LENEXT: if (state->extra) { NEEDBITS(state->extra); @@ -772,6 +787,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) } Tracevv((stderr, "inflate: length %u\n", state->length)); state->mode = DIST; + fallthrough; case DIST: for (;;) { this = state->distcode[BITS(state->distbits)]; @@ -797,6 +813,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) state->offset = (unsigned)this.val; state->extra = (unsigned)(this.op) & 15; state->mode = DISTEXT; + fallthrough; case DISTEXT: if (state->extra) { NEEDBITS(state->extra); @@ -817,6 +834,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) } Tracevv((stderr, "inflate: distance %u\n", state->offset)); state->mode = MATCH; + fallthrough; case MATCH: if (left == 0) goto inf_leave; copy = out - left; @@ -872,6 +890,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) } #ifdef GUNZIP state->mode = LENGTH; + fallthrough; case LENGTH: if (state->wrap && state->flags) { NEEDBITS(32); @@ -885,6 +904,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) } #endif state->mode = DONE; + fallthrough; case DONE: ret = Z_STREAM_END; goto inf_leave; @@ -894,6 +914,7 @@ __rcode int ZEXPORT inflate(z_streamp strm, int flush) case MEM: return Z_MEM_ERROR; case SYNC: + fallthrough; default: return Z_STREAM_ERROR; } |