diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c index 7e76083b3..b0314d2ab 100644 --- a/plat/st/common/bl2_io_storage.c +++ b/plat/st/common/bl2_io_storage.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -24,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -31,7 +33,9 @@ #include #include +#include #include +#include /* IO devices */ uintptr_t fip_dev_handle; @@ -95,6 +99,10 @@ static io_mtd_dev_spec_t spi_nand_dev_spec = { static const io_dev_connector_t *spi_dev_con; #endif +#if STM32MP_USB_PROGRAMMER +static const io_dev_connector_t *memmap_dev_con; +#endif + io_block_spec_t image_block_spec = { .offset = 0U, .length = 0U, @@ -128,6 +136,9 @@ static void print_boot_device(boot_api_context_t *boot_context) case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI: INFO("Using SPI NAND\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); @@ -246,6 +257,32 @@ static void boot_spi_nand(boot_api_context_t *boot_context) } #endif /* STM32MP_SPI_NAND */ +#if 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 stm32cubeprogrammer_usb(void) +{ + int ret __unused; + struct usb_handle *pdev; + + /* Init USB on platform */ + pdev = usb_dfu_plat_init(); + + ret = stm32cubeprog_usb_load(pdev, DWL_BUFFER_BASE, DWL_BUFFER_SIZE); + assert(ret == 0); +} +#endif + void stm32mp_io_setup(void) { int io_result __unused; @@ -297,6 +334,12 @@ void stm32mp_io_setup(void) boot_spi_nand(boot_context); break; #endif +#if STM32MP_USB_PROGRAMMER + case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB: + dmbsy(); + mmap_io_setup(); + break; +#endif default: ERROR("Boot interface %d not supported\n", @@ -357,6 +400,17 @@ int bl2_plat_handle_pre_image_load(unsigned int image_id) break; #endif +#if STM32MP_USB_PROGRAMMER + case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB: + if (image_id == FW_CONFIG_ID) { + stm32cubeprogrammer_usb(); + /* FIP loaded at DWL address */ + image_block_spec.offset = DWL_BUFFER_BASE; + image_block_spec.length = DWL_BUFFER_SIZE; + } + break; +#endif + default: ERROR("FIP Not found\n"); panic(); diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c index e87c529b7..7eaf0ed98 100644 --- a/plat/st/stm32mp1/bl2_plat_setup.c +++ b/plat/st/stm32mp1/bl2_plat_setup.c @@ -490,5 +490,19 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) void bl2_el3_plat_prepare_exit(void) { + uint16_t boot_itf = stm32mp_get_boot_itf_selected(); + + switch (boot_itf) { +#if STM32MP_USB_PROGRAMMER + case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB: + /* Invalidate the downloaded buffer used with io_memmap */ + inv_dcache_range(DWL_BUFFER_BASE, DWL_BUFFER_SIZE); + break; +#endif + default: + /* Do nothing in default case */ + break; + } + stm32mp1_security_setup(); } diff --git a/plat/st/stm32mp1/include/boot_api.h b/plat/st/stm32mp1/include/boot_api.h index c16639ac4..52b1d1aa0 100644 --- a/plat/st/stm32mp1/include/boot_api.h +++ b/plat/st/stm32mp1/include/boot_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved + * Copyright (c) 2017-2021, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -39,6 +39,9 @@ /* Boot occurred on QSPI NOR */ #define BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI 0x4U +/* Boot occurred on USB */ +#define BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB 0x6U + /* Boot occurred on QSPI NAND */ #define BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI 0x7U diff --git a/plat/st/stm32mp1/include/platform_def.h b/plat/st/stm32mp1/include/platform_def.h index 8a065bf75..1e9443ece 100644 --- a/plat/st/stm32mp1/include/platform_def.h +++ b/plat/st/stm32mp1/include/platform_def.h @@ -92,6 +92,10 @@ */ #define PLAT_STM32MP_NS_IMAGE_OFFSET BL33_BASE +/* Needed by STM32CubeProgrammer support */ +#define DWL_BUFFER_BASE (STM32MP_DDR_BASE + U(0x08000000)) +#define DWL_BUFFER_SIZE U(0x08000000) + /* * SSBL offset in case it's stored in eMMC boot partition. * We can fix it to 256K because TF-A size can't be bigger than SRAM diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk index 14f90d466..c8c2e5f0b 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -53,6 +53,9 @@ STM32MP_SPI_NAND ?= 0 STM32MP_SPI_NOR ?= 0 STM32MP_EMMC_BOOT ?= 0 +# Serial boot devices +STM32MP_USB_PROGRAMMER ?= 0 + # Device tree DTB_FILE_NAME ?= stm32mp157c-ev1.dtb ifeq ($(STM32MP_USE_STM32IMAGE),1) @@ -127,6 +130,7 @@ $(eval $(call assert_booleans,\ STM32MP_SPI_NOR \ STM32MP_EMMC_BOOT \ PLAT_XLAT_TABLES_DYNAMIC \ + STM32MP_USB_PROGRAMMER \ STM32MP_USE_STM32IMAGE \ ))) @@ -147,6 +151,7 @@ $(eval $(call add_defines,\ PLAT_XLAT_TABLES_DYNAMIC \ STM32_TF_A_COPIES \ PLAT_PARTITION_MAX_ENTRIES \ + STM32MP_USB_PROGRAMMER \ STM32MP_USE_STM32IMAGE \ ))) @@ -251,6 +256,17 @@ ifneq ($(filter 1,${STM32MP_RAW_NAND} ${STM32MP_SPI_NAND} ${STM32MP_SPI_NOR}),) BL2_SOURCES += plat/st/stm32mp1/stm32mp1_boot_device.c endif +ifeq (${STM32MP_USB_PROGRAMMER},1) +#The DFU stack uses only one end point, reduce the USB stack footprint +$(eval $(call add_define_val,CONFIG_USBD_EP_NB,1U)) +BL2_SOURCES += drivers/io/io_memmap.c \ + drivers/st/usb/stm32mp1_usb.c \ + drivers/usb/usb_device.c \ + plat/st/common/stm32cubeprogrammer_usb.c \ + plat/st/common/usb_dfu.c \ + plat/st/stm32mp1/stm32mp1_usb_dfu.c +endif + BL2_SOURCES += drivers/st/ddr/stm32mp1_ddr.c \ drivers/st/ddr/stm32mp1_ram.c @@ -274,7 +290,8 @@ check_boot_device: [ ${STM32MP_SDMMC} != 1 ] && \ [ ${STM32MP_RAW_NAND} != 1 ] && \ [ ${STM32MP_SPI_NAND} != 1 ] && \ - [ ${STM32MP_SPI_NOR} != 1 ]; then \ + [ ${STM32MP_SPI_NOR} != 1 ] && \ + [ ${STM32MP_USB_PROGRAMMER} != 1 ]; then \ echo "No boot device driver is enabled"; \ false; \ fi