]> git.proxmox.com Git - mirror_edk2.git/commitdiff
1) Improve the EFI Memory Map stability to improve ACPI S4 support
authormdkinney <mdkinney@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 27 Nov 2007 02:47:37 +0000 (02:47 +0000)
committermdkinney <mdkinney@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 27 Nov 2007 02:47:37 +0000 (02:47 +0000)
2) Update DXE IPL to always publish the MemoryTypeInformation HOB

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4327 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Core/Dxe/Mem/Page.c
MdeModulePkg/Core/DxeIplPeim/DxeIpl.h
MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
MdeModulePkg/Core/DxeIplPeim/DxeLoad.c

index c4f3274906b553382380873b0943e0b88b73b0ed..0ac2aa5c91562ac2d620c13c955284a4b1437bc7 100644 (file)
@@ -33,7 +33,10 @@ typedef struct {
   EFI_PHYSICAL_ADDRESS  BaseAddress;\r
   EFI_PHYSICAL_ADDRESS  MaximumAddress;\r
   UINT64                CurrentNumberOfPages;\r
+  UINT64                NumberOfPages;\r
   UINTN                 InformationIndex;\r
+  BOOLEAN               Special;\r
+  BOOLEAN               Runtime;\r
 } EFI_MEMORY_TYPE_STAISTICS;\r
 \r
 //\r
@@ -57,21 +60,21 @@ LIST_ENTRY   mFreeMemoryMapEntryList  = INITIALIZE_LIST_HEAD_VARIABLE (mFreeMemo
 BOOLEAN mMemoryTypeInformationInitialized = FALSE;\r
 \r
 EFI_MEMORY_TYPE_STAISTICS mMemoryTypeStatistics[EfiMaxMemoryType + 1] = {\r
-  { 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType },  // EfiReservedMemoryType\r
-  { 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType },  // EfiLoaderCode\r
-  { 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType },  // EfiLoaderData\r
-  { 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType },  // EfiBootServicesCode\r
-  { 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType },  // EfiBootServicesData\r
-  { 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType },  // EfiRuntimeServicesCode\r
-  { 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType },  // EfiRuntimeServicesData\r
-  { 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType },  // EfiConventionalMemory\r
-  { 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType },  // EfiUnusableMemory\r
-  { 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType },  // EfiACPIReclaimMemory\r
-  { 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType },  // EfiACPIMemoryNVS\r
-  { 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType },  // EfiMemoryMappedIO\r
-  { 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType },  // EfiMemoryMappedIOPortSpace\r
-  { 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType },  // EfiPalCode\r
-  { 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType }   // EfiMaxMemoryType\r
+  { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE,  FALSE },  // EfiReservedMemoryType\r
+  { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE },  // EfiLoaderCode\r
+  { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE },  // EfiLoaderData\r
+  { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE },  // EfiBootServicesCode\r
+  { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE },  // EfiBootServicesData\r
+  { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE,  TRUE  },  // EfiRuntimeServicesCode\r
+  { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE,  TRUE  },  // EfiRuntimeServicesData\r
+  { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE },  // EfiConventionalMemory\r
+  { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE },  // EfiUnusableMemory\r
+  { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE,  FALSE },  // EfiACPIReclaimMemory\r
+  { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE,  FALSE },  // EfiACPIMemoryNVS\r
+  { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE },  // EfiMemoryMappedIO\r
+  { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE },  // EfiMemoryMappedIOPortSpace\r
+  { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE,  TRUE  },  // EfiPalCode\r
+  { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }   // EfiMaxMemoryType\r
 };\r
 \r
 EFI_PHYSICAL_ADDRESS mDefaultMaximumAddress = EFI_MAX_ADDRESS;\r
@@ -397,6 +400,7 @@ Returns:
         mMemoryTypeStatistics[Type].BaseAddress, \r
         gMemoryTypeInformation[Index].NumberOfPages\r
         );\r
+      mMemoryTypeStatistics[Type].NumberOfPages   = gMemoryTypeInformation[Index].NumberOfPages;\r
       gMemoryTypeInformation[Index].NumberOfPages = 0;\r
     }\r
   }\r
@@ -1363,6 +1367,7 @@ Returns:
   LIST_ENTRY                        *Link;\r
   MEMORY_MAP                        *Entry;  \r
   EFI_GCD_MAP_ENTRY                 *GcdMapEntry;  \r
+  EFI_MEMORY_TYPE                   Type;\r
 \r
   //\r
   // Make sure the parameters are valid\r
@@ -1432,21 +1437,33 @@ Returns:
     Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);\r
     ASSERT (Entry->VirtualStart == 0);\r
 \r
+    //\r
+    // Convert internal map into an EFI_MEMORY_DESCRIPTOR\r
+    //\r
     MemoryMap->Type           = Entry->Type;\r
     MemoryMap->PhysicalStart  = Entry->Start;\r
     MemoryMap->VirtualStart   = Entry->VirtualStart;\r
     MemoryMap->NumberOfPages  = RShiftU64 (Entry->End - Entry->Start + 1, EFI_PAGE_SHIFT);\r
-  \r
-    switch (Entry->Type) {\r
-    case EfiRuntimeServicesCode:\r
-    case EfiRuntimeServicesData:\r
-    case EfiPalCode:\r
-      MemoryMap->Attribute = Entry->Attribute | EFI_MEMORY_RUNTIME;\r
-      break;\r
-\r
-    default:\r
-      MemoryMap->Attribute = Entry->Attribute;\r
-      break;\r
+    //\r
+    // If the memory type is EfiConventionalMemory, then determine if the range is part of a\r
+    // memory type bin and needs to be converted to the same memory type as the rest of the \r
+    // memory type bin in order to minimize EFI Memory Map changes across reboots.  This \r
+    // improves the chances for a successful S4 resume in the presence of minor page allocation\r
+    // differences across reboots.\r
+    //\r
+    if (MemoryMap->Type == EfiConventionalMemory) {\r
+      for (Type = (EFI_MEMORY_TYPE) 0; Type < EfiMaxMemoryType; Type++) {\r
+        if (mMemoryTypeStatistics[Type].Special                        &&\r
+            mMemoryTypeStatistics[Type].NumberOfPages > 0              &&\r
+            Entry->Start >= mMemoryTypeStatistics[Type].BaseAddress    &&\r
+            Entry->End   <= mMemoryTypeStatistics[Type].MaximumAddress    ) {\r
+          MemoryMap->Type = Type;\r
+        }\r
+      }\r
+    }\r
+    MemoryMap->Attribute = Entry->Attribute;\r
+    if (mMemoryTypeStatistics[MemoryMap->Type].Runtime) {\r
+      MemoryMap->Attribute |= EFI_MEMORY_RUNTIME;\r
     }\r
     \r
     MemoryMap = NextMemoryDescriptor (MemoryMap, Size);\r
index dab6839ef3e257f5eb064cebb7ebdea855ef7fb5..e82cf38db2edccb7c6df1449ec7a38a0238a18b6 100644 (file)
@@ -30,6 +30,8 @@ Abstract:
 #include <Ppi/SectionExtraction.h>\r
 #include <Ppi/FvLoadFile.h>\r
 #include <Ppi/MemoryDiscovered.h>\r
+#include <Ppi/ReadOnlyVariable2.h>\r
+#include <Guid/MemoryTypeInformation.h>\r
 #include <Ppi/Decompress.h>\r
 #include <Ppi/FirmwareVolumeInfo.h>\r
 \r
index c28525acaf3dc4ac8120de08dd1ae54ae761de04..898e67ed5aba3040cc03554a0238621a32a289cf 100644 (file)
   gEfiDxeIplPpiGuid                             # PPI SOMETIMES_PRODUCED\r
   gEfiPeiDecompressPpiGuid\r
   gEfiPeiFirmwareVolumeInfoPpiGuid\r
+  gEfiPeiReadOnlyVariable2PpiGuid\r
+\r
+[Guids]\r
+  gEfiMemoryTypeInformationGuid\r
 \r
 [FeaturePcd.common]\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSupportCustomDecompress\r
index d593e30c74b99710135b3e7e25601b4807788ec0..b7cadedd89c9f479adcc3095c3409d795c747e02 100644 (file)
@@ -170,6 +170,9 @@ DxeLoadCore (
   EFI_PEI_FV_HANDLE                         VolumeHandle;\r
   EFI_PEI_FILE_HANDLE                       FileHandle;\r
   UINTN                                     Instance;\r
+  EFI_PEI_READ_ONLY_VARIABLE2_PPI           *Variable;\r
+  UINTN                                     DataSize;\r
+  EFI_MEMORY_TYPE_INFORMATION               MemoryData [EfiMaxMemoryType + 1];\r
 \r
   //\r
   // if in S3 Resume, restore configure\r
@@ -192,6 +195,34 @@ DxeLoadCore (
     //\r
   }\r
   \r
+  Status = PeiServicesLocatePpi (\r
+             &gEfiPeiReadOnlyVariable2PpiGuid,\r
+             0,\r
+             NULL,\r
+             (VOID **)&Variable\r
+             );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  DataSize = sizeof (MemoryData);\r
+  Status = Variable->GetVariable ( \r
+                       Variable, \r
+                       EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,\r
+                       &gEfiMemoryTypeInformationGuid,\r
+                       NULL,\r
+                       &DataSize,\r
+                       &MemoryData\r
+                       );\r
+\r
+  if (!EFI_ERROR (Status)) {\r
+    //\r
+    // Build the GUID'd HOB for DXE\r
+    //\r
+    BuildGuidDataHob (\r
+      &gEfiMemoryTypeInformationGuid,\r
+      MemoryData,\r
+      DataSize\r
+      );\r
+  }\r
   //\r
   // If any FV contains an encapsulated FV extract that FV\r
   //\r