From 3852484dc6239d82cdff0f74fa7212d36df680d7 Mon Sep 17 00:00:00 2001 From: kettenis Date: Wed, 5 Jan 2022 18:54:20 +0000 Subject: [PATCH] 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@ --- sys/dev/pci/ppb.c | 39 +++++++++++++++++++++++++++++++-------- 1 file 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 #include +#ifdef __HAVE_FDT +#include +#include +#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; } } -- 2.20.1