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