diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2020-09-01 19:09:48 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2020-09-01 19:09:48 +0000 |
commit | b344bc340d5801e48286239a15399bdab458a27a (patch) | |
tree | 4b8a85eeecbbb7b6c66d925d39848c81cb9538f7 | |
parent | 2fdfbd5a777e7737c1c85698db7433cb107cf6d4 (diff) |
Store the device tree node in the pcitag_t.
-rw-r--r-- | sys/arch/powerpc64/dev/phb.c | 37 | ||||
-rw-r--r-- | sys/arch/powerpc64/include/pci_machdep.h | 5 |
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 |