+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