]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkModulePkg/Core/Dxe/Mem/Page.c
Update MDE and EdkModule packages for ICC build with /W4 /WX /Ox switches, for some...
[mirror_edk2.git] / EdkModulePkg / Core / Dxe / Mem / Page.c
index d14468945f2615762f90becbeb27e777807a7cfa..c4f3274906b553382380873b0943e0b88b73b0ed 100644 (file)
@@ -1,6 +1,6 @@
 /*++\r
 \r
-Copyright (c) 2006, Intel Corporation                                                         \r
+Copyright (c) 2007, 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
@@ -50,7 +50,10 @@ UINTN     mMemoryMapKey = 0;
 UINTN         mMapDepth = 0;\r
 MEMORY_MAP    mMapStack[MAX_MAP_DEPTH];\r
 UINTN         mFreeMapStack = 0;\r
-\r
+//\r
+// This list maintain the free memory map list\r
+//\r
+LIST_ENTRY   mFreeMemoryMapEntryList  = INITIALIZE_LIST_HEAD_VARIABLE (mFreeMemoryMapEntryList);\r
 BOOLEAN mMemoryTypeInformationInitialized = FALSE;\r
 \r
 EFI_MEMORY_TYPE_STAISTICS mMemoryTypeStatistics[EfiMaxMemoryType + 1] = {\r
@@ -94,6 +97,7 @@ EFI_MEMORY_TYPE_INFORMATION gMemoryTypeInformation[EfiMaxMemoryType + 1] = {
 //\r
 // Internal prototypes\r
 //\r
+STATIC\r
 VOID \r
 PromoteMemoryResource (\r
   VOID\r
@@ -127,7 +131,13 @@ VOID
 RemoveMemoryMapEntry (\r
   MEMORY_MAP      *Entry\r
   );\r
-\r
+  \r
+STATIC\r
+MEMORY_MAP *\r
+AllocateMemoryMapEntry (\r
+  VOID\r
+  );\r
\r
 VOID\r
 CoreAcquireMemoryLock (\r
   VOID\r
@@ -175,6 +185,7 @@ Returns:
   CoreReleaseLock (&gMemoryLock);\r
 }\r
 \r
+STATIC\r
 VOID\r
 PromoteMemoryResource (\r
   VOID\r
@@ -308,7 +319,7 @@ Returns:
     //\r
     // Make sure the memory type in the gMemoryTypeInformation[] array is valid\r
     //\r
-    Type = gMemoryTypeInformation[Index].Type;\r
+    Type = (EFI_MEMORY_TYPE) (gMemoryTypeInformation[Index].Type);\r
     if (Type < 0 || Type > EfiMaxMemoryType) {\r
       continue;\r
     }\r
@@ -333,7 +344,7 @@ Returns:
           //\r
           // Make sure the memory type in the gMemoryTypeInformation[] array is valid\r
           //\r
-          Type = gMemoryTypeInformation[FreeIndex].Type;\r
+          Type = (EFI_MEMORY_TYPE) (gMemoryTypeInformation[FreeIndex].Type);\r
           if (Type < 0 || Type > EfiMaxMemoryType) {\r
             continue;\r
           }\r
@@ -376,7 +387,7 @@ Returns:
     //\r
     // Make sure the memory type in the gMemoryTypeInformation[] array is valid\r
     //\r
-    Type = gMemoryTypeInformation[Index].Type;\r
+    Type = (EFI_MEMORY_TYPE) (gMemoryTypeInformation[Index].Type);\r
     if (Type < 0 || Type > EfiMaxMemoryType) {\r
       continue;\r
     }\r
@@ -394,7 +405,7 @@ Returns:
   // If the number of pages reserved for a memory type is 0, then all allocations for that type\r
   // should be in the default range.\r
   //\r
-  for (Type = 0; Type < EfiMaxMemoryType; Type++) {\r
+  for (Type = (EFI_MEMORY_TYPE) 0; Type < EfiMaxMemoryType; Type++) {\r
     for (Index = 0; gMemoryTypeInformation[Index].Type != EfiMaxMemoryType; Index++) {\r
       if (Type == (EFI_MEMORY_TYPE)gMemoryTypeInformation[Index].Type) {\r
         mMemoryTypeStatistics[Type].InformationIndex = Index;\r
@@ -507,7 +518,7 @@ Returns:
   //\r
 \r
   mMapStack[mMapDepth].Signature     = MEMORY_MAP_SIGNATURE;\r
-  mMapStack[mMapDepth].FromPool      = FALSE;\r
+  mMapStack[mMapDepth].FromPages      = FALSE;\r
   mMapStack[mMapDepth].Type          = Type;\r
   mMapStack[mMapDepth].Start         = Start;\r
   mMapStack[mMapDepth].End           = End;\r
@@ -562,11 +573,10 @@ Returns:
   mFreeMapStack += 1;\r
 \r
   while (mMapDepth) {\r
-\r
     //\r
-    // Allocate memory for a entry\r
+    // Deque an memory map entry from mFreeMemoryMapEntryList \r
     //\r
-    Entry = CoreAllocatePoolI (EfiRuntimeServicesData, sizeof(MEMORY_MAP));\r
+    Entry = AllocateMemoryMapEntry ();\r
     \r
     ASSERT (Entry);\r
 \r
@@ -578,20 +588,20 @@ Returns:
     if (mMapStack[mMapDepth].Link.ForwardLink != NULL) {\r
 \r
       //\r
-      // Move this entry to general pool\r
+      // Move this entry to general memory\r
       //\r
       RemoveEntryList (&mMapStack[mMapDepth].Link);\r
       mMapStack[mMapDepth].Link.ForwardLink = NULL;\r
 \r
       CopyMem (Entry , &mMapStack[mMapDepth], sizeof (MEMORY_MAP));\r
-      Entry->FromPool = TRUE;\r
+      Entry->FromPages = TRUE;\r
 \r
       //\r
       // Find insertion location\r
       //\r
       for (Link2 = gMemoryMap.ForwardLink; Link2 != &gMemoryMap; Link2 = Link2->ForwardLink) {\r
         Entry2 = CR (Link2, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);\r
-        if (Entry2->FromPool && Entry2->Start > Entry->Start) {\r
+        if (Entry2->FromPages && Entry2->Start > Entry->Start) {\r
           break;\r
         }\r
       }\r
@@ -599,12 +609,11 @@ Returns:
       InsertTailList (Link2, &Entry->Link);\r
 \r
     } else {\r
-\r
-      //\r
-      // It was removed, don't move it\r
+      // \r
+      // This item of mMapStack[mMapDepth] has already been dequeued from gMemoryMap list,\r
+      // so here no need to move it to memory.\r
       //\r
-      CoreFreePoolI (Entry);\r
-\r
+      InsertTailList (&mFreeMemoryMapEntryList, &Entry->Link);\r
     }\r
   }\r
 \r
@@ -635,11 +644,70 @@ Returns:
   RemoveEntryList (&Entry->Link);\r
   Entry->Link.ForwardLink = NULL;\r
 \r
-  if (Entry->FromPool) {\r
-    CoreFreePoolI (Entry);\r
+  if (Entry->FromPages) {\r
+       //\r
+       // Insert the free memory map descriptor to the end of mFreeMemoryMapEntryList\r
+       //\r
+    InsertTailList (&mFreeMemoryMapEntryList, &Entry->Link);\r
   }\r
 }\r
 \r
+STATIC\r
+MEMORY_MAP *\r
+AllocateMemoryMapEntry (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Internal function.  Deque a descriptor entry from the mFreeMemoryMapEntryList.\r
+  If the list is emtry, then allocate a new page to refuel the list. \r
+  Please Note this algorithm to allocate the memory map descriptor has a property\r
+  that the memory allocated for memory entries always grows, and will never really be freed \r
+  For example, if the current boot uses 2000 memory map entries at the maximum point, but\r
+  ends up with only 50 at the time the OS is booted, then the memory associated with the 1950 \r
+  memory map entries is still allocated from EfiBootServicesMemory.  \r
+\r
+Arguments:\r
+\r
+  NONE\r
+\r
+Returns:\r
+\r
+  The Memory map descriptor dequed from the mFreeMemoryMapEntryList\r
+\r
+--*/ \r
+{\r
+  MEMORY_MAP*            FreeDescriptorEntries;\r
+  MEMORY_MAP*            Entry;\r
+  UINTN                  Index;\r
+  \r
+  if (IsListEmpty (&mFreeMemoryMapEntryList)) {\r
+    // \r
+    // The list is empty, to allocate one page to refuel the list\r
+    //\r
+    FreeDescriptorEntries = CoreAllocatePoolPages (EfiBootServicesData, EFI_SIZE_TO_PAGES(DEFAULT_PAGE_ALLOCATION), DEFAULT_PAGE_ALLOCATION);\r
+    if(FreeDescriptorEntries != NULL) {\r
+      //\r
+      // Enque the free memmory map entries into the list\r
+      //\r
+      for (Index = 0; Index< DEFAULT_PAGE_ALLOCATION / sizeof(MEMORY_MAP); Index++) {\r
+        FreeDescriptorEntries[Index].Signature = MEMORY_MAP_SIGNATURE;\r
+        InsertTailList (&mFreeMemoryMapEntryList, &FreeDescriptorEntries[Index].Link);\r
+      }     \r
+    } else {\r
+      return NULL;\r
+    }\r
+  }\r
+  //\r
+  // dequeue the first descriptor from the list\r
+  //\r
+  Entry = CR (mFreeMemoryMapEntryList.ForwardLink, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);\r
+  RemoveEntryList (&Entry->Link);\r
+  \r
+  return Entry;\r
+}    \r
 \r
 STATIC\r
 EFI_STATUS\r
@@ -788,7 +856,7 @@ Returns:
       // Add a new one\r
       //\r
       mMapStack[mMapDepth].Signature = MEMORY_MAP_SIGNATURE;\r
-      mMapStack[mMapDepth].FromPool  = FALSE;\r
+      mMapStack[mMapDepth].FromPages  = FALSE;\r
       mMapStack[mMapDepth].Type      = Entry->Type;\r
       mMapStack[mMapDepth].Start     = RangeEnd+1;\r
       mMapStack[mMapDepth].End       = Entry->End;\r
@@ -1457,7 +1525,6 @@ Returns:
 \r
 --*/\r
 {\r
-  EFI_STATUS        Status;\r
   UINT64            Start;\r
 \r
   //\r
@@ -1471,7 +1538,7 @@ Returns:
   if (Start == 0) {\r
     DEBUG ((EFI_D_ERROR | EFI_D_PAGE, "AllocatePoolPages: failed to allocate %d pages\n", NumberOfPages));\r
   } else {\r
-    Status = CoreConvertPages (Start, NumberOfPages, PoolType);\r
+    CoreConvertPages (Start, NumberOfPages, PoolType);\r
   }\r
 \r
   return (VOID *)(UINTN)Start;\r