From: kettenis Date: Wed, 5 Jan 2022 18:54:20 +0000 (+0000) Subject: Use "bus-range" property to initialize the bus number configuration of X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=3852484dc6239d82cdff0f74fa7212d36df680d7;p=openbsd 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@ --- 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; } }