]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/DxeMemoryAllocationLib/MemoryAllocationLib.c
UefiLib:
[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 ASSERT (Buffer != NULL);
478 ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
479
480 Memory = InternalAllocatePool (PoolType, AllocationSize);
481 if (Memory != NULL) {
482 Memory = CopyMem (Memory, Buffer, AllocationSize);
483 }
484 return Memory;
485 }
486
487 /**
488 Copies a buffer to an allocated buffer of type EfiBootServicesData.
489
490 @param AllocationSize The number of bytes to allocate.
491 @param Buffer The buffer to copy to the allocated buffer.
492
493 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
494 If there is not enough memory remaining to satisfy the request, then NULL is returned.
495
496 **/
497 VOID *
498 EFIAPI
499 AllocateCopyPool (
500 IN UINTN AllocationSize,
501 IN CONST VOID *Buffer
502 )
503 {
504 return InternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer);
505 }
506
507 /**
508 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
509
510 @param AllocationSize The number of bytes to allocate.
511 @param Buffer The buffer to copy to the allocated buffer.
512
513 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
514 If there is not enough memory remaining to satisfy the request, then NULL is returned.
515
516 **/
517 VOID *
518 EFIAPI
519 AllocateRuntimeCopyPool (
520 IN UINTN AllocationSize,
521 IN CONST VOID *Buffer
522 )
523 {
524 return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);
525 }
526
527 /**
528 Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
529
530 @param AllocationSize The number of bytes to allocate.
531 @param Buffer The buffer to copy to the allocated buffer.
532
533 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
534 If there is not enough memory remaining to satisfy the request, then NULL is returned.
535
536 **/
537 VOID *
538 EFIAPI
539 AllocateReservedCopyPool (
540 IN UINTN AllocationSize,
541 IN CONST VOID *Buffer
542 )
543 {
544 return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);
545 }
546
547 /**
548 Copies a buffer to an allocated buffer of type EfiReservedMemoryType at a specified alignment.
549
550 @param Buffer Pointer to the buffer to free.
551
552 **/
553 VOID
554 EFIAPI
555 FreePool (
556 IN VOID *Buffer
557 )
558 {
559 EFI_STATUS Status;
560
561 Status = gBS->FreePool (Buffer);
562 ASSERT_EFI_ERROR (Status);
563 }
564
565 /**
566 Allocates a buffer of a certain pool type at a specified alignment.
567
568 @param PoolType The type of pool to allocate.
569 @param AllocationSize The number of bytes to allocate.
570 @param Alignment The requested alignment of the allocation. Must be a power of two. If Alignment is zero, then byte alignment is used.
571
572 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
573 If there is not enough memory remaining to satisfy the request, then NULL is returned.
574
575 **/
576 VOID *
577 InternalAllocateAlignedPool (
578 IN EFI_MEMORY_TYPE PoolType,
579 IN UINTN AllocationSize,
580 IN UINTN Alignment
581 )
582 {
583 VOID *RawAddress;
584 UINTN AlignedAddress;
585 UINTN AlignmentMask;
586 UINTN OverAllocationSize;
587 UINTN RealAllocationSize;
588 VOID **FreePointer;
589
590 //
591 // Alignment must be a power of two or zero.
592 //
593 ASSERT ((Alignment & (Alignment - 1)) == 0);
594
595 if (Alignment == 0) {
596 AlignmentMask = Alignment;
597 } else {
598 AlignmentMask = Alignment - 1;
599 }
600 //
601 // Calculate the extra memory size, over-allocate memory pool and get the aligned memory address.
602 //
603 OverAllocationSize = sizeof (RawAddress) + AlignmentMask;
604 RealAllocationSize = AllocationSize + OverAllocationSize;
605 //
606 // Make sure that AllocationSize plus OverAllocationSize does not overflow.
607 //
608 ASSERT (RealAllocationSize > AllocationSize);
609
610 RawAddress = InternalAllocatePool (PoolType, RealAllocationSize);
611 if (RawAddress == NULL) {
612 return NULL;
613 }
614 AlignedAddress = ((UINTN) RawAddress + OverAllocationSize) & ~AlignmentMask;
615 //
616 // Save the original memory address just before the aligned address.
617 //
618 FreePointer = (VOID **)(AlignedAddress - sizeof (RawAddress));
619 *FreePointer = RawAddress;
620
621 return (VOID *) AlignedAddress;
622 }
623
624 /**
625 Allocates a buffer of type EfiBootServicesData at a specified alignment.
626
627 @param AllocationSize The number of bytes to allocate.
628 @param Alignment The requested alignment of the allocation. Must be a power of two. If Alignment is zero, then byte alignment is used.
629
630 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
631 If there is not enough memory remaining to satisfy the request, then NULL is returned.
632
633 **/
634 VOID *
635 EFIAPI
636 AllocateAlignedPool (
637 IN UINTN AllocationSize,
638 IN UINTN Alignment
639 )
640 {
641 return InternalAllocateAlignedPool (EfiBootServicesData, AllocationSize, Alignment);
642 }
643
644 /**
645 Allocates a buffer of type EfiRuntimeServicesData at a specified alignment.
646
647 @param AllocationSize The number of bytes to allocate.
648 @param Alignment The requested alignment of the allocation. Must be a power of two.
649 If Alignment is zero, then byte alignment is used.
650
651 A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
652 If there is not enough memory remaining to satisfy the request, then NULL is returned.
653
654 **/
655 VOID *
656 EFIAPI
657 AllocateAlignedRuntimePool (
658 IN UINTN AllocationSize,
659 IN UINTN Alignment
660 )
661 {
662 return InternalAllocateAlignedPool (EfiRuntimeServicesData, AllocationSize, Alignment);
663 }
664
665 /**
666 Allocates a buffer of type EfiReservedMemoryType at a specified alignment.
667
668 @param AllocationSize The number of bytes to allocate.
669 @param Alignment The requested alignment of the allocation. Must be a power of two.
670 If Alignment is zero, then byte alignment is used.
671
672 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
673 If there is not enough memory remaining to satisfy the request, then NULL is returned.
674
675 **/
676 VOID *
677 EFIAPI
678 AllocateAlignedReservedPool (
679 IN UINTN AllocationSize,
680 IN UINTN Alignment
681 )
682 {
683 return InternalAllocateAlignedPool (EfiReservedMemoryType, AllocationSize, Alignment);
684 }
685
686 /**
687 Allocates and zeros a buffer of type EfiBootServicesData at a specified alignment.
688
689 @param PoolType The type of pool to allocate.
690 @param AllocationSize The number of bytes to allocate.
691 @param Alignment The requested alignment of the allocation. Must be a power of two.
692 If Alignment is zero, then byte alignment is used.
693
694 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
695 If there is not enough memory remaining to satisfy the request, then NULL is returned.
696
697 **/
698 VOID *
699 InternalAllocateAlignedZeroPool (
700 IN EFI_MEMORY_TYPE PoolType,
701 IN UINTN AllocationSize,
702 IN UINTN Alignment
703 )
704 {
705 VOID *Memory;
706 Memory = InternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);
707 if (Memory != NULL) {
708 Memory = ZeroMem (Memory, AllocationSize);
709 }
710 return Memory;
711 }
712
713 /**
714 Allocates and zeros a buffer of type EfiBootServicesData at a specified alignment.
715
716 @param AllocationSize The number of bytes to allocate.
717 @param Alignment The requested alignment of the allocation. Must be a power of two.
718 If Alignment is zero, then byte alignment is used.
719
720 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
721 If there is not enough memory remaining to satisfy the request, then NULL is returned.
722
723 **/
724 VOID *
725 EFIAPI
726 AllocateAlignedZeroPool (
727 IN UINTN AllocationSize,
728 IN UINTN Alignment
729 )
730 {
731 return InternalAllocateAlignedZeroPool (EfiBootServicesData, AllocationSize, Alignment);
732 }
733
734 /**
735 Allocates and zeros a buffer of type EfiRuntimeServicesData at a specified alignment.
736
737 @param AllocationSize The number of bytes to allocate.
738 @param Alignment The requested alignment of the allocation. Must be a power of two.
739 If Alignment is zero, then byte alignment is used.
740
741 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
742 If there is not enough memory remaining to satisfy the request, then NULL is returned.
743
744 **/
745 VOID *
746 EFIAPI
747 AllocateAlignedRuntimeZeroPool (
748 IN UINTN AllocationSize,
749 IN UINTN Alignment
750 )
751 {
752 return InternalAllocateAlignedZeroPool (EfiRuntimeServicesData, AllocationSize, Alignment);
753 }
754
755 /**
756 Allocates and zeros a buffer of type EfiReservedMemoryType at a specified alignment.
757
758 @param AllocationSize The number of bytes to allocate.
759 @param Alignment The requested alignment of the allocation. Must be a power of two.
760 If Alignment is zero, then byte alignment is used.
761
762 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
763 If there is not enough memory remaining to satisfy the request, then NULL is returned.
764
765 **/
766 VOID *
767 EFIAPI
768 AllocateAlignedReservedZeroPool (
769 IN UINTN AllocationSize,
770 IN UINTN Alignment
771 )
772 {
773 return InternalAllocateAlignedZeroPool (EfiReservedMemoryType, AllocationSize, Alignment);
774 }
775
776 /**
777 Copies a buffer to an allocated buffer of type EfiBootServicesData at a specified alignment.
778
779 @param PoolType The type of pool to allocate.
780 @param AllocationSize The number of bytes to allocate.
781 @param Buffer The buffer to copy to the allocated buffer.
782 @param Alignment The requested alignment of the allocation. Must be a power of two.
783 If Alignment is zero, then byte alignment is used.
784
785 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
786 If there is not enough memory remaining to satisfy the request, then NULL is returned.
787
788 **/
789 VOID *
790 InternalAllocateAlignedCopyPool (
791 IN EFI_MEMORY_TYPE PoolType,
792 IN UINTN AllocationSize,
793 IN CONST VOID *Buffer,
794 IN UINTN Alignment
795 )
796 {
797 VOID *Memory;
798
799 ASSERT (Buffer != NULL);
800 ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
801
802 Memory = InternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);
803 if (Memory != NULL) {
804 Memory = CopyMem (Memory, Buffer, AllocationSize);
805 }
806 return Memory;
807 }
808
809 /**
810 Copies a buffer to an allocated buffer of type EfiBootServicesData at a specified alignment.
811
812 @param AllocationSize The number of bytes to allocate.
813 @param Buffer The buffer to copy to the allocated buffer.
814 @param Alignment The requested alignment of the allocation. Must be a power of two.
815 If Alignment is zero, then byte alignment is used.
816
817 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
818 If there is not enough memory remaining to satisfy the request, then NULL is returned.
819
820 **/
821 VOID *
822 EFIAPI
823 AllocateAlignedCopyPool (
824 IN UINTN AllocationSize,
825 IN CONST VOID *Buffer,
826 IN UINTN Alignment
827 )
828 {
829 return InternalAllocateAlignedCopyPool (EfiBootServicesData, AllocationSize, Buffer, Alignment);
830 }
831
832 /**
833 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData at a specified alignment.
834
835 @param AllocationSize The number of bytes to allocate.
836 @param Buffer The buffer to copy to the allocated buffer.
837 @param Alignment The requested alignment of the allocation. Must be a power of two.
838 If Alignment is zero, then byte alignment is used.
839
840 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
841 If there is not enough memory remaining to satisfy the request, then NULL is returned.
842
843 **/
844 VOID *
845 EFIAPI
846 AllocateAlignedRuntimeCopyPool (
847 IN UINTN AllocationSize,
848 IN CONST VOID *Buffer,
849 IN UINTN Alignment
850 )
851 {
852 return InternalAllocateAlignedCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer, Alignment);
853 }
854
855 /**
856 Copies a buffer to an allocated buffer of type EfiReservedMemoryType at a specified alignment.
857
858 @param AllocationSize The number of bytes to allocate.
859 @param Buffer The buffer to copy to the allocated buffer.
860 @param Alignment The requested alignment of the allocation. Must be a power of two.
861 If Alignment is zero, then byte alignment is used.
862
863 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
864 If there is not enough memory remaining to satisfy the request, then NULL is returned.
865
866 **/
867 VOID *
868 EFIAPI
869 AllocateAlignedReservedCopyPool (
870 IN UINTN AllocationSize,
871 IN CONST VOID *Buffer,
872 IN UINTN Alignment
873 )
874 {
875 return InternalAllocateAlignedCopyPool (EfiReservedMemoryType, AllocationSize, Buffer, Alignment);
876 }
877
878 /**
879 Frees a buffer that was previously allocated with one of the aligned pool allocation functions
880 in the Memory Allocation Library.
881
882 @param Buffer Pointer to the buffer to free.
883
884 **/
885 VOID
886 EFIAPI
887 FreeAlignedPool (
888 IN VOID *Buffer
889 )
890 {
891 VOID *RawAddress;
892 VOID **FreePointer;
893 EFI_STATUS Status;
894
895 //
896 // Get the pre-saved original address in the over-allocate pool.
897 //
898 FreePointer = (VOID **)((UINTN) Buffer - sizeof (RawAddress));
899 RawAddress = *FreePointer;
900
901 Status = gBS->FreePool (RawAddress);
902 ASSERT_EFI_ERROR (Status);
903 }