Merge changes from topic "stm32-etzpc" into integration

* changes:
  plat/stm32mp1: sp_min relies on etzpc driver
  dts: stm32mp157c: add etzpc node
  drivers: introduce ST ETZPC driver
This commit is contained in:
Manish Pandey 2020-06-03 15:11:43 +00:00 committed by TrustedFirmware Code Review
commit 34a66d80be
7 changed files with 445 additions and 6 deletions

258
drivers/st/etzpc/etzpc.c Normal file
View File

@ -0,0 +1,258 @@
/*
* Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <errno.h>
#include <stdint.h>
#include <arch_helpers.h>
#include <common/debug.h>
#include <drivers/st/etzpc.h>
#include <dt-bindings/soc/st,stm32-etzpc.h>
#include <lib/mmio.h>
#include <lib/utils_def.h>
#include <libfdt.h>
#include <platform_def.h>
/* Device Tree related definitions */
#define ETZPC_COMPAT "st,stm32-etzpc"
#define ETZPC_LOCK_MASK 0x1U
#define ETZPC_MODE_SHIFT 8
#define ETZPC_MODE_MASK GENMASK(1, 0)
#define ETZPC_ID_SHIFT 16
#define ETZPC_ID_MASK GENMASK(7, 0)
/* ID Registers */
#define ETZPC_TZMA0_SIZE 0x000U
#define ETZPC_DECPROT0 0x010U
#define ETZPC_DECPROT_LOCK0 0x030U
#define ETZPC_HWCFGR 0x3F0U
#define ETZPC_VERR 0x3F4U
/* ID Registers fields */
#define ETZPC_TZMA0_SIZE_LOCK BIT(31)
#define ETZPC_DECPROT0_MASK GENMASK(1, 0)
#define ETZPC_HWCFGR_NUM_TZMA_SHIFT 0
#define ETZPC_HWCFGR_NUM_PER_SEC_SHIFT 8
#define ETZPC_HWCFGR_NUM_AHB_SEC_SHIFT 16
#define ETZPC_HWCFGR_CHUNCKS1N4_SHIFT 24
#define DECPROT_SHIFT 1
#define IDS_PER_DECPROT_REGS 16U
#define IDS_PER_DECPROT_LOCK_REGS 32U
/*
* etzpc_instance.
* base : register base address set during init given by user
* chunk_size : supported TZMA size steps
* num_tzma: number of TZMA zone read from register at init
* num_ahb_sec : number of securable AHB master zone read from register
* num_per_sec : number of securable AHB & APB Peripherals read from register
* revision : IP revision read from register at init
*/
struct etzpc_instance {
uintptr_t base;
uint8_t chunck_size;
uint8_t num_tzma;
uint8_t num_per_sec;
uint8_t num_ahb_sec;
uint8_t revision;
};
/* Only 1 instance of the ETZPC is expected per platform */
static struct etzpc_instance etzpc_dev;
/*
* Implementation uses uint8_t to store each securable DECPROT configuration.
* When resuming from deep suspend, the DECPROT configurations are restored.
*/
#define PERIPH_LOCK_BIT BIT(7)
#define PERIPH_ATTR_MASK GENMASK(2, 0)
#if ENABLE_ASSERTIONS
static bool valid_decprot_id(unsigned int id)
{
return id < (unsigned int)etzpc_dev.num_per_sec;
}
static bool valid_tzma_id(unsigned int id)
{
return id < (unsigned int)etzpc_dev.num_tzma;
}
#endif
/*
* etzpc_configure_decprot : Load a DECPROT configuration
* decprot_id : ID of the IP
* decprot_attr : Restriction access attribute
*/
void etzpc_configure_decprot(uint32_t decprot_id,
enum etzpc_decprot_attributes decprot_attr)
{
uintptr_t offset = 4U * (decprot_id / IDS_PER_DECPROT_REGS);
uint32_t shift = (decprot_id % IDS_PER_DECPROT_REGS) << DECPROT_SHIFT;
uint32_t masked_decprot = (uint32_t)decprot_attr & ETZPC_DECPROT0_MASK;
assert(valid_decprot_id(decprot_id));
mmio_clrsetbits_32(etzpc_dev.base + ETZPC_DECPROT0 + offset,
(uint32_t)ETZPC_DECPROT0_MASK << shift,
masked_decprot << shift);
}
/*
* etzpc_get_decprot : Get the DECPROT attribute
* decprot_id : ID of the IP
* return : Attribute of this DECPROT
*/
enum etzpc_decprot_attributes etzpc_get_decprot(uint32_t decprot_id)
{
uintptr_t offset = 4U * (decprot_id / IDS_PER_DECPROT_REGS);
uint32_t shift = (decprot_id % IDS_PER_DECPROT_REGS) << DECPROT_SHIFT;
uintptr_t base_decprot = etzpc_dev.base + offset;
uint32_t value;
assert(valid_decprot_id(decprot_id));
value = (mmio_read_32(base_decprot + ETZPC_DECPROT0) >> shift) &
ETZPC_DECPROT0_MASK;
return (enum etzpc_decprot_attributes)value;
}
/*
* etzpc_lock_decprot : Lock access to the DECPROT attribute
* decprot_id : ID of the IP
*/
void etzpc_lock_decprot(uint32_t decprot_id)
{
uintptr_t offset = 4U * (decprot_id / IDS_PER_DECPROT_LOCK_REGS);
uint32_t shift = BIT(decprot_id % IDS_PER_DECPROT_LOCK_REGS);
uintptr_t base_decprot = etzpc_dev.base + offset;
assert(valid_decprot_id(decprot_id));
mmio_write_32(base_decprot + ETZPC_DECPROT_LOCK0, shift);
}
/*
* etzpc_configure_tzma : Configure the target TZMA read only size
* tzma_id : ID of the memory
* tzma_value : read-only size
*/
void etzpc_configure_tzma(uint32_t tzma_id, uint16_t tzma_value)
{
assert(valid_tzma_id(tzma_id));
mmio_write_32(etzpc_dev.base + ETZPC_TZMA0_SIZE +
(sizeof(uint32_t) * tzma_id), tzma_value);
}
/*
* etzpc_get_tzma : Get the target TZMA read only size
* tzma_id : TZMA ID
* return : Size of read only size
*/
uint16_t etzpc_get_tzma(uint32_t tzma_id)
{
assert(valid_tzma_id(tzma_id));
return (uint16_t)mmio_read_32(etzpc_dev.base + ETZPC_TZMA0_SIZE +
(sizeof(uint32_t) * tzma_id));
}
/*
* etzpc_lock_tzma : Lock the target TZMA
* tzma_id : TZMA ID
*/
void etzpc_lock_tzma(uint32_t tzma_id)
{
assert(valid_tzma_id(tzma_id));
mmio_setbits_32(etzpc_dev.base + ETZPC_TZMA0_SIZE +
(sizeof(uint32_t) * tzma_id), ETZPC_TZMA0_SIZE_LOCK);
}
/*
* etzpc_get_lock_tzma : Return the lock status of the target TZMA
* tzma_id : TZMA ID
* return : True if TZMA is locked, false otherwise
*/
bool etzpc_get_lock_tzma(uint32_t tzma_id)
{
uint32_t tzma_size;
assert(valid_tzma_id(tzma_id));
tzma_size = mmio_read_32(etzpc_dev.base + ETZPC_TZMA0_SIZE +
(sizeof(uint32_t) * tzma_id));
return (tzma_size & ETZPC_TZMA0_SIZE_LOCK) != 0;
}
/*
* etzpc_get_num_per_sec : Return the DECPROT ID limit value
*/
uint8_t etzpc_get_num_per_sec(void)
{
return etzpc_dev.num_per_sec;
}
/*
* etzpc_get_revision : Return the ETZPC IP revision
*/
uint8_t etzpc_get_revision(void)
{
return etzpc_dev.revision;
}
/*
* etzpc_get_base_address : Return the ETZPC IP base address
*/
uintptr_t etzpc_get_base_address(void)
{
return etzpc_dev.base;
}
/*
* etzpc_init : Initialize the ETZPC driver
* Return 0 on success and a negative errno on failure
*/
int etzpc_init(void)
{
uint32_t hwcfg;
int node;
struct dt_node_info etzpc_info;
node = dt_get_node(&etzpc_info, -1, ETZPC_COMPAT);
if (node < 0) {
return -EIO;
}
/* Check ETZPC is secure only */
if (etzpc_info.status != DT_SECURE) {
return -EACCES;
}
etzpc_dev.base = etzpc_info.base;
hwcfg = mmio_read_32(etzpc_dev.base + ETZPC_HWCFGR);
etzpc_dev.num_tzma = (uint8_t)(hwcfg >> ETZPC_HWCFGR_NUM_TZMA_SHIFT);
etzpc_dev.num_per_sec = (uint8_t)(hwcfg >>
ETZPC_HWCFGR_NUM_PER_SEC_SHIFT);
etzpc_dev.num_ahb_sec = (uint8_t)(hwcfg >>
ETZPC_HWCFGR_NUM_AHB_SEC_SHIFT);
etzpc_dev.chunck_size = (uint8_t)(hwcfg >>
ETZPC_HWCFGR_CHUNCKS1N4_SHIFT);
etzpc_dev.revision = mmio_read_8(etzpc_dev.base + ETZPC_VERR);
VERBOSE("ETZPC version 0x%x", etzpc_dev.revision);
return 0;
}

View File

@ -362,5 +362,13 @@
#size-cells = <0>;
status = "disabled";
};
etzpc: etzpc@5c007000 {
compatible = "st,stm32-etzpc";
reg = <0x5C007000 0x400>;
clocks = <&rcc TZPC>;
status = "disabled";
secure-status = "okay";
};
};
};

View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef DRIVERS_ST_ETZPC_H
#define DRIVERS_ST_ETZPC_H
/* Define security level for each peripheral (DECPROT) */
enum etzpc_decprot_attributes {
ETZPC_DECPROT_S_RW = 0,
ETZPC_DECPROT_NS_R_S_W = 1,
ETZPC_DECPROT_MCU_ISOLATION = 2,
ETZPC_DECPROT_NS_RW = 3,
ETZPC_DECPROT_MAX = 4,
};
void etzpc_configure_decprot(uint32_t decprot_id,
enum etzpc_decprot_attributes decprot_attr);
enum etzpc_decprot_attributes etzpc_get_decprot(uint32_t decprot_id);
void etzpc_lock_decprot(uint32_t decprot_id);
void etzpc_configure_tzma(uint32_t tzma_id, uint16_t tzma_value);
uint16_t etzpc_get_tzma(uint32_t tzma_id);
void etzpc_lock_tzma(uint32_t tzma_id);
bool etzpc_get_lock_tzma(uint32_t tzma_id);
uint8_t etzpc_get_num_per_sec(void);
uint8_t etzpc_get_revision(void);
uintptr_t etzpc_get_base_address(void);
int etzpc_init(void);
#endif /* DRIVERS_ST_ETZPC_H */

View File

@ -0,0 +1,20 @@
/*
* Copyright (C) 2017-2020, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
*/
#ifndef _DT_BINDINGS_STM32_ETZPC_H
#define _DT_BINDINGS_STM32_ETZPC_H
/* DECPROT modes */
#define DECPROT_S_RW 0x0
#define DECPROT_NS_R_S_W 0x1
#define DECPROT_MCU_ISOLATION 0x2
#define DECPROT_NS_RW 0x3
/* DECPROT lock */
#define DECPROT_UNLOCK 0x0
#define DECPROT_LOCK 0x1
#endif /* _DT_BINDINGS_STM32_ETZPC_H */

View File

@ -6,10 +6,12 @@
SP_MIN_WITH_SECURE_FIQ := 1
BL32_SOURCES += plat/common/aarch32/platform_mp_stack.S \
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_topology.c
# Generic GIC v2
BL32_SOURCES += drivers/arm/gic/common/gic_common.c \
drivers/arm/gic/v2/gicv2_helpers.c \

View File

@ -17,6 +17,7 @@
#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_console.h>
#include <drivers/st/stm32_gpio.h>
#include <drivers/st/stm32_iwdg.h>
@ -76,6 +77,26 @@ entry_point_info_t *sp_min_plat_get_bl33_ep_info(void)
return next_image_info;
}
#define TZMA1_SECURE_RANGE STM32MP1_ETZPC_TZMA_ALL_SECURE
#define TZMA0_SECURE_RANGE STM32MP1_ETZPC_TZMA_ALL_SECURE
static void stm32mp1_etzpc_early_setup(void)
{
unsigned int n;
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);
/* Release security on all shared resources */
for (n = 0; n < STM32MP1_ETZPC_SEC_ID_LIMIT; n++) {
etzpc_configure_decprot(n, ETZPC_DECPROT_NS_RW);
}
}
/*******************************************************************************
* Perform any BL32 specific platform actions.
******************************************************************************/
@ -144,6 +165,8 @@ void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1,
#endif
console_set_scope(&console, console_flags);
}
stm32mp1_etzpc_early_setup();
}
/*******************************************************************************
@ -158,11 +181,6 @@ void sp_min_platform_setup(void)
stm32mp1_gic_init();
/* Unlock ETZPC securable peripherals */
#define STM32MP1_ETZPC_BASE 0x5C007000U
#define ETZPC_DECPROT0 0x010U
mmio_write_32(STM32MP1_ETZPC_BASE + ETZPC_DECPROT0, 0xFFFFFFFF);
/* Set GPIO bank Z as non secure */
for (uint32_t pin = 0U; pin < STM32MP_GPIOZ_PIN_MAX_COUNT; pin++) {
set_gpio_secure_cfg(GPIO_BANK_Z, pin, false);

View File

@ -246,6 +246,104 @@ enum ddr_type {
#define DEBUG_UART_TX_EN_REG RCC_MP_APB1ENSETR
#define DEBUG_UART_TX_EN RCC_MP_APB1ENSETR_UART4EN
/*******************************************************************************
* 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)
******************************************************************************/