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