]> xenbits.xensource.com Git - unikraft/unikraft.git/commitdiff
lib/ukintctlr: Add IRQ allocation
authorMichalis Pappas <michalis@unikraft.io>
Thu, 14 Sep 2023 10:43:27 +0000 (12:43 +0200)
committerRazvan Deaconescu <razvand@unikraft.io>
Fri, 20 Oct 2023 16:35:55 +0000 (19:35 +0300)
Add an IRQ allocation function that will automatically assign
from a pool of free IRQs.

Notice: Picking individual commits in this PR will break the build.

Signed-off-by: Marco Schlumpp <marco@unikraft.io>
Signed-off-by: Michalis Pappas <michalis@unikraft.io>
Reviewed-by: Sergiu Moga <sergiu@unikraft.io>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #1103

lib/ukintctlr/exportsyms.uk
lib/ukintctlr/ukintctlr.c

index 6375a3f5f351681c2fb15ddf21eb79aa272eb9cf..632f038d3ad1959e4cbf9d6a201a7cdc640c7a66 100644 (file)
@@ -2,6 +2,8 @@ uk_intctlr
 uk_intctlr_init
 uk_intctlr_irq_configure
 uk_intctlr_irq_fdt_xlat
+uk_intctlr_irq_alloc
+uk_intctlr_irq_free
 uk_intctlr_irq_handle
 uk_intctlr_irq_register
 uk_intctlr_irq_unregister
index d92ace980d962b325f697a237574d788be2a215f..401f145911a23687a25e50e809119f90fe8a6b09 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <stdlib.h>
 #include <uk/alloc.h>
+#include <uk/bitmap.h>
 #include <uk/plat/lcpu.h>
 #include <uk/plat/time.h>
 #include <uk/intctlr.h>
 #include <uk/arch/ctx.h>
 #endif /* CONFIG_LIBUKINTCTLR_ISR_ECTX_ASSERTIONS */
 
-#ifndef UK_INTCTLR_MAX_IRQ
+#if !defined(UK_INTCTLR_MAX_IRQ) ||                                    \
+       !defined(UK_INTCTLR_ALLOCABLE_IRQ_COUNT) ||                     \
+       !defined(UK_INTCTLR_FIRST_ALLOCABLE_IRQ) ||                     \
+       !defined(UK_INTCTLR_LAST_ALLOCABLE_IRQ)
 #error "Incomplete definition of uk_intctlr driver limits"
 #endif
 
 #define MAX_IRQ                                UK_INTCTLR_MAX_IRQ
 #define MAX_HANDLERS_PER_IRQ           CONFIG_LIBUKINTCTLR_MAX_HANDLERS_PER_IRQ
 
+#define ALLOCABLE_IRQ_COUNT            UK_INTCTLR_ALLOCABLE_IRQ_COUNT
+#define FIRST_ALLOCABLE_IRQ            UK_INTCTLR_FIRST_ALLOCABLE_IRQ
+#define LAST_ALLOCABLE_IRQ             UK_INTCTLR_LAST_ALLOCABLE_IRQ
+
 struct uk_intctlr_desc *uk_intctlr;
 
 UK_EVENT(UK_INTCTLR_EVENT_IRQ);
@@ -55,6 +63,8 @@ UK_EVENT(UK_INTCTLR_EVENT_IRQ);
 UK_TRACEPOINT(trace_uk_intctlr_unhandled_irq, "Unhandled irq=%lu\n",
              unsigned long);
 
+static unsigned long irqs_allocated[UK_BITS_TO_LONGS(ALLOCABLE_IRQ_COUNT)];
+
 /* IRQ handlers declarations */
 struct irq_handler {
        uk_intctlr_irq_handler_func_t func;
@@ -245,6 +255,45 @@ int uk_intctlr_irq_fdt_xlat(const void *fdt, int nodeoffset, __u32 index,
        return uk_intctlr->ops->fdt_xlat(fdt, nodeoffset, index, irq);
 }
 
+int uk_intctlr_irq_alloc(unsigned int *irqs, __sz count)
+{
+       unsigned long start, idx;
+
+       UK_ASSERT(irqs);
+
+       start = uk_bitmap_find_next_zero_area(irqs_allocated,
+                                             ALLOCABLE_IRQ_COUNT, 0,
+                                             count, 0);
+       if (start == ALLOCABLE_IRQ_COUNT)
+               return -ENOSPC;
+
+       uk_bitmap_set(irqs_allocated, start, count);
+       for (idx = start; idx < (start + count); idx++) {
+               *irqs = idx + FIRST_ALLOCABLE_IRQ;
+               irqs++;
+       }
+
+       return 0;
+}
+
+int uk_intctlr_irq_free(unsigned int *irqs, __sz count)
+{
+       int rc = 0;
+
+       UK_ASSERT(irqs);
+
+       for (__sz i = 0; i < count; i++) {
+               UK_ASSERT(irqs[i] >= FIRST_ALLOCABLE_IRQ &&
+                         irqs[i] <= LAST_ALLOCABLE_IRQ);
+
+               rc = uk_test_and_clear_bit(irqs[i] - FIRST_ALLOCABLE_IRQ,
+                                          irqs_allocated);
+               UK_ASSERT(rc);
+       }
+
+       return !rc;
+}
+
 int uk_intctlr_init(struct uk_alloc *a __unused)
 {
        UK_ASSERT(uk_intctlr);