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