Home | History | Annotate | Download | only in UefiMemoryAllocationProfileLib
      1 /** @file
      2   Support routines for memory allocation routines based
      3   on boot services for Dxe phase drivers, with memory profile support.
      4 
      5   Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
      6   This program and the accompanying materials
      7   are licensed and made available under the terms and conditions of the BSD License
      8   which accompanies this distribution.  The full text of the license may be found at
      9   http://opensource.org/licenses/bsd-license.php.
     10 
     11   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     12   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     13 
     14 **/
     15 
     16 
     17 #include <Uefi.h>
     18 
     19 
     20 #include <Library/MemoryAllocationLib.h>
     21 #include <Library/UefiBootServicesTableLib.h>
     22 #include <Library/BaseMemoryLib.h>
     23 #include <Library/DebugLib.h>
     24 
     25 #include <Library/MemoryProfileLib.h>
     26 
     27 /**
     28   Allocates one or more 4KB pages of a certain memory type.
     29 
     30   Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated
     31   buffer.  The buffer returned is aligned on a 4KB boundary.  If Pages is 0, then NULL is returned.
     32   If there is not enough memory remaining to satisfy the request, then NULL is returned.
     33 
     34   @param  MemoryType            The type of memory to allocate.
     35   @param  Pages                 The number of 4 KB pages to allocate.
     36 
     37   @return A pointer to the allocated buffer or NULL if allocation fails.
     38 
     39 **/
     40 VOID *
     41 InternalAllocatePages (
     42   IN EFI_MEMORY_TYPE  MemoryType,
     43   IN UINTN            Pages
     44   )
     45 {
     46   EFI_STATUS            Status;
     47   EFI_PHYSICAL_ADDRESS  Memory;
     48 
     49   if (Pages == 0) {
     50     return NULL;
     51   }
     52 
     53   Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);
     54   if (EFI_ERROR (Status)) {
     55     return NULL;
     56   }
     57   return (VOID *) (UINTN) Memory;
     58 }
     59 
     60 /**
     61   Allocates one or more 4KB pages of type EfiBootServicesData.
     62 
     63   Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the
     64   allocated buffer.  The buffer returned is aligned on a 4KB boundary.  If Pages is 0, then NULL
     65   is returned.  If there is not enough memory remaining to satisfy the request, then NULL is
     66   returned.
     67 
     68   @param  Pages                 The number of 4 KB pages to allocate.
     69 
     70   @return A pointer to the allocated buffer or NULL if allocation fails.
     71 
     72 **/
     73 VOID *
     74 EFIAPI
     75 AllocatePages (
     76   IN UINTN  Pages
     77   )
     78 {
     79   VOID  *Buffer;
     80 
     81   Buffer = InternalAllocatePages (EfiBootServicesData, Pages);
     82   if (Buffer != NULL) {
     83     MemoryProfileLibRecord (
     84       (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
     85       MEMORY_PROFILE_ACTION_LIB_ALLOCATE_PAGES,
     86       EfiBootServicesData,
     87       Buffer,
     88       EFI_PAGES_TO_SIZE (Pages),
     89       NULL
     90       );
     91   }
     92   return Buffer;
     93 }
     94 
     95 /**
     96   Allocates one or more 4KB pages of type EfiRuntimeServicesData.
     97 
     98   Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
     99   allocated buffer.  The buffer returned is aligned on a 4KB boundary.  If Pages is 0, then NULL
    100   is returned.  If there is not enough memory remaining to satisfy the request, then NULL is
    101   returned.
    102 
    103   @param  Pages                 The number of 4 KB pages to allocate.
    104 
    105   @return A pointer to the allocated buffer or NULL if allocation fails.
    106 
    107 **/
    108 VOID *
    109 EFIAPI
    110 AllocateRuntimePages (
    111   IN UINTN  Pages
    112   )
    113 {
    114   VOID  *Buffer;
    115 
    116   Buffer = InternalAllocatePages (EfiRuntimeServicesData, Pages);
    117   if (Buffer != NULL) {
    118     MemoryProfileLibRecord (
    119       (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
    120       MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_PAGES,
    121       EfiRuntimeServicesData,
    122       Buffer,
    123       EFI_PAGES_TO_SIZE (Pages),
    124       NULL
    125       );
    126   }
    127   return Buffer;
    128 }
    129 
    130 /**
    131   Allocates one or more 4KB pages of type EfiReservedMemoryType.
    132 
    133   Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the
    134   allocated buffer.  The buffer returned is aligned on a 4KB boundary.  If Pages is 0, then NULL
    135   is returned.  If there is not enough memory remaining to satisfy the request, then NULL is
    136   returned.
    137 
    138   @param  Pages                 The number of 4 KB pages to allocate.
    139 
    140   @return A pointer to the allocated buffer or NULL if allocation fails.
    141 
    142 **/
    143 VOID *
    144 EFIAPI
    145 AllocateReservedPages (
    146   IN UINTN  Pages
    147   )
    148 {
    149   VOID  *Buffer;
    150 
    151   Buffer = InternalAllocatePages (EfiReservedMemoryType, Pages);
    152   if (Buffer != NULL) {
    153     MemoryProfileLibRecord (
    154       (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
    155       MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_PAGES,
    156       EfiReservedMemoryType,
    157       Buffer,
    158       EFI_PAGES_TO_SIZE (Pages),
    159       NULL
    160       );
    161   }
    162   return Buffer;
    163 }
    164 
    165 /**
    166   Frees one or more 4KB pages that were previously allocated with one of the page allocation
    167   functions in the Memory Allocation Library.
    168 
    169   Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer.  Buffer
    170   must have been allocated on a previous call to the page allocation services of the Memory
    171   Allocation Library.  If it is not possible to free allocated pages, then this function will
    172   perform no actions.
    173 
    174   If Buffer was not allocated with a page allocation function in the Memory Allocation Library,
    175   then ASSERT().
    176   If Pages is zero, then ASSERT().
    177 
    178   @param  Buffer                The pointer to the buffer of pages to free.
    179   @param  Pages                 The number of 4 KB pages to free.
    180 
    181 **/
    182 VOID
    183 EFIAPI
    184 FreePages (
    185   IN VOID   *Buffer,
    186   IN UINTN  Pages
    187   )
    188 {
    189   EFI_STATUS        Status;
    190 
    191   ASSERT (Pages != 0);
    192   Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
    193   ASSERT_EFI_ERROR (Status);
    194 }
    195 
    196 /**
    197   Allocates one or more 4KB pages of a certain memory type at a specified alignment.
    198 
    199   Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment
    200   specified by Alignment.  The allocated buffer is returned.  If Pages is 0, then NULL is returned.
    201   If there is not enough memory at the specified alignment remaining to satisfy the request, then
    202   NULL is returned.
    203   If Alignment is not a power of two and Alignment is not zero, then ASSERT().
    204   If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
    205 
    206   @param  MemoryType            The type of memory to allocate.
    207   @param  Pages                 The number of 4 KB pages to allocate.
    208   @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
    209                                 If Alignment is zero, then byte alignment is used.
    210 
    211   @return A pointer to the allocated buffer or NULL if allocation fails.
    212 
    213 **/
    214 VOID *
    215 InternalAllocateAlignedPages (
    216   IN EFI_MEMORY_TYPE  MemoryType,
    217   IN UINTN            Pages,
    218   IN UINTN            Alignment
    219   )
    220 {
    221   EFI_STATUS            Status;
    222   EFI_PHYSICAL_ADDRESS  Memory;
    223   UINTN                 AlignedMemory;
    224   UINTN                 AlignmentMask;
    225   UINTN                 UnalignedPages;
    226   UINTN                 RealPages;
    227 
    228   //
    229   // Alignment must be a power of two or zero.
    230   //
    231   ASSERT ((Alignment & (Alignment - 1)) == 0);
    232 
    233   if (Pages == 0) {
    234     return NULL;
    235   }
    236   if (Alignment > EFI_PAGE_SIZE) {
    237     //
    238     // Calculate the total number of pages since alignment is larger than page size.
    239     //
    240     AlignmentMask  = Alignment - 1;
    241     RealPages      = Pages + EFI_SIZE_TO_PAGES (Alignment);
    242     //
    243     // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
    244     //
    245     ASSERT (RealPages > Pages);
    246 
    247     Status         = gBS->AllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory);
    248     if (EFI_ERROR (Status)) {
    249       return NULL;
    250     }
    251     AlignedMemory  = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask;
    252     UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN) Memory);
    253     if (UnalignedPages > 0) {
    254       //
    255       // Free first unaligned page(s).
    256       //
    257       Status = gBS->FreePages (Memory, UnalignedPages);
    258       ASSERT_EFI_ERROR (Status);
    259     }
    260     Memory         = (EFI_PHYSICAL_ADDRESS) (AlignedMemory + EFI_PAGES_TO_SIZE (Pages));
    261     UnalignedPages = RealPages - Pages - UnalignedPages;
    262     if (UnalignedPages > 0) {
    263       //
    264       // Free last unaligned page(s).
    265       //
    266       Status = gBS->FreePages (Memory, UnalignedPages);
    267       ASSERT_EFI_ERROR (Status);
    268     }
    269   } else {
    270     //
    271     // Do not over-allocate pages in this case.
    272     //
    273     Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);
    274     if (EFI_ERROR (Status)) {
    275       return NULL;
    276     }
    277     AlignedMemory  = (UINTN) Memory;
    278   }
    279   return (VOID *) AlignedMemory;
    280 }
    281 
    282 /**
    283   Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment.
    284 
    285   Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an
    286   alignment specified by Alignment.  The allocated buffer is returned.  If Pages is 0, then NULL is
    287   returned.  If there is not enough memory at the specified alignment remaining to satisfy the
    288   request, then NULL is returned.
    289 
    290   If Alignment is not a power of two and Alignment is not zero, then ASSERT().
    291   If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
    292 
    293   @param  Pages                 The number of 4 KB pages to allocate.
    294   @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
    295                                 If Alignment is zero, then byte alignment is used.
    296 
    297   @return A pointer to the allocated buffer or NULL if allocation fails.
    298 
    299 **/
    300 VOID *
    301 EFIAPI
    302 AllocateAlignedPages (
    303   IN UINTN  Pages,
    304   IN UINTN  Alignment
    305   )
    306 {
    307   VOID  *Buffer;
    308 
    309   Buffer = InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment);
    310   if (Buffer != NULL) {
    311     MemoryProfileLibRecord (
    312       (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
    313       MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_PAGES,
    314       EfiBootServicesData,
    315       Buffer,
    316       EFI_PAGES_TO_SIZE (Pages),
    317       NULL
    318       );
    319   }
    320   return Buffer;
    321 }
    322 
    323 /**
    324   Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
    325 
    326   Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an
    327   alignment specified by Alignment.  The allocated buffer is returned.  If Pages is 0, then NULL is
    328   returned.  If there is not enough memory at the specified alignment remaining to satisfy the
    329   request, then NULL is returned.
    330 
    331   If Alignment is not a power of two and Alignment is not zero, then ASSERT().
    332   If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
    333 
    334   @param  Pages                 The number of 4 KB pages to allocate.
    335   @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
    336                                 If Alignment is zero, then byte alignment is used.
    337 
    338   @return A pointer to the allocated buffer or NULL if allocation fails.
    339 
    340 **/
    341 VOID *
    342 EFIAPI
    343 AllocateAlignedRuntimePages (
    344   IN UINTN  Pages,
    345   IN UINTN  Alignment
    346   )
    347 {
    348   VOID  *Buffer;
    349 
    350   Buffer = InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);
    351   if (Buffer != NULL) {
    352     MemoryProfileLibRecord (
    353       (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
    354       MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RUNTIME_PAGES,
    355       EfiRuntimeServicesData,
    356       Buffer,
    357       EFI_PAGES_TO_SIZE (Pages),
    358       NULL
    359       );
    360   }
    361   return Buffer;
    362 }
    363 
    364 /**
    365   Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
    366 
    367   Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an
    368   alignment specified by Alignment.  The allocated buffer is returned.  If Pages is 0, then NULL is
    369   returned.  If there is not enough memory at the specified alignment remaining to satisfy the
    370   request, then NULL is returned.
    371 
    372   If Alignment is not a power of two and Alignment is not zero, then ASSERT().
    373   If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
    374 
    375   @param  Pages                 The number of 4 KB pages to allocate.
    376   @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
    377                                 If Alignment is zero, then byte alignment is used.
    378 
    379   @return A pointer to the allocated buffer or NULL if allocation fails.
    380 
    381 **/
    382 VOID *
    383 EFIAPI
    384 AllocateAlignedReservedPages (
    385   IN UINTN  Pages,
    386   IN UINTN  Alignment
    387   )
    388 {
    389   VOID  *Buffer;
    390 
    391   Buffer = InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment);
    392   if (Buffer != NULL) {
    393     MemoryProfileLibRecord (
    394       (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
    395       MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RESERVED_PAGES,
    396       EfiReservedMemoryType,
    397       Buffer,
    398       EFI_PAGES_TO_SIZE (Pages),
    399       NULL
    400       );
    401   }
    402   return Buffer;
    403 }
    404 
    405 /**
    406   Frees one or more 4KB pages that were previously allocated with one of the aligned page
    407   allocation functions in the Memory Allocation Library.
    408 
    409   Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer.  Buffer
    410   must have been allocated on a previous call to the aligned page allocation services of the Memory
    411   Allocation Library.  If it is not possible to free allocated pages, then this function will
    412   perform no actions.
    413 
    414   If Buffer was not allocated with an aligned page allocation function in the Memory Allocation
    415   Library, then ASSERT().
    416   If Pages is zero, then ASSERT().
    417 
    418   @param  Buffer                The pointer to the buffer of pages to free.
    419   @param  Pages                 The number of 4 KB pages to free.
    420 
    421 **/
    422 VOID
    423 EFIAPI
    424 FreeAlignedPages (
    425   IN VOID   *Buffer,
    426   IN UINTN  Pages
    427   )
    428 {
    429   EFI_STATUS  Status;
    430 
    431   ASSERT (Pages != 0);
    432   Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
    433   ASSERT_EFI_ERROR (Status);
    434 }
    435 
    436 /**
    437   Allocates a buffer of a certain pool type.
    438 
    439   Allocates the number bytes specified by AllocationSize of a certain pool type and returns a
    440   pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
    441   returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
    442 
    443   @param  MemoryType            The type of memory to allocate.
    444   @param  AllocationSize        The number of bytes to allocate.
    445 
    446   @return A pointer to the allocated buffer or NULL if allocation fails.
    447 
    448 **/
    449 VOID *
    450 InternalAllocatePool (
    451   IN EFI_MEMORY_TYPE  MemoryType,
    452   IN UINTN            AllocationSize
    453   )
    454 {
    455   EFI_STATUS  Status;
    456   VOID        *Memory;
    457 
    458   Status = gBS->AllocatePool (MemoryType, AllocationSize, &Memory);
    459   if (EFI_ERROR (Status)) {
    460     Memory = NULL;
    461   }
    462   return Memory;
    463 }
    464 
    465 /**
    466   Allocates a buffer of type EfiBootServicesData.
    467 
    468   Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a
    469   pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
    470   returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
    471 
    472   @param  AllocationSize        The number of bytes to allocate.
    473 
    474   @return A pointer to the allocated buffer or NULL if allocation fails.
    475 
    476 **/
    477 VOID *
    478 EFIAPI
    479 AllocatePool (
    480   IN UINTN  AllocationSize
    481   )
    482 {
    483   VOID  *Buffer;
    484 
    485   Buffer = InternalAllocatePool (EfiBootServicesData, AllocationSize);
    486   if (Buffer != NULL) {
    487     MemoryProfileLibRecord (
    488       (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
    489       MEMORY_PROFILE_ACTION_LIB_ALLOCATE_POOL,
    490       EfiBootServicesData,
    491       Buffer,
    492       AllocationSize,
    493       NULL
    494       );
    495   }
    496   return Buffer;
    497 }
    498 
    499 /**
    500   Allocates a buffer of type EfiRuntimeServicesData.
    501 
    502   Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns
    503   a pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
    504   returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
    505 
    506   @param  AllocationSize        The number of bytes to allocate.
    507 
    508   @return A pointer to the allocated buffer or NULL if allocation fails.
    509 
    510 **/
    511 VOID *
    512 EFIAPI
    513 AllocateRuntimePool (
    514   IN UINTN  AllocationSize
    515   )
    516 {
    517   VOID  *Buffer;
    518 
    519   Buffer = InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
    520   if (Buffer != NULL) {
    521     MemoryProfileLibRecord (
    522       (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
    523       MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_POOL,
    524       EfiRuntimeServicesData,
    525       Buffer,
    526       AllocationSize,
    527       NULL
    528       );
    529   }
    530   return Buffer;
    531 }
    532 
    533 /**
    534   Allocates a buffer of type EfiReservedMemoryType.
    535 
    536   Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns
    537   a pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
    538   returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
    539 
    540   @param  AllocationSize        The number of bytes to allocate.
    541 
    542   @return A pointer to the allocated buffer or NULL if allocation fails.
    543 
    544 **/
    545 VOID *
    546 EFIAPI
    547 AllocateReservedPool (
    548   IN UINTN  AllocationSize
    549   )
    550 {
    551   VOID  *Buffer;
    552 
    553   Buffer = InternalAllocatePool (EfiReservedMemoryType, AllocationSize);
    554   if (Buffer != NULL) {
    555     MemoryProfileLibRecord (
    556       (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
    557       MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_POOL,
    558       EfiReservedMemoryType,
    559       Buffer,
    560       AllocationSize,
    561       NULL
    562       );
    563   }
    564   return Buffer;
    565 }
    566 
    567 /**
    568   Allocates and zeros a buffer of a certain pool type.
    569 
    570   Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer
    571   with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a valid
    572   buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the request,
    573   then NULL is returned.
    574 
    575   @param  PoolType              The type of memory to allocate.
    576   @param  AllocationSize        The number of bytes to allocate and zero.
    577 
    578   @return A pointer to the allocated buffer or NULL if allocation fails.
    579 
    580 **/
    581 VOID *
    582 InternalAllocateZeroPool (
    583   IN EFI_MEMORY_TYPE  PoolType,
    584   IN UINTN            AllocationSize
    585   )
    586 {
    587   VOID  *Memory;
    588 
    589   Memory = InternalAllocatePool (PoolType, AllocationSize);
    590   if (Memory != NULL) {
    591     Memory = ZeroMem (Memory, AllocationSize);
    592   }
    593   return Memory;
    594 }
    595 
    596 /**
    597   Allocates and zeros a buffer of type EfiBootServicesData.
    598 
    599   Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
    600   buffer with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a
    601   valid buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the
    602   request, then NULL is returned.
    603 
    604   @param  AllocationSize        The number of bytes to allocate and zero.
    605 
    606   @return A pointer to the allocated buffer or NULL if allocation fails.
    607 
    608 **/
    609 VOID *
    610 EFIAPI
    611 AllocateZeroPool (
    612   IN UINTN  AllocationSize
    613   )
    614 {
    615   VOID  *Buffer;
    616 
    617   Buffer = InternalAllocateZeroPool (EfiBootServicesData, AllocationSize);
    618   if (Buffer != NULL) {
    619     MemoryProfileLibRecord (
    620       (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
    621       MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ZERO_POOL,
    622       EfiBootServicesData,
    623       Buffer,
    624       AllocationSize,
    625       NULL
    626       );
    627   }
    628   return Buffer;
    629 }
    630 
    631 /**
    632   Allocates and zeros a buffer of type EfiRuntimeServicesData.
    633 
    634   Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the
    635   buffer with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a
    636   valid buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the
    637   request, then NULL is returned.
    638 
    639   @param  AllocationSize        The number of bytes to allocate and zero.
    640 
    641   @return A pointer to the allocated buffer or NULL if allocation fails.
    642 
    643 **/
    644 VOID *
    645 EFIAPI
    646 AllocateRuntimeZeroPool (
    647   IN UINTN  AllocationSize
    648   )
    649 {
    650   VOID  *Buffer;
    651 
    652   Buffer = InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);
    653   if (Buffer != NULL) {
    654     MemoryProfileLibRecord (
    655       (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
    656       MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_ZERO_POOL,
    657       EfiRuntimeServicesData,
    658       Buffer,
    659       AllocationSize,
    660       NULL
    661       );
    662   }
    663   return Buffer;
    664 }
    665 
    666 /**
    667   Allocates and zeros a buffer of type EfiReservedMemoryType.
    668 
    669   Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the
    670   buffer with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a
    671   valid buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the
    672   request, then NULL is returned.
    673 
    674   @param  AllocationSize        The number of bytes to allocate and zero.
    675 
    676   @return A pointer to the allocated buffer or NULL if allocation fails.
    677 
    678 **/
    679 VOID *
    680 EFIAPI
    681 AllocateReservedZeroPool (
    682   IN UINTN  AllocationSize
    683   )
    684 {
    685   VOID  *Buffer;
    686 
    687   Buffer = InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);
    688   if (Buffer != NULL) {
    689     MemoryProfileLibRecord (
    690       (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
    691       MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_ZERO_POOL,
    692       EfiReservedMemoryType,
    693       Buffer,
    694       AllocationSize,
    695       NULL
    696       );
    697   }
    698   return Buffer;
    699 }
    700 
    701 /**
    702   Copies a buffer to an allocated buffer of a certain pool type.
    703 
    704   Allocates the number bytes specified by AllocationSize of a certain pool type, copies
    705   AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
    706   allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
    707   is not enough memory remaining to satisfy the request, then NULL is returned.
    708   If Buffer is NULL, then ASSERT().
    709   If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
    710 
    711   @param  PoolType              The type of pool to allocate.
    712   @param  AllocationSize        The number of bytes to allocate and zero.
    713   @param  Buffer                The buffer to copy to the allocated buffer.
    714 
    715   @return A pointer to the allocated buffer or NULL if allocation fails.
    716 
    717 **/
    718 VOID *
    719 InternalAllocateCopyPool (
    720   IN EFI_MEMORY_TYPE  PoolType,
    721   IN UINTN            AllocationSize,
    722   IN CONST VOID       *Buffer
    723   )
    724 {
    725   VOID  *Memory;
    726 
    727   ASSERT (Buffer != NULL);
    728   ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
    729 
    730   Memory = InternalAllocatePool (PoolType, AllocationSize);
    731   if (Memory != NULL) {
    732      Memory = CopyMem (Memory, Buffer, AllocationSize);
    733   }
    734   return Memory;
    735 }
    736 
    737 /**
    738   Copies a buffer to an allocated buffer of type EfiBootServicesData.
    739 
    740   Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies
    741   AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
    742   allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
    743   is not enough memory remaining to satisfy the request, then NULL is returned.
    744 
    745   If Buffer is NULL, then ASSERT().
    746   If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
    747 
    748   @param  AllocationSize        The number of bytes to allocate and zero.
    749   @param  Buffer                The buffer to copy to the allocated buffer.
    750 
    751   @return A pointer to the allocated buffer or NULL if allocation fails.
    752 
    753 **/
    754 VOID *
    755 EFIAPI
    756 AllocateCopyPool (
    757   IN UINTN       AllocationSize,
    758   IN CONST VOID  *Buffer
    759   )
    760 {
    761   VOID  *NewBuffer;
    762 
    763   NewBuffer = InternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer);
    764   if (NewBuffer != NULL) {
    765     MemoryProfileLibRecord (
    766       (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
    767       MEMORY_PROFILE_ACTION_LIB_ALLOCATE_COPY_POOL,
    768       EfiBootServicesData,
    769       NewBuffer,
    770       AllocationSize,
    771       NULL
    772       );
    773   }
    774   return NewBuffer;
    775 }
    776 
    777 /**
    778   Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
    779 
    780   Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies
    781   AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
    782   allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
    783   is not enough memory remaining to satisfy the request, then NULL is returned.
    784 
    785   If Buffer is NULL, then ASSERT().
    786   If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
    787 
    788   @param  AllocationSize        The number of bytes to allocate and zero.
    789   @param  Buffer                The buffer to copy to the allocated buffer.
    790 
    791   @return A pointer to the allocated buffer or NULL if allocation fails.
    792 
    793 **/
    794 VOID *
    795 EFIAPI
    796 AllocateRuntimeCopyPool (
    797   IN UINTN       AllocationSize,
    798   IN CONST VOID  *Buffer
    799   )
    800 {
    801   VOID  *NewBuffer;
    802 
    803   NewBuffer = InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);
    804   if (NewBuffer != NULL) {
    805     MemoryProfileLibRecord (
    806       (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
    807       MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_COPY_POOL,
    808       EfiRuntimeServicesData,
    809       NewBuffer,
    810       AllocationSize,
    811       NULL
    812       );
    813   }
    814   return NewBuffer;
    815 }
    816 
    817 /**
    818   Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
    819 
    820   Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies
    821   AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
    822   allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
    823   is not enough memory remaining to satisfy the request, then NULL is returned.
    824 
    825   If Buffer is NULL, then ASSERT().
    826   If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
    827 
    828   @param  AllocationSize        The number of bytes to allocate and zero.
    829   @param  Buffer                The buffer to copy to the allocated buffer.
    830 
    831   @return A pointer to the allocated buffer or NULL if allocation fails.
    832 
    833 **/
    834 VOID *
    835 EFIAPI
    836 AllocateReservedCopyPool (
    837   IN UINTN       AllocationSize,
    838   IN CONST VOID  *Buffer
    839   )
    840 {
    841   VOID  *NewBuffer;
    842 
    843   NewBuffer = InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);
    844   if (NewBuffer != NULL) {
    845     MemoryProfileLibRecord (
    846       (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
    847       MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_COPY_POOL,
    848       EfiRuntimeServicesData,
    849       NewBuffer,
    850       AllocationSize,
    851       NULL
    852       );
    853   }
    854   return NewBuffer;
    855 }
    856 
    857 /**
    858   Reallocates a buffer of a specified memory type.
    859 
    860   Allocates and zeros the number bytes specified by NewSize from memory of the type
    861   specified by PoolType.  If OldBuffer is not NULL, then the smaller of OldSize and
    862   NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
    863   OldBuffer is freed.  A pointer to the newly allocated buffer is returned.
    864   If NewSize is 0, then a valid buffer of 0 size is  returned.  If there is not
    865   enough memory remaining to satisfy the request, then NULL is returned.
    866 
    867   If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
    868   is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
    869 
    870   @param  PoolType       The type of pool to allocate.
    871   @param  OldSize        The size, in bytes, of OldBuffer.
    872   @param  NewSize        The size, in bytes, of the buffer to reallocate.
    873   @param  OldBuffer      The buffer to copy to the allocated buffer.  This is an optional
    874                          parameter that may be NULL.
    875 
    876   @return A pointer to the allocated buffer or NULL if allocation fails.
    877 
    878 **/
    879 VOID *
    880 InternalReallocatePool (
    881   IN EFI_MEMORY_TYPE  PoolType,
    882   IN UINTN            OldSize,
    883   IN UINTN            NewSize,
    884   IN VOID             *OldBuffer  OPTIONAL
    885   )
    886 {
    887   VOID  *NewBuffer;
    888 
    889   NewBuffer = InternalAllocateZeroPool (PoolType, NewSize);
    890   if (NewBuffer != NULL && OldBuffer != NULL) {
    891     CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize));
    892     FreePool (OldBuffer);
    893   }
    894   return NewBuffer;
    895 }
    896 
    897 /**
    898   Reallocates a buffer of type EfiBootServicesData.
    899 
    900   Allocates and zeros the number bytes specified by NewSize from memory of type
    901   EfiBootServicesData.  If OldBuffer is not NULL, then the smaller of OldSize and
    902   NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
    903   OldBuffer is freed.  A pointer to the newly allocated buffer is returned.
    904   If NewSize is 0, then a valid buffer of 0 size is  returned.  If there is not
    905   enough memory remaining to satisfy the request, then NULL is returned.
    906 
    907   If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
    908   is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
    909 
    910   @param  OldSize        The size, in bytes, of OldBuffer.
    911   @param  NewSize        The size, in bytes, of the buffer to reallocate.
    912   @param  OldBuffer      The buffer to copy to the allocated buffer.  This is an optional
    913                          parameter that may be NULL.
    914 
    915   @return A pointer to the allocated buffer or NULL if allocation fails.
    916 
    917 **/
    918 VOID *
    919 EFIAPI
    920 ReallocatePool (
    921   IN UINTN  OldSize,
    922   IN UINTN  NewSize,
    923   IN VOID   *OldBuffer  OPTIONAL
    924   )
    925 {
    926   VOID  *Buffer;
    927 
    928   Buffer = InternalReallocatePool (EfiBootServicesData, OldSize, NewSize, OldBuffer);
    929   if (Buffer != NULL) {
    930     MemoryProfileLibRecord (
    931       (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
    932       MEMORY_PROFILE_ACTION_LIB_REALLOCATE_POOL,
    933       EfiBootServicesData,
    934       Buffer,
    935       NewSize,
    936       NULL
    937       );
    938   }
    939   return Buffer;
    940 }
    941 
    942 /**
    943   Reallocates a buffer of type EfiRuntimeServicesData.
    944 
    945   Allocates and zeros the number bytes specified by NewSize from memory of type
    946   EfiRuntimeServicesData.  If OldBuffer is not NULL, then the smaller of OldSize and
    947   NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
    948   OldBuffer is freed.  A pointer to the newly allocated buffer is returned.
    949   If NewSize is 0, then a valid buffer of 0 size is  returned.  If there is not
    950   enough memory remaining to satisfy the request, then NULL is returned.
    951 
    952   If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
    953   is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
    954 
    955   @param  OldSize        The size, in bytes, of OldBuffer.
    956   @param  NewSize        The size, in bytes, of the buffer to reallocate.
    957   @param  OldBuffer      The buffer to copy to the allocated buffer.  This is an optional
    958                          parameter that may be NULL.
    959 
    960   @return A pointer to the allocated buffer or NULL if allocation fails.
    961 
    962 **/
    963 VOID *
    964 EFIAPI
    965 ReallocateRuntimePool (
    966   IN UINTN  OldSize,
    967   IN UINTN  NewSize,
    968   IN VOID   *OldBuffer  OPTIONAL
    969   )
    970 {
    971   VOID  *Buffer;
    972 
    973   Buffer = InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer);
    974   if (Buffer != NULL) {
    975     MemoryProfileLibRecord (
    976       (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
    977       MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RUNTIME_POOL,
    978       EfiRuntimeServicesData,
    979       Buffer,
    980       NewSize,
    981       NULL
    982       );
    983   }
    984   return Buffer;
    985 }
    986 
    987 /**
    988   Reallocates a buffer of type EfiReservedMemoryType.
    989 
    990   Allocates and zeros the number bytes specified by NewSize from memory of type
    991   EfiReservedMemoryType.  If OldBuffer is not NULL, then the smaller of OldSize and
    992   NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
    993   OldBuffer is freed.  A pointer to the newly allocated buffer is returned.
    994   If NewSize is 0, then a valid buffer of 0 size is  returned.  If there is not
    995   enough memory remaining to satisfy the request, then NULL is returned.
    996 
    997   If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
    998   is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
    999 
   1000   @param  OldSize        The size, in bytes, of OldBuffer.
   1001   @param  NewSize        The size, in bytes, of the buffer to reallocate.
   1002   @param  OldBuffer      The buffer to copy to the allocated buffer.  This is an optional
   1003                          parameter that may be NULL.
   1004 
   1005   @return A pointer to the allocated buffer or NULL if allocation fails.
   1006 
   1007 **/
   1008 VOID *
   1009 EFIAPI
   1010 ReallocateReservedPool (
   1011   IN UINTN  OldSize,
   1012   IN UINTN  NewSize,
   1013   IN VOID   *OldBuffer  OPTIONAL
   1014   )
   1015 {
   1016   VOID  *Buffer;
   1017 
   1018   Buffer = InternalReallocatePool (EfiReservedMemoryType, OldSize, NewSize, OldBuffer);
   1019   if (Buffer != NULL) {
   1020     MemoryProfileLibRecord (
   1021       (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
   1022       MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RESERVED_POOL,
   1023       EfiReservedMemoryType,
   1024       Buffer,
   1025       NewSize,
   1026       NULL
   1027       );
   1028   }
   1029   return Buffer;
   1030 }
   1031 
   1032 /**
   1033   Frees a buffer that was previously allocated with one of the pool allocation functions in the
   1034   Memory Allocation Library.
   1035 
   1036   Frees the buffer specified by Buffer.  Buffer must have been allocated on a previous call to the
   1037   pool allocation services of the Memory Allocation Library.  If it is not possible to free pool
   1038   resources, then this function will perform no actions.
   1039 
   1040   If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
   1041   then ASSERT().
   1042 
   1043   @param  Buffer                The pointer to the buffer to free.
   1044 
   1045 **/
   1046 VOID
   1047 EFIAPI
   1048 FreePool (
   1049   IN VOID   *Buffer
   1050   )
   1051 {
   1052   EFI_STATUS        Status;
   1053 
   1054   Status = gBS->FreePool (Buffer);
   1055   ASSERT_EFI_ERROR (Status);
   1056 }
   1057 
   1058