1/** @file
2  Support routines for memory allocation routines based
3  on boot services for Dxe phase drivers.
4
5  Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
6  This program and the accompanying materials
7  are licensed and made available under the terms and conditions of the BSD License
8  which accompanies this distribution.  The full text of the license may be found at
9  http://opensource.org/licenses/bsd-license.php.
10
11  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14**/
15
16
17#include <Uefi.h>
18
19
20#include <Library/MemoryAllocationLib.h>
21#include <Library/UefiBootServicesTableLib.h>
22#include <Library/BaseMemoryLib.h>
23#include <Library/DebugLib.h>
24
25/**
26  Allocates one or more 4KB pages of a certain memory type.
27
28  Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated
29  buffer.  The buffer returned is aligned on a 4KB boundary.  If Pages is 0, then NULL is returned.
30  If there is not enough memory remaining to satisfy the request, then NULL is returned.
31
32  @param  MemoryType            The type of memory to allocate.
33  @param  Pages                 The number of 4 KB pages to allocate.
34
35  @return A pointer to the allocated buffer or NULL if allocation fails.
36
37**/
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 = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);
52  if (EFI_ERROR (Status)) {
53    return NULL;
54  }
55  return (VOID *) (UINTN) Memory;
56}
57
58/**
59  Allocates one or more 4KB pages of type EfiBootServicesData.
60
61  Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the
62  allocated buffer.  The buffer returned is aligned on a 4KB boundary.  If Pages is 0, then NULL
63  is returned.  If there is not enough memory remaining to satisfy the request, then NULL is
64  returned.
65
66  @param  Pages                 The number of 4 KB pages to allocate.
67
68  @return A pointer to the allocated buffer or NULL if allocation fails.
69
70**/
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                The 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 = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
152  ASSERT_EFI_ERROR (Status);
153}
154
155/**
156  Allocates one or more 4KB pages of a certain memory type at a specified alignment.
157
158  Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment
159  specified by Alignment.  The allocated buffer is returned.  If Pages is 0, then NULL is returned.
160  If there is not enough memory at the specified alignment remaining to satisfy the request, then
161  NULL is returned.
162  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
163  If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
164
165  @param  MemoryType            The type of memory to allocate.
166  @param  Pages                 The number of 4 KB pages to allocate.
167  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
168                                If Alignment is zero, then byte alignment is used.
169
170  @return A pointer to the allocated buffer or NULL if allocation fails.
171
172**/
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         = gBS->AllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory);
207    if (EFI_ERROR (Status)) {
208      return NULL;
209    }
210    AlignedMemory  = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask;
211    UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN) Memory);
212    if (UnalignedPages > 0) {
213      //
214      // Free first unaligned page(s).
215      //
216      Status = gBS->FreePages (Memory, UnalignedPages);
217      ASSERT_EFI_ERROR (Status);
218    }
219    Memory         = (EFI_PHYSICAL_ADDRESS) (AlignedMemory + EFI_PAGES_TO_SIZE (Pages));
220    UnalignedPages = RealPages - Pages - UnalignedPages;
221    if (UnalignedPages > 0) {
222      //
223      // Free last unaligned page(s).
224      //
225      Status = gBS->FreePages (Memory, UnalignedPages);
226      ASSERT_EFI_ERROR (Status);
227    }
228  } else {
229    //
230    // Do not over-allocate pages in this case.
231    //
232    Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);
233    if (EFI_ERROR (Status)) {
234      return NULL;
235    }
236    AlignedMemory  = (UINTN) Memory;
237  }
238  return (VOID *) AlignedMemory;
239}
240
241/**
242  Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment.
243
244  Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an
245  alignment specified by Alignment.  The allocated buffer is returned.  If Pages is 0, then NULL is
246  returned.  If there is not enough memory at the specified alignment remaining to satisfy the
247  request, then NULL is returned.
248
249  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
250  If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
251
252  @param  Pages                 The number of 4 KB pages to allocate.
253  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
254                                If Alignment is zero, then byte alignment is used.
255
256  @return A pointer to the allocated buffer or NULL if allocation fails.
257
258**/
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                The 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 = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
353  ASSERT_EFI_ERROR (Status);
354}
355
356/**
357  Allocates a buffer of a certain pool type.
358
359  Allocates the number bytes specified by AllocationSize of a certain pool type and returns a
360  pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
361  returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
362
363  @param  MemoryType            The type of memory to allocate.
364  @param  AllocationSize        The number of bytes to allocate.
365
366  @return A pointer to the allocated buffer or NULL if allocation fails.
367
368**/
369VOID *
370InternalAllocatePool (
371  IN EFI_MEMORY_TYPE  MemoryType,
372  IN UINTN            AllocationSize
373  )
374{
375  EFI_STATUS  Status;
376  VOID        *Memory;
377
378  Status = gBS->AllocatePool (MemoryType, AllocationSize, &Memory);
379  if (EFI_ERROR (Status)) {
380    Memory = NULL;
381  }
382  return Memory;
383}
384
385/**
386  Allocates a buffer of type EfiBootServicesData.
387
388  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a
389  pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
390  returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
391
392  @param  AllocationSize        The number of bytes to allocate.
393
394  @return A pointer to the allocated buffer or NULL if allocation fails.
395
396**/
397VOID *
398EFIAPI
399AllocatePool (
400  IN UINTN  AllocationSize
401  )
402{
403  return InternalAllocatePool (EfiBootServicesData, AllocationSize);
404}
405
406/**
407  Allocates a buffer of type EfiRuntimeServicesData.
408
409  Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns
410  a pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
411  returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
412
413  @param  AllocationSize        The number of bytes to allocate.
414
415  @return A pointer to the allocated buffer or NULL if allocation fails.
416
417**/
418VOID *
419EFIAPI
420AllocateRuntimePool (
421  IN UINTN  AllocationSize
422  )
423{
424  return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
425}
426
427/**
428  Allocates a buffer of type EfiReservedMemoryType.
429
430  Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns
431  a pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
432  returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
433
434  @param  AllocationSize        The number of bytes to allocate.
435
436  @return A pointer to the allocated buffer or NULL if allocation fails.
437
438**/
439VOID *
440EFIAPI
441AllocateReservedPool (
442  IN UINTN  AllocationSize
443  )
444{
445  return InternalAllocatePool (EfiReservedMemoryType, AllocationSize);
446}
447
448/**
449  Allocates and zeros a buffer of a certain pool type.
450
451  Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer
452  with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a valid
453  buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the request,
454  then NULL is returned.
455
456  @param  PoolType              The type of memory to allocate.
457  @param  AllocationSize        The number of bytes to allocate and zero.
458
459  @return A pointer to the allocated buffer or NULL if allocation fails.
460
461**/
462VOID *
463InternalAllocateZeroPool (
464  IN EFI_MEMORY_TYPE  PoolType,
465  IN UINTN            AllocationSize
466  )
467{
468  VOID  *Memory;
469
470  Memory = InternalAllocatePool (PoolType, AllocationSize);
471  if (Memory != NULL) {
472    Memory = ZeroMem (Memory, AllocationSize);
473  }
474  return Memory;
475}
476
477/**
478  Allocates and zeros a buffer of type EfiBootServicesData.
479
480  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
481  buffer with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a
482  valid buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the
483  request, then NULL is returned.
484
485  @param  AllocationSize        The number of bytes to allocate and zero.
486
487  @return A pointer to the allocated buffer or NULL if allocation fails.
488
489**/
490VOID *
491EFIAPI
492AllocateZeroPool (
493  IN UINTN  AllocationSize
494  )
495{
496  return InternalAllocateZeroPool (EfiBootServicesData, AllocationSize);
497}
498
499/**
500  Allocates and zeros a buffer of type EfiRuntimeServicesData.
501
502  Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the
503  buffer with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a
504  valid buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the
505  request, then NULL is returned.
506
507  @param  AllocationSize        The number of bytes to allocate and zero.
508
509  @return A pointer to the allocated buffer or NULL if allocation fails.
510
511**/
512VOID *
513EFIAPI
514AllocateRuntimeZeroPool (
515  IN UINTN  AllocationSize
516  )
517{
518  return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);
519}
520
521/**
522  Allocates and zeros a buffer of type EfiReservedMemoryType.
523
524  Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the
525  buffer with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a
526  valid buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the
527  request, then NULL is returned.
528
529  @param  AllocationSize        The number of bytes to allocate and zero.
530
531  @return A pointer to the allocated buffer or NULL if allocation fails.
532
533**/
534VOID *
535EFIAPI
536AllocateReservedZeroPool (
537  IN UINTN  AllocationSize
538  )
539{
540  return InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);
541}
542
543/**
544  Copies a buffer to an allocated buffer of a certain pool type.
545
546  Allocates the number bytes specified by AllocationSize of a certain pool type, copies
547  AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
548  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
549  is not enough memory remaining to satisfy the request, then NULL is returned.
550  If Buffer is NULL, then ASSERT().
551  If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
552
553  @param  PoolType              The type of pool to allocate.
554  @param  AllocationSize        The number of bytes to allocate and zero.
555  @param  Buffer                The buffer to copy to the allocated buffer.
556
557  @return A pointer to the allocated buffer or NULL if allocation fails.
558
559**/
560VOID *
561InternalAllocateCopyPool (
562  IN EFI_MEMORY_TYPE  PoolType,
563  IN UINTN            AllocationSize,
564  IN CONST VOID       *Buffer
565  )
566{
567  VOID  *Memory;
568
569  ASSERT (Buffer != NULL);
570  ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
571
572  Memory = InternalAllocatePool (PoolType, AllocationSize);
573  if (Memory != NULL) {
574     Memory = CopyMem (Memory, Buffer, AllocationSize);
575  }
576  return Memory;
577}
578
579/**
580  Copies a buffer to an allocated buffer of type EfiBootServicesData.
581
582  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies
583  AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
584  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
585  is not enough memory remaining to satisfy the request, then NULL is returned.
586
587  If Buffer is NULL, then ASSERT().
588  If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
589
590  @param  AllocationSize        The number of bytes to allocate and zero.
591  @param  Buffer                The buffer to copy to the allocated buffer.
592
593  @return A pointer to the allocated buffer or NULL if allocation fails.
594
595**/
596VOID *
597EFIAPI
598AllocateCopyPool (
599  IN UINTN       AllocationSize,
600  IN CONST VOID  *Buffer
601  )
602{
603  return InternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer);
604}
605
606/**
607  Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
608
609  Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies
610  AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
611  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
612  is not enough memory remaining to satisfy the request, then NULL is returned.
613
614  If Buffer is NULL, then ASSERT().
615  If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
616
617  @param  AllocationSize        The number of bytes to allocate and zero.
618  @param  Buffer                The buffer to copy to the allocated buffer.
619
620  @return A pointer to the allocated buffer or NULL if allocation fails.
621
622**/
623VOID *
624EFIAPI
625AllocateRuntimeCopyPool (
626  IN UINTN       AllocationSize,
627  IN CONST VOID  *Buffer
628  )
629{
630  return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);
631}
632
633/**
634  Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
635
636  Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies
637  AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
638  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
639  is not enough memory remaining to satisfy the request, then NULL is returned.
640
641  If Buffer is NULL, then ASSERT().
642  If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
643
644  @param  AllocationSize        The number of bytes to allocate and zero.
645  @param  Buffer                The buffer to copy to the allocated buffer.
646
647  @return A pointer to the allocated buffer or NULL if allocation fails.
648
649**/
650VOID *
651EFIAPI
652AllocateReservedCopyPool (
653  IN UINTN       AllocationSize,
654  IN CONST VOID  *Buffer
655  )
656{
657  return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);
658}
659
660/**
661  Reallocates a buffer of a specified memory type.
662
663  Allocates and zeros the number bytes specified by NewSize from memory of the type
664  specified by PoolType.  If OldBuffer is not NULL, then the smaller of OldSize and
665  NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
666  OldBuffer is freed.  A pointer to the newly allocated buffer is returned.
667  If NewSize is 0, then a valid buffer of 0 size is  returned.  If there is not
668  enough memory remaining to satisfy the request, then NULL is returned.
669
670  If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
671  is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
672
673  @param  PoolType       The type of pool to allocate.
674  @param  OldSize        The size, in bytes, of OldBuffer.
675  @param  NewSize        The size, in bytes, of the buffer to reallocate.
676  @param  OldBuffer      The buffer to copy to the allocated buffer.  This is an optional
677                         parameter that may be NULL.
678
679  @return A pointer to the allocated buffer or NULL if allocation fails.
680
681**/
682VOID *
683InternalReallocatePool (
684  IN EFI_MEMORY_TYPE  PoolType,
685  IN UINTN            OldSize,
686  IN UINTN            NewSize,
687  IN VOID             *OldBuffer  OPTIONAL
688  )
689{
690  VOID  *NewBuffer;
691
692  NewBuffer = InternalAllocateZeroPool (PoolType, NewSize);
693  if (NewBuffer != NULL && OldBuffer != NULL) {
694    CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize));
695    FreePool (OldBuffer);
696  }
697  return NewBuffer;
698}
699
700/**
701  Reallocates a buffer of type EfiBootServicesData.
702
703  Allocates and zeros the number bytes specified by NewSize from memory of type
704  EfiBootServicesData.  If OldBuffer is not NULL, then the smaller of OldSize and
705  NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
706  OldBuffer is freed.  A pointer to the newly allocated buffer is returned.
707  If NewSize is 0, then a valid buffer of 0 size is  returned.  If there is not
708  enough memory remaining to satisfy the request, then NULL is returned.
709
710  If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
711  is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
712
713  @param  OldSize        The size, in bytes, of OldBuffer.
714  @param  NewSize        The size, in bytes, of the buffer to reallocate.
715  @param  OldBuffer      The buffer to copy to the allocated buffer.  This is an optional
716                         parameter that may be NULL.
717
718  @return A pointer to the allocated buffer or NULL if allocation fails.
719
720**/
721VOID *
722EFIAPI
723ReallocatePool (
724  IN UINTN  OldSize,
725  IN UINTN  NewSize,
726  IN VOID   *OldBuffer  OPTIONAL
727  )
728{
729  return InternalReallocatePool (EfiBootServicesData, OldSize, NewSize, OldBuffer);
730}
731
732/**
733  Reallocates a buffer of type EfiRuntimeServicesData.
734
735  Allocates and zeros the number bytes specified by NewSize from memory of type
736  EfiRuntimeServicesData.  If OldBuffer is not NULL, then the smaller of OldSize and
737  NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
738  OldBuffer is freed.  A pointer to the newly allocated buffer is returned.
739  If NewSize is 0, then a valid buffer of 0 size is  returned.  If there is not
740  enough memory remaining to satisfy the request, then NULL is returned.
741
742  If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
743  is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
744
745  @param  OldSize        The size, in bytes, of OldBuffer.
746  @param  NewSize        The size, in bytes, of the buffer to reallocate.
747  @param  OldBuffer      The buffer to copy to the allocated buffer.  This is an optional
748                         parameter that may be NULL.
749
750  @return A pointer to the allocated buffer or NULL if allocation fails.
751
752**/
753VOID *
754EFIAPI
755ReallocateRuntimePool (
756  IN UINTN  OldSize,
757  IN UINTN  NewSize,
758  IN VOID   *OldBuffer  OPTIONAL
759  )
760{
761  return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer);
762}
763
764/**
765  Reallocates a buffer of type EfiReservedMemoryType.
766
767  Allocates and zeros the number bytes specified by NewSize from memory of type
768  EfiReservedMemoryType.  If OldBuffer is not NULL, then the smaller of OldSize and
769  NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
770  OldBuffer is freed.  A pointer to the newly allocated buffer is returned.
771  If NewSize is 0, then a valid buffer of 0 size is  returned.  If there is not
772  enough memory remaining to satisfy the request, then NULL is returned.
773
774  If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
775  is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
776
777  @param  OldSize        The size, in bytes, of OldBuffer.
778  @param  NewSize        The size, in bytes, of the buffer to reallocate.
779  @param  OldBuffer      The buffer to copy to the allocated buffer.  This is an optional
780                         parameter that may be NULL.
781
782  @return A pointer to the allocated buffer or NULL if allocation fails.
783
784**/
785VOID *
786EFIAPI
787ReallocateReservedPool (
788  IN UINTN  OldSize,
789  IN UINTN  NewSize,
790  IN VOID   *OldBuffer  OPTIONAL
791  )
792{
793  return InternalReallocatePool (EfiReservedMemoryType, OldSize, NewSize, OldBuffer);
794}
795
796/**
797  Frees a buffer that was previously allocated with one of the pool allocation functions in the
798  Memory Allocation Library.
799
800  Frees the buffer specified by Buffer.  Buffer must have been allocated on a previous call to the
801  pool allocation services of the Memory Allocation Library.  If it is not possible to free pool
802  resources, then this function will perform no actions.
803
804  If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
805  then ASSERT().
806
807  @param  Buffer                The pointer to the buffer to free.
808
809**/
810VOID
811EFIAPI
812FreePool (
813  IN VOID   *Buffer
814  )
815{
816  EFI_STATUS    Status;
817
818  Status = gBS->FreePool (Buffer);
819  ASSERT_EFI_ERROR (Status);
820}
821
822