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 // We would rather waste some memory to save PEI code size.
163 Memory
= InternalAllocatePages (MemoryType
, Pages
+ EFI_SIZE_TO_PAGES (Alignment
));
164 if (Alignment
== 0) {
165 AlignmentMask
= Alignment
;
167 AlignmentMask
= Alignment
- 1;
169 return (VOID
*) (UINTN
) (((UINTN
) Memory
+ AlignmentMask
) & ~AlignmentMask
);
173 Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData
174 with an alignment specified by Alignment.
176 @param Pages The number of 4 KB pages to allocate.
177 @param Alignment The requested alignment of the allocation. Must be a power of two.
178 If Alignment is zero, then byte alignment is used.
180 @return The allocated buffer is returned. If Pages is 0, then NULL is returned.
181 If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.
186 AllocateAlignedPages (
191 return InternalAllocateAlignedPages (EfiBootServicesData
, Pages
, Alignment
);
195 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData
196 with an alignment specified by Alignment.
198 @param Pages The number of 4 KB pages to allocate.
199 @param Alignment The requested alignment of the allocation. Must be a power of two.
200 If Alignment is zero, then byte alignment is used.
202 @return The allocated buffer is returned. If Pages is 0, then NULL is returned.
203 If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.
208 AllocateAlignedRuntimePages (
213 return InternalAllocateAlignedPages (EfiRuntimeServicesData
, Pages
, Alignment
);
217 Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
219 @param Pages The number of 4 KB pages to allocate.
220 @param Alignment The requested alignment of the allocation. Must be a power of two.
221 If Alignment is zero, then byte alignment is used.
223 @return The allocated buffer is returned. If Pages is 0, then NULL is returned.
224 If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.
229 AllocateAlignedReservedPages (
234 return InternalAllocateAlignedPages (EfiReservedMemoryType
, Pages
, Alignment
);
238 Frees one or more 4KB pages that were previously allocated with
239 one of the aligned page allocation functions in the Memory Allocation Library.
241 @param Buffer Pointer to the buffer of pages to free.
242 @param Pages The number of 4 KB pages to free.
253 // PEI phase does not support to free pages, so leave it as NOP.
258 Allocates a buffer of a certain memory type.
260 @param MemoryType The type of memory to allocate.
261 @param AllocationSize The number of bytes to allocate.
263 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
264 If there is not enough memory remaining to satisfy the request, then NULL is returned.
268 InternalAllocatePool (
269 IN EFI_MEMORY_TYPE MemoryType
,
270 IN UINTN AllocationSize
274 // If we need lots of small runtime/reserved memory type from PEI in the future,
275 // we can consider providing a more complex algorithm that allocates runtime pages and
276 // provide pool allocations from those pages.
278 return InternalAllocatePages (MemoryType
, EFI_SIZE_TO_PAGES (AllocationSize
));
282 Allocates a buffer of type EfiBootServicesData.
284 @param AllocationSize The number of bytes to allocate.
286 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
287 If there is not enough memory remaining to satisfy the request, then NULL is returned.
293 IN UINTN AllocationSize
297 EFI_PEI_SERVICES
**PeiServices
;
300 PeiServices
= GetPeiServicesTablePointer ();
302 Status
= (*PeiServices
)->AllocatePool (PeiServices
, AllocationSize
, &Buffer
);
303 if (EFI_ERROR (Status
)) {
310 Allocates a buffer of type EfiRuntimeServicesData.
312 @param AllocationSize The number of bytes to allocate.
314 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
315 If there is not enough memory remaining to satisfy the request, then NULL is returned.
320 AllocateRuntimePool (
321 IN UINTN AllocationSize
324 return InternalAllocatePool (EfiRuntimeServicesData
, AllocationSize
);
328 Allocates a buffer of type EfiReservedMemoryType.
330 @param AllocationSize The number of bytes to allocate.
332 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
333 If there is not enough memory remaining to satisfy the request, then NULL is returned.
338 AllocateReservedPool (
339 IN UINTN AllocationSize
342 return InternalAllocatePool (EfiReservedMemoryType
, AllocationSize
);
346 Allocates and zeros a buffer of a certian pool type.
348 @param PoolType The type of memory to allocate.
349 @param AllocationSize The number of bytes to allocate and zero.
351 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
352 If there is not enough memory remaining to satisfy the request, then NULL is returned.
356 InternalAllocateZeroPool (
357 IN EFI_MEMORY_TYPE PoolType
,
358 IN UINTN AllocationSize
363 Memory
= InternalAllocatePool (PoolType
, AllocationSize
);
364 if (Memory
!= NULL
) {
365 Memory
= ZeroMem (Memory
, AllocationSize
);
371 Allocates and zeros a buffer of type EfiBootServicesData.
373 @param AllocationSize The number of bytes to allocate and zero.
375 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
376 If there is not enough memory remaining to satisfy the request, then NULL is returned.
382 IN UINTN AllocationSize
387 Memory
= AllocatePool (AllocationSize
);
388 if (Memory
!= NULL
) {
389 Memory
= ZeroMem (Memory
, AllocationSize
);
395 Allocates and zeros a buffer of type EfiRuntimeServicesData.
397 @param AllocationSize The number of bytes to allocate and zero.
399 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
400 If there is not enough memory remaining to satisfy the request, then NULL is returned.
405 AllocateRuntimeZeroPool (
406 IN UINTN AllocationSize
409 return InternalAllocateZeroPool (EfiRuntimeServicesData
, AllocationSize
);
413 Allocates and zeros a buffer of type EfiReservedMemoryType.
415 @param AllocationSize The number of bytes to allocate and zero.
417 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
418 If there is not enough memory remaining to satisfy the request, then NULL is returned.
423 AllocateReservedZeroPool (
424 IN UINTN AllocationSize
427 return InternalAllocateZeroPool (EfiReservedMemoryType
, AllocationSize
);
431 Copies a buffer to an allocated buffer of a certian memory type.
433 @param MemoryType The type of pool to allocate.
434 @param AllocationSize The number of bytes to allocate and zero.
435 @param Buffer The buffer to copy to the allocated buffer.
437 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
438 If there is not enough memory remaining to satisfy the request, then NULL is returned.
442 InternalAllocateCopyPool (
443 IN EFI_MEMORY_TYPE PoolType
,
444 IN UINTN AllocationSize
,
445 IN CONST VOID
*Buffer
450 Memory
= InternalAllocatePool (PoolType
, AllocationSize
);
451 if (Memory
!= NULL
) {
452 Memory
= CopyMem (Memory
, Buffer
, AllocationSize
);
458 Copies a buffer to an allocated buffer of type EfiBootServicesData.
460 @param AllocationSize The number of bytes to allocate.
461 @param Buffer The buffer to copy to the allocated buffer.
463 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
464 If there is not enough memory remaining to satisfy the request, then NULL is returned.
470 IN UINTN AllocationSize
,
471 IN CONST VOID
*Buffer
476 Memory
= AllocatePool (AllocationSize
);
477 if (Memory
!= NULL
) {
478 Memory
= CopyMem (Memory
, Buffer
, AllocationSize
);
484 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
486 @param AllocationSize The number of bytes to allocate.
487 @param Buffer The buffer to copy to the allocated buffer.
489 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
490 If there is not enough memory remaining to satisfy the request, then NULL is returned.
495 AllocateRuntimeCopyPool (
496 IN UINTN AllocationSize
,
497 IN CONST VOID
*Buffer
500 return InternalAllocateCopyPool (EfiRuntimeServicesData
, AllocationSize
, Buffer
);
504 Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
506 @param AllocationSize The number of bytes to allocate.
507 @param Buffer The buffer to copy to the allocated buffer.
509 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
510 If there is not enough memory remaining to satisfy the request, then NULL is returned.
515 AllocateReservedCopyPool (
516 IN UINTN AllocationSize
,
517 IN CONST VOID
*Buffer
520 return InternalAllocateCopyPool (EfiReservedMemoryType
, AllocationSize
, Buffer
);
524 Copies a buffer to an allocated buffer of type EfiReservedMemoryType at a specified alignment.
526 @param Buffer Pointer to the buffer to free.
536 // PEI phase does not support to free pool, so leave it as NOP.
541 Allocates a buffer of a certain pool type at a specified alignment.
543 @param PoolType The type of pool to allocate.
544 @param AllocationSize The number of bytes to allocate.
545 @param Alignment The requested alignment of the allocation. Must be a power of two. If Alignment is zero, then byte alignment is used.
547 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
548 If there is not enough memory remaining to satisfy the request, then NULL is returned.
552 InternalAllocateAlignedPool (
553 IN EFI_MEMORY_TYPE PoolType
,
554 IN UINTN AllocationSize
,
559 UINTN AlignedAddress
;
563 // Alignment must be a power of two or zero.
565 ASSERT ((Alignment
& (Alignment
- 1)) == 0);
567 if (Alignment
== 0) {
568 AlignmentMask
= Alignment
;
570 AlignmentMask
= Alignment
- 1;
573 RawAddress
= InternalAllocatePool (PoolType
, AllocationSize
+ AlignmentMask
);
575 AlignedAddress
= ((UINTN
) RawAddress
+ AlignmentMask
) & ~AlignmentMask
;
577 return (VOID
*) AlignedAddress
;
581 Allocates a buffer of type EfiBootServicesData at a specified alignment.
583 @param AllocationSize The number of bytes to allocate.
584 @param Alignment The requested alignment of the allocation. Must be a power of two. If Alignment is zero, then byte alignment is used.
586 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
587 If there is not enough memory remaining to satisfy the request, then NULL is returned.
592 AllocateAlignedPool (
593 IN UINTN AllocationSize
,
598 UINTN AlignedAddress
;
602 // Alignment must be a power of two or zero.
604 ASSERT ((Alignment
& (Alignment
- 1)) == 0);
606 if (Alignment
== 0) {
607 AlignmentMask
= Alignment
;
609 AlignmentMask
= Alignment
- 1;
612 RawAddress
= AllocatePool (AllocationSize
+ AlignmentMask
);
614 AlignedAddress
= ((UINTN
) RawAddress
+ AlignmentMask
) & ~AlignmentMask
;
616 return (VOID
*) AlignedAddress
;
620 Allocates a buffer of type EfiRuntimeServicesData at a specified alignment.
622 @param AllocationSize The number of bytes to allocate.
623 @param Alignment The requested alignment of the allocation. Must be a power of two.
624 If Alignment is zero, then byte alignment is used.
626 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
627 If there is not enough memory remaining to satisfy the request, then NULL is returned.
632 AllocateAlignedRuntimePool (
633 IN UINTN AllocationSize
,
637 return InternalAllocateAlignedPool (EfiRuntimeServicesData
, AllocationSize
, Alignment
);
641 Allocates a buffer of type EfiReservedMemoryType at a specified alignment.
643 @param AllocationSize The number of bytes to allocate.
644 @param Alignment The requested alignment of the allocation. Must be a power of two.
645 If Alignment is zero, then byte alignment is used.
647 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
648 If there is not enough memory remaining to satisfy the request, then NULL is returned.
653 AllocateAlignedReservedPool (
654 IN UINTN AllocationSize
,
658 return InternalAllocateAlignedPool (EfiReservedMemoryType
, AllocationSize
, Alignment
);
662 Allocates and zeros a buffer of type EfiBootServicesData at a specified alignment.
664 @param PoolType The type of pool to allocate.
665 @param AllocationSize The number of bytes to allocate.
666 @param Alignment The requested alignment of the allocation. Must be a power of two.
667 If Alignment is zero, then byte alignment is used.
669 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
670 If there is not enough memory remaining to satisfy the request, then NULL is returned.
674 InternalAllocateAlignedZeroPool (
675 IN EFI_MEMORY_TYPE PoolType
,
676 IN UINTN AllocationSize
,
682 Memory
= InternalAllocateAlignedPool (PoolType
, AllocationSize
, Alignment
);
683 if (Memory
!= NULL
) {
684 Memory
= ZeroMem (Memory
, AllocationSize
);
690 Allocates and zeros a buffer of type EfiBootServicesData at a specified alignment.
692 @param AllocationSize The number of bytes to allocate.
693 @param Alignment The requested alignment of the allocation. Must be a power of two.
694 If Alignment is zero, then byte alignment is used.
696 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
697 If there is not enough memory remaining to satisfy the request, then NULL is returned.
702 AllocateAlignedZeroPool (
703 IN UINTN AllocationSize
,
709 Memory
= AllocateAlignedPool (AllocationSize
, Alignment
);
710 if (Memory
!= NULL
) {
711 Memory
= ZeroMem (Memory
, AllocationSize
);
717 Allocates and zeros a buffer of type EfiRuntimeServicesData at a specified alignment.
719 @param AllocationSize The number of bytes to allocate.
720 @param Alignment The requested alignment of the allocation. Must be a power of two.
721 If Alignment is zero, then byte alignment is used.
723 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
724 If there is not enough memory remaining to satisfy the request, then NULL is returned.
729 AllocateAlignedRuntimeZeroPool (
730 IN UINTN AllocationSize
,
734 return InternalAllocateAlignedZeroPool (EfiRuntimeServicesData
, AllocationSize
, Alignment
);
738 Allocates and zeros a buffer of type EfiReservedMemoryType at a specified alignment.
740 @param AllocationSize The number of bytes to allocate.
741 @param Alignment The requested alignment of the allocation. Must be a power of two.
742 If Alignment is zero, then byte alignment is used.
744 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
745 If there is not enough memory remaining to satisfy the request, then NULL is returned.
750 AllocateAlignedReservedZeroPool (
751 IN UINTN AllocationSize
,
755 return InternalAllocateAlignedZeroPool (EfiReservedMemoryType
, AllocationSize
, Alignment
);
759 Copies a buffer to an allocated buffer of type EfiBootServicesData at a specified alignment.
761 @param PoolType The type of pool to allocate.
762 @param AllocationSize The number of bytes to allocate.
763 @param Buffer The buffer to copy to the allocated buffer.
764 @param Alignment The requested alignment of the allocation. Must be a power of two.
765 If Alignment is zero, then byte alignment is used.
767 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
768 If there is not enough memory remaining to satisfy the request, then NULL is returned.
772 InternalAllocateAlignedCopyPool (
773 IN EFI_MEMORY_TYPE PoolType
,
774 IN UINTN AllocationSize
,
775 IN CONST VOID
*Buffer
,
781 Memory
= InternalAllocateAlignedPool (PoolType
, AllocationSize
, Alignment
);
782 if (Memory
!= NULL
) {
783 Memory
= CopyMem (Memory
, Buffer
, AllocationSize
);
789 Copies a buffer to an allocated buffer of type EfiBootServicesData at a specified alignment.
791 @param AllocationSize The number of bytes to allocate.
792 @param Buffer The buffer to copy to the allocated buffer.
793 @param Alignment The requested alignment of the allocation. Must be a power of two.
794 If Alignment is zero, then byte alignment is used.
796 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
797 If there is not enough memory remaining to satisfy the request, then NULL is returned.
802 AllocateAlignedCopyPool (
803 IN UINTN AllocationSize
,
804 IN CONST VOID
*Buffer
,
810 Memory
= AllocateAlignedPool (AllocationSize
, Alignment
);
811 if (Memory
!= NULL
) {
812 Memory
= CopyMem (Memory
, Buffer
, AllocationSize
);
818 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData at a specified alignment.
820 @param AllocationSize The number of bytes to allocate.
821 @param Buffer The buffer to copy to the allocated buffer.
822 @param Alignment The requested alignment of the allocation. Must be a power of two.
823 If Alignment is zero, then byte alignment is used.
825 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
826 If there is not enough memory remaining to satisfy the request, then NULL is returned.
831 AllocateAlignedRuntimeCopyPool (
832 IN UINTN AllocationSize
,
833 IN CONST VOID
*Buffer
,
837 return InternalAllocateAlignedCopyPool (EfiRuntimeServicesData
, AllocationSize
, Buffer
, Alignment
);
841 Copies a buffer to an allocated buffer of type EfiReservedMemoryType at a specified alignment.
843 @param AllocationSize The number of bytes to allocate.
844 @param Buffer The buffer to copy to the allocated buffer.
845 @param Alignment The requested alignment of the allocation. Must be a power of two.
846 If Alignment is zero, then byte alignment is used.
848 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
849 If there is not enough memory remaining to satisfy the request, then NULL is returned.
854 AllocateAlignedReservedCopyPool (
855 IN UINTN AllocationSize
,
856 IN CONST VOID
*Buffer
,
860 return InternalAllocateAlignedCopyPool (EfiReservedMemoryType
, AllocationSize
, Buffer
, Alignment
);
864 Frees a buffer that was previously allocated with one of the aligned pool allocation functions
865 in the Memory Allocation Library.
867 @param Buffer Pointer to the buffer to free.
877 // PEI phase does not support to free pool, so leave it as NOP.