2 Support routines for memory allocation routines based
3 on boot services for Dxe phase drivers.
5 Copyright (c) 2006 - 2008, Intel Corporation<BR>
6 All rights reserved. This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 #include <Library/MemoryAllocationLib.h>
20 #include <Library/BaseMemoryLib.h>
21 #include <Library/DebugLib.h>
23 #include "DxeCoreMemoryAllocationServices.h"
26 Allocates one or more 4KB pages of a certain memory type.
28 Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated
29 buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL is returned.
30 If there is not enough memory remaining to satisfy the request, then NULL is returned.
32 @param MemoryType The type of memory to allocate.
33 @param Pages The number of 4 KB pages to allocate.
35 @return A pointer to the allocated buffer or NULL if allocation fails.
39 InternalAllocatePages (
40 IN EFI_MEMORY_TYPE MemoryType
,
45 EFI_PHYSICAL_ADDRESS Memory
;
51 Status
= CoreAllocatePages (AllocateAnyPages
, MemoryType
, Pages
, &Memory
);
52 if (EFI_ERROR (Status
)) {
55 return (VOID
*) (UINTN
) Memory
;
59 Allocates one or more 4KB pages of type EfiBootServicesData.
61 Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the
62 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
63 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
66 @param Pages The number of 4 KB pages to allocate.
68 @return A pointer to the allocated buffer or NULL if allocation fails.
77 return InternalAllocatePages (EfiBootServicesData
, Pages
);
81 Allocates one or more 4KB pages of type EfiRuntimeServicesData.
83 Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
84 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
85 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
88 @param Pages The number of 4 KB pages to allocate.
90 @return A pointer to the allocated buffer or NULL if allocation fails.
95 AllocateRuntimePages (
99 return InternalAllocatePages (EfiRuntimeServicesData
, Pages
);
103 Allocates one or more 4KB pages of type EfiReservedMemoryType.
105 Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the
106 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
107 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
110 @param Pages The number of 4 KB pages to allocate.
112 @return A pointer to the allocated buffer or NULL if allocation fails.
117 AllocateReservedPages (
121 return InternalAllocatePages (EfiReservedMemoryType
, Pages
);
125 Frees one or more 4KB pages that were previously allocated with one of the page allocation
126 functions in the Memory Allocation Library.
128 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
129 must have been allocated on a previous call to the page allocation services of the Memory
131 If Buffer was not allocated with a page allocation function in the Memory Allocation Library,
133 If Pages is zero, then ASSERT().
135 @param Buffer Pointer to the buffer of pages to free.
136 @param Pages The number of 4 KB pages to free.
149 Status
= CoreFreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
, Pages
);
150 ASSERT_EFI_ERROR (Status
);
154 Allocates one or more 4KB pages of a certain memory type at a specified alignment.
156 Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment
157 specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned.
158 If there is not enough memory at the specified alignment remaining to satisfy the request, then
160 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
162 @param MemoryType The type of memory to allocate.
163 @param Pages The number of 4 KB pages to allocate.
164 @param Alignment The requested alignment of the allocation. Must be a power of two.
165 If Alignment is zero, then byte alignment is used.
167 @return A pointer to the allocated buffer or NULL if allocation fails.
171 InternalAllocateAlignedPages (
172 IN EFI_MEMORY_TYPE MemoryType
,
178 EFI_PHYSICAL_ADDRESS Memory
;
181 UINTN UnalignedPages
;
185 // Alignment must be a power of two or zero.
187 ASSERT ((Alignment
& (Alignment
- 1)) == 0);
192 if (Alignment
> EFI_PAGE_SIZE
) {
194 // Caculate the total number of pages since alignment is larger than page size.
196 AlignmentMask
= Alignment
- 1;
197 RealPages
= Pages
+ EFI_SIZE_TO_PAGES (Alignment
);
199 // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
201 ASSERT (RealPages
> Pages
);
203 Status
= CoreAllocatePages (AllocateAnyPages
, MemoryType
, RealPages
, &Memory
);
204 if (EFI_ERROR (Status
)) {
207 AlignedMemory
= ((UINTN
) Memory
+ AlignmentMask
) & ~AlignmentMask
;
208 UnalignedPages
= EFI_SIZE_TO_PAGES (AlignedMemory
- (UINTN
) Memory
);
209 if (UnalignedPages
> 0) {
211 // Free first unaligned page(s).
213 Status
= CoreFreePages (Memory
, UnalignedPages
);
214 ASSERT_EFI_ERROR (Status
);
216 Memory
= (EFI_PHYSICAL_ADDRESS
) (AlignedMemory
+ EFI_PAGES_TO_SIZE (Pages
));
217 UnalignedPages
= RealPages
- Pages
- UnalignedPages
;
218 if (UnalignedPages
> 0) {
220 // Free last unaligned page(s).
222 Status
= CoreFreePages (Memory
, UnalignedPages
);
223 ASSERT_EFI_ERROR (Status
);
227 // Do not over-allocate pages in this case.
229 Status
= CoreAllocatePages (AllocateAnyPages
, MemoryType
, Pages
, &Memory
);
230 if (EFI_ERROR (Status
)) {
233 AlignedMemory
= (UINTN
) Memory
;
235 return (VOID
*) AlignedMemory
;
239 Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment.
241 Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an
242 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
243 returned. If there is not enough memory at the specified alignment remaining to satisfy the
244 request, then NULL is returned.
245 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
247 @param Pages The number of 4 KB pages to allocate.
248 @param Alignment The requested alignment of the allocation. Must be a power of two.
249 If Alignment is zero, then byte alignment is used.
251 @return A pointer to the allocated buffer or NULL if allocation fails.
256 AllocateAlignedPages (
261 return InternalAllocateAlignedPages (EfiBootServicesData
, Pages
, Alignment
);
265 Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
267 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an
268 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
269 returned. If there is not enough memory at the specified alignment remaining to satisfy the
270 request, then NULL is returned.
271 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
273 @param Pages The number of 4 KB pages to allocate.
274 @param Alignment The requested alignment of the allocation. Must be a power of two.
275 If Alignment is zero, then byte alignment is used.
277 @return A pointer to the allocated buffer or NULL if allocation fails.
282 AllocateAlignedRuntimePages (
287 return InternalAllocateAlignedPages (EfiRuntimeServicesData
, Pages
, Alignment
);
291 Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
293 Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an
294 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
295 returned. If there is not enough memory at the specified alignment remaining to satisfy the
296 request, then NULL is returned.
297 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
299 @param Pages The number of 4 KB pages to allocate.
300 @param Alignment The requested alignment of the allocation. Must be a power of two.
301 If Alignment is zero, then byte alignment is used.
303 @return A pointer to the allocated buffer or NULL if allocation fails.
308 AllocateAlignedReservedPages (
313 return InternalAllocateAlignedPages (EfiReservedMemoryType
, Pages
, Alignment
);
317 Frees one or more 4KB pages that were previously allocated with one of the aligned page
318 allocation functions in the Memory Allocation Library.
320 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
321 must have been allocated on a previous call to the aligned page allocation services of the Memory
323 If Buffer was not allocated with an aligned page allocation function in the Memory Allocation
324 Library, then ASSERT().
325 If Pages is zero, then ASSERT().
327 @param Buffer Pointer to the buffer of pages to free.
328 @param Pages The number of 4 KB pages to free.
341 Status
= CoreFreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
, Pages
);
342 ASSERT_EFI_ERROR (Status
);
346 Allocates a buffer of a certain pool type.
348 Allocates the number bytes specified by AllocationSize of a certain pool type and returns a
349 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
350 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
352 @param MemoryType The type of memory to allocate.
353 @param AllocationSize The number of bytes to allocate.
355 @return A pointer to the allocated buffer or NULL if allocation fails.
359 InternalAllocatePool (
360 IN EFI_MEMORY_TYPE MemoryType
,
361 IN UINTN AllocationSize
367 Status
= CoreAllocatePool (MemoryType
, AllocationSize
, &Memory
);
368 if (EFI_ERROR (Status
)) {
375 Allocates a buffer of type EfiBootServicesData.
377 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a
378 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
379 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
381 @param AllocationSize The number of bytes to allocate.
383 @return A pointer to the allocated buffer or NULL if allocation fails.
389 IN UINTN AllocationSize
392 return InternalAllocatePool (EfiBootServicesData
, AllocationSize
);
396 Allocates a buffer of type EfiRuntimeServicesData.
398 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns
399 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
400 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
402 @param AllocationSize The number of bytes to allocate.
404 @return A pointer to the allocated buffer or NULL if allocation fails.
409 AllocateRuntimePool (
410 IN UINTN AllocationSize
413 return InternalAllocatePool (EfiRuntimeServicesData
, AllocationSize
);
417 Allocates a buffer of type EfieservedMemoryType.
419 Allocates the number bytes specified by AllocationSize of type EfieservedMemoryType and returns
420 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
421 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
423 @param AllocationSize The number of bytes to allocate.
425 @return A pointer to the allocated buffer or NULL if allocation fails.
430 AllocateReservedPool (
431 IN UINTN AllocationSize
434 return InternalAllocatePool (EfiReservedMemoryType
, AllocationSize
);
438 Allocates and zeros a buffer of a certian pool type.
440 Allocates the number bytes specified by AllocationSize of a certian pool type, clears the buffer
441 with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid
442 buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request,
443 then NULL is returned.
445 @param PoolType The type of memory to allocate.
446 @param AllocationSize The number of bytes to allocate and zero.
448 @return A pointer to the allocated buffer or NULL if allocation fails.
452 InternalAllocateZeroPool (
453 IN EFI_MEMORY_TYPE PoolType
,
454 IN UINTN AllocationSize
459 Memory
= InternalAllocatePool (PoolType
, AllocationSize
);
460 if (Memory
!= NULL
) {
461 Memory
= ZeroMem (Memory
, AllocationSize
);
467 Allocates and zeros a buffer of type EfiBootServicesData.
469 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
470 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
471 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
472 request, then NULL is returned.
474 @param AllocationSize The number of bytes to allocate and zero.
476 @return A pointer to the allocated buffer or NULL if allocation fails.
482 IN UINTN AllocationSize
485 return InternalAllocateZeroPool (EfiBootServicesData
, AllocationSize
);
489 Allocates and zeros a buffer of type EfiRuntimeServicesData.
491 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the
492 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
493 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
494 request, then NULL is returned.
496 @param AllocationSize The number of bytes to allocate and zero.
498 @return A pointer to the allocated buffer or NULL if allocation fails.
503 AllocateRuntimeZeroPool (
504 IN UINTN AllocationSize
507 return InternalAllocateZeroPool (EfiRuntimeServicesData
, AllocationSize
);
511 Allocates and zeros a buffer of type EfiReservedMemoryType.
513 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the
514 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
515 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
516 request, then NULL is returned.
518 @param AllocationSize The number of bytes to allocate and zero.
520 @return A pointer to the allocated buffer or NULL if allocation fails.
525 AllocateReservedZeroPool (
526 IN UINTN AllocationSize
529 return InternalAllocateZeroPool (EfiReservedMemoryType
, AllocationSize
);
533 Copies a buffer to an allocated buffer of a certian pool type.
535 Allocates the number bytes specified by AllocationSize of a certian pool type, copies
536 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
537 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
538 is not enough memory remaining to satisfy the request, then NULL is returned.
539 If Buffer is NULL, then ASSERT().
540 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
542 @param PoolType The type of pool to allocate.
543 @param AllocationSize The number of bytes to allocate and zero.
544 @param Buffer The buffer to copy to the allocated buffer.
546 @return A pointer to the allocated buffer or NULL if allocation fails.
550 InternalAllocateCopyPool (
551 IN EFI_MEMORY_TYPE PoolType
,
552 IN UINTN AllocationSize
,
553 IN CONST VOID
*Buffer
558 ASSERT (Buffer
!= NULL
);
559 ASSERT (AllocationSize
<= (MAX_ADDRESS
- (UINTN
) Buffer
+ 1));
561 Memory
= InternalAllocatePool (PoolType
, AllocationSize
);
562 if (Memory
!= NULL
) {
563 Memory
= CopyMem (Memory
, Buffer
, AllocationSize
);
569 Copies a buffer to an allocated buffer of type EfiBootServicesData.
571 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies
572 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
573 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
574 is not enough memory remaining to satisfy the request, then NULL is returned.
575 If Buffer is NULL, then ASSERT().
576 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
578 @param AllocationSize The number of bytes to allocate and zero.
579 @param Buffer The buffer to copy to the allocated buffer.
581 @return A pointer to the allocated buffer or NULL if allocation fails.
587 IN UINTN AllocationSize
,
588 IN CONST VOID
*Buffer
591 return InternalAllocateCopyPool (EfiBootServicesData
, AllocationSize
, Buffer
);
595 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
597 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies
598 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
599 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
600 is not enough memory remaining to satisfy the request, then NULL is returned.
601 If Buffer is NULL, then ASSERT().
602 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
604 @param AllocationSize The number of bytes to allocate and zero.
605 @param Buffer The buffer to copy to the allocated buffer.
607 @return A pointer to the allocated buffer or NULL if allocation fails.
612 AllocateRuntimeCopyPool (
613 IN UINTN AllocationSize
,
614 IN CONST VOID
*Buffer
617 return InternalAllocateCopyPool (EfiRuntimeServicesData
, AllocationSize
, Buffer
);
621 Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
623 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies
624 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
625 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
626 is not enough memory remaining to satisfy the request, then NULL is returned.
627 If Buffer is NULL, then ASSERT().
628 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
630 @param AllocationSize The number of bytes to allocate and zero.
631 @param Buffer The buffer to copy to the allocated buffer.
633 @return A pointer to the allocated buffer or NULL if allocation fails.
638 AllocateReservedCopyPool (
639 IN UINTN AllocationSize
,
640 IN CONST VOID
*Buffer
643 return InternalAllocateCopyPool (EfiReservedMemoryType
, AllocationSize
, Buffer
);
647 Frees a buffer that was previously allocated with one of the pool allocation functions in the
648 Memory Allocation Library.
650 Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the
651 pool allocation services of the Memory Allocation Library.
652 If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
655 @param Buffer Pointer to the buffer to free.
666 Status
= CoreFreePool (Buffer
);
667 ASSERT_EFI_ERROR (Status
);