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