]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/PeiMemoryAllocationLib/MemoryAllocationLib.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdePkg / Library / PeiMemoryAllocationLib / MemoryAllocationLib.c
1 /** @file
2 Support routines for memory allocation routines
3 based on PeiService for PEI 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 #include <PiPei.h>
11
12 #include <Library/MemoryAllocationLib.h>
13 #include <Library/PeiServicesLib.h>
14 #include <Library/BaseMemoryLib.h>
15 #include <Library/DebugLib.h>
16 #include <Library/HobLib.h>
17
18 /**
19 Allocates one or more 4KB pages of a certain memory type.
20
21 Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated
22 buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL is returned.
23 If there is not enough memory remaining to satisfy the request, then NULL is returned.
24
25 @param MemoryType The type of memory to allocate.
26 @param Pages The number of 4 KB pages to allocate.
27
28 @return A pointer to the allocated buffer or NULL if allocation fails.
29
30 **/
31 VOID *
32 InternalAllocatePages (
33 IN EFI_MEMORY_TYPE MemoryType,
34 IN UINTN Pages
35 )
36 {
37 EFI_STATUS Status;
38 EFI_PHYSICAL_ADDRESS Memory;
39
40 if (Pages == 0) {
41 return NULL;
42 }
43
44 Status = PeiServicesAllocatePages (MemoryType, Pages, &Memory);
45 if (EFI_ERROR (Status)) {
46 return NULL;
47 }
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
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
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
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
137 FreePages (
138 IN VOID *Buffer,
139 IN UINTN Pages
140 )
141 {
142 EFI_STATUS Status;
143
144 ASSERT (Pages != 0);
145 Status = PeiServicesFreePages ((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.
162 Must be a power of two.
163 If Alignment is zero, then byte alignment is used.
164
165 @return A pointer to the allocated buffer or NULL if allocation fails.
166
167 **/
168 VOID *
169 InternalAllocateAlignedPages (
170 IN EFI_MEMORY_TYPE MemoryType,
171 IN UINTN Pages,
172 IN UINTN Alignment
173 )
174 {
175 EFI_STATUS Status;
176 EFI_PHYSICAL_ADDRESS Memory;
177 UINTN AlignedMemory;
178 UINTN AlignmentMask;
179 UINTN UnalignedPages;
180 UINTN RealPages;
181
182 //
183 // Alignment must be a power of two or zero.
184 //
185 ASSERT ((Alignment & (Alignment - 1)) == 0);
186
187 if (Pages == 0) {
188 return NULL;
189 }
190
191 if (Alignment > EFI_PAGE_SIZE) {
192 //
193 // Calculate the total number of pages since alignment is larger than page size.
194 //
195 AlignmentMask = Alignment - 1;
196 RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment);
197 //
198 // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
199 //
200 ASSERT (RealPages > Pages);
201
202 Status = PeiServicesAllocatePages (MemoryType, RealPages, &Memory);
203 if (EFI_ERROR (Status)) {
204 return NULL;
205 }
206
207 AlignedMemory = ((UINTN)Memory + AlignmentMask) & ~AlignmentMask;
208 UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN)Memory);
209 if (UnalignedPages > 0) {
210 //
211 // Free first unaligned page(s).
212 //
213 Status = PeiServicesFreePages (Memory, UnalignedPages);
214 ASSERT_EFI_ERROR (Status);
215 }
216
217 Memory = AlignedMemory + EFI_PAGES_TO_SIZE (Pages);
218 UnalignedPages = RealPages - Pages - UnalignedPages;
219 if (UnalignedPages > 0) {
220 //
221 // Free last unaligned page(s).
222 //
223 Status = PeiServicesFreePages (Memory, UnalignedPages);
224 ASSERT_EFI_ERROR (Status);
225 }
226 } else {
227 //
228 // Do not over-allocate pages in this case.
229 //
230 Status = PeiServicesAllocatePages (MemoryType, Pages, &Memory);
231 if (EFI_ERROR (Status)) {
232 return NULL;
233 }
234
235 AlignedMemory = (UINTN)Memory;
236 }
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.
254 Must be a power of two.
255 If Alignment is zero, then byte alignment is used.
256
257 @return A pointer to the allocated buffer or NULL if allocation fails.
258
259 **/
260 VOID *
261 EFIAPI
262 AllocateAlignedPages (
263 IN UINTN Pages,
264 IN UINTN Alignment
265 )
266 {
267 return InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment);
268 }
269
270 /**
271 Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
272
273 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an
274 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
275 returned. If there is not enough memory at the specified alignment remaining to satisfy the
276 request, then NULL is returned.
277
278 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
279 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
280
281 @param Pages The number of 4 KB pages to allocate.
282 @param Alignment The requested alignment of the allocation.
283 Must be a power of two.
284 If Alignment is zero, then byte alignment is used.
285
286 @return A pointer to the allocated buffer or NULL if allocation fails.
287
288 **/
289 VOID *
290 EFIAPI
291 AllocateAlignedRuntimePages (
292 IN UINTN Pages,
293 IN UINTN Alignment
294 )
295 {
296 return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);
297 }
298
299 /**
300 Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
301
302 Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an
303 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
304 returned. If there is not enough memory at the specified alignment remaining to satisfy the
305 request, then NULL is returned.
306
307 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
308 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
309
310 @param Pages The number of 4 KB pages to allocate.
311 @param Alignment The requested alignment of the allocation.
312 Must be a power of two.
313 If Alignment is zero, then byte alignment is used.
314
315 @return A pointer to the allocated buffer or NULL if allocation fails.
316
317 **/
318 VOID *
319 EFIAPI
320 AllocateAlignedReservedPages (
321 IN UINTN Pages,
322 IN UINTN Alignment
323 )
324 {
325 return InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment);
326 }
327
328 /**
329 Frees one or more 4KB pages that were previously allocated with one of the aligned page
330 allocation functions in the Memory Allocation Library.
331
332 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
333 must have been allocated on a previous call to the aligned page allocation services of the Memory
334 Allocation Library. If it is not possible to free allocated pages, then this function will
335 perform no actions.
336
337 If Buffer was not allocated with an aligned page allocation function in the Memory Allocation
338 Library, then ASSERT().
339 If Pages is zero, then ASSERT().
340
341 @param Buffer The pointer to the buffer of pages to free.
342 @param Pages The number of 4 KB pages to free.
343
344 **/
345 VOID
346 EFIAPI
347 FreeAlignedPages (
348 IN VOID *Buffer,
349 IN UINTN Pages
350 )
351 {
352 EFI_STATUS Status;
353
354 ASSERT (Pages != 0);
355 Status = PeiServicesFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages);
356 ASSERT_EFI_ERROR (Status);
357 }
358
359 /**
360 Allocates a buffer of a certain pool type.
361
362 Allocates the number bytes specified by AllocationSize of a certain pool type and returns a
363 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
364 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
365
366 @param MemoryType The type of memory to allocate.
367 @param AllocationSize The number of bytes to allocate.
368
369 @return A pointer to the allocated buffer or NULL if allocation fails.
370
371 **/
372 VOID *
373 InternalAllocatePool (
374 IN EFI_MEMORY_TYPE MemoryType,
375 IN UINTN AllocationSize
376 )
377 {
378 //
379 // If we need lots of small runtime/reserved memory type from PEI in the future,
380 // we can consider providing a more complex algorithm that allocates runtime pages and
381 // provide pool allocations from those pages.
382 //
383 return InternalAllocatePages (MemoryType, EFI_SIZE_TO_PAGES (AllocationSize));
384 }
385
386 /**
387 Allocates a buffer of type EfiBootServicesData.
388
389 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a
390 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
391 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
392
393 @param AllocationSize The number of bytes to allocate.
394
395 @return A pointer to the allocated buffer or NULL if allocation fails.
396
397 **/
398 VOID *
399 EFIAPI
400 AllocatePool (
401 IN UINTN AllocationSize
402 )
403 {
404 EFI_STATUS Status;
405 VOID *Buffer;
406
407 Status = PeiServicesAllocatePool (AllocationSize, &Buffer);
408 if (EFI_ERROR (Status)) {
409 Buffer = NULL;
410 }
411
412 return Buffer;
413 }
414
415 /**
416 Allocates a buffer of type EfiRuntimeServicesData.
417
418 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns
419 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
420 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
421
422 @param AllocationSize The number of bytes to allocate.
423
424 @return A pointer to the allocated buffer or NULL if allocation fails.
425
426 **/
427 VOID *
428 EFIAPI
429 AllocateRuntimePool (
430 IN UINTN AllocationSize
431 )
432 {
433 return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
434 }
435
436 /**
437 Allocates a buffer of type EfiReservedMemoryType.
438
439 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns
440 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
441 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
442
443 @param AllocationSize The number of bytes to allocate.
444
445 @return A pointer to the allocated buffer or NULL if allocation fails.
446
447 **/
448 VOID *
449 EFIAPI
450 AllocateReservedPool (
451 IN UINTN AllocationSize
452 )
453 {
454 return InternalAllocatePool (EfiReservedMemoryType, AllocationSize);
455 }
456
457 /**
458 Allocates and zeros a buffer of a certain pool type.
459
460 Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer
461 with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid
462 buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request,
463 then NULL is returned.
464
465 @param PoolType The type of memory to allocate.
466 @param AllocationSize The number of bytes to allocate and zero.
467
468 @return A pointer to the allocated buffer or NULL if allocation fails.
469
470 **/
471 VOID *
472 InternalAllocateZeroPool (
473 IN EFI_MEMORY_TYPE PoolType,
474 IN UINTN AllocationSize
475 )
476 {
477 VOID *Memory;
478
479 Memory = InternalAllocatePool (PoolType, AllocationSize);
480 if (Memory != NULL) {
481 Memory = ZeroMem (Memory, AllocationSize);
482 }
483
484 return Memory;
485 }
486
487 /**
488 Allocates and zeros a buffer of type EfiBootServicesData.
489
490 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
491 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
492 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
493 request, then NULL is returned.
494
495 @param AllocationSize The number of bytes to allocate and zero.
496
497 @return A pointer to the allocated buffer or NULL if allocation fails.
498
499 **/
500 VOID *
501 EFIAPI
502 AllocateZeroPool (
503 IN UINTN AllocationSize
504 )
505 {
506 VOID *Memory;
507
508 Memory = AllocatePool (AllocationSize);
509 if (Memory != NULL) {
510 Memory = ZeroMem (Memory, AllocationSize);
511 }
512
513 return Memory;
514 }
515
516 /**
517 Allocates and zeros a buffer of type EfiRuntimeServicesData.
518
519 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the
520 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
521 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
522 request, then NULL is returned.
523
524 @param AllocationSize The number of bytes to allocate and zero.
525
526 @return A pointer to the allocated buffer or NULL if allocation fails.
527
528 **/
529 VOID *
530 EFIAPI
531 AllocateRuntimeZeroPool (
532 IN UINTN AllocationSize
533 )
534 {
535 return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);
536 }
537
538 /**
539 Allocates and zeros a buffer of type EfiReservedMemoryType.
540
541 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the
542 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
543 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
544 request, then NULL is returned.
545
546 @param AllocationSize The number of bytes to allocate and zero.
547
548 @return A pointer to the allocated buffer or NULL if allocation fails.
549
550 **/
551 VOID *
552 EFIAPI
553 AllocateReservedZeroPool (
554 IN UINTN AllocationSize
555 )
556 {
557 return InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);
558 }
559
560 /**
561 Copies a buffer to an allocated buffer of a certain pool type.
562
563 Allocates the number bytes specified by AllocationSize of a certain pool type, copies
564 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
565 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
566 is not enough memory remaining to satisfy the request, then NULL is returned.
567 If Buffer is NULL, then ASSERT().
568 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
569
570 @param PoolType The type of pool to allocate.
571 @param AllocationSize The number of bytes to allocate and zero.
572 @param Buffer The buffer to copy to the allocated buffer.
573
574 @return A pointer to the allocated buffer or NULL if allocation fails.
575
576 **/
577 VOID *
578 InternalAllocateCopyPool (
579 IN EFI_MEMORY_TYPE PoolType,
580 IN UINTN AllocationSize,
581 IN CONST VOID *Buffer
582 )
583 {
584 VOID *Memory;
585
586 ASSERT (Buffer != NULL);
587 ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN)Buffer + 1));
588
589 Memory = InternalAllocatePool (PoolType, AllocationSize);
590 if (Memory != NULL) {
591 Memory = CopyMem (Memory, Buffer, AllocationSize);
592 }
593
594 return Memory;
595 }
596
597 /**
598 Copies a buffer to an allocated buffer of type EfiBootServicesData.
599
600 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies
601 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
602 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
603 is not enough memory remaining to satisfy the request, then NULL is returned.
604
605 If Buffer is NULL, then ASSERT().
606 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
607
608 @param AllocationSize The number of bytes to allocate and zero.
609 @param Buffer The buffer to copy to the allocated buffer.
610
611 @return A pointer to the allocated buffer or NULL if allocation fails.
612
613 **/
614 VOID *
615 EFIAPI
616 AllocateCopyPool (
617 IN UINTN AllocationSize,
618 IN CONST VOID *Buffer
619 )
620 {
621 VOID *Memory;
622
623 ASSERT (Buffer != NULL);
624 ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN)Buffer + 1));
625
626 Memory = AllocatePool (AllocationSize);
627 if (Memory != NULL) {
628 Memory = CopyMem (Memory, Buffer, AllocationSize);
629 }
630
631 return Memory;
632 }
633
634 /**
635 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
636
637 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies
638 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
639 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
640 is not enough memory remaining to satisfy the request, then NULL is returned.
641
642 If Buffer is NULL, then ASSERT().
643 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
644
645 @param AllocationSize The number of bytes to allocate and zero.
646 @param Buffer The buffer to copy to the allocated buffer.
647
648 @return A pointer to the allocated buffer or NULL if allocation fails.
649
650 **/
651 VOID *
652 EFIAPI
653 AllocateRuntimeCopyPool (
654 IN UINTN AllocationSize,
655 IN CONST VOID *Buffer
656 )
657 {
658 return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);
659 }
660
661 /**
662 Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
663
664 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies
665 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
666 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
667 is not enough memory remaining to satisfy the request, then NULL is returned.
668
669 If Buffer is NULL, then ASSERT().
670 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
671
672 @param AllocationSize The number of bytes to allocate and zero.
673 @param Buffer The buffer to copy to the allocated buffer.
674
675 @return A pointer to the allocated buffer or NULL if allocation fails.
676
677 **/
678 VOID *
679 EFIAPI
680 AllocateReservedCopyPool (
681 IN UINTN AllocationSize,
682 IN CONST VOID *Buffer
683 )
684 {
685 return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);
686 }
687
688 /**
689 Reallocates a buffer of a specified memory type.
690
691 Allocates and zeros the number bytes specified by NewSize from memory of the type
692 specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and
693 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
694 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
695 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
696 enough memory remaining to satisfy the request, then NULL is returned.
697
698 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
699 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
700
701 @param PoolType The type of pool to allocate.
702 @param OldSize The size, in bytes, of OldBuffer.
703 @param NewSize The size, in bytes, of the buffer to reallocate.
704 @param OldBuffer The buffer to copy to the allocated buffer. This is an
705 optional parameter that may be NULL.
706
707 @return A pointer to the allocated buffer or NULL if allocation fails.
708
709 **/
710 VOID *
711 InternalReallocatePool (
712 IN EFI_MEMORY_TYPE PoolType,
713 IN UINTN OldSize,
714 IN UINTN NewSize,
715 IN VOID *OldBuffer OPTIONAL
716 )
717 {
718 VOID *NewBuffer;
719
720 NewBuffer = InternalAllocateZeroPool (PoolType, NewSize);
721 if ((NewBuffer != NULL) && (OldBuffer != NULL)) {
722 CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize));
723 FreePool (OldBuffer);
724 }
725
726 return NewBuffer;
727 }
728
729 /**
730 Reallocates a buffer of type EfiBootServicesData.
731
732 Allocates and zeros the number bytes specified by NewSize from memory of type
733 EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
734 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
735 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
736 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
737 enough memory remaining to satisfy the request, then NULL is returned.
738
739 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
740 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
741
742 @param OldSize The size, in bytes, of OldBuffer.
743 @param NewSize The size, in bytes, of the buffer to reallocate.
744 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
745 parameter that may be NULL.
746
747 @return A pointer to the allocated buffer or NULL if allocation fails.
748
749 **/
750 VOID *
751 EFIAPI
752 ReallocatePool (
753 IN UINTN OldSize,
754 IN UINTN NewSize,
755 IN VOID *OldBuffer OPTIONAL
756 )
757 {
758 return InternalReallocatePool (EfiBootServicesData, OldSize, NewSize, OldBuffer);
759 }
760
761 /**
762 Reallocates a buffer of type EfiRuntimeServicesData.
763
764 Allocates and zeros the number bytes specified by NewSize from memory of type
765 EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
766 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
767 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
768 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
769 enough memory remaining to satisfy the request, then NULL is returned.
770
771 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
772 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
773
774 @param OldSize The size, in bytes, of OldBuffer.
775 @param NewSize The size, in bytes, of the buffer to reallocate.
776 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
777 parameter that may be NULL.
778
779 @return A pointer to the allocated buffer or NULL if allocation fails.
780
781 **/
782 VOID *
783 EFIAPI
784 ReallocateRuntimePool (
785 IN UINTN OldSize,
786 IN UINTN NewSize,
787 IN VOID *OldBuffer OPTIONAL
788 )
789 {
790 return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer);
791 }
792
793 /**
794 Reallocates a buffer of type EfiReservedMemoryType.
795
796 Allocates and zeros the number bytes specified by NewSize from memory of type
797 EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and
798 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
799 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
800 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
801 enough memory remaining to satisfy the request, then NULL is returned.
802
803 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
804 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
805
806 @param OldSize The size, in bytes, of OldBuffer.
807 @param NewSize The size, in bytes, of the buffer to reallocate.
808 @param OldBuffer The buffer to copy to the allocated buffer. This is an
809 optional parameter that may be NULL.
810
811 @return A pointer to the allocated buffer or NULL if allocation fails.
812
813 **/
814 VOID *
815 EFIAPI
816 ReallocateReservedPool (
817 IN UINTN OldSize,
818 IN UINTN NewSize,
819 IN VOID *OldBuffer OPTIONAL
820 )
821 {
822 return InternalReallocatePool (EfiReservedMemoryType, OldSize, NewSize, OldBuffer);
823 }
824
825 /**
826 Frees a buffer that was previously allocated with one of the pool allocation functions in the
827 Memory Allocation Library.
828
829 Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the
830 pool allocation services of the Memory Allocation Library. If it is not possible to free pool
831 resources, then this function will perform no actions.
832
833 If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
834 then ASSERT().
835
836 @param Buffer The pointer to the buffer to free.
837
838 **/
839 VOID
840 EFIAPI
841 FreePool (
842 IN VOID *Buffer
843 )
844 {
845 //
846 // PEI phase does not support to free pool, so leave it as NOP.
847 //
848 }