pci_host_generic*: basic implementation of bus range

Both ACPI and FDT support bus ranges for pci host bridges. Update
pci_host_generic*.[ch] with a default implementation to support this.
This will be used in the next set of changes for ACPI based host
bridge. No functional changes in this commit.

Reviewed by:	andrew
Differential Revision:	https://reviews.freebsd.org/D17657
This commit is contained in:
jchandra 2018-11-19 02:55:18 +00:00
parent 956387e5e9
commit 3b690e695d
4 changed files with 27 additions and 24 deletions

View File

@ -147,13 +147,14 @@ generic_pcie_read_config(device_t dev, u_int bus, u_int slot,
uint64_t offset;
uint32_t data;
if ((bus > PCI_BUSMAX) || (slot > PCI_SLOTMAX) ||
(func > PCI_FUNCMAX) || (reg > PCIE_REGMAX))
sc = device_get_softc(dev);
if ((bus < sc->bus_start) || (bus > sc->bus_end))
return (~0U);
if ((slot > PCI_SLOTMAX) || (func > PCI_FUNCMAX) ||
(reg > PCIE_REGMAX))
return (~0U);
sc = device_get_softc(dev);
offset = PCIE_ADDR_OFFSET(bus, slot, func, reg);
offset = PCIE_ADDR_OFFSET(bus - sc->bus_start, slot, func, reg);
t = sc->bst;
h = sc->bsh;
@ -183,13 +184,14 @@ generic_pcie_write_config(device_t dev, u_int bus, u_int slot,
bus_space_tag_t t;
uint64_t offset;
if ((bus > PCI_BUSMAX) || (slot > PCI_SLOTMAX) ||
(func > PCI_FUNCMAX) || (reg > PCIE_REGMAX))
sc = device_get_softc(dev);
if ((bus < sc->bus_start) || (bus > sc->bus_end))
return;
if ((slot > PCI_SLOTMAX) || (func > PCI_FUNCMAX) ||
(reg > PCIE_REGMAX))
return;
sc = device_get_softc(dev);
offset = PCIE_ADDR_OFFSET(bus, slot, func, reg);
offset = PCIE_ADDR_OFFSET(bus - sc->bus_start, slot, func, reg);
t = sc->bst;
h = sc->bsh;
@ -221,14 +223,11 @@ generic_pcie_read_ivar(device_t dev, device_t child, int index,
uintptr_t *result)
{
struct generic_pcie_core_softc *sc;
int secondary_bus;
sc = device_get_softc(dev);
if (index == PCIB_IVAR_BUS) {
/* this pcib adds only pci bus 0 as child */
secondary_bus = 0;
*result = secondary_bus;
*result = sc->bus_start;
return (0);
}

View File

@ -56,6 +56,8 @@ struct generic_pcie_core_softc {
struct rman io_rman;
struct resource *res;
struct resource *res1;
int bus_start;
int bus_end;
int ecam;
bus_space_tag_t bst;
bus_space_handle_t bsh;

View File

@ -125,7 +125,7 @@ pci_host_generic_acpi_attach(device_t dev)
struct generic_pcie_acpi_softc *sc;
ACPI_HANDLE handle;
ACPI_STATUS status;
int error;
int error, bus_start;
sc = device_get_softc(dev);
@ -136,10 +136,14 @@ pci_host_generic_acpi_attach(device_t dev)
device_printf(dev, "Bus is%s cache-coherent\n",
sc->base.coherent ? "" : " not");
if (!ACPI_FAILURE(acpi_GetInteger(handle, "_BBN", &sc->base.ecam)))
sc->base.ecam >>= 7;
else
if (!ACPI_FAILURE(acpi_GetInteger(handle, "_BBN", &bus_start))) {
sc->base.ecam = bus_start >> 7;
sc->base.bus_start = bus_start & 0x7F;
} else {
sc->base.ecam = 0;
sc->base.bus_start = 0;
}
sc->base.bus_end = 0xFF;
acpi_pcib_fetch_prt(dev, &sc->ap_prt);
@ -194,17 +198,12 @@ static int
generic_pcie_acpi_read_ivar(device_t dev, device_t child, int index,
uintptr_t *result)
{
ACPI_HANDLE handle;
struct generic_pcie_acpi_softc *sc;
int secondary_bus;
sc = device_get_softc(dev);
if (index == PCIB_IVAR_BUS) {
handle = acpi_get_handle(dev);
if (ACPI_FAILURE(acpi_GetInteger(handle, "_BBN", &secondary_bus)))
secondary_bus = sc->base.ecam * 0x80;
*result = secondary_bus;
*result = sc->base.ecam * 0x80 + sc->base.bus_start;
return (0);
}

View File

@ -152,6 +152,9 @@ pci_host_generic_attach(device_t dev)
device_printf(dev, "Bus is%s cache-coherent\n",
sc->base.coherent ? "" : " not");
/* TODO parse FDT bus ranges */
sc->base.bus_start = 0;
sc->base.bus_end = 0xFF;
error = pci_host_generic_core_attach(dev);
if (error != 0)
return (error);