diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c index 817f44972..7e76083b3 100644 --- a/plat/st/common/bl2_io_storage.c +++ b/plat/st/common/bl2_io_storage.c @@ -24,12 +24,14 @@ #include #include #include +#include #include #include #include #include #include +#include /* IO devices */ uintptr_t fip_dev_handle; @@ -39,10 +41,6 @@ static const io_dev_connector_t *fip_dev_con; #if STM32MP_SDMMC || STM32MP_EMMC static struct mmc_device_info mmc_info; -static io_block_spec_t gpt_block_spec = { - .offset = 0U, - .length = 34U * MMC_BLOCK_SIZE, /* Size of GPT table */ -}; static uint32_t block_buffer[MMC_BLOCK_SIZE] __aligned(MMC_BLOCK_SIZE); @@ -97,118 +95,17 @@ static io_mtd_dev_spec_t spi_nand_dev_spec = { static const io_dev_connector_t *spi_dev_con; #endif -static const io_uuid_spec_t fw_config_uuid_spec = { - .uuid = UUID_FW_CONFIG, -}; - -static const io_uuid_spec_t bl33_partition_spec = { - .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33 -}; - -static const io_uuid_spec_t tos_fw_config_uuid_spec = { - .uuid = UUID_TOS_FW_CONFIG, -}; - -static const io_uuid_spec_t hw_config_uuid_spec = { - .uuid = UUID_HW_CONFIG, -}; - -#ifdef AARCH32_SP_OPTEE -static const io_uuid_spec_t optee_header_partition_spec = { - .uuid = UUID_SECURE_PAYLOAD_BL32 -}; - -static const io_uuid_spec_t optee_core_partition_spec = { - .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1 -}; - -static const io_uuid_spec_t optee_paged_partition_spec = { - .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2 -}; -#else -static const io_uuid_spec_t bl32_partition_spec = { - .uuid = UUID_SECURE_PAYLOAD_BL32 -}; -#endif - -static io_block_spec_t image_block_spec = { +io_block_spec_t image_block_spec = { .offset = 0U, .length = 0U, }; -static int open_fip(const uintptr_t spec); -static int open_storage(const uintptr_t spec); - -struct plat_io_policy { - uintptr_t *dev_handle; - uintptr_t image_spec; - int (*check)(const uintptr_t spec); -}; - -static const struct plat_io_policy policies[] = { - [FIP_IMAGE_ID] = { - .dev_handle = &storage_dev_handle, - .image_spec = (uintptr_t)&image_block_spec, - .check = open_storage - }, -#ifdef AARCH32_SP_OPTEE - [BL32_IMAGE_ID] = { - .dev_handle = &fip_dev_handle, - .image_spec = (uintptr_t)&optee_header_partition_spec, - .check = open_fip - }, - [BL32_EXTRA1_IMAGE_ID] = { - .dev_handle = &fip_dev_handle, - .image_spec = (uintptr_t)&optee_core_partition_spec, - .check = open_fip - }, - [BL32_EXTRA2_IMAGE_ID] = { - .dev_handle = &fip_dev_handle, - .image_spec = (uintptr_t)&optee_paged_partition_spec, - .check = open_fip - }, -#else - [BL32_IMAGE_ID] = { - .dev_handle = &fip_dev_handle, - .image_spec = (uintptr_t)&bl32_partition_spec, - .check = open_fip - }, -#endif - [BL33_IMAGE_ID] = { - .dev_handle = &fip_dev_handle, - .image_spec = (uintptr_t)&bl33_partition_spec, - .check = open_fip - }, - [FW_CONFIG_ID] = { - .dev_handle = &fip_dev_handle, - .image_spec = (uintptr_t)&fw_config_uuid_spec, - .check = open_fip - }, - [TOS_FW_CONFIG_ID] = { - .dev_handle = &fip_dev_handle, - .image_spec = (uintptr_t)&tos_fw_config_uuid_spec, - .check = open_fip - }, - [HW_CONFIG_ID] = { - .dev_handle = &fip_dev_handle, - .image_spec = (uintptr_t)&hw_config_uuid_spec, - .check = open_fip - }, -#if STM32MP_SDMMC || STM32MP_EMMC - [GPT_IMAGE_ID] = { - .dev_handle = &storage_dev_handle, - .image_spec = (uintptr_t)&gpt_block_spec, - .check = open_storage - }, -#endif -}; - -static int open_fip(const uintptr_t spec) +int open_fip(const uintptr_t spec) { return io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); } -static int open_storage(const uintptr_t spec) +int open_storage(const uintptr_t spec) { return io_dev_init(storage_dev_handle, 0); } @@ -478,9 +375,7 @@ int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, int rc; const struct plat_io_policy *policy; - assert(image_id < ARRAY_SIZE(policies)); - - policy = &policies[image_id]; + policy = FCONF_GET_PROPERTY(stm32mp, io_policies, image_id); rc = policy->check(policy->image_spec); if (rc == 0) { *image_spec = policy->image_spec; diff --git a/plat/st/common/include/stm32mp_fconf_getter.h b/plat/st/common/include/stm32mp_fconf_getter.h new file mode 100644 index 000000000..3a8bb11a4 --- /dev/null +++ b/plat/st/common/include/stm32mp_fconf_getter.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2021, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef STM32MP_FCONF_GETTER +#define STM32MP_FCONF_GETTER + +#include + +#include + +/* IO policies */ +#define stm32mp__io_policies_getter(id) __extension__ ({ \ + assert((id) < MAX_NUMBER_IDS); \ + &policies[id]; \ +}) + +struct plat_io_policy { + uintptr_t *dev_handle; + uintptr_t image_spec; + int (*check)(const uintptr_t spec); +}; + +extern struct plat_io_policy policies[]; +int fconf_populate_stm32mp_io_policies(uintptr_t config); + +#endif /* STM32MP_FCONF_GETTER */ diff --git a/plat/st/common/include/stm32mp_io_storage.h b/plat/st/common/include/stm32mp_io_storage.h new file mode 100644 index 000000000..989c890d4 --- /dev/null +++ b/plat/st/common/include/stm32mp_io_storage.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2021, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef STM32MP_IO_STORAGE_H +#define STM32MP_IO_STORAGE_H + +#include + +#include + +/* IO devices handle */ +extern uintptr_t storage_dev_handle; +extern uintptr_t fip_dev_handle; + +extern io_block_spec_t image_block_spec; + +/* Function declarations */ +int open_fip(const uintptr_t spec); +int open_storage(const uintptr_t spec); + +#endif /* STM32MP_IO_STORAGE_H */ diff --git a/plat/st/common/stm32mp_fconf_io.c b/plat/st/common/stm32mp_fconf_io.c new file mode 100644 index 000000000..aa8cd5441 --- /dev/null +++ b/plat/st/common/stm32mp_fconf_io.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2021, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#if STM32MP_SDMMC || STM32MP_EMMC +static io_block_spec_t gpt_block_spec = { + .offset = 0U, + .length = 34U * MMC_BLOCK_SIZE, /* Size of GPT table */ +}; +#endif + +/* By default, STM32 platforms load images from the FIP */ +struct plat_io_policy policies[MAX_NUMBER_IDS] = { + [FIP_IMAGE_ID] = { + &storage_dev_handle, + (uintptr_t)&image_block_spec, + open_storage + }, +#if STM32MP_SDMMC || STM32MP_EMMC + [GPT_IMAGE_ID] = { + &storage_dev_handle, + (uintptr_t)&gpt_block_spec, + open_storage + }, +#endif +}; + +#define FCONF_ST_IO_UUID_NUMBER U(8) + +static io_uuid_spec_t fconf_stm32mp_uuids[FCONF_ST_IO_UUID_NUMBER]; +static OBJECT_POOL_ARRAY(fconf_stm32mp_uuids_pool, fconf_stm32mp_uuids); + +struct policies_load_info { + unsigned int image_id; + const char *name; +}; + +/* image id to property name table */ +static const struct policies_load_info load_info[FCONF_ST_IO_UUID_NUMBER] = { + {FW_CONFIG_ID, "fw_cfg_uuid"}, + {BL32_IMAGE_ID, "bl32_uuid"}, + {BL32_EXTRA1_IMAGE_ID, "bl32_extra1_uuid"}, + {BL32_EXTRA2_IMAGE_ID, "bl32_extra2_uuid"}, + {BL33_IMAGE_ID, "bl33_uuid"}, + {HW_CONFIG_ID, "hw_cfg_uuid"}, + {TOS_FW_CONFIG_ID, "tos_fw_cfg_uuid"}, + {NT_FW_CONFIG_ID, "nt_fw_cfg_uuid"}, +}; + +int fconf_populate_stm32mp_io_policies(uintptr_t config) +{ + int node; + unsigned int i; + + /* As libfdt uses void *, we can't avoid this cast */ + const void *dtb = (void *)config; + + /* Assert the node offset point to "st,io-fip-handle" compatible property */ + const char *compatible_str = "st,io-fip-handle"; + + node = fdt_node_offset_by_compatible(dtb, -1, compatible_str); + if (node < 0) { + ERROR("FCONF: Can't find %s compatible in dtb\n", compatible_str); + return node; + } + + /* Locate the uuid cells and read the value for all the load info uuid */ + for (i = 0U; i < FCONF_ST_IO_UUID_NUMBER; i++) { + union uuid_helper_t uuid_helper; + io_uuid_spec_t *uuid_ptr; + int err; + + uuid_ptr = pool_alloc(&fconf_stm32mp_uuids_pool); + err = fdtw_read_uuid(dtb, node, load_info[i].name, 16, + (uint8_t *)&uuid_helper); + if (err < 0) { + WARN("FCONF: Read cell failed for %s\n", load_info[i].name); + return err; + } + + VERBOSE("FCONF: stm32mp-io_policies.%s cell found with value = " + "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n", + load_info[i].name, + uuid_helper.uuid_struct.time_low[0], uuid_helper.uuid_struct.time_low[1], + uuid_helper.uuid_struct.time_low[2], uuid_helper.uuid_struct.time_low[3], + uuid_helper.uuid_struct.time_mid[0], uuid_helper.uuid_struct.time_mid[1], + uuid_helper.uuid_struct.time_hi_and_version[0], + uuid_helper.uuid_struct.time_hi_and_version[1], + uuid_helper.uuid_struct.clock_seq_hi_and_reserved, + uuid_helper.uuid_struct.clock_seq_low, + uuid_helper.uuid_struct.node[0], uuid_helper.uuid_struct.node[1], + uuid_helper.uuid_struct.node[2], uuid_helper.uuid_struct.node[3], + uuid_helper.uuid_struct.node[4], uuid_helper.uuid_struct.node[5]); + + uuid_ptr->uuid = uuid_helper.uuid_struct; + policies[load_info[i].image_id].image_spec = (uintptr_t)uuid_ptr; + policies[load_info[i].image_id].dev_handle = &fip_dev_handle; + policies[load_info[i].image_id].check = open_fip; + } + + return 0; +} + +FCONF_REGISTER_POPULATOR(TB_FW, stm32mp_io, fconf_populate_stm32mp_io_policies); diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c index 9053a2541..e87c529b7 100644 --- a/plat/st/stm32mp1/bl2_plat_setup.c +++ b/plat/st/stm32mp1/bl2_plat_setup.c @@ -330,6 +330,10 @@ skip_console_init: print_reset_reason(); +#if !STM32MP_USE_STM32IMAGE + fconf_populate("TB_FW", STM32MP_DTB_BASE); +#endif /* !STM32MP_USE_STM32IMAGE */ + stm32mp_io_setup(); } diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk index d415a1ecc..891cfa4b6 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -157,6 +157,7 @@ PLAT_INCLUDES += -Iplat/st/stm32mp1/include/ include lib/libfdt/libfdt.mk PLAT_BL_COMMON_SOURCES := common/fdt_wrappers.c \ + common/uuid.c \ plat/st/common/stm32mp_common.c \ plat/st/stm32mp1/stm32mp1_private.c @@ -196,6 +197,7 @@ BL2_SOURCES += drivers/io/io_fip.c \ lib/fconf/fconf.c \ lib/fconf/fconf_dyn_cfg_getter.c \ plat/st/common/bl2_io_storage.c \ + plat/st/common/stm32mp_fconf_io.c \ plat/st/stm32mp1/plat_bl2_mem_params_desc.c else BL2_SOURCES += drivers/io/io_dummy.c \