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
)))
136 Allocates one or more 4KB pages of a certain memory type.
138 Allocates the number of 4KB pages of a certain memory type and returns a pointer
139 to the allocated buffer. The buffer returned is aligned on a 4KB boundary. If
140 Pages is 0, then NULL is returned. If there is not enough memory remaining to
141 satisfy the request, then NULL is returned.
143 @param MemoryType The type of memory to allocate.
144 @param Pages The number of 4 KB pages to allocate.
146 @return A pointer to the allocated buffer or NULL if allocation fails.
150 InternalAllocatePages (
151 IN EFI_MEMORY_TYPE MemoryType
,
156 EFI_PHYSICAL_ADDRESS Memory
;
162 Status
= gSmst
->SmmAllocatePages (AllocateAnyPages
, MemoryType
, Pages
, &Memory
);
163 if (EFI_ERROR (Status
)) {
167 return (VOID
*)(UINTN
)Memory
;
171 Allocates one or more 4KB pages of type EfiRuntimeServicesData.
173 Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer
174 to the allocated buffer. The buffer returned is aligned on a 4KB boundary. If
175 Pages is 0, then NULL is returned. If there is not enough memory remaining to
176 satisfy the request, then NULL is returned.
178 @param Pages The number of 4 KB pages to allocate.
180 @return A pointer to the allocated buffer or NULL if allocation fails.
191 Buffer
= InternalAllocatePages (EfiRuntimeServicesData
, Pages
);
192 if (Buffer
!= NULL
) {
193 MemoryProfileLibRecord (
194 (PHYSICAL_ADDRESS
)(UINTN
)RETURN_ADDRESS (0),
195 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_PAGES
,
196 EfiRuntimeServicesData
,
198 EFI_PAGES_TO_SIZE (Pages
),
207 Allocates one or more 4KB pages of type EfiRuntimeServicesData.
209 Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a
210 pointer to the allocated buffer. The buffer returned is aligned on a 4KB boundary.
211 If Pages is 0, then NULL is returned. If there is not enough memory remaining
212 to satisfy the request, then NULL is returned.
214 @param Pages The number of 4 KB pages to allocate.
216 @return A pointer to the allocated buffer or NULL if allocation fails.
221 AllocateRuntimePages (
227 Buffer
= InternalAllocatePages (EfiRuntimeServicesData
, Pages
);
228 if (Buffer
!= NULL
) {
229 MemoryProfileLibRecord (
230 (PHYSICAL_ADDRESS
)(UINTN
)RETURN_ADDRESS (0),
231 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_PAGES
,
232 EfiRuntimeServicesData
,
234 EFI_PAGES_TO_SIZE (Pages
),
243 Allocates one or more 4KB pages of type EfiReservedMemoryType.
245 Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a
246 pointer to the allocated buffer. The buffer returned is aligned on a 4KB boundary.
247 If Pages is 0, then NULL is returned. If there is not enough memory remaining
248 to satisfy the request, then NULL is returned.
250 @param Pages The number of 4 KB pages to allocate.
252 @return A pointer to the allocated buffer or NULL if allocation fails.
257 AllocateReservedPages (
265 Frees one or more 4KB pages that were previously allocated with one of the page allocation
266 functions in the Memory Allocation Library.
268 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer.
269 Buffer must have been allocated on a previous call to the page allocation services
270 of the Memory Allocation Library. If it is not possible to free allocated pages,
271 then this function will perform no actions.
273 If Buffer was not allocated with a page allocation function in the Memory Allocation
274 Library, then ASSERT().
275 If Pages is zero, then ASSERT().
277 @param Buffer The pointer to the buffer of pages to free.
278 @param Pages The number of 4 KB pages to free.
291 if (BufferInSmram (Buffer
)) {
293 // When Buffer is in SMRAM range, it should be allocated by gSmst->SmmAllocatePages() service.
294 // So, gSmst->SmmFreePages() service is used to free it.
296 Status
= gSmst
->SmmFreePages ((EFI_PHYSICAL_ADDRESS
)(UINTN
)Buffer
, Pages
);
299 // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePages() service.
300 // So, gBS->FreePages() service is used to free it.
302 Status
= gBS
->FreePages ((EFI_PHYSICAL_ADDRESS
)(UINTN
)Buffer
, Pages
);
305 ASSERT_EFI_ERROR (Status
);
309 Allocates one or more 4KB pages of a certain memory type at a specified alignment.
311 Allocates the number of 4KB pages specified by Pages of a certain memory type
312 with an alignment specified by Alignment. The allocated buffer is returned.
313 If Pages is 0, then NULL is returned. If there is not enough memory at the
314 specified alignment remaining to satisfy the request, then NULL is returned.
315 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
316 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
318 @param MemoryType The type of memory to allocate.
319 @param Pages The number of 4 KB pages to allocate.
320 @param Alignment The requested alignment of the allocation.
321 Must be a power of two.
322 If Alignment is zero, then byte alignment is used.
324 @return A pointer to the allocated buffer or NULL if allocation fails.
328 InternalAllocateAlignedPages (
329 IN EFI_MEMORY_TYPE MemoryType
,
335 EFI_PHYSICAL_ADDRESS Memory
;
338 UINTN UnalignedPages
;
342 // Alignment must be a power of two or zero.
344 ASSERT ((Alignment
& (Alignment
- 1)) == 0);
350 if (Alignment
> EFI_PAGE_SIZE
) {
352 // Calculate the total number of pages since alignment is larger than page size.
354 AlignmentMask
= Alignment
- 1;
355 RealPages
= Pages
+ EFI_SIZE_TO_PAGES (Alignment
);
357 // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
359 ASSERT (RealPages
> Pages
);
361 Status
= gSmst
->SmmAllocatePages (AllocateAnyPages
, MemoryType
, RealPages
, &Memory
);
362 if (EFI_ERROR (Status
)) {
366 AlignedMemory
= ((UINTN
)Memory
+ AlignmentMask
) & ~AlignmentMask
;
367 UnalignedPages
= EFI_SIZE_TO_PAGES (AlignedMemory
- (UINTN
)Memory
);
368 if (UnalignedPages
> 0) {
370 // Free first unaligned page(s).
372 Status
= gSmst
->SmmFreePages (Memory
, UnalignedPages
);
373 ASSERT_EFI_ERROR (Status
);
376 Memory
= AlignedMemory
+ EFI_PAGES_TO_SIZE (Pages
);
377 UnalignedPages
= RealPages
- Pages
- UnalignedPages
;
378 if (UnalignedPages
> 0) {
380 // Free last unaligned page(s).
382 Status
= gSmst
->SmmFreePages (Memory
, UnalignedPages
);
383 ASSERT_EFI_ERROR (Status
);
387 // Do not over-allocate pages in this case.
389 Status
= gSmst
->SmmAllocatePages (AllocateAnyPages
, MemoryType
, Pages
, &Memory
);
390 if (EFI_ERROR (Status
)) {
394 AlignedMemory
= (UINTN
)Memory
;
397 return (VOID
*)AlignedMemory
;
401 Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
403 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData
404 with an alignment specified by Alignment. The allocated buffer is returned.
405 If Pages is 0, then NULL is returned. If there is not enough memory at the
406 specified alignment remaining to satisfy the request, then NULL is returned.
408 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
409 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
411 @param Pages The number of 4 KB pages to allocate.
412 @param Alignment The requested alignment of the allocation.
413 Must be a power of two.
414 If Alignment is zero, then byte alignment is used.
416 @return A pointer to the allocated buffer or NULL if allocation fails.
421 AllocateAlignedPages (
428 Buffer
= InternalAllocateAlignedPages (EfiRuntimeServicesData
, Pages
, Alignment
);
429 if (Buffer
!= NULL
) {
430 MemoryProfileLibRecord (
431 (PHYSICAL_ADDRESS
)(UINTN
)RETURN_ADDRESS (0),
432 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_PAGES
,
433 EfiRuntimeServicesData
,
435 EFI_PAGES_TO_SIZE (Pages
),
444 Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
446 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData
447 with an alignment specified by Alignment. The allocated buffer is returned.
448 If Pages is 0, then NULL is returned. If there is not enough memory at the
449 specified alignment remaining to satisfy the request, then NULL is returned.
451 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
452 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
454 @param Pages The number of 4 KB pages to allocate.
455 @param Alignment The requested alignment of the allocation.
456 Must be a power of two.
457 If Alignment is zero, then byte alignment is used.
459 @return A pointer to the allocated buffer or NULL if allocation fails.
464 AllocateAlignedRuntimePages (
471 Buffer
= InternalAllocateAlignedPages (EfiRuntimeServicesData
, Pages
, Alignment
);
472 if (Buffer
!= NULL
) {
473 MemoryProfileLibRecord (
474 (PHYSICAL_ADDRESS
)(UINTN
)RETURN_ADDRESS (0),
475 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RUNTIME_PAGES
,
476 EfiRuntimeServicesData
,
478 EFI_PAGES_TO_SIZE (Pages
),
487 Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
489 Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType
490 with an alignment specified by Alignment. The allocated buffer is returned.
491 If Pages is 0, then NULL is returned. If there is not enough memory at the
492 specified alignment remaining to satisfy the request, then NULL is returned.
494 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
495 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
497 @param Pages The number of 4 KB pages to allocate.
498 @param Alignment The requested alignment of the allocation.
499 Must be a power of two.
500 If Alignment is zero, then byte alignment is used.
502 @return A pointer to the allocated buffer or NULL if allocation fails.
507 AllocateAlignedReservedPages (
516 Frees one or more 4KB pages that were previously allocated with one of the aligned page
517 allocation functions in the Memory Allocation Library.
519 Frees the number of 4KB pages specified by Pages from the buffer specified by
520 Buffer. Buffer must have been allocated on a previous call to the aligned page
521 allocation services of the Memory Allocation Library. If it is not possible to
522 free allocated pages, then this function will perform no actions.
524 If Buffer was not allocated with an aligned page allocation function in the
525 Memory Allocation Library, then ASSERT().
526 If Pages is zero, then ASSERT().
528 @param Buffer The pointer to the buffer of pages to free.
529 @param Pages The number of 4 KB pages to free.
542 if (BufferInSmram (Buffer
)) {
544 // When Buffer is in SMRAM range, it should be allocated by gSmst->SmmAllocatePages() service.
545 // So, gSmst->SmmFreePages() service is used to free it.
547 Status
= gSmst
->SmmFreePages ((EFI_PHYSICAL_ADDRESS
)(UINTN
)Buffer
, Pages
);
550 // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePages() service.
551 // So, gBS->FreePages() service is used to free it.
553 Status
= gBS
->FreePages ((EFI_PHYSICAL_ADDRESS
)(UINTN
)Buffer
, Pages
);
556 ASSERT_EFI_ERROR (Status
);
560 Allocates a buffer of a certain pool type.
562 Allocates the number bytes specified by AllocationSize of a certain pool type
563 and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
564 valid buffer of 0 size is returned. If there is not enough memory remaining to
565 satisfy the request, then NULL is returned.
567 @param MemoryType The type of memory to allocate.
568 @param AllocationSize The number of bytes to allocate.
570 @return A pointer to the allocated buffer or NULL if allocation fails.
574 InternalAllocatePool (
575 IN EFI_MEMORY_TYPE MemoryType
,
576 IN UINTN AllocationSize
582 Status
= gSmst
->SmmAllocatePool (MemoryType
, AllocationSize
, &Memory
);
583 if (EFI_ERROR (Status
)) {
591 Allocates a buffer of type EfiRuntimeServicesData.
593 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData
594 and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
595 valid buffer of 0 size is returned. If there is not enough memory remaining to
596 satisfy the request, then NULL is returned.
598 @param AllocationSize The number of bytes to allocate.
600 @return A pointer to the allocated buffer or NULL if allocation fails.
606 IN UINTN AllocationSize
611 Buffer
= InternalAllocatePool (EfiRuntimeServicesData
, AllocationSize
);
612 if (Buffer
!= NULL
) {
613 MemoryProfileLibRecord (
614 (PHYSICAL_ADDRESS
)(UINTN
)RETURN_ADDRESS (0),
615 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_POOL
,
616 EfiRuntimeServicesData
,
627 Allocates a buffer of type EfiRuntimeServicesData.
629 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData
630 and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
631 valid buffer of 0 size is returned. If there is not enough memory remaining to
632 satisfy the request, then NULL is returned.
634 @param AllocationSize The number of bytes to allocate.
636 @return A pointer to the allocated buffer or NULL if allocation fails.
641 AllocateRuntimePool (
642 IN UINTN AllocationSize
647 Buffer
= InternalAllocatePool (EfiRuntimeServicesData
, AllocationSize
);
648 if (Buffer
!= NULL
) {
649 MemoryProfileLibRecord (
650 (PHYSICAL_ADDRESS
)(UINTN
)RETURN_ADDRESS (0),
651 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_POOL
,
652 EfiRuntimeServicesData
,
663 Allocates a buffer of type EfiReservedMemoryType.
665 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType
666 and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
667 valid buffer of 0 size is returned. If there is not enough memory remaining to
668 satisfy the request, then NULL is returned.
670 @param AllocationSize The number of bytes to allocate.
672 @return A pointer to the allocated buffer or NULL if allocation fails.
677 AllocateReservedPool (
678 IN UINTN AllocationSize
685 Allocates and zeros a buffer of a certain pool type.
687 Allocates the number bytes specified by AllocationSize of a certain pool type,
688 clears the buffer with zeros, and returns a pointer to the allocated buffer.
689 If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is
690 not enough memory remaining to satisfy the request, then NULL is returned.
692 @param PoolType The type of memory to allocate.
693 @param AllocationSize The number of bytes to allocate and zero.
695 @return A pointer to the allocated buffer or NULL if allocation fails.
699 InternalAllocateZeroPool (
700 IN EFI_MEMORY_TYPE PoolType
,
701 IN UINTN AllocationSize
706 Memory
= InternalAllocatePool (PoolType
, AllocationSize
);
707 if (Memory
!= NULL
) {
708 Memory
= ZeroMem (Memory
, AllocationSize
);
715 Allocates and zeros a buffer of type EfiRuntimeServicesData.
717 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData,
718 clears the buffer with zeros, and returns a pointer to the allocated buffer.
719 If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is
720 not enough memory remaining to satisfy the request, then NULL is returned.
722 @param AllocationSize The number of bytes to allocate and zero.
724 @return A pointer to the allocated buffer or NULL if allocation fails.
730 IN UINTN AllocationSize
735 Buffer
= InternalAllocateZeroPool (EfiRuntimeServicesData
, AllocationSize
);
736 if (Buffer
!= NULL
) {
737 MemoryProfileLibRecord (
738 (PHYSICAL_ADDRESS
)(UINTN
)RETURN_ADDRESS (0),
739 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ZERO_POOL
,
740 EfiRuntimeServicesData
,
751 Allocates and zeros a buffer of type EfiRuntimeServicesData.
753 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData,
754 clears the buffer with zeros, and returns a pointer to the allocated buffer.
755 If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is
756 not enough memory remaining to satisfy the request, then NULL is returned.
758 @param AllocationSize The number of bytes to allocate and zero.
760 @return A pointer to the allocated buffer or NULL if allocation fails.
765 AllocateRuntimeZeroPool (
766 IN UINTN AllocationSize
771 Buffer
= InternalAllocateZeroPool (EfiRuntimeServicesData
, AllocationSize
);
772 if (Buffer
!= NULL
) {
773 MemoryProfileLibRecord (
774 (PHYSICAL_ADDRESS
)(UINTN
)RETURN_ADDRESS (0),
775 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_ZERO_POOL
,
776 EfiRuntimeServicesData
,
787 Allocates and zeros a buffer of type EfiReservedMemoryType.
789 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType,
790 clears the buffer with zeros, and returns a pointer to the allocated buffer.
791 If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is
792 not enough memory remaining to satisfy the request, then NULL is returned.
794 @param AllocationSize The number of bytes to allocate and zero.
796 @return A pointer to the allocated buffer or NULL if allocation fails.
801 AllocateReservedZeroPool (
802 IN UINTN AllocationSize
809 Copies a buffer to an allocated buffer of a certain pool type.
811 Allocates the number bytes specified by AllocationSize of a certain pool type,
812 copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns
813 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer
814 of 0 size is returned. If there is not enough memory remaining to satisfy the
815 request, then NULL is returned. If Buffer is NULL, then ASSERT().
816 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
818 @param PoolType The type of pool to allocate.
819 @param AllocationSize The number of bytes to allocate and zero.
820 @param Buffer The buffer to copy to the allocated buffer.
822 @return A pointer to the allocated buffer or NULL if allocation fails.
826 InternalAllocateCopyPool (
827 IN EFI_MEMORY_TYPE PoolType
,
828 IN UINTN AllocationSize
,
829 IN CONST VOID
*Buffer
834 ASSERT (Buffer
!= NULL
);
835 ASSERT (AllocationSize
<= (MAX_ADDRESS
- (UINTN
)Buffer
+ 1));
837 Memory
= InternalAllocatePool (PoolType
, AllocationSize
);
838 if (Memory
!= NULL
) {
839 Memory
= CopyMem (Memory
, Buffer
, AllocationSize
);
846 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
848 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData,
849 copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns
850 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer
851 of 0 size is returned. If there is not enough memory remaining to satisfy the
852 request, then NULL is returned.
854 If Buffer is NULL, then ASSERT().
855 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
857 @param AllocationSize The number of bytes to allocate and zero.
858 @param Buffer The buffer to copy to the allocated buffer.
860 @return A pointer to the allocated buffer or NULL if allocation fails.
866 IN UINTN AllocationSize
,
867 IN CONST VOID
*Buffer
872 NewBuffer
= InternalAllocateCopyPool (EfiRuntimeServicesData
, AllocationSize
, Buffer
);
873 if (NewBuffer
!= NULL
) {
874 MemoryProfileLibRecord (
875 (PHYSICAL_ADDRESS
)(UINTN
)RETURN_ADDRESS (0),
876 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_COPY_POOL
,
877 EfiRuntimeServicesData
,
888 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
890 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData,
891 copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns
892 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer
893 of 0 size is returned. If there is not enough memory remaining to satisfy the
894 request, then NULL is returned.
896 If Buffer is NULL, then ASSERT().
897 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
899 @param AllocationSize The number of bytes to allocate and zero.
900 @param Buffer The buffer to copy to the allocated buffer.
902 @return A pointer to the allocated buffer or NULL if allocation fails.
907 AllocateRuntimeCopyPool (
908 IN UINTN AllocationSize
,
909 IN CONST VOID
*Buffer
914 NewBuffer
= InternalAllocateCopyPool (EfiRuntimeServicesData
, AllocationSize
, Buffer
);
915 if (NewBuffer
!= NULL
) {
916 MemoryProfileLibRecord (
917 (PHYSICAL_ADDRESS
)(UINTN
)RETURN_ADDRESS (0),
918 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_COPY_POOL
,
919 EfiRuntimeServicesData
,
930 Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
932 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType,
933 copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns
934 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer
935 of 0 size is returned. If there is not enough memory remaining to satisfy the
936 request, then NULL is returned.
938 If Buffer is NULL, then ASSERT().
939 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
941 @param AllocationSize The number of bytes to allocate and zero.
942 @param Buffer The buffer to copy to the allocated buffer.
944 @return A pointer to the allocated buffer or NULL if allocation fails.
949 AllocateReservedCopyPool (
950 IN UINTN AllocationSize
,
951 IN CONST VOID
*Buffer
958 Reallocates a buffer of a specified memory type.
960 Allocates and zeros the number bytes specified by NewSize from memory of the type
961 specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and
962 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
963 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
964 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
965 enough memory remaining to satisfy the request, then NULL is returned.
967 If the allocation of the new buffer is successful and the smaller of NewSize
968 and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
970 @param PoolType The type of pool to allocate.
971 @param OldSize The size, in bytes, of OldBuffer.
972 @param NewSize The size, in bytes, of the buffer to reallocate.
973 @param OldBuffer The buffer to copy to the allocated buffer. This is an
974 optional parameter that may be NULL.
976 @return A pointer to the allocated buffer or NULL if allocation fails.
980 InternalReallocatePool (
981 IN EFI_MEMORY_TYPE PoolType
,
984 IN VOID
*OldBuffer OPTIONAL
989 NewBuffer
= InternalAllocateZeroPool (PoolType
, NewSize
);
990 if ((NewBuffer
!= NULL
) && (OldBuffer
!= NULL
)) {
991 CopyMem (NewBuffer
, OldBuffer
, MIN (OldSize
, NewSize
));
992 FreePool (OldBuffer
);
999 Reallocates a buffer of type EfiRuntimeServicesData.
1001 Allocates and zeros the number bytes specified by NewSize from memory of type
1002 EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
1003 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
1004 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
1005 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
1006 enough memory remaining to satisfy the request, then NULL is returned.
1008 If the allocation of the new buffer is successful and the smaller of NewSize
1009 and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
1011 @param OldSize The size, in bytes, of OldBuffer.
1012 @param NewSize The size, in bytes, of the buffer to reallocate.
1013 @param OldBuffer The buffer to copy to the allocated buffer. This is an
1014 optional parameter that may be NULL.
1016 @return A pointer to the allocated buffer or NULL if allocation fails.
1024 IN VOID
*OldBuffer OPTIONAL
1029 Buffer
= InternalReallocatePool (EfiRuntimeServicesData
, OldSize
, NewSize
, OldBuffer
);
1030 if (Buffer
!= NULL
) {
1031 MemoryProfileLibRecord (
1032 (PHYSICAL_ADDRESS
)(UINTN
)RETURN_ADDRESS (0),
1033 MEMORY_PROFILE_ACTION_LIB_REALLOCATE_POOL
,
1034 EfiRuntimeServicesData
,
1045 Reallocates a buffer of type EfiRuntimeServicesData.
1047 Allocates and zeros the number bytes specified by NewSize from memory of type
1048 EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize
1049 and NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
1050 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
1051 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
1052 enough memory remaining to satisfy the request, then NULL is returned.
1054 If the allocation of the new buffer is successful and the smaller of NewSize
1055 and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
1057 @param OldSize The size, in bytes, of OldBuffer.
1058 @param NewSize The size, in bytes, of the buffer to reallocate.
1059 @param OldBuffer The buffer to copy to the allocated buffer. This is an
1060 optional parameter that may be NULL.
1062 @return A pointer to the allocated buffer or NULL if allocation fails.
1067 ReallocateRuntimePool (
1070 IN VOID
*OldBuffer OPTIONAL
1075 Buffer
= InternalReallocatePool (EfiRuntimeServicesData
, OldSize
, NewSize
, OldBuffer
);
1076 if (Buffer
!= NULL
) {
1077 MemoryProfileLibRecord (
1078 (PHYSICAL_ADDRESS
)(UINTN
)RETURN_ADDRESS (0),
1079 MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RUNTIME_POOL
,
1080 EfiRuntimeServicesData
,
1091 Reallocates a buffer of type EfiReservedMemoryType.
1093 Allocates and zeros the number bytes specified by NewSize from memory of type
1094 EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize
1095 and NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
1096 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
1097 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
1098 enough memory remaining to satisfy the request, then NULL is returned.
1100 If the allocation of the new buffer is successful and the smaller of NewSize
1101 and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
1103 @param OldSize The size, in bytes, of OldBuffer.
1104 @param NewSize The size, in bytes, of the buffer to reallocate.
1105 @param OldBuffer The buffer to copy to the allocated buffer. This is an
1106 optional parameter that may be NULL.
1108 @return A pointer to the allocated buffer or NULL if allocation fails.
1113 ReallocateReservedPool (
1116 IN VOID
*OldBuffer OPTIONAL
1123 Frees a buffer that was previously allocated with one of the pool allocation
1124 functions in the Memory Allocation Library.
1126 Frees the buffer specified by Buffer. Buffer must have been allocated on a
1127 previous call to the pool allocation services of the Memory Allocation Library.
1128 If it is not possible to free pool resources, then this function will perform
1131 If Buffer was not allocated with a pool allocation function in the Memory
1132 Allocation Library, then ASSERT().
1134 @param Buffer The pointer to the buffer to free.
1145 if (BufferInSmram (Buffer
)) {
1147 // When Buffer is in SMRAM range, it should be allocated by gSmst->SmmAllocatePool() service.
1148 // So, gSmst->SmmFreePool() service is used to free it.
1150 Status
= gSmst
->SmmFreePool (Buffer
);
1153 // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePool() service.
1154 // So, gBS->FreePool() service is used to free it.
1156 Status
= gBS
->FreePool (Buffer
);
1159 ASSERT_EFI_ERROR (Status
);