Reduce reserved memory consumption by page table buffer,
then OS can have more available memory to use.
Take PhysicalAddressBits = 48 and 2MB page granularity as example,
1:1 Virtual to Physical identity mapping page table buffer needs to be
((512 + 1) * 512 + 1) * 4096 = 1075843072 bytes = 0x40201000 bytes.

When BIOS does not support long mode waking vector, only allocate
2 pages (1G page enabled) or 6 pages for 4G page table, and 8 extra
pages to handles > 4G request by page fault.

Cc: Jiewen Yao <jiewen....@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Star Zeng <star.z...@intel.com>
---
 .../Universal/Acpi/AcpiS3SaveDxe/AcpiS3Save.c      | 193 +++++++++++++--------
 .../Universal/Acpi/AcpiS3SaveDxe/AcpiS3SaveDxe.inf |   5 +-
 2 files changed, 124 insertions(+), 74 deletions(-)

diff --git a/IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiS3Save.c 
b/IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiS3Save.c
index 6de1871..177a73b 100644
--- a/IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiS3Save.c
+++ b/IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiS3Save.c
@@ -2,7 +2,7 @@
   This is an implementation of the ACPI S3 Save protocol.  This is defined in
   S3 boot path specification 0.9.
 
-Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
 
 This program and the accompanying materials
 are licensed and made available under the terms and conditions
@@ -32,6 +32,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER 
EXPRESS OR IMPLIED.
 
 #include "AcpiS3Save.h"
 
+//
+// 8 extra pages for PF handler.
+//
+#define EXTRA_PAGE_TABLE_PAGES   8
+
 /**
   Hook point for AcpiVariableThunkPlatform for InstallAcpiS3Save.
 **/
@@ -303,21 +308,61 @@ FindAcpiFacsTable (
 }
 
 /**
-  Allocates and fills in the Page Directory and Page Table Entries to
-  establish a 1:1 Virtual to Physical mapping.
+  The function will check if long mode waking vector is supported.
+
+  @param[in] Facs   Pointer to FACS table.
+
+  @retval TRUE   Long mode waking vector is supported.
+  @retval FALSE  Long mode waking vector is not supported.
+
+**/
+BOOLEAN
+IsLongModeWakingVectorSupport (
+  IN EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs
+  )
+{
+  if ((Facs == NULL) ||
+      (Facs->Signature != 
EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) ) {
+    //
+    // 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)) {
+      //
+      // BIOS supports 64bit waking vector.
+      //
+      if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
+        return TRUE;
+      }
+    }
+  }
+  return FALSE;
+}
+
+/**
+  Allocates page table buffer.
+
+  @param[in] LongModeWakingVectorSupport    Support long mode waking vector or 
not.
+
   If BootScriptExector driver will run in 64-bit mode, this function will 
establish the 1:1 
-  virtual to physical mapping page table.
+  virtual to physical mapping page table when long mode waking vector is 
supported, otherwise
+  create 4G page table when long mode waking vector is not supported and let 
PF handler to
+  handle > 4G request.
   If BootScriptExector driver will not run in 64-bit mode, this function will 
do nothing. 
   
-  @return  the 1:1 Virtual to Physical identity mapping page table base 
address. 
+  @return Page table base address. 
 
 **/
 EFI_PHYSICAL_ADDRESS
-S3CreateIdentityMappingPageTables (
-  VOID
+S3AllocatePageTablesBuffer (
+  IN BOOLEAN    LongModeWakingVectorSupport
   )
 {  
   if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
+    UINTN                                         ExtraPageTablePages;
     UINT32                                        RegEax;
     UINT32                                        RegEdx;
     UINT8                                         PhysicalAddressBits;
@@ -328,74 +373,80 @@ S3CreateIdentityMappingPageTables (
     VOID                                          *Hob;
     BOOLEAN                                       Page1GSupport;
 
-    S3NvsPageTableAddress = (EFI_PHYSICAL_ADDRESS) PcdGet64 
(PcdIdentifyMappingPageTablePtr);
-    if (S3NvsPageTableAddress != 0x0) {
-      return S3NvsPageTableAddress;
-    } else {
-      Page1GSupport = FALSE;
-      if (PcdGetBool(PcdUse1GPageTable)) {
-        AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
-        if (RegEax >= 0x80000001) {
-          AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);
-          if ((RegEdx & BIT26) != 0) {
-            Page1GSupport = TRUE;
-          }
+    Page1GSupport = FALSE;
+    if (PcdGetBool(PcdUse1GPageTable)) {
+      AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
+      if (RegEax >= 0x80000001) {
+        AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);
+        if ((RegEdx & BIT26) != 0) {
+          Page1GSupport = TRUE;
         }
       }
-      
-      //
-      // Get physical address bits supported.
-      //
-      Hob = GetFirstHob (EFI_HOB_TYPE_CPU);
-      if (Hob != NULL) {
-        PhysicalAddressBits = ((EFI_HOB_CPU *) Hob)->SizeOfMemorySpace;
-      } else {
-        AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
-        if (RegEax >= 0x80000008) {
-          AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
-          PhysicalAddressBits = (UINT8) RegEax;
-        } else {
-          PhysicalAddressBits = 36;
-        }
-      }
-      
-      //
-      // IA-32e paging translates 48-bit linear addresses to 52-bit physical 
addresses.
-      //
-      ASSERT (PhysicalAddressBits <= 52);
-      if (PhysicalAddressBits > 48) {
-        PhysicalAddressBits = 48;
-      }
-      
-      //
-      // Calculate the table entries needed.
-      //
-      if (PhysicalAddressBits <= 39 ) {
-        NumberOfPml4EntriesNeeded = 1;
-        NumberOfPdpEntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits 
- 30));
-      } else {
-        NumberOfPml4EntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits 
- 39));
-        NumberOfPdpEntriesNeeded = 512;
-      }
-      
-      //
-      // We need calculate whole page size then allocate once, because S3 
restore page table does not know each page in Nvs.
-      //
-      if (!Page1GSupport) {
-        TotalPageTableSize = (UINTN)(1 + NumberOfPml4EntriesNeeded + 
NumberOfPml4EntriesNeeded * NumberOfPdpEntriesNeeded);
+    }
+
+    //
+    // Get physical address bits supported.
+    //
+    Hob = GetFirstHob (EFI_HOB_TYPE_CPU);
+    if (Hob != NULL) {
+      PhysicalAddressBits = ((EFI_HOB_CPU *) Hob)->SizeOfMemorySpace;
+    } else {
+      AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
+      if (RegEax >= 0x80000008) {
+        AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
+        PhysicalAddressBits = (UINT8) RegEax;
       } else {
-        TotalPageTableSize = (UINTN)(1 + NumberOfPml4EntriesNeeded);
+        PhysicalAddressBits = 36;
       }
-      DEBUG ((EFI_D_ERROR, "TotalPageTableSize - %x pages\n", 
TotalPageTableSize));
-      
+    }
+
+    //
+    // IA-32e paging translates 48-bit linear addresses to 52-bit physical 
addresses.
+    //
+    ASSERT (PhysicalAddressBits <= 52);
+    if (PhysicalAddressBits > 48) {
+      PhysicalAddressBits = 48;
+    }
+
+    ExtraPageTablePages = 0;
+    if (!LongModeWakingVectorSupport) {
       //
-      // By architecture only one PageMapLevel4 exists - so lets allocate 
storage for it.
+      // Create 4G page table when BIOS does not support long mode waking 
vector,
+      // and let PF handler to handle > 4G request.
       //
-      S3NvsPageTableAddress = 
(EFI_PHYSICAL_ADDRESS)(UINTN)AllocateMemoryBelow4G (EfiReservedMemoryType, 
EFI_PAGES_TO_SIZE(TotalPageTableSize));
-      ASSERT (S3NvsPageTableAddress != 0);
-      PcdSet64 (PcdIdentifyMappingPageTablePtr, S3NvsPageTableAddress); 
-      return S3NvsPageTableAddress;
+      PhysicalAddressBits = 32;
+      ExtraPageTablePages = EXTRA_PAGE_TABLE_PAGES;
+    }
+
+    //
+    // Calculate the table entries needed.
+    //
+    if (PhysicalAddressBits <= 39 ) {
+      NumberOfPml4EntriesNeeded = 1;
+      NumberOfPdpEntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 
30));
+    } else {
+      NumberOfPml4EntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 
39));
+      NumberOfPdpEntriesNeeded = 512;
     }
+
+    //
+    // We need calculate whole page size then allocate once, because S3 
restore page table does not know each page in Nvs.
+    //
+    if (!Page1GSupport) {
+      TotalPageTableSize = (UINTN)(1 + NumberOfPml4EntriesNeeded + 
NumberOfPml4EntriesNeeded * NumberOfPdpEntriesNeeded);
+    } else {
+      TotalPageTableSize = (UINTN)(1 + NumberOfPml4EntriesNeeded);
+    }
+
+    TotalPageTableSize += ExtraPageTablePages;
+    DEBUG ((EFI_D_ERROR, "AcpiS3Save TotalPageTableSize - 0x%x pages\n", 
TotalPageTableSize));
+
+    //
+    // By architecture only one PageMapLevel4 exists - so lets allocate 
storage for it.
+    //
+    S3NvsPageTableAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateMemoryBelow4G 
(EfiReservedMemoryType, EFI_PAGES_TO_SIZE(TotalPageTableSize));
+    ASSERT (S3NvsPageTableAddress != 0);
+    return S3NvsPageTableAddress;
   } else {
     //
     // If DXE is running 32-bit mode, no need to establish page table.
@@ -457,6 +508,7 @@ S3Ready (
   STATIC BOOLEAN                                AlreadyEntered;
   IA32_DESCRIPTOR                               *Idtr;
   IA32_IDT_GATE_DESCRIPTOR                      *IdtGate;
+  EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE  *Facs;
 
   DEBUG ((EFI_D_INFO, "S3Ready!\n"));
 
@@ -476,7 +528,8 @@ S3Ready (
   //
   // Get ACPI Table because we will save its position to variable
   //
-  AcpiS3Context->AcpiFacsTable = 
(EFI_PHYSICAL_ADDRESS)(UINTN)FindAcpiFacsTable ();
+  Facs = (EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *) FindAcpiFacsTable ();
+  AcpiS3Context->AcpiFacsTable = (EFI_PHYSICAL_ADDRESS) (UINTN) Facs;
   ASSERT (AcpiS3Context->AcpiFacsTable != 0);
 
   IdtGate = AllocateMemoryBelow4G (EfiReservedMemoryType, 
sizeof(IA32_IDT_GATE_DESCRIPTOR) * 0x100 + sizeof(IA32_DESCRIPTOR));
@@ -498,7 +551,7 @@ S3Ready (
   //
   // Allocate page table
   //
-  AcpiS3Context->S3NvsPageTableAddress = S3CreateIdentityMappingPageTables ();
+  AcpiS3Context->S3NvsPageTableAddress = S3AllocatePageTablesBuffer 
(IsLongModeWakingVectorSupport (Facs));
 
   //
   // Allocate stack
diff --git 
a/IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiS3SaveDxe.inf 
b/IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiS3SaveDxe.inf
index c5dec05..366eb14 100644
--- a/IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiS3SaveDxe.inf
+++ b/IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiS3SaveDxe.inf
@@ -1,7 +1,7 @@
 ## @file
 # AcpiS3Save module installs ACPI S3 Save protocol to prepare S3 boot data.
 #
-# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
 #
 # This program and the accompanying materials are
 # licensed and made available under the terms and conditions of the BSD License
@@ -77,9 +77,6 @@ [Pcd]
   gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdS3AcpiReservedMemorySize    ## 
SOMETIMES_CONSUMES
   gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdS3BootScriptStackSize       ## 
CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable                         ## 
CONSUMES
-  ## SOMETIMES_CONSUMES
-  ## SOMETIMES_PRODUCES
-  gEfiMdeModulePkgTokenSpaceGuid.PcdIdentifyMappingPageTablePtr
 
 [Depex]
   #
-- 
1.9.5.msysgit.0


------------------------------------------------------------------------------
Don't Limit Your Business. Reach for the Cloud.
GigeNET's Cloud Solutions provide you with the tools and support that
you need to offload your IT needs and focus on growing your business.
Configured For All Businesses. Start Your Cloud Today.
https://www.gigenetcloud.com/
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to