Store the device tree node in the pcitag_t like we do on powerpc64 andi
authorkettenis <kettenis@openbsd.org>
Fri, 11 Jun 2021 12:23:52 +0000 (12:23 +0000)
committerkettenis <kettenis@openbsd.org>
Fri, 11 Jun 2021 12:23:52 +0000 (12:23 +0000)
sparc64.  For now, do this only for aplpcie(4) as we only need this
functionality for Apple Silicon systems.

ok patrick@

sys/arch/arm64/dev/aplpcie.c
sys/arch/arm64/include/pci_machdep.h

index ff579cd..737459c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: aplpcie.c,v 1.2 2021/05/17 17:25:13 kettenis Exp $    */
+/*     $OpenBSD: aplpcie.c,v 1.3 2021/06/11 12:23:52 kettenis Exp $    */
 /*
  * Copyright (c) 2021 Mark Kettenis <kettenis@openbsd.org>
  *
@@ -317,11 +317,40 @@ aplpcie_bus_maxdevs(void *v, int bus)
        return 32;
 }
 
+int
+aplpcie_find_node(int node, int bus, int device, int function)
+{
+       uint32_t reg[5];
+       uint32_t phys_hi;
+       int child;
+
+       phys_hi = ((bus << 16) | (device << 11) | (function << 8));
+
+       for (child = OF_child(node); child; child = OF_peer(child)) {
+               if (OF_getpropintarray(child, "reg",
+                   reg, sizeof(reg)) != sizeof(reg))
+                       continue;
+
+               if (reg[0] == phys_hi)
+                       return child;
+
+               node = aplpcie_find_node(child, bus, device, function);
+               if (node)
+                       return node;
+       }
+
+       return 0;
+}
+
 pcitag_t
 aplpcie_make_tag(void *v, int bus, int device, int function)
 {
-       /* Return ECAM address. */
-       return ((bus << 20) | (device << 15) | (function << 12));
+       struct aplpcie_softc *sc = v;
+       int node;
+
+       node = aplpcie_find_node(sc->sc_node, bus, device, function);
+       return (((pcitag_t)node << 32) |
+           (bus << 20) | (device << 15) | (function << 12));
 }
 
 void
@@ -346,6 +375,7 @@ aplpcie_conf_read(void *v, pcitag_t tag, int reg)
 {
        struct aplpcie_softc *sc = v;
 
+       tag = PCITAG_OFFSET(tag);
        return HREAD4(sc, tag | reg);
 }
 
@@ -354,6 +384,7 @@ aplpcie_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
 {
        struct aplpcie_softc *sc = v;
 
+       tag = PCITAG_OFFSET(tag);
        HWRITE4(sc, tag | reg, data);
 }
 
index bd186bb..3cb9be0 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: pci_machdep.h,v 1.10 2021/05/17 17:25:13 kettenis Exp $ */
+/*     $OpenBSD: pci_machdep.h,v 1.11 2021/06/11 12:23:52 kettenis Exp $ */
 
 /*
  * Copyright (c) 2003-2004 Opsycon AB  (www.opsycon.se / www.opsycon.com)
  */
 
 typedef struct machine_pci_chipset *pci_chipset_tag_t;
-typedef u_long pcitag_t;
+typedef uint64_t pcitag_t;
+
+#define PCITAG_NODE(x)         ((x) >> 32)
+#define PCITAG_OFFSET(x)       ((x) & 0xffffffff)
 
 /* Supported interrupt types. */
 #define PCI_NONE               0