Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/arm/acpi Add quirks for Amazon Graviton PCIe root p...
details: https://anonhg.NetBSD.org/src/rev/3a74c66c8833
branches: trunk
changeset: 464610:3a74c66c8833
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Mon Oct 14 00:16:29 2019 +0000
description:
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.
diffstat:
sys/arch/arm/acpi/acpi_pci_machdep.c | 133 +++++++++++++++++++++++++++++++++-
sys/arch/arm/acpi/acpi_pci_machdep.h | 8 +-
sys/arch/arm/acpi/acpipchb.c | 7 +-
3 files changed, 141 insertions(+), 7 deletions(-)
diffs (236 lines):
diff -r fc64e46e3251 -r 3a74c66c8833 sys/arch/arm/acpi/acpi_pci_machdep.c
--- a/sys/arch/arm/acpi/acpi_pci_machdep.c Mon Oct 14 00:15:13 2019 +0000
+++ b/sys/arch/arm/acpi/acpi_pci_machdep.c Mon Oct 14 00:16:29 2019 +0000
@@ -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.10 2019/10/14 00:16:29 jmcneill 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.10 2019/10/14 00:16:29 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -60,6 +60,120 @@
#include <arm/pci/pci_msi_machdep.h>
+static int
+acpi_pci_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;
+ bus_size_t off;
+ int b, d, f;
+
+ pci_decompose_tag(pc, tag, &b, &d, &f);
+
+ if (ap->ap_bus == b) {
+ if (d > 0) {
+ *data = -1;
+ return EINVAL;
+ }
+ off = f * PCI_EXTCONF_SIZE + reg;
+ *data = bus_space_read_4(ap->ap_bst, ap->ap_conf_bsh, off);
+ return 0;
+ }
+
+ return acpimcfg_conf_read(pc, tag, reg, data);
+}
+
+static int
+acpi_pci_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;
+ bus_size_t off;
+ int b, d, f;
+
+ pci_decompose_tag(pc, tag, &b, &d, &f);
+
+ if (ap->ap_bus == b) {
+ if (d > 0) {
+ return EINVAL;
+ }
+ off = f * PCI_EXTCONF_SIZE + reg;
+ bus_space_write_4(ap->ap_bst, ap->ap_conf_bsh, off, data);
+ return 0;
+ }
+
+ return acpimcfg_conf_write(pc, tag, reg, data);
+}
+
+static ACPI_STATUS
+acpi_pci_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_STATUS rv;
+ int error;
+
+ 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;
+
+ return AE_CTRL_TERMINATE;
+}
+
+static void
+acpi_pci_amazon_graviton_init(struct pcibus_attach_args *pba)
+{
+ struct acpi_pci_context *ap = pba->pba_pc->pc_conf_v;
+ ACPI_STATUS rv;
+
+ rv = AcpiGetDevices(__UNCONST("AMZN0001"), acpi_pci_amazon_graviton_map, ap, NULL);
+ if (ACPI_FAILURE(rv))
+ return;
+
+ ap->ap_conf_read = acpi_pci_amazon_graviton_conf_read;
+ ap->ap_conf_write = acpi_pci_amazon_graviton_conf_write;
+}
+
+static const struct acpi_pci_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 pcibus_attach_args *);
+} acpi_pci_quirks[] = {
+ { "AMAZON", "GRAVITON", 0, acpi_pci_amazon_graviton_init },
+};
+
+static const struct acpi_pci_quirk *
+acpi_pci_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(acpi_pci_quirks); n++) {
+ const struct acpi_pci_quirk *q = &acpi_pci_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;
+}
+
struct acpi_pci_prt {
u_int prt_segment;
u_int prt_bus;
@@ -160,6 +274,7 @@
{
struct acpi_pci_context *ap = pba->pba_pc->pc_conf_v;
struct acpi_pci_prt *prt, *prtp;
+ const struct acpi_pci_quirk *q;
struct acpi_devnode *ad;
ACPI_HANDLE handle;
int seg, bus, dev, func;
@@ -202,6 +317,10 @@
TAILQ_INSERT_TAIL(&acpi_pci_irq_routes, prt, prt_list);
}
+ q = acpi_pci_find_quirk();
+ if (q != NULL)
+ q->q_init(pba);
+
acpimcfg_map_bus(self, pba->pba_pc, pba->pba_bus);
if (ad != NULL) {
@@ -260,7 +379,10 @@
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 +395,10 @@
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
diff -r fc64e46e3251 -r 3a74c66c8833 sys/arch/arm/acpi/acpi_pci_machdep.h
--- a/sys/arch/arm/acpi/acpi_pci_machdep.h Mon Oct 14 00:15:13 2019 +0000
+++ b/sys/arch/arm/acpi/acpi_pci_machdep.h Mon Oct 14 00:16:29 2019 +0000
@@ -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.3 2019/10/14 00:16:29 jmcneill Exp $ */
/*-
* Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -36,7 +36,13 @@
struct acpi_pci_context {
struct arm32_pci_chipset ap_pc;
+ device_t ap_dev;
u_int ap_seg;
+ int ap_bus;
+ 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);
};
#endif /* !_ARM_ACPI_PCI_MACHDEP_H */
diff -r fc64e46e3251 -r 3a74c66c8833 sys/arch/arm/acpi/acpipchb.c
--- a/sys/arch/arm/acpi/acpipchb.c Mon Oct 14 00:15:13 2019 +0000
+++ b/sys/arch/arm/acpi/acpipchb.c Mon Oct 14 00:16:29 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: acpipchb.c,v 1.9 2019/06/25 22:23:39 jmcneill Exp $ */
+/* $NetBSD: acpipchb.c,v 1.10 2019/10/14 00:16:29 jmcneill 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.10 2019/10/14 00:16:29 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -144,9 +144,12 @@
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_bus = sc->sc_bus;
+ sc->sc_ap.ap_bst = sc->sc_memt;
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)
Home |
Main Index |
Thread Index |
Old Index