Add support for multiple PCI segments. Only really implemented for arm64
authorkettenis <kettenis@openbsd.org>
Sun, 19 Aug 2018 08:23:47 +0000 (08:23 +0000)
committerkettenis <kettenis@openbsd.org>
Sun, 19 Aug 2018 08:23:47 +0000 (08:23 +0000)
for now as amd64/i386 firmware still caters for legacy OSes that only
support a single PCI segment.

ok patrick@

14 files changed:
sys/arch/amd64/amd64/acpi_machdep.c
sys/arch/amd64/include/pci_machdep.h
sys/arch/amd64/pci/pci_machdep.c
sys/arch/arm64/dev/acpipci.c
sys/arch/arm64/include/pci_machdep.h
sys/arch/i386/i386/acpi_machdep.c
sys/arch/i386/pci/pci_machdep.c
sys/arch/i386/pci/pci_machdep.h
sys/dev/acpi/acpi.c
sys/dev/acpi/acpimcfg.c
sys/dev/acpi/acpireg.h
sys/dev/acpi/acpivar.h
sys/dev/acpi/dsdt.c
sys/dev/acpi/dsdt.h

index 9c820b7..f136f07 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: acpi_machdep.c,v 1.84 2018/07/04 20:46:21 kettenis Exp $      */
+/*     $OpenBSD: acpi_machdep.c,v 1.85 2018/08/19 08:23:47 kettenis Exp $      */
 /*
  * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
  *
@@ -97,7 +97,6 @@ acpi_attach(struct device *parent, struct device *self, void *aux)
        sc->sc_iot = ba->ba_iot;
        sc->sc_memt = ba->ba_memt;
        sc->sc_dmat = &pci_bus_dma_tag;
-       sc->sc_pc = NULL;       /* Legacy 0xcf8/0xcfc access mechanism */
 
        acpi_attach_common(sc, ba->ba_acpipbase);
 }
index a919dfd..8a456f7 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: pci_machdep.h,v 1.26 2018/07/04 20:46:22 kettenis Exp $       */
+/*     $OpenBSD: pci_machdep.h,v 1.27 2018/08/19 08:23:47 kettenis Exp $       */
 /*     $NetBSD: pci_machdep.h,v 1.1 2003/02/26 21:26:11 fvdl Exp $     */
 
 /*
@@ -95,7 +95,8 @@ void          pci_dev_postattach(struct device *, struct pci_attach_args *);
 pcireg_t       pci_min_powerstate(pci_chipset_tag_t, pcitag_t);
 void           pci_set_powerstate_md(pci_chipset_tag_t, pcitag_t, int, int);
 
-pci_chipset_tag_t pci_mcfg_init(bus_space_tag_t, bus_addr_t, int, int);
+void           pci_mcfg_init(bus_space_tag_t, bus_addr_t, int, int, int);
+pci_chipset_tag_t pci_lookup_segment(int);
 
 /*
  * ALL OF THE FOLLOWING ARE MACHINE-DEPENDENT, AND SHOULD NOT BE USED
index 5e05c75..4e58376 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: pci_machdep.c,v 1.68 2018/07/04 20:46:22 kettenis Exp $       */
+/*     $OpenBSD: pci_machdep.c,v 1.69 2018/08/19 08:23:47 kettenis Exp $       */
 /*     $NetBSD: pci_machdep.c,v 1.3 2003/05/07 21:33:58 fvdl Exp $     */
 
 /*-
@@ -140,14 +140,22 @@ struct bus_dma_tag pci_bus_dma_tag = {
        _bus_dmamem_mmap,
 };
 
-pci_chipset_tag_t
-pci_mcfg_init(bus_space_tag_t iot, bus_addr_t addr, int min_bus, int max_bus)
+void
+pci_mcfg_init(bus_space_tag_t iot, bus_addr_t addr, int segment,
+    int min_bus, int max_bus)
 {
-       pci_mcfgt = iot;
-       pci_mcfg_addr = addr;
-       pci_mcfg_min_bus = min_bus;
-       pci_mcfg_max_bus = max_bus;
+       if (segment == 0) {
+               pci_mcfgt = iot;
+               pci_mcfg_addr = addr;
+               pci_mcfg_min_bus = min_bus;
+               pci_mcfg_max_bus = max_bus;
+       }
+}
 
+pci_chipset_tag_t
+pci_lookup_segment(int segment)
+{
+       KASSERT(segment == 0);
        return NULL;
 }
 
index 5b067a2..85d0b4a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: acpipci.c,v 1.6 2018/08/11 22:47:27 kettenis Exp $    */
+/*     $OpenBSD: acpipci.c,v 1.7 2018/08/19 08:23:47 kettenis Exp $    */
 /*
  * Copyright (c) 2018 Mark Kettenis
  *
 #include <dev/pci/pcivar.h>
 #include <dev/pci/ppbreg.h>
 
-bus_addr_t pci_mcfg_addr;
-int pci_mcfg_min_bus, pci_mcfg_max_bus;
-bus_space_tag_t pci_mcfgt;
-bus_space_handle_t pci_mcfgh;
+struct acpipci_mcfg {
+       SLIST_ENTRY(acpipci_mcfg) am_list;
+
+       uint16_t        am_segment;
+       uint8_t         am_min_bus;
+       uint8_t         am_max_bus;
+
+       bus_space_tag_t am_iot;
+       bus_space_handle_t am_ioh;
+
+       struct arm64_pci_chipset am_pc;
+};
 
 struct acpipci_trans {
        struct acpipci_trans *at_next;
@@ -51,16 +59,14 @@ 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_handle_t sc_ioh;
+       pci_chipset_tag_t sc_pc;
 
        struct bus_space sc_bus_iot;
        struct bus_space sc_bus_memt;
        struct acpipci_trans *sc_io_trans;
        struct acpipci_trans *sc_mem_trans;
 
-       struct arm64_pci_chipset sc_pc;
        struct extent   *sc_busex;
        struct extent   *sc_memex;
        struct extent   *sc_ioex;
@@ -130,12 +136,6 @@ acpipci_attach(struct device *parent, struct device *self, void *aux)
        uint64_t bbn = 0;
        uint64_t seg = 0;
 
-       /* Bail out early if we don't have a valid MCFG table. */
-       if (pci_mcfg_addr == 0 || pci_mcfg_max_bus <= pci_mcfg_min_bus) {
-               printf(": no registers\n");
-               return;
-       }
-
        sc->sc_acpi = (struct acpi_softc *)parent;
        sc->sc_node = aaa->aaa_node;
        printf(" %s", sc->sc_node->name);
@@ -151,15 +151,10 @@ acpipci_attach(struct device *parent, struct device *self, void *aux)
        aml_evalinteger(sc->sc_acpi, sc->sc_node, "_SEG", 0, NULL, &seg);
        sc->sc_seg = seg;
 
-       sc->sc_iot = pci_mcfgt;
-       sc->sc_ioh = pci_mcfgh;
-
+       sc->sc_iot = aaa->aaa_memt;
+       
        printf("\n");
 
-       /* XXX We only support segment 0 for now. */
-       if (seg != 0)
-               return;
-
        /* Create extents for our address spaces. */
        snprintf(sc->sc_busex_name, sizeof(sc->sc_busex_name),
            "%s pcibus", sc->sc_dev.dv_xname);
@@ -183,29 +178,23 @@ acpipci_attach(struct device *parent, struct device *self, void *aux)
        sc->sc_bus_memt.bus_private = sc->sc_mem_trans;
        sc->sc_bus_memt._space_map = acpipci_bs_map;
 
-       sc->sc_pc.pc_conf_v = sc;
-       sc->sc_pc.pc_attach_hook = acpipci_attach_hook;
-       sc->sc_pc.pc_bus_maxdevs = acpipci_bus_maxdevs;
-       sc->sc_pc.pc_make_tag = acpipci_make_tag;
-       sc->sc_pc.pc_decompose_tag = acpipci_decompose_tag;
-       sc->sc_pc.pc_conf_size = acpipci_conf_size;
-       sc->sc_pc.pc_conf_read = acpipci_conf_read;
-       sc->sc_pc.pc_conf_write = acpipci_conf_write;
-
-       sc->sc_pc.pc_intr_v = sc;
-       sc->sc_pc.pc_intr_map = acpipci_intr_map;
-       sc->sc_pc.pc_intr_map_msi = acpipci_intr_map_msi;
-       sc->sc_pc.pc_intr_map_msix = acpipci_intr_map_msix;
-       sc->sc_pc.pc_intr_string = acpipci_intr_string;
-       sc->sc_pc.pc_intr_establish = acpipci_intr_establish;
-       sc->sc_pc.pc_intr_disestablish = acpipci_intr_disestablish;
+       sc->sc_pc = pci_lookup_segment(seg);
+       KASSERT(sc->sc_pc->pc_intr_v == NULL);
+
+       sc->sc_pc->pc_intr_v = sc;
+       sc->sc_pc->pc_intr_map = acpipci_intr_map;
+       sc->sc_pc->pc_intr_map_msi = acpipci_intr_map_msi;
+       sc->sc_pc->pc_intr_map_msix = acpipci_intr_map_msix;
+       sc->sc_pc->pc_intr_string = acpipci_intr_string;
+       sc->sc_pc->pc_intr_establish = acpipci_intr_establish;
+       sc->sc_pc->pc_intr_disestablish = acpipci_intr_disestablish;
 
        memset(&pba, 0, sizeof(pba));
        pba.pba_busname = "pci";
        pba.pba_iot = &sc->sc_bus_iot;
        pba.pba_memt = &sc->sc_bus_memt;
        pba.pba_dmat = aaa->aaa_dmat;
-       pba.pba_pc = &sc->sc_pc;
+       pba.pba_pc = sc->sc_pc;
        pba.pba_busex = sc->sc_busex;
        pba.pba_ioex = sc->sc_ioex;
        pba.pba_memex = sc->sc_memex;
@@ -323,17 +312,25 @@ acpipci_conf_size(void *v, pcitag_t tag)
 pcireg_t
 acpipci_conf_read(void *v, pcitag_t tag, int reg)
 {
-       struct acpipci_softc *sc = v;
+       struct acpipci_mcfg *am = v;
+
+       if (tag < (am->am_min_bus << 20) ||
+           tag >= ((am->am_max_bus + 1) << 20))
+               return 0xffffffff;
 
-       return bus_space_read_4(sc->sc_iot, sc->sc_ioh, tag | reg);
+       return bus_space_read_4(am->am_iot, am->am_ioh, tag | reg);
 }
 
 void
 acpipci_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
 {
-       struct acpipci_softc *sc = v;
+       struct acpipci_mcfg *am = v;
+
+       if (tag < (am->am_min_bus << 20) ||
+           tag >= ((am->am_max_bus + 1) << 20))
+               return;
 
-       bus_space_write_4(sc->sc_iot, sc->sc_ioh, tag | reg, data);
+       bus_space_write_4(am->am_iot, am->am_ioh, tag | reg, data);
 }
 
 struct acpipci_intr_handle {
@@ -553,43 +550,67 @@ acpipci_bs_map(bus_space_tag_t t, bus_addr_t addr, bus_size_t size,
        return ENXIO;
 }
 
-struct arm64_pci_chipset pci_mcfg_chipset;
+SLIST_HEAD(,acpipci_mcfg) acpipci_mcfgs =
+    SLIST_HEAD_INITIALIZER(acpipci_mcfgs);
+
+void
+pci_mcfg_init(bus_space_tag_t iot, bus_addr_t addr, int segment,
+    int min_bus, int max_bus)
+{
+       struct acpipci_mcfg *am;
+
+       am = malloc(sizeof(struct acpipci_mcfg), M_DEVBUF, M_WAITOK | M_ZERO);
+       am->am_segment = segment;
+       am->am_min_bus = min_bus;
+       am->am_max_bus = max_bus;
+
+       am->am_iot = iot;
+       if (bus_space_map(iot, addr, (max_bus + 1) << 20, 0, &am->am_ioh))
+               panic("%s: can't map config space", __func__);
+
+       am->am_pc.pc_conf_v = am;
+       am->am_pc.pc_attach_hook = acpipci_attach_hook;
+       am->am_pc.pc_bus_maxdevs = acpipci_bus_maxdevs;
+       am->am_pc.pc_make_tag = acpipci_make_tag;
+       am->am_pc.pc_decompose_tag = acpipci_decompose_tag;
+       am->am_pc.pc_conf_size = acpipci_conf_size;
+       am->am_pc.pc_conf_read = acpipci_conf_read;
+       am->am_pc.pc_conf_write = acpipci_conf_write;
+       SLIST_INSERT_HEAD(&acpipci_mcfgs, am, am_list);
+}
 
 pcireg_t
-pci_mcfg_conf_read(void *v, pcitag_t tag, int reg)
+acpipci_dummy_conf_read(void *v, pcitag_t tag, int reg)
 {
-       return bus_space_read_4(pci_mcfgt, pci_mcfgh, tag | reg);
+       return 0xffffffff;
 }
 
 void
-pci_mcfg_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
+acpipci_dummy_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
 {
-       bus_space_write_4(pci_mcfgt, pci_mcfgh, tag | reg, data);
 }
 
+struct arm64_pci_chipset acpipci_dummy_chipset = {
+       .pc_attach_hook = acpipci_attach_hook,
+       .pc_bus_maxdevs = acpipci_bus_maxdevs,
+       .pc_make_tag = acpipci_make_tag,
+       .pc_decompose_tag = acpipci_decompose_tag,
+       .pc_conf_size = acpipci_conf_size,
+       .pc_conf_read = acpipci_dummy_conf_read,
+       .pc_conf_write = acpipci_dummy_conf_write,
+};
+
 pci_chipset_tag_t
-pci_mcfg_init(bus_space_tag_t iot, bus_addr_t addr, int min_bus, int max_bus)
+pci_lookup_segment(int segment)
 {
-       pci_chipset_tag_t pc = &pci_mcfg_chipset;
-
-       pci_mcfgt = iot;
-       pci_mcfg_addr = addr;
-       pci_mcfg_min_bus = min_bus;
-       pci_mcfg_max_bus = max_bus;
+       struct acpipci_mcfg *am;
 
-       if (bus_space_map(iot, addr, (pci_mcfg_max_bus + 1) << 20, 0,
-           &pci_mcfgh))
-               panic("%s: can't map config space", __func__);
-
-       memset(pc, 0, sizeof(*pc));
-       pc->pc_bus_maxdevs = acpipci_bus_maxdevs;
-       pc->pc_make_tag = acpipci_make_tag;
-       pc->pc_decompose_tag = acpipci_decompose_tag;
-       pc->pc_conf_size = acpipci_conf_size;
-       pc->pc_conf_read = pci_mcfg_conf_read;
-       pc->pc_conf_write = pci_mcfg_conf_write;
+       SLIST_FOREACH(am, &acpipci_mcfgs, am_list) {
+               if (am->am_segment == segment)
+                       return &am->am_pc;
+       }
 
-       return pc;
+       return &acpipci_dummy_chipset;
 }
 
 /*
index 32e742d..64739c2 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: pci_machdep.h,v 1.2 2018/07/05 19:25:38 kettenis Exp $ */
+/*     $OpenBSD: pci_machdep.h,v 1.3 2018/08/19 08:23:47 kettenis Exp $ */
 
 /*
  * Copyright (c) 2003-2004 Opsycon AB  (www.opsycon.se / www.opsycon.com)
@@ -97,4 +97,5 @@ struct arm64_pci_chipset {
 
 #define        pci_dev_postattach(a, b)
 
-pci_chipset_tag_t pci_mcfg_init(bus_space_tag_t, bus_addr_t, int, int);
+void    pci_mcfg_init(bus_space_tag_t, bus_addr_t, int, int, int);
+pci_chipset_tag_t pci_lookup_segment(int);
index 51c67d9..163f463 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: acpi_machdep.c,v 1.68 2018/07/04 20:46:22 kettenis Exp $      */
+/*     $OpenBSD: acpi_machdep.c,v 1.69 2018/08/19 08:23:47 kettenis Exp $      */
 /*
  * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
  *
@@ -107,7 +107,6 @@ acpi_attach(struct device *parent, struct device *self, void *aux)
        sc->sc_iot = ba->ba_iot;
        sc->sc_memt = ba->ba_memt;
        sc->sc_dmat = &pci_bus_dma_tag;
-       sc->sc_pc = NULL;       /* Legacy 0xcf8/0xcfc access mechanism */
 
        acpi_attach_common(sc, ba->ba_acpipbase);
 }
index 5973a61..b712ff2 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: pci_machdep.c,v 1.83 2018/07/04 20:46:22 kettenis Exp $       */
+/*     $OpenBSD: pci_machdep.c,v 1.84 2018/08/19 08:23:47 kettenis Exp $       */
 /*     $NetBSD: pci_machdep.c,v 1.28 1997/06/06 23:29:17 thorpej Exp $ */
 
 /*-
@@ -191,14 +191,22 @@ struct bus_dma_tag pci_bus_dma_tag = {
        _bus_dmamem_mmap,
 };
 
-pci_chipset_tag_t
-pci_mcfg_init(bus_space_tag_t iot, bus_addr_t addr, int min_bus, int max_bus)
+void
+pci_mcfg_init(bus_space_tag_t iot, bus_addr_t addr, int segment,
+    int min_bus, int max_bus)
 {
-       pci_mcfgt = iot;
-       pci_mcfg_addr = addr;
-       pci_mcfg_min_bus = min_bus;
-       pci_mcfg_max_bus = max_bus;
+       if (segment == 0) {
+               pci_mcfgt = iot;
+               pci_mcfg_addr = addr;
+               pci_mcfg_min_bus = min_bus;
+               pci_mcfg_max_bus = max_bus;
+       }
+}
 
+pci_chipset_tag_t
+pci_lookup_segment(int segment)
+{
+       KASSERT(segment == 0);
        return NULL;
 }
 
index 682909e..8cf0164 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: pci_machdep.h,v 1.29 2018/07/04 20:46:22 kettenis Exp $       */
+/*     $OpenBSD: pci_machdep.h,v 1.30 2018/08/19 08:23:47 kettenis Exp $       */
 /*     $NetBSD: pci_machdep.h,v 1.7 1997/06/06 23:29:18 thorpej Exp $  */
 
 /*
@@ -111,7 +111,8 @@ void                pci_dev_postattach(struct device *, struct pci_attach_args *);
 pcireg_t       pci_min_powerstate(pci_chipset_tag_t, pcitag_t);
 void           pci_set_powerstate_md(pci_chipset_tag_t, pcitag_t, int, int);
 
-pci_chipset_tag_t pci_mcfg_init(bus_space_tag_t, bus_addr_t, int, int);
+void           pci_mcfg_init(bus_space_tag_t, bus_addr_t, int, int, int);
+pci_chipset_tag_t pci_lookup_segment(int);
 
 /*
  * Section 6.2.4, `Miscellaneous Functions' of the PIC Specification,
index ccc7bef..ad0bab6 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpi.c,v 1.356 2018/08/03 22:18:13 kettenis Exp $ */
+/* $OpenBSD: acpi.c,v 1.357 2018/08/19 08:23:47 kettenis Exp $ */
 /*
  * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
  * Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
@@ -328,13 +328,6 @@ acpi_gasio(struct acpi_softc *sc, int iodir, int iospace, uint64_t address,
                break;
 
        case GAS_PCI_CFG_SPACE:
-               /* format of address:
-                *    bits 00..15 = register
-                *    bits 16..31 = function
-                *    bits 32..47 = device
-                *    bits 48..63 = bus
-                */
-
                /*
                 * The ACPI standard says that a function number of
                 * FFFF can be used to refer to all functions on a
@@ -349,7 +342,7 @@ acpi_gasio(struct acpi_softc *sc, int iodir, int iospace, uint64_t address,
                        return (0);
                }
 
-               pc = sc->sc_pc;
+               pc = pci_lookup_segment(ACPI_PCI_SEG(address));
                tag = pci_make_tag(pc,
                    ACPI_PCI_BUS(address), ACPI_PCI_DEV(address),
                    ACPI_PCI_FN(address));
@@ -564,7 +557,7 @@ acpi_getpci(struct aml_node *node, void *arg)
        struct acpi_pci *pci, *ppci;
        struct aml_value res;
        struct acpi_softc *sc = arg;
-       pci_chipset_tag_t pc = sc->sc_pc;
+       pci_chipset_tag_t pc;
        pcitag_t tag;
        uint64_t val;
        uint32_t reg;
@@ -610,6 +603,7 @@ acpi_getpci(struct aml_node *node, void *arg)
                return 0;
 
        pci = malloc(sizeof(*pci), M_DEVBUF, M_WAITOK|M_ZERO);
+       pci->seg = ppci->seg;
        pci->bus = ppci->sub;
        pci->dev = ACPI_ADR_PCIDEV(val);
        pci->fun = ACPI_ADR_PCIFUN(val);
@@ -643,6 +637,7 @@ acpi_getpci(struct aml_node *node, void *arg)
                free(pci, M_DEVBUF, sizeof(*pci));
                return (1);
        }
+       pc = pci_lookup_segment(pci->seg);
        tag = pci_make_tag(pc, pci->bus, pci->dev, pci->fun);
        reg = pci_conf_read(pc, tag, PCI_ID_REG);
        if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID) {
@@ -815,7 +810,7 @@ int
 acpi_pci_notify(struct aml_node *node, int ntype, void *arg)
 {
        struct acpi_pci *pdev = arg;
-       pci_chipset_tag_t pc = acpi_softc->sc_pc;
+       pci_chipset_tag_t pc;
        pcitag_t tag;
        pcireg_t reg;
        int offset;
@@ -824,6 +819,7 @@ acpi_pci_notify(struct aml_node *node, int ntype, void *arg)
        if (ntype != 2)
                return (0);
 
+       pc = pci_lookup_segment(pdev->seg);
        tag = pci_make_tag(pc, pdev->bus, pdev->dev, pdev->fun);
        if (pci_get_capability(pc, tag, PCI_CAP_PWRMGMT, &offset, 0)) {
                /* Clear the PME Status bit if it is set. */
index 311016d..2370c3b 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpimcfg.c,v 1.3 2018/07/04 20:46:22 kettenis Exp $ */
+/* $OpenBSD: acpimcfg.c,v 1.4 2018/08/19 08:23:47 kettenis Exp $ */
 /*
  * Copyright (c) 2010 Mark Kettenis <kettenis@openbsd.org>
  *
@@ -59,20 +59,20 @@ acpimcfg_match(struct device *parent, void *match, void *aux)
 void
 acpimcfg_attach(struct device *parent, struct device *self, void *aux)
 {
-       struct acpi_softc *sc = (struct acpi_softc *)parent;
        struct acpi_attach_args *aaa = aux;
        struct acpi_mcfg *mcfg = (struct acpi_mcfg *)aaa->aaa_table;
+       caddr_t addr = (caddr_t)(mcfg + 1);
 
-       printf(" addr 0x%llx, bus %d-%d\n", mcfg->base_address,
-           mcfg->min_bus_number, mcfg->max_bus_number);
+       printf("\n");
 
-       /*
-        * Some (broken?) BIOSen have an MCFG table for an empty bus
-        * range.  Ignore those tables.
-        */
-       if (mcfg->min_bus_number == mcfg->max_bus_number)
-               return;
+       while (addr < (caddr_t)mcfg + mcfg->hdr.length) {
+               struct acpi_mcfg_entry *entry = (struct acpi_mcfg_entry *)addr;
+
+               printf("%s: addr 0x%llx, bus %d-%d\n", self->dv_xname,
+                   entry->base_address, entry->min_bus_number, entry->max_bus_number);
 
-       sc->sc_pc = pci_mcfg_init(aaa->aaa_memt, mcfg->base_address,
-           mcfg->min_bus_number, mcfg->max_bus_number);
+               pci_mcfg_init(aaa->aaa_memt, entry->base_address,
+                    entry->segment, entry->min_bus_number, entry->max_bus_number);
+               addr += sizeof(struct acpi_mcfg_entry);
+       }
 }
index 6906074..76e92fc 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: acpireg.h,v 1.42 2018/07/01 10:26:17 kettenis Exp $   */
+/*     $OpenBSD: acpireg.h,v 1.43 2018/08/19 08:23:47 kettenis Exp $   */
 /*
  * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
  * Copyright (c) 2005 Marco Peereboom <marco@openbsd.org>
@@ -410,6 +410,9 @@ struct acpi_mcfg {
        struct acpi_table_header        hdr;
 #define MCFG_SIG       "MCFG"
        uint8_t         reserved[8];
+} __packed;
+
+struct acpi_mcfg_entry {
        uint64_t        base_address;
        uint16_t        segment;
        uint8_t         min_bus_number;
@@ -671,11 +674,12 @@ struct acpi_ivrs {
  */
 #define ACPI_ADR_PCIDEV(addr)  (uint16_t)(addr >> 16)
 #define ACPI_ADR_PCIFUN(addr)  (uint16_t)(addr & 0xFFFF)
-#define ACPI_PCI_BUS(addr) (uint16_t)((addr) >> 48)
-#define ACPI_PCI_DEV(addr) (uint16_t)((addr) >> 32)
+
+#define ACPI_PCI_SEG(addr) (uint16_t)((addr) >> 48)
+#define ACPI_PCI_BUS(addr) (uint8_t)((addr) >> 40)
+#define ACPI_PCI_DEV(addr) (uint8_t)((addr) >> 32)
 #define ACPI_PCI_FN(addr)  (uint16_t)((addr) >> 16)
 #define ACPI_PCI_REG(addr) (uint16_t)(addr)
-#define ACPI_PCI_ADDR(b,d,f,r) ((uint64_t)(b)<<48LL | (uint64_t)(d)<<32LL | (f)<<16LL | (r))
 
 /*
  * PM1 Status Registers Fixed Hardware Feature Status Bits
index f10f847..dd44349 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: acpivar.h,v 1.97 2018/08/03 22:18:13 kettenis Exp $   */
+/*     $OpenBSD: acpivar.h,v 1.98 2018/08/19 08:23:47 kettenis Exp $   */
 /*
  * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
  *
@@ -209,8 +209,6 @@ struct acpi_softc {
        bus_space_tag_t         sc_memt;
        bus_dma_tag_t           sc_dmat;
 
-       pci_chipset_tag_t       sc_pc;          /* XXX assume single segment */
-
        /*
         * First-level ACPI tables
         */
index 75ec47e..176c067 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: dsdt.c,v 1.242 2018/06/29 17:39:18 kettenis Exp $ */
+/* $OpenBSD: dsdt.c,v 1.243 2018/08/19 08:23:47 kettenis Exp $ */
 /*
  * Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
  *
@@ -2303,14 +2303,21 @@ aml_rdpciaddr(struct aml_node *pcidev, union amlpci_t *addr)
 {
        int64_t res;
 
+       addr->bus = 0;
+       addr->seg = 0;
        if (aml_evalinteger(acpi_softc, pcidev, "_ADR", 0, NULL, &res) == 0) {
                addr->fun = res & 0xFFFF;
                addr->dev = res >> 16;
        }
        while (pcidev != NULL) {
-               /* HID device (PCI or PCIE root): eval _BBN */
+               /* HID device (PCI or PCIE root): eval _SEG and _BBN */
                if (__aml_search(pcidev, "_HID", 0)) {
-                       if (aml_evalinteger(acpi_softc, pcidev, "_BBN", 0, NULL, &res) == 0) {
+                       if (aml_evalinteger(acpi_softc, pcidev, "_SEG",
+                               0, NULL, &res) == 0) {
+                               addr->seg = res;
+                       }
+                       if (aml_evalinteger(acpi_softc, pcidev, "_BBN",
+                               0, NULL, &res) == 0) {
                                addr->bus = res;
                                break;
                        }
index 2a52c9c..b49726d 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: dsdt.h,v 1.76 2018/07/05 19:25:38 kettenis Exp $ */
+/* $OpenBSD: dsdt.h,v 1.77 2018/08/19 08:23:47 kettenis Exp $ */
 /*
  * Copyright (c) 2005 Marco Peereboom <marco@openbsd.org>
  *
@@ -339,8 +339,9 @@ union amlpci_t {
        struct {
                uint16_t reg;
                uint16_t fun;
-               uint16_t dev;
-               uint16_t bus;
+               uint8_t dev;
+               uint8_t bus;
+               uint16_t seg;
        };
 };
 int                    aml_rdpciaddr(struct aml_node *pcidev,