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