diff --git a/plat/st/stm32mp2/bl2_plat_setup.c b/plat/st/stm32mp2/bl2_plat_setup.c index 724209a16..3c7c0d888 100644 --- a/plat/st/stm32mp2/bl2_plat_setup.c +++ b/plat/st/stm32mp2/bl2_plat_setup.c @@ -8,26 +8,202 @@ #include #include +#include +#include +#include +#include +#include #include #include #include +#include + +#define BOOT_CTX_ADDR 0x0e000020UL + +static void print_reset_reason(void) +{ + uint32_t rstsr = mmio_read_32(stm32mp_rcc_base() + RCC_C1BOOTRSTSCLRR); + + if (rstsr == 0U) { + WARN("Reset reason unknown\n"); + return; + } + + INFO("Reset reason (0x%x):\n", rstsr); + + if ((rstsr & RCC_C1BOOTRSTSCLRR_PADRSTF) == 0U) { + if ((rstsr & RCC_C1BOOTRSTSCLRR_STBYC1RSTF) != 0U) { + INFO("System exits from Standby for CA35\n"); + return; + } + + if ((rstsr & RCC_C1BOOTRSTSCLRR_D1STBYRSTF) != 0U) { + INFO("D1 domain exits from DStandby\n"); + return; + } + } + + if ((rstsr & RCC_C1BOOTRSTSCLRR_PORRSTF) != 0U) { + INFO(" Power-on Reset (rst_por)\n"); + return; + } + + if ((rstsr & RCC_C1BOOTRSTSCLRR_BORRSTF) != 0U) { + INFO(" Brownout Reset (rst_bor)\n"); + return; + } + + if ((rstsr & RCC_C1BOOTRSTSSETR_SYSC2RSTF) != 0U) { + INFO(" System reset (SYSRST) by M33\n"); + return; + } + + if ((rstsr & RCC_C1BOOTRSTSSETR_SYSC1RSTF) != 0U) { + INFO(" System reset (SYSRST) by A35\n"); + return; + } + + if ((rstsr & RCC_C1BOOTRSTSCLRR_HCSSRSTF) != 0U) { + INFO(" Clock failure on HSE\n"); + return; + } + + if ((rstsr & RCC_C1BOOTRSTSCLRR_IWDG1SYSRSTF) != 0U) { + INFO(" IWDG1 system reset (rst_iwdg1)\n"); + return; + } + + if ((rstsr & RCC_C1BOOTRSTSCLRR_IWDG2SYSRSTF) != 0U) { + INFO(" IWDG2 system reset (rst_iwdg2)\n"); + return; + } + + if ((rstsr & RCC_C1BOOTRSTSCLRR_IWDG3SYSRSTF) != 0U) { + INFO(" IWDG3 system reset (rst_iwdg3)\n"); + return; + } + + if ((rstsr & RCC_C1BOOTRSTSCLRR_IWDG4SYSRSTF) != 0U) { + INFO(" IWDG4 system reset (rst_iwdg4)\n"); + return; + } + + if ((rstsr & RCC_C1BOOTRSTSCLRR_IWDG5SYSRSTF) != 0U) { + INFO(" IWDG5 system reset (rst_iwdg5)\n"); + return; + } + + if ((rstsr & RCC_C1BOOTRSTSCLRR_C1P1RSTF) != 0U) { + INFO(" A35 processor core 1 reset\n"); + return; + } + + if ((rstsr & RCC_C1BOOTRSTSCLRR_PADRSTF) != 0U) { + INFO(" Pad Reset from NRST\n"); + return; + } + + if ((rstsr & RCC_C1BOOTRSTSCLRR_VCORERSTF) != 0U) { + INFO(" Reset due to a failure of VDD_CORE\n"); + return; + } + + if ((rstsr & RCC_C1BOOTRSTSCLRR_C1RSTF) != 0U) { + INFO(" A35 processor reset\n"); + return; + } + + ERROR(" Unidentified reset reason\n"); +} void bl2_el3_early_platform_setup(u_register_t arg0 __unused, u_register_t arg1 __unused, u_register_t arg2 __unused, u_register_t arg3 __unused) { + stm32mp_save_boot_ctx_address(BOOT_CTX_ADDR); } void bl2_platform_setup(void) { } +static void reset_backup_domain(void) +{ + uintptr_t pwr_base = stm32mp_pwr_base(); + uintptr_t rcc_base = stm32mp_rcc_base(); + + /* + * Disable the backup domain write protection. + * The protection is enable at each reset by hardware + * and must be disabled by software. + */ + mmio_setbits_32(pwr_base + PWR_BDCR1, PWR_BDCR1_DBD3P); + + while ((mmio_read_32(pwr_base + PWR_BDCR1) & PWR_BDCR1_DBD3P) == 0U) { + ; + } + + /* Reset backup domain on cold boot cases */ + if ((mmio_read_32(rcc_base + RCC_BDCR) & RCC_BDCR_RTCCKEN) == 0U) { + mmio_setbits_32(rcc_base + RCC_BDCR, RCC_BDCR_VSWRST); + + while ((mmio_read_32(rcc_base + RCC_BDCR) & RCC_BDCR_VSWRST) == 0U) { + ; + } + + mmio_clrbits_32(rcc_base + RCC_BDCR, RCC_BDCR_VSWRST); + } +} + void bl2_el3_plat_arch_setup(void) { + const char *board_model; + boot_api_context_t *boot_context = + (boot_api_context_t *)stm32mp_get_boot_ctx_address(); + if (stm32_otp_probe() != 0U) { EARLY_ERROR("OTP probe failed\n"); panic(); } + + mmap_add_region(BL_CODE_BASE, BL_CODE_BASE, + BL_CODE_END - BL_CODE_BASE, + MT_CODE | MT_SECURE); + + configure_mmu(); + + /* Prevent corruption of preloaded Device Tree */ + mmap_add_dynamic_region(DTB_BASE, DTB_BASE, + DTB_LIMIT - DTB_BASE, + MT_RO_DATA | MT_SECURE); + + if (dt_open_and_check(STM32MP_DTB_BASE) < 0) { + panic(); + } + + reset_backup_domain(); + + if (stm32mp2_clk_init() < 0) { + panic(); + } + + stm32_save_boot_info(boot_context); + + if (stm32mp_uart_console_setup() != 0) { + goto skip_console_init; + } + + board_model = dt_get_board_model(); + if (board_model != NULL) { + NOTICE("Model: %s\n", board_model); + } + + print_reset_reason(); + +skip_console_init: + fconf_populate("TB_FW", STM32MP_DTB_BASE); + + stm32mp_io_setup(); } diff --git a/plat/st/stm32mp2/include/boot_api.h b/plat/st/stm32mp2/include/boot_api.h index d3bed7631..580a65b59 100644 --- a/plat/st/stm32mp2/include/boot_api.h +++ b/plat/st/stm32mp2/include/boot_api.h @@ -86,7 +86,7 @@ /* Image Header related definitions */ /* Definition of header version */ -#define BOOT_API_HEADER_VERSION 0x00020000U +#define BOOT_API_HEADER_VERSION 0x00020200U /* * Magic number used to detect header in memory diff --git a/plat/st/stm32mp2/include/plat_tbbr_img_def.h b/plat/st/stm32mp2/include/plat_tbbr_img_def.h new file mode 100644 index 000000000..5dfd41f5f --- /dev/null +++ b/plat/st/stm32mp2/include/plat_tbbr_img_def.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2024, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLAT_TBBR_IMG_DEF_H +#define PLAT_TBBR_IMG_DEF_H + +#include + +/* Undef the existing values */ +#undef BKUP_FWU_METADATA_IMAGE_ID +#undef FWU_METADATA_IMAGE_ID +#undef FW_CONFIG_ID +#undef ENC_IMAGE_ID +#undef GPT_IMAGE_ID +#undef NT_FW_CONFIG_ID +#undef SOC_FW_CONFIG_ID +#undef TB_FW_CONFIG_ID +#undef HW_CONFIG_ID +#undef TRUSTED_BOOT_FW_CERT_ID +#undef SOC_FW_CONTENT_CERT_ID +#undef BL32_EXTRA1_IMAGE_ID +#undef TOS_FW_CONFIG_ID + +/* Define the STM32MP2 used ID */ +#define FW_CONFIG_ID U(1) +#define HW_CONFIG_ID U(2) +#define ENC_IMAGE_ID U(6) +#define BL32_EXTRA1_IMAGE_ID U(8) +#define FWU_METADATA_IMAGE_ID U(12) +#define BKUP_FWU_METADATA_IMAGE_ID U(13) +#define TOS_FW_CONFIG_ID U(16) +#define NT_FW_CONFIG_ID U(18) +#define SOC_FW_CONFIG_ID U(19) +#define TB_FW_CONFIG_ID U(20) +#define TRUSTED_BOOT_FW_CERT_ID U(21) +#define SOC_FW_CONTENT_CERT_ID U(23) +#define STM32MP_CONFIG_CERT_ID U(24) +#define GPT_IMAGE_ID U(25) + +/* Increase the MAX_NUMBER_IDS to match the authentication pool required */ +#define MAX_NUMBER_IDS U(26) + +#endif /* PLAT_TBBR_IMG_DEF_H */ + diff --git a/plat/st/stm32mp2/include/platform_def.h b/plat/st/stm32mp2/include/platform_def.h index 404c384f4..2f7570d78 100644 --- a/plat/st/stm32mp2/include/platform_def.h +++ b/plat/st/stm32mp2/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, STMicroelectronics - All Rights Reserved + * Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -61,11 +61,32 @@ #define BL2_LIMIT (STM32MP_BL2_BASE + \ STM32MP_BL2_SIZE) +#define BL2_RO_BASE STM32MP_BL2_RO_BASE +#define BL2_RO_LIMIT (STM32MP_BL2_RO_BASE + \ + STM32MP_BL2_RO_SIZE) + +#define BL2_RW_BASE STM32MP_BL2_RW_BASE +#define BL2_RW_LIMIT (STM32MP_BL2_RW_BASE + \ + STM32MP_BL2_RW_SIZE) + +/******************************************************************************* + * BL31 specific defines. + ******************************************************************************/ +#define BL31_BASE 0 +#define BL31_LIMIT STM32MP_BL31_SIZE + /******************************************************************************* * BL33 specific defines. ******************************************************************************/ #define BL33_BASE STM32MP_BL33_BASE +/******************************************************************************* + * DTB specific defines. + ******************************************************************************/ +#define DTB_BASE STM32MP_DTB_BASE +#define DTB_LIMIT (STM32MP_DTB_BASE + \ + STM32MP_DTB_SIZE) + /******************************************************************************* * Platform specific page table and MMU setup constants ******************************************************************************/ diff --git a/plat/st/stm32mp2/include/stm32mp2_private.h b/plat/st/stm32mp2/include/stm32mp2_private.h index e1403d238..2c44889ee 100644 --- a/plat/st/stm32mp2/include/stm32mp2_private.h +++ b/plat/st/stm32mp2/include/stm32mp2_private.h @@ -7,6 +7,8 @@ #ifndef STM32MP2_PRIVATE_H #define STM32MP2_PRIVATE_H +void configure_mmu(void); + /* Wrappers for OTP / BSEC functions */ static inline uint32_t stm32_otp_probe(void) { diff --git a/plat/st/stm32mp2/platform.mk b/plat/st/stm32mp2/platform.mk index d9a4d79d2..9614ed09a 100644 --- a/plat/st/stm32mp2/platform.mk +++ b/plat/st/stm32mp2/platform.mk @@ -13,6 +13,7 @@ include plat/st/common/common.mk CRASH_REPORTING := 1 ENABLE_PIE := 1 PROGRAMMABLE_RESET_ADDRESS := 1 +BL2_IN_XIP_MEM := 1 # Default Device tree DTB_FILE_NAME ?= stm32mp257f-ev1.dtb @@ -24,7 +25,7 @@ STM32_HEADER_VERSION_MAJOR := 2 STM32_HEADER_VERSION_MINOR := 2 # Set load address for serial boot devices -DWL_BUFFER_BASE ?= 0x87000000 +DWL_BUFFER_BASE ?= 0x87000000 # Device tree BL2_DTSI := stm32mp25-bl2.dtsi @@ -35,9 +36,26 @@ STM32_TF_STM32 := $(addprefix ${BUILD_PLAT}/tf-a-, $(patsubst %.dtb,%.stm32,$( STM32_LD_FILE := plat/st/stm32mp2/${ARCH}/stm32mp2.ld.S STM32_BINARY_MAPPING := plat/st/stm32mp2/${ARCH}/stm32mp2.S +# Enable flags for C files +$(eval $(call assert_booleans,\ + $(sort \ + STM32MP25 \ +))) + +$(eval $(call assert_numerics,\ + $(sort \ + PLAT_PARTITION_MAX_ENTRIES \ + STM32_HEADER_VERSION_MAJOR \ + STM32_TF_A_COPIES \ +))) + $(eval $(call add_defines,\ $(sort \ DWL_BUFFER_BASE \ + PLAT_PARTITION_MAX_ENTRIES \ + PLAT_TBBR_IMG_DEF \ + STM32_TF_A_COPIES \ + STM32MP25 \ ))) # STM32MP2x is based on Cortex-A35, which is Armv8.0, and does not support BTI @@ -51,6 +69,8 @@ PLAT_BL_COMMON_SOURCES += lib/cpus/${ARCH}/cortex_a35.S PLAT_BL_COMMON_SOURCES += drivers/st/uart/${ARCH}/stm32_console.S PLAT_BL_COMMON_SOURCES += plat/st/stm32mp2/${ARCH}/stm32mp2_helper.S +PLAT_BL_COMMON_SOURCES += plat/st/stm32mp2/stm32mp2_private.c + PLAT_BL_COMMON_SOURCES += drivers/st/bsec/bsec3.c \ drivers/st/reset/stm32mp2_reset.c @@ -58,10 +78,16 @@ PLAT_BL_COMMON_SOURCES += drivers/st/clk/clk-stm32-core.c \ drivers/st/clk/clk-stm32mp2.c BL2_SOURCES += plat/st/stm32mp2/plat_bl2_mem_params_desc.c + BL2_SOURCES += plat/st/stm32mp2/bl2_plat_setup.c +ifneq ($(filter 1,${STM32MP_EMMC} ${STM32MP_SDMMC}),) +BL2_SOURCES += drivers/st/mmc/stm32_sdmmc2.c +endif + ifeq (${STM32MP_USB_PROGRAMMER},1) BL2_SOURCES += plat/st/stm32mp2/stm32mp2_usb_dfu.c endif +# Compilation rules include plat/st/common/common_rules.mk diff --git a/plat/st/stm32mp2/stm32mp2_def.h b/plat/st/stm32mp2/stm32mp2_def.h index d65fcea81..c8fc64650 100644 --- a/plat/st/stm32mp2/stm32mp2_def.h +++ b/plat/st/stm32mp2/stm32mp2_def.h @@ -12,6 +12,10 @@ #include #endif #include +#ifndef __ASSEMBLER__ +#include +#endif +#include #include #include #include @@ -31,9 +35,6 @@ #define STM32MP_SYSRAM_BASE U(0x0E000000) #define STM32MP_SYSRAM_SIZE U(0x00040000) -#define STM32MP_SEC_SYSRAM_BASE STM32MP_SYSRAM_BASE -#define STM32MP_SEC_SYSRAM_SIZE STM32MP_SYSRAM_SIZE - /* DDR configuration */ #define STM32MP_DDR_BASE U(0x80000000) #define STM32MP_DDR_MAX_SIZE UL(0x100000000) /* Max 4GB */ @@ -49,28 +50,38 @@ enum ddr_type { /* Section used inside TF binaries */ #define STM32MP_PARAM_LOAD_SIZE U(0x00002400) /* 9 KB for param */ -/* 512 Octets reserved for header */ +/* 512 Bytes reserved for header */ #define STM32MP_HEADER_SIZE U(0x00000200) -#define STM32MP_HEADER_BASE (STM32MP_SEC_SYSRAM_BASE + \ +#define STM32MP_HEADER_BASE (STM32MP_SYSRAM_BASE + \ STM32MP_PARAM_LOAD_SIZE) /* round_up(STM32MP_PARAM_LOAD_SIZE + STM32MP_HEADER_SIZE, PAGE_SIZE) */ #define STM32MP_HEADER_RESERVED_SIZE U(0x3000) -#define STM32MP_BINARY_BASE (STM32MP_SEC_SYSRAM_BASE + \ +#define STM32MP_BINARY_BASE (STM32MP_SYSRAM_BASE + \ STM32MP_PARAM_LOAD_SIZE + \ STM32MP_HEADER_SIZE) -#define STM32MP_BINARY_SIZE (STM32MP_SEC_SYSRAM_SIZE - \ +#define STM32MP_BINARY_SIZE (STM32MP_SYSRAM_SIZE - \ (STM32MP_PARAM_LOAD_SIZE + \ STM32MP_HEADER_SIZE)) -#define STM32MP_BL2_SIZE U(0x0002A000) /* 168 KB for BL2 */ +#define STM32MP_BL2_RO_SIZE U(0x00020000) /* 128 KB */ +#define STM32MP_BL2_SIZE U(0x00029000) /* 164 KB for BL2 */ -#define STM32MP_BL2_BASE (STM32MP_SEC_SYSRAM_BASE + \ - STM32MP_SEC_SYSRAM_SIZE - \ +#define STM32MP_BL2_BASE (STM32MP_SYSRAM_BASE + \ + STM32MP_SYSRAM_SIZE - \ STM32MP_BL2_SIZE) +#define STM32MP_BL2_RO_BASE STM32MP_BL2_BASE + +#define STM32MP_BL2_RW_BASE (STM32MP_BL2_RO_BASE + \ + STM32MP_BL2_RO_SIZE) + +#define STM32MP_BL2_RW_SIZE (STM32MP_SYSRAM_BASE + \ + STM32MP_SYSRAM_SIZE - \ + STM32MP_BL2_RW_BASE) + /* BL2 and BL32/sp_min require 4 tables */ #define MAX_XLAT_TABLES U(4) /* 16 KB for mapping */ @@ -81,14 +92,25 @@ enum ddr_type { #define MAX_MMAP_REGIONS 6 /* DTB initialization value */ -#define STM32MP_BL2_DTB_SIZE U(0x00005000) /* 20 KB for DTB */ +#define STM32MP_BL2_DTB_SIZE U(0x00006000) /* 24 KB for DTB */ #define STM32MP_BL2_DTB_BASE (STM32MP_BL2_BASE - \ STM32MP_BL2_DTB_SIZE) +#if defined(IMAGE_BL2) +#define STM32MP_DTB_SIZE STM32MP_BL2_DTB_SIZE +#define STM32MP_DTB_BASE STM32MP_BL2_DTB_BASE +#endif + #define STM32MP_BL33_BASE (STM32MP_DDR_BASE + U(0x04000000)) #define STM32MP_BL33_MAX_SIZE U(0x400000) +/******************************************************************************* + * STM32MP2 device/io map related constants (used for MMU) + ******************************************************************************/ +#define STM32MP_DEVICE_BASE U(0x40000000) +#define STM32MP_DEVICE_SIZE U(0x40000000) + /******************************************************************************* * STM32MP2 RCC ******************************************************************************/ @@ -314,6 +336,7 @@ static inline uintptr_t tamp_bkpr(uint32_t idx) #define DT_DDR_COMPAT "st,stm32mp2-ddr" #define DT_PWR_COMPAT "st,stm32mp25-pwr" #define DT_RCC_CLK_COMPAT "st,stm32mp25-rcc" +#define DT_SDMMC2_COMPAT "st,stm32mp25-sdmmc2" #define DT_UART_COMPAT "st,stm32h7-uart" #endif /* STM32MP2_DEF_H */ diff --git a/plat/st/stm32mp2/stm32mp2_private.c b/plat/st/stm32mp2/stm32mp2_private.c new file mode 100644 index 000000000..199100c29 --- /dev/null +++ b/plat/st/stm32mp2/stm32mp2_private.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include + +#include + +#define BKPR_BOOT_MODE 96U + +#define MAP_SYSRAM MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \ + STM32MP_SYSRAM_SIZE, \ + MT_MEMORY | \ + MT_RW | \ + MT_SECURE | \ + MT_EXECUTE_NEVER) + +#define MAP_DEVICE MAP_REGION_FLAT(STM32MP_DEVICE_BASE, \ + STM32MP_DEVICE_SIZE, \ + MT_DEVICE | \ + MT_RW | \ + MT_SECURE | \ + MT_EXECUTE_NEVER) + +#if defined(IMAGE_BL2) +static const mmap_region_t stm32mp2_mmap[] = { + MAP_SYSRAM, + MAP_DEVICE, + {0} +}; +#endif + +void configure_mmu(void) +{ + mmap_add(stm32mp2_mmap); + init_xlat_tables(); + + enable_mmu_el3(0); +} + +uintptr_t stm32_get_gpio_bank_base(unsigned int bank) +{ + if (bank == GPIO_BANK_Z) { + return GPIOZ_BASE; + } + + assert(bank <= GPIO_BANK_K); + + return GPIOA_BASE + (bank * GPIO_BANK_OFFSET); +} + +uint32_t stm32_get_gpio_bank_offset(unsigned int bank) +{ + if (bank == GPIO_BANK_Z) { + return 0; + } + + assert(bank <= GPIO_BANK_K); + + return bank * GPIO_BANK_OFFSET; +} + +unsigned long stm32_get_gpio_bank_clock(unsigned int bank) +{ + if (bank == GPIO_BANK_Z) { + return CK_BUS_GPIOZ; + } + + assert(bank <= GPIO_BANK_K); + + return CK_BUS_GPIOA + (bank - GPIO_BANK_A); +} + +uintptr_t stm32_get_bkpr_boot_mode_addr(void) +{ + return tamp_bkpr(BKPR_BOOT_MODE); +}