Hi Artyom, all,
On 04/19/2012 10:29 PM, Artyom Tarasenko wrote:
On Thu, Apr 19, 2012 at 10:04 PM, Blue Swirl blauwirbel@gmail.com wrote:
On Thu, Apr 19, 2012 at 19:06, Artyom Tarasenko atar4qemu@gmail.com wrote:
On Sun, Mar 11, 2012 at 11:59 AM, Blue Swirl blauwirbel@gmail.com wrote:
A change in QEMU on how PCI bridges are setup revealed a bug in OpenBIOS PCI setup. On Sparc64, the BARs just happened to get somewhat correct values by accident before the commit but not after the change.
Don't use arch->io_base for PCI I/O port BARs.
Fix Sparc64 PCI memory base.
Could it be that the ranges property needs to be adjusted to look as it did before the patch?
This patch breaks HelenOS-0.4.3/sparc boot. But if I modify the ranges property to the old value, HelenOS boots.
0 > cd /pci@1fe,0 ok 0 > .properties [...] ranges -- 54 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 fe 01 00 00 00 00 00 00 00 02 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 01 fe 02 00 00 00 00 00 00 00 00 01 00 00 02 00 00 00 00 00 00 00 00 10 00 00 00 00 01 ff 00 00 00 00 00 00 00 00 10 00 00 00
Not sure about the best formatting. If I reformat it like this:
00000000 00000000 00000000 000001fe 01000000 00000000 02000000 01000000 00000000 00000000 000001fe 02000000 00000000 00010000 02000000 00000000 00100000 000001ff 00000000 00000000 10000000 ^^^^ this one (the third) used to be 0
On an Ultra-5 this should be 00000000.00000000.00000000.000001fe.01000000.00000000.01000000. 01000000.00000000.00000000.000001fe.02000000.00000000.01000000. 02000000.00000000.00000000.000001ff.00000000.00000001.00000000. 03000000.00000000.00000000.000001ff.00000000.00000001.00000000
http://git.kernel.org/?p=linux/kernel/git/davem/prtconfs.git;a=blob;f=ultra5...
I guess the problem is that the properties are added by finding the host bridge in the PCI bus (which btw isn't so nice), so we use the pci_mem_base. Using pci_mem_base = 0 would probably fix the BAR, but then VGA would get in the way. Probably something more complex is needed.
Hmm. Complicated. What is actually the meaning of this property? Don't we need the values ourselves? If these are just BARs, can't we pass the configuration from qemu?
I am now looking into this from the HelenOS point of view. The problem is that HelenOS miscomputes the framebuffer physical address.
I think I found the culprit in the ranges property of the PCI node. The mechanism of the bug seems to be as follows.
HelenOS reads the parent-relative address of the VGA node from the reg property. The address is 0x008000000. It then wants to apply it on the parent node's (PCI) ranges property. Using a packed C structure, a range is defined as follows:
typedef struct { uint32_t space; uint64_t child_base; uint64_t parent_base; uint64_t size; };
Note that in our case, the matching range is:
02000000 00000000 00100000 000001ff 00000000 00000000 10000000
child_base is 0x00100000 parent_base is 0x1ff00000000 reg_addr is 0x00800000
HelenOS then computes the resulting physical address using this formula:
pa = parent_base + (reg_addr - child_base);
The result is thus 0x1ff00700000 instead of the correct value 0x1ff00800000.
So it looks like either the child base should be 0, or reg_addr must be 0x00900000, or parent_base must be 0x1ff00100000. From the way this works e.g. on Sun E6500, the last option seems to be the correct one.
What do you think of it?
Jakub
On 2012-May-10 17:48 , Jakub Jermar wrote:
[...]
So it looks like either the child base should be 0, or reg_addr must be 0x00900000, or parent_base must be 0x1ff00100000. From the way this works e.g. on Sun E6500, the last option seems to be the correct one.
Agreed. On current SPARC, the only non-zero Range on PCI is for 64-bit memory. For the memory ranges we see:
0200.0000 0000.0000 0000.0000 8000.8090 0000.0000 0000.0007 0000.0000 0300.0000 0000.0001 0000.0000 8000.8091 0000.0000 0000.0007 0000.0000
My recollection is that memory space PCI RA (real address rather than physical address, because now we're behind a hypervisor) ranges from 8000.8090.0000.0000 through 8000.8097.FFFF.FFFF - which would match your guess that the parent_base needs to be hacked if 0800.0000 is going to be the BAR and is going to represent 1ff.0800.0000.
So, why does OpenBios have 0100.0000 as a child base in the first place?
On Thu, May 10, 2012 at 10:47 PM, Tarl Neustaedter tarl-b2@tarl.net wrote:
On 2012-May-10 17:48 , Jakub Jermar wrote:
[...]
So it looks like either the child base should be 0, or reg_addr must be 0x00900000, or parent_base must be 0x1ff00100000. From the way this works e.g. on Sun E6500, the last option seems to be the correct one.
Agreed. On current SPARC, the only non-zero Range on PCI is for 64-bit memory. For the memory ranges we see:
0200.0000 0000.0000 0000.0000 8000.8090 0000.0000 0000.0007 0000.0000 0300.0000 0000.0001 0000.0000 8000.8091 0000.0000 0000.0007 0000.0000
My recollection is that memory space PCI RA (real address rather than physical address, because now we're behind a hypervisor) ranges from 8000.8090.0000.0000 through 8000.8097.FFFF.FFFF - which would match your guess that the parent_base needs to be hacked if 0800.0000 is going to be the BAR and is going to represent 1ff.0800.0000.
So, why does OpenBios have 0100.0000 as a child base in the first place?
It's to avoid VGA legacy mapping at 0xa0000. If I change hwdefs.pci.pci_mem_base in arch/sparc64/openbios.c to 0, OpenBIOS will crash during VGA init. Previously this worked because the PCI devices were mapped somewhat randomly and by chance, VGA legacy low mem area was avoided.
I think the correct fix is to make QEMU VGA device disable the legacy mapping unless explicitly enabled. Alternatively the child base arithmetic could be fixed in OpenBIOS like proposed by Jakub.
-- OpenBIOS http://openbios.org/ Mailinglist: http://lists.openbios.org/mailman/listinfo Free your System - May the Forth be with you