git: 4713f5401317 - main - arm64: Add non-PCI MSI support

From: Andrew Turner <andrew_at_FreeBSD.org>
Date: Tue, 18 Nov 2025 18:02:35 UTC
The branch main has been updated by andrew:

URL: https://cgit.FreeBSD.org/src/commit/?id=4713f54013176fc73ada29cf094016fd3b328c80

commit 4713f54013176fc73ada29cf094016fd3b328c80
Author:     Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2025-11-18 18:00:30 +0000
Commit:     Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2025-11-18 18:00:30 +0000

    arm64: Add non-PCI MSI support
    
    Add the arm64 parts to support for non-PCI MSI and MSI-X interrupts.
    
    Sponsored by:   Arm Ltd
    Differential Revision:  https://reviews.freebsd.org/D53331
---
 sys/arm64/arm64/nexus.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 85 insertions(+)

diff --git a/sys/arm64/arm64/nexus.c b/sys/arm64/arm64/nexus.c
index 26b3389db172..012bf859eb3c 100644
--- a/sys/arm64/arm64/nexus.c
+++ b/sys/arm64/arm64/nexus.c
@@ -72,6 +72,8 @@
 #include "acpi_bus_if.h"
 #endif
 
+#include "pcib_if.h"
+
 extern struct bus_space memmap_bus;
 
 static MALLOC_DEFINE(M_NEXUSDEV, "nexusdev", "Nexus device");
@@ -123,6 +125,15 @@ static bus_get_bus_tag_t	nexus_get_bus_tag;
 
 #ifdef FDT
 static ofw_bus_map_intr_t	nexus_ofw_map_intr;
+/*
+ * PCIB interface
+ */
+static pcib_alloc_msi_t		nexus_fdt_pcib_alloc_msi;
+static pcib_release_msi_t	nexus_fdt_pcib_release_msi;
+static pcib_alloc_msix_t	nexus_fdt_pcib_alloc_msix;
+static pcib_release_msix_t	nexus_fdt_pcib_release_msix;
+static pcib_map_msi_t		nexus_fdt_pcib_map_msi;
+
 #endif
 
 static device_method_t nexus_methods[] = {
@@ -441,6 +452,13 @@ static device_method_t nexus_fdt_methods[] = {
 	/* OFW interface */
 	DEVMETHOD(ofw_bus_map_intr,	nexus_ofw_map_intr),
 
+	/* PCIB interface */
+	DEVMETHOD(pcib_alloc_msi,	nexus_fdt_pcib_alloc_msi),
+	DEVMETHOD(pcib_release_msi,	nexus_fdt_pcib_release_msi),
+	DEVMETHOD(pcib_alloc_msix,	nexus_fdt_pcib_alloc_msix),
+	DEVMETHOD(pcib_release_msix,	nexus_fdt_pcib_release_msix),
+	DEVMETHOD(pcib_map_msi,		nexus_fdt_pcib_map_msi),
+
 	DEVMETHOD_END,
 };
 
@@ -518,6 +536,73 @@ nexus_ofw_map_intr(device_t dev, device_t child, phandle_t iparent, int icells,
 	irq = intr_map_irq(NULL, iparent, (struct intr_map_data *)fdt_data);
 	return (irq);
 }
+
+static int
+nexus_fdt_pcib_alloc_msi(device_t dev, device_t child, int count, int maxcount,
+    int *irqs)
+{
+	phandle_t msi_parent;
+	int error;
+
+	error = ofw_bus_msimap(ofw_bus_get_node(child), 0, &msi_parent, NULL);
+	if (error != 0)
+		return (error);
+
+	return (intr_alloc_msi(dev, child, msi_parent, count, maxcount, irqs));
+}
+
+static int
+nexus_fdt_pcib_release_msi(device_t dev, device_t child, int count, int *irqs)
+{
+	phandle_t msi_parent;
+	int error;
+
+	error = ofw_bus_msimap(ofw_bus_get_node(child), 0, &msi_parent, NULL);
+	if (error != 0)
+		return (error);
+
+	return (intr_release_msi(dev, child, msi_parent, count, irqs));
+}
+
+static int
+nexus_fdt_pcib_alloc_msix(device_t dev, device_t child, int *irq)
+{
+	phandle_t msi_parent;
+	int error;
+
+	error = ofw_bus_msimap(ofw_bus_get_node(child), 0, &msi_parent, NULL);
+	if (error != 0)
+		return (error);
+
+	return (intr_alloc_msix(dev, child, msi_parent, irq));
+}
+
+static int
+nexus_fdt_pcib_release_msix(device_t dev, device_t child, int irq)
+{
+	phandle_t msi_parent;
+	int error;
+
+	error = ofw_bus_msimap(ofw_bus_get_node(child), 0, &msi_parent, NULL);
+	if (error != 0)
+		return (error);
+
+	return (intr_release_msix(dev, child, msi_parent, irq));
+}
+
+static int
+nexus_fdt_pcib_map_msi(device_t dev, device_t child, int irq, uint64_t *addr,
+    uint32_t *data)
+{
+	phandle_t msi_parent;
+	int error;
+
+	error = ofw_bus_msimap(ofw_bus_get_node(child), 0, &msi_parent, NULL);
+	if (error != 0)
+		return (error);
+
+	return (intr_map_msi(dev, child, msi_parent, irq, addr, data));
+}
 #endif
 
 #ifdef DEV_ACPI