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