13eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/*++
23eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
32c7e5c2febd407ed1849c06da50734dd6f751956hhtianCopyright (c) 2004 - 2006, Intel Corporation. All rights reserved.<BR>
42c7e5c2febd407ed1849c06da50734dd6f751956hhtianThis program and the accompanying materials
53eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangare licensed and made available under the terms and conditions of the BSD License
63eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangwhich accompanies this distribution.  The full text of the license may be found at
73eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwanghttp://opensource.org/licenses/bsd-license.php
83eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
93eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
103eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
113eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
123eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
133eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangModule Name:
143eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
153eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  MemoryAllocationLib.c
163eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
173eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangAbstract:
183eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
193eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Support routines for memory allocation routines for use with drivers.
203eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
213eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang--*/
223eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
233eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang#include "EdkIIGlueDxe.h"
243eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
253eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
263eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
273eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates one or more 4KB pages of a certain memory type.
283eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
293eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated
303eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  buffer.  The buffer returned is aligned on a 4KB boundary.  If Pages is 0, then NULL is returned.
313eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  If there is not enough memory remaining to satisfy the request, then NULL is returned.
323eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
333eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  MemoryType            The type of memory to allocate.
343eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Pages                 The number of 4 KB pages to allocate.
353eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
363eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @return A pointer to the allocated buffer or NULL if allocation fails.
373eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
383eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
393eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID *
403eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangInternalAllocatePages (
413eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN EFI_MEMORY_TYPE  MemoryType,
423eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN            Pages
433eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
443eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
453eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  EFI_STATUS            Status;
463eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  EFI_PHYSICAL_ADDRESS  Memory;
473eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
483eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  if (Pages == 0) {
493eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    return NULL;
503eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  }
513eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
523eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Status = (gBS->AllocatePages) (AllocateAnyPages, MemoryType, Pages, &Memory);
533eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  if (EFI_ERROR (Status)) {
543eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    Memory = 0;
553eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  }
563eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  return (VOID *) (UINTN) Memory;
573eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
583eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
593eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
603eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates one or more 4KB pages of type EfiBootServicesData.
613eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
623eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the
633eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  allocated buffer.  The buffer returned is aligned on a 4KB boundary.  If Pages is 0, then NULL
643eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  is returned.  If there is not enough memory remaining to satisfy the request, then NULL is
653eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  returned.
663eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
673eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Pages                 The number of 4 KB pages to allocate.
683eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
693eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @return A pointer to the allocated buffer or NULL if allocation fails.
703eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
713eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
723eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID *
733eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI
743eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangGlueAllocatePages (
753eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN  Pages
763eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
773eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
783eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  return InternalAllocatePages (EfiBootServicesData, Pages);
793eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
803eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
813eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
823eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates one or more 4KB pages of type EfiRuntimeServicesData.
833eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
843eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
853eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  allocated buffer.  The buffer returned is aligned on a 4KB boundary.  If Pages is 0, then NULL
863eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  is returned.  If there is not enough memory remaining to satisfy the request, then NULL is
873eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  returned.
883eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
893eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Pages                 The number of 4 KB pages to allocate.
903eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
913eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @return A pointer to the allocated buffer or NULL if allocation fails.
923eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
933eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
943eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID *
953eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI
963eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangAllocateRuntimePages (
973eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN  Pages
983eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
993eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
1003eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  return InternalAllocatePages (EfiRuntimeServicesData, Pages);
1013eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
1023eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
1033eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
1043eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates one or more 4KB pages of type EfiReservedMemoryType.
1053eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
1063eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the
1073eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  allocated buffer.  The buffer returned is aligned on a 4KB boundary.  If Pages is 0, then NULL
1083eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  is returned.  If there is not enough memory remaining to satisfy the request, then NULL is
1093eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  returned.
1103eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
1113eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Pages                 The number of 4 KB pages to allocate.
1123eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
1133eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @return A pointer to the allocated buffer or NULL if allocation fails.
1143eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
1153eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
1163eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID *
1173eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI
1183eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangAllocateReservedPages (
1193eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN  Pages
1203eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
1213eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
1223eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  return InternalAllocatePages (EfiReservedMemoryType, Pages);
1233eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
1243eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
1253eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
1263eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Frees one or more 4KB pages that were previously allocated with one of the page allocation
1273eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  functions in the Memory Allocation Library.
1283eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
1293eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer.  Buffer
1303eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  must have been allocated on a previous call to the page allocation services of the Memory
1313eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocation Library.
1323eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  If Buffer was not allocated with a page allocation function in the Memory Allocation Library,
1333eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  then ASSERT().
1343eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  If Pages is zero, then ASSERT().
1353eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
1363eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Buffer                Pointer to the buffer of pages to free.
1373eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Pages                 The number of 4 KB pages to free.
1383eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
1393eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
1403eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID
1413eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI
1423eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangGlueFreePages (
1433eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN VOID   *Buffer,
1443eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN  Pages
1453eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
1463eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
1473eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  EFI_STATUS  Status;
1483eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
1493eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  ASSERT (Pages != 0);
1503eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Status = (gBS->FreePages) ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
1513eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  ASSERT_EFI_ERROR (Status);
1523eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
1533eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
1543eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
1553eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates one or more 4KB pages of a certain memory type at a specified alignment.
1563eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
1573eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment
1583eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  specified by Alignment.  The allocated buffer is returned.  If Pages is 0, then NULL is returned.
1593eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  If there is not enough memory at the specified alignment remaining to satisfy the request, then
1603eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  NULL is returned.
1613eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
1623eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
1633eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  MemoryType            The type of memory to allocate.
1643eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Pages                 The number of 4 KB pages to allocate.
1653eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
1663eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang                                If Alignment is zero, then byte alignment is used.
1673eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
1683eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @return A pointer to the allocated buffer or NULL if allocation fails.
1693eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
1703eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
1713eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID *
1723eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangInternalAllocateAlignedPages (
1733eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN EFI_MEMORY_TYPE  MemoryType,
1743eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN            Pages,
1753eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN            Alignment
1763eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
1773eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
1783eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  EFI_STATUS            Status;
1793eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  EFI_PHYSICAL_ADDRESS  Memory;
1803eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  UINTN                 AlignedMemory;
1813eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  UINTN                 AlignmentMask;
1823eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  UINTN                 UnalignedPages;
1833eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  UINTN                 RealPages;
1843eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
1853eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  //
1863eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  // Alignment must be a power of two or zero.
1873eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  //
1883eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  ASSERT ((Alignment & (Alignment - 1)) == 0);
1893eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
1903eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  if (Pages == 0) {
1913eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    return NULL;
1923eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  }
1933eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  if (Alignment > EFI_PAGE_SIZE) {
1943eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    //
1953eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    // Caculate the total number of pages since alignment is larger than page size.
1963eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    //
1973eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    AlignmentMask  = Alignment - 1;
1983eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    RealPages      = Pages + EFI_SIZE_TO_PAGES (Alignment);
1993eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    //
2003eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
2013eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    //
2023eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    ASSERT (RealPages > Pages);
2033eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
2043eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    Status         = (gBS->AllocatePages) (AllocateAnyPages, MemoryType, RealPages, &Memory);
2053eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    if (EFI_ERROR (Status)) {
2063eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang      return NULL;
2073eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    }
2083eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    AlignedMemory  = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask;
2093eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    UnalignedPages = EFI_SIZE_TO_PAGES ((UINTN) Memory - AlignedMemory);
2103eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    if (UnalignedPages > 0) {
2113eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang      //
2123eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang      // Free first unaligned page(s).
2133eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang      //
2143eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang      Status = (gBS->FreePages) (Memory, UnalignedPages);
2153eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang      ASSERT_EFI_ERROR (Status);
2163eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    }
2173eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    Memory         = (EFI_PHYSICAL_ADDRESS) (AlignedMemory + EFI_PAGES_TO_SIZE (Pages));
2183eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    UnalignedPages = RealPages - Pages - UnalignedPages;
2193eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    if (UnalignedPages > 0) {
2203eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang      //
2213eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang      // Free last unaligned page(s).
2223eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang      //
2233eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang      Status = (gBS->FreePages) (Memory, UnalignedPages);
2243eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang      ASSERT_EFI_ERROR (Status);
2253eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    }
2263eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  } else {
2273eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    //
2283eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    // Do not over-allocate pages in this case.
2293eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    //
2303eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    Status = (gBS->AllocatePages) (AllocateAnyPages, MemoryType, Pages, &Memory);
2313eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    if (EFI_ERROR (Status)) {
2323eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang      return NULL;
2333eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    }
2343eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    AlignedMemory  = (UINTN) Memory;
2353eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  }
2363eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  return (VOID *) AlignedMemory;
2373eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
2383eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
2393eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
2403eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment.
2413eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
2423eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an
2433eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  alignment specified by Alignment.  The allocated buffer is returned.  If Pages is 0, then NULL is
2443eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  returned.  If there is not enough memory at the specified alignment remaining to satisfy the
2453eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  request, then NULL is returned.
2463eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
2473eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
2483eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Pages                 The number of 4 KB pages to allocate.
2493eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
2503eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang                                If Alignment is zero, then byte alignment is used.
2513eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
2523eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @return A pointer to the allocated buffer or NULL if allocation fails.
2533eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
2543eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
2553eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID *
2563eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI
2573eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangAllocateAlignedPages (
2583eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN  Pages,
2593eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN  Alignment
2603eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
2613eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
2623eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  return InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment);
2633eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
2643eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
2653eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
2663eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
2673eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
2683eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an
2693eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  alignment specified by Alignment.  The allocated buffer is returned.  If Pages is 0, then NULL is
2703eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  returned.  If there is not enough memory at the specified alignment remaining to satisfy the
2713eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  request, then NULL is returned.
2723eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
2733eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
2743eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Pages                 The number of 4 KB pages to allocate.
2753eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
2763eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang                                If Alignment is zero, then byte alignment is used.
2773eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
2783eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @return A pointer to the allocated buffer or NULL if allocation fails.
2793eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
2803eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
2813eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID *
2823eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI
2833eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangAllocateAlignedRuntimePages (
2843eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN  Pages,
2853eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN  Alignment
2863eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
2873eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
2883eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);
2893eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
2903eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
2913eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
2923eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
2933eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
2943eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an
2953eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  alignment specified by Alignment.  The allocated buffer is returned.  If Pages is 0, then NULL is
2963eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  returned.  If there is not enough memory at the specified alignment remaining to satisfy the
2973eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  request, then NULL is returned.
2983eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
2993eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
3003eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Pages                 The number of 4 KB pages to allocate.
3013eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
3023eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang                                If Alignment is zero, then byte alignment is used.
3033eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
3043eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @return A pointer to the allocated buffer or NULL if allocation fails.
3053eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
3063eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
3073eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID *
3083eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI
3093eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangAllocateAlignedReservedPages (
3103eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN  Pages,
3113eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN  Alignment
3123eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
3133eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
3143eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  return InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment);
3153eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
3163eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
3173eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
3183eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Frees one or more 4KB pages that were previously allocated with one of the aligned page
3193eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  allocation functions in the Memory Allocation Library.
3203eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
3213eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer.  Buffer
3223eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  must have been allocated on a previous call to the aligned page allocation services of the Memory
3233eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocation Library.
3243eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  If Buffer was not allocated with an aligned page allocation function in the Memory Allocation
3253eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Library, then ASSERT().
3263eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  If Pages is zero, then ASSERT().
3273eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
3283eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Buffer                Pointer to the buffer of pages to free.
3293eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Pages                 The number of 4 KB pages to free.
3303eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
3313eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
3323eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID
3333eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI
3343eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangFreeAlignedPages (
3353eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN VOID   *Buffer,
3363eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN  Pages
3373eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
3383eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
3393eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  EFI_STATUS  Status;
3403eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
3413eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  ASSERT (Pages != 0);
3423eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Status = (gBS->FreePages) ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
3433eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  ASSERT_EFI_ERROR (Status);
3443eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
3453eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
3463eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
3473eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates a buffer of a certain pool type.
3483eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
3493eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates the number bytes specified by AllocationSize of a certain pool type and returns a
3503eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
3513eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
3523eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
3533eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  MemoryType            The type of memory to allocate.
3543eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  AllocationSize        The number of bytes to allocate.
3553eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
3563eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @return A pointer to the allocated buffer or NULL if allocation fails.
3573eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
3583eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
3593eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID *
3603eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangInternalAllocatePool (
3613eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN EFI_MEMORY_TYPE  MemoryType,
3623eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN            AllocationSize
3633eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
3643eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
3653eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  EFI_STATUS  Status;
3663eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  VOID        *Memory;
3673eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
3683eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Status = (gBS->AllocatePool) (MemoryType, AllocationSize, &Memory);
3693eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  if (EFI_ERROR (Status)) {
3703eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    Memory = NULL;
3713eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  }
3723eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  return Memory;
3733eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
3743eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
3753eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
3763eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates a buffer of type EfiBootServicesData.
3773eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
3783eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a
3793eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
3803eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
3813eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
3823eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  AllocationSize        The number of bytes to allocate.
3833eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
3843eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @return A pointer to the allocated buffer or NULL if allocation fails.
3853eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
3863eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
3873eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID *
3883eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI
3893eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangGlueAllocatePool (
3903eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN  AllocationSize
3913eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
3923eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
3933eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  return InternalAllocatePool (EfiBootServicesData, AllocationSize);
3943eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
3953eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
3963eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
3973eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates a buffer of type EfiRuntimeServicesData.
3983eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
3993eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns
4003eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  a pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
4013eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
4023eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
4033eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  AllocationSize        The number of bytes to allocate.
4043eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
4053eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @return A pointer to the allocated buffer or NULL if allocation fails.
4063eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
4073eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
4083eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID *
4093eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI
4103eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangAllocateRuntimePool (
4113eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN  AllocationSize
4123eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
4133eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
4143eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
4153eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
4163eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
4173eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
4183eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates a buffer of type EfieservedMemoryType.
4193eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
4203eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates the number bytes specified by AllocationSize of type EfieservedMemoryType and returns
4213eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  a pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
4223eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
4233eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
4243eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  AllocationSize        The number of bytes to allocate.
4253eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
4263eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @return A pointer to the allocated buffer or NULL if allocation fails.
4273eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
4283eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
4293eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID *
4303eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI
4313eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangAllocateReservedPool (
4323eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN  AllocationSize
4333eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
4343eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
4353eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  return InternalAllocatePool (EfiReservedMemoryType, AllocationSize);
4363eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
4373eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
4383eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
4393eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates and zeros a buffer of a certian pool type.
4403eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
4413eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates the number bytes specified by AllocationSize of a certian pool type, clears the buffer
4423eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a valid
4433eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the request,
4443eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  then NULL is returned.
4453eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
4463eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  PoolType              The type of memory to allocate.
4473eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  AllocationSize        The number of bytes to allocate and zero.
4483eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
4493eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @return A pointer to the allocated buffer or NULL if allocation fails.
4503eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
4513eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
4523eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID *
4533eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangInternalAllocateZeroPool (
4543eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN EFI_MEMORY_TYPE  PoolType,
4553eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN            AllocationSize
4563eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
4573eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
4583eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  VOID  *Memory;
4593eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
4603eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Memory = InternalAllocatePool (PoolType, AllocationSize);
4613eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  if (Memory != NULL) {
4623eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    Memory = ZeroMem (Memory, AllocationSize);
4633eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  }
4643eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  return Memory;
4653eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
4663eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
4673eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
4683eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates and zeros a buffer of type EfiBootServicesData.
4693eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
4703eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
4713eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  buffer with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a
4723eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  valid buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the
4733eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  request, then NULL is returned.
4743eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
4753eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  AllocationSize        The number of bytes to allocate and zero.
4763eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
4773eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @return A pointer to the allocated buffer or NULL if allocation fails.
4783eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
4793eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
4803eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID *
4813eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI
4823eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangGlueAllocateZeroPool (
4833eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN  AllocationSize
4843eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
4853eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
4863eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  return InternalAllocateZeroPool (EfiBootServicesData, AllocationSize);
4873eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
4883eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
4893eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
4903eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates and zeros a buffer of type EfiRuntimeServicesData.
4913eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
4923eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the
4933eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  buffer with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a
4943eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  valid buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the
4953eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  request, then NULL is returned.
4963eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
4973eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  AllocationSize        The number of bytes to allocate and zero.
4983eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
4993eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @return A pointer to the allocated buffer or NULL if allocation fails.
5003eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
5013eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
5023eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID *
5033eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI
5043eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangAllocateRuntimeZeroPool (
5053eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN  AllocationSize
5063eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
5073eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
5083eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);
5093eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
5103eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
5113eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
5123eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates and zeros a buffer of type EfiReservedMemoryType.
5133eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
5143eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the
5153eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  buffer with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a
5163eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  valid buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the
5173eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  request, then NULL is returned.
5183eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
5193eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  AllocationSize        The number of bytes to allocate and zero.
5203eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
5213eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @return A pointer to the allocated buffer or NULL if allocation fails.
5223eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
5233eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
5243eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID *
5253eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI
5263eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangAllocateReservedZeroPool (
5273eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN  AllocationSize
5283eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
5293eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
5303eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  return InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);
5313eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
5323eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
5333eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
5343eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Copies a buffer to an allocated buffer of a certian pool type.
5353eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
5363eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates the number bytes specified by AllocationSize of a certian pool type, copies
5373eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
5383eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
5393eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  is not enough memory remaining to satisfy the request, then NULL is returned.
5403eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  If Buffer is NULL, then ASSERT().
5413eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  If AllocationSize is greater than (MAX_ADDRESS ? Buffer + 1), then ASSERT().
5423eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
5433eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  PoolType              The type of pool to allocate.
5443eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  AllocationSize        The number of bytes to allocate and zero.
5453eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Buffer                The buffer to copy to the allocated buffer.
5463eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
5473eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @return A pointer to the allocated buffer or NULL if allocation fails.
5483eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
5493eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
5503eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID *
5513eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangInternalAllocateCopyPool (
5523eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN EFI_MEMORY_TYPE  PoolType,
5533eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN            AllocationSize,
5543eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN CONST VOID       *Buffer
5553eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
5563eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
5573eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  VOID  *Memory;
5583eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
5593eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  ASSERT (Buffer != NULL);
5603eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
5613eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
5623eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Memory = InternalAllocatePool (PoolType, AllocationSize);
5633eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  if (Memory != NULL) {
5643eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang     Memory = CopyMem (Memory, Buffer, AllocationSize);
5653eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  }
5663eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  return Memory;
5673eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
5683eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
5693eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
5703eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Copies a buffer to an allocated buffer of type EfiBootServicesData.
5713eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
5723eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies
5733eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
5743eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
5753eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  is not enough memory remaining to satisfy the request, then NULL is returned.
5763eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  If Buffer is NULL, then ASSERT().
5773eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  If AllocationSize is greater than (MAX_ADDRESS ? Buffer + 1), then ASSERT().
5783eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
5793eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  AllocationSize        The number of bytes to allocate and zero.
5803eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Buffer                The buffer to copy to the allocated buffer.
5813eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
5823eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @return A pointer to the allocated buffer or NULL if allocation fails.
5833eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
5843eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
5853eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID *
5863eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI
5873eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangGlueAllocateCopyPool (
5883eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN       AllocationSize,
5893eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN CONST VOID  *Buffer
5903eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
5913eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
5923eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  return InternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer);
5933eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
5943eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
5953eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
5963eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
5973eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
5983eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies
5993eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
6003eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
6013eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  is not enough memory remaining to satisfy the request, then NULL is returned.
6023eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  If Buffer is NULL, then ASSERT().
6033eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  If AllocationSize is greater than (MAX_ADDRESS ? Buffer + 1), then ASSERT().
6043eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
6053eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  AllocationSize        The number of bytes to allocate and zero.
6063eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Buffer                The buffer to copy to the allocated buffer.
6073eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
6083eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @return A pointer to the allocated buffer or NULL if allocation fails.
6093eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
6103eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
6113eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID *
6123eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI
6133eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangAllocateRuntimeCopyPool (
6143eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN       AllocationSize,
6153eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN CONST VOID  *Buffer
6163eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
6173eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
6183eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);
6193eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
6203eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
6213eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
6223eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
6233eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
6243eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies
6253eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
6263eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
6273eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  is not enough memory remaining to satisfy the request, then NULL is returned.
6283eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  If Buffer is NULL, then ASSERT().
6293eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  If AllocationSize is greater than (MAX_ADDRESS ? Buffer + 1), then ASSERT().
6303eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
6313eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  AllocationSize        The number of bytes to allocate and zero.
6323eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Buffer                The buffer to copy to the allocated buffer.
6333eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
6343eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @return A pointer to the allocated buffer or NULL if allocation fails.
6353eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
6363eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
6373eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID *
6383eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI
6393eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangAllocateReservedCopyPool (
6403eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN       AllocationSize,
6413eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN CONST VOID  *Buffer
6423eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
6433eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
6443eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);
6453eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
6463eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
6473eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
6483eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Frees a buffer that was previously allocated with one of the pool allocation functions in the
6493eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Memory Allocation Library.
6503eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
6513eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Frees the buffer specified by Buffer.  Buffer must have been allocated on a previous call to the
6523eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  pool allocation services of the Memory Allocation Library.
6533eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
6543eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  then ASSERT().
6553eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
6563eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Buffer                Pointer to the buffer to free.
6573eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
6583eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
6593eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID
6603eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI
6613eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangGlueFreePool (
6623eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN VOID   *Buffer
6633eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
6643eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
6653eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  EFI_STATUS    Status;
6663eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
6673eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Status = (gBS->FreePool) (Buffer);
6683eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  ASSERT_EFI_ERROR (Status);
6693eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
6703eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
6713eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
6723eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates a buffer of a certain pool type at a specified alignment.
6733eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
6743eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates the number bytes specified by AllocationSize of a certain pool type with an alignment
6753eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  specified by Alignment.  The allocated buffer is returned.  If AllocationSize is 0, then a valid
6763eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  buffer of 0 size is returned.  If there is not enough memory at the specified alignment remaining
6773eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  to satisfy the request, then NULL is returned.
6783eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
6793eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
6803eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  PoolType              The type of pool to allocate.
6813eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  AllocationSize        The number of bytes to allocate.
6823eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.                            If Alignment is zero, then byte alignment is used.
6833eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang                                If Alignment is zero, then byte alignment is used.
6843eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
6853eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @return A pointer to the allocated buffer or NULL if allocation fails.
6863eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
6873eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
6883eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID *
6893eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangInternalAllocateAlignedPool (
6903eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN EFI_MEMORY_TYPE  PoolType,
6913eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN            AllocationSize,
6923eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN            Alignment
6933eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
6943eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
6953eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  VOID        *RawAddress;
6963eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  UINTN       AlignedAddress;
6973eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  UINTN       AlignmentMask;
6983eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  UINTN       OverAllocationSize;
6993eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  UINTN       RealAllocationSize;
7003eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  VOID        **FreePointer;
7013eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
7023eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  //
7033eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  // Alignment must be a power of two or zero.
7043eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  //
7053eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  ASSERT ((Alignment & (Alignment - 1)) == 0);
7063eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
7073eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  if (Alignment == 0) {
7083eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    AlignmentMask = Alignment;
7093eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  } else {
7103eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    AlignmentMask = Alignment - 1;
7113eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  }
7123eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  //
7133eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  // Calculate the extra memory size, over-allocate memory pool and get the aligned memory address.
7143eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  //
7153eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  OverAllocationSize  = sizeof (RawAddress) + AlignmentMask;
7163eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  RealAllocationSize  = AllocationSize + OverAllocationSize;
7173eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  //
7183eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  // Make sure that AllocationSize plus OverAllocationSize does not overflow.
7193eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  //
7203eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  ASSERT (RealAllocationSize > AllocationSize);
7213eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
7223eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  RawAddress = InternalAllocatePool (PoolType, RealAllocationSize);
7233eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  if (RawAddress == NULL) {
7243eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    return NULL;
7253eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  }
7263eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  AlignedAddress      = ((UINTN) RawAddress + OverAllocationSize) & ~AlignmentMask;
7273eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  //
7283eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  // Save the original memory address just before the aligned address.
7293eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  //
7303eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  FreePointer         = (VOID **)(AlignedAddress - sizeof (RawAddress));
7313eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  *FreePointer        = RawAddress;
7323eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
7333eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  return (VOID *) AlignedAddress;
7343eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
7353eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
7363eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
7373eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates a buffer of type EfiBootServicesData at a specified alignment.
7383eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
7393eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData with an
7403eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  alignment specified by Alignment.  The allocated buffer is returned.  If AllocationSize is 0,
7413eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  then a valid buffer of 0 size is returned.  If there is not enough memory at the specified
7423eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  alignment remaining to satisfy the request, then NULL is returned.
7433eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
7443eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
7453eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  AllocationSize        The number of bytes to allocate.
7463eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
7473eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang                                If Alignment is zero, then byte alignment is used.
7483eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
7493eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @return A pointer to the allocated buffer or NULL if allocation fails.
7503eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
7513eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
7523eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID *
7533eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI
7543eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangAllocateAlignedPool (
7553eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN  AllocationSize,
7563eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN  Alignment
7573eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
7583eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
7593eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  return InternalAllocateAlignedPool (EfiBootServicesData, AllocationSize, Alignment);
7603eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
7613eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
7623eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
7633eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates a buffer of type EfiRuntimeServicesData at a specified alignment.
7643eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
7653eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData with an
7663eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  alignment specified by Alignment.  The allocated buffer is returned.  If AllocationSize is 0,
7673eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  then a valid buffer of 0 size is returned.  If there is not enough memory at the specified
7683eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  alignment remaining to satisfy the request, then NULL is returned.
7693eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
7703eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
7713eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  AllocationSize        The number of bytes to allocate.
7723eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
7733eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang                                If Alignment is zero, then byte alignment is used.
7743eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
7753eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @return A pointer to the allocated buffer or NULL if allocation fails.
7763eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
7773eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
7783eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID *
7793eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI
7803eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangAllocateAlignedRuntimePool (
7813eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN  AllocationSize,
7823eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN  Alignment
7833eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
7843eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
7853eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  return InternalAllocateAlignedPool (EfiRuntimeServicesData, AllocationSize, Alignment);
7863eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
7873eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
7883eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
7893eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates a buffer of type EfieservedMemoryType at a specified alignment.
7903eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
7913eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates the number bytes specified by AllocationSize of type EfieservedMemoryType with an
7923eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  alignment specified by Alignment.  The allocated buffer is returned.  If AllocationSize is 0,
7933eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  then a valid buffer of 0 size is returned.  If there is not enough memory at the specified
7943eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  alignment remaining to satisfy the request, then NULL is returned.
7953eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
7963eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
7973eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  AllocationSize        The number of bytes to allocate.
7983eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
7993eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang                                If Alignment is zero, then byte alignment is used.
8003eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
8013eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @return A pointer to the allocated buffer or NULL if allocation fails.
8023eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
8033eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
8043eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID *
8053eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI
8063eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangAllocateAlignedReservedPool (
8073eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN  AllocationSize,
8083eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN  Alignment
8093eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
8103eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
8113eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  return InternalAllocateAlignedPool (EfiReservedMemoryType, AllocationSize, Alignment);
8123eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
8133eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
8143eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
8153eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates and zeros a buffer of a certain pool type at a specified alignment.
8163eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
8173eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates the number bytes specified by AllocationSize of a certain pool type with an alignment
8183eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  specified by Alignment, clears the buffer with zeros, and returns a pointer to the allocated
8193eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there is not
8203eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.
8213eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
8223eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
8233eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  PoolType              The type of pool to allocate.
8243eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  AllocationSize        The number of bytes to allocate.
8253eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
8263eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang                                If Alignment is zero, then byte alignment is used.
8273eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
8283eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @return A pointer to the allocated buffer or NULL if allocation fails.
8293eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
8303eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
8313eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID *
8323eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangInternalAllocateAlignedZeroPool (
8333eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN EFI_MEMORY_TYPE  PoolType,
8343eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN            AllocationSize,
8353eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN            Alignment
8363eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
8373eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
8383eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  VOID    *Memory;
8393eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Memory = InternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);
8403eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  if (Memory != NULL) {
8413eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    Memory = ZeroMem (Memory, AllocationSize);
8423eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  }
8433eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  return Memory;
8443eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
8453eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
8463eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
8473eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates and zeros a buffer of type EfiBootServicesData at a specified alignment.
8483eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
8493eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData with an
8503eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  alignment specified by Alignment, clears the buffer with zeros, and returns a pointer to the
8513eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
8523eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  is not enough memory at the specified alignment remaining to satisfy the request, then NULL is
8533eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  returned.
8543eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
8553eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
8563eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  AllocationSize        The number of bytes to allocate.
8573eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
8583eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang                                If Alignment is zero, then byte alignment is used.
8593eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
8603eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @return A pointer to the allocated buffer or NULL if allocation fails.
8613eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
8623eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
8633eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID *
8643eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI
8653eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangAllocateAlignedZeroPool (
8663eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN  AllocationSize,
8673eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN  Alignment
8683eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
8693eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
8703eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  return InternalAllocateAlignedZeroPool (EfiBootServicesData, AllocationSize, Alignment);
8713eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
8723eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
8733eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
8743eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates and zeros a buffer of type EfiRuntimeServicesData at a specified alignment.
8753eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
8763eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData with an
8773eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  alignment specified by Alignment, clears the buffer with zeros, and returns a pointer to the
8783eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
8793eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  is not enough memory at the specified alignment remaining to satisfy the request, then NULL is
8803eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  returned.
8813eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
8823eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
8833eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  AllocationSize        The number of bytes to allocate.
8843eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
8853eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang                                If Alignment is zero, then byte alignment is used.
8863eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
8873eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @return A pointer to the allocated buffer or NULL if allocation fails.
8883eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
8893eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
8903eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID *
8913eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI
8923eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangAllocateAlignedRuntimeZeroPool (
8933eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN  AllocationSize,
8943eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN  Alignment
8953eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
8963eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
8973eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  return InternalAllocateAlignedZeroPool (EfiRuntimeServicesData, AllocationSize, Alignment);
8983eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
8993eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
9003eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
9013eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates and zeros a buffer of type EfieservedMemoryType at a specified alignment.
9023eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
9033eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates the number bytes specified by AllocationSize of type EfieservedMemoryType with an
9043eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  alignment specified by Alignment, clears the buffer with zeros, and returns a pointer to the
9053eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
9063eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  is not enough memory at the specified alignment remaining to satisfy the request, then NULL is
9073eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  returned.
9083eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
9093eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
9103eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  AllocationSize        The number of bytes to allocate.
9113eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
9123eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang                                If Alignment is zero, then byte alignment is used.
9133eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
9143eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @return A pointer to the allocated buffer or NULL if allocation fails.
9153eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
9163eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
9173eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID *
9183eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI
9193eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangAllocateAlignedReservedZeroPool (
9203eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN  AllocationSize,
9213eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN  Alignment
9223eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
9233eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
9243eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  return InternalAllocateAlignedZeroPool (EfiReservedMemoryType, AllocationSize, Alignment);
9253eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
9263eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
9273eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
9283eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Copies a buffer to an allocated buffer of a certain pool type at a specified alignment.
9293eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
9303eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates the number bytes specified by AllocationSize of a certain pool type with an alignment
9313eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  specified by Alignment.  The allocated buffer is returned.  If AllocationSize is 0, then a valid
9323eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  buffer of 0 size is returned.  If there is not enough memory at the specified alignment remaining
9333eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  to satisfy the request, then NULL is returned.
9343eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
9353eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
9363eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  PoolType              The type of pool to allocate.
9373eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  AllocationSize        The number of bytes to allocate.
9383eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Buffer                The buffer to copy to the allocated buffer.
9393eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
9403eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang                                If Alignment is zero, then byte alignment is used.
9413eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
9423eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @return A pointer to the allocated buffer or NULL if allocation fails.
9433eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
9443eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
9453eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID *
9463eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangInternalAllocateAlignedCopyPool (
9473eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN EFI_MEMORY_TYPE  PoolType,
9483eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN            AllocationSize,
9493eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN CONST VOID       *Buffer,
9503eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN            Alignment
9513eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
9523eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
9533eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  VOID  *Memory;
9543eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
9553eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  ASSERT (Buffer != NULL);
9563eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
9573eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
9583eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Memory = InternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);
9593eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  if (Memory != NULL) {
9603eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    Memory = CopyMem (Memory, Buffer, AllocationSize);
9613eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  }
9623eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  return Memory;
9633eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
9643eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
9653eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
9663eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Copies a buffer to an allocated buffer of type EfiBootServicesData at a specified alignment.
9673eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
9683eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData type with an
9693eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  alignment specified by Alignment.  The allocated buffer is returned.  If AllocationSize is 0,
9703eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  then a valid buffer of 0 size is returned.  If there is not enough memory at the specified
9713eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  alignment remaining to satisfy the request, then NULL is returned.
9723eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
9733eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
9743eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  AllocationSize        The number of bytes to allocate.
9753eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Buffer                The buffer to copy to the allocated buffer.
9763eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
9773eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang                                If Alignment is zero, then byte alignment is used.
9783eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
9793eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @return A pointer to the allocated buffer or NULL if allocation fails.
9803eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
9813eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
9823eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID *
9833eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI
9843eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangAllocateAlignedCopyPool (
9853eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN       AllocationSize,
9863eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN CONST VOID  *Buffer,
9873eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN       Alignment
9883eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
9893eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
9903eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  return InternalAllocateAlignedCopyPool (EfiBootServicesData, AllocationSize, Buffer, Alignment);
9913eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
9923eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
9933eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
9943eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Copies a buffer to an allocated buffer of type EfiRuntimeServicesData at a specified alignment.
9953eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
9963eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData type with an
9973eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  alignment specified by Alignment.  The allocated buffer is returned.  If AllocationSize is 0,
9983eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  then a valid buffer of 0 size is returned.  If there is not enough memory at the specified
9993eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  alignment remaining to satisfy the request, then NULL is returned.
10003eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
10013eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
10023eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  AllocationSize        The number of bytes to allocate.
10033eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Buffer                The buffer to copy to the allocated buffer.
10043eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
10053eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang                                If Alignment is zero, then byte alignment is used.
10063eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
10073eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @return A pointer to the allocated buffer or NULL if allocation fails.
10083eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
10093eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
10103eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID *
10113eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI
10123eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangAllocateAlignedRuntimeCopyPool (
10133eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN       AllocationSize,
10143eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN CONST VOID  *Buffer,
10153eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN       Alignment
10163eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
10173eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
10183eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  return InternalAllocateAlignedCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer, Alignment);
10193eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
10203eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
10213eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
10223eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Copies a buffer to an allocated buffer of type EfiReservedMemoryType at a specified alignment.
10233eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
10243eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType type with an
10253eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  alignment specified by Alignment.  The allocated buffer is returned.  If AllocationSize is 0,
10263eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  then a valid buffer of 0 size is returned.  If there is not enough memory at the specified
10273eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  alignment remaining to satisfy the request, then NULL is returned.
10283eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
10293eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
10303eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  AllocationSize        The number of bytes to allocate.
10313eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Buffer                The buffer to copy to the allocated buffer.
10323eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
10333eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang                                If Alignment is zero, then byte alignment is used.
10343eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
10353eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @return A pointer to the allocated buffer or NULL if allocation fails.
10363eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
10373eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
10383eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID *
10393eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI
10403eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangAllocateAlignedReservedCopyPool (
10413eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN       AllocationSize,
10423eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN CONST VOID  *Buffer,
10433eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN       Alignment
10443eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
10453eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
10463eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  return InternalAllocateAlignedCopyPool (EfiReservedMemoryType, AllocationSize, Buffer, Alignment);
10473eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
10483eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
10493eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/**
10503eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Frees a buffer that was previously allocated with one of the aligned pool allocation functions
10513eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  in the Memory Allocation Library.
10523eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
10533eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Frees the buffer specified by Buffer.  Buffer must have been allocated on a previous call to the
10543eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  aligned pool allocation services of the Memory Allocation Library.
10553eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  If Buffer was not allocated with an aligned pool allocation function in the Memory Allocation
10563eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Library, then ASSERT().
10573eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
10583eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  @param  Buffer                Pointer to the buffer to free.
10593eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
10603eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang**/
10613eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID
10623eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEFIAPI
10633eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangFreeAlignedPool (
10643eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN VOID   *Buffer
10653eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
10663eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
10673eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  VOID        *RawAddress;
10683eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  VOID        **FreePointer;
10693eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  EFI_STATUS  Status;
10703eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
10713eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  //
10723eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  // Get the pre-saved original address in the over-allocate pool.
10733eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  //
10743eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  FreePointer = (VOID **)((UINTN) Buffer - sizeof (RawAddress));
10753eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  RawAddress  = *FreePointer;
10763eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
10773eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  Status = (gBS->FreePool) (RawAddress);
10783eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  ASSERT_EFI_ERROR (Status);
10793eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
1080