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
)))
134 Allocates one or more 4KB pages of a certain memory type.
136 Allocates the number of 4KB pages of a certain memory type and returns a pointer
137 to the allocated buffer. The buffer returned is aligned on a 4KB boundary. If
138 Pages is 0, then NULL is returned. If there is not enough memory remaining to
139 satisfy the request, then NULL is returned.
141 @param MemoryType The type of memory to allocate.
142 @param Pages The number of 4 KB pages to allocate.
144 @return A pointer to the allocated buffer or NULL if allocation fails.
148 InternalAllocatePages (
149 IN EFI_MEMORY_TYPE MemoryType
,
154 EFI_PHYSICAL_ADDRESS Memory
;
160 Status
= gSmst
->SmmAllocatePages (AllocateAnyPages
, MemoryType
, Pages
, &Memory
);
161 if (EFI_ERROR (Status
)) {
165 return (VOID
*)(UINTN
)Memory
;
169 Allocates one or more 4KB pages of type EfiRuntimeServicesData.
171 Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer
172 to the allocated buffer. The buffer returned is aligned on a 4KB boundary. If
173 Pages is 0, then NULL is returned. If there is not enough memory remaining to
174 satisfy the request, then NULL is returned.
176 @param Pages The number of 4 KB pages to allocate.
178 @return A pointer to the allocated buffer or NULL if allocation fails.
187 return InternalAllocatePages (EfiRuntimeServicesData
, Pages
);
191 Allocates one or more 4KB pages of type EfiRuntimeServicesData.
193 Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a
194 pointer to the allocated buffer. The buffer returned is aligned on a 4KB boundary.
195 If Pages is 0, then NULL is returned. If there is not enough memory remaining
196 to satisfy the request, then NULL is returned.
198 @param Pages The number of 4 KB pages to allocate.
200 @return A pointer to the allocated buffer or NULL if allocation fails.
205 AllocateRuntimePages (
209 return InternalAllocatePages (EfiRuntimeServicesData
, Pages
);
213 Allocates one or more 4KB pages of type EfiReservedMemoryType.
215 Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a
216 pointer to the allocated buffer. The buffer returned is aligned on a 4KB boundary.
217 If Pages is 0, then NULL is returned. If there is not enough memory remaining
218 to satisfy the request, then NULL is returned.
220 @param Pages The number of 4 KB pages to allocate.
222 @return A pointer to the allocated buffer or NULL if allocation fails.
227 AllocateReservedPages (
235 Frees one or more 4KB pages that were previously allocated with one of the page allocation
236 functions in the Memory Allocation Library.
238 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer.
239 Buffer must have been allocated on a previous call to the page allocation services
240 of the Memory Allocation Library. If it is not possible to free allocated pages,
241 then this function will perform no actions.
243 If Buffer was not allocated with a page allocation function in the Memory Allocation
244 Library, then ASSERT().
245 If Pages is zero, then ASSERT().
247 @param Buffer The pointer to the buffer of pages to free.
248 @param Pages The number of 4 KB pages to free.
261 if (BufferInSmram (Buffer
)) {
263 // When Buffer is in SMRAM range, it should be allocated by gSmst->SmmAllocatePages() service.
264 // So, gSmst->SmmFreePages() service is used to free it.
266 Status
= gSmst
->SmmFreePages ((EFI_PHYSICAL_ADDRESS
)(UINTN
)Buffer
, Pages
);
269 // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePages() service.
270 // So, gBS->FreePages() service is used to free it.
272 Status
= gBS
->FreePages ((EFI_PHYSICAL_ADDRESS
)(UINTN
)Buffer
, Pages
);
275 ASSERT_EFI_ERROR (Status
);
279 Allocates one or more 4KB pages of a certain memory type at a specified alignment.
281 Allocates the number of 4KB pages specified by Pages of a certain memory type
282 with an alignment specified by Alignment. The allocated buffer is returned.
283 If Pages is 0, then NULL is returned. If there is not enough memory at the
284 specified alignment remaining to satisfy the request, then NULL is returned.
285 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
286 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
288 @param MemoryType The type of memory to allocate.
289 @param Pages The number of 4 KB pages to allocate.
290 @param Alignment The requested alignment of the allocation.
291 Must be a power of two.
292 If Alignment is zero, then byte alignment is used.
294 @return A pointer to the allocated buffer or NULL if allocation fails.
298 InternalAllocateAlignedPages (
299 IN EFI_MEMORY_TYPE MemoryType
,
305 EFI_PHYSICAL_ADDRESS Memory
;
308 UINTN UnalignedPages
;
312 // Alignment must be a power of two or zero.
314 ASSERT ((Alignment
& (Alignment
- 1)) == 0);
320 if (Alignment
> EFI_PAGE_SIZE
) {
322 // Calculate the total number of pages since alignment is larger than page size.
324 AlignmentMask
= Alignment
- 1;
325 RealPages
= Pages
+ EFI_SIZE_TO_PAGES (Alignment
);
327 // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
329 ASSERT (RealPages
> Pages
);
331 Status
= gSmst
->SmmAllocatePages (AllocateAnyPages
, MemoryType
, RealPages
, &Memory
);
332 if (EFI_ERROR (Status
)) {
336 AlignedMemory
= ((UINTN
)Memory
+ AlignmentMask
) & ~AlignmentMask
;
337 UnalignedPages
= EFI_SIZE_TO_PAGES (AlignedMemory
- (UINTN
)Memory
);
338 if (UnalignedPages
> 0) {
340 // Free first unaligned page(s).
342 Status
= gSmst
->SmmFreePages (Memory
, UnalignedPages
);
343 ASSERT_EFI_ERROR (Status
);
346 Memory
= AlignedMemory
+ EFI_PAGES_TO_SIZE (Pages
);
347 UnalignedPages
= RealPages
- Pages
- UnalignedPages
;
348 if (UnalignedPages
> 0) {
350 // Free last unaligned page(s).
352 Status
= gSmst
->SmmFreePages (Memory
, UnalignedPages
);
353 ASSERT_EFI_ERROR (Status
);
357 // Do not over-allocate pages in this case.
359 Status
= gSmst
->SmmAllocatePages (AllocateAnyPages
, MemoryType
, Pages
, &Memory
);
360 if (EFI_ERROR (Status
)) {
364 AlignedMemory
= (UINTN
)Memory
;
367 return (VOID
*)AlignedMemory
;
371 Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
373 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData
374 with an alignment specified by Alignment. The allocated buffer is returned.
375 If Pages is 0, then NULL is returned. If there is not enough memory at the
376 specified alignment remaining to satisfy the request, then NULL is returned.
378 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
379 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
381 @param Pages The number of 4 KB pages to allocate.
382 @param Alignment The requested alignment of the allocation.
383 Must be a power of two.
384 If Alignment is zero, then byte alignment is used.
386 @return A pointer to the allocated buffer or NULL if allocation fails.
391 AllocateAlignedPages (
396 return InternalAllocateAlignedPages (EfiRuntimeServicesData
, Pages
, Alignment
);
400 Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
402 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData
403 with an alignment specified by Alignment. The allocated buffer is returned.
404 If Pages is 0, then NULL is returned. If there is not enough memory at the
405 specified alignment remaining to satisfy the request, then NULL is returned.
407 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
408 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
410 @param Pages The number of 4 KB pages to allocate.
411 @param Alignment The requested alignment of the allocation.
412 Must be a power of two.
413 If Alignment is zero, then byte alignment is used.
415 @return A pointer to the allocated buffer or NULL if allocation fails.
420 AllocateAlignedRuntimePages (
425 return InternalAllocateAlignedPages (EfiRuntimeServicesData
, Pages
, Alignment
);
429 Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
431 Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType
432 with an alignment specified by Alignment. The allocated buffer is returned.
433 If Pages is 0, then NULL is returned. If there is not enough memory at the
434 specified alignment remaining to satisfy the request, then NULL is returned.
436 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
437 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
439 @param Pages The number of 4 KB pages to allocate.
440 @param Alignment The requested alignment of the allocation.
441 Must be a power of two.
442 If Alignment is zero, then byte alignment is used.
444 @return A pointer to the allocated buffer or NULL if allocation fails.
449 AllocateAlignedReservedPages (
458 Frees one or more 4KB pages that were previously allocated with one of the aligned page
459 allocation functions in the Memory Allocation Library.
461 Frees the number of 4KB pages specified by Pages from the buffer specified by
462 Buffer. Buffer must have been allocated on a previous call to the aligned page
463 allocation services of the Memory Allocation Library. If it is not possible to
464 free allocated pages, then this function will perform no actions.
466 If Buffer was not allocated with an aligned page allocation function in the
467 Memory Allocation Library, then ASSERT().
468 If Pages is zero, then ASSERT().
470 @param Buffer The pointer to the buffer of pages to free.
471 @param Pages The number of 4 KB pages to free.
484 if (BufferInSmram (Buffer
)) {
486 // When Buffer is in SMRAM range, it should be allocated by gSmst->SmmAllocatePages() service.
487 // So, gSmst->SmmFreePages() service is used to free it.
489 Status
= gSmst
->SmmFreePages ((EFI_PHYSICAL_ADDRESS
)(UINTN
)Buffer
, Pages
);
492 // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePages() service.
493 // So, gBS->FreePages() service is used to free it.
495 Status
= gBS
->FreePages ((EFI_PHYSICAL_ADDRESS
)(UINTN
)Buffer
, Pages
);
498 ASSERT_EFI_ERROR (Status
);
502 Allocates a buffer of a certain pool type.
504 Allocates the number bytes specified by AllocationSize of a certain pool type
505 and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
506 valid buffer of 0 size is returned. If there is not enough memory remaining to
507 satisfy the request, then NULL is returned.
509 @param MemoryType The type of memory to allocate.
510 @param AllocationSize The number of bytes to allocate.
512 @return A pointer to the allocated buffer or NULL if allocation fails.
516 InternalAllocatePool (
517 IN EFI_MEMORY_TYPE MemoryType
,
518 IN UINTN AllocationSize
524 Status
= gSmst
->SmmAllocatePool (MemoryType
, AllocationSize
, &Memory
);
525 if (EFI_ERROR (Status
)) {
533 Allocates a buffer of type EfiRuntimeServicesData.
535 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData
536 and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
537 valid buffer of 0 size is returned. If there is not enough memory remaining to
538 satisfy the request, then NULL is returned.
540 @param AllocationSize The number of bytes to allocate.
542 @return A pointer to the allocated buffer or NULL if allocation fails.
548 IN UINTN AllocationSize
551 return InternalAllocatePool (EfiRuntimeServicesData
, AllocationSize
);
555 Allocates a buffer of type EfiRuntimeServicesData.
557 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData
558 and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
559 valid buffer of 0 size is returned. If there is not enough memory remaining to
560 satisfy the request, then NULL is returned.
562 @param AllocationSize The number of bytes to allocate.
564 @return A pointer to the allocated buffer or NULL if allocation fails.
569 AllocateRuntimePool (
570 IN UINTN AllocationSize
573 return InternalAllocatePool (EfiRuntimeServicesData
, AllocationSize
);
577 Allocates a buffer of type EfiReservedMemoryType.
579 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType
580 and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
581 valid buffer of 0 size is returned. If there is not enough memory remaining to
582 satisfy the request, then NULL is returned.
584 @param AllocationSize The number of bytes to allocate.
586 @return A pointer to the allocated buffer or NULL if allocation fails.
591 AllocateReservedPool (
592 IN UINTN AllocationSize
599 Allocates and zeros a buffer of a certain pool type.
601 Allocates the number bytes specified by AllocationSize of a certain pool type,
602 clears the buffer with zeros, and returns a pointer to the allocated buffer.
603 If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is
604 not enough memory remaining to satisfy the request, then NULL is returned.
606 @param PoolType The type of memory to allocate.
607 @param AllocationSize The number of bytes to allocate and zero.
609 @return A pointer to the allocated buffer or NULL if allocation fails.
613 InternalAllocateZeroPool (
614 IN EFI_MEMORY_TYPE PoolType
,
615 IN UINTN AllocationSize
620 Memory
= InternalAllocatePool (PoolType
, AllocationSize
);
621 if (Memory
!= NULL
) {
622 Memory
= ZeroMem (Memory
, AllocationSize
);
629 Allocates and zeros a buffer of type EfiRuntimeServicesData.
631 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData,
632 clears the buffer with zeros, and returns a pointer to the allocated buffer.
633 If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is
634 not enough memory remaining to satisfy the request, then NULL is returned.
636 @param AllocationSize The number of bytes to allocate and zero.
638 @return A pointer to the allocated buffer or NULL if allocation fails.
644 IN UINTN AllocationSize
647 return InternalAllocateZeroPool (EfiRuntimeServicesData
, AllocationSize
);
651 Allocates and zeros a buffer of type EfiRuntimeServicesData.
653 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData,
654 clears the buffer with zeros, and returns a pointer to the allocated buffer.
655 If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is
656 not enough memory remaining to satisfy the request, then NULL is returned.
658 @param AllocationSize The number of bytes to allocate and zero.
660 @return A pointer to the allocated buffer or NULL if allocation fails.
665 AllocateRuntimeZeroPool (
666 IN UINTN AllocationSize
669 return InternalAllocateZeroPool (EfiRuntimeServicesData
, AllocationSize
);
673 Allocates and zeros a buffer of type EfiReservedMemoryType.
675 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType,
676 clears the buffer with zeros, and returns a pointer to the allocated buffer.
677 If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is
678 not enough memory remaining to satisfy the request, then NULL is returned.
680 @param AllocationSize The number of bytes to allocate and zero.
682 @return A pointer to the allocated buffer or NULL if allocation fails.
687 AllocateReservedZeroPool (
688 IN UINTN AllocationSize
695 Copies a buffer to an allocated buffer of a certain pool type.
697 Allocates the number bytes specified by AllocationSize of a certain pool type,
698 copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns
699 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer
700 of 0 size is returned. If there is not enough memory remaining to satisfy the
701 request, then NULL is returned. If Buffer is NULL, then ASSERT().
702 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
704 @param PoolType The type of pool to allocate.
705 @param AllocationSize The number of bytes to allocate and zero.
706 @param Buffer The buffer to copy to the allocated buffer.
708 @return A pointer to the allocated buffer or NULL if allocation fails.
712 InternalAllocateCopyPool (
713 IN EFI_MEMORY_TYPE PoolType
,
714 IN UINTN AllocationSize
,
715 IN CONST VOID
*Buffer
720 ASSERT (Buffer
!= NULL
);
721 ASSERT (AllocationSize
<= (MAX_ADDRESS
- (UINTN
)Buffer
+ 1));
723 Memory
= InternalAllocatePool (PoolType
, AllocationSize
);
724 if (Memory
!= NULL
) {
725 Memory
= CopyMem (Memory
, Buffer
, AllocationSize
);
732 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
734 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData,
735 copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns
736 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer
737 of 0 size is returned. If there is not enough memory remaining to satisfy the
738 request, then NULL is returned.
740 If Buffer is NULL, then ASSERT().
741 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
743 @param AllocationSize The number of bytes to allocate and zero.
744 @param Buffer The buffer to copy to the allocated buffer.
746 @return A pointer to the allocated buffer or NULL if allocation fails.
752 IN UINTN AllocationSize
,
753 IN CONST VOID
*Buffer
756 return InternalAllocateCopyPool (EfiRuntimeServicesData
, AllocationSize
, Buffer
);
760 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
762 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData,
763 copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns
764 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer
765 of 0 size is returned. If there is not enough memory remaining to satisfy the
766 request, then NULL is returned.
768 If Buffer is NULL, then ASSERT().
769 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
771 @param AllocationSize The number of bytes to allocate and zero.
772 @param Buffer The buffer to copy to the allocated buffer.
774 @return A pointer to the allocated buffer or NULL if allocation fails.
779 AllocateRuntimeCopyPool (
780 IN UINTN AllocationSize
,
781 IN CONST VOID
*Buffer
784 return InternalAllocateCopyPool (EfiRuntimeServicesData
, AllocationSize
, Buffer
);
788 Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
790 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType,
791 copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns
792 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer
793 of 0 size is returned. If there is not enough memory remaining to satisfy the
794 request, then NULL is returned.
796 If Buffer is NULL, then ASSERT().
797 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
799 @param AllocationSize The number of bytes to allocate and zero.
800 @param Buffer The buffer to copy to the allocated buffer.
802 @return A pointer to the allocated buffer or NULL if allocation fails.
807 AllocateReservedCopyPool (
808 IN UINTN AllocationSize
,
809 IN CONST VOID
*Buffer
816 Reallocates a buffer of a specified memory type.
818 Allocates and zeros the number bytes specified by NewSize from memory of the type
819 specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and
820 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
821 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
822 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
823 enough memory remaining to satisfy the request, then NULL is returned.
825 If the allocation of the new buffer is successful and the smaller of NewSize
826 and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
828 @param PoolType The type of pool to allocate.
829 @param OldSize The size, in bytes, of OldBuffer.
830 @param NewSize The size, in bytes, of the buffer to reallocate.
831 @param OldBuffer The buffer to copy to the allocated buffer. This is an
832 optional parameter that may be NULL.
834 @return A pointer to the allocated buffer or NULL if allocation fails.
838 InternalReallocatePool (
839 IN EFI_MEMORY_TYPE PoolType
,
842 IN VOID
*OldBuffer OPTIONAL
847 NewBuffer
= InternalAllocateZeroPool (PoolType
, NewSize
);
848 if ((NewBuffer
!= NULL
) && (OldBuffer
!= NULL
)) {
849 CopyMem (NewBuffer
, OldBuffer
, MIN (OldSize
, NewSize
));
850 FreePool (OldBuffer
);
857 Reallocates a buffer of type EfiRuntimeServicesData.
859 Allocates and zeros the number bytes specified by NewSize from memory of type
860 EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
861 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
862 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
863 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
864 enough memory remaining to satisfy the request, then NULL is returned.
866 If the allocation of the new buffer is successful and the smaller of NewSize
867 and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
869 @param OldSize The size, in bytes, of OldBuffer.
870 @param NewSize The size, in bytes, of the buffer to reallocate.
871 @param OldBuffer The buffer to copy to the allocated buffer. This is an
872 optional parameter that may be NULL.
874 @return A pointer to the allocated buffer or NULL if allocation fails.
882 IN VOID
*OldBuffer OPTIONAL
885 return InternalReallocatePool (EfiRuntimeServicesData
, OldSize
, NewSize
, OldBuffer
);
889 Reallocates a buffer of type EfiRuntimeServicesData.
891 Allocates and zeros the number bytes specified by NewSize from memory of type
892 EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize
893 and NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
894 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
895 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
896 enough memory remaining to satisfy the request, then NULL is returned.
898 If the allocation of the new buffer is successful and the smaller of NewSize
899 and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
901 @param OldSize The size, in bytes, of OldBuffer.
902 @param NewSize The size, in bytes, of the buffer to reallocate.
903 @param OldBuffer The buffer to copy to the allocated buffer. This is an
904 optional parameter that may be NULL.
906 @return A pointer to the allocated buffer or NULL if allocation fails.
911 ReallocateRuntimePool (
914 IN VOID
*OldBuffer OPTIONAL
917 return InternalReallocatePool (EfiRuntimeServicesData
, OldSize
, NewSize
, OldBuffer
);
921 Reallocates a buffer of type EfiReservedMemoryType.
923 Allocates and zeros the number bytes specified by NewSize from memory of type
924 EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize
925 and NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
926 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
927 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
928 enough memory remaining to satisfy the request, then NULL is returned.
930 If the allocation of the new buffer is successful and the smaller of NewSize
931 and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
933 @param OldSize The size, in bytes, of OldBuffer.
934 @param NewSize The size, in bytes, of the buffer to reallocate.
935 @param OldBuffer The buffer to copy to the allocated buffer. This is an
936 optional parameter that may be NULL.
938 @return A pointer to the allocated buffer or NULL if allocation fails.
943 ReallocateReservedPool (
946 IN VOID
*OldBuffer OPTIONAL
953 Frees a buffer that was previously allocated with one of the pool allocation
954 functions in the Memory Allocation Library.
956 Frees the buffer specified by Buffer. Buffer must have been allocated on a
957 previous call to the pool allocation services of the Memory Allocation Library.
958 If it is not possible to free pool resources, then this function will perform
961 If Buffer was not allocated with a pool allocation function in the Memory
962 Allocation Library, then ASSERT().
964 @param Buffer The pointer to the buffer to free.
975 if (BufferInSmram (Buffer
)) {
977 // When Buffer is in SMRAM range, it should be allocated by gSmst->SmmAllocatePool() service.
978 // So, gSmst->SmmFreePool() service is used to free it.
980 Status
= gSmst
->SmmFreePool (Buffer
);
983 // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePool() service.
984 // So, gBS->FreePool() service is used to free it.
986 Status
= gBS
->FreePool (Buffer
);
989 ASSERT_EFI_ERROR (Status
);