TianoCore EDK2 master
Loading...
Searching...
No Matches
MemoryAllocationLib.c
Go to the documentation of this file.
1
18#include <Uefi.h>
19
23#include <Library/DebugLib.h>
24#include <Library/EmuThunkLib.h>
25
39VOID *
40InternalAllocatePages (
41 IN EFI_MEMORY_TYPE MemoryType,
42 IN UINTN Pages
43 )
44{
45 EFI_STATUS Status;
47
48 if (Pages == 0) {
49 return NULL;
50 }
51
52 return gEmuThunk->Valloc (Pages * EFI_PAGE_SIZE);
53}
54
68VOID *
69EFIAPI
71 IN UINTN Pages
72 )
73{
74 return InternalAllocatePages (EfiBootServicesData, Pages);
75}
76
90VOID *
91EFIAPI
93 IN UINTN Pages
94 )
95{
96 return InternalAllocatePages (EfiRuntimeServicesData, Pages);
97}
98
112VOID *
113EFIAPI
115 IN UINTN Pages
116 )
117{
118 return InternalAllocatePages (EfiReservedMemoryType, Pages);
119}
120
138VOID
139EFIAPI
141 IN VOID *Buffer,
142 IN UINTN Pages
143 )
144{
145 EFI_STATUS Status;
146
147 ASSERT (Pages != 0);
148 if (!gEmuThunk->Free (Buffer)) {
149 // The Free thunk will not free memory allocated in emulated EFI memory.
150 // The assmuption is this was allocated directly by EFI. We need this as some
151 // times protocols or EFI BootServices can return dynamically allocated buffers.
152 Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages);
153 ASSERT_EFI_ERROR (Status);
154 }
155}
156
174VOID *
176 IN EFI_MEMORY_TYPE MemoryType,
177 IN UINTN Pages,
178 IN UINTN Alignment
179 )
180{
181 EFI_STATUS Status;
182 VOID *Memory;
183 UINTN AlignedMemory;
184 UINTN AlignmentMask;
185 UINTN UnalignedPages;
186 UINTN RealPages;
187
188 //
189 // Alignment must be a power of two or zero.
190 //
191 ASSERT ((Alignment & (Alignment - 1)) == 0);
192
193 if (Pages == 0) {
194 return NULL;
195 }
196
197 if (Alignment > EFI_PAGE_SIZE) {
198 //
199 // Caculate the total number of pages since alignment is larger than page size.
200 //
201 AlignmentMask = Alignment - 1;
202 RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment);
203 //
204 // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
205 //
206 ASSERT (RealPages > Pages);
207
208 Memory = gEmuThunk->Valloc (Pages * EFI_PAGE_SIZE);
209 if (Memory != NULL) {
210 return NULL;
211 }
212
213 AlignedMemory = ((UINTN)Memory + AlignmentMask) & ~AlignmentMask;
214 UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN)Memory);
215 if (UnalignedPages > 0) {
216 //
217 // Free first unaligned page(s).
218 //
219 FreePages (Memory, UnalignedPages);
220 }
221
222 Memory = (VOID *)(AlignedMemory + EFI_PAGES_TO_SIZE (Pages));
223 UnalignedPages = RealPages - Pages - UnalignedPages;
224 if (UnalignedPages > 0) {
225 //
226 // Free last unaligned page(s).
227 //
228 FreePages (Memory, UnalignedPages);
229 }
230 } else {
231 //
232 // Do not over-allocate pages in this case.
233 //
234 Memory = gEmuThunk->Valloc (Pages * EFI_PAGE_SIZE);
235 if (Memory != NULL) {
236 return NULL;
237 }
238
239 AlignedMemory = (UINTN)Memory;
240 }
241
242 return (VOID *)AlignedMemory;
243}
244
262VOID *
263EFIAPI
265 IN UINTN Pages,
266 IN UINTN Alignment
267 )
268{
269 return InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment);
270}
271
289VOID *
290EFIAPI
292 IN UINTN Pages,
293 IN UINTN Alignment
294 )
295{
296 return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);
297}
298
316VOID *
317EFIAPI
319 IN UINTN Pages,
320 IN UINTN Alignment
321 )
322{
323 return InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment);
324}
325
343VOID
344EFIAPI
346 IN VOID *Buffer,
347 IN UINTN Pages
348 )
349{
350 FreePages (Buffer, Pages);
351}
352
366VOID *
368 IN EFI_MEMORY_TYPE MemoryType,
369 IN UINTN AllocationSize
370 )
371{
372 return gEmuThunk->Malloc (AllocationSize);
373}
374
387VOID *
388EFIAPI
390 IN UINTN AllocationSize
391 )
392{
393 return InternalAllocatePool (EfiBootServicesData, AllocationSize);
394}
395
408VOID *
409EFIAPI
411 IN UINTN AllocationSize
412 )
413{
414 return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
415}
416
429VOID *
430EFIAPI
432 IN UINTN AllocationSize
433 )
434{
435 return InternalAllocatePool (EfiReservedMemoryType, AllocationSize);
436}
437
452VOID *
454 IN EFI_MEMORY_TYPE PoolType,
455 IN UINTN AllocationSize
456 )
457{
458 VOID *Memory;
459
460 Memory = InternalAllocatePool (PoolType, AllocationSize);
461 if (Memory != NULL) {
462 Memory = ZeroMem (Memory, AllocationSize);
463 }
464
465 return Memory;
466}
467
481VOID *
482EFIAPI
484 IN UINTN AllocationSize
485 )
486{
487 return InternalAllocateZeroPool (EfiBootServicesData, AllocationSize);
488}
489
503VOID *
504EFIAPI
506 IN UINTN AllocationSize
507 )
508{
509 return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);
510}
511
525VOID *
526EFIAPI
528 IN UINTN AllocationSize
529 )
530{
531 return InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);
532}
533
551VOID *
553 IN EFI_MEMORY_TYPE PoolType,
554 IN UINTN AllocationSize,
555 IN CONST VOID *Buffer
556 )
557{
558 VOID *Memory;
559
560 ASSERT (Buffer != NULL);
561 ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN)Buffer + 1));
562
563 Memory = InternalAllocatePool (PoolType, AllocationSize);
564 if (Memory != NULL) {
565 Memory = CopyMem (Memory, Buffer, AllocationSize);
566 }
567
568 return Memory;
569}
570
588VOID *
589EFIAPI
591 IN UINTN AllocationSize,
592 IN CONST VOID *Buffer
593 )
594{
595 return InternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer);
596}
597
615VOID *
616EFIAPI
618 IN UINTN AllocationSize,
619 IN CONST VOID *Buffer
620 )
621{
622 return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);
623}
624
642VOID *
643EFIAPI
645 IN UINTN AllocationSize,
646 IN CONST VOID *Buffer
647 )
648{
649 return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);
650}
651
674VOID *
676 IN EFI_MEMORY_TYPE PoolType,
677 IN UINTN OldSize,
678 IN UINTN NewSize,
679 IN VOID *OldBuffer OPTIONAL
680 )
681{
682 VOID *NewBuffer;
683
684 NewBuffer = InternalAllocateZeroPool (PoolType, NewSize);
685 if ((NewBuffer != NULL) && (OldBuffer != NULL)) {
686 CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize));
687 FreePool (OldBuffer);
688 }
689
690 return NewBuffer;
691}
692
714VOID *
715EFIAPI
717 IN UINTN OldSize,
718 IN UINTN NewSize,
719 IN VOID *OldBuffer OPTIONAL
720 )
721{
722 return InternalReallocatePool (EfiBootServicesData, OldSize, NewSize, OldBuffer);
723}
724
746VOID *
747EFIAPI
749 IN UINTN OldSize,
750 IN UINTN NewSize,
751 IN VOID *OldBuffer OPTIONAL
752 )
753{
754 return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer);
755}
756
778VOID *
779EFIAPI
781 IN UINTN OldSize,
782 IN UINTN NewSize,
783 IN VOID *OldBuffer OPTIONAL
784 )
785{
786 return InternalReallocatePool (EfiReservedMemoryType, OldSize, NewSize, OldBuffer);
787}
788
803VOID
804EFIAPI
806 IN VOID *Buffer
807 )
808{
809 EFI_STATUS Status;
810
811 if (!gEmuThunk->Free (Buffer)) {
812 // The Free thunk will not free memory allocated in emulated EFI memory.
813 // The assmuption is this was allocated directly by EFI. We need this as some
814 // times protocols or EFI BootServices can return dynamically allocated buffers.
815 Status = gBS->FreePool (Buffer);
816 ASSERT_EFI_ERROR (Status);
817 }
818}
UINT64 UINTN
#define MAX_ADDRESS
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID EFIAPI FreePages(IN VOID *Buffer, IN UINTN Pages)
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
VOID *EFIAPI AllocateAlignedPages(IN UINTN Pages, IN UINTN Alignment)
VOID *EFIAPI AllocatePages(IN UINTN Pages)
VOID *EFIAPI ReallocatePool(IN UINTN OldSize, IN UINTN NewSize, IN VOID *OldBuffer OPTIONAL)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateRuntimePages(IN UINTN Pages)
VOID *EFIAPI AllocateReservedZeroPool(IN UINTN AllocationSize)
VOID *EFIAPI AllocateRuntimePool(IN UINTN AllocationSize)
VOID *EFIAPI ReallocateRuntimePool(IN UINTN OldSize, IN UINTN NewSize, IN VOID *OldBuffer OPTIONAL)
VOID * InternalReallocatePool(IN EFI_MEMORY_TYPE PoolType, IN UINTN OldSize, IN UINTN NewSize, IN VOID *OldBuffer OPTIONAL)
VOID *EFIAPI AllocateAlignedReservedPages(IN UINTN Pages, IN UINTN Alignment)
VOID *EFIAPI AllocateRuntimeCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
VOID *EFIAPI ReallocateReservedPool(IN UINTN OldSize, IN UINTN NewSize, IN VOID *OldBuffer OPTIONAL)
VOID * InternalAllocateCopyPool(IN EFI_MEMORY_TYPE PoolType, IN UINTN AllocationSize, IN CONST VOID *Buffer)
VOID *EFIAPI AllocateReservedPool(IN UINTN AllocationSize)
VOID EFIAPI FreeAlignedPages(IN VOID *Buffer, IN UINTN Pages)
VOID *EFIAPI AllocateAlignedRuntimePages(IN UINTN Pages, IN UINTN Alignment)
VOID *EFIAPI AllocateReservedPages(IN UINTN Pages)
VOID * InternalAllocatePool(IN EFI_MEMORY_TYPE MemoryType, IN UINTN AllocationSize)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
VOID *EFIAPI AllocateRuntimeZeroPool(IN UINTN AllocationSize)
VOID * InternalAllocateAlignedPages(IN EFI_MEMORY_TYPE MemoryType, IN UINTN Pages, IN UINTN Alignment)
VOID * InternalAllocateZeroPool(IN EFI_MEMORY_TYPE PoolType, IN UINTN AllocationSize)
VOID *EFIAPI AllocateReservedCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define MIN(a, b)
Definition: Base.h:1007
#define IN
Definition: Base.h:279
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
#define EFI_PAGES_TO_SIZE(Pages)
Definition: UefiBaseType.h:213
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
EFI_BOOT_SERVICES * gBS
EFI_MEMORY_TYPE
@ EfiBootServicesData
@ EfiReservedMemoryType
@ EfiRuntimeServicesData