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