diff --git a/arch/arm/mach-snapdragon/Kconfig b/arch/arm/mach-snapdragon/Kconfig index d85cfbcb4833..cd201cd32fe9 100644 --- a/arch/arm/mach-snapdragon/Kconfig +++ b/arch/arm/mach-snapdragon/Kconfig @@ -138,6 +138,28 @@ config QCOM_TMEL_ELF Path of the TME Elf file to be concatenated to u-boot.mbn to create boot rom expected multi-elf image +config SPL_QCOM_BOOT_FROM_PBL + bool "U-Boot SPL is loaded directly by PBL" + depends on SPL + default y + help + Enable this option when U-Boot SPL is loaded directly by PBL (Primary + Boot Loader). In this case, PBL passes boot parameters via r0 register + containing a pointer to pbl_shared_data structure. + + Disable this option when U-Boot SPL is loaded by XBL or another + intermediate bootloader (e.g., PBL->XBL->U-Boot SPL). In such cases, + the r0 register won't contain valid PBL shared data, and boot device + detection will use fallback mechanisms. + +config SPL_WRAPPER_ELF + bool "Create wrapper ELF for applicable platforms" + depends on SPL + help + Some platforms embed the U-Boot SPL binary within an ELF as a segment. + Additional tools are used to convert this ELF into an image that is + usable for the boot ROM. + choice prompt "Qualcomm boot0.h workaround" optional diff --git a/arch/arm/mach-snapdragon/fit-handler.c b/arch/arm/mach-snapdragon/fit-handler.c index fc419bd3f008..a2a6c179f4fc 100644 --- a/arch/arm/mach-snapdragon/fit-handler.c +++ b/arch/arm/mach-snapdragon/fit-handler.c @@ -10,6 +10,14 @@ #include #include +#define TOC_FDT "toc_fdt" + +/* + * Global TOC FDT load address populated by qcom_spl_get_toc_fdt_address + * Placed in .data section to ensure it persists + */ +static u64 g_toc_fdt_address __section(".data"); + /** * qcom_spl_get_fit_img_entry_point() - Get entry point from FIT image node. * @fit: Pointer to the FIT image blob. @@ -88,6 +96,49 @@ int qcom_spl_get_iftbl_entry_by_name(struct interface_table *if_tbl, return -ENOENT; } +/** + * qcom_spl_get_toc_fdt_address() - Look up the TOC FDT load address in the FIT + * + * Finds the optional "toc_fdt" image node in the FIT at + * CONFIG_SPL_LOAD_FIT_ADDRESS and records its load address in + * g_toc_fdt_address, for later use by bl2_plat_get_bl31_params_v2(). + * + * This is independent of qclib_post_process_from_spl(): the TOC FDT is + * already loaded into memory by the generic FIT loadables path, so its + * address only needs to be looked up, not computed by QCLIB. + */ +static void qcom_spl_get_toc_fdt_address(void) +{ + int ret; + int images_node; + int toc_fdt_node; + const void *fit = (const void *)CONFIG_SPL_LOAD_FIT_ADDRESS; + + images_node = fdt_subnode_offset(fit, 0, "images"); + if (images_node < 0) { + pr_err("Failed to find images node in FIT\n"); + return; + } + + /* + * This node is optional: boards whose FIT image carries no TOC FDT + * for BL31 are unaffected and g_toc_fdt_address remains 0. + */ + toc_fdt_node = fdt_subnode_offset(fit, images_node, TOC_FDT); + if (toc_fdt_node < 0) { + pr_debug("No '%s' node in FIT, BL31 will not receive a TOC FDT address\n", + TOC_FDT); + return; + } + + ret = qcom_spl_get_fit_img_entry_point((void *)fit, toc_fdt_node, + &g_toc_fdt_address); + if (ret) + pr_warn("Failed to get '%s' load address (%d)\n", TOC_FDT, ret); + else + printf("TOC FDT address: 0x%lx\n", (unsigned long)g_toc_fdt_address); +} + /** * bl2_plat_get_bl31_params_v2() - Retrieve and fixup BL31 parameters. * @bl32_entry: Entry point for BL32 (OP-TEE). @@ -110,6 +161,13 @@ struct bl_params *bl2_plat_get_bl31_params_v2(uintptr_t bl32_entry, bl_params = bl2_plat_get_bl31_params_v2_default(bl32_entry, bl33_entry, fdt_addr); + /* + * The TOC FDT is loaded into memory by the generic FIT loadables + * path regardless of QCOM_BOOT_FROM_PBL, so its load address is + * looked up here rather than in qclib_post_process_from_spl(). + */ + qcom_spl_get_toc_fdt_address(); + /* * Fixup the bl31 params based on platform requirements. */ @@ -124,6 +182,16 @@ struct bl_params *bl2_plat_get_bl31_params_v2(uintptr_t bl32_entry, node->ep_info->args.arg0 = qcsdi_address; pr_debug("Setting BL31 arg0 to QCSDI address: 0x%llx\n", qcsdi_address); + } else if (node->image_id == ATF_BL32_IMAGE_ID) { + /* + * Pass TOC FDT load address to BL32 via arg0 + */ + if (g_toc_fdt_address == 0) + pr_debug("TOC FDT address not set, BL32 will get arg0=0\n"); + + node->ep_info->args.arg0 = g_toc_fdt_address; + printf("TOC FDT address passed to BL32 (arg0): 0x%lx\n", + (unsigned long)node->ep_info->args.arg0); } } diff --git a/arch/arm/mach-snapdragon/nord-spl-wrap-elf.lds b/arch/arm/mach-snapdragon/nord-spl-wrap-elf.lds new file mode 100644 index 000000000000..b5c532499af5 --- /dev/null +++ b/arch/arm/mach-snapdragon/nord-spl-wrap-elf.lds @@ -0,0 +1,18 @@ +/* + * SPDX-License-Identifier: GPL-2.0 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ +PHDRS { + ptype PT_LOAD FLAGS(0x7); +} + +ENTRY(_entry) + +SECTIONS { + . = IMAGE_TEXT_BASE; + _entry = . ; + data : { + *(.data) + . = ALIGN(0x1000); + } :ptype +} diff --git a/arch/arm/mach-snapdragon/pbl-shared-data.c b/arch/arm/mach-snapdragon/pbl-shared-data.c index b9dce22c4171..a4b7533924c7 100644 --- a/arch/arm/mach-snapdragon/pbl-shared-data.c +++ b/arch/arm/mach-snapdragon/pbl-shared-data.c @@ -83,7 +83,7 @@ void save_boot_params(ulong r0, ulong r1, ulong r2, ulong r3) u32 __weak spl_boot_device(void) { struct pbl_shared_data *psd = &g_psd; - + if (CONFIG_IS_ENABLED(QCOM_BOOT_FROM_PBL)) { #ifdef DEBUG for (int i = 0; psd && i < psd->num_of_entries; i++) { printf("entry[0x%x] = %d 0x%08x %d\n", i, @@ -118,7 +118,7 @@ u32 __weak spl_boot_device(void) return BOOT_DEVICE_UFS; } } - + } out: pr_err("No boot device configured\n"); return BOOT_DEVICE_NONE; diff --git a/board/qualcomm/nord/Makefile b/board/qualcomm/nord/Makefile new file mode 100644 index 000000000000..1827dc93dbbe --- /dev/null +++ b/board/qualcomm/nord/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_SPL) := spl-nord.o diff --git a/board/qualcomm/nord/spl-nord.c b/board/qualcomm/nord/spl-nord.c new file mode 100644 index 000000000000..3a91c1d7a30c --- /dev/null +++ b/board/qualcomm/nord/spl-nord.c @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +/** + * spl_boot_device() - Report the boot device for nord-ride. + * + * nord-ride always boots the SPL FIT image from a UFS raw partition + * rather than via PBL, so the boot device is fixed. + * + * Return: BOOT_DEVICE_UFS + */ +u32 spl_boot_device(void) +{ + return BOOT_DEVICE_UFS; +} + +#if defined(CONFIG_SPL_BUILD) +/** + * board_init_f() - Main entry point for SPL. + * @dummy: Dummy argument (unused). + */ +void board_init_f(ulong dummy) +{ + int ret = 0; + + memset(__bss_start, 0, __bss_end - __bss_start); /* Clear BSS */ + + qcom_spl_malloc_init_f(); + + ret = spl_early_init(); + if (ret) { + pr_debug("spl_early_init() failed (%d)\n", ret); + goto fail; + } + + event_notify_null(EVT_LAST_STAGE_INIT); + + preloader_console_init(); + + + board_init_r(NULL, 0); + +fail: + if (ret) + reset_cpu(); +} +#endif /* CONFIG_SPL_BUILD */ diff --git a/common/spl/spl_atf.c b/common/spl/spl_atf.c index 8bc5db773950..2e28ad7ad292 100644 --- a/common/spl/spl_atf.c +++ b/common/spl/spl_atf.c @@ -206,6 +206,7 @@ static void __noreturn bl31_entry(ulong bl31_entry, ulong bl32_entry, if (!CONFIG_IS_ENABLED(SYS_DCACHE_OFF)) dcache_disable(); + printf("Jumping to BL31 at 0x%lx\n", bl31_entry); atf_entry(bl31_params, (void *)fdt_addr); } diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c index 18bff7b8d4af..e83866d25d9f 100644 --- a/common/spl/spl_fit.c +++ b/common/spl/spl_fit.c @@ -230,6 +230,7 @@ static int load_simple_fit(struct spl_load_info *info, ulong fit_offset, bool external_data = false; log_debug("starting\n"); + printf("Loading image: %s\n", fit_get_name(fit, node, NULL)); if (CONFIG_IS_ENABLED(BOOTMETH_VBE) && xpl_get_phase(info) != IH_PHASE_NONE) { enum image_phase_t phase; diff --git a/configs/qcom_nord_ride_spl_defconfig b/configs/qcom_nord_ride_spl_defconfig new file mode 100644 index 000000000000..ca2bab9d85bb --- /dev/null +++ b/configs/qcom_nord_ride_spl_defconfig @@ -0,0 +1,114 @@ +# Configuration for building U-Boot to be flashed +# to the uefi partition of Nord-Ride dev boards with +# the "Linux Embedded" partition layout (which have +# a dedicated "uefi" partition for edk2/U-Boot) + +#include "qcom_defconfig" + +# Otherwise buildman thinks this isn't an ARM platform +CONFIG_ARM=y + +CONFIG_FASTBOOT_BUF_ADDR=0xbc238000 +# CONFIG_OF_UPSTREAM is not set +CONFIG_DEFAULT_DEVICE_TREE="nord-ride" +CONFIG_TEXT_BASE=0xD8D00000 +CONFIG_REMAKE_ELF=y +CONFIG_EVENT=y +CONFIG_ENV_IS_IN_SCSI=y +CONFIG_ENV_SCSI_PART_USE_TYPE_GUID=y +# SCSI partition type GUID for logfs partition +CONFIG_ENV_SCSI_PART_TYPE_GUID="bc0330eb-3410-4951-a617-03898dbe3372" +# CONFIG_ENV_IS_DEFAULT is not set +# CONFIG_ENV_IS_NOWHERE is not set + +# SPL configurations for Nord-Ride +# Purpose: Load FIT image (containing TFA, OPTEE and U-Boot proper) +# from UFS storage and jump to next image (TFA) + +CONFIG_SPL=y +CONFIG_SPL_BUILD=y +CONFIG_SPL_FRAMEWORK=y +CONFIG_SPL_EVENT=y + +CONFIG_SPL_TEXT_BASE=0xbc180000 +CONFIG_SPL_MAX_SIZE=0x60000 +CONFIG_SPL_BSS_LIMIT=y +CONFIG_SPL_BSS_MAX_SIZE=0x10000 +# CONFIG_SPL_SEPARATE_BSS is not set + +# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set +CONFIG_SPL_HAVE_INIT_STACK=y +CONFIG_SPL_STACK=0xbc228000 + +CONFIG_SPL_SYS_MALLOC_F_LEN=0x10000 +CONFIG_SPL_SYS_MALLOC=y +CONFIG_SPL_HAS_CUSTOM_MALLOC_START=y +CONFIG_SPL_CUSTOM_SYS_MALLOC_ADDR=0xbc238000 +CONFIG_SPL_SYS_MALLOC_SIZE=0x48000 + +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y + +CONFIG_SPL_DM=y +CONFIG_SPL_OF_LIBFDT=y +CONFIG_SPL_OF_CONTROL=y +CONFIG_SPL_OF_REAL=y +CONFIG_SPL_SIMPLE_BUS=y + +CONFIG_SPL_DM_RESET=y + +CONFIG_SPL_CLK=y + +CONFIG_SPL_GPIO=y +CONFIG_SPL_DM_GPIO=y + +# CONFIG_SPL_MMC is not set + +CONFIG_SPL_UFS=y +CONFIG_SPL_UFS_QCOM=y + +CONFIG_SPL_UFS_RAW_U_BOOT_DEVNUM=4 +CONFIG_SPL_UFS_RAW_U_BOOT_SECTOR=0x0 +CONFIG_SPL_UFS_RAW_U_BOOT_USE_PARTITION=y +CONFIG_SPL_UFS_RAW_U_BOOT_PARTITION_NAME="uefi_a" +CONFIG_SPL_UFS_RAW_U_BOOT_PARTITION_NUM=1 + +CONFIG_SPL_PARTITIONS=y +CONFIG_SPL_DOS_PARTITION=y +CONFIG_SPL_CHARSET=y + +CONFIG_SPL_PHY=y +CONFIG_SPL_PHY_QCOM_QMP_UFS=y + +CONFIG_SPL_POWER=y +CONFIG_SPL_POWER_DOMAIN=y + +CONFIG_SPL_LOAD_FIT=y + +CONFIG_SPL_ATF=y + +CONFIG_SPL_REMAKE_ELF=y + +CONFIG_COUNTER_FREQUENCY=19200000 + +# CONFIG_SAVE_PREV_BL_FDT_ADDR is not set +# CONFIG_SAVE_PREV_BL_INITRAMFS_START_ADDR is not set +CONFIG_SPL_ATF_LOAD_IMAGE_V2=y +CONFIG_SPL_ATF_NO_PLATFORM_PARAM=y +CONFIG_SPL_HAS_LOAD_FIT_ADDRESS=y +CONFIG_SPL_LOAD_FIT_ADDRESS=0xbc1e8000 + +CONFIG_SPL_DRIVERS_MISC=y +CONFIG_SPL_SERIAL=y +CONFIG_SPL_MISC=y +CONFIG_SPL_QCOM_GENI=y +CONFIG_SPL_MSM_GENI_SERIAL=y + +CONFIG_SPL_BANNER_PRINT=y +CONFIG_SPL_CLK_STUB=y +CONFIG_SPL_PINCTRL=y +CONFIG_SPL_PINCTRL_QCOM_NORD=y +CONFIG_SPL_QCOM_SMEM=y +# CONFIG_SPL_QCOM_BOOT_FROM_PBL is not set +CONFIG_SYS_BOARD="nord" +CONFIG_SPL_WRAPPER_ELF=y diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig index 37775f0a484f..5e4cf2951c93 100644 --- a/drivers/pinctrl/qcom/Kconfig +++ b/drivers/pinctrl/qcom/Kconfig @@ -148,6 +148,14 @@ config PINCTRL_QCOM_NORD Say Y here to enable support for pinctrl on the Snapdragon Nord SoC, as well as the associated GPIO driver. +config SPL_PINCTRL_QCOM_NORD + bool "Qualcomm Nord Pinctrl in SPL" + depends on SPL_PINCTRL_GENERIC + select SPL_PINCTRL_QCOM + help + SPL variant of PINCTRL_QCOM_NORD. + See the help of PINCTRL_QCOM_NORD for details. + config PINCTRL_QCOM_QCM2290 bool "Qualcomm QCM2290 Pinctrl" default y if PINCTRL_QCOM_GENERIC diff --git a/include/configs/nord.h b/include/configs/nord.h new file mode 100644 index 000000000000..3b3793ad475b --- /dev/null +++ b/include/configs/nord.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef __CONFIGS_NORD_H +#define __CONFIGS_NORD_H + +#include + +#endif