From d6a1c66e27e7ccd631cdb36db2e302d903493508 Mon Sep 17 00:00:00 2001 From: kettenis Date: Sun, 19 Aug 2018 08:23:47 +0000 Subject: [PATCH] Add support for multiple PCI segments. Only really implemented for arm64 for now as amd64/i386 firmware still caters for legacy OSes that only support a single PCI segment. ok patrick@ --- sys/arch/amd64/amd64/acpi_machdep.c | 3 +- sys/arch/amd64/include/pci_machdep.h | 5 +- sys/arch/amd64/pci/pci_machdep.c | 22 ++-- sys/arch/arm64/dev/acpipci.c | 153 +++++++++++++++------------ sys/arch/arm64/include/pci_machdep.h | 5 +- sys/arch/i386/i386/acpi_machdep.c | 3 +- sys/arch/i386/pci/pci_machdep.c | 22 ++-- sys/arch/i386/pci/pci_machdep.h | 5 +- sys/dev/acpi/acpi.c | 18 ++-- sys/dev/acpi/acpimcfg.c | 24 ++--- sys/dev/acpi/acpireg.h | 12 ++- sys/dev/acpi/acpivar.h | 4 +- sys/dev/acpi/dsdt.c | 13 ++- sys/dev/acpi/dsdt.h | 7 +- 14 files changed, 170 insertions(+), 126 deletions(-) diff --git a/sys/arch/amd64/amd64/acpi_machdep.c b/sys/arch/amd64/amd64/acpi_machdep.c index 9c820b718df..f136f0743d4 100644 --- a/sys/arch/amd64/amd64/acpi_machdep.c +++ b/sys/arch/amd64/amd64/acpi_machdep.c @@ -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 * @@ -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); } diff --git a/sys/arch/amd64/include/pci_machdep.h b/sys/arch/amd64/include/pci_machdep.h index a919dfd77e2..8a456f72b09 100644 --- a/sys/arch/amd64/include/pci_machdep.h +++ b/sys/arch/amd64/include/pci_machdep.h @@ -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 diff --git a/sys/arch/amd64/pci/pci_machdep.c b/sys/arch/amd64/pci/pci_machdep.c index 5e05c750a0c..4e58376aff5 100644 --- a/sys/arch/amd64/pci/pci_machdep.c +++ b/sys/arch/amd64/pci/pci_machdep.c @@ -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; } diff --git a/sys/arch/arm64/dev/acpipci.c b/sys/arch/arm64/dev/acpipci.c index 5b067a254e8..85d0b4afa39 100644 --- a/sys/arch/arm64/dev/acpipci.c +++ b/sys/arch/arm64/dev/acpipci.c @@ -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 * @@ -34,10 +34,18 @@ #include #include -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; } /* diff --git a/sys/arch/arm64/include/pci_machdep.h b/sys/arch/arm64/include/pci_machdep.h index 32e742d8eaa..64739c2e755 100644 --- a/sys/arch/arm64/include/pci_machdep.h +++ b/sys/arch/arm64/include/pci_machdep.h @@ -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); diff --git a/sys/arch/i386/i386/acpi_machdep.c b/sys/arch/i386/i386/acpi_machdep.c index 51c67d9267b..163f46388bb 100644 --- a/sys/arch/i386/i386/acpi_machdep.c +++ b/sys/arch/i386/i386/acpi_machdep.c @@ -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 * @@ -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); } diff --git a/sys/arch/i386/pci/pci_machdep.c b/sys/arch/i386/pci/pci_machdep.c index 5973a6100cc..b712ff242ed 100644 --- a/sys/arch/i386/pci/pci_machdep.c +++ b/sys/arch/i386/pci/pci_machdep.c @@ -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; } diff --git a/sys/arch/i386/pci/pci_machdep.h b/sys/arch/i386/pci/pci_machdep.h index 682909eac28..8cf0164ed94 100644 --- a/sys/arch/i386/pci/pci_machdep.h +++ b/sys/arch/i386/pci/pci_machdep.h @@ -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, diff --git a/sys/dev/acpi/acpi.c b/sys/dev/acpi/acpi.c index ccc7befe976..ad0bab64b93 100644 --- a/sys/dev/acpi/acpi.c +++ b/sys/dev/acpi/acpi.c @@ -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 * Copyright (c) 2005 Jordan Hargrave @@ -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. */ diff --git a/sys/dev/acpi/acpimcfg.c b/sys/dev/acpi/acpimcfg.c index 311016dbd5e..2370c3b8b09 100644 --- a/sys/dev/acpi/acpimcfg.c +++ b/sys/dev/acpi/acpimcfg.c @@ -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 * @@ -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); + } } diff --git a/sys/dev/acpi/acpireg.h b/sys/dev/acpi/acpireg.h index 6906074507d..76e92fcb85d 100644 --- a/sys/dev/acpi/acpireg.h +++ b/sys/dev/acpi/acpireg.h @@ -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 * Copyright (c) 2005 Marco Peereboom @@ -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 diff --git a/sys/dev/acpi/acpivar.h b/sys/dev/acpi/acpivar.h index f10f8478813..dd443491c3d 100644 --- a/sys/dev/acpi/acpivar.h +++ b/sys/dev/acpi/acpivar.h @@ -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 * @@ -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 */ diff --git a/sys/dev/acpi/dsdt.c b/sys/dev/acpi/dsdt.c index 75ec47e663a..176c067dcf3 100644 --- a/sys/dev/acpi/dsdt.c +++ b/sys/dev/acpi/dsdt.c @@ -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 * @@ -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; } diff --git a/sys/dev/acpi/dsdt.h b/sys/dev/acpi/dsdt.h index 2a52c9ce832..b49726d75af 100644 --- a/sys/dev/acpi/dsdt.h +++ b/sys/dev/acpi/dsdt.h @@ -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 * @@ -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, -- 2.20.1