MdePkg PeiMemoryAllocationLib: Update InternalAllocateAlignedPages
[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_STATUS Status;
185 EFI_PHYSICAL_ADDRESS Memory;
186 UINTN AlignedMemory;
187 UINTN AlignmentMask;
188 UINTN UnalignedPages;
189 UINTN RealPages;
190
191 //
192 // Alignment must be a power of two or zero.
193 //
194 ASSERT ((Alignment & (Alignment - 1)) == 0);
195
196 if (Pages == 0) {
197 return NULL;
198 }
199 if (Alignment > EFI_PAGE_SIZE) {
200 //
201 // Calculate the total number of pages since alignment is larger than page size.
202 //
203 AlignmentMask = Alignment - 1;
204 RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment);
205 //
206 // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
207 //
208 ASSERT (RealPages > Pages);
209
210 Status = PeiServicesAllocatePages (MemoryType, RealPages, &Memory);
211 if (EFI_ERROR (Status)) {
212 return NULL;
213 }
214 AlignedMemory = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask;
215 UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN) Memory);
216 if (UnalignedPages > 0) {
217 //
218 // Free first unaligned page(s).
219 //
220 Status = PeiServicesFreePages (Memory, UnalignedPages);
221 ASSERT_EFI_ERROR (Status);
222 }
223 Memory = AlignedMemory + EFI_PAGES_TO_SIZE (Pages);
224 UnalignedPages = RealPages - Pages - UnalignedPages;
225 if (UnalignedPages > 0) {
226 //
227 // Free last unaligned page(s).
228 //
229 Status = PeiServicesFreePages (Memory, UnalignedPages);
230 ASSERT_EFI_ERROR (Status);
231 }
232 } else {
233 //
234 // Do not over-allocate pages in this case.
235 //
236 Status = PeiServicesAllocatePages (MemoryType, Pages, &Memory);
237 if (EFI_ERROR (Status)) {
238 return NULL;
239 }
240 AlignedMemory = (UINTN) Memory;
241 }
242 return (VOID *) AlignedMemory;
243 }
244
245 /**
246 Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment.
247
248 Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an
249 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
250 returned. If there is not enough memory at the specified alignment remaining to satisfy the
251 request, then NULL is returned.
252
253 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
254 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
255
256 @param Pages The number of 4 KB pages to allocate.
257 @param Alignment The requested alignment of the allocation.
258 Must be a power of two.
259 If Alignment is zero, then byte alignment is used.
260
261 @return A pointer to the allocated buffer or NULL if allocation fails.
262
263 **/
264 VOID *
265 EFIAPI
266 AllocateAlignedPages (
267 IN UINTN Pages,
268 IN UINTN Alignment
269 )
270 {
271 return InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment);
272 }
273
274 /**
275 Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
276
277 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an
278 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
279 returned. If there is not enough memory at the specified alignment remaining to satisfy the
280 request, then NULL is returned.
281
282 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
283 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
284
285 @param Pages The number of 4 KB pages to allocate.
286 @param Alignment The requested alignment of the allocation.
287 Must be a power of two.
288 If Alignment is zero, then byte alignment is used.
289
290 @return A pointer to the allocated buffer or NULL if allocation fails.
291
292 **/
293 VOID *
294 EFIAPI
295 AllocateAlignedRuntimePages (
296 IN UINTN Pages,
297 IN UINTN Alignment
298 )
299 {
300 return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);
301 }
302
303 /**
304 Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
305
306 Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an
307 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
308 returned. If there is not enough memory at the specified alignment remaining to satisfy the
309 request, then NULL is returned.
310
311 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
312 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
313
314 @param Pages The number of 4 KB pages to allocate.
315 @param Alignment The requested alignment of the allocation.
316 Must be a power of two.
317 If Alignment is zero, then byte alignment is used.
318
319 @return A pointer to the allocated buffer or NULL if allocation fails.
320
321 **/
322 VOID *
323 EFIAPI
324 AllocateAlignedReservedPages (
325 IN UINTN Pages,
326 IN UINTN Alignment
327 )
328 {
329 return InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment);
330 }
331
332 /**
333 Frees one or more 4KB pages that were previously allocated with one of the aligned page
334 allocation functions in the Memory Allocation Library.
335
336 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
337 must have been allocated on a previous call to the aligned page allocation services of the Memory
338 Allocation Library. If it is not possible to free allocated pages, then this function will
339 perform no actions.
340
341 If Buffer was not allocated with an aligned page allocation function in the Memory Allocation
342 Library, then ASSERT().
343 If Pages is zero, then ASSERT().
344
345 @param Buffer The pointer to the buffer of pages to free.
346 @param Pages The number of 4 KB pages to free.
347
348 **/
349 VOID
350 EFIAPI
351 FreeAlignedPages (
352 IN VOID *Buffer,
353 IN UINTN Pages
354 )
355 {
356 EFI_STATUS Status;
357
358 ASSERT (Pages != 0);
359 Status = PeiServicesFreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
360 ASSERT_EFI_ERROR (Status);
361 }
362
363 /**
364 Allocates a buffer of a certain pool type.
365
366 Allocates the number bytes specified by AllocationSize of a certain pool type and returns a
367 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
368 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
369
370 @param MemoryType The type of memory to allocate.
371 @param AllocationSize The number of bytes to allocate.
372
373 @return A pointer to the allocated buffer or NULL if allocation fails.
374
375 **/
376 VOID *
377 InternalAllocatePool (
378 IN EFI_MEMORY_TYPE MemoryType,
379 IN UINTN AllocationSize
380 )
381 {
382 //
383 // If we need lots of small runtime/reserved memory type from PEI in the future,
384 // we can consider providing a more complex algorithm that allocates runtime pages and
385 // provide pool allocations from those pages.
386 //
387 return InternalAllocatePages (MemoryType, EFI_SIZE_TO_PAGES (AllocationSize));
388 }
389
390 /**
391 Allocates a buffer of type EfiBootServicesData.
392
393 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a
394 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
395 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
396
397 @param AllocationSize The number of bytes to allocate.
398
399 @return A pointer to the allocated buffer or NULL if allocation fails.
400
401 **/
402 VOID *
403 EFIAPI
404 AllocatePool (
405 IN UINTN AllocationSize
406 )
407 {
408 EFI_STATUS Status;
409 VOID *Buffer;
410
411 Status = PeiServicesAllocatePool (AllocationSize, &Buffer);
412 if (EFI_ERROR (Status)) {
413 Buffer = NULL;
414 }
415 return Buffer;
416 }
417
418 /**
419 Allocates a buffer of type EfiRuntimeServicesData.
420
421 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns
422 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
423 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
424
425 @param AllocationSize The number of bytes to allocate.
426
427 @return A pointer to the allocated buffer or NULL if allocation fails.
428
429 **/
430 VOID *
431 EFIAPI
432 AllocateRuntimePool (
433 IN UINTN AllocationSize
434 )
435 {
436 return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
437 }
438
439 /**
440 Allocates a buffer of type EfiReservedMemoryType.
441
442 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns
443 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
444 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
445
446 @param AllocationSize The number of bytes to allocate.
447
448 @return A pointer to the allocated buffer or NULL if allocation fails.
449
450 **/
451 VOID *
452 EFIAPI
453 AllocateReservedPool (
454 IN UINTN AllocationSize
455 )
456 {
457 return InternalAllocatePool (EfiReservedMemoryType, AllocationSize);
458 }
459
460 /**
461 Allocates and zeros a buffer of a certain pool type.
462
463 Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer
464 with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid
465 buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request,
466 then NULL is returned.
467
468 @param PoolType The type of memory to allocate.
469 @param AllocationSize The number of bytes to allocate and zero.
470
471 @return A pointer to the allocated buffer or NULL if allocation fails.
472
473 **/
474 VOID *
475 InternalAllocateZeroPool (
476 IN EFI_MEMORY_TYPE PoolType,
477 IN UINTN AllocationSize
478 )
479 {
480 VOID *Memory;
481
482 Memory = InternalAllocatePool (PoolType, AllocationSize);
483 if (Memory != NULL) {
484 Memory = ZeroMem (Memory, AllocationSize);
485 }
486 return Memory;
487 }
488
489 /**
490 Allocates and zeros a buffer of type EfiBootServicesData.
491
492 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
493 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
494 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
495 request, then NULL is returned.
496
497 @param AllocationSize The number of bytes to allocate and zero.
498
499 @return A pointer to the allocated buffer or NULL if allocation fails.
500
501 **/
502 VOID *
503 EFIAPI
504 AllocateZeroPool (
505 IN UINTN AllocationSize
506 )
507 {
508 VOID *Memory;
509
510 Memory = AllocatePool (AllocationSize);
511 if (Memory != NULL) {
512 Memory = ZeroMem (Memory, AllocationSize);
513 }
514 return Memory;
515 }
516
517 /**
518 Allocates and zeros a buffer of type EfiRuntimeServicesData.
519
520 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the
521 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
522 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
523 request, then NULL is returned.
524
525 @param AllocationSize The number of bytes to allocate and zero.
526
527 @return A pointer to the allocated buffer or NULL if allocation fails.
528
529 **/
530 VOID *
531 EFIAPI
532 AllocateRuntimeZeroPool (
533 IN UINTN AllocationSize
534 )
535 {
536 return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);
537 }
538
539 /**
540 Allocates and zeros a buffer of type EfiReservedMemoryType.
541
542 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the
543 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
544 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
545 request, then NULL is returned.
546
547 @param AllocationSize The number of bytes to allocate and zero.
548
549 @return A pointer to the allocated buffer or NULL if allocation fails.
550
551 **/
552 VOID *
553 EFIAPI
554 AllocateReservedZeroPool (
555 IN UINTN AllocationSize
556 )
557 {
558 return InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);
559 }
560
561 /**
562 Copies a buffer to an allocated buffer of a certain pool type.
563
564 Allocates the number bytes specified by AllocationSize of a certain pool type, copies
565 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
566 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
567 is not enough memory remaining to satisfy the request, then NULL is returned.
568 If Buffer is NULL, then ASSERT().
569 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
570
571 @param PoolType The type of pool to allocate.
572 @param AllocationSize The number of bytes to allocate and zero.
573 @param Buffer The buffer to copy to the allocated buffer.
574
575 @return A pointer to the allocated buffer or NULL if allocation fails.
576
577 **/
578 VOID *
579 InternalAllocateCopyPool (
580 IN EFI_MEMORY_TYPE PoolType,
581 IN UINTN AllocationSize,
582 IN CONST VOID *Buffer
583 )
584 {
585 VOID *Memory;
586
587 ASSERT (Buffer != NULL);
588 ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
589
590 Memory = InternalAllocatePool (PoolType, AllocationSize);
591 if (Memory != NULL) {
592 Memory = CopyMem (Memory, Buffer, AllocationSize);
593 }
594 return Memory;
595 }
596
597 /**
598 Copies a buffer to an allocated buffer of type EfiBootServicesData.
599
600 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies
601 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
602 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
603 is not enough memory remaining to satisfy the request, then NULL is returned.
604
605 If Buffer is NULL, then ASSERT().
606 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
607
608 @param AllocationSize The number of bytes to allocate and zero.
609 @param Buffer The buffer to copy to the allocated buffer.
610
611 @return A pointer to the allocated buffer or NULL if allocation fails.
612
613 **/
614 VOID *
615 EFIAPI
616 AllocateCopyPool (
617 IN UINTN AllocationSize,
618 IN CONST VOID *Buffer
619 )
620 {
621 VOID *Memory;
622
623 ASSERT (Buffer != NULL);
624 ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
625
626 Memory = AllocatePool (AllocationSize);
627 if (Memory != NULL) {
628 Memory = CopyMem (Memory, Buffer, AllocationSize);
629 }
630 return Memory;
631 }
632
633 /**
634 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
635
636 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies
637 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
638 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
639 is not enough memory remaining to satisfy the request, then NULL is returned.
640
641 If Buffer is NULL, then ASSERT().
642 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
643
644 @param AllocationSize The number of bytes to allocate and zero.
645 @param Buffer The buffer to copy to the allocated buffer.
646
647 @return A pointer to the allocated buffer or NULL if allocation fails.
648
649 **/
650 VOID *
651 EFIAPI
652 AllocateRuntimeCopyPool (
653 IN UINTN AllocationSize,
654 IN CONST VOID *Buffer
655 )
656 {
657 return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);
658 }
659
660 /**
661 Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
662
663 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies
664 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
665 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
666 is not enough memory remaining to satisfy the request, then NULL is returned.
667
668 If Buffer is NULL, then ASSERT().
669 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
670
671 @param AllocationSize The number of bytes to allocate and zero.
672 @param Buffer The buffer to copy to the allocated buffer.
673
674 @return A pointer to the allocated buffer or NULL if allocation fails.
675
676 **/
677 VOID *
678 EFIAPI
679 AllocateReservedCopyPool (
680 IN UINTN AllocationSize,
681 IN CONST VOID *Buffer
682 )
683 {
684 return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);
685 }
686
687 /**
688 Reallocates a buffer of a specified memory type.
689
690 Allocates and zeros the number bytes specified by NewSize from memory of the type
691 specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and
692 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
693 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
694 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
695 enough memory remaining to satisfy the request, then NULL is returned.
696
697 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
698 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
699
700 @param PoolType The type of pool to allocate.
701 @param OldSize The size, in bytes, of OldBuffer.
702 @param NewSize The size, in bytes, of the buffer to reallocate.
703 @param OldBuffer The buffer to copy to the allocated buffer. This is an
704 optional parameter that may be NULL.
705
706 @return A pointer to the allocated buffer or NULL if allocation fails.
707
708 **/
709 VOID *
710 InternalReallocatePool (
711 IN EFI_MEMORY_TYPE PoolType,
712 IN UINTN OldSize,
713 IN UINTN NewSize,
714 IN VOID *OldBuffer OPTIONAL
715 )
716 {
717 VOID *NewBuffer;
718
719 NewBuffer = InternalAllocateZeroPool (PoolType, NewSize);
720 if (NewBuffer != NULL && OldBuffer != NULL) {
721 CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize));
722 FreePool (OldBuffer);
723 }
724 return NewBuffer;
725 }
726
727 /**
728 Reallocates a buffer of type EfiBootServicesData.
729
730 Allocates and zeros the number bytes specified by NewSize from memory of type
731 EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
732 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
733 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
734 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
735 enough memory remaining to satisfy the request, then NULL is returned.
736
737 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
738 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
739
740 @param OldSize The size, in bytes, of OldBuffer.
741 @param NewSize The size, in bytes, of the buffer to reallocate.
742 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
743 parameter that may be NULL.
744
745 @return A pointer to the allocated buffer or NULL if allocation fails.
746
747 **/
748 VOID *
749 EFIAPI
750 ReallocatePool (
751 IN UINTN OldSize,
752 IN UINTN NewSize,
753 IN VOID *OldBuffer OPTIONAL
754 )
755 {
756 return InternalReallocatePool (EfiBootServicesData, OldSize, NewSize, OldBuffer);
757 }
758
759 /**
760 Reallocates a buffer of type EfiRuntimeServicesData.
761
762 Allocates and zeros the number bytes specified by NewSize from memory of type
763 EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
764 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
765 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
766 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
767 enough memory remaining to satisfy the request, then NULL is returned.
768
769 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
770 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
771
772 @param OldSize The size, in bytes, of OldBuffer.
773 @param NewSize The size, in bytes, of the buffer to reallocate.
774 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
775 parameter that may be NULL.
776
777 @return A pointer to the allocated buffer or NULL if allocation fails.
778
779 **/
780 VOID *
781 EFIAPI
782 ReallocateRuntimePool (
783 IN UINTN OldSize,
784 IN UINTN NewSize,
785 IN VOID *OldBuffer OPTIONAL
786 )
787 {
788 return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer);
789 }
790
791 /**
792 Reallocates a buffer of type EfiReservedMemoryType.
793
794 Allocates and zeros the number bytes specified by NewSize from memory of type
795 EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and
796 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
797 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
798 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
799 enough memory remaining to satisfy the request, then NULL is returned.
800
801 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
802 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
803
804 @param OldSize The size, in bytes, of OldBuffer.
805 @param NewSize The size, in bytes, of the buffer to reallocate.
806 @param OldBuffer The buffer to copy to the allocated buffer. This is an
807 optional parameter that may be NULL.
808
809 @return A pointer to the allocated buffer or NULL if allocation fails.
810
811 **/
812 VOID *
813 EFIAPI
814 ReallocateReservedPool (
815 IN UINTN OldSize,
816 IN UINTN NewSize,
817 IN VOID *OldBuffer OPTIONAL
818 )
819 {
820 return InternalReallocatePool (EfiReservedMemoryType, OldSize, NewSize, OldBuffer);
821 }
822
823 /**
824 Frees a buffer that was previously allocated with one of the pool allocation functions in the
825 Memory Allocation Library.
826
827 Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the
828 pool allocation services of the Memory Allocation Library. If it is not possible to free pool
829 resources, then this function will perform no actions.
830
831 If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
832 then ASSERT().
833
834 @param Buffer The pointer to the buffer to free.
835
836 **/
837 VOID
838 EFIAPI
839 FreePool (
840 IN VOID *Buffer
841 )
842 {
843 //
844 // PEI phase does not support to free pool, so leave it as NOP.
845 //
846 }
847
848