} __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;
#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)
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 */
#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.
*/
#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)
*/
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__ */