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