From 18b415be9d631b3e0c3a3caacc5f02edb9413f6b Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Fri, 18 Jun 2021 11:33:26 +0200 Subject: [PATCH] feat(plat/st): improve FIP image loading from MMC Instead of using a scratch buffer of 512 bytes, we can directly use the image address and max size. The mmc_block_dev_spec struct info is then overwritten for each image with this info, except FW_CONFIG and GPT table which will still use the scratch buffer. This allows using multiple blocks read on MMC, and so improves the boot time. A cache invalidate is required for the remaining data not used from the first and last blocks read. It is not required for FW_CONFIG_ID, as it is in scratch buffer in SYSRAM, and also because bl_mem_params struct is overwritten in this case. This should also not be done if the image is not found (OP-TEE extra binaries when using SP_min). Change-Id: If3ecfdfe35bb9db66284036ca49c4bd1be4fd121 Signed-off-by: Yann Gautier --- plat/st/common/bl2_io_storage.c | 8 +++++++- plat/st/stm32mp1/bl2_plat_setup.c | 14 ++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c index 01c289db8..6c7618aba 100644 --- a/plat/st/common/bl2_io_storage.c +++ b/plat/st/common/bl2_io_storage.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -45,7 +46,7 @@ static io_block_spec_t gpt_block_spec = { static uint32_t block_buffer[MMC_BLOCK_SIZE] __aligned(MMC_BLOCK_SIZE); -static const io_block_dev_spec_t mmc_block_dev_spec = { +static io_block_dev_spec_t mmc_block_dev_spec = { /* It's used as temp buffer in block driver */ .buffer = { .offset = (size_t)&block_buffer, @@ -423,6 +424,11 @@ int bl2_plat_handle_pre_image_load(unsigned int image_id) image_block_spec.length = entry->length; gpt_init_done = true; + } else { + bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id); + + mmc_block_dev_spec.buffer.offset = bl_mem_params->image_info.image_base; + mmc_block_dev_spec.buffer.length = bl_mem_params->image_info.image_max_size; } break; diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c index 83e5cd136..53177f628 100644 --- a/plat/st/stm32mp1/bl2_plat_setup.c +++ b/plat/st/stm32mp1/bl2_plat_setup.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -395,6 +396,19 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) break; } +#if STM32MP_SDMMC || STM32MP_EMMC + /* + * Invalidate remaining data read from MMC but not flushed by load_image_flush(). + * We take the worst case which is 2 MMC blocks. + */ + if ((image_id != FW_CONFIG_ID) && + ((bl_mem_params->image_info.h.attr & IMAGE_ATTRIB_SKIP_LOADING) == 0U)) { + inv_dcache_range(bl_mem_params->image_info.image_base + + bl_mem_params->image_info.image_size, + 2U * MMC_BLOCK_SIZE); + } +#endif /* STM32MP_SDMMC || STM32MP_EMMC */ + return err; }