diff options
author | lei zhou <lei.zhou@linaro.org> | 2022-11-28 10:58:10 -0500 |
---|---|---|
committer | lei zhou <lei.zhou@linaro.org> | 2022-11-28 10:58:10 -0500 |
commit | 1443cdcb3c9f0ec635d8052d89d96d8423b8fe08 (patch) | |
tree | ad11276356d160e9449774c9da19b40fe4524eea | |
parent | edc1713019684d37b1518e914573fe85a55f8a45 (diff) |
imx-spl: use fdt-overlay to pass bl31_configs over bl31
Use FDT-OVERLAY as part of updatable TEE-FIT image to pass config
data to BL31 as part of Part Number so BL31's behaviour could be
overriden.
-rw-r--r-- | arch/arm/mach-imx/spl.c | 90 | ||||
-rw-r--r-- | common/spl/spl_fit.c | 54 |
2 files changed, 127 insertions, 17 deletions
diff --git a/arch/arm/mach-imx/spl.c b/arch/arm/mach-imx/spl.c index 0a9a34f410..2a6f3506b6 100644 --- a/arch/arm/mach-imx/spl.c +++ b/arch/arm/mach-imx/spl.c @@ -8,6 +8,8 @@ #define DEBUG +#include <linux/libfdt.h> + #include <common.h> #include <hang.h> #include <init.h> @@ -286,6 +288,42 @@ static inline void raw_write_daif(unsigned int daif) } static bool is_tee_present = false; +/* static uintptr_t configs_addr; + * TODO: define bl31_configs data structure passing into BL31 from SPL + */ +static struct bl31_configs { + bool tee_presence; + const char *config_1; + uint32_t config_2; +} g_configs; +static void *g_fdtoverlay; +#define ATF_CONFIGS_NODE "/atf-configs" +#define PROP_STRING_1 "property-2" +#define PROP_UINT32_1 "property-1" + +static int open_and_fetch_bl31_configs(uintptr_t configs_addr/*OUT*/, void *fdt_addr/*IN*/) +{ + int ret = fdt_check_header((void *)fdt_addr); + if (!ret) { + g_fdtoverlay = (void *)fdt_addr; + } + + if (!ret) { + int node = fdt_path_offset(g_fdtoverlay, ATF_CONFIGS_NODE); + if (node < 0) { + printf("Fail finding atf_config DT node\n"); + } + + const fdt32_t *cuint; + const char *prop = fdt_getprop(g_fdtoverlay, node, PROP_STRING_1, NULL); + cuint = fdt_getprop(g_fdtoverlay, node, PROP_UINT32_1, NULL); + printf("property-1 = %s, property-2 = %d\n", prop, fdt32_to_cpu(*cuint)); + // uint32_t size = fdt_read_uint32_default(fdt, node, "st,mem-size", 0U); + } + + return ret; +} + __weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) { typedef void __noreturn (*image_entry_noargs_t)(void); @@ -297,13 +335,21 @@ __weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) debug("image entry point: 0x%p\n", (void *)spl_image->entry_point); if (spl_image->flags & SPL_FIT_FOUND) { - debug("BL31 image entry point: 0x%p. \n", (void *)spl_image->entry_point); + debug("BL31 image entry point: 0x%p fdt_addr = 0x%p. \n", + (void *)spl_image->entry_point, (void *)spl_image->fdt_addr); typedef void __noreturn (*bl31_entry)(int, int, int, int); bl31_entry bl31_entry_point = (bl31_entry)(unsigned long)spl_image->entry_point; raw_write_daif(SPSR_EXCEPTION_MASK); dcache_disable(); - bl31_entry_point(is_tee_present, 22, 32, 44); + + /* + * Note: Avoid adding libfdt.a to imx-atf-bl31 to overflow OCRAM + * instead private bl31_configs data structure is passed over bl31. + */ + open_and_fetch_bl31_configs(&g_configs, spl_image->fdt_addr); + g_configs.tee_presence = is_tee_present; + bl31_entry_point(0, &g_configs, 32, 44); } else { /* * HAB looks for the CSF at the end of the authenticated @@ -489,11 +535,36 @@ int mmc_image_load_late(struct spl_image_info *spl_image, struct mmc *mmc) #endif #ifdef CONFIG_IMX_AERQ_PARTNUM_BOOT_SCHEME -/* Forward declaration of h_spl_load_read(), see detail implementation in +static int spl_fit_append_fdtoverlay(void *fdt_addr, struct spl_image_info *tee_info) +{ + int ret = 0; + + /* Make room in FDT for changes from the overlay */ + if (!tee_info || !tee_info->fdt_addr) + return -1; + + ret = fdt_increase_size(fdt_addr, tee_info->size); + if (ret < 0) + return ret; + + ret = fdt_overlay_apply_verbose(fdt_addr, + (void *)tee_info->fdt_addr); + if (ret) { + pr_err("failed to apply DT overlay!\n"); + } else { + debug("%s: TEE-FIT DT overlay applied spl_image->fdt_addr = 0x%p tee_info->fdt_addr = 0x%p \n", + __func__, fdt_addr, (void *)tee_info->fdt_addr); + } + + return ret; +} + +/* + * Forward declaration of h_spl_load_read(), see detail implementation in * common/spl/spl_mmc.c. */ ulong h_spl_load_read(struct spl_load_info *load, ulong sector, - ulong count, void *buf); + ulong count, void *buf); int mmc_image_load_late(struct spl_image_info *spl_image, struct mmc *mmc) { unsigned long count = 0, sector = CONFIG_MMCSD_RAW_MODE_TEE_FIT_SECTOR; // 2M bytes offset by default @@ -502,12 +573,15 @@ int mmc_image_load_late(struct spl_image_info *spl_image, struct mmc *mmc) struct spl_image_info tee_fit_info; int ret = 0; + /* + * Note: input *spl_image carries global FIT images information + * (u-boot/dtb and tee/dtb-overlay FIT images ) and will be passing around + */ memset(&tee_fit_info, 0, sizeof(tee_fit_info)); /* Avoid overwriting previously loaded u-boot at 0x40200000 */ header = spl_get_load_buffer(-sizeof(*header) - bd->blksz, 0); /* read FIT image header to find the image size & load address */ - /* TODO: BL32-FIT eMMC sector offset will be fetched from u-boot-fit-fdt as predefined */ count = blk_dread(bd, sector, 1, header); debug("bl31 hdr read sector %lx, count=%lu\n", sector, count); if (count == 0) { @@ -528,6 +602,8 @@ int mmc_image_load_late(struct spl_image_info *spl_image, struct mmc *mmc) if (!ret) { /* So far bl32-fit image is detected/loaded and authN'ed. */ is_tee_present = true; + + ret = spl_fit_append_fdtoverlay(spl_image->fdt_addr, &tee_fit_info); /* TODO: cache local tee_fit_info into global spl_image object for * passing config data into other stage of bootloader. * spl_image( need to be extended ) to cache BL32 specifc info from BL32-FDT @@ -538,10 +614,6 @@ int mmc_image_load_late(struct spl_image_info *spl_image, struct mmc *mmc) debug("Found BL32-FIT and loading result = %d.\n", ret); } - // 1. Load optee tee.bin to TEE_LOAD_ADDR - // if not detected, is_tee_present = false; - // 2. HAB4 authenticate the image - // 3. Cache optee entry_point into spl_image->fdt_addr return ret; } #endif diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c index 77516d8d7d..3677dda0f0 100644 --- a/common/spl/spl_fit.c +++ b/common/spl/spl_fit.c @@ -394,8 +394,8 @@ static bool os_takes_devicetree(uint8_t os) case IH_OS_U_BOOT: return true; case IH_OS_TEE: - /* TODO: Change to true to allow op-tee-fit image to carry fdt-overlay to override default behaviour. */ - return false; + /* allow op-tee-fit image to carry fdt-overlay to override default behaviour. */ + return true; case IH_OS_LINUX: return IS_ENABLED(CONFIG_SPL_OS_BOOT); default: @@ -437,7 +437,7 @@ static int spl_fit_append_fdt(struct spl_image_info *spl_image, return ret; } - /* Make the load-address of the FDT available for the SPL framework */ + /* Make the load-address of the FDT available */ spl_image->fdt_addr = map_sysmem(image_info.load_addr, 0); debug("%s FDT node addr = 0x%p. load_addr = %p\n", __func__, (void *)spl_image->fdt_addr, (void *)image_info.load_addr); if (CONFIG_IS_ENABLED(FIT_IMAGE_TINY)) @@ -719,13 +719,48 @@ static int spl_simple_fit_parse(struct spl_fit_info *ctx) ctx->images_node = fdt_path_offset(ctx->fit, FIT_IMAGES_PATH); if (ctx->images_node < 0) { debug("%s: Cannot find /images node: %d\n", __func__, - ctx->images_node); + ctx->images_node); return -EINVAL; } return 0; } +static int spl_fit_fetch_fdt(struct spl_image_info *spl_image, /*IN/OUT*/ + struct spl_load_info *info, ulong sector, + const struct spl_fit_info *ctx) +{ + struct spl_image_info image_info; + int node, ret = 0; + + /* + * Use the address following the image as target address for the + * device tree. + */ + image_info.load_addr = spl_image->load_addr + spl_image->size; + + /* Figure out which device tree the board wants to use */ + node = spl_fit_get_image_node(ctx, FIT_FDT_PROP, 0); + if (node < 0) { + debug("%s: cannot find FDT node\n", __func__); + return node; + } else { + ret = spl_load_fit_image(info, sector, ctx, node, + &image_info); + if (ret < 0) + return ret; + } + + /* Pass out tee_fdtoverlay image information to the caller */ + spl_image->fdt_addr = map_sysmem(image_info.load_addr, 0); + spl_image->load_addr = image_info.load_addr; + spl_image->size = image_info.size; + + debug("%s FDT node addr = 0x%p. load_addr = %p, fetched from TEE-FIT\n", __func__, + (void *)spl_image->fdt_addr, (void *)image_info.load_addr); + return ret; +} + int spl_load_simple_fit(struct spl_image_info *spl_image, struct spl_load_info *info, ulong sector, void *fit) { @@ -736,7 +771,7 @@ int spl_load_simple_fit(struct spl_image_info *spl_image, int index = 0; int firmware_node; - /* Read out entire FDT */ + /* Read out entire FDT from current FIT image. */ ret = spl_simple_fit_read(&ctx, info, sector, fit); if (ret < 0) return ret; @@ -788,7 +823,7 @@ int spl_load_simple_fit(struct spl_image_info *spl_image, } if (node < 0) { debug("%s: Cannot find u-boot image node: %d\n", - __func__, node); + __func__, node); return -1; } @@ -811,14 +846,17 @@ int spl_load_simple_fit(struct spl_image_info *spl_image, */ if (os_takes_devicetree(spl_image->os)) { if (IH_OS_TEE == spl_image->os) { - /* TODO: fetch fdt_overlay tee.dbo and apply to global spl_image->fdt_addr (U-Boot.dtb) */ - + /* Fetch fdt_overlay tee.dbo and later apply to global (U-Boot.dtb) */ + ret = spl_fit_fetch_fdt(spl_image, info, sector, &ctx); + if (ret) + return ret; } else { ret = spl_fit_append_fdt(spl_image, info, sector, &ctx); if (ret < 0 && spl_image->os != IH_OS_U_BOOT) return ret; } } + firmware_node = node; /* Now check if there are more images for us to load */ for (; ; index++) { |