]> git.proxmox.com Git - mirror_edk2.git/blob - EmulatorPkg/Library/GuardUefiMemoryAllocationLib/MemoryAllocationLib.c
EmulatorPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / EmulatorPkg / Library / GuardUefiMemoryAllocationLib / MemoryAllocationLib.c
1 /** @file
2 Support routines for memory allocation routines based
3 on boot services for Dxe phase drivers using OS malloc.
4
5 OS malloc is used so OS based malloc debugging tools can be used.
6 If a single driver links against this lib protocols from other
7 drivers, or EFI boot services can return a buffer that needs to
8 freed using the EFI scheme. This is why the gEmuThunk->Free ()
9 can detect if the memory rang is for EFI so the right free can be
10 called.
11
12 Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
13 Portions copyright (c) 2011, Apple Inc. All rights reserved.
14 SPDX-License-Identifier: BSD-2-Clause-Patent
15
16 **/
17
18
19 #include <Uefi.h>
20
21
22 #include <Library/MemoryAllocationLib.h>
23 #include <Library/UefiBootServicesTableLib.h>
24 #include <Library/BaseMemoryLib.h>
25 #include <Library/DebugLib.h>
26 #include <Library/EmuThunkLib.h>
27
28 /**
29 Allocates one or more 4KB pages of a certain memory type.
30
31 Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated
32 buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL is returned.
33 If there is not enough memory remaining to satisfy the request, then NULL is returned.
34
35 @param MemoryType The type of memory to allocate.
36 @param Pages The number of 4 KB pages to allocate.
37
38 @return A pointer to the allocated buffer or NULL if allocation fails.
39
40 **/
41 VOID *
42 InternalAllocatePages (
43 IN EFI_MEMORY_TYPE MemoryType,
44 IN UINTN Pages
45 )
46 {
47 EFI_STATUS Status;
48 EFI_PHYSICAL_ADDRESS Memory;
49
50 if (Pages == 0) {
51 return NULL;
52 }
53
54 return gEmuThunk->Valloc (Pages * EFI_PAGE_SIZE);
55 }
56
57 /**
58 Allocates one or more 4KB pages of type EfiBootServicesData.
59
60 Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the
61 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
62 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
63 returned.
64
65 @param Pages The number of 4 KB pages to allocate.
66
67 @return A pointer to the allocated buffer or NULL if allocation fails.
68
69 **/
70 VOID *
71 EFIAPI
72 AllocatePages (
73 IN UINTN Pages
74 )
75 {
76 return InternalAllocatePages (EfiBootServicesData, Pages);
77 }
78
79 /**
80 Allocates one or more 4KB pages of type EfiRuntimeServicesData.
81
82 Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
83 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
84 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
85 returned.
86
87 @param Pages The number of 4 KB pages to allocate.
88
89 @return A pointer to the allocated buffer or NULL if allocation fails.
90
91 **/
92 VOID *
93 EFIAPI
94 AllocateRuntimePages (
95 IN UINTN Pages
96 )
97 {
98 return InternalAllocatePages (EfiRuntimeServicesData, Pages);
99 }
100
101 /**
102 Allocates one or more 4KB pages of type EfiReservedMemoryType.
103
104 Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the
105 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
106 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
107 returned.
108
109 @param Pages The number of 4 KB pages to allocate.
110
111 @return A pointer to the allocated buffer or NULL if allocation fails.
112
113 **/
114 VOID *
115 EFIAPI
116 AllocateReservedPages (
117 IN UINTN Pages
118 )
119 {
120 return InternalAllocatePages (EfiReservedMemoryType, Pages);
121 }
122
123 /**
124 Frees one or more 4KB pages that were previously allocated with one of the page allocation
125 functions in the Memory Allocation Library.
126
127 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
128 must have been allocated on a previous call to the page allocation services of the Memory
129 Allocation Library. If it is not possible to free allocated pages, then this function will
130 perform no actions.
131
132 If Buffer was not allocated with a page allocation function in the Memory Allocation Library,
133 then ASSERT().
134 If Pages is zero, then ASSERT().
135
136 @param Buffer The pointer to the buffer of pages to free.
137 @param Pages The number of 4 KB pages to free.
138
139 **/
140 VOID
141 EFIAPI
142 FreePages (
143 IN VOID *Buffer,
144 IN UINTN Pages
145 )
146 {
147 EFI_STATUS Status;
148
149 ASSERT (Pages != 0);
150 if (!gEmuThunk->Free (Buffer)) {
151 // The Free thunk will not free memory allocated in emulated EFI memory.
152 // The assmuption is this was allocated directly by EFI. We need this as some
153 // times protocols or EFI BootServices can return dynamically allocated buffers.
154 Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
155 ASSERT_EFI_ERROR (Status);
156 }
157 }
158
159 /**
160 Allocates one or more 4KB pages of a certain memory type at a specified alignment.
161
162 Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment
163 specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned.
164 If there is not enough memory at the specified alignment remaining to satisfy the request, then
165 NULL is returned.
166 If Alignment is not a power of two and Alignment is not zero, 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. Must be a power of two.
171 If Alignment is zero, then byte alignment is used.
172
173 @return A pointer to the allocated buffer or NULL if allocation fails.
174
175 **/
176 VOID *
177 InternalAllocateAlignedPages (
178 IN EFI_MEMORY_TYPE MemoryType,
179 IN UINTN Pages,
180 IN UINTN Alignment
181 )
182 {
183 EFI_STATUS Status;
184 VOID *Memory;
185 UINTN AlignedMemory;
186 UINTN AlignmentMask;
187 UINTN UnalignedPages;
188 UINTN RealPages;
189
190 //
191 // Alignment must be a power of two or zero.
192 //
193 ASSERT ((Alignment & (Alignment - 1)) == 0);
194
195 if (Pages == 0) {
196 return NULL;
197 }
198 if (Alignment > EFI_PAGE_SIZE) {
199 //
200 // Caculate the total number of pages since alignment is larger than page size.
201 //
202 AlignmentMask = Alignment - 1;
203 RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment);
204 //
205 // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
206 //
207 ASSERT (RealPages > Pages);
208
209 Memory = gEmuThunk->Valloc (Pages * EFI_PAGE_SIZE);
210 if (Memory != NULL) {
211 return NULL;
212 }
213 AlignedMemory = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask;
214 UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN) Memory);
215 if (UnalignedPages > 0) {
216 //
217 // Free first unaligned page(s).
218 //
219 FreePages (Memory, UnalignedPages);
220 }
221 Memory = (VOID *) (AlignedMemory + EFI_PAGES_TO_SIZE (Pages));
222 UnalignedPages = RealPages - Pages - UnalignedPages;
223 if (UnalignedPages > 0) {
224 //
225 // Free last unaligned page(s).
226 //
227 FreePages (Memory, UnalignedPages);
228 }
229 } else {
230 //
231 // Do not over-allocate pages in this case.
232 //
233 Memory = gEmuThunk->Valloc (Pages * EFI_PAGE_SIZE);
234 if (Memory != NULL) {
235 return NULL;
236 }
237 AlignedMemory = (UINTN) Memory;
238 }
239 return (VOID *) AlignedMemory;
240 }
241
242 /**
243 Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment.
244
245 Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an
246 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
247 returned. If there is not enough memory at the specified alignment remaining to satisfy the
248 request, then NULL is returned.
249
250 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
251
252 @param Pages The number of 4 KB pages to allocate.
253 @param Alignment The requested alignment of the allocation. Must be a power of two.
254 If Alignment is zero, then byte alignment is used.
255
256 @return A pointer to the allocated buffer or NULL if allocation fails.
257
258 **/
259 VOID *
260 EFIAPI
261 AllocateAlignedPages (
262 IN UINTN Pages,
263 IN UINTN Alignment
264 )
265 {
266 return InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment);
267 }
268
269 /**
270 Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
271
272 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an
273 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
274 returned. If there is not enough memory at the specified alignment remaining to satisfy the
275 request, then NULL is returned.
276
277 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
278
279 @param Pages The number of 4 KB pages to allocate.
280 @param Alignment The requested alignment of the allocation. Must be a power of two.
281 If Alignment is zero, then byte alignment is used.
282
283 @return A pointer to the allocated buffer or NULL if allocation fails.
284
285 **/
286 VOID *
287 EFIAPI
288 AllocateAlignedRuntimePages (
289 IN UINTN Pages,
290 IN UINTN Alignment
291 )
292 {
293 return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);
294 }
295
296 /**
297 Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
298
299 Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an
300 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
301 returned. If there is not enough memory at the specified alignment remaining to satisfy the
302 request, then NULL is returned.
303
304 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
305
306 @param Pages The number of 4 KB pages to allocate.
307 @param Alignment The requested alignment of the allocation. Must be a power of two.
308 If Alignment is zero, then byte alignment is used.
309
310 @return A pointer to the allocated buffer or NULL if allocation fails.
311
312 **/
313 VOID *
314 EFIAPI
315 AllocateAlignedReservedPages (
316 IN UINTN Pages,
317 IN UINTN Alignment
318 )
319 {
320 return InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment);
321 }
322
323 /**
324 Frees one or more 4KB pages that were previously allocated with one of the aligned page
325 allocation functions in the Memory Allocation Library.
326
327 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
328 must have been allocated on a previous call to the aligned page allocation services of the Memory
329 Allocation Library. If it is not possible to free allocated pages, then this function will
330 perform no actions.
331
332 If Buffer was not allocated with an aligned page allocation function in the Memory Allocation
333 Library, then ASSERT().
334 If Pages is zero, then ASSERT().
335
336 @param Buffer The pointer to the buffer of pages to free.
337 @param Pages The number of 4 KB pages to free.
338
339 **/
340 VOID
341 EFIAPI
342 FreeAlignedPages (
343 IN VOID *Buffer,
344 IN UINTN Pages
345 )
346 {
347 FreePages (Buffer, Pages);
348 }
349
350 /**
351 Allocates a buffer of a certain pool type.
352
353 Allocates the number bytes specified by AllocationSize of a certain pool type and returns a
354 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
355 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
356
357 @param MemoryType The type of memory to allocate.
358 @param AllocationSize The number of bytes to allocate.
359
360 @return A pointer to the allocated buffer or NULL if allocation fails.
361
362 **/
363 VOID *
364 InternalAllocatePool (
365 IN EFI_MEMORY_TYPE MemoryType,
366 IN UINTN AllocationSize
367 )
368 {
369 return gEmuThunk->Malloc (AllocationSize);
370 }
371
372 /**
373 Allocates a buffer of type EfiBootServicesData.
374
375 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a
376 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
377 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
378
379 @param AllocationSize The number of bytes to allocate.
380
381 @return A pointer to the allocated buffer or NULL if allocation fails.
382
383 **/
384 VOID *
385 EFIAPI
386 AllocatePool (
387 IN UINTN AllocationSize
388 )
389 {
390 return InternalAllocatePool (EfiBootServicesData, AllocationSize);
391 }
392
393 /**
394 Allocates a buffer of type EfiRuntimeServicesData.
395
396 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns
397 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
398 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
399
400 @param AllocationSize The number of bytes to allocate.
401
402 @return A pointer to the allocated buffer or NULL if allocation fails.
403
404 **/
405 VOID *
406 EFIAPI
407 AllocateRuntimePool (
408 IN UINTN AllocationSize
409 )
410 {
411 return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
412 }
413
414 /**
415 Allocates a buffer of type EfiReservedMemoryType.
416
417 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns
418 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
419 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
420
421 @param AllocationSize The number of bytes to allocate.
422
423 @return A pointer to the allocated buffer or NULL if allocation fails.
424
425 **/
426 VOID *
427 EFIAPI
428 AllocateReservedPool (
429 IN UINTN AllocationSize
430 )
431 {
432 return InternalAllocatePool (EfiReservedMemoryType, AllocationSize);
433 }
434
435 /**
436 Allocates and zeros a buffer of a certain pool type.
437
438 Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer
439 with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid
440 buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request,
441 then NULL is returned.
442
443 @param PoolType The type of memory to allocate.
444 @param AllocationSize The number of bytes to allocate and zero.
445
446 @return A pointer to the allocated buffer or NULL if allocation fails.
447
448 **/
449 VOID *
450 InternalAllocateZeroPool (
451 IN EFI_MEMORY_TYPE PoolType,
452 IN UINTN AllocationSize
453 )
454 {
455 VOID *Memory;
456
457 Memory = InternalAllocatePool (PoolType, AllocationSize);
458 if (Memory != NULL) {
459 Memory = ZeroMem (Memory, AllocationSize);
460 }
461 return Memory;
462 }
463
464 /**
465 Allocates and zeros a buffer of type EfiBootServicesData.
466
467 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
468 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
469 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
470 request, then NULL is returned.
471
472 @param AllocationSize The number of bytes to allocate and zero.
473
474 @return A pointer to the allocated buffer or NULL if allocation fails.
475
476 **/
477 VOID *
478 EFIAPI
479 AllocateZeroPool (
480 IN UINTN AllocationSize
481 )
482 {
483 return InternalAllocateZeroPool (EfiBootServicesData, AllocationSize);
484 }
485
486 /**
487 Allocates and zeros a buffer of type EfiRuntimeServicesData.
488
489 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the
490 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
491 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
492 request, then NULL is returned.
493
494 @param AllocationSize The number of bytes to allocate and zero.
495
496 @return A pointer to the allocated buffer or NULL if allocation fails.
497
498 **/
499 VOID *
500 EFIAPI
501 AllocateRuntimeZeroPool (
502 IN UINTN AllocationSize
503 )
504 {
505 return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);
506 }
507
508 /**
509 Allocates and zeros a buffer of type EfiReservedMemoryType.
510
511 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, 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 AllocateReservedZeroPool (
524 IN UINTN AllocationSize
525 )
526 {
527 return InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);
528 }
529
530 /**
531 Copies a buffer to an allocated buffer of a certain pool type.
532
533 Allocates the number bytes specified by AllocationSize of a certain pool type, copies
534 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
535 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
536 is not enough memory remaining to satisfy the request, then NULL is returned.
537 If Buffer is NULL, then ASSERT().
538 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
539
540 @param PoolType The type of pool to allocate.
541 @param AllocationSize The number of bytes to allocate and zero.
542 @param Buffer The buffer to copy to the allocated buffer.
543
544 @return A pointer to the allocated buffer or NULL if allocation fails.
545
546 **/
547 VOID *
548 InternalAllocateCopyPool (
549 IN EFI_MEMORY_TYPE PoolType,
550 IN UINTN AllocationSize,
551 IN CONST VOID *Buffer
552 )
553 {
554 VOID *Memory;
555
556 ASSERT (Buffer != NULL);
557 ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
558
559 Memory = InternalAllocatePool (PoolType, AllocationSize);
560 if (Memory != NULL) {
561 Memory = CopyMem (Memory, Buffer, AllocationSize);
562 }
563 return Memory;
564 }
565
566 /**
567 Copies a buffer to an allocated buffer of type EfiBootServicesData.
568
569 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies
570 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
571 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
572 is not enough memory remaining to satisfy the request, then NULL is returned.
573
574 If Buffer is NULL, then ASSERT().
575 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
576
577 @param AllocationSize The number of bytes to allocate and zero.
578 @param Buffer The buffer to copy to the allocated buffer.
579
580 @return A pointer to the allocated buffer or NULL if allocation fails.
581
582 **/
583 VOID *
584 EFIAPI
585 AllocateCopyPool (
586 IN UINTN AllocationSize,
587 IN CONST VOID *Buffer
588 )
589 {
590 return InternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer);
591 }
592
593 /**
594 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
595
596 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies
597 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
598 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
599 is not enough memory remaining to satisfy the request, then NULL is returned.
600
601 If Buffer is NULL, then ASSERT().
602 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
603
604 @param AllocationSize The number of bytes to allocate and zero.
605 @param Buffer The buffer to copy to the allocated buffer.
606
607 @return A pointer to the allocated buffer or NULL if allocation fails.
608
609 **/
610 VOID *
611 EFIAPI
612 AllocateRuntimeCopyPool (
613 IN UINTN AllocationSize,
614 IN CONST VOID *Buffer
615 )
616 {
617 return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);
618 }
619
620 /**
621 Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
622
623 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies
624 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
625 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
626 is not enough memory remaining to satisfy the request, then NULL is returned.
627
628 If Buffer is NULL, then ASSERT().
629 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
630
631 @param AllocationSize The number of bytes to allocate and zero.
632 @param Buffer The buffer to copy to the allocated buffer.
633
634 @return A pointer to the allocated buffer or NULL if allocation fails.
635
636 **/
637 VOID *
638 EFIAPI
639 AllocateReservedCopyPool (
640 IN UINTN AllocationSize,
641 IN CONST VOID *Buffer
642 )
643 {
644 return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);
645 }
646
647 /**
648 Reallocates a buffer of a specified memory type.
649
650 Allocates and zeros the number bytes specified by NewSize from memory of the type
651 specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and
652 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
653 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
654 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
655 enough memory remaining to satisfy the request, then NULL is returned.
656
657 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
658 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
659
660 @param PoolType The type of pool to allocate.
661 @param OldSize The size, in bytes, of OldBuffer.
662 @param NewSize The size, in bytes, of the buffer to reallocate.
663 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
664 parameter that may be NULL.
665
666 @return A pointer to the allocated buffer or NULL if allocation fails.
667
668 **/
669 VOID *
670 InternalReallocatePool (
671 IN EFI_MEMORY_TYPE PoolType,
672 IN UINTN OldSize,
673 IN UINTN NewSize,
674 IN VOID *OldBuffer OPTIONAL
675 )
676 {
677 VOID *NewBuffer;
678
679 NewBuffer = InternalAllocateZeroPool (PoolType, NewSize);
680 if (NewBuffer != NULL && OldBuffer != NULL) {
681 CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize));
682 FreePool (OldBuffer);
683 }
684 return NewBuffer;
685 }
686
687 /**
688 Reallocates a buffer of type EfiBootServicesData.
689
690 Allocates and zeros the number bytes specified by NewSize from memory of type
691 EfiBootServicesData. 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 OldSize The size, in bytes, of OldBuffer.
701 @param NewSize The size, in bytes, of the buffer to reallocate.
702 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
703 parameter that may be NULL.
704
705 @return A pointer to the allocated buffer or NULL if allocation fails.
706
707 **/
708 VOID *
709 EFIAPI
710 ReallocatePool (
711 IN UINTN OldSize,
712 IN UINTN NewSize,
713 IN VOID *OldBuffer OPTIONAL
714 )
715 {
716 return InternalReallocatePool (EfiBootServicesData, OldSize, NewSize, OldBuffer);
717 }
718
719 /**
720 Reallocates a buffer of type EfiRuntimeServicesData.
721
722 Allocates and zeros the number bytes specified by NewSize from memory of type
723 EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
724 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
725 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
726 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
727 enough memory remaining to satisfy the request, then NULL is returned.
728
729 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
730 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
731
732 @param OldSize The size, in bytes, of OldBuffer.
733 @param NewSize The size, in bytes, of the buffer to reallocate.
734 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
735 parameter that may be NULL.
736
737 @return A pointer to the allocated buffer or NULL if allocation fails.
738
739 **/
740 VOID *
741 EFIAPI
742 ReallocateRuntimePool (
743 IN UINTN OldSize,
744 IN UINTN NewSize,
745 IN VOID *OldBuffer OPTIONAL
746 )
747 {
748 return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer);
749 }
750
751 /**
752 Reallocates a buffer of type EfiReservedMemoryType.
753
754 Allocates and zeros the number bytes specified by NewSize from memory of type
755 EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and
756 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
757 OldBuffer is freed. A pointer to the newly allocated buffer is returned.
758 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
759 enough memory remaining to satisfy the request, then NULL is returned.
760
761 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
762 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
763
764 @param OldSize The size, in bytes, of OldBuffer.
765 @param NewSize The size, in bytes, of the buffer to reallocate.
766 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
767 parameter that may be NULL.
768
769 @return A pointer to the allocated buffer or NULL if allocation fails.
770
771 **/
772 VOID *
773 EFIAPI
774 ReallocateReservedPool (
775 IN UINTN OldSize,
776 IN UINTN NewSize,
777 IN VOID *OldBuffer OPTIONAL
778 )
779 {
780 return InternalReallocatePool (EfiReservedMemoryType, OldSize, NewSize, OldBuffer);
781 }
782
783 /**
784 Frees a buffer that was previously allocated with one of the pool allocation functions in the
785 Memory Allocation Library.
786
787 Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the
788 pool allocation services of the Memory Allocation Library. If it is not possible to free pool
789 resources, then this function will perform no actions.
790
791 If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
792 then ASSERT().
793
794 @param Buffer The pointer to the buffer to free.
795
796 **/
797 VOID
798 EFIAPI
799 FreePool (
800 IN VOID *Buffer
801 )
802 {
803 EFI_STATUS Status;
804
805 if (!gEmuThunk->Free (Buffer)) {
806 // The Free thunk will not free memory allocated in emulated EFI memory.
807 // The assmuption is this was allocated directly by EFI. We need this as some
808 // times protocols or EFI BootServices can return dynamically allocated buffers.
809 Status = gBS->FreePool (Buffer);
810 ASSERT_EFI_ERROR (Status);
811 }
812 }
813