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