PlatformPei calls GetSystemMemorySizeBelow4gb() in three locations: - PublishPeiMemory(): on normal boot, the permanent PEI RAM is installed so that it ends with the RAM below 4GB,
- QemuInitializeRam(): on normal boot, memory resource descriptor HOBs are created for the RAM below 4GB; plus MTRR attributes are set (independently of S3 vs. normal boot) - MemMapInitialization(): an MMIO resource descriptor HOB is created for PCI resource allocation, on normal boot, starting at max(RAM below 4GB, 2GB). The first two of these is adjusted for the configured TSEG size, if PcdSmmSmramRequire is set: - In PublishPeiMemory(), the permanent PEI RAM is kept under TSEG. - In QemuInitializeRam(), we must keep the DXE out of TSEG. One idea would be to simply trim the [1MB .. LowerMemorySize] memory resource descriptor HOB, leaving a hole for TSEG in the memory space map. The SMM IPL will however want to massage the caching attributes of the SMRAM range that it loads the SMM core into, with gDS->SetMemorySpaceAttributes(), and that won't work on a hole. So, instead of trimming this range, split the TSEG area off, and report it as a cacheable reserved memory resource. Finally, since reserved memory can be allocated too, pre-allocate TSEG in InitializeRamRegions(), after QemuInitializeRam() returns. (Note that this step alone does not suffice without the resource descriptor HOB trickery: if we omit that, then the DXE IPL PEIM fails to load and start the DXE core.) - In MemMapInitialization(), the start of the PCI MMIO range is not affected. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek <[email protected]> --- OvmfPkg/PlatformPei/PlatformPei.inf | 1 + OvmfPkg/PlatformPei/MemDetect.c | 34 +++++++++++++++++++- OvmfPkg/OvmfPkg.dec | 7 ++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf index b9b0b20..0bf4c38 100644 --- a/OvmfPkg/PlatformPei/PlatformPei.inf +++ b/OvmfPkg/PlatformPei/PlatformPei.inf @@ -76,6 +76,7 @@ [Pcd] gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDecomprScratchEnd + gUefiOvmfPkgTokenSpaceGuid.PcdQ35TsegMbytes gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdS3AcpiReservedMemorySize gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize diff --git a/OvmfPkg/PlatformPei/MemDetect.c b/OvmfPkg/PlatformPei/MemDetect.c index 649b484..cb3f3dd 100644 --- a/OvmfPkg/PlatformPei/MemDetect.c +++ b/OvmfPkg/PlatformPei/MemDetect.c @@ -214,6 +214,12 @@ PublishPeiMemory ( MemorySize = PcdGet32 (PcdS3AcpiReservedMemorySize); } else { LowerMemorySize = GetSystemMemorySizeBelow4gb (); + if (FeaturePcdGet (PcdSmmSmramRequire)) { + // + // TSEG is chipped from the end of low RAM + // + LowerMemorySize -= FixedPcdGet8 (PcdQ35TsegMbytes) * SIZE_1MB; + } PeiMemoryCap = GetPeiMemoryCap (); DEBUG ((EFI_D_INFO, "%a: mPhysMemAddressWidth=%d PeiMemoryCap=%u KB\n", @@ -277,7 +283,18 @@ QemuInitializeRam ( // Create memory HOBs // AddMemoryRangeHob (0, BASE_512KB + BASE_128KB); - AddMemoryRangeHob (BASE_1MB, LowerMemorySize); + + if (FeaturePcdGet (PcdSmmSmramRequire)) { + UINT32 TsegSize; + + TsegSize = FixedPcdGet8 (PcdQ35TsegMbytes) * SIZE_1MB; + AddMemoryRangeHob (BASE_1MB, LowerMemorySize - TsegSize); + AddReservedMemoryBaseSizeHob (LowerMemorySize - TsegSize, TsegSize, + TRUE); + } else { + AddMemoryRangeHob (BASE_1MB, LowerMemorySize); + } + if (UpperMemorySize != 0) { AddUntestedMemoryBaseSizeHob (BASE_4GB, UpperMemorySize); } @@ -409,5 +426,20 @@ InitializeRamRegions ( (UINT64)(UINTN) PcdGet32 (PcdOvmfLockBoxStorageSize), mS3Supported ? EfiACPIMemoryNVS : EfiBootServicesData ); + + if (FeaturePcdGet (PcdSmmSmramRequire)) { + UINT32 TsegSize; + + // + // Make sure the TSEG area that we reported as a reserved memory resource + // cannot be used for reserved memory allocations. + // + TsegSize = FixedPcdGet8 (PcdQ35TsegMbytes) * SIZE_1MB; + BuildMemoryAllocationHob ( + GetSystemMemorySizeBelow4gb() - TsegSize, + TsegSize, + EfiReservedMemoryType + ); + } } } diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec index f9422f0..6d6d6c4 100644 --- a/OvmfPkg/OvmfPkg.dec +++ b/OvmfPkg/OvmfPkg.dec @@ -93,6 +93,13 @@ [PcdsFixedAtBuild] gUefiOvmfPkgTokenSpaceGuid.PcdVirtioScsiMaxTargetLimit|31|UINT16|6 gUefiOvmfPkgTokenSpaceGuid.PcdVirtioScsiMaxLunLimit|7|UINT32|7 + ## The following setting controls how many megabytes we configure as TSEG on + # Q35, for SMRAM purposes. Permitted values are: 1, 2, 8. Other values cause + # undefined behavior. + # + # This PCD is only consulted if PcdSmmSmramRequire is TRUE (see below). + gUefiOvmfPkgTokenSpaceGuid.PcdQ35TsegMbytes|1|UINT8|0x20 + [PcdsFixedAtBuild] gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogBase|0x0|UINT32|0x8 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogSize|0x0|UINT32|0x9 -- 1.8.3.1 _______________________________________________ edk2-devel mailing list [email protected] https://lists.01.org/mailman/listinfo/edk2-devel

