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