]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/PeiMemoryAllocationLib/MemoryAllocationLib.c
Update MemoryAllocationLib.AllocateAlignedPages API comments for memory overflow...
[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 - 2013, 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 EFI_MEMORY_TYPE RequestType;
49 EFI_PEI_HOB_POINTERS Hob;
50
51 if (Pages == 0) {
52 return NULL;
53 }
54
55 RequestType = MemoryType;
56 if (MemoryType == EfiReservedMemoryType) {
57 //
58 // PEI AllocatePages() doesn't support EfiReservedMemoryType.
59 // Change RequestType to EfiBootServicesData for memory allocation.
60 //
61 RequestType = EfiBootServicesData;
62 }
63
64 Status = PeiServicesAllocatePages (RequestType, Pages, &Memory);
65 if (EFI_ERROR (Status)) {
66 return NULL;
67 }
68
69 if (MemoryType == EfiReservedMemoryType) {
70 //
71 // Memory type needs to be updated to EfiReservedMemoryType. Per PI spec Volume 1,
72 // PEI AllocatePages() will automate the creation of the Memory Allocation HOB types.
73 // Search Memory Allocation HOB and find the matched memory region,
74 // then change its memory type to EfiReservedMemoryType.
75 //
76 Hob.Raw = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION);
77 while (Hob.Raw != NULL && Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress != Memory) {
78 Hob.Raw = GET_NEXT_HOB (Hob);
79 Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw);
80 }
81 ASSERT (Hob.Raw != NULL);
82 Hob.MemoryAllocation->AllocDescriptor.MemoryType = EfiReservedMemoryType;
83 }
84
85 return (VOID *) (UINTN) Memory;
86 }
87
88 /**
89 Allocates one or more 4KB pages of type EfiBootServicesData.
90
91 Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the
92 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
93 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
94 returned.
95
96 @param Pages The number of 4 KB pages to allocate.
97
98 @return A pointer to the allocated buffer or NULL if allocation fails.
99
100 **/
101 VOID *
102 EFIAPI
103 AllocatePages (
104 IN UINTN Pages
105 )
106 {
107 return InternalAllocatePages (EfiBootServicesData, Pages);
108 }
109
110 /**
111 Allocates one or more 4KB pages of type EfiRuntimeServicesData.
112
113 Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
114 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
115 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
116 returned.
117
118 @param Pages The number of 4 KB pages to allocate.
119
120 @return A pointer to the allocated buffer or NULL if allocation fails.
121
122 **/
123 VOID *
124 EFIAPI
125 AllocateRuntimePages (
126 IN UINTN Pages
127 )
128 {
129 return InternalAllocatePages (EfiRuntimeServicesData, Pages);
130 }
131
132 /**
133 Allocates one or more 4KB pages of type EfiReservedMemoryType.
134
135 Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the
136 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
137 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
138 returned.
139
140 @param Pages The number of 4 KB pages to allocate.
141
142 @return A pointer to the allocated buffer or NULL if allocation fails.
143
144 **/
145 VOID *
146 EFIAPI
147 AllocateReservedPages (
148 IN UINTN Pages
149 )
150 {
151 return InternalAllocatePages (EfiReservedMemoryType, Pages);
152 }
153
154 /**
155 Frees one or more 4KB pages that were previously allocated with one of the page allocation
156 functions in the Memory Allocation Library.
157
158 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
159 must have been allocated on a previous call to the page allocation services of the Memory
160 Allocation Library. If it is not possible to free allocated pages, then this function will
161 perform no actions.
162
163 If Buffer was not allocated with a page allocation function in the Memory Allocation Library,
164 then ASSERT().
165 If Pages is zero, then ASSERT().
166
167 @param Buffer The pointer to the buffer of pages to free.
168 @param Pages The number of 4 KB pages to free.
169
170 **/
171 VOID
172 EFIAPI
173 FreePages (
174 IN VOID *Buffer,
175 IN UINTN Pages
176 )
177 {
178 ASSERT (Pages != 0);
179 //
180 // PEI phase does not support to free pages, so leave it as NOP.
181 //
182 }
183
184 /**
185 Allocates one or more 4KB pages of a certain memory type at a specified alignment.
186
187 Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment
188 specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned.
189 If there is not enough memory at the specified alignment remaining to satisfy the request, then
190 NULL is returned.
191 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
192 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
193
194 @param MemoryType The type of memory to allocate.
195 @param Pages The number of 4 KB pages to allocate.
196 @param Alignment The requested alignment of the allocation.
197 Must be a power of two.
198 If Alignment is zero, then byte alignment is used.
199
200 @return A pointer to the allocated buffer or NULL if allocation fails.
201
202 **/
203 VOID *
204 InternalAllocateAlignedPages (
205 IN EFI_MEMORY_TYPE MemoryType,
206 IN UINTN Pages,
207 IN UINTN Alignment
208 )
209 {
210 VOID *Memory;
211 UINTN AlignmentMask;
212
213 //
214 // Alignment must be a power of two or zero.
215 //
216 ASSERT ((Alignment & (Alignment - 1)) == 0);
217
218 if (Pages == 0) {
219 return NULL;
220 }
221 //
222 // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
223 //
224 ASSERT (Pages <= (MAX_ADDRESS - EFI_SIZE_TO_PAGES (Alignment)));
225 //
226 // We would rather waste some memory to save PEI code size.
227 //
228 Memory = InternalAllocatePages (MemoryType, Pages + EFI_SIZE_TO_PAGES (Alignment));
229 if (Alignment == 0) {
230 AlignmentMask = Alignment;
231 } else {
232 AlignmentMask = Alignment - 1;
233 }
234 return (VOID *) (UINTN) (((UINTN) Memory + AlignmentMask) & ~AlignmentMask);
235 }
236
237 /**
238 Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment.
239
240 Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an
241 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
242 returned. If there is not enough memory at the specified alignment remaining to satisfy the
243 request, then NULL is returned.
244
245 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
246 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
247
248 @param Pages The number of 4 KB pages to allocate.
249 @param Alignment The requested alignment of the allocation.
250 Must be a power of two.
251 If Alignment is zero, then byte alignment is used.
252
253 @return A pointer to the allocated buffer or NULL if allocation fails.
254
255 **/
256 VOID *
257 EFIAPI
258 AllocateAlignedPages (
259 IN UINTN Pages,
260 IN UINTN Alignment
261 )
262 {
263 return InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment);
264 }
265
266 /**
267 Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
268
269 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an
270 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
271 returned. If there is not enough memory at the specified alignment remaining to satisfy the
272 request, then NULL is returned.
273
274 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
275 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
276
277 @param Pages The number of 4 KB pages to allocate.
278 @param Alignment The requested alignment of the allocation.
279 Must be a power of two.
280 If Alignment is zero, then byte alignment is used.
281
282 @return A pointer to the allocated buffer or NULL if allocation fails.
283
284 **/
285 VOID *
286 EFIAPI
287 AllocateAlignedRuntimePages (
288 IN UINTN Pages,
289 IN UINTN Alignment
290 )
291 {
292 return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);
293 }
294
295 /**
296 Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
297
298 Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an
299 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
300 returned. If there is not enough memory at the specified alignment remaining to satisfy the
301 request, then NULL is returned.
302
303 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
304 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
305
306 @param Pages The number of 4 KB pages to allocate.
307 @param Alignment The requested alignment of the allocation.
308 Must be a power of two.
309 If Alignment is zero, then byte alignment is used.
310
311 @return A pointer to the allocated buffer or NULL if allocation fails.
312
313 **/
314 VOID *
315 EFIAPI
316 AllocateAlignedReservedPages (
317 IN UINTN Pages,
318 IN UINTN Alignment
319 )
320 {
321 return InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment);
322 }
323
324 /**
325 Frees one or more 4KB pages that were previously allocated with one of the aligned page
326 allocation functions in the Memory Allocation Library.
327
328 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
329 must have been allocated on a previous call to the aligned page allocation services of the Memory
330 Allocation Library. If it is not possible to free allocated pages, then this function will
331 perform no actions.
332
333 If Buffer was not allocated with an aligned page allocation function in the Memory Allocation
334 Library, then ASSERT().
335 If Pages is zero, then ASSERT().
336
337 @param Buffer The pointer to the buffer of pages to free.
338 @param Pages The number of 4 KB pages to free.
339
340 **/
341 VOID
342 EFIAPI
343 FreeAlignedPages (
344 IN VOID *Buffer,
345 IN UINTN Pages
346 )
347 {
348 ASSERT (Pages != 0);
349 //
350 // PEI phase does not support to free pages, so leave it as NOP.
351 //
352 }
353
354 /**
355 Allocates a buffer of a certain pool type.
356
357 Allocates the number bytes specified by AllocationSize of a certain pool type and returns a
358 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
359 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
360
361 @param MemoryType The type of memory to allocate.
362 @param AllocationSize The number of bytes to allocate.
363
364 @return A pointer to the allocated buffer or NULL if allocation fails.
365
366 **/
367 VOID *
368 InternalAllocatePool (
369 IN EFI_MEMORY_TYPE MemoryType,
370 IN UINTN AllocationSize
371 )
372 {
373 //
374 // If we need lots of small runtime/reserved memory type from PEI in the future,
375 // we can consider providing a more complex algorithm that allocates runtime pages and
376 // provide pool allocations from those pages.
377 //
378 return InternalAllocatePages (MemoryType, EFI_SIZE_TO_PAGES (AllocationSize));
379 }
380
381 /**
382 Allocates a buffer of type EfiBootServicesData.
383
384 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a
385 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
386 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
387
388 @param AllocationSize The number of bytes to allocate.
389
390 @return A pointer to the allocated buffer or NULL if allocation fails.
391
392 **/
393 VOID *
394 EFIAPI
395 AllocatePool (
396 IN UINTN AllocationSize
397 )
398 {
399 EFI_STATUS Status;
400 VOID *Buffer;
401
402 Status = PeiServicesAllocatePool (AllocationSize, &Buffer);
403 if (EFI_ERROR (Status)) {
404 Buffer = NULL;
405 }
406 return Buffer;
407 }
408
409 /**
410 Allocates a buffer of type EfiRuntimeServicesData.
411
412 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns
413 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
414 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
415
416 @param AllocationSize The number of bytes to allocate.
417
418 @return A pointer to the allocated buffer or NULL if allocation fails.
419
420 **/
421 VOID *
422 EFIAPI
423 AllocateRuntimePool (
424 IN UINTN AllocationSize
425 )
426 {
427 return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
428 }
429
430 /**
431 Allocates a buffer of type EfiReservedMemoryType.
432
433 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns
434 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
435 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
436
437 @param AllocationSize The number of bytes to allocate.
438
439 @return A pointer to the allocated buffer or NULL if allocation fails.
440
441 **/
442 VOID *
443 EFIAPI
444 AllocateReservedPool (
445 IN UINTN AllocationSize
446 )
447 {
448 return InternalAllocatePool (EfiReservedMemoryType, AllocationSize);
449 }
450
451 /**
452 Allocates and zeros a buffer of a certain pool type.
453
454 Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer
455 with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid
456 buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request,
457 then NULL is returned.
458
459 @param PoolType The type of memory to allocate.
460 @param AllocationSize The number of bytes to allocate and zero.
461
462 @return A pointer to the allocated buffer or NULL if allocation fails.
463
464 **/
465 VOID *
466 InternalAllocateZeroPool (
467 IN EFI_MEMORY_TYPE PoolType,
468 IN UINTN AllocationSize
469 )
470 {
471 VOID *Memory;
472
473 Memory = InternalAllocatePool (PoolType, AllocationSize);
474 if (Memory != NULL) {
475 Memory = ZeroMem (Memory, AllocationSize);
476 }
477 return Memory;
478 }
479
480 /**
481 Allocates and zeros a buffer of type EfiBootServicesData.
482
483 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
484 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
485 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
486 request, then NULL is returned.
487
488 @param AllocationSize The number of bytes to allocate and zero.
489
490 @return A pointer to the allocated buffer or NULL if allocation fails.
491
492 **/
493 VOID *
494 EFIAPI
495 AllocateZeroPool (
496 IN UINTN AllocationSize
497 )
498 {
499 VOID *Memory;
500
501 Memory = AllocatePool (AllocationSize);
502 if (Memory != NULL) {
503 Memory = ZeroMem (Memory, AllocationSize);
504 }
505 return Memory;
506 }
507
508 /**
509 Allocates and zeros a buffer of type EfiRuntimeServicesData.
510
511 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the
512 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
513 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
514 request, then NULL is returned.
515
516 @param AllocationSize The number of bytes to allocate and zero.
517
518 @return A pointer to the allocated buffer or NULL if allocation fails.
519
520 **/
521 VOID *
522 EFIAPI
523 AllocateRuntimeZeroPool (
524 IN UINTN AllocationSize
525 )
526 {
527 return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);
528 }
529
530 /**
531 Allocates and zeros a buffer of type EfiReservedMemoryType.
532
533 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the
534 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
535 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
536 request, then NULL is returned.
537
538 @param AllocationSize The number of bytes to allocate and zero.
539
540 @return A pointer to the allocated buffer or NULL if allocation fails.
541
542 **/
543 VOID *
544 EFIAPI
545 AllocateReservedZeroPool (
546 IN UINTN AllocationSize
547 )
548 {
549 return InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);
550 }
551
552 /**
553 Copies a buffer to an allocated buffer of a certain pool type.
554
555 Allocates the number bytes specified by AllocationSize of a certain pool type, copies
556 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
557 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
558 is not enough memory remaining to satisfy the request, then NULL is returned.
559 If Buffer is NULL, then ASSERT().
560 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
561
562 @param PoolType The type of pool to allocate.
563 @param AllocationSize The number of bytes to allocate and zero.
564 @param Buffer The buffer to copy to the allocated buffer.
565
566 @return A pointer to the allocated buffer or NULL if allocation fails.
567
568 **/
569 VOID *
570 InternalAllocateCopyPool (
571 IN EFI_MEMORY_TYPE PoolType,
572 IN UINTN AllocationSize,
573 IN CONST VOID *Buffer
574 )
575 {
576 VOID *Memory;
577
578 ASSERT (Buffer != NULL);
579 ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
580
581 Memory = InternalAllocatePool (PoolType, AllocationSize);
582 if (Memory != NULL) {
583 Memory = CopyMem (Memory, Buffer, AllocationSize);
584 }
585 return Memory;
586 }
587
588 /**
589 Copies a buffer to an allocated buffer of type EfiBootServicesData.
590
591 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies
592 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
593 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
594 is not enough memory remaining to satisfy the request, then NULL is returned.
595
596 If Buffer is NULL, then ASSERT().
597 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
598
599 @param AllocationSize The number of bytes to allocate and zero.
600 @param Buffer The buffer to copy to the allocated buffer.
601
602 @return A pointer to the allocated buffer or NULL if allocation fails.
603
604 **/
605 VOID *
606 EFIAPI
607 AllocateCopyPool (
608 IN UINTN AllocationSize,
609 IN CONST VOID *Buffer
610 )
611 {
612 VOID *Memory;
613
614 ASSERT (Buffer != NULL);
615 ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
616
617 Memory = AllocatePool (AllocationSize);
618 if (Memory != NULL) {
619 Memory = CopyMem (Memory, Buffer, AllocationSize);
620 }
621 return Memory;
622 }
623
624 /**
625 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
626
627 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies
628 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
629 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
630 is not enough memory remaining to satisfy the request, then NULL is returned.
631
632 If Buffer is NULL, then ASSERT().
633 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
634
635 @param AllocationSize The number of bytes to allocate and zero.
636 @param Buffer The buffer to copy to the allocated buffer.
637
638 @return A pointer to the allocated buffer or NULL if allocation fails.
639
640 **/
641 VOID *
642 EFIAPI
643 AllocateRuntimeCopyPool (
644 IN UINTN AllocationSize,
645 IN CONST VOID *Buffer
646 )
647 {
648 return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);
649 }
650
651 /**
652 Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
653
654 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies
655 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
656 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
657 is not enough memory remaining to satisfy the request, then NULL is returned.
658
659 If Buffer is NULL, then ASSERT().
660 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
661
662 @param AllocationSize The number of bytes to allocate and zero.
663 @param Buffer The buffer to copy to the allocated buffer.
664
665 @return A pointer to the allocated buffer or NULL if allocation fails.
666
667 **/
668 VOID *
669 EFIAPI
670 AllocateReservedCopyPool (
671 IN UINTN AllocationSize,
672 IN CONST VOID *Buffer
673 )
674 {
675 return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);
676 }
677
678 /**
679 Reallocates a buffer of a specified memory type.
680
681 Allocates and zeros the number bytes specified by NewSize from memory of the type
682 specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and
683 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
684 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
685 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
686 enough memory remaining to satisfy the request, then NULL is returned.
687
688 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
689 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
690
691 @param PoolType The type of pool to allocate.
692 @param OldSize The size, in bytes, of OldBuffer.
693 @param NewSize The size, in bytes, of the buffer to reallocate.
694 @param OldBuffer The buffer to copy to the allocated buffer. This is an
695 optional parameter that may be NULL.
696
697 @return A pointer to the allocated buffer or NULL if allocation fails.
698
699 **/
700 VOID *
701 InternalReallocatePool (
702 IN EFI_MEMORY_TYPE PoolType,
703 IN UINTN OldSize,
704 IN UINTN NewSize,
705 IN VOID *OldBuffer OPTIONAL
706 )
707 {
708 VOID *NewBuffer;
709
710 NewBuffer = InternalAllocateZeroPool (PoolType, NewSize);
711 if (NewBuffer != NULL && OldBuffer != NULL) {
712 CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize));
713 FreePool (OldBuffer);
714 }
715 return NewBuffer;
716 }
717
718 /**
719 Reallocates a buffer of type EfiBootServicesData.
720
721 Allocates and zeros the number bytes specified by NewSize from memory of type
722 EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
723 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
724 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
725 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
726 enough memory remaining to satisfy the request, then NULL is returned.
727
728 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
729 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
730
731 @param OldSize The size, in bytes, of OldBuffer.
732 @param NewSize The size, in bytes, of the buffer to reallocate.
733 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
734 parameter that may be NULL.
735
736 @return A pointer to the allocated buffer or NULL if allocation fails.
737
738 **/
739 VOID *
740 EFIAPI
741 ReallocatePool (
742 IN UINTN OldSize,
743 IN UINTN NewSize,
744 IN VOID *OldBuffer OPTIONAL
745 )
746 {
747 return InternalReallocatePool (EfiBootServicesData, OldSize, NewSize, OldBuffer);
748 }
749
750 /**
751 Reallocates a buffer of type EfiRuntimeServicesData.
752
753 Allocates and zeros the number bytes specified by NewSize from memory of type
754 EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
755 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
756 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
757 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
758 enough memory remaining to satisfy the request, then NULL is returned.
759
760 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
761 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
762
763 @param OldSize The size, in bytes, of OldBuffer.
764 @param NewSize The size, in bytes, of the buffer to reallocate.
765 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
766 parameter that may be NULL.
767
768 @return A pointer to the allocated buffer or NULL if allocation fails.
769
770 **/
771 VOID *
772 EFIAPI
773 ReallocateRuntimePool (
774 IN UINTN OldSize,
775 IN UINTN NewSize,
776 IN VOID *OldBuffer OPTIONAL
777 )
778 {
779 return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer);
780 }
781
782 /**
783 Reallocates a buffer of type EfiReservedMemoryType.
784
785 Allocates and zeros the number bytes specified by NewSize from memory of type
786 EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and
787 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
788 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
789 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
790 enough memory remaining to satisfy the request, then NULL is returned.
791
792 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
793 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
794
795 @param OldSize The size, in bytes, of OldBuffer.
796 @param NewSize The size, in bytes, of the buffer to reallocate.
797 @param OldBuffer The buffer to copy to the allocated buffer. This is an
798 optional parameter that may be NULL.
799
800 @return A pointer to the allocated buffer or NULL if allocation fails.
801
802 **/
803 VOID *
804 EFIAPI
805 ReallocateReservedPool (
806 IN UINTN OldSize,
807 IN UINTN NewSize,
808 IN VOID *OldBuffer OPTIONAL
809 )
810 {
811 return InternalReallocatePool (EfiReservedMemoryType, OldSize, NewSize, OldBuffer);
812 }
813
814 /**
815 Frees a buffer that was previously allocated with one of the pool allocation functions in the
816 Memory Allocation Library.
817
818 Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the
819 pool allocation services of the Memory Allocation Library. If it is not possible to free pool
820 resources, then this function will perform no actions.
821
822 If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
823 then ASSERT().
824
825 @param Buffer The pointer to the buffer to free.
826
827 **/
828 VOID
829 EFIAPI
830 FreePool (
831 IN VOID *Buffer
832 )
833 {
834 //
835 // PEI phase does not support to free pool, so leave it as NOP.
836 //
837 }
838
839