Provide support for FIQ interrupts

This patch introduces support for FIQ virtual interrupts by adding
an "interrupt type" configuration for each INTID.

Following changes are done:
  - Helpers added to inject a virtual FIQ by setting HCR_EL2.VF
  - hf_interrupt_enable hypervisor call updated with a new
    "interrupt type" argument

Nominally, we intend to signal an NS interrupt to a SP as a virtual FIQ
using GICv3. The same interrupt can be signaled as a virtual IRQ if such
option is passed in the Hafnium interrupt enable call.
The reasoning is to ease migration of TEEs relying on receiving physical
Group1 NS/Group0 interrupts as FIQ (or foreign interrupts).
The same TEE now running as a Secure Partition receives a virtual FIQ
for a NS interrupt (or Group0 interrupt).
As mentioned above, there is also the flexibility to receive all
interrupts (Group1 S/Group1 NS/Group0) to the same vIRQ vector.

Change-Id: I78daf1ae226ea9cc01f65da36ae31ed9fff84f42
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 e72d3cd..6a636a4 100644
--- a/inc/hf/api.h
+++ b/inc/hf/api.h
@@ -27,7 +27,8 @@
 struct vcpu *api_abort(struct vcpu *current);
 struct vcpu *api_wake_up(struct vcpu *current, struct vcpu *target_vcpu);
 
-int64_t api_interrupt_enable(uint32_t intid, bool enable, struct vcpu *current);
+int64_t api_interrupt_enable(uint32_t intid, bool enable,
+			     enum interrupt_type type, struct vcpu *current);
 uint32_t api_interrupt_get(struct vcpu *current);
 int64_t api_interrupt_inject(ffa_vm_id_t target_vm_id,
 			     ffa_vcpu_index_t target_vcpu_idx, uint32_t intid,
diff --git a/inc/hf/vcpu.h b/inc/hf/vcpu.h
index 3668c8d..7a2bdf3 100644
--- a/inc/hf/vcpu.h
+++ b/inc/hf/vcpu.h
@@ -41,12 +41,16 @@
 	uint32_t interrupt_enabled[HF_NUM_INTIDS / INTERRUPT_REGISTER_BITS];
 	/** Bitfield keeping track of which interrupts are pending. */
 	uint32_t interrupt_pending[HF_NUM_INTIDS / INTERRUPT_REGISTER_BITS];
+	/** Bitfield recording the interrupt pin configuration. */
+	uint32_t interrupt_type[HF_NUM_INTIDS / INTERRUPT_REGISTER_BITS];
 	/**
 	 * The number of interrupts which are currently both enabled and
-	 * pending. i.e. the number of bits set in interrupt_enable &
-	 * interrupt_pending.
+	 * pending. Count independently virtual IRQ and FIQ interrupt types
+	 * i.e. the sum of the two counters is the number of bits set in
+	 * interrupt_enable & interrupt_pending.
 	 */
-	uint32_t enabled_and_pending_count;
+	uint32_t enabled_and_pending_irq_count;
+	uint32_t enabled_and_pending_fiq_count;
 };
 
 struct vcpu_fault_info {
@@ -116,3 +120,41 @@
 			    struct vcpu_fault_info *f);
 
 void vcpu_reset(struct vcpu *vcpu);
+
+static inline void vcpu_irq_count_increment(struct vcpu_locked vcpu_locked)
+{
+	vcpu_locked.vcpu->interrupts.enabled_and_pending_irq_count++;
+}
+
+static inline void vcpu_irq_count_decrement(struct vcpu_locked vcpu_locked)
+{
+	vcpu_locked.vcpu->interrupts.enabled_and_pending_irq_count--;
+}
+
+static inline void vcpu_fiq_count_increment(struct vcpu_locked vcpu_locked)
+{
+	vcpu_locked.vcpu->interrupts.enabled_and_pending_fiq_count++;
+}
+
+static inline void vcpu_fiq_count_decrement(struct vcpu_locked vcpu_locked)
+{
+	vcpu_locked.vcpu->interrupts.enabled_and_pending_fiq_count--;
+}
+
+static inline uint32_t vcpu_interrupt_irq_count_get(
+	struct vcpu_locked vcpu_locked)
+{
+	return vcpu_locked.vcpu->interrupts.enabled_and_pending_irq_count;
+}
+
+static inline uint32_t vcpu_interrupt_fiq_count_get(
+	struct vcpu_locked vcpu_locked)
+{
+	return vcpu_locked.vcpu->interrupts.enabled_and_pending_fiq_count;
+}
+
+static inline uint32_t vcpu_interrupt_count_get(struct vcpu_locked vcpu_locked)
+{
+	return vcpu_locked.vcpu->interrupts.enabled_and_pending_irq_count +
+	       vcpu_locked.vcpu->interrupts.enabled_and_pending_fiq_count;
+}