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