refactor: add interrupt_bitmap struct

Since bitmaps for tracking interrupt IDs are used in both
manifest parsing as well as interrupt handling make a common
struct that can be used. Also introduce helper functions for
accessing and modifying the bitmap.

Signed-off-by: Daniel Boulby <daniel.boulby@arm.com>
Change-Id: Icbbc931d732bf7075f854adbe517c6ea341dc5d0
diff --git a/inc/hf/interrupt_desc.h b/inc/hf/interrupt_desc.h
index 1f78e48..e95e47b 100644
--- a/inc/hf/interrupt_desc.h
+++ b/inc/hf/interrupt_desc.h
@@ -20,9 +20,36 @@
 /* The number of bits in each element of the interrupt bitfields. */
 #define INTERRUPT_REGISTER_BITS 32
 
-#define INTID_INDEX(intid) (intid / INTERRUPT_REGISTER_BITS)
-#define INTID_MASK(v, intid) (v << (intid % INTERRUPT_REGISTER_BITS))
+struct interrupt_bitmap {
+	uint32_t bitmap[HF_NUM_INTIDS / INTERRUPT_REGISTER_BITS];
+};
 
+static inline uint32_t interrupt_bitmap_get_value(
+	struct interrupt_bitmap *bitmap, uint32_t intid)
+{
+	uint32_t index = intid / INTERRUPT_REGISTER_BITS;
+	uint32_t shift = intid % INTERRUPT_REGISTER_BITS;
+
+	return (bitmap->bitmap[index] >> shift) & 1U;
+}
+
+static inline void interrupt_bitmap_set_value(struct interrupt_bitmap *bitmap,
+					      uint32_t intid)
+{
+	uint32_t index = intid / INTERRUPT_REGISTER_BITS;
+	uint32_t shift = intid % INTERRUPT_REGISTER_BITS;
+
+	bitmap->bitmap[index] |= 1U << shift;
+}
+
+static inline void interrupt_bitmap_clear_value(struct interrupt_bitmap *bitmap,
+						uint32_t intid)
+{
+	uint32_t index = intid / INTERRUPT_REGISTER_BITS;
+	uint32_t shift = intid % INTERRUPT_REGISTER_BITS;
+
+	bitmap->bitmap[index] &= ~(1U << shift);
+}
 /**
  * Attributes encoding in the manifest:
 
diff --git a/inc/hf/vcpu.h b/inc/hf/vcpu.h
index 47f9ed6..c960793 100644
--- a/inc/hf/vcpu.h
+++ b/inc/hf/vcpu.h
@@ -42,11 +42,11 @@
 
 struct interrupts {
 	/** Bitfield keeping track of which interrupts are enabled. */
-	uint32_t interrupt_enabled[HF_NUM_INTIDS / INTERRUPT_REGISTER_BITS];
+	struct interrupt_bitmap interrupt_enabled;
 	/** Bitfield keeping track of which interrupts are pending. */
-	uint32_t interrupt_pending[HF_NUM_INTIDS / INTERRUPT_REGISTER_BITS];
+	struct interrupt_bitmap interrupt_pending;
 	/** Bitfield recording the interrupt pin configuration. */
-	uint32_t interrupt_type[HF_NUM_INTIDS / INTERRUPT_REGISTER_BITS];
+	struct interrupt_bitmap interrupt_type;
 	/**
 	 * The number of interrupts which are currently both enabled and
 	 * pending. Count independently virtual IRQ and FIQ interrupt types
@@ -167,6 +167,63 @@
 
 void vcpu_set_phys_core_idx(struct vcpu *vcpu);
 
+static inline bool vcpu_is_virt_interrupt_enabled(struct interrupts *interrupts,
+						  uint32_t intid)
+{
+	return interrupt_bitmap_get_value(&interrupts->interrupt_enabled,
+					  intid) == 1U;
+}
+
+static inline void vcpu_virt_interrupt_set_enabled(
+	struct interrupts *interrupts, uint32_t intid)
+{
+	interrupt_bitmap_set_value(&interrupts->interrupt_enabled, intid);
+}
+
+static inline void vcpu_virt_interrupt_clear_enabled(
+	struct interrupts *interrupts, uint32_t intid)
+{
+	interrupt_bitmap_clear_value(&interrupts->interrupt_enabled, intid);
+}
+
+static inline bool vcpu_is_virt_interrupt_pending(struct interrupts *interrupts,
+						  uint32_t intid)
+{
+	return interrupt_bitmap_get_value(&interrupts->interrupt_pending,
+					  intid) == 1U;
+}
+
+static inline void vcpu_virt_interrupt_set_pending(
+	struct interrupts *interrupts, uint32_t intid)
+{
+	interrupt_bitmap_set_value(&interrupts->interrupt_pending, intid);
+}
+
+static inline void vcpu_virt_interrupt_clear_pending(
+	struct interrupts *interrupts, uint32_t intid)
+{
+	interrupt_bitmap_clear_value(&interrupts->interrupt_pending, intid);
+}
+
+static inline enum interrupt_type vcpu_virt_interrupt_get_type(
+	struct interrupts *interrupts, uint32_t intid)
+{
+	return (enum interrupt_type)interrupt_bitmap_get_value(
+		&interrupts->interrupt_type, intid);
+}
+
+static inline void vcpu_virt_interrupt_set_type(struct interrupts *interrupts,
+						uint32_t intid,
+						enum interrupt_type type)
+{
+	if (type == INTERRUPT_TYPE_IRQ) {
+		interrupt_bitmap_clear_value(&interrupts->interrupt_type,
+					     intid);
+	} else {
+		interrupt_bitmap_set_value(&interrupts->interrupt_type, intid);
+	}
+}
+
 static inline void vcpu_irq_count_increment(struct vcpu_locked vcpu_locked)
 {
 	vcpu_locked.vcpu->interrupts.enabled_and_pending_irq_count++;
@@ -187,6 +244,30 @@
 	vcpu_locked.vcpu->interrupts.enabled_and_pending_fiq_count--;
 }
 
+static inline void vcpu_interrupt_count_increment(
+	struct vcpu_locked vcpu_locked, struct interrupts *interrupts,
+	uint32_t intid)
+{
+	if (vcpu_virt_interrupt_get_type(interrupts, intid) ==
+	    INTERRUPT_TYPE_IRQ) {
+		vcpu_irq_count_increment(vcpu_locked);
+	} else {
+		vcpu_fiq_count_increment(vcpu_locked);
+	}
+}
+
+static inline void vcpu_interrupt_count_decrement(
+	struct vcpu_locked vcpu_locked, struct interrupts *interrupts,
+	uint32_t intid)
+{
+	if (vcpu_virt_interrupt_get_type(interrupts, intid) ==
+	    INTERRUPT_TYPE_IRQ) {
+		vcpu_irq_count_decrement(vcpu_locked);
+	} else {
+		vcpu_fiq_count_decrement(vcpu_locked);
+	}
+}
+
 static inline uint32_t vcpu_interrupt_irq_count_get(
 	struct vcpu_locked vcpu_locked)
 {