1 /** @file 2 The internal header file includes the common header files, defines 3 internal structure and functions used by SmmCore module. 4 5 Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR> 6 This program and the accompanying materials are licensed and made available 7 under the terms and conditions of the BSD License which accompanies this 8 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 #ifndef _SMM_CORE_H_ 17 #define _SMM_CORE_H_ 18 19 #include <PiSmm.h> 20 21 #include <Protocol/DxeSmmReadyToLock.h> 22 #include <Protocol/SmmReadyToLock.h> 23 #include <Protocol/SmmEndOfDxe.h> 24 #include <Protocol/CpuIo2.h> 25 #include <Protocol/SmmCommunication.h> 26 #include <Protocol/SmmAccess2.h> 27 #include <Protocol/FirmwareVolume2.h> 28 #include <Protocol/LoadedImage.h> 29 #include <Protocol/DevicePath.h> 30 #include <Protocol/Security.h> 31 #include <Protocol/Security2.h> 32 #include <Protocol/SmmExitBootServices.h> 33 #include <Protocol/SmmLegacyBoot.h> 34 #include <Protocol/SmmReadyToBoot.h> 35 36 #include <Guid/Apriori.h> 37 #include <Guid/EventGroup.h> 38 #include <Guid/EventLegacyBios.h> 39 #include <Guid/MemoryProfile.h> 40 #include <Guid/LoadModuleAtFixedAddress.h> 41 42 #include <Library/BaseLib.h> 43 #include <Library/BaseMemoryLib.h> 44 #include <Library/PeCoffLib.h> 45 #include <Library/PeCoffGetEntryPointLib.h> 46 #include <Library/CacheMaintenanceLib.h> 47 #include <Library/DebugLib.h> 48 #include <Library/ReportStatusCodeLib.h> 49 #include <Library/MemoryAllocationLib.h> 50 #include <Library/DevicePathLib.h> 51 #include <Library/UefiLib.h> 52 #include <Library/UefiBootServicesTableLib.h> 53 #include <Library/PcdLib.h> 54 #include <Library/SmmCorePlatformHookLib.h> 55 #include <Library/PerformanceLib.h> 56 #include <Library/TimerLib.h> 57 #include <Library/HobLib.h> 58 #include <Library/SmmMemLib.h> 59 60 #include "PiSmmCorePrivateData.h" 61 62 // 63 // Used to build a table of SMI Handlers that the SMM Core registers 64 // 65 typedef struct { 66 EFI_SMM_HANDLER_ENTRY_POINT2 Handler; 67 EFI_GUID *HandlerType; 68 EFI_HANDLE DispatchHandle; 69 BOOLEAN UnRegister; 70 } SMM_CORE_SMI_HANDLERS; 71 72 // 73 // Structure for recording the state of an SMM Driver 74 // 75 #define EFI_SMM_DRIVER_ENTRY_SIGNATURE SIGNATURE_32('s', 'd','r','v') 76 77 typedef struct { 78 UINTN Signature; 79 LIST_ENTRY Link; // mDriverList 80 81 LIST_ENTRY ScheduledLink; // mScheduledQueue 82 83 EFI_HANDLE FvHandle; 84 EFI_GUID FileName; 85 EFI_DEVICE_PATH_PROTOCOL *FvFileDevicePath; 86 EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv; 87 88 VOID *Depex; 89 UINTN DepexSize; 90 91 BOOLEAN Before; 92 BOOLEAN After; 93 EFI_GUID BeforeAfterGuid; 94 95 BOOLEAN Dependent; 96 BOOLEAN Scheduled; 97 BOOLEAN Initialized; 98 BOOLEAN DepexProtocolError; 99 100 EFI_HANDLE ImageHandle; 101 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; 102 // 103 // Image EntryPoint in SMRAM 104 // 105 PHYSICAL_ADDRESS ImageEntryPoint; 106 // 107 // Image Buffer in SMRAM 108 // 109 PHYSICAL_ADDRESS ImageBuffer; 110 // 111 // Image Page Number 112 // 113 UINTN NumberOfPage; 114 EFI_HANDLE SmmImageHandle; 115 EFI_LOADED_IMAGE_PROTOCOL SmmLoadedImage; 116 } EFI_SMM_DRIVER_ENTRY; 117 118 #define EFI_HANDLE_SIGNATURE SIGNATURE_32('h','n','d','l') 119 120 /// 121 /// IHANDLE - contains a list of protocol handles 122 /// 123 typedef struct { 124 UINTN Signature; 125 /// All handles list of IHANDLE 126 LIST_ENTRY AllHandles; 127 /// List of PROTOCOL_INTERFACE's for this handle 128 LIST_ENTRY Protocols; 129 UINTN LocateRequest; 130 } IHANDLE; 131 132 #define ASSERT_IS_HANDLE(a) ASSERT((a)->Signature == EFI_HANDLE_SIGNATURE) 133 134 #define PROTOCOL_ENTRY_SIGNATURE SIGNATURE_32('p','r','t','e') 135 136 /// 137 /// PROTOCOL_ENTRY - each different protocol has 1 entry in the protocol 138 /// database. Each handler that supports this protocol is listed, along 139 /// with a list of registered notifies. 140 /// 141 typedef struct { 142 UINTN Signature; 143 /// Link Entry inserted to mProtocolDatabase 144 LIST_ENTRY AllEntries; 145 /// ID of the protocol 146 EFI_GUID ProtocolID; 147 /// All protocol interfaces 148 LIST_ENTRY Protocols; 149 /// Registerd notification handlers 150 LIST_ENTRY Notify; 151 } PROTOCOL_ENTRY; 152 153 #define PROTOCOL_INTERFACE_SIGNATURE SIGNATURE_32('p','i','f','c') 154 155 /// 156 /// PROTOCOL_INTERFACE - each protocol installed on a handle is tracked 157 /// with a protocol interface structure 158 /// 159 typedef struct { 160 UINTN Signature; 161 /// Link on IHANDLE.Protocols 162 LIST_ENTRY Link; 163 /// Back pointer 164 IHANDLE *Handle; 165 /// Link on PROTOCOL_ENTRY.Protocols 166 LIST_ENTRY ByProtocol; 167 /// The protocol ID 168 PROTOCOL_ENTRY *Protocol; 169 /// The interface value 170 VOID *Interface; 171 } PROTOCOL_INTERFACE; 172 173 #define PROTOCOL_NOTIFY_SIGNATURE SIGNATURE_32('p','r','t','n') 174 175 /// 176 /// PROTOCOL_NOTIFY - used for each register notification for a protocol 177 /// 178 typedef struct { 179 UINTN Signature; 180 PROTOCOL_ENTRY *Protocol; 181 /// All notifications for this protocol 182 LIST_ENTRY Link; 183 /// Notification function 184 EFI_SMM_NOTIFY_FN Function; 185 /// Last position notified 186 LIST_ENTRY *Position; 187 } PROTOCOL_NOTIFY; 188 189 // 190 // SMM Core Global Variables 191 // 192 extern SMM_CORE_PRIVATE_DATA *gSmmCorePrivate; 193 extern EFI_SMM_SYSTEM_TABLE2 gSmmCoreSmst; 194 extern LIST_ENTRY gHandleList; 195 extern EFI_PHYSICAL_ADDRESS gLoadModuleAtFixAddressSmramBase; 196 197 /** 198 Called to initialize the memory service. 199 200 @param SmramRangeCount Number of SMRAM Regions 201 @param SmramRanges Pointer to SMRAM Descriptors 202 203 **/ 204 VOID 205 SmmInitializeMemoryServices ( 206 IN UINTN SmramRangeCount, 207 IN EFI_SMRAM_DESCRIPTOR *SmramRanges 208 ); 209 210 /** 211 The SmmInstallConfigurationTable() function is used to maintain the list 212 of configuration tables that are stored in the System Management System 213 Table. The list is stored as an array of (GUID, Pointer) pairs. The list 214 must be allocated from pool memory with PoolType set to EfiRuntimeServicesData. 215 216 @param SystemTable A pointer to the SMM System Table (SMST). 217 @param Guid A pointer to the GUID for the entry to add, update, or remove. 218 @param Table A pointer to the buffer of the table to add. 219 @param TableSize The size of the table to install. 220 221 @retval EFI_SUCCESS The (Guid, Table) pair was added, updated, or removed. 222 @retval EFI_INVALID_PARAMETER Guid is not valid. 223 @retval EFI_NOT_FOUND An attempt was made to delete a non-existent entry. 224 @retval EFI_OUT_OF_RESOURCES There is not enough memory available to complete the operation. 225 226 **/ 227 EFI_STATUS 228 EFIAPI 229 SmmInstallConfigurationTable ( 230 IN CONST EFI_SMM_SYSTEM_TABLE2 *SystemTable, 231 IN CONST EFI_GUID *Guid, 232 IN VOID *Table, 233 IN UINTN TableSize 234 ); 235 236 /** 237 Wrapper function to SmmInstallProtocolInterfaceNotify. This is the public API which 238 Calls the private one which contains a BOOLEAN parameter for notifications 239 240 @param UserHandle The handle to install the protocol handler on, 241 or NULL if a new handle is to be allocated 242 @param Protocol The protocol to add to the handle 243 @param InterfaceType Indicates whether Interface is supplied in 244 native form. 245 @param Interface The interface for the protocol being added 246 247 @return Status code 248 249 **/ 250 EFI_STATUS 251 EFIAPI 252 SmmInstallProtocolInterface ( 253 IN OUT EFI_HANDLE *UserHandle, 254 IN EFI_GUID *Protocol, 255 IN EFI_INTERFACE_TYPE InterfaceType, 256 IN VOID *Interface 257 ); 258 259 /** 260 Allocates pages from the memory map. 261 262 @param Type The type of allocation to perform 263 @param MemoryType The type of memory to turn the allocated pages 264 into 265 @param NumberOfPages The number of pages to allocate 266 @param Memory A pointer to receive the base allocated memory 267 address 268 269 @retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in spec. 270 @retval EFI_NOT_FOUND Could not allocate pages match the requirement. 271 @retval EFI_OUT_OF_RESOURCES No enough pages to allocate. 272 @retval EFI_SUCCESS Pages successfully allocated. 273 274 **/ 275 EFI_STATUS 276 EFIAPI 277 SmmAllocatePages ( 278 IN EFI_ALLOCATE_TYPE Type, 279 IN EFI_MEMORY_TYPE MemoryType, 280 IN UINTN NumberOfPages, 281 OUT EFI_PHYSICAL_ADDRESS *Memory 282 ); 283 284 /** 285 Allocates pages from the memory map. 286 287 @param Type The type of allocation to perform 288 @param MemoryType The type of memory to turn the allocated pages 289 into 290 @param NumberOfPages The number of pages to allocate 291 @param Memory A pointer to receive the base allocated memory 292 address 293 294 @retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in spec. 295 @retval EFI_NOT_FOUND Could not allocate pages match the requirement. 296 @retval EFI_OUT_OF_RESOURCES No enough pages to allocate. 297 @retval EFI_SUCCESS Pages successfully allocated. 298 299 **/ 300 EFI_STATUS 301 EFIAPI 302 SmmInternalAllocatePages ( 303 IN EFI_ALLOCATE_TYPE Type, 304 IN EFI_MEMORY_TYPE MemoryType, 305 IN UINTN NumberOfPages, 306 OUT EFI_PHYSICAL_ADDRESS *Memory 307 ); 308 309 /** 310 Frees previous allocated pages. 311 312 @param Memory Base address of memory being freed 313 @param NumberOfPages The number of pages to free 314 315 @retval EFI_NOT_FOUND Could not find the entry that covers the range 316 @retval EFI_INVALID_PARAMETER Address not aligned, Address is zero or NumberOfPages is zero. 317 @return EFI_SUCCESS Pages successfully freed. 318 319 **/ 320 EFI_STATUS 321 EFIAPI 322 SmmFreePages ( 323 IN EFI_PHYSICAL_ADDRESS Memory, 324 IN UINTN NumberOfPages 325 ); 326 327 /** 328 Frees previous allocated pages. 329 330 @param Memory Base address of memory being freed 331 @param NumberOfPages The number of pages to free 332 333 @retval EFI_NOT_FOUND Could not find the entry that covers the range 334 @retval EFI_INVALID_PARAMETER Address not aligned, Address is zero or NumberOfPages is zero. 335 @return EFI_SUCCESS Pages successfully freed. 336 337 **/ 338 EFI_STATUS 339 EFIAPI 340 SmmInternalFreePages ( 341 IN EFI_PHYSICAL_ADDRESS Memory, 342 IN UINTN NumberOfPages 343 ); 344 345 /** 346 Allocate pool of a particular type. 347 348 @param PoolType Type of pool to allocate 349 @param Size The amount of pool to allocate 350 @param Buffer The address to return a pointer to the allocated 351 pool 352 353 @retval EFI_INVALID_PARAMETER PoolType not valid 354 @retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed. 355 @retval EFI_SUCCESS Pool successfully allocated. 356 357 **/ 358 EFI_STATUS 359 EFIAPI 360 SmmAllocatePool ( 361 IN EFI_MEMORY_TYPE PoolType, 362 IN UINTN Size, 363 OUT VOID **Buffer 364 ); 365 366 /** 367 Allocate pool of a particular type. 368 369 @param PoolType Type of pool to allocate 370 @param Size The amount of pool to allocate 371 @param Buffer The address to return a pointer to the allocated 372 pool 373 374 @retval EFI_INVALID_PARAMETER PoolType not valid 375 @retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed. 376 @retval EFI_SUCCESS Pool successfully allocated. 377 378 **/ 379 EFI_STATUS 380 EFIAPI 381 SmmInternalAllocatePool ( 382 IN EFI_MEMORY_TYPE PoolType, 383 IN UINTN Size, 384 OUT VOID **Buffer 385 ); 386 387 /** 388 Frees pool. 389 390 @param Buffer The allocated pool entry to free 391 392 @retval EFI_INVALID_PARAMETER Buffer is not a valid value. 393 @retval EFI_SUCCESS Pool successfully freed. 394 395 **/ 396 EFI_STATUS 397 EFIAPI 398 SmmFreePool ( 399 IN VOID *Buffer 400 ); 401 402 /** 403 Frees pool. 404 405 @param Buffer The allocated pool entry to free 406 407 @retval EFI_INVALID_PARAMETER Buffer is not a valid value. 408 @retval EFI_SUCCESS Pool successfully freed. 409 410 **/ 411 EFI_STATUS 412 EFIAPI 413 SmmInternalFreePool ( 414 IN VOID *Buffer 415 ); 416 417 /** 418 Installs a protocol interface into the boot services environment. 419 420 @param UserHandle The handle to install the protocol handler on, 421 or NULL if a new handle is to be allocated 422 @param Protocol The protocol to add to the handle 423 @param InterfaceType Indicates whether Interface is supplied in 424 native form. 425 @param Interface The interface for the protocol being added 426 @param Notify indicates whether notify the notification list 427 for this protocol 428 429 @retval EFI_INVALID_PARAMETER Invalid parameter 430 @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate 431 @retval EFI_SUCCESS Protocol interface successfully installed 432 433 **/ 434 EFI_STATUS 435 SmmInstallProtocolInterfaceNotify ( 436 IN OUT EFI_HANDLE *UserHandle, 437 IN EFI_GUID *Protocol, 438 IN EFI_INTERFACE_TYPE InterfaceType, 439 IN VOID *Interface, 440 IN BOOLEAN Notify 441 ); 442 443 /** 444 Uninstalls all instances of a protocol:interfacer from a handle. 445 If the last protocol interface is remove from the handle, the 446 handle is freed. 447 448 @param UserHandle The handle to remove the protocol handler from 449 @param Protocol The protocol, of protocol:interface, to remove 450 @param Interface The interface, of protocol:interface, to remove 451 452 @retval EFI_INVALID_PARAMETER Protocol is NULL. 453 @retval EFI_SUCCESS Protocol interface successfully uninstalled. 454 455 **/ 456 EFI_STATUS 457 EFIAPI 458 SmmUninstallProtocolInterface ( 459 IN EFI_HANDLE UserHandle, 460 IN EFI_GUID *Protocol, 461 IN VOID *Interface 462 ); 463 464 /** 465 Queries a handle to determine if it supports a specified protocol. 466 467 @param UserHandle The handle being queried. 468 @param Protocol The published unique identifier of the protocol. 469 @param Interface Supplies the address where a pointer to the 470 corresponding Protocol Interface is returned. 471 472 @return The requested protocol interface for the handle 473 474 **/ 475 EFI_STATUS 476 EFIAPI 477 SmmHandleProtocol ( 478 IN EFI_HANDLE UserHandle, 479 IN EFI_GUID *Protocol, 480 OUT VOID **Interface 481 ); 482 483 /** 484 Add a new protocol notification record for the request protocol. 485 486 @param Protocol The requested protocol to add the notify 487 registration 488 @param Function Points to the notification function 489 @param Registration Returns the registration record 490 491 @retval EFI_INVALID_PARAMETER Invalid parameter 492 @retval EFI_SUCCESS Successfully returned the registration record 493 that has been added 494 495 **/ 496 EFI_STATUS 497 EFIAPI 498 SmmRegisterProtocolNotify ( 499 IN CONST EFI_GUID *Protocol, 500 IN EFI_SMM_NOTIFY_FN Function, 501 OUT VOID **Registration 502 ); 503 504 /** 505 Locates the requested handle(s) and returns them in Buffer. 506 507 @param SearchType The type of search to perform to locate the 508 handles 509 @param Protocol The protocol to search for 510 @param SearchKey Dependant on SearchType 511 @param BufferSize On input the size of Buffer. On output the 512 size of data returned. 513 @param Buffer The buffer to return the results in 514 515 @retval EFI_BUFFER_TOO_SMALL Buffer too small, required buffer size is 516 returned in BufferSize. 517 @retval EFI_INVALID_PARAMETER Invalid parameter 518 @retval EFI_SUCCESS Successfully found the requested handle(s) and 519 returns them in Buffer. 520 521 **/ 522 EFI_STATUS 523 EFIAPI 524 SmmLocateHandle ( 525 IN EFI_LOCATE_SEARCH_TYPE SearchType, 526 IN EFI_GUID *Protocol OPTIONAL, 527 IN VOID *SearchKey OPTIONAL, 528 IN OUT UINTN *BufferSize, 529 OUT EFI_HANDLE *Buffer 530 ); 531 532 /** 533 Return the first Protocol Interface that matches the Protocol GUID. If 534 Registration is pasased in return a Protocol Instance that was just add 535 to the system. If Retistration is NULL return the first Protocol Interface 536 you find. 537 538 @param Protocol The protocol to search for 539 @param Registration Optional Registration Key returned from 540 RegisterProtocolNotify() 541 @param Interface Return the Protocol interface (instance). 542 543 @retval EFI_SUCCESS If a valid Interface is returned 544 @retval EFI_INVALID_PARAMETER Invalid parameter 545 @retval EFI_NOT_FOUND Protocol interface not found 546 547 **/ 548 EFI_STATUS 549 EFIAPI 550 SmmLocateProtocol ( 551 IN EFI_GUID *Protocol, 552 IN VOID *Registration OPTIONAL, 553 OUT VOID **Interface 554 ); 555 556 /** 557 Function returns an array of handles that support the requested protocol 558 in a buffer allocated from pool. This is a version of SmmLocateHandle() 559 that allocates a buffer for the caller. 560 561 @param SearchType Specifies which handle(s) are to be returned. 562 @param Protocol Provides the protocol to search by. This 563 parameter is only valid for SearchType 564 ByProtocol. 565 @param SearchKey Supplies the search key depending on the 566 SearchType. 567 @param NumberHandles The number of handles returned in Buffer. 568 @param Buffer A pointer to the buffer to return the requested 569 array of handles that support Protocol. 570 571 @retval EFI_SUCCESS The result array of handles was returned. 572 @retval EFI_NOT_FOUND No handles match the search. 573 @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the 574 matching results. 575 @retval EFI_INVALID_PARAMETER One or more paramters are not valid. 576 577 **/ 578 EFI_STATUS 579 EFIAPI 580 SmmLocateHandleBuffer ( 581 IN EFI_LOCATE_SEARCH_TYPE SearchType, 582 IN EFI_GUID *Protocol OPTIONAL, 583 IN VOID *SearchKey OPTIONAL, 584 IN OUT UINTN *NumberHandles, 585 OUT EFI_HANDLE **Buffer 586 ); 587 588 /** 589 Manage SMI of a particular type. 590 591 @param HandlerType Points to the handler type or NULL for root SMI handlers. 592 @param Context Points to an optional context buffer. 593 @param CommBuffer Points to the optional communication buffer. 594 @param CommBufferSize Points to the size of the optional communication buffer. 595 596 @retval EFI_SUCCESS Interrupt source was processed successfully but not quiesced. 597 @retval EFI_INTERRUPT_PENDING One or more SMI sources could not be quiesced. 598 @retval EFI_WARN_INTERRUPT_SOURCE_PENDING Interrupt source was not handled or quiesced. 599 @retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED Interrupt source was handled and quiesced. 600 601 **/ 602 EFI_STATUS 603 EFIAPI 604 SmiManage ( 605 IN CONST EFI_GUID *HandlerType, 606 IN CONST VOID *Context OPTIONAL, 607 IN OUT VOID *CommBuffer OPTIONAL, 608 IN OUT UINTN *CommBufferSize OPTIONAL 609 ); 610 611 /** 612 Registers a handler to execute within SMM. 613 614 @param Handler Handler service funtion pointer. 615 @param HandlerType Points to the handler type or NULL for root SMI handlers. 616 @param DispatchHandle On return, contains a unique handle which can be used to later unregister the handler function. 617 618 @retval EFI_SUCCESS Handler register success. 619 @retval EFI_INVALID_PARAMETER Handler or DispatchHandle is NULL. 620 621 **/ 622 EFI_STATUS 623 EFIAPI 624 SmiHandlerRegister ( 625 IN EFI_SMM_HANDLER_ENTRY_POINT2 Handler, 626 IN CONST EFI_GUID *HandlerType OPTIONAL, 627 OUT EFI_HANDLE *DispatchHandle 628 ); 629 630 /** 631 Unregister a handler in SMM. 632 633 @param DispatchHandle The handle that was specified when the handler was registered. 634 635 @retval EFI_SUCCESS Handler function was successfully unregistered. 636 @retval EFI_INVALID_PARAMETER DispatchHandle does not refer to a valid handle. 637 638 **/ 639 EFI_STATUS 640 EFIAPI 641 SmiHandlerUnRegister ( 642 IN EFI_HANDLE DispatchHandle 643 ); 644 645 /** 646 This function is the main entry point for an SMM handler dispatch 647 or communicate-based callback. 648 649 @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister(). 650 @param Context Points to an optional handler context which was specified when the handler was registered. 651 @param CommBuffer A pointer to a collection of data in memory that will 652 be conveyed from a non-SMM environment into an SMM environment. 653 @param CommBufferSize The size of the CommBuffer. 654 655 @return Status Code 656 657 **/ 658 EFI_STATUS 659 EFIAPI 660 SmmDriverDispatchHandler ( 661 IN EFI_HANDLE DispatchHandle, 662 IN CONST VOID *Context, OPTIONAL 663 IN OUT VOID *CommBuffer, OPTIONAL 664 IN OUT UINTN *CommBufferSize OPTIONAL 665 ); 666 667 /** 668 This function is the main entry point for an SMM handler dispatch 669 or communicate-based callback. 670 671 @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister(). 672 @param Context Points to an optional handler context which was specified when the handler was registered. 673 @param CommBuffer A pointer to a collection of data in memory that will 674 be conveyed from a non-SMM environment into an SMM environment. 675 @param CommBufferSize The size of the CommBuffer. 676 677 @return Status Code 678 679 **/ 680 EFI_STATUS 681 EFIAPI 682 SmmLegacyBootHandler ( 683 IN EFI_HANDLE DispatchHandle, 684 IN CONST VOID *Context, OPTIONAL 685 IN OUT VOID *CommBuffer, OPTIONAL 686 IN OUT UINTN *CommBufferSize OPTIONAL 687 ); 688 689 /** 690 This function is the main entry point for an SMM handler dispatch 691 or communicate-based callback. 692 693 @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister(). 694 @param Context Points to an optional handler context which was specified when the handler was registered. 695 @param CommBuffer A pointer to a collection of data in memory that will 696 be conveyed from a non-SMM environment into an SMM environment. 697 @param CommBufferSize The size of the CommBuffer. 698 699 @return Status Code 700 701 **/ 702 EFI_STATUS 703 EFIAPI 704 SmmReadyToLockHandler ( 705 IN EFI_HANDLE DispatchHandle, 706 IN CONST VOID *Context, OPTIONAL 707 IN OUT VOID *CommBuffer, OPTIONAL 708 IN OUT UINTN *CommBufferSize OPTIONAL 709 ); 710 711 /** 712 This function is the main entry point for an SMM handler dispatch 713 or communicate-based callback. 714 715 @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister(). 716 @param Context Points to an optional handler context which was specified when the handler was registered. 717 @param CommBuffer A pointer to a collection of data in memory that will 718 be conveyed from a non-SMM environment into an SMM environment. 719 @param CommBufferSize The size of the CommBuffer. 720 721 @return Status Code 722 723 **/ 724 EFI_STATUS 725 EFIAPI 726 SmmEndOfDxeHandler ( 727 IN EFI_HANDLE DispatchHandle, 728 IN CONST VOID *Context, OPTIONAL 729 IN OUT VOID *CommBuffer, OPTIONAL 730 IN OUT UINTN *CommBufferSize OPTIONAL 731 ); 732 733 /** 734 This function is the main entry point for an SMM handler dispatch 735 or communicate-based callback. 736 737 @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister(). 738 @param Context Points to an optional handler context which was specified when the handler was registered. 739 @param CommBuffer A pointer to a collection of data in memory that will 740 be conveyed from a non-SMM environment into an SMM environment. 741 @param CommBufferSize The size of the CommBuffer. 742 743 @return Status Code 744 745 **/ 746 EFI_STATUS 747 EFIAPI 748 SmmExitBootServicesHandler ( 749 IN EFI_HANDLE DispatchHandle, 750 IN CONST VOID *Context, OPTIONAL 751 IN OUT VOID *CommBuffer, OPTIONAL 752 IN OUT UINTN *CommBufferSize OPTIONAL 753 ); 754 755 /** 756 This function is the main entry point for an SMM handler dispatch 757 or communicate-based callback. 758 759 @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister(). 760 @param Context Points to an optional handler context which was specified when the handler was registered. 761 @param CommBuffer A pointer to a collection of data in memory that will 762 be conveyed from a non-SMM environment into an SMM environment. 763 @param CommBufferSize The size of the CommBuffer. 764 765 @return Status Code 766 767 **/ 768 EFI_STATUS 769 EFIAPI 770 SmmReadyToBootHandler ( 771 IN EFI_HANDLE DispatchHandle, 772 IN CONST VOID *Context, OPTIONAL 773 IN OUT VOID *CommBuffer, OPTIONAL 774 IN OUT UINTN *CommBufferSize OPTIONAL 775 ); 776 777 /** 778 Place holder function until all the SMM System Table Service are available. 779 780 @param Arg1 Undefined 781 @param Arg2 Undefined 782 @param Arg3 Undefined 783 @param Arg4 Undefined 784 @param Arg5 Undefined 785 786 @return EFI_NOT_AVAILABLE_YET 787 788 **/ 789 EFI_STATUS 790 EFIAPI 791 SmmEfiNotAvailableYetArg5 ( 792 UINTN Arg1, 793 UINTN Arg2, 794 UINTN Arg3, 795 UINTN Arg4, 796 UINTN Arg5 797 ); 798 799 // 800 //Functions used during debug buils 801 // 802 803 /** 804 Traverse the discovered list for any drivers that were discovered but not loaded 805 because the dependency experessions evaluated to false. 806 807 **/ 808 VOID 809 SmmDisplayDiscoveredNotDispatched ( 810 VOID 811 ); 812 813 /** 814 Add free SMRAM region for use by memory service. 815 816 @param MemBase Base address of memory region. 817 @param MemLength Length of the memory region. 818 @param Type Memory type. 819 @param Attributes Memory region state. 820 821 **/ 822 VOID 823 SmmAddMemoryRegion ( 824 IN EFI_PHYSICAL_ADDRESS MemBase, 825 IN UINT64 MemLength, 826 IN EFI_MEMORY_TYPE Type, 827 IN UINT64 Attributes 828 ); 829 830 /** 831 Finds the protocol entry for the requested protocol. 832 833 @param Protocol The ID of the protocol 834 @param Create Create a new entry if not found 835 836 @return Protocol entry 837 838 **/ 839 PROTOCOL_ENTRY * 840 SmmFindProtocolEntry ( 841 IN EFI_GUID *Protocol, 842 IN BOOLEAN Create 843 ); 844 845 /** 846 Signal event for every protocol in protocol entry. 847 848 @param Prot Protocol interface 849 850 **/ 851 VOID 852 SmmNotifyProtocol ( 853 IN PROTOCOL_INTERFACE *Prot 854 ); 855 856 /** 857 Finds the protocol instance for the requested handle and protocol. 858 Note: This function doesn't do parameters checking, it's caller's responsibility 859 to pass in valid parameters. 860 861 @param Handle The handle to search the protocol on 862 @param Protocol GUID of the protocol 863 @param Interface The interface for the protocol being searched 864 865 @return Protocol instance (NULL: Not found) 866 867 **/ 868 PROTOCOL_INTERFACE * 869 SmmFindProtocolInterface ( 870 IN IHANDLE *Handle, 871 IN EFI_GUID *Protocol, 872 IN VOID *Interface 873 ); 874 875 /** 876 Removes Protocol from the protocol list (but not the handle list). 877 878 @param Handle The handle to remove protocol on. 879 @param Protocol GUID of the protocol to be moved 880 @param Interface The interface of the protocol 881 882 @return Protocol Entry 883 884 **/ 885 PROTOCOL_INTERFACE * 886 SmmRemoveInterfaceFromProtocol ( 887 IN IHANDLE *Handle, 888 IN EFI_GUID *Protocol, 889 IN VOID *Interface 890 ); 891 892 /** 893 This is the POSTFIX version of the dependency evaluator. This code does 894 not need to handle Before or After, as it is not valid to call this 895 routine in this case. POSTFIX means all the math is done on top of the stack. 896 897 @param DriverEntry DriverEntry element to update. 898 899 @retval TRUE If driver is ready to run. 900 @retval FALSE If driver is not ready to run or some fatal error 901 was found. 902 903 **/ 904 BOOLEAN 905 SmmIsSchedulable ( 906 IN EFI_SMM_DRIVER_ENTRY *DriverEntry 907 ); 908 909 // 910 // SmramProfile 911 // 912 913 /** 914 Initialize SMRAM profile. 915 916 **/ 917 VOID 918 SmramProfileInit ( 919 VOID 920 ); 921 922 /** 923 Install SMRAM profile protocol. 924 925 **/ 926 VOID 927 SmramProfileInstallProtocol ( 928 VOID 929 ); 930 931 /** 932 Register SMM image to SMRAM profile. 933 934 @param DriverEntry SMM image info. 935 @param RegisterToDxe Register image to DXE. 936 937 @return EFI_SUCCESS Register successfully. 938 @return EFI_UNSUPPORTED Memory profile unsupported, 939 or memory profile for the image is not required. 940 @return EFI_OUT_OF_RESOURCES No enough resource for this register. 941 942 **/ 943 EFI_STATUS 944 RegisterSmramProfileImage ( 945 IN EFI_SMM_DRIVER_ENTRY *DriverEntry, 946 IN BOOLEAN RegisterToDxe 947 ); 948 949 /** 950 Unregister image from SMRAM profile. 951 952 @param DriverEntry SMM image info. 953 @param UnregisterToDxe Unregister image from DXE. 954 955 @return EFI_SUCCESS Unregister successfully. 956 @return EFI_UNSUPPORTED Memory profile unsupported, 957 or memory profile for the image is not required. 958 @return EFI_NOT_FOUND The image is not found. 959 960 **/ 961 EFI_STATUS 962 UnregisterSmramProfileImage ( 963 IN EFI_SMM_DRIVER_ENTRY *DriverEntry, 964 IN BOOLEAN UnregisterToDxe 965 ); 966 967 /** 968 Update SMRAM profile information. 969 970 @param CallerAddress Address of caller who call Allocate or Free. 971 @param Action This Allocate or Free action. 972 @param MemoryType Memory type. 973 EfiMaxMemoryType means the MemoryType is unknown. 974 @param Size Buffer size. 975 @param Buffer Buffer address. 976 @param ActionString String for memory profile action. 977 Only needed for user defined allocate action. 978 979 @return EFI_SUCCESS Memory profile is updated. 980 @return EFI_UNSUPPORTED Memory profile is unsupported, 981 or memory profile for the image is not required, 982 or memory profile for the memory type is not required. 983 @return EFI_ACCESS_DENIED It is during memory profile data getting. 984 @return EFI_ABORTED Memory profile recording is not enabled. 985 @return EFI_OUT_OF_RESOURCES No enough resource to update memory profile for allocate action. 986 @return EFI_NOT_FOUND No matched allocate info found for free action. 987 988 **/ 989 EFI_STATUS 990 EFIAPI 991 SmmCoreUpdateProfile ( 992 IN PHYSICAL_ADDRESS CallerAddress, 993 IN MEMORY_PROFILE_ACTION Action, 994 IN EFI_MEMORY_TYPE MemoryType, // Valid for AllocatePages/AllocatePool 995 IN UINTN Size, // Valid for AllocatePages/FreePages/AllocatePool 996 IN VOID *Buffer, 997 IN CHAR8 *ActionString OPTIONAL 998 ); 999 1000 /** 1001 Register SMRAM profile handler. 1002 1003 **/ 1004 VOID 1005 RegisterSmramProfileHandler ( 1006 VOID 1007 ); 1008 1009 /** 1010 SMRAM profile ready to lock callback function. 1011 1012 **/ 1013 VOID 1014 SmramProfileReadyToLock ( 1015 VOID 1016 ); 1017 1018 /** 1019 Initialize MemoryAttributes support. 1020 **/ 1021 VOID 1022 EFIAPI 1023 SmmCoreInitializeMemoryAttributesTable ( 1024 VOID 1025 ); 1026 1027 /** 1028 This function returns a copy of the current memory map. The map is an array of 1029 memory descriptors, each of which describes a contiguous block of memory. 1030 1031 @param[in, out] MemoryMapSize A pointer to the size, in bytes, of the 1032 MemoryMap buffer. On input, this is the size of 1033 the buffer allocated by the caller. On output, 1034 it is the size of the buffer returned by the 1035 firmware if the buffer was large enough, or the 1036 size of the buffer needed to contain the map if 1037 the buffer was too small. 1038 @param[in, out] MemoryMap A pointer to the buffer in which firmware places 1039 the current memory map. 1040 @param[out] MapKey A pointer to the location in which firmware 1041 returns the key for the current memory map. 1042 @param[out] DescriptorSize A pointer to the location in which firmware 1043 returns the size, in bytes, of an individual 1044 EFI_MEMORY_DESCRIPTOR. 1045 @param[out] DescriptorVersion A pointer to the location in which firmware 1046 returns the version number associated with the 1047 EFI_MEMORY_DESCRIPTOR. 1048 1049 @retval EFI_SUCCESS The memory map was returned in the MemoryMap 1050 buffer. 1051 @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current 1052 buffer size needed to hold the memory map is 1053 returned in MemoryMapSize. 1054 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. 1055 1056 **/ 1057 EFI_STATUS 1058 EFIAPI 1059 SmmCoreGetMemoryMap ( 1060 IN OUT UINTN *MemoryMapSize, 1061 IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, 1062 OUT UINTN *MapKey, 1063 OUT UINTN *DescriptorSize, 1064 OUT UINT32 *DescriptorVersion 1065 ); 1066 1067 /// 1068 /// For generic EFI machines make the default allocations 4K aligned 1069 /// 1070 #define EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT (EFI_PAGE_SIZE) 1071 #define DEFAULT_PAGE_ALLOCATION (EFI_PAGE_SIZE) 1072 1073 extern UINTN mFullSmramRangeCount; 1074 extern EFI_SMRAM_DESCRIPTOR *mFullSmramRanges; 1075 1076 extern EFI_SMM_DRIVER_ENTRY *mSmmCoreDriverEntry; 1077 1078 extern EFI_LOADED_IMAGE_PROTOCOL *mSmmCoreLoadedImage; 1079 1080 // 1081 // Page management 1082 // 1083 1084 typedef struct { 1085 LIST_ENTRY Link; 1086 UINTN NumberOfPages; 1087 } FREE_PAGE_LIST; 1088 1089 extern LIST_ENTRY mSmmMemoryMap; 1090 1091 // 1092 // Pool management 1093 // 1094 1095 // 1096 // MIN_POOL_SHIFT must not be less than 5 1097 // 1098 #define MIN_POOL_SHIFT 6 1099 #define MIN_POOL_SIZE (1 << MIN_POOL_SHIFT) 1100 1101 // 1102 // MAX_POOL_SHIFT must not be less than EFI_PAGE_SHIFT - 1 1103 // 1104 #define MAX_POOL_SHIFT (EFI_PAGE_SHIFT - 1) 1105 #define MAX_POOL_SIZE (1 << MAX_POOL_SHIFT) 1106 1107 // 1108 // MAX_POOL_INDEX are calculated by maximum and minimum pool sizes 1109 // 1110 #define MAX_POOL_INDEX (MAX_POOL_SHIFT - MIN_POOL_SHIFT + 1) 1111 1112 typedef struct { 1113 UINTN Size; 1114 BOOLEAN Available; 1115 EFI_MEMORY_TYPE Type; 1116 } POOL_HEADER; 1117 1118 typedef struct { 1119 POOL_HEADER Header; 1120 LIST_ENTRY Link; 1121 } FREE_POOL_HEADER; 1122 1123 typedef enum { 1124 SmmPoolTypeCode, 1125 SmmPoolTypeData, 1126 SmmPoolTypeMax, 1127 } SMM_POOL_TYPE; 1128 1129 extern LIST_ENTRY mSmmPoolLists[SmmPoolTypeMax][MAX_POOL_INDEX]; 1130 1131 #endif 1132