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