summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2022-01-05 18:54:21 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2022-01-05 18:54:21 +0000
commitd29ec35a5643ad9a546423dadd67555c4bd3d659 (patch)
tree2634a6a05b5c17339b06d4a1f6cc37a8672dc8ec /sys
parent4acde2dbcca317dfef84e6263ff045e166af1b7f (diff)
Use "bus-range" property to initialize the bus number configuration of
the bridge when present on FDT platforms. Needed on platforms like the Apple M1 to make sure the PCI bus numbers match the IOMMU setup required by the device tree. ok patrick@
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pci/ppb.c39
1 files changed, 31 insertions, 8 deletions
diff --git a/sys/dev/pci/ppb.c b/sys/dev/pci/ppb.c
index c5ccd3b3d7d..bc008f3f3c5 100644
--- a/sys/dev/pci/ppb.c
+++ b/sys/dev/pci/ppb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ppb.c,v 1.68 2019/04/23 19:37:35 patrick Exp $ */
+/* $OpenBSD: ppb.c,v 1.69 2022/01/05 18:54:20 kettenis Exp $ */
/* $NetBSD: ppb.c,v 1.16 1997/06/06 23:48:05 thorpej Exp $ */
/*
@@ -42,6 +42,11 @@
#include <dev/pci/pcidevs.h>
#include <dev/pci/ppbreg.h>
+#ifdef __HAVE_FDT
+#include <machine/fdt.h>
+#include <dev/ofw/openfirm.h>
+#endif
+
#ifndef PCI_IO_START
#define PCI_IO_START 0
#endif
@@ -167,7 +172,7 @@ ppbattach(struct device *parent, struct device *self, void *aux)
* When the bus number isn't configured, try to allocate one
* ourselves.
*/
- if (busdata == 0 && pa->pa_busex)
+ if (busdata == 0 && pa->pa_busex)
ppb_alloc_busrange(sc, pa, &busdata);
/*
@@ -528,12 +533,31 @@ ppb_alloc_busrange(struct ppb_softc *sc, struct pci_attach_args *pa,
pcireg_t *busdata)
{
pci_chipset_tag_t pc = sc->sc_pc;
- u_long busnum, busrange;
+ u_long busnum, busrange = 0;
+
+#ifdef __HAVE_FDT
+ int node = PCITAG_NODE(pa->pa_tag);
+ uint32_t bus_range[2];
+
+ if (node && OF_getpropintarray(node, "bus-range", bus_range,
+ sizeof(bus_range)) == sizeof(bus_range)) {
+ if (extent_alloc_region(pa->pa_busex, bus_range[0],
+ bus_range[1] - bus_range[0] + 1, EX_NOWAIT) == 0) {
+ busnum = bus_range[0];
+ busrange = bus_range[1] - bus_range[0] + 1;
+ }
+ }
+#endif
- for (busrange = 16; busrange > 0; busrange >>= 1) {
- if (extent_alloc(pa->pa_busex, busrange, 1, 0, 0,
- EX_NOWAIT, &busnum))
- continue;
+ if (busrange == 0) {
+ for (busrange = 16; busrange > 0; busrange >>= 1) {
+ if (extent_alloc(pa->pa_busex, busrange, 1, 0, 0,
+ EX_NOWAIT, &busnum) == 0)
+ break;
+ }
+ }
+
+ if (busrange > 0) {
sc->sc_parent_busex = pa->pa_busex;
sc->sc_busnum = busnum;
sc->sc_busrange = busrange;
@@ -541,7 +565,6 @@ ppb_alloc_busrange(struct ppb_softc *sc, struct pci_attach_args *pa,
*busdata |= (busnum << 8);
*busdata |= ((busnum + busrange - 1) << 16);
pci_conf_write(pc, pa->pa_tag, PPB_REG_BUSINFO, *busdata);
- return;
}
}