1 /** @file
2 Support routines for memory allocation routines based
3 on boot services for Dxe phase drivers, with memory profile support.
4
5 Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php.
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15
16
17 #include <Uefi.h>
18
19
20 #include <Library/MemoryAllocationLib.h>
21 #include <Library/UefiBootServicesTableLib.h>
22 #include <Library/BaseMemoryLib.h>
23 #include <Library/DebugLib.h>
24
25 #include <Library/MemoryProfileLib.h>
26
27 /**
28 Allocates one or more 4KB pages of a certain memory type.
29
30 Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated
31 buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL is returned.
32 If there is not enough memory remaining to satisfy the request, then NULL is returned.
33
34 @param MemoryType The type of memory to allocate.
35 @param Pages The number of 4 KB pages to allocate.
36
37 @return A pointer to the allocated buffer or NULL if allocation fails.
38
39 **/
40 VOID *
InternalAllocatePages(IN EFI_MEMORY_TYPE MemoryType,IN UINTN Pages)41 InternalAllocatePages (
42 IN EFI_MEMORY_TYPE MemoryType,
43 IN UINTN Pages
44 )
45 {
46 EFI_STATUS Status;
47 EFI_PHYSICAL_ADDRESS Memory;
48
49 if (Pages == 0) {
50 return NULL;
51 }
52
53 Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);
54 if (EFI_ERROR (Status)) {
55 return NULL;
56 }
57 return (VOID *) (UINTN) Memory;
58 }
59
60 /**
61 Allocates one or more 4KB pages of type EfiBootServicesData.
62
63 Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the
64 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
65 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
66 returned.
67
68 @param Pages The number of 4 KB pages to allocate.
69
70 @return A pointer to the allocated buffer or NULL if allocation fails.
71
72 **/
73 VOID *
74 EFIAPI
AllocatePages(IN UINTN Pages)75 AllocatePages (
76 IN UINTN Pages
77 )
78 {
79 VOID *Buffer;
80
81 Buffer = InternalAllocatePages (EfiBootServicesData, Pages);
82 if (Buffer != NULL) {
83 MemoryProfileLibRecord (
84 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
85 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_PAGES,
86 EfiBootServicesData,
87 Buffer,
88 EFI_PAGES_TO_SIZE (Pages),
89 NULL
90 );
91 }
92 return Buffer;
93 }
94
95 /**
96 Allocates one or more 4KB pages of type EfiRuntimeServicesData.
97
98 Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
99 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
100 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
101 returned.
102
103 @param Pages The number of 4 KB pages to allocate.
104
105 @return A pointer to the allocated buffer or NULL if allocation fails.
106
107 **/
108 VOID *
109 EFIAPI
AllocateRuntimePages(IN UINTN Pages)110 AllocateRuntimePages (
111 IN UINTN Pages
112 )
113 {
114 VOID *Buffer;
115
116 Buffer = InternalAllocatePages (EfiRuntimeServicesData, Pages);
117 if (Buffer != NULL) {
118 MemoryProfileLibRecord (
119 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
120 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_PAGES,
121 EfiRuntimeServicesData,
122 Buffer,
123 EFI_PAGES_TO_SIZE (Pages),
124 NULL
125 );
126 }
127 return Buffer;
128 }
129
130 /**
131 Allocates one or more 4KB pages of type EfiReservedMemoryType.
132
133 Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the
134 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
135 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
136 returned.
137
138 @param Pages The number of 4 KB pages to allocate.
139
140 @return A pointer to the allocated buffer or NULL if allocation fails.
141
142 **/
143 VOID *
144 EFIAPI
AllocateReservedPages(IN UINTN Pages)145 AllocateReservedPages (
146 IN UINTN Pages
147 )
148 {
149 VOID *Buffer;
150
151 Buffer = InternalAllocatePages (EfiReservedMemoryType, Pages);
152 if (Buffer != NULL) {
153 MemoryProfileLibRecord (
154 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
155 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_PAGES,
156 EfiReservedMemoryType,
157 Buffer,
158 EFI_PAGES_TO_SIZE (Pages),
159 NULL
160 );
161 }
162 return Buffer;
163 }
164
165 /**
166 Frees one or more 4KB pages that were previously allocated with one of the page allocation
167 functions in the Memory Allocation Library.
168
169 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
170 must have been allocated on a previous call to the page allocation services of the Memory
171 Allocation Library. If it is not possible to free allocated pages, then this function will
172 perform no actions.
173
174 If Buffer was not allocated with a page allocation function in the Memory Allocation Library,
175 then ASSERT().
176 If Pages is zero, then ASSERT().
177
178 @param Buffer The pointer to the buffer of pages to free.
179 @param Pages The number of 4 KB pages to free.
180
181 **/
182 VOID
183 EFIAPI
FreePages(IN VOID * Buffer,IN UINTN Pages)184 FreePages (
185 IN VOID *Buffer,
186 IN UINTN Pages
187 )
188 {
189 EFI_STATUS Status;
190
191 ASSERT (Pages != 0);
192 Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
193 ASSERT_EFI_ERROR (Status);
194 }
195
196 /**
197 Allocates one or more 4KB pages of a certain memory type at a specified alignment.
198
199 Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment
200 specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned.
201 If there is not enough memory at the specified alignment remaining to satisfy the request, then
202 NULL is returned.
203 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
204 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
205
206 @param MemoryType The type of memory to allocate.
207 @param Pages The number of 4 KB pages to allocate.
208 @param Alignment The requested alignment of the allocation. Must be a power of two.
209 If Alignment is zero, then byte alignment is used.
210
211 @return A pointer to the allocated buffer or NULL if allocation fails.
212
213 **/
214 VOID *
InternalAllocateAlignedPages(IN EFI_MEMORY_TYPE MemoryType,IN UINTN Pages,IN UINTN Alignment)215 InternalAllocateAlignedPages (
216 IN EFI_MEMORY_TYPE MemoryType,
217 IN UINTN Pages,
218 IN UINTN Alignment
219 )
220 {
221 EFI_STATUS Status;
222 EFI_PHYSICAL_ADDRESS Memory;
223 UINTN AlignedMemory;
224 UINTN AlignmentMask;
225 UINTN UnalignedPages;
226 UINTN RealPages;
227
228 //
229 // Alignment must be a power of two or zero.
230 //
231 ASSERT ((Alignment & (Alignment - 1)) == 0);
232
233 if (Pages == 0) {
234 return NULL;
235 }
236 if (Alignment > EFI_PAGE_SIZE) {
237 //
238 // Calculate the total number of pages since alignment is larger than page size.
239 //
240 AlignmentMask = Alignment - 1;
241 RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment);
242 //
243 // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
244 //
245 ASSERT (RealPages > Pages);
246
247 Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory);
248 if (EFI_ERROR (Status)) {
249 return NULL;
250 }
251 AlignedMemory = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask;
252 UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN) Memory);
253 if (UnalignedPages > 0) {
254 //
255 // Free first unaligned page(s).
256 //
257 Status = gBS->FreePages (Memory, UnalignedPages);
258 ASSERT_EFI_ERROR (Status);
259 }
260 Memory = (EFI_PHYSICAL_ADDRESS) (AlignedMemory + EFI_PAGES_TO_SIZE (Pages));
261 UnalignedPages = RealPages - Pages - UnalignedPages;
262 if (UnalignedPages > 0) {
263 //
264 // Free last unaligned page(s).
265 //
266 Status = gBS->FreePages (Memory, UnalignedPages);
267 ASSERT_EFI_ERROR (Status);
268 }
269 } else {
270 //
271 // Do not over-allocate pages in this case.
272 //
273 Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);
274 if (EFI_ERROR (Status)) {
275 return NULL;
276 }
277 AlignedMemory = (UINTN) Memory;
278 }
279 return (VOID *) AlignedMemory;
280 }
281
282 /**
283 Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment.
284
285 Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an
286 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
287 returned. If there is not enough memory at the specified alignment remaining to satisfy the
288 request, then NULL is returned.
289
290 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
291 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
292
293 @param Pages The number of 4 KB pages to allocate.
294 @param Alignment The requested alignment of the allocation. Must be a power of two.
295 If Alignment is zero, then byte alignment is used.
296
297 @return A pointer to the allocated buffer or NULL if allocation fails.
298
299 **/
300 VOID *
301 EFIAPI
AllocateAlignedPages(IN UINTN Pages,IN UINTN Alignment)302 AllocateAlignedPages (
303 IN UINTN Pages,
304 IN UINTN Alignment
305 )
306 {
307 VOID *Buffer;
308
309 Buffer = InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment);
310 if (Buffer != NULL) {
311 MemoryProfileLibRecord (
312 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
313 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_PAGES,
314 EfiBootServicesData,
315 Buffer,
316 EFI_PAGES_TO_SIZE (Pages),
317 NULL
318 );
319 }
320 return Buffer;
321 }
322
323 /**
324 Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
325
326 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an
327 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
328 returned. If there is not enough memory at the specified alignment remaining to satisfy the
329 request, then NULL is returned.
330
331 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
332 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
333
334 @param Pages The number of 4 KB pages to allocate.
335 @param Alignment The requested alignment of the allocation. Must be a power of two.
336 If Alignment is zero, then byte alignment is used.
337
338 @return A pointer to the allocated buffer or NULL if allocation fails.
339
340 **/
341 VOID *
342 EFIAPI
AllocateAlignedRuntimePages(IN UINTN Pages,IN UINTN Alignment)343 AllocateAlignedRuntimePages (
344 IN UINTN Pages,
345 IN UINTN Alignment
346 )
347 {
348 VOID *Buffer;
349
350 Buffer = InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);
351 if (Buffer != NULL) {
352 MemoryProfileLibRecord (
353 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
354 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RUNTIME_PAGES,
355 EfiRuntimeServicesData,
356 Buffer,
357 EFI_PAGES_TO_SIZE (Pages),
358 NULL
359 );
360 }
361 return Buffer;
362 }
363
364 /**
365 Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
366
367 Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an
368 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
369 returned. If there is not enough memory at the specified alignment remaining to satisfy the
370 request, then NULL is returned.
371
372 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
373 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
374
375 @param Pages The number of 4 KB pages to allocate.
376 @param Alignment The requested alignment of the allocation. Must be a power of two.
377 If Alignment is zero, then byte alignment is used.
378
379 @return A pointer to the allocated buffer or NULL if allocation fails.
380
381 **/
382 VOID *
383 EFIAPI
AllocateAlignedReservedPages(IN UINTN Pages,IN UINTN Alignment)384 AllocateAlignedReservedPages (
385 IN UINTN Pages,
386 IN UINTN Alignment
387 )
388 {
389 VOID *Buffer;
390
391 Buffer = InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment);
392 if (Buffer != NULL) {
393 MemoryProfileLibRecord (
394 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
395 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RESERVED_PAGES,
396 EfiReservedMemoryType,
397 Buffer,
398 EFI_PAGES_TO_SIZE (Pages),
399 NULL
400 );
401 }
402 return Buffer;
403 }
404
405 /**
406 Frees one or more 4KB pages that were previously allocated with one of the aligned page
407 allocation functions in the Memory Allocation Library.
408
409 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
410 must have been allocated on a previous call to the aligned page allocation services of the Memory
411 Allocation Library. If it is not possible to free allocated pages, then this function will
412 perform no actions.
413
414 If Buffer was not allocated with an aligned page allocation function in the Memory Allocation
415 Library, then ASSERT().
416 If Pages is zero, then ASSERT().
417
418 @param Buffer The pointer to the buffer of pages to free.
419 @param Pages The number of 4 KB pages to free.
420
421 **/
422 VOID
423 EFIAPI
FreeAlignedPages(IN VOID * Buffer,IN UINTN Pages)424 FreeAlignedPages (
425 IN VOID *Buffer,
426 IN UINTN Pages
427 )
428 {
429 EFI_STATUS Status;
430
431 ASSERT (Pages != 0);
432 Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
433 ASSERT_EFI_ERROR (Status);
434 }
435
436 /**
437 Allocates a buffer of a certain pool type.
438
439 Allocates the number bytes specified by AllocationSize of a certain pool type and returns a
440 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
441 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
442
443 @param MemoryType The type of memory to allocate.
444 @param AllocationSize The number of bytes to allocate.
445
446 @return A pointer to the allocated buffer or NULL if allocation fails.
447
448 **/
449 VOID *
InternalAllocatePool(IN EFI_MEMORY_TYPE MemoryType,IN UINTN AllocationSize)450 InternalAllocatePool (
451 IN EFI_MEMORY_TYPE MemoryType,
452 IN UINTN AllocationSize
453 )
454 {
455 EFI_STATUS Status;
456 VOID *Memory;
457
458 Status = gBS->AllocatePool (MemoryType, AllocationSize, &Memory);
459 if (EFI_ERROR (Status)) {
460 Memory = NULL;
461 }
462 return Memory;
463 }
464
465 /**
466 Allocates a buffer of type EfiBootServicesData.
467
468 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a
469 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
470 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
471
472 @param AllocationSize The number of bytes to allocate.
473
474 @return A pointer to the allocated buffer or NULL if allocation fails.
475
476 **/
477 VOID *
478 EFIAPI
AllocatePool(IN UINTN AllocationSize)479 AllocatePool (
480 IN UINTN AllocationSize
481 )
482 {
483 VOID *Buffer;
484
485 Buffer = InternalAllocatePool (EfiBootServicesData, AllocationSize);
486 if (Buffer != NULL) {
487 MemoryProfileLibRecord (
488 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
489 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_POOL,
490 EfiBootServicesData,
491 Buffer,
492 AllocationSize,
493 NULL
494 );
495 }
496 return Buffer;
497 }
498
499 /**
500 Allocates a buffer of type EfiRuntimeServicesData.
501
502 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns
503 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
504 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
505
506 @param AllocationSize The number of bytes to allocate.
507
508 @return A pointer to the allocated buffer or NULL if allocation fails.
509
510 **/
511 VOID *
512 EFIAPI
AllocateRuntimePool(IN UINTN AllocationSize)513 AllocateRuntimePool (
514 IN UINTN AllocationSize
515 )
516 {
517 VOID *Buffer;
518
519 Buffer = InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
520 if (Buffer != NULL) {
521 MemoryProfileLibRecord (
522 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
523 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_POOL,
524 EfiRuntimeServicesData,
525 Buffer,
526 AllocationSize,
527 NULL
528 );
529 }
530 return Buffer;
531 }
532
533 /**
534 Allocates a buffer of type EfiReservedMemoryType.
535
536 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns
537 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
538 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
539
540 @param AllocationSize The number of bytes to allocate.
541
542 @return A pointer to the allocated buffer or NULL if allocation fails.
543
544 **/
545 VOID *
546 EFIAPI
AllocateReservedPool(IN UINTN AllocationSize)547 AllocateReservedPool (
548 IN UINTN AllocationSize
549 )
550 {
551 VOID *Buffer;
552
553 Buffer = InternalAllocatePool (EfiReservedMemoryType, AllocationSize);
554 if (Buffer != NULL) {
555 MemoryProfileLibRecord (
556 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
557 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_POOL,
558 EfiReservedMemoryType,
559 Buffer,
560 AllocationSize,
561 NULL
562 );
563 }
564 return Buffer;
565 }
566
567 /**
568 Allocates and zeros a buffer of a certain pool type.
569
570 Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer
571 with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid
572 buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request,
573 then NULL is returned.
574
575 @param PoolType The type of memory to allocate.
576 @param AllocationSize The number of bytes to allocate and zero.
577
578 @return A pointer to the allocated buffer or NULL if allocation fails.
579
580 **/
581 VOID *
InternalAllocateZeroPool(IN EFI_MEMORY_TYPE PoolType,IN UINTN AllocationSize)582 InternalAllocateZeroPool (
583 IN EFI_MEMORY_TYPE PoolType,
584 IN UINTN AllocationSize
585 )
586 {
587 VOID *Memory;
588
589 Memory = InternalAllocatePool (PoolType, AllocationSize);
590 if (Memory != NULL) {
591 Memory = ZeroMem (Memory, AllocationSize);
592 }
593 return Memory;
594 }
595
596 /**
597 Allocates and zeros a buffer of type EfiBootServicesData.
598
599 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
600 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
601 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
602 request, then NULL is returned.
603
604 @param AllocationSize The number of bytes to allocate and zero.
605
606 @return A pointer to the allocated buffer or NULL if allocation fails.
607
608 **/
609 VOID *
610 EFIAPI
AllocateZeroPool(IN UINTN AllocationSize)611 AllocateZeroPool (
612 IN UINTN AllocationSize
613 )
614 {
615 VOID *Buffer;
616
617 Buffer = InternalAllocateZeroPool (EfiBootServicesData, AllocationSize);
618 if (Buffer != NULL) {
619 MemoryProfileLibRecord (
620 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
621 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ZERO_POOL,
622 EfiBootServicesData,
623 Buffer,
624 AllocationSize,
625 NULL
626 );
627 }
628 return Buffer;
629 }
630
631 /**
632 Allocates and zeros a buffer of type EfiRuntimeServicesData.
633
634 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the
635 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
636 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
637 request, then NULL is returned.
638
639 @param AllocationSize The number of bytes to allocate and zero.
640
641 @return A pointer to the allocated buffer or NULL if allocation fails.
642
643 **/
644 VOID *
645 EFIAPI
AllocateRuntimeZeroPool(IN UINTN AllocationSize)646 AllocateRuntimeZeroPool (
647 IN UINTN AllocationSize
648 )
649 {
650 VOID *Buffer;
651
652 Buffer = InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);
653 if (Buffer != NULL) {
654 MemoryProfileLibRecord (
655 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
656 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_ZERO_POOL,
657 EfiRuntimeServicesData,
658 Buffer,
659 AllocationSize,
660 NULL
661 );
662 }
663 return Buffer;
664 }
665
666 /**
667 Allocates and zeros a buffer of type EfiReservedMemoryType.
668
669 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the
670 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
671 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
672 request, then NULL is returned.
673
674 @param AllocationSize The number of bytes to allocate and zero.
675
676 @return A pointer to the allocated buffer or NULL if allocation fails.
677
678 **/
679 VOID *
680 EFIAPI
AllocateReservedZeroPool(IN UINTN AllocationSize)681 AllocateReservedZeroPool (
682 IN UINTN AllocationSize
683 )
684 {
685 VOID *Buffer;
686
687 Buffer = InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);
688 if (Buffer != NULL) {
689 MemoryProfileLibRecord (
690 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
691 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_ZERO_POOL,
692 EfiReservedMemoryType,
693 Buffer,
694 AllocationSize,
695 NULL
696 );
697 }
698 return Buffer;
699 }
700
701 /**
702 Copies a buffer to an allocated buffer of a certain pool type.
703
704 Allocates the number bytes specified by AllocationSize of a certain pool type, copies
705 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
706 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
707 is not enough memory remaining to satisfy the request, then NULL is returned.
708 If Buffer is NULL, then ASSERT().
709 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
710
711 @param PoolType The type of pool to allocate.
712 @param AllocationSize The number of bytes to allocate and zero.
713 @param Buffer The buffer to copy to the allocated buffer.
714
715 @return A pointer to the allocated buffer or NULL if allocation fails.
716
717 **/
718 VOID *
InternalAllocateCopyPool(IN EFI_MEMORY_TYPE PoolType,IN UINTN AllocationSize,IN CONST VOID * Buffer)719 InternalAllocateCopyPool (
720 IN EFI_MEMORY_TYPE PoolType,
721 IN UINTN AllocationSize,
722 IN CONST VOID *Buffer
723 )
724 {
725 VOID *Memory;
726
727 ASSERT (Buffer != NULL);
728 ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
729
730 Memory = InternalAllocatePool (PoolType, AllocationSize);
731 if (Memory != NULL) {
732 Memory = CopyMem (Memory, Buffer, AllocationSize);
733 }
734 return Memory;
735 }
736
737 /**
738 Copies a buffer to an allocated buffer of type EfiBootServicesData.
739
740 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies
741 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
742 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
743 is not enough memory remaining to satisfy the request, then NULL is returned.
744
745 If Buffer is NULL, then ASSERT().
746 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
747
748 @param AllocationSize The number of bytes to allocate and zero.
749 @param Buffer The buffer to copy to the allocated buffer.
750
751 @return A pointer to the allocated buffer or NULL if allocation fails.
752
753 **/
754 VOID *
755 EFIAPI
AllocateCopyPool(IN UINTN AllocationSize,IN CONST VOID * Buffer)756 AllocateCopyPool (
757 IN UINTN AllocationSize,
758 IN CONST VOID *Buffer
759 )
760 {
761 VOID *NewBuffer;
762
763 NewBuffer = InternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer);
764 if (NewBuffer != NULL) {
765 MemoryProfileLibRecord (
766 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
767 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_COPY_POOL,
768 EfiBootServicesData,
769 NewBuffer,
770 AllocationSize,
771 NULL
772 );
773 }
774 return NewBuffer;
775 }
776
777 /**
778 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
779
780 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies
781 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
782 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
783 is not enough memory remaining to satisfy the request, then NULL is returned.
784
785 If Buffer is NULL, then ASSERT().
786 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
787
788 @param AllocationSize The number of bytes to allocate and zero.
789 @param Buffer The buffer to copy to the allocated buffer.
790
791 @return A pointer to the allocated buffer or NULL if allocation fails.
792
793 **/
794 VOID *
795 EFIAPI
AllocateRuntimeCopyPool(IN UINTN AllocationSize,IN CONST VOID * Buffer)796 AllocateRuntimeCopyPool (
797 IN UINTN AllocationSize,
798 IN CONST VOID *Buffer
799 )
800 {
801 VOID *NewBuffer;
802
803 NewBuffer = InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);
804 if (NewBuffer != NULL) {
805 MemoryProfileLibRecord (
806 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
807 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_COPY_POOL,
808 EfiRuntimeServicesData,
809 NewBuffer,
810 AllocationSize,
811 NULL
812 );
813 }
814 return NewBuffer;
815 }
816
817 /**
818 Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
819
820 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies
821 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
822 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
823 is not enough memory remaining to satisfy the request, then NULL is returned.
824
825 If Buffer is NULL, then ASSERT().
826 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
827
828 @param AllocationSize The number of bytes to allocate and zero.
829 @param Buffer The buffer to copy to the allocated buffer.
830
831 @return A pointer to the allocated buffer or NULL if allocation fails.
832
833 **/
834 VOID *
835 EFIAPI
AllocateReservedCopyPool(IN UINTN AllocationSize,IN CONST VOID * Buffer)836 AllocateReservedCopyPool (
837 IN UINTN AllocationSize,
838 IN CONST VOID *Buffer
839 )
840 {
841 VOID *NewBuffer;
842
843 NewBuffer = InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);
844 if (NewBuffer != NULL) {
845 MemoryProfileLibRecord (
846 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
847 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_COPY_POOL,
848 EfiRuntimeServicesData,
849 NewBuffer,
850 AllocationSize,
851 NULL
852 );
853 }
854 return NewBuffer;
855 }
856
857 /**
858 Reallocates a buffer of a specified memory type.
859
860 Allocates and zeros the number bytes specified by NewSize from memory of the type
861 specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and
862 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
863 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
864 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
865 enough memory remaining to satisfy the request, then NULL is returned.
866
867 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
868 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
869
870 @param PoolType The type of pool to allocate.
871 @param OldSize The size, in bytes, of OldBuffer.
872 @param NewSize The size, in bytes, of the buffer to reallocate.
873 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
874 parameter that may be NULL.
875
876 @return A pointer to the allocated buffer or NULL if allocation fails.
877
878 **/
879 VOID *
InternalReallocatePool(IN EFI_MEMORY_TYPE PoolType,IN UINTN OldSize,IN UINTN NewSize,IN VOID * OldBuffer OPTIONAL)880 InternalReallocatePool (
881 IN EFI_MEMORY_TYPE PoolType,
882 IN UINTN OldSize,
883 IN UINTN NewSize,
884 IN VOID *OldBuffer OPTIONAL
885 )
886 {
887 VOID *NewBuffer;
888
889 NewBuffer = InternalAllocateZeroPool (PoolType, NewSize);
890 if (NewBuffer != NULL && OldBuffer != NULL) {
891 CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize));
892 FreePool (OldBuffer);
893 }
894 return NewBuffer;
895 }
896
897 /**
898 Reallocates a buffer of type EfiBootServicesData.
899
900 Allocates and zeros the number bytes specified by NewSize from memory of type
901 EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
902 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
903 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
904 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
905 enough memory remaining to satisfy the request, then NULL is returned.
906
907 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
908 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
909
910 @param OldSize The size, in bytes, of OldBuffer.
911 @param NewSize The size, in bytes, of the buffer to reallocate.
912 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
913 parameter that may be NULL.
914
915 @return A pointer to the allocated buffer or NULL if allocation fails.
916
917 **/
918 VOID *
919 EFIAPI
ReallocatePool(IN UINTN OldSize,IN UINTN NewSize,IN VOID * OldBuffer OPTIONAL)920 ReallocatePool (
921 IN UINTN OldSize,
922 IN UINTN NewSize,
923 IN VOID *OldBuffer OPTIONAL
924 )
925 {
926 VOID *Buffer;
927
928 Buffer = InternalReallocatePool (EfiBootServicesData, OldSize, NewSize, OldBuffer);
929 if (Buffer != NULL) {
930 MemoryProfileLibRecord (
931 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
932 MEMORY_PROFILE_ACTION_LIB_REALLOCATE_POOL,
933 EfiBootServicesData,
934 Buffer,
935 NewSize,
936 NULL
937 );
938 }
939 return Buffer;
940 }
941
942 /**
943 Reallocates a buffer of type EfiRuntimeServicesData.
944
945 Allocates and zeros the number bytes specified by NewSize from memory of type
946 EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
947 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
948 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
949 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
950 enough memory remaining to satisfy the request, then NULL is returned.
951
952 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
953 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
954
955 @param OldSize The size, in bytes, of OldBuffer.
956 @param NewSize The size, in bytes, of the buffer to reallocate.
957 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
958 parameter that may be NULL.
959
960 @return A pointer to the allocated buffer or NULL if allocation fails.
961
962 **/
963 VOID *
964 EFIAPI
ReallocateRuntimePool(IN UINTN OldSize,IN UINTN NewSize,IN VOID * OldBuffer OPTIONAL)965 ReallocateRuntimePool (
966 IN UINTN OldSize,
967 IN UINTN NewSize,
968 IN VOID *OldBuffer OPTIONAL
969 )
970 {
971 VOID *Buffer;
972
973 Buffer = InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer);
974 if (Buffer != NULL) {
975 MemoryProfileLibRecord (
976 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
977 MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RUNTIME_POOL,
978 EfiRuntimeServicesData,
979 Buffer,
980 NewSize,
981 NULL
982 );
983 }
984 return Buffer;
985 }
986
987 /**
988 Reallocates a buffer of type EfiReservedMemoryType.
989
990 Allocates and zeros the number bytes specified by NewSize from memory of type
991 EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and
992 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
993 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
994 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
995 enough memory remaining to satisfy the request, then NULL is returned.
996
997 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
998 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
999
1000 @param OldSize The size, in bytes, of OldBuffer.
1001 @param NewSize The size, in bytes, of the buffer to reallocate.
1002 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
1003 parameter that may be NULL.
1004
1005 @return A pointer to the allocated buffer or NULL if allocation fails.
1006
1007 **/
1008 VOID *
1009 EFIAPI
ReallocateReservedPool(IN UINTN OldSize,IN UINTN NewSize,IN VOID * OldBuffer OPTIONAL)1010 ReallocateReservedPool (
1011 IN UINTN OldSize,
1012 IN UINTN NewSize,
1013 IN VOID *OldBuffer OPTIONAL
1014 )
1015 {
1016 VOID *Buffer;
1017
1018 Buffer = InternalReallocatePool (EfiReservedMemoryType, OldSize, NewSize, OldBuffer);
1019 if (Buffer != NULL) {
1020 MemoryProfileLibRecord (
1021 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),
1022 MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RESERVED_POOL,
1023 EfiReservedMemoryType,
1024 Buffer,
1025 NewSize,
1026 NULL
1027 );
1028 }
1029 return Buffer;
1030 }
1031
1032 /**
1033 Frees a buffer that was previously allocated with one of the pool allocation functions in the
1034 Memory Allocation Library.
1035
1036 Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the
1037 pool allocation services of the Memory Allocation Library. If it is not possible to free pool
1038 resources, then this function will perform no actions.
1039
1040 If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
1041 then ASSERT().
1042
1043 @param Buffer The pointer to the buffer to free.
1044
1045 **/
1046 VOID
1047 EFIAPI
FreePool(IN VOID * Buffer)1048 FreePool (
1049 IN VOID *Buffer
1050 )
1051 {
1052 EFI_STATUS Status;
1053
1054 Status = gBS->FreePool (Buffer);
1055 ASSERT_EFI_ERROR (Status);
1056 }
1057
1058