2 Support routines for memory allocation routines based on Standalone MM Core internal functions.
4 Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
5 Copyright (c) 2016 - 2021, ARM Limited. All rights reserved.<BR>
7 SPDX-License-Identifier: BSD-2-Clause-Patent
13 #include <Guid/MmramMemoryReserve.h>
14 #include <Library/MemoryAllocationLib.h>
15 #include <Library/BaseMemoryLib.h>
16 #include <Library/DebugLib.h>
17 #include <Library/HobLib.h>
18 #include "StandaloneMmCoreMemoryAllocationServices.h"
20 EFI_MM_SYSTEM_TABLE
*gMmst
= NULL
;
23 Allocates one or more 4KB pages of a certain memory type.
25 Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated
26 buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL is returned.
27 If there is not enough memory remaining to satisfy the request, then NULL is returned.
29 @param MemoryType The type of memory to allocate.
30 @param Pages The number of 4 KB pages to allocate.
32 @return A pointer to the allocated buffer or NULL if allocation fails.
36 InternalAllocatePages (
37 IN EFI_MEMORY_TYPE MemoryType
,
42 EFI_PHYSICAL_ADDRESS Memory
;
48 Status
= gMmst
->MmAllocatePages (AllocateAnyPages
, MemoryType
, Pages
, &Memory
);
49 if (EFI_ERROR (Status
)) {
52 return (VOID
*) (UINTN
) Memory
;
56 Allocates one or more 4KB pages of type EfiBootServicesData.
58 Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the
59 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
60 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
63 @param Pages The number of 4 KB pages to allocate.
65 @return A pointer to the allocated buffer or NULL if allocation fails.
74 return InternalAllocatePages (EfiRuntimeServicesData
, Pages
);
78 Allocates one or more 4KB pages of type EfiRuntimeServicesData.
80 Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
81 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
82 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
85 @param Pages The number of 4 KB pages to allocate.
87 @return A pointer to the allocated buffer or NULL if allocation fails.
92 AllocateRuntimePages (
96 return InternalAllocatePages (EfiRuntimeServicesData
, Pages
);
100 Allocates one or more 4KB pages of type EfiReservedMemoryType.
102 Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the
103 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
104 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
107 @param Pages The number of 4 KB pages to allocate.
109 @return A pointer to the allocated buffer or NULL if allocation fails.
114 AllocateReservedPages (
122 Frees one or more 4KB pages that were previously allocated with one of the page allocation
123 functions in the Memory Allocation Library.
125 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
126 must have been allocated on a previous call to the page allocation services of the Memory
127 Allocation Library. If it is not possible to free allocated pages, then this function will
130 If Buffer was not allocated with a page allocation function in the Memory Allocation Library,
132 If Pages is zero, then ASSERT().
134 @param Buffer Pointer to the buffer of pages to free.
135 @param Pages The number of 4 KB pages to free.
148 Status
= gMmst
->MmFreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
, Pages
);
149 ASSERT_EFI_ERROR (Status
);
153 Allocates one or more 4KB pages of a certain memory type at a specified alignment.
155 Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment
156 specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned.
157 If there is not enough memory at the specified alignment remaining to satisfy the request, then
159 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
160 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
162 @param MemoryType The type of memory to allocate.
163 @param Pages The number of 4 KB pages to allocate.
164 @param Alignment The requested alignment of the allocation. Must be a power of two.
165 If Alignment is zero, then byte alignment is used.
167 @return A pointer to the allocated buffer or NULL if allocation fails.
171 InternalAllocateAlignedPages (
172 IN EFI_MEMORY_TYPE MemoryType
,
178 EFI_PHYSICAL_ADDRESS Memory
;
181 UINTN UnalignedPages
;
185 // Alignment must be a power of two or zero.
187 ASSERT ((Alignment
& (Alignment
- 1)) == 0);
192 if (Alignment
> EFI_PAGE_SIZE
) {
194 // Calculate the total number of pages since alignment is larger than page size.
196 AlignmentMask
= Alignment
- 1;
197 RealPages
= Pages
+ EFI_SIZE_TO_PAGES (Alignment
);
199 // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
201 ASSERT (RealPages
> Pages
);
203 Status
= gMmst
->MmAllocatePages (AllocateAnyPages
, MemoryType
, RealPages
, &Memory
);
204 if (EFI_ERROR (Status
)) {
207 AlignedMemory
= ((UINTN
) Memory
+ AlignmentMask
) & ~AlignmentMask
;
208 UnalignedPages
= EFI_SIZE_TO_PAGES (AlignedMemory
- (UINTN
) Memory
);
209 if (UnalignedPages
> 0) {
211 // Free first unaligned page(s).
213 Status
= gMmst
->MmFreePages (Memory
, UnalignedPages
);
214 ASSERT_EFI_ERROR (Status
);
216 Memory
= (EFI_PHYSICAL_ADDRESS
) (AlignedMemory
+ EFI_PAGES_TO_SIZE (Pages
));
217 UnalignedPages
= RealPages
- Pages
- UnalignedPages
;
218 if (UnalignedPages
> 0) {
220 // Free last unaligned page(s).
222 Status
= gMmst
->MmFreePages (Memory
, UnalignedPages
);
223 ASSERT_EFI_ERROR (Status
);
227 // Do not over-allocate pages in this case.
229 Status
= gMmst
->MmAllocatePages (AllocateAnyPages
, MemoryType
, Pages
, &Memory
);
230 if (EFI_ERROR (Status
)) {
233 AlignedMemory
= (UINTN
) Memory
;
235 return (VOID
*) AlignedMemory
;
239 Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment.
241 Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an
242 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
243 returned. If there is not enough memory at the specified alignment remaining to satisfy the
244 request, then NULL is returned.
246 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
247 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
249 @param Pages The number of 4 KB pages to allocate.
250 @param Alignment The requested alignment of the allocation. Must be a power of two.
251 If Alignment is zero, then byte alignment is used.
253 @return A pointer to the allocated buffer or NULL if allocation fails.
258 AllocateAlignedPages (
263 return InternalAllocateAlignedPages (EfiRuntimeServicesData
, Pages
, Alignment
);
267 Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
269 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an
270 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
271 returned. If there is not enough memory at the specified alignment remaining to satisfy the
272 request, then NULL is returned.
274 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
275 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
277 @param Pages The number of 4 KB pages to allocate.
278 @param Alignment The requested alignment of the allocation. Must be a power of two.
279 If Alignment is zero, then byte alignment is used.
281 @return A pointer to the allocated buffer or NULL if allocation fails.
286 AllocateAlignedRuntimePages (
291 return InternalAllocateAlignedPages (EfiRuntimeServicesData
, Pages
, Alignment
);
295 Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
297 Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an
298 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
299 returned. If there is not enough memory at the specified alignment remaining to satisfy the
300 request, then NULL is returned.
302 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
303 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
305 @param Pages The number of 4 KB pages to allocate.
306 @param Alignment The requested alignment of the allocation. Must be a power of two.
307 If Alignment is zero, then byte alignment is used.
309 @return A pointer to the allocated buffer or NULL if allocation fails.
314 AllocateAlignedReservedPages (
323 Frees one or more 4KB pages that were previously allocated with one of the aligned page
324 allocation functions in the Memory Allocation Library.
326 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
327 must have been allocated on a previous call to the aligned page allocation services of the Memory
328 Allocation Library. If it is not possible to free allocated pages, then this function will
331 If Buffer was not allocated with an aligned page allocation function in the Memory Allocation
332 Library, then ASSERT().
333 If Pages is zero, then ASSERT().
335 @param Buffer Pointer to the buffer of pages to free.
336 @param Pages The number of 4 KB pages to free.
349 Status
= gMmst
->MmFreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
, Pages
);
350 ASSERT_EFI_ERROR (Status
);
354 Allocates a buffer of a certain pool type.
356 Allocates the number bytes specified by AllocationSize of a certain pool type and returns a
357 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
358 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
360 @param MemoryType The type of memory to allocate.
361 @param AllocationSize The number of bytes to allocate.
363 @return A pointer to the allocated buffer or NULL if allocation fails.
367 InternalAllocatePool (
368 IN EFI_MEMORY_TYPE MemoryType
,
369 IN UINTN AllocationSize
377 Status
= gMmst
->MmAllocatePool (MemoryType
, AllocationSize
, &Memory
);
378 if (EFI_ERROR (Status
)) {
385 Allocates a buffer of type EfiBootServicesData.
387 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a
388 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
389 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
391 @param AllocationSize The number of bytes to allocate.
393 @return A pointer to the allocated buffer or NULL if allocation fails.
399 IN UINTN AllocationSize
402 return InternalAllocatePool (EfiRuntimeServicesData
, AllocationSize
);
406 Allocates a buffer of type EfiRuntimeServicesData.
408 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns
409 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
410 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
412 @param AllocationSize The number of bytes to allocate.
414 @return A pointer to the allocated buffer or NULL if allocation fails.
419 AllocateRuntimePool (
420 IN UINTN AllocationSize
423 return InternalAllocatePool (EfiRuntimeServicesData
, AllocationSize
);
427 Allocates a buffer of type EfiReservedMemoryType.
429 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns
430 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
431 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
433 @param AllocationSize The number of bytes to allocate.
435 @return A pointer to the allocated buffer or NULL if allocation fails.
440 AllocateReservedPool (
441 IN UINTN AllocationSize
448 Allocates and zeros a buffer of a certain pool type.
450 Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer
451 with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid
452 buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request,
453 then NULL is returned.
455 @param PoolType The type of memory to allocate.
456 @param AllocationSize The number of bytes to allocate and zero.
458 @return A pointer to the allocated buffer or NULL if allocation fails.
462 InternalAllocateZeroPool (
463 IN EFI_MEMORY_TYPE PoolType
,
464 IN UINTN AllocationSize
469 Memory
= InternalAllocatePool (PoolType
, AllocationSize
);
470 if (Memory
!= NULL
) {
471 Memory
= ZeroMem (Memory
, AllocationSize
);
477 Allocates and zeros a buffer of type EfiBootServicesData.
479 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
480 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
481 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
482 request, then NULL is returned.
484 @param AllocationSize The number of bytes to allocate and zero.
486 @return A pointer to the allocated buffer or NULL if allocation fails.
492 IN UINTN AllocationSize
495 return InternalAllocateZeroPool (EfiRuntimeServicesData
, AllocationSize
);
499 Allocates and zeros a buffer of type EfiRuntimeServicesData.
501 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the
502 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
503 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
504 request, then NULL is returned.
506 @param AllocationSize The number of bytes to allocate and zero.
508 @return A pointer to the allocated buffer or NULL if allocation fails.
513 AllocateRuntimeZeroPool (
514 IN UINTN AllocationSize
517 return InternalAllocateZeroPool (EfiRuntimeServicesData
, AllocationSize
);
521 Allocates and zeros a buffer of type EfiReservedMemoryType.
523 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the
524 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
525 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
526 request, then NULL is returned.
528 @param AllocationSize The number of bytes to allocate and zero.
530 @return A pointer to the allocated buffer or NULL if allocation fails.
535 AllocateReservedZeroPool (
536 IN UINTN AllocationSize
543 Copies a buffer to an allocated buffer of a certain pool type.
545 Allocates the number bytes specified by AllocationSize of a certain pool type, copies
546 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
547 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
548 is not enough memory remaining to satisfy the request, then NULL is returned.
549 If Buffer is NULL, then ASSERT().
550 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
552 @param PoolType The type of pool to allocate.
553 @param AllocationSize The number of bytes to allocate and zero.
554 @param Buffer The buffer to copy to the allocated buffer.
556 @return A pointer to the allocated buffer or NULL if allocation fails.
560 InternalAllocateCopyPool (
561 IN EFI_MEMORY_TYPE PoolType
,
562 IN UINTN AllocationSize
,
563 IN CONST VOID
*Buffer
568 ASSERT (Buffer
!= NULL
);
569 ASSERT (AllocationSize
<= (MAX_ADDRESS
- (UINTN
) Buffer
+ 1));
571 Memory
= InternalAllocatePool (PoolType
, AllocationSize
);
572 if (Memory
!= NULL
) {
573 Memory
= CopyMem (Memory
, Buffer
, AllocationSize
);
579 Copies a buffer to an allocated buffer of type EfiBootServicesData.
581 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies
582 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
583 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
584 is not enough memory remaining to satisfy the request, then NULL is returned.
586 If Buffer is NULL, then ASSERT().
587 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
589 @param AllocationSize The number of bytes to allocate and zero.
590 @param Buffer The buffer to copy to the allocated buffer.
592 @return A pointer to the allocated buffer or NULL if allocation fails.
598 IN UINTN AllocationSize
,
599 IN CONST VOID
*Buffer
602 return InternalAllocateCopyPool (EfiRuntimeServicesData
, AllocationSize
, Buffer
);
606 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
608 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies
609 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
610 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
611 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 AllocationSize The number of bytes to allocate and zero.
617 @param Buffer The buffer to copy to the allocated buffer.
619 @return A pointer to the allocated buffer or NULL if allocation fails.
624 AllocateRuntimeCopyPool (
625 IN UINTN AllocationSize
,
626 IN CONST VOID
*Buffer
629 return InternalAllocateCopyPool (EfiRuntimeServicesData
, AllocationSize
, Buffer
);
633 Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
635 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies
636 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
637 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
638 is not enough memory remaining to satisfy the request, then NULL is returned.
640 If Buffer is NULL, then ASSERT().
641 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
643 @param AllocationSize The number of bytes to allocate and zero.
644 @param Buffer The buffer to copy to the allocated buffer.
646 @return A pointer to the allocated buffer or NULL if allocation fails.
651 AllocateReservedCopyPool (
652 IN UINTN AllocationSize
,
653 IN CONST VOID
*Buffer
660 Reallocates a buffer of a specified memory type.
662 Allocates and zeros the number bytes specified by NewSize from memory of the type
663 specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and
664 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
665 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
666 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
667 enough memory remaining to satisfy the request, then NULL is returned.
669 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
670 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
672 @param PoolType The type of pool to allocate.
673 @param OldSize The size, in bytes, of OldBuffer.
674 @param NewSize The size, in bytes, of the buffer to reallocate.
675 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
676 parameter that may be NULL.
678 @return A pointer to the allocated buffer or NULL if allocation fails.
682 InternalReallocatePool (
683 IN EFI_MEMORY_TYPE PoolType
,
686 IN VOID
*OldBuffer OPTIONAL
691 NewBuffer
= InternalAllocateZeroPool (PoolType
, NewSize
);
692 if (NewBuffer
!= NULL
&& OldBuffer
!= NULL
) {
693 CopyMem (NewBuffer
, OldBuffer
, MIN (OldSize
, NewSize
));
694 FreePool (OldBuffer
);
700 Reallocates a buffer of type EfiBootServicesData.
702 Allocates and zeros the number bytes specified by NewSize from memory of type
703 EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
704 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
705 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
706 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
707 enough memory remaining to satisfy the request, then NULL is returned.
709 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
710 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
712 @param OldSize The size, in bytes, of OldBuffer.
713 @param NewSize The size, in bytes, of the buffer to reallocate.
714 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
715 parameter that may be NULL.
717 @return A pointer to the allocated buffer or NULL if allocation fails.
725 IN VOID
*OldBuffer OPTIONAL
728 return InternalReallocatePool (EfiRuntimeServicesData
, OldSize
, NewSize
, OldBuffer
);
732 Reallocates a buffer of type EfiRuntimeServicesData.
734 Allocates and zeros the number bytes specified by NewSize from memory of type
735 EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
736 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
737 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
738 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
739 enough memory remaining to satisfy the request, then NULL is returned.
741 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
742 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
744 @param OldSize The size, in bytes, of OldBuffer.
745 @param NewSize The size, in bytes, of the buffer to reallocate.
746 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
747 parameter that may be NULL.
749 @return A pointer to the allocated buffer or NULL if allocation fails.
754 ReallocateRuntimePool (
757 IN VOID
*OldBuffer OPTIONAL
760 return InternalReallocatePool (EfiRuntimeServicesData
, OldSize
, NewSize
, OldBuffer
);
764 Reallocates a buffer of type EfiReservedMemoryType.
766 Allocates and zeros the number bytes specified by NewSize from memory of type
767 EfiReservedMemoryType. 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.
786 ReallocateReservedPool (
789 IN VOID
*OldBuffer OPTIONAL
796 Frees a buffer that was previously allocated with one of the pool allocation functions in the
797 Memory Allocation Library.
799 Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the
800 pool allocation services of the Memory Allocation Library. If it is not possible to free pool
801 resources, then this function will perform no actions.
803 If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
806 @param Buffer Pointer to the buffer to free.
817 Status
= gMmst
->MmFreePool (Buffer
);
818 ASSERT_EFI_ERROR (Status
);
822 The constructor function calls MmInitializeMemoryServices to initialize
823 memory in MMRAM and caches EFI_MM_SYSTEM_TABLE pointer.
825 @param [in] ImageHandle The firmware allocated handle for the EFI image.
826 @param [in] MmSystemTable A pointer to the Management mode System Table.
828 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
833 MemoryAllocationLibConstructor (
834 IN EFI_HANDLE ImageHandle
,
835 IN EFI_MM_SYSTEM_TABLE
*MmSystemTable
838 MM_CORE_PRIVATE_DATA
*MmCorePrivate
;
839 EFI_HOB_GUID_TYPE
*GuidHob
;
840 MM_CORE_DATA_HOB_DATA
*DataInHob
;
842 EFI_MMRAM_HOB_DESCRIPTOR_BLOCK
*MmramRangesHobData
;
843 EFI_MMRAM_DESCRIPTOR
*MmramRanges
;
844 UINTN MmramRangeCount
;
845 EFI_HOB_GUID_TYPE
*MmramRangesHob
;
847 HobStart
= GetHobList ();
848 DEBUG ((DEBUG_INFO
, "StandaloneMmCoreMemoryAllocationLibConstructor - 0x%x\n", HobStart
));
851 // Extract MM Core Private context from the Hob. If absent search for
852 // a Hob containing the MMRAM ranges
854 GuidHob
= GetNextGuidHob (&gMmCoreDataHobGuid
, HobStart
);
855 if (GuidHob
== NULL
) {
856 MmramRangesHob
= GetNextGuidHob (&gEfiMmPeiMmramMemoryReserveGuid
, HobStart
);
857 if (MmramRangesHob
== NULL
) {
858 return EFI_UNSUPPORTED
;
861 MmramRangesHobData
= GET_GUID_HOB_DATA (MmramRangesHob
);
862 if (MmramRangesHobData
== NULL
) {
863 return EFI_UNSUPPORTED
;
866 MmramRanges
= MmramRangesHobData
->Descriptor
;
867 if (MmramRanges
== NULL
) {
868 return EFI_UNSUPPORTED
;
871 MmramRangeCount
= (UINTN
) MmramRangesHobData
->NumberOfMmReservedRegions
;
872 if (MmramRanges
== NULL
) {
873 return EFI_UNSUPPORTED
;
877 DataInHob
= GET_GUID_HOB_DATA (GuidHob
);
878 MmCorePrivate
= (MM_CORE_PRIVATE_DATA
*)(UINTN
)DataInHob
->Address
;
879 MmramRanges
= (EFI_MMRAM_DESCRIPTOR
*)(UINTN
)MmCorePrivate
->MmramRanges
;
880 MmramRangeCount
= (UINTN
) MmCorePrivate
->MmramRangeCount
;
886 DEBUG ((DEBUG_INFO
, "MmramRangeCount - 0x%x\n", MmramRangeCount
));
887 for (Index
= 0; Index
< MmramRangeCount
; Index
++) {
888 DEBUG ((DEBUG_INFO
, "MmramRanges[%d]: 0x%016lx - 0x%016lx\n",
889 Index
, MmramRanges
[Index
].CpuStart
, MmramRanges
[Index
].PhysicalSize
));
894 // Initialize memory service using free MMRAM
896 DEBUG ((DEBUG_INFO
, "MmInitializeMemoryServices\n"));
897 MmInitializeMemoryServices ((UINTN
)MmramRangeCount
, (VOID
*)(UINTN
)MmramRanges
);
899 // Initialize MM Services Table
900 gMmst
= MmSystemTable
;