From: "Gerd Hoffmann" <kraxel@redhat.com>
To: Min Xu <min.m.xu@intel.com>
Cc: devel@edk2.groups.io, Ard Biesheuvel <ardb+tianocore@kernel.org>,
Jordan Justen <jordan.l.justen@intel.com>,
Brijesh Singh <brijesh.singh@amd.com>,
Erdem Aktas <erdemaktas@google.com>,
James Bottomley <jejb@linux.ibm.com>,
Jiewen Yao <jiewen.yao@intel.com>,
Tom Lendacky <thomas.lendacky@amd.com>,
Sebastien Boeuf <sebastien.boeuf@intel.com>
Subject: Re: [PATCH V8 28/47] OvmfPkg/PlatformInitLib: Create MemDetect.c
Date: Tue, 15 Mar 2022 09:14:57 +0100 [thread overview]
Message-ID: <20220315081457.6ykewdihqwrn7jt4@sirius.home.kraxel.org> (raw)
In-Reply-To: <a96ba6b2276aac339822791ed538640951479805.1647047482.git.min.m.xu@intel.com>
On Sat, Mar 12, 2022 at 09:53:53AM +0800, Min Xu wrote:
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3863
>
> Move functions in PlatformPei\MemDetect.c to PlatformInitLib\MemDetect.c.
>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Brijesh Singh <brijesh.singh@amd.com>
> Cc: Erdem Aktas <erdemaktas@google.com>
> Cc: James Bottomley <jejb@linux.ibm.com>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Tom Lendacky <thomas.lendacky@amd.com>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Cc: Sebastien Boeuf <sebastien.boeuf@intel.com>
> Signed-off-by: Min Xu <min.m.xu@intel.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
> OvmfPkg/Include/Library/PlatformInitLib.h | 37 +
> OvmfPkg/Library/PlatformInitLib/MemDetect.c | 842 ++++++++++++++++++
> .../PlatformInitLib/PlatformInitLib.inf | 49 +
> OvmfPkg/PlatformPei/MemDetect.c | 804 +----------------
> OvmfPkg/PlatformPei/Platform.h | 12 -
> 5 files changed, 929 insertions(+), 815 deletions(-)
> create mode 100644 OvmfPkg/Library/PlatformInitLib/MemDetect.c
>
> diff --git a/OvmfPkg/Include/Library/PlatformInitLib.h b/OvmfPkg/Include/Library/PlatformInitLib.h
> index 9b99d4c1f514..2e4bb8140368 100644
> --- a/OvmfPkg/Include/Library/PlatformInitLib.h
> +++ b/OvmfPkg/Include/Library/PlatformInitLib.h
> @@ -132,4 +132,41 @@ PlatformAddReservedMemoryBaseSizeHob (
> IN BOOLEAN Cacheable
> );
>
> +VOID
> +EFIAPI
> +PlatformQemuUc32BaseInitialization (
> + IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob
> + );
> +
> +UINT32
> +EFIAPI
> +PlatformGetSystemMemorySizeBelow4gb (
> + IN EFI_HOB_PLATFORM_INFO *PlatformInfoHob
> + );
> +
> +/**
> + Initialize the mPhysMemAddressWidth variable, based on guest RAM size.
> +**/
> +VOID
> +EFIAPI
> +PlatformAddressWidthInitialization (
> + IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob
> + );
> +
> +/**
> + Peform Memory Detection for QEMU / KVM
> +
> +**/
> +VOID
> +EFIAPI
> +PlatformQemuInitializeRam (
> + IN EFI_HOB_PLATFORM_INFO *PlatformInfoHob
> + );
> +
> +VOID
> +EFIAPI
> +PlatformQemuInitializeRamForS3 (
> + IN EFI_HOB_PLATFORM_INFO *PlatformInfoHob
> + );
> +
> #endif // PLATFORM_INIT_LIB_H_
> diff --git a/OvmfPkg/Library/PlatformInitLib/MemDetect.c b/OvmfPkg/Library/PlatformInitLib/MemDetect.c
> new file mode 100644
> index 000000000000..fbd3073bd3d1
> --- /dev/null
> +++ b/OvmfPkg/Library/PlatformInitLib/MemDetect.c
> @@ -0,0 +1,842 @@
> +/**@file
> + Memory Detection for Virtual Machines.
> +
> + Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +Module Name:
> +
> + MemDetect.c
> +
> +**/
> +
> +//
> +// The package level header files this module uses
> +//
> +#include <IndustryStandard/E820.h>
> +#include <IndustryStandard/I440FxPiix4.h>
> +#include <IndustryStandard/Q35MchIch9.h>
> +#include <IndustryStandard/CloudHv.h>
> +#include <IndustryStandard/Xen/arch-x86/hvm/start_info.h>
> +#include <PiPei.h>
> +#include <Register/Intel/SmramSaveStateMap.h>
> +
> +//
> +// The Library classes this module consumes
> +//
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/MemEncryptSevLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/PeimEntryPoint.h>
> +#include <Library/ResourcePublicationLib.h>
> +#include <Library/MtrrLib.h>
> +#include <Library/QemuFwCfgLib.h>
> +#include <Library/QemuFwCfgSimpleParserLib.h>
> +#include <Library/PlatformInitLib.h>
> +
> +VOID
> +EFIAPI
> +PlatformQemuUc32BaseInitialization (
> + IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob
> + )
> +{
> + UINT32 LowerMemorySize;
> +
> + if (PlatformInfoHob->HostBridgeDevId == 0xffff /* microvm */) {
> + return;
> + }
> +
> + if (PlatformInfoHob->HostBridgeDevId == 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);
> + PlatformInfoHob->Uc32Base = (UINT32)FixedPcdGet64 (PcdPciExpressBaseAddress);
> + return;
> + }
> +
> + if (PlatformInfoHob->HostBridgeDevId == CLOUDHV_DEVICE_ID) {
> + PlatformInfoHob->Uc32Size = CLOUDHV_MMIO_HOLE_SIZE;
> + PlatformInfoHob->Uc32Base = CLOUDHV_MMIO_HOLE_ADDRESS;
> + return;
> + }
> +
> + ASSERT (PlatformInfoHob->HostBridgeDevId == 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 = PlatformGetSystemMemorySizeBelow4gb (PlatformInfoHob);
> + PlatformInfoHob->Uc32Size = GetPowerOfTwo32 ((UINT32)(SIZE_4GB - LowerMemorySize));
> + PlatformInfoHob->Uc32Base = (UINT32)(SIZE_4GB - PlatformInfoHob->Uc32Size);
> + //
> + // Assuming that LowerMemorySize is at least 1 byte, Uc32Size is at most 2GB.
> + // Therefore mQemuUc32Base is at least 2GB.
> + //
> + ASSERT (PlatformInfoHob->Uc32Base >= BASE_2GB);
> +
> + if (PlatformInfoHob->Uc32Base != 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,
> + PlatformInfoHob->Uc32Base,
> + PlatformInfoHob->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 PlatformScanOrAdd64BitE820Ram()
> + 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
> +PlatformScanOrAdd64BitE820Ram (
> + 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;
> +}
> +
> +/**
> + Returns PVH memmap
> +
> + @param Entries Pointer to PVH memmap
> + @param Count Number of entries
> +
> + @return EFI_STATUS
> +**/
> +EFI_STATUS
> +GetPvhMemmapEntries (
> + struct hvm_memmap_table_entry **Entries,
> + UINT32 *Count
> + )
> +{
> + UINT32 *PVHResetVectorData;
> + struct hvm_start_info *pvh_start_info;
> +
> + PVHResetVectorData = (VOID *)(UINTN)PcdGet32 (PcdXenPvhStartOfDayStructPtr);
> + if (PVHResetVectorData == 0) {
> + return EFI_NOT_FOUND;
> + }
> +
> + pvh_start_info = (struct hvm_start_info *)(UINTN)PVHResetVectorData[0];
> +
> + *Entries = (struct hvm_memmap_table_entry *)(UINTN)pvh_start_info->memmap_paddr;
> + *Count = pvh_start_info->memmap_entries;
> +
> + return EFI_SUCCESS;
> +}
> +
> +STATIC
> +UINT64
> +GetHighestSystemMemoryAddressFromPvhMemmap (
> + BOOLEAN Below4gb
> + )
> +{
> + struct hvm_memmap_table_entry *Memmap;
> + UINT32 MemmapEntriesCount;
> + struct hvm_memmap_table_entry *Entry;
> + EFI_STATUS Status;
> + UINT32 Loop;
> + UINT64 HighestAddress;
> + UINT64 EntryEnd;
> +
> + HighestAddress = 0;
> +
> + Status = GetPvhMemmapEntries (&Memmap, &MemmapEntriesCount);
> + ASSERT_EFI_ERROR (Status);
> +
> + for (Loop = 0; Loop < MemmapEntriesCount; Loop++) {
> + Entry = Memmap + Loop;
> + EntryEnd = Entry->addr + Entry->size;
> +
> + if ((Entry->type == XEN_HVM_MEMMAP_TYPE_RAM) &&
> + (EntryEnd > HighestAddress))
> + {
> + if (Below4gb && (EntryEnd <= BASE_4GB)) {
> + HighestAddress = EntryEnd;
> + } else if (!Below4gb && (EntryEnd >= BASE_4GB)) {
> + HighestAddress = EntryEnd;
> + }
> + }
> + }
> +
> + return HighestAddress;
> +}
> +
> +UINT32
> +EFIAPI
> +PlatformGetSystemMemorySizeBelow4gb (
> + IN EFI_HOB_PLATFORM_INFO *PlatformInfoHob
> + )
> +{
> + EFI_STATUS Status;
> + UINT64 LowerMemorySize = 0;
> + UINT8 Cmos0x34;
> + UINT8 Cmos0x35;
> +
> + if (PlatformInfoHob->HostBridgeDevId == CLOUDHV_DEVICE_ID) {
> + // Get the information from PVH memmap
> + return (UINT32)GetHighestSystemMemoryAddressFromPvhMemmap (TRUE);
> + }
> +
> + Status = PlatformScanOrAdd64BitE820Ram (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
> +PlatformGetSystemMemorySizeAbove4gb (
> + )
> +{
> + 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
> +PlatformGetFirstNonAddress (
> + IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob
> + )
> +{
> + UINT64 FirstNonAddress;
> + UINT32 FwCfgPciMmio64Mb;
> + EFI_STATUS Status;
> + FIRMWARE_CONFIG_ITEM FwCfgItem;
> + UINTN FwCfgSize;
> + UINT64 HotPlugMemoryEnd;
> +
> + //
> + // 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 = PlatformScanOrAdd64BitE820Ram (FALSE, NULL, &FirstNonAddress);
> + if (EFI_ERROR (Status)) {
> + FirstNonAddress = BASE_4GB + PlatformGetSystemMemorySizeAbove4gb ();
> + }
> +
> + //
> + // 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
> +
> + //
> + // 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) {
> + PlatformInfoHob->PcdPciMmio64Size = 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 (PlatformInfoHob->PcdPciMmio64Size == 0) {
> + if (PlatformInfoHob->BootMode != BOOT_ON_S3_RESUME) {
> + DEBUG ((
> + DEBUG_INFO,
> + "%a: disabling 64-bit PCI host aperture\n",
> + __FUNCTION__
> + ));
> + }
> +
> + //
> + // 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.
> + //
> + PlatformInfoHob->PcdPciMmio64Base = ALIGN_VALUE (FirstNonAddress, (UINT64)SIZE_1GB);
> + PlatformInfoHob->PcdPciMmio64Size = ALIGN_VALUE (PlatformInfoHob->PcdPciMmio64Size, (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.
> + //
> + PlatformInfoHob->PcdPciMmio64Base = ALIGN_VALUE (PlatformInfoHob->PcdPciMmio64Base, GetPowerOfTwo64 (PlatformInfoHob->PcdPciMmio64Size));
> +
> + //
> + // The useful address space ends with the 64-bit PCI host aperture.
> + //
> + FirstNonAddress = PlatformInfoHob->PcdPciMmio64Base + PlatformInfoHob->PcdPciMmio64Size;
> + return FirstNonAddress;
> +}
> +
> +/**
> + Initialize the mPhysMemAddressWidth variable, based on guest RAM size.
> +**/
> +VOID
> +EFIAPI
> +PlatformAddressWidthInitialization (
> + IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob
> + )
> +{
> + UINT64 FirstNonAddress;
> + UINT8 PhysMemAddressWidth;
> +
> + //
> + // 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 = PlatformGetFirstNonAddress (PlatformInfoHob);
> + PhysMemAddressWidth = (UINT8)HighBitSet64 (FirstNonAddress);
> +
> + //
> + // If FirstNonAddress is not an integral power of two, then we need an
> + // additional bit.
> + //
> + if ((FirstNonAddress & (FirstNonAddress - 1)) != 0) {
> + ++PhysMemAddressWidth;
> + }
> +
> + //
> + // 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 (PhysMemAddressWidth <= 36) {
> + PhysMemAddressWidth = 36;
> + }
> +
> + ASSERT (PhysMemAddressWidth <= 48);
> +
> + PlatformInfoHob->FirstNonAddress = FirstNonAddress;
> + PlatformInfoHob->PhysMemAddressWidth = PhysMemAddressWidth;
> +}
> +
> +STATIC
> +VOID
> +QemuInitializeRamBelow1gb (
> + IN EFI_HOB_PLATFORM_INFO *PlatformInfoHob
> + )
> +{
> + if (PlatformInfoHob->SmmSmramRequire && PlatformInfoHob->Q35SmramAtDefaultSmbase) {
> + 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
> +
> +**/
> +VOID
> +EFIAPI
> +PlatformQemuInitializeRam (
> + IN EFI_HOB_PLATFORM_INFO *PlatformInfoHob
> + )
> +{
> + UINT64 LowerMemorySize;
> + UINT64 UpperMemorySize;
> + MTRR_SETTINGS MtrrSettings;
> + EFI_STATUS Status;
> +
> + DEBUG ((DEBUG_INFO, "%a called\n", __FUNCTION__));
> +
> + //
> + // Determine total memory size available
> + //
> + LowerMemorySize = PlatformGetSystemMemorySizeBelow4gb (PlatformInfoHob);
> +
> + if (PlatformInfoHob->BootMode == 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 (PlatformInfoHob);
> + } else {
> + //
> + // Create memory HOBs
> + //
> + QemuInitializeRamBelow1gb (PlatformInfoHob);
> +
> + if (PlatformInfoHob->SmmSmramRequire) {
> + UINT32 TsegSize;
> +
> + TsegSize = PlatformInfoHob->Q35TsegMbytes * 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 = PlatformScanOrAdd64BitE820Ram (TRUE, NULL, NULL);
> + if (EFI_ERROR (Status)) {
> + UpperMemorySize = PlatformGetSystemMemorySizeAbove4gb ();
> + 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 () && (PlatformInfoHob->HostBridgeDevId != 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 (
> + PlatformInfoHob->Uc32Base,
> + SIZE_4GB - PlatformInfoHob->Uc32Base,
> + CacheUncacheable
> + );
> + ASSERT_EFI_ERROR (Status);
> + }
> +}
> +
> +VOID
> +EFIAPI
> +PlatformQemuInitializeRamForS3 (
> + IN EFI_HOB_PLATFORM_INFO *PlatformInfoHob
> + )
> +{
> + if (PlatformInfoHob->S3Supported && (PlatformInfoHob->BootMode != BOOT_ON_S3_RESUME)) {
> + //
> + // This is the memory range that will be used for PEI on S3 resume
> + //
> + BuildMemoryAllocationHob (
> + PlatformInfoHob->S3AcpiReservedMemoryBase,
> + PlatformInfoHob->S3AcpiReservedMemorySize,
> + EfiACPIMemoryNVS
> + );
> +
> + //
> + // Cover the initial RAM area used as stack and temporary PEI heap.
> + //
> + // This is reserved as ACPI NVS so it can be used on S3 resume.
> + //
> + BuildMemoryAllocationHob (
> + PcdGet32 (PcdOvmfSecPeiTempRamBase),
> + PcdGet32 (PcdOvmfSecPeiTempRamSize),
> + EfiACPIMemoryNVS
> + );
> +
> + //
> + // SEC stores its table of GUIDed section handlers here.
> + //
> + BuildMemoryAllocationHob (
> + PcdGet64 (PcdGuidedExtractHandlerTableAddress),
> + PcdGet32 (PcdGuidedExtractHandlerTableSize),
> + EfiACPIMemoryNVS
> + );
> +
> + #ifdef MDE_CPU_X64
> + //
> + // Reserve the initial page tables built by the reset vector code.
> + //
> + // Since this memory range will be used by the Reset Vector on S3
> + // resume, it must be reserved as ACPI NVS.
> + //
> + BuildMemoryAllocationHob (
> + (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdOvmfSecPageTablesBase),
> + (UINT64)(UINTN)PcdGet32 (PcdOvmfSecPageTablesSize),
> + EfiACPIMemoryNVS
> + );
> +
> + if (PlatformInfoHob->SevEsIsEnabled) {
> + //
> + // If SEV-ES is enabled, reserve the GHCB-related memory area. This
> + // includes the extra page table used to break down the 2MB page
> + // mapping into 4KB page entries where the GHCB resides and the
> + // GHCB area itself.
> + //
> + // Since this memory range will be used by the Reset Vector on S3
> + // resume, it must be reserved as ACPI NVS.
> + //
> + BuildMemoryAllocationHob (
> + (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdOvmfSecGhcbPageTableBase),
> + (UINT64)(UINTN)PcdGet32 (PcdOvmfSecGhcbPageTableSize),
> + EfiACPIMemoryNVS
> + );
> + BuildMemoryAllocationHob (
> + (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdOvmfSecGhcbBase),
> + (UINT64)(UINTN)PcdGet32 (PcdOvmfSecGhcbSize),
> + EfiACPIMemoryNVS
> + );
> + BuildMemoryAllocationHob (
> + (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdOvmfSecGhcbBackupBase),
> + (UINT64)(UINTN)PcdGet32 (PcdOvmfSecGhcbBackupSize),
> + EfiACPIMemoryNVS
> + );
> + }
> +
> + #endif
> + }
> +
> + if (PlatformInfoHob->BootMode != BOOT_ON_S3_RESUME) {
> + if (!PlatformInfoHob->SmmSmramRequire) {
> + //
> + // 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),
> + PlatformInfoHob->S3Supported ? EfiACPIMemoryNVS : EfiBootServicesData
> + );
> + }
> +
> + if (PlatformInfoHob->SmmSmramRequire) {
> + UINT32 TsegSize;
> +
> + //
> + // Make sure the TSEG area that we reported as a reserved memory resource
> + // cannot be used for reserved memory allocations.
> + //
> + TsegSize = PlatformInfoHob->Q35TsegMbytes * SIZE_1MB;
> + BuildMemoryAllocationHob (
> + PlatformGetSystemMemorySizeBelow4gb (PlatformInfoHob) - TsegSize,
> + TsegSize,
> + EfiReservedMemoryType
> + );
> + //
> + // Similarly, allocate away the (already reserved) SMRAM at the default
> + // SMBASE, if it exists.
> + //
> + if (PlatformInfoHob->Q35SmramAtDefaultSmbase) {
> + BuildMemoryAllocationHob (
> + SMM_DEFAULT_SMBASE,
> + MCH_DEFAULT_SMBASE_SIZE,
> + EfiReservedMemoryType
> + );
> + }
> + }
> +
> + #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),
> + PlatformInfoHob->S3Supported ? EfiACPIMemoryNVS : EfiBootServicesData
> + );
> + }
> +
> + #endif
> + }
> +}
> diff --git a/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf b/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
> index 21813458cb59..19a88d363819 100644
> --- a/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
> +++ b/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
> @@ -24,15 +24,64 @@
>
> [Sources]
> Cmos.c
> + MemDetect.c
> Platform.c
>
> [Packages]
> + EmbeddedPkg/EmbeddedPkg.dec
> MdeModulePkg/MdeModulePkg.dec
> MdePkg/MdePkg.dec
> OvmfPkg/OvmfPkg.dec
> + UefiCpuPkg/UefiCpuPkg.dec
>
> [LibraryClasses]
> BaseLib
> DebugLib
> IoLib
> HobLib
> + QemuFwCfgLib
> + QemuFwCfgSimpleParserLib
> + MtrrLib
> + PcdLib
> + PciLib
> +
> +[FixedPcd]
> + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase
> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaSize
> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase
> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize
> +
> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCpuidBase
> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCpuidSize
> + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS
> + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory
> + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType
> + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode
> + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData
> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupBase
> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupSize
> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsBase
> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsSize
> +
> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase
> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize
> +
> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase
> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
> +
> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase
> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableSize
> +
> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase
> + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize
> + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
> + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
> + gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress
> + gUefiOvmfPkgTokenSpaceGuid.PcdXenPvhStartOfDayStructPtr
> + gUefiOvmfPkgTokenSpaceGuid.PcdXenPvhStartOfDayStructPtrSize
> + gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress
> + gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
> +
> +[FeaturePcd]
> + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode
> diff --git a/OvmfPkg/PlatformPei/MemDetect.c b/OvmfPkg/PlatformPei/MemDetect.c
> index 5709766f86f3..3907de1545de 100644
> --- a/OvmfPkg/PlatformPei/MemDetect.c
> +++ b/OvmfPkg/PlatformPei/MemDetect.c
> @@ -34,7 +34,7 @@ Module Name:
> #include <Library/PciLib.h>
> #include <Library/PeimEntryPoint.h>
> #include <Library/ResourcePublicationLib.h>
> -#include <Library/MtrrLib.h>
> +
> #include <Library/QemuFwCfgLib.h>
> #include <Library/QemuFwCfgSimpleParserLib.h>
>
> @@ -126,501 +126,6 @@ Q35SmramAtDefaultSmbaseInitialization (
> ASSERT_RETURN_ERROR (PcdStatus);
> }
>
> -VOID
> -EFIAPI
> -PlatformQemuUc32BaseInitialization (
> - IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob
> - )
> -{
> - UINT32 LowerMemorySize;
> -
> - if (PlatformInfoHob->HostBridgeDevId == 0xffff /* microvm */) {
> - return;
> - }
> -
> - if (PlatformInfoHob->HostBridgeDevId == 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);
> - PlatformInfoHob->Uc32Base = (UINT32)FixedPcdGet64 (PcdPciExpressBaseAddress);
> - return;
> - }
> -
> - if (PlatformInfoHob->HostBridgeDevId == CLOUDHV_DEVICE_ID) {
> - PlatformInfoHob->Uc32Size = CLOUDHV_MMIO_HOLE_SIZE;
> - PlatformInfoHob->Uc32Base = CLOUDHV_MMIO_HOLE_ADDRESS;
> - return;
> - }
> -
> - ASSERT (PlatformInfoHob->HostBridgeDevId == 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 = PlatformGetSystemMemorySizeBelow4gb (PlatformInfoHob);
> - PlatformInfoHob->Uc32Size = GetPowerOfTwo32 ((UINT32)(SIZE_4GB - LowerMemorySize));
> - PlatformInfoHob->Uc32Base = (UINT32)(SIZE_4GB - PlatformInfoHob->Uc32Size);
> - //
> - // Assuming that LowerMemorySize is at least 1 byte, Uc32Size is at most 2GB.
> - // Therefore mQemuUc32Base is at least 2GB.
> - //
> - ASSERT (PlatformInfoHob->Uc32Base >= BASE_2GB);
> -
> - if (PlatformInfoHob->Uc32Base != 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,
> - PlatformInfoHob->Uc32Base,
> - PlatformInfoHob->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 PlatformScanOrAdd64BitE820Ram()
> - 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
> -PlatformScanOrAdd64BitE820Ram (
> - 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;
> -}
> -
> -/**
> - Returns PVH memmap
> -
> - @param Entries Pointer to PVH memmap
> - @param Count Number of entries
> -
> - @return EFI_STATUS
> -**/
> -EFI_STATUS
> -GetPvhMemmapEntries (
> - struct hvm_memmap_table_entry **Entries,
> - UINT32 *Count
> - )
> -{
> - UINT32 *PVHResetVectorData;
> - struct hvm_start_info *pvh_start_info;
> -
> - PVHResetVectorData = (VOID *)(UINTN)PcdGet32 (PcdXenPvhStartOfDayStructPtr);
> - if (PVHResetVectorData == 0) {
> - return EFI_NOT_FOUND;
> - }
> -
> - pvh_start_info = (struct hvm_start_info *)(UINTN)PVHResetVectorData[0];
> -
> - *Entries = (struct hvm_memmap_table_entry *)(UINTN)pvh_start_info->memmap_paddr;
> - *Count = pvh_start_info->memmap_entries;
> -
> - return EFI_SUCCESS;
> -}
> -
> -STATIC
> -UINT64
> -GetHighestSystemMemoryAddressFromPvhMemmap (
> - BOOLEAN Below4gb
> - )
> -{
> - struct hvm_memmap_table_entry *Memmap;
> - UINT32 MemmapEntriesCount;
> - struct hvm_memmap_table_entry *Entry;
> - EFI_STATUS Status;
> - UINT32 Loop;
> - UINT64 HighestAddress;
> - UINT64 EntryEnd;
> -
> - HighestAddress = 0;
> -
> - Status = GetPvhMemmapEntries (&Memmap, &MemmapEntriesCount);
> - ASSERT_EFI_ERROR (Status);
> -
> - for (Loop = 0; Loop < MemmapEntriesCount; Loop++) {
> - Entry = Memmap + Loop;
> - EntryEnd = Entry->addr + Entry->size;
> -
> - if ((Entry->type == XEN_HVM_MEMMAP_TYPE_RAM) &&
> - (EntryEnd > HighestAddress))
> - {
> - if (Below4gb && (EntryEnd <= BASE_4GB)) {
> - HighestAddress = EntryEnd;
> - } else if (!Below4gb && (EntryEnd >= BASE_4GB)) {
> - HighestAddress = EntryEnd;
> - }
> - }
> - }
> -
> - return HighestAddress;
> -}
> -
> -UINT32
> -EFIAPI
> -PlatformGetSystemMemorySizeBelow4gb (
> - IN EFI_HOB_PLATFORM_INFO *PlatformInfoHob
> - )
> -{
> - EFI_STATUS Status;
> - UINT64 LowerMemorySize = 0;
> - UINT8 Cmos0x34;
> - UINT8 Cmos0x35;
> -
> - if (PlatformInfoHob->HostBridgeDevId == CLOUDHV_DEVICE_ID) {
> - // Get the information from PVH memmap
> - return (UINT32)GetHighestSystemMemoryAddressFromPvhMemmap (TRUE);
> - }
> -
> - Status = PlatformScanOrAdd64BitE820Ram (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
> -PlatformGetSystemMemorySizeAbove4gb (
> - )
> -{
> - 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
> -PlatformGetFirstNonAddress (
> - IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob
> - )
> -{
> - UINT64 FirstNonAddress;
> - UINT32 FwCfgPciMmio64Mb;
> - EFI_STATUS Status;
> - FIRMWARE_CONFIG_ITEM FwCfgItem;
> - UINTN FwCfgSize;
> - UINT64 HotPlugMemoryEnd;
> -
> - //
> - // 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 = PlatformScanOrAdd64BitE820Ram (FALSE, NULL, &FirstNonAddress);
> - if (EFI_ERROR (Status)) {
> - FirstNonAddress = BASE_4GB + PlatformGetSystemMemorySizeAbove4gb ();
> - }
> -
> - //
> - // 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
> -
> - //
> - // 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) {
> - PlatformInfoHob->PcdPciMmio64Size = 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 (PlatformInfoHob->PcdPciMmio64Size == 0) {
> - if (PlatformInfoHob->BootMode != BOOT_ON_S3_RESUME) {
> - DEBUG ((
> - DEBUG_INFO,
> - "%a: disabling 64-bit PCI host aperture\n",
> - __FUNCTION__
> - ));
> - }
> -
> - //
> - // 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.
> - //
> - PlatformInfoHob->PcdPciMmio64Base = ALIGN_VALUE (FirstNonAddress, (UINT64)SIZE_1GB);
> - PlatformInfoHob->PcdPciMmio64Size = ALIGN_VALUE (PlatformInfoHob->PcdPciMmio64Size, (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.
> - //
> - PlatformInfoHob->PcdPciMmio64Base = ALIGN_VALUE (PlatformInfoHob->PcdPciMmio64Base, GetPowerOfTwo64 (PlatformInfoHob->PcdPciMmio64Size));
> -
> - //
> - // The useful address space ends with the 64-bit PCI host aperture.
> - //
> - FirstNonAddress = PlatformInfoHob->PcdPciMmio64Base + PlatformInfoHob->PcdPciMmio64Size;
> - return FirstNonAddress;
> -}
> -
> -/**
> - Initialize the mPhysMemAddressWidth variable, based on guest RAM size.
> -**/
> -VOID
> -EFIAPI
> -PlatformAddressWidthInitialization (
> - IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob
> - )
> -{
> - UINT64 FirstNonAddress;
> - UINT8 PhysMemAddressWidth;
> -
> - //
> - // 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 = PlatformGetFirstNonAddress (PlatformInfoHob);
> - PhysMemAddressWidth = (UINT8)HighBitSet64 (FirstNonAddress);
> -
> - //
> - // If FirstNonAddress is not an integral power of two, then we need an
> - // additional bit.
> - //
> - if ((FirstNonAddress & (FirstNonAddress - 1)) != 0) {
> - ++PhysMemAddressWidth;
> - }
> -
> - //
> - // 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 (PhysMemAddressWidth <= 36) {
> - PhysMemAddressWidth = 36;
> - }
> -
> - ASSERT (PhysMemAddressWidth <= 48);
> -
> - PlatformInfoHob->FirstNonAddress = FirstNonAddress;
> - PlatformInfoHob->PhysMemAddressWidth = PhysMemAddressWidth;
> -}
> -
> /**
> Initialize the mPhysMemAddressWidth variable, based on guest RAM size.
> **/
> @@ -842,313 +347,6 @@ PublishPeiMemory (
> return Status;
> }
>
> -STATIC
> -VOID
> -QemuInitializeRamBelow1gb (
> - IN EFI_HOB_PLATFORM_INFO *PlatformInfoHob
> - )
> -{
> - if (PlatformInfoHob->SmmSmramRequire && PlatformInfoHob->Q35SmramAtDefaultSmbase) {
> - 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
> -PlatformQemuInitializeRam (
> - IN EFI_HOB_PLATFORM_INFO *PlatformInfoHob
> - )
> -{
> - UINT64 LowerMemorySize;
> - UINT64 UpperMemorySize;
> - MTRR_SETTINGS MtrrSettings;
> - EFI_STATUS Status;
> -
> - DEBUG ((DEBUG_INFO, "%a called\n", __FUNCTION__));
> -
> - //
> - // Determine total memory size available
> - //
> - LowerMemorySize = PlatformGetSystemMemorySizeBelow4gb (PlatformInfoHob);
> -
> - if (PlatformInfoHob->BootMode == 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 (PlatformInfoHob);
> - } else {
> - //
> - // Create memory HOBs
> - //
> - QemuInitializeRamBelow1gb (PlatformInfoHob);
> -
> - if (PlatformInfoHob->SmmSmramRequire) {
> - UINT32 TsegSize;
> -
> - TsegSize = PlatformInfoHob->Q35TsegMbytes * 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 = PlatformScanOrAdd64BitE820Ram (TRUE, NULL, NULL);
> - if (EFI_ERROR (Status)) {
> - UpperMemorySize = PlatformGetSystemMemorySizeAbove4gb ();
> - 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 () && (PlatformInfoHob->HostBridgeDevId != 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 (
> - PlatformInfoHob->Uc32Base,
> - SIZE_4GB - PlatformInfoHob->Uc32Base,
> - CacheUncacheable
> - );
> - ASSERT_EFI_ERROR (Status);
> - }
> -}
> -
> -STATIC
> -VOID
> -PlatformQemuInitializeRamForS3 (
> - IN EFI_HOB_PLATFORM_INFO *PlatformInfoHob
> - )
> -{
> - if (PlatformInfoHob->S3Supported && (PlatformInfoHob->BootMode != BOOT_ON_S3_RESUME)) {
> - //
> - // This is the memory range that will be used for PEI on S3 resume
> - //
> - BuildMemoryAllocationHob (
> - PlatformInfoHob->S3AcpiReservedMemoryBase,
> - PlatformInfoHob->S3AcpiReservedMemorySize,
> - EfiACPIMemoryNVS
> - );
> -
> - //
> - // Cover the initial RAM area used as stack and temporary PEI heap.
> - //
> - // This is reserved as ACPI NVS so it can be used on S3 resume.
> - //
> - BuildMemoryAllocationHob (
> - PcdGet32 (PcdOvmfSecPeiTempRamBase),
> - PcdGet32 (PcdOvmfSecPeiTempRamSize),
> - EfiACPIMemoryNVS
> - );
> -
> - //
> - // SEC stores its table of GUIDed section handlers here.
> - //
> - BuildMemoryAllocationHob (
> - PcdGet64 (PcdGuidedExtractHandlerTableAddress),
> - PcdGet32 (PcdGuidedExtractHandlerTableSize),
> - EfiACPIMemoryNVS
> - );
> -
> - #ifdef MDE_CPU_X64
> - //
> - // Reserve the initial page tables built by the reset vector code.
> - //
> - // Since this memory range will be used by the Reset Vector on S3
> - // resume, it must be reserved as ACPI NVS.
> - //
> - BuildMemoryAllocationHob (
> - (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdOvmfSecPageTablesBase),
> - (UINT64)(UINTN)PcdGet32 (PcdOvmfSecPageTablesSize),
> - EfiACPIMemoryNVS
> - );
> -
> - if (PlatformInfoHob->SevEsIsEnabled) {
> - //
> - // If SEV-ES is enabled, reserve the GHCB-related memory area. This
> - // includes the extra page table used to break down the 2MB page
> - // mapping into 4KB page entries where the GHCB resides and the
> - // GHCB area itself.
> - //
> - // Since this memory range will be used by the Reset Vector on S3
> - // resume, it must be reserved as ACPI NVS.
> - //
> - BuildMemoryAllocationHob (
> - (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdOvmfSecGhcbPageTableBase),
> - (UINT64)(UINTN)PcdGet32 (PcdOvmfSecGhcbPageTableSize),
> - EfiACPIMemoryNVS
> - );
> - BuildMemoryAllocationHob (
> - (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdOvmfSecGhcbBase),
> - (UINT64)(UINTN)PcdGet32 (PcdOvmfSecGhcbSize),
> - EfiACPIMemoryNVS
> - );
> - BuildMemoryAllocationHob (
> - (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdOvmfSecGhcbBackupBase),
> - (UINT64)(UINTN)PcdGet32 (PcdOvmfSecGhcbBackupSize),
> - EfiACPIMemoryNVS
> - );
> - }
> -
> - #endif
> - }
> -
> - if (PlatformInfoHob->BootMode != BOOT_ON_S3_RESUME) {
> - if (!PlatformInfoHob->SmmSmramRequire) {
> - //
> - // 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),
> - PlatformInfoHob->S3Supported ? EfiACPIMemoryNVS : EfiBootServicesData
> - );
> - }
> -
> - if (PlatformInfoHob->SmmSmramRequire) {
> - UINT32 TsegSize;
> -
> - //
> - // Make sure the TSEG area that we reported as a reserved memory resource
> - // cannot be used for reserved memory allocations.
> - //
> - TsegSize = PlatformInfoHob->Q35TsegMbytes * SIZE_1MB;
> - BuildMemoryAllocationHob (
> - PlatformGetSystemMemorySizeBelow4gb (PlatformInfoHob) - TsegSize,
> - TsegSize,
> - EfiReservedMemoryType
> - );
> - //
> - // Similarly, allocate away the (already reserved) SMRAM at the default
> - // SMBASE, if it exists.
> - //
> - if (PlatformInfoHob->Q35SmramAtDefaultSmbase) {
> - BuildMemoryAllocationHob (
> - SMM_DEFAULT_SMBASE,
> - MCH_DEFAULT_SMBASE_SIZE,
> - EfiReservedMemoryType
> - );
> - }
> - }
> -
> - #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),
> - PlatformInfoHob->S3Supported ? EfiACPIMemoryNVS : EfiBootServicesData
> - );
> - }
> -
> - #endif
> - }
> -}
> -
> /**
> Publish system RAM and reserve memory regions
>
> diff --git a/OvmfPkg/PlatformPei/Platform.h b/OvmfPkg/PlatformPei/Platform.h
> index 494836c3efe4..31670747d8b0 100644
> --- a/OvmfPkg/PlatformPei/Platform.h
> +++ b/OvmfPkg/PlatformPei/Platform.h
> @@ -32,18 +32,6 @@ PublishPeiMemory (
> VOID
> );
>
> -UINT32
> -EFIAPI
> -PlatformGetSystemMemorySizeBelow4gb (
> - IN EFI_HOB_PLATFORM_INFO *PlatformInfoHob
> - );
> -
> -VOID
> -EFIAPI
> -PlatformQemuUc32BaseInitialization (
> - IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob
> - );
> -
> VOID
> InitializeRamRegions (
> IN EFI_HOB_PLATFORM_INFO *PlatformInfoHob
> --
> 2.29.2.windows.2
>
--
next prev parent reply other threads:[~2022-03-15 8:15 UTC|newest]
Thread overview: 75+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-12 1:53 [PATCH V8 00/47] Enable Intel TDX in OvmfPkg (Config-A) Min Xu
2022-03-12 1:53 ` [PATCH V8 01/47] MdePkg: Add Tdx.h Min Xu
2022-03-12 1:53 ` [PATCH V8 02/47] MdePkg: Introduce basic Tdx functions in BaseLib Min Xu
2022-03-15 7:41 ` [edk2-devel] " Ni, Ray
2022-03-16 1:18 ` Min Xu
2022-03-16 1:26 ` Ni, Ray
2022-03-15 7:44 ` Ni, Ray
2022-03-16 2:15 ` Min Xu
2022-03-12 1:53 ` [PATCH V8 03/47] MdePkg: Add TdxLib to wrap Tdx operations Min Xu
2022-03-12 1:53 ` [PATCH V8 04/47] UefiCpuPkg: Extend VmgExitLibNull to handle #VE exception Min Xu
2022-03-12 1:53 ` [PATCH V8 05/47] OvmfPkg: Extend VmgExitLib " Min Xu
2022-03-12 1:53 ` [PATCH V8 06/47] UefiCpuPkg/CpuExceptionHandler: Add base support for the " Min Xu
2022-03-12 1:53 ` [PATCH V8 07/47] MdePkg: Add helper functions for Tdx guest in BaseIoLibIntrinsic Min Xu
2022-03-12 1:53 ` [PATCH V8 08/47] MdePkg: Support mmio " Min Xu
2022-03-12 1:53 ` [PATCH V8 09/47] MdePkg: Support IoFifo " Min Xu
2022-03-12 1:53 ` [PATCH V8 10/47] MdePkg: Support IoRead/IoWrite " Min Xu
2022-03-12 1:53 ` [PATCH V8 11/47] UefiCpuPkg: Support TDX in BaseXApicX2ApicLib Min Xu
2022-03-12 1:53 ` [PATCH V8 12/47] MdePkg: Add macro to check SEV / TDX guest Min Xu
2022-03-12 1:53 ` [PATCH V8 13/47] UefiCpuPkg: Enable Tdx support in MpInitLib Min Xu
2022-03-15 7:57 ` Ni, Ray
2022-03-16 8:32 ` Min Xu
2022-03-16 8:36 ` Ni, Ray
2022-03-16 11:53 ` Min Xu
2022-03-12 1:53 ` [PATCH V8 14/47] OvmfPkg: Add IntelTdx.h in OvmfPkg/Include/IndustryStandard Min Xu
2022-03-12 1:53 ` [PATCH V8 15/47] OvmfPkg: Add TdxMailboxLib Min Xu
2022-03-12 1:53 ` [PATCH V8 16/47] OvmfPkg: Create initial version of PlatformInitLib Min Xu
2022-03-15 7:41 ` Gerd Hoffmann
2022-03-12 1:53 ` [PATCH V8 17/47] OvmfPkg/PlatformInitLib: Add hob functions Min Xu
2022-03-15 7:42 ` Gerd Hoffmann
2022-03-12 1:53 ` [PATCH V8 18/47] OvmfPkg/PlatformPei: Move global variables to PlatformInfoHob Min Xu
2022-03-15 7:57 ` Gerd Hoffmann
2022-03-16 5:26 ` [edk2-devel] " Min Xu
2022-03-12 1:53 ` [PATCH V8 19/47] OvmfPkg/PlatformPei: Refactor MiscInitialization Min Xu
2022-03-15 7:59 ` Gerd Hoffmann
2022-03-12 1:53 ` [PATCH V8 20/47] OvmfPkg/PlatformPei: Refactor MiscInitialization for CloudHV Min Xu
2022-03-15 7:59 ` Gerd Hoffmann
2022-03-12 1:53 ` [PATCH V8 21/47] OvmfPkg/PlatformPei: Refactor AddressWidthInitialization Min Xu
2022-03-15 8:04 ` Gerd Hoffmann
2022-03-16 5:56 ` [edk2-devel] " Min Xu
2022-03-12 1:53 ` [PATCH V8 22/47] OvmfPkg/PlatformPei: Refactor MaxCpuCountInitialization Min Xu
2022-03-15 8:04 ` Gerd Hoffmann
2022-03-16 6:25 ` Min Xu
2022-03-12 1:53 ` [PATCH V8 23/47] OvmfPkg/PlatformPei: Refactor QemuUc32BaseInitialization Min Xu
2022-03-15 8:05 ` Gerd Hoffmann
2022-03-12 1:53 ` [PATCH V8 25/47] OvmfPkg/PlatformPei: Refactor MemMapInitialization Min Xu
2022-03-15 8:06 ` Gerd Hoffmann
2022-03-12 1:53 ` [PATCH V8 26/47] OvmfPkg/PlatformPei: Refactor NoexecDxeInitialization Min Xu
2022-03-15 8:13 ` Gerd Hoffmann
2022-03-12 1:53 ` [PATCH V8 27/47] OvmfPkg/PlatformPei: Refactor MiscInitialization Min Xu
2022-03-15 8:14 ` Gerd Hoffmann
2022-03-12 1:53 ` [PATCH V8 28/47] OvmfPkg/PlatformInitLib: Create MemDetect.c Min Xu
2022-03-15 8:14 ` Gerd Hoffmann [this message]
2022-03-12 1:53 ` [PATCH V8 29/47] OvmfPkg/PlatformInitLib: Move functions to Platform.c Min Xu
2022-03-15 8:15 ` Gerd Hoffmann
2022-03-12 1:53 ` [PATCH V8 30/47] MdePkg: Add EFI_RESOURCE_MEMORY_UNACCEPTED defition Min Xu
2022-03-15 8:15 ` Gerd Hoffmann
2022-03-12 1:53 ` [PATCH V8 31/47] OvmfPkg: Update PlatformInitLib to process Tdx hoblist Min Xu
2022-03-12 1:53 ` [PATCH V8 32/47] OvmfPkg/Sec: Declare local variable as volatile in SecCoreStartupWithStack Min Xu
2022-03-12 1:53 ` [PATCH V8 33/47] OvmfPkg: Update Sec to support Tdx Min Xu
2022-03-12 1:53 ` [PATCH V8 34/47] OvmfPkg: Check Tdx in QemuFwCfgPei to avoid DMA operation Min Xu
2022-03-12 1:54 ` [PATCH V8 35/47] MdeModulePkg: Skip setting IA32_ERER.NXE if it has already been set Min Xu
2022-03-15 5:16 ` Wang, Jian J
2022-03-12 1:54 ` [PATCH V8 36/47] MdeModulePkg: Add PcdTdxSharedBitMask Min Xu
2022-03-15 5:16 ` Wang, Jian J
2022-03-12 1:54 ` [PATCH V8 37/47] UefiCpuPkg: Update AddressEncMask in CpuPageTable Min Xu
2022-03-12 1:54 ` [PATCH V8 38/47] OvmfPkg: Update PlatformInitLib for Tdx guest Min Xu
2022-03-12 1:54 ` [PATCH V8 39/47] OvmfPkg: Update PlatformPei to support " Min Xu
2022-03-12 1:54 ` [PATCH V8 40/47] OvmfPkg: Update AcpiPlatformDxe to alter MADT table Min Xu
2022-03-15 3:55 ` 回复: [edk2-devel] [PATCH V8 00/47] Enable Intel TDX in OvmfPkg (Config-A) gaoliming
2022-03-15 7:11 ` Min Xu
2022-03-17 1:00 ` 回复: " gaoliming
2022-03-17 1:16 ` Min Xu
[not found] ` <5cf66f701073359f385e7ff28b5173555ab483c3.1647047482.git.min.m.xu@intel.com>
2022-03-15 8:05 ` [PATCH V8 24/47] OvmfPkg/PlatformPei: Refactor InitializeRamRegions Gerd Hoffmann
[not found] ` <16DB7F586DEAD807.23528@groups.io>
2022-03-17 5:31 ` [edk2-devel] [PATCH V8 12/47] MdePkg: Add macro to check SEV / TDX guest Min Xu
2022-03-18 1:13 ` 回复: " gaoliming
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220315081457.6ykewdihqwrn7jt4@sirius.home.kraxel.org \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox