]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/Dxe/Mem/Page.c
Assert() break point default is DEADLOOP().
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / Mem / Page.c
index c4f3274906b553382380873b0943e0b88b73b0ed..daf00f237d0f8a3b77431dad27d372d0eb2ded8e 100644 (file)
@@ -1,6 +1,8 @@
-/*++\r
+/** @file\r
+\r
+  UEFI Memory page management functions.\r
 \r
-Copyright (c) 2007, Intel Corporation                                                         \r
+Copyright (c) 2007 - 2008, Intel Corporation                                                         \r
 All rights reserved. This program and the accompanying materials                          \r
 are licensed and made available under the terms and conditions of the BSD License         \r
 which accompanies this distribution.  The full text of the license may be found at        \r
@@ -9,18 +11,7 @@ http://opensource.org/licenses/bsd-license.php
 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
 \r
-Module Name:\r
-\r
-  page.c\r
-\r
-Abstract:\r
-\r
-  EFI Memory page management\r
-\r
-\r
-Revision History\r
-\r
---*/\r
+**/\r
 \r
 #include <DxeMain.h>\r
 \r
@@ -33,7 +24,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 +51,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 +391,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 +1358,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
@@ -1427,26 +1423,38 @@ Returns:
   //\r
   // Build the map\r
   //\r
-  ZeroMem (MemoryMap, Size);\r
+  ZeroMem (MemoryMap, BufferSize);\r
   for (Link = gMemoryMap.ForwardLink; Link != &gMemoryMap; Link = Link->ForwardLink) {\r
     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