Recent ACPI versions have deprecated "Processor()" nodes in favout of
"Device()" nodes with a _HID() method that returns "ACPI0007".  This
diff tries to support machines with firmware that implements this.  If
you see something like:

  "ACPI0007" at acpi0 not configured

please try the following diff and report back with an updated dmesg.

Cheers,

Mark



Index: dev/acpi/acpi.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpi.c,v
retrieving revision 1.384
diff -u -p -r1.384 acpi.c
--- dev/acpi/acpi.c     11 May 2020 17:57:17 -0000      1.384
+++ dev/acpi/acpi.c     13 May 2020 18:44:32 -0000
@@ -72,6 +72,7 @@ int   acpi_debug = 16;
 
 int    acpi_poll_enabled;
 int    acpi_hasprocfvs;
+int    acpi_haspci;
 
 #define ACPIEN_RETRIES 15
 
Index: dev/acpi/acpivar.h
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpivar.h,v
retrieving revision 1.108
diff -u -p -r1.108 acpivar.h
--- dev/acpi/acpivar.h  8 May 2020 11:18:01 -0000       1.108
+++ dev/acpi/acpivar.h  13 May 2020 18:44:32 -0000
@@ -43,6 +43,7 @@ extern int acpi_debug;
 #endif
 
 extern int acpi_hasprocfvs;
+extern int acpi_haspci;
 
 struct klist;
 struct acpiec_softc;
Index: arch/amd64/amd64/mainbus.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/amd64/mainbus.c,v
retrieving revision 1.49
diff -u -p -r1.49 mainbus.c
--- arch/amd64/amd64/mainbus.c  7 Sep 2019 13:46:19 -0000       1.49
+++ arch/amd64/amd64/mainbus.c  13 May 2020 18:44:32 -0000
@@ -231,6 +231,13 @@ mainbus_attach(struct device *parent, st
 #endif
 
 #if NPCI > 0
+#if NACPI > 0
+       if (acpi_haspci) {
+               extern void acpipci_attach_busses(struct device *);
+
+               acpipci_attach_busses(self);
+       } else
+#endif
        {
                pci_init_extents();
 
@@ -245,9 +252,6 @@ mainbus_attach(struct device *parent, st
                mba.mba_pba.pba_domain = pci_ndomains++;
                mba.mba_pba.pba_bus = 0;
                config_found(self, &mba.mba_pba, mainbus_print);
-#if NACPI > 0
-               acpi_pciroots_attach(self, &mba.mba_pba, mainbus_print);
-#endif
        }
 #endif
 
Index: arch/amd64/conf/RAMDISK
===================================================================
RCS file: /cvs/src/sys/arch/amd64/conf/RAMDISK,v
retrieving revision 1.77
diff -u -p -r1.77 RAMDISK
--- arch/amd64/conf/RAMDISK     5 Mar 2020 16:36:30 -0000       1.77
+++ arch/amd64/conf/RAMDISK     13 May 2020 18:44:32 -0000
@@ -30,6 +30,7 @@ acpi0         at bios?
 #acpicpu*      at acpi?
 acpicmos*      at acpi?
 acpiec*                at acpi?
+acpipci*       at acpi?
 acpiprt*       at acpi?
 acpimadt0      at acpi?
 #acpitz*       at acpi?
Index: arch/amd64/conf/RAMDISK_CD
===================================================================
RCS file: /cvs/src/sys/arch/amd64/conf/RAMDISK_CD,v
retrieving revision 1.188
diff -u -p -r1.188 RAMDISK_CD
--- arch/amd64/conf/RAMDISK_CD  15 Feb 2020 08:49:11 -0000      1.188
+++ arch/amd64/conf/RAMDISK_CD  13 May 2020 18:44:32 -0000
@@ -37,6 +37,7 @@ acpi0         at bios?
 #acpicpu*      at acpi?
 acpicmos*      at acpi?
 acpiec*                at acpi?
+acpipci*       at acpi?
 acpiprt*       at acpi?
 acpimadt0      at acpi?
 #acpitz*       at acpi?
Index: arch/amd64/pci/acpipci.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/pci/acpipci.c,v
retrieving revision 1.3
diff -u -p -r1.3 acpipci.c
--- arch/amd64/pci/acpipci.c    7 Sep 2019 13:46:19 -0000       1.3
+++ arch/amd64/pci/acpipci.c    13 May 2020 18:44:32 -0000
@@ -53,6 +53,19 @@ struct acpipci_softc {
        struct device   sc_dev;
        struct acpi_softc *sc_acpi;
        struct aml_node *sc_node;
+
+       bus_space_tag_t sc_iot;
+       bus_space_tag_t sc_memt;
+       bus_dma_tag_t   sc_dmat;
+
+       struct extent   *sc_busex;
+       struct extent   *sc_memex;
+       struct extent   *sc_ioex;
+       char            sc_busex_name[32];
+       char            sc_ioex_name[32];
+       char            sc_memex_name[32];
+       int             sc_bus;
+       uint32_t        sc_seg;
 };
 
 int    acpipci_match(struct device *, void *, void *);
@@ -72,6 +85,11 @@ const char *acpipci_hids[] = {
        NULL
 };
 
+void   acpipci_attach_deferred(struct device *);
+int    acpipci_print(void *, const char *);
+int    acpipci_parse_resources(int, union acpi_resource *, void *);
+void   acpipci_osc(struct acpipci_softc *);
+
 int
 acpipci_match(struct device *parent, void *match, void *aux)
 {
@@ -86,15 +104,225 @@ acpipci_attach(struct device *parent, st
 {
        struct acpi_attach_args *aaa = aux;
        struct acpipci_softc *sc = (struct acpipci_softc *)self;
-       struct aml_value args[4];
        struct aml_value res;
-       static uint8_t uuid[16] = ACPI_PCI_UUID;
-       uint32_t buf[3];
+       uint64_t bbn = 0;
+       uint64_t seg = 0;
+
+       acpi_haspci = 1;
+
+       sc->sc_iot = aaa->aaa_iot;
+       sc->sc_memt = aaa->aaa_memt;
+       sc->sc_dmat = aaa->aaa_dmat;
 
        sc->sc_acpi = (struct acpi_softc *)parent;
        sc->sc_node = aaa->aaa_node;
        printf(" %s", sc->sc_node->name);
 
+       acpipci_osc(sc);
+
+       aml_evalinteger(sc->sc_acpi, sc->sc_node, "_BBN", 0, NULL, &bbn);
+       sc->sc_bus = bbn;
+
+       aml_evalinteger(sc->sc_acpi, sc->sc_node, "_SEG", 0, NULL, &seg);
+       sc->sc_seg = seg;
+
+       if (aml_evalname(sc->sc_acpi, sc->sc_node, "_CRS", 0, NULL, &res)) {
+               printf(": can't find resources\n");
+
+               pci_init_extents();
+               sc->sc_busex = pcibus_ex;
+               sc->sc_ioex = pciio_ex;
+               sc->sc_memex = pcimem_ex;
+
+               return;
+       }
+
+       /* Create extents for our address spaces. */
+       snprintf(sc->sc_busex_name, sizeof(sc->sc_busex_name),
+           "%s pcibus", sc->sc_dev.dv_xname);
+       snprintf(sc->sc_ioex_name, sizeof(sc->sc_ioex_name),
+           "%s pciio", sc->sc_dev.dv_xname);
+       snprintf(sc->sc_memex_name, sizeof(sc->sc_memex_name),
+           "%s pcimem", sc->sc_dev.dv_xname);
+       sc->sc_busex = extent_create(sc->sc_busex_name, 0, 255,
+           M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED);
+       sc->sc_ioex = extent_create(sc->sc_ioex_name, 0, 0xffffffff,
+           M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED);
+       sc->sc_memex = extent_create(sc->sc_memex_name, 0, (u_long)-1,
+           M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED);
+
+       aml_parse_resource(&res, acpipci_parse_resources, sc);
+
+       if (sc->sc_acpi->sc_major < 5) {
+               extent_destroy(sc->sc_ioex);
+               extent_destroy(sc->sc_memex);
+
+               pci_init_extents();
+               sc->sc_ioex =  pciio_ex;
+               sc->sc_memex = pcimem_ex;
+       }
+
+       printf("\n");
+
+#ifdef DIAGNOSTIC
+       extent_print(sc->sc_busex);
+       extent_print(sc->sc_ioex);
+       extent_print(sc->sc_memex);
+#endif
+}
+
+void
+acpipci_attach_bus(struct device *parent, struct acpipci_softc *sc)
+{
+       struct pcibus_attach_args pba;
+       pcitag_t tag;
+       pcireg_t id, class;
+
+       memset(&pba, 0, sizeof(pba));
+       pba.pba_busname = "pci";
+       pba.pba_iot = sc->sc_iot;
+       pba.pba_memt = sc->sc_memt;
+       pba.pba_dmat = sc->sc_dmat;
+       pba.pba_busex = sc->sc_busex;
+       pba.pba_ioex = sc->sc_ioex;
+       pba.pba_memex = sc->sc_memex;
+       pba.pba_pmemex = sc->sc_memex;
+       pba.pba_domain = pci_ndomains++;
+       pba.pba_bus = sc->sc_bus;
+
+       /* Enable MSI in ACPI 2.0 and above, unless we're told not to. */
+       if (sc->sc_acpi->sc_fadt->hdr.revision >= 2 &&
+           (sc->sc_acpi->sc_fadt->iapc_boot_arch & FADT_NO_MSI) == 0)
+               pba.pba_flags |= PCI_FLAGS_MSI_ENABLED;
+
+       /*
+        * Don't enable MSI on chipsets from low-end manifacturers
+        * like VIA and SiS.  We do this by looking at the host
+        * bridge, which should be device 0 function 0.
+        */
+       tag = pci_make_tag(pba.pba_pc, sc->sc_bus, 0, 0);
+       id = pci_conf_read(pba.pba_pc, tag, PCI_ID_REG);
+       class = pci_conf_read(pba.pba_pc, tag, PCI_CLASS_REG);
+       if (PCI_CLASS(class) == PCI_CLASS_BRIDGE &&
+           PCI_SUBCLASS(class) != PCI_SUBCLASS_BRIDGE_HOST &&
+           PCI_VENDOR(id) != PCI_VENDOR_AMD &&
+           PCI_VENDOR(id) != PCI_VENDOR_NVIDIA &&
+           PCI_VENDOR(id) != PCI_VENDOR_INTEL)
+               pba.pba_flags &= ~PCI_FLAGS_MSI_ENABLED;
+
+       /*
+        * Don't enable MSI on a HyperTransport bus.  In order to
+        * determine that a bus is a HyperTransport bus, we look at
+        * device 24 function 0, which is the HyperTransport
+        * host/primary interface integrated on most 64-bit AMD CPUs.
+        * If that device has a HyperTransport capability, this must
+        * be a HyperTransport bus and we disable MSI.
+        */
+       tag = pci_make_tag(pba.pba_pc, sc->sc_bus, 24, 0);
+       if (pci_get_capability(pba.pba_pc, tag, PCI_CAP_HT, NULL, NULL))
+               pba.pba_flags &= ~PCI_FLAGS_MSI_ENABLED;
+
+       config_found(parent, &pba, acpipci_print);
+}
+
+void
+acpipci_attach_busses(struct device *parent)
+{
+       int i;
+
+       for (i = 0; i < acpipci_cd.cd_ndevs; i++) {
+               if (acpipci_cd.cd_devs[i])
+                       acpipci_attach_bus(parent, acpipci_cd.cd_devs[i]);
+       }
+}
+
+int
+acpipci_print(void *aux, const char *pnp)
+{
+       struct pcibus_attach_args *pba = aux;
+
+       if (pnp)
+               printf("%s at %s", pba->pba_busname, pnp);
+       printf(" bus %d", pba->pba_bus);
+       return (UNCONF);
+}
+
+int
+acpipci_parse_resources(int crsidx, union acpi_resource *crs, void *arg)
+{
+       struct acpipci_softc *sc = arg;
+       int type = AML_CRSTYPE(crs);
+       int restype, tflags = 0;
+       u_long min, len = 0, tra = 0;
+
+       switch (type) {
+       case LR_WORD:
+               restype = crs->lr_word.type;
+               tflags = crs->lr_word.tflags;
+               min = crs->lr_word._min;
+               len = crs->lr_word._len;
+               tra = crs->lr_word._tra;
+               break;
+       case LR_DWORD:
+               restype = crs->lr_dword.type;
+               tflags = crs->lr_dword.tflags;
+               min = crs->lr_dword._min;
+               len = crs->lr_dword._len;
+               tra = crs->lr_dword._tra;
+               break;
+       case LR_QWORD:
+               restype = crs->lr_qword.type;
+               tflags = crs->lr_qword.tflags;
+               min = crs->lr_qword._min;
+               len = crs->lr_qword._len;
+               tra = crs->lr_qword._tra;
+               break;
+       case LR_MEM32FIXED:
+               /*
+                * Coreboot on the PC Engines apu2 incorrectly uses a
+                * Memory32Fixed resource descriptor to describe mmio
+                * address space forwarded to the PCI bus.
+                */
+               restype = LR_TYPE_MEMORY;
+               min = crs->lr_m32fixed._bas;
+               len = crs->lr_m32fixed._len;
+               break;
+       }
+
+       if (len == 0)
+               return 0;
+
+       switch (restype) {
+       case LR_TYPE_MEMORY:
+               if (tflags & LR_MEMORY_TTP)
+                       return 0;
+               extent_free(sc->sc_memex, min, len, EX_WAITOK | EX_CONFLICTOK);
+               break;
+       case LR_TYPE_IO:
+               if (tflags & LR_IO_TTP)
+                       return 0;
+               extent_free(sc->sc_ioex, min, len, EX_WAITOK | EX_CONFLICTOK);
+               break;
+       case LR_TYPE_BUS:
+               extent_free(sc->sc_busex, min, len, EX_WAITOK);
+               /*
+                * Let _CRS minimum bus number override _BBN.
+                */
+               sc->sc_bus = min;
+               break;
+       }
+
+       return 0;
+}
+
+void
+acpipci_osc(struct acpipci_softc *sc)
+{
+       struct aml_value args[4];
+       struct aml_value res;
+       static uint8_t uuid[16] = ACPI_PCI_UUID;
+       uint32_t buf[3];
+       
        memset(args, 0, sizeof(args));
        args[0].type = AML_OBJTYPE_BUFFER;
        args[0].v_buffer = uuid;
@@ -112,10 +340,8 @@ acpipci_attach(struct device *parent, st
        buf[1] = ACPI_PCI_PCIE_CONFIG | ACPI_PCI_MSI;
        buf[2] = ACPI_PCI_PCIE_HOTPLUG;
 
-       if (aml_evalname(sc->sc_acpi, sc->sc_node, "_OSC", 4, args, &res)) {
-               printf(": _OSC failed\n");
+       if (aml_evalname(sc->sc_acpi, sc->sc_node, "_OSC", 4, args, &res))
                return;
-       }
 
        if (res.type == AML_OBJTYPE_BUFFER) {
                size_t len = res.length;
@@ -128,6 +354,4 @@ acpipci_attach(struct device *parent, st
                        len -= 4;
                }
        }
-
-       printf("\n");
 }
Index: arch/amd64/pci/pci_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/pci/pci_machdep.c,v
retrieving revision 1.73
diff -u -p -r1.73 pci_machdep.c
--- arch/amd64/pci/pci_machdep.c        7 Sep 2019 13:46:19 -0000       1.73
+++ arch/amd64/pci/pci_machdep.c        13 May 2020 18:44:32 -0000
@@ -163,64 +163,6 @@ void
 pci_attach_hook(struct device *parent, struct device *self,
     struct pcibus_attach_args *pba)
 {
-       pci_chipset_tag_t pc = pba->pba_pc;
-       pcitag_t tag;
-       pcireg_t id, class;
-
-       if (pba->pba_bus != 0)
-               return;
-
-       /*
-        * In order to decide whether the system supports MSI we look
-        * at the host bridge, which should be device 0 function 0 on
-        * bus 0.  It is better to not enable MSI on systems that
-        * support it than the other way around, so be conservative
-        * here.  So we don't enable MSI if we don't find a host
-        * bridge there.  We also deliberately don't enable MSI on
-        * chipsets from low-end manifacturers like VIA and SiS.
-        */
-       tag = pci_make_tag(pc, 0, 0, 0);
-       id = pci_conf_read(pc, tag, PCI_ID_REG);
-       class = pci_conf_read(pc, tag, PCI_CLASS_REG);
-
-       if (PCI_CLASS(class) != PCI_CLASS_BRIDGE ||
-           PCI_SUBCLASS(class) != PCI_SUBCLASS_BRIDGE_HOST)
-               return;
-
-       switch (PCI_VENDOR(id)) {
-       case PCI_VENDOR_INTEL:
-               /*
-                * In the wonderful world of virtualization you can
-                * have the latest 64-bit AMD multicore CPU behind a
-                * prehistoric Intel host bridge.  Give them what they
-                * deserve.
-                */
-               switch (PCI_PRODUCT(id)) {
-               case PCI_PRODUCT_INTEL_82441FX: /* QEMU */
-               case PCI_PRODUCT_INTEL_82443BX: /* VMWare */
-                       break;
-               default:
-                       pba->pba_flags |= PCI_FLAGS_MSI_ENABLED;
-                       break;
-               }
-               break;
-       case PCI_VENDOR_NVIDIA:
-       case PCI_VENDOR_AMD:
-               pba->pba_flags |= PCI_FLAGS_MSI_ENABLED;
-               break;
-       }
-
-       /*
-        * Don't enable MSI on a HyperTransport bus.  In order to
-        * determine that bus 0 is a HyperTransport bus, we look at
-        * device 24 function 0, which is the HyperTransport
-        * host/primary interface integrated on most 64-bit AMD CPUs.
-        * If that device has a HyperTransport capability, bus 0 must
-        * be a HyperTransport bus and we disable MSI.
-        */
-       tag = pci_make_tag(pc, 0, 24, 0);
-       if (pci_get_capability(pc, tag, PCI_CAP_HT, NULL, NULL))
-               pba->pba_flags &= ~PCI_FLAGS_MSI_ENABLED;
 }
 
 int

Reply via email to