summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlei zhou <lei.zhou@linaro.org>2022-11-28 10:58:10 -0500
committerlei zhou <lei.zhou@linaro.org>2022-11-28 10:58:10 -0500
commit1443cdcb3c9f0ec635d8052d89d96d8423b8fe08 (patch)
treead11276356d160e9449774c9da19b40fe4524eea
parentedc1713019684d37b1518e914573fe85a55f8a45 (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.c90
-rw-r--r--common/spl/spl_fit.c54
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++) {