Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci Add a PCI resource manager and use it on Arm ACP...



details:   https://anonhg.NetBSD.org/src/rev/bc0f73338c5c
branches:  trunk
changeset: 371844:bc0f73338c5c
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Fri Oct 14 22:10:15 2022 +0000

description:
Add a PCI resource manager and use it on Arm ACPI platforms.

The Arm ACPI code relied on PCI_NETBSD_CONFIGURE to configure devices that
were not enabled by system firmware. This is not safe to do unless the
firmware explicitly permits it using a device specific method defined in
the PCI firmware spec.

Introduce a new PCI resource manager that discovers what has already been
configured by firmware and allocates from the remaining space. This will
ensure that devices setup by firmware are untouched and only will program
BARs of devices that are not enabled at boot time.

The current implementation assumes that the parent PCI-PCI bridge's
are already configured. A worthwhile improvement in the future would be
to support programming windows for bridges that are not fully configured.

diffstat:

 sys/arch/arm/acpi/acpipchb.c       |    32 +-
 sys/arch/arm/fdt/arm_simplefb.c    |    34 +-
 sys/arch/evbarm/conf/std.generic64 |     3 +-
 sys/dev/acpi/acpi_mcfg.c           |   157 +++--
 sys/dev/acpi/acpi_mcfg.h           |     5 +-
 sys/dev/acpi/acpi_pci.c            |    69 +--
 sys/dev/acpi/acpi_pci.h            |     3 +-
 sys/dev/pci/files.pci              |     4 +-
 sys/dev/pci/pci_resource.c         |  1001 ++++++++++++++++++++++++++++++++++++
 sys/dev/pci/pci_resource.h         |    50 +
 10 files changed, 1157 insertions(+), 201 deletions(-)

diffs (truncated from 1634 to 300 lines):

diff -r 03360fc370e8 -r bc0f73338c5c sys/arch/arm/acpi/acpipchb.c
--- a/sys/arch/arm/acpi/acpipchb.c      Fri Oct 14 19:43:35 2022 +0000
+++ b/sys/arch/arm/acpi/acpipchb.c      Fri Oct 14 22:10:15 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: acpipchb.c,v 1.30 2022/08/13 20:08:36 jmcneill Exp $ */
+/* $NetBSD: acpipchb.c,v 1.31 2022/10/14 22:10:15 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.30 2022/08/13 20:08:36 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpipchb.c,v 1.31 2022/10/14 22:10:15 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -48,7 +48,7 @@
 
 #include <dev/pci/pcireg.h>
 #include <dev/pci/pcivar.h>
-#include <dev/pci/pciconf.h>
+#include <dev/pci/pci_resource.h>
 
 #include <dev/acpi/acpivar.h>
 #include <dev/acpi/acpi_pci.h>
@@ -56,8 +56,6 @@
 
 #include <arm/acpi/acpi_pci_machdep.h>
 
-#define        PCIHOST_CACHELINE_SIZE          arm_dcache_align
-
 #define        ACPIPCHB_MAX_RANGES     64      /* XXX arbitrary limit */
 
 struct acpipchb_bus_range {
@@ -194,34 +192,16 @@
        struct arm32_pci_chipset *md_pc =
            (struct arm32_pci_chipset *)pba->pba_pc;
        struct acpi_pci_context *ap = md_pc->pc_conf_v;
-       struct pciconf_resources *pcires;
-       ACPI_STATUS rv;
+       const bool mapcfgspace = (ap->ap_flags & ACPI_PCI_FLAG_NO_MCFG) == 0;
        int error, val;
 
-       if (!acpi_pci_ignore_boot_config(sc->sc_handle)) {
-               return;
-       }
        if (get_bootconf_option(boot_args, "nopciconf",
                                BOOTOPT_TYPE_BOOLEAN, &val) && val) {
                return;
        }
 
-       if ((ap->ap_flags & ACPI_PCI_FLAG_NO_MCFG) != 0) {
-               pcires = pciconf_resource_init();
-               rv = AcpiWalkResources(sc->sc_handle, "_CRS",
-                   acpimcfg_configure_bus_cb, pcires);
-               if (ACPI_FAILURE(rv)) {
-                       error = ENXIO;
-               } else {
-                       error = pci_configure_bus(pba->pba_pc, pcires, ap->ap_bus,
-                           PCIHOST_CACHELINE_SIZE);
-               }
-               pciconf_resource_fini(pcires);
-       } else {
-               error = acpimcfg_configure_bus(sc->sc_dev, pba->pba_pc, sc->sc_handle,
-                   sc->sc_bus, PCIHOST_CACHELINE_SIZE);
-       }
-
+       error = acpimcfg_configure_bus(sc->sc_dev, pba->pba_pc, sc->sc_handle,
+           sc->sc_bus, mapcfgspace);
        if (error != 0) {
                aprint_error_dev(sc->sc_dev, "failed to configure bus, error %d\n",
                    error);
diff -r 03360fc370e8 -r bc0f73338c5c sys/arch/arm/fdt/arm_simplefb.c
--- a/sys/arch/arm/fdt/arm_simplefb.c   Fri Oct 14 19:43:35 2022 +0000
+++ b/sys/arch/arm/fdt/arm_simplefb.c   Fri Oct 14 22:10:15 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: arm_simplefb.c,v 1.12 2022/07/17 20:23:17 riastradh Exp $ */
+/* $NetBSD: arm_simplefb.c,v 1.13 2022/10/14 22:10:15 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2019 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
 #include "opt_vcons.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: arm_simplefb.c,v 1.12 2022/07/17 20:23:17 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: arm_simplefb.c,v 1.13 2022/10/14 22:10:15 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -174,26 +174,6 @@
 {
 }
 
-#if NPCI > 0 && defined(PCI_NETBSD_CONFIGURE)
-static void
-arm_simplefb_reconfig(void *arg, uint64_t new_addr)
-{
-       struct arm_simplefb_softc * const sc = &arm_simplefb_softc;
-       struct rasops_info *ri = &arm_simplefb_screen.scr_ri;
-       bus_space_tag_t bst = &arm_generic_bs_tag;
-
-       bus_space_unmap(bst, arm_simplefb_bsh, arm_simplefb_size);
-       bus_space_map(bst, new_addr, arm_simplefb_size,
-           BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_PREFETCHABLE,
-           &arm_simplefb_bsh);
-
-       sc->sc_bits = bus_space_vaddr(bst, arm_simplefb_bsh);
-       ri->ri_bits = sc->sc_bits;
-
-       arm_simplefb_addr = (bus_addr_t)new_addr;
-}
-#endif
-
 uint64_t
 arm_simplefb_physaddr(void)
 {
@@ -296,14 +276,4 @@
        wsdisplay_preattach(&arm_simplefb_stdscreen, ri, 0, 0, defattr);
 
        vcons_replay_msgbuf(&arm_simplefb_screen);
-
-#if NPCI > 0 && defined(PCI_NETBSD_CONFIGURE)
-       /*
-        * Let the PCI resource allocator know about our framebuffer. This
-        * lets us know if the FB base address changes so we can remap the
-        * framebuffer if necessary.
-        */
-       pciconf_resource_reserve(PCI_CONF_MAP_MEM, addr, size,
-           arm_simplefb_reconfig, NULL);
-#endif
 }
diff -r 03360fc370e8 -r bc0f73338c5c sys/arch/evbarm/conf/std.generic64
--- a/sys/arch/evbarm/conf/std.generic64        Fri Oct 14 19:43:35 2022 +0000
+++ b/sys/arch/evbarm/conf/std.generic64        Fri Oct 14 22:10:15 2022 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: std.generic64,v 1.19 2022/06/25 13:24:35 jmcneill Exp $
+#      $NetBSD: std.generic64,v 1.20 2022/10/14 22:10:15 jmcneill Exp $
 #
 #      generic NetBSD/evbarm64 with FDT support
 
@@ -19,6 +19,7 @@
 options        MODULAR
 options        MODULAR_DEFAULT_AUTOLOAD
 options        PCI_NETBSD_CONFIGURE
+options        PCI_RESOURCE
 options        PCI_SMCCC               # Arm PCI Conf Access Firmware Interface
 options        _ARM32_NEED_BUS_DMA_BOUNCE
 options        __HAVE_GENERIC_CPU_INITCLOCKS
diff -r 03360fc370e8 -r bc0f73338c5c sys/dev/acpi/acpi_mcfg.c
--- a/sys/dev/acpi/acpi_mcfg.c  Fri Oct 14 19:43:35 2022 +0000
+++ b/sys/dev/acpi/acpi_mcfg.c  Fri Oct 14 22:10:15 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: acpi_mcfg.c,v 1.25 2022/02/27 14:19:07 riastradh Exp $ */
+/*     $NetBSD: acpi_mcfg.c,v 1.26 2022/10/14 22:10:15 jmcneill Exp $  */
 
 /*-
  * Copyright (C) 2015 NONAKA Kimihiro <nonaka%NetBSD.org@localhost>
@@ -28,7 +28,7 @@
 #include "opt_pci.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_mcfg.c,v 1.25 2022/02/27 14:19:07 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_mcfg.c,v 1.26 2022/10/14 22:10:15 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/device.h>
@@ -37,7 +37,7 @@
 
 #include <dev/pci/pcireg.h>
 #include <dev/pci/pcivar.h>
-#include <dev/pci/pciconf.h>
+#include <dev/pci/pci_resource.h>
 #include <dev/pci/pcidevs.h>
 
 #include <dev/acpi/acpireg.h>
@@ -687,16 +687,14 @@
        return error;
 }
 
-#ifdef PCI_NETBSD_CONFIGURE
+#ifdef PCI_RESOURCE
 ACPI_STATUS
 acpimcfg_configure_bus_cb(ACPI_RESOURCE *res, void *ctx)
 {
-       struct pciconf_resources *pcires = ctx;
-       int type;
+       struct pci_resource_info *pciinfo = ctx;
        bus_addr_t addr;
        bus_size_t size;
-       const char *s;
-       int error;
+       int type;
 
        if (res->Type != ACPI_RESOURCE_TYPE_ADDRESS16 &&
            res->Type != ACPI_RESOURCE_TYPE_ADDRESS32 &&
@@ -707,21 +705,25 @@
                return AE_OK;
 
        if (res->Data.Address.ResourceType != ACPI_MEMORY_RANGE &&
-           res->Data.Address.ResourceType != ACPI_IO_RANGE)
+           res->Data.Address.ResourceType != ACPI_IO_RANGE &&
+           res->Data.Address.ResourceType != ACPI_BUS_NUMBER_RANGE)
                return AE_OK;
 
        if (res->Data.Address.ResourceType == ACPI_MEMORY_RANGE &&
            res->Data.Address.Info.Mem.Caching == ACPI_PREFETCHABLE_MEMORY) {
-               type = PCICONF_RESOURCE_PREFETCHABLE_MEM;
-               s = "prefetchable";
+               type = PCI_RANGE_PMEM;
        } else if (res->Data.Address.ResourceType == ACPI_MEMORY_RANGE &&
            res->Data.Address.Info.Mem.Caching != ACPI_PREFETCHABLE_MEMORY) {
-               type = PCICONF_RESOURCE_MEM;
-               s = "non-prefetchable";
+               if (res->Type == ACPI_RESOURCE_TYPE_ADDRESS64) {
+                       type = PCI_RANGE_PMEM;
+               } else {
+                       type = PCI_RANGE_MEM;
+               }
+       } else if (res->Data.Address.ResourceType == ACPI_BUS_NUMBER_RANGE) {
+               type = PCI_RANGE_BUS;
        } else {
                KASSERT(res->Data.Address.ResourceType == ACPI_IO_RANGE);
-               type = PCICONF_RESOURCE_IO;
-               s = "i/o";
+               type = PCI_RANGE_IO;
        }
 
        switch (res->Type) {
@@ -730,7 +732,7 @@
                    "MCFG: range 0x%04" PRIx16 " size %#" PRIx16 " (16-bit %s)\n",
                    res->Data.Address16.Address.Minimum,
                    res->Data.Address16.Address.AddressLength,
-                   s);
+                   pci_resource_typename(type));
                addr = res->Data.Address16.Address.Minimum;
                size = res->Data.Address16.Address.AddressLength;
                break;
@@ -739,7 +741,7 @@
                    "MCFG: range 0x%08" PRIx32 " size %#" PRIx32 " (32-bit %s)\n",
                    res->Data.Address32.Address.Minimum,
                    res->Data.Address32.Address.AddressLength,
-                   s);
+                   pci_resource_typename(type));
                addr = res->Data.Address32.Address.Minimum;
                size = res->Data.Address32.Address.AddressLength;
                break;
@@ -748,7 +750,7 @@
                    "MCFG: range 0x%016" PRIx64 " size %#" PRIx64 " (64-bit %s)\n",
                    res->Data.Address64.Address.Minimum,
                    res->Data.Address64.Address.AddressLength,
-                   s);
+                   pci_resource_typename(type));
                addr = res->Data.Address64.Address.Minimum;
                size = res->Data.Address64.Address.AddressLength;
                break;
@@ -757,93 +759,108 @@
                return AE_OK;
        }
 
-       error = pciconf_resource_add(pcires, type, addr, size);
+       pciinfo->ranges[type].start = addr;
+       pciinfo->ranges[type].end = addr + size - 1;
 
-       return error == 0 ? AE_OK : AE_NO_MEMORY;
+       return AE_OK;
 }
 
 int
 acpimcfg_configure_bus(device_t self, pci_chipset_tag_t pc, ACPI_HANDLE handle,
-    int bus, int cacheline_size)
+    int bus, bool mapcfgspace)
 {
-       struct pciconf_resources *pcires;
+       struct pci_resource_info pciinfo;
        struct mcfg_segment *seg;
        struct mcfg_bus *mb;
        bus_space_handle_t bsh[256];
        bool bsh_mapped[256];
-       int error, boff, b, d, f;
+       int error, boff, b, d, f, endbus;
        bus_addr_t baddr;
        ACPI_STATUS rv;
 
-       seg = acpimcfg_get_segment(pc, bus);
-       if (seg == NULL)
-               return ENOENT;
-
-       pcires = pciconf_resource_init();
+       if (mapcfgspace) {
+               seg = acpimcfg_get_segment(pc, bus);
+               if (seg == NULL) {
+                       return ENOENT;
+               }
+               endbus = seg->ms_bus_end;
 
-       /*
-        * Map config space for all possible busses and mark them valid during



Home | Main Index | Thread Index | Old Index