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