diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec index 1c9f8312b5..4d279c3c5d 100644 --- a/OvmfPkg/OvmfPkg.dec +++ b/OvmfPkg/OvmfPkg.dec @@ -89,6 +89,13 @@ 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|8|UINT8|0x20 + [PcdsFixedAtBuild] gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogBase|0x0|UINT32|0x8 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogSize|0x0|UINT32|0x9 diff --git a/OvmfPkg/PlatformPei/MemDetect.c b/OvmfPkg/PlatformPei/MemDetect.c index 5fe8b282c0..1bdc2df6ed 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/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf index 4b1e68de43..dc7729309b 100644 --- a/OvmfPkg/PlatformPei/PlatformPei.inf +++ b/OvmfPkg/PlatformPei/PlatformPei.inf @@ -75,6 +75,7 @@ gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDecompressionScratchEnd + gUefiOvmfPkgTokenSpaceGuid.PcdQ35TsegMbytes gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdS3AcpiReservedMemorySize gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize