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