summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorian <ian@FreeBSD.org>2015-12-21 18:07:32 +0000
committerian <ian@FreeBSD.org>2015-12-21 18:07:32 +0000
commitf2c27d05283dc9a5c359331976911732b48ec7b6 (patch)
treed71ce8ea746db2371af40f1155e7fe871d285138
parent5e0b3f1167b3511ce001af9ce6d5ffec64fbef24 (diff)
downloadFreeBSD-src-f2c27d05283dc9a5c359331976911732b48ec7b6.zip
FreeBSD-src-f2c27d05283dc9a5c359331976911732b48ec7b6.tar.gz
Implement OF_decode_addr() for arm. Move most of powerpc's implementation
into a new function that other platforms can share. This creates a new ofw_reg_to_paddr() function (in a new ofw_subr.c file) that contains most of the existing ppc implementation, mostly unchanged. The ppc code now calls the new MI code from the MD code, then creates a ppc-specific bus_space mapping from the results. The new arm implementation does the same in an arm-specific way. This also moves the declaration of OF_decode_addr() from ofw_machdep.h to openfirm.h, except on sparc64 which uses a different function signature. This will help all FDT platforms to set up early console access using OF_decode_addr().
-rw-r--r--sys/arm/arm/ofw_machdep.c71
-rw-r--r--sys/arm/include/ofw_machdep.h3
-rw-r--r--sys/conf/files1
-rw-r--r--sys/conf/files.arm1
-rw-r--r--sys/conf/files.powerpc1
-rw-r--r--sys/dev/ofw/ofw_subr.c177
-rw-r--r--sys/dev/ofw/ofw_subr.h49
-rw-r--r--sys/dev/ofw/openfirm.h11
-rw-r--r--sys/powerpc/include/ofw_machdep.h1
-rw-r--r--sys/powerpc/ofw/ofw_machdep.c140
10 files changed, 331 insertions, 124 deletions
diff --git a/sys/arm/arm/ofw_machdep.c b/sys/arm/arm/ofw_machdep.c
new file mode 100644
index 0000000..59b85c6
--- /dev/null
+++ b/sys/arm/arm/ofw_machdep.c
@@ -0,0 +1,71 @@
+/*-
+ * Copyright (c) 2015 Ian Lepore <ian@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_subr.h>
+
+int
+OF_decode_addr(phandle_t dev, int regno, bus_space_tag_t *tag,
+ bus_space_handle_t *handle)
+{
+ bus_addr_t addr;
+ bus_size_t size;
+ pcell_t pci_hi;
+ int flags, res;
+
+ res = ofw_reg_to_paddr(dev, regno, &addr, &size, &pci_hi);
+ if (res < 0)
+ return (res);
+
+ /*
+ * Nothing special to do for PCI busses right now.
+ * This may need to be handled per-platform when it does come up.
+ */
+#ifdef notyet
+ if (pci_hi == OFW_PADDR_NOT_PCI) {
+ *tag = fdtbus_bs_tag;
+ flags = 0;
+ } else {
+ *tag = fdtbus_bs_tag;
+ flags = (pci_hi & OFW_PCI_PHYS_HI_PREFETCHABLE) ?
+ BUS_SPACE_MAP_PREFETCHABLE: 0;
+ }
+#else
+ *tag = fdtbus_bs_tag;
+ flags = 0;
+#endif
+ return (bus_space_map(*tag, addr, size, flags, handle));
+}
+
diff --git a/sys/arm/include/ofw_machdep.h b/sys/arm/include/ofw_machdep.h
index d6bd576..54033ea 100644
--- a/sys/arm/include/ofw_machdep.h
+++ b/sys/arm/include/ofw_machdep.h
@@ -32,6 +32,9 @@
#ifndef _MACHINE_OFW_MACHDEP_H_
#define _MACHINE_OFW_MACHDEP_H_
+#include <sys/types.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
#include <vm/vm.h>
typedef uint32_t cell_t;
diff --git a/sys/conf/files b/sys/conf/files
index 55174f7..9345e3c 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -2094,6 +2094,7 @@ dev/ofw/ofw_bus_subr.c optional fdt
dev/ofw/ofw_fdt.c optional fdt
dev/ofw/ofw_if.m optional fdt
dev/ofw/ofw_iicbus.c optional fdt iicbus
+dev/ofw/ofw_subr.c optional fdt
dev/ofw/ofwbus.c optional fdt
dev/ofw/openfirm.c optional fdt
dev/ofw/openfirmio.c optional fdt
diff --git a/sys/conf/files.arm b/sys/conf/files.arm
index 292fd54..b3b9ea3 100644
--- a/sys/conf/files.arm
+++ b/sys/conf/files.arm
@@ -55,6 +55,7 @@ arm/arm/minidump_machdep.c optional mem
arm/arm/mp_machdep.c optional smp
arm/arm/mpcore_timer.c optional mpcore_timer
arm/arm/nexus.c standard
+arm/arm/ofw_machdep.c optional fdt
arm/arm/physmem.c standard
kern/pic_if.m optional arm_intrng
arm/arm/pl190.c optional pl190
diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc
index e8827d7..0a1e7c1 100644
--- a/sys/conf/files.powerpc
+++ b/sys/conf/files.powerpc
@@ -58,6 +58,7 @@ dev/ofw/ofw_disk.c optional ofwd aim
dev/ofw/ofw_iicbus.c optional iicbus aim
dev/ofw/ofwbus.c optional aim | fdt
dev/ofw/ofw_standard.c optional aim powerpc
+dev/ofw/ofw_subr.c optional aim powerpc
dev/powermac_nvram/powermac_nvram.c optional powermac_nvram powermac
dev/quicc/quicc_bfe_fdt.c optional quicc mpc85xx
dev/scc/scc_bfe_macio.c optional scc powermac
diff --git a/sys/dev/ofw/ofw_subr.c b/sys/dev/ofw/ofw_subr.c
new file mode 100644
index 0000000..e169b3f
--- /dev/null
+++ b/sys/dev/ofw/ofw_subr.c
@@ -0,0 +1,177 @@
+/*-
+ * Copyright (c) 2015 Ian Lepore <ian@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The initial ofw_reg_to_paddr() implementation has been copied from powerpc
+ * ofw_machdep.c OF_decode_addr(). It was added by Marcel Moolenaar, who did not
+ * assert copyright with the addition but still deserves credit for the work.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/libkern.h>
+
+#include <machine/bus.h>
+
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_pci.h>
+#include <dev/ofw/ofw_subr.h>
+
+static void
+get_addr_props(phandle_t node, uint32_t *addrp, uint32_t *sizep, int *pcip)
+{
+ char type[64];
+ uint32_t addr, size;
+ int pci, res;
+
+ res = OF_getencprop(node, "#address-cells", &addr, sizeof(addr));
+ if (res == -1)
+ addr = 2;
+ res = OF_getencprop(node, "#size-cells", &size, sizeof(size));
+ if (res == -1)
+ size = 1;
+ pci = 0;
+ if (addr == 3 && size == 2) {
+ res = OF_getprop(node, "device_type", type, sizeof(type));
+ if (res != -1) {
+ type[sizeof(type) - 1] = '\0';
+ pci = (strcmp(type, "pci") == 0) ? 1 : 0;
+ }
+ }
+ if (addrp != NULL)
+ *addrp = addr;
+ if (sizep != NULL)
+ *sizep = size;
+ if (pcip != NULL)
+ *pcip = pci;
+}
+
+int
+ofw_reg_to_paddr(phandle_t dev, int regno, bus_addr_t *paddr,
+ bus_size_t *psize, pcell_t *ppci_hi)
+{
+ pcell_t cell[32], pci_hi;
+ bus_addr_t addr, raddr, baddr;
+ bus_size_t size, rsize;
+ uint32_t c, nbridge, naddr, nsize;
+ phandle_t bridge, parent;
+ u_int spc, rspc;
+ int pci, pcib, res;
+
+ /* Sanity checking. */
+ if (dev == 0)
+ return (EINVAL);
+ bridge = OF_parent(dev);
+ if (bridge == 0)
+ return (EINVAL);
+ if (regno < 0)
+ return (EINVAL);
+ if (paddr == NULL || psize == NULL)
+ return (EINVAL);
+
+ get_addr_props(bridge, &naddr, &nsize, &pci);
+ res = OF_getencprop(dev, (pci) ? "assigned-addresses" : "reg",
+ cell, sizeof(cell));
+ if (res == -1)
+ return (ENXIO);
+ if (res % sizeof(cell[0]))
+ return (ENXIO);
+ res /= sizeof(cell[0]);
+ regno *= naddr + nsize;
+ if (regno + naddr + nsize > res)
+ return (EINVAL);
+ pci_hi = pci ? cell[regno] : OFW_PADDR_NOT_PCI;
+ spc = pci_hi & OFW_PCI_PHYS_HI_SPACEMASK;
+ addr = 0;
+ for (c = 0; c < naddr; c++)
+ addr = ((uint64_t)addr << 32) | cell[regno++];
+ size = 0;
+ for (c = 0; c < nsize; c++)
+ size = ((uint64_t)size << 32) | cell[regno++];
+ /*
+ * Map the address range in the bridge's decoding window as given
+ * by the "ranges" property. If a node doesn't have such property
+ * or the property is empty, we assume an identity mapping. The
+ * standard says a missing property indicates no possible mapping.
+ * This code is more liberal since the intended use is to get a
+ * console running early, and a printf to warn of malformed data
+ * is probably futile before the console is fully set up.
+ */
+ parent = OF_parent(bridge);
+ while (parent != 0) {
+ get_addr_props(parent, &nbridge, NULL, &pcib);
+ res = OF_getencprop(bridge, "ranges", cell, sizeof(cell));
+ if (res < 1)
+ goto next;
+ if (res % sizeof(cell[0]))
+ return (ENXIO);
+ /* Capture pci_hi if we just transitioned onto a PCI bus. */
+ if (pcib && pci_hi == OFW_PADDR_NOT_PCI) {
+ pci_hi = cell[0];
+ spc = pci_hi & OFW_PCI_PHYS_HI_SPACEMASK;
+ }
+ res /= sizeof(cell[0]);
+ regno = 0;
+ while (regno < res) {
+ rspc = (pci)
+ ? cell[regno] & OFW_PCI_PHYS_HI_SPACEMASK
+ : OFW_PADDR_NOT_PCI;
+ if (rspc != spc) {
+ regno += naddr + nbridge + nsize;
+ continue;
+ }
+ raddr = 0;
+ for (c = 0; c < naddr; c++)
+ raddr = ((uint64_t)raddr << 32) | cell[regno++];
+ rspc = (pcib)
+ ? cell[regno] & OFW_PCI_PHYS_HI_SPACEMASK
+ : OFW_PADDR_NOT_PCI;
+ baddr = 0;
+ for (c = 0; c < nbridge; c++)
+ baddr = ((uint64_t)baddr << 32) | cell[regno++];
+ rsize = 0;
+ for (c = 0; c < nsize; c++)
+ rsize = ((uint64_t)rsize << 32) | cell[regno++];
+ if (addr < raddr || addr >= raddr + rsize)
+ continue;
+ addr = addr - raddr + baddr;
+ if (rspc != OFW_PADDR_NOT_PCI)
+ spc = rspc;
+ }
+ next:
+ bridge = parent;
+ parent = OF_parent(bridge);
+ get_addr_props(bridge, &naddr, &nsize, &pci);
+ }
+
+ *paddr = addr;
+ *psize = size;
+ if (ppci_hi != NULL)
+ *ppci_hi = pci_hi;
+
+ return (0);
+}
diff --git a/sys/dev/ofw/ofw_subr.h b/sys/dev/ofw/ofw_subr.h
new file mode 100644
index 0000000..8fa64b2
--- /dev/null
+++ b/sys/dev/ofw/ofw_subr.h
@@ -0,0 +1,49 @@
+/*-
+ * Copyright (c) 2015 Ian Lepore <ian@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _DEV_OFW_OFW_SUBR_H_
+#define _DEV_OFW_OFW_SUBR_H_
+
+/*
+ * Translate an address from the Nth tuple of a device node's reg properties to
+ * a physical memory address, by applying the range mappings from all ancestors.
+ * This assumes that all ancestor ranges are simple numerical offsets for which
+ * addition and subtraction operations will perform the required mapping (the
+ * bit-options in the high word of standard PCI properties are also handled).
+ * After the call, *pci_hi (if non-NULL) contains the phys.hi cell of the
+ * device's parent PCI bus, or OFW_PADDR_NOT_PCI if no PCI bus is involved.
+ *
+ * This is intended to be a helper function called by the platform-specific
+ * implementation of OF_decode_addr(), and not for direct use by device drivers.
+ */
+#define OFW_PADDR_NOT_PCI (~0)
+
+int ofw_reg_to_paddr(phandle_t _dev, int _regno, bus_addr_t *_paddr,
+ bus_size_t *_size, pcell_t *_pci_hi);
+
+#endif
diff --git a/sys/dev/ofw/openfirm.h b/sys/dev/ofw/openfirm.h
index d3967a4..f5133eb 100644
--- a/sys/dev/ofw/openfirm.h
+++ b/sys/dev/ofw/openfirm.h
@@ -167,5 +167,16 @@ void OF_exit(void) __attribute__((noreturn));
/* User interface functions */
int OF_interpret(const char *cmd, int nreturns, ...);
+/*
+ * Decode the Nth register property of the given device node and create a bus
+ * space tag and handle for accessing it. This is for use in setting up things
+ * like early console output before newbus is available. The implementation is
+ * machine-dependent, and sparc uses a different function signature as well.
+ */
+#ifndef __sparc64__
+int OF_decode_addr(phandle_t dev, int regno, bus_space_tag_t *ptag,
+ bus_space_handle_t *phandle);
+#endif
+
#endif /* _KERNEL */
#endif /* _DEV_OPENFIRM_H_ */
diff --git a/sys/powerpc/include/ofw_machdep.h b/sys/powerpc/include/ofw_machdep.h
index 0ee75f4..8376e1a 100644
--- a/sys/powerpc/include/ofw_machdep.h
+++ b/sys/powerpc/include/ofw_machdep.h
@@ -37,7 +37,6 @@
typedef uint32_t cell_t;
-int OF_decode_addr(phandle_t, int, bus_space_tag_t *, bus_space_handle_t *);
void OF_getetheraddr(device_t dev, u_char *addr);
void OF_initial_setup(void *fdt_ptr, void *junk, int (*openfirm)(void *));
diff --git a/sys/powerpc/ofw/ofw_machdep.c b/sys/powerpc/ofw/ofw_machdep.c
index d085af9..5594d84 100644
--- a/sys/powerpc/ofw/ofw_machdep.c
+++ b/sys/powerpc/ofw/ofw_machdep.c
@@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_pci.h>
#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_subr.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
@@ -565,135 +566,28 @@ OF_getetheraddr(device_t dev, u_char *addr)
* register in the address space of its parent and recursively walk
* the device tree upward this way.
*/
-static void
-OF_get_addr_props(phandle_t node, uint32_t *addrp, uint32_t *sizep, int *pcip)
-{
- char type[64];
- uint32_t addr, size;
- int pci, res;
-
- res = OF_getencprop(node, "#address-cells", &addr, sizeof(addr));
- if (res == -1)
- addr = 2;
- res = OF_getencprop(node, "#size-cells", &size, sizeof(size));
- if (res == -1)
- size = 1;
- pci = 0;
- if (addr == 3 && size == 2) {
- res = OF_getprop(node, "device_type", type, sizeof(type));
- if (res != -1) {
- type[sizeof(type) - 1] = '\0';
- pci = (strcmp(type, "pci") == 0) ? 1 : 0;
- }
- }
- if (addrp != NULL)
- *addrp = addr;
- if (sizep != NULL)
- *sizep = size;
- if (pcip != NULL)
- *pcip = pci;
-}
-
int
OF_decode_addr(phandle_t dev, int regno, bus_space_tag_t *tag,
bus_space_handle_t *handle)
{
- uint32_t cell[32];
- bus_addr_t addr, raddr, baddr;
- bus_size_t size, rsize;
- uint32_t c, nbridge, naddr, nsize;
- phandle_t bridge, parent;
- u_int spc, rspc, prefetch;
- int pci, pcib, res;
-
- /* Sanity checking. */
- if (dev == 0)
- return (EINVAL);
- bridge = OF_parent(dev);
- if (bridge == 0)
- return (EINVAL);
- if (regno < 0)
- return (EINVAL);
- if (tag == NULL || handle == NULL)
- return (EINVAL);
-
- /* Assume big-endian unless we find a PCI device */
- *tag = &bs_be_tag;
-
- /* Get the requested register. */
- OF_get_addr_props(bridge, &naddr, &nsize, &pci);
- if (pci)
+ bus_addr_t addr;
+ bus_size_t size;
+ pcell_t pci_hi;
+ int flags, res;
+
+ res = ofw_reg_to_paddr(dev, regno, &addr, &size, &pci_hi);
+ if (res < 0)
+ return (res);
+
+ if (pci_hi == OFW_PADDR_NOT_PCI) {
+ *tag = &bs_be_tag;
+ flags = 0;
+ } else {
*tag = &bs_le_tag;
- res = OF_getencprop(dev, (pci) ? "assigned-addresses" : "reg",
- cell, sizeof(cell));
- if (res == -1)
- return (ENXIO);
- if (res % sizeof(cell[0]))
- return (ENXIO);
- res /= sizeof(cell[0]);
- regno *= naddr + nsize;
- if (regno + naddr + nsize > res)
- return (EINVAL);
- spc = (pci) ? cell[regno] & OFW_PCI_PHYS_HI_SPACEMASK : ~0;
- prefetch = (pci) ? cell[regno] & OFW_PCI_PHYS_HI_PREFETCHABLE : 0;
- addr = 0;
- for (c = 0; c < naddr; c++)
- addr = ((uint64_t)addr << 32) | cell[regno++];
- size = 0;
- for (c = 0; c < nsize; c++)
- size = ((uint64_t)size << 32) | cell[regno++];
-
- /*
- * Map the address range in the bridge's decoding window as given
- * by the "ranges" property. If a node doesn't have such property
- * then no mapping is done.
- */
- parent = OF_parent(bridge);
- while (parent != 0) {
- OF_get_addr_props(parent, &nbridge, NULL, &pcib);
- if (pcib)
- *tag = &bs_le_tag;
- res = OF_getencprop(bridge, "ranges", cell, sizeof(cell));
- if (res == -1)
- goto next;
- if (res % sizeof(cell[0]))
- return (ENXIO);
- res /= sizeof(cell[0]);
- regno = 0;
- while (regno < res) {
- rspc = (pci)
- ? cell[regno] & OFW_PCI_PHYS_HI_SPACEMASK
- : ~0;
- if (rspc != spc) {
- regno += naddr + nbridge + nsize;
- continue;
- }
- raddr = 0;
- for (c = 0; c < naddr; c++)
- raddr = ((uint64_t)raddr << 32) | cell[regno++];
- rspc = (pcib)
- ? cell[regno] & OFW_PCI_PHYS_HI_SPACEMASK
- : ~0;
- baddr = 0;
- for (c = 0; c < nbridge; c++)
- baddr = ((uint64_t)baddr << 32) | cell[regno++];
- rsize = 0;
- for (c = 0; c < nsize; c++)
- rsize = ((uint64_t)rsize << 32) | cell[regno++];
- if (addr < raddr || addr >= raddr + rsize)
- continue;
- addr = addr - raddr + baddr;
- if (rspc != ~0)
- spc = rspc;
- }
-
- next:
- bridge = parent;
- parent = OF_parent(bridge);
- OF_get_addr_props(bridge, &naddr, &nsize, &pci);
+ flags = (pci_hi & OFW_PCI_PHYS_HI_PREFETCHABLE) ?
+ BUS_SPACE_MAP_PREFETCHABLE: 0;
}
- return (bus_space_map(*tag, addr, size,
- prefetch ? BUS_SPACE_MAP_PREFETCHABLE : 0, handle));
+ return (bus_space_map(*tag, addr, size, flags, handle));
}
OpenPOWER on IntegriCloud