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 - 2017, Intel Corporation. All rights reserved.<BR>
16 This program and the accompanying materials
17 are licensed and made available under the terms and conditions of the BSD License
18 which accompanies this distribution. The full text of the license may be found at
19 http://opensource.org/licenses/bsd-license.php.
21 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
22 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
28 #include <Protocol/SmmAccess2.h>
29 #include <Library/MemoryAllocationLib.h>
30 #include <Library/UefiBootServicesTableLib.h>
31 #include <Library/SmmServicesTableLib.h>
32 #include <Library/BaseMemoryLib.h>
33 #include <Library/DebugLib.h>
35 EFI_SMRAM_DESCRIPTOR
*mSmramRanges
;
36 UINTN mSmramRangeCount
;
39 The constructor function caches SMRAM ranges that are present in the system.
41 It will ASSERT() if SMM Access2 Protocol doesn't exist.
42 It will ASSERT() if SMRAM ranges can't be got.
43 It will ASSERT() if Resource can't be allocated for cache SMRAM range.
44 It will always return EFI_SUCCESS.
46 @param ImageHandle The firmware allocated handle for the EFI image.
47 @param SystemTable A pointer to the EFI System Table.
49 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
54 SmmMemoryAllocationLibConstructor (
55 IN EFI_HANDLE ImageHandle
,
56 IN EFI_SYSTEM_TABLE
*SystemTable
60 EFI_SMM_ACCESS2_PROTOCOL
*SmmAccess
;
64 // Locate SMM Access2 Protocol
66 Status
= gBS
->LocateProtocol (
67 &gEfiSmmAccess2ProtocolGuid
,
71 ASSERT_EFI_ERROR (Status
);
74 // Get SMRAM range information
77 Status
= SmmAccess
->GetCapabilities (SmmAccess
, &Size
, NULL
);
78 ASSERT (Status
== EFI_BUFFER_TOO_SMALL
);
80 mSmramRanges
= (EFI_SMRAM_DESCRIPTOR
*) AllocatePool (Size
);
81 ASSERT (mSmramRanges
!= NULL
);
83 Status
= SmmAccess
->GetCapabilities (SmmAccess
, &Size
, mSmramRanges
);
84 ASSERT_EFI_ERROR (Status
);
86 mSmramRangeCount
= Size
/ sizeof (EFI_SMRAM_DESCRIPTOR
);
92 If SMM driver exits with an error, it must call this routine
93 to free the allocated resource before the exiting.
95 @param[in] ImageHandle The firmware allocated handle for the EFI image.
96 @param[in] SystemTable A pointer to the EFI System Table.
98 @retval EFI_SUCCESS The deconstructor always returns EFI_SUCCESS.
102 SmmMemoryAllocationLibDestructor (
103 IN EFI_HANDLE ImageHandle
,
104 IN EFI_SYSTEM_TABLE
*SystemTable
107 FreePool (mSmramRanges
);
113 Check whether the start address of buffer is within any of the SMRAM ranges.
115 @param[in] Buffer The pointer to the buffer to be checked.
117 @retval TRUE The buffer is in SMRAM ranges.
118 @retval FALSE The buffer is out of SMRAM ranges.
128 for (Index
= 0; Index
< mSmramRangeCount
; Index
++) {
129 if (((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
>= mSmramRanges
[Index
].CpuStart
) &&
130 ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
< (mSmramRanges
[Index
].CpuStart
+ mSmramRanges
[Index
].PhysicalSize
))) {
139 Allocates one or more 4KB pages of a certain memory type.
141 Allocates the number of 4KB pages of a certain memory type and returns a pointer
142 to the allocated buffer. The buffer returned is aligned on a 4KB boundary. If
143 Pages is 0, then NULL is returned. If there is not enough memory remaining to
144 satisfy the request, then NULL is returned.
146 @param MemoryType The type of memory to allocate.
147 @param Pages The number of 4 KB pages to allocate.
149 @return A pointer to the allocated buffer or NULL if allocation fails.
153 InternalAllocatePages (
154 IN EFI_MEMORY_TYPE MemoryType
,
159 EFI_PHYSICAL_ADDRESS Memory
;
165 Status
= gSmst
->SmmAllocatePages (AllocateAnyPages
, MemoryType
, Pages
, &Memory
);
166 if (EFI_ERROR (Status
)) {
169 return (VOID
*) (UINTN
) Memory
;
173 Allocates one or more 4KB pages of type EfiRuntimeServicesData.
175 Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer
176 to the allocated buffer. The buffer returned is aligned on a 4KB boundary. If
177 Pages is 0, then NULL is returned. If there is not enough memory remaining to
178 satisfy the request, then NULL is returned.
180 @param Pages The number of 4 KB pages to allocate.
182 @return A pointer to the allocated buffer or NULL if allocation fails.
191 return InternalAllocatePages (EfiRuntimeServicesData
, Pages
);
195 Allocates one or more 4KB pages of type EfiRuntimeServicesData.
197 Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a
198 pointer to the allocated buffer. The buffer returned is aligned on a 4KB boundary.
199 If Pages is 0, then NULL is returned. If there is not enough memory remaining
200 to satisfy the request, then NULL is returned.
202 @param Pages The number of 4 KB pages to allocate.
204 @return A pointer to the allocated buffer or NULL if allocation fails.
209 AllocateRuntimePages (
213 return InternalAllocatePages (EfiRuntimeServicesData
, Pages
);
217 Allocates one or more 4KB pages of type EfiReservedMemoryType.
219 Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a
220 pointer to the allocated buffer. The buffer returned is aligned on a 4KB boundary.
221 If Pages is 0, then NULL is returned. If there is not enough memory remaining
222 to satisfy the request, then NULL is returned.
224 @param Pages The number of 4 KB pages to allocate.
226 @return A pointer to the allocated buffer or NULL if allocation fails.
231 AllocateReservedPages (
239 Frees one or more 4KB pages that were previously allocated with one of the page allocation
240 functions in the Memory Allocation Library.
242 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer.
243 Buffer must have been allocated on a previous call to the page allocation services
244 of the Memory Allocation Library. If it is not possible to free allocated pages,
245 then this function will perform no actions.
247 If Buffer was not allocated with a page allocation function in the Memory Allocation
248 Library, then ASSERT().
249 If Pages is zero, then ASSERT().
251 @param Buffer The pointer to the buffer of pages to free.
252 @param Pages The number of 4 KB pages to free.
265 if (BufferInSmram (Buffer
)) {
267 // When Buffer is in SMRAM range, it should be allocated by gSmst->SmmAllocatePages() service.
268 // So, gSmst->SmmFreePages() service is used to free it.
270 Status
= gSmst
->SmmFreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
, Pages
);
273 // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePages() service.
274 // So, gBS->FreePages() service is used to free it.
276 Status
= gBS
->FreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
, Pages
);
278 ASSERT_EFI_ERROR (Status
);
282 Allocates one or more 4KB pages of a certain memory type at a specified alignment.
284 Allocates the number of 4KB pages specified by Pages of a certain memory type
285 with an alignment specified by Alignment. The allocated buffer is returned.
286 If Pages is 0, then NULL is returned. If there is not enough memory at the
287 specified alignment remaining to satisfy the request, then NULL is returned.
288 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
289 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
291 @param MemoryType The type of memory to allocate.
292 @param Pages The number of 4 KB pages to allocate.
293 @param Alignment The requested alignment of the allocation.
294 Must be a power of two.
295 If Alignment is zero, then byte alignment is used.
297 @return A pointer to the allocated buffer or NULL if allocation fails.
301 InternalAllocateAlignedPages (
302 IN EFI_MEMORY_TYPE MemoryType
,
308 EFI_PHYSICAL_ADDRESS Memory
;
311 UINTN UnalignedPages
;
315 // Alignment must be a power of two or zero.
317 ASSERT ((Alignment
& (Alignment
- 1)) == 0);
322 if (Alignment
> EFI_PAGE_SIZE
) {
324 // Calculate the total number of pages since alignment is larger than page size.
326 AlignmentMask
= Alignment
- 1;
327 RealPages
= Pages
+ EFI_SIZE_TO_PAGES (Alignment
);
329 // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
331 ASSERT (RealPages
> Pages
);
333 Status
= gSmst
->SmmAllocatePages (AllocateAnyPages
, MemoryType
, RealPages
, &Memory
);
334 if (EFI_ERROR (Status
)) {
337 AlignedMemory
= ((UINTN
) Memory
+ AlignmentMask
) & ~AlignmentMask
;
338 UnalignedPages
= EFI_SIZE_TO_PAGES (AlignedMemory
- (UINTN
) Memory
);
339 if (UnalignedPages
> 0) {
341 // Free first unaligned page(s).
343 Status
= gSmst
->SmmFreePages (Memory
, UnalignedPages
);
344 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
)) {
363 AlignedMemory
= (UINTN
) Memory
;
365 return (VOID
*) AlignedMemory
;
369 Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
371 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData
372 with an alignment specified by Alignment. The allocated buffer is returned.
373 If Pages is 0, then NULL is returned. If there is not enough memory at the
374 specified alignment remaining to satisfy the request, then NULL is returned.
376 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
377 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
379 @param Pages The number of 4 KB pages to allocate.
380 @param Alignment The requested alignment of the allocation.
381 Must be a power of two.
382 If Alignment is zero, then byte alignment is used.
384 @return A pointer to the allocated buffer or NULL if allocation fails.
389 AllocateAlignedPages (
394 return InternalAllocateAlignedPages (EfiRuntimeServicesData
, Pages
, Alignment
);
398 Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
400 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData
401 with an alignment specified by Alignment. The allocated buffer is returned.
402 If Pages is 0, then NULL is returned. If there is not enough memory at the
403 specified alignment remaining to satisfy the request, then NULL is returned.
405 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
406 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
408 @param Pages The number of 4 KB pages to allocate.
409 @param Alignment The requested alignment of the allocation.
410 Must be a power of two.
411 If Alignment is zero, then byte alignment is used.
413 @return A pointer to the allocated buffer or NULL if allocation fails.
418 AllocateAlignedRuntimePages (
423 return InternalAllocateAlignedPages (EfiRuntimeServicesData
, Pages
, Alignment
);
427 Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
429 Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType
430 with an alignment specified by Alignment. The allocated buffer is returned.
431 If Pages is 0, then NULL is returned. If there is not enough memory at the
432 specified alignment remaining to satisfy the request, then NULL is returned.
434 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
435 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
437 @param Pages The number of 4 KB pages to allocate.
438 @param Alignment The requested alignment of the allocation.
439 Must be a power of two.
440 If Alignment is zero, then byte alignment is used.
442 @return A pointer to the allocated buffer or NULL if allocation fails.
447 AllocateAlignedReservedPages (
456 Frees one or more 4KB pages that were previously allocated with one of the aligned page
457 allocation functions in the Memory Allocation Library.
459 Frees the number of 4KB pages specified by Pages from the buffer specified by
460 Buffer. Buffer must have been allocated on a previous call to the aligned page
461 allocation services of the Memory Allocation Library. If it is not possible to
462 free allocated pages, then this function will perform no actions.
464 If Buffer was not allocated with an aligned page allocation function in the
465 Memory Allocation Library, then ASSERT().
466 If Pages is zero, then ASSERT().
468 @param Buffer The pointer to the buffer of pages to free.
469 @param Pages The number of 4 KB pages to free.
482 if (BufferInSmram (Buffer
)) {
484 // When Buffer is in SMRAM range, it should be allocated by gSmst->SmmAllocatePages() service.
485 // So, gSmst->SmmFreePages() service is used to free it.
487 Status
= gSmst
->SmmFreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
, Pages
);
490 // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePages() service.
491 // So, gBS->FreePages() service is used to free it.
493 Status
= gBS
->FreePages ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Buffer
, Pages
);
495 ASSERT_EFI_ERROR (Status
);
499 Allocates a buffer of a certain pool type.
501 Allocates the number bytes specified by AllocationSize of a certain pool type
502 and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
503 valid buffer of 0 size is returned. If there is not enough memory remaining to
504 satisfy the request, then NULL is returned.
506 @param MemoryType The type of memory to allocate.
507 @param AllocationSize The number of bytes to allocate.
509 @return A pointer to the allocated buffer or NULL if allocation fails.
513 InternalAllocatePool (
514 IN EFI_MEMORY_TYPE MemoryType
,
515 IN UINTN AllocationSize
521 Status
= gSmst
->SmmAllocatePool (MemoryType
, AllocationSize
, &Memory
);
522 if (EFI_ERROR (Status
)) {
529 Allocates a buffer of type EfiRuntimeServicesData.
531 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData
532 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
534 satisfy the request, then NULL is returned.
536 @param AllocationSize The number of bytes to allocate.
538 @return A pointer to the allocated buffer or NULL if allocation fails.
544 IN UINTN AllocationSize
547 return InternalAllocatePool (EfiRuntimeServicesData
, AllocationSize
);
551 Allocates a buffer of type EfiRuntimeServicesData.
553 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData
554 and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
555 valid buffer of 0 size is returned. If there is not enough memory remaining to
556 satisfy the request, then NULL is returned.
558 @param AllocationSize The number of bytes to allocate.
560 @return A pointer to the allocated buffer or NULL if allocation fails.
565 AllocateRuntimePool (
566 IN UINTN AllocationSize
569 return InternalAllocatePool (EfiRuntimeServicesData
, AllocationSize
);
573 Allocates a buffer of type EfiReservedMemoryType.
575 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType
576 and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
577 valid buffer of 0 size is returned. If there is not enough memory remaining to
578 satisfy the request, then NULL is returned.
580 @param AllocationSize The number of bytes to allocate.
582 @return A pointer to the allocated buffer or NULL if allocation fails.
587 AllocateReservedPool (
588 IN UINTN AllocationSize
595 Allocates and zeros a buffer of a certain pool type.
597 Allocates the number bytes specified by AllocationSize of a certain pool type,
598 clears the buffer with zeros, and returns a pointer to the allocated buffer.
599 If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is
600 not enough memory remaining to satisfy the request, then NULL is returned.
602 @param PoolType The type of memory to allocate.
603 @param AllocationSize The number of bytes to allocate and zero.
605 @return A pointer to the allocated buffer or NULL if allocation fails.
609 InternalAllocateZeroPool (
610 IN EFI_MEMORY_TYPE PoolType
,
611 IN UINTN AllocationSize
616 Memory
= InternalAllocatePool (PoolType
, AllocationSize
);
617 if (Memory
!= NULL
) {
618 Memory
= ZeroMem (Memory
, AllocationSize
);
624 Allocates and zeros a buffer of type EfiRuntimeServicesData.
626 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData,
627 clears the buffer with zeros, and returns a pointer to the allocated buffer.
628 If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is
629 not enough memory remaining to satisfy the request, then NULL is returned.
631 @param AllocationSize The number of bytes to allocate and zero.
633 @return A pointer to the allocated buffer or NULL if allocation fails.
639 IN UINTN AllocationSize
642 return InternalAllocateZeroPool (EfiRuntimeServicesData
, AllocationSize
);
646 Allocates and zeros a buffer of type EfiRuntimeServicesData.
648 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData,
649 clears the buffer with zeros, and returns a pointer to the allocated buffer.
650 If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is
651 not enough memory remaining to satisfy the request, then NULL is returned.
653 @param AllocationSize The number of bytes to allocate and zero.
655 @return A pointer to the allocated buffer or NULL if allocation fails.
660 AllocateRuntimeZeroPool (
661 IN UINTN AllocationSize
664 return InternalAllocateZeroPool (EfiRuntimeServicesData
, AllocationSize
);
668 Allocates and zeros a buffer of type EfiReservedMemoryType.
670 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType,
671 clears the buffer with zeros, and returns a pointer to the allocated buffer.
672 If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is
673 not enough memory remaining to satisfy the request, then NULL is returned.
675 @param AllocationSize The number of bytes to allocate and zero.
677 @return A pointer to the allocated buffer or NULL if allocation fails.
682 AllocateReservedZeroPool (
683 IN UINTN AllocationSize
690 Copies a buffer to an allocated buffer of a certain pool type.
692 Allocates the number bytes specified by AllocationSize of a certain pool type,
693 copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns
694 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer
695 of 0 size is returned. If there is not enough memory remaining to satisfy the
696 request, then NULL is returned. If Buffer is NULL, then ASSERT().
697 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
699 @param PoolType The type of pool to allocate.
700 @param AllocationSize The number of bytes to allocate and zero.
701 @param Buffer The buffer to copy to the allocated buffer.
703 @return A pointer to the allocated buffer or NULL if allocation fails.
707 InternalAllocateCopyPool (
708 IN EFI_MEMORY_TYPE PoolType
,
709 IN UINTN AllocationSize
,
710 IN CONST VOID
*Buffer
715 ASSERT (Buffer
!= NULL
);
716 ASSERT (AllocationSize
<= (MAX_ADDRESS
- (UINTN
) Buffer
+ 1));
718 Memory
= InternalAllocatePool (PoolType
, AllocationSize
);
719 if (Memory
!= NULL
) {
720 Memory
= CopyMem (Memory
, Buffer
, AllocationSize
);
726 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
728 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData,
729 copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns
730 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer
731 of 0 size is returned. If there is not enough memory remaining to satisfy the
732 request, then NULL is returned.
734 If Buffer is NULL, then ASSERT().
735 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
737 @param AllocationSize The number of bytes to allocate and zero.
738 @param Buffer The buffer to copy to the allocated buffer.
740 @return A pointer to the allocated buffer or NULL if allocation fails.
746 IN UINTN AllocationSize
,
747 IN CONST VOID
*Buffer
750 return InternalAllocateCopyPool (EfiRuntimeServicesData
, AllocationSize
, Buffer
);
754 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
756 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData,
757 copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns
758 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer
759 of 0 size is returned. If there is not enough memory remaining to satisfy the
760 request, then NULL is returned.
762 If Buffer is NULL, then ASSERT().
763 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
765 @param AllocationSize The number of bytes to allocate and zero.
766 @param Buffer The buffer to copy to the allocated buffer.
768 @return A pointer to the allocated buffer or NULL if allocation fails.
773 AllocateRuntimeCopyPool (
774 IN UINTN AllocationSize
,
775 IN CONST VOID
*Buffer
778 return InternalAllocateCopyPool (EfiRuntimeServicesData
, AllocationSize
, Buffer
);
782 Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
784 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType,
785 copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns
786 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer
787 of 0 size is returned. If there is not enough memory remaining to satisfy the
788 request, then NULL is returned.
790 If Buffer is NULL, then ASSERT().
791 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
793 @param AllocationSize The number of bytes to allocate and zero.
794 @param Buffer The buffer to copy to the allocated buffer.
796 @return A pointer to the allocated buffer or NULL if allocation fails.
801 AllocateReservedCopyPool (
802 IN UINTN AllocationSize
,
803 IN CONST VOID
*Buffer
810 Reallocates a buffer of a specified memory type.
812 Allocates and zeros the number bytes specified by NewSize from memory of the type
813 specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and
814 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
815 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
816 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
817 enough memory remaining to satisfy the request, then NULL is returned.
819 If the allocation of the new buffer is successful and the smaller of NewSize
820 and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
822 @param PoolType The type of pool to allocate.
823 @param OldSize The size, in bytes, of OldBuffer.
824 @param NewSize The size, in bytes, of the buffer to reallocate.
825 @param OldBuffer The buffer to copy to the allocated buffer. This is an
826 optional parameter that may be NULL.
828 @return A pointer to the allocated buffer or NULL if allocation fails.
832 InternalReallocatePool (
833 IN EFI_MEMORY_TYPE PoolType
,
836 IN VOID
*OldBuffer OPTIONAL
841 NewBuffer
= InternalAllocateZeroPool (PoolType
, NewSize
);
842 if (NewBuffer
!= NULL
&& OldBuffer
!= NULL
) {
843 CopyMem (NewBuffer
, OldBuffer
, MIN (OldSize
, NewSize
));
844 FreePool (OldBuffer
);
850 Reallocates a buffer of type EfiRuntimeServicesData.
852 Allocates and zeros the number bytes specified by NewSize from memory of type
853 EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
854 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
855 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
856 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
857 enough memory remaining to satisfy the request, then NULL is returned.
859 If the allocation of the new buffer is successful and the smaller of NewSize
860 and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
862 @param OldSize The size, in bytes, of OldBuffer.
863 @param NewSize The size, in bytes, of the buffer to reallocate.
864 @param OldBuffer The buffer to copy to the allocated buffer. This is an
865 optional parameter that may be NULL.
867 @return A pointer to the allocated buffer or NULL if allocation fails.
875 IN VOID
*OldBuffer OPTIONAL
878 return InternalReallocatePool (EfiRuntimeServicesData
, OldSize
, NewSize
, OldBuffer
);
882 Reallocates a buffer of type EfiRuntimeServicesData.
884 Allocates and zeros the number bytes specified by NewSize from memory of type
885 EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize
886 and NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
887 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
888 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
889 enough memory remaining to satisfy the request, then NULL is returned.
891 If the allocation of the new buffer is successful and the smaller of NewSize
892 and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
894 @param OldSize The size, in bytes, of OldBuffer.
895 @param NewSize The size, in bytes, of the buffer to reallocate.
896 @param OldBuffer The buffer to copy to the allocated buffer. This is an
897 optional parameter that may be NULL.
899 @return A pointer to the allocated buffer or NULL if allocation fails.
904 ReallocateRuntimePool (
907 IN VOID
*OldBuffer OPTIONAL
910 return InternalReallocatePool (EfiRuntimeServicesData
, OldSize
, NewSize
, OldBuffer
);
914 Reallocates a buffer of type EfiReservedMemoryType.
916 Allocates and zeros the number bytes specified by NewSize from memory of type
917 EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize
918 and NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
919 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
920 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
921 enough memory remaining to satisfy the request, then NULL is returned.
923 If the allocation of the new buffer is successful and the smaller of NewSize
924 and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
926 @param OldSize The size, in bytes, of OldBuffer.
927 @param NewSize The size, in bytes, of the buffer to reallocate.
928 @param OldBuffer The buffer to copy to the allocated buffer. This is an
929 optional parameter that may be NULL.
931 @return A pointer to the allocated buffer or NULL if allocation fails.
936 ReallocateReservedPool (
939 IN VOID
*OldBuffer OPTIONAL
946 Frees a buffer that was previously allocated with one of the pool allocation
947 functions in the Memory Allocation Library.
949 Frees the buffer specified by Buffer. Buffer must have been allocated on a
950 previous call to the pool allocation services of the Memory Allocation Library.
951 If it is not possible to free pool resources, then this function will perform
954 If Buffer was not allocated with a pool allocation function in the Memory
955 Allocation Library, then ASSERT().
957 @param Buffer The pointer to the buffer to free.
968 if (BufferInSmram (Buffer
)) {
970 // When Buffer is in SMRAM range, it should be allocated by gSmst->SmmAllocatePool() service.
971 // So, gSmst->SmmFreePool() service is used to free it.
973 Status
= gSmst
->SmmFreePool (Buffer
);
976 // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePool() service.
977 // So, gBS->FreePool() service is used to free it.
979 Status
= gBS
->FreePool (Buffer
);
981 ASSERT_EFI_ERROR (Status
);