lib: utils/irqchip: Use heap in PLIC, APLIC and IMSIC drivers
authorAnup Patel <apatel@ventanamicro.com>
Wed, 19 Apr 2023 11:25:59 +0000 (16:55 +0530)
committerAnup Patel <anup@brainfault.org>
Mon, 5 Jun 2023 10:27:58 +0000 (15:57 +0530)
Let's use heap allocation in PLIC, APLIC, and IMSIC irqchip drivers
instead of using a fixed size global array.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
lib/utils/irqchip/fdt_irqchip_aplic.c
lib/utils/irqchip/fdt_irqchip_imsic.c
lib/utils/irqchip/fdt_irqchip_plic.c

index 965f02394c49af2ed0b839998fd1785ae54a627f..583a3e30fa5807066059c9cea24fe987a689b936 100644 (file)
 #include <libfdt.h>
 #include <sbi/riscv_asm.h>
 #include <sbi/sbi_error.h>
+#include <sbi/sbi_heap.h>
 #include <sbi_utils/fdt/fdt_helper.h>
 #include <sbi_utils/irqchip/fdt_irqchip.h>
 #include <sbi_utils/irqchip/aplic.h>
 
-#define APLIC_MAX_NR                   16
-
-static unsigned long aplic_count = 0;
-static struct aplic_data aplic[APLIC_MAX_NR];
-
 static int irqchip_aplic_warm_init(void)
 {
        /* Nothing to do here. */
@@ -32,15 +28,23 @@ static int irqchip_aplic_cold_init(void *fdt, int nodeoff,
        int rc;
        struct aplic_data *pd;
 
-       if (APLIC_MAX_NR <= aplic_count)
-               return SBI_ENOSPC;
-       pd = &aplic[aplic_count++];
+       pd = sbi_zalloc(sizeof(*pd));
+       if (!pd)
+               return SBI_ENOMEM;
 
        rc = fdt_parse_aplic_node(fdt, nodeoff, pd);
        if (rc)
-               return rc;
+               goto fail_free_data;
+
+       rc = aplic_cold_irqchip_init(pd);
+       if (rc)
+               goto fail_free_data;
+
+       return 0;
 
-       return aplic_cold_irqchip_init(pd);
+fail_free_data:
+       sbi_free(pd);
+       return rc;
 }
 
 static const struct fdt_match irqchip_aplic_match[] = {
index 6020ac0b992a1c67b79c86e980494bf6d2b8a8d1..590b2022b0a10d2dc76a77cccae3c54600c0c2d5 100644 (file)
 #include <libfdt.h>
 #include <sbi/riscv_asm.h>
 #include <sbi/sbi_error.h>
+#include <sbi/sbi_heap.h>
 #include <sbi/sbi_hartmask.h>
 #include <sbi_utils/fdt/fdt_helper.h>
 #include <sbi_utils/irqchip/fdt_irqchip.h>
 #include <sbi_utils/irqchip/imsic.h>
 
-#define IMSIC_MAX_NR                   16
-
-static unsigned long imsic_count = 0;
-static struct imsic_data imsic[IMSIC_MAX_NR];
-
 static int irqchip_imsic_update_hartid_table(void *fdt, int nodeoff,
                                             struct imsic_data *id)
 {
@@ -71,27 +67,27 @@ static int irqchip_imsic_cold_init(void *fdt, int nodeoff,
        int rc;
        struct imsic_data *id;
 
-       if (IMSIC_MAX_NR <= imsic_count)
-               return SBI_ENOSPC;
-       id = &imsic[imsic_count];
+       id = sbi_zalloc(sizeof(*id));
+       if (!id)
+               return SBI_ENOMEM;
 
        rc = fdt_parse_imsic_node(fdt, nodeoff, id);
-       if (rc)
-               return rc;
-       if (!id->targets_mmode)
-               return 0;
+       if (rc || !id->targets_mmode)
+               goto fail_free_data;
 
        rc = irqchip_imsic_update_hartid_table(fdt, nodeoff, id);
        if (rc)
-               return rc;
+               goto fail_free_data;
 
        rc = imsic_cold_irqchip_init(id);
        if (rc)
-               return rc;
-
-       imsic_count++;
+               goto fail_free_data;
 
        return 0;
+
+fail_free_data:
+       sbi_free(id);
+       return rc;
 }
 
 static const struct fdt_match irqchip_imsic_match[] = {
index 1aadf9190caeb092797e4e21d61e50a2948d828b..d7332848eff5fd4be535edc3d24ce97797b33e7a 100644 (file)
 #include <sbi/riscv_asm.h>
 #include <sbi/riscv_io.h>
 #include <sbi/sbi_error.h>
+#include <sbi/sbi_heap.h>
 #include <sbi/sbi_hartmask.h>
 #include <sbi_utils/fdt/fdt_helper.h>
 #include <sbi_utils/irqchip/fdt_irqchip.h>
 #include <sbi_utils/irqchip/plic.h>
 
-#define PLIC_MAX_NR                    16
-
-static unsigned long plic_count = 0;
-static struct plic_data plic[PLIC_MAX_NR];
-
 static struct plic_data *plic_hartid2data[SBI_HARTMASK_MAX_BITS];
-static int plic_hartid2context[SBI_HARTMASK_MAX_BITS][2];
+static int plic_hartid2context[SBI_HARTMASK_MAX_BITS][2] = { { -1 } };
 
 void fdt_plic_priority_save(u8 *priority, u32 num)
 {
@@ -114,16 +110,16 @@ static int irqchip_plic_update_hartid_table(void *fdt, int nodeoff,
 static int irqchip_plic_cold_init(void *fdt, int nodeoff,
                                  const struct fdt_match *match)
 {
-       int i, rc;
+       int rc;
        struct plic_data *pd;
 
-       if (PLIC_MAX_NR <= plic_count)
-               return SBI_ENOSPC;
-       pd = &plic[plic_count++];
+       pd = sbi_zalloc(sizeof(*pd));
+       if (!pd)
+               return SBI_ENOMEM;
 
        rc = fdt_parse_plic_node(fdt, nodeoff, pd);
        if (rc)
-               return rc;
+               goto fail_free_data;
 
        if (match->data) {
                void (*plic_plat_init)(struct plic_data *) = match->data;
@@ -132,17 +128,17 @@ static int irqchip_plic_cold_init(void *fdt, int nodeoff,
 
        rc = plic_cold_irqchip_init(pd);
        if (rc)
-               return rc;
+               goto fail_free_data;
 
-       if (plic_count == 1) {
-               for (i = 0; i < SBI_HARTMASK_MAX_BITS; i++) {
-                       plic_hartid2data[i] = NULL;
-                       plic_hartid2context[i][0] = -1;
-                       plic_hartid2context[i][1] = -1;
-               }
-       }
+       rc = irqchip_plic_update_hartid_table(fdt, nodeoff, pd);
+       if (rc)
+               goto fail_free_data;
+
+       return 0;
 
-       return irqchip_plic_update_hartid_table(fdt, nodeoff, pd);
+fail_free_data:
+       sbi_free(pd);
+       return rc;
 }
 
 #define THEAD_PLIC_CTRL_REG 0x1ffffc