1c9d75b3cSYann Gautier /* 2cddf1bd7SYann Gautier * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. 3c9d75b3cSYann Gautier * 4c9d75b3cSYann Gautier * SPDX-License-Identifier: BSD-3-Clause 5c9d75b3cSYann Gautier */ 6c9d75b3cSYann Gautier 7c9d75b3cSYann Gautier #include <assert.h> 8c9d75b3cSYann Gautier #include <string.h> 9c9d75b3cSYann Gautier 10c9d75b3cSYann Gautier #include <arch_helpers.h> 11c9d75b3cSYann Gautier #include <common/debug.h> 12*18b415beSYann Gautier #include <common/desc_image_load.h> 13c9d75b3cSYann Gautier #include <drivers/io/io_block.h> 14c9d75b3cSYann Gautier #include <drivers/io/io_driver.h> 151d204ee4SYann Gautier #include <drivers/io/io_fip.h> 1612e21dfdSLionel Debieve #include <drivers/io/io_mtd.h> 17c9d75b3cSYann Gautier #include <drivers/io/io_storage.h> 18c9d75b3cSYann Gautier #include <drivers/mmc.h> 19c9d75b3cSYann Gautier #include <drivers/partition/partition.h> 2012e21dfdSLionel Debieve #include <drivers/raw_nand.h> 2157044228SLionel Debieve #include <drivers/spi_nand.h> 22b1b218fbSLionel Debieve #include <drivers/spi_nor.h> 23c9d75b3cSYann Gautier #include <drivers/st/io_mmc.h> 2412e21dfdSLionel Debieve #include <drivers/st/stm32_fmc2_nand.h> 2557044228SLionel Debieve #include <drivers/st/stm32_qspi.h> 26c9d75b3cSYann Gautier #include <drivers/st/stm32_sdmmc2.h> 27c9d75b3cSYann Gautier #include <lib/mmio.h> 28c9d75b3cSYann Gautier #include <lib/utils.h> 29c9d75b3cSYann Gautier #include <plat/common/platform.h> 301d204ee4SYann Gautier #include <tools_share/firmware_image_package.h> 311d204ee4SYann Gautier 321d204ee4SYann Gautier #include <platform_def.h> 33c9d75b3cSYann Gautier 34c9d75b3cSYann Gautier /* IO devices */ 351d204ee4SYann Gautier uintptr_t fip_dev_handle; 361d204ee4SYann Gautier uintptr_t storage_dev_handle; 37c9d75b3cSYann Gautier 381d204ee4SYann Gautier static const io_dev_connector_t *fip_dev_con; 39c9d75b3cSYann Gautier 4046554b64SNicolas Le Bayon #if STM32MP_SDMMC || STM32MP_EMMC 41cddf1bd7SYann Gautier static struct mmc_device_info mmc_info; 42c9d75b3cSYann Gautier static io_block_spec_t gpt_block_spec = { 431d204ee4SYann Gautier .offset = 0U, 441d204ee4SYann Gautier .length = 34U * MMC_BLOCK_SIZE, /* Size of GPT table */ 45c9d75b3cSYann Gautier }; 46c9d75b3cSYann Gautier 47c9d75b3cSYann Gautier static uint32_t block_buffer[MMC_BLOCK_SIZE] __aligned(MMC_BLOCK_SIZE); 48c9d75b3cSYann Gautier 49*18b415beSYann Gautier static io_block_dev_spec_t mmc_block_dev_spec = { 50c9d75b3cSYann Gautier /* It's used as temp buffer in block driver */ 51c9d75b3cSYann Gautier .buffer = { 52c9d75b3cSYann Gautier .offset = (size_t)&block_buffer, 53c9d75b3cSYann Gautier .length = MMC_BLOCK_SIZE, 54c9d75b3cSYann Gautier }, 55c9d75b3cSYann Gautier .ops = { 56c9d75b3cSYann Gautier .read = mmc_read_blocks, 57c9d75b3cSYann Gautier .write = NULL, 58c9d75b3cSYann Gautier }, 59c9d75b3cSYann Gautier .block_size = MMC_BLOCK_SIZE, 60c9d75b3cSYann Gautier }; 61c9d75b3cSYann Gautier 62c9d75b3cSYann Gautier static const io_dev_connector_t *mmc_dev_con; 6346554b64SNicolas Le Bayon #endif /* STM32MP_SDMMC || STM32MP_EMMC */ 64c9d75b3cSYann Gautier 65b1b218fbSLionel Debieve #if STM32MP_SPI_NOR 66b1b218fbSLionel Debieve static io_mtd_dev_spec_t spi_nor_dev_spec = { 67b1b218fbSLionel Debieve .ops = { 68b1b218fbSLionel Debieve .init = spi_nor_init, 69b1b218fbSLionel Debieve .read = spi_nor_read, 70b1b218fbSLionel Debieve }, 71b1b218fbSLionel Debieve }; 72b1b218fbSLionel Debieve #endif 73b1b218fbSLionel Debieve 7412e21dfdSLionel Debieve #if STM32MP_RAW_NAND 7512e21dfdSLionel Debieve static io_mtd_dev_spec_t nand_dev_spec = { 7612e21dfdSLionel Debieve .ops = { 7712e21dfdSLionel Debieve .init = nand_raw_init, 7812e21dfdSLionel Debieve .read = nand_read, 791d204ee4SYann Gautier .seek = nand_seek_bb 8012e21dfdSLionel Debieve }, 8112e21dfdSLionel Debieve }; 8212e21dfdSLionel Debieve 8312e21dfdSLionel Debieve static const io_dev_connector_t *nand_dev_con; 8412e21dfdSLionel Debieve #endif 8512e21dfdSLionel Debieve 8657044228SLionel Debieve #if STM32MP_SPI_NAND 8757044228SLionel Debieve static io_mtd_dev_spec_t spi_nand_dev_spec = { 8857044228SLionel Debieve .ops = { 8957044228SLionel Debieve .init = spi_nand_init, 9057044228SLionel Debieve .read = nand_read, 911d204ee4SYann Gautier .seek = nand_seek_bb 9257044228SLionel Debieve }, 9357044228SLionel Debieve }; 94b1b218fbSLionel Debieve #endif 9557044228SLionel Debieve 96b1b218fbSLionel Debieve #if STM32MP_SPI_NAND || STM32MP_SPI_NOR 9757044228SLionel Debieve static const io_dev_connector_t *spi_dev_con; 9857044228SLionel Debieve #endif 9957044228SLionel Debieve 1001d204ee4SYann Gautier static const io_uuid_spec_t bl33_partition_spec = { 1011d204ee4SYann Gautier .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33 1021d204ee4SYann Gautier }; 1031d204ee4SYann Gautier 1041d204ee4SYann Gautier static const io_uuid_spec_t tos_fw_config_uuid_spec = { 1051d204ee4SYann Gautier .uuid = UUID_TOS_FW_CONFIG, 1061d204ee4SYann Gautier }; 1071d204ee4SYann Gautier 1081d204ee4SYann Gautier static const io_uuid_spec_t hw_config_uuid_spec = { 1091d204ee4SYann Gautier .uuid = UUID_HW_CONFIG, 1101d204ee4SYann Gautier }; 1111d204ee4SYann Gautier 1121989a19cSYann Gautier #ifdef AARCH32_SP_OPTEE 1131d204ee4SYann Gautier static const io_uuid_spec_t optee_header_partition_spec = { 1141d204ee4SYann Gautier .uuid = UUID_SECURE_PAYLOAD_BL32 1151989a19cSYann Gautier }; 1161989a19cSYann Gautier 1171d204ee4SYann Gautier static const io_uuid_spec_t optee_core_partition_spec = { 1181d204ee4SYann Gautier .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1 1191989a19cSYann Gautier }; 1201989a19cSYann Gautier 1211d204ee4SYann Gautier static const io_uuid_spec_t optee_paged_partition_spec = { 1221d204ee4SYann Gautier .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2 1231989a19cSYann Gautier }; 1241989a19cSYann Gautier #else 1251d204ee4SYann Gautier static const io_uuid_spec_t bl32_partition_spec = { 1261d204ee4SYann Gautier .uuid = UUID_SECURE_PAYLOAD_BL32 127c9d75b3cSYann Gautier }; 1281989a19cSYann Gautier #endif 129c9d75b3cSYann Gautier 1301d204ee4SYann Gautier static io_block_spec_t image_block_spec = { 1311d204ee4SYann Gautier .offset = 0U, 1321d204ee4SYann Gautier .length = 0U, 133c9d75b3cSYann Gautier }; 134c9d75b3cSYann Gautier 1351d204ee4SYann Gautier static int open_fip(const uintptr_t spec); 136c9d75b3cSYann Gautier static int open_storage(const uintptr_t spec); 137c9d75b3cSYann Gautier 138c9d75b3cSYann Gautier struct plat_io_policy { 139c9d75b3cSYann Gautier uintptr_t *dev_handle; 140c9d75b3cSYann Gautier uintptr_t image_spec; 141c9d75b3cSYann Gautier int (*check)(const uintptr_t spec); 142c9d75b3cSYann Gautier }; 143c9d75b3cSYann Gautier 144c9d75b3cSYann Gautier static const struct plat_io_policy policies[] = { 1451d204ee4SYann Gautier [FIP_IMAGE_ID] = { 1461d204ee4SYann Gautier .dev_handle = &storage_dev_handle, 1471d204ee4SYann Gautier .image_spec = (uintptr_t)&image_block_spec, 1481d204ee4SYann Gautier .check = open_storage 1491d204ee4SYann Gautier }, 1501989a19cSYann Gautier #ifdef AARCH32_SP_OPTEE 1511989a19cSYann Gautier [BL32_IMAGE_ID] = { 1521d204ee4SYann Gautier .dev_handle = &fip_dev_handle, 1531989a19cSYann Gautier .image_spec = (uintptr_t)&optee_header_partition_spec, 1541d204ee4SYann Gautier .check = open_fip 1551989a19cSYann Gautier }, 1561989a19cSYann Gautier [BL32_EXTRA1_IMAGE_ID] = { 1571d204ee4SYann Gautier .dev_handle = &fip_dev_handle, 15806c3b100SYann Gautier .image_spec = (uintptr_t)&optee_core_partition_spec, 1591d204ee4SYann Gautier .check = open_fip 1601989a19cSYann Gautier }, 1611989a19cSYann Gautier [BL32_EXTRA2_IMAGE_ID] = { 1621d204ee4SYann Gautier .dev_handle = &fip_dev_handle, 1631989a19cSYann Gautier .image_spec = (uintptr_t)&optee_paged_partition_spec, 1641d204ee4SYann Gautier .check = open_fip 1651989a19cSYann Gautier }, 1661989a19cSYann Gautier #else 167c9d75b3cSYann Gautier [BL32_IMAGE_ID] = { 1681d204ee4SYann Gautier .dev_handle = &fip_dev_handle, 1691d204ee4SYann Gautier .image_spec = (uintptr_t)&bl32_partition_spec, 1701d204ee4SYann Gautier .check = open_fip 171c9d75b3cSYann Gautier }, 1721989a19cSYann Gautier #endif 173c9d75b3cSYann Gautier [BL33_IMAGE_ID] = { 1741d204ee4SYann Gautier .dev_handle = &fip_dev_handle, 175c9d75b3cSYann Gautier .image_spec = (uintptr_t)&bl33_partition_spec, 1761d204ee4SYann Gautier .check = open_fip 1771d204ee4SYann Gautier }, 1781d204ee4SYann Gautier [TOS_FW_CONFIG_ID] = { 1791d204ee4SYann Gautier .dev_handle = &fip_dev_handle, 1801d204ee4SYann Gautier .image_spec = (uintptr_t)&tos_fw_config_uuid_spec, 1811d204ee4SYann Gautier .check = open_fip 1821d204ee4SYann Gautier }, 1831d204ee4SYann Gautier [HW_CONFIG_ID] = { 1841d204ee4SYann Gautier .dev_handle = &fip_dev_handle, 1851d204ee4SYann Gautier .image_spec = (uintptr_t)&hw_config_uuid_spec, 1861d204ee4SYann Gautier .check = open_fip 187c9d75b3cSYann Gautier }, 18846554b64SNicolas Le Bayon #if STM32MP_SDMMC || STM32MP_EMMC 189c9d75b3cSYann Gautier [GPT_IMAGE_ID] = { 190c9d75b3cSYann Gautier .dev_handle = &storage_dev_handle, 191c9d75b3cSYann Gautier .image_spec = (uintptr_t)&gpt_block_spec, 192c9d75b3cSYann Gautier .check = open_storage 193c9d75b3cSYann Gautier }, 19446554b64SNicolas Le Bayon #endif 195c9d75b3cSYann Gautier }; 196c9d75b3cSYann Gautier 1971d204ee4SYann Gautier static int open_fip(const uintptr_t spec) 198c9d75b3cSYann Gautier { 1991d204ee4SYann Gautier return io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); 200c9d75b3cSYann Gautier } 201c9d75b3cSYann Gautier 202c9d75b3cSYann Gautier static int open_storage(const uintptr_t spec) 203c9d75b3cSYann Gautier { 204c9d75b3cSYann Gautier return io_dev_init(storage_dev_handle, 0); 205c9d75b3cSYann Gautier } 206c9d75b3cSYann Gautier 207c9d75b3cSYann Gautier static void print_boot_device(boot_api_context_t *boot_context) 208c9d75b3cSYann Gautier { 209c9d75b3cSYann Gautier switch (boot_context->boot_interface_selected) { 210c9d75b3cSYann Gautier case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD: 211c9d75b3cSYann Gautier INFO("Using SDMMC\n"); 212c9d75b3cSYann Gautier break; 213c9d75b3cSYann Gautier case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC: 214c9d75b3cSYann Gautier INFO("Using EMMC\n"); 215c9d75b3cSYann Gautier break; 216b1b218fbSLionel Debieve case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI: 217b1b218fbSLionel Debieve INFO("Using QSPI NOR\n"); 218b1b218fbSLionel Debieve break; 21912e21dfdSLionel Debieve case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC: 22012e21dfdSLionel Debieve INFO("Using FMC NAND\n"); 22112e21dfdSLionel Debieve break; 22257044228SLionel Debieve case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI: 22357044228SLionel Debieve INFO("Using SPI NAND\n"); 22457044228SLionel Debieve break; 225c9d75b3cSYann Gautier default: 2261d204ee4SYann Gautier ERROR("Boot interface %u not found\n", 2271d204ee4SYann Gautier boot_context->boot_interface_selected); 228c9d75b3cSYann Gautier panic(); 229c9d75b3cSYann Gautier break; 230c9d75b3cSYann Gautier } 231c9d75b3cSYann Gautier 232c9d75b3cSYann Gautier if (boot_context->boot_interface_instance != 0U) { 233c9d75b3cSYann Gautier INFO(" Instance %d\n", boot_context->boot_interface_instance); 234c9d75b3cSYann Gautier } 235c9d75b3cSYann Gautier } 236c9d75b3cSYann Gautier 23746554b64SNicolas Le Bayon #if STM32MP_SDMMC || STM32MP_EMMC 2380b1aa772SYann Gautier static void boot_mmc(enum mmc_device_type mmc_dev_type, 2390b1aa772SYann Gautier uint16_t boot_interface_instance) 240c9d75b3cSYann Gautier { 241c9d75b3cSYann Gautier int io_result __unused; 242c9d75b3cSYann Gautier struct stm32_sdmmc2_params params; 243c9d75b3cSYann Gautier 24442beea8dSYann Gautier zeromem(¶ms, sizeof(struct stm32_sdmmc2_params)); 245c9d75b3cSYann Gautier 246cddf1bd7SYann Gautier mmc_info.mmc_dev_type = mmc_dev_type; 247c9d75b3cSYann Gautier 2480b1aa772SYann Gautier switch (boot_interface_instance) { 249c9d75b3cSYann Gautier case 1: 2503f9c9784SYann Gautier params.reg_base = STM32MP_SDMMC1_BASE; 251c9d75b3cSYann Gautier break; 252c9d75b3cSYann Gautier case 2: 2533f9c9784SYann Gautier params.reg_base = STM32MP_SDMMC2_BASE; 254c9d75b3cSYann Gautier break; 255c9d75b3cSYann Gautier case 3: 2563f9c9784SYann Gautier params.reg_base = STM32MP_SDMMC3_BASE; 257c9d75b3cSYann Gautier break; 258c9d75b3cSYann Gautier default: 259c9d75b3cSYann Gautier WARN("SDMMC instance not found, using default\n"); 2600b1aa772SYann Gautier if (mmc_dev_type == MMC_IS_SD) { 2610b1aa772SYann Gautier params.reg_base = STM32MP_SDMMC1_BASE; 2620b1aa772SYann Gautier } else { 2630b1aa772SYann Gautier params.reg_base = STM32MP_SDMMC2_BASE; 2640b1aa772SYann Gautier } 265c9d75b3cSYann Gautier break; 266c9d75b3cSYann Gautier } 267c9d75b3cSYann Gautier 268cddf1bd7SYann Gautier params.device_info = &mmc_info; 269c9d75b3cSYann Gautier if (stm32_sdmmc2_mmc_init(¶ms) != 0) { 2700b1aa772SYann Gautier ERROR("SDMMC%u init failed\n", boot_interface_instance); 271c9d75b3cSYann Gautier panic(); 272c9d75b3cSYann Gautier } 273c9d75b3cSYann Gautier 274c9d75b3cSYann Gautier /* Open MMC as a block device to read GPT table */ 275c9d75b3cSYann Gautier io_result = register_io_dev_block(&mmc_dev_con); 276c9d75b3cSYann Gautier if (io_result != 0) { 277c9d75b3cSYann Gautier panic(); 278c9d75b3cSYann Gautier } 279c9d75b3cSYann Gautier 2800b1aa772SYann Gautier io_result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_block_dev_spec, 281c9d75b3cSYann Gautier &storage_dev_handle); 282c9d75b3cSYann Gautier assert(io_result == 0); 2830b1aa772SYann Gautier } 28446554b64SNicolas Le Bayon #endif /* STM32MP_SDMMC || STM32MP_EMMC */ 2850b1aa772SYann Gautier 286b1b218fbSLionel Debieve #if STM32MP_SPI_NOR 287b1b218fbSLionel Debieve static void boot_spi_nor(boot_api_context_t *boot_context) 288b1b218fbSLionel Debieve { 289b1b218fbSLionel Debieve int io_result __unused; 290b1b218fbSLionel Debieve 291b1b218fbSLionel Debieve io_result = stm32_qspi_init(); 292b1b218fbSLionel Debieve assert(io_result == 0); 293b1b218fbSLionel Debieve 294b1b218fbSLionel Debieve io_result = register_io_dev_mtd(&spi_dev_con); 295b1b218fbSLionel Debieve assert(io_result == 0); 296b1b218fbSLionel Debieve 297b1b218fbSLionel Debieve /* Open connections to device */ 298b1b218fbSLionel Debieve io_result = io_dev_open(spi_dev_con, 299b1b218fbSLionel Debieve (uintptr_t)&spi_nor_dev_spec, 300b1b218fbSLionel Debieve &storage_dev_handle); 301b1b218fbSLionel Debieve assert(io_result == 0); 302b1b218fbSLionel Debieve } 303b1b218fbSLionel Debieve #endif /* STM32MP_SPI_NOR */ 304b1b218fbSLionel Debieve 30512e21dfdSLionel Debieve #if STM32MP_RAW_NAND 30612e21dfdSLionel Debieve static void boot_fmc2_nand(boot_api_context_t *boot_context) 30712e21dfdSLionel Debieve { 30812e21dfdSLionel Debieve int io_result __unused; 30912e21dfdSLionel Debieve 31012e21dfdSLionel Debieve io_result = stm32_fmc2_init(); 31112e21dfdSLionel Debieve assert(io_result == 0); 31212e21dfdSLionel Debieve 31312e21dfdSLionel Debieve /* Register the IO device on this platform */ 31412e21dfdSLionel Debieve io_result = register_io_dev_mtd(&nand_dev_con); 31512e21dfdSLionel Debieve assert(io_result == 0); 31612e21dfdSLionel Debieve 31712e21dfdSLionel Debieve /* Open connections to device */ 31812e21dfdSLionel Debieve io_result = io_dev_open(nand_dev_con, (uintptr_t)&nand_dev_spec, 31912e21dfdSLionel Debieve &storage_dev_handle); 32012e21dfdSLionel Debieve assert(io_result == 0); 32112e21dfdSLionel Debieve } 32212e21dfdSLionel Debieve #endif /* STM32MP_RAW_NAND */ 32312e21dfdSLionel Debieve 32457044228SLionel Debieve #if STM32MP_SPI_NAND 32557044228SLionel Debieve static void boot_spi_nand(boot_api_context_t *boot_context) 32657044228SLionel Debieve { 32757044228SLionel Debieve int io_result __unused; 32857044228SLionel Debieve 32957044228SLionel Debieve io_result = stm32_qspi_init(); 33057044228SLionel Debieve assert(io_result == 0); 33157044228SLionel Debieve 33257044228SLionel Debieve io_result = register_io_dev_mtd(&spi_dev_con); 33357044228SLionel Debieve assert(io_result == 0); 33457044228SLionel Debieve 33557044228SLionel Debieve /* Open connections to device */ 33657044228SLionel Debieve io_result = io_dev_open(spi_dev_con, 33757044228SLionel Debieve (uintptr_t)&spi_nand_dev_spec, 33857044228SLionel Debieve &storage_dev_handle); 33957044228SLionel Debieve assert(io_result == 0); 34057044228SLionel Debieve } 34157044228SLionel Debieve #endif /* STM32MP_SPI_NAND */ 34257044228SLionel Debieve 3430b1aa772SYann Gautier void stm32mp_io_setup(void) 3440b1aa772SYann Gautier { 3450b1aa772SYann Gautier int io_result __unused; 3460b1aa772SYann Gautier boot_api_context_t *boot_context = 3470b1aa772SYann Gautier (boot_api_context_t *)stm32mp_get_boot_ctx_address(); 3480b1aa772SYann Gautier 3490b1aa772SYann Gautier print_boot_device(boot_context); 3500b1aa772SYann Gautier 3510b1aa772SYann Gautier if ((boot_context->boot_partition_used_toboot == 1U) || 3520b1aa772SYann Gautier (boot_context->boot_partition_used_toboot == 2U)) { 3531d204ee4SYann Gautier INFO("Boot used partition fsbl%u\n", 3540b1aa772SYann Gautier boot_context->boot_partition_used_toboot); 3550b1aa772SYann Gautier } 3560b1aa772SYann Gautier 3571d204ee4SYann Gautier io_result = register_io_dev_fip(&fip_dev_con); 3580b1aa772SYann Gautier assert(io_result == 0); 3590b1aa772SYann Gautier 3601d204ee4SYann Gautier io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, 3611d204ee4SYann Gautier &fip_dev_handle); 3620b1aa772SYann Gautier 3630b1aa772SYann Gautier switch (boot_context->boot_interface_selected) { 36446554b64SNicolas Le Bayon #if STM32MP_SDMMC 3650b1aa772SYann Gautier case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD: 3660b1aa772SYann Gautier dmbsy(); 3670b1aa772SYann Gautier boot_mmc(MMC_IS_SD, boot_context->boot_interface_instance); 3680b1aa772SYann Gautier break; 36946554b64SNicolas Le Bayon #endif 37046554b64SNicolas Le Bayon #if STM32MP_EMMC 3710b1aa772SYann Gautier case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC: 3720b1aa772SYann Gautier dmbsy(); 3730b1aa772SYann Gautier boot_mmc(MMC_IS_EMMC, boot_context->boot_interface_instance); 374c9d75b3cSYann Gautier break; 37546554b64SNicolas Le Bayon #endif 376b1b218fbSLionel Debieve #if STM32MP_SPI_NOR 377b1b218fbSLionel Debieve case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI: 378b1b218fbSLionel Debieve dmbsy(); 379b1b218fbSLionel Debieve boot_spi_nor(boot_context); 380b1b218fbSLionel Debieve break; 381b1b218fbSLionel Debieve #endif 38212e21dfdSLionel Debieve #if STM32MP_RAW_NAND 38312e21dfdSLionel Debieve case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC: 38412e21dfdSLionel Debieve dmbsy(); 38512e21dfdSLionel Debieve boot_fmc2_nand(boot_context); 38612e21dfdSLionel Debieve break; 38712e21dfdSLionel Debieve #endif 38857044228SLionel Debieve #if STM32MP_SPI_NAND 38957044228SLionel Debieve case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI: 39057044228SLionel Debieve dmbsy(); 39157044228SLionel Debieve boot_spi_nand(boot_context); 39257044228SLionel Debieve break; 39357044228SLionel Debieve #endif 394c9d75b3cSYann Gautier 395c9d75b3cSYann Gautier default: 396c9d75b3cSYann Gautier ERROR("Boot interface %d not supported\n", 397c9d75b3cSYann Gautier boot_context->boot_interface_selected); 39871693a66SYann Gautier panic(); 399c9d75b3cSYann Gautier break; 400c9d75b3cSYann Gautier } 401c9d75b3cSYann Gautier } 402c9d75b3cSYann Gautier 4031d204ee4SYann Gautier int bl2_plat_handle_pre_image_load(unsigned int image_id) 4041d204ee4SYann Gautier { 4051d204ee4SYann Gautier static bool gpt_init_done __unused; 4061d204ee4SYann Gautier uint16_t boot_itf = stm32mp_get_boot_itf_selected(); 4071d204ee4SYann Gautier 4081d204ee4SYann Gautier switch (boot_itf) { 4091d204ee4SYann Gautier #if STM32MP_SDMMC || STM32MP_EMMC 4101d204ee4SYann Gautier case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD: 4111d204ee4SYann Gautier case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC: 4121d204ee4SYann Gautier if (!gpt_init_done) { 4131d204ee4SYann Gautier const partition_entry_t *entry; 4141d204ee4SYann Gautier 4151d204ee4SYann Gautier partition_init(GPT_IMAGE_ID); 4161d204ee4SYann Gautier entry = get_partition_entry(FIP_IMAGE_NAME); 4171d204ee4SYann Gautier if (entry == NULL) { 4181d204ee4SYann Gautier ERROR("Could NOT find the %s partition!\n", 4191d204ee4SYann Gautier FIP_IMAGE_NAME); 4201d204ee4SYann Gautier return -ENOENT; 4211d204ee4SYann Gautier } 4221d204ee4SYann Gautier 4231d204ee4SYann Gautier image_block_spec.offset = entry->start; 4241d204ee4SYann Gautier image_block_spec.length = entry->length; 4251d204ee4SYann Gautier 4261d204ee4SYann Gautier gpt_init_done = true; 427*18b415beSYann Gautier } else { 428*18b415beSYann Gautier bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id); 429*18b415beSYann Gautier 430*18b415beSYann Gautier mmc_block_dev_spec.buffer.offset = bl_mem_params->image_info.image_base; 431*18b415beSYann Gautier mmc_block_dev_spec.buffer.length = bl_mem_params->image_info.image_max_size; 4321d204ee4SYann Gautier } 4331d204ee4SYann Gautier 4341d204ee4SYann Gautier break; 4351d204ee4SYann Gautier #endif 4361d204ee4SYann Gautier 4371d204ee4SYann Gautier #if STM32MP_RAW_NAND || STM32MP_SPI_NAND 4381d204ee4SYann Gautier #if STM32MP_RAW_NAND 4391d204ee4SYann Gautier case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC: 4401d204ee4SYann Gautier #endif 4411d204ee4SYann Gautier #if STM32MP_SPI_NAND 4421d204ee4SYann Gautier case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI: 4431d204ee4SYann Gautier #endif 4441d204ee4SYann Gautier image_block_spec.offset = STM32MP_NAND_FIP_OFFSET; 4451d204ee4SYann Gautier break; 4461d204ee4SYann Gautier #endif 4471d204ee4SYann Gautier 4481d204ee4SYann Gautier #if STM32MP_SPI_NOR 4491d204ee4SYann Gautier case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI: 4501d204ee4SYann Gautier image_block_spec.offset = STM32MP_NOR_FIP_OFFSET; 4511d204ee4SYann Gautier break; 4521d204ee4SYann Gautier #endif 4531d204ee4SYann Gautier 4541d204ee4SYann Gautier default: 4551d204ee4SYann Gautier ERROR("FIP Not found\n"); 4561d204ee4SYann Gautier panic(); 4571d204ee4SYann Gautier } 4581d204ee4SYann Gautier 4591d204ee4SYann Gautier return 0; 4601d204ee4SYann Gautier } 4611d204ee4SYann Gautier 462c9d75b3cSYann Gautier /* 463c9d75b3cSYann Gautier * Return an IO device handle and specification which can be used to access 464c9d75b3cSYann Gautier * an image. Use this to enforce platform load policy. 465c9d75b3cSYann Gautier */ 466c9d75b3cSYann Gautier int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, 467c9d75b3cSYann Gautier uintptr_t *image_spec) 468c9d75b3cSYann Gautier { 469c9d75b3cSYann Gautier int rc; 470c9d75b3cSYann Gautier const struct plat_io_policy *policy; 471c9d75b3cSYann Gautier 472c9d75b3cSYann Gautier assert(image_id < ARRAY_SIZE(policies)); 473c9d75b3cSYann Gautier 474c9d75b3cSYann Gautier policy = &policies[image_id]; 475c9d75b3cSYann Gautier rc = policy->check(policy->image_spec); 476c9d75b3cSYann Gautier if (rc == 0) { 477c9d75b3cSYann Gautier *image_spec = policy->image_spec; 478c9d75b3cSYann Gautier *dev_handle = *(policy->dev_handle); 479c9d75b3cSYann Gautier } 480c9d75b3cSYann Gautier 481c9d75b3cSYann Gautier return rc; 482c9d75b3cSYann Gautier } 483