GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)
This commit is contained in:
@@ -0,0 +1,562 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <common/bl_common.h>
|
||||
#include <common/debug.h>
|
||||
#include <common/desc_image_load.h>
|
||||
#include <drivers/generic_delay_timer.h>
|
||||
#include <drivers/mmc.h>
|
||||
#include <drivers/st/bsec.h>
|
||||
#include <drivers/st/regulator_fixed.h>
|
||||
#include <drivers/st/stm32_iwdg.h>
|
||||
#include <drivers/st/stm32_rng.h>
|
||||
#include <drivers/st/stm32_uart.h>
|
||||
#include <drivers/st/stm32mp1_clk.h>
|
||||
#include <drivers/st/stm32mp1_pwr.h>
|
||||
#include <drivers/st/stm32mp1_ram.h>
|
||||
#include <drivers/st/stm32mp_pmic.h>
|
||||
#include <lib/fconf/fconf.h>
|
||||
#include <lib/fconf/fconf_dyn_cfg_getter.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <lib/optee_utils.h>
|
||||
#include <lib/xlat_tables/xlat_tables_v2.h>
|
||||
#include <plat/common/platform.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
#include <stm32mp_common.h>
|
||||
#include <stm32mp1_dbgmcu.h>
|
||||
|
||||
#if DEBUG
|
||||
static const char debug_msg[] = {
|
||||
"***************************************************\n"
|
||||
"** DEBUG ACCESS PORT IS OPEN! **\n"
|
||||
"** This boot image is only for debugging purpose **\n"
|
||||
"** and is unsafe for production use. **\n"
|
||||
"** **\n"
|
||||
"** If you see this message and you are not **\n"
|
||||
"** debugging report this immediately to your **\n"
|
||||
"** vendor! **\n"
|
||||
"***************************************************\n"
|
||||
};
|
||||
#endif
|
||||
|
||||
static void print_reset_reason(void)
|
||||
{
|
||||
uint32_t rstsr = mmio_read_32(stm32mp_rcc_base() + RCC_MP_RSTSCLRR);
|
||||
|
||||
if (rstsr == 0U) {
|
||||
WARN("Reset reason unknown\n");
|
||||
return;
|
||||
}
|
||||
|
||||
INFO("Reset reason (0x%x):\n", rstsr);
|
||||
|
||||
if ((rstsr & RCC_MP_RSTSCLRR_PADRSTF) == 0U) {
|
||||
if ((rstsr & RCC_MP_RSTSCLRR_STDBYRSTF) != 0U) {
|
||||
INFO("System exits from STANDBY\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((rstsr & RCC_MP_RSTSCLRR_CSTDBYRSTF) != 0U) {
|
||||
INFO("MPU exits from CSTANDBY\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ((rstsr & RCC_MP_RSTSCLRR_PORRSTF) != 0U) {
|
||||
INFO(" Power-on Reset (rst_por)\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((rstsr & RCC_MP_RSTSCLRR_BORRSTF) != 0U) {
|
||||
INFO(" Brownout Reset (rst_bor)\n");
|
||||
return;
|
||||
}
|
||||
|
||||
#if STM32MP15
|
||||
if ((rstsr & RCC_MP_RSTSCLRR_MCSYSRSTF) != 0U) {
|
||||
if ((rstsr & RCC_MP_RSTSCLRR_PADRSTF) != 0U) {
|
||||
INFO(" System reset generated by MCU (MCSYSRST)\n");
|
||||
} else {
|
||||
INFO(" Local reset generated by MCU (MCSYSRST)\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((rstsr & RCC_MP_RSTSCLRR_MPSYSRSTF) != 0U) {
|
||||
INFO(" System reset generated by MPU (MPSYSRST)\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((rstsr & RCC_MP_RSTSCLRR_HCSSRSTF) != 0U) {
|
||||
INFO(" Reset due to a clock failure on HSE\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((rstsr & RCC_MP_RSTSCLRR_IWDG1RSTF) != 0U) {
|
||||
INFO(" IWDG1 Reset (rst_iwdg1)\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((rstsr & RCC_MP_RSTSCLRR_IWDG2RSTF) != 0U) {
|
||||
INFO(" IWDG2 Reset (rst_iwdg2)\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((rstsr & RCC_MP_RSTSCLRR_MPUP0RSTF) != 0U) {
|
||||
INFO(" MPU Processor 0 Reset\n");
|
||||
return;
|
||||
}
|
||||
|
||||
#if STM32MP15
|
||||
if ((rstsr & RCC_MP_RSTSCLRR_MPUP1RSTF) != 0U) {
|
||||
INFO(" MPU Processor 1 Reset\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((rstsr & RCC_MP_RSTSCLRR_PADRSTF) != 0U) {
|
||||
INFO(" Pad Reset from NRST\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((rstsr & RCC_MP_RSTSCLRR_VCORERSTF) != 0U) {
|
||||
INFO(" Reset due to a failure of VDD_CORE\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ERROR(" Unidentified reset reason\n");
|
||||
}
|
||||
|
||||
void bl2_el3_early_platform_setup(u_register_t arg0,
|
||||
u_register_t arg1 __unused,
|
||||
u_register_t arg2 __unused,
|
||||
u_register_t arg3 __unused)
|
||||
{
|
||||
stm32mp_setup_early_console();
|
||||
|
||||
stm32mp_save_boot_ctx_address(arg0);
|
||||
}
|
||||
|
||||
void bl2_platform_setup(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = stm32mp1_ddr_probe();
|
||||
if (ret < 0) {
|
||||
ERROR("Invalid DDR init: error %d\n", ret);
|
||||
panic();
|
||||
}
|
||||
|
||||
/* Map DDR for binary load, now with cacheable attribute */
|
||||
ret = mmap_add_dynamic_region(STM32MP_DDR_BASE, STM32MP_DDR_BASE,
|
||||
STM32MP_DDR_MAX_SIZE, MT_MEMORY | MT_RW | MT_SECURE);
|
||||
if (ret < 0) {
|
||||
ERROR("DDR mapping: error %d\n", ret);
|
||||
panic();
|
||||
}
|
||||
}
|
||||
|
||||
#if STM32MP15
|
||||
static void update_monotonic_counter(void)
|
||||
{
|
||||
uint32_t version;
|
||||
uint32_t otp;
|
||||
|
||||
CASSERT(STM32_TF_VERSION <= MAX_MONOTONIC_VALUE,
|
||||
assert_stm32mp1_monotonic_counter_reach_max);
|
||||
|
||||
/* Check if monotonic counter needs to be incremented */
|
||||
if (stm32_get_otp_index(MONOTONIC_OTP, &otp, NULL) != 0) {
|
||||
panic();
|
||||
}
|
||||
|
||||
if (stm32_get_otp_value_from_idx(otp, &version) != 0) {
|
||||
panic();
|
||||
}
|
||||
|
||||
if ((version + 1U) < BIT(STM32_TF_VERSION)) {
|
||||
uint32_t result;
|
||||
|
||||
/* Need to increment the monotonic counter. */
|
||||
version = BIT(STM32_TF_VERSION) - 1U;
|
||||
|
||||
result = bsec_program_otp(version, otp);
|
||||
if (result != BSEC_OK) {
|
||||
ERROR("BSEC: MONOTONIC_OTP program Error %u\n",
|
||||
result);
|
||||
panic();
|
||||
}
|
||||
INFO("Monotonic counter has been incremented (value 0x%x)\n",
|
||||
version);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
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();
|
||||
uintptr_t pwr_base;
|
||||
uintptr_t rcc_base;
|
||||
|
||||
if (bsec_probe() != 0U) {
|
||||
panic();
|
||||
}
|
||||
|
||||
mmap_add_region(BL_CODE_BASE, BL_CODE_BASE,
|
||||
BL_CODE_END - BL_CODE_BASE,
|
||||
MT_CODE | MT_SECURE);
|
||||
|
||||
/* Prevent corruption of preloaded Device Tree */
|
||||
mmap_add_region(DTB_BASE, DTB_BASE,
|
||||
DTB_LIMIT - DTB_BASE,
|
||||
MT_RO_DATA | MT_SECURE);
|
||||
|
||||
configure_mmu();
|
||||
|
||||
if (dt_open_and_check(STM32MP_DTB_BASE) < 0) {
|
||||
panic();
|
||||
}
|
||||
|
||||
pwr_base = stm32mp_pwr_base();
|
||||
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_CR1, PWR_CR1_DBP);
|
||||
|
||||
while ((mmio_read_32(pwr_base + PWR_CR1) & PWR_CR1_DBP) == 0U) {
|
||||
;
|
||||
}
|
||||
|
||||
/* Reset backup domain on cold boot cases */
|
||||
if ((mmio_read_32(rcc_base + RCC_BDCR) & RCC_BDCR_RTCSRC_MASK) == 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);
|
||||
}
|
||||
|
||||
#if STM32MP15
|
||||
/* Disable MCKPROT */
|
||||
mmio_clrbits_32(rcc_base + RCC_TZCR, RCC_TZCR_MCKPROT);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set minimum reset pulse duration to 31ms for discrete power
|
||||
* supplied boards.
|
||||
*/
|
||||
if (dt_pmic_status() <= 0) {
|
||||
mmio_clrsetbits_32(rcc_base + RCC_RDLSICR,
|
||||
RCC_RDLSICR_MRD_MASK,
|
||||
31U << RCC_RDLSICR_MRD_SHIFT);
|
||||
}
|
||||
|
||||
generic_delay_timer_init();
|
||||
|
||||
#if STM32MP_UART_PROGRAMMER
|
||||
/* Disable programmer UART before changing clock tree */
|
||||
if (boot_context->boot_interface_selected ==
|
||||
BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART) {
|
||||
uintptr_t uart_prog_addr =
|
||||
get_uart_address(boot_context->boot_interface_instance);
|
||||
|
||||
stm32_uart_stop(uart_prog_addr);
|
||||
}
|
||||
#endif
|
||||
if (stm32mp1_clk_probe() < 0) {
|
||||
panic();
|
||||
}
|
||||
|
||||
if (stm32mp1_clk_init() < 0) {
|
||||
panic();
|
||||
}
|
||||
|
||||
stm32_save_boot_interface(boot_context->boot_interface_selected,
|
||||
boot_context->boot_interface_instance);
|
||||
stm32_save_boot_auth(boot_context->auth_status,
|
||||
boot_context->boot_partition_used_toboot);
|
||||
|
||||
#if STM32MP_USB_PROGRAMMER && STM32MP15
|
||||
/* Deconfigure all UART RX pins configured by ROM code */
|
||||
stm32mp1_deconfigure_uart_pins();
|
||||
#endif
|
||||
|
||||
if (stm32mp_uart_console_setup() != 0) {
|
||||
goto skip_console_init;
|
||||
}
|
||||
|
||||
stm32mp_print_cpuinfo();
|
||||
|
||||
board_model = dt_get_board_model();
|
||||
if (board_model != NULL) {
|
||||
NOTICE("Model: %s\n", board_model);
|
||||
}
|
||||
|
||||
stm32mp_print_boardinfo();
|
||||
|
||||
if (boot_context->auth_status != BOOT_API_CTX_AUTH_NO) {
|
||||
NOTICE("Bootrom authentication %s\n",
|
||||
(boot_context->auth_status == BOOT_API_CTX_AUTH_FAILED) ?
|
||||
"failed" : "succeeded");
|
||||
}
|
||||
|
||||
skip_console_init:
|
||||
#if !TRUSTED_BOARD_BOOT
|
||||
if (stm32mp_is_closed_device()) {
|
||||
/* Closed chip mandates authentication */
|
||||
ERROR("Secure chip: TRUSTED_BOARD_BOOT must be enabled\n");
|
||||
panic();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (fixed_regulator_register() != 0) {
|
||||
panic();
|
||||
}
|
||||
|
||||
if (dt_pmic_status() > 0) {
|
||||
initialize_pmic();
|
||||
if (pmic_voltages_init() != 0) {
|
||||
ERROR("PMIC voltages init failed\n");
|
||||
panic();
|
||||
}
|
||||
print_pmic_info_and_debug();
|
||||
}
|
||||
|
||||
stm32mp1_syscfg_init();
|
||||
|
||||
if (stm32_iwdg_init() < 0) {
|
||||
panic();
|
||||
}
|
||||
|
||||
stm32_iwdg_refresh();
|
||||
|
||||
if (bsec_read_debug_conf() != 0U) {
|
||||
if (stm32mp_is_closed_device()) {
|
||||
#if DEBUG
|
||||
WARN("\n%s", debug_msg);
|
||||
#else
|
||||
ERROR("***Debug opened on closed chip***\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if STM32MP13
|
||||
if (stm32_rng_init() != 0) {
|
||||
panic();
|
||||
}
|
||||
#endif
|
||||
|
||||
stm32mp1_arch_security_setup();
|
||||
|
||||
print_reset_reason();
|
||||
|
||||
#if STM32MP15
|
||||
update_monotonic_counter();
|
||||
#endif
|
||||
|
||||
stm32mp1_syscfg_enable_io_compensation_finish();
|
||||
|
||||
fconf_populate("TB_FW", STM32MP_DTB_BASE);
|
||||
|
||||
stm32mp_io_setup();
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* This function can be used by the platforms to update/use image
|
||||
* information for given `image_id`.
|
||||
******************************************************************************/
|
||||
int bl2_plat_handle_post_image_load(unsigned int image_id)
|
||||
{
|
||||
int err = 0;
|
||||
bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(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;
|
||||
const struct dyn_cfg_dtb_info_t *config_info;
|
||||
bl_mem_params_node_t *tos_fw_mem_params;
|
||||
unsigned int i;
|
||||
unsigned int idx;
|
||||
unsigned long long ddr_top __unused;
|
||||
const unsigned int image_ids[] = {
|
||||
BL32_IMAGE_ID,
|
||||
BL33_IMAGE_ID,
|
||||
HW_CONFIG_ID,
|
||||
TOS_FW_CONFIG_ID,
|
||||
};
|
||||
|
||||
assert(bl_mem_params != NULL);
|
||||
|
||||
switch (image_id) {
|
||||
case FW_CONFIG_ID:
|
||||
/* Set global DTB info for fixed fw_config information */
|
||||
set_config_info(STM32MP_FW_CONFIG_BASE, ~0UL, STM32MP_FW_CONFIG_MAX_SIZE,
|
||||
FW_CONFIG_ID);
|
||||
fconf_populate("FW_CONFIG", STM32MP_FW_CONFIG_BASE);
|
||||
|
||||
idx = dyn_cfg_dtb_info_get_index(TOS_FW_CONFIG_ID);
|
||||
|
||||
/* Iterate through all the fw config IDs */
|
||||
for (i = 0U; i < ARRAY_SIZE(image_ids); i++) {
|
||||
if ((image_ids[i] == TOS_FW_CONFIG_ID) && (idx == FCONF_INVALID_IDX)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bl_mem_params = get_bl_mem_params_node(image_ids[i]);
|
||||
assert(bl_mem_params != NULL);
|
||||
|
||||
config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, image_ids[i]);
|
||||
if (config_info == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bl_mem_params->image_info.image_base = config_info->config_addr;
|
||||
bl_mem_params->image_info.image_max_size = config_info->config_max_size;
|
||||
|
||||
bl_mem_params->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING;
|
||||
|
||||
switch (image_ids[i]) {
|
||||
case BL32_IMAGE_ID:
|
||||
bl_mem_params->ep_info.pc = config_info->config_addr;
|
||||
|
||||
/* In case of OPTEE, initialize address space with tos_fw addr */
|
||||
pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
|
||||
assert(pager_mem_params != NULL);
|
||||
pager_mem_params->image_info.image_base = config_info->config_addr;
|
||||
pager_mem_params->image_info.image_max_size =
|
||||
config_info->config_max_size;
|
||||
|
||||
/* Init base and size for pager if exist */
|
||||
paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
|
||||
if (paged_mem_params != NULL) {
|
||||
paged_mem_params->image_info.image_base = STM32MP_DDR_BASE +
|
||||
(dt_get_ddr_size() - STM32MP_DDR_S_SIZE -
|
||||
STM32MP_DDR_SHMEM_SIZE);
|
||||
paged_mem_params->image_info.image_max_size =
|
||||
STM32MP_DDR_S_SIZE;
|
||||
}
|
||||
break;
|
||||
|
||||
case BL33_IMAGE_ID:
|
||||
bl_mem_params->ep_info.pc = config_info->config_addr;
|
||||
break;
|
||||
|
||||
case HW_CONFIG_ID:
|
||||
case TOS_FW_CONFIG_ID:
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case BL32_IMAGE_ID:
|
||||
if (optee_header_is_valid(bl_mem_params->image_info.image_base)) {
|
||||
image_info_t *paged_image_info = NULL;
|
||||
|
||||
/* BL32 is OP-TEE header */
|
||||
bl_mem_params->ep_info.pc = bl_mem_params->image_info.image_base;
|
||||
pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
|
||||
assert(pager_mem_params != NULL);
|
||||
|
||||
paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
|
||||
if (paged_mem_params != NULL) {
|
||||
paged_image_info = &paged_mem_params->image_info;
|
||||
}
|
||||
|
||||
err = parse_optee_header(&bl_mem_params->ep_info,
|
||||
&pager_mem_params->image_info,
|
||||
paged_image_info);
|
||||
if (err != 0) {
|
||||
ERROR("OPTEE header parse error.\n");
|
||||
panic();
|
||||
}
|
||||
|
||||
/* Set optee boot info from parsed header data */
|
||||
if (paged_mem_params != NULL) {
|
||||
bl_mem_params->ep_info.args.arg0 =
|
||||
paged_mem_params->image_info.image_base;
|
||||
} else {
|
||||
bl_mem_params->ep_info.args.arg0 = 0U;
|
||||
}
|
||||
|
||||
bl_mem_params->ep_info.args.arg1 = 0U; /* Unused */
|
||||
bl_mem_params->ep_info.args.arg2 = 0U; /* No DT supported */
|
||||
} else {
|
||||
bl_mem_params->ep_info.pc = bl_mem_params->image_info.image_base;
|
||||
tos_fw_mem_params = get_bl_mem_params_node(TOS_FW_CONFIG_ID);
|
||||
assert(tos_fw_mem_params != NULL);
|
||||
bl_mem_params->image_info.image_max_size +=
|
||||
tos_fw_mem_params->image_info.image_max_size;
|
||||
bl_mem_params->ep_info.args.arg0 = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case BL33_IMAGE_ID:
|
||||
bl32_mem_params = get_bl_mem_params_node(BL32_IMAGE_ID);
|
||||
assert(bl32_mem_params != NULL);
|
||||
bl32_mem_params->ep_info.lr_svc = bl_mem_params->ep_info.pc;
|
||||
#if PSA_FWU_SUPPORT
|
||||
stm32mp1_fwu_set_boot_idx();
|
||||
#endif /* PSA_FWU_SUPPORT */
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Do nothing in default case */
|
||||
break;
|
||||
}
|
||||
|
||||
#if STM32MP_SDMMC || STM32MP_EMMC
|
||||
/*
|
||||
* Invalidate remaining data read from MMC but not flushed by load_image_flush().
|
||||
* We take the worst case which is 2 MMC blocks.
|
||||
*/
|
||||
if ((image_id != FW_CONFIG_ID) &&
|
||||
((bl_mem_params->image_info.h.attr & IMAGE_ATTRIB_SKIP_LOADING) == 0U)) {
|
||||
inv_dcache_range(bl_mem_params->image_info.image_base +
|
||||
bl_mem_params->image_info.image_size,
|
||||
2U * MMC_BLOCK_SIZE);
|
||||
}
|
||||
#endif /* STM32MP_SDMMC || STM32MP_EMMC */
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void bl2_el3_plat_prepare_exit(void)
|
||||
{
|
||||
uint16_t boot_itf = stm32mp_get_boot_itf_selected();
|
||||
|
||||
switch (boot_itf) {
|
||||
#if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER
|
||||
case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART:
|
||||
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 /* STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER */
|
||||
default:
|
||||
/* Do nothing in default case */
|
||||
break;
|
||||
}
|
||||
|
||||
stm32mp1_security_setup();
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#
|
||||
# Copyright (c) 2022, STMicroelectronics - All Rights Reserved
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
|
||||
# Override TBBR Cert to update generic certificate
|
||||
|
||||
$(eval $(call add_define,PDEF_CERTS))
|
||||
|
||||
PLAT_INCLUDE += -I${PLAT_DIR}include
|
||||
|
||||
src/stm32mp1_tbb_cert.o: ${PLAT_DIR}stm32mp1_tbb_cert.c
|
||||
${Q}${HOSTCC} -c ${HOSTCCFLAGS} ${INC_DIR} $< -o $@
|
||||
|
||||
PLAT_OBJECTS = src/stm32mp1_tbb_cert.o
|
||||
|
||||
OBJECTS += $(PLAT_OBJECTS)
|
||||
|
||||
@@ -0,0 +1,409 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2022, STMicroelectronics - All Rights Reserved
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef BOOT_API_H
|
||||
#define BOOT_API_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* Possible value of boot context field 'auth_status'
|
||||
*/
|
||||
#if STM32MP13
|
||||
/* No authentication done */
|
||||
#define BOOT_API_CTX_AUTH_NO 0x7CFDD351U
|
||||
/* Authentication done and failed */
|
||||
#define BOOT_API_CTX_AUTH_FAILED 0x51330884U
|
||||
/* Authentication done and success */
|
||||
#define BOOT_API_CTX_AUTH_SUCCESS 0x67E8CAE1U
|
||||
#endif
|
||||
#if STM32MP15
|
||||
/* No authentication done */
|
||||
#define BOOT_API_CTX_AUTH_NO 0x0U
|
||||
/* Authentication done and failed */
|
||||
#define BOOT_API_CTX_AUTH_FAILED 0x1U
|
||||
/* Authentication done and succeeded */
|
||||
#define BOOT_API_CTX_AUTH_SUCCESS 0x2U
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Possible value of boot context field 'boot_interface_sel'
|
||||
*/
|
||||
|
||||
/* Value of field 'boot_interface_sel' when no boot occurred */
|
||||
#define BOOT_API_CTX_BOOT_INTERFACE_SEL_NO 0x0U
|
||||
|
||||
/* Boot occurred on SD */
|
||||
#define BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD 0x1U
|
||||
|
||||
/* Boot occurred on EMMC */
|
||||
#define BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC 0x2U
|
||||
|
||||
/* Boot occurred on FMC */
|
||||
#define BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC 0x3U
|
||||
|
||||
/* Boot occurred on QSPI NOR */
|
||||
#define BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI 0x4U
|
||||
|
||||
/* Boot occurred on UART */
|
||||
#define BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART 0x5U
|
||||
|
||||
/* 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
|
||||
|
||||
/**
|
||||
* @brief Possible value of boot context field 'EmmcXferStatus'
|
||||
*/
|
||||
/*
|
||||
* Possible value of boot context field 'emmc_xfer_status'
|
||||
*/
|
||||
#define BOOT_API_CTX_EMMC_XFER_STATUS_NOT_STARTED 0x0U
|
||||
#define BOOT_API_CTX_EMMC_XFER_STATUS_DATAEND_DETECTED 0x1U
|
||||
#define BOOT_API_CTX_EMMC_XFER_STATUS_XFER_OVERALL_TIMEOUT_DETECTED 0x2U
|
||||
#define BOOT_API_CTX_EMMC_XFER_STATUS_XFER_DATA_TIMEOUT 0x3U
|
||||
|
||||
/*
|
||||
* Possible value of boot context field 'emmc_error_status'
|
||||
*/
|
||||
#define BOOT_API_CTX_EMMC_ERROR_STATUS_NONE 0x0U
|
||||
#define BOOT_API_CTX_EMMC_ERROR_STATUS_CMD_TIMEOUT 0x1U
|
||||
#define BOOT_API_CTX_EMMC_ERROR_STATUS_ACK_TIMEOUT 0x2U
|
||||
#define BOOT_API_CTX_EMMC_ERROR_STATUS_DATA_CRC_FAIL 0x3U
|
||||
#define BOOT_API_CTX_EMMC_ERROR_STATUS_NOT_ENOUGH_BOOT_DATA_RX 0x4U
|
||||
#define BOOT_API_CTX_EMMC_ERROR_STATUS_HEADER_NOT_FOUND 0x5U
|
||||
#define BOOT_API_CTX_EMMC_ERROR_STATUS_HEADER_SIZE_ZERO 0x6U
|
||||
#define BOOT_API_CTX_EMMC_ERROR_STATUS_IMAGE_NOT_COMPLETE 0x7U
|
||||
#define BOOT_API_CTX_EMMC_ERROR_STATUS_ACK_ERROR 0x8U
|
||||
|
||||
/* Image Header related definitions */
|
||||
|
||||
/* Definition of header version */
|
||||
#if STM32MP13
|
||||
#define BOOT_API_HEADER_VERSION 0x00020000U
|
||||
#endif
|
||||
#if STM32MP15
|
||||
#define BOOT_API_HEADER_VERSION 0x00010000U
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Magic number used to detect header in memory
|
||||
* Its value must be 'S' 'T' 'M' 0x32, i.e 0x324D5453 as field
|
||||
* 'bootapi_image_header_t.magic'
|
||||
* This identifies the start of a boot image.
|
||||
*/
|
||||
#define BOOT_API_IMAGE_HEADER_MAGIC_NB 0x324D5453U
|
||||
|
||||
/* Definitions related to Authentication used in image header structure */
|
||||
#define BOOT_API_ECDSA_PUB_KEY_LEN_IN_BYTES 64
|
||||
#define BOOT_API_ECDSA_SIGNATURE_LEN_IN_BYTES 64
|
||||
#define BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES 32
|
||||
|
||||
/* Possible values of the field 'boot_api_image_header_t.ecc_algo_type' */
|
||||
#define BOOT_API_ECDSA_ALGO_TYPE_P256NIST 1
|
||||
#define BOOT_API_ECDSA_ALGO_TYPE_BRAINPOOL256 2
|
||||
|
||||
/*
|
||||
* Extension headers related definitions
|
||||
*/
|
||||
/* 'bootapi_image_header_t.extension_flag' used for authentication feature */
|
||||
#define BOOT_API_AUTHENTICATION_EXTENSION_BIT BIT(0)
|
||||
/* 'bootapi_image_header_t.extension_flag' used for FSBL decryption feature */
|
||||
#define BOOT_API_FSBL_DECRYPTION_EXTENSION_BIT BIT(1)
|
||||
/* 'bootapi_image_header_t.extension_flag' used for padding header feature */
|
||||
#define BOOT_API_PADDING_EXTENSION_BIT BIT(31)
|
||||
/*
|
||||
* mask of bits of field 'bootapi_image_header_t.extension_flag'
|
||||
* used for extension headers
|
||||
*/
|
||||
#define BOOT_API_ALL_EXTENSIONS_MASK \
|
||||
(BOOT_API_AUTHENTICATION_EXTENSION_BIT | \
|
||||
BOOT_API_FSBL_DECRYPTION_EXTENSION_BIT | \
|
||||
BOOT_API_PADDING_EXTENSION_BIT)
|
||||
/*
|
||||
* Magic number of FSBL decryption extension header
|
||||
* The value shall gives the four bytes 'S','T',0x00,0x01 in memory
|
||||
*/
|
||||
#define BOOT_API_FSBL_DECRYPTION_HEADER_MAGIC_NB 0x01005453U
|
||||
|
||||
/*
|
||||
* Magic number of PKH revocation extension header
|
||||
* The value shall gives the four bytes 'S','T',0x00,0x02 in memory
|
||||
*/
|
||||
#define BOOT_API_AUTHENTICATION_HEADER_MAGIC_NB 0x02005453U
|
||||
|
||||
/* Max number of ECDSA public key hash in table */
|
||||
#define BOOT_API_AUTHENTICATION_NB_PKH_MAX 8U
|
||||
|
||||
/* ECDSA public key hash table size in bytes */
|
||||
#define BOOT_API_AUTHENTICATION_TABLE_SIZE_BYTES \
|
||||
(BOOT_API_AUTHENTICATION_NB_PKH_MAX * \
|
||||
BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES)
|
||||
|
||||
/*
|
||||
* Magic number of padding extension header
|
||||
* The value shall gives the four bytes 'S','T',0xFF,0xFF in memory
|
||||
*/
|
||||
#define BOOT_API_PADDING_HEADER_MAGIC_NB 0xFFFF5453U
|
||||
|
||||
/*
|
||||
* Cores secure magic numbers
|
||||
* Constant to be stored in bakcup register
|
||||
* BOOT_API_MAGIC_NUMBER_TAMP_BCK_REG_IDX
|
||||
*/
|
||||
#define BOOT_API_A7_CORE0_MAGIC_NUMBER 0xCA7FACE0U
|
||||
#define BOOT_API_A7_CORE1_MAGIC_NUMBER 0xCA7FACE1U
|
||||
|
||||
/*
|
||||
* TAMP_BCK4R register index
|
||||
* This register is used to write a Magic Number in order to restart
|
||||
* Cortex A7 Core 1 and make it execute @ branch address from TAMP_BCK5R
|
||||
*/
|
||||
#define BOOT_API_CORE1_MAGIC_NUMBER_TAMP_BCK_REG_IDX 4U
|
||||
|
||||
/*
|
||||
* TAMP_BCK5R register index
|
||||
* This register is used to contain the branch address of
|
||||
* Cortex A7 Core 1 when restarted by a TAMP_BCK4R magic number writing
|
||||
*/
|
||||
#define BOOT_API_CORE1_BRANCH_ADDRESS_TAMP_BCK_REG_IDX 5U
|
||||
|
||||
/*
|
||||
* Possible value of boot context field 'hse_clock_value_in_hz'
|
||||
*/
|
||||
#define BOOT_API_CTX_HSE_CLOCK_VALUE_UNDEFINED 0U
|
||||
#define BOOT_API_CTX_HSE_CLOCK_VALUE_24_MHZ 24000000U
|
||||
#define BOOT_API_CTX_HSE_CLOCK_VALUE_25_MHZ 25000000U
|
||||
#define BOOT_API_CTX_HSE_CLOCK_VALUE_26_MHZ 26000000U
|
||||
|
||||
/*
|
||||
* Possible value of boot context field 'boot_partition_used_toboot'
|
||||
*/
|
||||
#define BOOT_API_CTX_BOOT_PARTITION_UNDEFINED 0U
|
||||
|
||||
/* Used FSBL1 to boot */
|
||||
#define BOOT_API_CTX_BOOT_PARTITION_FSBL1 1U
|
||||
|
||||
/* Used FSBL2 to boot */
|
||||
#define BOOT_API_CTX_BOOT_PARTITION_FSBL2 2U
|
||||
|
||||
/* OTP_CFG0 */
|
||||
#define BOOT_API_OTP_MODE_WORD_NB 0
|
||||
/* Closed = OTP_CFG0[6] */
|
||||
#define BOOT_API_OTP_MODE_CLOSED_BIT_POS 6
|
||||
|
||||
#define BOOT_API_RETURN_OK 0x77U
|
||||
|
||||
/*
|
||||
* Boot Context related definitions
|
||||
*/
|
||||
|
||||
/*
|
||||
* Boot core boot configuration structure
|
||||
* Specifies all items of the cold boot configuration
|
||||
* Memory and peripheral part.
|
||||
*/
|
||||
typedef struct {
|
||||
/*
|
||||
* Boot interface used to boot : take values from defines
|
||||
* BOOT_API_CTX_BOOT_INTERFACE_SEL_XXX above
|
||||
*/
|
||||
uint16_t boot_interface_selected;
|
||||
uint16_t boot_interface_instance;
|
||||
#if STM32MP13
|
||||
uint32_t reserved1[12];
|
||||
#endif
|
||||
#if STM32MP15
|
||||
uint32_t reserved1[13];
|
||||
#endif
|
||||
uint32_t otp_afmux_values[3];
|
||||
uint32_t reserved[3];
|
||||
#if STM32MP15
|
||||
uint32_t reserved2[2];
|
||||
#endif
|
||||
uint32_t auth_status;
|
||||
|
||||
#if STM32MP15
|
||||
/*
|
||||
* Pointers to bootROM External Secure Services
|
||||
* - ECDSA verify signature
|
||||
*/
|
||||
uint32_t reserved3;
|
||||
uint32_t (*bootrom_ecdsa_verify_signature)(uint8_t *hash_in,
|
||||
uint8_t *pubkey_in,
|
||||
uint8_t *signature,
|
||||
uint32_t ecc_algo);
|
||||
uint32_t reserved4;
|
||||
#endif
|
||||
/*
|
||||
* Information specific to an SD boot
|
||||
* Updated each time an SD boot is at least attempted,
|
||||
* even if not successful
|
||||
* Note : This is useful to understand why an SD boot failed
|
||||
* in particular
|
||||
*/
|
||||
uint32_t sd_err_internal_timeout_cnt;
|
||||
uint32_t sd_err_dcrc_fail_cnt;
|
||||
uint32_t sd_err_dtimeout_cnt;
|
||||
uint32_t sd_err_ctimeout_cnt;
|
||||
uint32_t sd_err_ccrc_fail_cnt;
|
||||
uint32_t sd_overall_retry_cnt;
|
||||
/*
|
||||
* Information specific to an eMMC boot
|
||||
* Updated each time an eMMC boot is at least attempted,
|
||||
* even if not successful
|
||||
* Note : This is useful to understand why an eMMC boot failed
|
||||
* in particular
|
||||
*/
|
||||
uint32_t emmc_xfer_status;
|
||||
uint32_t emmc_error_status;
|
||||
uint32_t emmc_nbbytes_rxcopied_tosysram_download_area;
|
||||
uint32_t hse_clock_value_in_hz;
|
||||
/*
|
||||
* Boot partition :
|
||||
* ie FSBL partition on which the boot was successful
|
||||
*/
|
||||
uint32_t boot_partition_used_toboot;
|
||||
|
||||
} __packed boot_api_context_t;
|
||||
|
||||
/*
|
||||
* Image Header related definitions
|
||||
*/
|
||||
|
||||
/*
|
||||
* Structure used to define the common Header format used for FSBL, xloader,
|
||||
* ... and in particular used by bootROM for FSBL header readout.
|
||||
* FSBL header size is 256 Bytes = 0x100
|
||||
*/
|
||||
typedef struct {
|
||||
/* BOOT_API_IMAGE_HEADER_MAGIC_NB */
|
||||
uint32_t magic;
|
||||
uint8_t image_signature[BOOT_API_ECDSA_SIGNATURE_LEN_IN_BYTES];
|
||||
/*
|
||||
* Checksum of payload
|
||||
* 32-bit sum all payload bytes considered as 8 bit unsigned
|
||||
* numbers, discarding any overflow bits.
|
||||
* Use to check UART/USB downloaded image integrity when signature
|
||||
* is not used
|
||||
*/
|
||||
uint32_t payload_checksum;
|
||||
/* Image header version : should have value BOOT_API_HEADER_VERSION */
|
||||
uint32_t header_version;
|
||||
/* Image length in bytes */
|
||||
uint32_t image_length;
|
||||
/*
|
||||
* Image Entry point address : should be in the SYSRAM area
|
||||
* and at least within the download area range
|
||||
*/
|
||||
uint32_t image_entry_point;
|
||||
/* Reserved */
|
||||
uint32_t reserved1;
|
||||
/*
|
||||
* Image load address : not used by bootROM but to be consistent
|
||||
* with header format for other packages (xloader, ...)
|
||||
*/
|
||||
uint32_t load_address;
|
||||
/* Reserved */
|
||||
uint32_t reserved2;
|
||||
/* Image version to be compared by bootROM with monotonic
|
||||
* counter value in OTP_CFG4 prior executing the downloaded image
|
||||
*/
|
||||
uint32_t image_version;
|
||||
|
||||
#if STM32MP13
|
||||
/*
|
||||
* Extension flags :
|
||||
*
|
||||
* Bit 0 : Authentication extension header
|
||||
* value 0 : No signature check request
|
||||
* Bit 1 : Encryption extension header
|
||||
* Bit 2 : Padding extension header
|
||||
*/
|
||||
uint32_t extension_flags;
|
||||
/* Length in bytes of all extension headers */
|
||||
uint32_t extension_headers_length;
|
||||
/* Add binary type information */
|
||||
uint32_t binary_type;
|
||||
/* Pad up to 128 byte total size */
|
||||
uint8_t pad[16];
|
||||
/* Followed by extension header */
|
||||
uint8_t ext_header[];
|
||||
#endif
|
||||
#if STM32MP15
|
||||
/*
|
||||
* Option flags:
|
||||
* Bit 0 : No signature check request : 'No_sig_check'
|
||||
* value 1 : for No signature check request
|
||||
* value 0 : No request to bypass the signature check
|
||||
* Note : No signature check is never allowed on a Secured chip
|
||||
*/
|
||||
uint32_t option_flags;
|
||||
/*
|
||||
* Type of ECC algorithm to use :
|
||||
* value 1 : for P-256 NIST algorithm
|
||||
* value 2 : for Brainpool 256 algorithm
|
||||
* See definitions 'BOOT_API_ECDSA_ALGO_TYPE_XXX' above.
|
||||
*/
|
||||
uint32_t ecc_algo_type;
|
||||
/*
|
||||
* OEM ECC Public Key (aka Root pubk) provided in header on 512 bits.
|
||||
* The SHA-256 hash of the OEM ECC pubk must match the one stored
|
||||
* in OTP cells.
|
||||
*/
|
||||
uint8_t ecc_pubk[BOOT_API_ECDSA_PUB_KEY_LEN_IN_BYTES];
|
||||
/* Pad up to 256 byte total size */
|
||||
uint8_t pad[83];
|
||||
/* Add binary type information */
|
||||
uint8_t binary_type;
|
||||
#endif
|
||||
} __packed boot_api_image_header_t;
|
||||
|
||||
typedef uint8_t boot_api_sha256_t[BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES];
|
||||
|
||||
typedef struct {
|
||||
/* Extension header type:
|
||||
* BOOT_API_FSBL_DECRYPTION_HEADER_MAGIC_NB or
|
||||
* BOOT_API_AUTHENTICATION_HEADER_MAGIC_NB
|
||||
* BOOT_API_PADDING_HEADER_MAGIC_NB
|
||||
*/
|
||||
uint32_t type;
|
||||
/* Extension header len in byte */
|
||||
uint32_t len;
|
||||
/* parameters of this extension */
|
||||
uint8_t params[];
|
||||
} __packed boot_extension_header_t;
|
||||
|
||||
typedef struct {
|
||||
/* Idx of ECDSA public key to be used in table */
|
||||
uint32_t pk_idx;
|
||||
/* Number of ECDSA public key in table */
|
||||
uint32_t nb_pk;
|
||||
/*
|
||||
* Type of ECC algorithm to use :
|
||||
* value 1 : for P-256 NIST algorithm
|
||||
* value 2 : for Brainpool 256 algorithm
|
||||
* See definitions 'BOOT_API_ECDSA_ALGO_TYPE_XXX' above.
|
||||
*/
|
||||
uint32_t ecc_algo_type;
|
||||
/* ECDSA public key to be used to check signature. */
|
||||
uint8_t ecc_pubk[BOOT_API_ECDSA_PUB_KEY_LEN_IN_BYTES];
|
||||
/* table of Hash of Algo+ECDSA public key */
|
||||
boot_api_sha256_t pk_hashes[];
|
||||
} __packed boot_ext_header_params_authentication_t;
|
||||
|
||||
typedef struct {
|
||||
/* Size of encryption key (128 or 256) */
|
||||
uint32_t key_size;
|
||||
uint32_t derivation_cont;
|
||||
/* 128 msb bits of plain payload SHA256 */
|
||||
uint32_t hash[4];
|
||||
} __packed boot_ext_header_params_encrypted_fsbl_t;
|
||||
|
||||
#endif /* BOOT_API_H */
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef PLAT_DEF_FIP_UUID_H
|
||||
#define PLAT_DEF_FIP_UUID_H
|
||||
|
||||
#define UUID_STM32MP_CONFIG_CERT \
|
||||
{{0x50, 0x1d, 0x8d, 0xd2}, {0x8b, 0xce}, {0x49, 0xa5}, 0x84, 0xeb, \
|
||||
{0x55, 0x9a, 0x9f, 0x2e, 0xae, 0xaf} }
|
||||
#endif /* PLAT_DEF_FIP_UUID_H */
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2022, STMicroelectronics - All Rights Reserved
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef STM32MP1_IMG_DEF_H
|
||||
#define STM32MP1_IMG_DEF_H
|
||||
|
||||
#include <export/common/tbbr/tbbr_img_def_exp.h>
|
||||
|
||||
/* Undef the existing values */
|
||||
#undef BL32_EXTRA1_IMAGE_ID
|
||||
#undef BL32_EXTRA2_IMAGE_ID
|
||||
#undef TOS_FW_CONFIG_ID
|
||||
#undef TRUSTED_BOOT_FW_CERT_ID
|
||||
#undef FWU_METADATA_IMAGE_ID
|
||||
#undef BKUP_FWU_METADATA_IMAGE_ID
|
||||
#undef FW_CONFIG_ID
|
||||
#undef HW_CONFIG_ID
|
||||
#undef GPT_IMAGE_ID
|
||||
#undef ENC_IMAGE_ID
|
||||
|
||||
/* Define the STM32MP1 used ID */
|
||||
#define FW_CONFIG_ID U(1)
|
||||
#define HW_CONFIG_ID U(2)
|
||||
#define GPT_IMAGE_ID U(3)
|
||||
#define ENC_IMAGE_ID U(6)
|
||||
#define BL32_EXTRA1_IMAGE_ID U(8)
|
||||
#define BL32_EXTRA2_IMAGE_ID U(9)
|
||||
#define FWU_METADATA_IMAGE_ID U(12)
|
||||
#define BKUP_FWU_METADATA_IMAGE_ID U(13)
|
||||
#define TOS_FW_CONFIG_ID U(16)
|
||||
#define STM32MP_CONFIG_CERT_ID U(17)
|
||||
|
||||
/* Increase the MAX_NUMBER_IDS to match the authentication pool required */
|
||||
#define MAX_NUMBER_IDS U(19)
|
||||
|
||||
#endif /* STM32MP1_IMG_DEF_H */
|
||||
+218
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef PLATFORM_DEF_H
|
||||
#define PLATFORM_DEF_H
|
||||
|
||||
#include <arch.h>
|
||||
#include <drivers/arm/gic_common.h>
|
||||
#include <lib/utils_def.h>
|
||||
#include <plat/common/common_def.h>
|
||||
|
||||
#include "../stm32mp1_def.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Generic platform constants
|
||||
******************************************************************************/
|
||||
|
||||
/* Size of cacheable stacks */
|
||||
#if defined(IMAGE_BL32)
|
||||
#define PLATFORM_STACK_SIZE 0x600
|
||||
#else
|
||||
#define PLATFORM_STACK_SIZE 0xC00
|
||||
#endif
|
||||
|
||||
#define FIP_IMAGE_NAME "fip"
|
||||
#define METADATA_PART_1 "metadata1"
|
||||
#define METADATA_PART_2 "metadata2"
|
||||
|
||||
#define STM32MP_PRIMARY_CPU U(0x0)
|
||||
#define STM32MP_SECONDARY_CPU U(0x1)
|
||||
|
||||
#define PLATFORM_CLUSTER_COUNT U(1)
|
||||
#define PLATFORM_CLUSTER0_CORE_COUNT U(2)
|
||||
#define PLATFORM_CLUSTER1_CORE_COUNT U(0)
|
||||
#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER1_CORE_COUNT + \
|
||||
PLATFORM_CLUSTER0_CORE_COUNT)
|
||||
#define PLATFORM_MAX_CPUS_PER_CLUSTER 2
|
||||
|
||||
#define MAX_IO_DEVICES U(4)
|
||||
#define MAX_IO_HANDLES U(4)
|
||||
#define MAX_IO_BLOCK_DEVICES U(1)
|
||||
#define MAX_IO_MTD_DEVICES U(1)
|
||||
|
||||
/*******************************************************************************
|
||||
* BL2 specific defines.
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Put BL2 just below BL3-1. BL2_BASE is calculated using the current BL2 debug
|
||||
* size plus a little space for growth.
|
||||
*/
|
||||
#define BL2_BASE STM32MP_BL2_BASE
|
||||
#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)
|
||||
/*******************************************************************************
|
||||
* BL32 specific defines.
|
||||
******************************************************************************/
|
||||
#if defined(IMAGE_BL32)
|
||||
#if ENABLE_PIE
|
||||
#define BL32_BASE 0
|
||||
#define BL32_LIMIT STM32MP_BL32_SIZE
|
||||
#else
|
||||
#define BL32_BASE STM32MP_BL32_BASE
|
||||
#define BL32_LIMIT (STM32MP_BL32_BASE + \
|
||||
STM32MP_BL32_SIZE)
|
||||
#endif
|
||||
#endif /* defined(IMAGE_BL32) */
|
||||
|
||||
/*******************************************************************************
|
||||
* BL33 specific defines.
|
||||
******************************************************************************/
|
||||
#define BL33_BASE STM32MP_BL33_BASE
|
||||
|
||||
/*
|
||||
* Load address of BL33 for this platform port
|
||||
*/
|
||||
#define PLAT_STM32MP_NS_IMAGE_OFFSET BL33_BASE
|
||||
|
||||
/* Needed by STM32CubeProgrammer support */
|
||||
#define DWL_BUFFER_SIZE U(0x01000000)
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
#define PLAT_EMMC_BOOT_SSBL_OFFSET U(0x40000)
|
||||
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
******************************************************************************/
|
||||
#define PLAT_PHY_ADDR_SPACE_SIZE (ULL(1) << 32)
|
||||
#define PLAT_VIRT_ADDR_SPACE_SIZE (ULL(1) << 32)
|
||||
|
||||
/*******************************************************************************
|
||||
* Declarations and constants to access the mailboxes safely. Each mailbox is
|
||||
* aligned on the biggest cache line size in the platform. This is known only
|
||||
* to the platform as it might have a combination of integrated and external
|
||||
* caches. Such alignment ensures that two maiboxes do not sit on the same cache
|
||||
* line at any cache level. They could belong to different cpus/clusters &
|
||||
* get written while being protected by different locks causing corruption of
|
||||
* a valid mailbox address.
|
||||
******************************************************************************/
|
||||
#define CACHE_WRITEBACK_SHIFT 6
|
||||
#define CACHE_WRITEBACK_GRANULE (U(1) << CACHE_WRITEBACK_SHIFT)
|
||||
|
||||
/*
|
||||
* Secure Interrupt: based on the standard ARM mapping
|
||||
*/
|
||||
#define ARM_IRQ_SEC_PHY_TIMER U(29)
|
||||
|
||||
#define ARM_IRQ_SEC_SGI_0 U(8)
|
||||
#define ARM_IRQ_SEC_SGI_1 U(9)
|
||||
#define ARM_IRQ_SEC_SGI_2 U(10)
|
||||
#define ARM_IRQ_SEC_SGI_3 U(11)
|
||||
#define ARM_IRQ_SEC_SGI_4 U(12)
|
||||
#define ARM_IRQ_SEC_SGI_5 U(13)
|
||||
#define ARM_IRQ_SEC_SGI_6 U(14)
|
||||
#define ARM_IRQ_SEC_SGI_7 U(15)
|
||||
|
||||
#define STM32MP1_IRQ_TZC400 U(36)
|
||||
#define STM32MP1_IRQ_TAMPSERRS U(229)
|
||||
#define STM32MP1_IRQ_AXIERRIRQ U(244)
|
||||
|
||||
/*
|
||||
* Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
|
||||
* terminology. On a GICv2 system or mode, the lists will be merged and treated
|
||||
* as Group 0 interrupts.
|
||||
*/
|
||||
#define PLATFORM_G1S_PROPS(grp) \
|
||||
INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER, \
|
||||
GIC_HIGHEST_SEC_PRIORITY, \
|
||||
grp, GIC_INTR_CFG_LEVEL), \
|
||||
INTR_PROP_DESC(STM32MP1_IRQ_AXIERRIRQ, \
|
||||
GIC_HIGHEST_SEC_PRIORITY, \
|
||||
grp, GIC_INTR_CFG_LEVEL), \
|
||||
INTR_PROP_DESC(STM32MP1_IRQ_TZC400, \
|
||||
GIC_HIGHEST_SEC_PRIORITY, \
|
||||
grp, GIC_INTR_CFG_LEVEL), \
|
||||
INTR_PROP_DESC(ARM_IRQ_SEC_SGI_1, \
|
||||
GIC_HIGHEST_SEC_PRIORITY, \
|
||||
grp, GIC_INTR_CFG_EDGE), \
|
||||
INTR_PROP_DESC(ARM_IRQ_SEC_SGI_2, \
|
||||
GIC_HIGHEST_SEC_PRIORITY, \
|
||||
grp, GIC_INTR_CFG_EDGE), \
|
||||
INTR_PROP_DESC(ARM_IRQ_SEC_SGI_3, \
|
||||
GIC_HIGHEST_SEC_PRIORITY, \
|
||||
grp, GIC_INTR_CFG_EDGE), \
|
||||
INTR_PROP_DESC(ARM_IRQ_SEC_SGI_4, \
|
||||
GIC_HIGHEST_SEC_PRIORITY, \
|
||||
grp, GIC_INTR_CFG_EDGE), \
|
||||
INTR_PROP_DESC(ARM_IRQ_SEC_SGI_5, \
|
||||
GIC_HIGHEST_SEC_PRIORITY, \
|
||||
grp, GIC_INTR_CFG_EDGE), \
|
||||
INTR_PROP_DESC(ARM_IRQ_SEC_SGI_7, \
|
||||
GIC_HIGHEST_SEC_PRIORITY, \
|
||||
grp, GIC_INTR_CFG_EDGE)
|
||||
|
||||
#define PLATFORM_G0_PROPS(grp) \
|
||||
INTR_PROP_DESC(ARM_IRQ_SEC_SGI_0, \
|
||||
GIC_HIGHEST_SEC_PRIORITY, \
|
||||
grp, GIC_INTR_CFG_EDGE), \
|
||||
INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, \
|
||||
GIC_HIGHEST_SEC_PRIORITY, \
|
||||
grp, GIC_INTR_CFG_EDGE)
|
||||
|
||||
/*
|
||||
* Power
|
||||
*/
|
||||
#define PLAT_MAX_PWR_LVL U(1)
|
||||
|
||||
/* Local power state for power domains in Run state. */
|
||||
#define ARM_LOCAL_STATE_RUN U(0)
|
||||
/* Local power state for retention. Valid only for CPU power domains */
|
||||
#define ARM_LOCAL_STATE_RET U(1)
|
||||
/* Local power state for power-down. Valid for CPU and cluster power domains */
|
||||
#define ARM_LOCAL_STATE_OFF U(2)
|
||||
/*
|
||||
* This macro defines the deepest retention state possible.
|
||||
* A higher state id will represent an invalid or a power down state.
|
||||
*/
|
||||
#define PLAT_MAX_RET_STATE ARM_LOCAL_STATE_RET
|
||||
/*
|
||||
* This macro defines the deepest power down states possible. Any state ID
|
||||
* higher than this is invalid.
|
||||
*/
|
||||
#define PLAT_MAX_OFF_STATE ARM_LOCAL_STATE_OFF
|
||||
|
||||
/*******************************************************************************
|
||||
* Size of the per-cpu data in bytes that should be reserved in the generic
|
||||
* per-cpu data structure for the FVP port.
|
||||
******************************************************************************/
|
||||
#define PLAT_PCPU_DATA_SIZE 2
|
||||
|
||||
/*******************************************************************************
|
||||
* Number of parallel entry slots in SMT SCMI server entry context. For this
|
||||
* platform, SCMI server is reached through SMC only, hence the number of
|
||||
* entry slots.
|
||||
******************************************************************************/
|
||||
#define PLAT_SMT_ENTRY_COUNT PLATFORM_CORE_COUNT
|
||||
|
||||
#endif /* PLATFORM_DEF_H */
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2021, STMicroelectronics - All Rights Reserved
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef STM32MP1_DBGMCU_H
|
||||
#define STM32MP1_DBGMCU_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* Get chip version and ID from DBGMCU registers */
|
||||
int stm32mp1_dbgmcu_get_chip_version(uint32_t *chip_version);
|
||||
int stm32mp1_dbgmcu_get_chip_dev_id(uint32_t *chip_dev_id);
|
||||
|
||||
#endif /* STM32MP1_DBGMCU_H */
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (c) 2022, STMicroelectronics - All Rights Reserved
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef MBEDTLS_CONFIG_H
|
||||
#define MBEDTLS_CONFIG_H
|
||||
|
||||
/*
|
||||
* Key algorithms currently supported on mbed TLS libraries
|
||||
*/
|
||||
#define TF_MBEDTLS_USE_RSA 0
|
||||
#define TF_MBEDTLS_USE_ECDSA 1
|
||||
|
||||
/*
|
||||
* Hash algorithms currently supported on mbed TLS libraries
|
||||
*/
|
||||
#define TF_MBEDTLS_SHA256 1
|
||||
#define TF_MBEDTLS_SHA384 2
|
||||
#define TF_MBEDTLS_SHA512 3
|
||||
|
||||
/*
|
||||
* Configuration file to build mbed TLS with the required features for
|
||||
* Trusted Boot
|
||||
*/
|
||||
|
||||
#define MBEDTLS_PLATFORM_MEMORY
|
||||
#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
|
||||
/* Prevent mbed TLS from using snprintf so that it can use tf_snprintf. */
|
||||
#define MBEDTLS_PLATFORM_SNPRINTF_ALT
|
||||
|
||||
#define MBEDTLS_PKCS1_V21
|
||||
|
||||
#define MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
|
||||
#define MBEDTLS_X509_CHECK_KEY_USAGE
|
||||
#define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE
|
||||
|
||||
#define MBEDTLS_ASN1_PARSE_C
|
||||
#define MBEDTLS_ASN1_WRITE_C
|
||||
|
||||
#define MBEDTLS_BASE64_C
|
||||
#define MBEDTLS_BIGNUM_C
|
||||
|
||||
#define MBEDTLS_ERROR_C
|
||||
#define MBEDTLS_MD_C
|
||||
|
||||
#define MBEDTLS_MEMORY_BUFFER_ALLOC_C
|
||||
#define MBEDTLS_OID_C
|
||||
|
||||
#define MBEDTLS_PK_C
|
||||
#define MBEDTLS_PK_PARSE_C
|
||||
#define MBEDTLS_PK_WRITE_C
|
||||
|
||||
#define MBEDTLS_PLATFORM_C
|
||||
|
||||
#if TF_MBEDTLS_USE_ECDSA
|
||||
#define MBEDTLS_ECDSA_C
|
||||
#define MBEDTLS_ECP_C
|
||||
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||
#define MBEDTLS_ECP_NO_INTERNAL_RNG
|
||||
#endif
|
||||
#if TF_MBEDTLS_USE_RSA
|
||||
#define MBEDTLS_RSA_C
|
||||
#define MBEDTLS_X509_RSASSA_PSS_SUPPORT
|
||||
#endif
|
||||
|
||||
#define MBEDTLS_SHA256_C
|
||||
#if (TF_MBEDTLS_HASH_ALG_ID != TF_MBEDTLS_SHA256)
|
||||
#define MBEDTLS_SHA512_C
|
||||
#endif
|
||||
|
||||
#define MBEDTLS_VERSION_C
|
||||
|
||||
#define MBEDTLS_X509_USE_C
|
||||
#define MBEDTLS_X509_CRT_PARSE_C
|
||||
|
||||
#if TF_MBEDTLS_USE_AES_GCM
|
||||
#define MBEDTLS_AES_C
|
||||
#define MBEDTLS_CIPHER_C
|
||||
#define MBEDTLS_GCM_C
|
||||
#endif
|
||||
|
||||
/* MPI / BIGNUM options */
|
||||
#define MBEDTLS_MPI_WINDOW_SIZE 2
|
||||
|
||||
#if TF_MBEDTLS_USE_RSA
|
||||
#if TF_MBEDTLS_KEY_SIZE <= 2048
|
||||
#define MBEDTLS_MPI_MAX_SIZE 256
|
||||
#else
|
||||
#define MBEDTLS_MPI_MAX_SIZE 512
|
||||
#endif
|
||||
#else
|
||||
#define MBEDTLS_MPI_MAX_SIZE 256
|
||||
#endif
|
||||
|
||||
/* Memory buffer allocator options */
|
||||
#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 8
|
||||
|
||||
/*
|
||||
* Prevent the use of 128-bit division which
|
||||
* creates dependency on external libraries.
|
||||
*/
|
||||
#define MBEDTLS_NO_UDBL_DIVISION
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
/* System headers required to build mbed TLS with the current configuration */
|
||||
#include <stdlib.h>
|
||||
#include <mbedtls/check_config.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Mbed TLS heap size is smal as we only use the asn1
|
||||
* parsing functions
|
||||
* digest, signature and crypto algorithm are done by
|
||||
* other library.
|
||||
*/
|
||||
|
||||
#define TF_MBEDTLS_HEAP_SIZE U(5120)
|
||||
#endif /* MBEDTLS_CONFIG_H */
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef STM32MP1_PRIVATE_H
|
||||
#define STM32MP1_PRIVATE_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void configure_mmu(void);
|
||||
|
||||
void stm32mp1_arch_security_setup(void);
|
||||
void stm32mp1_security_setup(void);
|
||||
|
||||
void stm32mp1_gic_pcpu_init(void);
|
||||
void stm32mp1_gic_init(void);
|
||||
|
||||
void stm32mp1_syscfg_init(void);
|
||||
void stm32mp1_syscfg_enable_io_compensation_start(void);
|
||||
void stm32mp1_syscfg_enable_io_compensation_finish(void);
|
||||
void stm32mp1_syscfg_disable_io_compensation(void);
|
||||
uint32_t stm32mp1_syscfg_get_chip_version(void);
|
||||
uint32_t stm32mp1_syscfg_get_chip_dev_id(void);
|
||||
#if STM32MP13
|
||||
void stm32mp1_syscfg_boot_mode_enable(void);
|
||||
void stm32mp1_syscfg_boot_mode_disable(void);
|
||||
#endif
|
||||
#if STM32MP15
|
||||
static inline void stm32mp1_syscfg_boot_mode_enable(void){}
|
||||
static inline void stm32mp1_syscfg_boot_mode_disable(void){}
|
||||
#endif
|
||||
|
||||
void stm32mp1_deconfigure_uart_pins(void);
|
||||
|
||||
void stm32mp1_init_scmi_server(void);
|
||||
#endif /* STM32MP1_PRIVATE_H */
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef STM32MP1_SHARED_RESOURCES_H
|
||||
#define STM32MP1_SHARED_RESOURCES_H
|
||||
|
||||
#include <stm32mp_shared_resources.h>
|
||||
|
||||
#define STM32MP1_SHRES_GPIOZ(i) (STM32MP1_SHRES_GPIOZ_0 + (i))
|
||||
|
||||
enum stm32mp_shres {
|
||||
STM32MP1_SHRES_CRYP1,
|
||||
STM32MP1_SHRES_GPIOZ_0,
|
||||
STM32MP1_SHRES_GPIOZ_1,
|
||||
STM32MP1_SHRES_GPIOZ_2,
|
||||
STM32MP1_SHRES_GPIOZ_3,
|
||||
STM32MP1_SHRES_GPIOZ_4,
|
||||
STM32MP1_SHRES_GPIOZ_5,
|
||||
STM32MP1_SHRES_GPIOZ_6,
|
||||
STM32MP1_SHRES_GPIOZ_7,
|
||||
STM32MP1_SHRES_HASH1,
|
||||
STM32MP1_SHRES_I2C4,
|
||||
STM32MP1_SHRES_I2C6,
|
||||
STM32MP1_SHRES_IWDG1,
|
||||
STM32MP1_SHRES_MCU,
|
||||
STM32MP1_SHRES_MDMA,
|
||||
STM32MP1_SHRES_PLL3,
|
||||
STM32MP1_SHRES_RNG1,
|
||||
STM32MP1_SHRES_RTC,
|
||||
STM32MP1_SHRES_SPI6,
|
||||
STM32MP1_SHRES_USART1,
|
||||
|
||||
STM32MP1_SHRES_COUNT
|
||||
};
|
||||
#endif /* STM32MP1_SHARED_RESOURCES_H */
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2021, STMicroelectronics - All Rights Reserved
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef STM32MP1_SMC_H
|
||||
#define STM32MP1_SMC_H
|
||||
|
||||
/*
|
||||
* SMC function IDs for STM32 Service queries
|
||||
* STM32 SMC services use the space between 0x82000000 and 0x8200FFFF
|
||||
* like this is defined in SMC calling Convention by ARM
|
||||
* for SiP (silicon Partner)
|
||||
* https://developer.arm.com/docs/den0028/latest
|
||||
*/
|
||||
|
||||
/* Secure Service access from Non-secure */
|
||||
|
||||
/*
|
||||
* STM32_SMC_BSEC call API
|
||||
*
|
||||
* Argument a0: (input) SMCC ID
|
||||
* (output) status return code
|
||||
* Argument a1: (input) Service ID (STM32_SMC_BSEC_xxx)
|
||||
* Argument a2: (input) OTP index
|
||||
* (output) OTP read value, if applicable
|
||||
* Argument a3: (input) OTP value if applicable
|
||||
*/
|
||||
#define STM32_SMC_BSEC 0x82001003
|
||||
|
||||
/*
|
||||
* STM32_SIP_SMC_SCMI_AGENT0
|
||||
* STM32_SIP_SMC_SCMI_AGENT1
|
||||
* Process SCMI message pending in SCMI shared memory buffer.
|
||||
*
|
||||
* Argument a0: (input) SMCC ID
|
||||
*/
|
||||
#define STM32_SIP_SMC_SCMI_AGENT0 0x82002000
|
||||
#define STM32_SIP_SMC_SCMI_AGENT1 0x82002001
|
||||
|
||||
/* SMC function IDs for SiP Service queries */
|
||||
#define STM32_SIP_SVC_CALL_COUNT 0x8200ff00
|
||||
#define STM32_SIP_SVC_UID 0x8200ff01
|
||||
/* 0x8200ff02 is reserved */
|
||||
#define STM32_SIP_SVC_VERSION 0x8200ff03
|
||||
|
||||
/* STM32 SiP Service Calls version numbers */
|
||||
#define STM32_SIP_SVC_VERSION_MAJOR 0x0
|
||||
#define STM32_SIP_SVC_VERSION_MINOR 0x1
|
||||
|
||||
/* Number of STM32 SiP Calls implemented */
|
||||
#define STM32_COMMON_SIP_NUM_CALLS 3
|
||||
|
||||
/* Service for BSEC */
|
||||
#define STM32_SMC_READ_SHADOW 0x01
|
||||
#define STM32_SMC_PROG_OTP 0x02
|
||||
#define STM32_SMC_WRITE_SHADOW 0x03
|
||||
#define STM32_SMC_READ_OTP 0x04
|
||||
|
||||
/* SMC error codes */
|
||||
#define STM32_SMC_OK 0x00000000U
|
||||
#define STM32_SMC_NOT_SUPPORTED 0xFFFFFFFFU
|
||||
#define STM32_SMC_FAILED 0xFFFFFFFEU
|
||||
#define STM32_SMC_INVALID_PARAMS 0xFFFFFFFDU
|
||||
|
||||
#endif /* STM32MP1_SMC_H */
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef STM32MP1_TBB_CERT_H
|
||||
#define STM32MP1_TBB_CERT_H
|
||||
|
||||
#include <tbbr/tbb_cert.h>
|
||||
|
||||
/*
|
||||
* Enumerate the certificates that are used to establish the chain of trust
|
||||
*/
|
||||
enum {
|
||||
STM32MP_CONFIG_CERT = FWU_CERT + 1
|
||||
};
|
||||
|
||||
#endif /* STM32MP1_TBB_CERT_H */
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <common/bl_common.h>
|
||||
#include <common/desc_image_load.h>
|
||||
#include <plat/common/platform.h>
|
||||
|
||||
#include <platform_def.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 FW_CONFIG related information if it exists */
|
||||
{
|
||||
.image_id = 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_PLAT_SETUP),
|
||||
|
||||
.image_info.image_base = STM32MP_FW_CONFIG_BASE,
|
||||
.image_info.image_max_size = STM32MP_FW_CONFIG_MAX_SIZE,
|
||||
|
||||
.next_handoff_image_id = INVALID_IMAGE_ID,
|
||||
},
|
||||
|
||||
/* 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),
|
||||
|
||||
.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_SKIP_LOADING),
|
||||
|
||||
.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,
|
||||
},
|
||||
#if STM32MP15
|
||||
/* 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,
|
||||
},
|
||||
#endif
|
||||
|
||||
/* Fill HW_CONFIG related information if it exists */
|
||||
{
|
||||
.image_id = HW_CONFIG_ID,
|
||||
SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
|
||||
VERSION_2, entry_point_info_t,
|
||||
NON_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 TOS_FW_CONFIG related information if it exists */
|
||||
{
|
||||
.image_id = TOS_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 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.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_SKIP_LOADING),
|
||||
|
||||
.next_handoff_image_id = INVALID_IMAGE_ID,
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs)
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) 2022, STMicroelectronics - All Rights Reserved
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <firmware_image_package.h>
|
||||
|
||||
#include "tbbr_config.h"
|
||||
|
||||
toc_entry_t plat_def_toc_entries[] = {
|
||||
{
|
||||
.name = "STM32MP CONFIG CERT",
|
||||
.uuid = UUID_STM32MP_CONFIG_CERT,
|
||||
.cmdline_name = "stm32mp-cfg-cert"
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#
|
||||
# Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
|
||||
# Name of the platform defined source file name,
|
||||
# which contains platform defined UUID entries populated
|
||||
# in the plat_def_toc_entries[].
|
||||
PLAT_DEF_UUID_FILE_NAME := plat_def_uuid_config
|
||||
|
||||
INCLUDE_PATHS += -I${PLAT_DIR}/include -I./
|
||||
|
||||
PLAT_DEF_UUID := yes
|
||||
|
||||
ifeq (${PLAT_DEF_UUID},yes)
|
||||
HOSTCCFLAGS += -DPLAT_DEF_FIP_UUID
|
||||
|
||||
${PLAT_DEF_UUID_FILE_NAME}.o: ${PLAT_DIR}${PLAT_DEF_UUID_FILE_NAME}.c
|
||||
${HOSTCC} -c ${CPPFLAGS} ${HOSTCCFLAGS} ${INCLUDE_PATHS} $< -o $@
|
||||
|
||||
PLAT_OBJECTS += ${PLAT_DEF_UUID_FILE_NAME}.o
|
||||
endif
|
||||
|
||||
OBJECTS += ${PLAT_OBJECTS}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <common/desc_image_load.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* This function flushes the data structures so that they are visible
|
||||
* in memory for the next BL image.
|
||||
******************************************************************************/
|
||||
void plat_flush_next_bl_params(void)
|
||||
{
|
||||
flush_bl_params_desc();
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* This function returns the list of loadable images.
|
||||
******************************************************************************/
|
||||
bl_load_info_t *plat_get_bl_image_load_info(void)
|
||||
{
|
||||
return get_bl_load_info_from_mem_params_desc();
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* This function returns the list of executable images.
|
||||
******************************************************************************/
|
||||
bl_params_t *plat_get_next_bl_params(void)
|
||||
{
|
||||
bl_params_t *bl_params = get_next_bl_params_from_mem_params_desc();
|
||||
|
||||
populate_next_bl_params_config(bl_params);
|
||||
|
||||
return bl_params;
|
||||
}
|
||||
@@ -0,0 +1,553 @@
|
||||
#
|
||||
# Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
|
||||
ARM_CORTEX_A7 := yes
|
||||
ARM_WITH_NEON := yes
|
||||
BL2_AT_EL3 := 1
|
||||
USE_COHERENT_MEM := 0
|
||||
|
||||
STM32MP_EARLY_CONSOLE ?= 0
|
||||
STM32MP_RECONFIGURE_CONSOLE ?= 0
|
||||
STM32MP_UART_BAUDRATE ?= 115200
|
||||
|
||||
TRUSTED_BOARD_BOOT ?= 0
|
||||
STM32MP_USE_EXTERNAL_HEAP ?= 0
|
||||
|
||||
# Use secure library from the ROM code for authentication
|
||||
STM32MP_CRYPTO_ROM_LIB ?= 0
|
||||
|
||||
# Please don't increment this value without good understanding of
|
||||
# the monotonic counter
|
||||
STM32_TF_VERSION ?= 0
|
||||
|
||||
# Enable dynamic memory mapping
|
||||
PLAT_XLAT_TABLES_DYNAMIC := 1
|
||||
|
||||
# Default Device tree
|
||||
DTB_FILE_NAME ?= stm32mp157c-ev1.dtb
|
||||
|
||||
STM32MP13 ?= 0
|
||||
STM32MP15 ?= 0
|
||||
|
||||
ifeq ($(STM32MP13),1)
|
||||
ifeq ($(STM32MP15),1)
|
||||
$(error Cannot enable both flags STM32MP13 and STM32MP15)
|
||||
endif
|
||||
STM32MP13 := 1
|
||||
STM32MP15 := 0
|
||||
else ifeq ($(STM32MP15),1)
|
||||
STM32MP13 := 0
|
||||
STM32MP15 := 1
|
||||
else ifneq ($(findstring stm32mp13,$(DTB_FILE_NAME)),)
|
||||
STM32MP13 := 1
|
||||
STM32MP15 := 0
|
||||
else ifneq ($(findstring stm32mp15,$(DTB_FILE_NAME)),)
|
||||
STM32MP13 := 0
|
||||
STM32MP15 := 1
|
||||
endif
|
||||
|
||||
ifeq ($(STM32MP13),1)
|
||||
# Will use SRAM2 as mbedtls heap
|
||||
STM32MP_USE_EXTERNAL_HEAP := 1
|
||||
|
||||
# DDR controller with single AXI port and 16-bit interface
|
||||
STM32MP_DDR_DUAL_AXI_PORT:= 0
|
||||
STM32MP_DDR_32BIT_INTERFACE:= 0
|
||||
|
||||
ifeq (${TRUSTED_BOARD_BOOT},1)
|
||||
# PKA algo to include
|
||||
PKA_USE_NIST_P256 := 1
|
||||
PKA_USE_BRAINPOOL_P256T1:= 1
|
||||
endif
|
||||
|
||||
# STM32 image header version v2.0
|
||||
STM32_HEADER_VERSION_MAJOR:= 2
|
||||
STM32_HEADER_VERSION_MINOR:= 0
|
||||
endif
|
||||
|
||||
ifeq ($(STM32MP15),1)
|
||||
# DDR controller with dual AXI port and 32-bit interface
|
||||
STM32MP_DDR_DUAL_AXI_PORT:= 1
|
||||
STM32MP_DDR_32BIT_INTERFACE:= 1
|
||||
|
||||
# STM32 image header version v1.0
|
||||
STM32_HEADER_VERSION_MAJOR:= 1
|
||||
STM32_HEADER_VERSION_MINOR:= 0
|
||||
|
||||
# Add OP-TEE reserved shared memory area in mapping
|
||||
STM32MP15_OPTEE_RSV_SHM := 1
|
||||
$(eval $(call add_defines,STM32MP15_OPTEE_RSV_SHM))
|
||||
|
||||
STM32MP_CRYPTO_ROM_LIB := 1
|
||||
|
||||
# Decryption support
|
||||
ifneq ($(DECRYPTION_SUPPORT),none)
|
||||
$(error "DECRYPTION_SUPPORT not supported on STM32MP15")
|
||||
endif
|
||||
endif
|
||||
|
||||
# STM32 image header binary type for BL2
|
||||
STM32_HEADER_BL2_BINARY_TYPE:= 0x10
|
||||
|
||||
ifeq ($(AARCH32_SP),sp_min)
|
||||
# Disable Neon support: sp_min runtime may conflict with non-secure world
|
||||
TF_CFLAGS += -mfloat-abi=soft
|
||||
endif
|
||||
|
||||
TF_CFLAGS += -Wsign-compare
|
||||
TF_CFLAGS += -Wformat-signedness
|
||||
|
||||
# Not needed for Cortex-A7
|
||||
WORKAROUND_CVE_2017_5715:= 0
|
||||
WORKAROUND_CVE_2022_23960:= 0
|
||||
|
||||
# Number of TF-A copies in the device
|
||||
STM32_TF_A_COPIES := 2
|
||||
|
||||
# PLAT_PARTITION_MAX_ENTRIES must take care of STM32_TF-A_COPIES and other partitions
|
||||
# such as metadata (2) to find all the FIP partitions (default is 2).
|
||||
PLAT_PARTITION_MAX_ENTRIES := $(shell echo $$(($(STM32_TF_A_COPIES) + 4)))
|
||||
|
||||
ifeq (${PSA_FWU_SUPPORT},1)
|
||||
# Number of banks of updatable firmware
|
||||
NR_OF_FW_BANKS := 2
|
||||
NR_OF_IMAGES_IN_FW_BANK := 1
|
||||
|
||||
FWU_MAX_PART = $(shell echo $$(($(STM32_TF_A_COPIES) + 2 + $(NR_OF_FW_BANKS))))
|
||||
ifeq ($(shell test $(FWU_MAX_PART) -gt $(PLAT_PARTITION_MAX_ENTRIES); echo $$?),0)
|
||||
$(error "Required partition number is $(FWU_MAX_PART) where PLAT_PARTITION_MAX_ENTRIES is only \
|
||||
$(PLAT_PARTITION_MAX_ENTRIES)")
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(STM32MP13),1)
|
||||
STM32_HASH_VER := 4
|
||||
STM32_RNG_VER := 4
|
||||
else # Assuming STM32MP15
|
||||
STM32_HASH_VER := 2
|
||||
STM32_RNG_VER := 2
|
||||
endif
|
||||
|
||||
# Boot devices
|
||||
STM32MP_EMMC ?= 0
|
||||
STM32MP_SDMMC ?= 0
|
||||
STM32MP_RAW_NAND ?= 0
|
||||
STM32MP_SPI_NAND ?= 0
|
||||
STM32MP_SPI_NOR ?= 0
|
||||
STM32MP_EMMC_BOOT ?= 0
|
||||
|
||||
# Serial boot devices
|
||||
STM32MP_USB_PROGRAMMER ?= 0
|
||||
STM32MP_UART_PROGRAMMER ?= 0
|
||||
|
||||
# Download load address for serial boot devices
|
||||
DWL_BUFFER_BASE ?= 0xC7000000
|
||||
|
||||
# Device tree
|
||||
ifeq ($(STM32MP13),1)
|
||||
BL2_DTSI := stm32mp13-bl2.dtsi
|
||||
FDT_SOURCES := $(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl2.dts,$(DTB_FILE_NAME)))
|
||||
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
|
||||
|
||||
$(eval DTC_V = $(shell $(DTC) -v | awk '{print $$NF}'))
|
||||
$(eval DTC_VERSION = $(shell printf "%d" $(shell echo ${DTC_V} | cut -d- -f1 | sed "s/\./0/g" | grep -o "[0-9]*")))
|
||||
DTC_CPPFLAGS += ${INCLUDES}
|
||||
DTC_FLAGS += -Wno-unit_address_vs_reg
|
||||
ifeq ($(shell test $(DTC_VERSION) -ge 10601; echo $$?),0)
|
||||
DTC_FLAGS += -Wno-interrupt_provider
|
||||
endif
|
||||
|
||||
# Macros and rules to build TF binary
|
||||
STM32_TF_ELF_LDFLAGS := --hash-style=gnu --as-needed
|
||||
STM32_TF_STM32 := $(addprefix ${BUILD_PLAT}/tf-a-, $(patsubst %.dtb,%.stm32,$(DTB_FILE_NAME)))
|
||||
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
|
||||
|
||||
FIP_DEPS += dtbs
|
||||
STM32MP_HW_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)
|
||||
ifneq (${AARCH32_SP},none)
|
||||
FDT_SOURCES += $(addprefix fdts/, $(patsubst %.dtb,%.dts,$(STM32MP_FW_CONFIG_NAME)))
|
||||
endif
|
||||
# Add the FW_CONFIG to FIP and specify the same to certtool
|
||||
$(eval $(call TOOL_ADD_PAYLOAD,${STM32MP_FW_CONFIG},--fw-config))
|
||||
# Add the HW_CONFIG to FIP and specify the same to certtool
|
||||
$(eval $(call TOOL_ADD_PAYLOAD,${STM32MP_HW_CONFIG},--hw-config))
|
||||
ifeq ($(GENERATE_COT),1)
|
||||
STM32MP_CFG_CERT := $(BUILD_PLAT)/stm32mp_cfg_cert.crt
|
||||
# Add the STM32MP_CFG_CERT to FIP and specify the same to certtool
|
||||
$(eval $(call TOOL_ADD_PAYLOAD,${STM32MP_CFG_CERT},--stm32mp-cfg-cert))
|
||||
endif
|
||||
ifeq ($(AARCH32_SP),sp_min)
|
||||
STM32MP_TOS_FW_CONFIG := $(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl32.dtb,$(DTB_FILE_NAME)))
|
||||
$(eval $(call TOOL_ADD_PAYLOAD,${STM32MP_TOS_FW_CONFIG},--tos-fw-config))
|
||||
else
|
||||
# Add the build options to pack Trusted OS Extra1 and Trusted OS Extra2 images
|
||||
# in the FIP if the platform requires.
|
||||
ifneq ($(BL32_EXTRA1),)
|
||||
$(eval $(call TOOL_ADD_IMG,BL32_EXTRA1,--tos-fw-extra1,,$(ENCRYPT_BL32)))
|
||||
endif
|
||||
ifneq ($(BL32_EXTRA2),)
|
||||
$(eval $(call TOOL_ADD_IMG,BL32_EXTRA2,--tos-fw-extra2,,$(ENCRYPT_BL32)))
|
||||
endif
|
||||
endif
|
||||
|
||||
# Enable flags for C files
|
||||
$(eval $(call assert_booleans,\
|
||||
$(sort \
|
||||
PKA_USE_BRAINPOOL_P256T1 \
|
||||
PKA_USE_NIST_P256 \
|
||||
PLAT_TBBR_IMG_DEF \
|
||||
PLAT_XLAT_TABLES_DYNAMIC \
|
||||
STM32MP_CRYPTO_ROM_LIB \
|
||||
STM32MP_DDR_32BIT_INTERFACE \
|
||||
STM32MP_DDR_DUAL_AXI_PORT \
|
||||
STM32MP_EARLY_CONSOLE \
|
||||
STM32MP_EMMC \
|
||||
STM32MP_EMMC_BOOT \
|
||||
STM32MP_RAW_NAND \
|
||||
STM32MP_RECONFIGURE_CONSOLE \
|
||||
STM32MP_SDMMC \
|
||||
STM32MP_SPI_NAND \
|
||||
STM32MP_SPI_NOR \
|
||||
STM32MP_UART_PROGRAMMER \
|
||||
STM32MP_USB_PROGRAMMER \
|
||||
STM32MP_USE_EXTERNAL_HEAP \
|
||||
STM32MP13 \
|
||||
STM32MP15 \
|
||||
)))
|
||||
|
||||
$(eval $(call assert_numerics,\
|
||||
$(sort \
|
||||
PLAT_PARTITION_MAX_ENTRIES \
|
||||
STM32_HASH_VER \
|
||||
STM32_HEADER_VERSION_MAJOR \
|
||||
STM32_RNG_VER \
|
||||
STM32_TF_A_COPIES \
|
||||
STM32_TF_VERSION \
|
||||
STM32MP_UART_BAUDRATE \
|
||||
)))
|
||||
|
||||
$(eval $(call add_defines,\
|
||||
$(sort \
|
||||
DWL_BUFFER_BASE \
|
||||
PKA_USE_BRAINPOOL_P256T1 \
|
||||
PKA_USE_NIST_P256 \
|
||||
PLAT_PARTITION_MAX_ENTRIES \
|
||||
PLAT_TBBR_IMG_DEF \
|
||||
PLAT_XLAT_TABLES_DYNAMIC \
|
||||
STM32_HASH_VER \
|
||||
STM32_HEADER_VERSION_MAJOR \
|
||||
STM32_RNG_VER \
|
||||
STM32_TF_A_COPIES \
|
||||
STM32_TF_VERSION \
|
||||
STM32MP_CRYPTO_ROM_LIB \
|
||||
STM32MP_DDR_32BIT_INTERFACE \
|
||||
STM32MP_DDR_DUAL_AXI_PORT \
|
||||
STM32MP_EARLY_CONSOLE \
|
||||
STM32MP_EMMC \
|
||||
STM32MP_EMMC_BOOT \
|
||||
STM32MP_RAW_NAND \
|
||||
STM32MP_RECONFIGURE_CONSOLE \
|
||||
STM32MP_SDMMC \
|
||||
STM32MP_SPI_NAND \
|
||||
STM32MP_SPI_NOR \
|
||||
STM32MP_UART_BAUDRATE \
|
||||
STM32MP_UART_PROGRAMMER \
|
||||
STM32MP_USB_PROGRAMMER \
|
||||
STM32MP_USE_EXTERNAL_HEAP \
|
||||
STM32MP13 \
|
||||
STM32MP15 \
|
||||
)))
|
||||
|
||||
# Include paths and source files
|
||||
PLAT_INCLUDES := -Iplat/st/common/include/
|
||||
PLAT_INCLUDES += -Iplat/st/stm32mp1/include/
|
||||
|
||||
include lib/fconf/fconf.mk
|
||||
include lib/libfdt/libfdt.mk
|
||||
|
||||
PLAT_BL_COMMON_SOURCES := common/uuid.c \
|
||||
plat/st/common/stm32mp_common.c \
|
||||
plat/st/stm32mp1/stm32mp1_private.c
|
||||
|
||||
PLAT_BL_COMMON_SOURCES += drivers/st/uart/aarch32/stm32_console.S
|
||||
|
||||
ifneq (${ENABLE_STACK_PROTECTOR},0)
|
||||
PLAT_BL_COMMON_SOURCES += plat/st/stm32mp1/stm32mp1_stack_protector.c
|
||||
endif
|
||||
|
||||
include lib/xlat_tables_v2/xlat_tables.mk
|
||||
PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS}
|
||||
|
||||
PLAT_BL_COMMON_SOURCES += lib/cpus/aarch32/cortex_a7.S
|
||||
|
||||
PLAT_BL_COMMON_SOURCES += drivers/arm/tzc/tzc400.c \
|
||||
drivers/clk/clk.c \
|
||||
drivers/delay_timer/delay_timer.c \
|
||||
drivers/delay_timer/generic_delay_timer.c \
|
||||
drivers/st/bsec/bsec2.c \
|
||||
drivers/st/clk/stm32mp_clkfunc.c \
|
||||
drivers/st/ddr/stm32mp_ddr.c \
|
||||
drivers/st/ddr/stm32mp1_ddr_helpers.c \
|
||||
drivers/st/gpio/stm32_gpio.c \
|
||||
drivers/st/i2c/stm32_i2c.c \
|
||||
drivers/st/iwdg/stm32_iwdg.c \
|
||||
drivers/st/pmic/stm32mp_pmic.c \
|
||||
drivers/st/pmic/stpmic1.c \
|
||||
drivers/st/regulator/regulator_core.c \
|
||||
drivers/st/regulator/regulator_fixed.c \
|
||||
drivers/st/reset/stm32mp1_reset.c \
|
||||
plat/st/common/stm32mp_dt.c \
|
||||
plat/st/stm32mp1/stm32mp1_dbgmcu.c \
|
||||
plat/st/stm32mp1/stm32mp1_helper.S \
|
||||
plat/st/stm32mp1/stm32mp1_syscfg.c
|
||||
|
||||
ifeq ($(STM32MP13),1)
|
||||
PLAT_BL_COMMON_SOURCES += drivers/st/clk/clk-stm32-core.c \
|
||||
drivers/st/clk/clk-stm32mp13.c \
|
||||
drivers/st/crypto/stm32_rng.c
|
||||
else
|
||||
PLAT_BL_COMMON_SOURCES += drivers/st/clk/stm32mp1_clk.c
|
||||
endif
|
||||
|
||||
BL2_SOURCES += ${FCONF_SOURCES} ${FCONF_DYN_SOURCES}
|
||||
|
||||
BL2_SOURCES += drivers/io/io_fip.c \
|
||||
plat/st/common/bl2_io_storage.c \
|
||||
plat/st/common/stm32mp_fconf_io.c \
|
||||
plat/st/stm32mp1/plat_bl2_mem_params_desc.c \
|
||||
plat/st/stm32mp1/stm32mp1_fconf_firewall.c
|
||||
|
||||
include lib/zlib/zlib.mk
|
||||
|
||||
ifeq (${PSA_FWU_SUPPORT},1)
|
||||
include drivers/fwu/fwu.mk
|
||||
endif
|
||||
|
||||
|
||||
BL2_SOURCES += $(ZLIB_SOURCES)
|
||||
|
||||
BL2_SOURCES += drivers/io/io_block.c \
|
||||
drivers/io/io_mtd.c \
|
||||
drivers/io/io_storage.c \
|
||||
drivers/st/crypto/stm32_hash.c \
|
||||
plat/st/stm32mp1/bl2_plat_setup.c
|
||||
|
||||
ifneq (${DECRYPTION_SUPPORT},none)
|
||||
BL2_SOURCES += drivers/io/io_encrypted.c
|
||||
endif
|
||||
|
||||
ifeq (${TRUSTED_BOARD_BOOT},1)
|
||||
AUTH_SOURCES := drivers/auth/auth_mod.c \
|
||||
drivers/auth/crypto_mod.c \
|
||||
drivers/auth/img_parser_mod.c
|
||||
|
||||
ifeq (${GENERATE_COT},1)
|
||||
TFW_NVCTR_VAL := 0
|
||||
NTFW_NVCTR_VAL := 0
|
||||
KEY_SIZE :=
|
||||
KEY_ALG := ecdsa
|
||||
HASH_ALG := sha256
|
||||
|
||||
ifeq (${SAVE_KEYS},1)
|
||||
TRUSTED_WORLD_KEY ?= ${BUILD_PLAT}/trusted.pem
|
||||
NON_TRUSTED_WORLD_KEY ?= ${BUILD_PLAT}/non-trusted.pem
|
||||
BL32_KEY ?= ${BUILD_PLAT}/trusted_os.pem
|
||||
BL33_KEY ?= ${BUILD_PLAT}/non-trusted_os.pem
|
||||
endif
|
||||
|
||||
endif
|
||||
TF_MBEDTLS_KEY_ALG := ecdsa
|
||||
MBEDTLS_CONFIG_FILE ?= "<stm32mp1_mbedtls_config.h>"
|
||||
|
||||
include drivers/auth/mbedtls/mbedtls_x509.mk
|
||||
|
||||
COT_DESC_IN_DTB := 1
|
||||
AUTH_SOURCES += lib/fconf/fconf_cot_getter.c \
|
||||
lib/fconf/fconf_tbbr_getter.c \
|
||||
plat/st/common/stm32mp_crypto_lib.c
|
||||
|
||||
ifeq ($(STM32MP13),1)
|
||||
AUTH_SOURCES += drivers/st/crypto/stm32_pka.c
|
||||
AUTH_SOURCES += drivers/st/crypto/stm32_saes.c
|
||||
endif
|
||||
|
||||
BL2_SOURCES += $(AUTH_SOURCES) \
|
||||
plat/st/common/stm32mp_trusted_boot.c
|
||||
endif
|
||||
|
||||
ifneq ($(filter 1,${STM32MP_EMMC} ${STM32MP_SDMMC}),)
|
||||
BL2_SOURCES += drivers/mmc/mmc.c \
|
||||
drivers/partition/gpt.c \
|
||||
drivers/partition/partition.c \
|
||||
drivers/st/io/io_mmc.c \
|
||||
drivers/st/mmc/stm32_sdmmc2.c
|
||||
endif
|
||||
|
||||
ifeq (${STM32MP_RAW_NAND},1)
|
||||
$(eval $(call add_define_val,NAND_ONFI_DETECT,1))
|
||||
BL2_SOURCES += drivers/mtd/nand/raw_nand.c \
|
||||
drivers/st/fmc/stm32_fmc2_nand.c
|
||||
endif
|
||||
|
||||
ifeq (${STM32MP_SPI_NAND},1)
|
||||
BL2_SOURCES += drivers/mtd/nand/spi_nand.c
|
||||
endif
|
||||
|
||||
ifeq (${STM32MP_SPI_NOR},1)
|
||||
ifneq (${STM32MP_FORCE_MTD_START_OFFSET},)
|
||||
$(eval $(call add_define_val,STM32MP_NOR_FIP_OFFSET,${STM32MP_FORCE_MTD_START_OFFSET}))
|
||||
endif
|
||||
BL2_SOURCES += drivers/mtd/nor/spi_nor.c
|
||||
endif
|
||||
|
||||
ifneq ($(filter 1,${STM32MP_SPI_NAND} ${STM32MP_SPI_NOR}),)
|
||||
BL2_SOURCES += drivers/mtd/spi-mem/spi_mem.c \
|
||||
drivers/st/spi/stm32_qspi.c
|
||||
endif
|
||||
|
||||
ifneq ($(filter 1,${STM32MP_RAW_NAND} ${STM32MP_SPI_NAND}),)
|
||||
ifneq (${STM32MP_FORCE_MTD_START_OFFSET},)
|
||||
$(eval $(call add_define_val,STM32MP_NAND_FIP_OFFSET,${STM32MP_FORCE_MTD_START_OFFSET}))
|
||||
endif
|
||||
BL2_SOURCES += drivers/mtd/nand/core.c
|
||||
endif
|
||||
|
||||
ifneq ($(filter 1,${STM32MP_RAW_NAND} ${STM32MP_SPI_NAND} ${STM32MP_SPI_NOR}),)
|
||||
BL2_SOURCES += plat/st/stm32mp1/stm32mp1_boot_device.c
|
||||
endif
|
||||
|
||||
ifneq ($(filter 1,${STM32MP_UART_PROGRAMMER} ${STM32MP_USB_PROGRAMMER}),)
|
||||
BL2_SOURCES += drivers/io/io_memmap.c
|
||||
endif
|
||||
|
||||
ifeq (${STM32MP_UART_PROGRAMMER},1)
|
||||
BL2_SOURCES += drivers/st/uart/stm32_uart.c \
|
||||
plat/st/common/stm32cubeprogrammer_uart.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/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/stm32mp_ddr_test.c \
|
||||
drivers/st/ddr/stm32mp_ram.c \
|
||||
drivers/st/ddr/stm32mp1_ddr.c \
|
||||
drivers/st/ddr/stm32mp1_ram.c
|
||||
|
||||
BL2_SOURCES += common/desc_image_load.c \
|
||||
plat/st/stm32mp1/plat_image_load.c
|
||||
|
||||
BL2_SOURCES += lib/optee/optee_utils.c
|
||||
|
||||
# Compilation rules
|
||||
.PHONY: check_dtc_version stm32image clean_stm32image check_boot_device
|
||||
.SUFFIXES:
|
||||
|
||||
all: check_dtc_version stm32image ${STM32_TF_STM32}
|
||||
|
||||
distclean realclean clean: clean_stm32image
|
||||
|
||||
bl2: check_boot_device
|
||||
|
||||
check_boot_device:
|
||||
@if [ ${STM32MP_EMMC} != 1 ] && \
|
||||
[ ${STM32MP_SDMMC} != 1 ] && \
|
||||
[ ${STM32MP_RAW_NAND} != 1 ] && \
|
||||
[ ${STM32MP_SPI_NAND} != 1 ] && \
|
||||
[ ${STM32MP_SPI_NOR} != 1 ] && \
|
||||
[ ${STM32MP_UART_PROGRAMMER} != 1 ] && \
|
||||
[ ${STM32MP_USB_PROGRAMMER} != 1 ]; then \
|
||||
echo "No boot device driver is enabled"; \
|
||||
false; \
|
||||
fi
|
||||
|
||||
stm32image: ${STM32IMAGE}
|
||||
|
||||
${STM32IMAGE}: ${STM32IMAGE_SRC}
|
||||
${Q}${MAKE} CPPFLAGS="" --no-print-directory -C ${STM32IMAGEPATH}
|
||||
|
||||
clean_stm32image:
|
||||
${Q}${MAKE} --no-print-directory -C ${STM32IMAGEPATH} clean
|
||||
|
||||
check_dtc_version:
|
||||
@if [ ${DTC_VERSION} -lt 10404 ]; then \
|
||||
echo "dtc version too old (${DTC_V}), you need at least version 1.4.4"; \
|
||||
false; \
|
||||
fi
|
||||
|
||||
# Create DTB file for BL2
|
||||
${BUILD_PLAT}/fdts/%-bl2.dts: fdts/%.dts fdts/${BL2_DTSI} | ${BUILD_PLAT} fdt_dirs
|
||||
@echo '#include "$(patsubst fdts/%,%,$<)"' > $@
|
||||
@echo '#include "${BL2_DTSI}"' >> $@
|
||||
|
||||
${BUILD_PLAT}/fdts/%-bl2.dtb: ${BUILD_PLAT}/fdts/%-bl2.dts
|
||||
|
||||
ifeq ($(AARCH32_SP),sp_min)
|
||||
# Create DTB file for BL32
|
||||
${BUILD_PLAT}/fdts/%-bl32.dts: fdts/%.dts fdts/${BL32_DTSI} | ${BUILD_PLAT} fdt_dirs
|
||||
@echo '#include "$(patsubst fdts/%,%,$<)"' > $@
|
||||
@echo '#include "${BL32_DTSI}"' >> $@
|
||||
|
||||
${BUILD_PLAT}/fdts/%-bl32.dtb: ${BUILD_PLAT}/fdts/%-bl32.dts
|
||||
endif
|
||||
|
||||
${BUILD_PLAT}/stm32mp1-%.o: ${BUILD_PLAT}/fdts/%-bl2.dtb plat/st/stm32mp1/stm32mp1.S bl2
|
||||
@echo " AS stm32mp1.S"
|
||||
${Q}${AS} ${ASFLAGS} ${TF_CFLAGS} \
|
||||
-DDTB_BIN_PATH=\"$<\" \
|
||||
-c plat/st/stm32mp1/stm32mp1.S -o $@
|
||||
|
||||
$(eval $(call MAKE_LD,${STM32_TF_LINKERFILE},plat/st/stm32mp1/stm32mp1.ld.S,bl2))
|
||||
|
||||
tf-a-%.elf: stm32mp1-%.o ${STM32_TF_LINKERFILE}
|
||||
@echo " LDS $<"
|
||||
${Q}${LD} -o $@ ${STM32_TF_ELF_LDFLAGS} -Map=$(@:.elf=.map) --script ${STM32_TF_LINKERFILE} $<
|
||||
|
||||
tf-a-%.bin: tf-a-%.elf
|
||||
${Q}${OC} -O binary $< $@
|
||||
@echo
|
||||
@echo "Built $@ successfully"
|
||||
@echo
|
||||
|
||||
tf-a-%.stm32: ${STM32IMAGE} tf-a-%.bin
|
||||
@echo
|
||||
@echo "Generate $@"
|
||||
$(eval LOADADDR = $(shell cat $(@:.stm32=.map) | grep RAM | awk '{print $$2}'))
|
||||
$(eval ENTRY = $(shell cat $(@:.stm32=.map) | grep "__BL2_IMAGE_START" | awk '{print $$1}'))
|
||||
${Q}${STM32IMAGE} -s $(word 2,$^) -d $@ \
|
||||
-l $(LOADADDR) -e ${ENTRY} \
|
||||
-v ${STM32_TF_VERSION} \
|
||||
-m ${STM32_HEADER_VERSION_MAJOR} \
|
||||
-n ${STM32_HEADER_VERSION_MINOR} \
|
||||
-b ${STM32_HEADER_BL2_BINARY_TYPE}
|
||||
@echo
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2022, STMicroelectronics - All Rights Reserved
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <drivers/st/bsec.h>
|
||||
#include <drivers/st/bsec2_reg.h>
|
||||
|
||||
#include <stm32mp1_smc.h>
|
||||
|
||||
#include "bsec_svc.h"
|
||||
|
||||
uint32_t bsec_main(uint32_t x1, uint32_t x2, uint32_t x3,
|
||||
uint32_t *ret_otp_value)
|
||||
{
|
||||
uint32_t result;
|
||||
uint32_t tmp_data = 0U;
|
||||
|
||||
switch (x1) {
|
||||
case STM32_SMC_READ_SHADOW:
|
||||
result = bsec_read_otp(ret_otp_value, x2);
|
||||
break;
|
||||
case STM32_SMC_PROG_OTP:
|
||||
*ret_otp_value = 0U;
|
||||
result = bsec_program_otp(x3, x2);
|
||||
break;
|
||||
case STM32_SMC_WRITE_SHADOW:
|
||||
*ret_otp_value = 0U;
|
||||
result = bsec_write_otp(x3, x2);
|
||||
break;
|
||||
case STM32_SMC_READ_OTP:
|
||||
*ret_otp_value = 0U;
|
||||
result = bsec_read_otp(&tmp_data, x2);
|
||||
if (result != BSEC_OK) {
|
||||
break;
|
||||
}
|
||||
|
||||
result = bsec_shadow_register(x2);
|
||||
if (result != BSEC_OK) {
|
||||
break;
|
||||
}
|
||||
|
||||
result = bsec_read_otp(ret_otp_value, x2);
|
||||
if (result != BSEC_OK) {
|
||||
break;
|
||||
}
|
||||
|
||||
result = bsec_write_otp(tmp_data, x2);
|
||||
break;
|
||||
|
||||
default:
|
||||
return STM32_SMC_INVALID_PARAMS;
|
||||
}
|
||||
|
||||
return (result == BSEC_OK) ? STM32_SMC_OK : STM32_SMC_FAILED;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef BSEC_SVC_H
|
||||
#define BSEC_SVC_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* version of this service */
|
||||
/* must be increase at each structure modification */
|
||||
#define BSEC_SERVICE_VERSION 0x01U
|
||||
|
||||
uint32_t bsec_main(uint32_t x1, uint32_t x2, uint32_t x3,
|
||||
uint32_t *ret_otp_value);
|
||||
|
||||
#endif /* BSEC_SVC_H */
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2021, STMicroelectronics - All Rights Reserved
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <common/runtime_svc.h>
|
||||
#include <drivers/scmi-msg.h>
|
||||
#include <lib/psci/psci.h>
|
||||
#include <tools_share/uuid.h>
|
||||
|
||||
#include <stm32mp1_smc.h>
|
||||
|
||||
#include "bsec_svc.h"
|
||||
|
||||
/* STM32 SiP Service UUID */
|
||||
DEFINE_SVC_UUID2(stm32_sip_svc_uid,
|
||||
0xa778aa50, 0xf49b, 0x144a, 0x8a, 0x5e,
|
||||
0x26, 0x4d, 0x59, 0x94, 0xc2, 0x14);
|
||||
|
||||
/* Setup STM32MP1 Standard Services */
|
||||
static int32_t stm32mp1_svc_setup(void)
|
||||
{
|
||||
/*
|
||||
* PSCI is the only specification implemented as a Standard Service.
|
||||
* Invoke PSCI setup from here.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Top-level Standard Service SMC handler. This handler will in turn dispatch
|
||||
* calls to PSCI SMC handler.
|
||||
*/
|
||||
static uintptr_t stm32mp1_svc_smc_handler(uint32_t smc_fid, u_register_t x1,
|
||||
u_register_t x2, u_register_t x3,
|
||||
u_register_t x4, void *cookie,
|
||||
void *handle, u_register_t flags)
|
||||
{
|
||||
uint32_t ret1 = 0U, ret2 = 0U;
|
||||
bool ret_uid = false, ret2_enabled = false;
|
||||
|
||||
switch (smc_fid) {
|
||||
case STM32_SIP_SVC_CALL_COUNT:
|
||||
ret1 = STM32_COMMON_SIP_NUM_CALLS;
|
||||
break;
|
||||
|
||||
case STM32_SIP_SVC_UID:
|
||||
/* Return UUID to the caller */
|
||||
ret_uid = true;
|
||||
break;
|
||||
|
||||
case STM32_SIP_SVC_VERSION:
|
||||
/* Return the version of current implementation */
|
||||
ret1 = STM32_SIP_SVC_VERSION_MAJOR;
|
||||
ret2 = STM32_SIP_SVC_VERSION_MINOR;
|
||||
ret2_enabled = true;
|
||||
break;
|
||||
|
||||
case STM32_SMC_BSEC:
|
||||
ret1 = bsec_main(x1, x2, x3, &ret2);
|
||||
ret2_enabled = true;
|
||||
break;
|
||||
|
||||
case STM32_SIP_SMC_SCMI_AGENT0:
|
||||
scmi_smt_fastcall_smc_entry(0);
|
||||
break;
|
||||
case STM32_SIP_SMC_SCMI_AGENT1:
|
||||
scmi_smt_fastcall_smc_entry(1);
|
||||
break;
|
||||
|
||||
default:
|
||||
WARN("Unimplemented STM32MP1 Service Call: 0x%x\n", smc_fid);
|
||||
ret1 = STM32_SMC_NOT_SUPPORTED;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret_uid) {
|
||||
SMC_UUID_RET(handle, stm32_sip_svc_uid);
|
||||
}
|
||||
|
||||
if (ret2_enabled) {
|
||||
SMC_RET2(handle, ret1, ret2);
|
||||
}
|
||||
|
||||
SMC_RET1(handle, ret1);
|
||||
}
|
||||
|
||||
/* Register Standard Service Calls as runtime service */
|
||||
DECLARE_RT_SVC(stm32mp1_sip_svc,
|
||||
OEN_SIP_START,
|
||||
OEN_SIP_END,
|
||||
SMC_TYPE_FAST,
|
||||
stm32mp1_svc_setup,
|
||||
stm32mp1_svc_smc_handler
|
||||
);
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
#
|
||||
# Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
|
||||
ifeq ($(STM32MP13),1)
|
||||
$(error "SP_min is not supported on STM32MP13 platform")
|
||||
endif
|
||||
|
||||
SP_MIN_WITH_SECURE_FIQ := 1
|
||||
|
||||
override ENABLE_PIE := 1
|
||||
BL32_CFLAGS += -fpie -DENABLE_PIE
|
||||
BL32_LDFLAGS += $(PIE_LDFLAGS)
|
||||
|
||||
BL32_CFLAGS += -DSTM32MP_SHARED_RESOURCES
|
||||
|
||||
BL32_SOURCES += drivers/st/etzpc/etzpc.c \
|
||||
plat/common/aarch32/platform_mp_stack.S \
|
||||
plat/st/stm32mp1/sp_min/sp_min_setup.c \
|
||||
plat/st/stm32mp1/stm32mp1_pm.c \
|
||||
plat/st/stm32mp1/stm32mp1_shared_resources.c \
|
||||
plat/st/stm32mp1/stm32mp1_topology.c
|
||||
|
||||
# FDT wrappers
|
||||
include common/fdt_wrappers.mk
|
||||
BL32_SOURCES += ${FDT_WRAPPERS_SOURCES}
|
||||
|
||||
# Generic GIC v2
|
||||
include drivers/arm/gic/v2/gicv2.mk
|
||||
|
||||
BL32_SOURCES += ${GICV2_SOURCES} \
|
||||
plat/common/plat_gicv2.c \
|
||||
plat/st/stm32mp1/stm32mp1_gic.c
|
||||
|
||||
# Generic PSCI
|
||||
BL32_SOURCES += plat/common/plat_psci_common.c
|
||||
|
||||
# SCMI server drivers
|
||||
BL32_SOURCES += drivers/scmi-msg/base.c \
|
||||
drivers/scmi-msg/clock.c \
|
||||
drivers/scmi-msg/entry.c \
|
||||
drivers/scmi-msg/reset_domain.c \
|
||||
drivers/scmi-msg/smt.c
|
||||
|
||||
# stm32mp1 specific services
|
||||
BL32_SOURCES += plat/st/stm32mp1/services/bsec_svc.c \
|
||||
plat/st/stm32mp1/services/stm32mp1_svc_setup.c \
|
||||
plat/st/stm32mp1/stm32mp1_scmi.c
|
||||
|
||||
# Arm Archtecture services
|
||||
BL32_SOURCES += services/arm_arch_svc/arm_arch_svc_setup.c
|
||||
+197
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2022, 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/bl_common.h>
|
||||
#include <common/debug.h>
|
||||
#include <context.h>
|
||||
#include <drivers/arm/gicv2.h>
|
||||
#include <drivers/arm/tzc400.h>
|
||||
#include <drivers/generic_delay_timer.h>
|
||||
#include <drivers/st/bsec.h>
|
||||
#include <drivers/st/etzpc.h>
|
||||
#include <drivers/st/stm32_gpio.h>
|
||||
#include <drivers/st/stm32_iwdg.h>
|
||||
#include <drivers/st/stm32mp1_clk.h>
|
||||
#include <dt-bindings/clock/stm32mp1-clks.h>
|
||||
#include <lib/el3_runtime/context_mgmt.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <lib/xlat_tables/xlat_tables_v2.h>
|
||||
#include <plat/common/platform.h>
|
||||
|
||||
#include <platform_sp_min.h>
|
||||
|
||||
/******************************************************************************
|
||||
* Placeholder variables for copying the arguments that have been passed to
|
||||
* BL32 from BL2.
|
||||
******************************************************************************/
|
||||
static entry_point_info_t bl33_image_ep_info;
|
||||
|
||||
/*******************************************************************************
|
||||
* Interrupt handler for FIQ (secure IRQ)
|
||||
******************************************************************************/
|
||||
void sp_min_plat_fiq_handler(uint32_t id)
|
||||
{
|
||||
(void)plat_crash_console_init();
|
||||
|
||||
switch (id & INT_ID_MASK) {
|
||||
case STM32MP1_IRQ_TZC400:
|
||||
tzc400_init(STM32MP1_TZC_BASE);
|
||||
(void)tzc400_it_handler();
|
||||
panic();
|
||||
break;
|
||||
case STM32MP1_IRQ_AXIERRIRQ:
|
||||
ERROR("STM32MP1_IRQ_AXIERRIRQ generated\n");
|
||||
panic();
|
||||
break;
|
||||
default:
|
||||
ERROR("SECURE IT handler not define for it : %u\n", id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Return a pointer to the 'entry_point_info' structure of the next image for
|
||||
* the security state specified. BL33 corresponds to the non-secure image type
|
||||
* while BL32 corresponds to the secure image type. A NULL pointer is returned
|
||||
* if the image does not exist.
|
||||
******************************************************************************/
|
||||
entry_point_info_t *sp_min_plat_get_bl33_ep_info(void)
|
||||
{
|
||||
entry_point_info_t *next_image_info;
|
||||
|
||||
next_image_info = &bl33_image_ep_info;
|
||||
|
||||
if (next_image_info->pc == 0U) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return next_image_info;
|
||||
}
|
||||
|
||||
CASSERT((STM32MP_SEC_SYSRAM_BASE == STM32MP_SYSRAM_BASE) &&
|
||||
((STM32MP_SEC_SYSRAM_BASE + STM32MP_SEC_SYSRAM_SIZE) <=
|
||||
(STM32MP_SYSRAM_BASE + STM32MP_SYSRAM_SIZE)),
|
||||
assert_secure_sysram_fits_at_begining_of_sysram);
|
||||
|
||||
#ifdef STM32MP_NS_SYSRAM_BASE
|
||||
CASSERT((STM32MP_NS_SYSRAM_BASE >= STM32MP_SEC_SYSRAM_BASE) &&
|
||||
((STM32MP_NS_SYSRAM_BASE + STM32MP_NS_SYSRAM_SIZE) ==
|
||||
(STM32MP_SYSRAM_BASE + STM32MP_SYSRAM_SIZE)),
|
||||
assert_non_secure_sysram_fits_at_end_of_sysram);
|
||||
|
||||
CASSERT((STM32MP_NS_SYSRAM_BASE & (PAGE_SIZE_4KB - U(1))) == 0U,
|
||||
assert_non_secure_sysram_base_is_4kbyte_aligned);
|
||||
|
||||
#define TZMA1_SECURE_RANGE \
|
||||
(((STM32MP_NS_SYSRAM_BASE - STM32MP_SYSRAM_BASE) >> FOUR_KB_SHIFT) - 1U)
|
||||
#else
|
||||
#define TZMA1_SECURE_RANGE STM32MP1_ETZPC_TZMA_ALL_SECURE
|
||||
#endif /* STM32MP_NS_SYSRAM_BASE */
|
||||
#define TZMA0_SECURE_RANGE STM32MP1_ETZPC_TZMA_ALL_SECURE
|
||||
|
||||
static void stm32mp1_etzpc_early_setup(void)
|
||||
{
|
||||
if (etzpc_init() != 0) {
|
||||
panic();
|
||||
}
|
||||
|
||||
etzpc_configure_tzma(STM32MP1_ETZPC_TZMA_ROM, TZMA0_SECURE_RANGE);
|
||||
etzpc_configure_tzma(STM32MP1_ETZPC_TZMA_SYSRAM, TZMA1_SECURE_RANGE);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Perform any BL32 specific platform actions.
|
||||
******************************************************************************/
|
||||
void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1,
|
||||
u_register_t arg2, u_register_t arg3)
|
||||
{
|
||||
bl_params_t *params_from_bl2 = (bl_params_t *)arg0;
|
||||
uintptr_t dt_addr = arg1;
|
||||
|
||||
stm32mp_setup_early_console();
|
||||
|
||||
/* Imprecise aborts can be masked in NonSecure */
|
||||
write_scr(read_scr() | SCR_AW_BIT);
|
||||
|
||||
mmap_add_region(BL_CODE_BASE, BL_CODE_BASE,
|
||||
BL_CODE_END - BL_CODE_BASE,
|
||||
MT_CODE | MT_SECURE);
|
||||
|
||||
configure_mmu();
|
||||
|
||||
assert(params_from_bl2 != NULL);
|
||||
assert(params_from_bl2->h.type == PARAM_BL_PARAMS);
|
||||
assert(params_from_bl2->h.version >= VERSION_2);
|
||||
|
||||
bl_params_node_t *bl_params = params_from_bl2->head;
|
||||
|
||||
/*
|
||||
* Copy BL33 entry point information.
|
||||
* They are stored in Secure RAM, in BL2's address space.
|
||||
*/
|
||||
while (bl_params != NULL) {
|
||||
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;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
bl_params = bl_params->next_params_info;
|
||||
}
|
||||
|
||||
if (dt_open_and_check(dt_addr) < 0) {
|
||||
panic();
|
||||
}
|
||||
|
||||
if (bsec_probe() != 0) {
|
||||
panic();
|
||||
}
|
||||
|
||||
if (stm32mp1_clk_probe() < 0) {
|
||||
panic();
|
||||
}
|
||||
|
||||
(void)stm32mp_uart_console_setup();
|
||||
|
||||
stm32mp1_etzpc_early_setup();
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Initialize the MMU, security and the GIC.
|
||||
******************************************************************************/
|
||||
void sp_min_platform_setup(void)
|
||||
{
|
||||
generic_delay_timer_init();
|
||||
|
||||
stm32mp1_gic_init();
|
||||
|
||||
if (stm32_iwdg_init() < 0) {
|
||||
panic();
|
||||
}
|
||||
|
||||
stm32mp_lock_periph_registering();
|
||||
|
||||
stm32mp1_init_scmi_server();
|
||||
}
|
||||
|
||||
void sp_min_plat_arch_setup(void)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
.section .bl2_image
|
||||
.incbin BL2_BIN_PATH
|
||||
|
||||
.section .dtb_image
|
||||
.incbin DTB_BIN_PATH
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef STM32MP1_LD_S
|
||||
#define STM32MP1_LD_S
|
||||
|
||||
#include <lib/xlat_tables/xlat_tables_defs.h>
|
||||
#include <platform_def.h>
|
||||
|
||||
OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
|
||||
OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
|
||||
|
||||
ENTRY(__BL2_IMAGE_START__)
|
||||
|
||||
MEMORY {
|
||||
HEADER (rw) : ORIGIN = 0x00000000, LENGTH = STM32MP_HEADER_RESERVED_SIZE
|
||||
RAM (rwx) : ORIGIN = STM32MP_BINARY_BASE, LENGTH = STM32MP_BINARY_SIZE
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/*
|
||||
* TF mapping must conform to ROM code specification.
|
||||
*/
|
||||
.header : {
|
||||
__HEADER_START__ = .;
|
||||
KEEP(*(.header))
|
||||
. = ALIGN(4);
|
||||
__HEADER_END__ = .;
|
||||
} >HEADER
|
||||
|
||||
. = STM32MP_BINARY_BASE;
|
||||
.data . : {
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
__DATA_START__ = .;
|
||||
*(.data*)
|
||||
|
||||
/*
|
||||
* dtb.
|
||||
* The strongest and only alignment contraint is MMU 4K page.
|
||||
* Indeed as images below will be removed, 4K pages will be re-used.
|
||||
*/
|
||||
. = ( STM32MP_BL2_DTB_BASE - STM32MP_BINARY_BASE );
|
||||
__DTB_IMAGE_START__ = .;
|
||||
*(.dtb_image*)
|
||||
__DTB_IMAGE_END__ = .;
|
||||
|
||||
/*
|
||||
* bl2.
|
||||
* The strongest and only alignment contraint is MMU 4K page.
|
||||
* Indeed as images below will be removed, 4K pages will be re-used.
|
||||
*/
|
||||
#if SEPARATE_CODE_AND_RODATA
|
||||
. = ( STM32MP_BL2_RO_BASE - STM32MP_BINARY_BASE );
|
||||
#else
|
||||
. = ( STM32MP_BL2_BASE - STM32MP_BINARY_BASE );
|
||||
#endif
|
||||
__BL2_IMAGE_START__ = .;
|
||||
*(.bl2_image*)
|
||||
__BL2_IMAGE_END__ = .;
|
||||
|
||||
__DATA_END__ = .;
|
||||
} >RAM
|
||||
|
||||
__TF_END__ = .;
|
||||
|
||||
}
|
||||
#endif /* STM32MP1_LD_S */
|
||||
+209
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2022, STMicroelectronics - All Rights Reserved
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <drivers/nand.h>
|
||||
#include <drivers/raw_nand.h>
|
||||
#include <drivers/spi_nand.h>
|
||||
#include <drivers/spi_nor.h>
|
||||
#include <lib/utils.h>
|
||||
#include <plat/common/platform.h>
|
||||
|
||||
#if STM32MP_RAW_NAND || STM32MP_SPI_NAND
|
||||
#if STM32MP13
|
||||
void plat_get_scratch_buffer(void **buffer_addr, size_t *buf_size)
|
||||
{
|
||||
assert(buffer_addr != NULL);
|
||||
assert(buf_size != NULL);
|
||||
|
||||
*buffer_addr = (void *)STM32MP_MTD_BUFFER;
|
||||
*buf_size = PLATFORM_MTD_MAX_PAGE_SIZE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int get_data_from_otp(struct nand_device *nand_dev, bool is_slc)
|
||||
{
|
||||
uint32_t nand_param;
|
||||
uint32_t nand2_param __maybe_unused;
|
||||
|
||||
/* Check if NAND parameters are stored in OTP */
|
||||
if (stm32_get_otp_value(NAND_OTP, &nand_param) != 0) {
|
||||
ERROR("BSEC: NAND_OTP Error\n");
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
if (nand_param == 0U) {
|
||||
#if STM32MP13
|
||||
if (is_slc) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#if STM32MP15
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
if ((nand_param & NAND_PARAM_STORED_IN_OTP) == 0U) {
|
||||
#if STM32MP13
|
||||
if (is_slc) {
|
||||
goto ecc;
|
||||
}
|
||||
#endif
|
||||
#if STM32MP15
|
||||
goto ecc;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if STM32MP13
|
||||
if (stm32_get_otp_value(NAND2_OTP, &nand2_param) != 0) {
|
||||
ERROR("BSEC: NAND_OTP Error\n");
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
/* Check OTP configuration for this device */
|
||||
if ((((nand2_param & NAND2_CONFIG_DISTRIB) == NAND2_PNAND_NAND1_SNAND_NAND2) && !is_slc) ||
|
||||
(((nand2_param & NAND2_CONFIG_DISTRIB) == NAND2_PNAND_NAND2_SNAND_NAND1) && is_slc)) {
|
||||
nand_param = nand2_param << (NAND_PAGE_SIZE_SHIFT - NAND2_PAGE_SIZE_SHIFT);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* NAND parameter shall be read from OTP */
|
||||
if ((nand_param & NAND_WIDTH_MASK) != 0U) {
|
||||
nand_dev->buswidth = NAND_BUS_WIDTH_16;
|
||||
} else {
|
||||
nand_dev->buswidth = NAND_BUS_WIDTH_8;
|
||||
}
|
||||
|
||||
switch ((nand_param & NAND_PAGE_SIZE_MASK) >> NAND_PAGE_SIZE_SHIFT) {
|
||||
case NAND_PAGE_SIZE_2K:
|
||||
nand_dev->page_size = 0x800U;
|
||||
break;
|
||||
|
||||
case NAND_PAGE_SIZE_4K:
|
||||
nand_dev->page_size = 0x1000U;
|
||||
break;
|
||||
|
||||
case NAND_PAGE_SIZE_8K:
|
||||
nand_dev->page_size = 0x2000U;
|
||||
break;
|
||||
|
||||
default:
|
||||
ERROR("Cannot read NAND page size\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch ((nand_param & NAND_BLOCK_SIZE_MASK) >> NAND_BLOCK_SIZE_SHIFT) {
|
||||
case NAND_BLOCK_SIZE_64_PAGES:
|
||||
nand_dev->block_size = 64U * nand_dev->page_size;
|
||||
break;
|
||||
|
||||
case NAND_BLOCK_SIZE_128_PAGES:
|
||||
nand_dev->block_size = 128U * nand_dev->page_size;
|
||||
break;
|
||||
|
||||
case NAND_BLOCK_SIZE_256_PAGES:
|
||||
nand_dev->block_size = 256U * nand_dev->page_size;
|
||||
break;
|
||||
|
||||
default:
|
||||
ERROR("Cannot read NAND block size\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
nand_dev->size = ((nand_param & NAND_BLOCK_NB_MASK) >>
|
||||
NAND_BLOCK_NB_SHIFT) *
|
||||
NAND_BLOCK_NB_UNIT * nand_dev->block_size;
|
||||
|
||||
ecc:
|
||||
if (is_slc) {
|
||||
switch ((nand_param & NAND_ECC_BIT_NB_MASK) >>
|
||||
NAND_ECC_BIT_NB_SHIFT) {
|
||||
case NAND_ECC_BIT_NB_1_BITS:
|
||||
nand_dev->ecc.max_bit_corr = 1U;
|
||||
break;
|
||||
|
||||
case NAND_ECC_BIT_NB_4_BITS:
|
||||
nand_dev->ecc.max_bit_corr = 4U;
|
||||
break;
|
||||
|
||||
case NAND_ECC_BIT_NB_8_BITS:
|
||||
nand_dev->ecc.max_bit_corr = 8U;
|
||||
break;
|
||||
|
||||
case NAND_ECC_ON_DIE:
|
||||
nand_dev->ecc.mode = NAND_ECC_ONDIE;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (nand_dev->ecc.max_bit_corr == 0U) {
|
||||
ERROR("No valid eccbit number\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Selected multiple plane NAND */
|
||||
if ((nand_param & NAND_PLANE_BIT_NB_MASK) != 0U) {
|
||||
nand_dev->nb_planes = 2U;
|
||||
} else {
|
||||
nand_dev->nb_planes = 1U;
|
||||
}
|
||||
}
|
||||
|
||||
VERBOSE("OTP: Block %u Page %u Size %llu\n", nand_dev->block_size,
|
||||
nand_dev->page_size, nand_dev->size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* STM32MP_RAW_NAND || STM32MP_SPI_NAND */
|
||||
|
||||
#if STM32MP_RAW_NAND
|
||||
int plat_get_raw_nand_data(struct rawnand_device *device)
|
||||
{
|
||||
device->nand_dev->ecc.mode = NAND_ECC_HW;
|
||||
device->nand_dev->ecc.size = SZ_512;
|
||||
|
||||
return get_data_from_otp(device->nand_dev, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if STM32MP_SPI_NAND
|
||||
int plat_get_spi_nand_data(struct spinand_device *device)
|
||||
{
|
||||
zeromem(&device->spi_read_cache_op, sizeof(struct spi_mem_op));
|
||||
device->spi_read_cache_op.cmd.opcode = SPI_NAND_OP_READ_FROM_CACHE_4X;
|
||||
device->spi_read_cache_op.cmd.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
|
||||
device->spi_read_cache_op.addr.nbytes = 2U;
|
||||
device->spi_read_cache_op.addr.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
|
||||
device->spi_read_cache_op.dummy.nbytes = 1U;
|
||||
device->spi_read_cache_op.dummy.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
|
||||
device->spi_read_cache_op.data.buswidth = SPI_MEM_BUSWIDTH_4_LINE;
|
||||
device->spi_read_cache_op.data.dir = SPI_MEM_DATA_IN;
|
||||
|
||||
return get_data_from_otp(device->nand_dev, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if STM32MP_SPI_NOR
|
||||
int plat_get_nor_data(struct nor_device *device)
|
||||
{
|
||||
device->size = SZ_64M;
|
||||
|
||||
zeromem(&device->read_op, sizeof(struct spi_mem_op));
|
||||
device->read_op.cmd.opcode = SPI_NOR_OP_READ_1_1_4;
|
||||
device->read_op.cmd.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
|
||||
device->read_op.addr.nbytes = 3U;
|
||||
device->read_op.addr.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
|
||||
device->read_op.dummy.nbytes = 1U;
|
||||
device->read_op.dummy.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
|
||||
device->read_op.data.buswidth = SPI_MEM_BUSWIDTH_4_LINE;
|
||||
device->read_op.data.dir = SPI_MEM_DATA_IN;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2022, STMicroelectronics - All Rights Reserved
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <drivers/st/bsec.h>
|
||||
#include <drivers/st/bsec2_reg.h>
|
||||
#include <drivers/st/stm32mp1_rcc.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <lib/utils_def.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
#include <stm32mp1_dbgmcu.h>
|
||||
|
||||
#define DBGMCU_IDC U(0x00)
|
||||
|
||||
#define DBGMCU_IDC_DEV_ID_MASK GENMASK(11, 0)
|
||||
#define DBGMCU_IDC_REV_ID_MASK GENMASK(31, 16)
|
||||
#define DBGMCU_IDC_REV_ID_SHIFT 16
|
||||
|
||||
static int stm32mp1_dbgmcu_init(void)
|
||||
{
|
||||
if ((bsec_read_debug_conf() & BSEC_DBGSWGEN) == 0U) {
|
||||
INFO("Software access to all debug components is disabled\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
mmio_setbits_32(RCC_BASE + RCC_DBGCFGR, RCC_DBGCFGR_DBGCKEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Get silicon revision from DBGMCU registers.
|
||||
* @param chip_version: pointer to the read value.
|
||||
* @retval 0 on success, negative value on failure.
|
||||
*/
|
||||
int stm32mp1_dbgmcu_get_chip_version(uint32_t *chip_version)
|
||||
{
|
||||
assert(chip_version != NULL);
|
||||
|
||||
if (stm32mp1_dbgmcu_init() != 0) {
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
*chip_version = (mmio_read_32(DBGMCU_BASE + DBGMCU_IDC) &
|
||||
DBGMCU_IDC_REV_ID_MASK) >> DBGMCU_IDC_REV_ID_SHIFT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Get device ID from DBGMCU registers.
|
||||
* @param chip_dev_id: pointer to the read value.
|
||||
* @retval 0 on success, negative value on failure.
|
||||
*/
|
||||
int stm32mp1_dbgmcu_get_chip_dev_id(uint32_t *chip_dev_id)
|
||||
{
|
||||
assert(chip_dev_id != NULL);
|
||||
|
||||
if (stm32mp1_dbgmcu_init() != 0) {
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
*chip_dev_id = mmio_read_32(DBGMCU_BASE + DBGMCU_IDC) &
|
||||
DBGMCU_IDC_DEV_ID_MASK;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,669 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef STM32MP1_DEF_H
|
||||
#define STM32MP1_DEF_H
|
||||
|
||||
#include <common/tbbr/tbbr_img_def.h>
|
||||
#include <drivers/st/stm32mp1_rcc.h>
|
||||
#include <dt-bindings/clock/stm32mp1-clks.h>
|
||||
#include <dt-bindings/reset/stm32mp1-resets.h>
|
||||
#include <lib/utils_def.h>
|
||||
#include <lib/xlat_tables/xlat_tables_defs.h>
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
#include <drivers/st/bsec.h>
|
||||
#include <drivers/st/stm32mp1_clk.h>
|
||||
|
||||
#include <boot_api.h>
|
||||
#include <stm32mp_common.h>
|
||||
#include <stm32mp_dt.h>
|
||||
#include <stm32mp1_dbgmcu.h>
|
||||
#include <stm32mp1_private.h>
|
||||
#include <stm32mp1_shared_resources.h>
|
||||
#endif
|
||||
|
||||
#include "stm32mp1_fip_def.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* CHIP ID
|
||||
******************************************************************************/
|
||||
#if STM32MP13
|
||||
#define STM32MP1_CHIP_ID U(0x501)
|
||||
|
||||
#define STM32MP135C_PART_NB U(0x05010000)
|
||||
#define STM32MP135A_PART_NB U(0x05010001)
|
||||
#define STM32MP133C_PART_NB U(0x050100C0)
|
||||
#define STM32MP133A_PART_NB U(0x050100C1)
|
||||
#define STM32MP131C_PART_NB U(0x050106C8)
|
||||
#define STM32MP131A_PART_NB U(0x050106C9)
|
||||
#define STM32MP135F_PART_NB U(0x05010800)
|
||||
#define STM32MP135D_PART_NB U(0x05010801)
|
||||
#define STM32MP133F_PART_NB U(0x050108C0)
|
||||
#define STM32MP133D_PART_NB U(0x050108C1)
|
||||
#define STM32MP131F_PART_NB U(0x05010EC8)
|
||||
#define STM32MP131D_PART_NB U(0x05010EC9)
|
||||
#endif
|
||||
#if STM32MP15
|
||||
#define STM32MP1_CHIP_ID U(0x500)
|
||||
|
||||
#define STM32MP157C_PART_NB U(0x05000000)
|
||||
#define STM32MP157A_PART_NB U(0x05000001)
|
||||
#define STM32MP153C_PART_NB U(0x05000024)
|
||||
#define STM32MP153A_PART_NB U(0x05000025)
|
||||
#define STM32MP151C_PART_NB U(0x0500002E)
|
||||
#define STM32MP151A_PART_NB U(0x0500002F)
|
||||
#define STM32MP157F_PART_NB U(0x05000080)
|
||||
#define STM32MP157D_PART_NB U(0x05000081)
|
||||
#define STM32MP153F_PART_NB U(0x050000A4)
|
||||
#define STM32MP153D_PART_NB U(0x050000A5)
|
||||
#define STM32MP151F_PART_NB U(0x050000AE)
|
||||
#define STM32MP151D_PART_NB U(0x050000AF)
|
||||
#endif
|
||||
|
||||
#define STM32MP1_REV_B U(0x2000)
|
||||
#if STM32MP13
|
||||
#define STM32MP1_REV_Y U(0x1003)
|
||||
#define STM32MP1_REV_Z U(0x1001)
|
||||
#endif
|
||||
#if STM32MP15
|
||||
#define STM32MP1_REV_Z U(0x2001)
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* PACKAGE ID
|
||||
******************************************************************************/
|
||||
#if STM32MP15
|
||||
#define PKG_AA_LFBGA448 U(4)
|
||||
#define PKG_AB_LFBGA354 U(3)
|
||||
#define PKG_AC_TFBGA361 U(2)
|
||||
#define PKG_AD_TFBGA257 U(1)
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* STM32MP1 memory map related constants
|
||||
******************************************************************************/
|
||||
#define STM32MP_ROM_BASE U(0x00000000)
|
||||
#define STM32MP_ROM_SIZE U(0x00020000)
|
||||
#define STM32MP_ROM_SIZE_2MB_ALIGNED U(0x00200000)
|
||||
|
||||
#if STM32MP13
|
||||
#define STM32MP_SYSRAM_BASE U(0x2FFE0000)
|
||||
#define STM32MP_SYSRAM_SIZE U(0x00020000)
|
||||
#define SRAM1_BASE U(0x30000000)
|
||||
#define SRAM1_SIZE U(0x00004000)
|
||||
#define SRAM2_BASE U(0x30004000)
|
||||
#define SRAM2_SIZE U(0x00002000)
|
||||
#define SRAM3_BASE U(0x30006000)
|
||||
#define SRAM3_SIZE U(0x00002000)
|
||||
#define SRAMS_BASE SRAM1_BASE
|
||||
#define SRAMS_SIZE_2MB_ALIGNED U(0x00200000)
|
||||
#endif /* STM32MP13 */
|
||||
#if STM32MP15
|
||||
#define STM32MP_SYSRAM_BASE U(0x2FFC0000)
|
||||
#define STM32MP_SYSRAM_SIZE U(0x00040000)
|
||||
#endif /* STM32MP15 */
|
||||
|
||||
#define STM32MP_NS_SYSRAM_SIZE PAGE_SIZE
|
||||
#define STM32MP_NS_SYSRAM_BASE (STM32MP_SYSRAM_BASE + \
|
||||
STM32MP_SYSRAM_SIZE - \
|
||||
STM32MP_NS_SYSRAM_SIZE)
|
||||
|
||||
#define STM32MP_SCMI_NS_SHM_BASE STM32MP_NS_SYSRAM_BASE
|
||||
#define STM32MP_SCMI_NS_SHM_SIZE STM32MP_NS_SYSRAM_SIZE
|
||||
|
||||
#define STM32MP_SEC_SYSRAM_BASE STM32MP_SYSRAM_BASE
|
||||
#define STM32MP_SEC_SYSRAM_SIZE (STM32MP_SYSRAM_SIZE - \
|
||||
STM32MP_NS_SYSRAM_SIZE)
|
||||
|
||||
/* DDR configuration */
|
||||
#define STM32MP_DDR_BASE U(0xC0000000)
|
||||
#define STM32MP_DDR_MAX_SIZE U(0x40000000) /* Max 1GB */
|
||||
|
||||
/* DDR power initializations */
|
||||
#ifndef __ASSEMBLER__
|
||||
enum ddr_type {
|
||||
STM32MP_DDR3,
|
||||
STM32MP_LPDDR2,
|
||||
STM32MP_LPDDR3
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Section used inside TF binaries */
|
||||
#if STM32MP13
|
||||
/* 512 Octets reserved for header */
|
||||
#define STM32MP_HEADER_RESERVED_SIZE U(0x200)
|
||||
|
||||
#define STM32MP_BINARY_BASE STM32MP_SEC_SYSRAM_BASE
|
||||
|
||||
#define STM32MP_BINARY_SIZE STM32MP_SEC_SYSRAM_SIZE
|
||||
#endif
|
||||
#if STM32MP15
|
||||
#define STM32MP_PARAM_LOAD_SIZE U(0x00002400) /* 9 KB for param */
|
||||
/* 256 Octets reserved for header */
|
||||
#define STM32MP_HEADER_SIZE U(0x00000100)
|
||||
/* 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 + \
|
||||
STM32MP_PARAM_LOAD_SIZE + \
|
||||
STM32MP_HEADER_SIZE)
|
||||
|
||||
#define STM32MP_BINARY_SIZE (STM32MP_SEC_SYSRAM_SIZE - \
|
||||
(STM32MP_PARAM_LOAD_SIZE + \
|
||||
STM32MP_HEADER_SIZE))
|
||||
#endif
|
||||
|
||||
/* BL2 and BL32/sp_min require finer granularity tables */
|
||||
#if defined(IMAGE_BL2)
|
||||
#define MAX_XLAT_TABLES U(2) /* 8 KB for mapping */
|
||||
#endif
|
||||
|
||||
#if defined(IMAGE_BL32)
|
||||
#define MAX_XLAT_TABLES U(4) /* 16 KB for mapping */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* MAX_MMAP_REGIONS is usually:
|
||||
* BL stm32mp1_mmap size + mmap regions in *_plat_arch_setup
|
||||
*/
|
||||
#if defined(IMAGE_BL2)
|
||||
#if STM32MP_USB_PROGRAMMER
|
||||
#define MAX_MMAP_REGIONS 8
|
||||
#else
|
||||
#define MAX_MMAP_REGIONS 7
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if STM32MP13
|
||||
#define STM32MP_BL33_BASE STM32MP_DDR_BASE
|
||||
#endif
|
||||
#if STM32MP15
|
||||
#define STM32MP_BL33_BASE (STM32MP_DDR_BASE + U(0x100000))
|
||||
#endif
|
||||
#define STM32MP_BL33_MAX_SIZE U(0x400000)
|
||||
|
||||
/* Define maximum page size for NAND devices */
|
||||
#define PLATFORM_MTD_MAX_PAGE_SIZE U(0x1000)
|
||||
|
||||
/* Define location for the MTD scratch buffer */
|
||||
#if STM32MP13
|
||||
#define STM32MP_MTD_BUFFER (SRAM1_BASE + \
|
||||
SRAM1_SIZE - \
|
||||
PLATFORM_MTD_MAX_PAGE_SIZE)
|
||||
#endif
|
||||
/*******************************************************************************
|
||||
* STM32MP1 device/io map related constants (used for MMU)
|
||||
******************************************************************************/
|
||||
#define STM32MP1_DEVICE1_BASE U(0x40000000)
|
||||
#define STM32MP1_DEVICE1_SIZE U(0x40000000)
|
||||
|
||||
#define STM32MP1_DEVICE2_BASE U(0x80000000)
|
||||
#define STM32MP1_DEVICE2_SIZE U(0x40000000)
|
||||
|
||||
/*******************************************************************************
|
||||
* STM32MP1 RCC
|
||||
******************************************************************************/
|
||||
#define RCC_BASE U(0x50000000)
|
||||
|
||||
/*******************************************************************************
|
||||
* STM32MP1 PWR
|
||||
******************************************************************************/
|
||||
#define PWR_BASE U(0x50001000)
|
||||
|
||||
/*******************************************************************************
|
||||
* STM32MP1 GPIO
|
||||
******************************************************************************/
|
||||
#define GPIOA_BASE U(0x50002000)
|
||||
#define GPIOB_BASE U(0x50003000)
|
||||
#define GPIOC_BASE U(0x50004000)
|
||||
#define GPIOD_BASE U(0x50005000)
|
||||
#define GPIOE_BASE U(0x50006000)
|
||||
#define GPIOF_BASE U(0x50007000)
|
||||
#define GPIOG_BASE U(0x50008000)
|
||||
#define GPIOH_BASE U(0x50009000)
|
||||
#define GPIOI_BASE U(0x5000A000)
|
||||
#if STM32MP15
|
||||
#define GPIOJ_BASE U(0x5000B000)
|
||||
#define GPIOK_BASE U(0x5000C000)
|
||||
#define GPIOZ_BASE U(0x54004000)
|
||||
#endif
|
||||
#define GPIO_BANK_OFFSET U(0x1000)
|
||||
|
||||
/* Bank IDs used in GPIO driver API */
|
||||
#define GPIO_BANK_A U(0)
|
||||
#define GPIO_BANK_B U(1)
|
||||
#define GPIO_BANK_C U(2)
|
||||
#define GPIO_BANK_D U(3)
|
||||
#define GPIO_BANK_E U(4)
|
||||
#define GPIO_BANK_F U(5)
|
||||
#define GPIO_BANK_G U(6)
|
||||
#define GPIO_BANK_H U(7)
|
||||
#define GPIO_BANK_I U(8)
|
||||
#if STM32MP15
|
||||
#define GPIO_BANK_J U(9)
|
||||
#define GPIO_BANK_K U(10)
|
||||
#define GPIO_BANK_Z U(25)
|
||||
|
||||
#define STM32MP_GPIOZ_PIN_MAX_COUNT 8
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* STM32MP1 UART
|
||||
******************************************************************************/
|
||||
#if STM32MP13
|
||||
#define USART1_BASE U(0x4C000000)
|
||||
#define USART2_BASE U(0x4C001000)
|
||||
#endif
|
||||
#if STM32MP15
|
||||
#define USART1_BASE U(0x5C000000)
|
||||
#define USART2_BASE U(0x4000E000)
|
||||
#endif
|
||||
#define USART3_BASE U(0x4000F000)
|
||||
#define UART4_BASE U(0x40010000)
|
||||
#define UART5_BASE U(0x40011000)
|
||||
#define USART6_BASE U(0x44003000)
|
||||
#define UART7_BASE U(0x40018000)
|
||||
#define UART8_BASE U(0x40019000)
|
||||
|
||||
/* For UART crash console */
|
||||
#define STM32MP_DEBUG_USART_BASE UART4_BASE
|
||||
#if STM32MP13
|
||||
/* UART4 on HSI@64MHz, TX on GPIOF12 Alternate 8 (Disco board) */
|
||||
#define STM32MP_DEBUG_USART_CLK_FRQ 64000000
|
||||
#define DEBUG_UART_TX_GPIO_BANK_ADDRESS GPIOD_BASE
|
||||
#define DEBUG_UART_TX_GPIO_BANK_CLK_REG RCC_MP_S_AHB4ENSETR
|
||||
#define DEBUG_UART_TX_GPIO_BANK_CLK_EN RCC_MP_S_AHB4ENSETR_GPIODEN
|
||||
#define DEBUG_UART_TX_GPIO_PORT 6
|
||||
#define DEBUG_UART_TX_GPIO_ALTERNATE 8
|
||||
#define DEBUG_UART_TX_CLKSRC_REG RCC_UART4CKSELR
|
||||
#define DEBUG_UART_TX_CLKSRC RCC_UART4CKSELR_HSI
|
||||
#endif /* STM32MP13 */
|
||||
#if STM32MP15
|
||||
/* UART4 on HSI@64MHz, TX on GPIOG11 Alternate 6 */
|
||||
#define STM32MP_DEBUG_USART_CLK_FRQ 64000000
|
||||
#define DEBUG_UART_TX_GPIO_BANK_ADDRESS GPIOG_BASE
|
||||
#define DEBUG_UART_TX_GPIO_BANK_CLK_REG RCC_MP_AHB4ENSETR
|
||||
#define DEBUG_UART_TX_GPIO_BANK_CLK_EN RCC_MP_AHB4ENSETR_GPIOGEN
|
||||
#define DEBUG_UART_TX_GPIO_PORT 11
|
||||
#define DEBUG_UART_TX_GPIO_ALTERNATE 6
|
||||
#define DEBUG_UART_TX_CLKSRC_REG RCC_UART24CKSELR
|
||||
#define DEBUG_UART_TX_CLKSRC RCC_UART24CKSELR_HSI
|
||||
#endif /* STM32MP15 */
|
||||
#define DEBUG_UART_TX_EN_REG RCC_MP_APB1ENSETR
|
||||
#define DEBUG_UART_TX_EN RCC_MP_APB1ENSETR_UART4EN
|
||||
#define DEBUG_UART_RST_REG RCC_APB1RSTSETR
|
||||
#define DEBUG_UART_RST_BIT RCC_APB1RSTSETR_UART4RST
|
||||
|
||||
/*******************************************************************************
|
||||
* STM32MP1 ETZPC
|
||||
******************************************************************************/
|
||||
#define STM32MP1_ETZPC_BASE U(0x5C007000)
|
||||
|
||||
/* ETZPC TZMA IDs */
|
||||
#define STM32MP1_ETZPC_TZMA_ROM U(0)
|
||||
#define STM32MP1_ETZPC_TZMA_SYSRAM U(1)
|
||||
|
||||
#define STM32MP1_ETZPC_TZMA_ALL_SECURE GENMASK_32(9, 0)
|
||||
|
||||
/* ETZPC DECPROT IDs */
|
||||
#define STM32MP1_ETZPC_STGENC_ID 0
|
||||
#define STM32MP1_ETZPC_BKPSRAM_ID 1
|
||||
#define STM32MP1_ETZPC_IWDG1_ID 2
|
||||
#define STM32MP1_ETZPC_USART1_ID 3
|
||||
#define STM32MP1_ETZPC_SPI6_ID 4
|
||||
#define STM32MP1_ETZPC_I2C4_ID 5
|
||||
#define STM32MP1_ETZPC_RNG1_ID 7
|
||||
#define STM32MP1_ETZPC_HASH1_ID 8
|
||||
#define STM32MP1_ETZPC_CRYP1_ID 9
|
||||
#define STM32MP1_ETZPC_DDRCTRL_ID 10
|
||||
#define STM32MP1_ETZPC_DDRPHYC_ID 11
|
||||
#define STM32MP1_ETZPC_I2C6_ID 12
|
||||
#define STM32MP1_ETZPC_SEC_ID_LIMIT 13
|
||||
|
||||
#define STM32MP1_ETZPC_TIM2_ID 16
|
||||
#define STM32MP1_ETZPC_TIM3_ID 17
|
||||
#define STM32MP1_ETZPC_TIM4_ID 18
|
||||
#define STM32MP1_ETZPC_TIM5_ID 19
|
||||
#define STM32MP1_ETZPC_TIM6_ID 20
|
||||
#define STM32MP1_ETZPC_TIM7_ID 21
|
||||
#define STM32MP1_ETZPC_TIM12_ID 22
|
||||
#define STM32MP1_ETZPC_TIM13_ID 23
|
||||
#define STM32MP1_ETZPC_TIM14_ID 24
|
||||
#define STM32MP1_ETZPC_LPTIM1_ID 25
|
||||
#define STM32MP1_ETZPC_WWDG1_ID 26
|
||||
#define STM32MP1_ETZPC_SPI2_ID 27
|
||||
#define STM32MP1_ETZPC_SPI3_ID 28
|
||||
#define STM32MP1_ETZPC_SPDIFRX_ID 29
|
||||
#define STM32MP1_ETZPC_USART2_ID 30
|
||||
#define STM32MP1_ETZPC_USART3_ID 31
|
||||
#define STM32MP1_ETZPC_UART4_ID 32
|
||||
#define STM32MP1_ETZPC_UART5_ID 33
|
||||
#define STM32MP1_ETZPC_I2C1_ID 34
|
||||
#define STM32MP1_ETZPC_I2C2_ID 35
|
||||
#define STM32MP1_ETZPC_I2C3_ID 36
|
||||
#define STM32MP1_ETZPC_I2C5_ID 37
|
||||
#define STM32MP1_ETZPC_CEC_ID 38
|
||||
#define STM32MP1_ETZPC_DAC_ID 39
|
||||
#define STM32MP1_ETZPC_UART7_ID 40
|
||||
#define STM32MP1_ETZPC_UART8_ID 41
|
||||
#define STM32MP1_ETZPC_MDIOS_ID 44
|
||||
#define STM32MP1_ETZPC_TIM1_ID 48
|
||||
#define STM32MP1_ETZPC_TIM8_ID 49
|
||||
#define STM32MP1_ETZPC_USART6_ID 51
|
||||
#define STM32MP1_ETZPC_SPI1_ID 52
|
||||
#define STM32MP1_ETZPC_SPI4_ID 53
|
||||
#define STM32MP1_ETZPC_TIM15_ID 54
|
||||
#define STM32MP1_ETZPC_TIM16_ID 55
|
||||
#define STM32MP1_ETZPC_TIM17_ID 56
|
||||
#define STM32MP1_ETZPC_SPI5_ID 57
|
||||
#define STM32MP1_ETZPC_SAI1_ID 58
|
||||
#define STM32MP1_ETZPC_SAI2_ID 59
|
||||
#define STM32MP1_ETZPC_SAI3_ID 60
|
||||
#define STM32MP1_ETZPC_DFSDM_ID 61
|
||||
#define STM32MP1_ETZPC_TT_FDCAN_ID 62
|
||||
#define STM32MP1_ETZPC_LPTIM2_ID 64
|
||||
#define STM32MP1_ETZPC_LPTIM3_ID 65
|
||||
#define STM32MP1_ETZPC_LPTIM4_ID 66
|
||||
#define STM32MP1_ETZPC_LPTIM5_ID 67
|
||||
#define STM32MP1_ETZPC_SAI4_ID 68
|
||||
#define STM32MP1_ETZPC_VREFBUF_ID 69
|
||||
#define STM32MP1_ETZPC_DCMI_ID 70
|
||||
#define STM32MP1_ETZPC_CRC2_ID 71
|
||||
#define STM32MP1_ETZPC_ADC_ID 72
|
||||
#define STM32MP1_ETZPC_HASH2_ID 73
|
||||
#define STM32MP1_ETZPC_RNG2_ID 74
|
||||
#define STM32MP1_ETZPC_CRYP2_ID 75
|
||||
#define STM32MP1_ETZPC_SRAM1_ID 80
|
||||
#define STM32MP1_ETZPC_SRAM2_ID 81
|
||||
#define STM32MP1_ETZPC_SRAM3_ID 82
|
||||
#define STM32MP1_ETZPC_SRAM4_ID 83
|
||||
#define STM32MP1_ETZPC_RETRAM_ID 84
|
||||
#define STM32MP1_ETZPC_OTG_ID 85
|
||||
#define STM32MP1_ETZPC_SDMMC3_ID 86
|
||||
#define STM32MP1_ETZPC_DLYBSD3_ID 87
|
||||
#define STM32MP1_ETZPC_DMA1_ID 88
|
||||
#define STM32MP1_ETZPC_DMA2_ID 89
|
||||
#define STM32MP1_ETZPC_DMAMUX_ID 90
|
||||
#define STM32MP1_ETZPC_FMC_ID 91
|
||||
#define STM32MP1_ETZPC_QSPI_ID 92
|
||||
#define STM32MP1_ETZPC_DLYBQ_ID 93
|
||||
#define STM32MP1_ETZPC_ETH_ID 94
|
||||
#define STM32MP1_ETZPC_RSV_ID 95
|
||||
|
||||
#define STM32MP_ETZPC_MAX_ID 96
|
||||
|
||||
/*******************************************************************************
|
||||
* STM32MP1 TZC (TZ400)
|
||||
******************************************************************************/
|
||||
#define STM32MP1_TZC_BASE U(0x5C006000)
|
||||
|
||||
#if STM32MP13
|
||||
#define STM32MP1_FILTER_BIT_ALL TZC_400_REGION_ATTR_FILTER_BIT(0)
|
||||
#endif
|
||||
#if STM32MP15
|
||||
#define STM32MP1_FILTER_BIT_ALL (TZC_400_REGION_ATTR_FILTER_BIT(0) | \
|
||||
TZC_400_REGION_ATTR_FILTER_BIT(1))
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* STM32MP1 SDMMC
|
||||
******************************************************************************/
|
||||
#define STM32MP_SDMMC1_BASE U(0x58005000)
|
||||
#define STM32MP_SDMMC2_BASE U(0x58007000)
|
||||
#define STM32MP_SDMMC3_BASE U(0x48004000)
|
||||
|
||||
#define STM32MP_MMC_INIT_FREQ U(400000) /*400 KHz*/
|
||||
#define STM32MP_SD_NORMAL_SPEED_MAX_FREQ U(25000000) /*25 MHz*/
|
||||
#define STM32MP_SD_HIGH_SPEED_MAX_FREQ U(50000000) /*50 MHz*/
|
||||
#define STM32MP_EMMC_NORMAL_SPEED_MAX_FREQ U(26000000) /*26 MHz*/
|
||||
#define STM32MP_EMMC_HIGH_SPEED_MAX_FREQ U(52000000) /*52 MHz*/
|
||||
|
||||
/*******************************************************************************
|
||||
* STM32MP1 BSEC / OTP
|
||||
******************************************************************************/
|
||||
#define STM32MP1_OTP_MAX_ID 0x5FU
|
||||
#define STM32MP1_UPPER_OTP_START 0x20U
|
||||
|
||||
#define OTP_MAX_SIZE (STM32MP1_OTP_MAX_ID + 1U)
|
||||
|
||||
/* OTP labels */
|
||||
#define CFG0_OTP "cfg0_otp"
|
||||
#define PART_NUMBER_OTP "part_number_otp"
|
||||
#if STM32MP15
|
||||
#define PACKAGE_OTP "package_otp"
|
||||
#endif
|
||||
#define HW2_OTP "hw2_otp"
|
||||
#if STM32MP13
|
||||
#define NAND_OTP "cfg9_otp"
|
||||
#define NAND2_OTP "cfg10_otp"
|
||||
#endif
|
||||
#if STM32MP15
|
||||
#define NAND_OTP "nand_otp"
|
||||
#endif
|
||||
#define MONOTONIC_OTP "monotonic_otp"
|
||||
#define UID_OTP "uid_otp"
|
||||
#define PKH_OTP "pkh_otp"
|
||||
#define ENCKEY_OTP "enckey_otp"
|
||||
#define BOARD_ID_OTP "board_id"
|
||||
|
||||
/* OTP mask */
|
||||
/* CFG0 */
|
||||
#if STM32MP13
|
||||
#define CFG0_OTP_MODE_MASK GENMASK_32(9, 0)
|
||||
#define CFG0_OTP_MODE_SHIFT 0
|
||||
#define CFG0_OPEN_DEVICE 0x17U
|
||||
#define CFG0_CLOSED_DEVICE 0x3FU
|
||||
#define CFG0_CLOSED_DEVICE_NO_BOUNDARY_SCAN 0x17FU
|
||||
#define CFG0_CLOSED_DEVICE_NO_JTAG 0x3FFU
|
||||
#endif
|
||||
#if STM32MP15
|
||||
#define CFG0_CLOSED_DEVICE BIT(6)
|
||||
#endif
|
||||
|
||||
/* PART NUMBER */
|
||||
#if STM32MP13
|
||||
#define PART_NUMBER_OTP_PART_MASK GENMASK_32(11, 0)
|
||||
#endif
|
||||
#if STM32MP15
|
||||
#define PART_NUMBER_OTP_PART_MASK GENMASK_32(7, 0)
|
||||
#endif
|
||||
#define PART_NUMBER_OTP_PART_SHIFT 0
|
||||
|
||||
/* PACKAGE */
|
||||
#if STM32MP15
|
||||
#define PACKAGE_OTP_PKG_MASK GENMASK_32(29, 27)
|
||||
#define PACKAGE_OTP_PKG_SHIFT 27
|
||||
#endif
|
||||
|
||||
/* IWDG OTP */
|
||||
#define HW2_OTP_IWDG_HW_POS U(3)
|
||||
#define HW2_OTP_IWDG_FZ_STOP_POS U(5)
|
||||
#define HW2_OTP_IWDG_FZ_STANDBY_POS U(7)
|
||||
|
||||
/* HW2 OTP */
|
||||
#define HW2_OTP_PRODUCT_BELOW_2V5 BIT(13)
|
||||
|
||||
/* NAND OTP */
|
||||
/* NAND parameter storage flag */
|
||||
#define NAND_PARAM_STORED_IN_OTP BIT(31)
|
||||
|
||||
/* NAND page size in bytes */
|
||||
#define NAND_PAGE_SIZE_MASK GENMASK_32(30, 29)
|
||||
#define NAND_PAGE_SIZE_SHIFT 29
|
||||
#define NAND_PAGE_SIZE_2K U(0)
|
||||
#define NAND_PAGE_SIZE_4K U(1)
|
||||
#define NAND_PAGE_SIZE_8K U(2)
|
||||
|
||||
/* NAND block size in pages */
|
||||
#define NAND_BLOCK_SIZE_MASK GENMASK_32(28, 27)
|
||||
#define NAND_BLOCK_SIZE_SHIFT 27
|
||||
#define NAND_BLOCK_SIZE_64_PAGES U(0)
|
||||
#define NAND_BLOCK_SIZE_128_PAGES U(1)
|
||||
#define NAND_BLOCK_SIZE_256_PAGES U(2)
|
||||
|
||||
/* NAND number of block (in unit of 256 blocks) */
|
||||
#define NAND_BLOCK_NB_MASK GENMASK_32(26, 19)
|
||||
#define NAND_BLOCK_NB_SHIFT 19
|
||||
#define NAND_BLOCK_NB_UNIT U(256)
|
||||
|
||||
/* NAND bus width in bits */
|
||||
#define NAND_WIDTH_MASK BIT(18)
|
||||
#define NAND_WIDTH_SHIFT 18
|
||||
|
||||
/* NAND number of ECC bits per 512 bytes */
|
||||
#define NAND_ECC_BIT_NB_MASK GENMASK_32(17, 15)
|
||||
#define NAND_ECC_BIT_NB_SHIFT 15
|
||||
#define NAND_ECC_BIT_NB_UNSET U(0)
|
||||
#define NAND_ECC_BIT_NB_1_BITS U(1)
|
||||
#define NAND_ECC_BIT_NB_4_BITS U(2)
|
||||
#define NAND_ECC_BIT_NB_8_BITS U(3)
|
||||
#define NAND_ECC_ON_DIE U(4)
|
||||
|
||||
/* NAND number of planes */
|
||||
#define NAND_PLANE_BIT_NB_MASK BIT(14)
|
||||
|
||||
/* NAND2 OTP */
|
||||
#define NAND2_PAGE_SIZE_SHIFT 16
|
||||
|
||||
/* NAND2 config distribution */
|
||||
#define NAND2_CONFIG_DISTRIB BIT(0)
|
||||
#define NAND2_PNAND_NAND2_SNAND_NAND1 U(0)
|
||||
#define NAND2_PNAND_NAND1_SNAND_NAND2 U(1)
|
||||
|
||||
/* MONOTONIC OTP */
|
||||
#define MAX_MONOTONIC_VALUE 32
|
||||
|
||||
/* UID OTP */
|
||||
#define UID_WORD_NB U(3)
|
||||
|
||||
/* FWU configuration (max supported value is 15) */
|
||||
#define FWU_MAX_TRIAL_REBOOT U(3)
|
||||
|
||||
/*******************************************************************************
|
||||
* STM32MP1 TAMP
|
||||
******************************************************************************/
|
||||
#define TAMP_BASE U(0x5C00A000)
|
||||
#define TAMP_BKP_REGISTER_BASE (TAMP_BASE + U(0x100))
|
||||
#define TAMP_COUNTR U(0x40)
|
||||
|
||||
#if !(defined(__LINKER__) || defined(__ASSEMBLER__))
|
||||
static inline uintptr_t tamp_bkpr(uint32_t idx)
|
||||
{
|
||||
return TAMP_BKP_REGISTER_BASE + (idx << 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* STM32MP1 USB
|
||||
******************************************************************************/
|
||||
#define USB_OTG_BASE U(0x49000000)
|
||||
|
||||
/*******************************************************************************
|
||||
* STM32MP1 DDRCTRL
|
||||
******************************************************************************/
|
||||
#define DDRCTRL_BASE U(0x5A003000)
|
||||
|
||||
/*******************************************************************************
|
||||
* STM32MP1 DDRPHYC
|
||||
******************************************************************************/
|
||||
#define DDRPHYC_BASE U(0x5A004000)
|
||||
|
||||
/*******************************************************************************
|
||||
* STM32MP1 IWDG
|
||||
******************************************************************************/
|
||||
#define IWDG_MAX_INSTANCE U(2)
|
||||
#define IWDG1_INST U(0)
|
||||
#define IWDG2_INST U(1)
|
||||
|
||||
#define IWDG1_BASE U(0x5C003000)
|
||||
#define IWDG2_BASE U(0x5A002000)
|
||||
|
||||
/*******************************************************************************
|
||||
* Miscellaneous STM32MP1 peripherals base address
|
||||
******************************************************************************/
|
||||
#define BSEC_BASE U(0x5C005000)
|
||||
#if STM32MP13
|
||||
#define CRYP_BASE U(0x54002000)
|
||||
#endif
|
||||
#if STM32MP15
|
||||
#define CRYP1_BASE U(0x54001000)
|
||||
#endif
|
||||
#define DBGMCU_BASE U(0x50081000)
|
||||
#if STM32MP13
|
||||
#define HASH_BASE U(0x54003000)
|
||||
#endif
|
||||
#if STM32MP15
|
||||
#define HASH1_BASE U(0x54002000)
|
||||
#endif
|
||||
#if STM32MP13
|
||||
#define I2C3_BASE U(0x4C004000)
|
||||
#define I2C4_BASE U(0x4C005000)
|
||||
#define I2C5_BASE U(0x4C006000)
|
||||
#endif
|
||||
#if STM32MP15
|
||||
#define I2C4_BASE U(0x5C002000)
|
||||
#define I2C6_BASE U(0x5c009000)
|
||||
#endif
|
||||
#if STM32MP13
|
||||
#define RNG_BASE U(0x54004000)
|
||||
#endif
|
||||
#if STM32MP15
|
||||
#define RNG1_BASE U(0x54003000)
|
||||
#endif
|
||||
#define RTC_BASE U(0x5c004000)
|
||||
#if STM32MP13
|
||||
#define SPI4_BASE U(0x4C002000)
|
||||
#define SPI5_BASE U(0x4C003000)
|
||||
#endif
|
||||
#if STM32MP15
|
||||
#define SPI6_BASE U(0x5c001000)
|
||||
#endif
|
||||
#define STGEN_BASE U(0x5c008000)
|
||||
#define SYSCFG_BASE U(0x50020000)
|
||||
|
||||
/*******************************************************************************
|
||||
* STM32MP13 SAES
|
||||
******************************************************************************/
|
||||
#define SAES_BASE U(0x54005000)
|
||||
|
||||
/*******************************************************************************
|
||||
* STM32MP13 PKA
|
||||
******************************************************************************/
|
||||
#define PKA_BASE U(0x54006000)
|
||||
|
||||
/*******************************************************************************
|
||||
* REGULATORS
|
||||
******************************************************************************/
|
||||
/* 3 PWR + 1 VREFBUF + 14 PMIC regulators + 1 FIXED */
|
||||
#define PLAT_NB_RDEVS U(19)
|
||||
/* 2 FIXED */
|
||||
#define PLAT_NB_FIXED_REGS U(2)
|
||||
|
||||
/*******************************************************************************
|
||||
* Device Tree defines
|
||||
******************************************************************************/
|
||||
#define DT_BSEC_COMPAT "st,stm32mp15-bsec"
|
||||
#if STM32MP13
|
||||
#define DT_DDR_COMPAT "st,stm32mp13-ddr"
|
||||
#endif
|
||||
#if STM32MP15
|
||||
#define DT_DDR_COMPAT "st,stm32mp1-ddr"
|
||||
#endif
|
||||
#define DT_IWDG_COMPAT "st,stm32mp1-iwdg"
|
||||
#define DT_PWR_COMPAT "st,stm32mp1,pwr-reg"
|
||||
#if STM32MP13
|
||||
#define DT_RCC_CLK_COMPAT "st,stm32mp13-rcc"
|
||||
#define DT_RCC_SEC_CLK_COMPAT "st,stm32mp13-rcc-secure"
|
||||
#endif
|
||||
#if STM32MP15
|
||||
#define DT_RCC_CLK_COMPAT "st,stm32mp1-rcc"
|
||||
#define DT_RCC_SEC_CLK_COMPAT "st,stm32mp1-rcc-secure"
|
||||
#endif
|
||||
#define DT_SDMMC2_COMPAT "st,stm32-sdmmc2"
|
||||
#define DT_UART_COMPAT "st,stm32h7-uart"
|
||||
|
||||
#endif /* STM32MP1_DEF_H */
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <common/fdt_wrappers.h>
|
||||
#include <drivers/arm/tzc400.h>
|
||||
#include <drivers/clk.h>
|
||||
#include <dt-bindings/clock/stm32mp1-clks.h>
|
||||
#include <lib/fconf/fconf.h>
|
||||
#include <lib/object_pool.h>
|
||||
#include <libfdt.h>
|
||||
#include <tools_share/firmware_image_package.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
#include <stm32mp_fconf_getter.h>
|
||||
|
||||
#define STM32MP_REGION_PARAMS 4
|
||||
#define STM32MP_MAX_REGIONS 8
|
||||
#define FORCE_SEC_REGION BIT(31)
|
||||
|
||||
static uint32_t nb_regions;
|
||||
|
||||
struct dt_id_attr {
|
||||
fdt32_t id_attr[STM32MP_MAX_REGIONS];
|
||||
};
|
||||
|
||||
void stm32mp1_arch_security_setup(void)
|
||||
{
|
||||
#if STM32MP13
|
||||
clk_enable(TZC);
|
||||
#endif
|
||||
#if STM32MP15
|
||||
clk_enable(TZC1);
|
||||
clk_enable(TZC2);
|
||||
#endif
|
||||
|
||||
tzc400_init(STM32MP1_TZC_BASE);
|
||||
tzc400_disable_filters();
|
||||
|
||||
/*
|
||||
* Region 0 set to cover all DRAM at 0xC000_0000
|
||||
* Only secure access is granted in read/write.
|
||||
*/
|
||||
tzc400_configure_region0(TZC_REGION_S_RDWR, 0);
|
||||
|
||||
tzc400_set_action(TZC_ACTION_ERR);
|
||||
tzc400_enable_filters();
|
||||
}
|
||||
|
||||
void stm32mp1_security_setup(void)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
assert(nb_regions > 0U);
|
||||
|
||||
tzc400_init(STM32MP1_TZC_BASE);
|
||||
tzc400_disable_filters();
|
||||
|
||||
/*
|
||||
* Region 0 set to cover all DRAM at 0xC000_0000
|
||||
* No access is allowed.
|
||||
*/
|
||||
tzc400_configure_region0(TZC_REGION_S_NONE, 0);
|
||||
|
||||
for (i = 1U; i <= nb_regions; i++) {
|
||||
tzc400_update_filters(i, STM32MP1_FILTER_BIT_ALL);
|
||||
}
|
||||
|
||||
tzc400_set_action(TZC_ACTION_INT);
|
||||
tzc400_enable_filters();
|
||||
}
|
||||
|
||||
static int fconf_populate_stm32mp1_firewall(uintptr_t config)
|
||||
{
|
||||
int node, len;
|
||||
unsigned int i;
|
||||
const struct dt_id_attr *conf_list;
|
||||
const void *dtb = (const void *)config;
|
||||
|
||||
/* Assert the node offset point to "st,mem-firewall" compatible property */
|
||||
const char *compatible_str = "st,mem-firewall";
|
||||
|
||||
node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);
|
||||
if (node < 0) {
|
||||
ERROR("FCONF: Can't find %s compatible in dtb\n", compatible_str);
|
||||
return node;
|
||||
}
|
||||
|
||||
conf_list = (const struct dt_id_attr *)fdt_getprop(dtb, node, "memory-ranges", &len);
|
||||
if (conf_list == NULL) {
|
||||
WARN("FCONF: Read cell failed for %s\n", "memory-ranges");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Locate the memory cells and read all values */
|
||||
for (i = 0U; i < (unsigned int)(len / (sizeof(uint32_t) * STM32MP_REGION_PARAMS)); i++) {
|
||||
uint32_t base;
|
||||
uint32_t size;
|
||||
uint32_t sec_attr;
|
||||
uint32_t nsaid;
|
||||
|
||||
base = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS]);
|
||||
size = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 1]);
|
||||
sec_attr = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 2]);
|
||||
nsaid = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 3]);
|
||||
|
||||
VERBOSE("FCONF: stm32mp1-firewall cell found with value = 0x%x 0x%x 0x%x 0x%x\n",
|
||||
base, size, sec_attr, nsaid);
|
||||
|
||||
nb_regions++;
|
||||
|
||||
/* Configure region but keep disabled for secure access for BL2 load */
|
||||
tzc400_configure_region(0U, nb_regions, (unsigned long long)base,
|
||||
(unsigned long long)base + size - 1ULL, sec_attr, nsaid);
|
||||
}
|
||||
|
||||
/* Force flush as the value will be used cache off */
|
||||
flush_dcache_range((uintptr_t)&nb_regions, sizeof(uint32_t));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
FCONF_REGISTER_POPULATOR(FW_CONFIG, stm32mp1_firewall, fconf_populate_stm32mp1_firewall);
|
||||
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright (C) 2021-2022, STMicroelectronics - All Rights Reserved
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef STM32MP1_FIP_DEF_H
|
||||
#define STM32MP1_FIP_DEF_H
|
||||
|
||||
#if STM32MP15_OPTEE_RSV_SHM
|
||||
#define STM32MP_DDR_S_SIZE U(0x01E00000) /* 30 MB */
|
||||
#define STM32MP_DDR_SHMEM_SIZE U(0x00200000) /* 2 MB */
|
||||
#else
|
||||
#define STM32MP_DDR_S_SIZE U(0x02000000) /* 32 MB */
|
||||
#define STM32MP_DDR_SHMEM_SIZE U(0) /* empty */
|
||||
#endif
|
||||
|
||||
#if TRUSTED_BOARD_BOOT && !STM32MP_USE_EXTERNAL_HEAP
|
||||
#if STM32MP15
|
||||
#define STM32MP_BL2_RO_SIZE U(0x00014000) /* 80 KB */
|
||||
#define STM32MP_BL2_SIZE U(0x0001B000) /* 108 KB for BL2 */
|
||||
#endif /* STM32MP15 */
|
||||
#else /* TRUSTED_BOARD_BOOT && !STM32MP_USE_EXTERNAL_HEAP */
|
||||
#if STM32MP13
|
||||
#if BL2_IN_XIP_MEM
|
||||
#define STM32MP_BL2_RO_SIZE U(0x00015000) /* 84 KB */
|
||||
#define STM32MP_BL2_SIZE U(0x00017000) /* 92 KB for BL2 */
|
||||
#else
|
||||
/* STM32MP_BL2_RO_SIZE not used if !BL2_IN_XIP_MEM */
|
||||
#define STM32MP_BL2_SIZE U(0x0001B000) /* 108KB for BL2 */
|
||||
/* with 20KB for DTB, SYSRAM is full */
|
||||
#endif
|
||||
#endif /* STM32MP13 */
|
||||
#if STM32MP15
|
||||
#define STM32MP_BL2_RO_SIZE U(0x00011000) /* 68 KB */
|
||||
#define STM32MP_BL2_SIZE U(0x00016000) /* 88 KB for BL2 */
|
||||
#endif /* STM32MP15 */
|
||||
#endif /* TRUSTED_BOARD_BOOT && !STM32MP_USE_EXTERNAL_HEAP */
|
||||
|
||||
#if STM32MP13
|
||||
#if TRUSTED_BOARD_BOOT
|
||||
#define STM32MP_BL2_DTB_SIZE U(0x00005000) /* 20 KB for DTB */
|
||||
#else /* TRUSTED_BOARD_BOOT */
|
||||
#define STM32MP_BL2_DTB_SIZE U(0x00004000) /* 16 KB for DTB */
|
||||
#endif /* TRUSTED_BOARD_BOOT */
|
||||
#endif /* STM32MP13 */
|
||||
#if STM32MP15
|
||||
#define STM32MP_BL2_DTB_SIZE U(0x00007000) /* 28 KB for DTB */
|
||||
#endif /* STM32MP15 */
|
||||
#define STM32MP_BL32_SIZE U(0x0001B000) /* 108 KB for BL32 */
|
||||
#define STM32MP_BL32_DTB_SIZE U(0x00005000) /* 20 KB for DTB */
|
||||
#define STM32MP_FW_CONFIG_MAX_SIZE PAGE_SIZE /* 4 KB for FCONF DTB */
|
||||
#define STM32MP_HW_CONFIG_MAX_SIZE U(0x40000) /* 256 KB for HW config DTB */
|
||||
|
||||
#if STM32MP13
|
||||
#define STM32MP_BL2_BASE (STM32MP_BL2_DTB_BASE + \
|
||||
STM32MP_BL2_DTB_SIZE)
|
||||
#endif /* STM32MP13 */
|
||||
#if STM32MP15
|
||||
#define STM32MP_BL2_BASE (STM32MP_SEC_SYSRAM_BASE + \
|
||||
STM32MP_SEC_SYSRAM_SIZE - \
|
||||
STM32MP_BL2_SIZE)
|
||||
#endif /* STM32MP15 */
|
||||
|
||||
#define STM32MP_BL2_RO_BASE STM32MP_BL2_BASE
|
||||
|
||||
#define STM32MP_BL2_RW_BASE (STM32MP_BL2_RO_BASE + \
|
||||
STM32MP_BL2_RO_SIZE)
|
||||
|
||||
#if STM32MP13
|
||||
#define STM32MP_BL2_RW_SIZE (STM32MP_SYSRAM_BASE + \
|
||||
STM32MP_SYSRAM_SIZE - \
|
||||
STM32MP_BL2_RW_BASE)
|
||||
|
||||
#define STM32MP_BL2_DTB_BASE STM32MP_SEC_SYSRAM_BASE
|
||||
#endif /* STM32MP13 */
|
||||
#if STM32MP15
|
||||
#define STM32MP_BL2_RW_SIZE (STM32MP_SEC_SYSRAM_BASE + \
|
||||
STM32MP_SEC_SYSRAM_SIZE - \
|
||||
STM32MP_BL2_RW_BASE)
|
||||
|
||||
#define STM32MP_BL2_DTB_BASE (STM32MP_BL2_BASE - \
|
||||
STM32MP_BL2_DTB_SIZE)
|
||||
#endif /* STM32MP15 */
|
||||
|
||||
#define STM32MP_BL32_DTB_BASE STM32MP_SYSRAM_BASE
|
||||
|
||||
#define STM32MP_BL32_BASE (STM32MP_BL32_DTB_BASE + \
|
||||
STM32MP_BL32_DTB_SIZE)
|
||||
|
||||
|
||||
#if defined(IMAGE_BL2)
|
||||
#define STM32MP_DTB_SIZE STM32MP_BL2_DTB_SIZE
|
||||
#define STM32MP_DTB_BASE STM32MP_BL2_DTB_BASE
|
||||
#endif
|
||||
#if defined(IMAGE_BL32)
|
||||
#define STM32MP_DTB_SIZE STM32MP_BL32_DTB_SIZE
|
||||
#define STM32MP_DTB_BASE STM32MP_BL32_DTB_BASE
|
||||
#endif
|
||||
|
||||
#ifdef AARCH32_SP_OPTEE
|
||||
#define STM32MP_OPTEE_BASE STM32MP_SEC_SYSRAM_BASE
|
||||
|
||||
#define STM32MP_OPTEE_SIZE (STM32MP_BL2_DTB_BASE - \
|
||||
STM32MP_OPTEE_BASE)
|
||||
#endif
|
||||
|
||||
#if STM32MP13
|
||||
#define STM32MP_FW_CONFIG_BASE SRAM3_BASE
|
||||
#endif /* STM32MP13 */
|
||||
#if STM32MP15
|
||||
#define STM32MP_FW_CONFIG_BASE (STM32MP_SYSRAM_BASE + \
|
||||
STM32MP_SYSRAM_SIZE - \
|
||||
PAGE_SIZE)
|
||||
#endif /* STM32MP15 */
|
||||
#define STM32MP_HW_CONFIG_BASE (STM32MP_BL33_BASE + \
|
||||
STM32MP_BL33_MAX_SIZE)
|
||||
|
||||
/*
|
||||
* MAX_MMAP_REGIONS is usually:
|
||||
* BL stm32mp1_mmap size + mmap regions in *_plat_arch_setup
|
||||
*/
|
||||
#if defined(IMAGE_BL32)
|
||||
#define MAX_MMAP_REGIONS 10
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* STM32MP1 RAW partition offset for devices without GPT
|
||||
******************************************************************************/
|
||||
#define STM32MP_EMMC_BOOT_FIP_OFFSET U(0x00040000)
|
||||
#ifndef STM32MP_NOR_FIP_OFFSET
|
||||
#define STM32MP_NOR_FIP_OFFSET U(0x00080000)
|
||||
#endif
|
||||
#ifndef STM32MP_NAND_FIP_OFFSET
|
||||
#define STM32MP_NAND_FIP_OFFSET U(0x00200000)
|
||||
#endif
|
||||
|
||||
#endif /* STM32MP1_FIP_DEF_H */
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <libfdt.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
#include <common/bl_common.h>
|
||||
#include <common/debug.h>
|
||||
#include <drivers/arm/gicv2.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <lib/utils.h>
|
||||
#include <plat/common/platform.h>
|
||||
|
||||
struct stm32_gic_instance {
|
||||
uint32_t cells;
|
||||
uint32_t phandle_node;
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* On a GICv2 system, the Group 1 secure interrupts are treated as Group 0
|
||||
* interrupts.
|
||||
*****************************************************************************/
|
||||
static const interrupt_prop_t stm32mp1_interrupt_props[] = {
|
||||
PLATFORM_G1S_PROPS(GICV2_INTR_GROUP0),
|
||||
PLATFORM_G0_PROPS(GICV2_INTR_GROUP0)
|
||||
};
|
||||
|
||||
/* Fix target_mask_array as secondary core is not able to initialize it */
|
||||
static unsigned int target_mask_array[PLATFORM_CORE_COUNT] = {1, 2};
|
||||
|
||||
static gicv2_driver_data_t platform_gic_data = {
|
||||
.interrupt_props = stm32mp1_interrupt_props,
|
||||
.interrupt_props_num = ARRAY_SIZE(stm32mp1_interrupt_props),
|
||||
.target_masks = target_mask_array,
|
||||
.target_masks_num = ARRAY_SIZE(target_mask_array),
|
||||
};
|
||||
|
||||
static struct stm32_gic_instance stm32_gic;
|
||||
|
||||
void stm32mp1_gic_init(void)
|
||||
{
|
||||
int node;
|
||||
void *fdt;
|
||||
const fdt32_t *cuint;
|
||||
struct dt_node_info dt_gic;
|
||||
|
||||
if (fdt_get_address(&fdt) == 0) {
|
||||
panic();
|
||||
}
|
||||
|
||||
node = dt_get_node(&dt_gic, -1, "arm,cortex-a7-gic");
|
||||
if (node < 0) {
|
||||
panic();
|
||||
}
|
||||
|
||||
platform_gic_data.gicd_base = dt_gic.base;
|
||||
|
||||
cuint = fdt_getprop(fdt, node, "reg", NULL);
|
||||
if (cuint == NULL) {
|
||||
panic();
|
||||
}
|
||||
|
||||
platform_gic_data.gicc_base = fdt32_to_cpu(*(cuint + 2));
|
||||
|
||||
cuint = fdt_getprop(fdt, node, "#interrupt-cells", NULL);
|
||||
if (cuint == NULL) {
|
||||
panic();
|
||||
}
|
||||
|
||||
stm32_gic.cells = fdt32_to_cpu(*cuint);
|
||||
|
||||
stm32_gic.phandle_node = fdt_get_phandle(fdt, node);
|
||||
if (stm32_gic.phandle_node == 0U) {
|
||||
panic();
|
||||
}
|
||||
|
||||
gicv2_driver_init(&platform_gic_data);
|
||||
gicv2_distif_init();
|
||||
|
||||
stm32mp1_gic_pcpu_init();
|
||||
}
|
||||
|
||||
void stm32mp1_gic_pcpu_init(void)
|
||||
{
|
||||
gicv2_pcpu_distif_init();
|
||||
gicv2_set_pe_target_mask(plat_my_core_pos());
|
||||
gicv2_cpuif_enable();
|
||||
}
|
||||
@@ -0,0 +1,336 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
#include <arch.h>
|
||||
#include <asm_macros.S>
|
||||
#include <common/bl_common.h>
|
||||
#include <drivers/st/stm32_gpio.h>
|
||||
|
||||
#define GPIO_TX_SHIFT (DEBUG_UART_TX_GPIO_PORT << 1)
|
||||
|
||||
.globl platform_mem_init
|
||||
.globl plat_report_exception
|
||||
.globl plat_report_prefetch_abort
|
||||
.globl plat_report_data_abort
|
||||
.globl plat_get_my_entrypoint
|
||||
.globl plat_secondary_cold_boot_setup
|
||||
.globl plat_reset_handler
|
||||
.globl plat_is_my_cpu_primary
|
||||
.globl plat_my_core_pos
|
||||
.globl plat_crash_console_init
|
||||
.globl plat_crash_console_flush
|
||||
.globl plat_crash_console_putc
|
||||
.globl plat_panic_handler
|
||||
|
||||
func platform_mem_init
|
||||
/* Nothing to do, don't need to init SYSRAM */
|
||||
bx lr
|
||||
endfunc platform_mem_init
|
||||
|
||||
#if DEBUG
|
||||
func plat_report_exception
|
||||
mov r8, lr
|
||||
|
||||
/*
|
||||
* Test if an abort occurred
|
||||
* In this case the error message has already been displayed
|
||||
* by dedicated functions
|
||||
*/
|
||||
cmp r0, #MODE32_abt
|
||||
beq 1f
|
||||
|
||||
/* Test for an undefined instruction */
|
||||
cmp r0, #MODE32_und
|
||||
bne other_exception_lbl
|
||||
ldr r4, =undefined_str
|
||||
bl asm_print_str
|
||||
mrs r4, lr_und
|
||||
b print_exception_info
|
||||
|
||||
other_exception_lbl:
|
||||
/* Other exceptions */
|
||||
mov r9, r0
|
||||
ldr r4, =exception_start_str
|
||||
bl asm_print_str
|
||||
mov r4, r9
|
||||
bl asm_print_hex
|
||||
ldr r4, =exception_end_str
|
||||
bl asm_print_str
|
||||
mov r4, r6
|
||||
|
||||
print_exception_info:
|
||||
bl asm_print_hex
|
||||
|
||||
ldr r4, =end_error_str
|
||||
bl asm_print_str
|
||||
|
||||
1:
|
||||
bx r8
|
||||
endfunc plat_report_exception
|
||||
|
||||
func plat_report_prefetch_abort
|
||||
mov r8, lr
|
||||
mov r9, r0
|
||||
|
||||
ldr r4, =prefetch_abort_str
|
||||
bl asm_print_str
|
||||
|
||||
mov r4, r9
|
||||
sub r4, r4, #4
|
||||
bl asm_print_hex
|
||||
|
||||
ldr r4, =ifsr_str
|
||||
bl asm_print_str
|
||||
|
||||
ldcopr r4, IFSR
|
||||
bl asm_print_hex
|
||||
|
||||
ldr r4, =ifar_str
|
||||
bl asm_print_str
|
||||
|
||||
ldcopr r4, IFAR
|
||||
bl asm_print_hex
|
||||
|
||||
ldr r4, =end_error_str
|
||||
bl asm_print_str
|
||||
|
||||
bx r8
|
||||
endfunc plat_report_prefetch_abort
|
||||
|
||||
func plat_report_data_abort
|
||||
mov r8, lr
|
||||
mov r9, r0
|
||||
|
||||
ldr r4, =data_abort_str
|
||||
bl asm_print_str
|
||||
|
||||
mov r4, r9
|
||||
sub r4, r4, #8
|
||||
bl asm_print_hex
|
||||
|
||||
ldr r4, =dfsr_str
|
||||
bl asm_print_str
|
||||
|
||||
ldcopr r4, DFSR
|
||||
bl asm_print_hex
|
||||
|
||||
ldr r4, =dfar_str
|
||||
bl asm_print_str
|
||||
|
||||
ldcopr r4, DFAR
|
||||
bl asm_print_hex
|
||||
|
||||
ldr r4, =end_error_str
|
||||
bl asm_print_str
|
||||
|
||||
bx r8
|
||||
endfunc plat_report_data_abort
|
||||
#endif /* DEBUG */
|
||||
|
||||
func plat_reset_handler
|
||||
bx lr
|
||||
endfunc plat_reset_handler
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
* unsigned long plat_get_my_entrypoint (void);
|
||||
*
|
||||
* Main job of this routine is to distinguish between a cold and warm
|
||||
* boot.
|
||||
*
|
||||
* Currently supports only cold boot
|
||||
* ------------------------------------------------------------------
|
||||
*/
|
||||
func plat_get_my_entrypoint
|
||||
mov r0, #0
|
||||
bx lr
|
||||
endfunc plat_get_my_entrypoint
|
||||
|
||||
/* ---------------------------------------------
|
||||
* void plat_secondary_cold_boot_setup (void);
|
||||
*
|
||||
* Cold-booting secondary CPUs is not supported.
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
func plat_secondary_cold_boot_setup
|
||||
b .
|
||||
endfunc plat_secondary_cold_boot_setup
|
||||
|
||||
/* -----------------------------------------------------
|
||||
* unsigned int plat_is_my_cpu_primary (void);
|
||||
*
|
||||
* Find out whether the current cpu is the primary cpu.
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
func plat_is_my_cpu_primary
|
||||
ldcopr r0, MPIDR
|
||||
ldr r1, =(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
|
||||
and r0, r1
|
||||
cmp r0, #STM32MP_PRIMARY_CPU
|
||||
moveq r0, #1
|
||||
movne r0, #0
|
||||
bx lr
|
||||
endfunc plat_is_my_cpu_primary
|
||||
|
||||
/* -------------------------------------------
|
||||
* int plat_stm32mp1_get_core_pos(int mpidr);
|
||||
*
|
||||
* Return CorePos = (ClusterId * 4) + CoreId
|
||||
* -------------------------------------------
|
||||
*/
|
||||
func plat_stm32mp1_get_core_pos
|
||||
and r1, r0, #MPIDR_CPU_MASK
|
||||
and r0, r0, #MPIDR_CLUSTER_MASK
|
||||
add r0, r1, r0, LSR #6
|
||||
bx lr
|
||||
endfunc plat_stm32mp1_get_core_pos
|
||||
|
||||
/* ------------------------------------
|
||||
* unsigned int plat_my_core_pos(void)
|
||||
* ------------------------------------
|
||||
*/
|
||||
func plat_my_core_pos
|
||||
ldcopr r0, MPIDR
|
||||
b plat_stm32mp1_get_core_pos
|
||||
endfunc plat_my_core_pos
|
||||
|
||||
/* ---------------------------------------------
|
||||
* int plat_crash_console_init(void)
|
||||
*
|
||||
* Initialize the crash console without a C Runtime stack.
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
func plat_crash_console_init
|
||||
/* Reset UART peripheral */
|
||||
ldr r1, =(RCC_BASE + DEBUG_UART_RST_REG)
|
||||
ldr r2, =DEBUG_UART_RST_BIT
|
||||
str r2, [r1]
|
||||
1:
|
||||
ldr r0, [r1]
|
||||
ands r2, r0, r2
|
||||
beq 1b
|
||||
str r2, [r1, #4] /* RSTCLR register */
|
||||
2:
|
||||
ldr r0, [r1]
|
||||
ands r2, r0, r2
|
||||
bne 2b
|
||||
/* Enable GPIOs for UART TX */
|
||||
ldr r1, =(RCC_BASE + DEBUG_UART_TX_GPIO_BANK_CLK_REG)
|
||||
ldr r2, [r1]
|
||||
/* Configure GPIO */
|
||||
orr r2, r2, #DEBUG_UART_TX_GPIO_BANK_CLK_EN
|
||||
str r2, [r1]
|
||||
ldr r1, =DEBUG_UART_TX_GPIO_BANK_ADDRESS
|
||||
/* Set GPIO mode alternate */
|
||||
ldr r2, [r1, #GPIO_MODE_OFFSET]
|
||||
bic r2, r2, #(GPIO_MODE_MASK << GPIO_TX_SHIFT)
|
||||
orr r2, r2, #(GPIO_MODE_ALTERNATE << GPIO_TX_SHIFT)
|
||||
str r2, [r1, #GPIO_MODE_OFFSET]
|
||||
/* Set GPIO speed low */
|
||||
ldr r2, [r1, #GPIO_SPEED_OFFSET]
|
||||
bic r2, r2, #(GPIO_SPEED_MASK << GPIO_TX_SHIFT)
|
||||
str r2, [r1, #GPIO_SPEED_OFFSET]
|
||||
/* Set no-pull */
|
||||
ldr r2, [r1, #GPIO_PUPD_OFFSET]
|
||||
bic r2, r2, #(GPIO_PULL_MASK << GPIO_TX_SHIFT)
|
||||
str r2, [r1, #GPIO_PUPD_OFFSET]
|
||||
/* Set alternate */
|
||||
#if DEBUG_UART_TX_GPIO_PORT >= GPIO_ALT_LOWER_LIMIT
|
||||
ldr r2, [r1, #GPIO_AFRH_OFFSET]
|
||||
bic r2, r2, #(GPIO_ALTERNATE_MASK << \
|
||||
((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2))
|
||||
orr r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << \
|
||||
((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2))
|
||||
str r2, [r1, #GPIO_AFRH_OFFSET]
|
||||
#else
|
||||
ldr r2, [r1, #GPIO_AFRL_OFFSET]
|
||||
bic r2, r2, #(GPIO_ALTERNATE_MASK << (DEBUG_UART_TX_GPIO_PORT << 2))
|
||||
orr r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << (DEBUG_UART_TX_GPIO_PORT << 2))
|
||||
str r2, [r1, #GPIO_AFRL_OFFSET]
|
||||
#endif
|
||||
/* Enable UART clock, with its source */
|
||||
ldr r1, =(RCC_BASE + DEBUG_UART_TX_CLKSRC_REG)
|
||||
mov r2, #DEBUG_UART_TX_CLKSRC
|
||||
str r2, [r1]
|
||||
ldr r1, =(RCC_BASE + DEBUG_UART_TX_EN_REG)
|
||||
ldr r2, [r1]
|
||||
orr r2, r2, #DEBUG_UART_TX_EN
|
||||
str r2, [r1]
|
||||
|
||||
ldr r0, =STM32MP_DEBUG_USART_BASE
|
||||
ldr r1, =STM32MP_DEBUG_USART_CLK_FRQ
|
||||
ldr r2, =STM32MP_UART_BAUDRATE
|
||||
b console_stm32_core_init
|
||||
endfunc plat_crash_console_init
|
||||
|
||||
/* ---------------------------------------------
|
||||
* void plat_crash_console_flush(void)
|
||||
*
|
||||
* Flush the crash console without a C Runtime stack.
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
func plat_crash_console_flush
|
||||
ldr r0, =STM32MP_DEBUG_USART_BASE
|
||||
b console_stm32_core_flush
|
||||
endfunc plat_crash_console_flush
|
||||
|
||||
/* ---------------------------------------------
|
||||
* int plat_crash_console_putc(int c)
|
||||
*
|
||||
* Print a character on the crash console without a C Runtime stack.
|
||||
* Clobber list : r1 - r3
|
||||
*
|
||||
* In case of bootloading through uart, we keep console crash as this.
|
||||
* Characters could be sent to the programmer, but will be ignored.
|
||||
* No specific code in that case.
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
func plat_crash_console_putc
|
||||
ldr r1, =STM32MP_DEBUG_USART_BASE
|
||||
b console_stm32_core_putc
|
||||
endfunc plat_crash_console_putc
|
||||
|
||||
/* ----------------------------------------------------------
|
||||
* void plat_panic_handler(void) __dead2;
|
||||
* Report exception + endless loop.
|
||||
*
|
||||
* r6 holds the address where the fault occurred.
|
||||
* Filling lr with this value allows debuggers to reconstruct
|
||||
* the backtrace.
|
||||
* ----------------------------------------------------------
|
||||
*/
|
||||
func plat_panic_handler
|
||||
mrs r0, cpsr
|
||||
and r0, #MODE32_MASK
|
||||
bl plat_report_exception
|
||||
mov lr, r6
|
||||
b .
|
||||
endfunc plat_panic_handler
|
||||
|
||||
#if DEBUG
|
||||
.section .rodata.rev_err_str, "aS"
|
||||
prefetch_abort_str:
|
||||
.asciz "\nPrefetch Abort at: 0x"
|
||||
data_abort_str:
|
||||
.asciz "\nData Abort at: 0x"
|
||||
undefined_str:
|
||||
.asciz "\nUndefined instruction at: 0x"
|
||||
exception_start_str:
|
||||
.asciz "\nException mode=0x"
|
||||
exception_end_str:
|
||||
.asciz " at: 0x"
|
||||
dfsr_str:
|
||||
.asciz " DFSR = 0x"
|
||||
dfar_str:
|
||||
.asciz " DFAR = 0x"
|
||||
ifsr_str:
|
||||
.asciz " IFSR = 0x"
|
||||
ifar_str:
|
||||
.asciz " IFAR = 0x"
|
||||
end_error_str:
|
||||
.asciz "\n\r"
|
||||
#endif
|
||||
@@ -0,0 +1,243 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <bl32/sp_min/platform_sp_min.h>
|
||||
#include <common/debug.h>
|
||||
#include <drivers/arm/gic_common.h>
|
||||
#include <drivers/arm/gicv2.h>
|
||||
#include <drivers/clk.h>
|
||||
#include <dt-bindings/clock/stm32mp1-clks.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <lib/psci/psci.h>
|
||||
#include <plat/common/platform.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
static uintptr_t stm32_sec_entrypoint;
|
||||
static uint32_t cntfrq_core0;
|
||||
|
||||
/*******************************************************************************
|
||||
* STM32MP1 handler called when a CPU is about to enter standby.
|
||||
* call by core 1 to enter in wfi
|
||||
******************************************************************************/
|
||||
static void stm32_cpu_standby(plat_local_state_t cpu_state)
|
||||
{
|
||||
uint32_t interrupt = GIC_SPURIOUS_INTERRUPT;
|
||||
|
||||
assert(cpu_state == ARM_LOCAL_STATE_RET);
|
||||
|
||||
/*
|
||||
* Enter standby state
|
||||
* dsb is good practice before using wfi to enter low power states
|
||||
*/
|
||||
isb();
|
||||
dsb();
|
||||
while (interrupt == GIC_SPURIOUS_INTERRUPT) {
|
||||
wfi();
|
||||
|
||||
/* Acknoledge IT */
|
||||
interrupt = gicv2_acknowledge_interrupt();
|
||||
/* If Interrupt == 1022 it will be acknowledged by non secure */
|
||||
if ((interrupt != PENDING_G1_INTID) &&
|
||||
(interrupt != GIC_SPURIOUS_INTERRUPT)) {
|
||||
gicv2_end_of_interrupt(interrupt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* STM32MP1 handler called when a power domain is about to be turned on. The
|
||||
* mpidr determines the CPU to be turned on.
|
||||
* call by core 0 to activate core 1
|
||||
******************************************************************************/
|
||||
static int stm32_pwr_domain_on(u_register_t mpidr)
|
||||
{
|
||||
unsigned long current_cpu_mpidr = read_mpidr_el1();
|
||||
uintptr_t bkpr_core1_addr =
|
||||
tamp_bkpr(BOOT_API_CORE1_BRANCH_ADDRESS_TAMP_BCK_REG_IDX);
|
||||
uintptr_t bkpr_core1_magic =
|
||||
tamp_bkpr(BOOT_API_CORE1_MAGIC_NUMBER_TAMP_BCK_REG_IDX);
|
||||
|
||||
if (mpidr == current_cpu_mpidr) {
|
||||
return PSCI_E_INVALID_PARAMS;
|
||||
}
|
||||
|
||||
/* Only one valid entry point */
|
||||
if (stm32_sec_entrypoint != (uintptr_t)&sp_min_warm_entrypoint) {
|
||||
return PSCI_E_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
clk_enable(RTCAPB);
|
||||
|
||||
cntfrq_core0 = read_cntfrq_el0();
|
||||
|
||||
/* Write entrypoint in backup RAM register */
|
||||
mmio_write_32(bkpr_core1_addr, stm32_sec_entrypoint);
|
||||
|
||||
/* Write magic number in backup register */
|
||||
mmio_write_32(bkpr_core1_magic, BOOT_API_A7_CORE1_MAGIC_NUMBER);
|
||||
|
||||
clk_disable(RTCAPB);
|
||||
|
||||
/* Generate an IT to core 1 */
|
||||
gicv2_raise_sgi(ARM_IRQ_SEC_SGI_0, false, STM32MP_SECONDARY_CPU);
|
||||
|
||||
return PSCI_E_SUCCESS;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* STM32MP1 handler called when a power domain is about to be turned off. The
|
||||
* target_state encodes the power state that each level should transition to.
|
||||
******************************************************************************/
|
||||
static void stm32_pwr_domain_off(const psci_power_state_t *target_state)
|
||||
{
|
||||
/* Nothing to do */
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* STM32MP1 handler called when a power domain is about to be suspended. The
|
||||
* target_state encodes the power state that each level should transition to.
|
||||
******************************************************************************/
|
||||
static void stm32_pwr_domain_suspend(const psci_power_state_t *target_state)
|
||||
{
|
||||
/* Nothing to do, power domain is not disabled */
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* STM32MP1 handler called when a power domain has just been powered on after
|
||||
* being turned off earlier. The target_state encodes the low power state that
|
||||
* each level has woken up from.
|
||||
* call by core 1 just after wake up
|
||||
******************************************************************************/
|
||||
static void stm32_pwr_domain_on_finish(const psci_power_state_t *target_state)
|
||||
{
|
||||
stm32mp1_gic_pcpu_init();
|
||||
|
||||
write_cntfrq_el0(cntfrq_core0);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* STM32MP1 handler called when a power domain has just been powered on after
|
||||
* having been suspended earlier. The target_state encodes the low power state
|
||||
* that each level has woken up from.
|
||||
******************************************************************************/
|
||||
static void stm32_pwr_domain_suspend_finish(const psci_power_state_t
|
||||
*target_state)
|
||||
{
|
||||
/* Nothing to do, power domain is not disabled */
|
||||
}
|
||||
|
||||
static void __dead2 stm32_pwr_domain_pwr_down_wfi(const psci_power_state_t
|
||||
*target_state)
|
||||
{
|
||||
ERROR("stm32mpu1 Power Down WFI: operation not handled.\n");
|
||||
panic();
|
||||
}
|
||||
|
||||
static void __dead2 stm32_system_off(void)
|
||||
{
|
||||
ERROR("stm32mpu1 System Off: operation not handled.\n");
|
||||
panic();
|
||||
}
|
||||
|
||||
static void __dead2 stm32_system_reset(void)
|
||||
{
|
||||
mmio_setbits_32(stm32mp_rcc_base() + RCC_MP_GRSTCSETR,
|
||||
RCC_MP_GRSTCSETR_MPSYSRST);
|
||||
|
||||
/* Loop in case system reset is not immediately caught */
|
||||
for ( ; ; ) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
static int stm32_validate_power_state(unsigned int power_state,
|
||||
psci_power_state_t *req_state)
|
||||
{
|
||||
int pstate = psci_get_pstate_type(power_state);
|
||||
|
||||
if (pstate != 0) {
|
||||
return PSCI_E_INVALID_PARAMS;
|
||||
}
|
||||
|
||||
if (psci_get_pstate_pwrlvl(power_state)) {
|
||||
return PSCI_E_INVALID_PARAMS;
|
||||
}
|
||||
|
||||
if (psci_get_pstate_id(power_state)) {
|
||||
return PSCI_E_INVALID_PARAMS;
|
||||
}
|
||||
|
||||
req_state->pwr_domain_state[0] = ARM_LOCAL_STATE_RET;
|
||||
req_state->pwr_domain_state[1] = ARM_LOCAL_STATE_RUN;
|
||||
|
||||
return PSCI_E_SUCCESS;
|
||||
}
|
||||
|
||||
static int stm32_validate_ns_entrypoint(uintptr_t entrypoint)
|
||||
{
|
||||
/* The non-secure entry point must be in DDR */
|
||||
if (entrypoint < STM32MP_DDR_BASE) {
|
||||
return PSCI_E_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
return PSCI_E_SUCCESS;
|
||||
}
|
||||
|
||||
static int stm32_node_hw_state(u_register_t target_cpu,
|
||||
unsigned int power_level)
|
||||
{
|
||||
/*
|
||||
* The format of 'power_level' is implementation-defined, but 0 must
|
||||
* mean a CPU. Only allow level 0.
|
||||
*/
|
||||
if (power_level != MPIDR_AFFLVL0) {
|
||||
return PSCI_E_INVALID_PARAMS;
|
||||
}
|
||||
|
||||
/*
|
||||
* From psci view the CPU 0 is always ON,
|
||||
* CPU 1 can be SUSPEND or RUNNING.
|
||||
* Therefore do not manage POWER OFF state and always return HW_ON.
|
||||
*/
|
||||
|
||||
return (int)HW_ON;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Export the platform handlers. The ARM Standard platform layer will take care
|
||||
* of registering the handlers with PSCI.
|
||||
******************************************************************************/
|
||||
static const plat_psci_ops_t stm32_psci_ops = {
|
||||
.cpu_standby = stm32_cpu_standby,
|
||||
.pwr_domain_on = stm32_pwr_domain_on,
|
||||
.pwr_domain_off = stm32_pwr_domain_off,
|
||||
.pwr_domain_suspend = stm32_pwr_domain_suspend,
|
||||
.pwr_domain_on_finish = stm32_pwr_domain_on_finish,
|
||||
.pwr_domain_suspend_finish = stm32_pwr_domain_suspend_finish,
|
||||
.pwr_domain_pwr_down_wfi = stm32_pwr_domain_pwr_down_wfi,
|
||||
.system_off = stm32_system_off,
|
||||
.system_reset = stm32_system_reset,
|
||||
.validate_power_state = stm32_validate_power_state,
|
||||
.validate_ns_entrypoint = stm32_validate_ns_entrypoint,
|
||||
.get_node_hw_state = stm32_node_hw_state
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* Export the platform specific power ops.
|
||||
******************************************************************************/
|
||||
int plat_setup_psci_ops(uintptr_t sec_entrypoint,
|
||||
const plat_psci_ops_t **psci_ops)
|
||||
{
|
||||
stm32_sec_entrypoint = sec_entrypoint;
|
||||
*psci_ops = &stm32_psci_ops;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,788 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <drivers/clk.h>
|
||||
#include <drivers/st/stm32_gpio.h>
|
||||
#include <drivers/st/stm32_iwdg.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <lib/xlat_tables/xlat_tables_v2.h>
|
||||
#include <libfdt.h>
|
||||
|
||||
#include <plat/common/platform.h>
|
||||
#include <platform_def.h>
|
||||
|
||||
/* Internal layout of the 32bit OTP word board_id */
|
||||
#define BOARD_ID_BOARD_NB_MASK GENMASK(31, 16)
|
||||
#define BOARD_ID_BOARD_NB_SHIFT 16
|
||||
#define BOARD_ID_VARCPN_MASK GENMASK(15, 12)
|
||||
#define BOARD_ID_VARCPN_SHIFT 12
|
||||
#define BOARD_ID_REVISION_MASK GENMASK(11, 8)
|
||||
#define BOARD_ID_REVISION_SHIFT 8
|
||||
#define BOARD_ID_VARFG_MASK GENMASK(7, 4)
|
||||
#define BOARD_ID_VARFG_SHIFT 4
|
||||
#define BOARD_ID_BOM_MASK GENMASK(3, 0)
|
||||
|
||||
#define BOARD_ID2NB(_id) (((_id) & BOARD_ID_BOARD_NB_MASK) >> \
|
||||
BOARD_ID_BOARD_NB_SHIFT)
|
||||
#define BOARD_ID2VARCPN(_id) (((_id) & BOARD_ID_VARCPN_MASK) >> \
|
||||
BOARD_ID_VARCPN_SHIFT)
|
||||
#define BOARD_ID2REV(_id) (((_id) & BOARD_ID_REVISION_MASK) >> \
|
||||
BOARD_ID_REVISION_SHIFT)
|
||||
#define BOARD_ID2VARFG(_id) (((_id) & BOARD_ID_VARFG_MASK) >> \
|
||||
BOARD_ID_VARFG_SHIFT)
|
||||
#define BOARD_ID2BOM(_id) ((_id) & BOARD_ID_BOM_MASK)
|
||||
|
||||
#if STM32MP13
|
||||
#define TAMP_BOOT_MODE_BACKUP_REG_ID U(30)
|
||||
#endif
|
||||
#if STM32MP15
|
||||
#define TAMP_BOOT_MODE_BACKUP_REG_ID U(20)
|
||||
#endif
|
||||
#define TAMP_BOOT_MODE_ITF_MASK GENMASK(15, 8)
|
||||
#define TAMP_BOOT_MODE_ITF_SHIFT 8
|
||||
#define TAMP_BOOT_MODE_AUTH_MASK GENMASK(23, 16)
|
||||
#define TAMP_BOOT_MODE_AUTH_SHIFT 16
|
||||
|
||||
/*
|
||||
* Backup register to store fwu update information.
|
||||
* It should be writeable only by secure world, but also readable by non secure
|
||||
* (so it should be in Zone 2).
|
||||
*/
|
||||
#define TAMP_BOOT_FWU_INFO_REG_ID U(10)
|
||||
#define TAMP_BOOT_FWU_INFO_IDX_MSK GENMASK(3, 0)
|
||||
#define TAMP_BOOT_FWU_INFO_IDX_OFF U(0)
|
||||
#define TAMP_BOOT_FWU_INFO_CNT_MSK GENMASK(7, 4)
|
||||
#define TAMP_BOOT_FWU_INFO_CNT_OFF U(4)
|
||||
|
||||
#if defined(IMAGE_BL2)
|
||||
#define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \
|
||||
STM32MP_SYSRAM_SIZE, \
|
||||
MT_MEMORY | \
|
||||
MT_RW | \
|
||||
MT_SECURE | \
|
||||
MT_EXECUTE_NEVER)
|
||||
#elif defined(IMAGE_BL32)
|
||||
#define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SEC_SYSRAM_BASE, \
|
||||
STM32MP_SEC_SYSRAM_SIZE, \
|
||||
MT_MEMORY | \
|
||||
MT_RW | \
|
||||
MT_SECURE | \
|
||||
MT_EXECUTE_NEVER)
|
||||
|
||||
/* Non-secure SYSRAM is used a uncached memory for SCMI message transfer */
|
||||
#define MAP_NS_SYSRAM MAP_REGION_FLAT(STM32MP_NS_SYSRAM_BASE, \
|
||||
STM32MP_NS_SYSRAM_SIZE, \
|
||||
MT_DEVICE | \
|
||||
MT_RW | \
|
||||
MT_NS | \
|
||||
MT_EXECUTE_NEVER)
|
||||
#endif
|
||||
|
||||
#if STM32MP13
|
||||
#define MAP_SRAM_ALL MAP_REGION_FLAT(SRAMS_BASE, \
|
||||
SRAMS_SIZE_2MB_ALIGNED, \
|
||||
MT_MEMORY | \
|
||||
MT_RW | \
|
||||
MT_SECURE | \
|
||||
MT_EXECUTE_NEVER)
|
||||
#endif
|
||||
|
||||
#define MAP_DEVICE1 MAP_REGION_FLAT(STM32MP1_DEVICE1_BASE, \
|
||||
STM32MP1_DEVICE1_SIZE, \
|
||||
MT_DEVICE | \
|
||||
MT_RW | \
|
||||
MT_SECURE | \
|
||||
MT_EXECUTE_NEVER)
|
||||
|
||||
#define MAP_DEVICE2 MAP_REGION_FLAT(STM32MP1_DEVICE2_BASE, \
|
||||
STM32MP1_DEVICE2_SIZE, \
|
||||
MT_DEVICE | \
|
||||
MT_RW | \
|
||||
MT_SECURE | \
|
||||
MT_EXECUTE_NEVER)
|
||||
|
||||
#if defined(IMAGE_BL2)
|
||||
static const mmap_region_t stm32mp1_mmap[] = {
|
||||
MAP_SEC_SYSRAM,
|
||||
#if STM32MP13
|
||||
MAP_SRAM_ALL,
|
||||
#endif
|
||||
MAP_DEVICE1,
|
||||
#if STM32MP_RAW_NAND
|
||||
MAP_DEVICE2,
|
||||
#endif
|
||||
{0}
|
||||
};
|
||||
#endif
|
||||
#if defined(IMAGE_BL32)
|
||||
static const mmap_region_t stm32mp1_mmap[] = {
|
||||
MAP_SEC_SYSRAM,
|
||||
MAP_NS_SYSRAM,
|
||||
MAP_DEVICE1,
|
||||
MAP_DEVICE2,
|
||||
{0}
|
||||
};
|
||||
#endif
|
||||
|
||||
void configure_mmu(void)
|
||||
{
|
||||
mmap_add(stm32mp1_mmap);
|
||||
init_xlat_tables();
|
||||
|
||||
enable_mmu_svc_mon(0);
|
||||
}
|
||||
|
||||
uintptr_t stm32_get_gpio_bank_base(unsigned int bank)
|
||||
{
|
||||
#if STM32MP13
|
||||
assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_I);
|
||||
#endif
|
||||
#if STM32MP15
|
||||
if (bank == GPIO_BANK_Z) {
|
||||
return GPIOZ_BASE;
|
||||
}
|
||||
|
||||
assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
|
||||
#endif
|
||||
|
||||
return GPIOA_BASE + (bank * GPIO_BANK_OFFSET);
|
||||
}
|
||||
|
||||
uint32_t stm32_get_gpio_bank_offset(unsigned int bank)
|
||||
{
|
||||
#if STM32MP13
|
||||
assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_I);
|
||||
#endif
|
||||
#if STM32MP15
|
||||
if (bank == GPIO_BANK_Z) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
|
||||
#endif
|
||||
|
||||
return bank * GPIO_BANK_OFFSET;
|
||||
}
|
||||
|
||||
bool stm32_gpio_is_secure_at_reset(unsigned int bank)
|
||||
{
|
||||
#if STM32MP13
|
||||
return true;
|
||||
#endif
|
||||
#if STM32MP15
|
||||
if (bank == GPIO_BANK_Z) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned long stm32_get_gpio_bank_clock(unsigned int bank)
|
||||
{
|
||||
#if STM32MP13
|
||||
assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_I);
|
||||
#endif
|
||||
#if STM32MP15
|
||||
if (bank == GPIO_BANK_Z) {
|
||||
return GPIOZ;
|
||||
}
|
||||
|
||||
assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
|
||||
#endif
|
||||
|
||||
return GPIOA + (bank - GPIO_BANK_A);
|
||||
}
|
||||
|
||||
int stm32_get_gpio_bank_pinctrl_node(void *fdt, unsigned int bank)
|
||||
{
|
||||
const char *node_compatible = NULL;
|
||||
|
||||
switch (bank) {
|
||||
case GPIO_BANK_A:
|
||||
case GPIO_BANK_B:
|
||||
case GPIO_BANK_C:
|
||||
case GPIO_BANK_D:
|
||||
case GPIO_BANK_E:
|
||||
case GPIO_BANK_F:
|
||||
case GPIO_BANK_G:
|
||||
case GPIO_BANK_H:
|
||||
case GPIO_BANK_I:
|
||||
#if STM32MP13
|
||||
node_compatible = "st,stm32mp135-pinctrl";
|
||||
break;
|
||||
#endif
|
||||
#if STM32MP15
|
||||
case GPIO_BANK_J:
|
||||
case GPIO_BANK_K:
|
||||
node_compatible = "st,stm32mp157-pinctrl";
|
||||
break;
|
||||
case GPIO_BANK_Z:
|
||||
node_compatible = "st,stm32mp157-z-pinctrl";
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
panic();
|
||||
}
|
||||
|
||||
return fdt_node_offset_by_compatible(fdt, -1, node_compatible);
|
||||
}
|
||||
|
||||
#if STM32MP_UART_PROGRAMMER || !defined(IMAGE_BL2)
|
||||
/*
|
||||
* UART Management
|
||||
*/
|
||||
static const uintptr_t stm32mp1_uart_addresses[8] = {
|
||||
USART1_BASE,
|
||||
USART2_BASE,
|
||||
USART3_BASE,
|
||||
UART4_BASE,
|
||||
UART5_BASE,
|
||||
USART6_BASE,
|
||||
UART7_BASE,
|
||||
UART8_BASE,
|
||||
};
|
||||
|
||||
uintptr_t get_uart_address(uint32_t instance_nb)
|
||||
{
|
||||
if ((instance_nb == 0U) ||
|
||||
(instance_nb > ARRAY_SIZE(stm32mp1_uart_addresses))) {
|
||||
return 0U;
|
||||
}
|
||||
|
||||
return stm32mp1_uart_addresses[instance_nb - 1U];
|
||||
}
|
||||
#endif
|
||||
|
||||
#if STM32MP_USB_PROGRAMMER
|
||||
struct gpio_bank_pin_list {
|
||||
uint32_t bank;
|
||||
uint32_t pin;
|
||||
};
|
||||
|
||||
static const struct gpio_bank_pin_list gpio_list[] = {
|
||||
{ /* USART2_RX: GPIOA3 */
|
||||
.bank = 0U,
|
||||
.pin = 3U,
|
||||
},
|
||||
{ /* USART3_RX: GPIOB12 */
|
||||
.bank = 1U,
|
||||
.pin = 12U,
|
||||
},
|
||||
{ /* UART4_RX: GPIOB2 */
|
||||
.bank = 1U,
|
||||
.pin = 2U,
|
||||
},
|
||||
{ /* UART5_RX: GPIOB4 */
|
||||
.bank = 1U,
|
||||
.pin = 5U,
|
||||
},
|
||||
{ /* USART6_RX: GPIOC7 */
|
||||
.bank = 2U,
|
||||
.pin = 7U,
|
||||
},
|
||||
{ /* UART7_RX: GPIOF6 */
|
||||
.bank = 5U,
|
||||
.pin = 6U,
|
||||
},
|
||||
{ /* UART8_RX: GPIOE0 */
|
||||
.bank = 4U,
|
||||
.pin = 0U,
|
||||
},
|
||||
};
|
||||
|
||||
void stm32mp1_deconfigure_uart_pins(void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0U; i < ARRAY_SIZE(gpio_list); i++) {
|
||||
set_gpio_reset_cfg(gpio_list[i].bank, gpio_list[i].pin);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
uint32_t stm32mp_get_chip_version(void)
|
||||
{
|
||||
#if STM32MP13
|
||||
return stm32mp1_syscfg_get_chip_version();
|
||||
#endif
|
||||
#if STM32MP15
|
||||
uint32_t version = 0U;
|
||||
|
||||
if (stm32mp1_dbgmcu_get_chip_version(&version) < 0) {
|
||||
INFO("Cannot get CPU version, debug disabled\n");
|
||||
return 0U;
|
||||
}
|
||||
|
||||
return version;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t stm32mp_get_chip_dev_id(void)
|
||||
{
|
||||
#if STM32MP13
|
||||
return stm32mp1_syscfg_get_chip_dev_id();
|
||||
#endif
|
||||
#if STM32MP15
|
||||
uint32_t dev_id;
|
||||
|
||||
if (stm32mp1_dbgmcu_get_chip_dev_id(&dev_id) < 0) {
|
||||
INFO("Use default chip ID, debug disabled\n");
|
||||
dev_id = STM32MP1_CHIP_ID;
|
||||
}
|
||||
|
||||
return dev_id;
|
||||
#endif
|
||||
}
|
||||
|
||||
static uint32_t get_part_number(void)
|
||||
{
|
||||
static uint32_t part_number;
|
||||
|
||||
if (part_number != 0U) {
|
||||
return part_number;
|
||||
}
|
||||
|
||||
if (stm32_get_otp_value(PART_NUMBER_OTP, &part_number) != 0) {
|
||||
panic();
|
||||
}
|
||||
|
||||
part_number = (part_number & PART_NUMBER_OTP_PART_MASK) >>
|
||||
PART_NUMBER_OTP_PART_SHIFT;
|
||||
|
||||
part_number |= stm32mp_get_chip_dev_id() << 16;
|
||||
|
||||
return part_number;
|
||||
}
|
||||
|
||||
#if STM32MP15
|
||||
static uint32_t get_cpu_package(void)
|
||||
{
|
||||
uint32_t package;
|
||||
|
||||
if (stm32_get_otp_value(PACKAGE_OTP, &package) != 0) {
|
||||
panic();
|
||||
}
|
||||
|
||||
package = (package & PACKAGE_OTP_PKG_MASK) >>
|
||||
PACKAGE_OTP_PKG_SHIFT;
|
||||
|
||||
return package;
|
||||
}
|
||||
#endif
|
||||
|
||||
void stm32mp_get_soc_name(char name[STM32_SOC_NAME_SIZE])
|
||||
{
|
||||
char *cpu_s, *cpu_r, *pkg;
|
||||
|
||||
/* MPUs Part Numbers */
|
||||
switch (get_part_number()) {
|
||||
#if STM32MP13
|
||||
case STM32MP135F_PART_NB:
|
||||
cpu_s = "135F";
|
||||
break;
|
||||
case STM32MP135D_PART_NB:
|
||||
cpu_s = "135D";
|
||||
break;
|
||||
case STM32MP135C_PART_NB:
|
||||
cpu_s = "135C";
|
||||
break;
|
||||
case STM32MP135A_PART_NB:
|
||||
cpu_s = "135A";
|
||||
break;
|
||||
case STM32MP133F_PART_NB:
|
||||
cpu_s = "133F";
|
||||
break;
|
||||
case STM32MP133D_PART_NB:
|
||||
cpu_s = "133D";
|
||||
break;
|
||||
case STM32MP133C_PART_NB:
|
||||
cpu_s = "133C";
|
||||
break;
|
||||
case STM32MP133A_PART_NB:
|
||||
cpu_s = "133A";
|
||||
break;
|
||||
case STM32MP131F_PART_NB:
|
||||
cpu_s = "131F";
|
||||
break;
|
||||
case STM32MP131D_PART_NB:
|
||||
cpu_s = "131D";
|
||||
break;
|
||||
case STM32MP131C_PART_NB:
|
||||
cpu_s = "131C";
|
||||
break;
|
||||
case STM32MP131A_PART_NB:
|
||||
cpu_s = "131A";
|
||||
break;
|
||||
#endif
|
||||
#if STM32MP15
|
||||
case STM32MP157C_PART_NB:
|
||||
cpu_s = "157C";
|
||||
break;
|
||||
case STM32MP157A_PART_NB:
|
||||
cpu_s = "157A";
|
||||
break;
|
||||
case STM32MP153C_PART_NB:
|
||||
cpu_s = "153C";
|
||||
break;
|
||||
case STM32MP153A_PART_NB:
|
||||
cpu_s = "153A";
|
||||
break;
|
||||
case STM32MP151C_PART_NB:
|
||||
cpu_s = "151C";
|
||||
break;
|
||||
case STM32MP151A_PART_NB:
|
||||
cpu_s = "151A";
|
||||
break;
|
||||
case STM32MP157F_PART_NB:
|
||||
cpu_s = "157F";
|
||||
break;
|
||||
case STM32MP157D_PART_NB:
|
||||
cpu_s = "157D";
|
||||
break;
|
||||
case STM32MP153F_PART_NB:
|
||||
cpu_s = "153F";
|
||||
break;
|
||||
case STM32MP153D_PART_NB:
|
||||
cpu_s = "153D";
|
||||
break;
|
||||
case STM32MP151F_PART_NB:
|
||||
cpu_s = "151F";
|
||||
break;
|
||||
case STM32MP151D_PART_NB:
|
||||
cpu_s = "151D";
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
cpu_s = "????";
|
||||
break;
|
||||
}
|
||||
|
||||
/* Package */
|
||||
#if STM32MP13
|
||||
/* On STM32MP13, package is not present in OTP */
|
||||
pkg = "";
|
||||
#endif
|
||||
#if STM32MP15
|
||||
switch (get_cpu_package()) {
|
||||
case PKG_AA_LFBGA448:
|
||||
pkg = "AA";
|
||||
break;
|
||||
case PKG_AB_LFBGA354:
|
||||
pkg = "AB";
|
||||
break;
|
||||
case PKG_AC_TFBGA361:
|
||||
pkg = "AC";
|
||||
break;
|
||||
case PKG_AD_TFBGA257:
|
||||
pkg = "AD";
|
||||
break;
|
||||
default:
|
||||
pkg = "??";
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* REVISION */
|
||||
switch (stm32mp_get_chip_version()) {
|
||||
case STM32MP1_REV_B:
|
||||
cpu_r = "B";
|
||||
break;
|
||||
#if STM32MP13
|
||||
case STM32MP1_REV_Y:
|
||||
cpu_r = "Y";
|
||||
break;
|
||||
#endif
|
||||
case STM32MP1_REV_Z:
|
||||
cpu_r = "Z";
|
||||
break;
|
||||
default:
|
||||
cpu_r = "?";
|
||||
break;
|
||||
}
|
||||
|
||||
snprintf(name, STM32_SOC_NAME_SIZE,
|
||||
"STM32MP%s%s Rev.%s", cpu_s, pkg, cpu_r);
|
||||
}
|
||||
|
||||
void stm32mp_print_cpuinfo(void)
|
||||
{
|
||||
char name[STM32_SOC_NAME_SIZE];
|
||||
|
||||
stm32mp_get_soc_name(name);
|
||||
NOTICE("CPU: %s\n", name);
|
||||
}
|
||||
|
||||
void stm32mp_print_boardinfo(void)
|
||||
{
|
||||
uint32_t board_id = 0;
|
||||
|
||||
if (stm32_get_otp_value(BOARD_ID_OTP, &board_id) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (board_id != 0U) {
|
||||
char rev[2];
|
||||
|
||||
rev[0] = BOARD_ID2REV(board_id) - 1 + 'A';
|
||||
rev[1] = '\0';
|
||||
NOTICE("Board: MB%04x Var%u.%u Rev.%s-%02u\n",
|
||||
BOARD_ID2NB(board_id),
|
||||
BOARD_ID2VARCPN(board_id),
|
||||
BOARD_ID2VARFG(board_id),
|
||||
rev,
|
||||
BOARD_ID2BOM(board_id));
|
||||
}
|
||||
}
|
||||
|
||||
/* Return true when SoC provides a single Cortex-A7 core, and false otherwise */
|
||||
bool stm32mp_is_single_core(void)
|
||||
{
|
||||
#if STM32MP13
|
||||
return true;
|
||||
#endif
|
||||
#if STM32MP15
|
||||
bool single_core = false;
|
||||
|
||||
switch (get_part_number()) {
|
||||
case STM32MP151A_PART_NB:
|
||||
case STM32MP151C_PART_NB:
|
||||
case STM32MP151D_PART_NB:
|
||||
case STM32MP151F_PART_NB:
|
||||
single_core = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return single_core;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Return true when device is in closed state */
|
||||
bool stm32mp_is_closed_device(void)
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
if (stm32_get_otp_value(CFG0_OTP, &value) != 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#if STM32MP13
|
||||
value = (value & CFG0_OTP_MODE_MASK) >> CFG0_OTP_MODE_SHIFT;
|
||||
|
||||
switch (value) {
|
||||
case CFG0_OPEN_DEVICE:
|
||||
return false;
|
||||
case CFG0_CLOSED_DEVICE:
|
||||
case CFG0_CLOSED_DEVICE_NO_BOUNDARY_SCAN:
|
||||
case CFG0_CLOSED_DEVICE_NO_JTAG:
|
||||
return true;
|
||||
default:
|
||||
panic();
|
||||
}
|
||||
#endif
|
||||
#if STM32MP15
|
||||
return (value & CFG0_CLOSED_DEVICE) == CFG0_CLOSED_DEVICE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Return true when device supports secure boot */
|
||||
bool stm32mp_is_auth_supported(void)
|
||||
{
|
||||
bool supported = false;
|
||||
|
||||
switch (get_part_number()) {
|
||||
#if STM32MP13
|
||||
case STM32MP131C_PART_NB:
|
||||
case STM32MP131F_PART_NB:
|
||||
case STM32MP133C_PART_NB:
|
||||
case STM32MP133F_PART_NB:
|
||||
case STM32MP135C_PART_NB:
|
||||
case STM32MP135F_PART_NB:
|
||||
#endif
|
||||
#if STM32MP15
|
||||
case STM32MP151C_PART_NB:
|
||||
case STM32MP151F_PART_NB:
|
||||
case STM32MP153C_PART_NB:
|
||||
case STM32MP153F_PART_NB:
|
||||
case STM32MP157C_PART_NB:
|
||||
case STM32MP157F_PART_NB:
|
||||
#endif
|
||||
supported = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return supported;
|
||||
}
|
||||
|
||||
uint32_t stm32_iwdg_get_instance(uintptr_t base)
|
||||
{
|
||||
switch (base) {
|
||||
case IWDG1_BASE:
|
||||
return IWDG1_INST;
|
||||
case IWDG2_BASE:
|
||||
return IWDG2_INST;
|
||||
default:
|
||||
panic();
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t stm32_iwdg_get_otp_config(uint32_t iwdg_inst)
|
||||
{
|
||||
uint32_t iwdg_cfg = 0U;
|
||||
uint32_t otp_value;
|
||||
|
||||
if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) {
|
||||
panic();
|
||||
}
|
||||
|
||||
if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_HW_POS)) != 0U) {
|
||||
iwdg_cfg |= IWDG_HW_ENABLED;
|
||||
}
|
||||
|
||||
if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS)) != 0U) {
|
||||
iwdg_cfg |= IWDG_DISABLE_ON_STOP;
|
||||
}
|
||||
|
||||
if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS)) != 0U) {
|
||||
iwdg_cfg |= IWDG_DISABLE_ON_STANDBY;
|
||||
}
|
||||
|
||||
return iwdg_cfg;
|
||||
}
|
||||
|
||||
#if defined(IMAGE_BL2)
|
||||
uint32_t stm32_iwdg_shadow_update(uint32_t iwdg_inst, uint32_t flags)
|
||||
{
|
||||
uint32_t otp_value;
|
||||
uint32_t otp;
|
||||
uint32_t result;
|
||||
|
||||
if (stm32_get_otp_index(HW2_OTP, &otp, NULL) != 0) {
|
||||
panic();
|
||||
}
|
||||
|
||||
if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) {
|
||||
panic();
|
||||
}
|
||||
|
||||
if ((flags & IWDG_DISABLE_ON_STOP) != 0) {
|
||||
otp_value |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS);
|
||||
}
|
||||
|
||||
if ((flags & IWDG_DISABLE_ON_STANDBY) != 0) {
|
||||
otp_value |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS);
|
||||
}
|
||||
|
||||
result = bsec_write_otp(otp_value, otp);
|
||||
if (result != BSEC_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Sticky lock OTP_IWDG (read and write) */
|
||||
if ((bsec_set_sr_lock(otp) != BSEC_OK) ||
|
||||
(bsec_set_sw_lock(otp) != BSEC_OK)) {
|
||||
return BSEC_LOCK_FAIL;
|
||||
}
|
||||
|
||||
return BSEC_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
void stm32_save_boot_interface(uint32_t interface, uint32_t instance)
|
||||
{
|
||||
uintptr_t bkpr_itf_idx = tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
|
||||
|
||||
clk_enable(RTCAPB);
|
||||
|
||||
mmio_clrsetbits_32(bkpr_itf_idx,
|
||||
TAMP_BOOT_MODE_ITF_MASK,
|
||||
((interface << 4) | (instance & 0xFU)) <<
|
||||
TAMP_BOOT_MODE_ITF_SHIFT);
|
||||
|
||||
clk_disable(RTCAPB);
|
||||
}
|
||||
|
||||
void stm32_get_boot_interface(uint32_t *interface, uint32_t *instance)
|
||||
{
|
||||
static uint32_t itf;
|
||||
|
||||
if (itf == 0U) {
|
||||
uintptr_t bkpr = tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
|
||||
|
||||
clk_enable(RTCAPB);
|
||||
|
||||
itf = (mmio_read_32(bkpr) & TAMP_BOOT_MODE_ITF_MASK) >>
|
||||
TAMP_BOOT_MODE_ITF_SHIFT;
|
||||
|
||||
clk_disable(RTCAPB);
|
||||
}
|
||||
|
||||
*interface = itf >> 4;
|
||||
*instance = itf & 0xFU;
|
||||
}
|
||||
|
||||
void stm32_save_boot_auth(uint32_t auth_status, uint32_t boot_partition)
|
||||
{
|
||||
uint32_t boot_status = tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
|
||||
|
||||
clk_enable(RTCAPB);
|
||||
|
||||
mmio_clrsetbits_32(boot_status,
|
||||
TAMP_BOOT_MODE_AUTH_MASK,
|
||||
((auth_status << 4) | (boot_partition & 0xFU)) <<
|
||||
TAMP_BOOT_MODE_AUTH_SHIFT);
|
||||
|
||||
clk_disable(RTCAPB);
|
||||
}
|
||||
|
||||
#if PSA_FWU_SUPPORT
|
||||
void stm32mp1_fwu_set_boot_idx(void)
|
||||
{
|
||||
clk_enable(RTCAPB);
|
||||
mmio_clrsetbits_32(tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID),
|
||||
TAMP_BOOT_FWU_INFO_IDX_MSK,
|
||||
(plat_fwu_get_boot_idx() << TAMP_BOOT_FWU_INFO_IDX_OFF) &
|
||||
TAMP_BOOT_FWU_INFO_IDX_MSK);
|
||||
clk_disable(RTCAPB);
|
||||
}
|
||||
|
||||
uint32_t stm32_get_and_dec_fwu_trial_boot_cnt(void)
|
||||
{
|
||||
uintptr_t bkpr_fwu_cnt = tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID);
|
||||
uint32_t try_cnt;
|
||||
|
||||
clk_enable(RTCAPB);
|
||||
try_cnt = (mmio_read_32(bkpr_fwu_cnt) & TAMP_BOOT_FWU_INFO_CNT_MSK) >>
|
||||
TAMP_BOOT_FWU_INFO_CNT_OFF;
|
||||
|
||||
assert(try_cnt <= FWU_MAX_TRIAL_REBOOT);
|
||||
|
||||
if (try_cnt != 0U) {
|
||||
mmio_clrsetbits_32(bkpr_fwu_cnt, TAMP_BOOT_FWU_INFO_CNT_MSK,
|
||||
(try_cnt - 1U) << TAMP_BOOT_FWU_INFO_CNT_OFF);
|
||||
}
|
||||
clk_disable(RTCAPB);
|
||||
|
||||
return try_cnt;
|
||||
}
|
||||
|
||||
void stm32_set_max_fwu_trial_boot_cnt(void)
|
||||
{
|
||||
uintptr_t bkpr_fwu_cnt = tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID);
|
||||
|
||||
clk_enable(RTCAPB);
|
||||
mmio_clrsetbits_32(bkpr_fwu_cnt, TAMP_BOOT_FWU_INFO_CNT_MSK,
|
||||
(FWU_MAX_TRIAL_REBOOT << TAMP_BOOT_FWU_INFO_CNT_OFF) &
|
||||
TAMP_BOOT_FWU_INFO_CNT_MSK);
|
||||
clk_disable(RTCAPB);
|
||||
}
|
||||
#endif /* PSA_FWU_SUPPORT */
|
||||
@@ -0,0 +1,479 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2021, STMicroelectronics - All Rights Reserved
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
#include <drivers/clk.h>
|
||||
#include <drivers/scmi-msg.h>
|
||||
#include <drivers/scmi.h>
|
||||
#include <drivers/st/stm32mp1_clk.h>
|
||||
#include <drivers/st/stm32mp_reset.h>
|
||||
#include <dt-bindings/clock/stm32mp1-clks.h>
|
||||
#include <dt-bindings/reset/stm32mp1-resets.h>
|
||||
|
||||
#define TIMEOUT_US_1MS 1000U
|
||||
|
||||
#define SCMI_CLOCK_NAME_SIZE 16U
|
||||
#define SCMI_RSTD_NAME_SIZE 16U
|
||||
|
||||
/*
|
||||
* struct stm32_scmi_clk - Data for the exposed clock
|
||||
* @clock_id: Clock identifier in RCC clock driver
|
||||
* @name: Clock string ID exposed to agent
|
||||
* @enabled: State of the SCMI clock
|
||||
*/
|
||||
struct stm32_scmi_clk {
|
||||
unsigned long clock_id;
|
||||
const char *name;
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct stm32_scmi_rstd - Data for the exposed reset controller
|
||||
* @reset_id: Reset identifier in RCC reset driver
|
||||
* @name: Reset string ID exposed to agent
|
||||
*/
|
||||
struct stm32_scmi_rstd {
|
||||
unsigned long reset_id;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
/* Locate all non-secure SMT message buffers in last page of SYSRAM */
|
||||
#define SMT_BUFFER_BASE STM32MP_SCMI_NS_SHM_BASE
|
||||
#define SMT_BUFFER0_BASE SMT_BUFFER_BASE
|
||||
#define SMT_BUFFER1_BASE (SMT_BUFFER_BASE + 0x200)
|
||||
|
||||
CASSERT((STM32MP_SCMI_NS_SHM_BASE + STM32MP_SCMI_NS_SHM_SIZE) >=
|
||||
(SMT_BUFFER1_BASE + SMT_BUF_SLOT_SIZE),
|
||||
assert_scmi_non_secure_shm_fits_scmi_overall_buffer_size);
|
||||
|
||||
static struct scmi_msg_channel scmi_channel[] = {
|
||||
[0] = {
|
||||
.shm_addr = SMT_BUFFER0_BASE,
|
||||
.shm_size = SMT_BUF_SLOT_SIZE,
|
||||
},
|
||||
[1] = {
|
||||
.shm_addr = SMT_BUFFER1_BASE,
|
||||
.shm_size = SMT_BUF_SLOT_SIZE,
|
||||
},
|
||||
};
|
||||
|
||||
struct scmi_msg_channel *plat_scmi_get_channel(unsigned int agent_id)
|
||||
{
|
||||
assert(agent_id < ARRAY_SIZE(scmi_channel));
|
||||
|
||||
return &scmi_channel[agent_id];
|
||||
}
|
||||
|
||||
#define CLOCK_CELL(_scmi_id, _id, _name, _init_enabled) \
|
||||
[_scmi_id] = { \
|
||||
.clock_id = _id, \
|
||||
.name = _name, \
|
||||
.enabled = _init_enabled, \
|
||||
}
|
||||
|
||||
static struct stm32_scmi_clk stm32_scmi0_clock[] = {
|
||||
CLOCK_CELL(CK_SCMI0_HSE, CK_HSE, "ck_hse", true),
|
||||
CLOCK_CELL(CK_SCMI0_HSI, CK_HSI, "ck_hsi", true),
|
||||
CLOCK_CELL(CK_SCMI0_CSI, CK_CSI, "ck_csi", true),
|
||||
CLOCK_CELL(CK_SCMI0_LSE, CK_LSE, "ck_lse", true),
|
||||
CLOCK_CELL(CK_SCMI0_LSI, CK_LSI, "ck_lsi", true),
|
||||
CLOCK_CELL(CK_SCMI0_PLL2_Q, PLL2_Q, "pll2_q", true),
|
||||
CLOCK_CELL(CK_SCMI0_PLL2_R, PLL2_R, "pll2_r", true),
|
||||
CLOCK_CELL(CK_SCMI0_MPU, CK_MPU, "ck_mpu", true),
|
||||
CLOCK_CELL(CK_SCMI0_AXI, CK_AXI, "ck_axi", true),
|
||||
CLOCK_CELL(CK_SCMI0_BSEC, BSEC, "bsec", true),
|
||||
CLOCK_CELL(CK_SCMI0_CRYP1, CRYP1, "cryp1", false),
|
||||
CLOCK_CELL(CK_SCMI0_GPIOZ, GPIOZ, "gpioz", false),
|
||||
CLOCK_CELL(CK_SCMI0_HASH1, HASH1, "hash1", false),
|
||||
CLOCK_CELL(CK_SCMI0_I2C4, I2C4_K, "i2c4_k", false),
|
||||
CLOCK_CELL(CK_SCMI0_I2C6, I2C6_K, "i2c6_k", false),
|
||||
CLOCK_CELL(CK_SCMI0_IWDG1, IWDG1, "iwdg1", false),
|
||||
CLOCK_CELL(CK_SCMI0_RNG1, RNG1_K, "rng1_k", true),
|
||||
CLOCK_CELL(CK_SCMI0_RTC, RTC, "ck_rtc", true),
|
||||
CLOCK_CELL(CK_SCMI0_RTCAPB, RTCAPB, "rtcapb", true),
|
||||
CLOCK_CELL(CK_SCMI0_SPI6, SPI6_K, "spi6_k", false),
|
||||
CLOCK_CELL(CK_SCMI0_USART1, USART1_K, "usart1_k", false),
|
||||
};
|
||||
|
||||
static struct stm32_scmi_clk stm32_scmi1_clock[] = {
|
||||
CLOCK_CELL(CK_SCMI1_PLL3_Q, PLL3_Q, "pll3_q", true),
|
||||
CLOCK_CELL(CK_SCMI1_PLL3_R, PLL3_R, "pll3_r", true),
|
||||
CLOCK_CELL(CK_SCMI1_MCU, CK_MCU, "ck_mcu", false),
|
||||
};
|
||||
|
||||
#define RESET_CELL(_scmi_id, _id, _name) \
|
||||
[_scmi_id] = { \
|
||||
.reset_id = _id, \
|
||||
.name = _name, \
|
||||
}
|
||||
|
||||
static struct stm32_scmi_rstd stm32_scmi0_reset_domain[] = {
|
||||
RESET_CELL(RST_SCMI0_SPI6, SPI6_R, "spi6"),
|
||||
RESET_CELL(RST_SCMI0_I2C4, I2C4_R, "i2c4"),
|
||||
RESET_CELL(RST_SCMI0_I2C6, I2C6_R, "i2c6"),
|
||||
RESET_CELL(RST_SCMI0_USART1, USART1_R, "usart1"),
|
||||
RESET_CELL(RST_SCMI0_STGEN, STGEN_R, "stgen"),
|
||||
RESET_CELL(RST_SCMI0_GPIOZ, GPIOZ_R, "gpioz"),
|
||||
RESET_CELL(RST_SCMI0_CRYP1, CRYP1_R, "cryp1"),
|
||||
RESET_CELL(RST_SCMI0_HASH1, HASH1_R, "hash1"),
|
||||
RESET_CELL(RST_SCMI0_RNG1, RNG1_R, "rng1"),
|
||||
RESET_CELL(RST_SCMI0_MDMA, MDMA_R, "mdma"),
|
||||
RESET_CELL(RST_SCMI0_MCU, MCU_R, "mcu"),
|
||||
};
|
||||
|
||||
struct scmi_agent_resources {
|
||||
struct stm32_scmi_clk *clock;
|
||||
size_t clock_count;
|
||||
struct stm32_scmi_rstd *rstd;
|
||||
size_t rstd_count;
|
||||
};
|
||||
|
||||
static const struct scmi_agent_resources agent_resources[] = {
|
||||
[0] = {
|
||||
.clock = stm32_scmi0_clock,
|
||||
.clock_count = ARRAY_SIZE(stm32_scmi0_clock),
|
||||
.rstd = stm32_scmi0_reset_domain,
|
||||
.rstd_count = ARRAY_SIZE(stm32_scmi0_reset_domain),
|
||||
},
|
||||
[1] = {
|
||||
.clock = stm32_scmi1_clock,
|
||||
.clock_count = ARRAY_SIZE(stm32_scmi1_clock),
|
||||
},
|
||||
};
|
||||
|
||||
static const struct scmi_agent_resources *find_resource(unsigned int agent_id)
|
||||
{
|
||||
assert(agent_id < ARRAY_SIZE(agent_resources));
|
||||
|
||||
return &agent_resources[agent_id];
|
||||
}
|
||||
|
||||
#if ENABLE_ASSERTIONS
|
||||
static size_t plat_scmi_protocol_count_paranoid(void)
|
||||
{
|
||||
unsigned int n = 0U;
|
||||
unsigned int count = 0U;
|
||||
|
||||
for (n = 0U; n < ARRAY_SIZE(agent_resources); n++) {
|
||||
if (agent_resources[n].clock_count) {
|
||||
count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (n = 0U; n < ARRAY_SIZE(agent_resources); n++) {
|
||||
if (agent_resources[n].rstd_count) {
|
||||
count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const char vendor[] = "ST";
|
||||
static const char sub_vendor[] = "";
|
||||
|
||||
const char *plat_scmi_vendor_name(void)
|
||||
{
|
||||
return vendor;
|
||||
}
|
||||
|
||||
const char *plat_scmi_sub_vendor_name(void)
|
||||
{
|
||||
return sub_vendor;
|
||||
}
|
||||
|
||||
/* Currently supporting Clocks and Reset Domains */
|
||||
static const uint8_t plat_protocol_list[] = {
|
||||
SCMI_PROTOCOL_ID_CLOCK,
|
||||
SCMI_PROTOCOL_ID_RESET_DOMAIN,
|
||||
0U /* Null termination */
|
||||
};
|
||||
|
||||
size_t plat_scmi_protocol_count(void)
|
||||
{
|
||||
const size_t count = ARRAY_SIZE(plat_protocol_list) - 1U;
|
||||
|
||||
assert(count == plat_scmi_protocol_count_paranoid());
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
const uint8_t *plat_scmi_protocol_list(unsigned int agent_id __unused)
|
||||
{
|
||||
assert(plat_scmi_protocol_count_paranoid() ==
|
||||
(ARRAY_SIZE(plat_protocol_list) - 1U));
|
||||
|
||||
return plat_protocol_list;
|
||||
}
|
||||
|
||||
/*
|
||||
* Platform SCMI clocks
|
||||
*/
|
||||
static struct stm32_scmi_clk *find_clock(unsigned int agent_id,
|
||||
unsigned int scmi_id)
|
||||
{
|
||||
const struct scmi_agent_resources *resource = find_resource(agent_id);
|
||||
size_t n = 0U;
|
||||
|
||||
if (resource != NULL) {
|
||||
for (n = 0U; n < resource->clock_count; n++) {
|
||||
if (n == scmi_id) {
|
||||
return &resource->clock[n];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t plat_scmi_clock_count(unsigned int agent_id)
|
||||
{
|
||||
const struct scmi_agent_resources *resource = find_resource(agent_id);
|
||||
|
||||
if (resource == NULL) {
|
||||
return 0U;
|
||||
}
|
||||
|
||||
return resource->clock_count;
|
||||
}
|
||||
|
||||
const char *plat_scmi_clock_get_name(unsigned int agent_id,
|
||||
unsigned int scmi_id)
|
||||
{
|
||||
struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id);
|
||||
|
||||
if ((clock == NULL) ||
|
||||
!stm32mp_nsec_can_access_clock(clock->clock_id)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return clock->name;
|
||||
}
|
||||
|
||||
int32_t plat_scmi_clock_rates_array(unsigned int agent_id, unsigned int scmi_id,
|
||||
unsigned long *array, size_t *nb_elts)
|
||||
{
|
||||
struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id);
|
||||
|
||||
if (clock == NULL) {
|
||||
return SCMI_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (!stm32mp_nsec_can_access_clock(clock->clock_id)) {
|
||||
return SCMI_DENIED;
|
||||
}
|
||||
|
||||
if (array == NULL) {
|
||||
*nb_elts = 1U;
|
||||
} else if (*nb_elts == 1U) {
|
||||
*array = clk_get_rate(clock->clock_id);
|
||||
} else {
|
||||
return SCMI_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
return SCMI_SUCCESS;
|
||||
}
|
||||
|
||||
unsigned long plat_scmi_clock_get_rate(unsigned int agent_id,
|
||||
unsigned int scmi_id)
|
||||
{
|
||||
struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id);
|
||||
|
||||
if ((clock == NULL) ||
|
||||
!stm32mp_nsec_can_access_clock(clock->clock_id)) {
|
||||
return 0U;
|
||||
}
|
||||
|
||||
return clk_get_rate(clock->clock_id);
|
||||
}
|
||||
|
||||
int32_t plat_scmi_clock_get_state(unsigned int agent_id, unsigned int scmi_id)
|
||||
{
|
||||
struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id);
|
||||
|
||||
if ((clock == NULL) ||
|
||||
!stm32mp_nsec_can_access_clock(clock->clock_id)) {
|
||||
return 0U;
|
||||
}
|
||||
|
||||
return (int32_t)clock->enabled;
|
||||
}
|
||||
|
||||
int32_t plat_scmi_clock_set_state(unsigned int agent_id, unsigned int scmi_id,
|
||||
bool enable_not_disable)
|
||||
{
|
||||
struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id);
|
||||
|
||||
if (clock == NULL) {
|
||||
return SCMI_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (!stm32mp_nsec_can_access_clock(clock->clock_id)) {
|
||||
return SCMI_DENIED;
|
||||
}
|
||||
|
||||
if (enable_not_disable) {
|
||||
if (!clock->enabled) {
|
||||
VERBOSE("SCMI clock %u enable\n", scmi_id);
|
||||
clk_enable(clock->clock_id);
|
||||
clock->enabled = true;
|
||||
}
|
||||
} else {
|
||||
if (clock->enabled) {
|
||||
VERBOSE("SCMI clock %u disable\n", scmi_id);
|
||||
clk_disable(clock->clock_id);
|
||||
clock->enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
return SCMI_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Platform SCMI reset domains
|
||||
*/
|
||||
static struct stm32_scmi_rstd *find_rstd(unsigned int agent_id,
|
||||
unsigned int scmi_id)
|
||||
{
|
||||
const struct scmi_agent_resources *resource = find_resource(agent_id);
|
||||
size_t n;
|
||||
|
||||
if (resource != NULL) {
|
||||
for (n = 0U; n < resource->rstd_count; n++) {
|
||||
if (n == scmi_id) {
|
||||
return &resource->rstd[n];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *plat_scmi_rstd_get_name(unsigned int agent_id, unsigned int scmi_id)
|
||||
{
|
||||
const struct stm32_scmi_rstd *rstd = find_rstd(agent_id, scmi_id);
|
||||
|
||||
if (rstd == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return rstd->name;
|
||||
}
|
||||
|
||||
size_t plat_scmi_rstd_count(unsigned int agent_id)
|
||||
{
|
||||
const struct scmi_agent_resources *resource = find_resource(agent_id);
|
||||
|
||||
if (resource == NULL) {
|
||||
return 0U;
|
||||
}
|
||||
|
||||
return resource->rstd_count;
|
||||
}
|
||||
|
||||
int32_t plat_scmi_rstd_autonomous(unsigned int agent_id, unsigned int scmi_id,
|
||||
uint32_t state)
|
||||
{
|
||||
const struct stm32_scmi_rstd *rstd = find_rstd(agent_id, scmi_id);
|
||||
|
||||
if (rstd == NULL) {
|
||||
return SCMI_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (!stm32mp_nsec_can_access_reset(rstd->reset_id)) {
|
||||
return SCMI_DENIED;
|
||||
}
|
||||
|
||||
/* Supports only reset with context loss */
|
||||
if (state != 0U) {
|
||||
return SCMI_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
VERBOSE("SCMI reset %lu cycle\n", rstd->reset_id);
|
||||
|
||||
if (stm32mp_reset_assert(rstd->reset_id, TIMEOUT_US_1MS)) {
|
||||
return SCMI_HARDWARE_ERROR;
|
||||
}
|
||||
|
||||
if (stm32mp_reset_deassert(rstd->reset_id, TIMEOUT_US_1MS)) {
|
||||
return SCMI_HARDWARE_ERROR;
|
||||
}
|
||||
|
||||
return SCMI_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t plat_scmi_rstd_set_state(unsigned int agent_id, unsigned int scmi_id,
|
||||
bool assert_not_deassert)
|
||||
{
|
||||
const struct stm32_scmi_rstd *rstd = find_rstd(agent_id, scmi_id);
|
||||
|
||||
if (rstd == NULL) {
|
||||
return SCMI_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (!stm32mp_nsec_can_access_reset(rstd->reset_id)) {
|
||||
return SCMI_DENIED;
|
||||
}
|
||||
|
||||
if (assert_not_deassert) {
|
||||
VERBOSE("SCMI reset %lu set\n", rstd->reset_id);
|
||||
stm32mp_reset_set(rstd->reset_id);
|
||||
} else {
|
||||
VERBOSE("SCMI reset %lu release\n", rstd->reset_id);
|
||||
stm32mp_reset_release(rstd->reset_id);
|
||||
}
|
||||
|
||||
return SCMI_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize platform SCMI resources
|
||||
*/
|
||||
void stm32mp1_init_scmi_server(void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0U; i < ARRAY_SIZE(scmi_channel); i++) {
|
||||
scmi_smt_init_agent_channel(&scmi_channel[i]);
|
||||
}
|
||||
|
||||
for (i = 0U; i < ARRAY_SIZE(agent_resources); i++) {
|
||||
const struct scmi_agent_resources *res = &agent_resources[i];
|
||||
size_t j;
|
||||
|
||||
for (j = 0U; j < res->clock_count; j++) {
|
||||
struct stm32_scmi_clk *clk = &res->clock[j];
|
||||
|
||||
if ((clk->name == NULL) ||
|
||||
(strlen(clk->name) >= SCMI_CLOCK_NAME_SIZE)) {
|
||||
ERROR("Invalid SCMI clock name\n");
|
||||
panic();
|
||||
}
|
||||
|
||||
/* Sync SCMI clocks with their targeted initial state */
|
||||
if (clk->enabled &&
|
||||
stm32mp_nsec_can_access_clock(clk->clock_id)) {
|
||||
clk_enable(clk->clock_id);
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0U; j < res->rstd_count; j++) {
|
||||
struct stm32_scmi_rstd *rstd = &res->rstd[j];
|
||||
|
||||
if ((rstd->name == NULL) ||
|
||||
(strlen(rstd->name) >= SCMI_RSTD_NAME_SIZE)) {
|
||||
ERROR("Invalid SCMI reset domain name\n");
|
||||
panic();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+596
@@ -0,0 +1,596 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2022, STMicroelectronics - All Rights Reserved
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <drivers/st/etzpc.h>
|
||||
#include <drivers/st/stm32_gpio.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
#include <stm32mp_shared_resources.h>
|
||||
|
||||
/*
|
||||
* Once one starts to get the resource registering state, one cannot register
|
||||
* new resources. This ensures resource state cannot change.
|
||||
*/
|
||||
static bool registering_locked;
|
||||
|
||||
/*
|
||||
* Shared peripherals and resources registration
|
||||
*
|
||||
* Each resource assignation is stored in a table. The state defaults
|
||||
* to PERIPH_UNREGISTERED if the resource is not explicitly assigned.
|
||||
*
|
||||
* Resource driver that as not embedded (a.k.a their related CFG_xxx build
|
||||
* directive is disabled) are assigned to the non-secure world.
|
||||
*
|
||||
* Each pin of the GPIOZ bank can be secure or non-secure.
|
||||
*
|
||||
* It is the platform responsibility the ensure resource assignation
|
||||
* matches the access permission firewalls configuration.
|
||||
*/
|
||||
enum shres_state {
|
||||
SHRES_UNREGISTERED = 0,
|
||||
SHRES_SECURE,
|
||||
SHRES_NON_SECURE,
|
||||
};
|
||||
|
||||
/* Force uint8_t array for array of enum shres_state for size considerations */
|
||||
static uint8_t shres_state[STM32MP1_SHRES_COUNT];
|
||||
|
||||
static const char *shres2str_id_tbl[STM32MP1_SHRES_COUNT] __unused = {
|
||||
[STM32MP1_SHRES_GPIOZ(0)] = "GPIOZ0",
|
||||
[STM32MP1_SHRES_GPIOZ(1)] = "GPIOZ1",
|
||||
[STM32MP1_SHRES_GPIOZ(2)] = "GPIOZ2",
|
||||
[STM32MP1_SHRES_GPIOZ(3)] = "GPIOZ3",
|
||||
[STM32MP1_SHRES_GPIOZ(4)] = "GPIOZ4",
|
||||
[STM32MP1_SHRES_GPIOZ(5)] = "GPIOZ5",
|
||||
[STM32MP1_SHRES_GPIOZ(6)] = "GPIOZ6",
|
||||
[STM32MP1_SHRES_GPIOZ(7)] = "GPIOZ7",
|
||||
[STM32MP1_SHRES_IWDG1] = "IWDG1",
|
||||
[STM32MP1_SHRES_USART1] = "USART1",
|
||||
[STM32MP1_SHRES_SPI6] = "SPI6",
|
||||
[STM32MP1_SHRES_I2C4] = "I2C4",
|
||||
[STM32MP1_SHRES_RNG1] = "RNG1",
|
||||
[STM32MP1_SHRES_HASH1] = "HASH1",
|
||||
[STM32MP1_SHRES_CRYP1] = "CRYP1",
|
||||
[STM32MP1_SHRES_I2C6] = "I2C6",
|
||||
[STM32MP1_SHRES_RTC] = "RTC",
|
||||
[STM32MP1_SHRES_MCU] = "MCU",
|
||||
[STM32MP1_SHRES_MDMA] = "MDMA",
|
||||
[STM32MP1_SHRES_PLL3] = "PLL3",
|
||||
};
|
||||
|
||||
static const char __unused *shres2str_id(enum stm32mp_shres id)
|
||||
{
|
||||
assert(id < ARRAY_SIZE(shres2str_id_tbl));
|
||||
|
||||
return shres2str_id_tbl[id];
|
||||
}
|
||||
|
||||
static const char __unused *shres2str_state_tbl[] = {
|
||||
[SHRES_UNREGISTERED] = "unregistered",
|
||||
[SHRES_NON_SECURE] = "non-secure",
|
||||
[SHRES_SECURE] = "secure",
|
||||
};
|
||||
|
||||
static const char __unused *shres2str_state(unsigned int state)
|
||||
{
|
||||
assert(state < ARRAY_SIZE(shres2str_state_tbl));
|
||||
|
||||
return shres2str_state_tbl[state];
|
||||
}
|
||||
|
||||
/* Get resource state: these accesses lock the registering support */
|
||||
static void lock_registering(void)
|
||||
{
|
||||
registering_locked = true;
|
||||
}
|
||||
|
||||
static bool periph_is_non_secure(enum stm32mp_shres id)
|
||||
{
|
||||
lock_registering();
|
||||
|
||||
return (shres_state[id] == SHRES_NON_SECURE) ||
|
||||
(shres_state[id] == SHRES_UNREGISTERED);
|
||||
}
|
||||
|
||||
static bool periph_is_secure(enum stm32mp_shres id)
|
||||
{
|
||||
return !periph_is_non_secure(id);
|
||||
}
|
||||
|
||||
/* GPIOZ pin count is saved in RAM to prevent parsing FDT several times */
|
||||
static int8_t gpioz_nbpin = -1;
|
||||
|
||||
static unsigned int get_gpio_nbpin(unsigned int bank)
|
||||
{
|
||||
if (bank != GPIO_BANK_Z) {
|
||||
int count = fdt_get_gpio_bank_pin_count(bank);
|
||||
|
||||
assert((count >= 0) && ((unsigned int)count <= (GPIO_PIN_MAX + 1)));
|
||||
|
||||
return (unsigned int)count;
|
||||
}
|
||||
|
||||
if (gpioz_nbpin < 0) {
|
||||
int count = fdt_get_gpio_bank_pin_count(GPIO_BANK_Z);
|
||||
|
||||
assert((count == 0) || (count == STM32MP_GPIOZ_PIN_MAX_COUNT));
|
||||
|
||||
gpioz_nbpin = count;
|
||||
}
|
||||
|
||||
return (unsigned int)gpioz_nbpin;
|
||||
}
|
||||
|
||||
static unsigned int get_gpioz_nbpin(void)
|
||||
{
|
||||
return get_gpio_nbpin(GPIO_BANK_Z);
|
||||
}
|
||||
|
||||
static void register_periph(enum stm32mp_shres id, unsigned int state)
|
||||
{
|
||||
assert((id < STM32MP1_SHRES_COUNT) &&
|
||||
((state == SHRES_SECURE) || (state == SHRES_NON_SECURE)));
|
||||
|
||||
if (registering_locked) {
|
||||
if (shres_state[id] == state) {
|
||||
return;
|
||||
}
|
||||
panic();
|
||||
}
|
||||
|
||||
if ((shres_state[id] != SHRES_UNREGISTERED) &&
|
||||
(shres_state[id] != state)) {
|
||||
VERBOSE("Cannot change %s from %s to %s\n",
|
||||
shres2str_id(id),
|
||||
shres2str_state(shres_state[id]),
|
||||
shres2str_state(state));
|
||||
panic();
|
||||
}
|
||||
|
||||
if (shres_state[id] == SHRES_UNREGISTERED) {
|
||||
VERBOSE("Register %s as %s\n",
|
||||
shres2str_id(id), shres2str_state(state));
|
||||
}
|
||||
|
||||
if ((id >= STM32MP1_SHRES_GPIOZ(0)) &&
|
||||
(id <= STM32MP1_SHRES_GPIOZ(7)) &&
|
||||
((unsigned int)(id - STM32MP1_SHRES_GPIOZ(0)) >= get_gpioz_nbpin())) {
|
||||
ERROR("Invalid GPIO pin %d, %u pin(s) available\n",
|
||||
(int)(id - STM32MP1_SHRES_GPIOZ(0)), get_gpioz_nbpin());
|
||||
panic();
|
||||
}
|
||||
|
||||
shres_state[id] = (uint8_t)state;
|
||||
|
||||
/* Explore clock tree to lock dependencies */
|
||||
if (state == SHRES_SECURE) {
|
||||
enum stm32mp_shres clock_res_id;
|
||||
|
||||
switch (id) {
|
||||
case STM32MP1_SHRES_GPIOZ(0):
|
||||
case STM32MP1_SHRES_GPIOZ(1):
|
||||
case STM32MP1_SHRES_GPIOZ(2):
|
||||
case STM32MP1_SHRES_GPIOZ(3):
|
||||
case STM32MP1_SHRES_GPIOZ(4):
|
||||
case STM32MP1_SHRES_GPIOZ(5):
|
||||
case STM32MP1_SHRES_GPIOZ(6):
|
||||
case STM32MP1_SHRES_GPIOZ(7):
|
||||
clock_res_id = GPIOZ;
|
||||
break;
|
||||
case STM32MP1_SHRES_IWDG1:
|
||||
clock_res_id = IWDG1;
|
||||
break;
|
||||
case STM32MP1_SHRES_USART1:
|
||||
clock_res_id = USART1_K;
|
||||
break;
|
||||
case STM32MP1_SHRES_SPI6:
|
||||
clock_res_id = SPI6_K;
|
||||
break;
|
||||
case STM32MP1_SHRES_I2C4:
|
||||
clock_res_id = I2C4_K;
|
||||
break;
|
||||
case STM32MP1_SHRES_RNG1:
|
||||
clock_res_id = RNG1_K;
|
||||
break;
|
||||
case STM32MP1_SHRES_HASH1:
|
||||
clock_res_id = HASH1;
|
||||
break;
|
||||
case STM32MP1_SHRES_CRYP1:
|
||||
clock_res_id = CRYP1;
|
||||
break;
|
||||
case STM32MP1_SHRES_I2C6:
|
||||
clock_res_id = I2C6_K;
|
||||
break;
|
||||
case STM32MP1_SHRES_RTC:
|
||||
clock_res_id = RTC;
|
||||
break;
|
||||
default:
|
||||
/* No clock resource dependency */
|
||||
return;
|
||||
}
|
||||
|
||||
stm32mp1_register_clock_parents_secure(clock_res_id);
|
||||
}
|
||||
}
|
||||
|
||||
/* Register resource by ID */
|
||||
void stm32mp_register_secure_periph(enum stm32mp_shres id)
|
||||
{
|
||||
register_periph(id, SHRES_SECURE);
|
||||
}
|
||||
|
||||
void stm32mp_register_non_secure_periph(enum stm32mp_shres id)
|
||||
{
|
||||
register_periph(id, SHRES_NON_SECURE);
|
||||
}
|
||||
|
||||
static void register_periph_iomem(uintptr_t base, unsigned int state)
|
||||
{
|
||||
enum stm32mp_shres id;
|
||||
|
||||
switch (base) {
|
||||
case CRYP1_BASE:
|
||||
id = STM32MP1_SHRES_CRYP1;
|
||||
break;
|
||||
case HASH1_BASE:
|
||||
id = STM32MP1_SHRES_HASH1;
|
||||
break;
|
||||
case I2C4_BASE:
|
||||
id = STM32MP1_SHRES_I2C4;
|
||||
break;
|
||||
case I2C6_BASE:
|
||||
id = STM32MP1_SHRES_I2C6;
|
||||
break;
|
||||
case IWDG1_BASE:
|
||||
id = STM32MP1_SHRES_IWDG1;
|
||||
break;
|
||||
case RNG1_BASE:
|
||||
id = STM32MP1_SHRES_RNG1;
|
||||
break;
|
||||
case RTC_BASE:
|
||||
id = STM32MP1_SHRES_RTC;
|
||||
break;
|
||||
case SPI6_BASE:
|
||||
id = STM32MP1_SHRES_SPI6;
|
||||
break;
|
||||
case USART1_BASE:
|
||||
id = STM32MP1_SHRES_USART1;
|
||||
break;
|
||||
|
||||
case GPIOA_BASE:
|
||||
case GPIOB_BASE:
|
||||
case GPIOC_BASE:
|
||||
case GPIOD_BASE:
|
||||
case GPIOE_BASE:
|
||||
case GPIOF_BASE:
|
||||
case GPIOG_BASE:
|
||||
case GPIOH_BASE:
|
||||
case GPIOI_BASE:
|
||||
case GPIOJ_BASE:
|
||||
case GPIOK_BASE:
|
||||
case USART2_BASE:
|
||||
case USART3_BASE:
|
||||
case UART4_BASE:
|
||||
case UART5_BASE:
|
||||
case USART6_BASE:
|
||||
case UART7_BASE:
|
||||
case UART8_BASE:
|
||||
case IWDG2_BASE:
|
||||
/* Allow drivers to register some non-secure resources */
|
||||
VERBOSE("IO for non-secure resource 0x%x\n",
|
||||
(unsigned int)base);
|
||||
if (state != SHRES_NON_SECURE) {
|
||||
panic();
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
default:
|
||||
panic();
|
||||
}
|
||||
|
||||
register_periph(id, state);
|
||||
}
|
||||
|
||||
void stm32mp_register_secure_periph_iomem(uintptr_t base)
|
||||
{
|
||||
register_periph_iomem(base, SHRES_SECURE);
|
||||
}
|
||||
|
||||
void stm32mp_register_non_secure_periph_iomem(uintptr_t base)
|
||||
{
|
||||
register_periph_iomem(base, SHRES_NON_SECURE);
|
||||
}
|
||||
|
||||
void stm32mp_register_secure_gpio(unsigned int bank, unsigned int pin)
|
||||
{
|
||||
switch (bank) {
|
||||
case GPIO_BANK_Z:
|
||||
register_periph(STM32MP1_SHRES_GPIOZ(pin), SHRES_SECURE);
|
||||
break;
|
||||
default:
|
||||
ERROR("GPIO bank %u cannot be secured\n", bank);
|
||||
panic();
|
||||
}
|
||||
}
|
||||
|
||||
void stm32mp_register_non_secure_gpio(unsigned int bank, unsigned int pin)
|
||||
{
|
||||
switch (bank) {
|
||||
case GPIO_BANK_Z:
|
||||
register_periph(STM32MP1_SHRES_GPIOZ(pin), SHRES_NON_SECURE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static bool stm32mp_gpio_bank_is_non_secure(unsigned int bank)
|
||||
{
|
||||
unsigned int non_secure = 0U;
|
||||
unsigned int i;
|
||||
|
||||
lock_registering();
|
||||
|
||||
if (bank != GPIO_BANK_Z) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (i = 0U; i < get_gpioz_nbpin(); i++) {
|
||||
if (periph_is_non_secure(STM32MP1_SHRES_GPIOZ(i))) {
|
||||
non_secure++;
|
||||
}
|
||||
}
|
||||
|
||||
return non_secure == get_gpioz_nbpin();
|
||||
}
|
||||
|
||||
static bool stm32mp_gpio_bank_is_secure(unsigned int bank)
|
||||
{
|
||||
unsigned int secure = 0U;
|
||||
unsigned int i;
|
||||
|
||||
lock_registering();
|
||||
|
||||
if (bank != GPIO_BANK_Z) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0U; i < get_gpioz_nbpin(); i++) {
|
||||
if (periph_is_secure(STM32MP1_SHRES_GPIOZ(i))) {
|
||||
secure++;
|
||||
}
|
||||
}
|
||||
|
||||
return secure == get_gpioz_nbpin();
|
||||
}
|
||||
|
||||
bool stm32mp_nsec_can_access_clock(unsigned long clock_id)
|
||||
{
|
||||
enum stm32mp_shres shres_id = STM32MP1_SHRES_COUNT;
|
||||
|
||||
switch (clock_id) {
|
||||
case CK_CSI:
|
||||
case CK_HSE:
|
||||
case CK_HSE_DIV2:
|
||||
case CK_HSI:
|
||||
case CK_LSE:
|
||||
case CK_LSI:
|
||||
case PLL1_P:
|
||||
case PLL1_Q:
|
||||
case PLL1_R:
|
||||
case PLL2_P:
|
||||
case PLL2_Q:
|
||||
case PLL2_R:
|
||||
case PLL3_P:
|
||||
case PLL3_Q:
|
||||
case PLL3_R:
|
||||
case RTCAPB:
|
||||
return true;
|
||||
case GPIOZ:
|
||||
/* Allow clock access if at least one pin is non-secure */
|
||||
return !stm32mp_gpio_bank_is_secure(GPIO_BANK_Z);
|
||||
case CRYP1:
|
||||
shres_id = STM32MP1_SHRES_CRYP1;
|
||||
break;
|
||||
case HASH1:
|
||||
shres_id = STM32MP1_SHRES_HASH1;
|
||||
break;
|
||||
case I2C4_K:
|
||||
shres_id = STM32MP1_SHRES_I2C4;
|
||||
break;
|
||||
case I2C6_K:
|
||||
shres_id = STM32MP1_SHRES_I2C6;
|
||||
break;
|
||||
case IWDG1:
|
||||
shres_id = STM32MP1_SHRES_IWDG1;
|
||||
break;
|
||||
case RNG1_K:
|
||||
shres_id = STM32MP1_SHRES_RNG1;
|
||||
break;
|
||||
case RTC:
|
||||
shres_id = STM32MP1_SHRES_RTC;
|
||||
break;
|
||||
case SPI6_K:
|
||||
shres_id = STM32MP1_SHRES_SPI6;
|
||||
break;
|
||||
case USART1_K:
|
||||
shres_id = STM32MP1_SHRES_USART1;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return periph_is_non_secure(shres_id);
|
||||
}
|
||||
|
||||
bool stm32mp_nsec_can_access_reset(unsigned int reset_id)
|
||||
{
|
||||
enum stm32mp_shres shres_id = STM32MP1_SHRES_COUNT;
|
||||
|
||||
switch (reset_id) {
|
||||
case CRYP1_R:
|
||||
shres_id = STM32MP1_SHRES_CRYP1;
|
||||
break;
|
||||
case GPIOZ_R:
|
||||
/* GPIOZ reset mandates all pins are non-secure */
|
||||
return stm32mp_gpio_bank_is_non_secure(GPIO_BANK_Z);
|
||||
case HASH1_R:
|
||||
shres_id = STM32MP1_SHRES_HASH1;
|
||||
break;
|
||||
case I2C4_R:
|
||||
shres_id = STM32MP1_SHRES_I2C4;
|
||||
break;
|
||||
case I2C6_R:
|
||||
shres_id = STM32MP1_SHRES_I2C6;
|
||||
break;
|
||||
case MCU_R:
|
||||
shres_id = STM32MP1_SHRES_MCU;
|
||||
break;
|
||||
case MDMA_R:
|
||||
shres_id = STM32MP1_SHRES_MDMA;
|
||||
break;
|
||||
case RNG1_R:
|
||||
shres_id = STM32MP1_SHRES_RNG1;
|
||||
break;
|
||||
case SPI6_R:
|
||||
shres_id = STM32MP1_SHRES_SPI6;
|
||||
break;
|
||||
case USART1_R:
|
||||
shres_id = STM32MP1_SHRES_USART1;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return periph_is_non_secure(shres_id);
|
||||
}
|
||||
|
||||
static bool mckprot_protects_periph(enum stm32mp_shres id)
|
||||
{
|
||||
switch (id) {
|
||||
case STM32MP1_SHRES_MCU:
|
||||
case STM32MP1_SHRES_PLL3:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* ETZPC configuration at drivers initialization completion */
|
||||
static enum etzpc_decprot_attributes shres2decprot_attr(enum stm32mp_shres id)
|
||||
{
|
||||
assert((id < STM32MP1_SHRES_GPIOZ(0)) ||
|
||||
(id > STM32MP1_SHRES_GPIOZ(7)));
|
||||
|
||||
if (periph_is_non_secure(id)) {
|
||||
return ETZPC_DECPROT_NS_RW;
|
||||
}
|
||||
|
||||
return ETZPC_DECPROT_S_RW;
|
||||
}
|
||||
|
||||
static void set_etzpc_secure_configuration(void)
|
||||
{
|
||||
/* Some system peripherals shall be secure */
|
||||
etzpc_configure_decprot(STM32MP1_ETZPC_STGENC_ID, ETZPC_DECPROT_S_RW);
|
||||
etzpc_configure_decprot(STM32MP1_ETZPC_BKPSRAM_ID, ETZPC_DECPROT_S_RW);
|
||||
etzpc_configure_decprot(STM32MP1_ETZPC_DDRCTRL_ID,
|
||||
ETZPC_DECPROT_NS_R_S_W);
|
||||
etzpc_configure_decprot(STM32MP1_ETZPC_DDRPHYC_ID,
|
||||
ETZPC_DECPROT_NS_R_S_W);
|
||||
|
||||
/* Configure ETZPC with peripheral registering */
|
||||
etzpc_configure_decprot(STM32MP1_ETZPC_CRYP1_ID,
|
||||
shres2decprot_attr(STM32MP1_SHRES_CRYP1));
|
||||
etzpc_configure_decprot(STM32MP1_ETZPC_HASH1_ID,
|
||||
shres2decprot_attr(STM32MP1_SHRES_HASH1));
|
||||
etzpc_configure_decprot(STM32MP1_ETZPC_I2C4_ID,
|
||||
shres2decprot_attr(STM32MP1_SHRES_I2C4));
|
||||
etzpc_configure_decprot(STM32MP1_ETZPC_I2C6_ID,
|
||||
shres2decprot_attr(STM32MP1_SHRES_I2C6));
|
||||
etzpc_configure_decprot(STM32MP1_ETZPC_IWDG1_ID,
|
||||
shres2decprot_attr(STM32MP1_SHRES_IWDG1));
|
||||
etzpc_configure_decprot(STM32MP1_ETZPC_RNG1_ID,
|
||||
shres2decprot_attr(STM32MP1_SHRES_RNG1));
|
||||
etzpc_configure_decprot(STM32MP1_ETZPC_USART1_ID,
|
||||
shres2decprot_attr(STM32MP1_SHRES_USART1));
|
||||
etzpc_configure_decprot(STM32MP1_ETZPC_SPI6_ID,
|
||||
shres2decprot_attr(STM32MP1_SHRES_SPI6));
|
||||
}
|
||||
|
||||
static void check_rcc_secure_configuration(void)
|
||||
{
|
||||
uint32_t n;
|
||||
uint32_t error = 0U;
|
||||
bool mckprot = stm32mp1_rcc_is_mckprot();
|
||||
bool secure = stm32mp1_rcc_is_secure();
|
||||
|
||||
for (n = 0U; n < ARRAY_SIZE(shres_state); n++) {
|
||||
if (shres_state[n] != SHRES_SECURE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!secure || (mckprot_protects_periph(n) && (!mckprot))) {
|
||||
ERROR("RCC %s MCKPROT %s and %s secure\n",
|
||||
secure ? "secure" : "non-secure",
|
||||
mckprot ? "set" : "not set",
|
||||
shres2str_id(n));
|
||||
error++;
|
||||
}
|
||||
}
|
||||
|
||||
if (error != 0U) {
|
||||
panic();
|
||||
}
|
||||
}
|
||||
|
||||
static void set_gpio_secure_configuration(void)
|
||||
{
|
||||
uint32_t pin;
|
||||
|
||||
for (pin = 0U; pin < get_gpioz_nbpin(); pin++) {
|
||||
bool secure_state = periph_is_secure(STM32MP1_SHRES_GPIOZ(pin));
|
||||
|
||||
set_gpio_secure_cfg(GPIO_BANK_Z, pin, secure_state);
|
||||
}
|
||||
}
|
||||
|
||||
static void print_shared_resources_state(void)
|
||||
{
|
||||
unsigned int id;
|
||||
|
||||
for (id = 0U; id < STM32MP1_SHRES_COUNT; id++) {
|
||||
switch (shres_state[id]) {
|
||||
case SHRES_SECURE:
|
||||
INFO("stm32mp1 %s is secure\n", shres2str_id(id));
|
||||
break;
|
||||
case SHRES_NON_SECURE:
|
||||
case SHRES_UNREGISTERED:
|
||||
VERBOSE("stm32mp %s is non-secure\n", shres2str_id(id));
|
||||
break;
|
||||
default:
|
||||
VERBOSE("stm32mp %s is invalid\n", shres2str_id(id));
|
||||
panic();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void stm32mp_lock_periph_registering(void)
|
||||
{
|
||||
registering_locked = true;
|
||||
|
||||
print_shared_resources_state();
|
||||
|
||||
check_rcc_secure_configuration();
|
||||
set_etzpc_secure_configuration();
|
||||
set_gpio_secure_configuration();
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <plat/common/platform.h>
|
||||
|
||||
#define RANDOM_CANARY_VALUE 2144346116U
|
||||
|
||||
u_register_t plat_get_stack_protector_canary(void)
|
||||
{
|
||||
/*
|
||||
* Ideally, a random number should be returned instead of the
|
||||
* combination of a timer's value and a compile-time constant.
|
||||
*/
|
||||
return RANDOM_CANARY_VALUE ^ (u_register_t)read_cntpct_el0();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,411 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2022, STMicroelectronics - All Rights Reserved
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <drivers/clk.h>
|
||||
#include <drivers/delay_timer.h>
|
||||
#include <drivers/st/stpmic1.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <lib/utils_def.h>
|
||||
#include <libfdt.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
#include <stm32mp_common.h>
|
||||
#include <stm32mp_dt.h>
|
||||
#include <stm32mp1_private.h>
|
||||
|
||||
/*
|
||||
* SYSCFG REGISTER OFFSET (base relative)
|
||||
*/
|
||||
#define SYSCFG_BOOTR 0x00U
|
||||
#define SYSCFG_BOOTCR 0x0CU
|
||||
#if STM32MP15
|
||||
#define SYSCFG_IOCTRLSETR 0x18U
|
||||
#define SYSCFG_ICNR 0x1CU
|
||||
#endif
|
||||
#define SYSCFG_CMPCR 0x20U
|
||||
#define SYSCFG_CMPENSETR 0x24U
|
||||
#define SYSCFG_CMPENCLRR 0x28U
|
||||
#if STM32MP13
|
||||
#define SYSCFG_CMPSD1CR 0x30U
|
||||
#define SYSCFG_CMPSD1ENSETR 0x34U
|
||||
#define SYSCFG_CMPSD1ENCLRR 0x38U
|
||||
#define SYSCFG_CMPSD2CR 0x40U
|
||||
#define SYSCFG_CMPSD2ENSETR 0x44U
|
||||
#define SYSCFG_CMPSD2ENCLRR 0x48U
|
||||
#define SYSCFG_HSLVEN0R 0x50U
|
||||
#endif
|
||||
#define SYSCFG_IDC 0x380U
|
||||
|
||||
#define CMPCR_CMPENSETR_OFFSET 0x4U
|
||||
#define CMPCR_CMPENCLRR_OFFSET 0x8U
|
||||
|
||||
/*
|
||||
* SYSCFG_BOOTR Register
|
||||
*/
|
||||
#define SYSCFG_BOOTR_BOOT_MASK GENMASK(2, 0)
|
||||
#if STM32MP15
|
||||
#define SYSCFG_BOOTR_BOOTPD_MASK GENMASK(6, 4)
|
||||
#define SYSCFG_BOOTR_BOOTPD_SHIFT 4
|
||||
#endif
|
||||
|
||||
/*
|
||||
* SYSCFG_BOOTCR Register
|
||||
*/
|
||||
#define SYSCFG_BOOTCR_BMEN BIT(0)
|
||||
|
||||
/*
|
||||
* SYSCFG_IOCTRLSETR Register
|
||||
*/
|
||||
#define SYSCFG_IOCTRLSETR_HSLVEN_TRACE BIT(0)
|
||||
#define SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI BIT(1)
|
||||
#define SYSCFG_IOCTRLSETR_HSLVEN_ETH BIT(2)
|
||||
#define SYSCFG_IOCTRLSETR_HSLVEN_SDMMC BIT(3)
|
||||
#define SYSCFG_IOCTRLSETR_HSLVEN_SPI BIT(4)
|
||||
|
||||
/*
|
||||
* SYSCFG_ICNR Register
|
||||
*/
|
||||
#define SYSCFG_ICNR_AXI_M9 BIT(9)
|
||||
|
||||
/*
|
||||
* SYSCFG_CMPCR Register
|
||||
*/
|
||||
#define SYSCFG_CMPCR_SW_CTRL BIT(1)
|
||||
#define SYSCFG_CMPCR_READY BIT(8)
|
||||
#define SYSCFG_CMPCR_RANSRC GENMASK(19, 16)
|
||||
#define SYSCFG_CMPCR_RANSRC_SHIFT 16
|
||||
#define SYSCFG_CMPCR_RAPSRC GENMASK(23, 20)
|
||||
#define SYSCFG_CMPCR_ANSRC_SHIFT 24
|
||||
|
||||
#define SYSCFG_CMPCR_READY_TIMEOUT_US 10000U
|
||||
|
||||
/*
|
||||
* SYSCFG_CMPENSETR Register
|
||||
*/
|
||||
#define SYSCFG_CMPENSETR_MPU_EN BIT(0)
|
||||
|
||||
/*
|
||||
* HSLV definitions
|
||||
*/
|
||||
#define HSLV_IDX_TPIU 0U
|
||||
#define HSLV_IDX_QSPI 1U
|
||||
#define HSLV_IDX_ETH1 2U
|
||||
#define HSLV_IDX_ETH2 3U
|
||||
#define HSLV_IDX_SDMMC1 4U
|
||||
#define HSLV_IDX_SDMMC2 5U
|
||||
#define HSLV_IDX_SPI1 6U
|
||||
#define HSLV_IDX_SPI2 7U
|
||||
#define HSLV_IDX_SPI3 8U
|
||||
#define HSLV_IDX_SPI4 9U
|
||||
#define HSLV_IDX_SPI5 10U
|
||||
#define HSLV_IDX_LTDC 11U
|
||||
#define HSLV_NB_IDX 12U
|
||||
|
||||
#define HSLV_KEY 0x1018U
|
||||
|
||||
/*
|
||||
* SYSCFG_IDC Register
|
||||
*/
|
||||
#define SYSCFG_IDC_DEV_ID_MASK GENMASK(11, 0)
|
||||
#define SYSCFG_IDC_REV_ID_MASK GENMASK(31, 16)
|
||||
#define SYSCFG_IDC_REV_ID_SHIFT 16
|
||||
|
||||
static void enable_io_comp_cell_finish(uintptr_t cmpcr_off)
|
||||
{
|
||||
uint64_t start;
|
||||
|
||||
start = timeout_init_us(SYSCFG_CMPCR_READY_TIMEOUT_US);
|
||||
|
||||
while ((mmio_read_32(SYSCFG_BASE + cmpcr_off) & SYSCFG_CMPCR_READY) == 0U) {
|
||||
if (timeout_elapsed(start)) {
|
||||
/* Failure on IO compensation enable is not a issue: warn only. */
|
||||
WARN("IO compensation cell not ready\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mmio_clrbits_32(SYSCFG_BASE + cmpcr_off, SYSCFG_CMPCR_SW_CTRL);
|
||||
}
|
||||
|
||||
static void disable_io_comp_cell(uintptr_t cmpcr_off)
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
if (((mmio_read_32(SYSCFG_BASE + cmpcr_off) & SYSCFG_CMPCR_READY) == 0U) ||
|
||||
((mmio_read_32(SYSCFG_BASE + cmpcr_off + CMPCR_CMPENSETR_OFFSET) &
|
||||
SYSCFG_CMPENSETR_MPU_EN) == 0U)) {
|
||||
return;
|
||||
}
|
||||
|
||||
value = mmio_read_32(SYSCFG_BASE + cmpcr_off) >> SYSCFG_CMPCR_ANSRC_SHIFT;
|
||||
|
||||
mmio_clrbits_32(SYSCFG_BASE + cmpcr_off, SYSCFG_CMPCR_RANSRC | SYSCFG_CMPCR_RAPSRC);
|
||||
|
||||
value <<= SYSCFG_CMPCR_RANSRC_SHIFT;
|
||||
value |= mmio_read_32(SYSCFG_BASE + cmpcr_off);
|
||||
|
||||
mmio_write_32(SYSCFG_BASE + cmpcr_off, value | SYSCFG_CMPCR_SW_CTRL);
|
||||
|
||||
mmio_setbits_32(SYSCFG_BASE + cmpcr_off + CMPCR_CMPENCLRR_OFFSET, SYSCFG_CMPENSETR_MPU_EN);
|
||||
}
|
||||
|
||||
#if STM32MP13
|
||||
static int get_regu_max_voltage(void *fdt, int sdmmc_node,
|
||||
const char *regu_name, uint32_t *regu_val)
|
||||
{
|
||||
int node;
|
||||
const fdt32_t *cuint;
|
||||
|
||||
cuint = fdt_getprop(fdt, sdmmc_node, regu_name, NULL);
|
||||
if (cuint == NULL) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
node = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
|
||||
if (node < 0) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
cuint = fdt_getprop(fdt, node, "regulator-max-microvolt", NULL);
|
||||
if (cuint == NULL) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
*regu_val = fdt32_to_cpu(*cuint);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool sdmmc_is_low_voltage(uintptr_t sdmmc_base)
|
||||
{
|
||||
int ret;
|
||||
int node;
|
||||
void *fdt = NULL;
|
||||
uint32_t regu_max_val;
|
||||
|
||||
if (fdt_get_address(&fdt) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fdt == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
node = dt_match_instance_by_compatible(DT_SDMMC2_COMPAT, sdmmc_base);
|
||||
if (node < 0) {
|
||||
/* No SD or eMMC device on this instance, enable HSLV */
|
||||
return true;
|
||||
}
|
||||
|
||||
ret = get_regu_max_voltage(fdt, node, "vqmmc-supply", ®u_max_val);
|
||||
if ((ret < 0) || (regu_max_val > 1800000U)) {
|
||||
/*
|
||||
* The vqmmc-supply property should always be present for eMMC.
|
||||
* For SD-card, if it is not, then the card only supports 3.3V.
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void enable_hslv_by_index(uint32_t index)
|
||||
{
|
||||
bool apply_hslv;
|
||||
|
||||
assert(index < HSLV_NB_IDX);
|
||||
|
||||
switch (index) {
|
||||
case HSLV_IDX_SDMMC1:
|
||||
apply_hslv = sdmmc_is_low_voltage(STM32MP_SDMMC1_BASE);
|
||||
break;
|
||||
case HSLV_IDX_SDMMC2:
|
||||
apply_hslv = sdmmc_is_low_voltage(STM32MP_SDMMC2_BASE);
|
||||
break;
|
||||
default:
|
||||
apply_hslv = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (apply_hslv) {
|
||||
mmio_write_32(SYSCFG_BASE + SYSCFG_HSLVEN0R + index * sizeof(uint32_t), HSLV_KEY);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void enable_high_speed_mode_low_voltage(void)
|
||||
{
|
||||
#if STM32MP13
|
||||
uint32_t idx;
|
||||
|
||||
for (idx = 0U; idx < HSLV_NB_IDX; idx++) {
|
||||
enable_hslv_by_index(idx);
|
||||
}
|
||||
#endif
|
||||
#if STM32MP15
|
||||
mmio_write_32(SYSCFG_BASE + SYSCFG_IOCTRLSETR,
|
||||
SYSCFG_IOCTRLSETR_HSLVEN_TRACE |
|
||||
SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI |
|
||||
SYSCFG_IOCTRLSETR_HSLVEN_ETH |
|
||||
SYSCFG_IOCTRLSETR_HSLVEN_SDMMC |
|
||||
SYSCFG_IOCTRLSETR_HSLVEN_SPI);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void stm32mp1_syscfg_set_hslv(void)
|
||||
{
|
||||
uint32_t otp_value;
|
||||
uint32_t vdd_voltage;
|
||||
bool product_below_2v5;
|
||||
|
||||
/*
|
||||
* High Speed Low Voltage Pad mode Enable for SPI, SDMMC, ETH, QSPI
|
||||
* and TRACE. Needed above ~50MHz and conditioned by AFMUX selection.
|
||||
* It could be disabled for low frequencies or if AFMUX is selected
|
||||
* but the function is not used, typically for TRACE.
|
||||
* If high speed low voltage pad mode is node enable, platform will
|
||||
* over consume.
|
||||
*
|
||||
* WARNING:
|
||||
* Enabling High Speed mode while VDD > 2.7V
|
||||
* with the OTP product_below_2v5 (OTP 18, BIT 13)
|
||||
* erroneously set to 1 can damage the SoC!
|
||||
* => TF-A enables the low power mode only if VDD < 2.7V (in DT)
|
||||
* but this value needs to be consistent with board design.
|
||||
*/
|
||||
if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) {
|
||||
panic();
|
||||
}
|
||||
|
||||
product_below_2v5 = (otp_value & HW2_OTP_PRODUCT_BELOW_2V5) != 0U;
|
||||
|
||||
/* Get VDD supply */
|
||||
vdd_voltage = dt_get_pwr_vdd_voltage();
|
||||
|
||||
/* Check if VDD is Low Voltage */
|
||||
if (vdd_voltage == 0U) {
|
||||
WARN("VDD unknown\n");
|
||||
} else if (vdd_voltage < 2700000U) {
|
||||
enable_high_speed_mode_low_voltage();
|
||||
|
||||
if (!product_below_2v5) {
|
||||
INFO("Product_below_2v5=0: HSLVEN protected by HW\n");
|
||||
}
|
||||
} else {
|
||||
if (product_below_2v5) {
|
||||
ERROR("Product_below_2v5=1:\n");
|
||||
ERROR("\tHSLVEN update is destructive,\n");
|
||||
ERROR("\tno update as VDD > 2.7V\n");
|
||||
panic();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void stm32mp1_syscfg_init(void)
|
||||
{
|
||||
#if STM32MP15
|
||||
uint32_t bootr;
|
||||
|
||||
/*
|
||||
* Interconnect update : select master using the port 1.
|
||||
* LTDC = AXI_M9.
|
||||
*/
|
||||
mmio_write_32(SYSCFG_BASE + SYSCFG_ICNR, SYSCFG_ICNR_AXI_M9);
|
||||
|
||||
/* Disable Pull-Down for boot pin connected to VDD */
|
||||
bootr = mmio_read_32(SYSCFG_BASE + SYSCFG_BOOTR) &
|
||||
SYSCFG_BOOTR_BOOT_MASK;
|
||||
mmio_clrsetbits_32(SYSCFG_BASE + SYSCFG_BOOTR, SYSCFG_BOOTR_BOOTPD_MASK,
|
||||
bootr << SYSCFG_BOOTR_BOOTPD_SHIFT);
|
||||
#endif
|
||||
|
||||
stm32mp1_syscfg_set_hslv();
|
||||
|
||||
stm32mp1_syscfg_enable_io_compensation_start();
|
||||
}
|
||||
|
||||
void stm32mp1_syscfg_enable_io_compensation_start(void)
|
||||
{
|
||||
/*
|
||||
* Activate automatic I/O compensation.
|
||||
* Warning: need to ensure CSI enabled and ready in clock driver.
|
||||
* Enable non-secure clock, we assume non-secure is suspended.
|
||||
*/
|
||||
clk_enable(SYSCFG);
|
||||
|
||||
mmio_setbits_32(SYSCFG_BASE + CMPCR_CMPENSETR_OFFSET + SYSCFG_CMPCR,
|
||||
SYSCFG_CMPENSETR_MPU_EN);
|
||||
#if STM32MP13
|
||||
mmio_setbits_32(SYSCFG_BASE + CMPCR_CMPENSETR_OFFSET + SYSCFG_CMPSD1CR,
|
||||
SYSCFG_CMPENSETR_MPU_EN);
|
||||
mmio_setbits_32(SYSCFG_BASE + CMPCR_CMPENSETR_OFFSET + SYSCFG_CMPSD2CR,
|
||||
SYSCFG_CMPENSETR_MPU_EN);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void stm32mp1_syscfg_enable_io_compensation_finish(void)
|
||||
{
|
||||
enable_io_comp_cell_finish(SYSCFG_CMPCR);
|
||||
#if STM32MP13
|
||||
enable_io_comp_cell_finish(SYSCFG_CMPSD1CR);
|
||||
enable_io_comp_cell_finish(SYSCFG_CMPSD2CR);
|
||||
#endif
|
||||
}
|
||||
|
||||
void stm32mp1_syscfg_disable_io_compensation(void)
|
||||
{
|
||||
clk_enable(SYSCFG);
|
||||
|
||||
/*
|
||||
* Deactivate automatic I/O compensation.
|
||||
* Warning: CSI is disabled automatically in STOP if not
|
||||
* requested for other usages and always OFF in STANDBY.
|
||||
* Disable non-secure SYSCFG clock, we assume non-secure is suspended.
|
||||
*/
|
||||
disable_io_comp_cell(SYSCFG_CMPCR);
|
||||
#if STM32MP13
|
||||
disable_io_comp_cell(SYSCFG_CMPSD1CR);
|
||||
disable_io_comp_cell(SYSCFG_CMPSD2CR);
|
||||
#endif
|
||||
|
||||
clk_disable(SYSCFG);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Get silicon revision from SYSCFG registers.
|
||||
* @retval chip version (REV_ID).
|
||||
*/
|
||||
uint32_t stm32mp1_syscfg_get_chip_version(void)
|
||||
{
|
||||
return (mmio_read_32(SYSCFG_BASE + SYSCFG_IDC) &
|
||||
SYSCFG_IDC_REV_ID_MASK) >> SYSCFG_IDC_REV_ID_SHIFT;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Get device ID from SYSCFG registers.
|
||||
* @retval device ID (DEV_ID).
|
||||
*/
|
||||
uint32_t stm32mp1_syscfg_get_chip_dev_id(void)
|
||||
{
|
||||
return mmio_read_32(SYSCFG_BASE + SYSCFG_IDC) & SYSCFG_IDC_DEV_ID_MASK;
|
||||
}
|
||||
|
||||
#if STM32MP13
|
||||
void stm32mp1_syscfg_boot_mode_enable(void)
|
||||
{
|
||||
mmio_setbits_32(SYSCFG_BASE + SYSCFG_BOOTCR, SYSCFG_BOOTCR_BMEN);
|
||||
}
|
||||
|
||||
void stm32mp1_syscfg_boot_mode_disable(void)
|
||||
{
|
||||
mmio_clrbits_32(SYSCFG_BASE + SYSCFG_BOOTCR, SYSCFG_BOOTCR_BMEN);
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "tbbr/tbb_ext.h"
|
||||
#include "tbbr/tbb_key.h"
|
||||
|
||||
#include "tbbr/stm32mp1_tbb_cert.h"
|
||||
|
||||
/*
|
||||
* Certificates used in the chain of trust
|
||||
*
|
||||
* The order of the certificates must follow the enumeration specified in
|
||||
* stm32mp1_tbb_cert.h. All certificates are self-signed, so the issuer certificate
|
||||
* field points to itself.
|
||||
*/
|
||||
static cert_t stm32mp1_tbb_certs[] = {
|
||||
[0] = {
|
||||
.id = STM32MP_CONFIG_CERT,
|
||||
.opt = "stm32mp-cfg-cert",
|
||||
.help_msg = "STM32MP Config Certificate (output file)",
|
||||
.fn = NULL,
|
||||
.cn = "STM32MP config FW Certificate",
|
||||
.key = ROT_KEY,
|
||||
.issuer = STM32MP_CONFIG_CERT,
|
||||
.ext = {
|
||||
TRUSTED_FW_NVCOUNTER_EXT,
|
||||
HW_CONFIG_HASH_EXT,
|
||||
FW_CONFIG_HASH_EXT
|
||||
},
|
||||
.num_ext = 3
|
||||
},
|
||||
};
|
||||
|
||||
PLAT_REGISTER_COT(stm32mp1_tbb_certs);
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
#include <lib/psci/psci.h>
|
||||
#include <plat/common/platform.h>
|
||||
|
||||
/* 1 cluster, all cores into */
|
||||
static const unsigned char stm32mp1_power_domain_tree_desc[] = {
|
||||
PLATFORM_CLUSTER_COUNT,
|
||||
PLATFORM_CORE_COUNT,
|
||||
};
|
||||
|
||||
/* This function returns the platform topology */
|
||||
const unsigned char *plat_get_power_domain_tree_desc(void)
|
||||
{
|
||||
return stm32mp1_power_domain_tree_desc;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* This function implements a part of the critical interface between the psci
|
||||
* generic layer and the platform that allows the former to query the platform
|
||||
* to convert an MPIDR to a unique linear index. An error code (-1) is returned
|
||||
* in case the MPIDR is invalid.
|
||||
******************************************************************************/
|
||||
int plat_core_pos_by_mpidr(u_register_t mpidr)
|
||||
{
|
||||
unsigned int cluster_id, cpu_id;
|
||||
u_register_t mpidr_copy = mpidr;
|
||||
|
||||
mpidr_copy &= MPIDR_AFFINITY_MASK;
|
||||
|
||||
if ((mpidr_copy & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) != 0U) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cluster_id = (mpidr_copy >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
|
||||
cpu_id = (mpidr_copy >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
|
||||
|
||||
if (cluster_id >= PLATFORM_CLUSTER_COUNT) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Validate cpu_id by checking whether it represents a CPU in one
|
||||
* of the two clusters present on the platform.
|
||||
*/
|
||||
if (cpu_id >= PLATFORM_CORE_COUNT) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (int)cpu_id;
|
||||
}
|
||||
@@ -0,0 +1,423 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <drivers/st/bsec.h>
|
||||
#include <drivers/st/stm32mp1_usb.h>
|
||||
#include <drivers/usb_device.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
#include <stm32cubeprogrammer.h>
|
||||
#include <stm32mp_common.h>
|
||||
#include <usb_dfu.h>
|
||||
|
||||
/* String size (1 byte) + type (1 byte) + 24 UTF16 characters: 2 bytes each */
|
||||
#define SIZ_STRING_SERIAL U(24)
|
||||
#define USB_SIZ_STRING_SERIAL (1U + 1U + (SIZ_STRING_SERIAL * 2U))
|
||||
#define USBD_MAX_STR_DESC_SIZ 0x100
|
||||
#define USBD_VID 0x0483
|
||||
#define USBD_PID 0xDF11
|
||||
#define USBD_LANGID_STRING 0x409
|
||||
#define USBD_MANUFACTURER_STRING "STMicroelectronics"
|
||||
#define USBD_CONFIGURATION_STRING "DFU Config"
|
||||
#define USBD_INTERFACE_STRING "DFU Interface"
|
||||
|
||||
#if STM32MP13
|
||||
#define USB_DFU_ITF_NUM 2
|
||||
#endif
|
||||
#if STM32MP15
|
||||
#define USB_DFU_ITF_NUM 6
|
||||
#endif
|
||||
|
||||
#define USB_DFU_CONFIG_DESC_SIZ USB_DFU_DESC_SIZ(USB_DFU_ITF_NUM)
|
||||
|
||||
/* DFU devices */
|
||||
static struct usb_dfu_handle usb_dfu_handle;
|
||||
|
||||
/* USB Standard Device Descriptor */
|
||||
static const uint8_t usb_stm32mp1_desc[USB_LEN_DEV_DESC] = {
|
||||
USB_LEN_DEV_DESC, /* bLength */
|
||||
USB_DESC_TYPE_DEVICE, /* bDescriptorType */
|
||||
0x00, /* bcdUSB */
|
||||
0x02, /* version */
|
||||
0x00, /* bDeviceClass */
|
||||
0x00, /* bDeviceSubClass */
|
||||
0x00, /* bDeviceProtocol */
|
||||
USB_MAX_EP0_SIZE, /* bMaxPacketSize */
|
||||
LOBYTE(USBD_VID), /* idVendor */
|
||||
HIBYTE(USBD_VID), /* idVendor */
|
||||
LOBYTE(USBD_PID), /* idVendor */
|
||||
HIBYTE(USBD_PID), /* idVendor */
|
||||
0x00, /* bcdDevice rel. 2.00 */
|
||||
0x02,
|
||||
USBD_IDX_MFC_STR, /* Index of manufacturer string */
|
||||
USBD_IDX_PRODUCT_STR, /* Index of product string */
|
||||
USBD_IDX_SERIAL_STR, /* Index of serial number string */
|
||||
USBD_MAX_NUM_CONFIGURATION /* bNumConfigurations */
|
||||
}; /* USB_DeviceDescriptor */
|
||||
|
||||
/* USB Standard String Descriptor */
|
||||
static const uint8_t usb_stm32mp1_lang_id_desc[USB_LEN_LANGID_STR_DESC] = {
|
||||
USB_LEN_LANGID_STR_DESC,
|
||||
USB_DESC_TYPE_STRING,
|
||||
LOBYTE(USBD_LANGID_STRING),
|
||||
HIBYTE(USBD_LANGID_STRING),
|
||||
};
|
||||
|
||||
/* USB Standard Device Descriptor */
|
||||
static const uint8_t
|
||||
usbd_stm32mp1_qualifier_desc[USB_LEN_DEV_QUALIFIER_DESC] = {
|
||||
USB_LEN_DEV_QUALIFIER_DESC,
|
||||
USB_DESC_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x01,
|
||||
0x00,
|
||||
};
|
||||
|
||||
/* USB serial number: build dynamically */
|
||||
static uint8_t usb_stm32mp1_serial[USB_SIZ_STRING_SERIAL + 1];
|
||||
|
||||
/* USB DFU device Configuration Descriptor */
|
||||
static const uint8_t usb_stm32mp1_config_desc[USB_DFU_CONFIG_DESC_SIZ] = {
|
||||
0x09, /* bLength: Configuration Descriptor size */
|
||||
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
|
||||
USB_DFU_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */
|
||||
0x00,
|
||||
0x01, /* bNumInterfaces: 1 interface */
|
||||
0x01, /* bConfigurationValue: Configuration value */
|
||||
0x02, /* iConfiguration: Index of string descriptor for configuration */
|
||||
0xC0, /* bmAttributes: bus powered and Supprts Remote Wakeup */
|
||||
0x32, /* MaxPower 100 mA: this current is used for detecting Vbus */
|
||||
|
||||
/* Descriptor of DFU interface 0 Alternate setting 0..N */
|
||||
USBD_DFU_IF_DESC(0),
|
||||
USBD_DFU_IF_DESC(1),
|
||||
#if USB_DFU_ITF_NUM > 2
|
||||
USBD_DFU_IF_DESC(2),
|
||||
#endif
|
||||
#if USB_DFU_ITF_NUM > 3
|
||||
USBD_DFU_IF_DESC(3),
|
||||
#endif
|
||||
#if USB_DFU_ITF_NUM > 4
|
||||
USBD_DFU_IF_DESC(4),
|
||||
#endif
|
||||
#if USB_DFU_ITF_NUM > 5
|
||||
USBD_DFU_IF_DESC(5),
|
||||
#endif
|
||||
/* DFU Functional Descriptor */
|
||||
0x09, /* blength = 9 Bytes */
|
||||
DFU_DESCRIPTOR_TYPE, /* DFU Functional Descriptor */
|
||||
DFU_BM_ATTRIBUTE, /* bmAttribute for DFU */
|
||||
0xFF, /* DetachTimeOut = 255 ms */
|
||||
0x00,
|
||||
TRANSFER_SIZE_BYTES(USBD_DFU_XFER_SIZE), /* TransferSize = 1024 Byte */
|
||||
((USB_DFU_VERSION >> 0) & 0xFF), /* bcdDFUVersion */
|
||||
((USB_DFU_VERSION >> 8) & 0xFF)
|
||||
};
|
||||
|
||||
/* The user strings: one by alternate as defined in USBD_DFU_IF_DESC */
|
||||
#if STM32MP13
|
||||
const char *const if_desc_string[USB_DFU_ITF_NUM] = {
|
||||
"@SSBL /0x03/1*16Me",
|
||||
"@virtual /0xF1/1*512Ba"
|
||||
};
|
||||
#endif
|
||||
#if STM32MP15
|
||||
const char *const if_desc_string[USB_DFU_ITF_NUM] = {
|
||||
"@Partition0 /0x00/1*256Ke",
|
||||
"@FSBL /0x01/1*1Me",
|
||||
"@Partition2 /0x02/1*1Me",
|
||||
"@Partition3 /0x03/1*16Me",
|
||||
"@Partition4 /0x04/1*16Me",
|
||||
"@virtual /0xF1/1*512Ba"
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Buffer to build the unicode string provided to USB device stack */
|
||||
static uint8_t usb_str_dec[USBD_MAX_STR_DESC_SIZ];
|
||||
|
||||
/*
|
||||
* Convert Ascii string into unicode one
|
||||
* desc : descriptor buffer
|
||||
* unicode : Formatted string buffer (unicode)
|
||||
* len : descriptor length
|
||||
*/
|
||||
static void stm32mp1_get_string(const char *desc, uint8_t *unicode, uint16_t *len)
|
||||
{
|
||||
uint8_t idx = 0U;
|
||||
|
||||
if (desc == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
*len = strlen(desc) * 2U + 2U;
|
||||
unicode[idx++] = *len;
|
||||
unicode[idx++] = USB_DESC_TYPE_STRING;
|
||||
|
||||
while (*desc != '\0') {
|
||||
unicode[idx++] = *desc++;
|
||||
unicode[idx++] = 0x00U;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the serial number string descriptor
|
||||
*/
|
||||
static void update_serial_num_string(void)
|
||||
{
|
||||
uint8_t i;
|
||||
char serial_string[SIZ_STRING_SERIAL + 2U];
|
||||
/* serial number is set to 0 */
|
||||
uint32_t deviceserial[UID_WORD_NB] = {0U, 0U, 0U};
|
||||
uint32_t otp;
|
||||
uint32_t len;
|
||||
uint16_t length;
|
||||
|
||||
if (stm32_get_otp_index(UID_OTP, &otp, &len) != 0) {
|
||||
ERROR("BSEC: Get UID_OTP number Error\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((len / __WORD_BIT) != UID_WORD_NB) {
|
||||
ERROR("BSEC: Get UID_OTP length Error\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < UID_WORD_NB; i++) {
|
||||
if (bsec_shadow_read_otp(&deviceserial[i], i + otp) !=
|
||||
BSEC_OK) {
|
||||
ERROR("BSEC: UID%d Error\n", i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* build serial number with OTP value as in ROM code */
|
||||
snprintf(serial_string, sizeof(serial_string), "%08X%08X%08X",
|
||||
deviceserial[0], deviceserial[1], deviceserial[2]);
|
||||
|
||||
length = USB_SIZ_STRING_SERIAL;
|
||||
stm32mp1_get_string(serial_string, usb_stm32mp1_serial, &length);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return Device Qualifier descriptor
|
||||
* length : pointer data length
|
||||
* return : pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *stm32mp1_get_qualifier_desc(uint16_t *length)
|
||||
{
|
||||
*length = sizeof(usbd_stm32mp1_qualifier_desc);
|
||||
|
||||
return (uint8_t *)usbd_stm32mp1_qualifier_desc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return configuration descriptor
|
||||
* length : pointer data length
|
||||
* return : pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *stm32mp1_get_config_desc(uint16_t *length)
|
||||
{
|
||||
*length = sizeof(usb_stm32mp1_config_desc);
|
||||
|
||||
return (uint8_t *)usb_stm32mp1_config_desc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the device descriptor.
|
||||
* length: Pointer to data length variable
|
||||
* return : Pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *stm32mp1_device_desc(uint16_t *length)
|
||||
{
|
||||
*length = sizeof(usb_stm32mp1_desc);
|
||||
|
||||
return (uint8_t *)usb_stm32mp1_desc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the LangID string descriptor.
|
||||
* length: Pointer to data length variable
|
||||
* return : Pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *stm32mp1_lang_id_desc(uint16_t *length)
|
||||
{
|
||||
*length = sizeof(usb_stm32mp1_lang_id_desc);
|
||||
|
||||
return (uint8_t *)usb_stm32mp1_lang_id_desc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the product string descriptor.
|
||||
* length: Pointer to data length variable
|
||||
* return : Pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *stm32mp1_product_desc(uint16_t *length)
|
||||
{
|
||||
char name[STM32_SOC_NAME_SIZE];
|
||||
char product[128];
|
||||
uint32_t chip_id;
|
||||
uint32_t chip_version;
|
||||
|
||||
stm32mp_get_soc_name(name);
|
||||
chip_id = stm32mp_get_chip_dev_id();
|
||||
chip_version = stm32mp_get_chip_version();
|
||||
|
||||
snprintf(product, sizeof(product),
|
||||
"DFU @Device ID /0x%03X, @Revision ID /0x%04X, @Name /%s,",
|
||||
chip_id, chip_version, name);
|
||||
|
||||
stm32mp1_get_string(product, usb_str_dec, length);
|
||||
|
||||
return usb_str_dec;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the manufacturer string descriptor.
|
||||
* length: Pointer to data length variable
|
||||
* return : Pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *stm32mp1_manufacturer_desc(uint16_t *length)
|
||||
{
|
||||
stm32mp1_get_string(USBD_MANUFACTURER_STRING, usb_str_dec, length);
|
||||
|
||||
return usb_str_dec;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the serial number string descriptor.
|
||||
* length: Pointer to data length variable
|
||||
* return : Pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *stm32mp1_serial_desc(uint16_t *length)
|
||||
{
|
||||
*length = USB_SIZ_STRING_SERIAL;
|
||||
|
||||
return (uint8_t *)usb_stm32mp1_serial;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the configuration string descriptor.
|
||||
* length: Pointer to data length variable
|
||||
* return : Pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *stm32mp1_config_desc(uint16_t *length)
|
||||
{
|
||||
stm32mp1_get_string(USBD_CONFIGURATION_STRING, usb_str_dec, length);
|
||||
|
||||
return usb_str_dec;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the interface string descriptor.
|
||||
* length : Pointer to data length variable
|
||||
* return : Pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *stm32mp1_interface_desc(uint16_t *length)
|
||||
{
|
||||
stm32mp1_get_string(USBD_INTERFACE_STRING, usb_str_dec, length);
|
||||
|
||||
return usb_str_dec;
|
||||
}
|
||||
|
||||
/*
|
||||
* Manages the transfer of memory interfaces string descriptors.
|
||||
* index: descriptor index
|
||||
* length : pointer data length
|
||||
* return : pointer to the descriptor table or NULL if the descriptor
|
||||
* is not supported.
|
||||
*/
|
||||
static uint8_t *stm32mp1_get_usr_desc(uint8_t index, uint16_t *length)
|
||||
{
|
||||
if (index >= ARRAY_SIZE(if_desc_string)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
stm32mp1_get_string(if_desc_string[index], usb_str_dec, length);
|
||||
|
||||
return usb_str_dec;
|
||||
}
|
||||
|
||||
static const struct usb_desc dfu_desc = {
|
||||
.get_device_desc = stm32mp1_device_desc,
|
||||
.get_lang_id_desc = stm32mp1_lang_id_desc,
|
||||
.get_manufacturer_desc = stm32mp1_manufacturer_desc,
|
||||
.get_product_desc = stm32mp1_product_desc,
|
||||
.get_configuration_desc = stm32mp1_config_desc,
|
||||
.get_serial_desc = stm32mp1_serial_desc,
|
||||
.get_interface_desc = stm32mp1_interface_desc,
|
||||
.get_usr_desc = stm32mp1_get_usr_desc,
|
||||
.get_config_desc = stm32mp1_get_config_desc,
|
||||
.get_device_qualifier_desc = stm32mp1_get_qualifier_desc,
|
||||
/* only HS is supported, as ROM code */
|
||||
.get_other_speed_config_desc = NULL,
|
||||
};
|
||||
|
||||
static struct usb_handle usb_core_handle;
|
||||
static struct pcd_handle pcd_handle;
|
||||
|
||||
struct usb_handle *usb_dfu_plat_init(void)
|
||||
{
|
||||
/* Prepare USB Driver */
|
||||
pcd_handle.in_ep[0].maxpacket = USB_MAX_EP0_SIZE;
|
||||
pcd_handle.out_ep[0].maxpacket = USB_MAX_EP0_SIZE;
|
||||
stm32mp1_usb_init_driver(&usb_core_handle, &pcd_handle,
|
||||
(uint32_t *)USB_OTG_BASE);
|
||||
|
||||
#if STM32MP15
|
||||
/* STM32MP15 = keep the configuration from ROM code */
|
||||
usb_core_handle.ep0_state = USBD_EP0_DATA_IN;
|
||||
usb_core_handle.dev_state = USBD_STATE_CONFIGURED;
|
||||
#endif
|
||||
|
||||
/* Update the serial number string descriptor from the unique ID */
|
||||
update_serial_num_string();
|
||||
|
||||
/* Prepare USB DFU stack */
|
||||
usb_dfu_register(&usb_core_handle, &usb_dfu_handle);
|
||||
|
||||
/* Register DFU descriptor in USB stack */
|
||||
register_platform(&usb_core_handle, &dfu_desc);
|
||||
|
||||
return &usb_core_handle;
|
||||
}
|
||||
|
||||
/* Link between USB alternate and STM32CubeProgramer phase */
|
||||
uint8_t usb_dfu_get_phase(uint8_t alt)
|
||||
{
|
||||
uint8_t ret;
|
||||
|
||||
switch (alt) {
|
||||
#if STM32MP13
|
||||
case 0:
|
||||
ret = PHASE_SSBL;
|
||||
break;
|
||||
case 1:
|
||||
ret = PHASE_CMD;
|
||||
break;
|
||||
#endif
|
||||
#if STM32MP15
|
||||
case 3:
|
||||
ret = PHASE_SSBL;
|
||||
break;
|
||||
case 5:
|
||||
ret = PHASE_CMD;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ret = PHASE_RESET;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
Reference in New Issue
Block a user