[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] Re: Unusual physical address when using 64-bit BAR
From: |
Avi Kivity |
Subject: |
[Qemu-devel] Re: Unusual physical address when using 64-bit BAR |
Date: |
Tue, 29 Jun 2010 09:50:45 +0300 |
User-agent: |
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.10) Gecko/20100621 Fedora/3.0.5-1.fc13 Thunderbird/3.0.5 |
On 06/28/2010 11:38 PM, Cam Macdonell wrote:
Is this really the address the guest programmed, or is qemu
misinterpreting
it?
Well, what's the answer?
You're going to have to give me a hint on how to determine that.
lspci in the guest shows the following
Memory at c20000000000 (64-bit, non-prefetchable) [size=1024M]
does that demonstrate a guest generated address?
That's the result of a round trip: the guest programmed the address and
then read it back. It could have been screwed up in the first place, or
perhaps qemu screwed it up.
Add a printf() to the config space handlers in qemu (likely in your own
code) on writes and reads, and show the relevant writes (and reads) for
this BAR.
That's the theory of deductive debugging; however browsing the code
shows the guest is at fault:
for (i = 0; i < PCI_NUM_REGIONS; i++) {
int ofs;
if (i == PCI_ROM_SLOT)
ofs = PCI_ROM_ADDRESS;
else
ofs = PCI_BASE_ADDRESS_0 + i * 4;
u32 old = pci_config_readl(bdf, ofs);
u32 mask;
if (i == PCI_ROM_SLOT) {
mask = PCI_ROM_ADDRESS_MASK;
pci_config_writel(bdf, ofs, mask);
} else {
if (old & PCI_BASE_ADDRESS_SPACE_IO)
mask = PCI_BASE_ADDRESS_IO_MASK;
else
mask = PCI_BASE_ADDRESS_MEM_MASK;
pci_config_writel(bdf, ofs, ~0);
}
u32 val = pci_config_readl(bdf, ofs);
pci_config_writel(bdf, ofs, old);
if (val != 0) {
u32 size = (~(val & mask)) + 1;
if (val & PCI_BASE_ADDRESS_SPACE_IO)
paddr = &pci_bios_io_addr;
else
paddr = &pci_bios_mem_addr;
*paddr = ALIGN(*paddr, size);
pci_set_io_region_addr(bdf, i, *paddr);
*paddr += size;
}
}
break;
}
Seabios completely ignore the 64-bitness of the BAR. Looks like it also
thinks the second half of the BAR is an I/O region instead of memory
(hence the c200, that's part of the pci portio region.
Do post those reads and writes, I think there's more than one thing
wrong here.
--
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.