diff options
author | Wojciech Macek <wma@FreeBSD.org> | 2018-07-09 08:55:07 +0000 |
---|---|---|
committer | Wojciech Macek <wma@FreeBSD.org> | 2018-07-09 08:55:07 +0000 |
commit | db2156bc49a9c5e036f2c9b12385c4fcfc287213 (patch) | |
tree | d4c8de08724aa1403aca50c02ada412a718447ea | |
parent | 45e8acf71c041e9bce00f169d648855e49a0fadd (diff) | |
download | src-db2156bc49a9c5e036f2c9b12385c4fcfc287213.tar.gz src-db2156bc49a9c5e036f2c9b12385c4fcfc287213.zip |
ARM64: Add support for ThunderX2 PCIe
Submitted by: Patryk Duda <pdk@semihalf.com>
Obtained from: Semihalf
Sponsored by: Cavium
Differential revision: https://reviews.freebsd.org/D15141
Notes
Notes:
svn path=/head/; revision=336129
-rw-r--r-- | sys/dev/acpica/acpi_resource.c | 3 | ||||
-rw-r--r-- | sys/dev/pci/pci_host_generic.c | 2 | ||||
-rw-r--r-- | sys/dev/pci/pci_host_generic_acpi.c | 108 |
3 files changed, 90 insertions, 23 deletions
diff --git a/sys/dev/acpica/acpi_resource.c b/sys/dev/acpica/acpi_resource.c index 21543141b90c..ca98875e3ec1 100644 --- a/sys/dev/acpica/acpi_resource.c +++ b/sys/dev/acpica/acpi_resource.c @@ -560,6 +560,9 @@ acpi_res_set_memory(device_t dev, void *context, uint64_t base, if (cp == NULL) return; + while (bus_get_resource_start(dev, SYS_RES_MEMORY, cp->ar_nmem)) + cp->ar_nmem++; + bus_set_resource(dev, SYS_RES_MEMORY, cp->ar_nmem++, base, length); } diff --git a/sys/dev/pci/pci_host_generic.c b/sys/dev/pci/pci_host_generic.c index 54b5dbd9dff0..49fffa02c187 100644 --- a/sys/dev/pci/pci_host_generic.c +++ b/sys/dev/pci/pci_host_generic.c @@ -107,7 +107,7 @@ pci_host_generic_core_attach(device_t dev) return (error); rid = 0; - sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); + sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE | RF_SHAREABLE); if (sc->res == NULL) { device_printf(dev, "could not map memory.\n"); return (ENXIO); diff --git a/sys/dev/pci/pci_host_generic_acpi.c b/sys/dev/pci/pci_host_generic_acpi.c index 79ef2ae8e512..c96d8a594f21 100644 --- a/sys/dev/pci/pci_host_generic_acpi.c +++ b/sys/dev/pci/pci_host_generic_acpi.c @@ -1,4 +1,5 @@ /*- + * Copyright (C) 2018 Cavium Inc. * Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com> * Copyright (c) 2014 The FreeBSD Foundation * All rights reserved. @@ -96,12 +97,8 @@ struct generic_pcie_acpi_softc { /* Forward prototypes */ static int generic_pcie_acpi_probe(device_t dev); -static uint32_t generic_pcie_read_config(device_t dev, u_int bus, u_int slot, - u_int func, u_int reg, int bytes); -static void generic_pcie_write_config(device_t dev, u_int bus, u_int slot, - u_int func, u_int reg, uint32_t val, int bytes); -static int generic_pcie_release_resource(device_t dev, device_t child, - int type, int rid, struct resource *res); +static ACPI_STATUS pci_host_generic_acpi_parse_resource(ACPI_RESOURCE *, void *); +static int generic_pcie_acpi_read_ivar(device_t, device_t, int, uintptr_t *); static int generic_pcie_acpi_probe(device_t dev) @@ -127,6 +124,7 @@ pci_host_generic_acpi_attach(device_t dev) { struct generic_pcie_acpi_softc *sc; ACPI_HANDLE handle; + ACPI_STATUS status; int error; sc = device_get_softc(dev); @@ -138,46 +136,104 @@ 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 + sc->base.ecam = 0; + acpi_pcib_fetch_prt(dev, &sc->ap_prt); error = pci_host_generic_core_attach(dev); if (error != 0) return (error); + status = AcpiWalkResources(handle, "_CRS", + pci_host_generic_acpi_parse_resource, (void *)dev); + + if (ACPI_FAILURE(status)) + return (ENXIO); + device_add_child(dev, "pci", -1); return (bus_generic_attach(dev)); } -static int -generic_pcie_acpi_route_interrupt(device_t bus, device_t dev, int pin) +static ACPI_STATUS +pci_host_generic_acpi_parse_resource(ACPI_RESOURCE *res, void *arg) { + device_t dev = (device_t)arg; struct generic_pcie_acpi_softc *sc; + rman_res_t min, max; + int error; - sc = device_get_softc(bus); + switch (res->Type) { + case ACPI_RESOURCE_TYPE_ADDRESS32: + min = (rman_res_t)res->Data.Address32.Address.Minimum; + max = (rman_res_t)res->Data.Address32.Address.Maximum; + break; + case ACPI_RESOURCE_TYPE_ADDRESS64: + min = (rman_res_t)res->Data.Address64.Address.Minimum; + max = (rman_res_t)res->Data.Address64.Address.Maximum; + break; + default: + return (AE_OK); + } - return (acpi_pcib_route_interrupt(bus, dev, pin, &sc->ap_prt)); + sc = device_get_softc(dev); + + error = rman_manage_region(&sc->base.mem_rman, min, max); + if (error) { + device_printf(dev, "unable to allocate %lx-%lx range\n", min, max); + return (AE_NOT_FOUND); + } + device_printf(dev, "allocating %lx-%lx range\n", min, max); + + return (AE_OK); } -static struct rman * -generic_pcie_acpi_rman(struct generic_pcie_acpi_softc *sc, int type) +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); - switch (type) { - case SYS_RES_IOPORT: - return (&sc->base.io_rman); - case SYS_RES_MEMORY: - return (&sc->base.mem_rman); - default: - break; + 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; + return (0); } - return (NULL); + if (index == PCIB_IVAR_DOMAIN) { + *result = sc->base.ecam; + return (0); + } + + if (bootverbose) + device_printf(dev, "ERROR: Unknown index %d.\n", index); + return (ENOENT); +} + +static int +generic_pcie_acpi_route_interrupt(device_t bus, device_t dev, int pin) +{ + struct generic_pcie_acpi_softc *sc; + + sc = device_get_softc(bus); + + return (acpi_pcib_route_interrupt(bus, dev, pin, &sc->ap_prt)); } static struct resource * pci_host_generic_acpi_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) { + struct resource *res = NULL; + #if defined(NEW_PCIB) && defined(PCI_RES_BUS) struct generic_pcie_acpi_softc *sc; @@ -188,8 +244,15 @@ pci_host_generic_acpi_alloc_resource(device_t dev, device_t child, int type, } #endif - return (bus_generic_alloc_resource(dev, child, type, rid, start, end, - count, flags)); + if (type == SYS_RES_MEMORY) + res = pci_host_generic_core_alloc_resource(dev, child, type, + rid, start, end, count, flags); + + if (res == NULL) + res = bus_generic_alloc_resource(dev, child, type, rid, start, end, + count, flags); + + return (res); } static int @@ -308,6 +371,7 @@ static device_method_t generic_pcie_acpi_methods[] = { DEVMETHOD(bus_alloc_resource, pci_host_generic_acpi_alloc_resource), DEVMETHOD(bus_activate_resource, generic_pcie_acpi_activate_resource), DEVMETHOD(bus_deactivate_resource, generic_pcie_acpi_deactivate_resource), + DEVMETHOD(bus_read_ivar, generic_pcie_acpi_read_ivar), /* pcib interface */ DEVMETHOD(pcib_route_interrupt, generic_pcie_acpi_route_interrupt), |