Module Name:    src
Committed By:   jmcneill
Date:           Wed Nov 25 21:02:35 UTC 2020

Modified Files:
        src/sys/arch/arm/fdt: gicv3_fdt.c

Log Message:
Add support for message-based interrupts.


To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/arm/fdt/gicv3_fdt.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/arm/fdt/gicv3_fdt.c
diff -u src/sys/arch/arm/fdt/gicv3_fdt.c:1.9 src/sys/arch/arm/fdt/gicv3_fdt.c:1.10
--- src/sys/arch/arm/fdt/gicv3_fdt.c:1.9	Tue Nov 24 23:31:55 2020
+++ src/sys/arch/arm/fdt/gicv3_fdt.c	Wed Nov 25 21:02:35 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: gicv3_fdt.c,v 1.9 2020/11/24 23:31:55 jmcneill Exp $ */
+/* $NetBSD: gicv3_fdt.c,v 1.10 2020/11/25 21:02:35 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015-2018 Jared McNeill <jmcne...@invisible.ca>
@@ -31,7 +31,7 @@
 #define	_INTR_PRIVATE
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gicv3_fdt.c,v 1.9 2020/11/24 23:31:55 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gicv3_fdt.c,v 1.10 2020/11/25 21:02:35 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -48,6 +48,7 @@ __KERNEL_RCSID(0, "$NetBSD: gicv3_fdt.c,
 #include <arm/cortex/gicv3.h>
 #include <arm/cortex/gicv3_its.h>
 #include <arm/cortex/gic_reg.h>
+#include <arm/cortex/gic_v2m.h>
 
 #define	GICV3_MAXIRQ	1020
 
@@ -62,6 +63,7 @@ static void	gicv3_fdt_attach(device_t, d
 
 static int	gicv3_fdt_map_registers(struct gicv3_fdt_softc *);
 #if NPCI > 0 && defined(__HAVE_PCI_MSI_MSIX)
+static void	gicv3_fdt_attach_mbi(struct gicv3_fdt_softc *);
 static void	gicv3_fdt_attach_its(struct gicv3_fdt_softc *, bus_space_tag_t, int);
 #endif
 
@@ -176,12 +178,18 @@ gicv3_fdt_attach(device_t parent, device
 	}
 
 #if NPCI > 0 && defined(__HAVE_PCI_MSI_MSIX)
-	for (int child = OF_child(phandle); child; child = OF_peer(child)) {
-		if (!fdtbus_status_okay(child))
-			continue;
-		const char * const its_compat[] = { "arm,gic-v3-its", NULL };
-		if (of_match_compatible(child, its_compat))
-			gicv3_fdt_attach_its(sc, faa->faa_bst, child);
+	if (of_hasprop(phandle, "msi-controller")) {
+		/* Message Based Interrupts */
+		gicv3_fdt_attach_mbi(sc);
+	} else {
+		/* Interrupt Translation Services */
+		for (int child = OF_child(phandle); child; child = OF_peer(child)) {
+			if (!fdtbus_status_okay(child))
+				continue;
+			const char * const its_compat[] = { "arm,gic-v3-its", NULL };
+			if (of_match_compatible(child, its_compat))
+				gicv3_fdt_attach_its(sc, faa->faa_bst, child);
+		}
 	}
 #endif
 
@@ -257,6 +265,52 @@ gicv3_fdt_map_registers(struct gicv3_fdt
 
 #if NPCI > 0 && defined(__HAVE_PCI_MSI_MSIX)
 static void
+gicv3_fdt_attach_mbi(struct gicv3_fdt_softc *sc)
+{
+	struct gic_v2m_frame *frame;
+	const u_int *ranges;
+	bus_addr_t addr;
+	int len, frame_count;
+
+	if (of_hasprop(sc->sc_phandle, "mbi-alias")) {
+		aprint_error_dev(sc->sc_gic.sc_dev, "'mbi-alias' property not supported\n");
+		return;
+	}
+
+	if (fdtbus_get_reg(sc->sc_phandle, 0, &addr, NULL) != 0)
+		return;
+
+	ranges = fdtbus_get_prop(sc->sc_phandle, "mbi-ranges", &len);
+	if (ranges == NULL) {
+		aprint_error_dev(sc->sc_gic.sc_dev, "missing 'mbi-ranges' property\n");
+		return;
+	}
+
+	frame_count = 0;
+	while (len >= 8) {
+		const u_int base_spi = be32dec(&ranges[0]);
+		const u_int num_spis = be32dec(&ranges[1]);
+
+		frame = kmem_zalloc(sizeof(*frame), KM_SLEEP);
+		frame->frame_reg = addr;
+		frame->frame_pic = pic_list[0];
+		frame->frame_base = base_spi;
+		frame->frame_count = num_spis;
+
+		if (gic_v2m_init(frame, sc->sc_gic.sc_dev, frame_count++) != 0) {
+			aprint_error_dev(sc->sc_gic.sc_dev, "failed to initialize MBI frame\n");
+		} else {
+			aprint_normal_dev(sc->sc_gic.sc_dev, "MBI frame @ %#" PRIx64
+			    ", SPIs %u-%u\n", frame->frame_reg,
+			    frame->frame_base, frame->frame_base + frame->frame_count - 1);
+		}
+
+		ranges += 2;
+		len -= 8;
+	}
+}
+
+static void
 gicv3_fdt_attach_its(struct gicv3_fdt_softc *sc, bus_space_tag_t bst, int phandle)
 {
 	bus_space_handle_t bsh;

Reply via email to