git: b313229969cc - main - pci: avoid accidental clobbering of regs on some fdt platforms
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 29 Dec 2024 03:57:08 UTC
The branch main has been updated by kevans: URL: https://cgit.FreeBSD.org/src/commit/?id=b313229969cc56a057dfea28506784fd5468c6f3 commit b313229969cc56a057dfea28506784fd5468c6f3 Author: Kyle Evans <kevans@FreeBSD.org> AuthorDate: 2024-12-29 03:57:03 +0000 Commit: Kyle Evans <kevans@FreeBSD.org> CommitDate: 2024-12-29 03:57:03 +0000 pci: avoid accidental clobbering of regs on some fdt platforms Most pci controllers will just have a single reg for the config space, but others (e.g., on Apple Silicon) may have more following that to describe, e.g., controller port space. Bump the "ranges" rid space up to avoid overriding these other memory resources. Reviewed by: jhb Differential Revision: https://reviews.freebsd.org/D43921 --- sys/dev/pci/pci_host_generic.c | 22 +++++++++++++++++----- sys/dev/pci/pci_host_generic.h | 1 + sys/dev/pci/pci_host_generic_acpi.c | 1 + sys/dev/pci/pci_host_generic_fdt.c | 1 + 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/sys/dev/pci/pci_host_generic.c b/sys/dev/pci/pci_host_generic.c index 373a54a25a4d..884ab25548ce 100644 --- a/sys/dev/pci/pci_host_generic.c +++ b/sys/dev/pci/pci_host_generic.c @@ -59,6 +59,12 @@ #define PCI_RF_FLAGS 0 #endif +/* + * We allocate "ranges" specified mappings higher up in the rid space to avoid + * conflicts with various definitions in the wild that may have other registers + * attributed to the controller besides just the config space. + */ +#define RANGE_RID(idx) ((idx) + 100) /* Forward prototypes */ @@ -173,7 +179,7 @@ pci_host_generic_core_attach(device_t dev) phys_base = sc->ranges[tuple].phys_base; pci_base = sc->ranges[tuple].pci_base; size = sc->ranges[tuple].size; - rid = tuple + 1; + rid = RANGE_RID(tuple); if (size == 0) continue; /* empty range element */ switch (FLAG_TYPE(sc->ranges[tuple].flags)) { @@ -210,6 +216,7 @@ pci_host_generic_core_attach(device_t dev) error); continue; } + sc->ranges[tuple].rid = rid; sc->ranges[tuple].res = bus_alloc_resource_any(dev, type, &rid, RF_ACTIVE | RF_UNMAPPED | flags); if (sc->ranges[tuple].res == NULL) { @@ -246,7 +253,7 @@ int pci_host_generic_core_detach(device_t dev) { struct generic_pcie_core_softc *sc; - int error, tuple, type; + int error, rid, tuple, type; sc = device_get_softc(dev); @@ -255,8 +262,13 @@ pci_host_generic_core_detach(device_t dev) return (error); for (tuple = 0; tuple < MAX_RANGES_TUPLES; tuple++) { - if (sc->ranges[tuple].size == 0) + rid = sc->ranges[tuple].rid; + if (sc->ranges[tuple].size == 0) { + MPASS(sc->ranges[tuple].res == NULL); continue; /* empty range element */ + } + + MPASS(rid != -1); switch (FLAG_TYPE(sc->ranges[tuple].flags)) { case FLAG_TYPE_PMEM: case FLAG_TYPE_MEM: @@ -269,9 +281,9 @@ pci_host_generic_core_detach(device_t dev) continue; } if (sc->ranges[tuple].res != NULL) - bus_release_resource(dev, type, tuple + 1, + bus_release_resource(dev, type, rid, sc->ranges[tuple].res); - bus_delete_resource(dev, type, tuple + 1); + bus_delete_resource(dev, type, rid); } rman_fini(&sc->io_rman); rman_fini(&sc->mem_rman); diff --git a/sys/dev/pci/pci_host_generic.h b/sys/dev/pci/pci_host_generic.h index 7aa8852fd30a..6579cd0918c4 100644 --- a/sys/dev/pci/pci_host_generic.h +++ b/sys/dev/pci/pci_host_generic.h @@ -64,6 +64,7 @@ struct pcie_range { #define FLAG_TYPE_MEM 0x2 #define FLAG_TYPE_PMEM 0x3 struct resource *res; + int rid; }; struct generic_pcie_core_softc { diff --git a/sys/dev/pci/pci_host_generic_acpi.c b/sys/dev/pci/pci_host_generic_acpi.c index 1ff3a6bda707..f12632e7205b 100644 --- a/sys/dev/pci/pci_host_generic_acpi.c +++ b/sys/dev/pci/pci_host_generic_acpi.c @@ -182,6 +182,7 @@ pci_host_generic_acpi_parse_resource(ACPI_RESOURCE *res, void *arg) /* Save detected ranges */ if (res->Data.Address.ResourceType == ACPI_MEMORY_RANGE || res->Data.Address.ResourceType == ACPI_IO_RANGE) { + sc->base.ranges[r].rid = -1; sc->base.ranges[r].pci_base = min; sc->base.ranges[r].phys_base = min + off; sc->base.ranges[r].size = max - min + 1; diff --git a/sys/dev/pci/pci_host_generic_fdt.c b/sys/dev/pci/pci_host_generic_fdt.c index 4e933dec35db..73c6201dc14b 100644 --- a/sys/dev/pci/pci_host_generic_fdt.c +++ b/sys/dev/pci/pci_host_generic_fdt.c @@ -215,6 +215,7 @@ parse_pci_mem_ranges(device_t dev, struct generic_pcie_core_softc *sc) sc->ranges[i].flags |= FLAG_TYPE_MEM; } + sc->ranges[i].rid = -1; sc->ranges[i].pci_base = 0; for (k = 0; k < (pci_addr_cells - 1); k++) { sc->ranges[i].pci_base <<= 32;