]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/DxeMemoryAllocationLib/MemoryAllocationLib.c
Initial import.
[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 Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory);
172 if (EFI_ERROR (Status)) {
173 return NULL;
174 }
175 AlignedMemory = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask;
176 UnalignedPages = EFI_SIZE_TO_PAGES ((UINTN) Memory - AlignedMemory);
177 if (UnalignedPages > 0) {
178 //
179 // Free first unaligned page(s).
180 //
181 Status = gBS->FreePages (Memory, UnalignedPages);
182 ASSERT_EFI_ERROR (Status);
183 }
184 Memory = (EFI_PHYSICAL_ADDRESS) (AlignedMemory + EFI_PAGES_TO_SIZE (Pages));
185 UnalignedPages = RealPages - Pages - UnalignedPages;
186 if (UnalignedPages > 0) {
187 //
188 // Free last unaligned page(s).
189 //
190 Status = gBS->FreePages (Memory, UnalignedPages);
191 ASSERT_EFI_ERROR (Status);
192 }
193 } else {
194 //
195 // Do not over-allocate pages in this case.
196 //
197 Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);
198 if (EFI_ERROR (Status)) {
199 return NULL;
200 }
201 AlignedMemory = (UINTN) Memory;
202 }
203 return (VOID *) AlignedMemory;
204 }
205
206 /**
207 Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData
208 with an alignment specified by Alignment.
209
210 @param Pages The number of 4 KB pages to allocate.
211 @param Alignment The requested alignment of the allocation. Must be a power of two.
212 If Alignment is zero, then byte alignment is used.
213
214 @return The allocated buffer is returned.<BR>
215 If Pages is 0, then NULL is returned.<BR>
216 If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.
217
218 **/
219 VOID *
220 EFIAPI
221 AllocateAlignedPages (
222 IN UINTN Pages,
223 IN UINTN Alignment
224 )
225 {
226 return InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment);
227 }
228
229 /**
230 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData
231 with an alignment specified by Alignment.
232
233 @param Pages The number of 4 KB pages to allocate.
234 @param Alignment The requested alignment of the allocation. Must be a power of two.
235 If Alignment is zero, then byte alignment is used.
236
237 @return The allocated buffer is returned. If Pages is 0, then NULL is returned.
238 If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.
239
240 **/
241 VOID *
242 EFIAPI
243 AllocateAlignedRuntimePages (
244 IN UINTN Pages,
245 IN UINTN Alignment
246 )
247 {
248 return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);
249 }
250
251 /**
252 Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
253
254 @param Pages The number of 4 KB pages to allocate.
255 @param Alignment The requested alignment of the allocation. Must be a power of two.
256 If Alignment is zero, then byte alignment is used.
257
258 @return The allocated buffer is returned. If Pages is 0, then NULL is returned.
259 If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.
260
261 **/
262 VOID *
263 EFIAPI
264 AllocateAlignedReservedPages (
265 IN UINTN Pages,
266 IN UINTN Alignment
267 )
268 {
269 return InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment);
270 }
271
272 /**
273 Frees one or more 4KB pages that were previously allocated with
274 one of the aligned page allocation functions in the Memory Allocation Library.
275
276 @param Buffer Pointer to the buffer of pages to free.
277 @param Pages The number of 4 KB pages to free.
278
279 **/
280 VOID
281 EFIAPI
282 FreeAlignedPages (
283 IN VOID *Buffer,
284 IN UINTN Pages
285 )
286 {
287 EFI_STATUS Status;
288
289 ASSERT (Pages != 0);
290 Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
291 ASSERT_EFI_ERROR (Status);
292 }
293
294 /**
295 Allocates a buffer of a certain memory type.
296
297 @param MemoryType The type of memory to allocate.
298 @param AllocationSize The number of bytes to allocate.
299
300 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
301 If there is not enough memory remaining to satisfy the request, then NULL is returned.
302
303 **/
304 VOID *
305 InternalAllocatePool (
306 IN EFI_MEMORY_TYPE MemoryType,
307 IN UINTN AllocationSize
308 )
309 {
310 EFI_STATUS Status;
311 VOID *Memory;
312
313 Status = gBS->AllocatePool (MemoryType, AllocationSize, &Memory);
314 if (EFI_ERROR (Status)) {
315 Memory = NULL;
316 }
317 return Memory;
318 }
319
320 /**
321 Allocates a buffer of type EfiBootServicesData.
322
323 @param AllocationSize The number of bytes to allocate.
324
325 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
326 If there is not enough memory remaining to satisfy the request, then NULL is returned.
327
328 **/
329 VOID *
330 EFIAPI
331 AllocatePool (
332 IN UINTN AllocationSize
333 )
334 {
335 return InternalAllocatePool (EfiBootServicesData, AllocationSize);
336 }
337
338 /**
339 Allocates a buffer of type EfiRuntimeServicesData.
340
341 @param AllocationSize The number of bytes to allocate.
342
343 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
344 If there is not enough memory remaining to satisfy the request, then NULL is returned.
345
346 **/
347 VOID *
348 EFIAPI
349 AllocateRuntimePool (
350 IN UINTN AllocationSize
351 )
352 {
353 return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
354 }
355
356 /**
357 Allocates a buffer of type EfiReservedMemoryType.
358
359 @param AllocationSize The number of bytes to allocate.
360
361 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
362 If there is not enough memory remaining to satisfy the request, then NULL is returned.
363
364 **/
365 VOID *
366 EFIAPI
367 AllocateReservedPool (
368 IN UINTN AllocationSize
369 )
370 {
371 return InternalAllocatePool (EfiReservedMemoryType, AllocationSize);
372 }
373
374 /**
375 Allocates and zeros a buffer of a certian pool type.
376
377 @param PoolType The type of memory to allocate.
378 @param AllocationSize The number of bytes to allocate and zero.
379
380 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
381 If there is not enough memory remaining to satisfy the request, then NULL is returned.
382
383 **/
384 VOID *
385 InternalAllocateZeroPool (
386 IN EFI_MEMORY_TYPE PoolType,
387 IN UINTN AllocationSize
388 )
389 {
390 VOID *Memory;
391 Memory = InternalAllocatePool (PoolType, AllocationSize);
392 if (Memory != NULL) {
393 Memory = ZeroMem (Memory, AllocationSize);
394 }
395 return Memory;
396 }
397
398 /**
399 Allocates and zeros a buffer of type EfiBootServicesData.
400
401 @param AllocationSize The number of bytes to allocate and zero.
402
403 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
404 If there is not enough memory remaining to satisfy the request, then NULL is returned.
405
406 **/
407 VOID *
408 EFIAPI
409 AllocateZeroPool (
410 IN UINTN AllocationSize
411 )
412 {
413 return InternalAllocateZeroPool (EfiBootServicesData, AllocationSize);
414 }
415
416 /**
417 Allocates and zeros a buffer of type EfiRuntimeServicesData.
418
419 @param AllocationSize The number of bytes to allocate and zero.
420
421 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
422 If there is not enough memory remaining to satisfy the request, then NULL is returned.
423
424 **/
425 VOID *
426 EFIAPI
427 AllocateRuntimeZeroPool (
428 IN UINTN AllocationSize
429 )
430 {
431 return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);
432 }
433
434 /**
435 Allocates and zeros a buffer of type EfiReservedMemoryType.
436
437 @param AllocationSize The number of bytes to allocate and zero.
438
439 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
440 If there is not enough memory remaining to satisfy the request, then NULL is returned.
441
442 **/
443 VOID *
444 EFIAPI
445 AllocateReservedZeroPool (
446 IN UINTN AllocationSize
447 )
448 {
449 return InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);
450 }
451
452 /**
453 Copies a buffer to an allocated buffer of a certian memory type.
454
455 @param MemoryType The type of pool to allocate.
456 @param AllocationSize The number of bytes to allocate and zero.
457 @param Buffer The buffer to copy to the allocated buffer.
458
459 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
460 If there is not enough memory remaining to satisfy the request, then NULL is returned.
461
462 **/
463 VOID *
464 InternalAllocateCopyPool (
465 IN EFI_MEMORY_TYPE PoolType,
466 IN UINTN AllocationSize,
467 IN CONST VOID *Buffer
468 )
469 {
470 VOID *Memory;
471
472 Memory = InternalAllocatePool (PoolType, AllocationSize);
473 if (Memory != NULL) {
474 Memory = CopyMem (Memory, Buffer, AllocationSize);
475 }
476 return Memory;
477 }
478
479 /**
480 Copies a buffer to an allocated buffer of type EfiBootServicesData.
481
482 @param AllocationSize The number of bytes to allocate.
483 @param Buffer The buffer to copy to the allocated buffer.
484
485 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
486 If there is not enough memory remaining to satisfy the request, then NULL is returned.
487
488 **/
489 VOID *
490 EFIAPI
491 AllocateCopyPool (
492 IN UINTN AllocationSize,
493 IN CONST VOID *Buffer
494 )
495 {
496 return InternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer);
497 }
498
499 /**
500 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
501
502 @param AllocationSize The number of bytes to allocate.
503 @param Buffer The buffer to copy to the allocated buffer.
504
505 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
506 If there is not enough memory remaining to satisfy the request, then NULL is returned.
507
508 **/
509 VOID *
510 EFIAPI
511 AllocateRuntimeCopyPool (
512 IN UINTN AllocationSize,
513 IN CONST VOID *Buffer
514 )
515 {
516 return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);
517 }
518
519 /**
520 Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
521
522 @param AllocationSize The number of bytes to allocate.
523 @param Buffer The buffer to copy to the allocated buffer.
524
525 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
526 If there is not enough memory remaining to satisfy the request, then NULL is returned.
527
528 **/
529 VOID *
530 EFIAPI
531 AllocateReservedCopyPool (
532 IN UINTN AllocationSize,
533 IN CONST VOID *Buffer
534 )
535 {
536 return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);
537 }
538
539 /**
540 Copies a buffer to an allocated buffer of type EfiReservedMemoryType at a specified alignment.
541
542 @param Buffer Pointer to the buffer to free.
543
544 **/
545 VOID
546 EFIAPI
547 FreePool (
548 IN VOID *Buffer
549 )
550 {
551 EFI_STATUS Status;
552
553 Status = gBS->FreePool (Buffer);
554 ASSERT_EFI_ERROR (Status);
555 }
556
557 /**
558 Allocates a buffer of a certain pool type at a specified alignment.
559
560 @param PoolType The type of pool to allocate.
561 @param AllocationSize The number of bytes to allocate.
562 @param Alignment The requested alignment of the allocation. Must be a power of two. If Alignment is zero, then byte alignment is used.
563
564 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
565 If there is not enough memory remaining to satisfy the request, then NULL is returned.
566
567 **/
568 VOID *
569 InternalAllocateAlignedPool (
570 IN EFI_MEMORY_TYPE PoolType,
571 IN UINTN AllocationSize,
572 IN UINTN Alignment
573 )
574 {
575 VOID *RawAddress;
576 UINTN AlignedAddress;
577 UINTN AlignmentMask;
578 UINTN OverAllocationSize;
579 VOID **FreePointer;
580 EFI_STATUS Status;
581
582 //
583 // Alignment must be a power of two or zero.
584 //
585 ASSERT ((Alignment & (Alignment - 1)) == 0);
586
587 if (Alignment == 0) {
588 AlignmentMask = Alignment;
589 } else {
590 AlignmentMask = Alignment - 1;
591 }
592 //
593 // Calculate the extra memory size, over-allocate memory pool and get the aligned memory address.
594 //
595 OverAllocationSize = sizeof (RawAddress) + AlignmentMask;
596 Status = gBS->AllocatePool (PoolType, AllocationSize + OverAllocationSize, &RawAddress);
597 if (EFI_ERROR (Status)) {
598 return NULL;
599 }
600 AlignedAddress = ((UINTN) RawAddress + OverAllocationSize) & ~AlignmentMask;
601 //
602 // Save the original memory address just before the aligned address.
603 //
604 FreePointer = (VOID **)(AlignedAddress - sizeof (RawAddress));
605 *FreePointer = RawAddress;
606
607 return (VOID *) AlignedAddress;
608 }
609
610 /**
611 Allocates a buffer of type EfiBootServicesData at a specified alignment.
612
613 @param AllocationSize The number of bytes to allocate.
614 @param Alignment The requested alignment of the allocation. Must be a power of two. If Alignment is zero, then byte alignment is used.
615
616 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
617 If there is not enough memory remaining to satisfy the request, then NULL is returned.
618
619 **/
620 VOID *
621 EFIAPI
622 AllocateAlignedPool (
623 IN UINTN AllocationSize,
624 IN UINTN Alignment
625 )
626 {
627 return InternalAllocateAlignedPool (EfiBootServicesData, AllocationSize, Alignment);
628 }
629
630 /**
631 Allocates a buffer of type EfiRuntimeServicesData at a specified alignment.
632
633 @param AllocationSize The number of bytes to allocate.
634 @param Alignment The requested alignment of the allocation. Must be a power of two.
635 If Alignment is zero, then byte alignment is used.
636
637 A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
638 If there is not enough memory remaining to satisfy the request, then NULL is returned.
639
640 **/
641 VOID *
642 EFIAPI
643 AllocateAlignedRuntimePool (
644 IN UINTN AllocationSize,
645 IN UINTN Alignment
646 )
647 {
648 return InternalAllocateAlignedPool (EfiRuntimeServicesData, AllocationSize, Alignment);
649 }
650
651 /**
652 Allocates a buffer of type EfiReservedMemoryType at a specified alignment.
653
654 @param AllocationSize The number of bytes to allocate.
655 @param Alignment The requested alignment of the allocation. Must be a power of two.
656 If Alignment is zero, then byte alignment is used.
657
658 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
659 If there is not enough memory remaining to satisfy the request, then NULL is returned.
660
661 **/
662 VOID *
663 EFIAPI
664 AllocateAlignedReservedPool (
665 IN UINTN AllocationSize,
666 IN UINTN Alignment
667 )
668 {
669 return InternalAllocateAlignedPool (EfiReservedMemoryType, AllocationSize, Alignment);
670 }
671
672 /**
673 Allocates and zeros a buffer of type EfiBootServicesData at a specified alignment.
674
675 @param PoolType The type of pool to allocate.
676 @param AllocationSize The number of bytes to allocate.
677 @param Alignment The requested alignment of the allocation. Must be a power of two.
678 If Alignment is zero, then byte alignment is used.
679
680 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
681 If there is not enough memory remaining to satisfy the request, then NULL is returned.
682
683 **/
684 VOID *
685 InternalAllocateAlignedZeroPool (
686 IN EFI_MEMORY_TYPE PoolType,
687 IN UINTN AllocationSize,
688 IN UINTN Alignment
689 )
690 {
691 VOID *Memory;
692 Memory = InternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);
693 if (Memory != NULL) {
694 Memory = ZeroMem (Memory, AllocationSize);
695 }
696 return Memory;
697 }
698
699 /**
700 Allocates and zeros a buffer of type EfiBootServicesData at a specified alignment.
701
702 @param AllocationSize The number of bytes to allocate.
703 @param Alignment The requested alignment of the allocation. Must be a power of two.
704 If Alignment is zero, then byte alignment is used.
705
706 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
707 If there is not enough memory remaining to satisfy the request, then NULL is returned.
708
709 **/
710 VOID *
711 EFIAPI
712 AllocateAlignedZeroPool (
713 IN UINTN AllocationSize,
714 IN UINTN Alignment
715 )
716 {
717 return InternalAllocateAlignedZeroPool (EfiBootServicesData, AllocationSize, Alignment);
718 }
719
720 /**
721 Allocates and zeros a buffer of type EfiRuntimeServicesData at a specified alignment.
722
723 @param AllocationSize The number of bytes to allocate.
724 @param Alignment The requested alignment of the allocation. Must be a power of two.
725 If Alignment is zero, then byte alignment is used.
726
727 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
728 If there is not enough memory remaining to satisfy the request, then NULL is returned.
729
730 **/
731 VOID *
732 EFIAPI
733 AllocateAlignedRuntimeZeroPool (
734 IN UINTN AllocationSize,
735 IN UINTN Alignment
736 )
737 {
738 return InternalAllocateAlignedZeroPool (EfiRuntimeServicesData, AllocationSize, Alignment);
739 }
740
741 /**
742 Allocates and zeros a buffer of type EfiReservedMemoryType at a specified alignment.
743
744 @param AllocationSize The number of bytes to allocate.
745 @param Alignment The requested alignment of the allocation. Must be a power of two.
746 If Alignment is zero, then byte alignment is used.
747
748 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
749 If there is not enough memory remaining to satisfy the request, then NULL is returned.
750
751 **/
752 VOID *
753 EFIAPI
754 AllocateAlignedReservedZeroPool (
755 IN UINTN AllocationSize,
756 IN UINTN Alignment
757 )
758 {
759 return InternalAllocateAlignedZeroPool (EfiReservedMemoryType, AllocationSize, Alignment);
760 }
761
762 /**
763 Copies a buffer to an allocated buffer of type EfiBootServicesData at a specified alignment.
764
765 @param PoolType The type of pool to allocate.
766 @param AllocationSize The number of bytes to allocate.
767 @param Buffer The buffer to copy to the allocated buffer.
768 @param Alignment The requested alignment of the allocation. Must be a power of two.
769 If Alignment is zero, then byte alignment is used.
770
771 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
772 If there is not enough memory remaining to satisfy the request, then NULL is returned.
773
774 **/
775 VOID *
776 InternalAllocateAlignedCopyPool (
777 IN EFI_MEMORY_TYPE PoolType,
778 IN UINTN AllocationSize,
779 IN CONST VOID *Buffer,
780 IN UINTN Alignment
781 )
782 {
783 VOID *Memory;
784
785 Memory = InternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);
786 if (Memory != NULL) {
787 Memory = CopyMem (Memory, Buffer, AllocationSize);
788 }
789 return Memory;
790 }
791
792 /**
793 Copies a buffer to an allocated buffer of type EfiBootServicesData at a specified alignment.
794
795 @param AllocationSize The number of bytes to allocate.
796 @param Buffer The buffer to copy to the allocated buffer.
797 @param Alignment The requested alignment of the allocation. Must be a power of two.
798 If Alignment is zero, then byte alignment is used.
799
800 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
801 If there is not enough memory remaining to satisfy the request, then NULL is returned.
802
803 **/
804 VOID *
805 EFIAPI
806 AllocateAlignedCopyPool (
807 IN UINTN AllocationSize,
808 IN CONST VOID *Buffer,
809 IN UINTN Alignment
810 )
811 {
812 return InternalAllocateAlignedCopyPool (EfiBootServicesData, AllocationSize, Buffer, Alignment);
813 }
814
815 /**
816 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData at a specified alignment.
817
818 @param AllocationSize The number of bytes to allocate.
819 @param Buffer The buffer to copy to the allocated buffer.
820 @param Alignment The requested alignment of the allocation. Must be a power of two.
821 If Alignment is zero, then byte alignment is used.
822
823 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
824 If there is not enough memory remaining to satisfy the request, then NULL is returned.
825
826 **/
827 VOID *
828 EFIAPI
829 AllocateAlignedRuntimeCopyPool (
830 IN UINTN AllocationSize,
831 IN CONST VOID *Buffer,
832 IN UINTN Alignment
833 )
834 {
835 return InternalAllocateAlignedCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer, Alignment);
836 }
837
838 /**
839 Copies a buffer to an allocated buffer of type EfiReservedMemoryType at a specified alignment.
840
841 @param AllocationSize The number of bytes to allocate.
842 @param Buffer The buffer to copy to the allocated buffer.
843 @param Alignment The requested alignment of the allocation. Must be a power of two.
844 If Alignment is zero, then byte alignment is used.
845
846 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.
847 If there is not enough memory remaining to satisfy the request, then NULL is returned.
848
849 **/
850 VOID *
851 EFIAPI
852 AllocateAlignedReservedCopyPool (
853 IN UINTN AllocationSize,
854 IN CONST VOID *Buffer,
855 IN UINTN Alignment
856 )
857 {
858 return InternalAllocateAlignedCopyPool (EfiReservedMemoryType, AllocationSize, Buffer, Alignment);
859 }
860
861 /**
862 Frees a buffer that was previously allocated with one of the aligned pool allocation functions
863 in the Memory Allocation Library.
864
865 @param Buffer Pointer to the buffer to free.
866
867 **/
868 VOID
869 EFIAPI
870 FreeAlignedPool (
871 IN VOID *Buffer
872 )
873 {
874 VOID *RawAddress;
875 VOID **FreePointer;
876 EFI_STATUS Status;
877
878 //
879 // Get the pre-saved original address in the over-allocate pool.
880 //
881 FreePointer = (VOID **)((UINTN) Buffer - sizeof (RawAddress));
882 RawAddress = *FreePointer;
883
884 Status = gBS->FreePool (RawAddress);
885 ASSERT_EFI_ERROR (Status);
886 }