So the 24-core arm64 machine I have now contains two PCI host bridges.
And since this isn't a PeeCee those are exposed as two separate PCI
"segments".  This means I need to add support for muliple segments to
the ACPI code.  The diff does this by adding a segment argument to the
pci_mcfg_init() function and introducing a new pci_lookup_segment()
function.  For amd64 and i386 I continue to assume that there is only
a segment zero.  On those platforms ACPI should never use additional
segments unless we explicitly tell it that we support it (which we
don't do).  A lookup of a non-zero segment will trigger a KASSERT.
For arm64 I still only support segment zero, but a lookup of other
segments will not trigger a panic.  Instead I return a "dummy" PCI
chipset tag that returns 0xfffffff for all config space reads and
ignores all config space writes.

I will implement true multi-segment support for arm64 in a follow-up
diff.

ok?


Index: arch/amd64/amd64/acpi_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/amd64/acpi_machdep.c,v
retrieving revision 1.84
diff -u -p -r1.84 acpi_machdep.c
--- arch/amd64/amd64/acpi_machdep.c     4 Jul 2018 20:46:21 -0000       1.84
+++ arch/amd64/amd64/acpi_machdep.c     16 Aug 2018 21:02:48 -0000
@@ -97,7 +97,6 @@ acpi_attach(struct device *parent, struc
        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: arch/amd64/include/pci_machdep.h
===================================================================
RCS file: /cvs/src/sys/arch/amd64/include/pci_machdep.h,v
retrieving revision 1.26
diff -u -p -r1.26 pci_machdep.h
--- arch/amd64/include/pci_machdep.h    4 Jul 2018 20:46:22 -0000       1.26
+++ arch/amd64/include/pci_machdep.h    16 Aug 2018 21:02:48 -0000
@@ -95,7 +95,8 @@ void          pci_dev_postattach(struct device 
 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: arch/amd64/pci/pci_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/pci/pci_machdep.c,v
retrieving revision 1.68
diff -u -p -r1.68 pci_machdep.c
--- arch/amd64/pci/pci_machdep.c        4 Jul 2018 20:46:22 -0000       1.68
+++ arch/amd64/pci/pci_machdep.c        16 Aug 2018 21:02:48 -0000
@@ -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: arch/arm64/dev/acpipci.c
===================================================================
RCS file: /cvs/src/sys/arch/arm64/dev/acpipci.c,v
retrieving revision 1.6
diff -u -p -r1.6 acpipci.c
--- arch/arm64/dev/acpipci.c    11 Aug 2018 22:47:27 -0000      1.6
+++ arch/arm64/dev/acpipci.c    16 Aug 2018 21:02:48 -0000
@@ -567,11 +567,15 @@ pci_mcfg_conf_write(void *v, pcitag_t ta
        bus_space_write_4(pci_mcfgt, pci_mcfgh, tag | reg, data);
 }
 
-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_chipset_tag_t pc = &pci_mcfg_chipset;
 
+       if (segment != 0)
+               return;
+
        pci_mcfgt = iot;
        pci_mcfg_addr = addr;
        pci_mcfg_min_bus = min_bus;
@@ -588,8 +592,35 @@ pci_mcfg_init(bus_space_tag_t iot, bus_a
        pc->pc_conf_size = acpipci_conf_size;
        pc->pc_conf_read = pci_mcfg_conf_read;
        pc->pc_conf_write = pci_mcfg_conf_write;
+}
+
+pcireg_t
+pci_dummy_conf_read(void *v, pcitag_t tag, int reg)
+{
+       return 0xffffffff;
+}
+
+void
+pci_dummy_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
+{
+}
+
+struct arm64_pci_chipset pci_dummy_chipset = {
+       .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 = pci_dummy_conf_read,
+       .pc_conf_write = pci_dummy_conf_write,
+};
+
+pci_chipset_tag_t
+pci_lookup_segment(int segment)
+{
+       if (segment == 0)
+               return &pci_mcfg_chipset;
 
-       return pc;
+       return &pci_dummy_chipset;
 }
 
 /*
Index: arch/i386/i386/acpi_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/acpi_machdep.c,v
retrieving revision 1.68
diff -u -p -r1.68 acpi_machdep.c
--- arch/i386/i386/acpi_machdep.c       4 Jul 2018 20:46:22 -0000       1.68
+++ arch/i386/i386/acpi_machdep.c       16 Aug 2018 21:02:48 -0000
@@ -107,7 +107,6 @@ acpi_attach(struct device *parent, struc
        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: arch/i386/pci/pci_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/i386/pci/pci_machdep.c,v
retrieving revision 1.83
diff -u -p -r1.83 pci_machdep.c
--- arch/i386/pci/pci_machdep.c 4 Jul 2018 20:46:22 -0000       1.83
+++ arch/i386/pci/pci_machdep.c 16 Aug 2018 21:02:48 -0000
@@ -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: arch/i386/pci/pci_machdep.h
===================================================================
RCS file: /cvs/src/sys/arch/i386/pci/pci_machdep.h,v
retrieving revision 1.29
diff -u -p -r1.29 pci_machdep.h
--- arch/i386/pci/pci_machdep.h 4 Jul 2018 20:46:22 -0000       1.29
+++ arch/i386/pci/pci_machdep.h 16 Aug 2018 21:02:48 -0000
@@ -111,7 +111,8 @@ void                pci_dev_postattach(struct device 
 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: dev/acpi/acpi.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpi.c,v
retrieving revision 1.356
diff -u -p -r1.356 acpi.c
--- dev/acpi/acpi.c     3 Aug 2018 22:18:13 -0000       1.356
+++ dev/acpi/acpi.c     16 Aug 2018 21:02:49 -0000
@@ -328,13 +328,6 @@ acpi_gasio(struct acpi_softc *sc, int io
                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 io
                        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 
        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 
                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 
                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, i
        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: dev/acpi/acpimcfg.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpimcfg.c,v
retrieving revision 1.3
diff -u -p -r1.3 acpimcfg.c
--- dev/acpi/acpimcfg.c 4 Jul 2018 20:46:22 -0000       1.3
+++ dev/acpi/acpimcfg.c 16 Aug 2018 21:02:49 -0000
@@ -59,7 +59,6 @@ acpimcfg_match(struct device *parent, vo
 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;
 
@@ -73,6 +72,6 @@ acpimcfg_attach(struct device *parent, s
        if (mcfg->min_bus_number == mcfg->max_bus_number)
                return;
 
-       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, mcfg->base_address,
+           mcfg->segment, mcfg->min_bus_number, mcfg->max_bus_number);
 }
Index: dev/acpi/acpireg.h
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpireg.h,v
retrieving revision 1.42
diff -u -p -r1.42 acpireg.h
--- dev/acpi/acpireg.h  1 Jul 2018 10:26:17 -0000       1.42
+++ dev/acpi/acpireg.h  16 Aug 2018 21:02:49 -0000
@@ -671,11 +671,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: dev/acpi/acpivar.h
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpivar.h,v
retrieving revision 1.97
diff -u -p -r1.97 acpivar.h
--- dev/acpi/acpivar.h  3 Aug 2018 22:18:13 -0000       1.97
+++ dev/acpi/acpivar.h  16 Aug 2018 21:02:49 -0000
@@ -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: dev/acpi/dsdt.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/dsdt.c,v
retrieving revision 1.242
diff -u -p -r1.242 dsdt.c
--- dev/acpi/dsdt.c     29 Jun 2018 17:39:18 -0000      1.242
+++ dev/acpi/dsdt.c     16 Aug 2018 21:02:49 -0000
@@ -2303,14 +2303,21 @@ aml_rdpciaddr(struct aml_node *pcidev, u
 {
        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: dev/acpi/dsdt.h
===================================================================
RCS file: /cvs/src/sys/dev/acpi/dsdt.h,v
retrieving revision 1.76
diff -u -p -r1.76 dsdt.h
--- dev/acpi/dsdt.h     5 Jul 2018 19:25:38 -0000       1.76
+++ dev/acpi/dsdt.h     16 Aug 2018 21:02:49 -0000
@@ -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,

Reply via email to