Index: sys/arm64/cavium/thunder_pcie_common.h =================================================================== --- sys/arm64/cavium/thunder_pcie_common.h +++ sys/arm64/cavium/thunder_pcie_common.h @@ -39,5 +39,9 @@ uint64_t range_addr_pci_to_phys(struct pcie_range *, uint64_t); int thunder_pcie_identify_ecam(device_t, int *); +#ifdef THUNDERX_PASS_1_1_ERRATA +struct resource *thunder_pcie_alloc_resource(device_t, + device_t, int, int *, rman_res_t, rman_res_t, rman_res_t, u_int); +#endif #endif /* _CAVIUM_THUNDER_PCIE_COMMON_H_ */ Index: sys/arm64/cavium/thunder_pcie_common.c =================================================================== --- sys/arm64/cavium/thunder_pcie_common.c +++ sys/arm64/cavium/thunder_pcie_common.c @@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$"); #include "opt_platform.h" +#include "opt_bus.h" #include #include @@ -52,8 +53,10 @@ #include #endif -#include +#include #include +#include +#include #include #include @@ -142,3 +145,42 @@ return (0); } + +#ifdef THUNDERX_PASS_1_1_ERRATA +struct resource * +thunder_pcie_alloc_resource(device_t dev, device_t child, int type, int *rid, + rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) +{ + pci_addr_t map, testval; + + /* + * If Enhanced Allocation is not used, we can't allocate any random + * range. All internal devices have hardcoded place where they can + * be located within PCI address space. Fortunately, we can read + * this value from BAR. + */ + if (((type == SYS_RES_IOPORT) || (type == SYS_RES_MEMORY)) && + RMAN_IS_DEFAULT_RANGE(start, end)) { + + /* Read BAR manually to get resource address and size */ + pci_read_bar(child, *rid, &map, &testval, NULL); + + /* Mask the information bits */ + if (PCI_BAR_MEM(map)) + map &= PCIM_BAR_MEM_BASE; + else + map &= PCIM_BAR_IO_BASE; + + if (PCI_BAR_MEM(testval)) + testval &= PCIM_BAR_MEM_BASE; + else + testval &= PCIM_BAR_IO_BASE; + + start = map; + end = start + count - 1; + } + + return (pci_host_generic_alloc_resource(dev, child, type, rid, start, + end, count, flags)); +} +#endif Index: sys/arm64/cavium/thunder_pcie_fdt.c =================================================================== --- sys/arm64/cavium/thunder_pcie_fdt.c +++ sys/arm64/cavium/thunder_pcie_fdt.c @@ -49,6 +49,10 @@ #include "thunder_pcie_common.h" +#ifdef THUNDERX_PASS_1_1_ERRATA +static struct resource * thunder_pcie_fdt_alloc_resource(device_t, device_t, + int, int *, rman_res_t, rman_res_t, rman_res_t, u_int); +#endif static int thunder_pcie_fdt_attach(device_t); static int thunder_pcie_fdt_probe(device_t); @@ -56,6 +60,9 @@ /* Device interface */ DEVMETHOD(device_probe, thunder_pcie_fdt_probe), DEVMETHOD(device_attach, thunder_pcie_fdt_attach), +#ifdef THUNDERX_PASS_1_1_ERRATA + DEVMETHOD(bus_alloc_resource, thunder_pcie_fdt_alloc_resource), +#endif /* End */ DEVMETHOD_END @@ -105,3 +112,17 @@ return (pci_host_generic_attach(dev)); } +#ifdef THUNDERX_PASS_1_1_ERRATA +static struct resource * +thunder_pcie_fdt_alloc_resource(device_t dev, device_t child, int type, int *rid, + rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) +{ + + if ((int)ofw_bus_get_node(child) > 0) + return (pci_host_generic_alloc_resource(dev, child, + type, rid, start, end, count, flags)); + + return (thunder_pcie_alloc_resource(dev, child, + type, rid, start, end, count, flags)); +} +#endif Index: sys/dev/pci/pci_host_generic.h =================================================================== --- sys/dev/pci/pci_host_generic.h +++ sys/dev/pci/pci_host_generic.h @@ -66,6 +66,8 @@ extern devclass_t generic_pcie_devclass; DECLARE_CLASS(generic_pcie_driver); +struct resource *pci_host_generic_alloc_resource(device_t, + device_t, int, int *, rman_res_t, rman_res_t, rman_res_t, u_int); int pci_host_generic_attach(device_t); #endif /* __PCI_HOST_GENERIC_H_ */ Index: sys/dev/pci/pci_host_generic.c =================================================================== --- sys/dev/pci/pci_host_generic.c +++ sys/dev/pci/pci_host_generic.c @@ -104,9 +104,6 @@ uintptr_t *result); static int generic_pcie_write_ivar(device_t dev, device_t child, int index, uintptr_t value); -static struct resource *generic_pcie_alloc_resource(device_t dev, - device_t child, int type, int *rid, rman_res_t start, rman_res_t end, - rman_res_t count, u_int flags); static struct resource *generic_pcie_alloc_resource_ofw(device_t, device_t, int, int *, rman_res_t, rman_res_t, rman_res_t, u_int); static struct resource *generic_pcie_alloc_resource_pcie(device_t dev, @@ -508,8 +505,8 @@ child, type, rid, res)); } -static struct resource * -generic_pcie_alloc_resource(device_t dev, device_t child, int type, int *rid, +struct resource * +pci_host_generic_alloc_resource(device_t dev, device_t child, int type, int *rid, rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) { @@ -661,7 +658,7 @@ DEVMETHOD(device_attach, pci_host_generic_attach), DEVMETHOD(bus_read_ivar, generic_pcie_read_ivar), DEVMETHOD(bus_write_ivar, generic_pcie_write_ivar), - DEVMETHOD(bus_alloc_resource, generic_pcie_alloc_resource), + DEVMETHOD(bus_alloc_resource, pci_host_generic_alloc_resource), DEVMETHOD(bus_adjust_resource, generic_pcie_adjust_resource), DEVMETHOD(bus_release_resource, generic_pcie_release_resource), DEVMETHOD(bus_activate_resource, generic_pcie_activate_resource),