Re: PCI range checking under qemu-system-sparc64

Marius Strobl <[email protected]>
Newsgroups gmane.os.freebsd.devel.sparc
Message-ID <[email protected]>
On Sun, Sep 13, 2015 at 10:39:41AM +0000, Alexey Dokuchaev wrote:
> On Sun, Sep 13, 2015 at 04:21:43AM +0200, Marius Strobl wrote:
> > However, looking at ebus(4), I've spotted a bug in the conversion
> > to NEW_PCIB. Interested parties might want to give the attached
> > patch a try. That bug definitely can lead to the problem seen with
> > QEMU, I'm not sure it's the only one in that regard, though; I'm
> > fairly certain in this case there's no problem with interpreting
> > the device-tree involved, given that the same code is used for
> > ISA busses which - at least in reality - unlike EBus ones use
> > I/O port instead of memory space for the resources of devices
> > such as UARTs etc. There could be other spots not prepared for
> > EBus devices suddenly requesting SYS_RES_IOPORT, too, though.
> 
> I've applied that patch, but it alone is not enough to allow the boot
> to proceed further in QEMU. :(
> 

Err, right, on a second look the bug I thought existed in ebus(4)
actually isn't there; its code I added as part of the conversion
to NEW_PCIB is just a bit unclean/unobvious but in fact does the
right thing, even if a child resource would map to SYS_RES_IOPORT.

However, I noticed that the cause of failure likely is a bug in
the "ranges" property of the QEMU EBus bridge. The following is
an example from a T1-AC200 demonstrating how a correct setup
looks like:
ebus0: <PCI-EBus3 bridge> mem 0xf0000000-0xf0ffffff,0xf1000000-0xf17fffff at device 12.0 on pci1
child_hi child_lo phys_hi  phys_mid phys_lo  size
00000010 00000000 82016010 00000000 f0000000 01000000
00000014 00000000 82016014 00000000 f1000000 00800000

When mapping EBus child resources, their adresses are translated
to the address base specified by (phys_mid << 32) | phys_lo on
the parent side, based on the range the child resource falls
into (determined via child_hi, child_lo and size). For PCI-EBus-
bridges, the parent address range further must [1, p. 113 f.]
match the resources on the PCI side, i. e. the BARs. In the above
case that's 0xf0000000 determined by (phys_mid << 32) | phys_lo
and size 0x1000000 from the ranges property and mem 0xf0000000-
0xf0ffffff from the first BAR (see dmesg snippet) for example.

With QEMU we get (based on the dump from Mark and your dmesg):
ebus0: <PCI-EBus2 bridge> port 0x4000-0x7fff mem 0x3000000-0x3ffffff at device 3.0 on pci0
child_hi child_lo phys_hi  phys_mid phys_lo  size
00000010 00000000 02001810 00000000 00000000 01000000
00000014 00000000 01001814 00000000 00000000 00004000

So here, the parent addresses don't match as for example
0x00000000 determined by (phys_mid << 32) | phys_lo doesn't
match BAR 0, which is mem 0x3000000-0x3ffffff. Likewise for
the second BAR and range combo. Sizes are correct, though.

Note that according to the dump from Mark, the BARs of the
PCI-EBus-bridge at least match its "assigned-addresses"
property. So it might be as simple as fixing phys_mid and
phys_lo in the device tree file shipping with OpenBIOS, iff
such a thing exists and the device tree isn't assembled
dynamically somehow.

Marius

1: Peripheral Component Interconnect Input Output Controller,
   Part No.: 802-7837-01, Sun Microelectronics, March 1997
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-sparc64
To unsubscribe, send any mail to "[email protected]"
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.