]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Change the file name case to follow coding style: The first character should be capital.
authorqhuang8 <qhuang8@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 21 May 2008 01:00:57 +0000 (01:00 +0000)
committerqhuang8 <qhuang8@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 21 May 2008 01:00:57 +0000 (01:00 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@5246 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Core/Dxe/Mem/Pool.c [new file with mode: 0644]
MdeModulePkg/Core/Dxe/Mem/pool.c [deleted file]

diff --git a/MdeModulePkg/Core/Dxe/Mem/Pool.c b/MdeModulePkg/Core/Dxe/Mem/Pool.c
new file mode 100644 (file)
index 0000000..1adaa1f
--- /dev/null
@@ -0,0 +1,555 @@
+/** @file \r
+\r
+  UEFI Memory pool management functions.\r
+\r
+Copyright (c) 2006 - 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
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+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
+**/\r
+\r
+#include <DxeMain.h>\r
+\r
+#define POOL_FREE_SIGNATURE   EFI_SIGNATURE_32('p','f','r','0')\r
+typedef struct {\r
+  UINT32          Signature;\r
+  UINT32          Index;\r
+  LIST_ENTRY      Link;\r
+} POOL_FREE;\r
+\r
+\r
+#define POOL_HEAD_SIGNATURE   EFI_SIGNATURE_32('p','h','d','0')\r
+typedef struct {\r
+  UINT32          Signature;\r
+  UINT32          Size;\r
+  EFI_MEMORY_TYPE Type;\r
+  UINTN           Reserved;\r
+  CHAR8           Data[1];\r
+} POOL_HEAD;\r
+\r
+#define SIZE_OF_POOL_HEAD EFI_FIELD_OFFSET(POOL_HEAD,Data)\r
+\r
+#define POOL_TAIL_SIGNATURE   EFI_SIGNATURE_32('p','t','a','l')\r
+typedef struct {\r
+  UINT32      Signature;\r
+  UINT32      Size;\r
+} POOL_TAIL;\r
+\r
+\r
+#define POOL_SHIFT  7\r
+\r
+#define POOL_OVERHEAD (SIZE_OF_POOL_HEAD + sizeof(POOL_TAIL))\r
+\r
+#define HEAD_TO_TAIL(a)   \\r
+  ((POOL_TAIL *) (((CHAR8 *) (a)) + (a)->Size - sizeof(POOL_TAIL)));\r
+\r
+\r
+#define SIZE_TO_LIST(a)   ((a) >> POOL_SHIFT)\r
+#define LIST_TO_SIZE(a)   ((a+1) << POOL_SHIFT)\r
+\r
+#define MAX_POOL_LIST       SIZE_TO_LIST(DEFAULT_PAGE_ALLOCATION)\r
+\r
+#define MAX_POOL_SIZE     (MAX_ADDRESS - POOL_OVERHEAD)\r
+\r
+//\r
+// Globals\r
+//\r
+\r
+#define POOL_SIGNATURE  EFI_SIGNATURE_32('p','l','s','t')\r
+typedef struct {\r
+    INTN             Signature;\r
+    UINTN            Used;\r
+    EFI_MEMORY_TYPE  MemoryType;\r
+    LIST_ENTRY       FreeList[MAX_POOL_LIST];\r
+    LIST_ENTRY       Link;\r
+} POOL; \r
+\r
+\r
+POOL            PoolHead[EfiMaxMemoryType];\r
+LIST_ENTRY      PoolHeadList;\r
+\r
+//\r
+//\r
+//\r
+\r
+\r
+/**\r
+  Called to initialize the pool.\r
+\r
+**/\r
+VOID\r
+CoreInitializePool (\r
+  VOID\r
+  )\r
+{\r
+  UINTN  Type;\r
+  UINTN  Index;\r
+\r
+  for (Type=0; Type < EfiMaxMemoryType; Type++) {\r
+    PoolHead[Type].Signature  = 0;\r
+    PoolHead[Type].Used       = 0;\r
+    PoolHead[Type].MemoryType = (EFI_MEMORY_TYPE) Type;\r
+    for (Index=0; Index < MAX_POOL_LIST; Index++) {\r
+        InitializeListHead (&PoolHead[Type].FreeList[Index]);\r
+    }\r
+  }\r
+  InitializeListHead (&PoolHeadList);\r
+}\r
+\r
+\r
+/**\r
+  Look up pool head for specified memory type.\r
+\r
+  @param  MemoryType             Memory type of which pool head is looked for \r
+\r
+  @return Pointer of Corresponding pool head.\r
+\r
+**/\r
+STATIC\r
+POOL *\r
+LookupPoolHead (\r
+  IN EFI_MEMORY_TYPE  MemoryType\r
+  )\r
+{\r
+  LIST_ENTRY      *Link;\r
+  POOL            *Pool;\r
+  UINTN           Index;\r
+\r
+  if (MemoryType >= 0 && MemoryType < EfiMaxMemoryType) {\r
+    return &PoolHead[MemoryType];\r
+  }\r
+\r
+  if (MemoryType < 0) {\r
+\r
+    for (Link = PoolHeadList.ForwardLink; Link != &PoolHeadList; Link = Link->ForwardLink) {\r
+      Pool = CR(Link, POOL, Link, POOL_SIGNATURE);\r
+      if (Pool->MemoryType == MemoryType) {\r
+        return Pool;\r
+      }\r
+    }\r
+\r
+    Pool = CoreAllocatePoolI (EfiBootServicesData, sizeof (POOL));\r
+    if (Pool == NULL) {\r
+      return NULL;\r
+    }\r
+\r
+    Pool->Signature = POOL_SIGNATURE;\r
+    Pool->Used      = 0;\r
+    Pool->MemoryType = MemoryType;\r
+    for (Index=0; Index < MAX_POOL_LIST; Index++) {\r
+      InitializeListHead (&Pool->FreeList[Index]);\r
+    }\r
+\r
+    InsertHeadList (&PoolHeadList, &Pool->Link);\r
+\r
+    return Pool;\r
+  }\r
+\r
+  return NULL;\r
+}\r
+\r
\r
+\r
+\r
+/**\r
+  Allocate pool of a particular type.\r
+\r
+  @param  PoolType               Type of pool to allocate \r
+  @param  Size                   The amount of pool to allocate \r
+  @param  Buffer                 The address to return a pointer to the allocated \r
+                                 pool \r
+\r
+  @retval EFI_INVALID_PARAMETER  PoolType not valid \r
+  @retval EFI_OUT_OF_RESOURCES   Size exceeds max pool size or allocation failed. \r
+  @retval EFI_SUCCESS            Pool successfully allocated.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CoreAllocatePool (\r
+  IN EFI_MEMORY_TYPE  PoolType,\r
+  IN UINTN            Size,\r
+  OUT VOID            **Buffer\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+\r
+  //\r
+  // If it's not a valid type, fail it\r
+  //\r
+  if ((PoolType >= EfiMaxMemoryType && PoolType <= 0x7fffffff) ||\r
+       PoolType == EfiConventionalMemory) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  \r
+  *Buffer = NULL;\r
+  \r
+  //\r
+  // If size is too large, fail it\r
+  // Base on the EFI spec, return status of EFI_OUT_OF_RESOURCES\r
+  //\r
+  if (Size > MAX_POOL_SIZE) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  //\r
+  // Acquire the memory lock and make the allocation\r
+  //\r
+  Status = CoreAcquireLockOrFail (&gMemoryLock);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  *Buffer = CoreAllocatePoolI (PoolType, Size);\r
+  CoreReleaseMemoryLock ();\r
+  return (*Buffer != NULL) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES;\r
+}\r
+\r
+\r
+\r
+/**\r
+  Internal function to allocate pool of a particular type.\r
+  Caller must have the memory lock held\r
+\r
+  @param  PoolType               Type of pool to allocate \r
+  @param  Size                   The amount of pool to allocate \r
+\r
+  @return The allocate pool, or NULL\r
+\r
+**/\r
+VOID *\r
+CoreAllocatePoolI (\r
+  IN EFI_MEMORY_TYPE  PoolType,\r
+  IN UINTN            Size\r
+  )\r
+{\r
+  POOL        *Pool;\r
+  POOL_FREE   *Free;\r
+  POOL_HEAD   *Head;\r
+  POOL_TAIL   *Tail;\r
+  CHAR8       *NewPage;\r
+  VOID        *Buffer;\r
+  UINTN       Index;\r
+  UINTN       FSize;\r
+  UINTN       Offset;\r
+  UINTN       Adjustment;\r
+  UINTN       NoPages;\r
+\r
+  ASSERT_LOCKED (&gMemoryLock);\r
+\r
+  //\r
+  // Adjust the size by the pool header & tail overhead\r
+  //\r
+  \r
+  //\r
+  // Adjusting the Size to be of proper alignment so that\r
+  // we don't get an unaligned access fault later when\r
+  // pool_Tail is being initialized\r
+  //\r
+  ALIGN_VARIABLE (Size, Adjustment);\r
+\r
+  Size += POOL_OVERHEAD;\r
+  Index = SIZE_TO_LIST(Size);\r
+  Pool = LookupPoolHead (PoolType);\r
+  if (Pool== NULL) {\r
+    return NULL;\r
+  }\r
+  Head = NULL;\r
+\r
+  //\r
+  // If allocation is over max size, just allocate pages for the request\r
+  // (slow)\r
+  //\r
+  if (Index >= MAX_POOL_LIST) {\r
+    NoPages = EFI_SIZE_TO_PAGES(Size) + EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION) - 1;\r
+    NoPages &= ~(EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION) - 1);\r
+    Head = CoreAllocatePoolPages (PoolType, NoPages, DEFAULT_PAGE_ALLOCATION);\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // If there's no free pool in the proper list size, go get some more pages\r
+  //\r
+  if (IsListEmpty (&Pool->FreeList[Index])) {\r
+\r
+    //\r
+    // Get another page\r
+    //\r
+    NewPage = CoreAllocatePoolPages(PoolType, EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION), DEFAULT_PAGE_ALLOCATION);\r
+    if (NewPage == NULL) {\r
+      goto Done;\r
+    }\r
+\r
+    //\r
+    // Carve up new page into free pool blocks\r
+    //\r
+    Offset = 0;\r
+    while (Offset < DEFAULT_PAGE_ALLOCATION) {\r
+      ASSERT (Index < MAX_POOL_LIST);\r
+      FSize = LIST_TO_SIZE(Index);\r
+\r
+      while (Offset + FSize <= DEFAULT_PAGE_ALLOCATION) {\r
+        Free = (POOL_FREE *) &NewPage[Offset];          \r
+        Free->Signature = POOL_FREE_SIGNATURE;\r
+        Free->Index     = (UINT32)Index;\r
+        InsertHeadList (&Pool->FreeList[Index], &Free->Link);\r
+        Offset += FSize;\r
+      }\r
+\r
+      Index -= 1;\r
+    }\r
+\r
+    ASSERT (Offset == DEFAULT_PAGE_ALLOCATION);\r
+    Index = SIZE_TO_LIST(Size);\r
+  }\r
+\r
+  //\r
+  // Remove entry from free pool list\r
+  //\r
+  Free = CR (Pool->FreeList[Index].ForwardLink, POOL_FREE, Link, POOL_FREE_SIGNATURE);\r
+  RemoveEntryList (&Free->Link);\r
+\r
+  Head = (POOL_HEAD *) Free;\r
+\r
+Done:\r
+  Buffer = NULL;\r
+\r
+  if (Head != NULL) {\r
+    \r
+    //\r
+    // If we have a pool buffer, fill in the header & tail info\r
+    //\r
+    Head->Signature = POOL_HEAD_SIGNATURE;\r
+    Head->Size      = (UINT32) Size;\r
+    Head->Type      = (EFI_MEMORY_TYPE) PoolType;\r
+    Tail            = HEAD_TO_TAIL (Head);\r
+    Tail->Signature = POOL_TAIL_SIGNATURE;\r
+    Tail->Size      = (UINT32) Size;\r
+    Buffer          = Head->Data;\r
+    DEBUG_CLEAR_MEMORY (Buffer, Size - POOL_OVERHEAD);\r
+\r
+    DEBUG (\r
+      (DEBUG_POOL,\r
+      "AllocatePoolI: Type %x, Addr %x (len %x) %,d\n",\r
+       PoolType, \r
+       Buffer, \r
+       Size - POOL_OVERHEAD, \r
+      Pool->Used)\r
+      );\r
+\r
+    //\r
+    // Account the allocation\r
+    //\r
+    Pool->Used += Size;\r
+\r
+  } else {\r
+    DEBUG ((DEBUG_ERROR | DEBUG_POOL, "AllocatePool: failed to allocate %d bytes\n", Size));\r
+  }\r
+\r
+  return Buffer;\r
+}\r
+  \r
+\r
+\r
+\r
+/**\r
+  Frees pool.\r
+\r
+  @param  Buffer                 The allocated pool entry to free \r
+\r
+  @retval EFI_INVALID_PARAMETER  Buffer is not a valid value. \r
+  @retval EFI_SUCCESS            Pool successfully freed.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CoreFreePool (\r
+  IN VOID        *Buffer\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+\r
+  if (NULL == Buffer) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  CoreAcquireMemoryLock ();\r
+  Status = CoreFreePoolI (Buffer);\r
+  CoreReleaseMemoryLock ();\r
+  return Status;\r
+}\r
+\r
+\r
+\r
+/**\r
+  Internal function to free a pool entry.\r
+  Caller must have the memory lock held\r
+\r
+  @param  Buffer                 The allocated pool entry to free \r
+\r
+  @retval EFI_INVALID_PARAMETER  Buffer not valid \r
+  @retval EFI_SUCCESS            Buffer successfully freed.\r
+\r
+**/\r
+EFI_STATUS\r
+CoreFreePoolI (\r
+  IN VOID       *Buffer\r
+  )\r
+{\r
+  POOL        *Pool;\r
+  POOL_HEAD   *Head;\r
+  POOL_TAIL   *Tail;\r
+  POOL_FREE   *Free;\r
+  UINTN       Index;\r
+  UINTN       NoPages;\r
+  UINTN       Size;\r
+  CHAR8       *NewPage;\r
+  UINTN       FSize;\r
+  UINTN       Offset;\r
+  BOOLEAN     AllFree;\r
+\r
+  ASSERT(NULL != Buffer);\r
+  //\r
+  // Get the head & tail of the pool entry\r
+  //\r
+  Head = CR (Buffer, POOL_HEAD, Data, POOL_HEAD_SIGNATURE);\r
+  ASSERT(NULL != Head);\r
+\r
+  if (Head->Signature != POOL_HEAD_SIGNATURE) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Tail = HEAD_TO_TAIL (Head);\r
+  ASSERT(NULL != Tail);\r
+\r
+  //\r
+  // Debug\r
+  //\r
+  ASSERT (Tail->Signature == POOL_TAIL_SIGNATURE);\r
+  ASSERT (Head->Size == Tail->Size);\r
+  ASSERT_LOCKED (&gMemoryLock);\r
+\r
+  if (Tail->Signature != POOL_TAIL_SIGNATURE) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Head->Size != Tail->Size) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Determine the pool type and account for it\r
+  //\r
+  Size = Head->Size;\r
+  Pool = LookupPoolHead (Head->Type);\r
+  if (Pool == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  Pool->Used -= Size;\r
+  DEBUG ((DEBUG_POOL, "FreePool: %x (len %x) %,d\n", Head->Data, Head->Size - POOL_OVERHEAD, Pool->Used));\r
+\r
+  //\r
+  // Determine the pool list \r
+  //\r
+  Index = SIZE_TO_LIST(Size);\r
+  DEBUG_CLEAR_MEMORY (Head, Size);\r
+\r
+  //\r
+  // If it's not on the list, it must be pool pages\r
+  //\r
+  if (Index >= MAX_POOL_LIST) {\r
+\r
+    //\r
+    // Return the memory pages back to free memory\r
+    //\r
+    NoPages = EFI_SIZE_TO_PAGES(Size) + EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION) - 1;\r
+    NoPages &= ~(EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION) - 1);\r
+    CoreFreePoolPages ((EFI_PHYSICAL_ADDRESS) (UINTN) Head, NoPages);\r
+\r
+  } else {\r
+\r
+    //\r
+    // Put the pool entry onto the free pool list\r
+    //\r
+    Free = (POOL_FREE *) Head;\r
+    ASSERT(NULL != Free);\r
+    Free->Signature = POOL_FREE_SIGNATURE;\r
+    Free->Index     = (UINT32)Index;\r
+    InsertHeadList (&Pool->FreeList[Index], &Free->Link);\r
+\r
+    //\r
+    // See if all the pool entries in the same page as Free are freed pool \r
+    // entries\r
+    //\r
+    NewPage = (CHAR8 *)((UINTN)Free & ~((DEFAULT_PAGE_ALLOCATION) -1));\r
+    Free = (POOL_FREE *) &NewPage[0];\r
+    ASSERT(NULL != Free);\r
+\r
+    if (Free->Signature == POOL_FREE_SIGNATURE) {\r
+\r
+      Index = Free->Index;\r
+\r
+      AllFree = TRUE;\r
+      Offset = 0;\r
+      \r
+      while ((Offset < DEFAULT_PAGE_ALLOCATION) && (AllFree)) {\r
+        FSize = LIST_TO_SIZE(Index);\r
+        while (Offset + FSize <= DEFAULT_PAGE_ALLOCATION) {\r
+          Free = (POOL_FREE *) &NewPage[Offset];\r
+          ASSERT(NULL != Free);\r
+          if (Free->Signature != POOL_FREE_SIGNATURE) {\r
+            AllFree = FALSE;\r
+          }\r
+          Offset += FSize;\r
+        }\r
+        Index -= 1;\r
+      }\r
+\r
+      if (AllFree) {\r
+\r
+        //\r
+        // All of the pool entries in the same page as Free are free pool \r
+        // entries\r
+        // Remove all of these pool entries from the free loop lists.\r
+        //\r
+        Free = (POOL_FREE *) &NewPage[0];\r
+        ASSERT(NULL != Free);\r
+        Index = Free->Index;\r
+        Offset = 0;\r
+        \r
+        while (Offset < DEFAULT_PAGE_ALLOCATION) {\r
+          FSize = LIST_TO_SIZE(Index);\r
+          while (Offset + FSize <= DEFAULT_PAGE_ALLOCATION) {\r
+            Free = (POOL_FREE *) &NewPage[Offset];\r
+            ASSERT(NULL != Free);\r
+            RemoveEntryList (&Free->Link);\r
+            Offset += FSize;\r
+          }\r
+          Index -= 1;\r
+        }\r
+\r
+        //\r
+        // Free the page\r
+        //\r
+        CoreFreePoolPages ((EFI_PHYSICAL_ADDRESS) (UINTN)NewPage, EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION));\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  // If this is an OS specific memory type, then check to see if the last \r
+  // portion of that memory type has been freed.  If it has, then free the\r
+  // list entry for that memory type\r
+  //\r
+  if (Pool->MemoryType < 0 && Pool->Used == 0) {\r
+    RemoveEntryList (&Pool->Link);\r
+    CoreFreePoolI (Pool);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/MdeModulePkg/Core/Dxe/Mem/pool.c b/MdeModulePkg/Core/Dxe/Mem/pool.c
deleted file mode 100644 (file)
index 1adaa1f..0000000
+++ /dev/null
@@ -1,555 +0,0 @@
-/** @file \r
-\r
-  UEFI Memory pool management functions.\r
-\r
-Copyright (c) 2006 - 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
-http://opensource.org/licenses/bsd-license.php                                            \r
-                                                                                          \r
-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
-**/\r
-\r
-#include <DxeMain.h>\r
-\r
-#define POOL_FREE_SIGNATURE   EFI_SIGNATURE_32('p','f','r','0')\r
-typedef struct {\r
-  UINT32          Signature;\r
-  UINT32          Index;\r
-  LIST_ENTRY      Link;\r
-} POOL_FREE;\r
-\r
-\r
-#define POOL_HEAD_SIGNATURE   EFI_SIGNATURE_32('p','h','d','0')\r
-typedef struct {\r
-  UINT32          Signature;\r
-  UINT32          Size;\r
-  EFI_MEMORY_TYPE Type;\r
-  UINTN           Reserved;\r
-  CHAR8           Data[1];\r
-} POOL_HEAD;\r
-\r
-#define SIZE_OF_POOL_HEAD EFI_FIELD_OFFSET(POOL_HEAD,Data)\r
-\r
-#define POOL_TAIL_SIGNATURE   EFI_SIGNATURE_32('p','t','a','l')\r
-typedef struct {\r
-  UINT32      Signature;\r
-  UINT32      Size;\r
-} POOL_TAIL;\r
-\r
-\r
-#define POOL_SHIFT  7\r
-\r
-#define POOL_OVERHEAD (SIZE_OF_POOL_HEAD + sizeof(POOL_TAIL))\r
-\r
-#define HEAD_TO_TAIL(a)   \\r
-  ((POOL_TAIL *) (((CHAR8 *) (a)) + (a)->Size - sizeof(POOL_TAIL)));\r
-\r
-\r
-#define SIZE_TO_LIST(a)   ((a) >> POOL_SHIFT)\r
-#define LIST_TO_SIZE(a)   ((a+1) << POOL_SHIFT)\r
-\r
-#define MAX_POOL_LIST       SIZE_TO_LIST(DEFAULT_PAGE_ALLOCATION)\r
-\r
-#define MAX_POOL_SIZE     (MAX_ADDRESS - POOL_OVERHEAD)\r
-\r
-//\r
-// Globals\r
-//\r
-\r
-#define POOL_SIGNATURE  EFI_SIGNATURE_32('p','l','s','t')\r
-typedef struct {\r
-    INTN             Signature;\r
-    UINTN            Used;\r
-    EFI_MEMORY_TYPE  MemoryType;\r
-    LIST_ENTRY       FreeList[MAX_POOL_LIST];\r
-    LIST_ENTRY       Link;\r
-} POOL; \r
-\r
-\r
-POOL            PoolHead[EfiMaxMemoryType];\r
-LIST_ENTRY      PoolHeadList;\r
-\r
-//\r
-//\r
-//\r
-\r
-\r
-/**\r
-  Called to initialize the pool.\r
-\r
-**/\r
-VOID\r
-CoreInitializePool (\r
-  VOID\r
-  )\r
-{\r
-  UINTN  Type;\r
-  UINTN  Index;\r
-\r
-  for (Type=0; Type < EfiMaxMemoryType; Type++) {\r
-    PoolHead[Type].Signature  = 0;\r
-    PoolHead[Type].Used       = 0;\r
-    PoolHead[Type].MemoryType = (EFI_MEMORY_TYPE) Type;\r
-    for (Index=0; Index < MAX_POOL_LIST; Index++) {\r
-        InitializeListHead (&PoolHead[Type].FreeList[Index]);\r
-    }\r
-  }\r
-  InitializeListHead (&PoolHeadList);\r
-}\r
-\r
-\r
-/**\r
-  Look up pool head for specified memory type.\r
-\r
-  @param  MemoryType             Memory type of which pool head is looked for \r
-\r
-  @return Pointer of Corresponding pool head.\r
-\r
-**/\r
-STATIC\r
-POOL *\r
-LookupPoolHead (\r
-  IN EFI_MEMORY_TYPE  MemoryType\r
-  )\r
-{\r
-  LIST_ENTRY      *Link;\r
-  POOL            *Pool;\r
-  UINTN           Index;\r
-\r
-  if (MemoryType >= 0 && MemoryType < EfiMaxMemoryType) {\r
-    return &PoolHead[MemoryType];\r
-  }\r
-\r
-  if (MemoryType < 0) {\r
-\r
-    for (Link = PoolHeadList.ForwardLink; Link != &PoolHeadList; Link = Link->ForwardLink) {\r
-      Pool = CR(Link, POOL, Link, POOL_SIGNATURE);\r
-      if (Pool->MemoryType == MemoryType) {\r
-        return Pool;\r
-      }\r
-    }\r
-\r
-    Pool = CoreAllocatePoolI (EfiBootServicesData, sizeof (POOL));\r
-    if (Pool == NULL) {\r
-      return NULL;\r
-    }\r
-\r
-    Pool->Signature = POOL_SIGNATURE;\r
-    Pool->Used      = 0;\r
-    Pool->MemoryType = MemoryType;\r
-    for (Index=0; Index < MAX_POOL_LIST; Index++) {\r
-      InitializeListHead (&Pool->FreeList[Index]);\r
-    }\r
-\r
-    InsertHeadList (&PoolHeadList, &Pool->Link);\r
-\r
-    return Pool;\r
-  }\r
-\r
-  return NULL;\r
-}\r
-\r
\r
-\r
-\r
-/**\r
-  Allocate pool of a particular type.\r
-\r
-  @param  PoolType               Type of pool to allocate \r
-  @param  Size                   The amount of pool to allocate \r
-  @param  Buffer                 The address to return a pointer to the allocated \r
-                                 pool \r
-\r
-  @retval EFI_INVALID_PARAMETER  PoolType not valid \r
-  @retval EFI_OUT_OF_RESOURCES   Size exceeds max pool size or allocation failed. \r
-  @retval EFI_SUCCESS            Pool successfully allocated.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-CoreAllocatePool (\r
-  IN EFI_MEMORY_TYPE  PoolType,\r
-  IN UINTN            Size,\r
-  OUT VOID            **Buffer\r
-  )\r
-{\r
-  EFI_STATUS    Status;\r
-\r
-  //\r
-  // If it's not a valid type, fail it\r
-  //\r
-  if ((PoolType >= EfiMaxMemoryType && PoolType <= 0x7fffffff) ||\r
-       PoolType == EfiConventionalMemory) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  \r
-  *Buffer = NULL;\r
-  \r
-  //\r
-  // If size is too large, fail it\r
-  // Base on the EFI spec, return status of EFI_OUT_OF_RESOURCES\r
-  //\r
-  if (Size > MAX_POOL_SIZE) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  //\r
-  // Acquire the memory lock and make the allocation\r
-  //\r
-  Status = CoreAcquireLockOrFail (&gMemoryLock);\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  *Buffer = CoreAllocatePoolI (PoolType, Size);\r
-  CoreReleaseMemoryLock ();\r
-  return (*Buffer != NULL) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES;\r
-}\r
-\r
-\r
-\r
-/**\r
-  Internal function to allocate pool of a particular type.\r
-  Caller must have the memory lock held\r
-\r
-  @param  PoolType               Type of pool to allocate \r
-  @param  Size                   The amount of pool to allocate \r
-\r
-  @return The allocate pool, or NULL\r
-\r
-**/\r
-VOID *\r
-CoreAllocatePoolI (\r
-  IN EFI_MEMORY_TYPE  PoolType,\r
-  IN UINTN            Size\r
-  )\r
-{\r
-  POOL        *Pool;\r
-  POOL_FREE   *Free;\r
-  POOL_HEAD   *Head;\r
-  POOL_TAIL   *Tail;\r
-  CHAR8       *NewPage;\r
-  VOID        *Buffer;\r
-  UINTN       Index;\r
-  UINTN       FSize;\r
-  UINTN       Offset;\r
-  UINTN       Adjustment;\r
-  UINTN       NoPages;\r
-\r
-  ASSERT_LOCKED (&gMemoryLock);\r
-\r
-  //\r
-  // Adjust the size by the pool header & tail overhead\r
-  //\r
-  \r
-  //\r
-  // Adjusting the Size to be of proper alignment so that\r
-  // we don't get an unaligned access fault later when\r
-  // pool_Tail is being initialized\r
-  //\r
-  ALIGN_VARIABLE (Size, Adjustment);\r
-\r
-  Size += POOL_OVERHEAD;\r
-  Index = SIZE_TO_LIST(Size);\r
-  Pool = LookupPoolHead (PoolType);\r
-  if (Pool== NULL) {\r
-    return NULL;\r
-  }\r
-  Head = NULL;\r
-\r
-  //\r
-  // If allocation is over max size, just allocate pages for the request\r
-  // (slow)\r
-  //\r
-  if (Index >= MAX_POOL_LIST) {\r
-    NoPages = EFI_SIZE_TO_PAGES(Size) + EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION) - 1;\r
-    NoPages &= ~(EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION) - 1);\r
-    Head = CoreAllocatePoolPages (PoolType, NoPages, DEFAULT_PAGE_ALLOCATION);\r
-    goto Done;\r
-  }\r
-\r
-  //\r
-  // If there's no free pool in the proper list size, go get some more pages\r
-  //\r
-  if (IsListEmpty (&Pool->FreeList[Index])) {\r
-\r
-    //\r
-    // Get another page\r
-    //\r
-    NewPage = CoreAllocatePoolPages(PoolType, EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION), DEFAULT_PAGE_ALLOCATION);\r
-    if (NewPage == NULL) {\r
-      goto Done;\r
-    }\r
-\r
-    //\r
-    // Carve up new page into free pool blocks\r
-    //\r
-    Offset = 0;\r
-    while (Offset < DEFAULT_PAGE_ALLOCATION) {\r
-      ASSERT (Index < MAX_POOL_LIST);\r
-      FSize = LIST_TO_SIZE(Index);\r
-\r
-      while (Offset + FSize <= DEFAULT_PAGE_ALLOCATION) {\r
-        Free = (POOL_FREE *) &NewPage[Offset];          \r
-        Free->Signature = POOL_FREE_SIGNATURE;\r
-        Free->Index     = (UINT32)Index;\r
-        InsertHeadList (&Pool->FreeList[Index], &Free->Link);\r
-        Offset += FSize;\r
-      }\r
-\r
-      Index -= 1;\r
-    }\r
-\r
-    ASSERT (Offset == DEFAULT_PAGE_ALLOCATION);\r
-    Index = SIZE_TO_LIST(Size);\r
-  }\r
-\r
-  //\r
-  // Remove entry from free pool list\r
-  //\r
-  Free = CR (Pool->FreeList[Index].ForwardLink, POOL_FREE, Link, POOL_FREE_SIGNATURE);\r
-  RemoveEntryList (&Free->Link);\r
-\r
-  Head = (POOL_HEAD *) Free;\r
-\r
-Done:\r
-  Buffer = NULL;\r
-\r
-  if (Head != NULL) {\r
-    \r
-    //\r
-    // If we have a pool buffer, fill in the header & tail info\r
-    //\r
-    Head->Signature = POOL_HEAD_SIGNATURE;\r
-    Head->Size      = (UINT32) Size;\r
-    Head->Type      = (EFI_MEMORY_TYPE) PoolType;\r
-    Tail            = HEAD_TO_TAIL (Head);\r
-    Tail->Signature = POOL_TAIL_SIGNATURE;\r
-    Tail->Size      = (UINT32) Size;\r
-    Buffer          = Head->Data;\r
-    DEBUG_CLEAR_MEMORY (Buffer, Size - POOL_OVERHEAD);\r
-\r
-    DEBUG (\r
-      (DEBUG_POOL,\r
-      "AllocatePoolI: Type %x, Addr %x (len %x) %,d\n",\r
-       PoolType, \r
-       Buffer, \r
-       Size - POOL_OVERHEAD, \r
-      Pool->Used)\r
-      );\r
-\r
-    //\r
-    // Account the allocation\r
-    //\r
-    Pool->Used += Size;\r
-\r
-  } else {\r
-    DEBUG ((DEBUG_ERROR | DEBUG_POOL, "AllocatePool: failed to allocate %d bytes\n", Size));\r
-  }\r
-\r
-  return Buffer;\r
-}\r
-  \r
-\r
-\r
-\r
-/**\r
-  Frees pool.\r
-\r
-  @param  Buffer                 The allocated pool entry to free \r
-\r
-  @retval EFI_INVALID_PARAMETER  Buffer is not a valid value. \r
-  @retval EFI_SUCCESS            Pool successfully freed.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-CoreFreePool (\r
-  IN VOID        *Buffer\r
-  )\r
-{\r
-  EFI_STATUS Status;\r
-\r
-  if (NULL == Buffer) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  CoreAcquireMemoryLock ();\r
-  Status = CoreFreePoolI (Buffer);\r
-  CoreReleaseMemoryLock ();\r
-  return Status;\r
-}\r
-\r
-\r
-\r
-/**\r
-  Internal function to free a pool entry.\r
-  Caller must have the memory lock held\r
-\r
-  @param  Buffer                 The allocated pool entry to free \r
-\r
-  @retval EFI_INVALID_PARAMETER  Buffer not valid \r
-  @retval EFI_SUCCESS            Buffer successfully freed.\r
-\r
-**/\r
-EFI_STATUS\r
-CoreFreePoolI (\r
-  IN VOID       *Buffer\r
-  )\r
-{\r
-  POOL        *Pool;\r
-  POOL_HEAD   *Head;\r
-  POOL_TAIL   *Tail;\r
-  POOL_FREE   *Free;\r
-  UINTN       Index;\r
-  UINTN       NoPages;\r
-  UINTN       Size;\r
-  CHAR8       *NewPage;\r
-  UINTN       FSize;\r
-  UINTN       Offset;\r
-  BOOLEAN     AllFree;\r
-\r
-  ASSERT(NULL != Buffer);\r
-  //\r
-  // Get the head & tail of the pool entry\r
-  //\r
-  Head = CR (Buffer, POOL_HEAD, Data, POOL_HEAD_SIGNATURE);\r
-  ASSERT(NULL != Head);\r
-\r
-  if (Head->Signature != POOL_HEAD_SIGNATURE) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  Tail = HEAD_TO_TAIL (Head);\r
-  ASSERT(NULL != Tail);\r
-\r
-  //\r
-  // Debug\r
-  //\r
-  ASSERT (Tail->Signature == POOL_TAIL_SIGNATURE);\r
-  ASSERT (Head->Size == Tail->Size);\r
-  ASSERT_LOCKED (&gMemoryLock);\r
-\r
-  if (Tail->Signature != POOL_TAIL_SIGNATURE) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (Head->Size != Tail->Size) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // Determine the pool type and account for it\r
-  //\r
-  Size = Head->Size;\r
-  Pool = LookupPoolHead (Head->Type);\r
-  if (Pool == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  Pool->Used -= Size;\r
-  DEBUG ((DEBUG_POOL, "FreePool: %x (len %x) %,d\n", Head->Data, Head->Size - POOL_OVERHEAD, Pool->Used));\r
-\r
-  //\r
-  // Determine the pool list \r
-  //\r
-  Index = SIZE_TO_LIST(Size);\r
-  DEBUG_CLEAR_MEMORY (Head, Size);\r
-\r
-  //\r
-  // If it's not on the list, it must be pool pages\r
-  //\r
-  if (Index >= MAX_POOL_LIST) {\r
-\r
-    //\r
-    // Return the memory pages back to free memory\r
-    //\r
-    NoPages = EFI_SIZE_TO_PAGES(Size) + EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION) - 1;\r
-    NoPages &= ~(EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION) - 1);\r
-    CoreFreePoolPages ((EFI_PHYSICAL_ADDRESS) (UINTN) Head, NoPages);\r
-\r
-  } else {\r
-\r
-    //\r
-    // Put the pool entry onto the free pool list\r
-    //\r
-    Free = (POOL_FREE *) Head;\r
-    ASSERT(NULL != Free);\r
-    Free->Signature = POOL_FREE_SIGNATURE;\r
-    Free->Index     = (UINT32)Index;\r
-    InsertHeadList (&Pool->FreeList[Index], &Free->Link);\r
-\r
-    //\r
-    // See if all the pool entries in the same page as Free are freed pool \r
-    // entries\r
-    //\r
-    NewPage = (CHAR8 *)((UINTN)Free & ~((DEFAULT_PAGE_ALLOCATION) -1));\r
-    Free = (POOL_FREE *) &NewPage[0];\r
-    ASSERT(NULL != Free);\r
-\r
-    if (Free->Signature == POOL_FREE_SIGNATURE) {\r
-\r
-      Index = Free->Index;\r
-\r
-      AllFree = TRUE;\r
-      Offset = 0;\r
-      \r
-      while ((Offset < DEFAULT_PAGE_ALLOCATION) && (AllFree)) {\r
-        FSize = LIST_TO_SIZE(Index);\r
-        while (Offset + FSize <= DEFAULT_PAGE_ALLOCATION) {\r
-          Free = (POOL_FREE *) &NewPage[Offset];\r
-          ASSERT(NULL != Free);\r
-          if (Free->Signature != POOL_FREE_SIGNATURE) {\r
-            AllFree = FALSE;\r
-          }\r
-          Offset += FSize;\r
-        }\r
-        Index -= 1;\r
-      }\r
-\r
-      if (AllFree) {\r
-\r
-        //\r
-        // All of the pool entries in the same page as Free are free pool \r
-        // entries\r
-        // Remove all of these pool entries from the free loop lists.\r
-        //\r
-        Free = (POOL_FREE *) &NewPage[0];\r
-        ASSERT(NULL != Free);\r
-        Index = Free->Index;\r
-        Offset = 0;\r
-        \r
-        while (Offset < DEFAULT_PAGE_ALLOCATION) {\r
-          FSize = LIST_TO_SIZE(Index);\r
-          while (Offset + FSize <= DEFAULT_PAGE_ALLOCATION) {\r
-            Free = (POOL_FREE *) &NewPage[Offset];\r
-            ASSERT(NULL != Free);\r
-            RemoveEntryList (&Free->Link);\r
-            Offset += FSize;\r
-          }\r
-          Index -= 1;\r
-        }\r
-\r
-        //\r
-        // Free the page\r
-        //\r
-        CoreFreePoolPages ((EFI_PHYSICAL_ADDRESS) (UINTN)NewPage, EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION));\r
-      }\r
-    }\r
-  }\r
-\r
-  //\r
-  // If this is an OS specific memory type, then check to see if the last \r
-  // portion of that memory type has been freed.  If it has, then free the\r
-  // list entry for that memory type\r
-  //\r
-  if (Pool->MemoryType < 0 && Pool->Used == 0) {\r
-    RemoveEntryList (&Pool->Link);\r
-    CoreFreePoolI (Pool);\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r