2 Support routines for memory allocation routines based on SMM Core internal functions.
4 The PI System Management Mode Core Interface Specification only allows the use
5 of EfiRuntimeServicesCode and EfiRuntimeServicesData memory types for memory
6 allocations as the SMRAM space should be reserved after BDS phase. The functions
7 in the Memory Allocation Library use EfiBootServicesData as the default memory
8 allocation type. For this SMM specific instance of the Memory Allocation Library,
9 EfiRuntimeServicesData is used as the default memory type for all allocations.
10 In addition, allocation for the Reserved memory types are not supported and will
13 Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
14 This program and the accompanying materials
15 are licensed and made available under the terms and conditions of the BSD License
16 which accompanies this distribution. The full text of the license may be found at
17 http://opensource.org/licenses/bsd-license.php
19 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
20 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
26 #include <Protocol/SmmAccess2.h>
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 EFI_SMRAM_DESCRIPTOR
*mSmmCoreMemoryAllocLibSmramRanges
= NULL
;
34 UINTN mSmmCoreMemoryAllocLibSmramRangeCount
= 0;
37 Check whether the start address of buffer is within any of the SMRAM ranges.
39 @param[in] Buffer The pointer to the buffer to be checked.
41 @retval TURE The buffer is in SMRAM ranges.
42 @retval FALSE The buffer is out of SMRAM ranges.
52 for (Index
= 0; Index
< mSmmCoreMemoryAllocLibSmramRangeCount
; Index
++) {
53 if (((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
>= mSmmCoreMemoryAllocLibSmramRanges
[Index
].CpuStart
) &&
54 ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
< (mSmmCoreMemoryAllocLibSmramRanges
[Index
].CpuStart
+ mSmmCoreMemoryAllocLibSmramRanges
[Index
].PhysicalSize
))) {
63 Allocates one or more 4KB pages of a certain memory type.
65 Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated
66 buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL is returned.
67 If there is not enough memory remaining to satisfy the request, then NULL is returned.
69 @param MemoryType The type of memory to allocate.
70 @param Pages The number of 4 KB pages to allocate.
72 @return A pointer to the allocated buffer or NULL if allocation fails.
76 InternalAllocatePages (
77 IN EFI_MEMORY_TYPE MemoryType
,
82 EFI_PHYSICAL_ADDRESS Memory
;
88 Status
= SmmAllocatePages (AllocateAnyPages
, MemoryType
, Pages
, &Memory
);
89 if (EFI_ERROR (Status
)) {
92 return (VOID
*) (UINTN
) Memory
;
96 Allocates one or more 4KB pages of type EfiRuntimeServicesData.
98 Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
99 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
100 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
103 @param Pages The number of 4 KB pages to allocate.
105 @return A pointer to the allocated buffer or NULL if allocation fails.
114 return InternalAllocatePages (EfiRuntimeServicesData
, Pages
);
118 Allocates one or more 4KB pages of type EfiRuntimeServicesData.
120 Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
121 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
122 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
125 @param Pages The number of 4 KB pages to allocate.
127 @return A pointer to the allocated buffer or NULL if allocation fails.
132 AllocateRuntimePages (
136 return InternalAllocatePages (EfiRuntimeServicesData
, Pages
);
140 Allocates one or more 4KB pages of type EfiReservedMemoryType.
142 Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the
143 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
144 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
147 @param Pages The number of 4 KB pages to allocate.
149 @return A pointer to the allocated buffer or NULL if allocation fails.
154 AllocateReservedPages (
162 Frees one or more 4KB pages that were previously allocated with one of the page allocation
163 functions in the Memory Allocation Library.
165 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
166 must have been allocated on a previous call to the page allocation services of the Memory
167 Allocation Library. If it is not possible to free allocated pages, then this function will
170 If Buffer was not allocated with a page allocation function in the Memory Allocation Library,
172 If Pages is zero, then ASSERT().
174 @param Buffer Pointer to the buffer of pages to free.
175 @param Pages The number of 4 KB pages to free.
188 if (BufferInSmram (Buffer
)) {
190 // When Buffer is in SMRAM range, it should be allocated by SmmAllocatePages() service.
191 // So, SmmFreePages() service is used to free it.
193 Status
= SmmFreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
, Pages
);
196 // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePages() service.
197 // So, gBS->FreePages() service is used to free it.
199 Status
= gBS
->FreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
, Pages
);
201 ASSERT_EFI_ERROR (Status
);
205 Allocates one or more 4KB pages of a certain memory type at a specified alignment.
207 Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment
208 specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned.
209 If there is not enough memory at the specified alignment remaining to satisfy the request, then
211 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
212 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
214 @param MemoryType The type of memory to allocate.
215 @param Pages The number of 4 KB pages to allocate.
216 @param Alignment The requested alignment of the allocation. Must be a power of two.
217 If Alignment is zero, then byte alignment is used.
219 @return A pointer to the allocated buffer or NULL if allocation fails.
223 InternalAllocateAlignedPages (
224 IN EFI_MEMORY_TYPE MemoryType
,
230 EFI_PHYSICAL_ADDRESS Memory
;
233 UINTN UnalignedPages
;
237 // Alignment must be a power of two or zero.
239 ASSERT ((Alignment
& (Alignment
- 1)) == 0);
244 if (Alignment
> EFI_PAGE_SIZE
) {
246 // Calculate the total number of pages since alignment is larger than page size.
248 AlignmentMask
= Alignment
- 1;
249 RealPages
= Pages
+ EFI_SIZE_TO_PAGES (Alignment
);
251 // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
253 ASSERT (RealPages
> Pages
);
255 Status
= SmmAllocatePages (AllocateAnyPages
, MemoryType
, RealPages
, &Memory
);
256 if (EFI_ERROR (Status
)) {
259 AlignedMemory
= ((UINTN
) Memory
+ AlignmentMask
) & ~AlignmentMask
;
260 UnalignedPages
= EFI_SIZE_TO_PAGES (AlignedMemory
- (UINTN
) Memory
);
261 if (UnalignedPages
> 0) {
263 // Free first unaligned page(s).
265 Status
= SmmFreePages (Memory
, UnalignedPages
);
266 ASSERT_EFI_ERROR (Status
);
268 Memory
= (EFI_PHYSICAL_ADDRESS
) (AlignedMemory
+ EFI_PAGES_TO_SIZE (Pages
));
269 UnalignedPages
= RealPages
- Pages
- UnalignedPages
;
270 if (UnalignedPages
> 0) {
272 // Free last unaligned page(s).
274 Status
= SmmFreePages (Memory
, UnalignedPages
);
275 ASSERT_EFI_ERROR (Status
);
279 // Do not over-allocate pages in this case.
281 Status
= SmmAllocatePages (AllocateAnyPages
, MemoryType
, Pages
, &Memory
);
282 if (EFI_ERROR (Status
)) {
285 AlignedMemory
= (UINTN
) Memory
;
287 return (VOID
*) AlignedMemory
;
291 Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
293 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an
294 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
295 returned. If there is not enough memory at the specified alignment remaining to satisfy the
296 request, then NULL is returned.
298 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
299 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
301 @param Pages The number of 4 KB pages to allocate.
302 @param Alignment The requested alignment of the allocation. Must be a power of two.
303 If Alignment is zero, then byte alignment is used.
305 @return A pointer to the allocated buffer or NULL if allocation fails.
310 AllocateAlignedPages (
315 return InternalAllocateAlignedPages (EfiRuntimeServicesData
, Pages
, Alignment
);
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 AllocateAlignedRuntimePages (
343 return InternalAllocateAlignedPages (EfiRuntimeServicesData
, Pages
, Alignment
);
347 Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
349 Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an
350 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
351 returned. If there is not enough memory at the specified alignment remaining to satisfy the
352 request, then NULL is returned.
354 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
355 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
357 @param Pages The number of 4 KB pages to allocate.
358 @param Alignment The requested alignment of the allocation. Must be a power of two.
359 If Alignment is zero, then byte alignment is used.
361 @return A pointer to the allocated buffer or NULL if allocation fails.
366 AllocateAlignedReservedPages (
375 Frees one or more 4KB pages that were previously allocated with one of the aligned page
376 allocation functions in the Memory Allocation Library.
378 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
379 must have been allocated on a previous call to the aligned page allocation services of the Memory
380 Allocation Library. If it is not possible to free allocated pages, then this function will
383 If Buffer was not allocated with an aligned page allocation function in the Memory Allocation
384 Library, then ASSERT().
385 If Pages is zero, then ASSERT().
387 @param Buffer Pointer to the buffer of pages to free.
388 @param Pages The number of 4 KB pages to free.
401 if (BufferInSmram (Buffer
)) {
403 // When Buffer is in SMRAM range, it should be allocated by SmmAllocatePages() service.
404 // So, SmmFreePages() service is used to free it.
406 Status
= SmmFreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
, Pages
);
409 // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePages() service.
410 // So, gBS->FreePages() service is used to free it.
412 Status
= gBS
->FreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
, Pages
);
414 ASSERT_EFI_ERROR (Status
);
418 Allocates a buffer of a certain pool type.
420 Allocates the number bytes specified by AllocationSize of a certain pool type and returns a
421 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
422 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
424 @param MemoryType The type of memory to allocate.
425 @param AllocationSize The number of bytes to allocate.
427 @return A pointer to the allocated buffer or NULL if allocation fails.
431 InternalAllocatePool (
432 IN EFI_MEMORY_TYPE MemoryType
,
433 IN UINTN AllocationSize
441 Status
= SmmAllocatePool (MemoryType
, AllocationSize
, &Memory
);
442 if (EFI_ERROR (Status
)) {
449 Allocates a buffer of type EfiRuntimeServicesData.
451 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns a
452 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
453 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
455 @param AllocationSize The number of bytes to allocate.
457 @return A pointer to the allocated buffer or NULL if allocation fails.
463 IN UINTN AllocationSize
466 return InternalAllocatePool (EfiRuntimeServicesData
, AllocationSize
);
470 Allocates a buffer of type EfiRuntimeServicesData.
472 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns
473 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
474 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
476 @param AllocationSize The number of bytes to allocate.
478 @return A pointer to the allocated buffer or NULL if allocation fails.
483 AllocateRuntimePool (
484 IN UINTN AllocationSize
487 return InternalAllocatePool (EfiRuntimeServicesData
, AllocationSize
);
491 Allocates a buffer of type EfiReservedMemoryType.
493 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns
494 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
495 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
497 @param AllocationSize The number of bytes to allocate.
499 @return A pointer to the allocated buffer or NULL if allocation fails.
504 AllocateReservedPool (
505 IN UINTN AllocationSize
512 Allocates and zeros a buffer of a certain pool type.
514 Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer
515 with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid
516 buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request,
517 then NULL is returned.
519 @param PoolType The type of memory to allocate.
520 @param AllocationSize The number of bytes to allocate and zero.
522 @return A pointer to the allocated buffer or NULL if allocation fails.
526 InternalAllocateZeroPool (
527 IN EFI_MEMORY_TYPE PoolType
,
528 IN UINTN AllocationSize
533 Memory
= InternalAllocatePool (PoolType
, AllocationSize
);
534 if (Memory
!= NULL
) {
535 Memory
= ZeroMem (Memory
, AllocationSize
);
541 Allocates and zeros a buffer of type EfiRuntimeServicesData.
543 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the
544 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
545 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
546 request, then NULL is returned.
548 @param AllocationSize The number of bytes to allocate and zero.
550 @return A pointer to the allocated buffer or NULL if allocation fails.
556 IN UINTN AllocationSize
559 return InternalAllocateZeroPool (EfiRuntimeServicesData
, AllocationSize
);
563 Allocates and zeros a buffer of type EfiRuntimeServicesData.
565 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the
566 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
567 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
568 request, then NULL is returned.
570 @param AllocationSize The number of bytes to allocate and zero.
572 @return A pointer to the allocated buffer or NULL if allocation fails.
577 AllocateRuntimeZeroPool (
578 IN UINTN AllocationSize
581 return InternalAllocateZeroPool (EfiRuntimeServicesData
, AllocationSize
);
585 Allocates and zeros a buffer of type EfiReservedMemoryType.
587 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the
588 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
589 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
590 request, then NULL is returned.
592 @param AllocationSize The number of bytes to allocate and zero.
594 @return A pointer to the allocated buffer or NULL if allocation fails.
599 AllocateReservedZeroPool (
600 IN UINTN AllocationSize
607 Copies a buffer to an allocated buffer of a certain pool type.
609 Allocates the number bytes specified by AllocationSize of a certain pool type, copies
610 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
611 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
612 is not enough memory remaining to satisfy the request, then NULL is returned.
613 If Buffer is NULL, then ASSERT().
614 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
616 @param PoolType The type of pool to allocate.
617 @param AllocationSize The number of bytes to allocate and zero.
618 @param Buffer The buffer to copy to the allocated buffer.
620 @return A pointer to the allocated buffer or NULL if allocation fails.
624 InternalAllocateCopyPool (
625 IN EFI_MEMORY_TYPE PoolType
,
626 IN UINTN AllocationSize
,
627 IN CONST VOID
*Buffer
632 ASSERT (Buffer
!= NULL
);
633 ASSERT (AllocationSize
<= (MAX_ADDRESS
- (UINTN
) Buffer
+ 1));
635 Memory
= InternalAllocatePool (PoolType
, AllocationSize
);
636 if (Memory
!= NULL
) {
637 Memory
= CopyMem (Memory
, Buffer
, AllocationSize
);
643 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
645 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies
646 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
647 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
648 is not enough memory remaining to satisfy the request, then NULL is returned.
650 If Buffer is NULL, then ASSERT().
651 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
653 @param AllocationSize The number of bytes to allocate and zero.
654 @param Buffer The buffer to copy to the allocated buffer.
656 @return A pointer to the allocated buffer or NULL if allocation fails.
662 IN UINTN AllocationSize
,
663 IN CONST VOID
*Buffer
666 return InternalAllocateCopyPool (EfiRuntimeServicesData
, AllocationSize
, Buffer
);
670 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
672 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies
673 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
674 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
675 is not enough memory remaining to satisfy the request, then NULL is returned.
677 If Buffer is NULL, then ASSERT().
678 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
680 @param AllocationSize The number of bytes to allocate and zero.
681 @param Buffer The buffer to copy to the allocated buffer.
683 @return A pointer to the allocated buffer or NULL if allocation fails.
688 AllocateRuntimeCopyPool (
689 IN UINTN AllocationSize
,
690 IN CONST VOID
*Buffer
693 return InternalAllocateCopyPool (EfiRuntimeServicesData
, AllocationSize
, Buffer
);
697 Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
699 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies
700 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
701 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
702 is not enough memory remaining to satisfy the request, then NULL is returned.
704 If Buffer is NULL, then ASSERT().
705 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
707 @param AllocationSize The number of bytes to allocate and zero.
708 @param Buffer The buffer to copy to the allocated buffer.
710 @return A pointer to the allocated buffer or NULL if allocation fails.
715 AllocateReservedCopyPool (
716 IN UINTN AllocationSize
,
717 IN CONST VOID
*Buffer
724 Reallocates a buffer of a specified memory type.
726 Allocates and zeros the number bytes specified by NewSize from memory of the type
727 specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and
728 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
729 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
730 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
731 enough memory remaining to satisfy the request, then NULL is returned.
733 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
734 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
736 @param PoolType The type of pool to allocate.
737 @param OldSize The size, in bytes, of OldBuffer.
738 @param NewSize The size, in bytes, of the buffer to reallocate.
739 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
740 parameter that may be NULL.
742 @return A pointer to the allocated buffer or NULL if allocation fails.
746 InternalReallocatePool (
747 IN EFI_MEMORY_TYPE PoolType
,
750 IN VOID
*OldBuffer OPTIONAL
755 NewBuffer
= InternalAllocateZeroPool (PoolType
, NewSize
);
756 if (NewBuffer
!= NULL
&& OldBuffer
!= NULL
) {
757 CopyMem (NewBuffer
, OldBuffer
, MIN (OldSize
, NewSize
));
758 FreePool (OldBuffer
);
764 Reallocates a buffer of type EfiRuntimeServicesData.
766 Allocates and zeros the number bytes specified by NewSize from memory of type
767 EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
768 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
769 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
770 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
771 enough memory remaining to satisfy the request, then NULL is returned.
773 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
774 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
776 @param OldSize The size, in bytes, of OldBuffer.
777 @param NewSize The size, in bytes, of the buffer to reallocate.
778 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
779 parameter that may be NULL.
781 @return A pointer to the allocated buffer or NULL if allocation fails.
789 IN VOID
*OldBuffer OPTIONAL
792 return InternalReallocatePool (EfiRuntimeServicesData
, OldSize
, NewSize
, OldBuffer
);
796 Reallocates a buffer of type EfiRuntimeServicesData.
798 Allocates and zeros the number bytes specified by NewSize from memory of type
799 EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
800 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
801 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
802 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
803 enough memory remaining to satisfy the request, then NULL is returned.
805 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
806 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
808 @param OldSize The size, in bytes, of OldBuffer.
809 @param NewSize The size, in bytes, of the buffer to reallocate.
810 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
811 parameter that may be NULL.
813 @return A pointer to the allocated buffer or NULL if allocation fails.
818 ReallocateRuntimePool (
821 IN VOID
*OldBuffer OPTIONAL
824 return InternalReallocatePool (EfiRuntimeServicesData
, OldSize
, NewSize
, OldBuffer
);
828 Reallocates a buffer of type EfiReservedMemoryType.
830 Allocates and zeros the number bytes specified by NewSize from memory of type
831 EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and
832 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
833 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
834 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
835 enough memory remaining to satisfy the request, then NULL is returned.
837 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
838 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
840 @param OldSize The size, in bytes, of OldBuffer.
841 @param NewSize The size, in bytes, of the buffer to reallocate.
842 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
843 parameter that may be NULL.
845 @return A pointer to the allocated buffer or NULL if allocation fails.
850 ReallocateReservedPool (
853 IN VOID
*OldBuffer OPTIONAL
860 Frees a buffer that was previously allocated with one of the pool allocation functions in the
861 Memory Allocation Library.
863 Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the
864 pool allocation services of the Memory Allocation Library. If it is not possible to free pool
865 resources, then this function will perform no actions.
867 If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
870 @param Buffer Pointer to the buffer to free.
881 if (BufferInSmram (Buffer
)) {
883 // When Buffer is in SMRAM range, it should be allocated by SmmAllocatePool() service.
884 // So, SmmFreePool() service is used to free it.
886 Status
= SmmFreePool (Buffer
);
889 // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePool() service.
890 // So, gBS->FreePool() service is used to free it.
892 Status
= gBS
->FreePool (Buffer
);
894 ASSERT_EFI_ERROR (Status
);
898 The constructor function calls SmmInitializeMemoryServices to initialize memory in SMRAM.
900 @param ImageHandle The firmware allocated handle for the EFI image.
901 @param SystemTable A pointer to the EFI System Table.
903 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
908 PiSmmCoreMemoryAllocationLibConstructor (
909 IN EFI_HANDLE ImageHandle
,
910 IN EFI_SYSTEM_TABLE
*SystemTable
913 SMM_CORE_PRIVATE_DATA
*SmmCorePrivate
;
916 SmmCorePrivate
= (SMM_CORE_PRIVATE_DATA
*)ImageHandle
;
918 // Initialize memory service using free SMRAM
920 SmmInitializeMemoryServices (SmmCorePrivate
->SmramRangeCount
, SmmCorePrivate
->SmramRanges
);
922 mSmmCoreMemoryAllocLibSmramRangeCount
= SmmCorePrivate
->SmramRangeCount
;
923 Size
= mSmmCoreMemoryAllocLibSmramRangeCount
* sizeof (EFI_SMRAM_DESCRIPTOR
);
924 mSmmCoreMemoryAllocLibSmramRanges
= (EFI_SMRAM_DESCRIPTOR
*) AllocatePool (Size
);
925 ASSERT (mSmmCoreMemoryAllocLibSmramRanges
!= NULL
);
926 CopyMem (mSmmCoreMemoryAllocLibSmramRanges
, SmmCorePrivate
->SmramRanges
, Size
);