]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/DxeMemoryAllocationLib/MemoryAllocationLib.c
Ported to GNU assembly.
[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 if (RealPages <= Pages) {
172 //
173 // This extra checking is to make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
174 //
175 return NULL;
176 }
177
178 Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory);
179 if (EFI_ERROR (Status)) {
180 return NULL;
181 }
182 AlignedMemory = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask;
183 UnalignedPages = EFI_SIZE_TO_PAGES ((UINTN) Memory - AlignedMemory);
184 if (UnalignedPages > 0) {
185 //
186 // Free first unaligned page(s).
187 //
188 Status = gBS->FreePages (Memory, UnalignedPages);
189 ASSERT_EFI_ERROR (Status);
190 }
191 Memory = (EFI_PHYSICAL_ADDRESS) (AlignedMemory + EFI_PAGES_TO_SIZE (Pages));
192 UnalignedPages = RealPages - Pages - UnalignedPages;
193 if (UnalignedPages > 0) {
194 //
195 // Free last unaligned page(s).
196 //
197 Status = gBS->FreePages (Memory, UnalignedPages);
198 ASSERT_EFI_ERROR (Status);
199 }
200 } else {
201 //
202 // Do not over-allocate pages in this case.
203 //
204 Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);
205 if (EFI_ERROR (Status)) {
206 return NULL;
207 }
208 AlignedMemory = (UINTN) Memory;
209 }
210 return (VOID *) AlignedMemory;
211 }
212
213 /**
214 Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData
215 with an alignment specified by Alignment.
216
217 @param Pages The number of 4 KB pages to allocate.
218 @param Alignment The requested alignment of the allocation. Must be a power of two.
219 If Alignment is zero, then byte alignment is used.
220
221 @return The allocated buffer is returned.<BR>
222 If Pages is 0, then NULL is returned.<BR>
223 If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.
224
225 **/
226 VOID *
227 EFIAPI
228 AllocateAlignedPages (
229 IN UINTN Pages,
230 IN UINTN Alignment
231 )
232 {
233 return InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment);
234 }
235
236 /**
237 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData
238 with an alignment specified by Alignment.
239
240 @param Pages The number of 4 KB pages to allocate.
241 @param Alignment The requested alignment of the allocation. Must be a power of two.
242 If Alignment is zero, then byte alignment is used.
243
244 @return The allocated buffer is returned. If Pages is 0, then NULL is returned.
245 If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.
246
247 **/
248 VOID *
249 EFIAPI
250 AllocateAlignedRuntimePages (
251 IN UINTN Pages,
252 IN UINTN Alignment
253 )
254 {
255 return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);
256 }
257
258 /**
259 Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
260
261 @param Pages The number of 4 KB pages to allocate.
262 @param Alignment The requested alignment of the allocation. Must be a power of two.
263 If Alignment is zero, then byte alignment is used.
264
265 @return The allocated buffer is returned. If Pages is 0, then NULL is returned.
266 If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.
267
268 **/
269 VOID *
270 EFIAPI
271 AllocateAlignedReservedPages (
272 IN UINTN Pages,
273 IN UINTN Alignment
274 )
275 {
276 return InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment);
277 }
278
279 /**
280 Frees one or more 4KB pages that were previously allocated with
281 one of the aligned page allocation functions in the Memory Allocation Library.
282
283 @param Buffer Pointer to the buffer of pages to free.
284 @param Pages The number of 4 KB pages to free.
285
286 **/
287 VOID
288 EFIAPI
289 FreeAlignedPages (
290 IN VOID *Buffer,
291 IN UINTN Pages
292 )
293 {
294 EFI_STATUS Status;
295
296 ASSERT (Pages != 0);
297 Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
298 ASSERT_EFI_ERROR (Status);
299 }
300
301 /**
302 Allocates a buffer of a certain memory type.
303
304 @param MemoryType The type of memory to allocate.
305 @param AllocationSize The number of bytes to allocate.
306
307 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
308 If there is not enough memory remaining to satisfy the request, then NULL is returned.
309
310 **/
311 VOID *
312 InternalAllocatePool (
313 IN EFI_MEMORY_TYPE MemoryType,
314 IN UINTN AllocationSize
315 )
316 {
317 EFI_STATUS Status;
318 VOID *Memory;
319
320 Status = gBS->AllocatePool (MemoryType, AllocationSize, &Memory);
321 if (EFI_ERROR (Status)) {
322 Memory = NULL;
323 }
324 return Memory;
325 }
326
327 /**
328 Allocates a buffer of type EfiBootServicesData.
329
330 @param AllocationSize The number of bytes to allocate.
331
332 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
333 If there is not enough memory remaining to satisfy the request, then NULL is returned.
334
335 **/
336 VOID *
337 EFIAPI
338 AllocatePool (
339 IN UINTN AllocationSize
340 )
341 {
342 return InternalAllocatePool (EfiBootServicesData, AllocationSize);
343 }
344
345 /**
346 Allocates a buffer of type EfiRuntimeServicesData.
347
348 @param AllocationSize The number of bytes to allocate.
349
350 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
351 If there is not enough memory remaining to satisfy the request, then NULL is returned.
352
353 **/
354 VOID *
355 EFIAPI
356 AllocateRuntimePool (
357 IN UINTN AllocationSize
358 )
359 {
360 return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
361 }
362
363 /**
364 Allocates a buffer of type EfiReservedMemoryType.
365
366 @param AllocationSize The number of bytes to allocate.
367
368 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
369 If there is not enough memory remaining to satisfy the request, then NULL is returned.
370
371 **/
372 VOID *
373 EFIAPI
374 AllocateReservedPool (
375 IN UINTN AllocationSize
376 )
377 {
378 return InternalAllocatePool (EfiReservedMemoryType, AllocationSize);
379 }
380
381 /**
382 Allocates and zeros a buffer of a certian pool type.
383
384 @param PoolType The type of memory to allocate.
385 @param AllocationSize The number of bytes to allocate and zero.
386
387 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
388 If there is not enough memory remaining to satisfy the request, then NULL is returned.
389
390 **/
391 VOID *
392 InternalAllocateZeroPool (
393 IN EFI_MEMORY_TYPE PoolType,
394 IN UINTN AllocationSize
395 )
396 {
397 VOID *Memory;
398 Memory = InternalAllocatePool (PoolType, AllocationSize);
399 if (Memory != NULL) {
400 Memory = ZeroMem (Memory, AllocationSize);
401 }
402 return Memory;
403 }
404
405 /**
406 Allocates and zeros a buffer of type EfiBootServicesData.
407
408 @param AllocationSize The number of bytes to allocate and zero.
409
410 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
411 If there is not enough memory remaining to satisfy the request, then NULL is returned.
412
413 **/
414 VOID *
415 EFIAPI
416 AllocateZeroPool (
417 IN UINTN AllocationSize
418 )
419 {
420 return InternalAllocateZeroPool (EfiBootServicesData, AllocationSize);
421 }
422
423 /**
424 Allocates and zeros a buffer of type EfiRuntimeServicesData.
425
426 @param AllocationSize The number of bytes to allocate and zero.
427
428 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
429 If there is not enough memory remaining to satisfy the request, then NULL is returned.
430
431 **/
432 VOID *
433 EFIAPI
434 AllocateRuntimeZeroPool (
435 IN UINTN AllocationSize
436 )
437 {
438 return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);
439 }
440
441 /**
442 Allocates and zeros a buffer of type EfiReservedMemoryType.
443
444 @param AllocationSize The number of bytes to allocate and zero.
445
446 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
447 If there is not enough memory remaining to satisfy the request, then NULL is returned.
448
449 **/
450 VOID *
451 EFIAPI
452 AllocateReservedZeroPool (
453 IN UINTN AllocationSize
454 )
455 {
456 return InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);
457 }
458
459 /**
460 Copies a buffer to an allocated buffer of a certian memory type.
461
462 @param MemoryType The type of pool to allocate.
463 @param AllocationSize The number of bytes to allocate and zero.
464 @param Buffer The buffer to copy to the allocated buffer.
465
466 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
467 If there is not enough memory remaining to satisfy the request, then NULL is returned.
468
469 **/
470 VOID *
471 InternalAllocateCopyPool (
472 IN EFI_MEMORY_TYPE PoolType,
473 IN UINTN AllocationSize,
474 IN CONST VOID *Buffer
475 )
476 {
477 VOID *Memory;
478
479 Memory = InternalAllocatePool (PoolType, AllocationSize);
480 if (Memory != NULL) {
481 Memory = CopyMem (Memory, Buffer, AllocationSize);
482 }
483 return Memory;
484 }
485
486 /**
487 Copies a buffer to an allocated buffer of type EfiBootServicesData.
488
489 @param AllocationSize The number of bytes to allocate.
490 @param Buffer The buffer to copy to the allocated buffer.
491
492 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
493 If there is not enough memory remaining to satisfy the request, then NULL is returned.
494
495 **/
496 VOID *
497 EFIAPI
498 AllocateCopyPool (
499 IN UINTN AllocationSize,
500 IN CONST VOID *Buffer
501 )
502 {
503 return InternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer);
504 }
505
506 /**
507 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
508
509 @param AllocationSize The number of bytes to allocate.
510 @param Buffer The buffer to copy to the allocated buffer.
511
512 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
513 If there is not enough memory remaining to satisfy the request, then NULL is returned.
514
515 **/
516 VOID *
517 EFIAPI
518 AllocateRuntimeCopyPool (
519 IN UINTN AllocationSize,
520 IN CONST VOID *Buffer
521 )
522 {
523 return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);
524 }
525
526 /**
527 Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
528
529 @param AllocationSize The number of bytes to allocate.
530 @param Buffer The buffer to copy to the allocated buffer.
531
532 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
533 If there is not enough memory remaining to satisfy the request, then NULL is returned.
534
535 **/
536 VOID *
537 EFIAPI
538 AllocateReservedCopyPool (
539 IN UINTN AllocationSize,
540 IN CONST VOID *Buffer
541 )
542 {
543 return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);
544 }
545
546 /**
547 Copies a buffer to an allocated buffer of type EfiReservedMemoryType at a specified alignment.
548
549 @param Buffer Pointer to the buffer to free.
550
551 **/
552 VOID
553 EFIAPI
554 FreePool (
555 IN VOID *Buffer
556 )
557 {
558 EFI_STATUS Status;
559
560 Status = gBS->FreePool (Buffer);
561 ASSERT_EFI_ERROR (Status);
562 }
563
564 /**
565 Allocates a buffer of a certain pool type at a specified alignment.
566
567 @param PoolType The type of pool to allocate.
568 @param AllocationSize The number of bytes to allocate.
569 @param Alignment The requested alignment of the allocation. Must be a power of two. If Alignment is zero, then byte alignment is used.
570
571 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
572 If there is not enough memory remaining to satisfy the request, then NULL is returned.
573
574 **/
575 VOID *
576 InternalAllocateAlignedPool (
577 IN EFI_MEMORY_TYPE PoolType,
578 IN UINTN AllocationSize,
579 IN UINTN Alignment
580 )
581 {
582 VOID *RawAddress;
583 UINTN AlignedAddress;
584 UINTN AlignmentMask;
585 UINTN OverAllocationSize;
586 UINTN RealAllocationSize;
587 VOID **FreePointer;
588
589 //
590 // Alignment must be a power of two or zero.
591 //
592 ASSERT ((Alignment & (Alignment - 1)) == 0);
593
594 if (Alignment == 0) {
595 AlignmentMask = Alignment;
596 } else {
597 AlignmentMask = Alignment - 1;
598 }
599 //
600 // Calculate the extra memory size, over-allocate memory pool and get the aligned memory address.
601 //
602 OverAllocationSize = sizeof (RawAddress) + AlignmentMask;
603 RealAllocationSize = AllocationSize + OverAllocationSize;
604 if (RealAllocationSize <= AllocationSize ) {
605 //
606 // This extra checking is to make sure that AllocationSize plus OverAllocationSize does not overflow.
607 //
608 return NULL;
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 Memory = InternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);
800 if (Memory != NULL) {
801 Memory = CopyMem (Memory, Buffer, AllocationSize);
802 }
803 return Memory;
804 }
805
806 /**
807 Copies a buffer to an allocated buffer of type EfiBootServicesData at a specified alignment.
808
809 @param AllocationSize The number of bytes to allocate.
810 @param Buffer The buffer to copy to the allocated buffer.
811 @param Alignment The requested alignment of the allocation. Must be a power of two.
812 If Alignment is zero, then byte alignment is used.
813
814 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
815 If there is not enough memory remaining to satisfy the request, then NULL is returned.
816
817 **/
818 VOID *
819 EFIAPI
820 AllocateAlignedCopyPool (
821 IN UINTN AllocationSize,
822 IN CONST VOID *Buffer,
823 IN UINTN Alignment
824 )
825 {
826 return InternalAllocateAlignedCopyPool (EfiBootServicesData, AllocationSize, Buffer, Alignment);
827 }
828
829 /**
830 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData at a specified alignment.
831
832 @param AllocationSize The number of bytes to allocate.
833 @param Buffer The buffer to copy to the allocated buffer.
834 @param Alignment The requested alignment of the allocation. Must be a power of two.
835 If Alignment is zero, then byte alignment is used.
836
837 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
838 If there is not enough memory remaining to satisfy the request, then NULL is returned.
839
840 **/
841 VOID *
842 EFIAPI
843 AllocateAlignedRuntimeCopyPool (
844 IN UINTN AllocationSize,
845 IN CONST VOID *Buffer,
846 IN UINTN Alignment
847 )
848 {
849 return InternalAllocateAlignedCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer, Alignment);
850 }
851
852 /**
853 Copies a buffer to an allocated buffer of type EfiReservedMemoryType at a specified alignment.
854
855 @param AllocationSize The number of bytes to allocate.
856 @param Buffer The buffer to copy to the allocated buffer.
857 @param Alignment The requested alignment of the allocation. Must be a power of two.
858 If Alignment is zero, then byte alignment is used.
859
860 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
861 If there is not enough memory remaining to satisfy the request, then NULL is returned.
862
863 **/
864 VOID *
865 EFIAPI
866 AllocateAlignedReservedCopyPool (
867 IN UINTN AllocationSize,
868 IN CONST VOID *Buffer,
869 IN UINTN Alignment
870 )
871 {
872 return InternalAllocateAlignedCopyPool (EfiReservedMemoryType, AllocationSize, Buffer, Alignment);
873 }
874
875 /**
876 Frees a buffer that was previously allocated with one of the aligned pool allocation functions
877 in the Memory Allocation Library.
878
879 @param Buffer Pointer to the buffer to free.
880
881 **/
882 VOID
883 EFIAPI
884 FreeAlignedPool (
885 IN VOID *Buffer
886 )
887 {
888 VOID *RawAddress;
889 VOID **FreePointer;
890 EFI_STATUS Status;
891
892 //
893 // Get the pre-saved original address in the over-allocate pool.
894 //
895 FreePointer = (VOID **)((UINTN) Buffer - sizeof (RawAddress));
896 RawAddress = *FreePointer;
897
898 Status = gBS->FreePool (RawAddress);
899 ASSERT_EFI_ERROR (Status);
900 }