2 Support routines for memory allocation routines for use with drivers.
4 Copyright (c) 2006, Intel Corporation<BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 Module Name: MemoryAllocationLib.c
20 Allocates the number of 4KB pages specified by Pages of a certain memory type.
22 @param MemoryType The type of memory to allocate.
23 @param Pages The number of 4 KB pages to allocate.
25 @return A pointer to the allocated buffer. The buffer returned is aligned on a 4KB boundary.
26 If Pages is 0, then NULL is returned.
27 If there is not enough memory remaining to satisfy the request, then NULL is returned.
31 InternalAllocatePages (
32 IN EFI_MEMORY_TYPE MemoryType
,
37 EFI_PHYSICAL_ADDRESS Memory
;
38 EFI_PEI_SERVICES
**PeiServices
;
44 PeiServices
= GetPeiServicesTablePointer ();
45 Status
= (*PeiServices
)->AllocatePages (PeiServices
, MemoryType
, Pages
, &Memory
);
46 if (EFI_ERROR (Status
)) {
49 return (VOID
*) (UINTN
) Memory
;
53 Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData.
55 @param Pages The number of 4 KB pages to allocate.
57 @return A pointer to the allocated buffer. The buffer returned is aligned on a 4KB boundary.
58 If Pages is 0, then NULL is returned.
59 If there is not enough memory remaining to satisfy the request, then NULL is returned.
68 return InternalAllocatePages (EfiBootServicesData
, Pages
);
72 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData.
74 @param Pages The number of 4 KB pages to allocate.
76 @return A pointer to the allocated buffer. The buffer returned is aligned on a 4KB boundary.
77 If Pages is 0, then NULL is returned.
78 If there is not enough memory remaining to satisfy the request, then NULL is returned.
83 AllocateRuntimePages (
87 return InternalAllocatePages (EfiRuntimeServicesData
, Pages
);
91 Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType.
93 @param Pages The number of 4 KB pages to allocate.
95 @return A pointer to the allocated buffer. The buffer returned is aligned on a 4KB boundary.
96 If Pages is 0, then NULL is returned.
97 If there is not enough memory remaining to satisfy the request, then NULL is returned.
102 AllocateReservedPages (
106 return InternalAllocatePages (EfiReservedMemoryType
, Pages
);
110 Frees one or more 4KB pages that were previously allocated with
111 one of the page allocation functions in the Memory Allocation Library.
113 @param Buffer Pointer to the buffer of pages to free.
114 @param Pages The number of 4 KB pages to free.
125 // PEI phase does not support to free pages, so leave it as NOP.
130 Allocates the number of 4KB pages specified by Pages of a certian memory type
131 with an alignment specified by Alignment.
133 @param MemoryType The type of memory to allocate.
134 @param Pages The number of 4 KB pages to allocate.
135 @param Alignment The requested alignment of the allocation. Must be a power of two.
136 If Alignment is zero, then byte alignment is used.
138 @return The allocated buffer is returned. If Pages is 0, then NULL is returned.
139 If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.
143 InternalAllocateAlignedPages (
144 IN EFI_MEMORY_TYPE MemoryType
,
153 // Alignment must be a power of two or zero.
155 ASSERT ((Alignment
& (Alignment
- 1)) == 0);
161 // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
163 ASSERT (Pages
<= (MAX_ADDRESS
- EFI_SIZE_TO_PAGES (Alignment
)));
165 // We would rather waste some memory to save PEI code size.
167 Memory
= InternalAllocatePages (MemoryType
, Pages
+ EFI_SIZE_TO_PAGES (Alignment
));
168 if (Alignment
== 0) {
169 AlignmentMask
= Alignment
;
171 AlignmentMask
= Alignment
- 1;
173 return (VOID
*) (UINTN
) (((UINTN
) Memory
+ AlignmentMask
) & ~AlignmentMask
);
177 Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData
178 with an alignment specified by Alignment.
180 @param Pages The number of 4 KB pages to allocate.
181 @param Alignment The requested alignment of the allocation. Must be a power of two.
182 If Alignment is zero, then byte alignment is used.
184 @return The allocated buffer is returned. If Pages is 0, then NULL is returned.
185 If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.
190 AllocateAlignedPages (
195 return InternalAllocateAlignedPages (EfiBootServicesData
, Pages
, Alignment
);
199 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData
200 with an alignment specified by Alignment.
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.
206 @return The allocated buffer is returned. If Pages is 0, then NULL is returned.
207 If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.
212 AllocateAlignedRuntimePages (
217 return InternalAllocateAlignedPages (EfiRuntimeServicesData
, Pages
, Alignment
);
221 Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
223 @param Pages The number of 4 KB pages to allocate.
224 @param Alignment The requested alignment of the allocation. Must be a power of two.
225 If Alignment is zero, then byte alignment is used.
227 @return The allocated buffer is returned. If Pages is 0, then NULL is returned.
228 If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.
233 AllocateAlignedReservedPages (
238 return InternalAllocateAlignedPages (EfiReservedMemoryType
, Pages
, Alignment
);
242 Frees one or more 4KB pages that were previously allocated with
243 one of the aligned page allocation functions in the Memory Allocation Library.
245 @param Buffer Pointer to the buffer of pages to free.
246 @param Pages The number of 4 KB pages to free.
257 // PEI phase does not support to free pages, so leave it as NOP.
262 Allocates a buffer of a certain memory type.
264 @param MemoryType The type of memory to allocate.
265 @param AllocationSize The number of bytes to allocate.
267 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
268 If there is not enough memory remaining to satisfy the request, then NULL is returned.
272 InternalAllocatePool (
273 IN EFI_MEMORY_TYPE MemoryType
,
274 IN UINTN AllocationSize
278 // If we need lots of small runtime/reserved memory type from PEI in the future,
279 // we can consider providing a more complex algorithm that allocates runtime pages and
280 // provide pool allocations from those pages.
282 return InternalAllocatePages (MemoryType
, EFI_SIZE_TO_PAGES (AllocationSize
));
286 Allocates a buffer of type EfiBootServicesData.
288 @param AllocationSize The number of bytes to allocate.
290 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
291 If there is not enough memory remaining to satisfy the request, then NULL is returned.
297 IN UINTN AllocationSize
301 EFI_PEI_SERVICES
**PeiServices
;
304 PeiServices
= GetPeiServicesTablePointer ();
306 Status
= (*PeiServices
)->AllocatePool (PeiServices
, AllocationSize
, &Buffer
);
307 if (EFI_ERROR (Status
)) {
314 Allocates a buffer of type EfiRuntimeServicesData.
316 @param AllocationSize The number of bytes to allocate.
318 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
319 If there is not enough memory remaining to satisfy the request, then NULL is returned.
324 AllocateRuntimePool (
325 IN UINTN AllocationSize
328 return InternalAllocatePool (EfiRuntimeServicesData
, AllocationSize
);
332 Allocates a buffer of type EfiReservedMemoryType.
334 @param AllocationSize The number of bytes to allocate.
336 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
337 If there is not enough memory remaining to satisfy the request, then NULL is returned.
342 AllocateReservedPool (
343 IN UINTN AllocationSize
346 return InternalAllocatePool (EfiReservedMemoryType
, AllocationSize
);
350 Allocates and zeros a buffer of a certian pool type.
352 @param PoolType The type of memory to allocate.
353 @param AllocationSize The number of bytes to allocate and zero.
355 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
356 If there is not enough memory remaining to satisfy the request, then NULL is returned.
360 InternalAllocateZeroPool (
361 IN EFI_MEMORY_TYPE PoolType
,
362 IN UINTN AllocationSize
367 Memory
= InternalAllocatePool (PoolType
, AllocationSize
);
368 if (Memory
!= NULL
) {
369 Memory
= ZeroMem (Memory
, AllocationSize
);
375 Allocates and zeros a buffer of type EfiBootServicesData.
377 @param AllocationSize The number of bytes to allocate and zero.
379 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
380 If there is not enough memory remaining to satisfy the request, then NULL is returned.
386 IN UINTN AllocationSize
391 Memory
= AllocatePool (AllocationSize
);
392 if (Memory
!= NULL
) {
393 Memory
= ZeroMem (Memory
, AllocationSize
);
399 Allocates and zeros a buffer of type EfiRuntimeServicesData.
401 @param AllocationSize The number of bytes to allocate and zero.
403 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
404 If there is not enough memory remaining to satisfy the request, then NULL is returned.
409 AllocateRuntimeZeroPool (
410 IN UINTN AllocationSize
413 return InternalAllocateZeroPool (EfiRuntimeServicesData
, AllocationSize
);
417 Allocates and zeros a buffer of type EfiReservedMemoryType.
419 @param AllocationSize The number of bytes to allocate and zero.
421 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
422 If there is not enough memory remaining to satisfy the request, then NULL is returned.
427 AllocateReservedZeroPool (
428 IN UINTN AllocationSize
431 return InternalAllocateZeroPool (EfiReservedMemoryType
, AllocationSize
);
435 Copies a buffer to an allocated buffer of a certian memory type.
437 @param MemoryType The type of pool to allocate.
438 @param AllocationSize The number of bytes to allocate and zero.
439 @param Buffer The buffer to copy to the allocated buffer.
441 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
442 If there is not enough memory remaining to satisfy the request, then NULL is returned.
446 InternalAllocateCopyPool (
447 IN EFI_MEMORY_TYPE PoolType
,
448 IN UINTN AllocationSize
,
449 IN CONST VOID
*Buffer
454 Memory
= InternalAllocatePool (PoolType
, AllocationSize
);
455 if (Memory
!= NULL
) {
456 Memory
= CopyMem (Memory
, Buffer
, AllocationSize
);
462 Copies a buffer to an allocated buffer of type EfiBootServicesData.
464 @param AllocationSize The number of bytes to allocate.
465 @param Buffer The buffer to copy to the allocated buffer.
467 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
468 If there is not enough memory remaining to satisfy the request, then NULL is returned.
474 IN UINTN AllocationSize
,
475 IN CONST VOID
*Buffer
480 Memory
= AllocatePool (AllocationSize
);
481 if (Memory
!= NULL
) {
482 Memory
= CopyMem (Memory
, Buffer
, AllocationSize
);
488 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
490 @param AllocationSize The number of bytes to allocate.
491 @param Buffer The buffer to copy to the allocated buffer.
493 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
494 If there is not enough memory remaining to satisfy the request, then NULL is returned.
499 AllocateRuntimeCopyPool (
500 IN UINTN AllocationSize
,
501 IN CONST VOID
*Buffer
504 return InternalAllocateCopyPool (EfiRuntimeServicesData
, AllocationSize
, Buffer
);
508 Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
510 @param AllocationSize The number of bytes to allocate.
511 @param Buffer The buffer to copy to the allocated buffer.
513 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
514 If there is not enough memory remaining to satisfy the request, then NULL is returned.
519 AllocateReservedCopyPool (
520 IN UINTN AllocationSize
,
521 IN CONST VOID
*Buffer
524 return InternalAllocateCopyPool (EfiReservedMemoryType
, AllocationSize
, Buffer
);
528 Copies a buffer to an allocated buffer of type EfiReservedMemoryType at a specified alignment.
530 @param Buffer Pointer to the buffer to free.
540 // PEI phase does not support to free pool, so leave it as NOP.
545 Allocates a buffer of a certain pool type at a specified alignment.
547 @param PoolType The type of pool to allocate.
548 @param AllocationSize The number of bytes to allocate.
549 @param Alignment The requested alignment of the allocation. Must be a power of two. If Alignment is zero, then byte alignment is used.
551 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
552 If there is not enough memory remaining to satisfy the request, then NULL is returned.
556 InternalAllocateAlignedPool (
557 IN EFI_MEMORY_TYPE PoolType
,
558 IN UINTN AllocationSize
,
563 UINTN AlignedAddress
;
567 // Alignment must be a power of two or zero.
569 ASSERT ((Alignment
& (Alignment
- 1)) == 0);
571 if (Alignment
== 0) {
572 AlignmentMask
= Alignment
;
574 AlignmentMask
= Alignment
- 1;
577 // Make sure that AllocationSize plus AlignmentMask does not overflow.
579 ASSERT (AllocationSize
<= (MAX_ADDRESS
- AlignmentMask
));
581 RawAddress
= InternalAllocatePool (PoolType
, AllocationSize
+ AlignmentMask
);
583 AlignedAddress
= ((UINTN
) RawAddress
+ AlignmentMask
) & ~AlignmentMask
;
585 return (VOID
*) AlignedAddress
;
589 Allocates a buffer of type EfiBootServicesData at a specified alignment.
591 @param AllocationSize The number of bytes to allocate.
592 @param Alignment The requested alignment of the allocation. Must be a power of two. If Alignment is zero, then byte alignment is used.
594 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
595 If there is not enough memory remaining to satisfy the request, then NULL is returned.
600 AllocateAlignedPool (
601 IN UINTN AllocationSize
,
606 UINTN AlignedAddress
;
610 // Alignment must be a power of two or zero.
612 ASSERT ((Alignment
& (Alignment
- 1)) == 0);
614 if (Alignment
== 0) {
615 AlignmentMask
= Alignment
;
617 AlignmentMask
= Alignment
- 1;
621 // Make sure that AllocationSize plus AlignmentMask does not overflow.
623 ASSERT (AllocationSize
<= (MAX_ADDRESS
- AlignmentMask
));
625 RawAddress
= AllocatePool (AllocationSize
+ AlignmentMask
);
627 AlignedAddress
= ((UINTN
) RawAddress
+ AlignmentMask
) & ~AlignmentMask
;
629 return (VOID
*) AlignedAddress
;
633 Allocates a buffer of type EfiRuntimeServicesData at a specified alignment.
635 @param AllocationSize The number of bytes to allocate.
636 @param Alignment The requested alignment of the allocation. Must be a power of two.
637 If Alignment is zero, then byte alignment is used.
639 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
640 If there is not enough memory remaining to satisfy the request, then NULL is returned.
645 AllocateAlignedRuntimePool (
646 IN UINTN AllocationSize
,
650 return InternalAllocateAlignedPool (EfiRuntimeServicesData
, AllocationSize
, Alignment
);
654 Allocates a buffer of type EfiReservedMemoryType at a specified alignment.
656 @param AllocationSize The number of bytes to allocate.
657 @param Alignment The requested alignment of the allocation. Must be a power of two.
658 If Alignment is zero, then byte alignment is used.
660 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
661 If there is not enough memory remaining to satisfy the request, then NULL is returned.
666 AllocateAlignedReservedPool (
667 IN UINTN AllocationSize
,
671 return InternalAllocateAlignedPool (EfiReservedMemoryType
, AllocationSize
, Alignment
);
675 Allocates and zeros a buffer of type EfiBootServicesData at a specified alignment.
677 @param PoolType The type of pool to allocate.
678 @param AllocationSize The number of bytes to allocate.
679 @param Alignment The requested alignment of the allocation. Must be a power of two.
680 If Alignment is zero, then byte alignment is used.
682 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
683 If there is not enough memory remaining to satisfy the request, then NULL is returned.
687 InternalAllocateAlignedZeroPool (
688 IN EFI_MEMORY_TYPE PoolType
,
689 IN UINTN AllocationSize
,
695 Memory
= InternalAllocateAlignedPool (PoolType
, AllocationSize
, Alignment
);
696 if (Memory
!= NULL
) {
697 Memory
= ZeroMem (Memory
, AllocationSize
);
703 Allocates and zeros a buffer of type EfiBootServicesData at a specified alignment.
705 @param AllocationSize The number of bytes to allocate.
706 @param Alignment The requested alignment of the allocation. Must be a power of two.
707 If Alignment is zero, then byte alignment is used.
709 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
710 If there is not enough memory remaining to satisfy the request, then NULL is returned.
715 AllocateAlignedZeroPool (
716 IN UINTN AllocationSize
,
722 Memory
= AllocateAlignedPool (AllocationSize
, Alignment
);
723 if (Memory
!= NULL
) {
724 Memory
= ZeroMem (Memory
, AllocationSize
);
730 Allocates and zeros a buffer of type EfiRuntimeServicesData at a specified alignment.
732 @param AllocationSize The number of bytes to allocate.
733 @param Alignment The requested alignment of the allocation. Must be a power of two.
734 If Alignment is zero, then byte alignment is used.
736 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
737 If there is not enough memory remaining to satisfy the request, then NULL is returned.
742 AllocateAlignedRuntimeZeroPool (
743 IN UINTN AllocationSize
,
747 return InternalAllocateAlignedZeroPool (EfiRuntimeServicesData
, AllocationSize
, Alignment
);
751 Allocates and zeros a buffer of type EfiReservedMemoryType at a specified alignment.
753 @param AllocationSize The number of bytes to allocate.
754 @param Alignment The requested alignment of the allocation. Must be a power of two.
755 If Alignment is zero, then byte alignment is used.
757 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
758 If there is not enough memory remaining to satisfy the request, then NULL is returned.
763 AllocateAlignedReservedZeroPool (
764 IN UINTN AllocationSize
,
768 return InternalAllocateAlignedZeroPool (EfiReservedMemoryType
, AllocationSize
, Alignment
);
772 Copies a buffer to an allocated buffer of type EfiBootServicesData at a specified alignment.
774 @param PoolType The type of pool to allocate.
775 @param AllocationSize The number of bytes to allocate.
776 @param Buffer The buffer to copy to the allocated buffer.
777 @param Alignment The requested alignment of the allocation. Must be a power of two.
778 If Alignment is zero, then byte alignment is used.
780 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
781 If there is not enough memory remaining to satisfy the request, then NULL is returned.
785 InternalAllocateAlignedCopyPool (
786 IN EFI_MEMORY_TYPE PoolType
,
787 IN UINTN AllocationSize
,
788 IN CONST VOID
*Buffer
,
794 Memory
= InternalAllocateAlignedPool (PoolType
, AllocationSize
, Alignment
);
795 if (Memory
!= NULL
) {
796 Memory
= CopyMem (Memory
, Buffer
, AllocationSize
);
802 Copies a buffer to an allocated buffer of type EfiBootServicesData at a specified alignment.
804 @param AllocationSize The number of bytes to allocate.
805 @param Buffer The buffer to copy to the allocated buffer.
806 @param Alignment The requested alignment of the allocation. Must be a power of two.
807 If Alignment is zero, then byte alignment is used.
809 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
810 If there is not enough memory remaining to satisfy the request, then NULL is returned.
815 AllocateAlignedCopyPool (
816 IN UINTN AllocationSize
,
817 IN CONST VOID
*Buffer
,
823 Memory
= AllocateAlignedPool (AllocationSize
, Alignment
);
824 if (Memory
!= NULL
) {
825 Memory
= CopyMem (Memory
, Buffer
, AllocationSize
);
831 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData at a specified alignment.
833 @param AllocationSize The number of bytes to allocate.
834 @param Buffer The buffer to copy to the allocated buffer.
835 @param Alignment The requested alignment of the allocation. Must be a power of two.
836 If Alignment is zero, then byte alignment is used.
838 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
839 If there is not enough memory remaining to satisfy the request, then NULL is returned.
844 AllocateAlignedRuntimeCopyPool (
845 IN UINTN AllocationSize
,
846 IN CONST VOID
*Buffer
,
850 return InternalAllocateAlignedCopyPool (EfiRuntimeServicesData
, AllocationSize
, Buffer
, Alignment
);
854 Copies a buffer to an allocated buffer of type EfiReservedMemoryType at a specified alignment.
856 @param AllocationSize The number of bytes to allocate.
857 @param Buffer The buffer to copy to the allocated buffer.
858 @param Alignment The requested alignment of the allocation. Must be a power of two.
859 If Alignment is zero, then byte alignment is used.
861 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
862 If there is not enough memory remaining to satisfy the request, then NULL is returned.
867 AllocateAlignedReservedCopyPool (
868 IN UINTN AllocationSize
,
869 IN CONST VOID
*Buffer
,
873 return InternalAllocateAlignedCopyPool (EfiReservedMemoryType
, AllocationSize
, Buffer
, Alignment
);
877 Frees a buffer that was previously allocated with one of the aligned pool allocation functions
878 in the Memory Allocation Library.
880 @param Buffer Pointer to the buffer to free.
890 // PEI phase does not support to free pool, so leave it as NOP.