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