Date: Wed, 18 Sep 2019 07:16:00 +0000 (UTC) From: "Jayachandran C." <jchandra@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r352471 - in stable/12/sys/dev: acpica pci Message-ID: <201909180716.x8I7G04n099865@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jchandra Date: Wed Sep 18 07:16:00 2019 New Revision: 352471 URL: https://svnweb.freebsd.org/changeset/base/352471 Log: MFC r340599-r340601 r340599: acpica, pci_host_generic_acpi: redo pci_host_generic_acpi.c This is a major update for pci_host_generic_acpi.c, the current implementation has some gaps that are better fixed up in one go. The changes are to: * Follow x86 method of not adding PCI resources to PCI host bridge in ACPI code. This has been moved to pci_host_generic_acpi.c, where we walk thru its resources of the host bridge and add them. * Fixup code in pci_host_generic_acpi.c to read all decoded ranges and update the 'ranges' property. This allows us to share most of the code with generic implementation (and the FDT one). * Parse and setup IO ranges and bus ranges when walking the resources above. Drop most of the changes related to this from acpica code. * Add the ECAM memory area as mem resource 0. Implement the logic to get the ECAM area from MCFG (using bus range which we now decode), or from _CBA (using _BBN/bus range). Drop aarch64 ifdefs from acpica code which did part of this. * Switch resource activation to similar code as FDT implementation, this can be moved into generic implementation in a later pass. * Drop the mechanism of using the 7th bit of bus number as the domain, this is not correct and will work only in very specific cases. Use _SEG as PCI domain and use the bus ranges of the host bridge to provide start bus number. This commit should not make any functional change to dev/acpica/acpi.c for other architectures, almost all the changes there are to revert earlier additions in this file done for aarch64. Reviewed by: andrew Differential Revision: https://reviews.freebsd.org/D17791 r340600: pci_host_generic, acpi_resource: drop unneeded code Now that we are handling PCI resources in pci_host_generic_acpi.c, we don't need these change (made by r336129) Reviewed by: andrew Differential Revision: https://reviews.freebsd.org/D17792 r340601: pci_host_generic : move activate/release to generic code Now that the ACPI and FDT implementations for activating and deactivating resources are the same, we can move it to pci_host_generic.c. No functional changes. Reviewed by: andrew Differential Revision: https://reviews.freebsd.org/D17793 Modified: stable/12/sys/dev/acpica/acpi.c stable/12/sys/dev/acpica/acpi_resource.c stable/12/sys/dev/pci/pci_host_generic.c stable/12/sys/dev/pci/pci_host_generic_acpi.c stable/12/sys/dev/pci/pci_host_generic_fdt.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/dev/acpica/acpi.c ============================================================================== --- stable/12/sys/dev/acpica/acpi.c Wed Sep 18 07:09:16 2019 (r352470) +++ stable/12/sys/dev/acpica/acpi.c Wed Sep 18 07:16:00 2019 (r352471) @@ -179,9 +179,7 @@ static int acpi_child_location_str_method(device_t acd char *buf, size_t buflen); static int acpi_child_pnpinfo_str_method(device_t acdev, device_t child, char *buf, size_t buflen); -#if defined(__i386__) || defined(__amd64__) static void acpi_enable_pcie(void); -#endif static void acpi_hint_device_unit(device_t acdev, device_t child, const char *name, int *unitp); static void acpi_reset_interfaces(device_t dev); @@ -502,10 +500,8 @@ acpi_attach(device_t dev) goto out; } -#if defined(__i386__) || defined(__amd64__) /* Handle MCFG table if present. */ acpi_enable_pcie(); -#endif /* * Note that some systems (specifically, those with namespace evaluation @@ -1286,11 +1282,10 @@ acpi_set_resource(device_t dev, device_t child, int ty struct acpi_softc *sc = device_get_softc(dev); struct acpi_device *ad = device_get_ivars(child); struct resource_list *rl = &ad->ad_rl; -#if defined(__i386__) || defined(__amd64__) ACPI_DEVICE_INFO *devinfo; -#endif rman_res_t end; - + int allow; + /* Ignore IRQ resources for PCI link devices. */ if (type == SYS_RES_IRQ && ACPI_ID_PROBE(dev, child, pcilink_ids) != NULL) return (0); @@ -1304,11 +1299,15 @@ acpi_set_resource(device_t dev, device_t child, int ty * x86 of a PCI bridge claiming the I/O ports used for PCI config * access. */ -#if defined(__i386__) || defined(__amd64__) if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) { if (ACPI_SUCCESS(AcpiGetObjectInfo(ad->ad_handle, &devinfo))) { if ((devinfo->Flags & ACPI_PCI_ROOT_BRIDGE) != 0) { - if (!(type == SYS_RES_IOPORT && start == CONF1_ADDR_PORT)) { +#if defined(__i386__) || defined(__amd64__) + allow = (type == SYS_RES_IOPORT && start == CONF1_ADDR_PORT); +#else + allow = 0; +#endif + if (!allow) { AcpiOsFree(devinfo); return (0); } @@ -1316,7 +1315,6 @@ acpi_set_resource(device_t dev, device_t child, int ty AcpiOsFree(devinfo); } } -#endif #ifdef INTRNG /* map with default for now */ @@ -1873,15 +1871,18 @@ acpi_isa_pnp_probe(device_t bus, device_t child, struc return_VALUE (result); } -#if defined(__i386__) || defined(__amd64__) /* * Look for a MCFG table. If it is present, use the settings for * domain (segment) 0 to setup PCI config space access via the memory * map. + * + * On non-x86 architectures (arm64 for now), this will be done from the + * PCI host bridge driver. */ static void acpi_enable_pcie(void) { +#if defined(__i386__) || defined(__amd64__) ACPI_TABLE_HEADER *hdr; ACPI_MCFG_ALLOCATION *alloc, *end; ACPI_STATUS status; @@ -1900,32 +1901,9 @@ acpi_enable_pcie(void) } alloc++; } +#endif } -#elif defined(__aarch64__) -static void -acpi_enable_pcie(device_t child, int segment) -{ - ACPI_TABLE_HEADER *hdr; - ACPI_MCFG_ALLOCATION *alloc, *end; - ACPI_STATUS status; - status = AcpiGetTable(ACPI_SIG_MCFG, 1, &hdr); - if (ACPI_FAILURE(status)) - return; - - end = (ACPI_MCFG_ALLOCATION *)((char *)hdr + hdr->Length); - alloc = (ACPI_MCFG_ALLOCATION *)((ACPI_TABLE_MCFG *)hdr + 1); - while (alloc < end) { - if (alloc->PciSegment == segment) { - bus_set_resource(child, SYS_RES_MEMORY, 0, - alloc->Address, 0x10000000); - return; - } - alloc++; - } -} -#endif - /* * Scan all of the ACPI namespace and attach child devices. * @@ -2015,9 +1993,6 @@ acpi_probe_child(ACPI_HANDLE handle, UINT32 level, voi { ACPI_DEVICE_INFO *devinfo; struct acpi_device *ad; -#ifdef __aarch64__ - int segment; -#endif struct acpi_prw_data prw; ACPI_OBJECT_TYPE type; ACPI_HANDLE h; @@ -2120,13 +2095,6 @@ acpi_probe_child(ACPI_HANDLE handle, UINT32 level, voi ad->ad_cls_class = strtoul(devinfo->ClassCode.String, NULL, 16); } -#ifdef __aarch64__ - if ((devinfo->Flags & ACPI_PCI_ROOT_BRIDGE) != 0) { - if (ACPI_SUCCESS(acpi_GetInteger(handle, "_SEG", &segment))) { - acpi_enable_pcie(child, segment); - } - } -#endif AcpiOsFree(devinfo); } break; Modified: stable/12/sys/dev/acpica/acpi_resource.c ============================================================================== --- stable/12/sys/dev/acpica/acpi_resource.c Wed Sep 18 07:09:16 2019 (r352470) +++ stable/12/sys/dev/acpica/acpi_resource.c Wed Sep 18 07:16:00 2019 (r352471) @@ -612,10 +612,6 @@ acpi_res_set_memory(device_t dev, void *context, uint6 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); } Modified: stable/12/sys/dev/pci/pci_host_generic.c ============================================================================== --- stable/12/sys/dev/pci/pci_host_generic.c Wed Sep 18 07:09:16 2019 (r352470) +++ stable/12/sys/dev/pci/pci_host_generic.c Wed Sep 18 07:16:00 2019 (r352471) @@ -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 | RF_SHAREABLE); + sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (sc->res == NULL) { device_printf(dev, "could not map memory.\n"); return (ENXIO); @@ -341,6 +341,82 @@ fail: } static int +generic_pcie_activate_resource(device_t dev, device_t child, int type, + int rid, struct resource *r) +{ + struct generic_pcie_core_softc *sc; + uint64_t phys_base; + uint64_t pci_base; + uint64_t size; + int found; + int res; + int i; + + sc = device_get_softc(dev); + + if ((res = rman_activate_resource(r)) != 0) + return (res); + + switch (type) { + case SYS_RES_IOPORT: + found = 0; + for (i = 0; i < MAX_RANGES_TUPLES; i++) { + pci_base = sc->ranges[i].pci_base; + phys_base = sc->ranges[i].phys_base; + size = sc->ranges[i].size; + + if ((rid > pci_base) && (rid < (pci_base + size))) { + found = 1; + break; + } + } + if (found) { + rman_set_start(r, rman_get_start(r) + phys_base); + rman_set_end(r, rman_get_end(r) + phys_base); + res = BUS_ACTIVATE_RESOURCE(device_get_parent(dev), + child, type, rid, r); + } else { + device_printf(dev, + "Failed to activate IOPORT resource\n"); + res = 0; + } + break; + case SYS_RES_MEMORY: + case SYS_RES_IRQ: + res = BUS_ACTIVATE_RESOURCE(device_get_parent(dev), child, + type, rid, r); + break; + default: + break; + } + + return (res); +} + +static int +generic_pcie_deactivate_resource(device_t dev, device_t child, int type, + int rid, struct resource *r) +{ + int res; + + if ((res = rman_deactivate_resource(r)) != 0) + return (res); + + switch (type) { + case SYS_RES_IOPORT: + case SYS_RES_MEMORY: + case SYS_RES_IRQ: + res = BUS_DEACTIVATE_RESOURCE(device_get_parent(dev), child, + type, rid, r); + break; + default: + break; + } + + return (res); +} + +static int generic_pcie_adjust_resource(device_t dev, device_t child, int type, struct resource *res, rman_res_t start, rman_res_t end) { @@ -375,6 +451,8 @@ static device_method_t generic_pcie_methods[] = { DEVMETHOD(bus_write_ivar, generic_pcie_write_ivar), DEVMETHOD(bus_alloc_resource, pci_host_generic_core_alloc_resource), DEVMETHOD(bus_adjust_resource, generic_pcie_adjust_resource), + DEVMETHOD(bus_activate_resource, generic_pcie_activate_resource), + DEVMETHOD(bus_deactivate_resource, generic_pcie_deactivate_resource), DEVMETHOD(bus_release_resource, pci_host_generic_core_release_resource), DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), Modified: stable/12/sys/dev/pci/pci_host_generic_acpi.c ============================================================================== --- stable/12/sys/dev/pci/pci_host_generic_acpi.c Wed Sep 18 07:09:16 2019 (r352470) +++ stable/12/sys/dev/pci/pci_host_generic_acpi.c Wed Sep 18 07:16:00 2019 (r352471) @@ -63,9 +63,8 @@ __FBSDID("$FreeBSD$"); #include <machine/intr.h> #include "pcib_if.h" +#include "acpi_bus_if.h" -int pci_host_generic_acpi_attach(device_t); - /* Assembling ECAM Configuration Address */ #define PCIE_BUS_SHIFT 20 #define PCIE_SLOT_SHIFT 15 @@ -100,6 +99,9 @@ static int generic_pcie_acpi_probe(device_t dev); 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 *); +/* + * generic_pcie_acpi_probe - look for root bridge flag + */ static int generic_pcie_acpi_probe(device_t dev) { @@ -119,81 +121,201 @@ generic_pcie_acpi_probe(device_t dev) return (BUS_PROBE_GENERIC); } -int -pci_host_generic_acpi_attach(device_t dev) +/* + * pci_host_generic_acpi_parse_resource - parse PCI memory, IO and bus spaces + * 'produced' by this bridge + */ +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; + struct rman *rm; + rman_res_t min, max, off; + int r; + + rm = NULL; + sc = device_get_softc(dev); + r = sc->base.nranges; + switch (res->Type) { + case ACPI_RESOURCE_TYPE_ADDRESS16: + min = res->Data.Address16.Address.Minimum; + max = res->Data.Address16.Address.Maximum; + break; + case ACPI_RESOURCE_TYPE_ADDRESS32: + min = res->Data.Address32.Address.Minimum; + max = res->Data.Address32.Address.Maximum; + off = res->Data.Address32.Address.TranslationOffset; + break; + case ACPI_RESOURCE_TYPE_ADDRESS64: + if (res->Data.Address.ResourceType != ACPI_MEMORY_RANGE) + break; + min = res->Data.Address64.Address.Minimum; + max = res->Data.Address64.Address.Maximum; + off = res->Data.Address64.Address.TranslationOffset; + break; + default: + return (AE_OK); + } + + /* Save detected ranges */ + if (res->Data.Address.ResourceType == ACPI_MEMORY_RANGE || + res->Data.Address.ResourceType == ACPI_IO_RANGE) { + sc->base.ranges[r].pci_base = min; + sc->base.ranges[r].phys_base = min + off; + sc->base.ranges[r].size = max - min + 1; + if (res->Data.Address.ResourceType == ACPI_MEMORY_RANGE) + sc->base.ranges[r].flags |= FLAG_MEM; + else if (res->Data.Address.ResourceType == ACPI_IO_RANGE) + sc->base.ranges[r].flags |= FLAG_IO; + sc->base.nranges++; + } else if (res->Data.Address.ResourceType == ACPI_BUS_NUMBER_RANGE) { + sc->base.bus_start = min; + sc->base.bus_end = max; + } + return (AE_OK); +} + +static int +pci_host_acpi_get_ecam_resource(device_t dev) +{ + struct generic_pcie_acpi_softc *sc; + struct acpi_device *ad; + struct resource_list *rl; + ACPI_TABLE_HEADER *hdr; + ACPI_MCFG_ALLOCATION *mcfg_entry, *mcfg_end; ACPI_HANDLE handle; ACPI_STATUS status; - int error, bus_start; + rman_res_t base, start, end; + int found, val; sc = device_get_softc(dev); + handle = acpi_get_handle(dev); + /* Try MCFG first */ + status = AcpiGetTable(ACPI_SIG_MCFG, 1, &hdr); + if (ACPI_SUCCESS(status)) { + found = FALSE; + mcfg_end = (ACPI_MCFG_ALLOCATION *)((char *)hdr + hdr->Length); + mcfg_entry = (ACPI_MCFG_ALLOCATION *)((ACPI_TABLE_MCFG *)hdr + 1); + while (mcfg_entry < mcfg_end && !found) { + if (mcfg_entry->PciSegment == sc->base.ecam && + mcfg_entry->StartBusNumber <= sc->base.bus_start && + mcfg_entry->EndBusNumber >= sc->base.bus_start) + found = TRUE; + else + mcfg_entry++; + } + if (found) { + if (mcfg_entry->EndBusNumber < sc->base.bus_end) { + device_printf(dev, "bus end mismatch! expected %d found %d.\n", + sc->base.bus_end, (int)mcfg_entry->EndBusNumber); + sc->base.bus_end = mcfg_entry->EndBusNumber; + } + base = mcfg_entry->Address; + } else { + device_printf(dev, "MCFG exists, but does not have bus %d-%d\n", + sc->base.bus_start, sc->base.bus_end); + return (ENXIO); + } + } else { + status = acpi_GetInteger(handle, "_CBA", &val); + if (ACPI_SUCCESS(status)) + base = val; + else + return (ENXIO); + } + + /* add as MEM rid 0 */ + ad = device_get_ivars(dev); + rl = &ad->ad_rl; + start = base + (sc->base.bus_start << PCIE_BUS_SHIFT); + end = base + ((sc->base.bus_end + 1) << PCIE_BUS_SHIFT) - 1; + resource_list_add(rl, SYS_RES_MEMORY, 0, start, end, end - start + 1); + if (bootverbose) + device_printf(dev, "ECAM for bus %d-%d at mem %jx-%jx\n", + sc->base.bus_start, sc->base.bus_end, start, end); + return (0); +} + +static int +pci_host_generic_acpi_attach(device_t dev) +{ + struct generic_pcie_acpi_softc *sc; + ACPI_HANDLE handle; + uint64_t phys_base; + uint64_t pci_base; + uint64_t size; + ACPI_STATUS status; + int error; + int tuple; + + sc = device_get_softc(dev); handle = acpi_get_handle(dev); + + /* Get Start bus number for the PCI host bus is from _BBN method */ + status = acpi_GetInteger(handle, "_BBN", &sc->base.bus_start); + if (ACPI_FAILURE(status)) { + device_printf(dev, "No _BBN, using start bus 0\n"); + sc->base.bus_start = 0; + } + sc->base.bus_end = 255; + + /* Get PCI Segment (domain) needed for MCFG lookup */ + status = acpi_GetInteger(handle, "_SEG", &sc->base.ecam); + if (ACPI_FAILURE(status)) { + device_printf(dev, "No _SEG for PCI Bus, using segment 0\n"); + sc->base.ecam = 0; + } + + /* Bus decode ranges */ + status = AcpiWalkResources(handle, "_CRS", + pci_host_generic_acpi_parse_resource, (void *)dev); + if (ACPI_FAILURE(status)) + return (ENXIO); + + /* Coherency attribute */ if (ACPI_FAILURE(acpi_GetInteger(handle, "_CCA", &sc->base.coherent))) sc->base.coherent = 0; if (bootverbose) device_printf(dev, "Bus is%s cache-coherent\n", sc->base.coherent ? "" : " not"); - 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; - + /* add config space resource */ + pci_host_acpi_get_ecam_resource(dev); 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); + for (tuple = 0; tuple < MAX_RANGES_TUPLES; tuple++) { + phys_base = sc->base.ranges[tuple].phys_base; + pci_base = sc->base.ranges[tuple].pci_base; + size = sc->base.ranges[tuple].size; + if (phys_base == 0 || size == 0) + continue; /* empty range element */ + if (sc->base.ranges[tuple].flags & FLAG_MEM) { + error = rman_manage_region(&sc->base.mem_rman, + phys_base, phys_base + size - 1); + } else if (sc->base.ranges[tuple].flags & FLAG_IO) { + error = rman_manage_region(&sc->base.io_rman, + pci_base + PCI_IO_WINDOW_OFFSET, + pci_base + PCI_IO_WINDOW_OFFSET + size - 1); + } else + continue; + if (error) { + device_printf(dev, "rman_manage_region() failed." + "error = %d\n", error); + rman_fini(&sc->base.mem_rman); + return (error); + } + } - if (ACPI_FAILURE(status)) - return (ENXIO); - device_add_child(dev, "pci", -1); return (bus_generic_attach(dev)); } -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; - - 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); - } - - 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 int generic_pcie_acpi_read_ivar(device_t dev, device_t child, int index, uintptr_t *result) @@ -203,7 +325,7 @@ generic_pcie_acpi_read_ivar(device_t dev, device_t chi sc = device_get_softc(dev); if (index == PCIB_IVAR_BUS) { - *result = sc->base.ecam * 0x80 + sc->base.bus_start; + *result = sc->base.bus_start; return (0); } @@ -223,68 +345,10 @@ generic_pcie_acpi_route_interrupt(device_t bus, device 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; - - if (type == PCI_RES_BUS) { - sc = device_get_softc(dev); - return (pci_domain_alloc_bus(sc->base.ecam, child, rid, start, - end, count, flags)); - } -#endif - - 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 -generic_pcie_acpi_activate_resource(device_t dev, device_t child, int type, - int rid, struct resource *r) -{ - struct generic_pcie_acpi_softc *sc; - int res; - - sc = device_get_softc(dev); - - if ((res = rman_activate_resource(r)) != 0) - return (res); - - res = BUS_ACTIVATE_RESOURCE(device_get_parent(dev), child, type, rid,r); - return (res); -} - -static int -generic_pcie_acpi_deactivate_resource(device_t dev, device_t child, int type, - int rid, struct resource *r) -{ - int res; - - if ((res = rman_deactivate_resource(r)) != 0) - return (res); - - res = BUS_DEACTIVATE_RESOURCE(device_get_parent(dev), child, type, - rid, r); - return (res); -} - -static int generic_pcie_acpi_alloc_msi(device_t pci, device_t child, int count, int maxcount, int *irqs) { @@ -347,29 +411,22 @@ static int generic_pcie_acpi_get_id(device_t pci, device_t child, enum pci_id_type type, uintptr_t *id) { - struct generic_pcie_acpi_softc *sc; - int err; - /* Use the PCI RID to find the MSI ID */ - if (type == PCI_ID_MSI) { - sc = device_get_softc(pci); - type = PCI_ID_RID; - err = pcib_get_id(pci, child, type, id); - if (err != 0) - return (err); - *id |= sc->base.ecam << 16; - return (0); - } - - return (pcib_get_id(pci, child, type, id)); + /* + * Use the PCI RID to find the MSI ID for now, we support only 1:1 + * mapping + * + * On aarch64, more complex mapping would come from IORT table + */ + if (type == PCI_ID_MSI) + return (pcib_get_id(pci, child, PCI_ID_RID, id)); + else + return (pcib_get_id(pci, child, type, id)); } static device_method_t generic_pcie_acpi_methods[] = { DEVMETHOD(device_probe, generic_pcie_acpi_probe), DEVMETHOD(device_attach, pci_host_generic_acpi_attach), - 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 */ Modified: stable/12/sys/dev/pci/pci_host_generic_fdt.c ============================================================================== --- stable/12/sys/dev/pci/pci_host_generic_fdt.c Wed Sep 18 07:09:16 2019 (r352470) +++ stable/12/sys/dev/pci/pci_host_generic_fdt.c Wed Sep 18 07:16:00 2019 (r352471) @@ -385,82 +385,6 @@ pci_host_generic_alloc_resource(device_t dev, device_t } static int -generic_pcie_fdt_activate_resource(device_t dev, device_t child, int type, - int rid, struct resource *r) -{ - struct generic_pcie_fdt_softc *sc; - uint64_t phys_base; - uint64_t pci_base; - uint64_t size; - int found; - int res; - int i; - - sc = device_get_softc(dev); - - if ((res = rman_activate_resource(r)) != 0) - return (res); - - switch(type) { - case SYS_RES_IOPORT: - found = 0; - for (i = 0; i < MAX_RANGES_TUPLES; i++) { - pci_base = sc->base.ranges[i].pci_base; - phys_base = sc->base.ranges[i].phys_base; - size = sc->base.ranges[i].size; - - if ((rid > pci_base) && (rid < (pci_base + size))) { - found = 1; - break; - } - } - if (found) { - rman_set_start(r, rman_get_start(r) + phys_base); - rman_set_end(r, rman_get_end(r) + phys_base); - res = BUS_ACTIVATE_RESOURCE(device_get_parent(dev), - child, type, rid, r); - } else { - device_printf(dev, - "Failed to activate IOPORT resource\n"); - res = 0; - } - break; - case SYS_RES_MEMORY: - case SYS_RES_IRQ: - res = BUS_ACTIVATE_RESOURCE(device_get_parent(dev), child, - type, rid, r); - break; - default: - break; - } - - return (res); -} - -static int -generic_pcie_fdt_deactivate_resource(device_t dev, device_t child, int type, - int rid, struct resource *r) -{ - int res; - - if ((res = rman_deactivate_resource(r)) != 0) - return (res); - - switch(type) { - case SYS_RES_IOPORT: - case SYS_RES_MEMORY: - case SYS_RES_IRQ: - res = BUS_DEACTIVATE_RESOURCE(device_get_parent(dev), child, - type, rid, r); - break; - default: - break; - } - - return (res); -} - -static int generic_pcie_fdt_alloc_msi(device_t pci, device_t child, int count, int maxcount, int *irqs) { @@ -630,8 +554,6 @@ static device_method_t generic_pcie_fdt_methods[] = { DEVMETHOD(device_attach, pci_host_generic_attach), DEVMETHOD(bus_alloc_resource, pci_host_generic_alloc_resource), DEVMETHOD(bus_release_resource, generic_pcie_fdt_release_resource), - DEVMETHOD(bus_activate_resource, generic_pcie_fdt_activate_resource), - DEVMETHOD(bus_deactivate_resource,generic_pcie_fdt_deactivate_resource), /* pcib interface */ DEVMETHOD(pcib_route_interrupt, generic_pcie_fdt_route_interrupt),
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201909180716.x8I7G04n099865>