Introduce interrupt registration framework in BL3-1

This patch introduces a framework for registering interrupts routed to
EL3. The interrupt routing model is governed by the SCR_EL3.IRQ and
FIQ bits and the security state an interrupt is generated in. The
framework recognizes three type of interrupts depending upon which
exception level and security state they should be handled in
i.e. Secure EL1 interrupts, Non-secure interrupts and EL3
interrupts. It provides an API and macros that allow a runtime service
to register an handler for a type of interrupt and specify the routing
model. The framework validates the routing model and uses the context
management framework to ensure that it is applied to the SCR_EL3 prior
to entry into the target security state. It saves the handler in
internal data structures. An API is provided to retrieve the handler
when an interrupt of a particular type is asserted. Registration is
expected to be done once by the primary CPU. The same handler and
routing model is used for all CPUs.

Support for EL3 interrupts will be added to the framework in the
future. A makefile flag has been added to allow the FVP port choose
between ARM GIC v2 and v3 support in EL3. The latter version is
currently unsupported.

A framework for handling interrupts in BL3-1 will be introduced in
subsequent patches. The default routing model in the absence of any
handlers expects no interrupts to be routed to EL3.

Change-Id: Idf7c023b34fcd4800a5980f2bef85e4b5c29e649
diff --git a/plat/fvp/plat_gic.c b/plat/fvp/plat_gic.c
index db3c9cf..dd409f5 100644
--- a/plat/fvp/plat_gic.c
+++ b/plat/fvp/plat_gic.c
@@ -29,9 +29,12 @@
  */
 
 #include <arch_helpers.h>
+#include <assert.h>
+#include <bl_common.h>
 #include <debug.h>
 #include <gic_v2.h>
 #include <gic_v3.h>
+#include <interrupt_mgmt.h>
 #include <platform.h>
 #include <stdint.h>
 
@@ -284,3 +287,38 @@
 	gic_cpuif_setup(gicc_base);
 	gic_distif_setup(gicd_base);
 }
+
+/*******************************************************************************
+ * An ARM processor signals interrupt exceptions through the IRQ and FIQ pins.
+ * The interrupt controller knows which pin/line it uses to signal a type of
+ * interrupt. The platform knows which interrupt controller type is being used
+ * in a particular security state e.g. with an ARM GIC, normal world could use
+ * the GICv2 features while the secure world could use GICv3 features and vice
+ * versa.
+ * This function is exported by the platform to let the interrupt management
+ * framework determine for a type of interrupt and security state, which line
+ * should be used in the SCR_EL3 to control its routing to EL3. The interrupt
+ * line is represented as the bit position of the IRQ or FIQ bit in the SCR_EL3.
+ ******************************************************************************/
+uint32_t plat_interrupt_type_to_line(uint32_t type, uint32_t security_state)
+{
+	uint32_t gicc_base = platform_get_cfgvar(CONFIG_GICC_ADDR);
+
+	assert(type == INTR_TYPE_S_EL1 ||
+	       type == INTR_TYPE_EL3 ||
+	       type == INTR_TYPE_NS);
+
+	assert(security_state == NON_SECURE || security_state == SECURE);
+
+	/*
+	 * We ignore the security state parameter under the assumption that
+	 * both normal and secure worlds are using ARM GICv2. This parameter
+	 * will be used when the secure world starts using GICv3.
+	 */
+#if FVP_GIC_ARCH == 2
+	return gicv2_interrupt_type_to_line(gicc_base, type);
+#else
+#error "Invalid GIC architecture version specified for FVP port"
+#endif
+}
+
diff --git a/plat/fvp/platform.h b/plat/fvp/platform.h
index bd76d67..814fb77 100644
--- a/plat/fvp/platform.h
+++ b/plat/fvp/platform.h
@@ -430,6 +430,8 @@
 extern void gic_cpuif_setup(unsigned int);
 extern void gic_pcpu_distif_setup(unsigned int);
 extern void gic_setup(void);
+extern uint32_t plat_interrupt_type_to_line(uint32_t type,
+					    uint32_t security_state);
 
 /* Declarations for fvp_topology.c */
 extern int plat_setup_topology(void);
diff --git a/plat/fvp/platform.mk b/plat/fvp/platform.mk
index 4de001b..3ae36d8 100644
--- a/plat/fvp/platform.mk
+++ b/plat/fvp/platform.mk
@@ -71,3 +71,8 @@
 	BL31_SOURCES		+=	drivers/arm/tzc400/tzc400.c		\
 					plat/fvp/plat_security.c
 endif
+
+# Flag used by the FVP port to determine the version of ARM GIC architecture
+# to use for interrupt management in EL3.
+FVP_GIC_ARCH		:=	2
+$(eval $(call add_define,FVP_GIC_ARCH))