]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Create 4G page table by default, and using PF to handle >4G MMIO access, to improve...
authorjyao1 <jyao1@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 14 Aug 2012 04:42:50 +0000 (04:42 +0000)
committerjyao1 <jyao1@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 14 Aug 2012 04:42:50 +0000 (04:42 +0000)
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

MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/IA32/SetIdtEntry.c
MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/X64/S3Asm.S
MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/X64/S3Asm.asm
MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/X64/SetIdtEntry.c
UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c

index 2fbbdb2e315029166e929a33c23eeb41a7a4c99f..04d4893a97c1c920de4937bf7d2d8cd9ed7959bd 100644 (file)
@@ -78,6 +78,9 @@
 [FeaturePcd]\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode\r
 \r
 [FeaturePcd]\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode\r
 \r
+[Pcd]\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable\r
+\r
 [Depex]\r
   gEfiLockBoxProtocolGuid\r
 \r
 [Depex]\r
   gEfiLockBoxProtocolGuid\r
 \r
index 8221be6c8729e44d963fb09cd6eace399a4927f9..9f04959cd98404751e5164c9003b1f13c1698c9d 100644 (file)
@@ -3,7 +3,7 @@
 \r
   Set a IDT entry for interrupt vector 3 for debug purpose for IA32 platform\r
 \r
 \r
   Set a IDT entry for interrupt vector 3 for debug purpose for IA32 platform\r
 \r
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
 \r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 \r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
@@ -54,7 +54,7 @@ SetIdtEntry (
   S3DebugBuffer = (UINTN) (AcpiS3Context->S3DebugBufferAddress);\r
 \r
   IdtEntry->OffsetLow       = (UINT16)S3DebugBuffer;\r
   S3DebugBuffer = (UINTN) (AcpiS3Context->S3DebugBufferAddress);\r
 \r
   IdtEntry->OffsetLow       = (UINT16)S3DebugBuffer;\r
-  IdtEntry->SegmentSelector = (UINT16)AsmReadCs ();;\r
+  IdtEntry->SegmentSelector = (UINT16)AsmReadCs ();\r
   IdtEntry->Attributes      = (UINT16)INTERRUPT_GATE_ATTRIBUTE;\r
   IdtEntry->OffsetHigh      = (UINT16)(S3DebugBuffer >> 16);\r
 \r
   IdtEntry->Attributes      = (UINT16)INTERRUPT_GATE_ATTRIBUTE;\r
   IdtEntry->OffsetHigh      = (UINT16)(S3DebugBuffer >> 16);\r
 \r
index 7f5bdebfd214fbf1e5775132bf8e8a076a07c8f6..dcce6fb6aefd201fc446bb8b49ee1ccc4803e9d3 100644 (file)
@@ -2,7 +2,7 @@
 #   This is the assembly code for transferring to control to OS S3 waking vector\r
 #   for X64 platform\r
 #\r
 #   This is the assembly code for transferring to control to OS S3 waking vector\r
 #   for X64 platform\r
 #\r
-# Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
 #\r
 # This program and the accompanying materials are\r
 # licensed and made available under the terms and conditions of the BSD License\r
 #\r
 # This program and the accompanying materials are\r
 # licensed and made available under the terms and conditions of the BSD License\r
@@ -80,3 +80,51 @@ ASM_PFX(AsmTransferControl16):
 ASM_GLOBAL ASM_PFX(AsmJmpAddr32)\r
 ASM_PFX(AsmJmpAddr32):\r
     .long    0\r
 ASM_GLOBAL ASM_PFX(AsmJmpAddr32)\r
 ASM_PFX(AsmJmpAddr32):\r
     .long    0\r
+\r
+ASM_GLOBAL ASM_PFX(PageFaultHandlerHook)\r
+ASM_PFX(PageFaultHandlerHook):\r
+    pushq    %rax                         # save all volatile registers\r
+    pushq    %rcx\r
+    pushq    %rdx\r
+    pushq    %r8\r
+    pushq    %r9\r
+    pushq    %r10\r
+    pushq    %r11\r
+    # save volatile fp registers\r
+    addq     $-0x68, %rsp\r
+    stmxcsr  0x60(%rsp)\r
+    movdqa   %xmm0, 0x0(%rsp) \r
+    movdqa   %xmm1, 0x10(%rsp) \r
+    movdqa   %xmm2, 0x20(%rsp) \r
+    movdqa   %xmm3, 0x30(%rsp) \r
+    movdqa   %xmm4, 0x40(%rsp) \r
+    movdqa   %xmm5, 0x50(%rsp) \r
+\r
+    addq     $-0x20, %rsp\r
+    call     ASM_PFX(PageFaultHandler)\r
+    addq     $0x20, %rsp\r
+\r
+    # load volatile fp registers\r
+    ldmxcsr  0x60(%rsp)\r
+    movdqa   0x0(%rsp), %xmm0\r
+    movdqa   0x10(%rsp), %xmm1\r
+    movdqa   0x20(%rsp), %xmm2\r
+    movdqa   0x30(%rsp), %xmm3\r
+    movdqa   0x40(%rsp), %xmm4\r
+    movdqa   0x50(%rsp), %xmm5\r
+    addq     $0x68, %rsp\r
+\r
+    testb    %al, %al\r
+\r
+    popq     %r11\r
+    popq     %r10\r
+    popq     %r9\r
+    popq     %r8\r
+    popq     %rdx\r
+    popq     %rcx\r
+    popq     %rax                         # restore all volatile registers\r
+    jnz      L1\r
+    jmpq     *ASM_PFX(mOriginalHandler)\r
+L1:\r
+    addq     $0x08, %rsp                  # skip error code for PF\r
+    iretq\r
index f3d327df75c894699aa02a5ffa5bb8a881dceea7..0b7432daf7cfe99e6d61d6c949f4fa4cfec716f0 100644 (file)
@@ -2,7 +2,7 @@
 ;   This is the assembly code for transferring to control to OS S3 waking vector\r
 ;   for X64 platform\r
 ;\r
 ;   This is the assembly code for transferring to control to OS S3 waking vector\r
 ;   for X64 platform\r
 ;\r
-; Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>\r
+; Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
 ;\r
 ; This program and the accompanying materials\r
 ; are licensed and made available under the terms and conditions of the BSD License\r
 ;\r
 ; This program and the accompanying materials\r
 ; are licensed and made available under the terms and conditions of the BSD License\r
@@ -14,6 +14,9 @@
 ;\r
 ;;\r
 \r
 ;\r
 ;;\r
 \r
+EXTERN mOriginalHandler:QWORD\r
+EXTERN PageFaultHandler:PROC\r
+\r
     .code\r
     \r
 EXTERNDEF   AsmFixAddress16:DWORD\r
     .code\r
     \r
 EXTERNDEF   AsmFixAddress16:DWORD\r
@@ -81,4 +84,52 @@ AsmTransferControl16  PROC
 AsmJmpAddr32 DD  ?\r
 AsmTransferControl16  ENDP\r
 \r
 AsmJmpAddr32 DD  ?\r
 AsmTransferControl16  ENDP\r
 \r
+PageFaultHandlerHook PROC\r
+    push    rax                         ; save all volatile registers\r
+    push    rcx\r
+    push    rdx\r
+    push    r8\r
+    push    r9\r
+    push    r10\r
+    push    r11\r
+    ; save volatile fp registers\r
+    add     rsp, -68h\r
+    stmxcsr [rsp + 60h]\r
+    movdqa  [rsp + 0h], xmm0\r
+    movdqa  [rsp + 10h], xmm1\r
+    movdqa  [rsp + 20h], xmm2\r
+    movdqa  [rsp + 30h], xmm3\r
+    movdqa  [rsp + 40h], xmm4\r
+    movdqa  [rsp + 50h], xmm5\r
+\r
+    add     rsp, -20h\r
+    call    PageFaultHandler\r
+    add     rsp, 20h\r
+    \r
+    ; load volatile fp registers\r
+    ldmxcsr [rsp + 60h]\r
+    movdqa  xmm0,  [rsp + 0h]\r
+    movdqa  xmm1,  [rsp + 10h]\r
+    movdqa  xmm2,  [rsp + 20h]\r
+    movdqa  xmm3,  [rsp + 30h]\r
+    movdqa  xmm4,  [rsp + 40h]\r
+    movdqa  xmm5,  [rsp + 50h]\r
+    add     rsp, 68h\r
+\r
+    test    al, al\r
+    \r
+    pop     r11\r
+    pop     r10\r
+    pop     r9\r
+    pop     r8\r
+    pop     rdx\r
+    pop     rcx\r
+    pop     rax                         ; restore all volatile registers\r
+    jnz     @F\r
+    jmp     mOriginalHandler\r
+@@:\r
+    add     rsp, 08h                    ; skip error code for PF\r
+    iretq\r
+PageFaultHandlerHook ENDP\r
+\r
     END\r
     END\r
index 975cf3a561757f5c1c8b034ca7b12b329e27d463..db11697e7c00c7f5a1ed90d7ba0e08caa3b97a4d 100644 (file)
@@ -33,6 +33,63 @@ typedef struct {
 #define INTERRUPT_GATE_ATTRIBUTE   0x8e00\r
 \r
 #pragma pack()\r
 #define INTERRUPT_GATE_ATTRIBUTE   0x8e00\r
 \r
 #pragma pack()\r
+\r
+#define IA32_PG_P                   BIT0\r
+#define IA32_PG_RW                  BIT1\r
+#define IA32_PG_PS                  BIT7\r
+\r
+UINT64                             mPhyMask;\r
+BOOLEAN                            mPage1GSupport;\r
+VOID                               *mOriginalHandler;\r
+UINTN                              mS3NvsPageTableAddress;\r
+\r
+VOID\r
+EFIAPI\r
+PageFaultHandlerHook (\r
+  VOID\r
+  );\r
+\r
+VOID\r
+HookPageFaultHandler (\r
+  IN INTERRUPT_GATE_DESCRIPTOR                     *IdtEntry\r
+  )\r
+{\r
+  UINT32         RegEax;\r
+  UINT32         RegEdx;\r
+\r
+  AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);\r
+  mPhyMask = LShiftU64 (1, (UINT8)RegEax) - 1;\r
+  mPhyMask &= (1ull << 48) - SIZE_4KB;\r
+\r
+  mPage1GSupport = FALSE;\r
+  if (PcdGetBool(PcdUse1GPageTable)) {\r
+    AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);\r
+    if (RegEax >= 0x80000001) {\r
+      AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);\r
+      if ((RegEdx & BIT26) != 0) {\r
+        mPage1GSupport = TRUE;\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  // Set Page Fault entry to catch >4G access\r
+  //\r
+  mOriginalHandler = (VOID *)(UINTN)(LShiftU64 (IdtEntry->Offset63To32, 32) + IdtEntry->Offset15To0 + (IdtEntry->Offset31To16 << 16));\r
+  IdtEntry->Offset15To0     = (UINT16)((UINTN)PageFaultHandlerHook);\r
+  IdtEntry->SegmentSelector = (UINT16)AsmReadCs ();\r
+  IdtEntry->Attributes      = (UINT16)INTERRUPT_GATE_ATTRIBUTE;\r
+  IdtEntry->Offset31To16    = (UINT16)((UINTN)PageFaultHandlerHook >> 16);\r
+  IdtEntry->Offset63To32    = (UINT32)((UINTN)PageFaultHandlerHook >> 32);\r
+  IdtEntry->Reserved        = 0;\r
+\r
+  if (mPage1GSupport) {\r
+    mS3NvsPageTableAddress = (UINTN)(AsmReadCr3 () & mPhyMask) + EFI_PAGES_TO_SIZE(2);\r
+  }else {\r
+    mS3NvsPageTableAddress = (UINTN)(AsmReadCr3 () & mPhyMask) + EFI_PAGES_TO_SIZE(6);\r
+  }\r
+}\r
+\r
 /**\r
   Set a IDT entry for interrupt vector 3 for debug purpose.\r
 \r
 /**\r
   Set a IDT entry for interrupt vector 3 for debug purpose.\r
 \r
@@ -66,11 +123,69 @@ SetIdtEntry (
   S3DebugBuffer = (UINTN) (AcpiS3Context->S3DebugBufferAddress);\r
 \r
   IdtEntry->Offset15To0     = (UINT16)S3DebugBuffer;\r
   S3DebugBuffer = (UINTN) (AcpiS3Context->S3DebugBufferAddress);\r
 \r
   IdtEntry->Offset15To0     = (UINT16)S3DebugBuffer;\r
-  IdtEntry->SegmentSelector = (UINT16)AsmReadCs ();;\r
+  IdtEntry->SegmentSelector = (UINT16)AsmReadCs ();\r
   IdtEntry->Attributes      = (UINT16)INTERRUPT_GATE_ATTRIBUTE;\r
   IdtEntry->Offset31To16    = (UINT16)(S3DebugBuffer >> 16);\r
   IdtEntry->Offset63To32    = (UINT32)(S3DebugBuffer >> 32);\r
   IdtEntry->Reserved        = 0;\r
 \r
   IdtEntry->Attributes      = (UINT16)INTERRUPT_GATE_ATTRIBUTE;\r
   IdtEntry->Offset31To16    = (UINT16)(S3DebugBuffer >> 16);\r
   IdtEntry->Offset63To32    = (UINT32)(S3DebugBuffer >> 32);\r
   IdtEntry->Reserved        = 0;\r
 \r
+  IdtEntry = (INTERRUPT_GATE_DESCRIPTOR *)(IdtDescriptor->Base + (14 * sizeof (INTERRUPT_GATE_DESCRIPTOR)));\r
+  HookPageFaultHandler (IdtEntry);\r
+\r
+  AsmWriteIdtr (IdtDescriptor);\r
+}\r
+\r
+UINTN\r
+GetNewPage (\r
+  IN UINTN  PageNum\r
+  )\r
+{\r
+  UINTN  NewPage;\r
+  NewPage = mS3NvsPageTableAddress;\r
+  ZeroMem ((VOID *)NewPage, EFI_PAGES_TO_SIZE(PageNum));\r
+  mS3NvsPageTableAddress += EFI_PAGES_TO_SIZE(PageNum);\r
+  return NewPage;\r
 }\r
 \r
 }\r
 \r
+BOOLEAN\r
+EFIAPI\r
+PageFaultHandler (\r
+  VOID\r
+  )\r
+{\r
+  UINT64         *PageTable;\r
+  UINT64         PFAddress;\r
+  UINTN          PTIndex;\r
+\r
+  PFAddress = AsmReadCr2 ();\r
+  DEBUG ((EFI_D_ERROR, "BootScript - PageFaultHandler: Cr2 - %lx\n", PFAddress));\r
+\r
+  if (PFAddress >= mPhyMask + SIZE_4KB) {\r
+    return FALSE;\r
+  }\r
+  PFAddress &= mPhyMask;\r
+\r
+  PageTable = (UINT64*)(UINTN)(AsmReadCr3 () & mPhyMask);\r
+\r
+  PTIndex = BitFieldRead64 (PFAddress, 39, 47);\r
+  // PML4E\r
+  if ((PageTable[PTIndex] & IA32_PG_P) == 0) {\r
+    PageTable[PTIndex] = GetNewPage (1) | IA32_PG_P | IA32_PG_RW;\r
+  }\r
+  PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & mPhyMask);\r
+  PTIndex = BitFieldRead64 (PFAddress, 30, 38);\r
+  // PDPTE\r
+  if (mPage1GSupport) {\r
+    PageTable[PTIndex] = PFAddress | IA32_PG_P | IA32_PG_RW | IA32_PG_PS;\r
+  } else {\r
+    if ((PageTable[PTIndex] & IA32_PG_P) == 0) {\r
+      PageTable[PTIndex] = GetNewPage (1) | IA32_PG_P | IA32_PG_RW;\r
+    }\r
+    PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & mPhyMask);\r
+    PTIndex = BitFieldRead64 (PFAddress, 21, 29);\r
+    // PD\r
+    PageTable[PTIndex] = PFAddress | IA32_PG_P | IA32_PG_RW | IA32_PG_PS;\r
+  }\r
+\r
+  return TRUE;\r
+}\r
index 189f0c50c4a784ffa8394f5a040c27fda8d8c4af..de3aec85e185375cce9660e05c219160d461b741 100644 (file)
@@ -367,6 +367,41 @@ WriteToOsS3PerformanceData (
   PerfHeader->S3EntryNum = (UINT32) Index;\r
 }\r
 \r
   PerfHeader->S3EntryNum = (UINT32) Index;\r
 }\r
 \r
+/**\r
+  The function will check if current waking vector is long mode.\r
+\r
+  @param  AcpiS3Context                 a pointer to a structure of ACPI_S3_CONTEXT\r
+\r
+  @retval TRUE   Current context need long mode waking vector.\r
+  @retval FALSE  Current context need not long mode waking vector.\r
+**/\r
+BOOLEAN\r
+IsLongModeWakingVector (\r
+  IN ACPI_S3_CONTEXT                *AcpiS3Context\r
+  )\r
+{\r
+  EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE  *Facs;\r
+\r
+  Facs = (EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *) ((UINTN) (AcpiS3Context->AcpiFacsTable));\r
+  if ((Facs == NULL) ||\r
+      (Facs->Signature != EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) ||\r
+      ((Facs->FirmwareWakingVector == 0) && (Facs->XFirmwareWakingVector == 0)) ) {\r
+    // Something wrong with FACS\r
+    return FALSE;\r
+  }\r
+  if (Facs->XFirmwareWakingVector != 0) {\r
+    if ((Facs->Version == EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION) &&\r
+        ((Facs->Flags & EFI_ACPI_4_0_64BIT_WAKE_SUPPORTED_F) != 0) &&\r
+        ((Facs->Flags & EFI_ACPI_4_0_OSPM_64BIT_WAKE__F) != 0)) {\r
+      // Both BIOS and OS wants 64bit vector\r
+      if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {\r
+        return TRUE;\r
+      }\r
+    }\r
+  }\r
+  return FALSE;\r
+}\r
+\r
 /**\r
   Jump to OS waking vector.\r
   The function will install boot script done PPI, report S3 resume status code, and then jump to OS waking vector.\r
 /**\r
   Jump to OS waking vector.\r
   The function will install boot script done PPI, report S3 resume status code, and then jump to OS waking vector.\r
@@ -483,10 +518,12 @@ S3ResumeBootOs (
   If BootScriptExector driver will not run in 64-bit mode, this function will do nothing. \r
 \r
   @param S3NvsPageTableAddress   PageTableAddress in ACPINvs\r
   If BootScriptExector driver will not run in 64-bit mode, this function will do nothing. \r
 \r
   @param S3NvsPageTableAddress   PageTableAddress in ACPINvs\r
+  @param Build4GPageTableOnly    If BIOS just build 4G page table only\r
 **/\r
 VOID\r
 RestoreS3PageTables (\r
 **/\r
 VOID\r
 RestoreS3PageTables (\r
-  IN UINTN                                         S3NvsPageTableAddress\r
+  IN UINTN                                         S3NvsPageTableAddress,\r
+  IN BOOLEAN                                       Build4GPageTableOnly\r
   )\r
 {\r
   if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {\r
   )\r
 {\r
   if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {\r
@@ -513,7 +550,7 @@ RestoreS3PageTables (
     //\r
     // The assumption is : whole page table is allocated in CONTINOUS memory and CR3 points to TOP page.\r
     //\r
     //\r
     // The assumption is : whole page table is allocated in CONTINOUS memory and CR3 points to TOP page.\r
     //\r
-    DEBUG ((EFI_D_ERROR, "S3NvsPageTableAddress - %x\n", S3NvsPageTableAddress));\r
+    DEBUG ((EFI_D_ERROR, "S3NvsPageTableAddress - %x (%x)\n", (UINTN)S3NvsPageTableAddress, (UINTN)Build4GPageTableOnly));\r
 \r
     //\r
     // By architecture only one PageMapLevel4 exists - so lets allocate storgage for it.\r
 \r
     //\r
     // By architecture only one PageMapLevel4 exists - so lets allocate storgage for it.\r
@@ -556,6 +593,14 @@ RestoreS3PageTables (
       PhysicalAddressBits = 48;\r
     }\r
 \r
       PhysicalAddressBits = 48;\r
     }\r
 \r
+    //\r
+    // NOTE: In order to save time to create full page table, we just create 4G page table by default.\r
+    // And let PF handler in BootScript driver to create more on request.\r
+    //\r
+    if (Build4GPageTableOnly) {\r
+      PhysicalAddressBits = 32;\r
+      ZeroMem (PageMap, EFI_PAGES_TO_SIZE(2));\r
+    }\r
     //\r
     // Calculate the table entries needed.\r
     //\r
     //\r
     // Calculate the table entries needed.\r
     //\r
@@ -827,6 +872,7 @@ S3RestoreConfig2 (
   EFI_SMRAM_DESCRIPTOR                          *SmramDescriptor;\r
   SMM_S3_RESUME_STATE                           *SmmS3ResumeState;\r
   VOID                                          *GuidHob;\r
   EFI_SMRAM_DESCRIPTOR                          *SmramDescriptor;\r
   SMM_S3_RESUME_STATE                           *SmmS3ResumeState;\r
   VOID                                          *GuidHob;\r
+  BOOLEAN                                       Build4GPageTableOnly;\r
 \r
   DEBUG ((EFI_D_ERROR, "Enter S3 PEIM\r\n"));\r
 \r
 \r
   DEBUG ((EFI_D_ERROR, "Enter S3 PEIM\r\n"));\r
 \r
@@ -888,7 +934,12 @@ S3RestoreConfig2 (
     //\r
     // Need reconstruct page table here, since we do not trust ACPINvs.\r
     //\r
     //\r
     // Need reconstruct page table here, since we do not trust ACPINvs.\r
     //\r
-    RestoreS3PageTables ((UINTN)AcpiS3Context->S3NvsPageTableAddress);\r
+    if (IsLongModeWakingVector (AcpiS3Context)) {\r
+      Build4GPageTableOnly = FALSE;\r
+    } else {\r
+      Build4GPageTableOnly = TRUE;\r
+    }\r
+    RestoreS3PageTables ((UINTN)AcpiS3Context->S3NvsPageTableAddress, Build4GPageTableOnly);\r
   }\r
 \r
   //\r
   }\r
 \r
   //\r