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