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