Home | History | Annotate | Download | only in UefiMemoryAllocationLib
      1 /** @file
      2   Support routines for memory allocation routines based
      3   on boot services for Dxe phase drivers.
      4 
      5   Copyright (c) 2006 - 2015, 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 /**
     26   Allocates one or more 4KB pages of a certain memory type.
     27 
     28   Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated
     29   buffer.  The buffer returned is aligned on a 4KB boundary.  If Pages is 0, then NULL is returned.
     30   If there is not enough memory remaining to satisfy the request, then NULL is returned.
     31 
     32   @param  MemoryType            The type of memory to allocate.
     33   @param  Pages                 The number of 4 KB pages to allocate.
     34 
     35   @return A pointer to the allocated buffer or NULL if allocation fails.
     36 
     37 **/
     38 VOID *
     39 InternalAllocatePages (
     40   IN EFI_MEMORY_TYPE  MemoryType,
     41   IN UINTN            Pages
     42   )
     43 {
     44   EFI_STATUS            Status;
     45   EFI_PHYSICAL_ADDRESS  Memory;
     46 
     47   if (Pages == 0) {
     48     return NULL;
     49   }
     50 
     51   Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);
     52   if (EFI_ERROR (Status)) {
     53     return NULL;
     54   }
     55   return (VOID *) (UINTN) Memory;
     56 }
     57 
     58 /**
     59   Allocates one or more 4KB pages of type EfiBootServicesData.
     60 
     61   Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the
     62   allocated buffer.  The buffer returned is aligned on a 4KB boundary.  If Pages is 0, then NULL
     63   is returned.  If there is not enough memory remaining to satisfy the request, then NULL is
     64   returned.
     65 
     66   @param  Pages                 The number of 4 KB pages to allocate.
     67 
     68   @return A pointer to the allocated buffer or NULL if allocation fails.
     69 
     70 **/
     71 VOID *
     72 EFIAPI
     73 AllocatePages (
     74   IN UINTN  Pages
     75   )
     76 {
     77   return InternalAllocatePages (EfiBootServicesData, Pages);
     78 }
     79 
     80 /**
     81   Allocates one or more 4KB pages of type EfiRuntimeServicesData.
     82 
     83   Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
     84   allocated buffer.  The buffer returned is aligned on a 4KB boundary.  If Pages is 0, then NULL
     85   is returned.  If there is not enough memory remaining to satisfy the request, then NULL is
     86   returned.
     87 
     88   @param  Pages                 The number of 4 KB pages to allocate.
     89 
     90   @return A pointer to the allocated buffer or NULL if allocation fails.
     91 
     92 **/
     93 VOID *
     94 EFIAPI
     95 AllocateRuntimePages (
     96   IN UINTN  Pages
     97   )
     98 {
     99   return InternalAllocatePages (EfiRuntimeServicesData, Pages);
    100 }
    101 
    102 /**
    103   Allocates one or more 4KB pages of type EfiReservedMemoryType.
    104 
    105   Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the
    106   allocated buffer.  The buffer returned is aligned on a 4KB boundary.  If Pages is 0, then NULL
    107   is returned.  If there is not enough memory remaining to satisfy the request, then NULL is
    108   returned.
    109 
    110   @param  Pages                 The number of 4 KB pages to allocate.
    111 
    112   @return A pointer to the allocated buffer or NULL if allocation fails.
    113 
    114 **/
    115 VOID *
    116 EFIAPI
    117 AllocateReservedPages (
    118   IN UINTN  Pages
    119   )
    120 {
    121   return InternalAllocatePages (EfiReservedMemoryType, Pages);
    122 }
    123 
    124 /**
    125   Frees one or more 4KB pages that were previously allocated with one of the page allocation
    126   functions in the Memory Allocation Library.
    127 
    128   Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer.  Buffer
    129   must have been allocated on a previous call to the page allocation services of the Memory
    130   Allocation Library.  If it is not possible to free allocated pages, then this function will
    131   perform no actions.
    132 
    133   If Buffer was not allocated with a page allocation function in the Memory Allocation Library,
    134   then ASSERT().
    135   If Pages is zero, then ASSERT().
    136 
    137   @param  Buffer                The pointer to the buffer of pages to free.
    138   @param  Pages                 The number of 4 KB pages to free.
    139 
    140 **/
    141 VOID
    142 EFIAPI
    143 FreePages (
    144   IN VOID   *Buffer,
    145   IN UINTN  Pages
    146   )
    147 {
    148   EFI_STATUS  Status;
    149 
    150   ASSERT (Pages != 0);
    151   Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
    152   ASSERT_EFI_ERROR (Status);
    153 }
    154 
    155 /**
    156   Allocates one or more 4KB pages of a certain memory type at a specified alignment.
    157 
    158   Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment
    159   specified by Alignment.  The allocated buffer is returned.  If Pages is 0, then NULL is returned.
    160   If there is not enough memory at the specified alignment remaining to satisfy the request, then
    161   NULL is returned.
    162   If Alignment is not a power of two and Alignment is not zero, then ASSERT().
    163   If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
    164 
    165   @param  MemoryType            The type of memory to allocate.
    166   @param  Pages                 The number of 4 KB pages to allocate.
    167   @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
    168                                 If Alignment is zero, then byte alignment is used.
    169 
    170   @return A pointer to the allocated buffer or NULL if allocation fails.
    171 
    172 **/
    173 VOID *
    174 InternalAllocateAlignedPages (
    175   IN EFI_MEMORY_TYPE  MemoryType,
    176   IN UINTN            Pages,
    177   IN UINTN            Alignment
    178   )
    179 {
    180   EFI_STATUS            Status;
    181   EFI_PHYSICAL_ADDRESS  Memory;
    182   UINTN                 AlignedMemory;
    183   UINTN                 AlignmentMask;
    184   UINTN                 UnalignedPages;
    185   UINTN                 RealPages;
    186 
    187   //
    188   // Alignment must be a power of two or zero.
    189   //
    190   ASSERT ((Alignment & (Alignment - 1)) == 0);
    191 
    192   if (Pages == 0) {
    193     return NULL;
    194   }
    195   if (Alignment > EFI_PAGE_SIZE) {
    196     //
    197     // Calculate the total number of pages since alignment is larger than page size.
    198     //
    199     AlignmentMask  = Alignment - 1;
    200     RealPages      = Pages + EFI_SIZE_TO_PAGES (Alignment);
    201     //
    202     // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
    203     //
    204     ASSERT (RealPages > Pages);
    205 
    206     Status         = gBS->AllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory);
    207     if (EFI_ERROR (Status)) {
    208       return NULL;
    209     }
    210     AlignedMemory  = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask;
    211     UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN) Memory);
    212     if (UnalignedPages > 0) {
    213       //
    214       // Free first unaligned page(s).
    215       //
    216       Status = gBS->FreePages (Memory, UnalignedPages);
    217       ASSERT_EFI_ERROR (Status);
    218     }
    219     Memory         = (EFI_PHYSICAL_ADDRESS) (AlignedMemory + EFI_PAGES_TO_SIZE (Pages));
    220     UnalignedPages = RealPages - Pages - UnalignedPages;
    221     if (UnalignedPages > 0) {
    222       //
    223       // Free last unaligned page(s).
    224       //
    225       Status = gBS->FreePages (Memory, UnalignedPages);
    226       ASSERT_EFI_ERROR (Status);
    227     }
    228   } else {
    229     //
    230     // Do not over-allocate pages in this case.
    231     //
    232     Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);
    233     if (EFI_ERROR (Status)) {
    234       return NULL;
    235     }
    236     AlignedMemory  = (UINTN) Memory;
    237   }
    238   return (VOID *) AlignedMemory;
    239 }
    240 
    241 /**
    242   Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment.
    243 
    244   Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an
    245   alignment specified by Alignment.  The allocated buffer is returned.  If Pages is 0, then NULL is
    246   returned.  If there is not enough memory at the specified alignment remaining to satisfy the
    247   request, then NULL is returned.
    248 
    249   If Alignment is not a power of two and Alignment is not zero, then ASSERT().
    250   If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
    251 
    252   @param  Pages                 The number of 4 KB pages to allocate.
    253   @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
    254                                 If Alignment is zero, then byte alignment is used.
    255 
    256   @return A pointer to the allocated buffer or NULL if allocation fails.
    257 
    258 **/
    259 VOID *
    260 EFIAPI
    261 AllocateAlignedPages (
    262   IN UINTN  Pages,
    263   IN UINTN  Alignment
    264   )
    265 {
    266   return InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment);
    267 }
    268 
    269 /**
    270   Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
    271 
    272   Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an
    273   alignment specified by Alignment.  The allocated buffer is returned.  If Pages is 0, then NULL is
    274   returned.  If there is not enough memory at the specified alignment remaining to satisfy the
    275   request, then NULL is returned.
    276 
    277   If Alignment is not a power of two and Alignment is not zero, then ASSERT().
    278   If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
    279 
    280   @param  Pages                 The number of 4 KB pages to allocate.
    281   @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
    282                                 If Alignment is zero, then byte alignment is used.
    283 
    284   @return A pointer to the allocated buffer or NULL if allocation fails.
    285 
    286 **/
    287 VOID *
    288 EFIAPI
    289 AllocateAlignedRuntimePages (
    290   IN UINTN  Pages,
    291   IN UINTN  Alignment
    292   )
    293 {
    294   return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);
    295 }
    296 
    297 /**
    298   Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
    299 
    300   Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an
    301   alignment specified by Alignment.  The allocated buffer is returned.  If Pages is 0, then NULL is
    302   returned.  If there is not enough memory at the specified alignment remaining to satisfy the
    303   request, then NULL is returned.
    304 
    305   If Alignment is not a power of two and Alignment is not zero, then ASSERT().
    306   If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
    307 
    308   @param  Pages                 The number of 4 KB pages to allocate.
    309   @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
    310                                 If Alignment is zero, then byte alignment is used.
    311 
    312   @return A pointer to the allocated buffer or NULL if allocation fails.
    313 
    314 **/
    315 VOID *
    316 EFIAPI
    317 AllocateAlignedReservedPages (
    318   IN UINTN  Pages,
    319   IN UINTN  Alignment
    320   )
    321 {
    322   return InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment);
    323 }
    324 
    325 /**
    326   Frees one or more 4KB pages that were previously allocated with one of the aligned page
    327   allocation functions in the Memory Allocation Library.
    328 
    329   Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer.  Buffer
    330   must have been allocated on a previous call to the aligned page allocation services of the Memory
    331   Allocation Library.  If it is not possible to free allocated pages, then this function will
    332   perform no actions.
    333 
    334   If Buffer was not allocated with an aligned page allocation function in the Memory Allocation
    335   Library, then ASSERT().
    336   If Pages is zero, then ASSERT().
    337 
    338   @param  Buffer                The pointer to the buffer of pages to free.
    339   @param  Pages                 The number of 4 KB pages to free.
    340 
    341 **/
    342 VOID
    343 EFIAPI
    344 FreeAlignedPages (
    345   IN VOID   *Buffer,
    346   IN UINTN  Pages
    347   )
    348 {
    349   EFI_STATUS  Status;
    350 
    351   ASSERT (Pages != 0);
    352   Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
    353   ASSERT_EFI_ERROR (Status);
    354 }
    355 
    356 /**
    357   Allocates a buffer of a certain pool type.
    358 
    359   Allocates the number bytes specified by AllocationSize of a certain pool type and returns a
    360   pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
    361   returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
    362 
    363   @param  MemoryType            The type of memory to allocate.
    364   @param  AllocationSize        The number of bytes to allocate.
    365 
    366   @return A pointer to the allocated buffer or NULL if allocation fails.
    367 
    368 **/
    369 VOID *
    370 InternalAllocatePool (
    371   IN EFI_MEMORY_TYPE  MemoryType,
    372   IN UINTN            AllocationSize
    373   )
    374 {
    375   EFI_STATUS  Status;
    376   VOID        *Memory;
    377 
    378   Status = gBS->AllocatePool (MemoryType, AllocationSize, &Memory);
    379   if (EFI_ERROR (Status)) {
    380     Memory = NULL;
    381   }
    382   return Memory;
    383 }
    384 
    385 /**
    386   Allocates a buffer of type EfiBootServicesData.
    387 
    388   Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a
    389   pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
    390   returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
    391 
    392   @param  AllocationSize        The number of bytes to allocate.
    393 
    394   @return A pointer to the allocated buffer or NULL if allocation fails.
    395 
    396 **/
    397 VOID *
    398 EFIAPI
    399 AllocatePool (
    400   IN UINTN  AllocationSize
    401   )
    402 {
    403   return InternalAllocatePool (EfiBootServicesData, AllocationSize);
    404 }
    405 
    406 /**
    407   Allocates a buffer of type EfiRuntimeServicesData.
    408 
    409   Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns
    410   a pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
    411   returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
    412 
    413   @param  AllocationSize        The number of bytes to allocate.
    414 
    415   @return A pointer to the allocated buffer or NULL if allocation fails.
    416 
    417 **/
    418 VOID *
    419 EFIAPI
    420 AllocateRuntimePool (
    421   IN UINTN  AllocationSize
    422   )
    423 {
    424   return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
    425 }
    426 
    427 /**
    428   Allocates a buffer of type EfiReservedMemoryType.
    429 
    430   Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns
    431   a pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
    432   returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
    433 
    434   @param  AllocationSize        The number of bytes to allocate.
    435 
    436   @return A pointer to the allocated buffer or NULL if allocation fails.
    437 
    438 **/
    439 VOID *
    440 EFIAPI
    441 AllocateReservedPool (
    442   IN UINTN  AllocationSize
    443   )
    444 {
    445   return InternalAllocatePool (EfiReservedMemoryType, AllocationSize);
    446 }
    447 
    448 /**
    449   Allocates and zeros a buffer of a certain pool type.
    450 
    451   Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer
    452   with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a valid
    453   buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the request,
    454   then NULL is returned.
    455 
    456   @param  PoolType              The type of memory to allocate.
    457   @param  AllocationSize        The number of bytes to allocate and zero.
    458 
    459   @return A pointer to the allocated buffer or NULL if allocation fails.
    460 
    461 **/
    462 VOID *
    463 InternalAllocateZeroPool (
    464   IN EFI_MEMORY_TYPE  PoolType,
    465   IN UINTN            AllocationSize
    466   )
    467 {
    468   VOID  *Memory;
    469 
    470   Memory = InternalAllocatePool (PoolType, AllocationSize);
    471   if (Memory != NULL) {
    472     Memory = ZeroMem (Memory, AllocationSize);
    473   }
    474   return Memory;
    475 }
    476 
    477 /**
    478   Allocates and zeros a buffer of type EfiBootServicesData.
    479 
    480   Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
    481   buffer with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a
    482   valid buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the
    483   request, then NULL is returned.
    484 
    485   @param  AllocationSize        The number of bytes to allocate and zero.
    486 
    487   @return A pointer to the allocated buffer or NULL if allocation fails.
    488 
    489 **/
    490 VOID *
    491 EFIAPI
    492 AllocateZeroPool (
    493   IN UINTN  AllocationSize
    494   )
    495 {
    496   return InternalAllocateZeroPool (EfiBootServicesData, AllocationSize);
    497 }
    498 
    499 /**
    500   Allocates and zeros a buffer of type EfiRuntimeServicesData.
    501 
    502   Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the
    503   buffer with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a
    504   valid buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the
    505   request, then NULL is returned.
    506 
    507   @param  AllocationSize        The number of bytes to allocate and zero.
    508 
    509   @return A pointer to the allocated buffer or NULL if allocation fails.
    510 
    511 **/
    512 VOID *
    513 EFIAPI
    514 AllocateRuntimeZeroPool (
    515   IN UINTN  AllocationSize
    516   )
    517 {
    518   return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);
    519 }
    520 
    521 /**
    522   Allocates and zeros a buffer of type EfiReservedMemoryType.
    523 
    524   Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the
    525   buffer with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a
    526   valid buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the
    527   request, then NULL is returned.
    528 
    529   @param  AllocationSize        The number of bytes to allocate and zero.
    530 
    531   @return A pointer to the allocated buffer or NULL if allocation fails.
    532 
    533 **/
    534 VOID *
    535 EFIAPI
    536 AllocateReservedZeroPool (
    537   IN UINTN  AllocationSize
    538   )
    539 {
    540   return InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);
    541 }
    542 
    543 /**
    544   Copies a buffer to an allocated buffer of a certain pool type.
    545 
    546   Allocates the number bytes specified by AllocationSize of a certain pool type, copies
    547   AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
    548   allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
    549   is not enough memory remaining to satisfy the request, then NULL is returned.
    550   If Buffer is NULL, then ASSERT().
    551   If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
    552 
    553   @param  PoolType              The type of pool to allocate.
    554   @param  AllocationSize        The number of bytes to allocate and zero.
    555   @param  Buffer                The buffer to copy to the allocated buffer.
    556 
    557   @return A pointer to the allocated buffer or NULL if allocation fails.
    558 
    559 **/
    560 VOID *
    561 InternalAllocateCopyPool (
    562   IN EFI_MEMORY_TYPE  PoolType,
    563   IN UINTN            AllocationSize,
    564   IN CONST VOID       *Buffer
    565   )
    566 {
    567   VOID  *Memory;
    568 
    569   ASSERT (Buffer != NULL);
    570   ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
    571 
    572   Memory = InternalAllocatePool (PoolType, AllocationSize);
    573   if (Memory != NULL) {
    574      Memory = CopyMem (Memory, Buffer, AllocationSize);
    575   }
    576   return Memory;
    577 }
    578 
    579 /**
    580   Copies a buffer to an allocated buffer of type EfiBootServicesData.
    581 
    582   Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies
    583   AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
    584   allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
    585   is not enough memory remaining to satisfy the request, then NULL is returned.
    586 
    587   If Buffer is NULL, then ASSERT().
    588   If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
    589 
    590   @param  AllocationSize        The number of bytes to allocate and zero.
    591   @param  Buffer                The buffer to copy to the allocated buffer.
    592 
    593   @return A pointer to the allocated buffer or NULL if allocation fails.
    594 
    595 **/
    596 VOID *
    597 EFIAPI
    598 AllocateCopyPool (
    599   IN UINTN       AllocationSize,
    600   IN CONST VOID  *Buffer
    601   )
    602 {
    603   return InternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer);
    604 }
    605 
    606 /**
    607   Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
    608 
    609   Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies
    610   AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
    611   allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
    612   is not enough memory remaining to satisfy the request, then NULL is returned.
    613 
    614   If Buffer is NULL, then ASSERT().
    615   If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
    616 
    617   @param  AllocationSize        The number of bytes to allocate and zero.
    618   @param  Buffer                The buffer to copy to the allocated buffer.
    619 
    620   @return A pointer to the allocated buffer or NULL if allocation fails.
    621 
    622 **/
    623 VOID *
    624 EFIAPI
    625 AllocateRuntimeCopyPool (
    626   IN UINTN       AllocationSize,
    627   IN CONST VOID  *Buffer
    628   )
    629 {
    630   return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);
    631 }
    632 
    633 /**
    634   Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
    635 
    636   Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies
    637   AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
    638   allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
    639   is not enough memory remaining to satisfy the request, then NULL is returned.
    640 
    641   If Buffer is NULL, then ASSERT().
    642   If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
    643 
    644   @param  AllocationSize        The number of bytes to allocate and zero.
    645   @param  Buffer                The buffer to copy to the allocated buffer.
    646 
    647   @return A pointer to the allocated buffer or NULL if allocation fails.
    648 
    649 **/
    650 VOID *
    651 EFIAPI
    652 AllocateReservedCopyPool (
    653   IN UINTN       AllocationSize,
    654   IN CONST VOID  *Buffer
    655   )
    656 {
    657   return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);
    658 }
    659 
    660 /**
    661   Reallocates a buffer of a specified memory type.
    662 
    663   Allocates and zeros the number bytes specified by NewSize from memory of the type
    664   specified by PoolType.  If OldBuffer is not NULL, then the smaller of OldSize and
    665   NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
    666   OldBuffer is freed.  A pointer to the newly allocated buffer is returned.
    667   If NewSize is 0, then a valid buffer of 0 size is  returned.  If there is not
    668   enough memory remaining to satisfy the request, then NULL is returned.
    669 
    670   If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
    671   is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
    672 
    673   @param  PoolType       The type of pool to allocate.
    674   @param  OldSize        The size, in bytes, of OldBuffer.
    675   @param  NewSize        The size, in bytes, of the buffer to reallocate.
    676   @param  OldBuffer      The buffer to copy to the allocated buffer.  This is an optional
    677                          parameter that may be NULL.
    678 
    679   @return A pointer to the allocated buffer or NULL if allocation fails.
    680 
    681 **/
    682 VOID *
    683 InternalReallocatePool (
    684   IN EFI_MEMORY_TYPE  PoolType,
    685   IN UINTN            OldSize,
    686   IN UINTN            NewSize,
    687   IN VOID             *OldBuffer  OPTIONAL
    688   )
    689 {
    690   VOID  *NewBuffer;
    691 
    692   NewBuffer = InternalAllocateZeroPool (PoolType, NewSize);
    693   if (NewBuffer != NULL && OldBuffer != NULL) {
    694     CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize));
    695     FreePool (OldBuffer);
    696   }
    697   return NewBuffer;
    698 }
    699 
    700 /**
    701   Reallocates a buffer of type EfiBootServicesData.
    702 
    703   Allocates and zeros the number bytes specified by NewSize from memory of type
    704   EfiBootServicesData.  If OldBuffer is not NULL, then the smaller of OldSize and
    705   NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
    706   OldBuffer is freed.  A pointer to the newly allocated buffer is returned.
    707   If NewSize is 0, then a valid buffer of 0 size is  returned.  If there is not
    708   enough memory remaining to satisfy the request, then NULL is returned.
    709 
    710   If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
    711   is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
    712 
    713   @param  OldSize        The size, in bytes, of OldBuffer.
    714   @param  NewSize        The size, in bytes, of the buffer to reallocate.
    715   @param  OldBuffer      The buffer to copy to the allocated buffer.  This is an optional
    716                          parameter that may be NULL.
    717 
    718   @return A pointer to the allocated buffer or NULL if allocation fails.
    719 
    720 **/
    721 VOID *
    722 EFIAPI
    723 ReallocatePool (
    724   IN UINTN  OldSize,
    725   IN UINTN  NewSize,
    726   IN VOID   *OldBuffer  OPTIONAL
    727   )
    728 {
    729   return InternalReallocatePool (EfiBootServicesData, OldSize, NewSize, OldBuffer);
    730 }
    731 
    732 /**
    733   Reallocates a buffer of type EfiRuntimeServicesData.
    734 
    735   Allocates and zeros the number bytes specified by NewSize from memory of type
    736   EfiRuntimeServicesData.  If OldBuffer is not NULL, then the smaller of OldSize and
    737   NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
    738   OldBuffer is freed.  A pointer to the newly allocated buffer is returned.
    739   If NewSize is 0, then a valid buffer of 0 size is  returned.  If there is not
    740   enough memory remaining to satisfy the request, then NULL is returned.
    741 
    742   If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
    743   is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
    744 
    745   @param  OldSize        The size, in bytes, of OldBuffer.
    746   @param  NewSize        The size, in bytes, of the buffer to reallocate.
    747   @param  OldBuffer      The buffer to copy to the allocated buffer.  This is an optional
    748                          parameter that may be NULL.
    749 
    750   @return A pointer to the allocated buffer or NULL if allocation fails.
    751 
    752 **/
    753 VOID *
    754 EFIAPI
    755 ReallocateRuntimePool (
    756   IN UINTN  OldSize,
    757   IN UINTN  NewSize,
    758   IN VOID   *OldBuffer  OPTIONAL
    759   )
    760 {
    761   return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer);
    762 }
    763 
    764 /**
    765   Reallocates a buffer of type EfiReservedMemoryType.
    766 
    767   Allocates and zeros the number bytes specified by NewSize from memory of type
    768   EfiReservedMemoryType.  If OldBuffer is not NULL, then the smaller of OldSize and
    769   NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
    770   OldBuffer is freed.  A pointer to the newly allocated buffer is returned.
    771   If NewSize is 0, then a valid buffer of 0 size is  returned.  If there is not
    772   enough memory remaining to satisfy the request, then NULL is returned.
    773 
    774   If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
    775   is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
    776 
    777   @param  OldSize        The size, in bytes, of OldBuffer.
    778   @param  NewSize        The size, in bytes, of the buffer to reallocate.
    779   @param  OldBuffer      The buffer to copy to the allocated buffer.  This is an optional
    780                          parameter that may be NULL.
    781 
    782   @return A pointer to the allocated buffer or NULL if allocation fails.
    783 
    784 **/
    785 VOID *
    786 EFIAPI
    787 ReallocateReservedPool (
    788   IN UINTN  OldSize,
    789   IN UINTN  NewSize,
    790   IN VOID   *OldBuffer  OPTIONAL
    791   )
    792 {
    793   return InternalReallocatePool (EfiReservedMemoryType, OldSize, NewSize, OldBuffer);
    794 }
    795 
    796 /**
    797   Frees a buffer that was previously allocated with one of the pool allocation functions in the
    798   Memory Allocation Library.
    799 
    800   Frees the buffer specified by Buffer.  Buffer must have been allocated on a previous call to the
    801   pool allocation services of the Memory Allocation Library.  If it is not possible to free pool
    802   resources, then this function will perform no actions.
    803 
    804   If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
    805   then ASSERT().
    806 
    807   @param  Buffer                The pointer to the buffer to free.
    808 
    809 **/
    810 VOID
    811 EFIAPI
    812 FreePool (
    813   IN VOID   *Buffer
    814   )
    815 {
    816   EFI_STATUS    Status;
    817 
    818   Status = gBS->FreePool (Buffer);
    819   ASSERT_EFI_ERROR (Status);
    820 }
    821 
    822