diff --git a/fdts/stm32mp15-bl2.dtsi b/fdts/stm32mp15-bl2.dtsi index ce9ad85bf72bd94670d39b3fab55a5069333fcca..1c59990245dc3d6301519e2b4e8008a97f5ad506 100644 --- a/fdts/stm32mp15-bl2.dtsi +++ b/fdts/stm32mp15-bl2.dtsi @@ -28,6 +28,7 @@ }; }; +#if !STM32MP_USE_STM32IMAGE /* * UUID's here are UUID RFC 4122 compliant meaning fieds are stored in * network order (big endian) @@ -52,4 +53,5 @@ nt_fw_content_cert_uuid = <0x8ec4c1f3 0x5d63e411 0xa7a987ee 0x40b23fa7>; }; }; +#endif /* !STM32MP_USE_STM32IMAGE */ }; diff --git a/plat/st/common/bl2_stm32_io_storage.c b/plat/st/common/bl2_stm32_io_storage.c new file mode 100644 index 0000000000000000000000000000000000000000..5e7ecfad483f31496b24d5814bef21448682ae44 --- /dev/null +++ b/plat/st/common/bl2_stm32_io_storage.c @@ -0,0 +1,769 @@ +/* + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <string.h> + +#include <platform_def.h> + +#include <arch_helpers.h> +#include <common/debug.h> +#include <common/desc_image_load.h> +#include <drivers/io/io_block.h> +#include <drivers/io/io_driver.h> +#include <drivers/io/io_dummy.h> +#include <drivers/io/io_memmap.h> +#include <drivers/io/io_mtd.h> +#include <drivers/io/io_storage.h> +#include <drivers/mmc.h> +#include <drivers/partition/partition.h> +#include <drivers/raw_nand.h> +#include <drivers/spi_nand.h> +#include <drivers/spi_nor.h> +#include <drivers/st/io_mmc.h> +#include <drivers/st/io_stm32image.h> +#include <drivers/st/stm32_fmc2_nand.h> +#include <drivers/st/stm32_qspi.h> +#include <drivers/st/stm32_sdmmc2.h> +#include <lib/mmio.h> +#include <lib/utils.h> +#include <lib/usb/usb_core.h> +#include <lib/usb/usb_st_dfu.h> +#include <plat/common/platform.h> + +#include <stm32cubeprogrammer.h> + +/* IO devices */ +#ifndef AARCH32_SP_OPTEE +static const io_dev_connector_t *dummy_dev_con; +static uintptr_t dummy_dev_handle; +static uintptr_t dummy_dev_spec; +#endif + +static uintptr_t image_dev_handle; +static uintptr_t storage_dev_handle; + +#if STM32MP_SDMMC || STM32MP_EMMC +static io_block_spec_t gpt_block_spec = { + .offset = 0, + .length = 34 * MMC_BLOCK_SIZE, /* Size of GPT table */ +}; + +static uint32_t block_buffer[MMC_BLOCK_SIZE] __aligned(MMC_BLOCK_SIZE); + +static const io_block_dev_spec_t mmc_block_dev_spec = { + /* It's used as temp buffer in block driver */ + .buffer = { + .offset = (size_t)&block_buffer, + .length = MMC_BLOCK_SIZE, + }, + .ops = { + .read = mmc_read_blocks, + .write = NULL, + }, + .block_size = MMC_BLOCK_SIZE, +}; + +static const io_dev_connector_t *mmc_dev_con; +#endif /* STM32MP_SDMMC || STM32MP_EMMC */ + +#if STM32MP_SPI_NOR +static io_mtd_dev_spec_t spi_nor_dev_spec = { + .ops = { + .init = spi_nor_init, + .read = spi_nor_read, + }, +}; +#endif + +#if STM32MP_RAW_NAND +static io_mtd_dev_spec_t nand_dev_spec = { + .ops = { + .init = nand_raw_init, + .read = nand_read, + }, +}; + +static const io_dev_connector_t *nand_dev_con; +#endif + +#if STM32MP_SPI_NAND +static io_mtd_dev_spec_t spi_nand_dev_spec = { + .ops = { + .init = spi_nand_init, + .read = nand_read, + }, +}; +#endif + +#if STM32MP_SPI_NAND || STM32MP_SPI_NOR +static const io_dev_connector_t *spi_dev_con; +#endif + +#if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER +static const io_dev_connector_t *memmap_dev_con; +#endif + +#ifdef AARCH32_SP_OPTEE +static const struct stm32image_part_info optee_header_partition_spec = { + .name = OPTEE_HEADER_IMAGE_NAME, + .binary_type = OPTEE_HEADER_BINARY_TYPE, +}; + +static const struct stm32image_part_info optee_core_partition_spec = { + .name = OPTEE_CORE_IMAGE_NAME, + .binary_type = OPTEE_CORE_BINARY_TYPE, +}; + +static const struct stm32image_part_info optee_paged_partition_spec = { + .name = OPTEE_PAGED_IMAGE_NAME, + .binary_type = OPTEE_PAGED_BINARY_TYPE, +}; +#else +static const io_block_spec_t bl32_block_spec = { + .offset = BL32_BASE, + .length = STM32MP_BL32_SIZE +}; +#endif + +static const struct stm32image_part_info bl33_partition_spec = { + .name = BL33_IMAGE_NAME, + .binary_type = BL33_BINARY_TYPE, +}; + +enum { + IMG_IDX_BL33, +#ifdef AARCH32_SP_OPTEE + IMG_IDX_OPTEE_HEADER, + IMG_IDX_OPTEE_CORE, + IMG_IDX_OPTEE_PAGED, +#endif + IMG_IDX_NUM +}; + +static struct stm32image_device_info stm32image_dev_info_spec __unused = { + .lba_size = MMC_BLOCK_SIZE, + .part_info[IMG_IDX_BL33] = { + .name = BL33_IMAGE_NAME, + .binary_type = BL33_BINARY_TYPE, + }, +#ifdef AARCH32_SP_OPTEE + .part_info[IMG_IDX_OPTEE_HEADER] = { + .name = OPTEE_HEADER_IMAGE_NAME, + .binary_type = OPTEE_HEADER_BINARY_TYPE, + }, + .part_info[IMG_IDX_OPTEE_CORE] = { + .name = OPTEE_CORE_IMAGE_NAME, + .binary_type = OPTEE_CORE_BINARY_TYPE, + }, + .part_info[IMG_IDX_OPTEE_PAGED] = { + .name = OPTEE_PAGED_IMAGE_NAME, + .binary_type = OPTEE_PAGED_BINARY_TYPE, + }, +#endif +}; + +static io_block_spec_t image_block_spec = { + .offset = 0, + .length = 0, +}; + +static const io_dev_connector_t *stm32image_dev_con __unused; + +#ifndef AARCH32_SP_OPTEE +static int open_dummy(const uintptr_t spec); +#endif +static int open_image(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[] = { +#ifdef AARCH32_SP_OPTEE + [BL32_IMAGE_ID] = { + .dev_handle = &image_dev_handle, + .image_spec = (uintptr_t)&optee_header_partition_spec, + .check = open_image + }, + [BL32_EXTRA1_IMAGE_ID] = { + .dev_handle = &image_dev_handle, + .image_spec = (uintptr_t)&optee_core_partition_spec, + .check = open_image + }, + [BL32_EXTRA2_IMAGE_ID] = { + .dev_handle = &image_dev_handle, + .image_spec = (uintptr_t)&optee_paged_partition_spec, + .check = open_image + }, +#else + [BL32_IMAGE_ID] = { + .dev_handle = &dummy_dev_handle, + .image_spec = (uintptr_t)&bl32_block_spec, + .check = open_dummy + }, +#endif + [BL33_IMAGE_ID] = { + .dev_handle = &image_dev_handle, + .image_spec = (uintptr_t)&bl33_partition_spec, + .check = open_image + }, +#if STM32MP_SDMMC || STM32MP_EMMC + [GPT_IMAGE_ID] = { + .dev_handle = &storage_dev_handle, + .image_spec = (uintptr_t)&gpt_block_spec, + .check = open_storage + }, +#endif + [STM32_IMAGE_ID] = { + .dev_handle = &storage_dev_handle, + .image_spec = (uintptr_t)&image_block_spec, + .check = open_storage + }, +}; + +#ifndef AARCH32_SP_OPTEE +static int open_dummy(const uintptr_t spec) +{ + return io_dev_init(dummy_dev_handle, 0); +} +#endif + +static int open_image(const uintptr_t spec) +{ + return io_dev_init(image_dev_handle, 0); +} + +static int open_storage(const uintptr_t spec) +{ + return io_dev_init(storage_dev_handle, 0); +} + +static void print_boot_device(boot_api_context_t *boot_context) +{ + switch (boot_context->boot_interface_selected) { + case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD: + INFO("Using SDMMC\n"); + break; + case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC: + INFO("Using EMMC\n"); + break; + case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_SPI: + INFO("Using SPI NOR\n"); + break; + case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC: + INFO("Using FMC NAND\n"); + break; + case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_SPI: + INFO("Using SPI NAND\n"); + break; + case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART: + INFO("Using UART\n"); + break; + case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB: + INFO("Using USB\n"); + break; + default: + ERROR("Boot interface %u not found\n", + boot_context->boot_interface_selected); + panic(); + break; + } + + if (boot_context->boot_interface_instance != 0U) { + INFO(" Instance %d\n", boot_context->boot_interface_instance); + } +} + +static void stm32image_io_setup(void) +{ + int io_result __unused; + + io_result = register_io_dev_stm32image(&stm32image_dev_con); + assert(io_result == 0); + + io_result = io_dev_open(stm32image_dev_con, + (uintptr_t)&stm32image_dev_info_spec, + &image_dev_handle); + assert(io_result == 0); +} + +#if STM32MP_SDMMC || STM32MP_EMMC +static void boot_mmc(enum mmc_device_type mmc_dev_type, + uint16_t boot_interface_instance) +{ + int io_result __unused; + uint8_t idx; + struct stm32image_part_info *part; + struct stm32_sdmmc2_params params; + struct mmc_device_info device_info; + const partition_entry_t *entry; + + zeromem(&device_info, sizeof(struct mmc_device_info)); + zeromem(¶ms, sizeof(struct stm32_sdmmc2_params)); + + device_info.mmc_dev_type = mmc_dev_type; + + switch (boot_interface_instance) { + case 1: + params.reg_base = STM32MP_SDMMC1_BASE; + break; + case 2: + params.reg_base = STM32MP_SDMMC2_BASE; + break; + case 3: + params.reg_base = STM32MP_SDMMC3_BASE; + break; + default: + WARN("SDMMC instance not found, using default\n"); + if (mmc_dev_type == MMC_IS_SD) { + params.reg_base = STM32MP_SDMMC1_BASE; + } else { + params.reg_base = STM32MP_SDMMC2_BASE; + } + break; + } + + if (mmc_dev_type == MMC_IS_SD) { + params.flags = MMC_FLAG_SD_CMD6; + } + + params.device_info = &device_info; + if (stm32_sdmmc2_mmc_init(¶ms) != 0) { + ERROR("SDMMC%u init failed\n", boot_interface_instance); + panic(); + } + + /* Open MMC as a block device to read GPT table */ + io_result = register_io_dev_block(&mmc_dev_con); + if (io_result != 0) { + panic(); + } + + io_result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_block_dev_spec, + &storage_dev_handle); + assert(io_result == 0); + + partition_init(GPT_IMAGE_ID); + + io_result = io_dev_close(storage_dev_handle); + assert(io_result == 0); + + stm32image_dev_info_spec.device_size = + stm32_sdmmc2_mmc_get_device_size(); + + for (idx = 0U; idx < IMG_IDX_NUM; idx++) { + part = &stm32image_dev_info_spec.part_info[idx]; + entry = get_partition_entry(part->name); + if (entry == NULL) { + ERROR("Partition %s not found\n", part->name); + panic(); + } + + part->part_offset = entry->start; + part->bkp_offset = 0U; + } + + /* + * Re-open MMC with io_mmc, for better perfs compared to + * io_block. + */ + io_result = register_io_dev_mmc(&mmc_dev_con); + assert(io_result == 0); + + io_result = io_dev_open(mmc_dev_con, 0, &storage_dev_handle); + assert(io_result == 0); +} +#endif /* STM32MP_SDMMC || STM32MP_EMMC */ + +#if STM32MP_SPI_NOR +static void boot_spi_nor(boot_api_context_t *boot_context) +{ + int io_result __unused; + uint8_t idx; + struct stm32image_part_info *part; + + io_result = stm32_qspi_init(); + assert(io_result == 0); + + io_result = register_io_dev_mtd(&spi_dev_con); + assert(io_result == 0); + + /* Open connections to device */ + io_result = io_dev_open(spi_dev_con, + (uintptr_t)&spi_nor_dev_spec, + &storage_dev_handle); + assert(io_result == 0); + + stm32image_dev_info_spec.device_size = spi_nor_dev_spec.device_size; + + idx = IMG_IDX_BL33; + part = &stm32image_dev_info_spec.part_info[idx]; + part->part_offset = STM32MP_NOR_BL33_OFFSET; + part->bkp_offset = 0U; + +#ifdef AARCH32_SP_OPTEE + idx = IMG_IDX_OPTEE_HEADER; + part = &stm32image_dev_info_spec.part_info[idx]; + part->part_offset = STM32MP_NOR_TEEH_OFFSET; + part->bkp_offset = 0U; + + idx = IMG_IDX_OPTEE_PAGED; + part = &stm32image_dev_info_spec.part_info[idx]; + part->part_offset = STM32MP_NOR_TEED_OFFSET; + part->bkp_offset = 0U; + + idx = IMG_IDX_OPTEE_CORE; + part = &stm32image_dev_info_spec.part_info[idx]; + part->part_offset = STM32MP_NOR_TEEX_OFFSET; + part->bkp_offset = 0U; +#endif +} +#endif /* STM32MP_SPI_NOR */ + +#if STM32MP_RAW_NAND +static void boot_fmc2_nand(boot_api_context_t *boot_context) +{ + int io_result __unused; + uint8_t idx; + struct stm32image_part_info *part; + + io_result = stm32_fmc2_init(); + assert(io_result == 0); + + /* Register the IO device on this platform */ + io_result = register_io_dev_mtd(&nand_dev_con); + assert(io_result == 0); + + /* Open connections to device */ + io_result = io_dev_open(nand_dev_con, (uintptr_t)&nand_dev_spec, + &storage_dev_handle); + assert(io_result == 0); + + stm32image_dev_info_spec.device_size = nand_dev_spec.device_size; + + idx = IMG_IDX_BL33; + part = &stm32image_dev_info_spec.part_info[idx]; + part->part_offset = STM32MP_NAND_BL33_OFFSET; + part->bkp_offset = nand_dev_spec.erase_size; + +#ifdef AARCH32_SP_OPTEE + idx = IMG_IDX_OPTEE_HEADER; + part = &stm32image_dev_info_spec.part_info[idx]; + part->part_offset = STM32MP_NAND_TEEH_OFFSET; + part->bkp_offset = nand_dev_spec.erase_size; + + idx = IMG_IDX_OPTEE_PAGED; + part = &stm32image_dev_info_spec.part_info[idx]; + part->part_offset = STM32MP_NAND_TEED_OFFSET; + part->bkp_offset = nand_dev_spec.erase_size; + + idx = IMG_IDX_OPTEE_CORE; + part = &stm32image_dev_info_spec.part_info[idx]; + part->part_offset = STM32MP_NAND_TEEX_OFFSET; + part->bkp_offset = nand_dev_spec.erase_size; +#endif +} +#endif /* STM32MP_RAW_NAND */ + +#if STM32MP_SPI_NAND +static void boot_spi_nand(boot_api_context_t *boot_context) +{ + int io_result __unused; + uint8_t idx; + struct stm32image_part_info *part; + + io_result = stm32_qspi_init(); + assert(io_result == 0); + + io_result = register_io_dev_mtd(&spi_dev_con); + assert(io_result == 0); + + /* Open connections to device */ + io_result = io_dev_open(spi_dev_con, + (uintptr_t)&spi_nand_dev_spec, + &storage_dev_handle); + assert(io_result == 0); + + stm32image_dev_info_spec.device_size = spi_nand_dev_spec.device_size; + + idx = IMG_IDX_BL33; + part = &stm32image_dev_info_spec.part_info[idx]; + part->part_offset = STM32MP_NAND_BL33_OFFSET; + part->bkp_offset = spi_nand_dev_spec.erase_size; + +#ifdef AARCH32_SP_OPTEE + idx = IMG_IDX_OPTEE_HEADER; + part = &stm32image_dev_info_spec.part_info[idx]; + part->part_offset = STM32MP_NAND_TEEH_OFFSET; + part->bkp_offset = spi_nand_dev_spec.erase_size; + + idx = IMG_IDX_OPTEE_PAGED; + part = &stm32image_dev_info_spec.part_info[idx]; + part->part_offset = STM32MP_NAND_TEED_OFFSET; + part->bkp_offset = spi_nand_dev_spec.erase_size; + + idx = IMG_IDX_OPTEE_CORE; + part = &stm32image_dev_info_spec.part_info[idx]; + part->part_offset = STM32MP_NAND_TEEX_OFFSET; + part->bkp_offset = spi_nand_dev_spec.erase_size; +#endif +} +#endif /* STM32MP_SPI_NAND */ + +#if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER +static void mmap_io_setup(void) +{ + int io_result __unused; + + io_result = register_io_dev_memmap(&memmap_dev_con); + assert(io_result == 0); + + io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, + &storage_dev_handle); + assert(io_result == 0); +} + +static void stm32image_mmap_setup(void) +{ + uint8_t idx; + struct stm32image_part_info *part; + + stm32image_dev_info_spec.device_size = DWL_BUFFER_SIZE; + + idx = IMG_IDX_BL33; + part = &stm32image_dev_info_spec.part_info[idx]; + part->part_offset = 0; + part->bkp_offset = 0; +} +#endif + +#if STM32MP_UART_PROGRAMMER +static void stm32cubeprogrammer_uart(unsigned int image_id) +{ + int ret __unused; + boot_api_context_t *boot_context = + (boot_api_context_t *)stm32mp_get_boot_ctx_address(); + uintptr_t uart_base; + + uart_base = get_uart_address(boot_context->boot_interface_instance); + ret = stm32cubeprog_uart_load(image_id, uart_base, FLASHLAYOUT_BASE, FLASHLAYOUT_SIZE, + DWL_BUFFER_BASE, DWL_BUFFER_SIZE); + assert(ret == 0); + + flush_dcache_range(FLASHLAYOUT_BASE, FLASHLAYOUT_SIZE); +} +#endif + +#if STM32MP_USB_PROGRAMMER +static void stm32cubeprogrammer_usb(unsigned int image_id) +{ + usb_handle_t *pdev; + int ret __unused; + + /* init USB on platform */ + pdev = usb_dfu_plat_init(); + + ret = stm32cubeprog_usb_load(image_id, pdev, FLASHLAYOUT_BASE, FLASHLAYOUT_SIZE, + DWL_BUFFER_BASE, DWL_BUFFER_SIZE); + assert(ret == 0); + + flush_dcache_range(FLASHLAYOUT_BASE, FLASHLAYOUT_SIZE); +} +#endif + +void stm32mp_io_setup(void) +{ + int io_result __unused; + boot_api_context_t *boot_context = + (boot_api_context_t *)stm32mp_get_boot_ctx_address(); + + print_boot_device(boot_context); + + if ((boot_context->boot_partition_used_toboot == 1U) || + (boot_context->boot_partition_used_toboot == 2U)) { + INFO("Boot used partition fsbl%d\n", + boot_context->boot_partition_used_toboot); + } + +#ifndef AARCH32_SP_OPTEE + io_result = register_io_dev_dummy(&dummy_dev_con); + assert(io_result == 0); + + io_result = io_dev_open(dummy_dev_con, dummy_dev_spec, + &dummy_dev_handle); + assert(io_result == 0); +#endif + + switch (boot_context->boot_interface_selected) { +#if STM32MP_SDMMC + case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD: + dmbsy(); + boot_mmc(MMC_IS_SD, boot_context->boot_interface_instance); + stm32image_io_setup(); + break; +#endif +#if STM32MP_EMMC + case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC: + dmbsy(); + boot_mmc(MMC_IS_EMMC, boot_context->boot_interface_instance); + stm32image_io_setup(); + break; +#endif +#if STM32MP_SPI_NOR + case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_SPI: + dmbsy(); + boot_spi_nor(boot_context); + stm32image_io_setup(); + break; +#endif +#if STM32MP_RAW_NAND + case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC: + dmbsy(); + boot_fmc2_nand(boot_context); + stm32image_io_setup(); + break; +#endif +#if STM32MP_SPI_NAND + case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_SPI: + dmbsy(); + boot_spi_nand(boot_context); + stm32image_io_setup(); + break; +#endif +#if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER +#if STM32MP_UART_PROGRAMMER + case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART: +#endif +#if STM32MP_USB_PROGRAMMER + case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB: +#endif + dmbsy(); + mmap_io_setup(); + stm32image_mmap_setup(); + stm32image_io_setup(); + break; +#endif + default: + ERROR("Boot interface %d not supported\n", + boot_context->boot_interface_selected); + panic(); + break; + } +} + +int bl2_plat_handle_pre_image_load(unsigned int image_id) +{ + boot_api_context_t *boot_context = + (boot_api_context_t *)stm32mp_get_boot_ctx_address(); + + switch (boot_context->boot_interface_selected) { +#if STM32MP_UART_PROGRAMMER + case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART: + if (image_id == BL33_IMAGE_ID) { + stm32cubeprogrammer_uart(STM32_IMAGE_ID); + /* BL33 at SSBL load address */ + image_block_spec.offset = DWL_BUFFER_BASE; + image_block_spec.length = DWL_BUFFER_SIZE; + } + break; +#endif +#if STM32MP_USB_PROGRAMMER + case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB: + if (image_id == BL33_IMAGE_ID) { + stm32cubeprogrammer_usb(STM32_IMAGE_ID); + /* BL33 at SSBL load address */ + image_block_spec.offset = DWL_BUFFER_BASE; + image_block_spec.length = DWL_BUFFER_SIZE; + } + break; +#endif + default: + break; + } + + return 0; +} + +/* + * Return an IO device handle and specification which can be used to access + * an image. Use this to enforce platform load policy. + */ +int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, + uintptr_t *image_spec) +{ + int rc; + const struct plat_io_policy *policy; + + assert(image_id < ARRAY_SIZE(policies)); + + policy = &policies[image_id]; + rc = policy->check(policy->image_spec); + if (rc == 0) { + *image_spec = policy->image_spec; + *dev_handle = *(policy->dev_handle); + } + + return rc; +} + +/* + * This function shall return 0 if it cannot find an alternate + * image to be loaded and any non-zero value otherwise. + */ +int plat_try_next_boot_source(unsigned int image_id) +{ + int io_result __unused; + const struct stm32image_part_info *partition_spec; + struct stm32image_part_info *part; + const struct plat_io_policy *policy; + uint32_t idx; + static unsigned int backup_nb; + static unsigned int backup_id = MAX_NUMBER_IDS; + + assert(image_id < ARRAY_SIZE(policies)); + + if (backup_id != image_id) { + backup_id = image_id; + backup_nb = 0; + } + + backup_nb++; + + if (backup_nb >= PLATFORM_MTD_BACKUP_BLOCKS) { + return 0; + } + + policy = &policies[image_id]; + partition_spec = (struct stm32image_part_info *)policy->image_spec; + for (idx = 0U; idx < STM32_PART_NUM; idx++) { + part = &stm32image_dev_info_spec.part_info[idx]; + if (part->binary_type == partition_spec->binary_type) { + break; + } + } + + assert(idx < STM32_PART_NUM); + + if (part->bkp_offset == 0U) { + return 0; + } + + part->part_offset += part->bkp_offset; + /* + * Reopen the io_dev as it was closed in the load_auth_image() + * sequence. + */ + io_result = io_dev_open(stm32image_dev_con, + (uintptr_t)&stm32image_dev_info_spec, + &image_dev_handle); + assert(io_result == 0); + + return 1; +} diff --git a/plat/st/common/include/stm32mp_common.h b/plat/st/common/include/stm32mp_common.h index 065f8bf5546c18634638605b0037a06b57bb4963..c3da2098376708b84048778791f5b17e2fa25f3a 100644 --- a/plat/st/common/include/stm32mp_common.h +++ b/plat/st/common/include/stm32mp_common.h @@ -118,6 +118,7 @@ unsigned long stm32mp_clk_get_rate(unsigned long id); /* Initialise the IO layer and register platform IO devices */ void stm32mp_io_setup(void); +#if STM32MP_USE_STM32IMAGE /* * Check that the STM32 header of a .stm32 binary image is valid * @param header: pointer to the stm32 image header @@ -125,6 +126,7 @@ void stm32mp_io_setup(void); * @return: 0 on success, negative value in case of error */ int stm32mp_check_header(boot_api_image_header_t *header, uintptr_t buffer); +#endif #if TRUSTED_BOARD_BOOT void stm32mp_save_loaded_header(void *header); diff --git a/plat/st/common/stm32cubeprogrammer_uart.c b/plat/st/common/stm32cubeprogrammer_uart.c index 8195b22443e60bd95f78d819bdc390b96fa03921..2bfe509f391c4b7f9a17ed92ce2b4af4c9416016 100644 --- a/plat/st/common/stm32cubeprogrammer_uart.c +++ b/plat/st/common/stm32cubeprogrammer_uart.c @@ -377,6 +377,7 @@ static int uart_start_cmd(unsigned int image_id, uintptr_t buffer) return 0; } +#if !STM32MP_USE_STM32IMAGE if (image_id == FIP_IMAGE_ID) { if (!is_valid_header((fip_toc_header_t *)buffer)) { STM32PROG_ERROR("FIP Header check failed at phase %d\n", @@ -386,6 +387,7 @@ static int uart_start_cmd(unsigned int image_id, uintptr_t buffer) VERBOSE("FIP header looks OK.\n"); } +#else if (image_id == STM32_IMAGE_ID) { /* Verify header and checksum payload */ ret = stm32mp_check_header((boot_api_image_header_t *)buffer, @@ -398,6 +400,7 @@ static int uart_start_cmd(unsigned int image_id, uintptr_t buffer) VERBOSE("STM32 header looks OK.\n"); } +#endif return 0; } diff --git a/plat/st/common/stm32cubeprogrammer_usb.c b/plat/st/common/stm32cubeprogrammer_usb.c index 3f3a172a1c0e14df7d4c80f403f86947baf59464..0121af949f02c9517508be8d256bc7ed89093f67 100644 --- a/plat/st/common/stm32cubeprogrammer_usb.c +++ b/plat/st/common/stm32cubeprogrammer_usb.c @@ -128,7 +128,9 @@ static int dfu_callback_download(uint8_t alt, uintptr_t *buffer, uint32_t *len, static int dfu_callback_manifestation(uint8_t alt, void *user_data) { +#if STM32MP_USE_STM32IMAGE int result; +#endif boot_api_image_header_t *header; dfu_state_t *dfu = (dfu_state_t *)user_data; @@ -149,6 +151,7 @@ static int dfu_callback_manifestation(uint8_t alt, void *user_data) header->image_length + sizeof(boot_api_image_header_t)); +#if STM32MP_USE_STM32IMAGE /* Verify header and checksum payload */ INFO("Flashlayout Header check at %lx\n", (uintptr_t)header); @@ -159,7 +162,7 @@ static int dfu_callback_manifestation(uint8_t alt, void *user_data) DFU_ERROR("Header check failed for phase %d\n", alt); return -EIO; } - +#endif /* Configure U-Boot loading */ dfu->phase = PHASE_SSBL; dfu->address = dfu->ssbl_base; @@ -168,6 +171,7 @@ static int dfu_callback_manifestation(uint8_t alt, void *user_data) break; case PHASE_SSBL: +#if !STM32MP_USE_STM32IMAGE if (dfu->image_id == FIP_IMAGE_ID) { if (!is_valid_header((fip_toc_header_t *)dfu->base)) { DFU_ERROR("FIP Header check failed for phase %d\n", alt); @@ -176,6 +180,7 @@ static int dfu_callback_manifestation(uint8_t alt, void *user_data) VERBOSE("FIP header looks OK.\n"); } +#else if (dfu->image_id == STM32_IMAGE_ID) { header = (boot_api_image_header_t *)dfu->base; /* Verify header and checksum payload */ @@ -189,7 +194,7 @@ static int dfu_callback_manifestation(uint8_t alt, void *user_data) VERBOSE("STM32 header looks OK.\n"); } - +#endif /* Configure End with request detach */ dfu->phase = PHASE_FLASHLAYOUT; dfu->address = UNDEFINED_DOWN_ADDR; diff --git a/plat/st/common/stm32mp_common.c b/plat/st/common/stm32mp_common.c index 495de74767bc6eacd82a1c59843a626c9c1d52ec..bd7b5f7dec1c4690e6874b28e270be17a63ea7bf 100644 --- a/plat/st/common/stm32mp_common.c +++ b/plat/st/common/stm32mp_common.c @@ -108,6 +108,7 @@ void stm32mp_pwr_regs_unlock(void) } } +#if STM32MP_USE_STM32IMAGE int stm32mp_check_header(boot_api_image_header_t *header, uintptr_t buffer) { /* @@ -144,6 +145,7 @@ int stm32mp_check_header(boot_api_image_header_t *header, uintptr_t buffer) return 0; } +#endif /* Return CPU supply name */ const char *stm32mp_get_cpu_supply_name(void) @@ -165,7 +167,7 @@ const char *stm32mp_get_cpu_supply_name(void) return supply; } -#if TRUSTED_BOARD_BOOT +#if TRUSTED_BOARD_BOOT && STM32MP_USE_STM32IMAGE /* Save pointer to last loaded header */ static boot_api_image_header_t *latest_stm32_header; diff --git a/plat/st/common/stm32mp_trusted_boot.c b/plat/st/common/stm32mp_trusted_boot.c index 21dfdbb150bcc0f2f94b52f5183f98f78056d32e..41981eb1c85594f166f5287b81fd6b90b807647c 100644 --- a/plat/st/common/stm32mp_trusted_boot.c +++ b/plat/st/common/stm32mp_trusted_boot.c @@ -97,7 +97,9 @@ int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr) return -EINVAL; } +#if !STM32MP_USE_STM32IMAGE int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size) { return get_mbedtls_heap_helper(heap_addr, heap_size); } +#endif diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c index fe5a843c9642f5b9482625793d687919b3755d43..bfc5796d2635bb75b5de7114714da790135a6e45 100644 --- a/plat/st/stm32mp1/bl2_plat_setup.c +++ b/plat/st/stm32mp1/bl2_plat_setup.c @@ -186,6 +186,14 @@ void bl2_platform_setup(void) panic(); } +#if STM32MP_USE_STM32IMAGE +#ifdef AARCH32_SP_OPTEE + INFO("BL2 runs OP-TEE setup\n"); +#else + INFO("BL2 runs SP_MIN setup\n"); +#endif +#endif + if (!stm32mp1_ddr_is_restored()) { uint32_t bkpr_core1_magic = tamp_bkpr(BOOT_API_CORE1_MAGIC_NUMBER_TAMP_BCK_REG_IDX); @@ -342,6 +350,12 @@ void bl2_el3_plat_arch_setup(void) BL_CODE_END - BL_CODE_BASE, MT_CODE | MT_SECURE); +#if STM32MP_USE_STM32IMAGE && !defined(AARCH32_SP_OPTEE) + /* Prevent corruption of preloaded BL32 */ + mmap_add_region(BL32_BASE, BL32_BASE, + BL32_LIMIT - BL32_BASE, + MT_RO_DATA | MT_SECURE); +#endif /* Prevent corruption of preloaded Device Tree */ mmap_add_region(DTB_BASE, DTB_BASE, DTB_LIMIT - DTB_BASE, @@ -529,11 +543,44 @@ skip_console_init: print_pmic_info_and_debug(); } +#if STM32MP_USE_STM32IMAGE + if (!stm32mp1_ddr_is_restored()) { + stm32mp_io_setup(); + } +#else fconf_populate("TB_FW", STM32MP_DTB_BASE); stm32mp_io_setup(); +#endif } +#if defined(AARCH32_SP_OPTEE) && STM32MP_USE_STM32IMAGE +static void set_mem_params_info(entry_point_info_t *ep_info, + image_info_t *unpaged, image_info_t *paged) +{ + uintptr_t bl32_ep = 0; + + /* Use the default dram setup if no valid ep found */ + if (get_optee_header_ep(ep_info, &bl32_ep) && + (bl32_ep >= STM32MP_OPTEE_BASE) && + (bl32_ep < (STM32MP_OPTEE_BASE + STM32MP_OPTEE_SIZE))) { + assert((STM32MP_OPTEE_BASE >= BL2_LIMIT) || + ((STM32MP_OPTEE_BASE + STM32MP_OPTEE_SIZE) <= BL2_BASE)); + + unpaged->image_base = STM32MP_OPTEE_BASE; + unpaged->image_max_size = STM32MP_OPTEE_SIZE; + } else { + unpaged->image_base = STM32MP_DDR_BASE + dt_get_ddr_size() - + STM32MP_DDR_S_SIZE - + STM32MP_DDR_SHMEM_SIZE; + unpaged->image_max_size = STM32MP_DDR_S_SIZE; + } + paged->image_base = STM32MP_DDR_BASE + dt_get_ddr_size() - + STM32MP_DDR_S_SIZE - STM32MP_DDR_SHMEM_SIZE; + paged->image_max_size = STM32MP_DDR_S_SIZE; +} +#endif + /******************************************************************************* * This function can be used by the platforms to update/use image * information for given `image_id`. @@ -545,6 +592,7 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) bl_mem_params_node_t *bl32_mem_params; bl_mem_params_node_t *pager_mem_params __unused; bl_mem_params_node_t *paged_mem_params __unused; +#if !STM32MP_USE_STM32IMAGE const struct dyn_cfg_dtb_info_t *config_info; bl_mem_params_node_t *tos_fw_mem_params; unsigned int i; @@ -556,15 +604,17 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) HW_CONFIG_ID, TOS_FW_CONFIG_ID, }; +#endif assert(bl_mem_params != NULL); -#if TRUSTED_BOARD_BOOT +#if TRUSTED_BOARD_BOOT && STM32MP_USE_STM32IMAGE /* Clean header to avoid loaded header reused */ stm32mp_delete_loaded_header(); #endif switch (image_id) { +#if !STM32MP_USE_STM32IMAGE case FW_CONFIG_ID: /* Set global DTB info for fixed fw_config information */ set_config_info(STM32MP_FW_CONFIG_BASE, STM32MP_FW_CONFIG_MAX_SIZE, FW_CONFIG_ID); @@ -630,11 +680,14 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) } break; +#endif /* !STM32MP_USE_STM32IMAGE */ case BL32_IMAGE_ID: +#if defined(AARCH32_SP_OPTEE) || !STM32MP_USE_STM32IMAGE bl_mem_params->ep_info.pc = bl_mem_params->image_info.image_base; if (get_optee_header_ep(&bl_mem_params->ep_info, &bl_mem_params->ep_info.pc) == 1) { /* BL32 is OP-TEE header */ +#if !STM32MP_USE_STM32IMAGE if (wakeup_ddr_sr) { bl_mem_params->ep_info.pc = stm32_pm_get_optee_ep(); if (stm32mp1_addr_inside_backupsram(bl_mem_params->ep_info.pc)) { @@ -643,10 +696,16 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) break; } +#endif pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID); paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID); assert((pager_mem_params != NULL) && (paged_mem_params != NULL)); +#if STM32MP_USE_STM32IMAGE + set_mem_params_info(&bl_mem_params->ep_info, &pager_mem_params->image_info, + &paged_mem_params->image_info); +#endif + err = parse_optee_header(&bl_mem_params->ep_info, &pager_mem_params->image_info, &paged_mem_params->image_info); @@ -660,9 +719,13 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) bl_mem_params->ep_info.args.arg1 = 0; /* Unused */ bl_mem_params->ep_info.args.arg2 = 0; /* No DT supported */ } else { +#if STM32MP_USE_STM32IMAGE + bl_mem_params->ep_info.pc = STM32MP_BL32_BASE; +#else tos_fw_mem_params = get_bl_mem_params_node(TOS_FW_CONFIG_ID); bl_mem_params->image_info.image_max_size += tos_fw_mem_params->image_info.image_max_size; +#endif bl_mem_params->ep_info.args.arg0 = 0; #if STM32MP_SP_MIN_IN_DDR @@ -675,6 +738,7 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) bl_mem_params->ep_info.args.arg3 = (u_register_t)&bl2_to_bl32_args; #endif } +#endif break; case BL33_IMAGE_ID: diff --git a/plat/st/stm32mp1/include/platform_def.h b/plat/st/stm32mp1/include/platform_def.h index 75c58d5407ee9d1130c85b31698d68b19488d516..0de1749b6f83362389d390c57ca27776cc1a9bfd 100644 --- a/plat/st/stm32mp1/include/platform_def.h +++ b/plat/st/stm32mp1/include/platform_def.h @@ -25,7 +25,22 @@ #define PLATFORM_STACK_SIZE 0xC00 #endif +#if STM32MP_USE_STM32IMAGE +#ifdef AARCH32_SP_OPTEE +#define OPTEE_HEADER_IMAGE_NAME "teeh" +#define OPTEE_CORE_IMAGE_NAME "teex" +#define OPTEE_PAGED_IMAGE_NAME "teed" +#define OPTEE_HEADER_BINARY_TYPE U(0x20) +#define OPTEE_CORE_BINARY_TYPE U(0x21) +#define OPTEE_PAGED_BINARY_TYPE U(0x22) +#endif + +/* SSBL = second stage boot loader */ +#define BL33_IMAGE_NAME "ssbl" +#define BL33_BINARY_TYPE U(0x0) +#else /* STM32MP_USE_STM32IMAGE */ #define FIP_IMAGE_NAME "fip" +#endif /* STM32MP_USE_STM32IMAGE */ #define STM32MP_PRIMARY_CPU U(0x0) #define STM32MP_SECONDARY_CPU U(0x1) @@ -56,7 +71,7 @@ /******************************************************************************* * BL32 specific defines. ******************************************************************************/ -#ifndef AARCH32_SP_OPTEE +#if STM32MP_USE_STM32IMAGE || defined(IMAGE_BL32) #if ENABLE_PIE #define BL32_BASE 0 #define BL32_LIMIT STM32MP_BL32_SIZE diff --git a/plat/st/stm32mp1/include/stm32mp1_private.h b/plat/st/stm32mp1/include/stm32mp1_private.h index ccec2e2a6601554a77f21bd0faa896d606c781e9..04e41fa9347bb155db57848b0a5a6982fa728cf9 100644 --- a/plat/st/stm32mp1/include/stm32mp1_private.h +++ b/plat/st/stm32mp1/include/stm32mp1_private.h @@ -42,6 +42,10 @@ void stm32mp1_syscfg_init(void); void stm32mp1_syscfg_enable_io_compensation(void); void stm32mp1_syscfg_disable_io_compensation(void); +#if STM32MP_USE_STM32IMAGE +uint32_t stm32mp_get_ddr_ns_size(void); +#endif + void stm32mp1_init_scmi_server(void); void stm32mp1_pm_save_scmi_state(uint8_t *state, size_t size); void stm32mp1_pm_restore_scmi_state(uint8_t *state, size_t size); diff --git a/plat/st/stm32mp1/plat_bl2_stm32_mem_params_desc.c b/plat/st/stm32mp1/plat_bl2_stm32_mem_params_desc.c new file mode 100644 index 0000000000000000000000000000000000000000..16f2b832c9c4ef738093f35f160ac962400643eb --- /dev/null +++ b/plat/st/stm32mp1/plat_bl2_stm32_mem_params_desc.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <platform_def.h> + +#include <common/bl_common.h> +#include <common/desc_image_load.h> +#include <plat/common/platform.h> + +/******************************************************************************* + * Following descriptor provides BL image/ep information that gets used + * by BL2 to load the images and also subset of this information is + * passed to next BL image. The image loading sequence is managed by + * populating the images in required loading order. The image execution + * sequence is managed by populating the `next_handoff_image_id` with + * the next executable image id. + ******************************************************************************/ +static bl_mem_params_node_t bl2_mem_params_descs[] = { + /* Fill BL32 related information */ + { + .image_id = BL32_IMAGE_ID, + + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, + VERSION_2, entry_point_info_t, + SECURE | EXECUTABLE | EP_FIRST_EXE), + +#if !defined(AARCH32_SP_OPTEE) + .ep_info.pc = STM32MP_BL32_BASE, +#endif + .ep_info.spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM, + SPSR_E_LITTLE, + DISABLE_ALL_EXCEPTIONS), + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, + VERSION_2, image_info_t, + IMAGE_ATTRIB_PLAT_SETUP), +#if defined(AARCH32_SP_OPTEE) + /* optee header is loaded in SYSRAM above BL2 */ + .image_info.image_base = STM32MP_OPTEE_BASE, + .image_info.image_max_size = STM32MP_OPTEE_SIZE, +#else + .image_info.image_base = STM32MP_BL32_BASE, + .image_info.image_max_size = STM32MP_BL32_BIN_SIZE, +#endif + .next_handoff_image_id = BL33_IMAGE_ID, + }, + + /* Fill BL32 external 1 image related information */ + { + .image_id = BL32_EXTRA1_IMAGE_ID, + + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, + VERSION_2, entry_point_info_t, + SECURE | NON_EXECUTABLE), + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, + VERSION_2, image_info_t, + IMAGE_ATTRIB_SKIP_LOADING), + + .next_handoff_image_id = INVALID_IMAGE_ID, + }, + + /* Fill BL32 external 2 image related information */ + { + .image_id = BL32_EXTRA2_IMAGE_ID, + + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, + VERSION_2, entry_point_info_t, + SECURE | NON_EXECUTABLE), + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, + VERSION_2, image_info_t, + IMAGE_ATTRIB_SKIP_LOADING), + + .next_handoff_image_id = INVALID_IMAGE_ID, + }, + + /* Fill BL33 related information */ + { + .image_id = BL33_IMAGE_ID, + + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, + VERSION_2, entry_point_info_t, + NON_SECURE | EXECUTABLE), + + .ep_info.pc = PLAT_STM32MP_NS_IMAGE_OFFSET, + .ep_info.spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM, + SPSR_E_LITTLE, + DISABLE_ALL_EXCEPTIONS), + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, + VERSION_2, image_info_t, + 0), + + .image_info.image_base = PLAT_STM32MP_NS_IMAGE_OFFSET, + .image_info.image_max_size = STM32MP_DDR_MAX_SIZE - + (PLAT_STM32MP_NS_IMAGE_OFFSET - STM32MP_DDR_BASE), + + .next_handoff_image_id = INVALID_IMAGE_ID, + } +}; + +REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs) diff --git a/plat/st/stm32mp1/plat_image_load.c b/plat/st/stm32mp1/plat_image_load.c index 1744484acd94a1dcebeb6770e4e01b21a58b3388..8a56ac8804ed06a0e09faf10c7cfc1fe5c4188a0 100644 --- a/plat/st/stm32mp1/plat_image_load.c +++ b/plat/st/stm32mp1/plat_image_load.c @@ -25,6 +25,39 @@ void plat_flush_next_bl_params(void) ******************************************************************************/ bl_load_info_t *plat_get_bl_image_load_info(void) { +#if STM32MP_USE_STM32IMAGE + bl_mem_params_node_t *bl33 = get_bl_mem_params_node(BL33_IMAGE_ID); + uint32_t ddr_ns_size = stm32mp_get_ddr_ns_size(); + + /* + * If going back from CSTANDBY / STANDBY and DDR was in Self-Refresh, + * BL33 must not be loaded as it would overwrite the code already + * in DDR. For this, the BL33 part of the bl_mem_params_desc_ptr + * struct should be modified to skip its loading + */ + if (stm32mp1_is_wakeup_from_standby()) { + bl_mem_params_node_t *bl32; + + bl33->image_info.h.attr |= IMAGE_ATTRIB_SKIP_LOADING; + bl32 = get_bl_mem_params_node(BL32_IMAGE_ID); + bl32->image_info.h.attr |= IMAGE_ATTRIB_SKIP_LOADING; +#if defined(AARCH32_SP_OPTEE) + bl32->ep_info.pc = stm32_pm_get_optee_ep(); + + if (stm32mp1_addr_inside_backupsram(bl32->ep_info.pc)) { + stm32mp_clk_enable(BKPSRAM); + } +#else + /* Set ep_info PC to 0, to inform BL32 it is a reset after STANDBY */ + bl33->ep_info.pc = 0; +#endif + } + + /* Max size is non-secure DDR end address minus image_base */ + bl33->image_info.image_max_size = STM32MP_DDR_BASE + ddr_ns_size - + bl33->image_info.image_base; +#endif /* STM32MP_USE_STM32IMAGE */ + return get_bl_load_info_from_mem_params_desc(); } diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk index a7f064fff99f3d4a27a291dc9ccb535b11a8de91..f4520ae03a6818dcc521f56b6bddf96319261763 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -9,11 +9,18 @@ ARM_WITH_NEON := yes BL2_AT_EL3 := 1 USE_COHERENT_MEM := 0 +# Allow TF-A to concatenate BL2 & BL32 binaries in a single file, +# share DTB file between BL2 and BL32 +# If it is set to 0, then FIP and FCONF are used +STM32MP_USE_STM32IMAGE ?= 0 + # Add specific ST version ST_VERSION := r1.0 VERSION_STRING := v${VERSION_MAJOR}.${VERSION_MINOR}-${ST_VERSION}(${BUILD_TYPE}):${BUILD_STRING} +ifneq ($(STM32MP_USE_STM32IMAGE),1) ENABLE_PIE := 1 +endif TRUSTED_BOARD_BOOT ?= 0 # Please don't increment this value without good understanding of @@ -48,6 +55,8 @@ STM32_TF_A_COPIES := 2 STM32_BL33_PARTS_NUM := 1 ifeq ($(AARCH32_SP),optee) STM32_RUNTIME_PARTS_NUM := 3 +else ifeq ($(STM32MP_USE_STM32IMAGE),1) +STM32_RUNTIME_PARTS_NUM := 0 else STM32_RUNTIME_PARTS_NUM := 1 endif @@ -74,12 +83,21 @@ endif # Device tree DTB_FILE_NAME ?= stm32mp157c-ev1.dtb +ifeq ($(STM32MP_USE_STM32IMAGE),1) +ifeq ($(AARCH32_SP),optee) +BL2_DTSI := stm32mp15-bl2.dtsi +FDT_SOURCES := $(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl2.dts,$(DTB_FILE_NAME))) +else +FDT_SOURCES := $(addprefix fdts/, $(patsubst %.dtb,%.dts,$(DTB_FILE_NAME))) +endif +else BL2_DTSI := stm32mp15-bl2.dtsi FDT_SOURCES := $(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl2.dts,$(DTB_FILE_NAME))) ifeq ($(AARCH32_SP),sp_min) BL32_DTSI := stm32mp15-bl32.dtsi FDT_SOURCES += $(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl32.dts,$(DTB_FILE_NAME))) endif +endif DTC_FLAGS += -Wno-unit_address_vs_reg # Macros and rules to build TF binary @@ -88,12 +106,18 @@ STM32_TF_STM32 := $(addprefix ${BUILD_PLAT}/tf-a-, $(patsubst %.dtb,%.stm32,$(D STM32_TF_LINKERFILE := ${BUILD_PLAT}/stm32mp1.ld ASFLAGS += -DBL2_BIN_PATH=\"${BUILD_PLAT}/bl2.bin\" +ifeq ($(AARCH32_SP),sp_min) +# BL32 is built only if using SP_MIN +BL32_DEP := bl32 +ASFLAGS += -DBL32_BIN_PATH=\"${BUILD_PLAT}/bl32.bin\" +endif # Variables for use with stm32image STM32IMAGEPATH ?= tools/stm32image STM32IMAGE ?= ${STM32IMAGEPATH}/stm32image${BIN_EXT} STM32IMAGE_SRC := ${STM32IMAGEPATH}/stm32image.c +ifneq (${STM32MP_USE_STM32IMAGE},1) STM32MP_NT_FW_CONFIG := ${BL33_CFG} STM32MP_FW_CONFIG_NAME := $(patsubst %.dtb,%-fw-config.dtb,$(DTB_FILE_NAME)) STM32MP_FW_CONFIG := ${BUILD_PLAT}/fdts/$(STM32MP_FW_CONFIG_NAME) @@ -115,6 +139,7 @@ ifneq ($(BL32_EXTRA2),) $(eval $(call TOOL_ADD_IMG,BL32_EXTRA2,--tos-fw-extra2)) endif endif +endif # Enable flags for C files $(eval $(call assert_booleans,\ @@ -127,6 +152,7 @@ $(eval $(call assert_booleans,\ PLAT_XLAT_TABLES_DYNAMIC \ STM32MP_UART_PROGRAMMER \ STM32MP_USB_PROGRAMMER \ + STM32MP_USE_STM32IMAGE \ STM32MP_DDR_DUAL_AXI_PORT \ STM32MP_SP_MIN_IN_DDR \ ))) @@ -151,6 +177,7 @@ $(eval $(call add_defines,\ STM32MP_UART_PROGRAMMER \ STM32MP_USB_PROGRAMMER \ STM32_TF_VERSION \ + STM32MP_USE_STM32IMAGE \ STM32MP_DDR_DUAL_AXI_PORT \ STM32MP_SP_MIN_IN_DDR \ ))) @@ -198,17 +225,27 @@ PLAT_BL_COMMON_SOURCES += drivers/arm/tzc/tzc400.c \ plat/st/stm32mp1/stm32mp1_helper.S \ plat/st/stm32mp1/stm32mp1_syscfg.c -BL2_SOURCES += lib/fconf/fconf.c \ +ifneq (${STM32MP_USE_STM32IMAGE},1) +BL2_SOURCES += drivers/io/io_fip.c \ + plat/st/common/bl2_io_storage.c \ + plat/st/stm32mp1/plat_bl2_mem_params_desc.c + +BL2_SOURCES += lib/fconf/fconf.c \ lib/fconf/fconf_dyn_cfg_getter.c \ plat/st/common/stm32mp_fconf_io.c \ plat/st/stm32mp1/stm32mp1_fconf_firewall.c +else +BL2_SOURCES += drivers/io/io_dummy.c \ + drivers/st/io/io_stm32image.c \ + plat/st/common/bl2_stm32_io_storage.c \ + plat/st/stm32mp1/plat_bl2_stm32_mem_params_desc.c \ + plat/st/stm32mp1/stm32mp1_security.c +endif BL2_SOURCES += drivers/io/io_block.c \ - drivers/io/io_fip.c \ drivers/io/io_mtd.c \ drivers/io/io_storage.c \ drivers/st/crypto/stm32_hash.c \ - plat/st/common/bl2_io_storage.c \ plat/st/stm32mp1/bl2_plat_setup.c ifeq (${TRUSTED_BOARD_BOOT},1) @@ -216,6 +253,7 @@ AUTH_SOURCES := drivers/auth/auth_mod.c \ drivers/auth/crypto_mod.c \ drivers/auth/img_parser_mod.c +ifneq (${STM32MP_USE_STM32IMAGE},1) IMG_PARSER_LIB_MK := drivers/auth/mbedtls/mbedtls_x509.mk $(info Including ${IMG_PARSER_LIB_MK}) @@ -223,6 +261,11 @@ include ${IMG_PARSER_LIB_MK} AUTH_SOURCES += drivers/auth/tbbr/tbbr_cot_common.c \ plat/st/common/stm32mp_crypto_lib.c +else +AUTH_SOURCES += plat/st/common/stm32mp_cot.c \ + plat/st/common/stm32mp_crypto_lib.c \ + plat/st/common/stm32mp_img_parser_lib.c +endif BL2_SOURCES += $(AUTH_SOURCES) \ plat/st/common/stm32mp_trusted_boot.c @@ -284,7 +327,6 @@ BL2_SOURCES += drivers/st/ddr/stm32mp1_ddr.c \ drivers/st/ddr/stm32mp1_ram.c BL2_SOURCES += common/desc_image_load.c \ - plat/st/stm32mp1/plat_bl2_mem_params_desc.c \ plat/st/stm32mp1/plat_image_load.c BL2_SOURCES += lib/optee/optee_utils.c @@ -318,6 +360,13 @@ check_dtc_version: false; \ fi +ifeq ($(STM32MP_USE_STM32IMAGE)$(AARCH32_SP),1sp_min) +${BUILD_PLAT}/stm32mp1-%.o: ${BUILD_PLAT}/fdts/%.dtb plat/st/stm32mp1/stm32mp1.S bl2 ${BL32_DEP} + @echo " AS stm32mp1.S" + ${Q}${AS} ${ASFLAGS} ${TF_CFLAGS} \ + -DDTB_BIN_PATH=\"$<\" \ + -c $(word 2,$^) -o $@ +else # Create DTB file for BL2 ${BUILD_PLAT}/fdts/%-bl2.dts: fdts/%.dts fdts/${BL2_DTSI} | ${BUILD_PLAT} fdt_dirs @echo '#include "$(patsubst fdts/%,%,$<)"' > $@ @@ -339,6 +388,7 @@ ${BUILD_PLAT}/stm32mp1-%.o: ${BUILD_PLAT}/fdts/%-bl2.dtb plat/st/stm32mp1/stm32m ${Q}${AS} ${ASFLAGS} ${TF_CFLAGS} \ -DDTB_BIN_PATH=\"$<\" \ -c plat/st/stm32mp1/stm32mp1.S -o $@ +endif $(eval $(call MAKE_LD,${STM32_TF_LINKERFILE},plat/st/stm32mp1/stm32mp1.ld.S,2)) diff --git a/plat/st/stm32mp1/sp_min/sp_min_setup.c b/plat/st/stm32mp1/sp_min/sp_min_setup.c index e9c445b304df3849be980e468b5fa8e8dae421f9..94d3219191fecde8a44ec0ef9347bf284dee515c 100644 --- a/plat/st/stm32mp1/sp_min/sp_min_setup.c +++ b/plat/st/stm32mp1/sp_min/sp_min_setup.c @@ -308,6 +308,7 @@ static void stm32mp1_etzpc_early_setup(void) etzpc_configure_tzma(STM32MP1_ETZPC_TZMA_SYSRAM, TZMA1_SECURE_RANGE); } +#if !STM32MP_USE_STM32IMAGE static void populate_ns_dt(u_register_t ns_dt_addr, uintptr_t sec_base, size_t sec_size) { void *external_fdt = (void *)ns_dt_addr; @@ -350,6 +351,7 @@ out: ret = mmap_remove_dynamic_region(ns_dt_addr, STM32MP_HW_CONFIG_MAX_SIZE); assert(ret == 0); } +#endif /******************************************************************************* * Setup UART console using device tree information. @@ -403,9 +405,13 @@ void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1, uintptr_t bl2_code_end = 0U; uintptr_t bl2_end = 0U; #endif +#if STM32MP_USE_STM32IMAGE + uintptr_t dt_addr = STM32MP_DTB_BASE; +#else uintptr_t dt_addr = arg1; uintptr_t sec_base = 0U; size_t sec_size = 0U; +#endif /* Imprecise aborts can be masked in NonSecure */ write_scr(read_scr() | SCR_AW_BIT); @@ -473,10 +479,12 @@ void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1, } } +#if !STM32MP_USE_STM32IMAGE if (bl_params->image_id == BL32_IMAGE_ID) { sec_base = bl_params->image_info->image_base; sec_size = bl_params->image_info->image_max_size; } +#endif bl_params = bl_params->next_params_info; } @@ -497,6 +505,7 @@ void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1, stm32mp1_etzpc_early_setup(); +#if !STM32MP_USE_STM32IMAGE if (arg2 != 0U) { /* This will expect the BL32 DT and BL32 are grouped */ if (dt_addr < sec_base) { @@ -510,6 +519,7 @@ void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1, } else { INFO("Non-secure device tree not found\n"); } +#endif if (dt_pmic_status() > 0) { initialize_pmic(); diff --git a/plat/st/stm32mp1/stm32mp1.S b/plat/st/stm32mp1/stm32mp1.S index 7c4e050976d22e17612ad4e9964b601d51618dab..1b7e9e7effbf391585f63812da2c5c9ff732a9d5 100644 --- a/plat/st/stm32mp1/stm32mp1.S +++ b/plat/st/stm32mp1/stm32mp1.S @@ -4,6 +4,13 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#if STM32MP_USE_STM32IMAGE +#ifdef BL32_BIN_PATH +.section .bl32_image +.incbin BL32_BIN_PATH +#endif +#endif + .section .bl2_image .incbin BL2_BIN_PATH diff --git a/plat/st/stm32mp1/stm32mp1.ld.S b/plat/st/stm32mp1/stm32mp1.ld.S index d90469de1b0590ca0d1f7928a678f8a417e1f4d3..c643c895707eda000f7b1f43d770928d3cd8cb8a 100644 --- a/plat/st/stm32mp1/stm32mp1.ld.S +++ b/plat/st/stm32mp1/stm32mp1.ld.S @@ -43,7 +43,11 @@ SECTIONS * The strongest and only alignment contraint is MMU 4K page. * Indeed as images below will be removed, 4K pages will be re-used. */ +#if STM32MP_USE_STM32IMAGE + . = ( STM32MP_DTB_BASE - STM32MP_BINARY_BASE ); +#else . = ( STM32MP_BL2_DTB_BASE - STM32MP_BINARY_BASE ); +#endif __DTB_IMAGE_START__ = .; *(.dtb_image*) __DTB_IMAGE_END__ = .; @@ -58,6 +62,18 @@ SECTIONS *(.bl2_image*) __BL2_IMAGE_END__ = .; +#if STM32MP_USE_STM32IMAGE && !defined(AARCH32_SP_OPTEE) + /* + * bl32 will be settled by bl2. + * The strongest and only alignment constraint is 8 words to simplify + * memraise8 assembly code. + */ + . = ( STM32MP_BL32_BASE - STM32MP_BINARY_BASE ); + __BL32_IMAGE_START__ = .; + *(.bl32_image*) + __BL32_IMAGE_END__ = .; +#endif + __DATA_END__ = .; } >RAM diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h index 9c4533f0af4e43641ae315e380cd2f2f8f42a760..b468065070a7fe223e276b4a95388ca4fd9427ea 100644 --- a/plat/st/stm32mp1/stm32mp1_def.h +++ b/plat/st/stm32mp1/stm32mp1_def.h @@ -96,7 +96,14 @@ /* DDR configuration */ #define STM32MP_DDR_BASE U(0xC0000000) #define STM32MP_DDR_MAX_SIZE U(0x40000000) /* Max 1GB */ +#if STM32MP_USE_STM32IMAGE +#define STM32MP_DDR_S_SIZE U(0x01E00000) /* 30 MB */ +#ifdef AARCH32_SP_OPTEE +#define STM32MP_DDR_SHMEM_SIZE U(0x00200000) /* 2 MB */ +#endif +#else #define STM32MP_DDR_S_SIZE U(0x02000000) /* 32 MB */ +#endif /* DDR power initializations */ #ifndef __ASSEMBLER__ @@ -122,29 +129,22 @@ enum ddr_type { (STM32MP_PARAM_LOAD_SIZE + \ STM32MP_HEADER_SIZE)) +#if STM32MP_USE_STM32IMAGE +#define STM32MP_BL2_SIZE U(0x0001C000) /* 112 KB for BL2 */ + #ifdef AARCH32_SP_OPTEE #define STM32MP_OPTEE_BASE STM32MP_SEC_SYSRAM_BASE -#define STM32MP_OPTEE_SIZE (STM32MP_DTB_BASE - \ +#define STM32MP_OPTEE_SIZE (TF_A_MAPPING_START - \ STM32MP_OPTEE_BASE) -#define STM32MP_BL2_SIZE U(0x0001B000) /* 108 KB for BL2 */ - #define STM32MP_BL2_BASE (STM32MP_SEC_SYSRAM_BASE + \ STM32MP_SEC_SYSRAM_SIZE - \ STM32MP_BL2_SIZE) -#define STM32MP_BL32_BASE STM32MP_SEC_SYSRAM_BASE -#elif STM32MP_SP_MIN_IN_DDR -#define STM32MP_BL32_SIZE U(0x00025000) /* 148 KB for BL32 */ -#define STM32MP_BL32_BIN_SIZE (STM32MP_BL32_SIZE + \ - STM32MP_BL32_DTB_SIZE) -#define STM32MP_BL2_SIZE U(0x0001C000) /* 112 KB for BL2 */ +#define STM32MP_BL32_BASE STM32MP_SEC_SYSRAM_BASE -#define STM32MP_BL2_BASE (STM32MP_SEC_SYSRAM_BASE + \ - STM32MP_SEC_SYSRAM_SIZE - \ - STM32MP_BL2_SIZE) -#else +#else /* AARCH32_SP_OPTEE */ #define STM32MP_BL32_SIZE U(0x00019000) /* 96 KB for BL32 */ #define STM32MP_BL32_BIN_SIZE STM32MP_BL32_SIZE @@ -152,12 +152,18 @@ enum ddr_type { STM32MP_SEC_SYSRAM_SIZE - \ STM32MP_BL32_SIZE) -#define STM32MP_BL2_SIZE U(0x0001B000) /* 108 KB for BL2 */ - +#define STM32MP_BL2_BASE (STM32MP_BL32_BASE - \ + STM32MP_BL2_SIZE) +#endif /* AARCH32_SP_OPTEE */ +#else /* STM32MP_USE_STM32IMAGE */ #define STM32MP_BL2_BASE (STM32MP_SEC_SYSRAM_BASE + \ STM32MP_SEC_SYSRAM_SIZE - \ STM32MP_BL2_SIZE) -#endif + +#define STM32MP_BL2_SIZE U(0x0001B000) /* 108 KB for BL2 */ + +#define STM32MP_BL32_SIZE U(0x00019000) /* 100 KB for BL32 */ +#endif /* STM32MP_USE_STM32IMAGE */ /* BL2 and BL32/sp_min require finer granularity tables */ #if defined(IMAGE_BL2) @@ -186,16 +192,28 @@ enum ddr_type { #endif #endif #if defined(IMAGE_BL32) - #define MAX_MMAP_REGIONS 10 + #if STM32MP_USE_STM32IMAGE + #define MAX_MMAP_REGIONS 6 + #else + #define MAX_MMAP_REGIONS 10 + #endif #endif +#if STM32MP_USE_STM32IMAGE +/* DTB initialization value */ +#define STM32MP_DTB_SIZE U(0x00006000) /* 24 KB for DTB */ + +#define STM32MP_DTB_BASE (STM32MP_BL2_BASE - \ + STM32MP_DTB_SIZE) +#define TF_A_MAPPING_START STM32MP_DTB_BASE +#else /* STM32MP_USE_STM32IMAGE */ #define STM32MP_BL2_DTB_SIZE U(0x00006000) /* 24 KB for DTB */ #define STM32MP_BL2_DTB_BASE (STM32MP_BL2_BASE - \ STM32MP_BL2_DTB_SIZE) #define STM32MP_BL32_DTB_SIZE U(0x00006000) /* 24 KB for DTB */ -#define STM32MP_BL32_DTB_BASE (STM32MP_BL32_BASE - \ - STM32MP_BL32_DTB_SIZE) +#define STM32MP_BL32_DTB_BASE (STM32MP_BL32_BASE + \ + STM32MP_BL32_SIZE) #if defined(IMAGE_BL2) #define STM32MP_DTB_SIZE STM32MP_BL2_DTB_SIZE #define STM32MP_DTB_BASE STM32MP_BL2_DTB_BASE @@ -204,6 +222,8 @@ enum ddr_type { #define STM32MP_DTB_SIZE STM32MP_BL32_DTB_SIZE #define STM32MP_DTB_BASE STM32MP_BL32_DTB_BASE #endif +#define TF_A_MAPPING_START STM32MP_BL2_DTB_BASE +#endif /* STM32MP_USE_STM32IMAGE */ #define STM32MP_FW_CONFIG_BASE (STM32MP_SYSRAM_BASE + \ STM32MP_SYSRAM_SIZE - \ @@ -228,8 +248,24 @@ enum ddr_type { /******************************************************************************* * STM32MP1 RAW partition offset for MTD devices ******************************************************************************/ +#if STM32MP_USE_STM32IMAGE +#define STM32MP_NOR_BL33_OFFSET U(0x00080000) +#ifdef AARCH32_SP_OPTEE +#define STM32MP_NOR_TEEH_OFFSET U(0x00300000) +#define STM32MP_NOR_TEED_OFFSET U(0x00340000) +#define STM32MP_NOR_TEEX_OFFSET U(0x003C0000) +#endif + +#define STM32MP_NAND_BL33_OFFSET U(0x00200000) +#ifdef AARCH32_SP_OPTEE +#define STM32MP_NAND_TEEH_OFFSET U(0x00600000) +#define STM32MP_NAND_TEED_OFFSET U(0x00680000) +#define STM32MP_NAND_TEEX_OFFSET U(0x00700000) +#endif +#else /* STM32MP_USE_STM32IMAGE */ #define STM32MP_NOR_FIP_OFFSET U(0x00080000) #define STM32MP_NAND_FIP_OFFSET U(0x00200000) +#endif /* STM32MP_USE_STM32IMAGE */ /******************************************************************************* * STM32MP1 device/io map related constants (used for MMU) diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c index 1bca5863d2129ec1a866aa16d8638359e13c328d..84db0219ac125d98deed52fe92e74df15089c2c4 100644 --- a/plat/st/stm32mp1/stm32mp1_private.c +++ b/plat/st/stm32mp1/stm32mp1_private.c @@ -749,6 +749,32 @@ int plat_bind_regulator(struct stm32mp_regulator *regu) return 0; } +#if STM32MP_USE_STM32IMAGE +/* Get the non-secure DDR size */ +uint32_t stm32mp_get_ddr_ns_size(void) +{ + static uint32_t ddr_ns_size; + uint32_t ddr_size; + + if (ddr_ns_size != 0U) { + return ddr_ns_size; + } + + ddr_size = dt_get_ddr_size(); + if ((ddr_size <= STM32MP_DDR_S_SIZE) || (ddr_size > STM32MP_DDR_MAX_SIZE)) { + panic(); + } + +#if defined(AARCH32_SP_OPTEE) + ddr_ns_size = ddr_size - (STM32MP_DDR_S_SIZE + STM32MP_DDR_SHMEM_SIZE); +#else + ddr_ns_size = ddr_size; +#endif + + return ddr_ns_size; +} +#endif + bool stm32mp1_addr_inside_backupsram(uintptr_t addr) { return (addr >= STM32MP_BACKUP_RAM_BASE) && diff --git a/plat/st/stm32mp1/stm32mp1_security.c b/plat/st/stm32mp1/stm32mp1_security.c new file mode 100644 index 0000000000000000000000000000000000000000..aad6b683977706369789e0d0b4ecf10fd315b93b --- /dev/null +++ b/plat/st/stm32mp1/stm32mp1_security.c @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdint.h> + +#include <platform_def.h> + +#include <common/debug.h> +#include <drivers/arm/tzc400.h> +#include <drivers/st/stm32mp1_clk.h> +#include <dt-bindings/clock/stm32mp1-clks.h> +#include <dt-bindings/soc/stm32mp1-tzc400.h> +#include <lib/mmio.h> + +static unsigned int region_nb; + +static void init_tzc400_begin(unsigned int region0_attr) +{ + tzc400_init(STM32MP1_TZC_BASE); + tzc400_disable_filters(); + + /* Region 0 set to cover all DRAM at 0xC000_0000 */ + tzc400_configure_region0(region0_attr, 0); + + region_nb = 1U; +} + +static void init_tzc400_end(unsigned int action) +{ + tzc400_set_action(action); + tzc400_enable_filters(); +} + +static void tzc400_add_region(unsigned long long region_base, + unsigned long long region_top, bool sec) +{ + unsigned int sec_attr; + unsigned int nsaid_permissions; + + if (sec) { + sec_attr = TZC_REGION_S_RDWR; + nsaid_permissions = 0; + } else { + sec_attr = TZC_REGION_S_NONE; + nsaid_permissions = TZC_REGION_NSEC_ALL_ACCESS_RDWR; + } + + tzc400_configure_region(STM32MP1_FILTER_BIT_ALL, region_nb, region_base, + region_top, sec_attr, nsaid_permissions); + + region_nb++; +} + +/******************************************************************************* + * Initialize the TrustZone Controller. Configure Region 0 with Secure RW access + * and allow Non-Secure masters full access. + ******************************************************************************/ +static void init_tzc400(void) +{ + unsigned long long region_base, region_top; + unsigned long long ddr_base = STM32MP_DDR_BASE; + unsigned long long ddr_ns_size = + (unsigned long long)stm32mp_get_ddr_ns_size(); + unsigned long long ddr_ns_top = ddr_base + (ddr_ns_size - 1U); + unsigned long long ddr_top __unused; + + init_tzc400_begin(TZC_REGION_S_NONE); + + /* + * Region 1 set to cover all non-secure DRAM at 0xC000_0000. Apply the + * same configuration to all filters in the TZC. + */ + region_base = ddr_base; + region_top = ddr_ns_top; + tzc400_add_region(region_base, region_top, false); + +#if defined(AARCH32_SP_OPTEE) + /* Region 2 set to cover all secure DRAM. */ + region_base = region_top + 1U; + region_top += STM32MP_DDR_S_SIZE; + tzc400_add_region(region_base, region_top, true); + + ddr_top = STM32MP_DDR_BASE + dt_get_ddr_size() - 1U; + if (region_top < ddr_top) { + /* Region 3 set to cover non-secure memory DRAM after BL32. */ + region_base = region_top + 1U; + region_top = ddr_top; + tzc400_add_region(region_base, region_top, false); + } +#endif + + /* + * Raise an interrupt (secure FIQ) if a NS device tries to access + * secure memory + */ + init_tzc400_end(TZC_ACTION_INT); +} + +/******************************************************************************* + * Initialize the TrustZone Controller. + * Early initialization create only one region with full access to secure. + * This setting is used before and during DDR initialization. + ******************************************************************************/ +static void early_init_tzc400(void) +{ + stm32mp_clk_enable(TZC1); + stm32mp_clk_enable(TZC2); + + /* Region 0 set to cover all DRAM secure at 0xC000_0000 */ + init_tzc400_begin(TZC_REGION_S_RDWR); + + /* Raise an exception if a NS device tries to access secure memory */ + init_tzc400_end(TZC_ACTION_ERR); +} + +/******************************************************************************* + * Initialize the secure environment. At this moment only the TrustZone + * Controller is initialized. + ******************************************************************************/ +void stm32mp1_arch_security_setup(void) +{ + early_init_tzc400(); +} + +/******************************************************************************* + * Initialize the secure environment. At this moment only the TrustZone + * Controller is initialized. + ******************************************************************************/ +void stm32mp1_security_setup(void) +{ + init_tzc400(); +}