diff options
Diffstat (limited to 'lib')
34 files changed, 574 insertions, 289 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 41de2671cc6..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/ @@ -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/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..94ba7c5589b 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,6 +215,7 @@ out: * Return: status code */ static efi_status_t efi_binary_run_dp(void *image, size_t size, void *fdt, + void *initrd, size_t initrd_sz, struct efi_device_path *dp_dev, struct efi_device_path *dp_img) { @@ -230,6 +233,10 @@ static efi_status_t efi_binary_run_dp(void *image, size_t size, void *fdt, if (ret != EFI_SUCCESS) return ret; + ret = efi_install_initrd(initrd, initrd_sz); + if (ret != EFI_SUCCESS) + return ret; + return efi_run_image(image, size, dp_dev, dp_img); } @@ -239,13 +246,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 +278,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 +367,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 f220daa048f..dbebb37dc04 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -3195,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; @@ -3213,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); @@ -3266,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_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_gop.c b/lib/efi_loader/efi_gop.c index 4593975be5a..3abb47d610e 100644 --- a/lib/efi_loader/efi_gop.c +++ b/lib/efi_loader/efi_gop.c @@ -26,6 +26,7 @@ static const efi_guid_t efi_gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; * @ops: graphical output protocol interface * @info: graphical output mode information * @mode: graphical output mode + * @vdev: backing video device * @bpix: bits per pixel * @fb: frame buffer */ @@ -34,6 +35,7 @@ struct efi_gop_obj { struct efi_gop ops; struct efi_gop_mode_info info; struct efi_gop_mode mode; + struct udevice *vdev; /* Fields we only have access to during init */ u32 bpix; void *fb; @@ -122,6 +124,7 @@ static __always_inline efi_status_t gop_blt_int(struct efi_gop *this, u32 *fb32 = gopobj->fb; u16 *fb16 = gopobj->fb; struct efi_gop_pixel *buffer = __builtin_assume_aligned(bufferp, 4); + bool blt_to_video = (operation != EFI_BLT_VIDEO_TO_BLT_BUFFER); if (delta) { /* Check for 4 byte alignment */ @@ -245,6 +248,9 @@ static __always_inline efi_status_t gop_blt_int(struct efi_gop *this, dlineoff += dwidth; } + if (blt_to_video) + video_damage(gopobj->vdev, dx, dy, width, height); + return EFI_SUCCESS; } @@ -551,6 +557,7 @@ efi_status_t efi_gop_register(void) gopobj->info.pixels_per_scanline = col; gopobj->bpix = bpix; gopobj->fb = map_sysmem(fb_base, fb_size); + gopobj->vdev = vdev; return EFI_SUCCESS; } diff --git a/lib/efi_loader/efi_helper.c b/lib/efi_loader/efi_helper.c index 8c32059edda..19fb5d03fec 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, @@ -623,6 +623,35 @@ efi_status_t efi_install_fdt(void *fdt) } /** + * efi_install_initrd() - install initrd + * + * Install the initrd located at @initrd using the EFI_LOAD_FILE2 + * protocol. + * + * @initrd: address of initrd or NULL if none is provided + * @initrd_sz: size of initrd + * Return: status code + */ +efi_status_t efi_install_initrd(void *initrd, size_t initd_sz) +{ + efi_status_t ret; + struct efi_device_path *dp_initrd; + + if (!initrd) + return EFI_SUCCESS; + + 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) + efi_free_pool(dp_initrd); + + return ret; +} + +/** * do_bootefi_exec() - execute EFI binary * * The image indicated by @handle is started. When it returns the allocated 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/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/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", |