Non-secure interrupt handling with managed exit

This patch implements the scenario when non-secure interrupt occurs
while executing a Secure Partition at S-EL1.

A non-secure interrupt traps as FIQ at S-EL2.
If the SP supports managed exit:
 1. The SPMC decreases the current core priority mask register to
    prevent other interrupts triggering while the managed exit
    operation is on-going.
 2. The SPMC injects a "managed exit" virtual interrupt to the current
    SP and resumes it.
 3. The SP traps to its interrupt handler (IRQ or FIQ depending on
    the interrupt enable call), it performs its housekeeping and returns
    with FFA_MSG_SEND_DIRECT_RESP.
 4. The SPMC on receiving FFA_MSG_SEND_DIRECT_RESP, increases the
    current core priority mask register and forwards the direct message
    response to the "other world".
 5. The SPMD transfers control back to non-secure world for handling of
    the non-secure interrupt. The SP driver can schedule again the SP
    by another direct message request.

If the SP does not support managed exit:
  1. The SP is pre-empted and its live context saved.
  2. The SPMC switches to "other world" with FFA_INTERRUPT.
  3. the SPMD forwards FFA_INTERRUPT to the normal world.
  4. The normal world handles the non-secure interrupt.
  5. The SP driver has the possiblity to schedule again
     the SP by ffa_run.

Change-Id: I7858e5ad49225d2c26e6d4c31f8f4d007d6a7d07
Signed-off-by: Manish Pandey <manish.pandey2@arm.com>
Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
diff --git a/inc/hf/api.h b/inc/hf/api.h
index 6a636a4..8af07ee 100644
--- a/inc/hf/api.h
+++ b/inc/hf/api.h
@@ -33,6 +33,9 @@
 int64_t api_interrupt_inject(ffa_vm_id_t target_vm_id,
 			     ffa_vcpu_index_t target_vcpu_idx, uint32_t intid,
 			     struct vcpu *current, struct vcpu **next);
+int64_t api_interrupt_inject_locked(struct vcpu_locked target_locked,
+				    uint32_t intid, struct vcpu *current,
+				    struct vcpu **next);
 
 struct ffa_value api_ffa_msg_send(ffa_vm_id_t sender_vm_id,
 				  ffa_vm_id_t receiver_vm_id, uint32_t size,
@@ -87,3 +90,6 @@
 					      struct vcpu **next);
 struct ffa_value api_ffa_secondary_ep_register(ipaddr_t entry_point,
 					       struct vcpu *current);
+struct vcpu *api_switch_to_other_world(struct vcpu *current,
+				       struct ffa_value other_world_ret,
+				       enum vcpu_state vcpu_state);