37273dde561ac45e889e8ecc33c0ef089349faf2
[mirror_edk2.git] / MdePkg / Library / PeiMemoryAllocationLib / MemoryAllocationLib.c
1 /** @file
2 Support routines for memory allocation routines
3 based on PeiService for PEI phase drivers.
4
5 Copyright (c) 2006 - 2017, 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 <PiPei.h>
18
19
20 #include <Library/MemoryAllocationLib.h>
21 #include <Library/PeiServicesLib.h>
22 #include <Library/BaseMemoryLib.h>
23 #include <Library/DebugLib.h>
24 #include <Library/HobLib.h>
25
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 *
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 = PeiServicesAllocatePages (MemoryType, Pages, &Memory);
54 if (EFI_ERROR (Status)) {
55 return NULL;
56 }
57
58 return (VOID *) (UINTN) Memory;
59 }
60
61 /**
62 Allocates one or more 4KB pages of type EfiBootServicesData.
63
64 Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the
65 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
66 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
67 returned.
68
69 @param Pages The number of 4 KB pages to allocate.
70
71 @return A pointer to the allocated buffer or NULL if allocation fails.
72
73 **/
74 VOID *
75 EFIAPI
76 AllocatePages (
77 IN UINTN Pages
78 )
79 {
80 return InternalAllocatePages (EfiBootServicesData, Pages);
81 }
82
83 /**
84 Allocates one or more 4KB pages of type EfiRuntimeServicesData.
85
86 Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
87 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
88 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
89 returned.
90
91 @param Pages The number of 4 KB pages to allocate.
92
93 @return A pointer to the allocated buffer or NULL if allocation fails.
94
95 **/
96 VOID *
97 EFIAPI
98 AllocateRuntimePages (
99 IN UINTN Pages
100 )
101 {
102 return InternalAllocatePages (EfiRuntimeServicesData, Pages);
103 }
104
105 /**
106 Allocates one or more 4KB pages of type EfiReservedMemoryType.
107
108 Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the
109 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
110 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
111 returned.
112
113 @param Pages The number of 4 KB pages to allocate.
114
115 @return A pointer to the allocated buffer or NULL if allocation fails.
116
117 **/
118 VOID *
119 EFIAPI
120 AllocateReservedPages (
121 IN UINTN Pages
122 )
123 {
124 return InternalAllocatePages (EfiReservedMemoryType, Pages);
125 }
126
127 /**
128 Frees one or more 4KB pages that were previously allocated with one of the page allocation
129 functions in the Memory Allocation Library.
130
131 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
132 must have been allocated on a previous call to the page allocation services of the Memory
133 Allocation Library. If it is not possible to free allocated pages, then this function will
134 perform no actions.
135
136 If Buffer was not allocated with a page allocation function in the Memory Allocation Library,
137 then ASSERT().
138 If Pages is zero, then ASSERT().
139
140 @param Buffer The pointer to the buffer of pages to free.
141 @param Pages The number of 4 KB pages to free.
142
143 **/
144 VOID
145 EFIAPI
146 FreePages (
147 IN VOID *Buffer,
148 IN UINTN Pages
149 )
150 {
151 EFI_STATUS Status;
152
153 ASSERT (Pages != 0);
154 Status = PeiServicesFreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
155 ASSERT_EFI_ERROR (Status);
156 }
157
158 /**
159 Allocates one or more 4KB pages of a certain memory type at a specified alignment.
160
161 Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment
162 specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned.
163 If there is not enough memory at the specified alignment remaining to satisfy the request, then
164 NULL is returned.
165 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
166 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
167
168 @param MemoryType The type of memory to allocate.
169 @param Pages The number of 4 KB pages to allocate.
170 @param Alignment The requested alignment of the allocation.
171 Must be a power of two.
172 If Alignment is zero, then byte alignment is used.
173
174 @return A pointer to the allocated buffer or NULL if allocation fails.
175
176 **/
177 VOID *
178 InternalAllocateAlignedPages (
179 IN EFI_MEMORY_TYPE MemoryType,
180 IN UINTN Pages,
181 IN UINTN Alignment
182 )
183 {
184 EFI_PHYSICAL_ADDRESS Memory;
185 EFI_PHYSICAL_ADDRESS AlignedMemory;
186 EFI_PEI_HOB_POINTERS Hob;
187 BOOLEAN SkipBeforeMemHob;
188 BOOLEAN SkipAfterMemHob;
189 EFI_PHYSICAL_ADDRESS HobBaseAddress;
190 UINT64 HobLength;
191 EFI_MEMORY_TYPE HobMemoryType;
192 UINTN TotalPages;
193
194 //
195 // Alignment must be a power of two or zero.
196 //
197 ASSERT ((Alignment & (Alignment - 1)) == 0);
198
199 if (Pages == 0) {
200 return NULL;
201 }
202 //
203 // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
204 //
205 ASSERT (Pages <= (MAX_ADDRESS - EFI_SIZE_TO_PAGES (Alignment)));
206
207 //
208 // We would rather waste some memory to save PEI code size.
209 // meaning in addition to the requested size for the aligned mem,
210 // we simply reserve an overhead memory equal to Alignmemt(page-aligned), no matter what.
211 // The overhead mem size could be reduced later with more involved malloc mechanisms
212 // (e.g., somthing that can detect the alignment boundary before allocating memory or
213 // can request that memory be allocated at a certain address that is aleady aligned).
214 //
215 TotalPages = Pages + (Alignment <= EFI_PAGE_SIZE ? 0 : EFI_SIZE_TO_PAGES(Alignment));
216 Memory = (EFI_PHYSICAL_ADDRESS) (UINTN) InternalAllocatePages (MemoryType, TotalPages);
217 if (Memory == 0) {
218 DEBUG((DEBUG_INFO, "Out of memory resource! \n"));
219 return NULL;
220 }
221 DEBUG ((DEBUG_INFO, "Allocated Memory unaligned: Address = 0x%LX, Pages = 0x%X, Type = %d \n", Memory, TotalPages, (UINTN) MemoryType));
222
223 //
224 // Alignment calculation
225 //
226 AlignedMemory = Memory;
227 if (Alignment > EFI_PAGE_SIZE) {
228 AlignedMemory = ALIGN_VALUE (Memory, Alignment);
229 }
230 DEBUG ((DEBUG_INFO, "After aligning to 0x%X bytes: Address = 0x%LX, Pages = 0x%X \n", Alignment, AlignedMemory, Pages));
231
232 //
233 // In general three HOBs cover the total allocated space.
234 // The aligned portion is covered by the aligned mem HOB and
235 // the unaligned(to be freed) portions before and after the aligned portion are covered by newly created HOBs.
236 //
237 // Before mem HOB covers the region between "Memory" and "AlignedMemory"
238 // Aligned mem HOB covers the region between "AlignedMemory" and "AlignedMemory + EFI_PAGES_TO_SIZE(Pages)"
239 // After mem HOB covers the region between "AlignedMemory + EFI_PAGES_TO_SIZE(Pages)" and "Memory + EFI_PAGES_TO_SIZE(TotalPages)"
240 //
241 // The before or after mem HOBs need to be skipped under special cases where the aligned portion
242 // touches either the top or bottom of the original allocated space.
243 //
244 SkipBeforeMemHob = FALSE;
245 SkipAfterMemHob = FALSE;
246 if (Memory == AlignedMemory) {
247 SkipBeforeMemHob = TRUE;
248 }
249 if ((Memory + EFI_PAGES_TO_SIZE(TotalPages)) == (AlignedMemory + EFI_PAGES_TO_SIZE(Pages))) {
250 //
251 // This condition is never met in the current implementation.
252 // There is always some after-mem since the overhead mem(used in TotalPages)
253 // is no less than Alignment.
254 //
255 SkipAfterMemHob = TRUE;
256 }
257
258 //
259 // Search for the mem HOB referring to the original(unaligned) allocation
260 // and update the size and type if needed.
261 //
262 Hob.Raw = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION);
263 while (Hob.Raw != NULL) {
264 if (Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress == Memory) {
265 break;
266 }
267 Hob.Raw = GET_NEXT_HOB (Hob);
268 Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw);
269 }
270 ASSERT (Hob.Raw != NULL);
271 if (SkipBeforeMemHob) {
272 //
273 // Use this HOB as aligned mem HOB as there is no portion before it.
274 //
275 HobLength = EFI_PAGES_TO_SIZE(Pages);
276 Hob.MemoryAllocation->AllocDescriptor.MemoryLength = HobLength;
277 } else {
278 //
279 // Use this HOB as before mem HOB and create a new HOB for the aligned portion
280 //
281 HobLength = (AlignedMemory - Memory);
282 Hob.MemoryAllocation->AllocDescriptor.MemoryLength = HobLength;
283 Hob.MemoryAllocation->AllocDescriptor.MemoryType = EfiConventionalMemory;
284 }
285
286 HobBaseAddress = Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress;
287 HobMemoryType = Hob.MemoryAllocation->AllocDescriptor.MemoryType;
288
289 //
290 // Build the aligned mem HOB if needed
291 //
292 if (!SkipBeforeMemHob) {
293 DEBUG((DEBUG_INFO, "Updated before-mem HOB with BaseAddress = %LX, Length = %LX, MemoryType = %d \n",
294 HobBaseAddress, HobLength, (UINTN) HobMemoryType));
295
296 HobBaseAddress = AlignedMemory;
297 HobLength = EFI_PAGES_TO_SIZE(Pages);
298 HobMemoryType = MemoryType;
299
300 BuildMemoryAllocationHob (
301 HobBaseAddress,
302 HobLength,
303 HobMemoryType
304 );
305
306 DEBUG((DEBUG_INFO, "Created aligned-mem HOB with BaseAddress = %LX, Length = %LX, MemoryType = %d \n",
307 HobBaseAddress, HobLength, (UINTN) HobMemoryType));
308 } else {
309 if (HobBaseAddress != 0) {
310 DEBUG((DEBUG_INFO, "Updated aligned-mem HOB with BaseAddress = %LX, Length = %LX, MemoryType = %d \n",
311 HobBaseAddress, HobLength, (UINTN) HobMemoryType));
312 }
313 }
314
315
316 //
317 // Build the after mem HOB if needed
318 //
319 if (!SkipAfterMemHob) {
320 HobBaseAddress = AlignedMemory + EFI_PAGES_TO_SIZE(Pages);
321 HobLength = (Memory + EFI_PAGES_TO_SIZE(TotalPages)) - (AlignedMemory + EFI_PAGES_TO_SIZE(Pages));
322 HobMemoryType = EfiConventionalMemory;
323
324 BuildMemoryAllocationHob (
325 HobBaseAddress,
326 HobLength,
327 HobMemoryType
328 );
329
330 DEBUG((DEBUG_INFO, "Created after-mem HOB with BaseAddress = %LX, Length = %LX, MemoryType = %d \n",
331 HobBaseAddress, HobLength, (UINTN) HobMemoryType));
332 }
333
334 return (VOID *) (UINTN) AlignedMemory;
335 }
336
337 /**
338 Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment.
339
340 Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an
341 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
342 returned. If there is not enough memory at the specified alignment remaining to satisfy the
343 request, then NULL is returned.
344
345 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
346 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
347
348 @param Pages The number of 4 KB pages to allocate.
349 @param Alignment The requested alignment of the allocation.
350 Must be a power of two.
351 If Alignment is zero, then byte alignment is used.
352
353 @return A pointer to the allocated buffer or NULL if allocation fails.
354
355 **/
356 VOID *
357 EFIAPI
358 AllocateAlignedPages (
359 IN UINTN Pages,
360 IN UINTN Alignment
361 )
362 {
363 return InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment);
364 }
365
366 /**
367 Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
368
369 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an
370 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
371 returned. If there is not enough memory at the specified alignment remaining to satisfy the
372 request, then NULL is returned.
373
374 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
375 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
376
377 @param Pages The number of 4 KB pages to allocate.
378 @param Alignment The requested alignment of the allocation.
379 Must be a power of two.
380 If Alignment is zero, then byte alignment is used.
381
382 @return A pointer to the allocated buffer or NULL if allocation fails.
383
384 **/
385 VOID *
386 EFIAPI
387 AllocateAlignedRuntimePages (
388 IN UINTN Pages,
389 IN UINTN Alignment
390 )
391 {
392 return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);
393 }
394
395 /**
396 Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
397
398 Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an
399 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
400 returned. If there is not enough memory at the specified alignment remaining to satisfy the
401 request, then NULL is returned.
402
403 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
404 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
405
406 @param Pages The number of 4 KB pages to allocate.
407 @param Alignment The requested alignment of the allocation.
408 Must be a power of two.
409 If Alignment is zero, then byte alignment is used.
410
411 @return A pointer to the allocated buffer or NULL if allocation fails.
412
413 **/
414 VOID *
415 EFIAPI
416 AllocateAlignedReservedPages (
417 IN UINTN Pages,
418 IN UINTN Alignment
419 )
420 {
421 return InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment);
422 }
423
424 /**
425 Frees one or more 4KB pages that were previously allocated with one of the aligned page
426 allocation functions in the Memory Allocation Library.
427
428 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
429 must have been allocated on a previous call to the aligned page allocation services of the Memory
430 Allocation Library. If it is not possible to free allocated pages, then this function will
431 perform no actions.
432
433 If Buffer was not allocated with an aligned page allocation function in the Memory Allocation
434 Library, then ASSERT().
435 If Pages is zero, then ASSERT().
436
437 @param Buffer The pointer to the buffer of pages to free.
438 @param Pages The number of 4 KB pages to free.
439
440 **/
441 VOID
442 EFIAPI
443 FreeAlignedPages (
444 IN VOID *Buffer,
445 IN UINTN Pages
446 )
447 {
448 EFI_STATUS Status;
449
450 ASSERT (Pages != 0);
451 Status = PeiServicesFreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
452 ASSERT_EFI_ERROR (Status);
453 }
454
455 /**
456 Allocates a buffer of a certain pool type.
457
458 Allocates the number bytes specified by AllocationSize of a certain pool type and returns a
459 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
460 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
461
462 @param MemoryType The type of memory to allocate.
463 @param AllocationSize The number of bytes to allocate.
464
465 @return A pointer to the allocated buffer or NULL if allocation fails.
466
467 **/
468 VOID *
469 InternalAllocatePool (
470 IN EFI_MEMORY_TYPE MemoryType,
471 IN UINTN AllocationSize
472 )
473 {
474 //
475 // If we need lots of small runtime/reserved memory type from PEI in the future,
476 // we can consider providing a more complex algorithm that allocates runtime pages and
477 // provide pool allocations from those pages.
478 //
479 return InternalAllocatePages (MemoryType, EFI_SIZE_TO_PAGES (AllocationSize));
480 }
481
482 /**
483 Allocates a buffer of type EfiBootServicesData.
484
485 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a
486 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
487 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
488
489 @param AllocationSize The number of bytes to allocate.
490
491 @return A pointer to the allocated buffer or NULL if allocation fails.
492
493 **/
494 VOID *
495 EFIAPI
496 AllocatePool (
497 IN UINTN AllocationSize
498 )
499 {
500 EFI_STATUS Status;
501 VOID *Buffer;
502
503 Status = PeiServicesAllocatePool (AllocationSize, &Buffer);
504 if (EFI_ERROR (Status)) {
505 Buffer = NULL;
506 }
507 return Buffer;
508 }
509
510 /**
511 Allocates a buffer of type EfiRuntimeServicesData.
512
513 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns
514 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
515 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
516
517 @param AllocationSize The number of bytes to allocate.
518
519 @return A pointer to the allocated buffer or NULL if allocation fails.
520
521 **/
522 VOID *
523 EFIAPI
524 AllocateRuntimePool (
525 IN UINTN AllocationSize
526 )
527 {
528 return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
529 }
530
531 /**
532 Allocates a buffer of type EfiReservedMemoryType.
533
534 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns
535 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
536 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
537
538 @param AllocationSize The number of bytes to allocate.
539
540 @return A pointer to the allocated buffer or NULL if allocation fails.
541
542 **/
543 VOID *
544 EFIAPI
545 AllocateReservedPool (
546 IN UINTN AllocationSize
547 )
548 {
549 return InternalAllocatePool (EfiReservedMemoryType, AllocationSize);
550 }
551
552 /**
553 Allocates and zeros a buffer of a certain pool type.
554
555 Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer
556 with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid
557 buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request,
558 then NULL is returned.
559
560 @param PoolType The type of memory to allocate.
561 @param AllocationSize The number of bytes to allocate and zero.
562
563 @return A pointer to the allocated buffer or NULL if allocation fails.
564
565 **/
566 VOID *
567 InternalAllocateZeroPool (
568 IN EFI_MEMORY_TYPE PoolType,
569 IN UINTN AllocationSize
570 )
571 {
572 VOID *Memory;
573
574 Memory = InternalAllocatePool (PoolType, AllocationSize);
575 if (Memory != NULL) {
576 Memory = ZeroMem (Memory, AllocationSize);
577 }
578 return Memory;
579 }
580
581 /**
582 Allocates and zeros a buffer of type EfiBootServicesData.
583
584 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
585 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
586 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
587 request, then NULL is returned.
588
589 @param AllocationSize The number of bytes to allocate and zero.
590
591 @return A pointer to the allocated buffer or NULL if allocation fails.
592
593 **/
594 VOID *
595 EFIAPI
596 AllocateZeroPool (
597 IN UINTN AllocationSize
598 )
599 {
600 VOID *Memory;
601
602 Memory = AllocatePool (AllocationSize);
603 if (Memory != NULL) {
604 Memory = ZeroMem (Memory, AllocationSize);
605 }
606 return Memory;
607 }
608
609 /**
610 Allocates and zeros a buffer of type EfiRuntimeServicesData.
611
612 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the
613 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
614 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
615 request, then NULL is returned.
616
617 @param AllocationSize The number of bytes to allocate and zero.
618
619 @return A pointer to the allocated buffer or NULL if allocation fails.
620
621 **/
622 VOID *
623 EFIAPI
624 AllocateRuntimeZeroPool (
625 IN UINTN AllocationSize
626 )
627 {
628 return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);
629 }
630
631 /**
632 Allocates and zeros a buffer of type EfiReservedMemoryType.
633
634 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, 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
646 AllocateReservedZeroPool (
647 IN UINTN AllocationSize
648 )
649 {
650 return InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);
651 }
652
653 /**
654 Copies a buffer to an allocated buffer of a certain pool type.
655
656 Allocates the number bytes specified by AllocationSize of a certain pool type, copies
657 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
658 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
659 is not enough memory remaining to satisfy the request, then NULL is returned.
660 If Buffer is NULL, then ASSERT().
661 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
662
663 @param PoolType The type of pool to allocate.
664 @param AllocationSize The number of bytes to allocate and zero.
665 @param Buffer The buffer to copy to the allocated buffer.
666
667 @return A pointer to the allocated buffer or NULL if allocation fails.
668
669 **/
670 VOID *
671 InternalAllocateCopyPool (
672 IN EFI_MEMORY_TYPE PoolType,
673 IN UINTN AllocationSize,
674 IN CONST VOID *Buffer
675 )
676 {
677 VOID *Memory;
678
679 ASSERT (Buffer != NULL);
680 ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
681
682 Memory = InternalAllocatePool (PoolType, AllocationSize);
683 if (Memory != NULL) {
684 Memory = CopyMem (Memory, Buffer, AllocationSize);
685 }
686 return Memory;
687 }
688
689 /**
690 Copies a buffer to an allocated buffer of type EfiBootServicesData.
691
692 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies
693 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
694 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
695 is not enough memory remaining to satisfy the request, then NULL is returned.
696
697 If Buffer is NULL, then ASSERT().
698 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
699
700 @param AllocationSize The number of bytes to allocate and zero.
701 @param Buffer The buffer to copy to the allocated buffer.
702
703 @return A pointer to the allocated buffer or NULL if allocation fails.
704
705 **/
706 VOID *
707 EFIAPI
708 AllocateCopyPool (
709 IN UINTN AllocationSize,
710 IN CONST VOID *Buffer
711 )
712 {
713 VOID *Memory;
714
715 ASSERT (Buffer != NULL);
716 ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
717
718 Memory = AllocatePool (AllocationSize);
719 if (Memory != NULL) {
720 Memory = CopyMem (Memory, Buffer, AllocationSize);
721 }
722 return Memory;
723 }
724
725 /**
726 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
727
728 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies
729 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
730 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
731 is not enough memory remaining to satisfy the request, then NULL is returned.
732
733 If Buffer is NULL, then ASSERT().
734 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
735
736 @param AllocationSize The number of bytes to allocate and zero.
737 @param Buffer The buffer to copy to the allocated buffer.
738
739 @return A pointer to the allocated buffer or NULL if allocation fails.
740
741 **/
742 VOID *
743 EFIAPI
744 AllocateRuntimeCopyPool (
745 IN UINTN AllocationSize,
746 IN CONST VOID *Buffer
747 )
748 {
749 return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);
750 }
751
752 /**
753 Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
754
755 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies
756 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
757 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
758 is not enough memory remaining to satisfy the request, then NULL is returned.
759
760 If Buffer is NULL, then ASSERT().
761 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
762
763 @param AllocationSize The number of bytes to allocate and zero.
764 @param Buffer The buffer to copy to the allocated buffer.
765
766 @return A pointer to the allocated buffer or NULL if allocation fails.
767
768 **/
769 VOID *
770 EFIAPI
771 AllocateReservedCopyPool (
772 IN UINTN AllocationSize,
773 IN CONST VOID *Buffer
774 )
775 {
776 return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);
777 }
778
779 /**
780 Reallocates a buffer of a specified memory type.
781
782 Allocates and zeros the number bytes specified by NewSize from memory of the type
783 specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and
784 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
785 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
786 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
787 enough memory remaining to satisfy the request, then NULL is returned.
788
789 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
790 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
791
792 @param PoolType The type of pool to allocate.
793 @param OldSize The size, in bytes, of OldBuffer.
794 @param NewSize The size, in bytes, of the buffer to reallocate.
795 @param OldBuffer The buffer to copy to the allocated buffer. This is an
796 optional parameter that may be NULL.
797
798 @return A pointer to the allocated buffer or NULL if allocation fails.
799
800 **/
801 VOID *
802 InternalReallocatePool (
803 IN EFI_MEMORY_TYPE PoolType,
804 IN UINTN OldSize,
805 IN UINTN NewSize,
806 IN VOID *OldBuffer OPTIONAL
807 )
808 {
809 VOID *NewBuffer;
810
811 NewBuffer = InternalAllocateZeroPool (PoolType, NewSize);
812 if (NewBuffer != NULL && OldBuffer != NULL) {
813 CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize));
814 FreePool (OldBuffer);
815 }
816 return NewBuffer;
817 }
818
819 /**
820 Reallocates a buffer of type EfiBootServicesData.
821
822 Allocates and zeros the number bytes specified by NewSize from memory of type
823 EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
824 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
825 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
826 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
827 enough memory remaining to satisfy the request, then NULL is returned.
828
829 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
830 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
831
832 @param OldSize The size, in bytes, of OldBuffer.
833 @param NewSize The size, in bytes, of the buffer to reallocate.
834 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
835 parameter that may be NULL.
836
837 @return A pointer to the allocated buffer or NULL if allocation fails.
838
839 **/
840 VOID *
841 EFIAPI
842 ReallocatePool (
843 IN UINTN OldSize,
844 IN UINTN NewSize,
845 IN VOID *OldBuffer OPTIONAL
846 )
847 {
848 return InternalReallocatePool (EfiBootServicesData, OldSize, NewSize, OldBuffer);
849 }
850
851 /**
852 Reallocates a buffer of type EfiRuntimeServicesData.
853
854 Allocates and zeros the number bytes specified by NewSize from memory of type
855 EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
856 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
857 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
858 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
859 enough memory remaining to satisfy the request, then NULL is returned.
860
861 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
862 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
863
864 @param OldSize The size, in bytes, of OldBuffer.
865 @param NewSize The size, in bytes, of the buffer to reallocate.
866 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
867 parameter that may be NULL.
868
869 @return A pointer to the allocated buffer or NULL if allocation fails.
870
871 **/
872 VOID *
873 EFIAPI
874 ReallocateRuntimePool (
875 IN UINTN OldSize,
876 IN UINTN NewSize,
877 IN VOID *OldBuffer OPTIONAL
878 )
879 {
880 return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer);
881 }
882
883 /**
884 Reallocates a buffer of type EfiReservedMemoryType.
885
886 Allocates and zeros the number bytes specified by NewSize from memory of type
887 EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and
888 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
889 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
890 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
891 enough memory remaining to satisfy the request, then NULL is returned.
892
893 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
894 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
895
896 @param OldSize The size, in bytes, of OldBuffer.
897 @param NewSize The size, in bytes, of the buffer to reallocate.
898 @param OldBuffer The buffer to copy to the allocated buffer. This is an
899 optional parameter that may be NULL.
900
901 @return A pointer to the allocated buffer or NULL if allocation fails.
902
903 **/
904 VOID *
905 EFIAPI
906 ReallocateReservedPool (
907 IN UINTN OldSize,
908 IN UINTN NewSize,
909 IN VOID *OldBuffer OPTIONAL
910 )
911 {
912 return InternalReallocatePool (EfiReservedMemoryType, OldSize, NewSize, OldBuffer);
913 }
914
915 /**
916 Frees a buffer that was previously allocated with one of the pool allocation functions in the
917 Memory Allocation Library.
918
919 Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the
920 pool allocation services of the Memory Allocation Library. If it is not possible to free pool
921 resources, then this function will perform no actions.
922
923 If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
924 then ASSERT().
925
926 @param Buffer The pointer to the buffer to free.
927
928 **/
929 VOID
930 EFIAPI
931 FreePool (
932 IN VOID *Buffer
933 )
934 {
935 //
936 // PEI phase does not support to free pool, so leave it as NOP.
937 //
938 }
939
940