Add support for synchronous FIQ handling in TSP

This patch adds support in the TSP for handling S-EL1 interrupts
handed over by the TSPD. It includes GIC support in its platform port,
updates various statistics related to FIQ handling, exports an entry
point that the TSPD can use to hand over interrupts and defines the
handover protocol w.r.t what context is the TSP expected to preserve
and the state in which the entry point is invoked by the TSPD.

Change-Id: I93b22e5a8133400e4da366f5fc862f871038df39
diff --git a/bl32/tsp/aarch64/tsp_entrypoint.S b/bl32/tsp/aarch64/tsp_entrypoint.S
index fab64cf..bb0880f 100644
--- a/bl32/tsp/aarch64/tsp_entrypoint.S
+++ b/bl32/tsp/aarch64/tsp_entrypoint.S
@@ -39,6 +39,7 @@
 	.globl	tsp_cpu_suspend_entry
 	.globl	tsp_cpu_resume_entry
 	.globl	tsp_fast_smc_entry
+	.globl	tsp_fiq_entry
 
 	/* ---------------------------------------------
 	 * Populate the params in x0-x7 from the pointer
@@ -53,6 +54,22 @@
 	smc	#0
 	.endm
 
+	.macro	save_eret_context reg1 reg2
+	mrs	\reg1, elr_el1
+	mrs	\reg2, spsr_el1
+	stp	\reg1, \reg2, [sp, #-0x10]!
+	stp	x30, x18, [sp, #-0x10]!
+	.endm
+
+	.macro restore_eret_context reg1 reg2
+	ldp	x30, x18, [sp], #0x10
+	ldp	\reg1, \reg2, [sp], #0x10
+	msr	elr_el1, \reg1
+	msr	spsr_el1, \reg2
+	.endm
+
+	.section	.text, "ax"
+	.align 3
 
 func tsp_entrypoint
 
@@ -227,6 +244,58 @@
 	restore_args_call_smc
 
 	/*---------------------------------------------
+	 * This entrypoint is used by the TSPD to pass
+	 * control for handling a pending S-EL1 FIQ.
+	 * 'x0' contains a magic number which indicates
+	 * this. TSPD expects control to be handed back
+	 * at the end of FIQ processing. This is done
+	 * through an SMC. The handover agreement is:
+	 *
+	 * 1. PSTATE.DAIF are set upon entry. 'x1' has
+	 *    the ELR_EL3 from the non-secure state.
+	 * 2. TSP has to preserve the callee saved
+	 *    general purpose registers, SP_EL1/EL0 and
+	 *    LR.
+	 * 3. TSP has to preserve the system and vfp
+	 *    registers (if applicable).
+	 * 4. TSP can use 'x0-x18' to enable its C
+	 *    runtime.
+	 * 5. TSP returns to TSPD using an SMC with
+	 *    'x0' = TSP_HANDLED_S_EL1_FIQ
+	 * ---------------------------------------------
+	 */
+func	tsp_fiq_entry
+#if DEBUG
+	mov	x2, #(TSP_HANDLE_FIQ_AND_RETURN & ~0xffff)
+	movk	x2, #(TSP_HANDLE_FIQ_AND_RETURN &  0xffff)
+	cmp	x0, x2
+	b.ne	tsp_fiq_entry_panic
+#endif
+	/*---------------------------------------------
+	 * Save any previous context needed to perform
+	 * an exception return from S-EL1 e.g. context
+	 * from a previous IRQ. Update statistics and
+	 * handle the FIQ before returning to the TSPD.
+	 * IRQ/FIQs are not enabled since that will
+	 * complicate the implementation. Execution
+	 * will be transferred back to the normal world
+	 * in any case. A non-zero return value from the
+	 * fiq handler is an error.
+	 * ---------------------------------------------
+	 */
+	save_eret_context x2 x3
+	bl	tsp_update_sync_fiq_stats
+	bl	tsp_fiq_handler
+	cbnz	x0, tsp_fiq_entry_panic
+	restore_eret_context x2 x3
+	mov	x0, #(TSP_HANDLED_S_EL1_FIQ & ~0xffff)
+	movk	x0, #(TSP_HANDLED_S_EL1_FIQ &  0xffff)
+	smc	#0
+
+tsp_fiq_entry_panic:
+	b	tsp_fiq_entry_panic
+
+	/*---------------------------------------------
 	 * This entrypoint is used by the TSPD when this
 	 * cpu resumes execution after an earlier
 	 * CPU_SUSPEND psci call to ask the TSP to