Merge pull request #305 from achingupta/ag/tf-issues#306

Ag/tf issues#306
diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S
index accb11b..bbc7f1b 100644
--- a/bl31/aarch64/runtime_exceptions.S
+++ b/bl31/aarch64/runtime_exceptions.S
@@ -79,6 +79,14 @@
 	str	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
 	bl	save_gp_registers
 
+	/*
+	 * Save the EL3 system registers needed to return from
+	 * this exception.
+	 */
+	mrs	x0, spsr_el3
+	mrs	x1, elr_el3
+	stp	x0, x1, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
+
 	/* Switch to the runtime stack i.e. SP_EL0 */
 	ldr	x2, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]
 	mov	x20, sp
@@ -96,13 +104,29 @@
 
 	/*
 	 * Get the registered handler for this interrupt type. A
-	 * NULL return value implies that an interrupt was generated
-	 * for which there is no handler registered or the interrupt
-	 * was routed incorrectly. This is a problem of the framework
-	 * so report it as an error.
+	 * NULL return value could be 'cause of the following
+	 * conditions:
+	 *
+	 * a. An interrupt of a type was routed correctly but a
+	 *    handler for its type was not registered.
+	 *
+	 * b. An interrupt of a type was not routed correctly so
+	 *    a handler for its type was not registered.
+	 *
+	 * c. An interrupt of a type was routed correctly to EL3,
+	 *    but was deasserted before its pending state could
+	 *    be read. Another interrupt of a different type pended
+	 *    at the same time and its type was reported as pending
+	 *    instead. However, a handler for this type was not
+	 *    registered.
+	 *
+	 * a. and b. can only happen due to a programming error.
+	 * The occurrence of c. could be beyond the control of
+	 * Trusted Firmware. It makes sense to return from this
+	 * exception instead of reporting an error.
 	 */
 	bl	get_interrupt_type_handler
-	cbz	x0, interrupt_error_\label
+	cbz	x0, interrupt_exit_\label
 	mov	x21, x0
 
 	mov	x0, #INTR_ID_UNAVAILABLE
@@ -117,14 +141,6 @@
 	b.eq	interrupt_exit_\label
 #endif
 
-	/*
-	 * Save the EL3 system registers needed to return from
-	 * this exception.
-	 */
-	mrs	x3, spsr_el3
-	mrs	x4, elr_el3
-	stp	x3, x4, [x20, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
-
 	/* Set the current security state in the 'flags' parameter */
 	mrs	x2, scr_el3
 	ubfx	x1, x2, #0, #1
@@ -142,13 +158,6 @@
 	/* Return from exception, possibly in a different security state */
 	b	el3_exit
 
-	/*
-	 * This label signifies a problem with the interrupt management
-	 * framework where it is not safe to go back to the instruction
-	 * where the interrupt was generated.
-	 */
-interrupt_error_\label:
-	bl	report_unhandled_interrupt
 	.endm
 
 
diff --git a/drivers/arm/gic/arm_gic.c b/drivers/arm/gic/arm_gic.c
index 2888e71..5217471 100644
--- a/drivers/arm/gic/arm_gic.c
+++ b/drivers/arm/gic/arm_gic.c
@@ -401,7 +401,7 @@
 	uint32_t id;
 
 	assert(g_gicc_base);
-	id = gicc_read_hppir(g_gicc_base);
+	id = gicc_read_hppir(g_gicc_base) & INT_ID_MASK;
 
 	/* Assume that all secure interrupts are S-EL1 interrupts */
 	if (id < 1022)
@@ -423,7 +423,7 @@
 	uint32_t id;
 
 	assert(g_gicc_base);
-	id = gicc_read_hppir(g_gicc_base);
+	id = gicc_read_hppir(g_gicc_base) & INT_ID_MASK;
 
 	if (id < 1022)
 		return id;
@@ -435,7 +435,7 @@
 	 * Find out which non-secure interrupt it is under the assumption that
 	 * the GICC_CTLR.AckCtl bit is 0.
 	 */
-	return gicc_read_ahppir(g_gicc_base);
+	return gicc_read_ahppir(g_gicc_base) & INT_ID_MASK;
 }
 
 /*******************************************************************************
diff --git a/include/drivers/arm/gic_v2.h b/include/drivers/arm/gic_v2.h
index a2d3eee..54276b8 100644
--- a/include/drivers/arm/gic_v2.h
+++ b/include/drivers/arm/gic_v2.h
@@ -99,6 +99,9 @@
 #define GICC_DIR		0x1000
 #define GICC_PRIODROP           GICC_EOIR
 
+/* Common CPU Interface definitions */
+#define INT_ID_MASK		0x3ff
+
 /* GICC_CTLR bit definitions */
 #define EOI_MODE_NS		(1 << 10)
 #define EOI_MODE_S		(1 << 9)