Add code to acpiiort(4) to look up named components in the IORT and
authorpatrick <patrick@openbsd.org>
Mon, 15 Mar 2021 22:56:48 +0000 (22:56 +0000)
committerpatrick <patrick@openbsd.org>
Mon, 15 Mar 2021 22:56:48 +0000 (22:56 +0000)
map them.  This makes ACPI's call to acpi_iommu_device_map() do work
through acpiiort(4).

ok kettenis@

sys/arch/arm64/arm64/acpi_machdep.c
sys/arch/arm64/dev/acpiiort.c
sys/arch/arm64/dev/acpiiort.h

index 5d78f6d..721f45e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: acpi_machdep.c,v 1.12 2021/03/15 22:44:57 patrick Exp $       */
+/*     $OpenBSD: acpi_machdep.c,v 1.13 2021/03/15 22:56:48 patrick Exp $       */
 /*
  * Copyright (c) 2018 Mark Kettenis
  *
@@ -31,6 +31,8 @@
 #include <dev/acpi/acpivar.h>
 #include <dev/acpi/dsdt.h>
 
+#include <arm64/dev/acpiiort.h>
+
 int    lid_action;
 int    pwr_action = 1;
 
@@ -220,5 +222,5 @@ acpi_resume_mp(void)
 bus_dma_tag_t
 acpi_iommu_device_map(struct aml_node *node, bus_dma_tag_t dmat)
 {
-       return dmat;
+       return acpiiort_device_map(node, dmat);
 }
index 710d8fd..8569b49 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpiiort.c,v 1.2 2021/03/15 22:48:57 patrick Exp $ */
+/* $OpenBSD: acpiiort.c,v 1.3 2021/03/15 22:56:48 patrick Exp $ */
 /*
  * Copyright (c) 2021 Patrick Wildt <patrick@blueri.se>
  *
@@ -21,6 +21,7 @@
 
 #include <dev/acpi/acpireg.h>
 #include <dev/acpi/acpivar.h>
+#include <dev/acpi/dsdt.h>
 
 #include <arm64/dev/acpiiort.h>
 
@@ -101,3 +102,75 @@ acpiiort_smmu_map(struct acpi_iort_node *node, uint32_t rid,
 
        return dmat;
 }
+
+bus_dma_tag_t
+acpiiort_device_map(struct aml_node *root, bus_dma_tag_t dmat)
+{
+       struct acpi_table_header *hdr;
+       struct acpi_iort *iort = NULL;
+       struct acpi_iort_node *node;
+       struct acpi_iort_mapping *map;
+       struct acpi_iort_nc_node *nc;
+       struct acpi_q *entry;
+       const char *name;
+       uint32_t rid, offset;
+       int i;
+
+       name = aml_nodename(root);
+
+       /* Look for IORT table. */
+       SIMPLEQ_FOREACH(entry, &acpi_softc->sc_tables, q_next) {
+               hdr = entry->q_table;
+               if (strncmp(hdr->signature, IORT_SIG,
+                   sizeof(hdr->signature)) == 0) {
+                       iort = entry->q_table;
+                       break;
+               }
+       }
+       if (iort == NULL)
+               return dmat;
+
+       /* Find our named component. */
+       offset = iort->offset;
+       for (i = 0; i < iort->number_of_nodes; i++) {
+               node = (struct acpi_iort_node *)((char *)iort + offset);
+               if (node->type == ACPI_IORT_NAMED_COMPONENT) {
+                       nc = (struct acpi_iort_nc_node *)&node[1];
+                       if (strcmp(nc->device_object_name, name) == 0)
+                               break;
+               }
+               offset += node->length;
+       }
+
+       /* No NC found? Weird. */
+       if (i >= iort->number_of_nodes)
+               return dmat;
+
+       /* Find our output base towards SMMU. */
+       map = (struct acpi_iort_mapping *)((char *)node + node->mapping_offset);
+       for (i = 0; i < node->number_of_mappings; i++) {
+               offset = map[i].output_reference;
+
+               if (map[i].flags & ACPI_IORT_MAPPING_SINGLE) {
+                       rid = map[i].output_base;
+                       break;
+               }
+
+               /* Mapping encodes number of IDs in the range minus one. */
+               if (map[i].input_base <= rid &&
+                   rid <= map[i].input_base + map[i].number_of_ids) {
+                       rid = map[i].output_base + (rid - map[i].input_base);
+                       break;
+               }
+       }
+
+       /* No mapping found? Even weirder. */
+       if (i >= node->number_of_mappings)
+               return dmat;
+
+       node = (struct acpi_iort_node *)((char *)iort + offset);
+       if (node->type == ACPI_IORT_SMMU)
+               return acpiiort_smmu_map(node, rid, dmat);
+
+       return dmat;
+}
index fd0c991..5aaaa02 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpiiort.h,v 1.2 2021/03/15 22:48:57 patrick Exp $ */
+/* $OpenBSD: acpiiort.h,v 1.3 2021/03/15 22:56:48 patrick Exp $ */
 /*
  * Copyright (c) 2021 Patrick Wildt <patrick@blueri.se>
  *
@@ -32,3 +32,4 @@ struct acpiiort_smmu {
 
 void acpiiort_smmu_register(struct acpiiort_smmu *);
 bus_dma_tag_t acpiiort_smmu_map(struct acpi_iort_node *, uint32_t, bus_dma_tag_t);
+bus_dma_tag_t acpiiort_device_map(struct aml_node *, bus_dma_tag_t);