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 - 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