On Tue, Nov 19, 2013 at 01:31:39PM +0100, Laszlo Ersek wrote: > On 11/19/13 09:54, Gerd Hoffmann wrote: > > Hi, > > > >> ACPI PciWindow32: Base=0xA0000000 End=0xFEEFFFFF Length=0x5EF00000 > > > >> begin32=c0000000 end32=fec00000 begin64=0 end64=0 > > > > qemu & seabios pick a 32bit window size which allows to cover it with > > a single mtrr entry. Size must be a power of two for that to work. > > > > [root@fedora ~]# cat /proc/mtrr > > reg00: base=0x080000000 ( 2048MB), size= 2048MB, count=1: uncachable > > > > So we have three cases for piix (as you've figured in the source code > > already). Start at 0x80000000 (2G window), 0xc0000000 (1G window) and > > 0xe0000000 (512M window). > > > > btw: q35 has a fixed 1G window, max low ram addr is 0xb000000, the > > remaining address space (0xb0000000 -> 0xc0000000) is used for > > mmconfig. > > > >> I guess the range starting at 0xc0000000 is somehow "incompatible" > >> with the EFI memory map. (I can't actually explain this idea because, > >> again, this second range is a proper subset of the former, and its > >> size is still 1004MB.) > > > > Probably efi places the gfx memory bar somewhere between 0xa0000000 > > and 0xc0000000. Sets up efifb accordingly. Then the linux kernel > > loads and figures "Oh, that bar is outside the 0xc0000000+ window" and > > goes remap it -> efifb writes go into nowhere. > > Thank you for the explanation. > > How do I fix it though? :) I could change the MMIO HOBs in PEI > (OvmfPkg/PlatformPei/Platform.c): > > // > // Video memory + Legacy BIOS region > // > AddIoMemoryRangeHob (0x0A0000, BASE_1MB); > > // > // address purpose size > // ------------ -------- ------------------------- > // max(top, 2g) PCI MMIO 0xFC000000 - max(top, 2g) > // 0xFC000000 gap 44 MB > // 0xFEC00000 IO-APIC 4 KB > // 0xFEC01000 gap 1020 KB > // 0xFED00000 HPET 1 KB > // 0xFED00400 gap 1023 KB > // 0xFEE00000 LAPIC 1 MB > // > AddIoMemoryRangeHob (TopOfMemory < BASE_2GB ? BASE_2GB : TopOfMemory, > 0xFC000000); > AddIoMemoryBaseSizeHob (0xFEC00000, SIZE_4KB); > AddIoMemoryBaseSizeHob (0xFED00000, SIZE_1KB); > AddIoMemoryBaseSizeHob (PcdGet32(PcdCpuLocalApicBaseAddress), SIZE_1MB); > > to imitate the same three cases. The HOB with the lowest address > produced here would affect the BAR placement as well. > > ... Yes, I tested the attached patch, and it makes the display work in > both 2560MB guests. > > However, I don't like the idea of hardwiring those boundaries here. (The > current values are also hardwired, but they are better: they are not the > consequence of "SeaBIOS has done it like this forever" -- inter-firmware > dependency, especially when they aren't each other's payloads, is bad > IMHO.) We'd need something dynamic here, like a memory map from qemu. > > ... Which puts us in the same boat with Wei :) > > Thanks > Laszlo
So the bug is really qemu being too conservative with it's ACPI tables, isn't it? The MTRRs in BIOS don't affect much: AFAIK they are completely ignored if it's exiting to the host, but I'm not sure about assigned devices. Alex, can you remind us all what happens there? > From 9cf2af82399d7d7a9717ff6ac17860b66c705a64 Mon Sep 17 00:00:00 2001 > From: Laszlo Ersek <ler...@redhat.com> > Date: Tue, 19 Nov 2013 13:07:41 +0100 > Subject: [PATCH] OvmfPkg/PlatformPei: follow SeaBIOS tradition with 32-bit PCI > hole placement > > Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Laszlo Ersek <ler...@redhat.com> > --- > OvmfPkg/PlatformPei/Platform.c | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c > index fb56e99..5bc0d74 100644 > --- a/OvmfPkg/PlatformPei/Platform.c > +++ b/OvmfPkg/PlatformPei/Platform.c > @@ -197,7 +197,7 @@ MemMapInitialization ( > // > // address purpose size > // ------------ -------- ------------------------- > - // max(top, 2g) PCI MMIO 0xFC000000 - max(top, 2g) > + // 2G/3G/3.5G PCI MMIO 0xFC000000 - 2G/3G/3.5G > // 0xFC000000 gap 44 MB > // 0xFEC00000 IO-APIC 4 KB > // 0xFEC01000 gap 1020 KB > @@ -205,7 +205,9 @@ MemMapInitialization ( > // 0xFED00400 gap 1023 KB > // 0xFEE00000 LAPIC 1 MB > // > - AddIoMemoryRangeHob (TopOfMemory < BASE_2GB ? BASE_2GB : TopOfMemory, > 0xFC000000); > + AddIoMemoryRangeHob (TopOfMemory <= 0x80000000 ? 0x80000000 : > + TopOfMemory <= 0xC0000000 ? 0xC0000000 : > + 0xE0000000, 0xFC000000); > AddIoMemoryBaseSizeHob (0xFEC00000, SIZE_4KB); > AddIoMemoryBaseSizeHob (0xFED00000, SIZE_1KB); > AddIoMemoryBaseSizeHob (PcdGet32(PcdCpuLocalApicBaseAddress), SIZE_1MB); > -- > 1.8.3.1 >