-/* $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>
*
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
{
struct aplpcie_softc *sc = v;
+ tag = PCITAG_OFFSET(tag);
return HREAD4(sc, tag | reg);
}
{
struct aplpcie_softc *sc = v;
+ tag = PCITAG_OFFSET(tag);
HWRITE4(sc, tag | reg, data);
}
-/* $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