2 Support routines for memory allocation routines based on SMM Core internal functions.
4 Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include <Protocol/SmmAccess2.h>
18 #include <Library/MemoryAllocationLib.h>
19 #include <Library/UefiBootServicesTableLib.h>
20 #include <Library/BaseMemoryLib.h>
21 #include <Library/DebugLib.h>
22 #include "PiSmmCoreMemoryAllocationServices.h"
24 EFI_SMRAM_DESCRIPTOR
*mSmmCoreMemoryAllocLibSmramRanges
= NULL
;
25 UINTN mSmmCoreMemoryAllocLibSmramRangeCount
= 0;
28 Check whether the start address of buffer is within any of the SMRAM ranges.
30 @param[in] Buffer The pointer to the buffer to be checked.
32 @retval TURE The buffer is in SMRAM ranges.
33 @retval FALSE The buffer is out of SMRAM ranges.
43 for (Index
= 0; Index
< mSmmCoreMemoryAllocLibSmramRangeCount
; Index
++) {
44 if (((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
>= mSmmCoreMemoryAllocLibSmramRanges
[Index
].CpuStart
) &&
45 ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
< (mSmmCoreMemoryAllocLibSmramRanges
[Index
].CpuStart
+ mSmmCoreMemoryAllocLibSmramRanges
[Index
].PhysicalSize
))) {
54 Allocates one or more 4KB pages of a certain memory type.
56 Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated
57 buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL is returned.
58 If there is not enough memory remaining to satisfy the request, then NULL is returned.
60 @param MemoryType The type of memory to allocate.
61 @param Pages The number of 4 KB pages to allocate.
63 @return A pointer to the allocated buffer or NULL if allocation fails.
67 InternalAllocatePages (
68 IN EFI_MEMORY_TYPE MemoryType
,
73 EFI_PHYSICAL_ADDRESS Memory
;
79 Status
= SmmAllocatePages (AllocateAnyPages
, MemoryType
, Pages
, &Memory
);
80 if (EFI_ERROR (Status
)) {
83 return (VOID
*) (UINTN
) Memory
;
87 Allocates one or more 4KB pages of type EfiBootServicesData.
89 Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the
90 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
91 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
94 @param Pages The number of 4 KB pages to allocate.
96 @return A pointer to the allocated buffer or NULL if allocation fails.
105 return InternalAllocatePages (EfiRuntimeServicesData
, Pages
);
109 Allocates one or more 4KB pages of type EfiRuntimeServicesData.
111 Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
112 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
113 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
116 @param Pages The number of 4 KB pages to allocate.
118 @return A pointer to the allocated buffer or NULL if allocation fails.
123 AllocateRuntimePages (
127 return InternalAllocatePages (EfiRuntimeServicesData
, Pages
);
131 Allocates one or more 4KB pages of type EfiReservedMemoryType.
133 Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the
134 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
135 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
138 @param Pages The number of 4 KB pages to allocate.
140 @return A pointer to the allocated buffer or NULL if allocation fails.
145 AllocateReservedPages (
153 Frees one or more 4KB pages that were previously allocated with one of the page allocation
154 functions in the Memory Allocation Library.
156 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
157 must have been allocated on a previous call to the page allocation services of the Memory
158 Allocation Library. If it is not possible to free allocated pages, then this function will
161 If Buffer was not allocated with a page allocation function in the Memory Allocation Library,
163 If Pages is zero, then ASSERT().
165 @param Buffer Pointer to the buffer of pages to free.
166 @param Pages The number of 4 KB pages to free.
179 if (BufferInSmram (Buffer
)) {
181 // When Buffer is in SMRAM range, it should be allocated by SmmAllocatePages() service.
182 // So, SmmFreePages() service is used to free it.
184 Status
= SmmFreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
, Pages
);
187 // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePages() service.
188 // So, gBS->FreePages() service is used to free it.
190 Status
= gBS
->FreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
, Pages
);
192 ASSERT_EFI_ERROR (Status
);
196 Allocates one or more 4KB pages of a certain memory type at a specified alignment.
198 Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment
199 specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned.
200 If there is not enough memory at the specified alignment remaining to satisfy the request, then
202 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
203 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
205 @param MemoryType The type of memory to allocate.
206 @param Pages The number of 4 KB pages to allocate.
207 @param Alignment The requested alignment of the allocation. Must be a power of two.
208 If Alignment is zero, then byte alignment is used.
210 @return A pointer to the allocated buffer or NULL if allocation fails.
214 InternalAllocateAlignedPages (
215 IN EFI_MEMORY_TYPE MemoryType
,
221 EFI_PHYSICAL_ADDRESS Memory
;
224 UINTN UnalignedPages
;
228 // Alignment must be a power of two or zero.
230 ASSERT ((Alignment
& (Alignment
- 1)) == 0);
235 if (Alignment
> EFI_PAGE_SIZE
) {
237 // Calculate the total number of pages since alignment is larger than page size.
239 AlignmentMask
= Alignment
- 1;
240 RealPages
= Pages
+ EFI_SIZE_TO_PAGES (Alignment
);
242 // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
244 ASSERT (RealPages
> Pages
);
246 Status
= SmmAllocatePages (AllocateAnyPages
, MemoryType
, RealPages
, &Memory
);
247 if (EFI_ERROR (Status
)) {
250 AlignedMemory
= ((UINTN
) Memory
+ AlignmentMask
) & ~AlignmentMask
;
251 UnalignedPages
= EFI_SIZE_TO_PAGES (AlignedMemory
- (UINTN
) Memory
);
252 if (UnalignedPages
> 0) {
254 // Free first unaligned page(s).
256 Status
= SmmFreePages (Memory
, UnalignedPages
);
257 ASSERT_EFI_ERROR (Status
);
259 Memory
= (EFI_PHYSICAL_ADDRESS
) (AlignedMemory
+ EFI_PAGES_TO_SIZE (Pages
));
260 UnalignedPages
= RealPages
- Pages
- UnalignedPages
;
261 if (UnalignedPages
> 0) {
263 // Free last unaligned page(s).
265 Status
= SmmFreePages (Memory
, UnalignedPages
);
266 ASSERT_EFI_ERROR (Status
);
270 // Do not over-allocate pages in this case.
272 Status
= SmmAllocatePages (AllocateAnyPages
, MemoryType
, Pages
, &Memory
);
273 if (EFI_ERROR (Status
)) {
276 AlignedMemory
= (UINTN
) Memory
;
278 return (VOID
*) AlignedMemory
;
282 Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment.
284 Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an
285 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
286 returned. If there is not enough memory at the specified alignment remaining to satisfy the
287 request, then NULL is returned.
289 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
290 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
292 @param Pages The number of 4 KB pages to allocate.
293 @param Alignment The requested alignment of the allocation. Must be a power of two.
294 If Alignment is zero, then byte alignment is used.
296 @return A pointer to the allocated buffer or NULL if allocation fails.
301 AllocateAlignedPages (
306 return InternalAllocateAlignedPages (EfiRuntimeServicesData
, Pages
, Alignment
);
310 Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
312 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an
313 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
314 returned. If there is not enough memory at the specified alignment remaining to satisfy the
315 request, then NULL is returned.
317 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
318 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
320 @param Pages The number of 4 KB pages to allocate.
321 @param Alignment The requested alignment of the allocation. Must be a power of two.
322 If Alignment is zero, then byte alignment is used.
324 @return A pointer to the allocated buffer or NULL if allocation fails.
329 AllocateAlignedRuntimePages (
334 return InternalAllocateAlignedPages (EfiRuntimeServicesData
, Pages
, Alignment
);
338 Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
340 Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an
341 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
342 returned. If there is not enough memory at the specified alignment remaining to satisfy the
343 request, then NULL is returned.
345 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
346 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
348 @param Pages The number of 4 KB pages to allocate.
349 @param Alignment The requested alignment of the allocation. Must be a power of two.
350 If Alignment is zero, then byte alignment is used.
352 @return A pointer to the allocated buffer or NULL if allocation fails.
357 AllocateAlignedReservedPages (
366 Frees one or more 4KB pages that were previously allocated with one of the aligned page
367 allocation functions in the Memory Allocation Library.
369 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
370 must have been allocated on a previous call to the aligned page allocation services of the Memory
371 Allocation Library. If it is not possible to free allocated pages, then this function will
374 If Buffer was not allocated with an aligned page allocation function in the Memory Allocation
375 Library, then ASSERT().
376 If Pages is zero, then ASSERT().
378 @param Buffer Pointer to the buffer of pages to free.
379 @param Pages The number of 4 KB pages to free.
392 if (BufferInSmram (Buffer
)) {
394 // When Buffer is in SMRAM range, it should be allocated by SmmAllocatePages() service.
395 // So, SmmFreePages() service is used to free it.
397 Status
= SmmFreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
, Pages
);
400 // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePages() service.
401 // So, gBS->FreePages() service is used to free it.
403 Status
= gBS
->FreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
, Pages
);
405 ASSERT_EFI_ERROR (Status
);
409 Allocates a buffer of a certain pool type.
411 Allocates the number bytes specified by AllocationSize of a certain pool type and returns a
412 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
413 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
415 @param MemoryType The type of memory to allocate.
416 @param AllocationSize The number of bytes to allocate.
418 @return A pointer to the allocated buffer or NULL if allocation fails.
422 InternalAllocatePool (
423 IN EFI_MEMORY_TYPE MemoryType
,
424 IN UINTN AllocationSize
432 Status
= SmmAllocatePool (MemoryType
, AllocationSize
, &Memory
);
433 if (EFI_ERROR (Status
)) {
440 Allocates a buffer of type EfiBootServicesData.
442 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a
443 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
444 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
446 @param AllocationSize The number of bytes to allocate.
448 @return A pointer to the allocated buffer or NULL if allocation fails.
454 IN UINTN AllocationSize
457 return InternalAllocatePool (EfiRuntimeServicesData
, AllocationSize
);
461 Allocates a buffer of type EfiRuntimeServicesData.
463 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns
464 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
465 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
467 @param AllocationSize The number of bytes to allocate.
469 @return A pointer to the allocated buffer or NULL if allocation fails.
474 AllocateRuntimePool (
475 IN UINTN AllocationSize
478 return InternalAllocatePool (EfiRuntimeServicesData
, AllocationSize
);
482 Allocates a buffer of type EfiReservedMemoryType.
484 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns
485 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
486 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
488 @param AllocationSize The number of bytes to allocate.
490 @return A pointer to the allocated buffer or NULL if allocation fails.
495 AllocateReservedPool (
496 IN UINTN AllocationSize
503 Allocates and zeros a buffer of a certain pool type.
505 Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer
506 with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid
507 buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request,
508 then NULL is returned.
510 @param PoolType The type of memory to allocate.
511 @param AllocationSize The number of bytes to allocate and zero.
513 @return A pointer to the allocated buffer or NULL if allocation fails.
517 InternalAllocateZeroPool (
518 IN EFI_MEMORY_TYPE PoolType
,
519 IN UINTN AllocationSize
524 Memory
= InternalAllocatePool (PoolType
, AllocationSize
);
525 if (Memory
!= NULL
) {
526 Memory
= ZeroMem (Memory
, AllocationSize
);
532 Allocates and zeros a buffer of type EfiBootServicesData.
534 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
535 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
536 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
537 request, then NULL is returned.
539 @param AllocationSize The number of bytes to allocate and zero.
541 @return A pointer to the allocated buffer or NULL if allocation fails.
547 IN UINTN AllocationSize
550 return InternalAllocateZeroPool (EfiRuntimeServicesData
, AllocationSize
);
554 Allocates and zeros a buffer of type EfiRuntimeServicesData.
556 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the
557 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
558 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
559 request, then NULL is returned.
561 @param AllocationSize The number of bytes to allocate and zero.
563 @return A pointer to the allocated buffer or NULL if allocation fails.
568 AllocateRuntimeZeroPool (
569 IN UINTN AllocationSize
572 return InternalAllocateZeroPool (EfiRuntimeServicesData
, AllocationSize
);
576 Allocates and zeros a buffer of type EfiReservedMemoryType.
578 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the
579 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
580 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
581 request, then NULL is returned.
583 @param AllocationSize The number of bytes to allocate and zero.
585 @return A pointer to the allocated buffer or NULL if allocation fails.
590 AllocateReservedZeroPool (
591 IN UINTN AllocationSize
598 Copies a buffer to an allocated buffer of a certain pool type.
600 Allocates the number bytes specified by AllocationSize of a certain pool type, copies
601 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
602 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
603 is not enough memory remaining to satisfy the request, then NULL is returned.
604 If Buffer is NULL, then ASSERT().
605 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
607 @param PoolType The type of pool to allocate.
608 @param AllocationSize The number of bytes to allocate and zero.
609 @param Buffer The buffer to copy to the allocated buffer.
611 @return A pointer to the allocated buffer or NULL if allocation fails.
615 InternalAllocateCopyPool (
616 IN EFI_MEMORY_TYPE PoolType
,
617 IN UINTN AllocationSize
,
618 IN CONST VOID
*Buffer
623 ASSERT (Buffer
!= NULL
);
624 ASSERT (AllocationSize
<= (MAX_ADDRESS
- (UINTN
) Buffer
+ 1));
626 Memory
= InternalAllocatePool (PoolType
, AllocationSize
);
627 if (Memory
!= NULL
) {
628 Memory
= CopyMem (Memory
, Buffer
, AllocationSize
);
634 Copies a buffer to an allocated buffer of type EfiBootServicesData.
636 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies
637 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
638 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
639 is not enough memory remaining to satisfy the request, then NULL is returned.
641 If Buffer is NULL, then ASSERT().
642 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
644 @param AllocationSize The number of bytes to allocate and zero.
645 @param Buffer The buffer to copy to the allocated buffer.
647 @return A pointer to the allocated buffer or NULL if allocation fails.
653 IN UINTN AllocationSize
,
654 IN CONST VOID
*Buffer
657 return InternalAllocateCopyPool (EfiRuntimeServicesData
, AllocationSize
, Buffer
);
661 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
663 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies
664 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
665 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
666 is not enough memory remaining to satisfy the request, then NULL is returned.
668 If Buffer is NULL, then ASSERT().
669 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
671 @param AllocationSize The number of bytes to allocate and zero.
672 @param Buffer The buffer to copy to the allocated buffer.
674 @return A pointer to the allocated buffer or NULL if allocation fails.
679 AllocateRuntimeCopyPool (
680 IN UINTN AllocationSize
,
681 IN CONST VOID
*Buffer
684 return InternalAllocateCopyPool (EfiRuntimeServicesData
, AllocationSize
, Buffer
);
688 Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
690 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies
691 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
692 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
693 is not enough memory remaining to satisfy the request, then NULL is returned.
695 If Buffer is NULL, then ASSERT().
696 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
698 @param AllocationSize The number of bytes to allocate and zero.
699 @param Buffer The buffer to copy to the allocated buffer.
701 @return A pointer to the allocated buffer or NULL if allocation fails.
706 AllocateReservedCopyPool (
707 IN UINTN AllocationSize
,
708 IN CONST VOID
*Buffer
715 Reallocates a buffer of a specified memory type.
717 Allocates and zeros the number bytes specified by NewSize from memory of the type
718 specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and
719 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
720 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
721 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
722 enough memory remaining to satisfy the request, then NULL is returned.
724 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
725 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
727 @param PoolType The type of pool to allocate.
728 @param OldSize The size, in bytes, of OldBuffer.
729 @param NewSize The size, in bytes, of the buffer to reallocate.
730 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
731 parameter that may be NULL.
733 @return A pointer to the allocated buffer or NULL if allocation fails.
737 InternalReallocatePool (
738 IN EFI_MEMORY_TYPE PoolType
,
741 IN VOID
*OldBuffer OPTIONAL
746 NewBuffer
= InternalAllocateZeroPool (PoolType
, NewSize
);
747 if (NewBuffer
!= NULL
&& OldBuffer
!= NULL
) {
748 CopyMem (NewBuffer
, OldBuffer
, MIN (OldSize
, NewSize
));
749 FreePool (OldBuffer
);
755 Reallocates a buffer of type EfiBootServicesData.
757 Allocates and zeros the number bytes specified by NewSize from memory of type
758 EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
759 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
760 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
761 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
762 enough memory remaining to satisfy the request, then NULL is returned.
764 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
765 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
767 @param OldSize The size, in bytes, of OldBuffer.
768 @param NewSize The size, in bytes, of the buffer to reallocate.
769 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
770 parameter that may be NULL.
772 @return A pointer to the allocated buffer or NULL if allocation fails.
780 IN VOID
*OldBuffer OPTIONAL
783 return InternalReallocatePool (EfiRuntimeServicesData
, OldSize
, NewSize
, OldBuffer
);
787 Reallocates a buffer of type EfiRuntimeServicesData.
789 Allocates and zeros the number bytes specified by NewSize from memory of type
790 EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
791 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
792 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
793 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
794 enough memory remaining to satisfy the request, then NULL is returned.
796 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
797 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
799 @param OldSize The size, in bytes, of OldBuffer.
800 @param NewSize The size, in bytes, of the buffer to reallocate.
801 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
802 parameter that may be NULL.
804 @return A pointer to the allocated buffer or NULL if allocation fails.
809 ReallocateRuntimePool (
812 IN VOID
*OldBuffer OPTIONAL
815 return InternalReallocatePool (EfiRuntimeServicesData
, OldSize
, NewSize
, OldBuffer
);
819 Reallocates a buffer of type EfiReservedMemoryType.
821 Allocates and zeros the number bytes specified by NewSize from memory of type
822 EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and
823 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
824 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
825 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
826 enough memory remaining to satisfy the request, then NULL is returned.
828 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
829 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
831 @param OldSize The size, in bytes, of OldBuffer.
832 @param NewSize The size, in bytes, of the buffer to reallocate.
833 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
834 parameter that may be NULL.
836 @return A pointer to the allocated buffer or NULL if allocation fails.
841 ReallocateReservedPool (
844 IN VOID
*OldBuffer OPTIONAL
851 Frees a buffer that was previously allocated with one of the pool allocation functions in the
852 Memory Allocation Library.
854 Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the
855 pool allocation services of the Memory Allocation Library. If it is not possible to free pool
856 resources, then this function will perform no actions.
858 If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
861 @param Buffer Pointer to the buffer to free.
872 if (BufferInSmram (Buffer
)) {
874 // When Buffer is in SMRAM range, it should be allocated by SmmAllocatePool() service.
875 // So, SmmFreePool() service is used to free it.
877 Status
= SmmFreePool (Buffer
);
880 // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePool() service.
881 // So, gBS->FreePool() service is used to free it.
883 Status
= gBS
->FreePool (Buffer
);
885 ASSERT_EFI_ERROR (Status
);
889 The constructor function calls SmmInitializeMemoryServices to initialize memory in SMRAM.
891 @param ImageHandle The firmware allocated handle for the EFI image.
892 @param SystemTable A pointer to the EFI System Table.
894 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
899 PiSmmCoreMemoryAllocationLibConstructor (
900 IN EFI_HANDLE ImageHandle
,
901 IN EFI_SYSTEM_TABLE
*SystemTable
904 SMM_CORE_PRIVATE_DATA
*SmmCorePrivate
;
907 SmmCorePrivate
= (SMM_CORE_PRIVATE_DATA
*)ImageHandle
;
909 // Initialize memory service using free SMRAM
911 SmmInitializeMemoryServices (SmmCorePrivate
->SmramRangeCount
, SmmCorePrivate
->SmramRanges
);
913 mSmmCoreMemoryAllocLibSmramRangeCount
= SmmCorePrivate
->FullSmramRangeCount
;
914 Size
= mSmmCoreMemoryAllocLibSmramRangeCount
* sizeof (EFI_SMRAM_DESCRIPTOR
);
915 mSmmCoreMemoryAllocLibSmramRanges
= (EFI_SMRAM_DESCRIPTOR
*) AllocatePool (Size
);
916 ASSERT (mSmmCoreMemoryAllocLibSmramRanges
!= NULL
);
917 CopyMem (mSmmCoreMemoryAllocLibSmramRanges
, SmmCorePrivate
->FullSmramRanges
, Size
);