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