summaryrefslogtreecommitdiff
path: root/UefiCpuPkg
diff options
context:
space:
mode:
authorjyao1 <jyao1@6f19259b-4bc3-4df7-8a09-765794883524>2012-08-14 04:42:50 +0000
committerjyao1 <jyao1@6f19259b-4bc3-4df7-8a09-765794883524>2012-08-14 04:42:50 +0000
commitd0bf562330e5309a92e55e44063a8ea37ead4d1d (patch)
treed5b3c46df035fe4f7221441d7898177c4159a84a /UefiCpuPkg
parent743094a2898ed8a1f07e770f50cd2d3081be2c0f (diff)
Create 4G page table by default, and using PF to handle >4G MMIO access, to improve S3 performance.
signed-off-by: jiewen.yao@intel.com reviewed-by: rui.sun@intel.com git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13631 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'UefiCpuPkg')
-rw-r--r--UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c57
1 files changed, 54 insertions, 3 deletions
diff --git a/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c b/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c
index 189f0c50c..de3aec85e 100644
--- a/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c
+++ b/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c
@@ -368,6 +368,41 @@ WriteToOsS3PerformanceData (
}
/**
+ The function will check if current waking vector is long mode.
+
+ @param AcpiS3Context a pointer to a structure of ACPI_S3_CONTEXT
+
+ @retval TRUE Current context need long mode waking vector.
+ @retval FALSE Current context need not long mode waking vector.
+**/
+BOOLEAN
+IsLongModeWakingVector (
+ IN ACPI_S3_CONTEXT *AcpiS3Context
+ )
+{
+ EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs;
+
+ Facs = (EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *) ((UINTN) (AcpiS3Context->AcpiFacsTable));
+ if ((Facs == NULL) ||
+ (Facs->Signature != EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) ||
+ ((Facs->FirmwareWakingVector == 0) && (Facs->XFirmwareWakingVector == 0)) ) {
+ // Something wrong with FACS
+ return FALSE;
+ }
+ if (Facs->XFirmwareWakingVector != 0) {
+ if ((Facs->Version == EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION) &&
+ ((Facs->Flags & EFI_ACPI_4_0_64BIT_WAKE_SUPPORTED_F) != 0) &&
+ ((Facs->Flags & EFI_ACPI_4_0_OSPM_64BIT_WAKE__F) != 0)) {
+ // Both BIOS and OS wants 64bit vector
+ if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+/**
Jump to OS waking vector.
The function will install boot script done PPI, report S3 resume status code, and then jump to OS waking vector.
@@ -483,10 +518,12 @@ S3ResumeBootOs (
If BootScriptExector driver will not run in 64-bit mode, this function will do nothing.
@param S3NvsPageTableAddress PageTableAddress in ACPINvs
+ @param Build4GPageTableOnly If BIOS just build 4G page table only
**/
VOID
RestoreS3PageTables (
- IN UINTN S3NvsPageTableAddress
+ IN UINTN S3NvsPageTableAddress,
+ IN BOOLEAN Build4GPageTableOnly
)
{
if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
@@ -513,7 +550,7 @@ RestoreS3PageTables (
//
// The assumption is : whole page table is allocated in CONTINOUS memory and CR3 points to TOP page.
//
- DEBUG ((EFI_D_ERROR, "S3NvsPageTableAddress - %x\n", S3NvsPageTableAddress));
+ DEBUG ((EFI_D_ERROR, "S3NvsPageTableAddress - %x (%x)\n", (UINTN)S3NvsPageTableAddress, (UINTN)Build4GPageTableOnly));
//
// By architecture only one PageMapLevel4 exists - so lets allocate storgage for it.
@@ -557,6 +594,14 @@ RestoreS3PageTables (
}
//
+ // NOTE: In order to save time to create full page table, we just create 4G page table by default.
+ // And let PF handler in BootScript driver to create more on request.
+ //
+ if (Build4GPageTableOnly) {
+ PhysicalAddressBits = 32;
+ ZeroMem (PageMap, EFI_PAGES_TO_SIZE(2));
+ }
+ //
// Calculate the table entries needed.
//
if (PhysicalAddressBits <= 39) {
@@ -827,6 +872,7 @@ S3RestoreConfig2 (
EFI_SMRAM_DESCRIPTOR *SmramDescriptor;
SMM_S3_RESUME_STATE *SmmS3ResumeState;
VOID *GuidHob;
+ BOOLEAN Build4GPageTableOnly;
DEBUG ((EFI_D_ERROR, "Enter S3 PEIM\r\n"));
@@ -888,7 +934,12 @@ S3RestoreConfig2 (
//
// Need reconstruct page table here, since we do not trust ACPINvs.
//
- RestoreS3PageTables ((UINTN)AcpiS3Context->S3NvsPageTableAddress);
+ if (IsLongModeWakingVector (AcpiS3Context)) {
+ Build4GPageTableOnly = FALSE;
+ } else {
+ Build4GPageTableOnly = TRUE;
+ }
+ RestoreS3PageTables ((UINTN)AcpiS3Context->S3NvsPageTableAddress, Build4GPageTableOnly);
}
//