\r
UINT8 mPhysMemAddressWidth;\r
\r
+STATIC UINT32 mS3AcpiReservedMemoryBase;\r
+STATIC UINT32 mS3AcpiReservedMemorySize;\r
+\r
UINT32\r
GetSystemMemorySizeBelow4gb (\r
VOID\r
EFI_STATUS Status;\r
EFI_PHYSICAL_ADDRESS MemoryBase;\r
UINT64 MemorySize;\r
- UINT64 LowerMemorySize;\r
+ UINT32 LowerMemorySize;\r
UINT32 PeiMemoryCap;\r
\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
+ //\r
+ // If S3 is supported, then the S3 permanent PEI memory is placed next,\r
+ // downwards. Its size is primarily dictated by CpuMpPei. The formula below\r
+ // is an approximation.\r
+ //\r
+ if (mS3Supported) {\r
+ mS3AcpiReservedMemorySize = SIZE_512KB +\r
+ PcdGet32 (PcdCpuMaxLogicalProcessorNumber) *\r
+ PcdGet32 (PcdCpuApStackSize);\r
+ mS3AcpiReservedMemoryBase = LowerMemorySize - mS3AcpiReservedMemorySize;\r
+ LowerMemorySize = mS3AcpiReservedMemoryBase;\r
+ }\r
+\r
if (mBootMode == BOOT_ON_S3_RESUME) {\r
- MemoryBase = PcdGet32 (PcdS3AcpiReservedMemoryBase);\r
- MemorySize = PcdGet32 (PcdS3AcpiReservedMemorySize);\r
+ MemoryBase = mS3AcpiReservedMemoryBase;\r
+ MemorySize = mS3AcpiReservedMemorySize;\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
__FUNCTION__, mPhysMemAddressWidth, PeiMemoryCap >> 10));\r
LowerMemorySize = GetSystemMemorySizeBelow4gb ();\r
UpperMemorySize = GetSystemMemorySizeAbove4gb ();\r
\r
- if (mBootMode != BOOT_ON_S3_RESUME) {\r
+ if (mBootMode == BOOT_ON_S3_RESUME) {\r
+ //\r
+ // Create the following memory HOB as an exception on the S3 boot path.\r
+ //\r
+ // Normally we'd create memory HOBs only on the normal boot path. However,\r
+ // CpuMpPei specifically needs such a low-memory HOB on the S3 path as\r
+ // well, for "borrowing" a subset of it temporarily, for the AP startup\r
+ // vector.\r
+ //\r
+ // CpuMpPei saves the original contents of the borrowed area in permanent\r
+ // PEI RAM, in a backup buffer allocated with the normal PEI services.\r
+ // CpuMpPei restores the original contents ("returns" the borrowed area) at\r
+ // End-of-PEI. End-of-PEI in turn is emitted by S3Resume2Pei before\r
+ // transfering control to the OS's wakeup vector in the FACS.\r
+ //\r
+ // We expect any other PEIMs that "borrow" memory similarly to CpuMpPei to\r
+ // restore the original contents. Furthermore, we expect all such PEIMs\r
+ // (CpuMpPei included) to claim the borrowed areas by producing memory\r
+ // allocation HOBs, and to honor preexistent memory allocation HOBs when\r
+ // looking for an area to borrow.\r
+ //\r
+ AddMemoryRangeHob (0, BASE_512KB + BASE_128KB);\r
+ } else {\r
//\r
// Create memory HOBs\r
//\r
// This is the memory range that will be used for PEI on S3 resume\r
//\r
BuildMemoryAllocationHob (\r
- (EFI_PHYSICAL_ADDRESS)(UINTN) PcdGet32 (PcdS3AcpiReservedMemoryBase),\r
- (UINT64)(UINTN) PcdGet32 (PcdS3AcpiReservedMemorySize),\r
+ mS3AcpiReservedMemoryBase,\r
+ mS3AcpiReservedMemorySize,\r
EfiACPIMemoryNVS\r
);\r
\r