From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by mx.groups.io with SMTP id smtpd.web08.9091.1645271832752102625 for ; Sat, 19 Feb 2022 03:58:15 -0800 Authentication-Results: mx.groups.io; dkim=fail reason="unable to parse pub key" header.i=@intel.com header.s=intel header.b=gfeW8279; spf=pass (domain: intel.com, ip: 192.55.52.151, mailfrom: min.m.xu@intel.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1645271895; x=1676807895; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=DetUimqtjCA//W/pkLXNYK58lV5C/rsTY34UgiuCpmQ=; b=gfeW8279/e0bz7casFzII1blcgY5MQZQhrMC94RyGgn/MNR0Lj4TbOLA PiR++gOKsfneEFKEsymWYEVOc04buMV1PXIBceDGTcBTxjo7NGqtxu0zG OLS3jMJcBzOU54f/w2O+vvGqNxEzXR4LB5X3kHroM7+nqAwUMMd65sG8t /UWznCYPXJdYVemoF/NN9/CAIOnCqq97iTRIC4VKjyRzJuP586O8KL59t 06QOBYrwOZgjClMSrGGG3Jy5XKnUp8TFYhUvlqZZL6nx8p1RDjBu78JxL iPiw/NgyXZyoU+PM05ql96w1upOb7OoCWRYcg+4NooCk6QJ1+joWq5pFv w==; X-IronPort-AV: E=McAfee;i="6200,9189,10262"; a="231915457" X-IronPort-AV: E=Sophos;i="5.88,381,1635231600"; d="scan'208";a="231915457" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Feb 2022 03:58:15 -0800 X-IronPort-AV: E=Sophos;i="5.88,381,1635231600"; d="scan'208";a="546691254" Received: from mxu9-mobl1.ccr.corp.intel.com ([10.249.175.253]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Feb 2022 03:58:12 -0800 From: "Min Xu" To: devel@edk2.groups.io Cc: Min Xu , Ard Biesheuvel , Jordan Justen , Brijesh Singh , Erdem Aktas , James Bottomley , Jiewen Yao , Tom Lendacky , Gerd Hoffmann Subject: [PATCH V6 22/42] OvmfPkg/PlatformPei: Update memory functions with PlatformInitLib Date: Sat, 19 Feb 2022 19:56:35 +0800 Message-Id: <87fde5906c7c53c8af7f3e13b72355f0983ec9a1.1645261990.git.min.m.xu@intel.com> X-Mailer: git-send-email 2.29.2.windows.2 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3429 Memory functions in OvmfPkg/PlatformPei are updated with the ones in PlatformInitLib. Cc: Ard Biesheuvel Cc: Jordan Justen Cc: Brijesh Singh Cc: Erdem Aktas Cc: James Bottomley Cc: Jiewen Yao Cc: Tom Lendacky Cc: Gerd Hoffmann Signed-off-by: Min Xu --- OvmfPkg/PlatformPei/MemDetect.c | 654 ++------------------------------ OvmfPkg/PlatformPei/Platform.c | 9 +- OvmfPkg/PlatformPei/Platform.h | 5 - 3 files changed, 34 insertions(+), 634 deletions(-) diff --git a/OvmfPkg/PlatformPei/MemDetect.c b/OvmfPkg/PlatformPei/MemDetect.c index d19a344d18b8..9b62625f9d91 100644 --- a/OvmfPkg/PlatformPei/MemDetect.c +++ b/OvmfPkg/PlatformPei/MemDetect.c @@ -50,6 +50,7 @@ STATIC UINT16 mQ35TsegMbytes; BOOLEAN mQ35SmramAtDefaultSmbase; UINT32 mQemuUc32Base; +UINT32 mLowerMemorySize = 0; VOID Q35TsegMbytesInitialization ( @@ -140,406 +141,11 @@ QemuUc32BaseInitialization ( VOID ) { - UINT32 LowerMemorySize; - UINT32 Uc32Size; - if (mHostBridgeDevId == 0xffff /* microvm */) { 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; - } - - if (mHostBridgeDevId == CLOUDHV_DEVICE_ID) { - Uc32Size = CLOUDHV_MMIO_HOLE_SIZE; - mQemuUc32Base = CLOUDHV_MMIO_HOLE_ADDRESS; - 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. - - Find the highest exclusive >=4GB RAM address, or produce memory resource - descriptor HOBs for RAM entries that start at or above 4GB. - - @param[out] MaxAddress If MaxAddress is NULL, then ScanOrAdd64BitE820Ram() - produces memory resource descriptor HOBs for RAM - entries that start at or above 4GB. - - Otherwise, MaxAddress holds the highest exclusive - >=4GB RAM address on output. If QEMU's fw_cfg E820 - RAM map contains no RAM entry that starts outside of - the 32-bit address range, then MaxAddress is exactly - 4GB on output. - - @retval EFI_SUCCESS The fw_cfg E820 RAM map was found and processed. - - @retval EFI_PROTOCOL_ERROR The RAM map was found, but its size wasn't a - whole multiple of sizeof(EFI_E820_ENTRY64). No - RAM entry was processed. - - @return Error codes from QemuFwCfgFindFile(). No RAM - entry was processed. -**/ -STATIC -EFI_STATUS -ScanOrAdd64BitE820Ram ( - IN BOOLEAN AddHighHob, - OUT UINT64 *LowMemory OPTIONAL, - OUT UINT64 *MaxAddress OPTIONAL - ) -{ - EFI_STATUS Status; - FIRMWARE_CONFIG_ITEM FwCfgItem; - UINTN FwCfgSize; - EFI_E820_ENTRY64 E820Entry; - UINTN Processed; - - Status = QemuFwCfgFindFile ("etc/e820", &FwCfgItem, &FwCfgSize); - if (EFI_ERROR (Status)) { - return Status; - } - - if (FwCfgSize % sizeof E820Entry != 0) { - return EFI_PROTOCOL_ERROR; - } - - if (LowMemory != NULL) { - *LowMemory = 0; - } - - if (MaxAddress != NULL) { - *MaxAddress = BASE_4GB; - } - - QemuFwCfgSelectItem (FwCfgItem); - for (Processed = 0; Processed < FwCfgSize; Processed += sizeof E820Entry) { - QemuFwCfgReadBytes (sizeof E820Entry, &E820Entry); - DEBUG (( - DEBUG_VERBOSE, - "%a: Base=0x%Lx Length=0x%Lx Type=%u\n", - __FUNCTION__, - E820Entry.BaseAddr, - E820Entry.Length, - E820Entry.Type - )); - if (E820Entry.Type == EfiAcpiAddressRangeMemory) { - if (AddHighHob && (E820Entry.BaseAddr >= BASE_4GB)) { - UINT64 Base; - UINT64 End; - - // - // Round up the start address, and round down the end address. - // - Base = ALIGN_VALUE (E820Entry.BaseAddr, (UINT64)EFI_PAGE_SIZE); - End = (E820Entry.BaseAddr + E820Entry.Length) & - ~(UINT64)EFI_PAGE_MASK; - if (Base < End) { - PlatformAddMemoryRangeHob (Base, End); - DEBUG (( - DEBUG_VERBOSE, - "%a: PlatformAddMemoryRangeHob [0x%Lx, 0x%Lx)\n", - __FUNCTION__, - Base, - End - )); - } - } - - if (MaxAddress || LowMemory) { - UINT64 Candidate; - - Candidate = E820Entry.BaseAddr + E820Entry.Length; - if (MaxAddress && (Candidate > *MaxAddress)) { - *MaxAddress = Candidate; - DEBUG (( - DEBUG_VERBOSE, - "%a: MaxAddress=0x%Lx\n", - __FUNCTION__, - *MaxAddress - )); - } - - if (LowMemory && (Candidate > *LowMemory) && (Candidate < BASE_4GB)) { - *LowMemory = Candidate; - DEBUG (( - DEBUG_VERBOSE, - "%a: LowMemory=0x%Lx\n", - __FUNCTION__, - *LowMemory - )); - } - } - } - } - - return EFI_SUCCESS; -} - -UINT32 -GetSystemMemorySizeBelow4gb ( - VOID - ) -{ - EFI_STATUS Status; - UINT64 LowerMemorySize = 0; - UINT8 Cmos0x34; - UINT8 Cmos0x35; - - Status = ScanOrAdd64BitE820Ram (FALSE, &LowerMemorySize, NULL); - if ((Status == EFI_SUCCESS) && (LowerMemorySize > 0)) { - return (UINT32)LowerMemorySize; - } - - // - // CMOS 0x34/0x35 specifies the system memory above 16 MB. - // * CMOS(0x35) is the high byte - // * CMOS(0x34) is the low byte - // * The size is specified in 64kb chunks - // * Since this is memory above 16MB, the 16MB must be added - // into the calculation to get the total memory size. - // - - Cmos0x34 = (UINT8)PlatformCmosRead8 (0x34); - Cmos0x35 = (UINT8)PlatformCmosRead8 (0x35); - - return (UINT32)(((UINTN)((Cmos0x35 << 8) + Cmos0x34) << 16) + SIZE_16MB); -} - -STATIC -UINT64 -GetSystemMemorySizeAbove4gb ( - ) -{ - UINT32 Size; - UINTN CmosIndex; - - // - // CMOS 0x5b-0x5d specifies the system memory above 4GB MB. - // * CMOS(0x5d) is the most significant size byte - // * CMOS(0x5c) is the middle size byte - // * CMOS(0x5b) is the least significant size byte - // * The size is specified in 64kb chunks - // - - Size = 0; - for (CmosIndex = 0x5d; CmosIndex >= 0x5b; CmosIndex--) { - Size = (UINT32)(Size << 8) + (UINT32)PlatformCmosRead8 (CmosIndex); - } - - return LShiftU64 (Size, 16); -} - -/** - Return the highest address that DXE could possibly use, plus one. -**/ -STATIC -UINT64 -GetFirstNonAddress ( - VOID - ) -{ - UINT64 FirstNonAddress; - UINT64 Pci64Base, Pci64Size; - UINT32 FwCfgPciMmio64Mb; - EFI_STATUS Status; - FIRMWARE_CONFIG_ITEM FwCfgItem; - UINTN FwCfgSize; - UINT64 HotPlugMemoryEnd; - RETURN_STATUS PcdStatus; - - // - // set FirstNonAddress to suppress incorrect compiler/analyzer warnings - // - FirstNonAddress = 0; - - // - // If QEMU presents an E820 map, then get the highest exclusive >=4GB RAM - // address from it. This can express an address >= 4GB+1TB. - // - // Otherwise, get the flat size of the memory above 4GB from the CMOS (which - // can only express a size smaller than 1TB), and add it to 4GB. - // - Status = ScanOrAdd64BitE820Ram (FALSE, NULL, &FirstNonAddress); - if (EFI_ERROR (Status)) { - FirstNonAddress = BASE_4GB + GetSystemMemorySizeAbove4gb (); - } - - // - // If DXE is 32-bit, then we're done; PciBusDxe will degrade 64-bit MMIO - // resources to 32-bit anyway. See DegradeResource() in - // "PciResourceSupport.c". - // - #ifdef MDE_CPU_IA32 - if (!FeaturePcdGet (PcdDxeIplSwitchToLongMode)) { - return FirstNonAddress; - } - - #endif - - // - // Otherwise, in order to calculate the highest address plus one, we must - // consider the 64-bit PCI host aperture too. Fetch the default size. - // - Pci64Size = PcdGet64 (PcdPciMmio64Size); - - // - // See if the user specified the number of megabytes for the 64-bit PCI host - // aperture. Accept an aperture size up to 16TB. - // - // As signaled by the "X-" prefix, this knob is experimental, and might go - // away at any time. - // - Status = QemuFwCfgParseUint32 ( - "opt/ovmf/X-PciMmio64Mb", - FALSE, - &FwCfgPciMmio64Mb - ); - switch (Status) { - case EFI_UNSUPPORTED: - case EFI_NOT_FOUND: - break; - case EFI_SUCCESS: - if (FwCfgPciMmio64Mb <= 0x1000000) { - Pci64Size = LShiftU64 (FwCfgPciMmio64Mb, 20); - break; - } - - // - // fall through - // - default: - DEBUG (( - DEBUG_WARN, - "%a: ignoring malformed 64-bit PCI host aperture size from fw_cfg\n", - __FUNCTION__ - )); - break; - } - - if (Pci64Size == 0) { - if (mBootMode != BOOT_ON_S3_RESUME) { - DEBUG (( - DEBUG_INFO, - "%a: disabling 64-bit PCI host aperture\n", - __FUNCTION__ - )); - PcdStatus = PcdSet64S (PcdPciMmio64Size, 0); - ASSERT_RETURN_ERROR (PcdStatus); - } - - // - // There's nothing more to do; the amount of memory above 4GB fully - // determines the highest address plus one. The memory hotplug area (see - // below) plays no role for the firmware in this case. - // - return FirstNonAddress; - } - - // - // The "etc/reserved-memory-end" fw_cfg file, when present, contains an - // absolute, exclusive end address for the memory hotplug area. This area - // starts right at the end of the memory above 4GB. The 64-bit PCI host - // aperture must be placed above it. - // - Status = QemuFwCfgFindFile ( - "etc/reserved-memory-end", - &FwCfgItem, - &FwCfgSize - ); - if (!EFI_ERROR (Status) && (FwCfgSize == sizeof HotPlugMemoryEnd)) { - QemuFwCfgSelectItem (FwCfgItem); - QemuFwCfgReadBytes (FwCfgSize, &HotPlugMemoryEnd); - DEBUG (( - DEBUG_VERBOSE, - "%a: HotPlugMemoryEnd=0x%Lx\n", - __FUNCTION__, - HotPlugMemoryEnd - )); - - ASSERT (HotPlugMemoryEnd >= FirstNonAddress); - FirstNonAddress = HotPlugMemoryEnd; - } - - // - // SeaBIOS aligns both boundaries of the 64-bit PCI host aperture to 1GB, so - // that the host can map it with 1GB hugepages. Follow suit. - // - Pci64Base = ALIGN_VALUE (FirstNonAddress, (UINT64)SIZE_1GB); - Pci64Size = ALIGN_VALUE (Pci64Size, (UINT64)SIZE_1GB); - - // - // The 64-bit PCI host aperture should also be "naturally" aligned. The - // alignment is determined by rounding the size of the aperture down to the - // next smaller or equal power of two. That is, align the aperture by the - // largest BAR size that can fit into it. - // - Pci64Base = ALIGN_VALUE (Pci64Base, GetPowerOfTwo64 (Pci64Size)); - - if (mBootMode != BOOT_ON_S3_RESUME) { - // - // The core PciHostBridgeDxe driver will automatically add this range to - // the GCD memory space map through our PciHostBridgeLib instance; here we - // only need to set the PCDs. - // - PcdStatus = PcdSet64S (PcdPciMmio64Base, Pci64Base); - ASSERT_RETURN_ERROR (PcdStatus); - PcdStatus = PcdSet64S (PcdPciMmio64Size, Pci64Size); - ASSERT_RETURN_ERROR (PcdStatus); - - DEBUG (( - DEBUG_INFO, - "%a: Pci64Base=0x%Lx Pci64Size=0x%Lx\n", - __FUNCTION__, - Pci64Base, - Pci64Size - )); - } - - // - // The useful address space ends with the 64-bit PCI host aperture. - // - FirstNonAddress = Pci64Base + Pci64Size; - return FirstNonAddress; + mQemuUc32Base = PlatformQemuUc32BaseInitialization (mHostBridgeDevId, mLowerMemorySize); } /** @@ -550,36 +156,19 @@ AddressWidthInitialization ( VOID ) { - UINT64 FirstNonAddress; - - // - // As guest-physical memory size grows, the permanent PEI RAM requirements - // are dominated by the identity-mapping page tables built by the DXE IPL. - // The DXL IPL keys off of the physical address bits advertized in the CPU - // HOB. To conserve memory, we calculate the minimum address width here. - // - FirstNonAddress = GetFirstNonAddress (); - mPhysMemAddressWidth = (UINT8)HighBitSet64 (FirstNonAddress); - - // - // If FirstNonAddress is not an integral power of two, then we need an - // additional bit. - // - if ((FirstNonAddress & (FirstNonAddress - 1)) != 0) { - ++mPhysMemAddressWidth; - } - - // - // The minimum address width is 36 (covers up to and excluding 64 GB, which - // is the maximum for Ia32 + PAE). The theoretical architecture maximum for - // X64 long mode is 52 bits, but the DXE IPL clamps that down to 48 bits. We - // can simply assert that here, since 48 bits are good enough for 256 TB. - // - if (mPhysMemAddressWidth <= 36) { - mPhysMemAddressWidth = 36; - } - - ASSERT (mPhysMemAddressWidth <= 48); + UINT64 Pci64Base; + UINT64 Pci64Size; + UINT64 FirstNonAddress; + RETURN_STATUS PcdStatus; + + Pci64Base = 0; + Pci64Size = 0; + FirstNonAddress = PlatformGetFirstNonAddress (&Pci64Base, &Pci64Size, PcdGet64 (PcdPciMmio64Size)); + mPhysMemAddressWidth = PlatformAddressWidthInitialization (FirstNonAddress); + PcdStatus = PcdSet64S (PcdPciMmio64Base, Pci64Base); + ASSERT_RETURN_ERROR (PcdStatus); + PcdStatus = PcdSet64S (PcdPciMmio64Size, Pci64Size); + ASSERT_RETURN_ERROR (PcdStatus); } /** @@ -664,7 +253,7 @@ PublishPeiMemory ( UINT32 LowerMemorySize; UINT32 PeiMemoryCap; - LowerMemorySize = GetSystemMemorySizeBelow4gb (); + LowerMemorySize = PlatformGetSystemMemorySizeBelow4gb (); if (FeaturePcdGet (PcdSmmSmramRequire)) { // // TSEG is chipped from the end of low RAM @@ -736,162 +325,6 @@ PublishPeiMemory ( return Status; } -STATIC -VOID -QemuInitializeRamBelow1gb ( - VOID - ) -{ - if (FeaturePcdGet (PcdSmmSmramRequire) && mQ35SmramAtDefaultSmbase) { - PlatformAddMemoryRangeHob (0, SMM_DEFAULT_SMBASE); - PlatformAddReservedMemoryBaseSizeHob ( - SMM_DEFAULT_SMBASE, - MCH_DEFAULT_SMBASE_SIZE, - TRUE /* Cacheable */ - ); - STATIC_ASSERT ( - SMM_DEFAULT_SMBASE + MCH_DEFAULT_SMBASE_SIZE < BASE_512KB + BASE_128KB, - "end of SMRAM at default SMBASE ends at, or exceeds, 640KB" - ); - PlatformAddMemoryRangeHob ( - SMM_DEFAULT_SMBASE + MCH_DEFAULT_SMBASE_SIZE, - BASE_512KB + BASE_128KB - ); - } else { - PlatformAddMemoryRangeHob (0, BASE_512KB + BASE_128KB); - } -} - -/** - Peform Memory Detection for QEMU / KVM - -**/ -STATIC -VOID -QemuInitializeRam ( - VOID - ) -{ - UINT64 LowerMemorySize; - UINT64 UpperMemorySize; - MTRR_SETTINGS MtrrSettings; - EFI_STATUS Status; - - DEBUG ((DEBUG_INFO, "%a called\n", __FUNCTION__)); - - // - // Determine total memory size available - // - LowerMemorySize = GetSystemMemorySizeBelow4gb (); - - if (mBootMode == BOOT_ON_S3_RESUME) { - // - // Create the following memory HOB as an exception on the S3 boot path. - // - // Normally we'd create memory HOBs only on the normal boot path. However, - // CpuMpPei specifically needs such a low-memory HOB on the S3 path as - // well, for "borrowing" a subset of it temporarily, for the AP startup - // vector. - // - // CpuMpPei saves the original contents of the borrowed area in permanent - // PEI RAM, in a backup buffer allocated with the normal PEI services. - // CpuMpPei restores the original contents ("returns" the borrowed area) at - // End-of-PEI. End-of-PEI in turn is emitted by S3Resume2Pei before - // transferring control to the OS's wakeup vector in the FACS. - // - // We expect any other PEIMs that "borrow" memory similarly to CpuMpPei to - // restore the original contents. Furthermore, we expect all such PEIMs - // (CpuMpPei included) to claim the borrowed areas by producing memory - // allocation HOBs, and to honor preexistent memory allocation HOBs when - // looking for an area to borrow. - // - QemuInitializeRamBelow1gb (); - } else { - // - // Create memory HOBs - // - QemuInitializeRamBelow1gb (); - - if (FeaturePcdGet (PcdSmmSmramRequire)) { - UINT32 TsegSize; - - TsegSize = mQ35TsegMbytes * SIZE_1MB; - PlatformAddMemoryRangeHob (BASE_1MB, LowerMemorySize - TsegSize); - PlatformAddReservedMemoryBaseSizeHob ( - LowerMemorySize - TsegSize, - TsegSize, - TRUE - ); - } else { - PlatformAddMemoryRangeHob (BASE_1MB, LowerMemorySize); - } - - // - // If QEMU presents an E820 map, then create memory HOBs for the >=4GB RAM - // entries. Otherwise, create a single memory HOB with the flat >=4GB - // memory size read from the CMOS. - // - Status = ScanOrAdd64BitE820Ram (TRUE, NULL, NULL); - if (EFI_ERROR (Status)) { - UpperMemorySize = GetSystemMemorySizeAbove4gb (); - if (UpperMemorySize != 0) { - PlatformAddMemoryBaseSizeHob (BASE_4GB, UpperMemorySize); - } - } - } - - // - // We'd like to keep the following ranges uncached: - // - [640 KB, 1 MB) - // - [LowerMemorySize, 4 GB) - // - // Everything else should be WB. Unfortunately, programming the inverse (ie. - // keeping the default UC, and configuring the complement set of the above as - // WB) is not reliable in general, because the end of the upper RAM can have - // practically any alignment, and we may not have enough variable MTRRs to - // cover it exactly. - // - if (IsMtrrSupported () && (mHostBridgeDevId != CLOUDHV_DEVICE_ID)) { - MtrrGetAllMtrrs (&MtrrSettings); - - // - // MTRRs disabled, fixed MTRRs disabled, default type is uncached - // - ASSERT ((MtrrSettings.MtrrDefType & BIT11) == 0); - ASSERT ((MtrrSettings.MtrrDefType & BIT10) == 0); - ASSERT ((MtrrSettings.MtrrDefType & 0xFF) == 0); - - // - // flip default type to writeback - // - SetMem (&MtrrSettings.Fixed, sizeof MtrrSettings.Fixed, 0x06); - ZeroMem (&MtrrSettings.Variables, sizeof MtrrSettings.Variables); - MtrrSettings.MtrrDefType |= BIT11 | BIT10 | 6; - MtrrSetAllMtrrs (&MtrrSettings); - - // - // Set memory range from 640KB to 1MB to uncacheable - // - Status = MtrrSetMemoryAttribute ( - BASE_512KB + BASE_128KB, - BASE_1MB - (BASE_512KB + BASE_128KB), - CacheUncacheable - ); - ASSERT_EFI_ERROR (Status); - - // - // 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 ( - mQemuUc32Base, - SIZE_4GB - mQemuUc32Base, - CacheUncacheable - ); - ASSERT_EFI_ERROR (Status); - } -} - /** Publish system RAM and reserve memory regions @@ -901,7 +334,15 @@ InitializeRamRegions ( VOID ) { - QemuInitializeRam (); + PlatformInitializeRamRegions ( + mQemuUc32Base, + mHostBridgeDevId, + FeaturePcdGet (PcdSmmSmramRequire), + mBootMode, + mS3Supported, + mLowerMemorySize, + mQ35TsegMbytes + ); SevInitializeRam (); @@ -979,28 +420,6 @@ InitializeRamRegions ( } if (mBootMode != BOOT_ON_S3_RESUME) { - if (!FeaturePcdGet (PcdSmmSmramRequire)) { - // - // Reserve the lock box storage area - // - // Since this memory range will be used on S3 resume, it must be - // reserved as ACPI NVS. - // - // If S3 is unsupported, then various drivers might still write to the - // LockBox area. We ought to prevent DXE from serving allocation requests - // such that they would overlap the LockBox storage. - // - ZeroMem ( - (VOID *)(UINTN)PcdGet32 (PcdOvmfLockBoxStorageBase), - (UINTN)PcdGet32 (PcdOvmfLockBoxStorageSize) - ); - BuildMemoryAllocationHob ( - (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdOvmfLockBoxStorageBase), - (UINT64)(UINTN)PcdGet32 (PcdOvmfLockBoxStorageSize), - mS3Supported ? EfiACPIMemoryNVS : EfiBootServicesData - ); - } - if (FeaturePcdGet (PcdSmmSmramRequire)) { UINT32 TsegSize; @@ -1010,7 +429,7 @@ InitializeRamRegions ( // TsegSize = mQ35TsegMbytes * SIZE_1MB; BuildMemoryAllocationHob ( - GetSystemMemorySizeBelow4gb () - TsegSize, + PlatformGetSystemMemorySizeBelow4gb () - TsegSize, TsegSize, EfiReservedMemoryType ); @@ -1026,26 +445,5 @@ InitializeRamRegions ( ); } } - - #ifdef MDE_CPU_X64 - if (FixedPcdGet32 (PcdOvmfWorkAreaSize) != 0) { - // - // Reserve the work area. - // - // Since this memory range will be used by the Reset Vector on S3 - // resume, it must be reserved as ACPI NVS. - // - // If S3 is unsupported, then various drivers might still write to the - // work area. We ought to prevent DXE from serving allocation requests - // such that they would overlap the work area. - // - BuildMemoryAllocationHob ( - (EFI_PHYSICAL_ADDRESS)(UINTN)FixedPcdGet32 (PcdOvmfWorkAreaBase), - (UINT64)(UINTN)FixedPcdGet32 (PcdOvmfWorkAreaSize), - mS3Supported ? EfiACPIMemoryNVS : EfiBootServicesData - ); - } - - #endif } } diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c index 62480c3c40e5..7e98f97c8480 100644 --- a/OvmfPkg/PlatformPei/Platform.c +++ b/OvmfPkg/PlatformPei/Platform.c @@ -57,6 +57,8 @@ BOOLEAN mS3Supported = FALSE; UINT32 mMaxCpuCount; +extern UINT32 mLowerMemorySize; + VOID MemMapInitialization ( VOID @@ -85,7 +87,7 @@ MemMapInitialization ( return; } - TopOfLowRam = GetSystemMemorySizeBelow4gb (); + TopOfLowRam = PlatformGetSystemMemorySizeBelow4gb (); PciExBarBase = 0; if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) { // @@ -736,6 +738,11 @@ InitializePlatform ( Q35SmramAtDefaultSmbaseInitialization (); } + // + // Fetch the lower memory size (Below 4G) + // + mLowerMemorySize = PlatformGetSystemMemorySizeBelow4gb (); + PublishPeiMemory (); QemuUc32BaseInitialization (); diff --git a/OvmfPkg/PlatformPei/Platform.h b/OvmfPkg/PlatformPei/Platform.h index f193ff736549..64af9cde1002 100644 --- a/OvmfPkg/PlatformPei/Platform.h +++ b/OvmfPkg/PlatformPei/Platform.h @@ -31,11 +31,6 @@ PublishPeiMemory ( VOID ); -UINT32 -GetSystemMemorySizeBelow4gb ( - VOID - ); - VOID QemuUc32BaseInitialization ( VOID -- 2.29.2.windows.2