Module Name: src Committed By: martin Date: Tue Oct 15 19:37:58 UTC 2019
Modified Files: src/sys/arch/arm/acpi [netbsd-9]: acpi_pci_machdep.c acpi_pci_machdep.h acpipchb.c Log Message: Pull up following revision(s) (requested by jmcneill in ticket #332): sys/arch/arm/acpi/acpipchb.c: revision 1.10 sys/arch/arm/acpi/acpipchb.c: revision 1.11 sys/arch/arm/acpi/acpipchb.c: revision 1.12 sys/arch/arm/acpi/acpi_pci_machdep.h: revision 1.3 sys/arch/arm/acpi/acpi_pci_machdep.h: revision 1.4 sys/arch/arm/acpi/acpi_pci_machdep.c: revision 1.10 sys/arch/arm/acpi/acpi_pci_machdep.c: revision 1.11 Add quirks for Amazon Graviton PCIe root ports. Configuration space for the root port is found in a child AMZN0001 resource, not the MCFG table. - More Amazon Graviton quirks: - Ignore devno > 0 on the PCIe root port. - Fixup PCIe bridge bus number register on the root port. - Move quirk handling to acpipchb so it can be applied before the bus is configured. - Fix detection of root port resources for Graviton and remove no longer required bridge fixup To generate a diff of this commit: cvs rdiff -u -r1.9 -r1.9.6.1 src/sys/arch/arm/acpi/acpi_pci_machdep.c cvs rdiff -u -r1.2 -r1.2.8.1 src/sys/arch/arm/acpi/acpi_pci_machdep.h cvs rdiff -u -r1.9 -r1.9.2.1 src/sys/arch/arm/acpi/acpipchb.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/acpi/acpi_pci_machdep.c diff -u src/sys/arch/arm/acpi/acpi_pci_machdep.c:1.9 src/sys/arch/arm/acpi/acpi_pci_machdep.c:1.9.6.1 --- src/sys/arch/arm/acpi/acpi_pci_machdep.c:1.9 Sat Dec 8 15:04:40 2018 +++ src/sys/arch/arm/acpi/acpi_pci_machdep.c Tue Oct 15 19:37:58 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: acpi_pci_machdep.c,v 1.9 2018/12/08 15:04:40 jmcneill Exp $ */ +/* $NetBSD: acpi_pci_machdep.c,v 1.9.6.1 2019/10/15 19:37:58 martin Exp $ */ /*- * Copyright (c) 2018 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: acpi_pci_machdep.c,v 1.9 2018/12/08 15:04:40 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: acpi_pci_machdep.c,v 1.9.6.1 2019/10/15 19:37:58 martin Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -215,6 +215,11 @@ acpi_pci_md_attach_hook(device_t parent, static int acpi_pci_md_bus_maxdevs(void *v, int busno) { + struct acpi_pci_context * const ap = v; + + if (ap->ap_bus_maxdevs != NULL) + return ap->ap_bus_maxdevs(ap, busno); + return 32; } @@ -260,7 +265,10 @@ acpi_pci_md_conf_read(void *v, pcitag_t if (offset < 0 || offset >= PCI_EXTCONF_SIZE) return (pcireg_t) -1; - acpimcfg_conf_read(&ap->ap_pc, tag, offset, &val); + if (ap->ap_conf_read != NULL) + ap->ap_conf_read(&ap->ap_pc, tag, offset, &val); + else + acpimcfg_conf_read(&ap->ap_pc, tag, offset, &val); return val; } @@ -273,7 +281,10 @@ acpi_pci_md_conf_write(void *v, pcitag_t if (offset < 0 || offset >= PCI_EXTCONF_SIZE) return; - acpimcfg_conf_write(&ap->ap_pc, tag, offset, val); + if (ap->ap_conf_write != NULL) + ap->ap_conf_write(&ap->ap_pc, tag, offset, val); + else + acpimcfg_conf_write(&ap->ap_pc, tag, offset, val); } static int Index: src/sys/arch/arm/acpi/acpi_pci_machdep.h diff -u src/sys/arch/arm/acpi/acpi_pci_machdep.h:1.2 src/sys/arch/arm/acpi/acpi_pci_machdep.h:1.2.8.1 --- src/sys/arch/arm/acpi/acpi_pci_machdep.h:1.2 Fri Oct 19 11:40:27 2018 +++ src/sys/arch/arm/acpi/acpi_pci_machdep.h Tue Oct 15 19:37:58 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: acpi_pci_machdep.h,v 1.2 2018/10/19 11:40:27 jmcneill Exp $ */ +/* $NetBSD: acpi_pci_machdep.h,v 1.2.8.1 2019/10/15 19:37:58 martin Exp $ */ /*- * Copyright (c) 2018 The NetBSD Foundation, Inc. @@ -36,7 +36,15 @@ extern struct arm32_pci_chipset arm_acpi struct acpi_pci_context { struct arm32_pci_chipset ap_pc; + device_t ap_dev; u_int ap_seg; + int ap_bus; + ACPI_HANDLE ap_handle; + bus_space_tag_t ap_bst; + bus_space_handle_t ap_conf_bsh; + int (*ap_conf_read)(pci_chipset_tag_t, pcitag_t, int, pcireg_t *); + int (*ap_conf_write)(pci_chipset_tag_t, pcitag_t, int, pcireg_t); + int (*ap_bus_maxdevs)(struct acpi_pci_context *, int); }; #endif /* !_ARM_ACPI_PCI_MACHDEP_H */ Index: src/sys/arch/arm/acpi/acpipchb.c diff -u src/sys/arch/arm/acpi/acpipchb.c:1.9 src/sys/arch/arm/acpi/acpipchb.c:1.9.2.1 --- src/sys/arch/arm/acpi/acpipchb.c:1.9 Tue Jun 25 22:23:39 2019 +++ src/sys/arch/arm/acpi/acpipchb.c Tue Oct 15 19:37:58 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: acpipchb.c,v 1.9 2019/06/25 22:23:39 jmcneill Exp $ */ +/* $NetBSD: acpipchb.c,v 1.9.2.1 2019/10/15 19:37:58 martin Exp $ */ /*- * Copyright (c) 2018 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: acpipchb.c,v 1.9 2019/06/25 22:23:39 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: acpipchb.c,v 1.9.2.1 2019/10/15 19:37:58 martin Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -92,6 +92,132 @@ struct acpipchb_softc { struct acpipchb_bus_space sc_pciio_bst; }; +static int +acpipchb_amazon_graviton_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t *data) +{ + struct acpi_pci_context *ap = pc->pc_conf_v; + int b, d, f; + + pci_decompose_tag(pc, tag, &b, &d, &f); + + if (ap->ap_bus == b) { + if (d > 0 || f > 0) { + *data = -1; + return EINVAL; + } + *data = bus_space_read_4(ap->ap_bst, ap->ap_conf_bsh, reg); + return 0; + } + + return acpimcfg_conf_read(pc, tag, reg, data); +} + +static int +acpipchb_amazon_graviton_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data) +{ + struct acpi_pci_context *ap = pc->pc_conf_v; + int b, d, f; + + pci_decompose_tag(pc, tag, &b, &d, &f); + + if (ap->ap_bus == b) { + if (d > 0 || f > 0) { + return EINVAL; + } + bus_space_write_4(ap->ap_bst, ap->ap_conf_bsh, reg, data); + return 0; + } + + return acpimcfg_conf_write(pc, tag, reg, data); +} + +static int +acpipchb_amazon_graviton_bus_maxdevs(struct acpi_pci_context *ap, int busno) +{ + if (busno == ap->ap_bus + 1) + return 1; + + return 32; +} + +static ACPI_STATUS +acpipchb_amazon_graviton_map(ACPI_HANDLE handle, UINT32 level, void *ctx, void **retval) +{ + struct acpi_pci_context *ap = ctx; + struct acpi_resources res; + struct acpi_mem *mem; + ACPI_HANDLE parent; + ACPI_STATUS rv; + int error; + + rv = AcpiGetParent(handle, &parent); + if (ACPI_FAILURE(rv)) + return rv; + if (ap->ap_handle != parent) + return AE_OK; + + rv = acpi_resource_parse(ap->ap_dev, handle, "_CRS", &res, &acpi_resource_parse_ops_quiet); + if (ACPI_FAILURE(rv)) + return rv; + + mem = acpi_res_mem(&res, 0); + if (mem == NULL) { + acpi_resource_cleanup(&res); + return AE_NOT_FOUND; + } + + error = bus_space_map(ap->ap_bst, mem->ar_base, mem->ar_length, 0, &ap->ap_conf_bsh); + if (error != 0) + return AE_NO_MEMORY; + + ap->ap_conf_read = acpipchb_amazon_graviton_conf_read; + ap->ap_conf_write = acpipchb_amazon_graviton_conf_write; + ap->ap_bus_maxdevs = acpipchb_amazon_graviton_bus_maxdevs; + + return AE_CTRL_TERMINATE; +} + +static void +acpipchb_amazon_graviton_init(struct acpi_pci_context *ap) +{ + ACPI_STATUS rv; + + rv = AcpiGetDevices(__UNCONST("AMZN0001"), acpipchb_amazon_graviton_map, ap, NULL); + if (ACPI_FAILURE(rv)) + return; +} + +static const struct acpipchb_quirk { + const char q_oemid[ACPI_OEM_ID_SIZE+1]; + const char q_oemtableid[ACPI_OEM_TABLE_ID_SIZE+1]; + uint32_t q_oemrevision; + void (*q_init)(struct acpi_pci_context *); +} acpipchb_quirks[] = { + { "AMAZON", "GRAVITON", 0, acpipchb_amazon_graviton_init }, +}; + +static const struct acpipchb_quirk * +acpipchb_find_quirk(void) +{ + ACPI_STATUS rv; + ACPI_TABLE_MCFG *mcfg; + u_int n; + + rv = AcpiGetTable(ACPI_SIG_MCFG, 0, (ACPI_TABLE_HEADER **)&mcfg); + if (ACPI_FAILURE(rv)) + return NULL; + + for (n = 0; n < __arraycount(acpipchb_quirks); n++) { + const struct acpipchb_quirk *q = &acpipchb_quirks[n]; + if (memcmp(q->q_oemid, mcfg->Header.OemId, ACPI_OEM_ID_SIZE) == 0 && + memcmp(q->q_oemtableid, mcfg->Header.OemTableId, ACPI_OEM_TABLE_ID_SIZE) == 0 && + q->q_oemrevision == mcfg->Header.OemRevision) + return q; + } + + return NULL; +} + static int acpipchb_match(device_t, cfdata_t, void *); static void acpipchb_attach(device_t, device_t, void *); @@ -122,6 +248,7 @@ acpipchb_attach(device_t parent, device_ struct acpipchb_softc * const sc = device_private(self); struct acpi_attach_args *aa = aux; struct pcibus_attach_args pba; + const struct acpipchb_quirk *q; ACPI_INTEGER cca, seg; sc->sc_dev = self; @@ -144,9 +271,17 @@ acpipchb_attach(device_t parent, device_ if (cca == 0) sc->sc_dmat._nranges = 0; + sc->sc_ap.ap_dev = self; sc->sc_ap.ap_pc = *aa->aa_pc; sc->sc_ap.ap_pc.pc_conf_v = &sc->sc_ap; sc->sc_ap.ap_seg = seg; + sc->sc_ap.ap_handle = sc->sc_handle; + sc->sc_ap.ap_bus = sc->sc_bus; + sc->sc_ap.ap_bst = sc->sc_memt; + + q = acpipchb_find_quirk(); + if (q != NULL) + q->q_init(&sc->sc_ap); if (acpi_pci_ignore_boot_config(sc->sc_handle)) { if (acpimcfg_configure_bus(self, &sc->sc_ap.ap_pc, sc->sc_handle, sc->sc_bus, PCIHOST_CACHELINE_SIZE) != 0)