summaryrefslogtreecommitdiffstats
path: root/OvmfPkg/PlatformPei/Platform.c
diff options
context:
space:
mode:
authorLaszlo Ersek <lersek@redhat.com>2015-09-02 18:45:44 +0000
committerlersek <lersek@Edk2>2015-09-02 18:45:44 +0000
commitc68d3a697874a81f076ae57dc16acfe255d2986b (patch)
treed0e08604713353db3669fa689f6afd5dae20c86b /OvmfPkg/PlatformPei/Platform.c
parentf1cbea148c1d1392302bf1469fad26aea6cf3659 (diff)
downloadedk2-c68d3a697874a81f076ae57dc16acfe255d2986b.tar.gz
edk2-c68d3a697874a81f076ae57dc16acfe255d2986b.tar.bz2
edk2-c68d3a697874a81f076ae57dc16acfe255d2986b.zip
OvmfPkg: PlatformPei: force 32-bit MMIO aperture above 3 GB on Q35
The logic we have in place for i440fx does not work reliably on q35. For example, if the guest has 2GB of RAM, we allow the PCI root bridge driver to allocate the legacy video RAM BAR from the [2048 MB, 2816 MB] range, which falls strictly outside of the Q35 PCI host MMIO aperture that QEMU configures, and advertizes in ACPI. In turn, PCI BARs that exist outside of the PCI host aperture that is exposed in ACPI break Windows guests. Allocating PCI MMIO resources at or above 3GB on Q35 ensures that we stay within QEMU's aperture. (See the "w32.begin" assignments in "hw/pci-host/q35.c".) Furthermore, in pc_q35_init() (file "hw/i386/pc_q35.c"), QEMU ensures that the low RAM never "leaks" above 3GB. The i440fx logic is left unchanged. The Windows guest malfunction on Q35 was reported by Jon Panozzo of Lime Technology, Inc. Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Igor Mammedov <imammedo@redhat.com> Cc: Jon Panozzo <jonp@lime-technology.com> Cc: "Gabriel L. Somlo" <somlo@cmu.edu> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Jordan Justen <jordan.l.justen@intel.com> Tested-by: Jonathan Panozzo <jonp@lime-technology.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18393 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'OvmfPkg/PlatformPei/Platform.c')
-rw-r--r--OvmfPkg/PlatformPei/Platform.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index 2cc4c7e973..6a7bc52c45 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -204,7 +204,20 @@ MemMapInitialization (
if (!mXen) {
UINT32 TopOfLowRam;
+ UINT32 PciBase;
+
TopOfLowRam = GetSystemMemorySizeBelow4gb ();
+ if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
+ //
+ // A 3GB base will always fall into Q35's 32-bit PCI host aperture,
+ // regardless of the Q35 MMCONFIG BAR. Correspondingly, QEMU never lets
+ // the RAM below 4 GB exceed it.
+ //
+ PciBase = BASE_2GB + BASE_1GB;
+ ASSERT (TopOfLowRam <= PciBase);
+ } else {
+ PciBase = (TopOfLowRam < BASE_2GB) ? BASE_2GB : TopOfLowRam;
+ }
//
// address purpose size
@@ -219,8 +232,7 @@ MemMapInitialization (
// 0xFED20000 gap 896 KB
// 0xFEE00000 LAPIC 1 MB
//
- AddIoMemoryRangeHob (TopOfLowRam < BASE_2GB ?
- BASE_2GB : TopOfLowRam, 0xFC000000);
+ AddIoMemoryRangeHob (PciBase, 0xFC000000);
AddIoMemoryBaseSizeHob (0xFEC00000, SIZE_4KB);
AddIoMemoryBaseSizeHob (0xFED00000, SIZE_1KB);
if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {