]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg: PlatformPei: account for TSEG size with PcdSmmSmramRequire set
authorLaszlo Ersek <lersek@redhat.com>
Mon, 30 Nov 2015 18:41:33 +0000 (18:41 +0000)
committerlersek <lersek@Edk2>
Mon, 30 Nov 2015 18:41:33 +0000 (18:41 +0000)
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.

We choose the largest option (8MB) for the default TSEG size. Michael
Kinney pointed out that the SMBASE relocation in PiSmmCpuDxeSmm consumes
SMRAM proportionally to the number of CPUs. From the three options
available, he reported that 8MB was both necessary and sufficient for the
SMBASE relocation to succeed with 255 CPUs:

- http://thread.gmane.org/gmane.comp.bios.edk2.devel/3020/focus=3137
- http://thread.gmane.org/gmane.comp.bios.edk2.devel/3020/focus=3177

Cc: Michael Kinney <michael.d.kinney@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Michael Kinney <michael.d.kinney@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@19039 6f19259b-4bc3-4df7-8a09-765794883524

OvmfPkg/OvmfPkg.dec
OvmfPkg/PlatformPei/MemDetect.c
OvmfPkg/PlatformPei/PlatformPei.inf

index 1c9f8312b560d56858ebad7825d5264517369ca0..4d279c3c5d0c055366e690db5c7bf53b680efbed 100644 (file)
   gUefiOvmfPkgTokenSpaceGuid.PcdVirtioScsiMaxTargetLimit|31|UINT16|6\r
   gUefiOvmfPkgTokenSpaceGuid.PcdVirtioScsiMaxLunLimit|7|UINT32|7\r
 \r
+  ## The following setting controls how many megabytes we configure as TSEG on\r
+  #  Q35, for SMRAM purposes. Permitted values are: 1, 2, 8. Other values cause\r
+  #  undefined behavior.\r
+  #\r
+  #  This PCD is only consulted if PcdSmmSmramRequire is TRUE (see below).\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdQ35TsegMbytes|8|UINT8|0x20\r
+\r
 [PcdsFixedAtBuild]\r
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogBase|0x0|UINT32|0x8\r
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogSize|0x0|UINT32|0x9\r
index 5fe8b282c09f76a2ba337278fd92648f01c708d1..1bdc2df6ed91910fa30411f29abcf377027cb63e 100644 (file)
@@ -214,6 +214,12 @@ PublishPeiMemory (
     MemorySize = PcdGet32 (PcdS3AcpiReservedMemorySize);\r
   } else {\r
     LowerMemorySize = GetSystemMemorySizeBelow4gb ();\r
+    if (FeaturePcdGet (PcdSmmSmramRequire)) {\r
+      //\r
+      // TSEG is chipped from the end of low RAM\r
+      //\r
+      LowerMemorySize -= FixedPcdGet8 (PcdQ35TsegMbytes) * SIZE_1MB;\r
+    }\r
 \r
     PeiMemoryCap = GetPeiMemoryCap ();\r
     DEBUG ((EFI_D_INFO, "%a: mPhysMemAddressWidth=%d PeiMemoryCap=%u KB\n",\r
@@ -277,7 +283,18 @@ QemuInitializeRam (
     // Create memory HOBs\r
     //\r
     AddMemoryRangeHob (0, BASE_512KB + BASE_128KB);\r
-    AddMemoryRangeHob (BASE_1MB, LowerMemorySize);\r
+\r
+    if (FeaturePcdGet (PcdSmmSmramRequire)) {\r
+      UINT32 TsegSize;\r
+\r
+      TsegSize = FixedPcdGet8 (PcdQ35TsegMbytes) * SIZE_1MB;\r
+      AddMemoryRangeHob (BASE_1MB, LowerMemorySize - TsegSize);\r
+      AddReservedMemoryBaseSizeHob (LowerMemorySize - TsegSize, TsegSize,\r
+        TRUE);\r
+    } else {\r
+      AddMemoryRangeHob (BASE_1MB, LowerMemorySize);\r
+    }\r
+\r
     if (UpperMemorySize != 0) {\r
       AddUntestedMemoryBaseSizeHob (BASE_4GB, UpperMemorySize);\r
     }\r
@@ -409,5 +426,20 @@ InitializeRamRegions (
       (UINT64)(UINTN) PcdGet32 (PcdOvmfLockBoxStorageSize),\r
       mS3Supported ? EfiACPIMemoryNVS : EfiBootServicesData\r
       );\r
+\r
+    if (FeaturePcdGet (PcdSmmSmramRequire)) {\r
+      UINT32 TsegSize;\r
+\r
+      //\r
+      // Make sure the TSEG area that we reported as a reserved memory resource\r
+      // cannot be used for reserved memory allocations.\r
+      //\r
+      TsegSize = FixedPcdGet8 (PcdQ35TsegMbytes) * SIZE_1MB;\r
+      BuildMemoryAllocationHob (\r
+        GetSystemMemorySizeBelow4gb() - TsegSize,\r
+        TsegSize,\r
+        EfiReservedMemoryType\r
+        );\r
+    }\r
   }\r
 }\r
index 4b1e68de43ac7a0c0283d591d2a5cb1d5bf7c049..dc7729309b516a2c57cb473f4e0d5aff1b1fc9f5 100644 (file)
@@ -75,6 +75,7 @@
   gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize\r
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId\r
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDecompressionScratchEnd\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdQ35TsegMbytes\r
   gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdS3AcpiReservedMemorySize\r
   gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize\r