2 Support routines for memory allocation routines based on SMM Core internal functions,
3 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 as the SMRAM space should be reserved after BDS phase. The functions
8 in the Memory Allocation Library use EfiBootServicesData as the default memory
9 allocation type. For this SMM specific instance of the Memory Allocation Library,
10 EfiRuntimeServicesData is used as the default memory type for all allocations.
11 In addition, allocation for the Reserved memory types are not supported and will
14 Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
15 This program and the accompanying materials
16 are licensed and made available under the terms and conditions of the BSD License
17 which accompanies this distribution. The full text of the license may be found at
18 http://opensource.org/licenses/bsd-license.php
20 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
21 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
27 #include <Library/MemoryAllocationLib.h>
28 #include <Library/UefiBootServicesTableLib.h>
29 #include <Library/BaseMemoryLib.h>
30 #include <Library/DebugLib.h>
31 #include "PiSmmCoreMemoryAllocationServices.h"
33 #include <Library/MemoryProfileLib.h>
35 EFI_SMRAM_DESCRIPTOR
*mSmmCoreMemoryAllocLibSmramRanges
= NULL
;
36 UINTN mSmmCoreMemoryAllocLibSmramRangeCount
= 0;
39 Check whether the start address of buffer is within any of the SMRAM ranges.
41 @param[in] Buffer The pointer to the buffer to be checked.
43 @retval TRUE The buffer is in SMRAM ranges.
44 @retval FALSE The buffer is out of SMRAM ranges.
54 for (Index
= 0; Index
< mSmmCoreMemoryAllocLibSmramRangeCount
; Index
++) {
55 if (((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
>= mSmmCoreMemoryAllocLibSmramRanges
[Index
].CpuStart
) &&
56 ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
< (mSmmCoreMemoryAllocLibSmramRanges
[Index
].CpuStart
+ mSmmCoreMemoryAllocLibSmramRanges
[Index
].PhysicalSize
))) {
65 Allocates one or more 4KB pages of a certain memory type.
67 Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated
68 buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL is returned.
69 If there is not enough memory remaining to satisfy the request, then NULL is returned.
71 @param MemoryType The type of memory to allocate.
72 @param Pages The number of 4 KB pages to allocate.
74 @return A pointer to the allocated buffer or NULL if allocation fails.
78 InternalAllocatePages (
79 IN EFI_MEMORY_TYPE MemoryType
,
84 EFI_PHYSICAL_ADDRESS Memory
;
90 Status
= SmmAllocatePages (AllocateAnyPages
, MemoryType
, Pages
, &Memory
);
91 if (EFI_ERROR (Status
)) {
94 return (VOID
*) (UINTN
) Memory
;
98 Allocates one or more 4KB pages of type EfiRuntimeServicesData.
100 Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
101 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
102 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
105 @param Pages The number of 4 KB pages to allocate.
107 @return A pointer to the allocated buffer or NULL if allocation fails.
118 Buffer
= InternalAllocatePages (EfiRuntimeServicesData
, Pages
);
119 if (Buffer
!= NULL
) {
120 MemoryProfileLibRecord (
121 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
122 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_PAGES
,
123 EfiRuntimeServicesData
,
125 EFI_PAGES_TO_SIZE(Pages
),
133 Allocates one or more 4KB pages of type EfiRuntimeServicesData.
135 Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
136 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
137 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
140 @param Pages The number of 4 KB pages to allocate.
142 @return A pointer to the allocated buffer or NULL if allocation fails.
147 AllocateRuntimePages (
153 Buffer
= InternalAllocatePages (EfiRuntimeServicesData
, Pages
);
154 if (Buffer
!= NULL
) {
155 MemoryProfileLibRecord (
156 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
157 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_PAGES
,
158 EfiRuntimeServicesData
,
160 EFI_PAGES_TO_SIZE(Pages
),
168 Allocates one or more 4KB pages of type EfiReservedMemoryType.
170 Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the
171 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
172 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
175 @param Pages The number of 4 KB pages to allocate.
177 @return A pointer to the allocated buffer or NULL if allocation fails.
182 AllocateReservedPages (
190 Frees one or more 4KB pages that were previously allocated with one of the page allocation
191 functions in the Memory Allocation Library.
193 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
194 must have been allocated on a previous call to the page allocation services of the Memory
195 Allocation Library. If it is not possible to free allocated pages, then this function will
198 If Buffer was not allocated with a page allocation function in the Memory Allocation Library,
200 If Pages is zero, then ASSERT().
202 @param Buffer Pointer to the buffer of pages to free.
203 @param Pages The number of 4 KB pages to free.
216 if (BufferInSmram (Buffer
)) {
218 // When Buffer is in SMRAM range, it should be allocated by SmmAllocatePages() service.
219 // So, SmmFreePages() service is used to free it.
221 Status
= SmmFreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
, Pages
);
224 // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePages() service.
225 // So, gBS->FreePages() service is used to free it.
227 Status
= gBS
->FreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
, Pages
);
229 ASSERT_EFI_ERROR (Status
);
233 Allocates one or more 4KB pages of a certain memory type at a specified alignment.
235 Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment
236 specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned.
237 If there is not enough memory at the specified alignment remaining to satisfy the request, then
239 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
240 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
242 @param MemoryType The type of memory to allocate.
243 @param Pages The number of 4 KB pages to allocate.
244 @param Alignment The requested alignment of the allocation. Must be a power of two.
245 If Alignment is zero, then byte alignment is used.
247 @return A pointer to the allocated buffer or NULL if allocation fails.
251 InternalAllocateAlignedPages (
252 IN EFI_MEMORY_TYPE MemoryType
,
258 EFI_PHYSICAL_ADDRESS Memory
;
261 UINTN UnalignedPages
;
265 // Alignment must be a power of two or zero.
267 ASSERT ((Alignment
& (Alignment
- 1)) == 0);
272 if (Alignment
> EFI_PAGE_SIZE
) {
274 // Calculate the total number of pages since alignment is larger than page size.
276 AlignmentMask
= Alignment
- 1;
277 RealPages
= Pages
+ EFI_SIZE_TO_PAGES (Alignment
);
279 // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
281 ASSERT (RealPages
> Pages
);
283 Status
= SmmAllocatePages (AllocateAnyPages
, MemoryType
, RealPages
, &Memory
);
284 if (EFI_ERROR (Status
)) {
287 AlignedMemory
= ((UINTN
) Memory
+ AlignmentMask
) & ~AlignmentMask
;
288 UnalignedPages
= EFI_SIZE_TO_PAGES (AlignedMemory
- (UINTN
) Memory
);
289 if (UnalignedPages
> 0) {
291 // Free first unaligned page(s).
293 Status
= SmmFreePages (Memory
, UnalignedPages
);
294 ASSERT_EFI_ERROR (Status
);
296 Memory
= (EFI_PHYSICAL_ADDRESS
) (AlignedMemory
+ EFI_PAGES_TO_SIZE (Pages
));
297 UnalignedPages
= RealPages
- Pages
- UnalignedPages
;
298 if (UnalignedPages
> 0) {
300 // Free last unaligned page(s).
302 Status
= SmmFreePages (Memory
, UnalignedPages
);
303 ASSERT_EFI_ERROR (Status
);
307 // Do not over-allocate pages in this case.
309 Status
= SmmAllocatePages (AllocateAnyPages
, MemoryType
, Pages
, &Memory
);
310 if (EFI_ERROR (Status
)) {
313 AlignedMemory
= (UINTN
) Memory
;
315 return (VOID
*) AlignedMemory
;
319 Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
321 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an
322 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
323 returned. If there is not enough memory at the specified alignment remaining to satisfy the
324 request, then NULL is returned.
326 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
327 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
329 @param Pages The number of 4 KB pages to allocate.
330 @param Alignment The requested alignment of the allocation. Must be a power of two.
331 If Alignment is zero, then byte alignment is used.
333 @return A pointer to the allocated buffer or NULL if allocation fails.
338 AllocateAlignedPages (
345 Buffer
= InternalAllocateAlignedPages (EfiRuntimeServicesData
, Pages
, Alignment
);
346 if (Buffer
!= NULL
) {
347 MemoryProfileLibRecord (
348 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
349 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_PAGES
,
350 EfiRuntimeServicesData
,
352 EFI_PAGES_TO_SIZE(Pages
),
360 Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
362 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an
363 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
364 returned. If there is not enough memory at the specified alignment remaining to satisfy the
365 request, then NULL is returned.
367 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
368 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
370 @param Pages The number of 4 KB pages to allocate.
371 @param Alignment The requested alignment of the allocation. Must be a power of two.
372 If Alignment is zero, then byte alignment is used.
374 @return A pointer to the allocated buffer or NULL if allocation fails.
379 AllocateAlignedRuntimePages (
386 Buffer
= InternalAllocateAlignedPages (EfiRuntimeServicesData
, Pages
, Alignment
);
387 if (Buffer
!= NULL
) {
388 MemoryProfileLibRecord (
389 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
390 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RUNTIME_PAGES
,
391 EfiRuntimeServicesData
,
393 EFI_PAGES_TO_SIZE(Pages
),
401 Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
403 Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an
404 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
405 returned. If there is not enough memory at the specified alignment remaining to satisfy the
406 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. Must be a power of two.
413 If Alignment is zero, then byte alignment is used.
415 @return A pointer to the allocated buffer or NULL if allocation fails.
420 AllocateAlignedReservedPages (
429 Frees one or more 4KB pages that were previously allocated with one of the aligned page
430 allocation functions in the Memory Allocation Library.
432 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
433 must have been allocated on a previous call to the aligned page allocation services of the Memory
434 Allocation Library. If it is not possible to free allocated pages, then this function will
437 If Buffer was not allocated with an aligned page allocation function in the Memory Allocation
438 Library, then ASSERT().
439 If Pages is zero, then ASSERT().
441 @param Buffer Pointer to the buffer of pages to free.
442 @param Pages The number of 4 KB pages to free.
455 if (BufferInSmram (Buffer
)) {
457 // When Buffer is in SMRAM range, it should be allocated by SmmAllocatePages() service.
458 // So, SmmFreePages() service is used to free it.
460 Status
= SmmFreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
, Pages
);
463 // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePages() service.
464 // So, gBS->FreePages() service is used to free it.
466 Status
= gBS
->FreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
, Pages
);
468 ASSERT_EFI_ERROR (Status
);
472 Allocates a buffer of a certain pool type.
474 Allocates the number bytes specified by AllocationSize of a certain pool type and returns a
475 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
476 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
478 @param MemoryType The type of memory to allocate.
479 @param AllocationSize The number of bytes to allocate.
481 @return A pointer to the allocated buffer or NULL if allocation fails.
485 InternalAllocatePool (
486 IN EFI_MEMORY_TYPE MemoryType
,
487 IN UINTN AllocationSize
495 Status
= SmmAllocatePool (MemoryType
, AllocationSize
, &Memory
);
496 if (EFI_ERROR (Status
)) {
503 Allocates a buffer of type EfiRuntimeServicesData.
505 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns a
506 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
507 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
509 @param AllocationSize The number of bytes to allocate.
511 @return A pointer to the allocated buffer or NULL if allocation fails.
517 IN UINTN AllocationSize
522 Buffer
= InternalAllocatePool (EfiRuntimeServicesData
, AllocationSize
);
523 if (Buffer
!= NULL
) {
524 MemoryProfileLibRecord (
525 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
526 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_POOL
,
527 EfiRuntimeServicesData
,
537 Allocates a buffer of type EfiRuntimeServicesData.
539 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns
540 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
541 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
543 @param AllocationSize The number of bytes to allocate.
545 @return A pointer to the allocated buffer or NULL if allocation fails.
550 AllocateRuntimePool (
551 IN UINTN AllocationSize
556 Buffer
= InternalAllocatePool (EfiRuntimeServicesData
, AllocationSize
);
557 if (Buffer
!= NULL
) {
558 MemoryProfileLibRecord (
559 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
560 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_POOL
,
561 EfiRuntimeServicesData
,
571 Allocates a buffer of type EfiReservedMemoryType.
573 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns
574 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
575 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
577 @param AllocationSize The number of bytes to allocate.
579 @return A pointer to the allocated buffer or NULL if allocation fails.
584 AllocateReservedPool (
585 IN UINTN AllocationSize
592 Allocates and zeros a buffer of a certain pool type.
594 Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer
595 with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid
596 buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request,
597 then NULL is returned.
599 @param PoolType The type of memory to allocate.
600 @param AllocationSize The number of bytes to allocate and zero.
602 @return A pointer to the allocated buffer or NULL if allocation fails.
606 InternalAllocateZeroPool (
607 IN EFI_MEMORY_TYPE PoolType
,
608 IN UINTN AllocationSize
613 Memory
= InternalAllocatePool (PoolType
, AllocationSize
);
614 if (Memory
!= NULL
) {
615 Memory
= ZeroMem (Memory
, AllocationSize
);
621 Allocates and zeros a buffer of type EfiRuntimeServicesData.
623 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the
624 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
625 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
626 request, then NULL is returned.
628 @param AllocationSize The number of bytes to allocate and zero.
630 @return A pointer to the allocated buffer or NULL if allocation fails.
636 IN UINTN AllocationSize
641 Buffer
= InternalAllocateZeroPool (EfiRuntimeServicesData
, AllocationSize
);
642 if (Buffer
!= NULL
) {
643 MemoryProfileLibRecord (
644 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
645 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ZERO_POOL
,
646 EfiRuntimeServicesData
,
656 Allocates and zeros a buffer of type EfiRuntimeServicesData.
658 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the
659 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
660 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
661 request, then NULL is returned.
663 @param AllocationSize The number of bytes to allocate and zero.
665 @return A pointer to the allocated buffer or NULL if allocation fails.
670 AllocateRuntimeZeroPool (
671 IN UINTN AllocationSize
676 Buffer
= InternalAllocateZeroPool (EfiRuntimeServicesData
, AllocationSize
);
677 if (Buffer
!= NULL
) {
678 MemoryProfileLibRecord (
679 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
680 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_ZERO_POOL
,
681 EfiRuntimeServicesData
,
691 Allocates and zeros a buffer of type EfiReservedMemoryType.
693 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the
694 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
695 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
696 request, then NULL is returned.
698 @param AllocationSize The number of bytes to allocate and zero.
700 @return A pointer to the allocated buffer or NULL if allocation fails.
705 AllocateReservedZeroPool (
706 IN UINTN AllocationSize
713 Copies a buffer to an allocated buffer of a certain pool type.
715 Allocates the number bytes specified by AllocationSize of a certain pool type, copies
716 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
717 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
718 is not enough memory remaining to satisfy the request, then NULL is returned.
719 If Buffer is NULL, then ASSERT().
720 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
722 @param PoolType The type of pool to allocate.
723 @param AllocationSize The number of bytes to allocate and zero.
724 @param Buffer The buffer to copy to the allocated buffer.
726 @return A pointer to the allocated buffer or NULL if allocation fails.
730 InternalAllocateCopyPool (
731 IN EFI_MEMORY_TYPE PoolType
,
732 IN UINTN AllocationSize
,
733 IN CONST VOID
*Buffer
738 ASSERT (Buffer
!= NULL
);
739 ASSERT (AllocationSize
<= (MAX_ADDRESS
- (UINTN
) Buffer
+ 1));
741 Memory
= InternalAllocatePool (PoolType
, AllocationSize
);
742 if (Memory
!= NULL
) {
743 Memory
= CopyMem (Memory
, Buffer
, AllocationSize
);
749 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
751 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies
752 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
753 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
754 is not enough memory remaining to satisfy the request, then NULL is returned.
756 If Buffer is NULL, then ASSERT().
757 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
759 @param AllocationSize The number of bytes to allocate and zero.
760 @param Buffer The buffer to copy to the allocated buffer.
762 @return A pointer to the allocated buffer or NULL if allocation fails.
768 IN UINTN AllocationSize
,
769 IN CONST VOID
*Buffer
774 NewBuffer
= InternalAllocateCopyPool (EfiRuntimeServicesData
, AllocationSize
, Buffer
);
775 if (NewBuffer
!= NULL
) {
776 MemoryProfileLibRecord (
777 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
778 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_COPY_POOL
,
779 EfiRuntimeServicesData
,
789 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
791 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies
792 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
793 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
794 is not enough memory remaining to satisfy the request, then NULL is returned.
796 If Buffer is NULL, then ASSERT().
797 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
799 @param AllocationSize The number of bytes to allocate and zero.
800 @param Buffer The buffer to copy to the allocated buffer.
802 @return A pointer to the allocated buffer or NULL if allocation fails.
807 AllocateRuntimeCopyPool (
808 IN UINTN AllocationSize
,
809 IN CONST VOID
*Buffer
814 NewBuffer
= InternalAllocateCopyPool (EfiRuntimeServicesData
, AllocationSize
, Buffer
);
815 if (NewBuffer
!= NULL
) {
816 MemoryProfileLibRecord (
817 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
818 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_COPY_POOL
,
819 EfiRuntimeServicesData
,
829 Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
831 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies
832 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
833 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
834 is not enough memory remaining to satisfy the request, then NULL is returned.
836 If Buffer is NULL, then ASSERT().
837 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
839 @param AllocationSize The number of bytes to allocate and zero.
840 @param Buffer The buffer to copy to the allocated buffer.
842 @return A pointer to the allocated buffer or NULL if allocation fails.
847 AllocateReservedCopyPool (
848 IN UINTN AllocationSize
,
849 IN CONST VOID
*Buffer
856 Reallocates a buffer of a specified memory type.
858 Allocates and zeros the number bytes specified by NewSize from memory of the type
859 specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and
860 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
861 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
862 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
863 enough memory remaining to satisfy the request, then NULL is returned.
865 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
866 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
868 @param PoolType The type of pool to allocate.
869 @param OldSize The size, in bytes, of OldBuffer.
870 @param NewSize The size, in bytes, of the buffer to reallocate.
871 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
872 parameter that may be NULL.
874 @return A pointer to the allocated buffer or NULL if allocation fails.
878 InternalReallocatePool (
879 IN EFI_MEMORY_TYPE PoolType
,
882 IN VOID
*OldBuffer OPTIONAL
887 NewBuffer
= InternalAllocateZeroPool (PoolType
, NewSize
);
888 if (NewBuffer
!= NULL
&& OldBuffer
!= NULL
) {
889 CopyMem (NewBuffer
, OldBuffer
, MIN (OldSize
, NewSize
));
890 FreePool (OldBuffer
);
896 Reallocates a buffer of type EfiRuntimeServicesData.
898 Allocates and zeros the number bytes specified by NewSize from memory of type
899 EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
900 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
901 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
902 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
903 enough memory remaining to satisfy the request, then NULL is returned.
905 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
906 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
908 @param OldSize The size, in bytes, of OldBuffer.
909 @param NewSize The size, in bytes, of the buffer to reallocate.
910 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
911 parameter that may be NULL.
913 @return A pointer to the allocated buffer or NULL if allocation fails.
921 IN VOID
*OldBuffer OPTIONAL
926 Buffer
= InternalReallocatePool (EfiRuntimeServicesData
, OldSize
, NewSize
, OldBuffer
);
927 if (Buffer
!= NULL
) {
928 MemoryProfileLibRecord (
929 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
930 MEMORY_PROFILE_ACTION_LIB_REALLOCATE_POOL
,
931 EfiRuntimeServicesData
,
941 Reallocates a buffer of type EfiRuntimeServicesData.
943 Allocates and zeros the number bytes specified by NewSize from memory of type
944 EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
945 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
946 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
947 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
948 enough memory remaining to satisfy the request, then NULL is returned.
950 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
951 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
953 @param OldSize The size, in bytes, of OldBuffer.
954 @param NewSize The size, in bytes, of the buffer to reallocate.
955 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
956 parameter that may be NULL.
958 @return A pointer to the allocated buffer or NULL if allocation fails.
963 ReallocateRuntimePool (
966 IN VOID
*OldBuffer OPTIONAL
971 Buffer
= InternalReallocatePool (EfiRuntimeServicesData
, OldSize
, NewSize
, OldBuffer
);
972 if (Buffer
!= NULL
) {
973 MemoryProfileLibRecord (
974 (PHYSICAL_ADDRESS
) (UINTN
) RETURN_ADDRESS(0),
975 MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RUNTIME_POOL
,
976 EfiRuntimeServicesData
,
986 Reallocates a buffer of type EfiReservedMemoryType.
988 Allocates and zeros the number bytes specified by NewSize from memory of type
989 EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and
990 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
991 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
992 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
993 enough memory remaining to satisfy the request, then NULL is returned.
995 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
996 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
998 @param OldSize The size, in bytes, of OldBuffer.
999 @param NewSize The size, in bytes, of the buffer to reallocate.
1000 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
1001 parameter that may be NULL.
1003 @return A pointer to the allocated buffer or NULL if allocation fails.
1008 ReallocateReservedPool (
1011 IN VOID
*OldBuffer OPTIONAL
1018 Frees a buffer that was previously allocated with one of the pool allocation functions in the
1019 Memory Allocation Library.
1021 Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the
1022 pool allocation services of the Memory Allocation Library. If it is not possible to free pool
1023 resources, then this function will perform no actions.
1025 If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
1028 @param Buffer Pointer to the buffer to free.
1039 if (BufferInSmram (Buffer
)) {
1041 // When Buffer is in SMRAM range, it should be allocated by SmmAllocatePool() service.
1042 // So, SmmFreePool() service is used to free it.
1044 Status
= SmmFreePool (Buffer
);
1047 // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePool() service.
1048 // So, gBS->FreePool() service is used to free it.
1050 Status
= gBS
->FreePool (Buffer
);
1052 ASSERT_EFI_ERROR (Status
);
1056 The constructor function calls SmmInitializeMemoryServices to initialize memory in SMRAM.
1058 @param ImageHandle The firmware allocated handle for the EFI image.
1059 @param SystemTable A pointer to the EFI System Table.
1061 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
1066 PiSmmCoreMemoryAllocationLibConstructor (
1067 IN EFI_HANDLE ImageHandle
,
1068 IN EFI_SYSTEM_TABLE
*SystemTable
1071 SMM_CORE_PRIVATE_DATA
*SmmCorePrivate
;
1074 SmmCorePrivate
= (SMM_CORE_PRIVATE_DATA
*)ImageHandle
;
1076 // Initialize memory service using free SMRAM
1078 SmmInitializeMemoryServices (SmmCorePrivate
->SmramRangeCount
, SmmCorePrivate
->SmramRanges
);
1080 mSmmCoreMemoryAllocLibSmramRangeCount
= SmmCorePrivate
->SmramRangeCount
;
1081 Size
= mSmmCoreMemoryAllocLibSmramRangeCount
* sizeof (EFI_SMRAM_DESCRIPTOR
);
1082 mSmmCoreMemoryAllocLibSmramRanges
= (EFI_SMRAM_DESCRIPTOR
*) AllocatePool (Size
);
1083 ASSERT (mSmmCoreMemoryAllocLibSmramRanges
!= NULL
);
1084 CopyMem (mSmmCoreMemoryAllocLibSmramRanges
, SmmCorePrivate
->SmramRanges
, Size
);