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