summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2020-09-01 19:09:48 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2020-09-01 19:09:48 +0000
commitb344bc340d5801e48286239a15399bdab458a27a (patch)
tree4b8a85eeecbbb7b6c66d925d39848c81cb9538f7
parent2fdfbd5a777e7737c1c85698db7433cb107cf6d4 (diff)
Store the device tree node in the pcitag_t.
-rw-r--r--sys/arch/powerpc64/dev/phb.c37
-rw-r--r--sys/arch/powerpc64/include/pci_machdep.h5
2 files changed, 38 insertions, 4 deletions
diff --git a/sys/arch/powerpc64/dev/phb.c b/sys/arch/powerpc64/dev/phb.c
index 2b728c0335e..bedd1880ba2 100644
--- a/sys/arch/powerpc64/dev/phb.c
+++ b/sys/arch/powerpc64/dev/phb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: phb.c,v 1.13 2020/08/23 10:11:17 kettenis Exp $ */
+/* $OpenBSD: phb.c,v 1.14 2020/09/01 19:09:47 kettenis Exp $ */
/*
* Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org>
*
@@ -390,11 +390,40 @@ phb_bus_maxdevs(void *v, int bus)
return 32;
}
+int
+phb_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 = phb_find_node(child, bus, device, function);
+ if (node)
+ return node;
+ }
+
+ return 0;
+}
+
pcitag_t
phb_make_tag(void *v, int bus, int device, int function)
{
- /* Return OPAL bus_dev_func. */
- return ((bus << 8) | (device << 3) | (function << 0));
+ struct phb_softc *sc = v;
+ int node;
+
+ node = phb_find_node(sc->sc_node, bus, device, function);
+ return (((pcitag_t)node << 32) |
+ (bus << 8) | (device << 3) | (function << 0));
}
void
@@ -423,6 +452,7 @@ phb_conf_read(void *v, pcitag_t tag, int reg)
uint16_t pci_error_state;
uint8_t freeze_state;
+ tag = PCITAG_OFFSET(tag);
error = opal_pci_config_read_word(sc->sc_phb_id,
tag, reg, opal_phys(&data));
if (error == OPAL_SUCCESS && data != 0xffffffff)
@@ -446,6 +476,7 @@ phb_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
{
struct phb_softc *sc = v;
+ tag = PCITAG_OFFSET(tag);
opal_pci_config_write_word(sc->sc_phb_id, tag, reg, data);
}
diff --git a/sys/arch/powerpc64/include/pci_machdep.h b/sys/arch/powerpc64/include/pci_machdep.h
index 3e551ae589a..d44e0b01537 100644
--- a/sys/arch/powerpc64/include/pci_machdep.h
+++ b/sys/arch/powerpc64/include/pci_machdep.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pci_machdep.h,v 1.2 2020/06/10 16:31:27 kettenis Exp $ */
+/* $OpenBSD: pci_machdep.h,v 1.3 2020/09/01 19:09:47 kettenis Exp $ */
/*
* Copyright (c) 2003-2004 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -29,6 +29,9 @@
typedef struct ppc64_pci_chipset *pci_chipset_tag_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
#define PCI_INTX 1