MemoryAllocationLib: For boundary case: “AllocationSize + OverAllocationSize >= 4G”
[mirror_edk2.git] / MdePkg / Library / DxeMemoryAllocationLib / MemoryAllocationLib.c
1 /** @file
2 Support routines for memory allocation routines for use with drivers.
3
4 Copyright (c) 2006, Intel Corporation<BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 Module Name: MemoryAllocationLib.c
14
15 **/
16
17
18
19 /**
20 Allocates the number of 4KB pages specified by Pages of a certain memory type.
21
22 @param MemoryType The type of memory to allocate.
23 @param Pages The number of 4 KB pages to allocate.
24
25 @return A pointer to the allocated buffer. The buffer returned is aligned on a 4KB boundary.<BR>
26 If Pages is 0, then NULL is returned.<BR>
27 If there is not enough memory remaining to satisfy the request, then NULL is returned.
28
29 **/
30 VOID *
31 InternalAllocatePages (
32 IN EFI_MEMORY_TYPE MemoryType,
33 IN UINTN Pages
34 )
35 {
36 EFI_STATUS Status;
37 EFI_PHYSICAL_ADDRESS Memory;
38
39 if (Pages == 0) {
40 return NULL;
41 }
42
43 Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);
44 if (EFI_ERROR (Status)) {
45 Memory = 0;
46 }
47 return (VOID *) (UINTN) Memory;
48 }
49
50 /**
51 Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData.
52
53 @param Pages The number of 4 KB pages to allocate.
54
55 @return A pointer to the allocated buffer. The buffer returned is aligned on a 4KB boundary.<BR>
56 If Pages is 0, then NULL is returned.<BR>
57 If there is not enough memory remaining to satisfy the request, then NULL is returned.
58
59 **/
60 VOID *
61 EFIAPI
62 AllocatePages (
63 IN UINTN Pages
64 )
65 {
66 return InternalAllocatePages (EfiBootServicesData, Pages);
67 }
68
69 /**
70 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData.
71
72 @param Pages The number of 4 KB pages to allocate.
73
74 @return A pointer to the allocated buffer. The buffer returned is aligned on a 4KB boundary.<BR>
75 If Pages is 0, then NULL is returned.<BR>
76 If there is not enough memory remaining to satisfy the request, then NULL is returned.
77
78 **/
79 VOID *
80 EFIAPI
81 AllocateRuntimePages (
82 IN UINTN Pages
83 )
84 {
85 return InternalAllocatePages (EfiRuntimeServicesData, Pages);
86 }
87
88 /**
89 Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType.
90
91 @param Pages The number of 4 KB pages to allocate.
92
93 @return A pointer to the allocated buffer. The buffer returned is aligned on a 4KB boundary.<BR>
94 If Pages is 0, then NULL is returned.<BR>
95 If there is not enough memory remaining to satisfy the request, then NULL is returned.
96
97 **/
98 VOID *
99 EFIAPI
100 AllocateReservedPages (
101 IN UINTN Pages
102 )
103 {
104 return InternalAllocatePages (EfiReservedMemoryType, Pages);
105 }
106
107 /**
108 Frees one or more 4KB pages that were previously allocated with
109 one of the page allocation functions in the Memory Allocation Library.
110
111 @param Buffer Pointer to the buffer of pages to free.
112 @param Pages The number of 4 KB pages to free.
113
114 **/
115 VOID
116 EFIAPI
117 FreePages (
118 IN VOID *Buffer,
119 IN UINTN Pages
120 )
121 {
122 EFI_STATUS Status;
123
124 ASSERT (Pages != 0);
125 Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
126 ASSERT_EFI_ERROR (Status);
127 }
128
129 /**
130 Allocates the number of 4KB pages specified by Pages of a certian memory type
131 with an alignment specified by Alignment.
132
133 @param MemoryType The type of memory to allocate.
134 @param Pages The number of 4 KB pages to allocate.
135 @param Alignment The requested alignment of the allocation. Must be a power of two.
136 If Alignment is zero, then byte alignment is used.
137
138 @return The allocated buffer is returned.<BR>
139 If Pages is 0, then NULL is returned.<BR>
140 If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.
141
142 **/
143 VOID *
144 InternalAllocateAlignedPages (
145 IN EFI_MEMORY_TYPE MemoryType,
146 IN UINTN Pages,
147 IN UINTN Alignment
148 )
149 {
150 EFI_STATUS Status;
151 EFI_PHYSICAL_ADDRESS Memory;
152 UINTN AlignedMemory;
153 UINTN AlignmentMask;
154 UINTN UnalignedPages;
155 UINTN RealPages;
156
157 //
158 // Alignment must be a power of two or zero.
159 //
160 ASSERT ((Alignment & (Alignment - 1)) == 0);
161
162 if (Pages == 0) {
163 return NULL;
164 }
165 if (Alignment > EFI_PAGE_SIZE) {
166 //
167 // Caculate the total number of pages since alignment is larger than page size.
168 //
169 AlignmentMask = Alignment - 1;
170 RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment);
171 //
172 // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
173 //
174 ASSERT (RealPages > Pages);
175
176 Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory);
177 if (EFI_ERROR (Status)) {
178 return NULL;
179 }
180 AlignedMemory = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask;
181 UnalignedPages = EFI_SIZE_TO_PAGES ((UINTN) Memory - AlignedMemory);
182 if (UnalignedPages > 0) {
183 //
184 // Free first unaligned page(s).
185 //
186 Status = gBS->FreePages (Memory, UnalignedPages);
187 ASSERT_EFI_ERROR (Status);
188 }
189 Memory = (EFI_PHYSICAL_ADDRESS) (AlignedMemory + EFI_PAGES_TO_SIZE (Pages));
190 UnalignedPages = RealPages - Pages - UnalignedPages;
191 if (UnalignedPages > 0) {
192 //
193 // Free last unaligned page(s).
194 //
195 Status = gBS->FreePages (Memory, UnalignedPages);
196 ASSERT_EFI_ERROR (Status);
197 }
198 } else {
199 //
200 // Do not over-allocate pages in this case.
201 //
202 Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);
203 if (EFI_ERROR (Status)) {
204 return NULL;
205 }
206 AlignedMemory = (UINTN) Memory;
207 }
208 return (VOID *) AlignedMemory;
209 }
210
211 /**
212 Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData
213 with an alignment specified by Alignment.
214
215 @param Pages The number of 4 KB pages to allocate.
216 @param Alignment The requested alignment of the allocation. Must be a power of two.
217 If Alignment is zero, then byte alignment is used.
218
219 @return The allocated buffer is returned.<BR>
220 If Pages is 0, then NULL is returned.<BR>
221 If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.
222
223 **/
224 VOID *
225 EFIAPI
226 AllocateAlignedPages (
227 IN UINTN Pages,
228 IN UINTN Alignment
229 )
230 {
231 return InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment);
232 }
233
234 /**
235 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData
236 with an alignment specified by Alignment.
237
238 @param Pages The number of 4 KB pages to allocate.
239 @param Alignment The requested alignment of the allocation. Must be a power of two.
240 If Alignment is zero, then byte alignment is used.
241
242 @return The allocated buffer is returned. If Pages is 0, then NULL is returned.
243 If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.
244
245 **/
246 VOID *
247 EFIAPI
248 AllocateAlignedRuntimePages (
249 IN UINTN Pages,
250 IN UINTN Alignment
251 )
252 {
253 return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);
254 }
255
256 /**
257 Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
258
259 @param Pages The number of 4 KB pages to allocate.
260 @param Alignment The requested alignment of the allocation. Must be a power of two.
261 If Alignment is zero, then byte alignment is used.
262
263 @return The allocated buffer is returned. If Pages is 0, then NULL is returned.
264 If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.
265
266 **/
267 VOID *
268 EFIAPI
269 AllocateAlignedReservedPages (
270 IN UINTN Pages,
271 IN UINTN Alignment
272 )
273 {
274 return InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment);
275 }
276
277 /**
278 Frees one or more 4KB pages that were previously allocated with
279 one of the aligned page allocation functions in the Memory Allocation Library.
280
281 @param Buffer Pointer to the buffer of pages to free.
282 @param Pages The number of 4 KB pages to free.
283
284 **/
285 VOID
286 EFIAPI
287 FreeAlignedPages (
288 IN VOID *Buffer,
289 IN UINTN Pages
290 )
291 {
292 EFI_STATUS Status;
293
294 ASSERT (Pages != 0);
295 Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
296 ASSERT_EFI_ERROR (Status);
297 }
298
299 /**
300 Allocates a buffer of a certain memory type.
301
302 @param MemoryType The type of memory to allocate.
303 @param AllocationSize The number of bytes to allocate.
304
305 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
306 If there is not enough memory remaining to satisfy the request, then NULL is returned.
307
308 **/
309 VOID *
310 InternalAllocatePool (
311 IN EFI_MEMORY_TYPE MemoryType,
312 IN UINTN AllocationSize
313 )
314 {
315 EFI_STATUS Status;
316 VOID *Memory;
317
318 Status = gBS->AllocatePool (MemoryType, AllocationSize, &Memory);
319 if (EFI_ERROR (Status)) {
320 Memory = NULL;
321 }
322 return Memory;
323 }
324
325 /**
326 Allocates a buffer of type EfiBootServicesData.
327
328 @param AllocationSize The number of bytes to allocate.
329
330 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
331 If there is not enough memory remaining to satisfy the request, then NULL is returned.
332
333 **/
334 VOID *
335 EFIAPI
336 AllocatePool (
337 IN UINTN AllocationSize
338 )
339 {
340 return InternalAllocatePool (EfiBootServicesData, AllocationSize);
341 }
342
343 /**
344 Allocates a buffer of type EfiRuntimeServicesData.
345
346 @param AllocationSize The number of bytes to allocate.
347
348 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
349 If there is not enough memory remaining to satisfy the request, then NULL is returned.
350
351 **/
352 VOID *
353 EFIAPI
354 AllocateRuntimePool (
355 IN UINTN AllocationSize
356 )
357 {
358 return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
359 }
360
361 /**
362 Allocates a buffer of type EfiReservedMemoryType.
363
364 @param AllocationSize The number of bytes to allocate.
365
366 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
367 If there is not enough memory remaining to satisfy the request, then NULL is returned.
368
369 **/
370 VOID *
371 EFIAPI
372 AllocateReservedPool (
373 IN UINTN AllocationSize
374 )
375 {
376 return InternalAllocatePool (EfiReservedMemoryType, AllocationSize);
377 }
378
379 /**
380 Allocates and zeros a buffer of a certian pool type.
381
382 @param PoolType The type of memory to allocate.
383 @param AllocationSize The number of bytes to allocate and zero.
384
385 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
386 If there is not enough memory remaining to satisfy the request, then NULL is returned.
387
388 **/
389 VOID *
390 InternalAllocateZeroPool (
391 IN EFI_MEMORY_TYPE PoolType,
392 IN UINTN AllocationSize
393 )
394 {
395 VOID *Memory;
396 Memory = InternalAllocatePool (PoolType, AllocationSize);
397 if (Memory != NULL) {
398 Memory = ZeroMem (Memory, AllocationSize);
399 }
400 return Memory;
401 }
402
403 /**
404 Allocates and zeros a buffer of type EfiBootServicesData.
405
406 @param AllocationSize The number of bytes to allocate and zero.
407
408 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
409 If there is not enough memory remaining to satisfy the request, then NULL is returned.
410
411 **/
412 VOID *
413 EFIAPI
414 AllocateZeroPool (
415 IN UINTN AllocationSize
416 )
417 {
418 return InternalAllocateZeroPool (EfiBootServicesData, AllocationSize);
419 }
420
421 /**
422 Allocates and zeros a buffer of type EfiRuntimeServicesData.
423
424 @param AllocationSize The number of bytes to allocate and zero.
425
426 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
427 If there is not enough memory remaining to satisfy the request, then NULL is returned.
428
429 **/
430 VOID *
431 EFIAPI
432 AllocateRuntimeZeroPool (
433 IN UINTN AllocationSize
434 )
435 {
436 return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);
437 }
438
439 /**
440 Allocates and zeros a buffer of type EfiReservedMemoryType.
441
442 @param AllocationSize The number of bytes to allocate and zero.
443
444 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
445 If there is not enough memory remaining to satisfy the request, then NULL is returned.
446
447 **/
448 VOID *
449 EFIAPI
450 AllocateReservedZeroPool (
451 IN UINTN AllocationSize
452 )
453 {
454 return InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);
455 }
456
457 /**
458 Copies a buffer to an allocated buffer of a certian memory type.
459
460 @param MemoryType The type of pool to allocate.
461 @param AllocationSize The number of bytes to allocate and zero.
462 @param Buffer The buffer to copy to the allocated buffer.
463
464 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
465 If there is not enough memory remaining to satisfy the request, then NULL is returned.
466
467 **/
468 VOID *
469 InternalAllocateCopyPool (
470 IN EFI_MEMORY_TYPE PoolType,
471 IN UINTN AllocationSize,
472 IN CONST VOID *Buffer
473 )
474 {
475 VOID *Memory;
476
477 Memory = InternalAllocatePool (PoolType, AllocationSize);
478 if (Memory != NULL) {
479 Memory = CopyMem (Memory, Buffer, AllocationSize);
480 }
481 return Memory;
482 }
483
484 /**
485 Copies a buffer to an allocated buffer of type EfiBootServicesData.
486
487 @param AllocationSize The number of bytes to allocate.
488 @param Buffer The buffer to copy to the allocated buffer.
489
490 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
491 If there is not enough memory remaining to satisfy the request, then NULL is returned.
492
493 **/
494 VOID *
495 EFIAPI
496 AllocateCopyPool (
497 IN UINTN AllocationSize,
498 IN CONST VOID *Buffer
499 )
500 {
501 return InternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer);
502 }
503
504 /**
505 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
506
507 @param AllocationSize The number of bytes to allocate.
508 @param Buffer The buffer to copy to the allocated buffer.
509
510 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
511 If there is not enough memory remaining to satisfy the request, then NULL is returned.
512
513 **/
514 VOID *
515 EFIAPI
516 AllocateRuntimeCopyPool (
517 IN UINTN AllocationSize,
518 IN CONST VOID *Buffer
519 )
520 {
521 return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);
522 }
523
524 /**
525 Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
526
527 @param AllocationSize The number of bytes to allocate.
528 @param Buffer The buffer to copy to the allocated buffer.
529
530 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
531 If there is not enough memory remaining to satisfy the request, then NULL is returned.
532
533 **/
534 VOID *
535 EFIAPI
536 AllocateReservedCopyPool (
537 IN UINTN AllocationSize,
538 IN CONST VOID *Buffer
539 )
540 {
541 return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);
542 }
543
544 /**
545 Copies a buffer to an allocated buffer of type EfiReservedMemoryType at a specified alignment.
546
547 @param Buffer Pointer to the buffer to free.
548
549 **/
550 VOID
551 EFIAPI
552 FreePool (
553 IN VOID *Buffer
554 )
555 {
556 EFI_STATUS Status;
557
558 Status = gBS->FreePool (Buffer);
559 ASSERT_EFI_ERROR (Status);
560 }
561
562 /**
563 Allocates a buffer of a certain pool type at a specified alignment.
564
565 @param PoolType The type of pool to allocate.
566 @param AllocationSize The number of bytes to allocate.
567 @param Alignment The requested alignment of the allocation. Must be a power of two. If Alignment is zero, then byte alignment is used.
568
569 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
570 If there is not enough memory remaining to satisfy the request, then NULL is returned.
571
572 **/
573 VOID *
574 InternalAllocateAlignedPool (
575 IN EFI_MEMORY_TYPE PoolType,
576 IN UINTN AllocationSize,
577 IN UINTN Alignment
578 )
579 {
580 VOID *RawAddress;
581 UINTN AlignedAddress;
582 UINTN AlignmentMask;
583 UINTN OverAllocationSize;
584 UINTN RealAllocationSize;
585 VOID **FreePointer;
586
587 //
588 // Alignment must be a power of two or zero.
589 //
590 ASSERT ((Alignment & (Alignment - 1)) == 0);
591
592 if (Alignment == 0) {
593 AlignmentMask = Alignment;
594 } else {
595 AlignmentMask = Alignment - 1;
596 }
597 //
598 // Calculate the extra memory size, over-allocate memory pool and get the aligned memory address.
599 //
600 OverAllocationSize = sizeof (RawAddress) + AlignmentMask;
601 RealAllocationSize = AllocationSize + OverAllocationSize;
602 //
603 // Make sure that AllocationSize plus OverAllocationSize does not overflow.
604 //
605 ASSERT (RealAllocationSize > AllocationSize);
606
607 RawAddress = InternalAllocatePool (PoolType, RealAllocationSize);
608 if (RawAddress == NULL) {
609 return NULL;
610 }
611 AlignedAddress = ((UINTN) RawAddress + OverAllocationSize) & ~AlignmentMask;
612 //
613 // Save the original memory address just before the aligned address.
614 //
615 FreePointer = (VOID **)(AlignedAddress - sizeof (RawAddress));
616 *FreePointer = RawAddress;
617
618 return (VOID *) AlignedAddress;
619 }
620
621 /**
622 Allocates a buffer of type EfiBootServicesData at a specified alignment.
623
624 @param AllocationSize The number of bytes to allocate.
625 @param Alignment The requested alignment of the allocation. Must be a power of two. If Alignment is zero, then byte alignment is used.
626
627 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
628 If there is not enough memory remaining to satisfy the request, then NULL is returned.
629
630 **/
631 VOID *
632 EFIAPI
633 AllocateAlignedPool (
634 IN UINTN AllocationSize,
635 IN UINTN Alignment
636 )
637 {
638 return InternalAllocateAlignedPool (EfiBootServicesData, AllocationSize, Alignment);
639 }
640
641 /**
642 Allocates a buffer of type EfiRuntimeServicesData at a specified alignment.
643
644 @param AllocationSize The number of bytes to allocate.
645 @param Alignment The requested alignment of the allocation. Must be a power of two.
646 If Alignment is zero, then byte alignment is used.
647
648 A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
649 If there is not enough memory remaining to satisfy the request, then NULL is returned.
650
651 **/
652 VOID *
653 EFIAPI
654 AllocateAlignedRuntimePool (
655 IN UINTN AllocationSize,
656 IN UINTN Alignment
657 )
658 {
659 return InternalAllocateAlignedPool (EfiRuntimeServicesData, AllocationSize, Alignment);
660 }
661
662 /**
663 Allocates a buffer of type EfiReservedMemoryType at a specified alignment.
664
665 @param AllocationSize The number of bytes to allocate.
666 @param Alignment The requested alignment of the allocation. Must be a power of two.
667 If Alignment is zero, then byte alignment is used.
668
669 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
670 If there is not enough memory remaining to satisfy the request, then NULL is returned.
671
672 **/
673 VOID *
674 EFIAPI
675 AllocateAlignedReservedPool (
676 IN UINTN AllocationSize,
677 IN UINTN Alignment
678 )
679 {
680 return InternalAllocateAlignedPool (EfiReservedMemoryType, AllocationSize, Alignment);
681 }
682
683 /**
684 Allocates and zeros a buffer of type EfiBootServicesData at a specified alignment.
685
686 @param PoolType The type of pool to allocate.
687 @param AllocationSize The number of bytes to allocate.
688 @param Alignment The requested alignment of the allocation. Must be a power of two.
689 If Alignment is zero, then byte alignment is used.
690
691 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
692 If there is not enough memory remaining to satisfy the request, then NULL is returned.
693
694 **/
695 VOID *
696 InternalAllocateAlignedZeroPool (
697 IN EFI_MEMORY_TYPE PoolType,
698 IN UINTN AllocationSize,
699 IN UINTN Alignment
700 )
701 {
702 VOID *Memory;
703 Memory = InternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);
704 if (Memory != NULL) {
705 Memory = ZeroMem (Memory, AllocationSize);
706 }
707 return Memory;
708 }
709
710 /**
711 Allocates and zeros a buffer of type EfiBootServicesData at a specified alignment.
712
713 @param AllocationSize The number of bytes to allocate.
714 @param Alignment The requested alignment of the allocation. Must be a power of two.
715 If Alignment is zero, then byte alignment is used.
716
717 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
718 If there is not enough memory remaining to satisfy the request, then NULL is returned.
719
720 **/
721 VOID *
722 EFIAPI
723 AllocateAlignedZeroPool (
724 IN UINTN AllocationSize,
725 IN UINTN Alignment
726 )
727 {
728 return InternalAllocateAlignedZeroPool (EfiBootServicesData, AllocationSize, Alignment);
729 }
730
731 /**
732 Allocates and zeros a buffer of type EfiRuntimeServicesData at a specified alignment.
733
734 @param AllocationSize The number of bytes to allocate.
735 @param Alignment The requested alignment of the allocation. Must be a power of two.
736 If Alignment is zero, then byte alignment is used.
737
738 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
739 If there is not enough memory remaining to satisfy the request, then NULL is returned.
740
741 **/
742 VOID *
743 EFIAPI
744 AllocateAlignedRuntimeZeroPool (
745 IN UINTN AllocationSize,
746 IN UINTN Alignment
747 )
748 {
749 return InternalAllocateAlignedZeroPool (EfiRuntimeServicesData, AllocationSize, Alignment);
750 }
751
752 /**
753 Allocates and zeros a buffer of type EfiReservedMemoryType at a specified alignment.
754
755 @param AllocationSize The number of bytes to allocate.
756 @param Alignment The requested alignment of the allocation. Must be a power of two.
757 If Alignment is zero, then byte alignment is used.
758
759 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
760 If there is not enough memory remaining to satisfy the request, then NULL is returned.
761
762 **/
763 VOID *
764 EFIAPI
765 AllocateAlignedReservedZeroPool (
766 IN UINTN AllocationSize,
767 IN UINTN Alignment
768 )
769 {
770 return InternalAllocateAlignedZeroPool (EfiReservedMemoryType, AllocationSize, Alignment);
771 }
772
773 /**
774 Copies a buffer to an allocated buffer of type EfiBootServicesData at a specified alignment.
775
776 @param PoolType The type of pool to allocate.
777 @param AllocationSize The number of bytes to allocate.
778 @param Buffer The buffer to copy to the allocated buffer.
779 @param Alignment The requested alignment of the allocation. Must be a power of two.
780 If Alignment is zero, then byte alignment is used.
781
782 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
783 If there is not enough memory remaining to satisfy the request, then NULL is returned.
784
785 **/
786 VOID *
787 InternalAllocateAlignedCopyPool (
788 IN EFI_MEMORY_TYPE PoolType,
789 IN UINTN AllocationSize,
790 IN CONST VOID *Buffer,
791 IN UINTN Alignment
792 )
793 {
794 VOID *Memory;
795
796 Memory = InternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);
797 if (Memory != NULL) {
798 Memory = CopyMem (Memory, Buffer, AllocationSize);
799 }
800 return Memory;
801 }
802
803 /**
804 Copies a buffer to an allocated buffer of type EfiBootServicesData at a specified alignment.
805
806 @param AllocationSize The number of bytes to allocate.
807 @param Buffer The buffer to copy to the allocated buffer.
808 @param Alignment The requested alignment of the allocation. Must be a power of two.
809 If Alignment is zero, then byte alignment is used.
810
811 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
812 If there is not enough memory remaining to satisfy the request, then NULL is returned.
813
814 **/
815 VOID *
816 EFIAPI
817 AllocateAlignedCopyPool (
818 IN UINTN AllocationSize,
819 IN CONST VOID *Buffer,
820 IN UINTN Alignment
821 )
822 {
823 return InternalAllocateAlignedCopyPool (EfiBootServicesData, AllocationSize, Buffer, Alignment);
824 }
825
826 /**
827 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData at a specified alignment.
828
829 @param AllocationSize The number of bytes to allocate.
830 @param Buffer The buffer to copy to the allocated buffer.
831 @param Alignment The requested alignment of the allocation. Must be a power of two.
832 If Alignment is zero, then byte alignment is used.
833
834 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
835 If there is not enough memory remaining to satisfy the request, then NULL is returned.
836
837 **/
838 VOID *
839 EFIAPI
840 AllocateAlignedRuntimeCopyPool (
841 IN UINTN AllocationSize,
842 IN CONST VOID *Buffer,
843 IN UINTN Alignment
844 )
845 {
846 return InternalAllocateAlignedCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer, Alignment);
847 }
848
849 /**
850 Copies a buffer to an allocated buffer of type EfiReservedMemoryType at a specified alignment.
851
852 @param AllocationSize The number of bytes to allocate.
853 @param Buffer The buffer to copy to the allocated buffer.
854 @param Alignment The requested alignment of the allocation. Must be a power of two.
855 If Alignment is zero, then byte alignment is used.
856
857 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
858 If there is not enough memory remaining to satisfy the request, then NULL is returned.
859
860 **/
861 VOID *
862 EFIAPI
863 AllocateAlignedReservedCopyPool (
864 IN UINTN AllocationSize,
865 IN CONST VOID *Buffer,
866 IN UINTN Alignment
867 )
868 {
869 return InternalAllocateAlignedCopyPool (EfiReservedMemoryType, AllocationSize, Buffer, Alignment);
870 }
871
872 /**
873 Frees a buffer that was previously allocated with one of the aligned pool allocation functions
874 in the Memory Allocation Library.
875
876 @param Buffer Pointer to the buffer to free.
877
878 **/
879 VOID
880 EFIAPI
881 FreeAlignedPool (
882 IN VOID *Buffer
883 )
884 {
885 VOID *RawAddress;
886 VOID **FreePointer;
887 EFI_STATUS Status;
888
889 //
890 // Get the pre-saved original address in the over-allocate pool.
891 //
892 FreePointer = (VOID **)((UINTN) Buffer - sizeof (RawAddress));
893 RawAddress = *FreePointer;
894
895 Status = gBS->FreePool (RawAddress);
896 ASSERT_EFI_ERROR (Status);
897 }