PCI range checking under qemu-system-sparc64
Mark Cave-Ayland
mark.cave-ayland at ilande.co.uk
Tue Sep 15 22:15:30 UTC 2015
On 13/09/15 19:01, Marius Strobl wrote:
> 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.
Aha - I bet that's it. I've tweaked OpenBIOS to update phys_mid the same
as "assigned-addresses" and that now gives me the following for /pci/ebus:
0 > cd /pci/ebus ok
0 > .properties
name "ebus"
vendor-id 108e
device-id 1000
revision-id 1
class-code 68000
min-grant 0
max-latency 0
devsel-speed 0
fast-back-to-back <empty>
66mhz-capable <empty>
subsystem-vendor-id 1af4
subsystem-id 1100
cache-line-size a00
model "ebus"
compatible {"pci108e,1000", "pciclass,068000"}
#address-cells 2
#size-cells 1
#interrupt-cells 1
assigned-addresses -- 28 : 02 00 18 10 00 00 00 00 03 00 00 00 00
00 00 00 01 00 00 00 01 00 18 14 00 00 00 00 00 00 40 00 00 00 00 00 00
00 40 00
reg 00001800 00000000 00000000 00000000 00000000
02001810 00000000 00000000 00000000 01000000
01001814 00000000 00000000 00000000 00004000
interrupt-map -- 14 : 00 00 00 14 00 00 03 f8 00 00 00 01 ff
e1 b9 48 00 00 00 2b
interrupt-map-mask -- c : 00 00 01 ff ff ff ff ff 00 00 00 03
ranges -- 30 : 00 00 00 10 00 00 00 00 02 00 18 10 00
00 00 00 03 00 00 00 01 00 00 00 00 00 00 14 00 00 00 00 01 00 18 14 00
00 00 00 00 00 40 00 00 00 40 00
ok
Properly formatted, ranges now looks like this:
00000010 00000000 02001810 00000000 03000000 01000000
00000014 00000000 01001814 00000000 00004000 00004000
...and in my tests here it doesn't appear to regress any of my test
images. As I still don't have a FreeBSD environment setup yet, I've
uploaded the binary to http://www.ilande.co.uk/tmp/openbios-sparc64 - if
someone with QEMU 2.4 could replace openbios-sparc64 with the downloaded
version and post a boot log in -nographic mode then that would be great.
BTW does the comment on D2791 mean that it has been superseded by a new
patch that has been committed to trunk?
ATB,
Mark.
More information about the freebsd-sparc64
mailing list