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 - 2017, Intel Corporation. All rights reserved.<BR>
16 This program and the accompanying materials
17 are licensed and made available under the terms and conditions of the BSD License
18 which accompanies this distribution. The full text of the license may be found at
19 http://opensource.org/licenses/bsd-license.php.
21 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
22 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
28 #include <Protocol/SmmAccess2.h>
29 #include <Library/MemoryAllocationLib.h>
30 #include <Library/UefiBootServicesTableLib.h>
31 #include <Library/SmmServicesTableLib.h>
32 #include <Library/BaseMemoryLib.h>
33 #include <Library/DebugLib.h>
35 #include <Library/MemoryProfileLib.h>
37 EFI_SMRAM_DESCRIPTOR
*mSmramRanges
;
38 UINTN mSmramRangeCount
;
41 The constructor function caches SMRAM ranges that are present in the system.
43 It will ASSERT() if SMM Access2 Protocol doesn't exist.
44 It will ASSERT() if SMRAM ranges can't be got.
45 It will ASSERT() if Resource can't be allocated for cache SMRAM range.
46 It will always return EFI_SUCCESS.
48 @param ImageHandle The firmware allocated handle for the EFI image.
49 @param SystemTable A pointer to the EFI System Table.
51 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
56 SmmMemoryAllocationLibConstructor (
57 IN EFI_HANDLE ImageHandle
,
58 IN EFI_SYSTEM_TABLE
*SystemTable
62 EFI_SMM_ACCESS2_PROTOCOL
*SmmAccess
;
66 // Locate SMM Access2 Protocol
68 Status
= gBS
->LocateProtocol (
69 &gEfiSmmAccess2ProtocolGuid
,
73 ASSERT_EFI_ERROR (Status
);
76 // Get SMRAM range information
79 Status
= SmmAccess
->GetCapabilities (SmmAccess
, &Size
, NULL
);
80 ASSERT (Status
== EFI_BUFFER_TOO_SMALL
);
82 mSmramRanges
= (EFI_SMRAM_DESCRIPTOR
*) AllocatePool (Size
);
83 ASSERT (mSmramRanges
!= NULL
);
85 Status
= SmmAccess
->GetCapabilities (SmmAccess
, &Size
, mSmramRanges
);
86 ASSERT_EFI_ERROR (Status
);
88 mSmramRangeCount
= Size
/ sizeof (EFI_SMRAM_DESCRIPTOR
);
94 If SMM driver exits with an error, it must call this routine
95 to free the allocated resource before the exiting.
97 @param[in] ImageHandle The firmware allocated handle for the EFI image.
98 @param[in] SystemTable A pointer to the EFI System Table.
100 @retval EFI_SUCCESS The deconstructor always returns EFI_SUCCESS.
104 SmmMemoryAllocationLibDestructor (
105 IN EFI_HANDLE ImageHandle
,
106 IN EFI_SYSTEM_TABLE
*SystemTable
109 FreePool (mSmramRanges
);
115 Check whether the start address of buffer is within any of the SMRAM ranges.
117 @param[in] Buffer The pointer to the buffer to be checked.
119 @retval TRUE The buffer is in SMRAM ranges.
120 @retval FALSE The buffer is out of SMRAM ranges.
130 for (Index
= 0; Index
< mSmramRangeCount
; Index
++) {
131 if (((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
>= mSmramRanges
[Index
].CpuStart
) &&
132 ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
< (mSmramRanges
[Index
].CpuStart
+ mSmramRanges
[Index
].PhysicalSize
))) {
141 Allocates one or more 4KB pages of a certain memory type.
143 Allocates the number of 4KB pages of a certain memory type and returns a pointer
144 to the allocated buffer. The buffer returned is aligned on a 4KB boundary. If
145 Pages is 0, then NULL is returned. If there is not enough memory remaining to
146 satisfy the request, then NULL is returned.
148 @param MemoryType The type of memory to allocate.
149 @param Pages The number of 4 KB pages to allocate.
151 @return A pointer to the allocated buffer or NULL if allocation fails.
155 InternalAllocatePages (
156 IN EFI_MEMORY_TYPE MemoryType
,
161 EFI_PHYSICAL_ADDRESS Memory
;
167 Status
= gSmst
->SmmAllocatePages (AllocateAnyPages
, MemoryType
, Pages
, &Memory
);
168 if (EFI_ERROR (Status
)) {
171 return (VOID
*) (UINTN
) Memory
;
175 Allocates one or more 4KB pages of type EfiRuntimeServicesData.
177 Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer
178 to the allocated buffer. The buffer returned is aligned on a 4KB boundary. If
179 Pages is 0, then NULL is returned. If there is not enough memory remaining to
180 satisfy the request, then NULL is returned.
182 @param Pages The number of 4 KB pages to allocate.
184 @return A pointer to the allocated buffer or NULL if allocation fails.
195 Buffer
= InternalAllocatePages (EfiRuntimeServicesData
, Pages
);
196 if (Buffer
!= NULL
) {
197 MemoryProfileLibRecord (
198 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
199 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_PAGES
,
200 EfiRuntimeServicesData
,
202 EFI_PAGES_TO_SIZE(Pages
),
210 Allocates one or more 4KB pages of type EfiRuntimeServicesData.
212 Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a
213 pointer to the allocated buffer. The buffer returned is aligned on a 4KB boundary.
214 If Pages is 0, then NULL is returned. If there is not enough memory remaining
215 to satisfy the request, then NULL is returned.
217 @param Pages The number of 4 KB pages to allocate.
219 @return A pointer to the allocated buffer or NULL if allocation fails.
224 AllocateRuntimePages (
230 Buffer
= InternalAllocatePages (EfiRuntimeServicesData
, Pages
);
231 if (Buffer
!= NULL
) {
232 MemoryProfileLibRecord (
233 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
234 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_PAGES
,
235 EfiRuntimeServicesData
,
237 EFI_PAGES_TO_SIZE(Pages
),
245 Allocates one or more 4KB pages of type EfiReservedMemoryType.
247 Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a
248 pointer to the allocated buffer. The buffer returned is aligned on a 4KB boundary.
249 If Pages is 0, then NULL is returned. If there is not enough memory remaining
250 to satisfy the request, then NULL is returned.
252 @param Pages The number of 4 KB pages to allocate.
254 @return A pointer to the allocated buffer or NULL if allocation fails.
259 AllocateReservedPages (
267 Frees one or more 4KB pages that were previously allocated with one of the page allocation
268 functions in the Memory Allocation Library.
270 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer.
271 Buffer must have been allocated on a previous call to the page allocation services
272 of the Memory Allocation Library. If it is not possible to free allocated pages,
273 then this function will perform no actions.
275 If Buffer was not allocated with a page allocation function in the Memory Allocation
276 Library, then ASSERT().
277 If Pages is zero, then ASSERT().
279 @param Buffer The pointer to the buffer of pages to free.
280 @param Pages The number of 4 KB pages to free.
293 if (BufferInSmram (Buffer
)) {
295 // When Buffer is in SMRAM range, it should be allocated by gSmst->SmmAllocatePages() service.
296 // So, gSmst->SmmFreePages() service is used to free it.
298 Status
= gSmst
->SmmFreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
, Pages
);
301 // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePages() service.
302 // So, gBS->FreePages() service is used to free it.
304 Status
= gBS
->FreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
, Pages
);
306 ASSERT_EFI_ERROR (Status
);
310 Allocates one or more 4KB pages of a certain memory type at a specified alignment.
312 Allocates the number of 4KB pages specified by Pages of a certain memory type
313 with an alignment specified by Alignment. The allocated buffer is returned.
314 If Pages is 0, then NULL is returned. If there is not enough memory at the
315 specified alignment remaining to satisfy the request, then NULL is returned.
316 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
317 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
319 @param MemoryType The type of memory to allocate.
320 @param Pages The number of 4 KB pages to allocate.
321 @param Alignment The requested alignment of the allocation.
322 Must be a power of two.
323 If Alignment is zero, then byte alignment is used.
325 @return A pointer to the allocated buffer or NULL if allocation fails.
329 InternalAllocateAlignedPages (
330 IN EFI_MEMORY_TYPE MemoryType
,
336 EFI_PHYSICAL_ADDRESS Memory
;
339 UINTN UnalignedPages
;
343 // Alignment must be a power of two or zero.
345 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
)) {
365 AlignedMemory
= ((UINTN
) Memory
+ AlignmentMask
) & ~AlignmentMask
;
366 UnalignedPages
= EFI_SIZE_TO_PAGES (AlignedMemory
- (UINTN
) Memory
);
367 if (UnalignedPages
> 0) {
369 // Free first unaligned page(s).
371 Status
= gSmst
->SmmFreePages (Memory
, UnalignedPages
);
372 ASSERT_EFI_ERROR (Status
);
374 Memory
= AlignedMemory
+ EFI_PAGES_TO_SIZE (Pages
);
375 UnalignedPages
= RealPages
- Pages
- UnalignedPages
;
376 if (UnalignedPages
> 0) {
378 // Free last unaligned page(s).
380 Status
= gSmst
->SmmFreePages (Memory
, UnalignedPages
);
381 ASSERT_EFI_ERROR (Status
);
385 // Do not over-allocate pages in this case.
387 Status
= gSmst
->SmmAllocatePages (AllocateAnyPages
, MemoryType
, Pages
, &Memory
);
388 if (EFI_ERROR (Status
)) {
391 AlignedMemory
= (UINTN
) Memory
;
393 return (VOID
*) AlignedMemory
;
397 Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
399 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData
400 with an alignment specified by Alignment. The allocated buffer is returned.
401 If Pages is 0, then NULL is returned. If there is not enough memory at the
402 specified alignment remaining to satisfy the request, then NULL is returned.
404 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
405 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
407 @param Pages The number of 4 KB pages to allocate.
408 @param Alignment The requested alignment of the allocation.
409 Must be a power of two.
410 If Alignment is zero, then byte alignment is used.
412 @return A pointer to the allocated buffer or NULL if allocation fails.
417 AllocateAlignedPages (
424 Buffer
= InternalAllocateAlignedPages (EfiRuntimeServicesData
, Pages
, Alignment
);
425 if (Buffer
!= NULL
) {
426 MemoryProfileLibRecord (
427 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
428 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_PAGES
,
429 EfiRuntimeServicesData
,
431 EFI_PAGES_TO_SIZE(Pages
),
439 Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
441 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData
442 with an alignment specified by Alignment. The allocated buffer is returned.
443 If Pages is 0, then NULL is returned. If there is not enough memory at the
444 specified alignment remaining to satisfy the request, then NULL is returned.
446 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
447 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
449 @param Pages The number of 4 KB pages to allocate.
450 @param Alignment The requested alignment of the allocation.
451 Must be a power of two.
452 If Alignment is zero, then byte alignment is used.
454 @return A pointer to the allocated buffer or NULL if allocation fails.
459 AllocateAlignedRuntimePages (
466 Buffer
= InternalAllocateAlignedPages (EfiRuntimeServicesData
, Pages
, Alignment
);
467 if (Buffer
!= NULL
) {
468 MemoryProfileLibRecord (
469 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
470 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RUNTIME_PAGES
,
471 EfiRuntimeServicesData
,
473 EFI_PAGES_TO_SIZE(Pages
),
481 Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
483 Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType
484 with an alignment specified by Alignment. The allocated buffer is returned.
485 If Pages is 0, then NULL is returned. If there is not enough memory at the
486 specified alignment remaining to satisfy the request, then NULL is returned.
488 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
489 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
491 @param Pages The number of 4 KB pages to allocate.
492 @param Alignment The requested alignment of the allocation.
493 Must be a power of two.
494 If Alignment is zero, then byte alignment is used.
496 @return A pointer to the allocated buffer or NULL if allocation fails.
501 AllocateAlignedReservedPages (
510 Frees one or more 4KB pages that were previously allocated with one of the aligned page
511 allocation functions in the Memory Allocation Library.
513 Frees the number of 4KB pages specified by Pages from the buffer specified by
514 Buffer. Buffer must have been allocated on a previous call to the aligned page
515 allocation services of the Memory Allocation Library. If it is not possible to
516 free allocated pages, then this function will perform no actions.
518 If Buffer was not allocated with an aligned page allocation function in the
519 Memory Allocation Library, then ASSERT().
520 If Pages is zero, then ASSERT().
522 @param Buffer The pointer to the buffer of pages to free.
523 @param Pages The number of 4 KB pages to free.
536 if (BufferInSmram (Buffer
)) {
538 // When Buffer is in SMRAM range, it should be allocated by gSmst->SmmAllocatePages() service.
539 // So, gSmst->SmmFreePages() service is used to free it.
541 Status
= gSmst
->SmmFreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
, Pages
);
544 // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePages() service.
545 // So, gBS->FreePages() service is used to free it.
547 Status
= gBS
->FreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
, Pages
);
549 ASSERT_EFI_ERROR (Status
);
553 Allocates a buffer of a certain pool type.
555 Allocates the number bytes specified by AllocationSize of a certain pool type
556 and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
557 valid buffer of 0 size is returned. If there is not enough memory remaining to
558 satisfy the request, then NULL is returned.
560 @param MemoryType The type of memory to allocate.
561 @param AllocationSize The number of bytes to allocate.
563 @return A pointer to the allocated buffer or NULL if allocation fails.
567 InternalAllocatePool (
568 IN EFI_MEMORY_TYPE MemoryType
,
569 IN UINTN AllocationSize
575 Status
= gSmst
->SmmAllocatePool (MemoryType
, AllocationSize
, &Memory
);
576 if (EFI_ERROR (Status
)) {
583 Allocates a buffer of type EfiRuntimeServicesData.
585 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData
586 and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
587 valid buffer of 0 size is returned. If there is not enough memory remaining to
588 satisfy the request, then NULL is returned.
590 @param AllocationSize The number of bytes to allocate.
592 @return A pointer to the allocated buffer or NULL if allocation fails.
598 IN UINTN AllocationSize
603 Buffer
= InternalAllocatePool (EfiRuntimeServicesData
, AllocationSize
);
604 if (Buffer
!= NULL
) {
605 MemoryProfileLibRecord (
606 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
607 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_POOL
,
608 EfiRuntimeServicesData
,
618 Allocates a buffer of type EfiRuntimeServicesData.
620 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData
621 and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
622 valid buffer of 0 size is returned. If there is not enough memory remaining to
623 satisfy the request, then NULL is returned.
625 @param AllocationSize The number of bytes to allocate.
627 @return A pointer to the allocated buffer or NULL if allocation fails.
632 AllocateRuntimePool (
633 IN UINTN AllocationSize
638 Buffer
= InternalAllocatePool (EfiRuntimeServicesData
, AllocationSize
);
639 if (Buffer
!= NULL
) {
640 MemoryProfileLibRecord (
641 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
642 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_POOL
,
643 EfiRuntimeServicesData
,
653 Allocates a buffer of type EfiReservedMemoryType.
655 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType
656 and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
657 valid buffer of 0 size is returned. If there is not enough memory remaining to
658 satisfy the request, then NULL is returned.
660 @param AllocationSize The number of bytes to allocate.
662 @return A pointer to the allocated buffer or NULL if allocation fails.
667 AllocateReservedPool (
668 IN UINTN AllocationSize
675 Allocates and zeros a buffer of a certain pool type.
677 Allocates the number bytes specified by AllocationSize of a certain pool type,
678 clears the buffer with zeros, and returns a pointer to the allocated buffer.
679 If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is
680 not enough memory remaining to satisfy the request, then NULL is returned.
682 @param PoolType The type of memory to allocate.
683 @param AllocationSize The number of bytes to allocate and zero.
685 @return A pointer to the allocated buffer or NULL if allocation fails.
689 InternalAllocateZeroPool (
690 IN EFI_MEMORY_TYPE PoolType
,
691 IN UINTN AllocationSize
696 Memory
= InternalAllocatePool (PoolType
, AllocationSize
);
697 if (Memory
!= NULL
) {
698 Memory
= ZeroMem (Memory
, AllocationSize
);
704 Allocates and zeros a buffer of type EfiRuntimeServicesData.
706 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData,
707 clears the buffer with zeros, and returns a pointer to the allocated buffer.
708 If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is
709 not enough memory remaining to satisfy the request, then NULL is returned.
711 @param AllocationSize The number of bytes to allocate and zero.
713 @return A pointer to the allocated buffer or NULL if allocation fails.
719 IN UINTN AllocationSize
724 Buffer
= InternalAllocateZeroPool (EfiRuntimeServicesData
, AllocationSize
);
725 if (Buffer
!= NULL
) {
726 MemoryProfileLibRecord (
727 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
728 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ZERO_POOL
,
729 EfiRuntimeServicesData
,
739 Allocates and zeros a buffer of type EfiRuntimeServicesData.
741 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData,
742 clears the buffer with zeros, and returns a pointer to the allocated buffer.
743 If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is
744 not enough memory remaining to satisfy the request, then NULL is returned.
746 @param AllocationSize The number of bytes to allocate and zero.
748 @return A pointer to the allocated buffer or NULL if allocation fails.
753 AllocateRuntimeZeroPool (
754 IN UINTN AllocationSize
759 Buffer
= InternalAllocateZeroPool (EfiRuntimeServicesData
, AllocationSize
);
760 if (Buffer
!= NULL
) {
761 MemoryProfileLibRecord (
762 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
763 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_ZERO_POOL
,
764 EfiRuntimeServicesData
,
774 Allocates and zeros a buffer of type EfiReservedMemoryType.
776 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType,
777 clears the buffer with zeros, and returns a pointer to the allocated buffer.
778 If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is
779 not enough memory remaining to satisfy the request, then NULL is returned.
781 @param AllocationSize The number of bytes to allocate and zero.
783 @return A pointer to the allocated buffer or NULL if allocation fails.
788 AllocateReservedZeroPool (
789 IN UINTN AllocationSize
796 Copies a buffer to an allocated buffer of a certain pool type.
798 Allocates the number bytes specified by AllocationSize of a certain pool type,
799 copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns
800 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer
801 of 0 size is returned. If there is not enough memory remaining to satisfy the
802 request, then NULL is returned. If Buffer is NULL, then ASSERT().
803 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
805 @param PoolType The type of pool to allocate.
806 @param AllocationSize The number of bytes to allocate and zero.
807 @param Buffer The buffer to copy to the allocated buffer.
809 @return A pointer to the allocated buffer or NULL if allocation fails.
813 InternalAllocateCopyPool (
814 IN EFI_MEMORY_TYPE PoolType
,
815 IN UINTN AllocationSize
,
816 IN CONST VOID
*Buffer
821 ASSERT (Buffer
!= NULL
);
822 ASSERT (AllocationSize
<= (MAX_ADDRESS
- (UINTN
) Buffer
+ 1));
824 Memory
= InternalAllocatePool (PoolType
, AllocationSize
);
825 if (Memory
!= NULL
) {
826 Memory
= CopyMem (Memory
, Buffer
, AllocationSize
);
832 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
834 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData,
835 copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns
836 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer
837 of 0 size is returned. If there is not enough memory remaining to satisfy the
838 request, then NULL is returned.
840 If Buffer is NULL, then ASSERT().
841 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
843 @param AllocationSize The number of bytes to allocate and zero.
844 @param Buffer The buffer to copy to the allocated buffer.
846 @return A pointer to the allocated buffer or NULL if allocation fails.
852 IN UINTN AllocationSize
,
853 IN CONST VOID
*Buffer
858 NewBuffer
= InternalAllocateCopyPool (EfiRuntimeServicesData
, AllocationSize
, Buffer
);
859 if (NewBuffer
!= NULL
) {
860 MemoryProfileLibRecord (
861 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
862 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_COPY_POOL
,
863 EfiRuntimeServicesData
,
873 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
875 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData,
876 copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns
877 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer
878 of 0 size is returned. If there is not enough memory remaining to satisfy the
879 request, then NULL is returned.
881 If Buffer is NULL, then ASSERT().
882 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
884 @param AllocationSize The number of bytes to allocate and zero.
885 @param Buffer The buffer to copy to the allocated buffer.
887 @return A pointer to the allocated buffer or NULL if allocation fails.
892 AllocateRuntimeCopyPool (
893 IN UINTN AllocationSize
,
894 IN CONST VOID
*Buffer
899 NewBuffer
= InternalAllocateCopyPool (EfiRuntimeServicesData
, AllocationSize
, Buffer
);
900 if (NewBuffer
!= NULL
) {
901 MemoryProfileLibRecord (
902 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
903 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_COPY_POOL
,
904 EfiRuntimeServicesData
,
914 Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
916 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType,
917 copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns
918 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer
919 of 0 size is returned. If there is not enough memory remaining to satisfy the
920 request, then NULL is returned.
922 If Buffer is NULL, then ASSERT().
923 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
925 @param AllocationSize The number of bytes to allocate and zero.
926 @param Buffer The buffer to copy to the allocated buffer.
928 @return A pointer to the allocated buffer or NULL if allocation fails.
933 AllocateReservedCopyPool (
934 IN UINTN AllocationSize
,
935 IN CONST VOID
*Buffer
942 Reallocates a buffer of a specified memory type.
944 Allocates and zeros the number bytes specified by NewSize from memory of the type
945 specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and
946 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
947 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
948 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
949 enough memory remaining to satisfy the request, then NULL is returned.
951 If the allocation of the new buffer is successful and the smaller of NewSize
952 and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
954 @param PoolType The type of pool to allocate.
955 @param OldSize The size, in bytes, of OldBuffer.
956 @param NewSize The size, in bytes, of the buffer to reallocate.
957 @param OldBuffer The buffer to copy to the allocated buffer. This is an
958 optional parameter that may be NULL.
960 @return A pointer to the allocated buffer or NULL if allocation fails.
964 InternalReallocatePool (
965 IN EFI_MEMORY_TYPE PoolType
,
968 IN VOID
*OldBuffer OPTIONAL
973 NewBuffer
= InternalAllocateZeroPool (PoolType
, NewSize
);
974 if (NewBuffer
!= NULL
&& OldBuffer
!= NULL
) {
975 CopyMem (NewBuffer
, OldBuffer
, MIN (OldSize
, NewSize
));
976 FreePool (OldBuffer
);
982 Reallocates a buffer of type EfiRuntimeServicesData.
984 Allocates and zeros the number bytes specified by NewSize from memory of type
985 EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
986 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
987 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
988 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
989 enough memory remaining to satisfy the request, then NULL is returned.
991 If the allocation of the new buffer is successful and the smaller of NewSize
992 and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
994 @param OldSize The size, in bytes, of OldBuffer.
995 @param NewSize The size, in bytes, of the buffer to reallocate.
996 @param OldBuffer The buffer to copy to the allocated buffer. This is an
997 optional parameter that may be NULL.
999 @return A pointer to the allocated buffer or NULL if allocation fails.
1007 IN VOID
*OldBuffer OPTIONAL
1012 Buffer
= InternalReallocatePool (EfiRuntimeServicesData
, OldSize
, NewSize
, OldBuffer
);
1013 if (Buffer
!= NULL
) {
1014 MemoryProfileLibRecord (
1015 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
1016 MEMORY_PROFILE_ACTION_LIB_REALLOCATE_POOL
,
1017 EfiRuntimeServicesData
,
1027 Reallocates a buffer of type EfiRuntimeServicesData.
1029 Allocates and zeros the number bytes specified by NewSize from memory of type
1030 EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize
1031 and NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
1032 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
1033 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
1034 enough memory remaining to satisfy the request, then NULL is returned.
1036 If the allocation of the new buffer is successful and the smaller of NewSize
1037 and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
1039 @param OldSize The size, in bytes, of OldBuffer.
1040 @param NewSize The size, in bytes, of the buffer to reallocate.
1041 @param OldBuffer The buffer to copy to the allocated buffer. This is an
1042 optional parameter that may be NULL.
1044 @return A pointer to the allocated buffer or NULL if allocation fails.
1049 ReallocateRuntimePool (
1052 IN VOID
*OldBuffer OPTIONAL
1057 Buffer
= InternalReallocatePool (EfiRuntimeServicesData
, OldSize
, NewSize
, OldBuffer
);
1058 if (Buffer
!= NULL
) {
1059 MemoryProfileLibRecord (
1060 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
1061 MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RUNTIME_POOL
,
1062 EfiRuntimeServicesData
,
1072 Reallocates a buffer of type EfiReservedMemoryType.
1074 Allocates and zeros the number bytes specified by NewSize from memory of type
1075 EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize
1076 and NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
1077 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
1078 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
1079 enough memory remaining to satisfy the request, then NULL is returned.
1081 If the allocation of the new buffer is successful and the smaller of NewSize
1082 and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
1084 @param OldSize The size, in bytes, of OldBuffer.
1085 @param NewSize The size, in bytes, of the buffer to reallocate.
1086 @param OldBuffer The buffer to copy to the allocated buffer. This is an
1087 optional parameter that may be NULL.
1089 @return A pointer to the allocated buffer or NULL if allocation fails.
1094 ReallocateReservedPool (
1097 IN VOID
*OldBuffer OPTIONAL
1104 Frees a buffer that was previously allocated with one of the pool allocation
1105 functions in the Memory Allocation Library.
1107 Frees the buffer specified by Buffer. Buffer must have been allocated on a
1108 previous call to the pool allocation services of the Memory Allocation Library.
1109 If it is not possible to free pool resources, then this function will perform
1112 If Buffer was not allocated with a pool allocation function in the Memory
1113 Allocation Library, then ASSERT().
1115 @param Buffer The pointer to the buffer to free.
1126 if (BufferInSmram (Buffer
)) {
1128 // When Buffer is in SMRAM range, it should be allocated by gSmst->SmmAllocatePool() service.
1129 // So, gSmst->SmmFreePool() service is used to free it.
1131 Status
= gSmst
->SmmFreePool (Buffer
);
1134 // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePool() service.
1135 // So, gBS->FreePool() service is used to free it.
1137 Status
= gBS
->FreePool (Buffer
);
1139 ASSERT_EFI_ERROR (Status
);