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