TianoCore EDK2 master
Loading...
Searching...
No Matches
MemoryAllocationLib.c
Go to the documentation of this file.
1
10#include <PiPei.h>
11
12#include <Library/BaseLib.h>
14#include <Library/PrePiLib.h>
15#include <Library/DebugLib.h>
16
18VOID *
19EFIAPI
20InternalAllocatePages (
21 IN UINTN Pages,
22 IN EFI_MEMORY_TYPE MemoryType
23 )
24{
27 UINTN PagesSize;
28
29 Hob.Raw = GetHobList ();
30
31 if (Pages == 0) {
32 return NULL;
33 }
34
35 //
36 // Calculate the new top of memory based on the memory type
37 //
38 switch (MemoryType) {
43 PagesSize = ALIGN_VALUE (Pages, EFI_SIZE_TO_PAGES (RUNTIME_PAGE_ALLOCATION_GRANULARITY)) * EFI_PAGE_SIZE;
44 NewTop = Hob.HandoffInformationTable->EfiFreeMemoryTop & ~(EFI_PHYSICAL_ADDRESS)(RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1);
45 break;
46
47 default:
48 PagesSize = Pages * EFI_PAGE_SIZE;
49 NewTop = Hob.HandoffInformationTable->EfiFreeMemoryTop & ~(EFI_PHYSICAL_ADDRESS)EFI_PAGE_MASK;
50 break;
51 }
52
53 //
54 // Verify that the subtraction does not underflow NewTop
55 //
56 if (PagesSize > NewTop) {
57 return NULL;
58 }
59
60 NewTop -= PagesSize;
61
62 //
63 // Verify that there is sufficient memory to satisfy the allocation
64 //
65 if (NewTop < (Hob.HandoffInformationTable->EfiFreeMemoryBottom + sizeof (EFI_HOB_MEMORY_ALLOCATION))) {
66 return NULL;
67 }
68
69 //
70 // Update the PHIT to reflect the memory usage
71 //
72 Hob.HandoffInformationTable->EfiFreeMemoryTop = NewTop;
73
74 //
75 // Create a memory allocation HOB.
76 //
78 Hob.HandoffInformationTable->EfiFreeMemoryTop,
79 PagesSize,
80 MemoryType
81 );
82
83 return (VOID *)(UINTN)Hob.HandoffInformationTable->EfiFreeMemoryTop;
84}
85
99VOID *
100EFIAPI
102 IN UINTN Pages
103 )
104{
105 return InternalAllocatePages (Pages, EfiBootServicesData);
106}
107
121VOID *
122EFIAPI
124 IN UINTN Pages
125 )
126{
127 return InternalAllocatePages (Pages, EfiRuntimeServicesData);
128}
129
143VOID *
144EFIAPI
146 IN UINTN Pages
147 )
148{
149 return InternalAllocatePages (Pages, EfiReservedMemoryType);
150}
151
168VOID *
169EFIAPI
171 IN UINTN Pages,
172 IN UINTN Alignment
173 )
174{
175 VOID *Memory;
176 UINTN AlignmentMask;
177
178 //
179 // Alignment must be a power of two or zero.
180 //
181 ASSERT ((Alignment & (Alignment - 1)) == 0);
182
183 if (Pages == 0) {
184 return NULL;
185 }
186
187 //
188 // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
189 //
190 ASSERT (Pages <= (MAX_ADDRESS - EFI_SIZE_TO_PAGES (Alignment)));
191 //
192 // We would rather waste some memory to save PEI code size.
193 //
194 Memory = (VOID *)(UINTN)AllocatePages (Pages + EFI_SIZE_TO_PAGES (Alignment));
195 if (Alignment == 0) {
196 AlignmentMask = Alignment;
197 } else {
198 AlignmentMask = Alignment - 1;
199 }
200
201 return (VOID *)(UINTN)(((UINTN)Memory + AlignmentMask) & ~AlignmentMask);
202}
203
220VOID *
221EFIAPI
223 IN UINTN Pages,
224 IN UINTN Alignment
225 )
226{
227 VOID *Memory;
228 UINTN AlignmentMask;
229
230 //
231 // Alignment must be a power of two or zero.
232 //
233 ASSERT ((Alignment & (Alignment - 1)) == 0);
234
235 if (Pages == 0) {
236 return NULL;
237 }
238
239 //
240 // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
241 //
242 ASSERT (Pages <= (MAX_ADDRESS - EFI_SIZE_TO_PAGES (Alignment)));
243 //
244 // We would rather waste some memory to save PEI code size.
245 //
246 Memory = (VOID *)(UINTN)AllocateReservedPages (Pages + EFI_SIZE_TO_PAGES (Alignment));
247 if (Alignment == 0) {
248 AlignmentMask = Alignment;
249 } else {
250 AlignmentMask = Alignment - 1;
251 }
252
253 return (VOID *)(UINTN)(((UINTN)Memory + AlignmentMask) & ~AlignmentMask);
254}
255
273VOID
274EFIAPI
276 IN VOID *Buffer,
277 IN UINTN Pages
278 )
279{
280 // For now, we do not support the ability to free pages in the PrePei Memory Allocator.
281 // The allocated memory is lost.
282}
283
296VOID *
297EFIAPI
299 IN UINTN AllocationSize
300 )
301{
303
304 Hob = GetHobList ();
305
306 //
307 // Verify that there is sufficient memory to satisfy the allocation
308 //
309 if (AllocationSize > 0x10000) {
310 // Please call AllocatePages for big allocations
311 return 0;
312 } else {
314 EFI_HOB_TYPE_MEMORY_POOL,
315 (UINT16)(sizeof (EFI_HOB_MEMORY_POOL) +
316 AllocationSize)
317 );
318 return (VOID *)(Hob + 1);
319 }
320}
321
335VOID *
336EFIAPI
338 IN UINTN AllocationSize
339 )
340{
341 VOID *Buffer;
342
343 Buffer = AllocatePool (AllocationSize);
344 if (Buffer == NULL) {
345 return NULL;
346 }
347
348 ZeroMem (Buffer, AllocationSize);
349
350 return Buffer;
351}
352
367VOID
368EFIAPI
370 IN VOID *Buffer
371 )
372{
373 // Not implemented yet
374}
375
397VOID *
398EFIAPI
400 IN UINTN OldSize,
401 IN UINTN NewSize,
402 IN VOID *OldBuffer OPTIONAL
403 )
404{
405 VOID *NewBuffer;
406
407 // Validate the OldBuffer is HobAllocated.
409 EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob;
410
411 if (OldBuffer != NULL) {
412 HandOffHob = GetHobList ();
413 ASSERT (((EFI_PHYSICAL_ADDRESS)(UINTN)OldBuffer >= HandOffHob->EfiMemoryBottom));
414 ASSERT (((EFI_PHYSICAL_ADDRESS)((UINTN)OldBuffer + OldSize) <= HandOffHob->EfiFreeMemoryBottom));
415 }
416
418
419 // If new buffer would be smaller just return old buffer as FreePool isn't supported.
420 if ((OldBuffer != NULL) && (OldSize >= NewSize)) {
421 return OldBuffer;
422 }
423
424 NewBuffer = AllocateZeroPool (NewSize);
425 if ((NewBuffer != NULL) && (OldBuffer != NULL)) {
426 CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize));
427 FreePool (OldBuffer);
428 }
429
430 return NewBuffer;
431}
432
450VOID *
451EFIAPI
453 IN UINTN AllocationSize,
454 IN CONST VOID *Buffer
455 )
456{
457 VOID *Memory;
458
459 ASSERT (Buffer != NULL);
460 ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN)Buffer + 1));
461
462 Memory = AllocatePool (AllocationSize);
463 if (Memory != NULL) {
464 Memory = CopyMem (Memory, Buffer, AllocationSize);
465 }
466
467 return Memory;
468}
UINT64 UINTN
#define MAX_ADDRESS
VOID EFIAPI BuildMemoryAllocationHob(IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN EFI_MEMORY_TYPE MemoryType)
Definition: HobLib.c:601
VOID *EFIAPI GetHobList(VOID)
Definition: HobLib.c:76
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 AllocateAlignedReservedPages(IN UINTN Pages, IN UINTN Alignment)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateReservedPages(IN UINTN Pages)
VOID *EFIAPI AllocateRuntimePages(IN UINTN Pages)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define MIN(a, b)
Definition: Base.h:1007
#define VOID
Definition: Base.h:269
#define ALIGN_VALUE(Value, Alignment)
Definition: Base.h:948
#define IN
Definition: Base.h:279
#define DEBUG_CODE_BEGIN()
Definition: DebugLib.h:565
#define DEBUG_CODE_END()
Definition: DebugLib.h:579
VOID * CreateHob(IN UINT16 HobType, IN UINT16 HobLenght)
Definition: Hob.c:101
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
EFI_MEMORY_TYPE
@ EfiBootServicesData
@ EfiReservedMemoryType
@ EfiACPIMemoryNVS
@ EfiRuntimeServicesCode
@ EfiRuntimeServicesData
EFI_PHYSICAL_ADDRESS EfiFreeMemoryBottom
Definition: PiHob.h:92
EFI_PHYSICAL_ADDRESS EfiFreeMemoryTop
Definition: PiHob.h:88
EFI_PHYSICAL_ADDRESS EfiMemoryBottom
Definition: PiHob.h:83