From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: redhat.com, ip: 209.85.221.68, mailfrom: philmd@redhat.com) Received: from mail-wr1-f68.google.com (mail-wr1-f68.google.com [209.85.221.68]) by groups.io with SMTP; Mon, 03 Jun 2019 04:07:25 -0700 Received: by mail-wr1-f68.google.com with SMTP id b18so11538431wrq.12 for ; Mon, 03 Jun 2019 04:07:24 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:openpgp:message-id :date:user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=sifAierIGdESrXH7OqCFUsaMVz0hkJfEyUqBJkXzLg0=; b=tLPZPHQcSalT4jIwgI9bl0fLf3iwpJQHu92lhuyoOWwvOMT5lag1utHqVja73Nkarq 5Qkqq3PR0y240OJIvSldXUg7Q3zw8NJFQDbTXBMb5dOlOncdydkudXe+qK9cMD5bDOr8 wGL3fH6dl0HQ2Ox79IRsNIM7FM+IR2gayHaxKq2/vkwVGK7RO59ZjQgEdznGSQYb0ziV eeKy0C+gBdOxhR1EJwYXnL5Rc3nfqaa29TQ3Pf3KWcb9dqwccYxDRWas0Y7xgWnqtW3o khYyq+Pq+poeFySl/zjBC0m7GyXhA1v0RO6A3w/IbuN+Usp0nRWUsBuScBh6xH6jHVk7 RsOw== X-Gm-Message-State: APjAAAXUIh3TUk+cd703224uxFJsK2dvKef02/+UWQ3b8HNhXxS4GcxW wMZRZBf9yz234MoV6kxLEiMHXg== X-Google-Smtp-Source: APXvYqyxubFimTNH25uU+49YM3eWLYdlvDH9Iiv2eGZ34K0yHHTBwRLkFxkb710c+eaImJKwTMC/tA== X-Received: by 2002:a5d:4b12:: with SMTP id v18mr1932634wrq.348.1559560043618; Mon, 03 Jun 2019 04:07:23 -0700 (PDT) Return-Path: Received: from [192.168.1.38] (183.red-88-21-202.staticip.rima-tde.net. [88.21.202.183]) by smtp.gmail.com with ESMTPSA id s14sm12069206wrw.10.2019.06.03.04.07.22 (version=TLS1_3 cipher=AEAD-AES128-GCM-SHA256 bits=128/128); Mon, 03 Jun 2019 04:07:23 -0700 (PDT) Subject: Re: [edk2-devel] [PATCH for-edk2-stable201905 6/6] OvmfPkg/PlatformPei: set 32-bit UC area at PciBase / PciExBarBase (pc/q35) To: devel@edk2.groups.io, lersek@redhat.com Cc: Ard Biesheuvel , Gerd Hoffmann , Jordan Justen References: <20190529151209.17503-1-lersek@redhat.com> <20190529151209.17503-7-lersek@redhat.com> From: =?UTF-8?B?UGhpbGlwcGUgTWF0aGlldS1EYXVkw6k=?= Openpgp: id=89C1E78F601EE86C867495CBA2A3FD6EDEADC0DE; url=http://pgp.mit.edu/pks/lookup?op=get&search=0xA2A3FD6EDEADC0DE Message-ID: Date: Mon, 3 Jun 2019 13:07:22 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.6.1 MIME-Version: 1.0 In-Reply-To: <20190529151209.17503-7-lersek@redhat.com> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit On 5/29/19 5:12 PM, Laszlo Ersek wrote: > (This is a replacement for commit 39b9a5ffe661 ("OvmfPkg/PlatformPei: fix > MTRR for low-RAM sizes that have many bits clear", 2019-05-16).) > > Reintroduce the same logic as seen in commit 39b9a5ffe661 for the pc > (i440fx) board type. > > For q35, the same approach doesn't work any longer, given that (a) we'd > like to keep the PCIEXBAR in the platform DSC a fixed-at-build PCD, and > (b) QEMU expects the PCIEXBAR to reside at a lower address than the 32-bit > PCI MMIO aperture. > > Therefore, introduce a helper function for determining the 32-bit > "uncacheable" (MMIO) area base address: > > - On q35, this function behaves statically. Furthermore, the MTRR setup > exploits that the range [0xB000_0000, 0xFFFF_FFFF] can be marked UC with > just two variable MTRRs (one at 0xB000_0000 (size 256MB), another at > 0xC000_0000 (size 1GB)). > > - On pc (i440fx), the function behaves dynamically, implementing the same > logic as commit 39b9a5ffe661 did. The PciBase value is adjusted to the > value calculated, similarly to commit 39b9a5ffe661. A further > simplification is that we show that the UC32 area size truncation to a > whole power of two automatically guarantees a >=2GB base address. > > Cc: Ard Biesheuvel > Cc: Gerd Hoffmann > Cc: Jordan Justen > Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1859 > Signed-off-by: Laszlo Ersek Reviewed-by: Philippe Mathieu-Daude > --- > OvmfPkg/PlatformPei/Platform.h | 7 +++ > OvmfPkg/PlatformPei/MemDetect.c | 59 ++++++++++++++++++-- > OvmfPkg/PlatformPei/Platform.c | 5 +- > 3 files changed, 66 insertions(+), 5 deletions(-) > > diff --git a/OvmfPkg/PlatformPei/Platform.h b/OvmfPkg/PlatformPei/Platform.h > index 81af8b71480f..2f3cebcd3a6a 100644 > --- a/OvmfPkg/PlatformPei/Platform.h > +++ b/OvmfPkg/PlatformPei/Platform.h > @@ -62,6 +62,11 @@ GetSystemMemorySizeBelow4gb ( > VOID > ); > > +VOID > +QemuUc32BaseInitialization ( > + VOID > + ); > + > VOID > InitializeRamRegions ( > VOID > @@ -114,4 +119,6 @@ extern UINT32 mMaxCpuCount; > > extern UINT16 mHostBridgeDevId; > > +extern UINT32 mQemuUc32Base; > + > #endif // _PLATFORM_PEI_H_INCLUDED_ > diff --git a/OvmfPkg/PlatformPei/MemDetect.c b/OvmfPkg/PlatformPei/MemDetect.c > index e890e36408a6..d451989f31c9 100644 > --- a/OvmfPkg/PlatformPei/MemDetect.c > +++ b/OvmfPkg/PlatformPei/MemDetect.c > @@ -14,6 +14,7 @@ Module Name: > // The package level header files this module uses > // > #include > +#include > #include > #include > > @@ -42,6 +43,8 @@ STATIC UINT32 mS3AcpiReservedMemorySize; > > STATIC UINT16 mQ35TsegMbytes; > > +UINT32 mQemuUc32Base; > + > VOID > Q35TsegMbytesInitialization ( > VOID > @@ -98,6 +101,54 @@ Q35TsegMbytesInitialization ( > } > > > +VOID > +QemuUc32BaseInitialization ( > + VOID > + ) > +{ > + UINT32 LowerMemorySize; > + UINT32 Uc32Size; > + > + if (mXen) { > + return; > + } > + > + if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) { > + // > + // On q35, the 32-bit area that we'll mark as UC, through variable MTRRs, > + // starts at PcdPciExpressBaseAddress. The platform DSC is responsible for > + // setting PcdPciExpressBaseAddress such that describing the > + // [PcdPciExpressBaseAddress, 4GB) range require a very small number of > + // variable MTRRs (preferably 1 or 2). > + // > + ASSERT (FixedPcdGet64 (PcdPciExpressBaseAddress) <= MAX_UINT32); > + mQemuUc32Base = (UINT32)FixedPcdGet64 (PcdPciExpressBaseAddress); > + return; > + } > + > + ASSERT (mHostBridgeDevId == INTEL_82441_DEVICE_ID); > + // > + // On i440fx, start with the [LowerMemorySize, 4GB) range. Make sure one > + // variable MTRR suffices by truncating the size to a whole power of two, > + // while keeping the end affixed to 4GB. This will round the base up. > + // > + LowerMemorySize = GetSystemMemorySizeBelow4gb (); > + Uc32Size = GetPowerOfTwo32 ((UINT32)(SIZE_4GB - LowerMemorySize)); > + mQemuUc32Base = (UINT32)(SIZE_4GB - Uc32Size); > + // > + // Assuming that LowerMemorySize is at least 1 byte, Uc32Size is at most 2GB. > + // Therefore mQemuUc32Base is at least 2GB. > + // > + ASSERT (mQemuUc32Base >= BASE_2GB); > + > + if (mQemuUc32Base != LowerMemorySize) { > + DEBUG ((DEBUG_VERBOSE, "%a: rounded UC32 base from 0x%x up to 0x%x, for " > + "an UC32 size of 0x%x\n", __FUNCTION__, LowerMemorySize, mQemuUc32Base, > + Uc32Size)); > + } > +} > + > + > /** > Iterate over the RAM entries in QEMU's fw_cfg E820 RAM map that start outside > of the 32-bit address range. > @@ -688,11 +739,11 @@ QemuInitializeRam ( > ASSERT_EFI_ERROR (Status); > > // > - // Set memory range from the "top of lower RAM" (RAM below 4GB) to 4GB as > - // uncacheable > + // Set the memory range from the start of the 32-bit MMIO area (32-bit PCI > + // MMIO aperture on i440fx, PCIEXBAR on q35) to 4GB as uncacheable. > // > - Status = MtrrSetMemoryAttribute (LowerMemorySize, > - SIZE_4GB - LowerMemorySize, CacheUncacheable); > + Status = MtrrSetMemoryAttribute (mQemuUc32Base, SIZE_4GB - mQemuUc32Base, > + CacheUncacheable); > ASSERT_EFI_ERROR (Status); > } > } > diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c > index 0876316eefbc..3ba2459872d9 100644 > --- a/OvmfPkg/PlatformPei/Platform.c > +++ b/OvmfPkg/PlatformPei/Platform.c > @@ -191,7 +191,8 @@ MemMapInitialization ( > ASSERT (PciExBarBase <= MAX_UINT32 - SIZE_256MB); > PciBase = (UINT32)(PciExBarBase + SIZE_256MB); > } else { > - PciBase = (TopOfLowRam < BASE_2GB) ? BASE_2GB : TopOfLowRam; > + ASSERT (TopOfLowRam <= mQemuUc32Base); > + PciBase = mQemuUc32Base; > } > > // > @@ -650,6 +651,8 @@ InitializePlatform ( > > PublishPeiMemory (); > > + QemuUc32BaseInitialization (); > + > InitializeRamRegions (); > > if (mXen) { >