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