]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/DxeMemoryAllocationLib/MemoryAllocationLib.c
remove some comments introduced by tools.
[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 **/
14
15
16 #include <PiDxe.h>
17
18
19 #include <Library/MemoryAllocationLib.h>
20 #include <Library/UefiBootServicesTableLib.h>
21 #include <Library/BaseMemoryLib.h>
22 #include <Library/DebugLib.h>
23
24 #include "MemoryAllocationLibInternals.h"
25
26 /**
27 Allocates one or more 4KB pages of a certain memory type.
28
29 Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated
30 buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL is returned.
31 If there is not enough memory remaining to satisfy the request, then NULL is returned.
32
33 @param MemoryType The type of memory to allocate.
34 @param Pages The number of 4 KB pages to allocate.
35
36 @return A pointer to the allocated buffer or NULL if allocation fails.
37
38 **/
39 VOID *
40 InternalAllocatePages (
41 IN EFI_MEMORY_TYPE MemoryType,
42 IN UINTN Pages
43 )
44 {
45 EFI_STATUS Status;
46 EFI_PHYSICAL_ADDRESS Memory;
47
48 if (Pages == 0) {
49 return NULL;
50 }
51
52 Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);
53 if (EFI_ERROR (Status)) {
54 Memory = 0;
55 }
56 return (VOID *) (UINTN) Memory;
57 }
58
59 /**
60 Allocates one or more 4KB pages of type EfiBootServicesData.
61
62 Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the
63 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
64 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
65 returned.
66
67 @param Pages The number of 4 KB pages to allocate.
68
69 @return A pointer to the allocated buffer or NULL if allocation fails.
70
71 **/
72 VOID *
73 EFIAPI
74 AllocatePages (
75 IN UINTN Pages
76 )
77 {
78 return InternalAllocatePages (EfiBootServicesData, Pages);
79 }
80
81 /**
82 Allocates one or more 4KB pages of type EfiRuntimeServicesData.
83
84 Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
85 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
86 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
87 returned.
88
89 @param Pages The number of 4 KB pages to allocate.
90
91 @return A pointer to the allocated buffer or NULL if allocation fails.
92
93 **/
94 VOID *
95 EFIAPI
96 AllocateRuntimePages (
97 IN UINTN Pages
98 )
99 {
100 return InternalAllocatePages (EfiRuntimeServicesData, Pages);
101 }
102
103 /**
104 Allocates one or more 4KB pages of type EfiReservedMemoryType.
105
106 Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the
107 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
108 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
109 returned.
110
111 @param Pages The number of 4 KB pages to allocate.
112
113 @return A pointer to the allocated buffer or NULL if allocation fails.
114
115 **/
116 VOID *
117 EFIAPI
118 AllocateReservedPages (
119 IN UINTN Pages
120 )
121 {
122 return InternalAllocatePages (EfiReservedMemoryType, Pages);
123 }
124
125 /**
126 Frees one or more 4KB pages that were previously allocated with one of the page allocation
127 functions in the Memory Allocation Library.
128
129 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
130 must have been allocated on a previous call to the page allocation services of the Memory
131 Allocation Library.
132 If Buffer was not allocated with a page allocation function in the Memory Allocation Library,
133 then ASSERT().
134 If Pages is zero, then ASSERT().
135
136 @param Buffer Pointer to the buffer of pages to free.
137 @param Pages The number of 4 KB pages to free.
138
139 **/
140 VOID
141 EFIAPI
142 FreePages (
143 IN VOID *Buffer,
144 IN UINTN Pages
145 )
146 {
147 EFI_STATUS Status;
148
149 ASSERT (Pages != 0);
150 Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
151 ASSERT_EFI_ERROR (Status);
152 }
153
154 /**
155 Allocates one or more 4KB pages of a certain memory type at a specified alignment.
156
157 Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment
158 specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned.
159 If there is not enough memory at the specified alignment remaining to satisfy the request, then
160 NULL is returned.
161 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
162
163 @param MemoryType The type of memory to allocate.
164 @param Pages The number of 4 KB pages to allocate.
165 @param Alignment The requested alignment of the allocation. Must be a power of two.
166 If Alignment is zero, then byte alignment is used.
167
168 @return A pointer to the allocated buffer or NULL if allocation fails.
169
170 **/
171 VOID *
172 InternalAllocateAlignedPages (
173 IN EFI_MEMORY_TYPE MemoryType,
174 IN UINTN Pages,
175 IN UINTN Alignment
176 )
177 {
178 EFI_STATUS Status;
179 EFI_PHYSICAL_ADDRESS Memory;
180 UINTN AlignedMemory;
181 UINTN AlignmentMask;
182 UINTN UnalignedPages;
183 UINTN RealPages;
184
185 //
186 // Alignment must be a power of two or zero.
187 //
188 ASSERT ((Alignment & (Alignment - 1)) == 0);
189
190 if (Pages == 0) {
191 return NULL;
192 }
193 if (Alignment > EFI_PAGE_SIZE) {
194 //
195 // Caculate the total number of pages since alignment is larger than page size.
196 //
197 AlignmentMask = Alignment - 1;
198 RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment);
199 //
200 // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
201 //
202 ASSERT (RealPages > Pages);
203
204 Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory);
205 if (EFI_ERROR (Status)) {
206 return NULL;
207 }
208 AlignedMemory = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask;
209 UnalignedPages = EFI_SIZE_TO_PAGES ((UINTN) Memory - AlignedMemory);
210 if (UnalignedPages > 0) {
211 //
212 // Free first unaligned page(s).
213 //
214 Status = gBS->FreePages (Memory, UnalignedPages);
215 ASSERT_EFI_ERROR (Status);
216 }
217 Memory = (EFI_PHYSICAL_ADDRESS) (AlignedMemory + EFI_PAGES_TO_SIZE (Pages));
218 UnalignedPages = RealPages - Pages - UnalignedPages;
219 if (UnalignedPages > 0) {
220 //
221 // Free last unaligned page(s).
222 //
223 Status = gBS->FreePages (Memory, UnalignedPages);
224 ASSERT_EFI_ERROR (Status);
225 }
226 } else {
227 //
228 // Do not over-allocate pages in this case.
229 //
230 Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);
231 if (EFI_ERROR (Status)) {
232 return NULL;
233 }
234 AlignedMemory = (UINTN) Memory;
235 }
236 return (VOID *) AlignedMemory;
237 }
238
239 /**
240 Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment.
241
242 Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an
243 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
244 returned. If there is not enough memory at the specified alignment remaining to satisfy the
245 request, then NULL is returned.
246 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
247
248 @param Pages The number of 4 KB pages to allocate.
249 @param Alignment The requested alignment of the allocation. Must be a power of two.
250 If Alignment is zero, then byte alignment is used.
251
252 @return A pointer to the allocated buffer or NULL if allocation fails.
253
254 **/
255 VOID *
256 EFIAPI
257 AllocateAlignedPages (
258 IN UINTN Pages,
259 IN UINTN Alignment
260 )
261 {
262 return InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment);
263 }
264
265 /**
266 Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
267
268 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an
269 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
270 returned. If there is not enough memory at the specified alignment remaining to satisfy the
271 request, then NULL is returned.
272 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
273
274 @param Pages The number of 4 KB pages to allocate.
275 @param Alignment The requested alignment of the allocation. Must be a power of two.
276 If Alignment is zero, then byte alignment is used.
277
278 @return A pointer to the allocated buffer or NULL if allocation fails.
279
280 **/
281 VOID *
282 EFIAPI
283 AllocateAlignedRuntimePages (
284 IN UINTN Pages,
285 IN UINTN Alignment
286 )
287 {
288 return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);
289 }
290
291 /**
292 Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
293
294 Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an
295 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
296 returned. If there is not enough memory at the specified alignment remaining to satisfy the
297 request, then NULL is returned.
298 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
299
300 @param Pages The number of 4 KB pages to allocate.
301 @param Alignment The requested alignment of the allocation. Must be a power of two.
302 If Alignment is zero, then byte alignment is used.
303
304 @return A pointer to the allocated buffer or NULL if allocation fails.
305
306 **/
307 VOID *
308 EFIAPI
309 AllocateAlignedReservedPages (
310 IN UINTN Pages,
311 IN UINTN Alignment
312 )
313 {
314 return InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment);
315 }
316
317 /**
318 Frees one or more 4KB pages that were previously allocated with one of the aligned page
319 allocation functions in the Memory Allocation Library.
320
321 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
322 must have been allocated on a previous call to the aligned page allocation services of the Memory
323 Allocation Library.
324 If Buffer was not allocated with an aligned page allocation function in the Memory Allocation
325 Library, then ASSERT().
326 If Pages is zero, then ASSERT().
327
328 @param Buffer Pointer to the buffer of pages to free.
329 @param Pages The number of 4 KB pages to free.
330
331 **/
332 VOID
333 EFIAPI
334 FreeAlignedPages (
335 IN VOID *Buffer,
336 IN UINTN Pages
337 )
338 {
339 EFI_STATUS Status;
340
341 ASSERT (Pages != 0);
342 Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
343 ASSERT_EFI_ERROR (Status);
344 }
345
346 /**
347 Allocates a buffer of a certain pool type.
348
349 Allocates the number bytes specified by AllocationSize of a certain pool type and returns a
350 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
351 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
352
353 @param MemoryType The type of memory to allocate.
354 @param AllocationSize The number of bytes to allocate.
355
356 @return A pointer to the allocated buffer or NULL if allocation fails.
357
358 **/
359 VOID *
360 InternalAllocatePool (
361 IN EFI_MEMORY_TYPE MemoryType,
362 IN UINTN AllocationSize
363 )
364 {
365 EFI_STATUS Status;
366 VOID *Memory;
367
368 Status = gBS->AllocatePool (MemoryType, AllocationSize, &Memory);
369 if (EFI_ERROR (Status)) {
370 Memory = NULL;
371 }
372 return Memory;
373 }
374
375 /**
376 Allocates a buffer of type EfiBootServicesData.
377
378 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a
379 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
380 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
381
382 @param AllocationSize The number of bytes to allocate.
383
384 @return A pointer to the allocated buffer or NULL if allocation fails.
385
386 **/
387 VOID *
388 EFIAPI
389 AllocatePool (
390 IN UINTN AllocationSize
391 )
392 {
393 return InternalAllocatePool (EfiBootServicesData, AllocationSize);
394 }
395
396 /**
397 Allocates a buffer of type EfiRuntimeServicesData.
398
399 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns
400 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
401 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
402
403 @param AllocationSize The number of bytes to allocate.
404
405 @return A pointer to the allocated buffer or NULL if allocation fails.
406
407 **/
408 VOID *
409 EFIAPI
410 AllocateRuntimePool (
411 IN UINTN AllocationSize
412 )
413 {
414 return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
415 }
416
417 /**
418 Allocates a buffer of type EfieservedMemoryType.
419
420 Allocates the number bytes specified by AllocationSize of type EfieservedMemoryType and returns
421 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
422 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
423
424 @param AllocationSize The number of bytes to allocate.
425
426 @return A pointer to the allocated buffer or NULL if allocation fails.
427
428 **/
429 VOID *
430 EFIAPI
431 AllocateReservedPool (
432 IN UINTN AllocationSize
433 )
434 {
435 return InternalAllocatePool (EfiReservedMemoryType, AllocationSize);
436 }
437
438 /**
439 Allocates and zeros a buffer of a certian pool type.
440
441 Allocates the number bytes specified by AllocationSize of a certian pool type, clears the buffer
442 with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid
443 buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request,
444 then NULL is returned.
445
446 @param PoolType The type of memory to allocate.
447 @param AllocationSize The number of bytes to allocate and zero.
448
449 @return A pointer to the allocated buffer or NULL if allocation fails.
450
451 **/
452 VOID *
453 InternalAllocateZeroPool (
454 IN EFI_MEMORY_TYPE PoolType,
455 IN UINTN AllocationSize
456 )
457 {
458 VOID *Memory;
459
460 Memory = InternalAllocatePool (PoolType, AllocationSize);
461 if (Memory != NULL) {
462 Memory = ZeroMem (Memory, AllocationSize);
463 }
464 return Memory;
465 }
466
467 /**
468 Allocates and zeros a buffer of type EfiBootServicesData.
469
470 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
471 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
472 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
473 request, then NULL is returned.
474
475 @param AllocationSize The number of bytes to allocate and zero.
476
477 @return A pointer to the allocated buffer or NULL if allocation fails.
478
479 **/
480 VOID *
481 EFIAPI
482 AllocateZeroPool (
483 IN UINTN AllocationSize
484 )
485 {
486 return InternalAllocateZeroPool (EfiBootServicesData, AllocationSize);
487 }
488
489 /**
490 Allocates and zeros a buffer of type EfiRuntimeServicesData.
491
492 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the
493 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
494 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
495 request, then NULL is returned.
496
497 @param AllocationSize The number of bytes to allocate and zero.
498
499 @return A pointer to the allocated buffer or NULL if allocation fails.
500
501 **/
502 VOID *
503 EFIAPI
504 AllocateRuntimeZeroPool (
505 IN UINTN AllocationSize
506 )
507 {
508 return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);
509 }
510
511 /**
512 Allocates and zeros a buffer of type EfiReservedMemoryType.
513
514 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the
515 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
516 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
517 request, then NULL is returned.
518
519 @param AllocationSize The number of bytes to allocate and zero.
520
521 @return A pointer to the allocated buffer or NULL if allocation fails.
522
523 **/
524 VOID *
525 EFIAPI
526 AllocateReservedZeroPool (
527 IN UINTN AllocationSize
528 )
529 {
530 return InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);
531 }
532
533 /**
534 Copies a buffer to an allocated buffer of a certian pool type.
535
536 Allocates the number bytes specified by AllocationSize of a certian pool type, copies
537 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
538 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
539 is not enough memory remaining to satisfy the request, then NULL is returned.
540 If Buffer is NULL, then ASSERT().
541 If AllocationSize is greater than (MAX_ADDRESS ? Buffer + 1), then ASSERT().
542
543 @param PoolType The type of pool to allocate.
544 @param AllocationSize The number of bytes to allocate and zero.
545 @param Buffer The buffer to copy to the allocated buffer.
546
547 @return A pointer to the allocated buffer or NULL if allocation fails.
548
549 **/
550 VOID *
551 InternalAllocateCopyPool (
552 IN EFI_MEMORY_TYPE PoolType,
553 IN UINTN AllocationSize,
554 IN CONST VOID *Buffer
555 )
556 {
557 VOID *Memory;
558
559 ASSERT (Buffer != NULL);
560 ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
561
562 Memory = InternalAllocatePool (PoolType, AllocationSize);
563 if (Memory != NULL) {
564 Memory = CopyMem (Memory, Buffer, AllocationSize);
565 }
566 return Memory;
567 }
568
569 /**
570 Copies a buffer to an allocated buffer of type EfiBootServicesData.
571
572 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies
573 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
574 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
575 is not enough memory remaining to satisfy the request, then NULL is returned.
576 If Buffer is NULL, then ASSERT().
577 If AllocationSize is greater than (MAX_ADDRESS ? Buffer + 1), then ASSERT().
578
579 @param AllocationSize The number of bytes to allocate and zero.
580 @param Buffer The buffer to copy to the allocated buffer.
581
582 @return A pointer to the allocated buffer or NULL if allocation fails.
583
584 **/
585 VOID *
586 EFIAPI
587 AllocateCopyPool (
588 IN UINTN AllocationSize,
589 IN CONST VOID *Buffer
590 )
591 {
592 return InternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer);
593 }
594
595 /**
596 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
597
598 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies
599 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
600 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
601 is not enough memory remaining to satisfy the request, then NULL is returned.
602 If Buffer is NULL, then ASSERT().
603 If AllocationSize is greater than (MAX_ADDRESS ? Buffer + 1), then ASSERT().
604
605 @param AllocationSize The number of bytes to allocate and zero.
606 @param Buffer The buffer to copy to the allocated buffer.
607
608 @return A pointer to the allocated buffer or NULL if allocation fails.
609
610 **/
611 VOID *
612 EFIAPI
613 AllocateRuntimeCopyPool (
614 IN UINTN AllocationSize,
615 IN CONST VOID *Buffer
616 )
617 {
618 return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);
619 }
620
621 /**
622 Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
623
624 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies
625 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
626 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
627 is not enough memory remaining to satisfy the request, then NULL is returned.
628 If Buffer is NULL, then ASSERT().
629 If AllocationSize is greater than (MAX_ADDRESS ? Buffer + 1), then ASSERT().
630
631 @param AllocationSize The number of bytes to allocate and zero.
632 @param Buffer The buffer to copy to the allocated buffer.
633
634 @return A pointer to the allocated buffer or NULL if allocation fails.
635
636 **/
637 VOID *
638 EFIAPI
639 AllocateReservedCopyPool (
640 IN UINTN AllocationSize,
641 IN CONST VOID *Buffer
642 )
643 {
644 return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);
645 }
646
647 /**
648 Frees a buffer that was previously allocated with one of the pool allocation functions in the
649 Memory Allocation Library.
650
651 Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the
652 pool allocation services of the Memory Allocation Library.
653 If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
654 then ASSERT().
655
656 @param Buffer Pointer to the buffer to free.
657
658 **/
659 VOID
660 EFIAPI
661 FreePool (
662 IN VOID *Buffer
663 )
664 {
665 EFI_STATUS Status;
666
667 Status = gBS->FreePool (Buffer);
668 ASSERT_EFI_ERROR (Status);
669 }
670
671 /**
672 Allocates a buffer of a certain pool type at a specified alignment.
673
674 Allocates the number bytes specified by AllocationSize of a certain pool type with an alignment
675 specified by Alignment. The allocated buffer is returned. If AllocationSize is 0, then a valid
676 buffer of 0 size is returned. If there is not enough memory at the specified alignment remaining
677 to satisfy the request, then NULL is returned.
678 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
679
680 @param PoolType The type of pool to allocate.
681 @param AllocationSize The number of bytes to allocate.
682 @param Alignment The requested alignment of the allocation. Must be a power of two. If Alignment is zero, then byte alignment is used.
683 If Alignment is zero, then byte alignment is used.
684
685 @return A pointer to the allocated buffer or NULL if allocation fails.
686
687 **/
688 VOID *
689 InternalAllocateAlignedPool (
690 IN EFI_MEMORY_TYPE PoolType,
691 IN UINTN AllocationSize,
692 IN UINTN Alignment
693 )
694 {
695 VOID *RawAddress;
696 UINTN AlignedAddress;
697 UINTN AlignmentMask;
698 UINTN OverAllocationSize;
699 UINTN RealAllocationSize;
700 VOID **FreePointer;
701
702 //
703 // Alignment must be a power of two or zero.
704 //
705 ASSERT ((Alignment & (Alignment - 1)) == 0);
706
707 if (Alignment == 0) {
708 AlignmentMask = Alignment;
709 } else {
710 AlignmentMask = Alignment - 1;
711 }
712 //
713 // Calculate the extra memory size, over-allocate memory pool and get the aligned memory address.
714 //
715 OverAllocationSize = sizeof (RawAddress) + AlignmentMask;
716 RealAllocationSize = AllocationSize + OverAllocationSize;
717 //
718 // Make sure that AllocationSize plus OverAllocationSize does not overflow.
719 //
720 ASSERT (RealAllocationSize > AllocationSize);
721
722 RawAddress = InternalAllocatePool (PoolType, RealAllocationSize);
723 if (RawAddress == NULL) {
724 return NULL;
725 }
726 AlignedAddress = ((UINTN) RawAddress + OverAllocationSize) & ~AlignmentMask;
727 //
728 // Save the original memory address just before the aligned address.
729 //
730 FreePointer = (VOID **)(AlignedAddress - sizeof (RawAddress));
731 *FreePointer = RawAddress;
732
733 return (VOID *) AlignedAddress;
734 }
735
736 /**
737 Allocates a buffer of type EfiBootServicesData at a specified alignment.
738
739 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData with an
740 alignment specified by Alignment. The allocated buffer is returned. If AllocationSize is 0,
741 then a valid buffer of 0 size is returned. If there is not enough memory at the specified
742 alignment remaining to satisfy the request, then NULL is returned.
743 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
744
745 @param AllocationSize The number of bytes to allocate.
746 @param Alignment The requested alignment of the allocation. Must be a power of two.
747 If Alignment is zero, then byte alignment is used.
748
749 @return A pointer to the allocated buffer or NULL if allocation fails.
750
751 **/
752 VOID *
753 EFIAPI
754 AllocateAlignedPool (
755 IN UINTN AllocationSize,
756 IN UINTN Alignment
757 )
758 {
759 return InternalAllocateAlignedPool (EfiBootServicesData, AllocationSize, Alignment);
760 }
761
762 /**
763 Allocates a buffer of type EfiRuntimeServicesData at a specified alignment.
764
765 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData with an
766 alignment specified by Alignment. The allocated buffer is returned. If AllocationSize is 0,
767 then a valid buffer of 0 size is returned. If there is not enough memory at the specified
768 alignment remaining to satisfy the request, then NULL is returned.
769 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
770
771 @param AllocationSize The number of bytes to allocate.
772 @param Alignment The requested alignment of the allocation. Must be a power of two.
773 If Alignment is zero, then byte alignment is used.
774
775 @return A pointer to the allocated buffer or NULL if allocation fails.
776
777 **/
778 VOID *
779 EFIAPI
780 AllocateAlignedRuntimePool (
781 IN UINTN AllocationSize,
782 IN UINTN Alignment
783 )
784 {
785 return InternalAllocateAlignedPool (EfiRuntimeServicesData, AllocationSize, Alignment);
786 }
787
788 /**
789 Allocates a buffer of type EfieservedMemoryType at a specified alignment.
790
791 Allocates the number bytes specified by AllocationSize of type EfieservedMemoryType with an
792 alignment specified by Alignment. The allocated buffer is returned. If AllocationSize is 0,
793 then a valid buffer of 0 size is returned. If there is not enough memory at the specified
794 alignment remaining to satisfy the request, then NULL is returned.
795 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
796
797 @param AllocationSize The number of bytes to allocate.
798 @param Alignment The requested alignment of the allocation. Must be a power of two.
799 If Alignment is zero, then byte alignment is used.
800
801 @return A pointer to the allocated buffer or NULL if allocation fails.
802
803 **/
804 VOID *
805 EFIAPI
806 AllocateAlignedReservedPool (
807 IN UINTN AllocationSize,
808 IN UINTN Alignment
809 )
810 {
811 return InternalAllocateAlignedPool (EfiReservedMemoryType, AllocationSize, Alignment);
812 }
813
814 /**
815 Allocates and zeros a buffer of a certain pool type at a specified alignment.
816
817 Allocates the number bytes specified by AllocationSize of a certain pool type with an alignment
818 specified by Alignment, clears the buffer with zeros, and returns a pointer to the allocated
819 buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is not
820 enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.
821 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
822
823 @param PoolType The type of pool to allocate.
824 @param AllocationSize The number of bytes to allocate.
825 @param Alignment The requested alignment of the allocation. Must be a power of two.
826 If Alignment is zero, then byte alignment is used.
827
828 @return A pointer to the allocated buffer or NULL if allocation fails.
829
830 **/
831 VOID *
832 InternalAllocateAlignedZeroPool (
833 IN EFI_MEMORY_TYPE PoolType,
834 IN UINTN AllocationSize,
835 IN UINTN Alignment
836 )
837 {
838 VOID *Memory;
839 Memory = InternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);
840 if (Memory != NULL) {
841 Memory = ZeroMem (Memory, AllocationSize);
842 }
843 return Memory;
844 }
845
846 /**
847 Allocates and zeros a buffer of type EfiBootServicesData at a specified alignment.
848
849 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData with an
850 alignment specified by Alignment, clears the buffer with zeros, and returns a pointer to the
851 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
852 is not enough memory at the specified alignment remaining to satisfy the request, then NULL is
853 returned.
854 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
855
856 @param AllocationSize The number of bytes to allocate.
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 or NULL if allocation fails.
861
862 **/
863 VOID *
864 EFIAPI
865 AllocateAlignedZeroPool (
866 IN UINTN AllocationSize,
867 IN UINTN Alignment
868 )
869 {
870 return InternalAllocateAlignedZeroPool (EfiBootServicesData, AllocationSize, Alignment);
871 }
872
873 /**
874 Allocates and zeros a buffer of type EfiRuntimeServicesData at a specified alignment.
875
876 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData with an
877 alignment specified by Alignment, clears the buffer with zeros, and returns a pointer to the
878 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
879 is not enough memory at the specified alignment remaining to satisfy the request, then NULL is
880 returned.
881 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
882
883 @param AllocationSize The number of bytes to allocate.
884 @param Alignment The requested alignment of the allocation. Must be a power of two.
885 If Alignment is zero, then byte alignment is used.
886
887 @return A pointer to the allocated buffer or NULL if allocation fails.
888
889 **/
890 VOID *
891 EFIAPI
892 AllocateAlignedRuntimeZeroPool (
893 IN UINTN AllocationSize,
894 IN UINTN Alignment
895 )
896 {
897 return InternalAllocateAlignedZeroPool (EfiRuntimeServicesData, AllocationSize, Alignment);
898 }
899
900 /**
901 Allocates and zeros a buffer of type EfieservedMemoryType at a specified alignment.
902
903 Allocates the number bytes specified by AllocationSize of type EfieservedMemoryType with an
904 alignment specified by Alignment, clears the buffer with zeros, and returns a pointer to the
905 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
906 is not enough memory at the specified alignment remaining to satisfy the request, then NULL is
907 returned.
908 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
909
910 @param AllocationSize The number of bytes to allocate.
911 @param Alignment The requested alignment of the allocation. Must be a power of two.
912 If Alignment is zero, then byte alignment is used.
913
914 @return A pointer to the allocated buffer or NULL if allocation fails.
915
916 **/
917 VOID *
918 EFIAPI
919 AllocateAlignedReservedZeroPool (
920 IN UINTN AllocationSize,
921 IN UINTN Alignment
922 )
923 {
924 return InternalAllocateAlignedZeroPool (EfiReservedMemoryType, AllocationSize, Alignment);
925 }
926
927 /**
928 Copies a buffer to an allocated buffer of a certain pool type at a specified alignment.
929
930 Allocates the number bytes specified by AllocationSize of a certain pool type with an alignment
931 specified by Alignment. The allocated buffer is returned. If AllocationSize is 0, then a valid
932 buffer of 0 size is returned. If there is not enough memory at the specified alignment remaining
933 to satisfy the request, then NULL is returned.
934 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
935
936 @param PoolType The type of pool to allocate.
937 @param AllocationSize The number of bytes to allocate.
938 @param Buffer The buffer to copy to the allocated buffer.
939 @param Alignment The requested alignment of the allocation. Must be a power of two.
940 If Alignment is zero, then byte alignment is used.
941
942 @return A pointer to the allocated buffer or NULL if allocation fails.
943
944 **/
945 VOID *
946 InternalAllocateAlignedCopyPool (
947 IN EFI_MEMORY_TYPE PoolType,
948 IN UINTN AllocationSize,
949 IN CONST VOID *Buffer,
950 IN UINTN Alignment
951 )
952 {
953 VOID *Memory;
954
955 ASSERT (Buffer != NULL);
956 ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
957
958 Memory = InternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);
959 if (Memory != NULL) {
960 Memory = CopyMem (Memory, Buffer, AllocationSize);
961 }
962 return Memory;
963 }
964
965 /**
966 Copies a buffer to an allocated buffer of type EfiBootServicesData at a specified alignment.
967
968 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData type with an
969 alignment specified by Alignment. The allocated buffer is returned. If AllocationSize is 0,
970 then a valid buffer of 0 size is returned. If there is not enough memory at the specified
971 alignment remaining to satisfy the request, then NULL is returned.
972 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
973
974 @param AllocationSize The number of bytes to allocate.
975 @param Buffer The buffer to copy to the allocated buffer.
976 @param Alignment The requested alignment of the allocation. Must be a power of two.
977 If Alignment is zero, then byte alignment is used.
978
979 @return A pointer to the allocated buffer or NULL if allocation fails.
980
981 **/
982 VOID *
983 EFIAPI
984 AllocateAlignedCopyPool (
985 IN UINTN AllocationSize,
986 IN CONST VOID *Buffer,
987 IN UINTN Alignment
988 )
989 {
990 return InternalAllocateAlignedCopyPool (EfiBootServicesData, AllocationSize, Buffer, Alignment);
991 }
992
993 /**
994 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData at a specified alignment.
995
996 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData type with an
997 alignment specified by Alignment. The allocated buffer is returned. If AllocationSize is 0,
998 then a valid buffer of 0 size is returned. If there is not enough memory at the specified
999 alignment remaining to satisfy the request, then NULL is returned.
1000 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
1001
1002 @param AllocationSize The number of bytes to allocate.
1003 @param Buffer The buffer to copy to the allocated buffer.
1004 @param Alignment The requested alignment of the allocation. Must be a power of two.
1005 If Alignment is zero, then byte alignment is used.
1006
1007 @return A pointer to the allocated buffer or NULL if allocation fails.
1008
1009 **/
1010 VOID *
1011 EFIAPI
1012 AllocateAlignedRuntimeCopyPool (
1013 IN UINTN AllocationSize,
1014 IN CONST VOID *Buffer,
1015 IN UINTN Alignment
1016 )
1017 {
1018 return InternalAllocateAlignedCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer, Alignment);
1019 }
1020
1021 /**
1022 Copies a buffer to an allocated buffer of type EfiReservedMemoryType at a specified alignment.
1023
1024 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType type with an
1025 alignment specified by Alignment. The allocated buffer is returned. If AllocationSize is 0,
1026 then a valid buffer of 0 size is returned. If there is not enough memory at the specified
1027 alignment remaining to satisfy the request, then NULL is returned.
1028 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
1029
1030 @param AllocationSize The number of bytes to allocate.
1031 @param Buffer The buffer to copy to the allocated buffer.
1032 @param Alignment The requested alignment of the allocation. Must be a power of two.
1033 If Alignment is zero, then byte alignment is used.
1034
1035 @return A pointer to the allocated buffer or NULL if allocation fails.
1036
1037 **/
1038 VOID *
1039 EFIAPI
1040 AllocateAlignedReservedCopyPool (
1041 IN UINTN AllocationSize,
1042 IN CONST VOID *Buffer,
1043 IN UINTN Alignment
1044 )
1045 {
1046 return InternalAllocateAlignedCopyPool (EfiReservedMemoryType, AllocationSize, Buffer, Alignment);
1047 }
1048
1049 /**
1050 Frees a buffer that was previously allocated with one of the aligned pool allocation functions
1051 in the Memory Allocation Library.
1052
1053 Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the
1054 aligned pool allocation services of the Memory Allocation Library.
1055 If Buffer was not allocated with an aligned pool allocation function in the Memory Allocation
1056 Library, then ASSERT().
1057
1058 @param Buffer Pointer to the buffer to free.
1059
1060 **/
1061 VOID
1062 EFIAPI
1063 FreeAlignedPool (
1064 IN VOID *Buffer
1065 )
1066 {
1067 VOID *RawAddress;
1068 VOID **FreePointer;
1069 EFI_STATUS Status;
1070
1071 //
1072 // Get the pre-saved original address in the over-allocate pool.
1073 //
1074 FreePointer = (VOID **)((UINTN) Buffer - sizeof (RawAddress));
1075 RawAddress = *FreePointer;
1076
1077 Status = gBS->FreePool (RawAddress);
1078 ASSERT_EFI_ERROR (Status);
1079 }