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