Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F173201819
D59169.id186204.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D59169.id186204.diff
View Options
diff --git a/sys/arm64/acpica/acpi_iort.c b/sys/arm64/acpica/acpi_iort.c
--- a/sys/arm64/acpica/acpi_iort.c
+++ b/sys/arm64/acpica/acpi_iort.c
@@ -763,6 +763,19 @@
return (NULL);
}
+int
+acpi_iort_lookup_pci_id(device_t bus, device_t child, uintptr_t *devid)
+{
+ struct iort_node *node;
+
+ node = acpi_iort_lookup_iwb_node(bus, child);
+ if (!node)
+ return (ENODEV);
+
+ *devid = node->entries.mappings[0].outbase;
+ return (0);
+}
+
int
acpi_iort_lookup_its_from_iwb(device_t dev, int *its_id)
{
@@ -786,6 +799,54 @@
return (ENODEV);
}
+int
+acpi_iort_alloc_msis(device_t bus, device_t dev, int *count)
+{
+ int *irqs;
+ int irq_count;
+ int error;
+ int i;
+ int its_id;
+ u_int xref;
+ int pxm;
+
+ irq_count = *count;
+ irqs = mallocarray(irq_count, sizeof(int), M_DEVBUF, M_WAITOK | M_ZERO);
+
+ error = acpi_iort_lookup_its_from_iwb(dev, &its_id);
+ if (error)
+ return (error);
+
+ error = acpi_iort_its_lookup(its_id, &xref, &pxm);
+ if (error)
+ return (error);
+
+ error = intr_alloc_msi(bus, dev, xref, irq_count, irq_count, irqs);
+ if (error)
+ return (error);
+
+ for (i = 0; i < irq_count; i++) {
+ error = bus_generic_rl_set_resource(bus, dev, SYS_RES_IRQ,
+ i + 1, irqs[i], 1);
+ if (error != 0)
+ break;
+ }
+
+ *count = irq_count;
+
+ /* Clean up resources if something failed */
+ if (error != 0) {
+ for (int j = 0; j < i; j++) {
+ bus_generic_rl_delete_resource(bus, dev, SYS_RES_IRQ,
+ j + 1);
+
+ }
+ }
+
+ free(irqs, M_DEVBUF);
+ return (error);
+}
+
device_t
acpi_iort_get_iwb_dev(int iwb_id)
{
diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c
--- a/sys/dev/acpica/acpi.c
+++ b/sys/dev/acpica/acpi.c
@@ -158,6 +158,11 @@
static isa_pnp_probe_t acpi_isa_pnp_probe;
+#ifdef __aarch64__
+static pci_get_id_t acpi_pci_get_id;
+static pci_alloc_msi_t acpi_pci_alloc_msi;
+#endif
+
static void acpi_reserve_resources(device_t dev);
static int acpi_sysres_alloc(device_t dev);
static uint32_t acpi_isa_get_logicalid(device_t dev);
@@ -251,6 +256,12 @@
/* ISA emulation */
DEVMETHOD(isa_pnp_probe, acpi_isa_pnp_probe),
+ /* PCI emulation */
+#ifdef __aarch64__
+ DEVMETHOD(pci_get_id, acpi_pci_get_id),
+ DEVMETHOD(pci_alloc_msi, acpi_pci_alloc_msi),
+#endif
+
DEVMETHOD_END
};
@@ -2333,6 +2344,36 @@
return_VALUE (result);
}
+#ifdef __aarch64__
+static int
+acpi_pci_get_id(device_t dev, device_t child, enum pci_id_type type,
+ uintptr_t *id)
+{
+ if (dev != device_get_parent(child))
+ return (EINVAL);
+
+ if (type != PCI_ID_MSI)
+ return (EINVAL);
+
+ if (!acpi_iort_lookup_pci_id(dev, child, id))
+ return (0);
+
+ return (ENXIO);
+}
+
+static int
+acpi_pci_alloc_msi(device_t bus, device_t child, int *count)
+{
+ if (bus != device_get_parent(child))
+ return (EINVAL);
+
+ if (!acpi_iort_alloc_msis(bus, child, count))
+ return (0);
+
+ return (ENXIO);
+}
+#endif
+
/*
* Look for a MCFG table. If it is present, use the settings for
* domain (segment) 0 to setup PCI config space access via the memory
diff --git a/sys/dev/acpica/acpivar.h b/sys/dev/acpica/acpivar.h
--- a/sys/dev/acpica/acpivar.h
+++ b/sys/dev/acpica/acpivar.h
@@ -639,6 +639,8 @@
uint64_t *xref, u_int *devid);
int acpi_iort_lookup_its_from_iwb(device_t dev, int *its_id);
device_t acpi_iort_get_iwb_dev(int iwb_id);
+int acpi_iort_lookup_pci_id(device_t bus, device_t child, uintptr_t *devid);
+int acpi_iort_alloc_msis(device_t bus, device_t child, int *count);
#endif
#endif /* _KERNEL */
#endif /* !_ACPIVAR_H_ */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Sep 25, 6:40 AM (8 h, 38 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
39585542
Default Alt Text
D59169.id186204.diff (3 KB)
Attached To
Mode
D59169: dev: acpica: Add PCI device methods for aarch64
Attached
Detach File
Event Timeline
Log In to Comment