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/src/api.c b/src/api.c
index 94af06d..39b6298 100644
--- a/src/api.c
+++ b/src/api.c
@@ -614,8 +614,7 @@
 				    struct vcpu **next)
 {
 	struct vcpu *target_vcpu = target_locked.vcpu;
-	uint32_t intid_index = INTID_INDEX(intid);
-	uint32_t intid_mask = INTID_MASK(1U, intid);
+	struct interrupts *interrupts = &target_vcpu->interrupts;
 	int64_t ret = 0;
 
 	/*
@@ -623,19 +622,13 @@
 	 * if it is enabled and was not previously pending. Otherwise we can
 	 * skip everything except setting the pending bit.
 	 */
-	if (!(target_vcpu->interrupts.interrupt_enabled[intid_index] &
-	      ~target_vcpu->interrupts.interrupt_pending[intid_index] &
-	      intid_mask)) {
+	if (!(vcpu_is_virt_interrupt_enabled(interrupts, intid) &&
+	      !vcpu_is_virt_interrupt_pending(interrupts, intid))) {
 		goto out;
 	}
 
 	/* Increment the count. */
-	if ((target_vcpu->interrupts.interrupt_type[intid_index] &
-	     intid_mask) == INTID_MASK(INTERRUPT_TYPE_IRQ, intid)) {
-		vcpu_irq_count_increment(target_locked);
-	} else {
-		vcpu_fiq_count_increment(target_locked);
-	}
+	vcpu_interrupt_count_increment(target_locked, interrupts, intid);
 
 	/*
 	 * Only need to update state if there was not already an
@@ -657,7 +650,7 @@
 
 out:
 	/* Either way, make it pending. */
-	target_vcpu->interrupts.interrupt_pending[intid_index] |= intid_mask;
+	vcpu_virt_interrupt_set_pending(interrupts, intid);
 
 	return ret;
 }
@@ -2061,8 +2054,7 @@
 			     enum interrupt_type type, struct vcpu *current)
 {
 	struct vcpu_locked current_locked;
-	uint32_t intid_index = INTID_INDEX(intid);
-	uint32_t intid_mask = INTID_MASK(1U, intid);
+	struct interrupts *interrupts = &current->interrupts;
 
 	if (intid >= HF_NUM_INTIDS) {
 		return -1;
@@ -2070,49 +2062,29 @@
 
 	current_locked = vcpu_lock(current);
 	if (enable) {
-		if (type == INTERRUPT_TYPE_IRQ) {
-			current->interrupts.interrupt_type[intid_index] &=
-				~intid_mask;
-		} else if (type == INTERRUPT_TYPE_FIQ) {
-			current->interrupts.interrupt_type[intid_index] |=
-				intid_mask;
-		}
-
 		/*
 		 * If it is pending and was not enabled before, increment the
 		 * count.
 		 */
-		if (current->interrupts.interrupt_pending[intid_index] &
-		    ~current->interrupts.interrupt_enabled[intid_index] &
-		    intid_mask) {
-			if ((current->interrupts.interrupt_type[intid_index] &
-			     intid_mask) ==
-			    INTID_MASK(INTERRUPT_TYPE_IRQ, intid)) {
-				vcpu_irq_count_increment(current_locked);
-			} else {
-				vcpu_fiq_count_increment(current_locked);
-			}
+		if (vcpu_is_virt_interrupt_pending(interrupts, intid) &&
+		    !vcpu_is_virt_interrupt_enabled(interrupts, intid)) {
+			vcpu_interrupt_count_increment(current_locked,
+						       interrupts, intid);
 		}
-		current->interrupts.interrupt_enabled[intid_index] |=
-			intid_mask;
+		vcpu_virt_interrupt_set_enabled(interrupts, intid);
+		vcpu_virt_interrupt_set_type(interrupts, intid, type);
 	} else {
 		/*
 		 * If it is pending and was enabled before, decrement the count.
 		 */
-		if (current->interrupts.interrupt_pending[intid_index] &
-		    current->interrupts.interrupt_enabled[intid_index] &
-		    intid_mask) {
-			if ((current->interrupts.interrupt_type[intid_index] &
-			     intid_mask) ==
-			    INTID_MASK(INTERRUPT_TYPE_IRQ, intid)) {
-				vcpu_irq_count_decrement(current_locked);
-			} else {
-				vcpu_fiq_count_decrement(current_locked);
-			}
+		if (vcpu_is_virt_interrupt_pending(interrupts, intid) &&
+		    vcpu_is_virt_interrupt_enabled(interrupts, intid)) {
+			vcpu_interrupt_count_decrement(current_locked,
+						       interrupts, intid);
 		}
-		current->interrupts.interrupt_enabled[intid_index] &=
-			~intid_mask;
-		current->interrupts.interrupt_type[intid_index] &= ~intid_mask;
+		vcpu_virt_interrupt_clear_enabled(interrupts, intid);
+		vcpu_virt_interrupt_set_type(interrupts, intid,
+					     INTERRUPT_TYPE_IRQ);
 	}
 
 	vcpu_unlock(&current_locked);
@@ -2129,6 +2101,7 @@
 	uint32_t i;
 	uint32_t first_interrupt = HF_INVALID_INTID;
 	struct vcpu_locked current_locked;
+	struct interrupts *interrupts = &current->interrupts;
 
 	/*
 	 * Find the first enabled and pending interrupt ID, return it, and
@@ -2137,27 +2110,23 @@
 	current_locked = vcpu_lock(current);
 	for (i = 0; i < HF_NUM_INTIDS / INTERRUPT_REGISTER_BITS; ++i) {
 		uint32_t enabled_and_pending =
-			current->interrupts.interrupt_enabled[i] &
-			current->interrupts.interrupt_pending[i];
+			interrupts->interrupt_enabled.bitmap[i] &
+			interrupts->interrupt_pending.bitmap[i];
 
 		if (enabled_and_pending != 0) {
 			uint8_t bit_index = ctz(enabled_and_pending);
-			uint32_t intid_mask = 1U << bit_index;
+
+			first_interrupt =
+				i * INTERRUPT_REGISTER_BITS + bit_index;
 
 			/*
 			 * Mark it as no longer pending and decrement the count.
 			 */
-			current->interrupts.interrupt_pending[i] &= ~intid_mask;
+			vcpu_virt_interrupt_clear_pending(interrupts,
+							  first_interrupt);
 
-			if ((current->interrupts.interrupt_type[i] &
-			     intid_mask) == (INTERRUPT_TYPE_IRQ << bit_index)) {
-				vcpu_irq_count_decrement(current_locked);
-			} else {
-				vcpu_fiq_count_decrement(current_locked);
-			}
-
-			first_interrupt =
-				i * INTERRUPT_REGISTER_BITS + bit_index;
+			vcpu_interrupt_count_decrement(
+				current_locked, interrupts, first_interrupt);
 			break;
 		}
 	}
diff --git a/src/manifest.c b/src/manifest.c
index 58a2ff2..1108c93 100644
--- a/src/manifest.c
+++ b/src/manifest.c
@@ -43,7 +43,7 @@
  * in the manifest.
  */
 struct allocated_fields {
-	uint32_t intids[HF_NUM_INTIDS / INTERRUPT_REGISTER_BITS];
+	struct interrupt_bitmap intids;
 	struct {
 		uintptr_t base;
 		uintptr_t limit;
@@ -543,7 +543,7 @@
 	struct uint32list_iter list;
 	uint16_t i = 0;
 	uint32_t j = 0;
-	uint32_t *allocated_intids = allocated_fields->intids;
+	struct interrupt_bitmap allocated_intids = allocated_fields->intids;
 
 	dlog_verbose("  Partition Device Regions\n");
 
@@ -604,23 +604,19 @@
 		while (uint32list_has_next(&list) &&
 		       j < PARTITION_MAX_INTERRUPTS_PER_DEVICE) {
 			uint32_t intid;
-			uint32_t intid_index;
-			uint32_t intid_mask;
 
 			TRY(uint32list_get_next(
 				&list, &dev_regions[i].interrupts[j].id));
 			intid = dev_regions[i].interrupts[j].id;
-			intid_index = INTID_INDEX(intid);
-			intid_mask = INTID_MASK(1U, intid);
 
 			dlog_verbose("        ID = %u\n", intid);
 
-			if ((allocated_intids[intid_index] & intid_mask) !=
-			    0U) {
+			if (interrupt_bitmap_get_value(&allocated_intids,
+						       intid) == 1U) {
 				return MANIFEST_ERROR_INTERRUPT_ID_REPEATED;
 			}
 
-			allocated_intids[intid_index] |= intid_mask;
+			interrupt_bitmap_set_value(&allocated_intids, intid);
 
 			if (uint32list_has_next(&list)) {
 				TRY(uint32list_get_next(&list,