• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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