diff options
-rw-r--r-- | drivers/arm/tzc/tzc400.c | 105 | ||||
-rw-r--r-- | include/drivers/arm/tzc400.h | 3 | ||||
-rw-r--r-- | plat/st/stm32mp1/sp_min/sp_min_setup.c | 4 | ||||
-rw-r--r-- | plat/st/stm32mp1/stm32mp1_def.h | 5 | ||||
-rw-r--r-- | plat/st/stm32mp1/stm32mp1_security.c | 5 |
5 files changed, 110 insertions, 12 deletions
diff --git a/drivers/arm/tzc/tzc400.c b/drivers/arm/tzc/tzc400.c index 9798ed4e5f..9fc1578a1a 100644 --- a/drivers/arm/tzc/tzc400.c +++ b/drivers/arm/tzc/tzc400.c @@ -10,6 +10,7 @@ #include <common/debug.h> #include <drivers/arm/tzc400.h> #include <lib/mmio.h> +#include <lib/utils_def.h> #include "tzc_common_private.h" @@ -70,6 +71,77 @@ DEFINE_TZC_COMMON_WRITE_REGION_ID_ACCESS(400, 400) DEFINE_TZC_COMMON_CONFIGURE_REGION0(400) DEFINE_TZC_COMMON_CONFIGURE_REGION(400) +static void _tzc400_clear_it(uintptr_t base, uint32_t filter) +{ + mmio_write_32(base + INT_CLEAR, BIT_32(filter)); +} + +static uint32_t _tzc400_get_int_by_filter(uintptr_t base, uint32_t filter) +{ + return mmio_read_32(base + INT_STATUS) & BIT_32(filter); +} + +#if DEBUG +static unsigned long _tzc400_get_fail_address(uintptr_t base, uint32_t filter) +{ + unsigned long fail_address; + + fail_address = mmio_read_32(base + FAIL_ADDRESS_LOW_OFF + + (filter * FILTER_OFFSET)); +#ifdef __aarch64__ + fail_address += (unsigned long)mmio_read_32(base + FAIL_ADDRESS_HIGH_OFF + + (filter * FILTER_OFFSET)) << 32; +#endif + + return fail_address; +} + +static uint32_t _tzc400_get_fail_id(uintptr_t base, uint32_t filter) +{ + return mmio_read_32(base + FAIL_ID + (filter * FILTER_OFFSET)); +} + +static uint32_t _tzc400_get_fail_control(uintptr_t base, uint32_t filter) +{ + return mmio_read_32(base + FAIL_CONTROL_OFF + (filter * FILTER_OFFSET)); +} + +static void _tzc400_dump_fail_filter(uintptr_t base, uint32_t filter) +{ + uint32_t control_fail; + uint32_t fail_id; + unsigned long address_fail; + + address_fail = _tzc400_get_fail_address(base, filter); + ERROR("Illegal access to 0x%lx:\n", address_fail); + + fail_id = _tzc400_get_fail_id(base, filter); + ERROR("\tFAIL_ID = 0x%x\n", fail_id); + + control_fail = _tzc400_get_fail_control(base, filter); + if (((control_fail & BIT_32(FAIL_CONTROL_NS_SHIFT)) >> FAIL_CONTROL_NS_SHIFT) == + FAIL_CONTROL_NS_NONSECURE) { + ERROR("\tNon-Secure\n"); + } else { + ERROR("\tSecure\n"); + } + + if (((control_fail & BIT_32(FAIL_CONTROL_PRIV_SHIFT)) >> FAIL_CONTROL_PRIV_SHIFT) == + FAIL_CONTROL_PRIV_PRIV) { + ERROR("\tPrivilege\n"); + } else { + ERROR("\tUnprivilege\n"); + } + + if (((control_fail & BIT_32(FAIL_CONTROL_DIR_SHIFT)) >> FAIL_CONTROL_DIR_SHIFT) == + FAIL_CONTROL_DIR_WRITE) { + ERROR("\tWrite\n"); + } else { + ERROR("\tRead\n"); + } +} +#endif /* DEBUG */ + static unsigned int _tzc400_get_gate_keeper(uintptr_t base, unsigned int filter) { @@ -108,11 +180,6 @@ void tzc400_set_action(unsigned int action) assert(tzc400.base != 0U); assert(action <= TZC_ACTION_ERR_INT); - /* - * - Currently no handler is provided to trap an error via interrupt - * or exception. - * - The interrupt action has not been tested. - */ _tzc400_write_action(tzc400.base, action); } @@ -245,3 +312,31 @@ void tzc400_disable_filters(void) for (filter = 0; filter < tzc400.num_filters; filter++) _tzc400_set_gate_keeper(tzc400.base, filter, 0); } + +int tzc400_it_handler(void) +{ + uint32_t filter; + uint32_t filter_it_pending = tzc400.num_filters; + + assert(tzc400.base != 0U); + + for (filter = 0U; filter < tzc400.num_filters; filter++) { + if (_tzc400_get_int_by_filter(tzc400.base, filter) != 0U) { + filter_it_pending = filter; + break; + } + } + + if (filter_it_pending == tzc400.num_filters) { + ERROR("TZC-400: No interrupt pending!\n"); + return -1; + } + +#if DEBUG + _tzc400_dump_fail_filter(tzc400.base, filter_it_pending); +#endif + + _tzc400_clear_it(tzc400.base, filter_it_pending); + + return 0; +} diff --git a/include/drivers/arm/tzc400.h b/include/drivers/arm/tzc400.h index aacd5dfea3..5f8a48f570 100644 --- a/include/drivers/arm/tzc400.h +++ b/include/drivers/arm/tzc400.h @@ -90,6 +90,8 @@ #define TZC_400_REGION_SIZE U(0x20) #define TZC_400_ACTION_OFF U(0x4) +#define FILTER_OFFSET U(0x10) + #ifndef __ASSEMBLER__ #include <cdefs.h> @@ -110,6 +112,7 @@ void tzc400_configure_region(unsigned int filters, void tzc400_set_action(unsigned int action); void tzc400_enable_filters(void); void tzc400_disable_filters(void); +int tzc400_it_handler(void); static inline void tzc_init(uintptr_t base) { diff --git a/plat/st/stm32mp1/sp_min/sp_min_setup.c b/plat/st/stm32mp1/sp_min/sp_min_setup.c index b639fcb358..9b8c3ea27c 100644 --- a/plat/st/stm32mp1/sp_min/sp_min_setup.c +++ b/plat/st/stm32mp1/sp_min/sp_min_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -45,7 +45,7 @@ void sp_min_plat_fiq_handler(uint32_t id) { switch (id & INT_ID_MASK) { case STM32MP1_IRQ_TZC400: - ERROR("STM32MP1_IRQ_TZC400 generated\n"); + (void)tzc400_it_handler(); panic(); break; case STM32MP1_IRQ_AXIERRIRQ: diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h index ee04a23fd9..f4aeab532c 100644 --- a/plat/st/stm32mp1/stm32mp1_def.h +++ b/plat/st/stm32mp1/stm32mp1_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -381,7 +381,8 @@ enum ddr_type { #define STM32MP1_TZC_ETH_ID U(10) #define STM32MP1_TZC_DAP_ID U(15) -#define STM32MP1_FILTER_BIT_ALL U(3) +#define STM32MP1_FILTER_BIT_ALL (TZC_400_REGION_ATTR_FILTER_BIT(0) | \ + TZC_400_REGION_ATTR_FILTER_BIT(1)) /******************************************************************************* * STM32MP1 SDMMC diff --git a/plat/st/stm32mp1/stm32mp1_security.c b/plat/st/stm32mp1/stm32mp1_security.c index 3a29ba9661..195b3a5501 100644 --- a/plat/st/stm32mp1/stm32mp1_security.c +++ b/plat/st/stm32mp1/stm32mp1_security.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -75,8 +75,7 @@ static void init_tzc400(void) TZC_REGION_NSEC_ALL_ACCESS_RDWR); #endif - /* Raise an exception if a NS device tries to access secure memory */ - tzc400_set_action(TZC_ACTION_ERR); + tzc400_set_action(TZC_ACTION_INT); tzc400_enable_filters(); } |