2 Support routines for memory allocation routines based
3 on SMM Services Table services for SMM phase drivers, with memory profile support.
5 The PI System Management Mode Core Interface Specification only allows the use
6 of EfiRuntimeServicesCode and EfiRuntimeServicesData memory types for memory
7 allocations through the SMM Services Table as the SMRAM space should be
8 reserved after BDS phase. The functions in the Memory Allocation Library use
9 EfiBootServicesData as the default memory allocation type. For this SMM
10 specific instance of the Memory Allocation Library, EfiRuntimeServicesData
11 is used as the default memory type for all allocations. In addition,
12 allocation for the Reserved memory types are not supported and will always
15 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
16 SPDX-License-Identifier: BSD-2-Clause-Patent
22 #include <Protocol/SmmAccess2.h>
23 #include <Library/MemoryAllocationLib.h>
24 #include <Library/UefiBootServicesTableLib.h>
25 #include <Library/SmmServicesTableLib.h>
26 #include <Library/BaseMemoryLib.h>
27 #include <Library/DebugLib.h>
29 #include <Library/MemoryProfileLib.h>
31 EFI_SMRAM_DESCRIPTOR
*mSmramRanges
;
32 UINTN mSmramRangeCount
;
35 The constructor function caches SMRAM ranges that are present in the system.
37 It will ASSERT() if SMM Access2 Protocol doesn't exist.
38 It will ASSERT() if SMRAM ranges can't be got.
39 It will ASSERT() if Resource can't be allocated for cache SMRAM range.
40 It will always return EFI_SUCCESS.
42 @param ImageHandle The firmware allocated handle for the EFI image.
43 @param SystemTable A pointer to the EFI System Table.
45 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
50 SmmMemoryAllocationLibConstructor (
51 IN EFI_HANDLE ImageHandle
,
52 IN EFI_SYSTEM_TABLE
*SystemTable
56 EFI_SMM_ACCESS2_PROTOCOL
*SmmAccess
;
60 // Locate SMM Access2 Protocol
62 Status
= gBS
->LocateProtocol (
63 &gEfiSmmAccess2ProtocolGuid
,
67 ASSERT_EFI_ERROR (Status
);
70 // Get SMRAM range information
73 Status
= SmmAccess
->GetCapabilities (SmmAccess
, &Size
, NULL
);
74 ASSERT (Status
== EFI_BUFFER_TOO_SMALL
);
76 mSmramRanges
= (EFI_SMRAM_DESCRIPTOR
*) AllocatePool (Size
);
77 ASSERT (mSmramRanges
!= NULL
);
79 Status
= SmmAccess
->GetCapabilities (SmmAccess
, &Size
, mSmramRanges
);
80 ASSERT_EFI_ERROR (Status
);
82 mSmramRangeCount
= Size
/ sizeof (EFI_SMRAM_DESCRIPTOR
);
88 If SMM driver exits with an error, it must call this routine
89 to free the allocated resource before the exiting.
91 @param[in] ImageHandle The firmware allocated handle for the EFI image.
92 @param[in] SystemTable A pointer to the EFI System Table.
94 @retval EFI_SUCCESS The deconstructor always returns EFI_SUCCESS.
98 SmmMemoryAllocationLibDestructor (
99 IN EFI_HANDLE ImageHandle
,
100 IN EFI_SYSTEM_TABLE
*SystemTable
103 FreePool (mSmramRanges
);
109 Check whether the start address of buffer is within any of the SMRAM ranges.
111 @param[in] Buffer The pointer to the buffer to be checked.
113 @retval TRUE The buffer is in SMRAM ranges.
114 @retval FALSE The buffer is out of SMRAM ranges.
124 for (Index
= 0; Index
< mSmramRangeCount
; Index
++) {
125 if (((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
>= mSmramRanges
[Index
].CpuStart
) &&
126 ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
< (mSmramRanges
[Index
].CpuStart
+ mSmramRanges
[Index
].PhysicalSize
))) {
135 Allocates one or more 4KB pages of a certain memory type.
137 Allocates the number of 4KB pages of a certain memory type and returns a pointer
138 to the allocated buffer. The buffer returned is aligned on a 4KB boundary. If
139 Pages is 0, then NULL is returned. If there is not enough memory remaining to
140 satisfy the request, then NULL is returned.
142 @param MemoryType The type of memory to allocate.
143 @param Pages The number of 4 KB pages to allocate.
145 @return A pointer to the allocated buffer or NULL if allocation fails.
149 InternalAllocatePages (
150 IN EFI_MEMORY_TYPE MemoryType
,
155 EFI_PHYSICAL_ADDRESS Memory
;
161 Status
= gSmst
->SmmAllocatePages (AllocateAnyPages
, MemoryType
, Pages
, &Memory
);
162 if (EFI_ERROR (Status
)) {
165 return (VOID
*) (UINTN
) Memory
;
169 Allocates one or more 4KB pages of type EfiRuntimeServicesData.
171 Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer
172 to the allocated buffer. The buffer returned is aligned on a 4KB boundary. If
173 Pages is 0, then NULL is returned. If there is not enough memory remaining to
174 satisfy the request, then NULL is returned.
176 @param Pages The number of 4 KB pages to allocate.
178 @return A pointer to the allocated buffer or NULL if allocation fails.
189 Buffer
= InternalAllocatePages (EfiRuntimeServicesData
, Pages
);
190 if (Buffer
!= NULL
) {
191 MemoryProfileLibRecord (
192 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
193 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_PAGES
,
194 EfiRuntimeServicesData
,
196 EFI_PAGES_TO_SIZE(Pages
),
204 Allocates one or more 4KB pages of type EfiRuntimeServicesData.
206 Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a
207 pointer to the allocated buffer. The buffer returned is aligned on a 4KB boundary.
208 If Pages is 0, then NULL is returned. If there is not enough memory remaining
209 to satisfy the request, then NULL is returned.
211 @param Pages The number of 4 KB pages to allocate.
213 @return A pointer to the allocated buffer or NULL if allocation fails.
218 AllocateRuntimePages (
224 Buffer
= InternalAllocatePages (EfiRuntimeServicesData
, Pages
);
225 if (Buffer
!= NULL
) {
226 MemoryProfileLibRecord (
227 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
228 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_PAGES
,
229 EfiRuntimeServicesData
,
231 EFI_PAGES_TO_SIZE(Pages
),
239 Allocates one or more 4KB pages of type EfiReservedMemoryType.
241 Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a
242 pointer to the allocated buffer. The buffer returned is aligned on a 4KB boundary.
243 If Pages is 0, then NULL is returned. If there is not enough memory remaining
244 to satisfy the request, then NULL is returned.
246 @param Pages The number of 4 KB pages to allocate.
248 @return A pointer to the allocated buffer or NULL if allocation fails.
253 AllocateReservedPages (
261 Frees one or more 4KB pages that were previously allocated with one of the page allocation
262 functions in the Memory Allocation Library.
264 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer.
265 Buffer must have been allocated on a previous call to the page allocation services
266 of the Memory Allocation Library. If it is not possible to free allocated pages,
267 then this function will perform no actions.
269 If Buffer was not allocated with a page allocation function in the Memory Allocation
270 Library, then ASSERT().
271 If Pages is zero, then ASSERT().
273 @param Buffer The pointer to the buffer of pages to free.
274 @param Pages The number of 4 KB pages to free.
287 if (BufferInSmram (Buffer
)) {
289 // When Buffer is in SMRAM range, it should be allocated by gSmst->SmmAllocatePages() service.
290 // So, gSmst->SmmFreePages() service is used to free it.
292 Status
= gSmst
->SmmFreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
, Pages
);
295 // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePages() service.
296 // So, gBS->FreePages() service is used to free it.
298 Status
= gBS
->FreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
, Pages
);
300 ASSERT_EFI_ERROR (Status
);
304 Allocates one or more 4KB pages of a certain memory type at a specified alignment.
306 Allocates the number of 4KB pages specified by Pages of a certain memory type
307 with an alignment specified by Alignment. The allocated buffer is returned.
308 If Pages is 0, then NULL is returned. If there is not enough memory at the
309 specified alignment remaining to satisfy the request, then NULL is returned.
310 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
311 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
313 @param MemoryType The type of memory to allocate.
314 @param Pages The number of 4 KB pages to allocate.
315 @param Alignment The requested alignment of the allocation.
316 Must be a power of two.
317 If Alignment is zero, then byte alignment is used.
319 @return A pointer to the allocated buffer or NULL if allocation fails.
323 InternalAllocateAlignedPages (
324 IN EFI_MEMORY_TYPE MemoryType
,
330 EFI_PHYSICAL_ADDRESS Memory
;
333 UINTN UnalignedPages
;
337 // Alignment must be a power of two or zero.
339 ASSERT ((Alignment
& (Alignment
- 1)) == 0);
344 if (Alignment
> EFI_PAGE_SIZE
) {
346 // Calculate the total number of pages since alignment is larger than page size.
348 AlignmentMask
= Alignment
- 1;
349 RealPages
= Pages
+ EFI_SIZE_TO_PAGES (Alignment
);
351 // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
353 ASSERT (RealPages
> Pages
);
355 Status
= gSmst
->SmmAllocatePages (AllocateAnyPages
, MemoryType
, RealPages
, &Memory
);
356 if (EFI_ERROR (Status
)) {
359 AlignedMemory
= ((UINTN
) Memory
+ AlignmentMask
) & ~AlignmentMask
;
360 UnalignedPages
= EFI_SIZE_TO_PAGES (AlignedMemory
- (UINTN
) Memory
);
361 if (UnalignedPages
> 0) {
363 // Free first unaligned page(s).
365 Status
= gSmst
->SmmFreePages (Memory
, UnalignedPages
);
366 ASSERT_EFI_ERROR (Status
);
368 Memory
= AlignedMemory
+ EFI_PAGES_TO_SIZE (Pages
);
369 UnalignedPages
= RealPages
- Pages
- UnalignedPages
;
370 if (UnalignedPages
> 0) {
372 // Free last unaligned page(s).
374 Status
= gSmst
->SmmFreePages (Memory
, UnalignedPages
);
375 ASSERT_EFI_ERROR (Status
);
379 // Do not over-allocate pages in this case.
381 Status
= gSmst
->SmmAllocatePages (AllocateAnyPages
, MemoryType
, Pages
, &Memory
);
382 if (EFI_ERROR (Status
)) {
385 AlignedMemory
= (UINTN
) Memory
;
387 return (VOID
*) AlignedMemory
;
391 Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
393 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData
394 with an alignment specified by Alignment. The allocated buffer is returned.
395 If Pages is 0, then NULL is returned. If there is not enough memory at the
396 specified alignment remaining to satisfy the request, then NULL is returned.
398 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
399 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
401 @param Pages The number of 4 KB pages to allocate.
402 @param Alignment The requested alignment of the allocation.
403 Must be a power of two.
404 If Alignment is zero, then byte alignment is used.
406 @return A pointer to the allocated buffer or NULL if allocation fails.
411 AllocateAlignedPages (
418 Buffer
= InternalAllocateAlignedPages (EfiRuntimeServicesData
, Pages
, Alignment
);
419 if (Buffer
!= NULL
) {
420 MemoryProfileLibRecord (
421 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
422 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_PAGES
,
423 EfiRuntimeServicesData
,
425 EFI_PAGES_TO_SIZE(Pages
),
433 Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
435 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData
436 with an alignment specified by Alignment. The allocated buffer is returned.
437 If Pages is 0, then NULL is returned. If there is not enough memory at the
438 specified alignment remaining to satisfy the request, then NULL is returned.
440 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
441 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
443 @param Pages The number of 4 KB pages to allocate.
444 @param Alignment The requested alignment of the allocation.
445 Must be a power of two.
446 If Alignment is zero, then byte alignment is used.
448 @return A pointer to the allocated buffer or NULL if allocation fails.
453 AllocateAlignedRuntimePages (
460 Buffer
= InternalAllocateAlignedPages (EfiRuntimeServicesData
, Pages
, Alignment
);
461 if (Buffer
!= NULL
) {
462 MemoryProfileLibRecord (
463 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
464 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RUNTIME_PAGES
,
465 EfiRuntimeServicesData
,
467 EFI_PAGES_TO_SIZE(Pages
),
475 Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
477 Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType
478 with an alignment specified by Alignment. The allocated buffer is returned.
479 If Pages is 0, then NULL is returned. If there is not enough memory at the
480 specified alignment remaining to satisfy the request, then NULL is returned.
482 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
483 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
485 @param Pages The number of 4 KB pages to allocate.
486 @param Alignment The requested alignment of the allocation.
487 Must be a power of two.
488 If Alignment is zero, then byte alignment is used.
490 @return A pointer to the allocated buffer or NULL if allocation fails.
495 AllocateAlignedReservedPages (
504 Frees one or more 4KB pages that were previously allocated with one of the aligned page
505 allocation functions in the Memory Allocation Library.
507 Frees the number of 4KB pages specified by Pages from the buffer specified by
508 Buffer. Buffer must have been allocated on a previous call to the aligned page
509 allocation services of the Memory Allocation Library. If it is not possible to
510 free allocated pages, then this function will perform no actions.
512 If Buffer was not allocated with an aligned page allocation function in the
513 Memory Allocation Library, then ASSERT().
514 If Pages is zero, then ASSERT().
516 @param Buffer The pointer to the buffer of pages to free.
517 @param Pages The number of 4 KB pages to free.
530 if (BufferInSmram (Buffer
)) {
532 // When Buffer is in SMRAM range, it should be allocated by gSmst->SmmAllocatePages() service.
533 // So, gSmst->SmmFreePages() service is used to free it.
535 Status
= gSmst
->SmmFreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
, Pages
);
538 // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePages() service.
539 // So, gBS->FreePages() service is used to free it.
541 Status
= gBS
->FreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
, Pages
);
543 ASSERT_EFI_ERROR (Status
);
547 Allocates a buffer of a certain pool type.
549 Allocates the number bytes specified by AllocationSize of a certain pool type
550 and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
551 valid buffer of 0 size is returned. If there is not enough memory remaining to
552 satisfy the request, then NULL is returned.
554 @param MemoryType The type of memory to allocate.
555 @param AllocationSize The number of bytes to allocate.
557 @return A pointer to the allocated buffer or NULL if allocation fails.
561 InternalAllocatePool (
562 IN EFI_MEMORY_TYPE MemoryType
,
563 IN UINTN AllocationSize
569 Status
= gSmst
->SmmAllocatePool (MemoryType
, AllocationSize
, &Memory
);
570 if (EFI_ERROR (Status
)) {
577 Allocates a buffer of type EfiRuntimeServicesData.
579 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData
580 and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
581 valid buffer of 0 size is returned. If there is not enough memory remaining to
582 satisfy the request, then NULL is returned.
584 @param AllocationSize The number of bytes to allocate.
586 @return A pointer to the allocated buffer or NULL if allocation fails.
592 IN UINTN AllocationSize
597 Buffer
= InternalAllocatePool (EfiRuntimeServicesData
, AllocationSize
);
598 if (Buffer
!= NULL
) {
599 MemoryProfileLibRecord (
600 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
601 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_POOL
,
602 EfiRuntimeServicesData
,
612 Allocates a buffer of type EfiRuntimeServicesData.
614 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData
615 and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
616 valid buffer of 0 size is returned. If there is not enough memory remaining to
617 satisfy the request, then NULL is returned.
619 @param AllocationSize The number of bytes to allocate.
621 @return A pointer to the allocated buffer or NULL if allocation fails.
626 AllocateRuntimePool (
627 IN UINTN AllocationSize
632 Buffer
= InternalAllocatePool (EfiRuntimeServicesData
, AllocationSize
);
633 if (Buffer
!= NULL
) {
634 MemoryProfileLibRecord (
635 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
636 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_POOL
,
637 EfiRuntimeServicesData
,
647 Allocates a buffer of type EfiReservedMemoryType.
649 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType
650 and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
651 valid buffer of 0 size is returned. If there is not enough memory remaining to
652 satisfy the request, then NULL is returned.
654 @param AllocationSize The number of bytes to allocate.
656 @return A pointer to the allocated buffer or NULL if allocation fails.
661 AllocateReservedPool (
662 IN UINTN AllocationSize
669 Allocates and zeros a buffer of a certain pool type.
671 Allocates the number bytes specified by AllocationSize of a certain pool type,
672 clears the buffer with zeros, and returns a pointer to the allocated buffer.
673 If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is
674 not enough memory remaining to satisfy the request, then NULL is returned.
676 @param PoolType The type of memory to allocate.
677 @param AllocationSize The number of bytes to allocate and zero.
679 @return A pointer to the allocated buffer or NULL if allocation fails.
683 InternalAllocateZeroPool (
684 IN EFI_MEMORY_TYPE PoolType
,
685 IN UINTN AllocationSize
690 Memory
= InternalAllocatePool (PoolType
, AllocationSize
);
691 if (Memory
!= NULL
) {
692 Memory
= ZeroMem (Memory
, AllocationSize
);
698 Allocates and zeros a buffer of type EfiRuntimeServicesData.
700 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData,
701 clears the buffer with zeros, and returns a pointer to the allocated buffer.
702 If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is
703 not enough memory remaining to satisfy the request, then NULL is returned.
705 @param AllocationSize The number of bytes to allocate and zero.
707 @return A pointer to the allocated buffer or NULL if allocation fails.
713 IN UINTN AllocationSize
718 Buffer
= InternalAllocateZeroPool (EfiRuntimeServicesData
, AllocationSize
);
719 if (Buffer
!= NULL
) {
720 MemoryProfileLibRecord (
721 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
722 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ZERO_POOL
,
723 EfiRuntimeServicesData
,
733 Allocates and zeros a buffer of type EfiRuntimeServicesData.
735 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData,
736 clears the buffer with zeros, and returns a pointer to the allocated buffer.
737 If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is
738 not enough memory remaining to satisfy the request, then NULL is returned.
740 @param AllocationSize The number of bytes to allocate and zero.
742 @return A pointer to the allocated buffer or NULL if allocation fails.
747 AllocateRuntimeZeroPool (
748 IN UINTN AllocationSize
753 Buffer
= InternalAllocateZeroPool (EfiRuntimeServicesData
, AllocationSize
);
754 if (Buffer
!= NULL
) {
755 MemoryProfileLibRecord (
756 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
757 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_ZERO_POOL
,
758 EfiRuntimeServicesData
,
768 Allocates and zeros a buffer of type EfiReservedMemoryType.
770 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType,
771 clears the buffer with zeros, and returns a pointer to the allocated buffer.
772 If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is
773 not enough memory remaining to satisfy the request, then NULL is returned.
775 @param AllocationSize The number of bytes to allocate and zero.
777 @return A pointer to the allocated buffer or NULL if allocation fails.
782 AllocateReservedZeroPool (
783 IN UINTN AllocationSize
790 Copies a buffer to an allocated buffer of a certain pool type.
792 Allocates the number bytes specified by AllocationSize of a certain pool type,
793 copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns
794 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer
795 of 0 size is returned. If there is not enough memory remaining to satisfy the
796 request, then NULL is returned. If Buffer is NULL, then ASSERT().
797 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
799 @param PoolType The type of pool to allocate.
800 @param AllocationSize The number of bytes to allocate and zero.
801 @param Buffer The buffer to copy to the allocated buffer.
803 @return A pointer to the allocated buffer or NULL if allocation fails.
807 InternalAllocateCopyPool (
808 IN EFI_MEMORY_TYPE PoolType
,
809 IN UINTN AllocationSize
,
810 IN CONST VOID
*Buffer
815 ASSERT (Buffer
!= NULL
);
816 ASSERT (AllocationSize
<= (MAX_ADDRESS
- (UINTN
) Buffer
+ 1));
818 Memory
= InternalAllocatePool (PoolType
, AllocationSize
);
819 if (Memory
!= NULL
) {
820 Memory
= CopyMem (Memory
, Buffer
, AllocationSize
);
826 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
828 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData,
829 copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns
830 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer
831 of 0 size is returned. If there is not enough memory remaining to satisfy the
832 request, then NULL is returned.
834 If Buffer is NULL, then ASSERT().
835 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
837 @param AllocationSize The number of bytes to allocate and zero.
838 @param Buffer The buffer to copy to the allocated buffer.
840 @return A pointer to the allocated buffer or NULL if allocation fails.
846 IN UINTN AllocationSize
,
847 IN CONST VOID
*Buffer
852 NewBuffer
= InternalAllocateCopyPool (EfiRuntimeServicesData
, AllocationSize
, Buffer
);
853 if (NewBuffer
!= NULL
) {
854 MemoryProfileLibRecord (
855 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
856 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_COPY_POOL
,
857 EfiRuntimeServicesData
,
867 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
869 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData,
870 copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns
871 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer
872 of 0 size is returned. If there is not enough memory remaining to satisfy the
873 request, then NULL is returned.
875 If Buffer is NULL, then ASSERT().
876 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
878 @param AllocationSize The number of bytes to allocate and zero.
879 @param Buffer The buffer to copy to the allocated buffer.
881 @return A pointer to the allocated buffer or NULL if allocation fails.
886 AllocateRuntimeCopyPool (
887 IN UINTN AllocationSize
,
888 IN CONST VOID
*Buffer
893 NewBuffer
= InternalAllocateCopyPool (EfiRuntimeServicesData
, AllocationSize
, Buffer
);
894 if (NewBuffer
!= NULL
) {
895 MemoryProfileLibRecord (
896 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
897 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_COPY_POOL
,
898 EfiRuntimeServicesData
,
908 Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
910 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType,
911 copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns
912 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer
913 of 0 size is returned. If there is not enough memory remaining to satisfy the
914 request, then NULL is returned.
916 If Buffer is NULL, then ASSERT().
917 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
919 @param AllocationSize The number of bytes to allocate and zero.
920 @param Buffer The buffer to copy to the allocated buffer.
922 @return A pointer to the allocated buffer or NULL if allocation fails.
927 AllocateReservedCopyPool (
928 IN UINTN AllocationSize
,
929 IN CONST VOID
*Buffer
936 Reallocates a buffer of a specified memory type.
938 Allocates and zeros the number bytes specified by NewSize from memory of the type
939 specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and
940 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
941 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
942 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
943 enough memory remaining to satisfy the request, then NULL is returned.
945 If the allocation of the new buffer is successful and the smaller of NewSize
946 and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
948 @param PoolType The type of pool to allocate.
949 @param OldSize The size, in bytes, of OldBuffer.
950 @param NewSize The size, in bytes, of the buffer to reallocate.
951 @param OldBuffer The buffer to copy to the allocated buffer. This is an
952 optional parameter that may be NULL.
954 @return A pointer to the allocated buffer or NULL if allocation fails.
958 InternalReallocatePool (
959 IN EFI_MEMORY_TYPE PoolType
,
962 IN VOID
*OldBuffer OPTIONAL
967 NewBuffer
= InternalAllocateZeroPool (PoolType
, NewSize
);
968 if (NewBuffer
!= NULL
&& OldBuffer
!= NULL
) {
969 CopyMem (NewBuffer
, OldBuffer
, MIN (OldSize
, NewSize
));
970 FreePool (OldBuffer
);
976 Reallocates a buffer of type EfiRuntimeServicesData.
978 Allocates and zeros the number bytes specified by NewSize from memory of type
979 EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
980 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
981 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
982 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
983 enough memory remaining to satisfy the request, then NULL is returned.
985 If the allocation of the new buffer is successful and the smaller of NewSize
986 and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
988 @param OldSize The size, in bytes, of OldBuffer.
989 @param NewSize The size, in bytes, of the buffer to reallocate.
990 @param OldBuffer The buffer to copy to the allocated buffer. This is an
991 optional parameter that may be NULL.
993 @return A pointer to the allocated buffer or NULL if allocation fails.
1001 IN VOID
*OldBuffer OPTIONAL
1006 Buffer
= InternalReallocatePool (EfiRuntimeServicesData
, OldSize
, NewSize
, OldBuffer
);
1007 if (Buffer
!= NULL
) {
1008 MemoryProfileLibRecord (
1009 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
1010 MEMORY_PROFILE_ACTION_LIB_REALLOCATE_POOL
,
1011 EfiRuntimeServicesData
,
1021 Reallocates a buffer of type EfiRuntimeServicesData.
1023 Allocates and zeros the number bytes specified by NewSize from memory of type
1024 EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize
1025 and NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
1026 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
1027 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
1028 enough memory remaining to satisfy the request, then NULL is returned.
1030 If the allocation of the new buffer is successful and the smaller of NewSize
1031 and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
1033 @param OldSize The size, in bytes, of OldBuffer.
1034 @param NewSize The size, in bytes, of the buffer to reallocate.
1035 @param OldBuffer The buffer to copy to the allocated buffer. This is an
1036 optional parameter that may be NULL.
1038 @return A pointer to the allocated buffer or NULL if allocation fails.
1043 ReallocateRuntimePool (
1046 IN VOID
*OldBuffer OPTIONAL
1051 Buffer
= InternalReallocatePool (EfiRuntimeServicesData
, OldSize
, NewSize
, OldBuffer
);
1052 if (Buffer
!= NULL
) {
1053 MemoryProfileLibRecord (
1054 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
1055 MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RUNTIME_POOL
,
1056 EfiRuntimeServicesData
,
1066 Reallocates a buffer of type EfiReservedMemoryType.
1068 Allocates and zeros the number bytes specified by NewSize from memory of type
1069 EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize
1070 and NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
1071 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
1072 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
1073 enough memory remaining to satisfy the request, then NULL is returned.
1075 If the allocation of the new buffer is successful and the smaller of NewSize
1076 and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
1078 @param OldSize The size, in bytes, of OldBuffer.
1079 @param NewSize The size, in bytes, of the buffer to reallocate.
1080 @param OldBuffer The buffer to copy to the allocated buffer. This is an
1081 optional parameter that may be NULL.
1083 @return A pointer to the allocated buffer or NULL if allocation fails.
1088 ReallocateReservedPool (
1091 IN VOID
*OldBuffer OPTIONAL
1098 Frees a buffer that was previously allocated with one of the pool allocation
1099 functions in the Memory Allocation Library.
1101 Frees the buffer specified by Buffer. Buffer must have been allocated on a
1102 previous call to the pool allocation services of the Memory Allocation Library.
1103 If it is not possible to free pool resources, then this function will perform
1106 If Buffer was not allocated with a pool allocation function in the Memory
1107 Allocation Library, then ASSERT().
1109 @param Buffer The pointer to the buffer to free.
1120 if (BufferInSmram (Buffer
)) {
1122 // When Buffer is in SMRAM range, it should be allocated by gSmst->SmmAllocatePool() service.
1123 // So, gSmst->SmmFreePool() service is used to free it.
1125 Status
= gSmst
->SmmFreePool (Buffer
);
1128 // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePool() service.
1129 // So, gBS->FreePool() service is used to free it.
1131 Status
= gBS
->FreePool (Buffer
);
1133 ASSERT_EFI_ERROR (Status
);