]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Library/DxeCoreMemoryAllocationLib/MemoryAllocationLib.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Library / DxeCoreMemoryAllocationLib / MemoryAllocationLib.c
1 /** @file
2 Support routines for memory allocation routines based
3 on DxeCore Memory Allocation services for DxeCore,
4 with memory profile support.
5
6 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
7 SPDX-License-Identifier: BSD-2-Clause-Patent
8
9 **/
10
11 #include <PiDxe.h>
12
13 #include <Library/MemoryAllocationLib.h>
14 #include <Library/BaseMemoryLib.h>
15 #include <Library/DebugLib.h>
16 #include "DxeCoreMemoryAllocationServices.h"
17
18 #include <Library/MemoryProfileLib.h>
19
20 /**
21 Allocates one or more 4KB pages of a certain memory type.
22
23 Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated
24 buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL is returned.
25 If there is not enough memory remaining to satisfy the request, then NULL is returned.
26
27 @param MemoryType The type of memory to allocate.
28 @param Pages The number of 4 KB pages to allocate.
29
30 @return A pointer to the allocated buffer or NULL if allocation fails.
31
32 **/
33 VOID *
34 InternalAllocatePages (
35 IN EFI_MEMORY_TYPE MemoryType,
36 IN UINTN Pages
37 )
38 {
39 EFI_STATUS Status;
40 EFI_PHYSICAL_ADDRESS Memory;
41
42 if (Pages == 0) {
43 return NULL;
44 }
45
46 Status = CoreAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);
47 if (EFI_ERROR (Status)) {
48 return NULL;
49 }
50
51 return (VOID *)(UINTN)Memory;
52 }
53
54 /**
55 Allocates one or more 4KB pages of type EfiBootServicesData.
56
57 Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the
58 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
59 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
60 returned.
61
62 @param Pages The number of 4 KB pages to allocate.
63
64 @return A pointer to the allocated buffer or NULL if allocation fails.
65
66 **/
67 VOID *
68 EFIAPI
69 AllocatePages (
70 IN UINTN Pages
71 )
72 {
73 VOID *Buffer;
74
75 Buffer = InternalAllocatePages (EfiBootServicesData, Pages);
76 if (Buffer != NULL) {
77 MemoryProfileLibRecord (
78 (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
79 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_PAGES,
80 EfiBootServicesData,
81 Buffer,
82 EFI_PAGES_TO_SIZE (Pages),
83 NULL
84 );
85 }
86
87 return Buffer;
88 }
89
90 /**
91 Allocates one or more 4KB pages of type EfiRuntimeServicesData.
92
93 Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
94 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
95 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
96 returned.
97
98 @param Pages The number of 4 KB pages to allocate.
99
100 @return A pointer to the allocated buffer or NULL if allocation fails.
101
102 **/
103 VOID *
104 EFIAPI
105 AllocateRuntimePages (
106 IN UINTN Pages
107 )
108 {
109 VOID *Buffer;
110
111 Buffer = InternalAllocatePages (EfiRuntimeServicesData, Pages);
112 if (Buffer != NULL) {
113 MemoryProfileLibRecord (
114 (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
115 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_PAGES,
116 EfiRuntimeServicesData,
117 Buffer,
118 EFI_PAGES_TO_SIZE (Pages),
119 NULL
120 );
121 }
122
123 return Buffer;
124 }
125
126 /**
127 Allocates one or more 4KB pages of type EfiReservedMemoryType.
128
129 Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the
130 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
131 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
132 returned.
133
134 @param Pages The number of 4 KB pages to allocate.
135
136 @return A pointer to the allocated buffer or NULL if allocation fails.
137
138 **/
139 VOID *
140 EFIAPI
141 AllocateReservedPages (
142 IN UINTN Pages
143 )
144 {
145 VOID *Buffer;
146
147 Buffer = InternalAllocatePages (EfiReservedMemoryType, Pages);
148 if (Buffer != NULL) {
149 MemoryProfileLibRecord (
150 (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
151 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_PAGES,
152 EfiReservedMemoryType,
153 Buffer,
154 EFI_PAGES_TO_SIZE (Pages),
155 NULL
156 );
157 }
158
159 return Buffer;
160 }
161
162 /**
163 Frees one or more 4KB pages that were previously allocated with one of the page allocation
164 functions in the Memory Allocation Library.
165
166 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
167 must have been allocated on a previous call to the page allocation services of the Memory
168 Allocation Library. If it is not possible to free allocated pages, then this function will
169 perform no actions.
170
171 If Buffer was not allocated with a page allocation function in the Memory Allocation Library,
172 then ASSERT().
173 If Pages is zero, then ASSERT().
174
175 @param Buffer Pointer to the buffer of pages to free.
176 @param Pages The number of 4 KB pages to free.
177
178 **/
179 VOID
180 EFIAPI
181 FreePages (
182 IN VOID *Buffer,
183 IN UINTN Pages
184 )
185 {
186 EFI_STATUS Status;
187
188 ASSERT (Pages != 0);
189 Status = CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages);
190 ASSERT_EFI_ERROR (Status);
191 }
192
193 /**
194 Allocates one or more 4KB pages of a certain memory type at a specified alignment.
195
196 Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment
197 specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned.
198 If there is not enough memory at the specified alignment remaining to satisfy the request, then
199 NULL is returned.
200 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
201 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
202
203 @param MemoryType The type of memory to allocate.
204 @param Pages The number of 4 KB pages to allocate.
205 @param Alignment The requested alignment of the allocation. Must be a power of two.
206 If Alignment is zero, then byte alignment is used.
207
208 @return A pointer to the allocated buffer or NULL if allocation fails.
209
210 **/
211 VOID *
212 InternalAllocateAlignedPages (
213 IN EFI_MEMORY_TYPE MemoryType,
214 IN UINTN Pages,
215 IN UINTN Alignment
216 )
217 {
218 EFI_STATUS Status;
219 EFI_PHYSICAL_ADDRESS Memory;
220 UINTN AlignedMemory;
221 UINTN AlignmentMask;
222 UINTN UnalignedPages;
223 UINTN RealPages;
224
225 //
226 // Alignment must be a power of two or zero.
227 //
228 ASSERT ((Alignment & (Alignment - 1)) == 0);
229
230 if (Pages == 0) {
231 return NULL;
232 }
233
234 if (Alignment > EFI_PAGE_SIZE) {
235 //
236 // Calculate the total number of pages since alignment is larger than page size.
237 //
238 AlignmentMask = Alignment - 1;
239 RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment);
240 //
241 // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
242 //
243 ASSERT (RealPages > Pages);
244
245 Status = CoreAllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory);
246 if (EFI_ERROR (Status)) {
247 return NULL;
248 }
249
250 AlignedMemory = ((UINTN)Memory + AlignmentMask) & ~AlignmentMask;
251 UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN)Memory);
252 if (UnalignedPages > 0) {
253 //
254 // Free first unaligned page(s).
255 //
256 Status = CoreFreePages (Memory, UnalignedPages);
257 ASSERT_EFI_ERROR (Status);
258 }
259
260 Memory = AlignedMemory + EFI_PAGES_TO_SIZE (Pages);
261 UnalignedPages = RealPages - Pages - UnalignedPages;
262 if (UnalignedPages > 0) {
263 //
264 // Free last unaligned page(s).
265 //
266 Status = CoreFreePages (Memory, UnalignedPages);
267 ASSERT_EFI_ERROR (Status);
268 }
269 } else {
270 //
271 // Do not over-allocate pages in this case.
272 //
273 Status = CoreAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);
274 if (EFI_ERROR (Status)) {
275 return NULL;
276 }
277
278 AlignedMemory = (UINTN)Memory;
279 }
280
281 return (VOID *)AlignedMemory;
282 }
283
284 /**
285 Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment.
286
287 Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an
288 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
289 returned. If there is not enough memory at the specified alignment remaining to satisfy the
290 request, then NULL is returned.
291
292 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
293 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
294
295 @param Pages The number of 4 KB pages to allocate.
296 @param Alignment The requested alignment of the allocation. Must be a power of two.
297 If Alignment is zero, then byte alignment is used.
298
299 @return A pointer to the allocated buffer or NULL if allocation fails.
300
301 **/
302 VOID *
303 EFIAPI
304 AllocateAlignedPages (
305 IN UINTN Pages,
306 IN UINTN Alignment
307 )
308 {
309 VOID *Buffer;
310
311 Buffer = InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment);
312 if (Buffer != NULL) {
313 MemoryProfileLibRecord (
314 (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
315 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_PAGES,
316 EfiBootServicesData,
317 Buffer,
318 EFI_PAGES_TO_SIZE (Pages),
319 NULL
320 );
321 }
322
323 return Buffer;
324 }
325
326 /**
327 Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
328
329 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an
330 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
331 returned. If there is not enough memory at the specified alignment remaining to satisfy the
332 request, then NULL is returned.
333
334 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
335 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
336
337 @param Pages The number of 4 KB pages to allocate.
338 @param Alignment The requested alignment of the allocation. Must be a power of two.
339 If Alignment is zero, then byte alignment is used.
340
341 @return A pointer to the allocated buffer or NULL if allocation fails.
342
343 **/
344 VOID *
345 EFIAPI
346 AllocateAlignedRuntimePages (
347 IN UINTN Pages,
348 IN UINTN Alignment
349 )
350 {
351 VOID *Buffer;
352
353 Buffer = InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);
354 if (Buffer != NULL) {
355 MemoryProfileLibRecord (
356 (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
357 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RUNTIME_PAGES,
358 EfiRuntimeServicesData,
359 Buffer,
360 EFI_PAGES_TO_SIZE (Pages),
361 NULL
362 );
363 }
364
365 return Buffer;
366 }
367
368 /**
369 Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
370
371 Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an
372 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
373 returned. If there is not enough memory at the specified alignment remaining to satisfy the
374 request, then NULL is returned.
375
376 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
377 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
378
379 @param Pages The number of 4 KB pages to allocate.
380 @param Alignment The requested alignment of the allocation. Must be a power of two.
381 If Alignment is zero, then byte alignment is used.
382
383 @return A pointer to the allocated buffer or NULL if allocation fails.
384
385 **/
386 VOID *
387 EFIAPI
388 AllocateAlignedReservedPages (
389 IN UINTN Pages,
390 IN UINTN Alignment
391 )
392 {
393 VOID *Buffer;
394
395 Buffer = InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment);
396 if (Buffer != NULL) {
397 MemoryProfileLibRecord (
398 (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
399 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RESERVED_PAGES,
400 EfiReservedMemoryType,
401 Buffer,
402 EFI_PAGES_TO_SIZE (Pages),
403 NULL
404 );
405 }
406
407 return Buffer;
408 }
409
410 /**
411 Frees one or more 4KB pages that were previously allocated with one of the aligned page
412 allocation functions in the Memory Allocation Library.
413
414 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
415 must have been allocated on a previous call to the aligned page allocation services of the Memory
416 Allocation Library. If it is not possible to free allocated pages, then this function will
417 perform no actions.
418
419 If Buffer was not allocated with an aligned page allocation function in the Memory Allocation
420 Library, then ASSERT().
421 If Pages is zero, then ASSERT().
422
423 @param Buffer Pointer to the buffer of pages to free.
424 @param Pages The number of 4 KB pages to free.
425
426 **/
427 VOID
428 EFIAPI
429 FreeAlignedPages (
430 IN VOID *Buffer,
431 IN UINTN Pages
432 )
433 {
434 EFI_STATUS Status;
435
436 ASSERT (Pages != 0);
437 Status = CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages);
438 ASSERT_EFI_ERROR (Status);
439 }
440
441 /**
442 Allocates a buffer of a certain pool type.
443
444 Allocates the number bytes specified by AllocationSize of a certain pool type and returns a
445 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
446 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
447
448 @param MemoryType The type of memory to allocate.
449 @param AllocationSize The number of bytes to allocate.
450
451 @return A pointer to the allocated buffer or NULL if allocation fails.
452
453 **/
454 VOID *
455 InternalAllocatePool (
456 IN EFI_MEMORY_TYPE MemoryType,
457 IN UINTN AllocationSize
458 )
459 {
460 EFI_STATUS Status;
461 VOID *Memory;
462
463 Memory = NULL;
464
465 Status = CoreAllocatePool (MemoryType, AllocationSize, &Memory);
466 if (EFI_ERROR (Status)) {
467 Memory = NULL;
468 }
469
470 return Memory;
471 }
472
473 /**
474 Allocates a buffer of type EfiBootServicesData.
475
476 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a
477 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
478 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
479
480 @param AllocationSize The number of bytes to allocate.
481
482 @return A pointer to the allocated buffer or NULL if allocation fails.
483
484 **/
485 VOID *
486 EFIAPI
487 AllocatePool (
488 IN UINTN AllocationSize
489 )
490 {
491 VOID *Buffer;
492
493 Buffer = InternalAllocatePool (EfiBootServicesData, AllocationSize);
494 if (Buffer != NULL) {
495 MemoryProfileLibRecord (
496 (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
497 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_POOL,
498 EfiBootServicesData,
499 Buffer,
500 AllocationSize,
501 NULL
502 );
503 }
504
505 return Buffer;
506 }
507
508 /**
509 Allocates a buffer of type EfiRuntimeServicesData.
510
511 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns
512 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
513 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
514
515 @param AllocationSize The number of bytes to allocate.
516
517 @return A pointer to the allocated buffer or NULL if allocation fails.
518
519 **/
520 VOID *
521 EFIAPI
522 AllocateRuntimePool (
523 IN UINTN AllocationSize
524 )
525 {
526 VOID *Buffer;
527
528 Buffer = InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
529 if (Buffer != NULL) {
530 MemoryProfileLibRecord (
531 (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
532 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_POOL,
533 EfiRuntimeServicesData,
534 Buffer,
535 AllocationSize,
536 NULL
537 );
538 }
539
540 return Buffer;
541 }
542
543 /**
544 Allocates a buffer of type EfiReservedMemoryType.
545
546 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns
547 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
548 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
549
550 @param AllocationSize The number of bytes to allocate.
551
552 @return A pointer to the allocated buffer or NULL if allocation fails.
553
554 **/
555 VOID *
556 EFIAPI
557 AllocateReservedPool (
558 IN UINTN AllocationSize
559 )
560 {
561 VOID *Buffer;
562
563 Buffer = InternalAllocatePool (EfiReservedMemoryType, AllocationSize);
564 if (Buffer != NULL) {
565 MemoryProfileLibRecord (
566 (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
567 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_POOL,
568 EfiReservedMemoryType,
569 Buffer,
570 AllocationSize,
571 NULL
572 );
573 }
574
575 return Buffer;
576 }
577
578 /**
579 Allocates and zeros a buffer of a certain pool type.
580
581 Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer
582 with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid
583 buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request,
584 then NULL is returned.
585
586 @param PoolType The type of memory to allocate.
587 @param AllocationSize The number of bytes to allocate and zero.
588
589 @return A pointer to the allocated buffer or NULL if allocation fails.
590
591 **/
592 VOID *
593 InternalAllocateZeroPool (
594 IN EFI_MEMORY_TYPE PoolType,
595 IN UINTN AllocationSize
596 )
597 {
598 VOID *Memory;
599
600 Memory = InternalAllocatePool (PoolType, AllocationSize);
601 if (Memory != NULL) {
602 Memory = ZeroMem (Memory, AllocationSize);
603 }
604
605 return Memory;
606 }
607
608 /**
609 Allocates and zeros a buffer of type EfiBootServicesData.
610
611 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
612 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
613 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
614 request, then NULL is returned.
615
616 @param AllocationSize The number of bytes to allocate and zero.
617
618 @return A pointer to the allocated buffer or NULL if allocation fails.
619
620 **/
621 VOID *
622 EFIAPI
623 AllocateZeroPool (
624 IN UINTN AllocationSize
625 )
626 {
627 VOID *Buffer;
628
629 Buffer = InternalAllocateZeroPool (EfiBootServicesData, AllocationSize);
630 if (Buffer != NULL) {
631 MemoryProfileLibRecord (
632 (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
633 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ZERO_POOL,
634 EfiBootServicesData,
635 Buffer,
636 AllocationSize,
637 NULL
638 );
639 }
640
641 return Buffer;
642 }
643
644 /**
645 Allocates and zeros a buffer of type EfiRuntimeServicesData.
646
647 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the
648 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
649 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
650 request, then NULL is returned.
651
652 @param AllocationSize The number of bytes to allocate and zero.
653
654 @return A pointer to the allocated buffer or NULL if allocation fails.
655
656 **/
657 VOID *
658 EFIAPI
659 AllocateRuntimeZeroPool (
660 IN UINTN AllocationSize
661 )
662 {
663 VOID *Buffer;
664
665 Buffer = InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);
666 if (Buffer != NULL) {
667 MemoryProfileLibRecord (
668 (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
669 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_ZERO_POOL,
670 EfiRuntimeServicesData,
671 Buffer,
672 AllocationSize,
673 NULL
674 );
675 }
676
677 return Buffer;
678 }
679
680 /**
681 Allocates and zeros a buffer of type EfiReservedMemoryType.
682
683 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the
684 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
685 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
686 request, then NULL is returned.
687
688 @param AllocationSize The number of bytes to allocate and zero.
689
690 @return A pointer to the allocated buffer or NULL if allocation fails.
691
692 **/
693 VOID *
694 EFIAPI
695 AllocateReservedZeroPool (
696 IN UINTN AllocationSize
697 )
698 {
699 VOID *Buffer;
700
701 Buffer = InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);
702 if (Buffer != NULL) {
703 MemoryProfileLibRecord (
704 (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
705 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_ZERO_POOL,
706 EfiReservedMemoryType,
707 Buffer,
708 AllocationSize,
709 NULL
710 );
711 }
712
713 return Buffer;
714 }
715
716 /**
717 Copies a buffer to an allocated buffer of a certain pool type.
718
719 Allocates the number bytes specified by AllocationSize of a certain pool type, copies
720 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
721 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
722 is not enough memory remaining to satisfy the request, then NULL is returned.
723 If Buffer is NULL, then ASSERT().
724 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
725
726 @param PoolType The type of pool to allocate.
727 @param AllocationSize The number of bytes to allocate and zero.
728 @param Buffer The buffer to copy to the allocated buffer.
729
730 @return A pointer to the allocated buffer or NULL if allocation fails.
731
732 **/
733 VOID *
734 InternalAllocateCopyPool (
735 IN EFI_MEMORY_TYPE PoolType,
736 IN UINTN AllocationSize,
737 IN CONST VOID *Buffer
738 )
739 {
740 VOID *Memory;
741
742 ASSERT (Buffer != NULL);
743 ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN)Buffer + 1));
744
745 Memory = InternalAllocatePool (PoolType, AllocationSize);
746 if (Memory != NULL) {
747 Memory = CopyMem (Memory, Buffer, AllocationSize);
748 }
749
750 return Memory;
751 }
752
753 /**
754 Copies a buffer to an allocated buffer of type EfiBootServicesData.
755
756 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies
757 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
758 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
759 is not enough memory remaining to satisfy the request, then NULL is returned.
760
761 If Buffer is NULL, then ASSERT().
762 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
763
764 @param AllocationSize The number of bytes to allocate and zero.
765 @param Buffer The buffer to copy to the allocated buffer.
766
767 @return A pointer to the allocated buffer or NULL if allocation fails.
768
769 **/
770 VOID *
771 EFIAPI
772 AllocateCopyPool (
773 IN UINTN AllocationSize,
774 IN CONST VOID *Buffer
775 )
776 {
777 VOID *NewBuffer;
778
779 NewBuffer = InternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer);
780 if (NewBuffer != NULL) {
781 MemoryProfileLibRecord (
782 (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
783 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_COPY_POOL,
784 EfiBootServicesData,
785 NewBuffer,
786 AllocationSize,
787 NULL
788 );
789 }
790
791 return NewBuffer;
792 }
793
794 /**
795 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
796
797 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies
798 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
799 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
800 is not enough memory remaining to satisfy the request, then NULL is returned.
801
802 If Buffer is NULL, then ASSERT().
803 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
804
805 @param AllocationSize The number of bytes to allocate and zero.
806 @param Buffer The buffer to copy to the allocated buffer.
807
808 @return A pointer to the allocated buffer or NULL if allocation fails.
809
810 **/
811 VOID *
812 EFIAPI
813 AllocateRuntimeCopyPool (
814 IN UINTN AllocationSize,
815 IN CONST VOID *Buffer
816 )
817 {
818 VOID *NewBuffer;
819
820 NewBuffer = InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);
821 if (NewBuffer != NULL) {
822 MemoryProfileLibRecord (
823 (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
824 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_COPY_POOL,
825 EfiRuntimeServicesData,
826 NewBuffer,
827 AllocationSize,
828 NULL
829 );
830 }
831
832 return NewBuffer;
833 }
834
835 /**
836 Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
837
838 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies
839 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
840 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
841 is not enough memory remaining to satisfy the request, then NULL is returned.
842
843 If Buffer is NULL, then ASSERT().
844 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
845
846 @param AllocationSize The number of bytes to allocate and zero.
847 @param Buffer The buffer to copy to the allocated buffer.
848
849 @return A pointer to the allocated buffer or NULL if allocation fails.
850
851 **/
852 VOID *
853 EFIAPI
854 AllocateReservedCopyPool (
855 IN UINTN AllocationSize,
856 IN CONST VOID *Buffer
857 )
858 {
859 VOID *NewBuffer;
860
861 NewBuffer = InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);
862 if (NewBuffer != NULL) {
863 MemoryProfileLibRecord (
864 (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
865 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_COPY_POOL,
866 EfiRuntimeServicesData,
867 NewBuffer,
868 AllocationSize,
869 NULL
870 );
871 }
872
873 return NewBuffer;
874 }
875
876 /**
877 Reallocates a buffer of a specified memory type.
878
879 Allocates and zeros the number bytes specified by NewSize from memory of the type
880 specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and
881 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
882 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
883 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
884 enough memory remaining to satisfy the request, then NULL is returned.
885
886 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
887 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
888
889 @param PoolType The type of pool to allocate.
890 @param OldSize The size, in bytes, of OldBuffer.
891 @param NewSize The size, in bytes, of the buffer to reallocate.
892 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
893 parameter that may be NULL.
894
895 @return A pointer to the allocated buffer or NULL if allocation fails.
896
897 **/
898 VOID *
899 InternalReallocatePool (
900 IN EFI_MEMORY_TYPE PoolType,
901 IN UINTN OldSize,
902 IN UINTN NewSize,
903 IN VOID *OldBuffer OPTIONAL
904 )
905 {
906 VOID *NewBuffer;
907
908 NewBuffer = InternalAllocateZeroPool (PoolType, NewSize);
909 if ((NewBuffer != NULL) && (OldBuffer != NULL)) {
910 CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize));
911 FreePool (OldBuffer);
912 }
913
914 return NewBuffer;
915 }
916
917 /**
918 Reallocates a buffer of type EfiBootServicesData.
919
920 Allocates and zeros the number bytes specified by NewSize from memory of type
921 EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
922 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
923 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
924 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
925 enough memory remaining to satisfy the request, then NULL is returned.
926
927 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
928 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
929
930 @param OldSize The size, in bytes, of OldBuffer.
931 @param NewSize The size, in bytes, of the buffer to reallocate.
932 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
933 parameter that may be NULL.
934
935 @return A pointer to the allocated buffer or NULL if allocation fails.
936
937 **/
938 VOID *
939 EFIAPI
940 ReallocatePool (
941 IN UINTN OldSize,
942 IN UINTN NewSize,
943 IN VOID *OldBuffer OPTIONAL
944 )
945 {
946 VOID *Buffer;
947
948 Buffer = InternalReallocatePool (EfiBootServicesData, OldSize, NewSize, OldBuffer);
949 if (Buffer != NULL) {
950 MemoryProfileLibRecord (
951 (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
952 MEMORY_PROFILE_ACTION_LIB_REALLOCATE_POOL,
953 EfiBootServicesData,
954 Buffer,
955 NewSize,
956 NULL
957 );
958 }
959
960 return Buffer;
961 }
962
963 /**
964 Reallocates a buffer of type EfiRuntimeServicesData.
965
966 Allocates and zeros the number bytes specified by NewSize from memory of type
967 EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
968 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
969 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
970 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
971 enough memory remaining to satisfy the request, then NULL is returned.
972
973 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
974 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
975
976 @param OldSize The size, in bytes, of OldBuffer.
977 @param NewSize The size, in bytes, of the buffer to reallocate.
978 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
979 parameter that may be NULL.
980
981 @return A pointer to the allocated buffer or NULL if allocation fails.
982
983 **/
984 VOID *
985 EFIAPI
986 ReallocateRuntimePool (
987 IN UINTN OldSize,
988 IN UINTN NewSize,
989 IN VOID *OldBuffer OPTIONAL
990 )
991 {
992 VOID *Buffer;
993
994 Buffer = InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer);
995 if (Buffer != NULL) {
996 MemoryProfileLibRecord (
997 (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
998 MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RUNTIME_POOL,
999 EfiRuntimeServicesData,
1000 Buffer,
1001 NewSize,
1002 NULL
1003 );
1004 }
1005
1006 return Buffer;
1007 }
1008
1009 /**
1010 Reallocates a buffer of type EfiReservedMemoryType.
1011
1012 Allocates and zeros the number bytes specified by NewSize from memory of type
1013 EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and
1014 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
1015 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
1016 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
1017 enough memory remaining to satisfy the request, then NULL is returned.
1018
1019 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
1020 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
1021
1022 @param OldSize The size, in bytes, of OldBuffer.
1023 @param NewSize The size, in bytes, of the buffer to reallocate.
1024 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
1025 parameter that may be NULL.
1026
1027 @return A pointer to the allocated buffer or NULL if allocation fails.
1028
1029 **/
1030 VOID *
1031 EFIAPI
1032 ReallocateReservedPool (
1033 IN UINTN OldSize,
1034 IN UINTN NewSize,
1035 IN VOID *OldBuffer OPTIONAL
1036 )
1037 {
1038 VOID *Buffer;
1039
1040 Buffer = InternalReallocatePool (EfiReservedMemoryType, OldSize, NewSize, OldBuffer);
1041 if (Buffer != NULL) {
1042 MemoryProfileLibRecord (
1043 (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0),
1044 MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RESERVED_POOL,
1045 EfiReservedMemoryType,
1046 Buffer,
1047 NewSize,
1048 NULL
1049 );
1050 }
1051
1052 return Buffer;
1053 }
1054
1055 /**
1056 Frees a buffer that was previously allocated with one of the pool allocation functions in the
1057 Memory Allocation Library.
1058
1059 Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the
1060 pool allocation services of the Memory Allocation Library. If it is not possible to free pool
1061 resources, then this function will perform no actions.
1062
1063 If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
1064 then ASSERT().
1065
1066 @param Buffer Pointer to the buffer to free.
1067
1068 **/
1069 VOID
1070 EFIAPI
1071 FreePool (
1072 IN VOID *Buffer
1073 )
1074 {
1075 EFI_STATUS Status;
1076
1077 Status = CoreFreePool (Buffer);
1078 ASSERT_EFI_ERROR (Status);
1079 }