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 arm: acpi: Add support for SMCCC based PCI...
details: https://anonhg.NetBSD.org/src/rev/88d778778ae7
branches: trunk
changeset: 1022799:88d778778ae7
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Sat Aug 07 21:27:53 2021 +0000
description:
arm: acpi: Add support for SMCCC based PCI config access.
diffstat:
sys/arch/arm/acpi/acpi_pci_machdep.c | 34 +++++++-
sys/arch/arm/acpi/acpi_pci_machdep.h | 6 +-
sys/arch/arm/acpi/acpi_pci_smccc.c | 129 +++++++++++++++++++++++++++++++++++
sys/arch/arm/acpi/acpipchb.c | 50 +++++++++++--
sys/arch/arm/acpi/files.acpi | 3 +-
5 files changed, 205 insertions(+), 17 deletions(-)
diffs (truncated from 360 to 300 lines):
diff -r be4df54ba479 -r 88d778778ae7 sys/arch/arm/acpi/acpi_pci_machdep.c
--- a/sys/arch/arm/acpi/acpi_pci_machdep.c Sat Aug 07 21:24:56 2021 +0000
+++ b/sys/arch/arm/acpi/acpi_pci_machdep.c Sat Aug 07 21:27:53 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_pci_machdep.c,v 1.18 2020/06/17 06:45:09 thorpej Exp $ */
+/* $NetBSD: acpi_pci_machdep.c,v 1.19 2021/08/07 21:27:53 jmcneill Exp $ */
/*-
* Copyright (c) 2018, 2020 The NetBSD Foundation, Inc.
@@ -29,10 +29,12 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include "opt_pci.h"
+
#define _INTR_PRIVATE
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_pci_machdep.c,v 1.18 2020/06/17 06:45:09 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_pci_machdep.c,v 1.19 2021/08/07 21:27:53 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -60,6 +62,10 @@
#include <arm/acpi/acpi_iort.h>
#include <arm/acpi/acpi_pci_machdep.h>
+#ifdef PCI_SMCCC
+#include <arm/pci/pci_smccc.h>
+#endif
+
#include <arm/pci/pci_msi_machdep.h>
struct acpi_pci_prt {
@@ -94,7 +100,7 @@
static TAILQ_HEAD(, acpi_pci_intr) acpi_pci_intrs =
TAILQ_HEAD_INITIALIZER(acpi_pci_intrs);
-static const struct acpi_pci_quirk acpi_pci_quirks[] = {
+static const struct acpi_pci_quirk acpi_pci_mcfg_quirks[] = {
/* OEM ID OEM Table ID Revision Seg Func */
{ "AMAZON", "GRAVITON", 0, -1, acpi_pci_graviton_init },
{ "ARMLTD", "ARMN1SDP", 0x20181101, 0, acpi_pci_n1sdp_init },
@@ -102,6 +108,13 @@
{ "NXP ", "LX2160 ", 0, -1, acpi_pci_layerscape_gen4_init },
};
+#ifdef PCI_SMCCC
+static const struct acpi_pci_quirk acpi_pci_smccc_quirk = {
+ .q_segment = -1,
+ .q_init = acpi_pci_smccc_init,
+};
+#endif
+
pci_chipset_tag_t acpi_pci_md_get_chipset_tag(struct acpi_softc *, int, int);
static void acpi_pci_md_attach_hook(device_t, device_t,
@@ -554,11 +567,19 @@
u_int n;
rv = AcpiGetTable(ACPI_SIG_MCFG, 0, (ACPI_TABLE_HEADER **)&mcfg);
- if (ACPI_FAILURE(rv))
+ if (ACPI_FAILURE(rv)) {
+#ifdef PCI_SMCCC
+ uint32_t ver = pci_smccc_version();
+ aprint_debug("%s: SMCCC version %#x\n", __func__, ver);
+ if (PCI_SMCCC_SUCCESS(ver)) {
+ return &acpi_pci_smccc_quirk;
+ }
+#endif
return NULL;
+ }
- for (n = 0; n < __arraycount(acpi_pci_quirks); n++) {
- const struct acpi_pci_quirk *q = &acpi_pci_quirks[n];
+ for (n = 0; n < __arraycount(acpi_pci_mcfg_quirks); n++) {
+ const struct acpi_pci_quirk *q = &acpi_pci_mcfg_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 &&
@@ -589,6 +610,7 @@
pct->pct_ap.ap_pc.pc_intr_v = &pct->pct_ap;
pct->pct_ap.ap_seg = seg;
pct->pct_ap.ap_bus = bbn;
+ pct->pct_ap.ap_maxbus = -1;
pct->pct_ap.ap_bst = acpi_softc->sc_memt;
q = acpi_pci_md_find_quirk(seg);
diff -r be4df54ba479 -r 88d778778ae7 sys/arch/arm/acpi/acpi_pci_machdep.h
--- a/sys/arch/arm/acpi/acpi_pci_machdep.h Sat Aug 07 21:24:56 2021 +0000
+++ b/sys/arch/arm/acpi/acpi_pci_machdep.h Sat Aug 07 21:27:53 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_pci_machdep.h,v 1.7 2020/02/01 13:26:43 jmcneill Exp $ */
+/* $NetBSD: acpi_pci_machdep.h,v 1.8 2021/08/07 21:27:53 jmcneill Exp $ */
/*-
* Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -39,12 +39,15 @@
device_t ap_dev;
u_int ap_seg;
int ap_bus;
+ int ap_maxbus;
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);
void *ap_conf_priv;
int ap_pciflags_clear;
+ u_int ap_flags;
+#define ACPI_PCI_FLAG_NO_MCFG __BIT(0) /* ignore MCFG table */
};
struct acpi_pci_quirk {
@@ -57,6 +60,7 @@
const struct acpi_pci_quirk * acpi_pci_md_find_quirk(int);
+void acpi_pci_smccc_init(struct acpi_pci_context *);
void acpi_pci_graviton_init(struct acpi_pci_context *);
void acpi_pci_layerscape_gen4_init(struct acpi_pci_context *);
void acpi_pci_n1sdp_init(struct acpi_pci_context *);
diff -r be4df54ba479 -r 88d778778ae7 sys/arch/arm/acpi/acpi_pci_smccc.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/arm/acpi/acpi_pci_smccc.c Sat Aug 07 21:27:53 2021 +0000
@@ -0,0 +1,129 @@
+/* $NetBSD: acpi_pci_smccc.c,v 1.1 2021/08/07 21:27:53 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2021 Jared McNeill <jmcneill%invisible.ca@localhost>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: acpi_pci_smccc.c,v 1.1 2021/08/07 21:27:53 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pciconf.h>
+
+#include <dev/acpi/acpivar.h>
+#include <dev/acpi/acpi_pci.h>
+#include <dev/acpi/acpi_mcfg.h>
+
+#include <arm/acpi/acpi_pci_machdep.h>
+
+#include <arm/pci/pci_smccc.h>
+
+static int
+acpi_pci_smccc_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;
+ int status;
+
+ pci_decompose_tag(pc, tag, &b, &d, &f);
+
+ if (b < ap->ap_bus || b > ap->ap_maxbus) {
+ *data = -1;
+ return EINVAL;
+ }
+
+ status = pci_smccc_read(PCI_SMCCC_SBDF(ap->ap_seg, b, d, f), reg,
+ PCI_SMCCC_ACCESS_32BIT, data);
+ if (!PCI_SMCCC_SUCCESS(status)) {
+ *data = -1;
+ return EINVAL;
+ }
+
+ return 0;
+}
+
+static int
+acpi_pci_smccc_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;
+ int status;
+
+ pci_decompose_tag(pc, tag, &b, &d, &f);
+
+ if (b < ap->ap_bus || b > ap->ap_maxbus) {
+ return EINVAL;
+ }
+
+ status = pci_smccc_write(PCI_SMCCC_SBDF(ap->ap_seg, b, d, f), reg,
+ PCI_SMCCC_ACCESS_32BIT, data);
+ if (!PCI_SMCCC_SUCCESS(status)) {
+ return EINVAL;
+ }
+
+ return 0;
+}
+
+
+void
+acpi_pci_smccc_init(struct acpi_pci_context *ap)
+{
+ int status, ver;
+ uint8_t bus_start, bus_end;
+ uint16_t next_seg;
+
+ ver = pci_smccc_version();
+ if (!PCI_SMCCC_SUCCESS(ver)) {
+ aprint_error_dev(ap->ap_dev,
+ "SMCCC: PCI_VERSION call failed, status %#x\n", ver);
+ return;
+ }
+ aprint_normal_dev(ap->ap_dev, "SMCCC: PCI impl. version %u.%u\n",
+ (ver >> 16) & 0x7fff, ver & 0xffff);
+
+ status = pci_smccc_get_seg_info(ap->ap_seg, &bus_start, &bus_end,
+ &next_seg);
+ if (!PCI_SMCCC_SUCCESS(status)) {
+ aprint_error_dev(ap->ap_dev,
+ "SMCCC: No info for segment %u, status %#x\n",
+ ap->ap_seg, status);
+ return;
+ }
+ aprint_normal_dev(ap->ap_dev, "SMCCC: segment %u, bus %u-%u\n",
+ ap->ap_seg, bus_start, bus_end);
+
+ ap->ap_bus = bus_start;
+ ap->ap_maxbus = bus_end;
+ ap->ap_conf_read = acpi_pci_smccc_conf_read;
+ ap->ap_conf_write = acpi_pci_smccc_conf_write;
+ ap->ap_flags |= ACPI_PCI_FLAG_NO_MCFG;
+ ap->ap_pciflags_clear = PCI_FLAGS_MSI_OKAY | PCI_FLAGS_MSIX_OKAY;
+}
diff -r be4df54ba479 -r 88d778778ae7 sys/arch/arm/acpi/acpipchb.c
--- a/sys/arch/arm/acpi/acpipchb.c Sat Aug 07 21:24:56 2021 +0000
+++ b/sys/arch/arm/acpi/acpipchb.c Sat Aug 07 21:27:53 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: acpipchb.c,v 1.26 2021/08/07 16:18:42 thorpej Exp $ */
+/* $NetBSD: acpipchb.c,v 1.27 2021/08/07 21:27:53 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.26 2021/08/07 16:18:42 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpipchb.c,v 1.27 2021/08/07 21:27:53 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -92,6 +92,7 @@
static int acpipchb_match(device_t, cfdata_t, void *);
static void acpipchb_attach(device_t, device_t, void *);
+static void acpipchb_configure_bus(struct acpipchb_softc *, struct pcibus_attach_args *);
static void acpipchb_setup_ranges(struct acpipchb_softc *,
struct pcibus_attach_args *);
static void acpipchb_setup_quirks(struct acpipchb_softc *,
@@ -152,13 +153,6 @@
acpi_claim_childdevs(self, aa->aa_node);
- if (acpi_pci_ignore_boot_config(sc->sc_handle)) {
- if (acpimcfg_configure_bus(self, aa->aa_pc, sc->sc_handle,
- sc->sc_bus, PCIHOST_CACHELINE_SIZE) != 0) {
- aprint_error_dev(self, "failed to configure bus\n");
- }
- }
-
memset(&pba, 0, sizeof(pba));
pba.pba_flags = aa->aa_pciflags &
~(PCI_FLAGS_MEM_OKAY | PCI_FLAGS_IO_OKAY);
@@ -174,10 +168,48 @@
acpipchb_setup_ranges(sc, &pba);
acpipchb_setup_quirks(sc, &pba);
+ acpipchb_configure_bus(sc, &pba);
+
Home |
Main Index |
Thread Index |
Old Index