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