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