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