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 <PiDxe.h>
18
19
20#include <Library/MemoryAllocationLib.h>
21#include <Library/BaseMemoryLib.h>
22#include <Library/DebugLib.h>
23#include "DxeCoreMemoryAllocationServices.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**/
38VOID *
39InternalAllocatePages (
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 = CoreAllocatePages (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**/
71VOID *
72EFIAPI
73AllocatePages (
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**/
93VOID *
94EFIAPI
95AllocateRuntimePages (
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**/
115VOID *
116EFIAPI
117AllocateReservedPages (
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                Pointer to the buffer of pages to free.
138  @param  Pages                 The number of 4 KB pages to free.
139
140**/
141VOID
142EFIAPI
143FreePages (
144  IN VOID   *Buffer,
145  IN UINTN  Pages
146  )
147{
148  EFI_STATUS  Status;
149
150  ASSERT (Pages != 0);
151  Status = CoreFreePages ((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**/
173VOID *
174InternalAllocateAlignedPages (
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         = CoreAllocatePages (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 = CoreFreePages (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 = CoreFreePages (Memory, UnalignedPages);
226      ASSERT_EFI_ERROR (Status);
227    }
228  } else {
229    //
230    // Do not over-allocate pages in this case.
231    //
232    Status = CoreAllocatePages (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**/
259VOID *
260EFIAPI
261AllocateAlignedPages (
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**/
287VOID *
288EFIAPI
289AllocateAlignedRuntimePages (
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**/
315VOID *
316EFIAPI
317AllocateAlignedReservedPages (
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                Pointer to the buffer of pages to free.
339  @param  Pages                 The number of 4 KB pages to free.
340
341**/
342VOID
343EFIAPI
344FreeAlignedPages (
345  IN VOID   *Buffer,
346  IN UINTN  Pages
347  )
348{
349  EFI_STATUS  Status;
350
351  ASSERT (Pages != 0);
352  Status = CoreFreePages ((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**/
369VOID *
370InternalAllocatePool (
371  IN EFI_MEMORY_TYPE  MemoryType,
372  IN UINTN            AllocationSize
373  )
374{
375  EFI_STATUS  Status;
376  VOID        *Memory;
377
378  Memory = NULL;
379
380  Status = CoreAllocatePool (MemoryType, AllocationSize, &Memory);
381  if (EFI_ERROR (Status)) {
382    Memory = NULL;
383  }
384  return Memory;
385}
386
387/**
388  Allocates a buffer of type EfiBootServicesData.
389
390  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a
391  pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
392  returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
393
394  @param  AllocationSize        The number of bytes to allocate.
395
396  @return A pointer to the allocated buffer or NULL if allocation fails.
397
398**/
399VOID *
400EFIAPI
401AllocatePool (
402  IN UINTN  AllocationSize
403  )
404{
405  return InternalAllocatePool (EfiBootServicesData, AllocationSize);
406}
407
408/**
409  Allocates a buffer of type EfiRuntimeServicesData.
410
411  Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns
412  a pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
413  returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
414
415  @param  AllocationSize        The number of bytes to allocate.
416
417  @return A pointer to the allocated buffer or NULL if allocation fails.
418
419**/
420VOID *
421EFIAPI
422AllocateRuntimePool (
423  IN UINTN  AllocationSize
424  )
425{
426  return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
427}
428
429/**
430  Allocates a buffer of type EfiReservedMemoryType.
431
432  Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns
433  a pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
434  returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
435
436  @param  AllocationSize        The number of bytes to allocate.
437
438  @return A pointer to the allocated buffer or NULL if allocation fails.
439
440**/
441VOID *
442EFIAPI
443AllocateReservedPool (
444  IN UINTN  AllocationSize
445  )
446{
447  return InternalAllocatePool (EfiReservedMemoryType, AllocationSize);
448}
449
450/**
451  Allocates and zeros a buffer of a certain pool type.
452
453  Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer
454  with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a valid
455  buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the request,
456  then NULL is returned.
457
458  @param  PoolType              The type of memory to allocate.
459  @param  AllocationSize        The number of bytes to allocate and zero.
460
461  @return A pointer to the allocated buffer or NULL if allocation fails.
462
463**/
464VOID *
465InternalAllocateZeroPool (
466  IN EFI_MEMORY_TYPE  PoolType,
467  IN UINTN            AllocationSize
468  )
469{
470  VOID  *Memory;
471
472  Memory = InternalAllocatePool (PoolType, AllocationSize);
473  if (Memory != NULL) {
474    Memory = ZeroMem (Memory, AllocationSize);
475  }
476  return Memory;
477}
478
479/**
480  Allocates and zeros a buffer of type EfiBootServicesData.
481
482  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
483  buffer with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a
484  valid buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the
485  request, then NULL is returned.
486
487  @param  AllocationSize        The number of bytes to allocate and zero.
488
489  @return A pointer to the allocated buffer or NULL if allocation fails.
490
491**/
492VOID *
493EFIAPI
494AllocateZeroPool (
495  IN UINTN  AllocationSize
496  )
497{
498  return InternalAllocateZeroPool (EfiBootServicesData, AllocationSize);
499}
500
501/**
502  Allocates and zeros a buffer of type EfiRuntimeServicesData.
503
504  Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the
505  buffer with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a
506  valid buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the
507  request, then NULL is returned.
508
509  @param  AllocationSize        The number of bytes to allocate and zero.
510
511  @return A pointer to the allocated buffer or NULL if allocation fails.
512
513**/
514VOID *
515EFIAPI
516AllocateRuntimeZeroPool (
517  IN UINTN  AllocationSize
518  )
519{
520  return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);
521}
522
523/**
524  Allocates and zeros a buffer of type EfiReservedMemoryType.
525
526  Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the
527  buffer with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a
528  valid buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the
529  request, then NULL is returned.
530
531  @param  AllocationSize        The number of bytes to allocate and zero.
532
533  @return A pointer to the allocated buffer or NULL if allocation fails.
534
535**/
536VOID *
537EFIAPI
538AllocateReservedZeroPool (
539  IN UINTN  AllocationSize
540  )
541{
542  return InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);
543}
544
545/**
546  Copies a buffer to an allocated buffer of a certain pool type.
547
548  Allocates the number bytes specified by AllocationSize of a certain pool type, copies
549  AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
550  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
551  is not enough memory remaining to satisfy the request, then NULL is returned.
552  If Buffer is NULL, then ASSERT().
553  If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
554
555  @param  PoolType              The type of pool to allocate.
556  @param  AllocationSize        The number of bytes to allocate and zero.
557  @param  Buffer                The buffer to copy to the allocated buffer.
558
559  @return A pointer to the allocated buffer or NULL if allocation fails.
560
561**/
562VOID *
563InternalAllocateCopyPool (
564  IN EFI_MEMORY_TYPE  PoolType,
565  IN UINTN            AllocationSize,
566  IN CONST VOID       *Buffer
567  )
568{
569  VOID  *Memory;
570
571  ASSERT (Buffer != NULL);
572  ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
573
574  Memory = InternalAllocatePool (PoolType, AllocationSize);
575  if (Memory != NULL) {
576     Memory = CopyMem (Memory, Buffer, AllocationSize);
577  }
578  return Memory;
579}
580
581/**
582  Copies a buffer to an allocated buffer of type EfiBootServicesData.
583
584  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies
585  AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
586  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
587  is not enough memory remaining to satisfy the request, then NULL is returned.
588
589  If Buffer is NULL, then ASSERT().
590  If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
591
592  @param  AllocationSize        The number of bytes to allocate and zero.
593  @param  Buffer                The buffer to copy to the allocated buffer.
594
595  @return A pointer to the allocated buffer or NULL if allocation fails.
596
597**/
598VOID *
599EFIAPI
600AllocateCopyPool (
601  IN UINTN       AllocationSize,
602  IN CONST VOID  *Buffer
603  )
604{
605  return InternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer);
606}
607
608/**
609  Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
610
611  Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies
612  AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
613  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
614  is not enough memory remaining to satisfy the request, then NULL is returned.
615
616  If Buffer is NULL, then ASSERT().
617  If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
618
619  @param  AllocationSize        The number of bytes to allocate and zero.
620  @param  Buffer                The buffer to copy to the allocated buffer.
621
622  @return A pointer to the allocated buffer or NULL if allocation fails.
623
624**/
625VOID *
626EFIAPI
627AllocateRuntimeCopyPool (
628  IN UINTN       AllocationSize,
629  IN CONST VOID  *Buffer
630  )
631{
632  return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);
633}
634
635/**
636  Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
637
638  Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies
639  AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
640  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
641  is not enough memory remaining to satisfy the request, then NULL is returned.
642
643  If Buffer is NULL, then ASSERT().
644  If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
645
646  @param  AllocationSize        The number of bytes to allocate and zero.
647  @param  Buffer                The buffer to copy to the allocated buffer.
648
649  @return A pointer to the allocated buffer or NULL if allocation fails.
650
651**/
652VOID *
653EFIAPI
654AllocateReservedCopyPool (
655  IN UINTN       AllocationSize,
656  IN CONST VOID  *Buffer
657  )
658{
659  return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);
660}
661
662/**
663  Reallocates a buffer of a specified memory type.
664
665  Allocates and zeros the number bytes specified by NewSize from memory of the type
666  specified by PoolType.  If OldBuffer is not NULL, then the smaller of OldSize and
667  NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
668  OldBuffer is freed.  A pointer to the newly allocated buffer is returned.
669  If NewSize is 0, then a valid buffer of 0 size is  returned.  If there is not
670  enough memory remaining to satisfy the request, then NULL is returned.
671
672  If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
673  is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
674
675  @param  PoolType       The type of pool to allocate.
676  @param  OldSize        The size, in bytes, of OldBuffer.
677  @param  NewSize        The size, in bytes, of the buffer to reallocate.
678  @param  OldBuffer      The buffer to copy to the allocated buffer.  This is an optional
679                         parameter that may be NULL.
680
681  @return A pointer to the allocated buffer or NULL if allocation fails.
682
683**/
684VOID *
685InternalReallocatePool (
686  IN EFI_MEMORY_TYPE  PoolType,
687  IN UINTN            OldSize,
688  IN UINTN            NewSize,
689  IN VOID             *OldBuffer  OPTIONAL
690  )
691{
692  VOID  *NewBuffer;
693
694  NewBuffer = InternalAllocateZeroPool (PoolType, NewSize);
695  if (NewBuffer != NULL && OldBuffer != NULL) {
696    CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize));
697    FreePool (OldBuffer);
698  }
699  return NewBuffer;
700}
701
702/**
703  Reallocates a buffer of type EfiBootServicesData.
704
705  Allocates and zeros the number bytes specified by NewSize from memory of type
706  EfiBootServicesData.  If OldBuffer is not NULL, then the smaller of OldSize and
707  NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
708  OldBuffer is freed.  A pointer to the newly allocated buffer is returned.
709  If NewSize is 0, then a valid buffer of 0 size is  returned.  If there is not
710  enough memory remaining to satisfy the request, then NULL is returned.
711
712  If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
713  is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
714
715  @param  OldSize        The size, in bytes, of OldBuffer.
716  @param  NewSize        The size, in bytes, of the buffer to reallocate.
717  @param  OldBuffer      The buffer to copy to the allocated buffer.  This is an optional
718                         parameter that may be NULL.
719
720  @return A pointer to the allocated buffer or NULL if allocation fails.
721
722**/
723VOID *
724EFIAPI
725ReallocatePool (
726  IN UINTN  OldSize,
727  IN UINTN  NewSize,
728  IN VOID   *OldBuffer  OPTIONAL
729  )
730{
731  return InternalReallocatePool (EfiBootServicesData, OldSize, NewSize, OldBuffer);
732}
733
734/**
735  Reallocates a buffer of type EfiRuntimeServicesData.
736
737  Allocates and zeros the number bytes specified by NewSize from memory of type
738  EfiRuntimeServicesData.  If OldBuffer is not NULL, then the smaller of OldSize and
739  NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
740  OldBuffer is freed.  A pointer to the newly allocated buffer is returned.
741  If NewSize is 0, then a valid buffer of 0 size is  returned.  If there is not
742  enough memory remaining to satisfy the request, then NULL is returned.
743
744  If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
745  is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
746
747  @param  OldSize        The size, in bytes, of OldBuffer.
748  @param  NewSize        The size, in bytes, of the buffer to reallocate.
749  @param  OldBuffer      The buffer to copy to the allocated buffer.  This is an optional
750                         parameter that may be NULL.
751
752  @return A pointer to the allocated buffer or NULL if allocation fails.
753
754**/
755VOID *
756EFIAPI
757ReallocateRuntimePool (
758  IN UINTN  OldSize,
759  IN UINTN  NewSize,
760  IN VOID   *OldBuffer  OPTIONAL
761  )
762{
763  return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer);
764}
765
766/**
767  Reallocates a buffer of type EfiReservedMemoryType.
768
769  Allocates and zeros the number bytes specified by NewSize from memory of type
770  EfiReservedMemoryType.  If OldBuffer is not NULL, then the smaller of OldSize and
771  NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
772  OldBuffer is freed.  A pointer to the newly allocated buffer is returned.
773  If NewSize is 0, then a valid buffer of 0 size is  returned.  If there is not
774  enough memory remaining to satisfy the request, then NULL is returned.
775
776  If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
777  is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
778
779  @param  OldSize        The size, in bytes, of OldBuffer.
780  @param  NewSize        The size, in bytes, of the buffer to reallocate.
781  @param  OldBuffer      The buffer to copy to the allocated buffer.  This is an optional
782                         parameter that may be NULL.
783
784  @return A pointer to the allocated buffer or NULL if allocation fails.
785
786**/
787VOID *
788EFIAPI
789ReallocateReservedPool (
790  IN UINTN  OldSize,
791  IN UINTN  NewSize,
792  IN VOID   *OldBuffer  OPTIONAL
793  )
794{
795  return InternalReallocatePool (EfiReservedMemoryType, OldSize, NewSize, OldBuffer);
796}
797
798/**
799  Frees a buffer that was previously allocated with one of the pool allocation functions in the
800  Memory Allocation Library.
801
802  Frees the buffer specified by Buffer.  Buffer must have been allocated on a previous call to the
803  pool allocation services of the Memory Allocation Library.  If it is not possible to free pool
804  resources, then this function will perform no actions.
805
806  If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
807  then ASSERT().
808
809  @param  Buffer                Pointer to the buffer to free.
810
811**/
812VOID
813EFIAPI
814FreePool (
815  IN VOID   *Buffer
816  )
817{
818  EFI_STATUS    Status;
819
820  Status = CoreFreePool (Buffer);
821  ASSERT_EFI_ERROR (Status);
822}
823
824