feat(stm32mp2): add BL31 device tree support

BL31 will need to access a device tree for several configurations (UART,
GIC, OTP mapping...).
Create a BL31 device tree (SOC_FW_CONFIG). It is loaded in DDR, in a
spare area.

Signed-off-by: Yann Gautier <yann.gautier@foss.st.com>
Signed-off-by: Maxime Méré <maxime.mere@foss.st.com>
Change-Id: I320a05859e1aa3dd8db9a274e7201075a8c250c2
This commit is contained in:
Maxime Méré 2024-10-02 18:24:40 +02:00
parent 742d0e6ef3
commit 27dd11dbf5
11 changed files with 157 additions and 2 deletions

View file

@ -31,6 +31,7 @@
bl32_extra2_uuid = "8ea87bb1-cfa2-3f4d-85fd-e7bba50220d9";
bl33_uuid = "d6d0eea7-fcea-d54b-9782-9934f234b6e4";
hw_cfg_uuid = "08b8f1d9-c9cf-9349-a962-6fbc6b7265cc";
soc_fw_cfg_uuid = "9979814b-0376-fb46-8c8e-8d267f7859e0";
tos_fw_cfg_uuid = "26257c1a-dbc6-7f47-8d96-c4c4b0248021";
nt_fw_cfg_uuid = "28da9815-93e8-7e44-ac66-1aaf801550f9";
};

13
fdts/stm32mp25-bl31.dtsi Normal file
View file

@ -0,0 +1,13 @@
// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause)
/*
* Copyright (C) 2024, STMicroelectronics - All Rights Reserved
*/
/ {
soc@0 {
rifsc@42080000 {
/delete-node/ mmc@48220000;
/delete-node/ mmc@48230000;
};
};
};

View file

@ -31,6 +31,10 @@
id = <BL31_IMAGE_ID>;
};
soc_fw-config {
id = <SOC_FW_CONFIG_ID>;
};
tos_fw {
id = <BL32_IMAGE_ID>;
};

View file

@ -11,6 +11,10 @@
/ {
dtb-registry {
soc_fw-config {
load-address = <0x0 0x81ff0000>;
max-size = <0x10000>;
};
tos_fw {
load-address = <0x0 0x82000000>;
max-size = <0x2000000>;

View file

@ -77,7 +77,7 @@ struct plat_io_policy policies[MAX_NUMBER_IDS] = {
#define DEFAULT_UUID_NUMBER U(7)
#ifdef __aarch64__
#define BL31_UUID_NUMBER U(1)
#define BL31_UUID_NUMBER U(2)
#else
#define BL31_UUID_NUMBER U(0)
#endif
@ -115,6 +115,7 @@ static const struct policies_load_info load_info[FCONF_ST_IO_UUID_NUMBER] = {
{FW_CONFIG_ID, "fw_cfg_uuid"},
#ifdef __aarch64__
{BL31_IMAGE_ID, "bl31_uuid"},
{SOC_FW_CONFIG_ID, "soc_fw_cfg_uuid"},
#endif
{BL32_IMAGE_ID, "bl32_uuid"},
{BL32_EXTRA1_IMAGE_ID, "bl32_extra1_uuid"},

View file

@ -280,6 +280,7 @@ int bl2_plat_handle_post_image_load(unsigned int image_id)
unsigned int i;
const unsigned int image_ids[] = {
BL31_IMAGE_ID,
SOC_FW_CONFIG_ID,
BL32_IMAGE_ID,
BL33_IMAGE_ID,
HW_CONFIG_ID,
@ -345,6 +346,7 @@ int bl2_plat_handle_post_image_load(unsigned int image_id)
break;
case HW_CONFIG_ID:
case SOC_FW_CONFIG_ID:
break;
default:

View file

@ -8,12 +8,16 @@
#include <stdint.h>
#include <common/bl_common.h>
#include <drivers/generic_delay_timer.h>
#include <drivers/st/stm32_console.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <plat/common/platform.h>
#include <platform_def.h>
static entry_point_info_t bl32_image_ep_info;
static entry_point_info_t bl33_image_ep_info;
void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
@ -31,6 +35,12 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
BL_CODE_END - BL_CODE_BASE,
MT_CODE | MT_SECURE);
/*
* Map soc_fw_config device tree with secure property, i.e. default region.
* DDR region definitions will be finalized at BL32 level.
*/
mmap_add_region(arg1, arg1, STM32MP_SOC_FW_CONFIG_MAX_SIZE, MT_RO_DATA | MT_SECURE);
#if USE_COHERENT_MEM
/* Map coherent memory */
mmap_add_region(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_BASE,
@ -40,6 +50,20 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
configure_mmu();
ret = dt_open_and_check(arg1);
if (ret < 0) {
EARLY_ERROR("%s: failed to open DT (%d)\n", __func__, ret);
panic();
}
ret = stm32mp2_clk_init();
if (ret < 0) {
EARLY_ERROR("%s: failed init clocks (%d)\n", __func__, ret);
panic();
}
(void)stm32mp_uart_console_setup();
/*
* Map upper SYSRAM where bl_params_t are stored in BL2
*/
@ -60,6 +84,31 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
bl_params_node_t *bl_params = params_from_bl2->head;
while (bl_params != NULL) {
/*
* Copy BL33 entry point information.
* They are stored in Secure RAM, in BL2's address space.
*/
if (bl_params->image_id == BL33_IMAGE_ID) {
bl33_image_ep_info = *bl_params->ep_info;
/*
* Check if hw_configuration is given to BL32 and
* share it to BL33
*/
if (arg2 != 0U) {
bl33_image_ep_info.args.arg0 = 0U;
bl33_image_ep_info.args.arg1 = 0U;
bl33_image_ep_info.args.arg2 = arg2;
}
}
if (bl_params->image_id == BL32_IMAGE_ID) {
bl32_image_ep_info = *bl_params->ep_info;
if (arg2 != 0U) {
bl32_image_ep_info.args.arg3 = arg2;
}
}
bl_params = bl_params->next_params_info;
}
@ -81,5 +130,27 @@ void bl31_platform_setup(void)
entry_point_info_t *bl31_plat_get_next_image_ep_info(unsigned int type)
{
return NULL;
entry_point_info_t *next_image_info = NULL;
assert(sec_state_is_valid(type));
switch (type) {
case NON_SECURE:
next_image_info = &bl33_image_ep_info;
break;
case SECURE:
next_image_info = &bl32_image_ep_info;
break;
default:
break;
}
/* None of the next images on ST platforms can have 0x0 as the entrypoint */
if ((next_image_info == NULL) || (next_image_info->pc == 0UL)) {
return NULL;
}
return next_image_info;
}

View file

@ -70,6 +70,21 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = {
.next_handoff_image_id = BL32_IMAGE_ID,
},
/* Fill SoC FW config related information */
{
.image_id = SOC_FW_CONFIG_ID,
SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
VERSION_2, entry_point_info_t,
SECURE | NON_EXECUTABLE),
SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
VERSION_2, image_info_t,
IMAGE_ATTRIB_SKIP_LOADING),
.next_handoff_image_id = INVALID_IMAGE_ID,
},
/* Fill BL32 related information */
{
.image_id = BL32_IMAGE_ID,

View file

@ -48,6 +48,8 @@ STM32MP_DDR_FIP_IO_STORAGE := 1
# Device tree
BL2_DTSI := stm32mp25-bl2.dtsi
FDT_SOURCES := $(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl2.dts,$(DTB_FILE_NAME)))
BL31_DTSI := stm32mp25-bl31.dtsi
FDT_SOURCES += $(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl31.dts,$(DTB_FILE_NAME)))
# Macros and rules to build TF binary
STM32_TF_STM32 := $(addprefix ${BUILD_PLAT}/tf-a-, $(patsubst %.dtb,%.stm32,$(DTB_FILE_NAME)))
@ -56,6 +58,7 @@ STM32_BINARY_MAPPING := plat/st/stm32mp2/${ARCH}/stm32mp2.S
STM32MP_FW_CONFIG_NAME := $(patsubst %.dtb,%-fw-config.dtb,$(DTB_FILE_NAME))
STM32MP_FW_CONFIG := ${BUILD_PLAT}/fdts/$(STM32MP_FW_CONFIG_NAME)
STM32MP_SOC_FW_CONFIG := $(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl31.dtb,$(DTB_FILE_NAME)))
ifeq (${STM32MP_DDR_FIP_IO_STORAGE},1)
STM32MP_DDR_FW_PATH ?= drivers/st/ddr/phy/firmware/bin/stm32mp2
STM32MP_DDR_FW_NAME := ${DDR_TYPE}_pmu_train.bin
@ -64,6 +67,8 @@ endif
FDT_SOURCES += $(addprefix fdts/, $(patsubst %.dtb,%.dts,$(STM32MP_FW_CONFIG_NAME)))
# Add the FW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_PAYLOAD,${STM32MP_FW_CONFIG},--fw-config))
# Add the SOC_FW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_IMG,STM32MP_SOC_FW_CONFIG,--soc-fw-config))
ifeq (${STM32MP_DDR_FIP_IO_STORAGE},1)
# Add the FW_DDR to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_IMG,STM32MP_DDR_FW,--ddr-fw))
@ -198,4 +203,11 @@ check_ddr_type:
false; \
fi
# Create DTB file for BL31
${BUILD_PLAT}/fdts/%-bl31.dts: fdts/%.dts fdts/${BL31_DTSI} | $$(@D)/
@echo '#include "$(patsubst fdts/%,%,$<)"' > $@
@echo '#include "${BL31_DTSI}"' >> $@
${BUILD_PLAT}/fdts/%-bl31.dtb: ${BUILD_PLAT}/fdts/%-bl31.dts
include plat/st/common/common_rules.mk

View file

@ -138,7 +138,11 @@ enum ddr_type {
* MAX_MMAP_REGIONS is usually:
* BL stm32mp2_mmap size + mmap regions in *_plat_arch_setup
*/
#if defined(IMAGE_BL31)
#define MAX_MMAP_REGIONS 7
#else
#define MAX_MMAP_REGIONS 6
#endif
/* DTB initialization value */
#define STM32MP_BL2_DTB_SIZE U(0x00006000) /* 24 KB for DTB */
@ -166,6 +170,7 @@ enum ddr_type {
#define STM32MP_HW_CONFIG_BASE (STM32MP_BL33_BASE + \
STM32MP_BL33_MAX_SIZE)
#define STM32MP_HW_CONFIG_MAX_SIZE U(0x40000)
#define STM32MP_SOC_FW_CONFIG_MAX_SIZE U(0x10000) /* 64kB for BL31 DT */
/*******************************************************************************
* STM32MP2 device/io map related constants (used for MMU)

View file

@ -117,6 +117,33 @@ unsigned long stm32_get_gpio_bank_clock(unsigned int bank)
return CK_BUS_GPIOA + (bank - GPIO_BANK_A);
}
#if STM32MP_UART_PROGRAMMER || !defined(IMAGE_BL2)
/*
* UART Management
*/
static const uintptr_t stm32mp2_uart_addresses[STM32MP_NB_OF_UART] = {
USART1_BASE,
USART2_BASE,
USART3_BASE,
UART4_BASE,
UART5_BASE,
USART6_BASE,
UART7_BASE,
UART8_BASE,
UART9_BASE,
};
uintptr_t get_uart_address(uint32_t instance_nb)
{
if ((instance_nb == 0U) ||
(instance_nb > STM32MP_NB_OF_UART)) {
return 0U;
}
return stm32mp2_uart_addresses[instance_nb - 1U];
}
#endif
uint32_t stm32mp_get_chip_version(void)
{
static uint32_t rev;