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
)) {
53 return (VOID
*)(UINTN
)Memory
;
57 Allocates one or more 4KB pages of type EfiBootServicesData.
59 Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the
60 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
61 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
64 @param Pages The number of 4 KB pages to allocate.
66 @return A pointer to the allocated buffer or NULL if allocation fails.
75 return InternalAllocatePages (EfiRuntimeServicesData
, Pages
);
79 Allocates one or more 4KB pages of type EfiRuntimeServicesData.
81 Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
82 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
83 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
86 @param Pages The number of 4 KB pages to allocate.
88 @return A pointer to the allocated buffer or NULL if allocation fails.
93 AllocateRuntimePages (
97 return InternalAllocatePages (EfiRuntimeServicesData
, Pages
);
101 Allocates one or more 4KB pages of type EfiReservedMemoryType.
103 Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the
104 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
105 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
108 @param Pages The number of 4 KB pages to allocate.
110 @return A pointer to the allocated buffer or NULL if allocation fails.
115 AllocateReservedPages (
123 Frees one or more 4KB pages that were previously allocated with one of the page allocation
124 functions in the Memory Allocation Library.
126 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
127 must have been allocated on a previous call to the page allocation services of the Memory
128 Allocation Library. If it is not possible to free allocated pages, then this function will
131 If Buffer was not allocated with a page allocation function in the Memory Allocation Library,
133 If Pages is zero, then ASSERT().
135 @param Buffer Pointer to the buffer of pages to free.
136 @param Pages The number of 4 KB pages to free.
149 Status
= gMmst
->MmFreePages ((EFI_PHYSICAL_ADDRESS
)(UINTN
)Buffer
, Pages
);
150 ASSERT_EFI_ERROR (Status
);
154 Allocates one or more 4KB pages of a certain memory type at a specified alignment.
156 Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment
157 specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned.
158 If there is not enough memory at the specified alignment remaining to satisfy the request, then
160 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
161 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
163 @param MemoryType The type of memory to allocate.
164 @param Pages The number of 4 KB pages to allocate.
165 @param Alignment The requested alignment of the allocation. Must be a power of two.
166 If Alignment is zero, then byte alignment is used.
168 @return A pointer to the allocated buffer or NULL if allocation fails.
172 InternalAllocateAlignedPages (
173 IN EFI_MEMORY_TYPE MemoryType
,
179 EFI_PHYSICAL_ADDRESS Memory
;
182 UINTN UnalignedPages
;
186 // Alignment must be a power of two or zero.
188 ASSERT ((Alignment
& (Alignment
- 1)) == 0);
194 if (Alignment
> EFI_PAGE_SIZE
) {
196 // Calculate the total number of pages since alignment is larger than page size.
198 AlignmentMask
= Alignment
- 1;
199 RealPages
= Pages
+ EFI_SIZE_TO_PAGES (Alignment
);
201 // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
203 ASSERT (RealPages
> Pages
);
205 Status
= gMmst
->MmAllocatePages (AllocateAnyPages
, MemoryType
, RealPages
, &Memory
);
206 if (EFI_ERROR (Status
)) {
210 AlignedMemory
= ((UINTN
)Memory
+ AlignmentMask
) & ~AlignmentMask
;
211 UnalignedPages
= EFI_SIZE_TO_PAGES (AlignedMemory
- (UINTN
)Memory
);
212 if (UnalignedPages
> 0) {
214 // Free first unaligned page(s).
216 Status
= gMmst
->MmFreePages (Memory
, UnalignedPages
);
217 ASSERT_EFI_ERROR (Status
);
220 Memory
= (EFI_PHYSICAL_ADDRESS
)(AlignedMemory
+ EFI_PAGES_TO_SIZE (Pages
));
221 UnalignedPages
= RealPages
- Pages
- UnalignedPages
;
222 if (UnalignedPages
> 0) {
224 // Free last unaligned page(s).
226 Status
= gMmst
->MmFreePages (Memory
, UnalignedPages
);
227 ASSERT_EFI_ERROR (Status
);
231 // Do not over-allocate pages in this case.
233 Status
= gMmst
->MmAllocatePages (AllocateAnyPages
, MemoryType
, Pages
, &Memory
);
234 if (EFI_ERROR (Status
)) {
238 AlignedMemory
= (UINTN
)Memory
;
241 return (VOID
*)AlignedMemory
;
245 Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment.
247 Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an
248 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
249 returned. If there is not enough memory at the specified alignment remaining to satisfy the
250 request, then NULL is returned.
252 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
253 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
255 @param Pages The number of 4 KB pages to allocate.
256 @param Alignment The requested alignment of the allocation. Must be a power of two.
257 If Alignment is zero, then byte alignment is used.
259 @return A pointer to the allocated buffer or NULL if allocation fails.
264 AllocateAlignedPages (
269 return InternalAllocateAlignedPages (EfiRuntimeServicesData
, Pages
, Alignment
);
273 Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
275 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an
276 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
277 returned. If there is not enough memory at the specified alignment remaining to satisfy the
278 request, then NULL is returned.
280 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
281 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
283 @param Pages The number of 4 KB pages to allocate.
284 @param Alignment The requested alignment of the allocation. Must be a power of two.
285 If Alignment is zero, then byte alignment is used.
287 @return A pointer to the allocated buffer or NULL if allocation fails.
292 AllocateAlignedRuntimePages (
297 return InternalAllocateAlignedPages (EfiRuntimeServicesData
, Pages
, Alignment
);
301 Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
303 Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an
304 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
305 returned. If there is not enough memory at the specified alignment remaining to satisfy the
306 request, then NULL is returned.
308 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
309 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
311 @param Pages The number of 4 KB pages to allocate.
312 @param Alignment The requested alignment of the allocation. Must be a power of two.
313 If Alignment is zero, then byte alignment is used.
315 @return A pointer to the allocated buffer or NULL if allocation fails.
320 AllocateAlignedReservedPages (
329 Frees one or more 4KB pages that were previously allocated with one of the aligned page
330 allocation functions in the Memory Allocation Library.
332 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
333 must have been allocated on a previous call to the aligned page allocation services of the Memory
334 Allocation Library. If it is not possible to free allocated pages, then this function will
337 If Buffer was not allocated with an aligned page allocation function in the Memory Allocation
338 Library, then ASSERT().
339 If Pages is zero, then ASSERT().
341 @param Buffer Pointer to the buffer of pages to free.
342 @param Pages The number of 4 KB pages to free.
355 Status
= gMmst
->MmFreePages ((EFI_PHYSICAL_ADDRESS
)(UINTN
)Buffer
, Pages
);
356 ASSERT_EFI_ERROR (Status
);
360 Allocates a buffer of a certain pool type.
362 Allocates the number bytes specified by AllocationSize of a certain pool type and returns a
363 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
364 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
366 @param MemoryType The type of memory to allocate.
367 @param AllocationSize The number of bytes to allocate.
369 @return A pointer to the allocated buffer or NULL if allocation fails.
373 InternalAllocatePool (
374 IN EFI_MEMORY_TYPE MemoryType
,
375 IN UINTN AllocationSize
383 Status
= gMmst
->MmAllocatePool (MemoryType
, AllocationSize
, &Memory
);
384 if (EFI_ERROR (Status
)) {
392 Allocates a buffer of type EfiBootServicesData.
394 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a
395 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
396 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
398 @param AllocationSize The number of bytes to allocate.
400 @return A pointer to the allocated buffer or NULL if allocation fails.
406 IN UINTN AllocationSize
409 return InternalAllocatePool (EfiRuntimeServicesData
, AllocationSize
);
413 Allocates a buffer of type EfiRuntimeServicesData.
415 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns
416 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
417 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
419 @param AllocationSize The number of bytes to allocate.
421 @return A pointer to the allocated buffer or NULL if allocation fails.
426 AllocateRuntimePool (
427 IN UINTN AllocationSize
430 return InternalAllocatePool (EfiRuntimeServicesData
, AllocationSize
);
434 Allocates a buffer of type EfiReservedMemoryType.
436 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns
437 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
438 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
440 @param AllocationSize The number of bytes to allocate.
442 @return A pointer to the allocated buffer or NULL if allocation fails.
447 AllocateReservedPool (
448 IN UINTN AllocationSize
455 Allocates and zeros a buffer of a certain pool type.
457 Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer
458 with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid
459 buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request,
460 then NULL is returned.
462 @param PoolType The type of memory to allocate.
463 @param AllocationSize The number of bytes to allocate and zero.
465 @return A pointer to the allocated buffer or NULL if allocation fails.
469 InternalAllocateZeroPool (
470 IN EFI_MEMORY_TYPE PoolType
,
471 IN UINTN AllocationSize
476 Memory
= InternalAllocatePool (PoolType
, AllocationSize
);
477 if (Memory
!= NULL
) {
478 Memory
= ZeroMem (Memory
, AllocationSize
);
485 Allocates and zeros a buffer of type EfiBootServicesData.
487 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
488 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
489 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
490 request, then NULL is returned.
492 @param AllocationSize The number of bytes to allocate and zero.
494 @return A pointer to the allocated buffer or NULL if allocation fails.
500 IN UINTN AllocationSize
503 return InternalAllocateZeroPool (EfiRuntimeServicesData
, AllocationSize
);
507 Allocates and zeros a buffer of type EfiRuntimeServicesData.
509 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the
510 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
511 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
512 request, then NULL is returned.
514 @param AllocationSize The number of bytes to allocate and zero.
516 @return A pointer to the allocated buffer or NULL if allocation fails.
521 AllocateRuntimeZeroPool (
522 IN UINTN AllocationSize
525 return InternalAllocateZeroPool (EfiRuntimeServicesData
, AllocationSize
);
529 Allocates and zeros a buffer of type EfiReservedMemoryType.
531 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the
532 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
533 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
534 request, then NULL is returned.
536 @param AllocationSize The number of bytes to allocate and zero.
538 @return A pointer to the allocated buffer or NULL if allocation fails.
543 AllocateReservedZeroPool (
544 IN UINTN AllocationSize
551 Copies a buffer to an allocated buffer of a certain pool type.
553 Allocates the number bytes specified by AllocationSize of a certain pool type, copies
554 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
555 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
556 is not enough memory remaining to satisfy the request, then NULL is returned.
557 If Buffer is NULL, then ASSERT().
558 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
560 @param PoolType The type of pool to allocate.
561 @param AllocationSize The number of bytes to allocate and zero.
562 @param Buffer The buffer to copy to the allocated buffer.
564 @return A pointer to the allocated buffer or NULL if allocation fails.
568 InternalAllocateCopyPool (
569 IN EFI_MEMORY_TYPE PoolType
,
570 IN UINTN AllocationSize
,
571 IN CONST VOID
*Buffer
576 ASSERT (Buffer
!= NULL
);
577 ASSERT (AllocationSize
<= (MAX_ADDRESS
- (UINTN
)Buffer
+ 1));
579 Memory
= InternalAllocatePool (PoolType
, AllocationSize
);
580 if (Memory
!= NULL
) {
581 Memory
= CopyMem (Memory
, Buffer
, AllocationSize
);
588 Copies a buffer to an allocated buffer of type EfiBootServicesData.
590 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies
591 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
592 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
593 is not enough memory remaining to satisfy the request, then NULL is returned.
595 If Buffer is NULL, then ASSERT().
596 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
598 @param AllocationSize The number of bytes to allocate and zero.
599 @param Buffer The buffer to copy to the allocated buffer.
601 @return A pointer to the allocated buffer or NULL if allocation fails.
607 IN UINTN AllocationSize
,
608 IN CONST VOID
*Buffer
611 return InternalAllocateCopyPool (EfiRuntimeServicesData
, AllocationSize
, Buffer
);
615 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
617 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies
618 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
619 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
620 is not enough memory remaining to satisfy the request, then NULL is returned.
622 If Buffer is NULL, then ASSERT().
623 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
625 @param AllocationSize The number of bytes to allocate and zero.
626 @param Buffer The buffer to copy to the allocated buffer.
628 @return A pointer to the allocated buffer or NULL if allocation fails.
633 AllocateRuntimeCopyPool (
634 IN UINTN AllocationSize
,
635 IN CONST VOID
*Buffer
638 return InternalAllocateCopyPool (EfiRuntimeServicesData
, AllocationSize
, Buffer
);
642 Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
644 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies
645 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
646 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
647 is not enough memory remaining to satisfy the request, then NULL is returned.
649 If Buffer is NULL, then ASSERT().
650 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
652 @param AllocationSize The number of bytes to allocate and zero.
653 @param Buffer The buffer to copy to the allocated buffer.
655 @return A pointer to the allocated buffer or NULL if allocation fails.
660 AllocateReservedCopyPool (
661 IN UINTN AllocationSize
,
662 IN CONST VOID
*Buffer
669 Reallocates a buffer of a specified memory type.
671 Allocates and zeros the number bytes specified by NewSize from memory of the type
672 specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and
673 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
674 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
675 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
676 enough memory remaining to satisfy the request, then NULL is returned.
678 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
679 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
681 @param PoolType The type of pool to allocate.
682 @param OldSize The size, in bytes, of OldBuffer.
683 @param NewSize The size, in bytes, of the buffer to reallocate.
684 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
685 parameter that may be NULL.
687 @return A pointer to the allocated buffer or NULL if allocation fails.
691 InternalReallocatePool (
692 IN EFI_MEMORY_TYPE PoolType
,
695 IN VOID
*OldBuffer OPTIONAL
700 NewBuffer
= InternalAllocateZeroPool (PoolType
, NewSize
);
701 if ((NewBuffer
!= NULL
) && (OldBuffer
!= NULL
)) {
702 CopyMem (NewBuffer
, OldBuffer
, MIN (OldSize
, NewSize
));
703 FreePool (OldBuffer
);
710 Reallocates a buffer of type EfiBootServicesData.
712 Allocates and zeros the number bytes specified by NewSize from memory of type
713 EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
714 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
715 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
716 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
717 enough memory remaining to satisfy the request, then NULL is returned.
719 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
720 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
722 @param OldSize The size, in bytes, of OldBuffer.
723 @param NewSize The size, in bytes, of the buffer to reallocate.
724 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
725 parameter that may be NULL.
727 @return A pointer to the allocated buffer or NULL if allocation fails.
735 IN VOID
*OldBuffer OPTIONAL
738 return InternalReallocatePool (EfiRuntimeServicesData
, OldSize
, NewSize
, OldBuffer
);
742 Reallocates a buffer of type EfiRuntimeServicesData.
744 Allocates and zeros the number bytes specified by NewSize from memory of type
745 EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
746 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
747 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
748 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
749 enough memory remaining to satisfy the request, then NULL is returned.
751 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
752 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
754 @param OldSize The size, in bytes, of OldBuffer.
755 @param NewSize The size, in bytes, of the buffer to reallocate.
756 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
757 parameter that may be NULL.
759 @return A pointer to the allocated buffer or NULL if allocation fails.
764 ReallocateRuntimePool (
767 IN VOID
*OldBuffer OPTIONAL
770 return InternalReallocatePool (EfiRuntimeServicesData
, OldSize
, NewSize
, OldBuffer
);
774 Reallocates a buffer of type EfiReservedMemoryType.
776 Allocates and zeros the number bytes specified by NewSize from memory of type
777 EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and
778 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
779 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
780 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
781 enough memory remaining to satisfy the request, then NULL is returned.
783 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
784 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
786 @param OldSize The size, in bytes, of OldBuffer.
787 @param NewSize The size, in bytes, of the buffer to reallocate.
788 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
789 parameter that may be NULL.
791 @return A pointer to the allocated buffer or NULL if allocation fails.
796 ReallocateReservedPool (
799 IN VOID
*OldBuffer OPTIONAL
806 Frees a buffer that was previously allocated with one of the pool allocation functions in the
807 Memory Allocation Library.
809 Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the
810 pool allocation services of the Memory Allocation Library. If it is not possible to free pool
811 resources, then this function will perform no actions.
813 If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
816 @param Buffer Pointer to the buffer to free.
827 Status
= gMmst
->MmFreePool (Buffer
);
828 ASSERT_EFI_ERROR (Status
);
832 The constructor function calls MmInitializeMemoryServices to initialize
833 memory in MMRAM and caches EFI_MM_SYSTEM_TABLE pointer.
835 @param [in] ImageHandle The firmware allocated handle for the EFI image.
836 @param [in] MmSystemTable A pointer to the Management mode System Table.
838 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
843 MemoryAllocationLibConstructor (
844 IN EFI_HANDLE ImageHandle
,
845 IN EFI_MM_SYSTEM_TABLE
*MmSystemTable
848 MM_CORE_PRIVATE_DATA
*MmCorePrivate
;
849 EFI_HOB_GUID_TYPE
*GuidHob
;
850 MM_CORE_DATA_HOB_DATA
*DataInHob
;
852 EFI_MMRAM_HOB_DESCRIPTOR_BLOCK
*MmramRangesHobData
;
853 EFI_MMRAM_DESCRIPTOR
*MmramRanges
;
854 UINTN MmramRangeCount
;
855 EFI_HOB_GUID_TYPE
*MmramRangesHob
;
857 HobStart
= GetHobList ();
858 DEBUG ((DEBUG_INFO
, "StandaloneMmCoreMemoryAllocationLibConstructor - 0x%x\n", HobStart
));
861 // Extract MM Core Private context from the Hob. If absent search for
862 // a Hob containing the MMRAM ranges
864 GuidHob
= GetNextGuidHob (&gMmCoreDataHobGuid
, HobStart
);
865 if (GuidHob
== NULL
) {
866 MmramRangesHob
= GetNextGuidHob (&gEfiMmPeiMmramMemoryReserveGuid
, HobStart
);
867 if (MmramRangesHob
== NULL
) {
868 return EFI_UNSUPPORTED
;
871 MmramRangesHobData
= GET_GUID_HOB_DATA (MmramRangesHob
);
872 if (MmramRangesHobData
== NULL
) {
873 return EFI_UNSUPPORTED
;
876 MmramRanges
= MmramRangesHobData
->Descriptor
;
877 if (MmramRanges
== NULL
) {
878 return EFI_UNSUPPORTED
;
881 MmramRangeCount
= (UINTN
)MmramRangesHobData
->NumberOfMmReservedRegions
;
882 if (MmramRanges
== NULL
) {
883 return EFI_UNSUPPORTED
;
886 DataInHob
= GET_GUID_HOB_DATA (GuidHob
);
887 MmCorePrivate
= (MM_CORE_PRIVATE_DATA
*)(UINTN
)DataInHob
->Address
;
888 MmramRanges
= (EFI_MMRAM_DESCRIPTOR
*)(UINTN
)MmCorePrivate
->MmramRanges
;
889 MmramRangeCount
= (UINTN
)MmCorePrivate
->MmramRangeCount
;
895 DEBUG ((DEBUG_INFO
, "MmramRangeCount - 0x%x\n", MmramRangeCount
));
896 for (Index
= 0; Index
< MmramRangeCount
; Index
++) {
899 "MmramRanges[%d]: 0x%016lx - 0x%016lx\n",
901 MmramRanges
[Index
].CpuStart
,
902 MmramRanges
[Index
].PhysicalSize
908 // Initialize memory service using free MMRAM
910 DEBUG ((DEBUG_INFO
, "MmInitializeMemoryServices\n"));
911 MmInitializeMemoryServices ((UINTN
)MmramRangeCount
, (VOID
*)(UINTN
)MmramRanges
);
913 // Initialize MM Services Table
914 gMmst
= MmSystemTable
;