Merge changes from topic "tzc400_stm32mp" into integration

* changes:
  stm32mp1: add TZC400 interrupt management
  stm32mp1: use TZC400 macro to describe filters
  tzc400: add support for interrupts
diff --git a/drivers/arm/tzc/tzc400.c b/drivers/arm/tzc/tzc400.c
index 9798ed4..9fc1578 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_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 @@
 	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 @@
 	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 aacd5df..5f8a48f 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_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 b639fcb..9b8c3ea 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 @@
 {
 	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 ee04a23..f4aeab5 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 @@
 #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 3a29ba9..195b3a5 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 @@
 				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();
 }