]> xenbits.xensource.com Git - unikraft/unikraft.git/commitdiff
plat/drivers/gic: Add a method for fetching the `GICD` from `MADT`
authorSergiu Moga <sergiu.moga@protonmail.com>
Tue, 23 May 2023 12:52:42 +0000 (15:52 +0300)
committerUnikraft <monkey@unikraft.io>
Fri, 11 Aug 2023 16:42:01 +0000 (16:42 +0000)
Since this applies for both `GICv2` and `GICv3`, implement a generic
method of fetching the unique `GICD` structure from the `MADT`.

Unlike `Devicetree`'s `reg` property, `ACPI` does not inform us of
the length of the `GIC Distributor`'s address space and therefore
one must assume the page-aligned default size from the specification:
- for GICv2: ARM Generic Interrupt Controller Architecture version
2.0 Issue B.b
- for GICv3: ARM Generic Interrupt Controller Architecture version
3 and version 4 Issue H

Signed-off-by: Sergiu Moga <sergiu.moga@protonmail.com>
Reviewed-by: Razvan Virtan <virtanrazvan@gmail.com>
Reviewed-by: Michalis Pappas <michalis@unikraft.io>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
Tested-by: Unikraft CI <monkey@unikraft.io>
GitHub-Closes: #912

plat/common/include/uk/plat/common/madt.h
plat/drivers/gic/gic-common.c
plat/drivers/include/gic/gic-v2.h
plat/drivers/include/gic/gic-v3.h
plat/drivers/include/gic/gic.h

index a3674c5d54bb3a779bcd5e408ad77292fa4517e4..1c57a8c51ed9a3769db8cc5f2bba043ebd75eb7d 100644 (file)
@@ -191,6 +191,11 @@ struct acpi_madt_gicc {
 } __packed;
 
 /* GIC Distributor (GICD) Structure */
+#define ACPI_MADT_GICD_VERSION_NONE                            0x0
+#define ACPI_MADT_GICD_VERSION_1                               0x1
+#define ACPI_MADT_GICD_VERSION_2                               0x2
+#define ACPI_MADT_GICD_VERSION_3                               0x3
+#define ACPI_MADT_GICD_VERSION_4                               0x4
 struct acpi_madt_gicd {
        struct acpi_subsdt_hdr hdr;
        __u16 reserved;
index 156be99a044b1814190f6b43a08c177b576be218..d66dfd694d0100cf9dbb92420955870ce52acdd7 100644 (file)
@@ -34,6 +34,7 @@
 #include <gic/gic.h>
 #include <gic/gic-v2.h>
 #include <gic/gic-v3.h>
+#include <uk/plat/common/acpi.h>
 
 /** Sanity check for GIC driver availability */
 #if !defined(CONFIG_LIBGICV2) && !defined(CONFIG_LIBGICV3)
@@ -78,3 +79,40 @@ uint32_t gic_irq_translate(uint32_t type, uint32_t irq)
 
        return (uint32_t)-1;
 }
+
+#if defined(CONFIG_UKPLAT_ACPI)
+int acpi_get_gicd(struct _gic_dev *g)
+{
+       union {
+               struct acpi_madt_gicd *gicd;
+               struct acpi_subsdt_hdr *h;
+       } m;
+       struct acpi_madt *madt;
+       __sz off, len;
+
+       madt = acpi_get_madt();
+       UK_ASSERT(madt);
+
+       len = madt->hdr.tab_len - sizeof(*madt);
+       for (off = 0; off < len; off += m.h->len) {
+               m.h = (struct acpi_subsdt_hdr *)(madt->entries + off);
+
+               if (m.h->type != ACPI_MADT_GICD)
+                       continue;
+
+               if (m.gicd->version == ACPI_MADT_GICD_VERSION_2)
+                       g->dist_mem_size = GICD_V2_MEM_SZ;
+               else if (m.gicd->version == ACPI_MADT_GICD_VERSION_3)
+                       g->dist_mem_size = GICD_V3_MEM_SZ;
+               else
+                       return -ENOTSUP;
+
+               g->dist_mem_addr = m.gicd->paddr;
+
+               /* Only one GIC Distributor */
+               return 0;
+       }
+
+       return -ENOENT;
+}
+#endif /* CONFIG_UKPLAT_ACPI */
index 8677e154f69a77eb0bfb684985a7c44c46b228dc..a05cf4682d07d8a7c1a6eaf154d08cfa2a1082e5 100644 (file)
 
 #include <gic/gic.h>
 
+/* GICv2 GICD register map size page aligned up according to
+ * ARM Generic Interrupt Controller Architecture version 2.0 Issue B.b.
+ */
+#define GICD_V2_MEM_SZ                                 0x01000
+
 /*
  * Distributor registers. Unikraft only supports running on non-secure
  * so we just describe non-secure registers.
index b01a8aa11cfeafcb8d3d8ac9bd2cbfaeea044f21..5588de944be3fa865bcaa90b7367b9d28bfd49d7 100644 (file)
  */
 #define GICC_CTLR_EL1_EOImode_drop     (1U << 1)
 
+/* Default size according to ARM Generic Interrupt Controller Architecture
+ * Specification GIC Architecture version 3 and version 4 Issue H.
+ */
+#define GICD_V3_MEM_SZ                 0x10000
+
 #define GICD_STATUSR                   (0x010)
 #define GICD_SETSPI_NSR                        (0x040)
 #define GICD_CLRSPI_NSR                        (0x048)
index 483267e0fd492d6f0786169f54bd4234e4a34705..820b9cd1b4d45777c5789906e5e2c00e388e3023 100644 (file)
@@ -166,4 +166,15 @@ int _dtb_init_gic(const void *fdt, struct _gic_dev **dev);
  */
 uint32_t gic_irq_translate(uint32_t type, uint32_t irq);
 
+/**
+ * Fetch data from an existing MADT's GICD table.
+ *
+ * @param _gic_dev The driver whose memory base and size to fill in
+ *
+ * @return 0 on success, < 0 otherwise
+ */
+#if defined(CONFIG_UKPLAT_ACPI)
+int acpi_get_gicd(struct _gic_dev *g);
+#endif /* CONFIG_UKPLAT_ACPI */
+
 #endif /* __PLAT_DRV_ARM_GIC_COMMON_H__ */