On 14/06/2019 12:59, Alexey Kardashevskiy wrote: > The pseries platform uses the PCI_PROBE_DEVTREE method of PCI probing > which is basically reading "assigned-addresses" of every PCI device. > However if the property is missing or zero sized, then there is > no fallback of any kind and the PCI resources remain undiscovered, i.e. > pdev->resource[] array is empty. > > This adds a fallback which parses the "reg" property in pretty much same > way except it marks resources as "unset" which later makes Linux assign > those resources with proper addresses. > > Signed-off-by: Alexey Kardashevskiy <aik@xxxxxxxxx> > --- > > This is an attempts to boot linux directly under QEMU without slof/rtas; > the aim is to use petitboot instead and let the guest kernel configure > devices. > > QEMU does not allocate resources, it creates correct "reg" and zero length > "assigned-addresses" (which is probably a bug on its own) which is > normally populated by SLOF later but not during this exercise. > > --- > arch/powerpc/kernel/pci_of_scan.c | 10 ++++++++++ > 1 file changed, 10 insertions(+) > > diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c > index 64ad92016b63..cfe6ec3c6aaf 100644 > --- a/arch/powerpc/kernel/pci_of_scan.c > +++ b/arch/powerpc/kernel/pci_of_scan.c > @@ -82,10 +82,18 @@ static void of_pci_parse_addrs(struct device_node *node, struct pci_dev *dev) > const __be32 *addrs; > u32 i; > int proplen; > + bool unset = false; > > addrs = of_get_property(node, "assigned-addresses", &proplen); > if (!addrs) > return; Ah. Of course, these 2 lines above should go, my bad. I'll repost if there are no other (and bigger) problems with this. > + if (!addrs || !proplen) { > + addrs = of_get_property(node, "reg", &proplen); > + if (!addrs || !proplen) > + return; > + unset = true; > + } > + > pr_debug(" parse addresses (%d bytes) @ %p\n", proplen, addrs); > for (; proplen >= 20; proplen -= 20, addrs += 5) { > flags = pci_parse_of_flags(of_read_number(addrs, 1), 0); > @@ -110,6 +118,8 @@ static void of_pci_parse_addrs(struct device_node *node, struct pci_dev *dev) > continue; > } > res->flags = flags; > + if (unset) > + res->flags |= IORESOURCE_UNSET; > res->name = pci_name(dev); > region.start = base; > region.end = base + size - 1; > -- Alexey