2 Support routines for memory allocation routines based
3 on SMM Services Table services for SMM phase drivers.
5 The PI System Management Mode Core Interface Specification only allows the use
6 of EfiRuntimeServicesCode and EfiRuntimeServicesData memory types for memory
7 allocations through the SMM Services Table as the SMRAM space should be
8 reserved after BDS phase. The functions in the Memory Allocation Library use
9 EfiBootServicesData as the default memory allocation type. For this SMM
10 specific instance of the Memory Allocation Library, EfiRuntimeServicesData
11 is used as the default memory type for all allocations. In addition,
12 allocation for the Reserved memory types are not supported and will always
15 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
16 SPDX-License-Identifier: BSD-2-Clause-Patent
22 #include <Protocol/SmmAccess2.h>
23 #include <Library/MemoryAllocationLib.h>
24 #include <Library/UefiBootServicesTableLib.h>
25 #include <Library/SmmServicesTableLib.h>
26 #include <Library/BaseMemoryLib.h>
27 #include <Library/DebugLib.h>
29 EFI_SMRAM_DESCRIPTOR
*mSmramRanges
;
30 UINTN mSmramRangeCount
;
33 The constructor function caches SMRAM ranges that are present in the system.
35 It will ASSERT() if SMM Access2 Protocol doesn't exist.
36 It will ASSERT() if SMRAM ranges can't be got.
37 It will ASSERT() if Resource can't be allocated for cache SMRAM range.
38 It will always return EFI_SUCCESS.
40 @param ImageHandle The firmware allocated handle for the EFI image.
41 @param SystemTable A pointer to the EFI System Table.
43 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
48 SmmMemoryAllocationLibConstructor (
49 IN EFI_HANDLE ImageHandle
,
50 IN EFI_SYSTEM_TABLE
*SystemTable
54 EFI_SMM_ACCESS2_PROTOCOL
*SmmAccess
;
58 // Locate SMM Access2 Protocol
60 Status
= gBS
->LocateProtocol (
61 &gEfiSmmAccess2ProtocolGuid
,
65 ASSERT_EFI_ERROR (Status
);
68 // Get SMRAM range information
71 Status
= SmmAccess
->GetCapabilities (SmmAccess
, &Size
, NULL
);
72 ASSERT (Status
== EFI_BUFFER_TOO_SMALL
);
74 mSmramRanges
= (EFI_SMRAM_DESCRIPTOR
*) AllocatePool (Size
);
75 ASSERT (mSmramRanges
!= NULL
);
77 Status
= SmmAccess
->GetCapabilities (SmmAccess
, &Size
, mSmramRanges
);
78 ASSERT_EFI_ERROR (Status
);
80 mSmramRangeCount
= Size
/ sizeof (EFI_SMRAM_DESCRIPTOR
);
86 If SMM driver exits with an error, it must call this routine
87 to free the allocated resource before the exiting.
89 @param[in] ImageHandle The firmware allocated handle for the EFI image.
90 @param[in] SystemTable A pointer to the EFI System Table.
92 @retval EFI_SUCCESS The deconstructor always returns EFI_SUCCESS.
96 SmmMemoryAllocationLibDestructor (
97 IN EFI_HANDLE ImageHandle
,
98 IN EFI_SYSTEM_TABLE
*SystemTable
101 FreePool (mSmramRanges
);
107 Check whether the start address of buffer is within any of the SMRAM ranges.
109 @param[in] Buffer The pointer to the buffer to be checked.
111 @retval TRUE The buffer is in SMRAM ranges.
112 @retval FALSE The buffer is out of SMRAM ranges.
122 for (Index
= 0; Index
< mSmramRangeCount
; Index
++) {
123 if (((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
>= mSmramRanges
[Index
].CpuStart
) &&
124 ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
< (mSmramRanges
[Index
].CpuStart
+ mSmramRanges
[Index
].PhysicalSize
))) {
133 Allocates one or more 4KB pages of a certain memory type.
135 Allocates the number of 4KB pages of a certain memory type and returns a pointer
136 to the allocated buffer. The buffer returned is aligned on a 4KB boundary. If
137 Pages is 0, then NULL is returned. If there is not enough memory remaining to
138 satisfy the request, then NULL is returned.
140 @param MemoryType The type of memory to allocate.
141 @param Pages The number of 4 KB pages to allocate.
143 @return A pointer to the allocated buffer or NULL if allocation fails.
147 InternalAllocatePages (
148 IN EFI_MEMORY_TYPE MemoryType
,
153 EFI_PHYSICAL_ADDRESS Memory
;
159 Status
= gSmst
->SmmAllocatePages (AllocateAnyPages
, MemoryType
, Pages
, &Memory
);
160 if (EFI_ERROR (Status
)) {
163 return (VOID
*) (UINTN
) Memory
;
167 Allocates one or more 4KB pages of type EfiRuntimeServicesData.
169 Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer
170 to the allocated buffer. The buffer returned is aligned on a 4KB boundary. If
171 Pages is 0, then NULL is returned. If there is not enough memory remaining to
172 satisfy the request, then NULL is returned.
174 @param Pages The number of 4 KB pages to allocate.
176 @return A pointer to the allocated buffer or NULL if allocation fails.
185 return InternalAllocatePages (EfiRuntimeServicesData
, Pages
);
189 Allocates one or more 4KB pages of type EfiRuntimeServicesData.
191 Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a
192 pointer to the allocated buffer. The buffer returned is aligned on a 4KB boundary.
193 If Pages is 0, then NULL is returned. If there is not enough memory remaining
194 to satisfy the request, then NULL is returned.
196 @param Pages The number of 4 KB pages to allocate.
198 @return A pointer to the allocated buffer or NULL if allocation fails.
203 AllocateRuntimePages (
207 return InternalAllocatePages (EfiRuntimeServicesData
, Pages
);
211 Allocates one or more 4KB pages of type EfiReservedMemoryType.
213 Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a
214 pointer to the allocated buffer. The buffer returned is aligned on a 4KB boundary.
215 If Pages is 0, then NULL is returned. If there is not enough memory remaining
216 to satisfy the request, then NULL is returned.
218 @param Pages The number of 4 KB pages to allocate.
220 @return A pointer to the allocated buffer or NULL if allocation fails.
225 AllocateReservedPages (
233 Frees one or more 4KB pages that were previously allocated with one of the page allocation
234 functions in the Memory Allocation Library.
236 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer.
237 Buffer must have been allocated on a previous call to the page allocation services
238 of the Memory Allocation Library. If it is not possible to free allocated pages,
239 then this function will perform no actions.
241 If Buffer was not allocated with a page allocation function in the Memory Allocation
242 Library, then ASSERT().
243 If Pages is zero, then ASSERT().
245 @param Buffer The pointer to the buffer of pages to free.
246 @param Pages The number of 4 KB pages to free.
259 if (BufferInSmram (Buffer
)) {
261 // When Buffer is in SMRAM range, it should be allocated by gSmst->SmmAllocatePages() service.
262 // So, gSmst->SmmFreePages() service is used to free it.
264 Status
= gSmst
->SmmFreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
, Pages
);
267 // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePages() service.
268 // So, gBS->FreePages() service is used to free it.
270 Status
= gBS
->FreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
, Pages
);
272 ASSERT_EFI_ERROR (Status
);
276 Allocates one or more 4KB pages of a certain memory type at a specified alignment.
278 Allocates the number of 4KB pages specified by Pages of a certain memory type
279 with an alignment specified by Alignment. The allocated buffer is returned.
280 If Pages is 0, then NULL is returned. If there is not enough memory at the
281 specified alignment remaining to satisfy the request, then NULL is returned.
282 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
283 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
285 @param MemoryType The type of memory to allocate.
286 @param Pages The number of 4 KB pages to allocate.
287 @param Alignment The requested alignment of the allocation.
288 Must be a power of two.
289 If Alignment is zero, then byte alignment is used.
291 @return A pointer to the allocated buffer or NULL if allocation fails.
295 InternalAllocateAlignedPages (
296 IN EFI_MEMORY_TYPE MemoryType
,
302 EFI_PHYSICAL_ADDRESS Memory
;
305 UINTN UnalignedPages
;
309 // Alignment must be a power of two or zero.
311 ASSERT ((Alignment
& (Alignment
- 1)) == 0);
316 if (Alignment
> EFI_PAGE_SIZE
) {
318 // Calculate the total number of pages since alignment is larger than page size.
320 AlignmentMask
= Alignment
- 1;
321 RealPages
= Pages
+ EFI_SIZE_TO_PAGES (Alignment
);
323 // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
325 ASSERT (RealPages
> Pages
);
327 Status
= gSmst
->SmmAllocatePages (AllocateAnyPages
, MemoryType
, RealPages
, &Memory
);
328 if (EFI_ERROR (Status
)) {
331 AlignedMemory
= ((UINTN
) Memory
+ AlignmentMask
) & ~AlignmentMask
;
332 UnalignedPages
= EFI_SIZE_TO_PAGES (AlignedMemory
- (UINTN
) Memory
);
333 if (UnalignedPages
> 0) {
335 // Free first unaligned page(s).
337 Status
= gSmst
->SmmFreePages (Memory
, UnalignedPages
);
338 ASSERT_EFI_ERROR (Status
);
340 Memory
= AlignedMemory
+ EFI_PAGES_TO_SIZE (Pages
);
341 UnalignedPages
= RealPages
- Pages
- UnalignedPages
;
342 if (UnalignedPages
> 0) {
344 // Free last unaligned page(s).
346 Status
= gSmst
->SmmFreePages (Memory
, UnalignedPages
);
347 ASSERT_EFI_ERROR (Status
);
351 // Do not over-allocate pages in this case.
353 Status
= gSmst
->SmmAllocatePages (AllocateAnyPages
, MemoryType
, Pages
, &Memory
);
354 if (EFI_ERROR (Status
)) {
357 AlignedMemory
= (UINTN
) Memory
;
359 return (VOID
*) AlignedMemory
;
363 Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
365 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData
366 with an alignment specified by Alignment. The allocated buffer is returned.
367 If Pages is 0, then NULL is returned. If there is not enough memory at the
368 specified alignment remaining to satisfy the request, then NULL is returned.
370 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
371 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
373 @param Pages The number of 4 KB pages to allocate.
374 @param Alignment The requested alignment of the allocation.
375 Must be a power of two.
376 If Alignment is zero, then byte alignment is used.
378 @return A pointer to the allocated buffer or NULL if allocation fails.
383 AllocateAlignedPages (
388 return InternalAllocateAlignedPages (EfiRuntimeServicesData
, Pages
, Alignment
);
392 Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
394 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData
395 with an alignment specified by Alignment. The allocated buffer is returned.
396 If Pages is 0, then NULL is returned. If there is not enough memory at the
397 specified alignment remaining to satisfy the request, then NULL is returned.
399 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
400 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
402 @param Pages The number of 4 KB pages to allocate.
403 @param Alignment The requested alignment of the allocation.
404 Must be a power of two.
405 If Alignment is zero, then byte alignment is used.
407 @return A pointer to the allocated buffer or NULL if allocation fails.
412 AllocateAlignedRuntimePages (
417 return InternalAllocateAlignedPages (EfiRuntimeServicesData
, Pages
, Alignment
);
421 Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
423 Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType
424 with an alignment specified by Alignment. The allocated buffer is returned.
425 If Pages is 0, then NULL is returned. If there is not enough memory at the
426 specified alignment remaining to satisfy the request, then NULL is returned.
428 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
429 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
431 @param Pages The number of 4 KB pages to allocate.
432 @param Alignment The requested alignment of the allocation.
433 Must be a power of two.
434 If Alignment is zero, then byte alignment is used.
436 @return A pointer to the allocated buffer or NULL if allocation fails.
441 AllocateAlignedReservedPages (
450 Frees one or more 4KB pages that were previously allocated with one of the aligned page
451 allocation functions in the Memory Allocation Library.
453 Frees the number of 4KB pages specified by Pages from the buffer specified by
454 Buffer. Buffer must have been allocated on a previous call to the aligned page
455 allocation services of the Memory Allocation Library. If it is not possible to
456 free allocated pages, then this function will perform no actions.
458 If Buffer was not allocated with an aligned page allocation function in the
459 Memory Allocation Library, then ASSERT().
460 If Pages is zero, then ASSERT().
462 @param Buffer The pointer to the buffer of pages to free.
463 @param Pages The number of 4 KB pages to free.
476 if (BufferInSmram (Buffer
)) {
478 // When Buffer is in SMRAM range, it should be allocated by gSmst->SmmAllocatePages() service.
479 // So, gSmst->SmmFreePages() service is used to free it.
481 Status
= gSmst
->SmmFreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
, Pages
);
484 // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePages() service.
485 // So, gBS->FreePages() service is used to free it.
487 Status
= gBS
->FreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
, Pages
);
489 ASSERT_EFI_ERROR (Status
);
493 Allocates a buffer of a certain pool type.
495 Allocates the number bytes specified by AllocationSize of a certain pool type
496 and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
497 valid buffer of 0 size is returned. If there is not enough memory remaining to
498 satisfy the request, then NULL is returned.
500 @param MemoryType The type of memory to allocate.
501 @param AllocationSize The number of bytes to allocate.
503 @return A pointer to the allocated buffer or NULL if allocation fails.
507 InternalAllocatePool (
508 IN EFI_MEMORY_TYPE MemoryType
,
509 IN UINTN AllocationSize
515 Status
= gSmst
->SmmAllocatePool (MemoryType
, AllocationSize
, &Memory
);
516 if (EFI_ERROR (Status
)) {
523 Allocates a buffer of type EfiRuntimeServicesData.
525 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData
526 and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
527 valid buffer of 0 size is returned. If there is not enough memory remaining to
528 satisfy the request, then NULL is returned.
530 @param AllocationSize The number of bytes to allocate.
532 @return A pointer to the allocated buffer or NULL if allocation fails.
538 IN UINTN AllocationSize
541 return InternalAllocatePool (EfiRuntimeServicesData
, AllocationSize
);
545 Allocates a buffer of type EfiRuntimeServicesData.
547 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData
548 and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
549 valid buffer of 0 size is returned. If there is not enough memory remaining to
550 satisfy the request, then NULL is returned.
552 @param AllocationSize The number of bytes to allocate.
554 @return A pointer to the allocated buffer or NULL if allocation fails.
559 AllocateRuntimePool (
560 IN UINTN AllocationSize
563 return InternalAllocatePool (EfiRuntimeServicesData
, AllocationSize
);
567 Allocates a buffer of type EfiReservedMemoryType.
569 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType
570 and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
571 valid buffer of 0 size is returned. If there is not enough memory remaining to
572 satisfy the request, then NULL is returned.
574 @param AllocationSize The number of bytes to allocate.
576 @return A pointer to the allocated buffer or NULL if allocation fails.
581 AllocateReservedPool (
582 IN UINTN AllocationSize
589 Allocates and zeros a buffer of a certain pool type.
591 Allocates the number bytes specified by AllocationSize of a certain pool type,
592 clears the buffer with zeros, and returns a pointer to the allocated buffer.
593 If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is
594 not enough memory remaining to satisfy the request, then NULL is returned.
596 @param PoolType The type of memory to allocate.
597 @param AllocationSize The number of bytes to allocate and zero.
599 @return A pointer to the allocated buffer or NULL if allocation fails.
603 InternalAllocateZeroPool (
604 IN EFI_MEMORY_TYPE PoolType
,
605 IN UINTN AllocationSize
610 Memory
= InternalAllocatePool (PoolType
, AllocationSize
);
611 if (Memory
!= NULL
) {
612 Memory
= ZeroMem (Memory
, AllocationSize
);
618 Allocates and zeros a buffer of type EfiRuntimeServicesData.
620 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData,
621 clears the buffer with zeros, and returns a pointer to the allocated buffer.
622 If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is
623 not enough memory remaining to satisfy the request, then NULL is returned.
625 @param AllocationSize The number of bytes to allocate and zero.
627 @return A pointer to the allocated buffer or NULL if allocation fails.
633 IN UINTN AllocationSize
636 return InternalAllocateZeroPool (EfiRuntimeServicesData
, AllocationSize
);
640 Allocates and zeros a buffer of type EfiRuntimeServicesData.
642 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData,
643 clears the buffer with zeros, and returns a pointer to the allocated buffer.
644 If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is
645 not enough memory remaining to satisfy the request, then NULL is returned.
647 @param AllocationSize The number of bytes to allocate and zero.
649 @return A pointer to the allocated buffer or NULL if allocation fails.
654 AllocateRuntimeZeroPool (
655 IN UINTN AllocationSize
658 return InternalAllocateZeroPool (EfiRuntimeServicesData
, AllocationSize
);
662 Allocates and zeros a buffer of type EfiReservedMemoryType.
664 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType,
665 clears the buffer with zeros, and returns a pointer to the allocated buffer.
666 If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is
667 not enough memory remaining to satisfy the request, then NULL is returned.
669 @param AllocationSize The number of bytes to allocate and zero.
671 @return A pointer to the allocated buffer or NULL if allocation fails.
676 AllocateReservedZeroPool (
677 IN UINTN AllocationSize
684 Copies a buffer to an allocated buffer of a certain pool type.
686 Allocates the number bytes specified by AllocationSize of a certain pool type,
687 copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns
688 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer
689 of 0 size is returned. If there is not enough memory remaining to satisfy the
690 request, then NULL is returned. If Buffer is NULL, then ASSERT().
691 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
693 @param PoolType The type of pool to allocate.
694 @param AllocationSize The number of bytes to allocate and zero.
695 @param Buffer The buffer to copy to the allocated buffer.
697 @return A pointer to the allocated buffer or NULL if allocation fails.
701 InternalAllocateCopyPool (
702 IN EFI_MEMORY_TYPE PoolType
,
703 IN UINTN AllocationSize
,
704 IN CONST VOID
*Buffer
709 ASSERT (Buffer
!= NULL
);
710 ASSERT (AllocationSize
<= (MAX_ADDRESS
- (UINTN
) Buffer
+ 1));
712 Memory
= InternalAllocatePool (PoolType
, AllocationSize
);
713 if (Memory
!= NULL
) {
714 Memory
= CopyMem (Memory
, Buffer
, AllocationSize
);
720 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
722 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData,
723 copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns
724 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer
725 of 0 size is returned. If there is not enough memory remaining to satisfy the
726 request, then NULL is returned.
728 If Buffer is NULL, then ASSERT().
729 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
731 @param AllocationSize The number of bytes to allocate and zero.
732 @param Buffer The buffer to copy to the allocated buffer.
734 @return A pointer to the allocated buffer or NULL if allocation fails.
740 IN UINTN AllocationSize
,
741 IN CONST VOID
*Buffer
744 return InternalAllocateCopyPool (EfiRuntimeServicesData
, AllocationSize
, Buffer
);
748 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
750 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData,
751 copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns
752 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer
753 of 0 size is returned. If there is not enough memory remaining to satisfy the
754 request, then NULL is returned.
756 If Buffer is NULL, then ASSERT().
757 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
759 @param AllocationSize The number of bytes to allocate and zero.
760 @param Buffer The buffer to copy to the allocated buffer.
762 @return A pointer to the allocated buffer or NULL if allocation fails.
767 AllocateRuntimeCopyPool (
768 IN UINTN AllocationSize
,
769 IN CONST VOID
*Buffer
772 return InternalAllocateCopyPool (EfiRuntimeServicesData
, AllocationSize
, Buffer
);
776 Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
778 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType,
779 copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns
780 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer
781 of 0 size is returned. If there is not enough memory remaining to satisfy the
782 request, then NULL is returned.
784 If Buffer is NULL, then ASSERT().
785 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
787 @param AllocationSize The number of bytes to allocate and zero.
788 @param Buffer The buffer to copy to the allocated buffer.
790 @return A pointer to the allocated buffer or NULL if allocation fails.
795 AllocateReservedCopyPool (
796 IN UINTN AllocationSize
,
797 IN CONST VOID
*Buffer
804 Reallocates a buffer of a specified memory type.
806 Allocates and zeros the number bytes specified by NewSize from memory of the type
807 specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and
808 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
809 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
810 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
811 enough memory remaining to satisfy the request, then NULL is returned.
813 If the allocation of the new buffer is successful and the smaller of NewSize
814 and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
816 @param PoolType The type of pool to allocate.
817 @param OldSize The size, in bytes, of OldBuffer.
818 @param NewSize The size, in bytes, of the buffer to reallocate.
819 @param OldBuffer The buffer to copy to the allocated buffer. This is an
820 optional parameter that may be NULL.
822 @return A pointer to the allocated buffer or NULL if allocation fails.
826 InternalReallocatePool (
827 IN EFI_MEMORY_TYPE PoolType
,
830 IN VOID
*OldBuffer OPTIONAL
835 NewBuffer
= InternalAllocateZeroPool (PoolType
, NewSize
);
836 if (NewBuffer
!= NULL
&& OldBuffer
!= NULL
) {
837 CopyMem (NewBuffer
, OldBuffer
, MIN (OldSize
, NewSize
));
838 FreePool (OldBuffer
);
844 Reallocates a buffer of type EfiRuntimeServicesData.
846 Allocates and zeros the number bytes specified by NewSize from memory of type
847 EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
848 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
849 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
850 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
851 enough memory remaining to satisfy the request, then NULL is returned.
853 If the allocation of the new buffer is successful and the smaller of NewSize
854 and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
856 @param OldSize The size, in bytes, of OldBuffer.
857 @param NewSize The size, in bytes, of the buffer to reallocate.
858 @param OldBuffer The buffer to copy to the allocated buffer. This is an
859 optional parameter that may be NULL.
861 @return A pointer to the allocated buffer or NULL if allocation fails.
869 IN VOID
*OldBuffer OPTIONAL
872 return InternalReallocatePool (EfiRuntimeServicesData
, OldSize
, NewSize
, OldBuffer
);
876 Reallocates a buffer of type EfiRuntimeServicesData.
878 Allocates and zeros the number bytes specified by NewSize from memory of type
879 EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize
880 and NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
881 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
882 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
883 enough memory remaining to satisfy the request, then NULL is returned.
885 If the allocation of the new buffer is successful and the smaller of NewSize
886 and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
888 @param OldSize The size, in bytes, of OldBuffer.
889 @param NewSize The size, in bytes, of the buffer to reallocate.
890 @param OldBuffer The buffer to copy to the allocated buffer. This is an
891 optional parameter that may be NULL.
893 @return A pointer to the allocated buffer or NULL if allocation fails.
898 ReallocateRuntimePool (
901 IN VOID
*OldBuffer OPTIONAL
904 return InternalReallocatePool (EfiRuntimeServicesData
, OldSize
, NewSize
, OldBuffer
);
908 Reallocates a buffer of type EfiReservedMemoryType.
910 Allocates and zeros the number bytes specified by NewSize from memory of type
911 EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize
912 and NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
913 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
914 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
915 enough memory remaining to satisfy the request, then NULL is returned.
917 If the allocation of the new buffer is successful and the smaller of NewSize
918 and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
920 @param OldSize The size, in bytes, of OldBuffer.
921 @param NewSize The size, in bytes, of the buffer to reallocate.
922 @param OldBuffer The buffer to copy to the allocated buffer. This is an
923 optional parameter that may be NULL.
925 @return A pointer to the allocated buffer or NULL if allocation fails.
930 ReallocateReservedPool (
933 IN VOID
*OldBuffer OPTIONAL
940 Frees a buffer that was previously allocated with one of the pool allocation
941 functions in the Memory Allocation Library.
943 Frees the buffer specified by Buffer. Buffer must have been allocated on a
944 previous call to the pool allocation services of the Memory Allocation Library.
945 If it is not possible to free pool resources, then this function will perform
948 If Buffer was not allocated with a pool allocation function in the Memory
949 Allocation Library, then ASSERT().
951 @param Buffer The pointer to the buffer to free.
962 if (BufferInSmram (Buffer
)) {
964 // When Buffer is in SMRAM range, it should be allocated by gSmst->SmmAllocatePool() service.
965 // So, gSmst->SmmFreePool() service is used to free it.
967 Status
= gSmst
->SmmFreePool (Buffer
);
970 // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePool() service.
971 // So, gBS->FreePool() service is used to free it.
973 Status
= gBS
->FreePool (Buffer
);
975 ASSERT_EFI_ERROR (Status
);