Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F142373988
D25121.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D25121.id.diff
View Options
Index: head/sys/dev/pci/pci_host_generic.h
===================================================================
--- head/sys/dev/pci/pci_host_generic.h
+++ head/sys/dev/pci/pci_host_generic.h
@@ -59,14 +59,20 @@
uint64_t phys_base;
uint64_t size;
uint64_t flags;
-#define FLAG_IO (1 << 0)
-#define FLAG_MEM (1 << 1)
+#define FLAG_TYPE(x) ((x) & FLAG_TYPE_MASK)
+#define FLAG_TYPE_MASK 0x3
+#define FLAG_TYPE_INVALID 0x0
+#define FLAG_TYPE_IO 0x1
+#define FLAG_TYPE_MEM 0x2
+#define FLAG_TYPE_PMEM 0x3
};
struct generic_pcie_core_softc {
struct pcie_range ranges[MAX_RANGES_TUPLES];
int nranges;
int coherent;
+ bool has_pmem;
+ struct rman pmem_rman;
struct rman mem_rman;
struct rman io_rman;
struct resource *res;
Index: head/sys/dev/pci/pci_host_generic.c
===================================================================
--- head/sys/dev/pci/pci_host_generic.c
+++ head/sys/dev/pci/pci_host_generic.c
@@ -70,8 +70,11 @@
pci_host_generic_core_attach(device_t dev)
{
struct generic_pcie_core_softc *sc;
+ uint64_t phys_base;
+ uint64_t pci_base;
+ uint64_t size;
int error;
- int rid;
+ int rid, tuple;
sc = device_get_softc(dev);
sc->dev = dev;
@@ -101,12 +104,23 @@
sc->bst = rman_get_bustag(sc->res);
sc->bsh = rman_get_bushandle(sc->res);
+ sc->has_pmem = false;
+ sc->pmem_rman.rm_type = RMAN_ARRAY;
+ sc->pmem_rman.rm_descr = "PCIe Prefetch Memory";
+
sc->mem_rman.rm_type = RMAN_ARRAY;
sc->mem_rman.rm_descr = "PCIe Memory";
+
sc->io_rman.rm_type = RMAN_ARRAY;
sc->io_rman.rm_descr = "PCIe IO window";
/* Initialize rman and allocate memory regions */
+ error = rman_init(&sc->pmem_rman);
+ if (error) {
+ device_printf(dev, "rman_init() failed. error = %d\n", error);
+ return (error);
+ }
+
error = rman_init(&sc->mem_rman);
if (error) {
device_printf(dev, "rman_init() failed. error = %d\n", error);
@@ -119,6 +133,39 @@
return (error);
}
+ for (tuple = 0; tuple < MAX_RANGES_TUPLES; tuple++) {
+ phys_base = sc->ranges[tuple].phys_base;
+ pci_base = sc->ranges[tuple].pci_base;
+ size = sc->ranges[tuple].size;
+ if (phys_base == 0 || size == 0)
+ continue; /* empty range element */
+ switch (FLAG_TYPE(sc->ranges[tuple].flags)) {
+ case FLAG_TYPE_PMEM:
+ sc->has_pmem = true;
+ error = rman_manage_region(&sc->pmem_rman,
+ phys_base, phys_base + size - 1);
+ break;
+ case FLAG_TYPE_MEM:
+ error = rman_manage_region(&sc->mem_rman,
+ phys_base, phys_base + size - 1);
+ break;
+ case FLAG_TYPE_IO:
+ error = rman_manage_region(&sc->io_rman,
+ phys_base, phys_base + size - 1);
+ break;
+ default:
+ continue;
+ }
+ if (error) {
+ device_printf(dev, "rman_manage_region() failed."
+ "error = %d\n", error);
+ rman_fini(&sc->pmem_rman);
+ rman_fini(&sc->mem_rman);
+ rman_fini(&sc->io_rman);
+ return (error);
+ }
+ }
+
return (0);
}
@@ -236,13 +283,15 @@
}
static struct rman *
-generic_pcie_rman(struct generic_pcie_core_softc *sc, int type)
+generic_pcie_rman(struct generic_pcie_core_softc *sc, int type, int flags)
{
switch (type) {
case SYS_RES_IOPORT:
return (&sc->io_rman);
case SYS_RES_MEMORY:
+ if (sc->has_pmem && (flags & RF_PREFETCHABLE) != 0)
+ return (&sc->pmem_rman);
return (&sc->mem_rman);
default:
break;
@@ -266,7 +315,7 @@
}
#endif
- rm = generic_pcie_rman(sc, type);
+ rm = generic_pcie_rman(sc, type, rman_get_flags(res));
if (rm != NULL) {
KASSERT(rman_is_region_manager(res, rm), ("rman mismatch"));
rman_release_resource(res);
@@ -282,6 +331,11 @@
struct generic_pcie_core_softc *sc;
struct resource *res;
struct rman *rm;
+ uint64_t phys_base;
+ uint64_t pci_base;
+ uint64_t size;
+ int i, space;
+ bool found;
sc = device_get_softc(dev);
@@ -292,11 +346,56 @@
}
#endif
- rm = generic_pcie_rman(sc, type);
+ rm = generic_pcie_rman(sc, type, flags);
if (rm == NULL)
return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
type, rid, start, end, count, flags));
+ /* Translate the address from a PCI address to a physical address */
+ switch (type) {
+ case SYS_RES_IOPORT:
+ case SYS_RES_MEMORY:
+ found = false;
+ for (i = 0; i < MAX_RANGES_TUPLES; i++) {
+ pci_base = sc->ranges[i].pci_base;
+ phys_base = sc->ranges[i].phys_base;
+ size = sc->ranges[i].size;
+
+ if (start < pci_base || start >= pci_base + size)
+ continue;
+
+ switch (FLAG_TYPE(sc->ranges[i].flags)) {
+ case FLAG_TYPE_MEM:
+ case FLAG_TYPE_PMEM:
+ space = SYS_RES_MEMORY;
+ break;
+ case FLAG_TYPE_IO:
+ space = SYS_RES_IOPORT;
+ break;
+ default:
+ space = -1;
+ continue;
+ }
+
+ if (type == space) {
+ start = start - pci_base + phys_base;
+ end = end - pci_base + phys_base;
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ device_printf(dev,
+ "Failed to allocate %s resource %lx-%lx for %s\n",
+ type == SYS_RES_IOPORT ? "IOPORT" : "MEMORY",
+ start, end, device_get_nameunit(child));
+ return (NULL);
+ }
+ break;
+ default:
+ break;
+ }
+
if (bootverbose) {
device_printf(dev,
"rman_reserve_resource: start=%#jx, end=%#jx, count=%#jx\n",
@@ -330,53 +429,15 @@
int rid, struct resource *r)
{
struct generic_pcie_core_softc *sc;
- uint64_t phys_base;
- uint64_t pci_base;
- uint64_t size;
- int found;
int res;
- int i;
sc = device_get_softc(dev);
if ((res = rman_activate_resource(r)) != 0)
return (res);
- switch (type) {
- case SYS_RES_IOPORT:
- case SYS_RES_MEMORY:
- found = 0;
- for (i = 0; i < MAX_RANGES_TUPLES; i++) {
- pci_base = sc->ranges[i].pci_base;
- phys_base = sc->ranges[i].phys_base;
- size = sc->ranges[i].size;
-
- if ((rman_get_start(r) >= pci_base) && (rman_get_start(r) < (pci_base + size))) {
- found = 1;
- break;
- }
- }
- if (found) {
- rman_set_start(r, rman_get_start(r) - pci_base + phys_base);
- rman_set_end(r, rman_get_end(r) - pci_base + phys_base);
- res = BUS_ACTIVATE_RESOURCE(device_get_parent(dev),
- child, type, rid, r);
- } else {
- device_printf(dev,
- "Failed to activate %s resource\n",
- type == SYS_RES_IOPORT ? "IOPORT" : "MEMORY");
- res = ENXIO;
- }
- break;
- case SYS_RES_IRQ:
- res = BUS_ACTIVATE_RESOURCE(device_get_parent(dev), child,
- type, rid, r);
- break;
- default:
- break;
- }
-
- return (res);
+ return (BUS_ACTIVATE_RESOURCE(device_get_parent(dev), child, type,
+ rid, r));
}
static int
@@ -416,7 +477,7 @@
end));
#endif
- rm = generic_pcie_rman(sc, type);
+ rm = generic_pcie_rman(sc, type, rman_get_flags(res));
if (rm != NULL)
return (rman_adjust_resource(res, start, end));
return (bus_generic_adjust_resource(dev, child, type, res, start, end));
Index: head/sys/dev/pci/pci_host_generic_acpi.c
===================================================================
--- head/sys/dev/pci/pci_host_generic_acpi.c
+++ head/sys/dev/pci/pci_host_generic_acpi.c
@@ -159,9 +159,9 @@
sc->base.ranges[r].phys_base = min + off;
sc->base.ranges[r].size = max - min + 1;
if (res->Data.Address.ResourceType == ACPI_MEMORY_RANGE)
- sc->base.ranges[r].flags |= FLAG_MEM;
+ sc->base.ranges[r].flags |= FLAG_TYPE_MEM;
else if (res->Data.Address.ResourceType == ACPI_IO_RANGE)
- sc->base.ranges[r].flags |= FLAG_IO;
+ sc->base.ranges[r].flags |= FLAG_TYPE_IO;
sc->base.nranges++;
} else if (res->Data.Address.ResourceType == ACPI_BUS_NUMBER_RANGE) {
sc->base.bus_start = min;
@@ -234,12 +234,8 @@
{
struct generic_pcie_acpi_softc *sc;
ACPI_HANDLE handle;
- uint64_t phys_base;
- uint64_t pci_base;
- uint64_t size;
ACPI_STATUS status;
int error;
- int tuple;
sc = device_get_softc(dev);
handle = acpi_get_handle(dev);
@@ -278,29 +274,6 @@
error = pci_host_generic_core_attach(dev);
if (error != 0)
return (error);
-
- for (tuple = 0; tuple < MAX_RANGES_TUPLES; tuple++) {
- phys_base = sc->base.ranges[tuple].phys_base;
- pci_base = sc->base.ranges[tuple].pci_base;
- size = sc->base.ranges[tuple].size;
- if (phys_base == 0 || size == 0)
- continue; /* empty range element */
- if (sc->base.ranges[tuple].flags & FLAG_MEM) {
- error = rman_manage_region(&sc->base.mem_rman,
- pci_base, pci_base + size - 1);
- } else if (sc->base.ranges[tuple].flags & FLAG_IO) {
- error = rman_manage_region(&sc->base.io_rman,
- pci_base + PCI_IO_WINDOW_OFFSET,
- pci_base + PCI_IO_WINDOW_OFFSET + size - 1);
- } else
- continue;
- if (error) {
- device_printf(dev, "rman_manage_region() failed."
- "error = %d\n", error);
- rman_fini(&sc->base.mem_rman);
- return (error);
- }
- }
return (0);
}
Index: head/sys/dev/pci/pci_host_generic_fdt.c
===================================================================
--- head/sys/dev/pci/pci_host_generic_fdt.c
+++ head/sys/dev/pci/pci_host_generic_fdt.c
@@ -123,12 +123,8 @@
pci_host_generic_attach(device_t dev)
{
struct generic_pcie_fdt_softc *sc;
- uint64_t phys_base;
- uint64_t pci_base;
- uint64_t size;
phandle_t node;
int error;
- int tuple;
sc = device_get_softc(dev);
@@ -157,28 +153,6 @@
if (error != 0)
return (error);
- for (tuple = 0; tuple < MAX_RANGES_TUPLES; tuple++) {
- phys_base = sc->base.ranges[tuple].phys_base;
- pci_base = sc->base.ranges[tuple].pci_base;
- size = sc->base.ranges[tuple].size;
- if (phys_base == 0 || size == 0)
- continue; /* empty range element */
- if (sc->base.ranges[tuple].flags & FLAG_MEM) {
- error = rman_manage_region(&sc->base.mem_rman,
- pci_base, pci_base + size - 1);
- } else if (sc->base.ranges[tuple].flags & FLAG_IO) {
- error = rman_manage_region(&sc->base.io_rman,
- pci_base, pci_base + size - 1);
- } else
- continue;
- if (error) {
- device_printf(dev, "rman_manage_region() failed."
- "error = %d\n", error);
- rman_fini(&sc->base.mem_rman);
- return (error);
- }
- }
-
ofw_bus_setup_iinfo(node, &sc->pci_iinfo, sizeof(cell_t));
device_add_child(dev, "pci", -1);
@@ -221,9 +195,9 @@
attributes = (base_ranges[j++] >> SPACE_CODE_SHIFT) & \
SPACE_CODE_MASK;
if (attributes == SPACE_CODE_IO_SPACE) {
- sc->ranges[i].flags |= FLAG_IO;
+ sc->ranges[i].flags |= FLAG_TYPE_IO;
} else {
- sc->ranges[i].flags |= FLAG_MEM;
+ sc->ranges[i].flags |= FLAG_TYPE_MEM;
}
sc->ranges[i].pci_base = 0;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Jan 20, 6:34 AM (14 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27760174
Default Alt Text
D25121.id.diff (10 KB)
Attached To
Mode
D25121: Clean up the pci host generic driver
Attached
Detach File
Event Timeline
Log In to Comment