svn commit: r307347 - stable/11/sys/dev/ofw
Michal Meloun
mmel at FreeBSD.org
Sat Oct 15 09:09:27 UTC 2016
Author: mmel
Date: Sat Oct 15 09:09:25 2016
New Revision: 307347
URL: https://svnweb.freebsd.org/changeset/base/307347
Log:
MFC r302951,r302952,r304071:
r302951:
OFWPCI: Improve resource handling. - add new rman for prefetchable memory.
Is used only if given 'ranges'
property contains prefetchable memory range.
r302952:
OFWPCI: Add support for NEW_PCIB.
r304071:
OFWPCI: Don't strip RF_ACTIVE from flags when parent bus method is called.
Modified:
stable/11/sys/dev/ofw/ofwpci.c
stable/11/sys/dev/ofw/ofwpci.h
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/sys/dev/ofw/ofwpci.c
==============================================================================
--- stable/11/sys/dev/ofw/ofwpci.c Sat Oct 15 08:52:42 2016 (r307346)
+++ stable/11/sys/dev/ofw/ofwpci.c Sat Oct 15 09:09:25 2016 (r307347)
@@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
+#include <dev/pci/pcib_private.h>
#include <machine/bus.h>
#include <machine/md_var.h>
@@ -94,6 +95,7 @@ static phandle_t ofw_pci_get_node(device
* local methods
*/
static int ofw_pci_fill_ranges(phandle_t, struct ofw_pci_range *);
+static struct rman *ofw_pci_get_rman(struct ofw_pci_softc *, int, u_int);
/*
* Driver methods.
@@ -137,13 +139,14 @@ ofw_pci_init(device_t dev)
phandle_t node;
u_int32_t busrange[2];
struct ofw_pci_range *rp;
- int error;
+ int i, error;
struct ofw_pci_cell_info *cell_info;
node = ofw_bus_get_node(dev);
sc = device_get_softc(dev);
sc->sc_initialized = 1;
sc->sc_range = NULL;
+ sc->sc_pci_domain = device_get_unit(dev);
cell_info = (struct ofw_pci_cell_info *)malloc(sizeof(*cell_info),
M_DEVBUF, M_WAITOK | M_ZERO);
@@ -201,17 +204,27 @@ ofw_pci_init(device_t dev)
}
sc->sc_mem_rman.rm_type = RMAN_ARRAY;
- sc->sc_mem_rman.rm_descr = "PCI Memory";
+ sc->sc_mem_rman.rm_descr = "PCI Non Prefetchable Memory";
error = rman_init(&sc->sc_mem_rman);
if (error != 0) {
device_printf(dev, "rman_init() failed. error = %d\n", error);
goto out;
}
- for (rp = sc->sc_range; rp < sc->sc_range + sc->sc_nrange &&
- rp->pci_hi != 0; rp++) {
+ sc->sc_pmem_rman.rm_type = RMAN_ARRAY;
+ sc->sc_pmem_rman.rm_descr = "PCI Prefetchable Memory";
+ error = rman_init(&sc->sc_pmem_rman);
+ if (error != 0) {
+ device_printf(dev, "rman_init() failed. error = %d\n", error);
+ goto out;
+ }
+
+ for (i = 0; i < sc->sc_nrange; i++) {
error = 0;
+ rp = sc->sc_range + i;
+ if (sc->sc_range_mask & ((uint64_t)1 << i))
+ continue;
switch (rp->pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) {
case OFW_PCI_PHYS_HI_SPACE_CONFIG:
break;
@@ -221,8 +234,14 @@ ofw_pci_init(device_t dev)
break;
case OFW_PCI_PHYS_HI_SPACE_MEM32:
case OFW_PCI_PHYS_HI_SPACE_MEM64:
- error = rman_manage_region(&sc->sc_mem_rman, rp->pci,
- rp->pci + rp->size - 1);
+ if (rp->pci_hi & OFW_PCI_PHYS_HI_PREFETCHABLE) {
+ sc->sc_have_pmem = 1;
+ error = rman_manage_region(&sc->sc_pmem_rman,
+ rp->pci, rp->pci + rp->size - 1);
+ } else {
+ error = rman_manage_region(&sc->sc_mem_rman,
+ rp->pci, rp->pci + rp->size - 1);
+ }
break;
}
@@ -244,6 +263,7 @@ out:
free(sc->sc_range, M_DEVBUF);
rman_fini(&sc->sc_io_rman);
rman_fini(&sc->sc_mem_rman);
+ rman_fini(&sc->sc_pmem_rman);
return (error);
}
@@ -318,7 +338,7 @@ ofw_pci_read_ivar(device_t dev, device_t
switch (which) {
case PCIB_IVAR_DOMAIN:
- *result = device_get_unit(dev);
+ *result = sc->sc_pci_domain;
return (0);
case PCIB_IVAR_BUS:
*result = sc->sc_bus;
@@ -385,28 +405,23 @@ ofw_pci_alloc_resource(device_t bus, dev
struct rman *rm;
int needactivate;
+
needactivate = flags & RF_ACTIVE;
flags &= ~RF_ACTIVE;
sc = device_get_softc(bus);
- switch (type) {
- case SYS_RES_MEMORY:
- rm = &sc->sc_mem_rman;
- break;
-
- case SYS_RES_IOPORT:
- rm = &sc->sc_io_rman;
- break;
-
- case SYS_RES_IRQ:
- return (bus_alloc_resource(bus, type, rid, start, end, count,
- flags));
+#if defined(NEW_PCIB) && defined(PCI_RES_BUS)
+ if (type == PCI_RES_BUS) {
+ return (pci_domain_alloc_bus(sc->sc_pci_domain, child, rid,
+ start, end, count, flags | needactivate));
+ }
+#endif
- default:
- device_printf(bus, "unknown resource request from %s\n",
- device_get_nameunit(child));
- return (NULL);
+ rm = ofw_pci_get_rman(sc, type, flags);
+ if (rm == NULL) {
+ return (bus_generic_alloc_resource(bus, child, type, rid,
+ start, end, count, flags | needactivate));
}
rv = rman_reserve_resource(rm, start, end, count, flags, child);
@@ -435,15 +450,30 @@ static int
ofw_pci_release_resource(device_t bus, device_t child, int type, int rid,
struct resource *res)
{
+ struct ofw_pci_softc *sc;
+ struct rman *rm;
+ int error;
- if (rman_get_flags(res) & RF_ACTIVE) {
- int error;
+ sc = device_get_softc(bus);
+
+#if defined(NEW_PCIB) && defined(PCI_RES_BUS)
+ if (type == PCI_RES_BUS)
+ return (pci_domain_release_bus(sc->sc_pci_domain, child, rid,
+ res));
+#endif
+ rm = ofw_pci_get_rman(sc, type, rman_get_flags(res));
+ if (rm == NULL) {
+ return (bus_generic_release_resource(bus, child, type, rid,
+ res));
+ }
+ KASSERT(rman_is_region_manager(res, rm), ("rman mismatch"));
+
+ if (rman_get_flags(res) & RF_ACTIVE) {
error = bus_deactivate_resource(child, type, rid, res);
if (error != 0)
return (error);
}
-
return (rman_release_resource(res));
}
@@ -454,63 +484,62 @@ ofw_pci_activate_resource(device_t bus,
struct ofw_pci_softc *sc;
bus_space_handle_t handle;
bus_space_tag_t tag;
+ struct ofw_pci_range *rp;
+ vm_paddr_t start;
+ int space;
int rv;
sc = device_get_softc(bus);
- if (type == SYS_RES_IRQ) {
- return (bus_activate_resource(bus, type, rid, res));
+ if (type != SYS_RES_IOPORT && type != SYS_RES_MEMORY) {
+ return (bus_generic_activate_resource(bus, child, type, rid,
+ res));
}
- if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) {
- struct ofw_pci_range *rp;
- vm_paddr_t start;
- int space;
-
- start = (vm_paddr_t)rman_get_start(res);
-
- /*
- * Map this through the ranges list
- */
- for (rp = sc->sc_range; rp < sc->sc_range + sc->sc_nrange &&
- rp->pci_hi != 0; rp++) {
- if (start < rp->pci || start >= rp->pci + rp->size)
- continue;
-
- switch (rp->pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) {
- case OFW_PCI_PHYS_HI_SPACE_IO:
- space = SYS_RES_IOPORT;
- break;
- case OFW_PCI_PHYS_HI_SPACE_MEM32:
- case OFW_PCI_PHYS_HI_SPACE_MEM64:
- space = SYS_RES_MEMORY;
- break;
- default:
- space = -1;
- }
- if (type == space) {
- start += (rp->host - rp->pci);
- break;
+ start = (vm_paddr_t)rman_get_start(res);
+
+ /*
+ * Map this through the ranges list
+ */
+ for (rp = sc->sc_range; rp < sc->sc_range + sc->sc_nrange &&
+ rp->pci_hi != 0; rp++) {
+ if (start < rp->pci || start >= rp->pci + rp->size)
+ continue;
+
+ switch (rp->pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) {
+ case OFW_PCI_PHYS_HI_SPACE_IO:
+ space = SYS_RES_IOPORT;
+ break;
+ case OFW_PCI_PHYS_HI_SPACE_MEM32:
+ case OFW_PCI_PHYS_HI_SPACE_MEM64:
+ space = SYS_RES_MEMORY;
+ break;
+ default:
+ space = -1;
}
+
+ if (type == space) {
+ start += (rp->host - rp->pci);
+ break;
}
+ }
- if (bootverbose)
- printf("ofw_pci mapdev: start %jx, len %jd\n",
- (rman_res_t)start, rman_get_size(res));
-
- tag = BUS_GET_BUS_TAG(child, child);
- if (tag == NULL)
- return (ENOMEM);
-
- rman_set_bustag(res, tag);
- rv = bus_space_map(tag, start,
- rman_get_size(res), 0, &handle);
- if (rv != 0)
- return (ENOMEM);
+ if (bootverbose)
+ printf("ofw_pci mapdev: start %jx, len %jd\n",
+ (rman_res_t)start, rman_get_size(res));
+
+ tag = BUS_GET_BUS_TAG(child, child);
+ if (tag == NULL)
+ return (ENOMEM);
+
+ rman_set_bustag(res, tag);
+ rv = bus_space_map(tag, start,
+ rman_get_size(res), 0, &handle);
+ if (rv != 0)
+ return (ENOMEM);
- rman_set_bushandle(res, handle);
- rman_set_virtual(res, (void *)handle); /* XXX for powerpc only ? */
- }
+ rman_set_bushandle(res, handle);
+ rman_set_virtual(res, (void *)handle); /* XXX for powerpc only ? */
return (rman_activate_resource(res));
}
@@ -528,17 +557,19 @@ static int
ofw_pci_deactivate_resource(device_t bus, device_t child, int type, int rid,
struct resource *res)
{
+ struct ofw_pci_softc *sc;
+ vm_size_t psize;
- /*
- * If this is a memory resource, unmap it.
- */
- if ((type == SYS_RES_MEMORY) || (type == SYS_RES_IOPORT)) {
- u_int32_t psize;
+ sc = device_get_softc(bus);
- psize = rman_get_size(res);
- pmap_unmapdev((vm_offset_t)rman_get_virtual(res), psize);
+ if (type != SYS_RES_IOPORT && type != SYS_RES_MEMORY) {
+ return (bus_generic_deactivate_resource(bus, child, type, rid,
+ res));
}
+ psize = rman_get_size(res);
+ pmap_unmapdev((vm_offset_t)rman_get_virtual(res), psize);
+
return (rman_deactivate_resource(res));
}
@@ -550,24 +581,20 @@ ofw_pci_adjust_resource(device_t bus, de
struct ofw_pci_softc *sc;
sc = device_get_softc(bus);
- KASSERT(!(rman_get_flags(res) & RF_ACTIVE),
- ("active resources cannot be adjusted"));
- if (rman_get_flags(res) & RF_ACTIVE)
- return (EINVAL);
+#if defined(NEW_PCIB) && defined(PCI_RES_BUS)
+ if (type == PCI_RES_BUS)
+ return (pci_domain_adjust_bus(sc->sc_pci_domain, child, res,
+ start, end));
+#endif
- switch (type) {
- case SYS_RES_MEMORY:
- rm = &sc->sc_mem_rman;
- break;
- case SYS_RES_IOPORT:
- rm = &sc->sc_io_rman;
- break;
- default:
- return (ENXIO);
+ rm = ofw_pci_get_rman(sc, type, rman_get_flags(res));
+ if (rm == NULL) {
+ return (bus_generic_adjust_resource(bus, child, type, res,
+ start, end));
}
-
- if (!rman_is_region_manager(res, rm))
- return (EINVAL);
+ KASSERT(rman_is_region_manager(res, rm), ("rman mismatch"));
+ KASSERT(!(rman_get_flags(res) & RF_ACTIVE),
+ ("active resources cannot be adjusted"));
return (rman_adjust_resource(res, start, end));
}
@@ -629,3 +656,22 @@ ofw_pci_fill_ranges(phandle_t node, stru
free(base_ranges, M_DEVBUF);
return (nranges);
}
+
+static struct rman *
+ofw_pci_get_rman(struct ofw_pci_softc *sc, int type, u_int flags)
+{
+
+ switch (type) {
+ case SYS_RES_IOPORT:
+ return (&sc->sc_io_rman);
+ case SYS_RES_MEMORY:
+ if (sc->sc_have_pmem && (flags & RF_PREFETCHABLE))
+ return (&sc->sc_pmem_rman);
+ else
+ return (&sc->sc_mem_rman);
+ default:
+ break;
+ }
+
+ return (NULL);
+}
Modified: stable/11/sys/dev/ofw/ofwpci.h
==============================================================================
--- stable/11/sys/dev/ofw/ofwpci.h Sat Oct 15 08:52:42 2016 (r307346)
+++ stable/11/sys/dev/ofw/ofwpci.h Sat Oct 15 09:09:25 2016 (r307347)
@@ -60,15 +60,19 @@ struct ofw_pci_softc {
int sc_bus;
int sc_initialized;
int sc_quirks;
+ int sc_have_pmem;
struct ofw_pci_range *sc_range;
int sc_nrange;
+ uint64_t sc_range_mask;
struct ofw_pci_cell_info *sc_cell_info;
struct rman sc_io_rman;
struct rman sc_mem_rman;
+ struct rman sc_pmem_rman;
bus_space_tag_t sc_memt;
bus_dma_tag_t sc_dmat;
+ int sc_pci_domain;
struct ofw_bus_iinfo sc_pci_iinfo;
};
More information about the svn-src-stable-11
mailing list