Restore ThunderX Pass1.1 PCI changes removed by r295962

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.

Obtained from:         Semihalf
Sponsored by:          Cavium
Approved by:           cognet (mentor)
Reviewed by:           zbb
Differential revision: https://reviews.freebsd.org/D5455
This commit is contained in:
Wojciech Macek 2016-02-26 12:16:11 +00:00
parent 98179b624c
commit 2445e7c84e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=296091
5 changed files with 72 additions and 7 deletions

View file

@ -52,8 +52,10 @@ __FBSDID("$FreeBSD$");
#include <dev/ofw/ofw_pci.h>
#endif
#include <dev/pci/pcivar.h>
#include <sys/pciio.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pci_private.h>
#include <dev/pci/pcib_private.h>
#include <dev/pci/pci_host_generic.h>
@ -142,3 +144,42 @@ thunder_pcie_identify_ecam(device_t dev, int *ecam)
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

View file

@ -39,5 +39,9 @@ uint32_t range_addr_is_phys(struct pcie_range *, uint64_t, uint64_t);
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_ */

View file

@ -49,6 +49,10 @@ __FBSDID("$FreeBSD$");
#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 @@ static device_method_t thunder_pcie_fdt_methods[] = {
/* 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 @@ thunder_pcie_fdt_attach(device_t dev)
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

View file

@ -104,9 +104,6 @@ static int generic_pcie_read_ivar(device_t dev, device_t child, int index,
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 @@ generic_pcie_release_resource(device_t dev, device_t child, int type,
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 @@ static device_method_t generic_pcie_methods[] = {
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),

View file

@ -66,6 +66,8 @@ struct generic_pcie_softc {
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_ */