2 SMM Base Helper SMM driver.
4 This driver is the counterpart of the SMM Base On SMM Base2 Thunk driver. It
5 provides helping services in SMM to the SMM Base On SMM Base2 Thunk driver.
7 Copyright (c) 2009 - 2010, Intel Corporation
8 All rights reserved. This program and the accompanying materials
9 are licensed and made available under the terms and conditions of the BSD License
10 which accompanies this distribution. The full text of the license may be found at
11 http://opensource.org/licenses/bsd-license.php
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 #include <Library/DebugLib.h>
20 #include <Library/UefiBootServicesTableLib.h>
21 #include <Library/SmmServicesTableLib.h>
22 #include <Library/BaseLib.h>
23 #include <Library/BaseMemoryLib.h>
24 #include <Library/PeCoffLib.h>
25 #include <Library/DevicePathLib.h>
26 #include <Library/CacheMaintenanceLib.h>
27 #include <Library/MemoryAllocationLib.h>
28 #include <Guid/SmmBaseThunkCommunication.h>
29 #include <Protocol/SmmBaseHelperReady.h>
30 #include <Protocol/SmmCpu.h>
31 #include <Protocol/LoadedImage.h>
32 #include <Protocol/SmmCpuSaveState.h>
33 #include <Protocol/MpService.h>
34 #include <Protocol/LoadPe32Image.h>
35 #include <Protocol/SmmReadyToLock.h>
38 /// Structure for tracking paired information of registered Framework SMI handler
39 /// and correpsonding dispatch handle for SMI handler thunk.
43 EFI_HANDLE DispatchHandle
;
44 EFI_HANDLE SmmImageHandle
;
45 EFI_SMM_CALLBACK_ENTRY_POINT CallbackAddress
;
46 VOID
*CommunicationBuffer
;
52 /// PI SMM CPU Save State register index
54 EFI_SMM_SAVE_STATE_REGISTER Register
;
56 /// Offset in Framework SMST
59 } CPU_SAVE_STATE_CONVERSION
;
61 #define CPU_SAVE_STATE_GET_OFFSET(Field) (UINTN)(&(((EFI_SMM_CPU_SAVE_STATE *) 0)->Ia32SaveState.Field))
64 EFI_HANDLE mDispatchHandle
;
65 EFI_SMM_CPU_PROTOCOL
*mSmmCpu
;
66 EFI_PE32_IMAGE_PROTOCOL
*mLoadPe32Image
;
67 EFI_GUID mEfiSmmCpuIoGuid
= EFI_SMM_CPU_IO_GUID
;
68 EFI_SMM_BASE_HELPER_READY_PROTOCOL
*mSmmBaseHelperReady
;
69 EFI_SMM_SYSTEM_TABLE
*mFrameworkSmst
;
70 UINTN mNumberOfProcessors
;
71 BOOLEAN mLocked
= FALSE
;
73 LIST_ENTRY mCallbackInfoListHead
= INITIALIZE_LIST_HEAD_VARIABLE (mCallbackInfoListHead
);
75 CPU_SAVE_STATE_CONVERSION mCpuSaveStateConvTable
[] = {
76 {EFI_SMM_SAVE_STATE_REGISTER_LDTBASE
, CPU_SAVE_STATE_GET_OFFSET(LDTBase
)},
77 {EFI_SMM_SAVE_STATE_REGISTER_ES
, CPU_SAVE_STATE_GET_OFFSET(ES
)},
78 {EFI_SMM_SAVE_STATE_REGISTER_CS
, CPU_SAVE_STATE_GET_OFFSET(CS
)},
79 {EFI_SMM_SAVE_STATE_REGISTER_SS
, CPU_SAVE_STATE_GET_OFFSET(SS
)},
80 {EFI_SMM_SAVE_STATE_REGISTER_DS
, CPU_SAVE_STATE_GET_OFFSET(DS
)},
81 {EFI_SMM_SAVE_STATE_REGISTER_FS
, CPU_SAVE_STATE_GET_OFFSET(FS
)},
82 {EFI_SMM_SAVE_STATE_REGISTER_GS
, CPU_SAVE_STATE_GET_OFFSET(GS
)},
83 {EFI_SMM_SAVE_STATE_REGISTER_TR_SEL
, CPU_SAVE_STATE_GET_OFFSET(TR
)},
84 {EFI_SMM_SAVE_STATE_REGISTER_DR7
, CPU_SAVE_STATE_GET_OFFSET(DR7
)},
85 {EFI_SMM_SAVE_STATE_REGISTER_DR6
, CPU_SAVE_STATE_GET_OFFSET(DR6
)},
86 {EFI_SMM_SAVE_STATE_REGISTER_RAX
, CPU_SAVE_STATE_GET_OFFSET(EAX
)},
87 {EFI_SMM_SAVE_STATE_REGISTER_RBX
, CPU_SAVE_STATE_GET_OFFSET(EBX
)},
88 {EFI_SMM_SAVE_STATE_REGISTER_RCX
, CPU_SAVE_STATE_GET_OFFSET(ECX
)},
89 {EFI_SMM_SAVE_STATE_REGISTER_RDX
, CPU_SAVE_STATE_GET_OFFSET(EDX
)},
90 {EFI_SMM_SAVE_STATE_REGISTER_RSP
, CPU_SAVE_STATE_GET_OFFSET(ESP
)},
91 {EFI_SMM_SAVE_STATE_REGISTER_RBP
, CPU_SAVE_STATE_GET_OFFSET(EBP
)},
92 {EFI_SMM_SAVE_STATE_REGISTER_RSI
, CPU_SAVE_STATE_GET_OFFSET(ESI
)},
93 {EFI_SMM_SAVE_STATE_REGISTER_RDI
, CPU_SAVE_STATE_GET_OFFSET(EDI
)},
94 {EFI_SMM_SAVE_STATE_REGISTER_RIP
, CPU_SAVE_STATE_GET_OFFSET(EIP
)},
95 {EFI_SMM_SAVE_STATE_REGISTER_RFLAGS
, CPU_SAVE_STATE_GET_OFFSET(EFLAGS
)},
96 {EFI_SMM_SAVE_STATE_REGISTER_CR0
, CPU_SAVE_STATE_GET_OFFSET(CR0
)},
97 {EFI_SMM_SAVE_STATE_REGISTER_CR3
, CPU_SAVE_STATE_GET_OFFSET(CR3
)}
101 Framework SMST SmmInstallConfigurationTable() Thunk.
103 This thunk calls the PI SMM SmmInstallConfigurationTable() and then update the configuration
104 table related fields in the Framework SMST because the PI SMM SmmInstallConfigurationTable()
105 function may modify these fields.
107 @param[in] SystemTable A pointer to the SMM System Table.
108 @param[in] Guid A pointer to the GUID for the entry to add, update, or remove.
109 @param[in] Table A pointer to the buffer of the table to add.
110 @param[in] TableSize The size of the table to install.
112 @retval EFI_SUCCESS The (Guid, Table) pair was added, updated, or removed.
113 @retval EFI_INVALID_PARAMETER Guid is not valid.
114 @retval EFI_NOT_FOUND An attempt was made to delete a non-existent entry.
115 @retval EFI_OUT_OF_RESOURCES There is not enough memory available to complete the operation.
119 SmmInstallConfigurationTable (
120 IN EFI_SMM_SYSTEM_TABLE
*SystemTable
,
128 Status
= gSmst
->SmmInstallConfigurationTable (gSmst
, Guid
, Table
, TableSize
);
129 if (!EFI_ERROR (Status
)) {
130 mFrameworkSmst
->NumberOfTableEntries
= gSmst
->NumberOfTableEntries
;
131 mFrameworkSmst
->SmmConfigurationTable
= gSmst
->SmmConfigurationTable
;
137 Construct a Framework SMST based on the PI SMM SMST.
139 @return Pointer to the constructed Framework SMST.
141 EFI_SMM_SYSTEM_TABLE
*
142 ConstructFrameworkSmst (
146 EFI_SMM_SYSTEM_TABLE
*FrameworkSmst
;
148 FrameworkSmst
= (EFI_SMM_SYSTEM_TABLE
*)AllocatePool (sizeof (EFI_SMM_SYSTEM_TABLE
));
149 ASSERT (FrameworkSmst
!= NULL
);
152 /// Copy same things from PI SMST to Framework SMST
154 CopyMem (FrameworkSmst
, gSmst
, (UINTN
)(&((EFI_SMM_SYSTEM_TABLE
*)0)->SmmIo
));
156 &FrameworkSmst
->SmmIo
,
158 sizeof (EFI_SMM_SYSTEM_TABLE
) - (UINTN
)(&((EFI_SMM_SYSTEM_TABLE
*)0)->SmmIo
)
162 /// Update Framework SMST
164 FrameworkSmst
->Hdr
.Revision
= EFI_SMM_SYSTEM_TABLE_REVISION
;
165 CopyGuid (&FrameworkSmst
->EfiSmmCpuIoGuid
, &mEfiSmmCpuIoGuid
);
167 FrameworkSmst
->CpuSaveState
= (EFI_SMM_CPU_SAVE_STATE
*)AllocateZeroPool (mNumberOfProcessors
* sizeof (EFI_SMM_CPU_SAVE_STATE
));
168 ASSERT (FrameworkSmst
->CpuSaveState
!= NULL
);
171 /// Do not support floating point state now
173 FrameworkSmst
->CpuOptionalFloatingPointState
= NULL
;
175 FrameworkSmst
->SmmInstallConfigurationTable
= SmmInstallConfigurationTable
;
177 return FrameworkSmst
;
181 Load a given Framework SMM driver into SMRAM and invoke its entry point.
183 @param[in] ParentImageHandle Parent Image Handle.
184 @param[in] FilePath Location of the image to be installed as the handler.
185 @param[in] SourceBuffer Optional source buffer in case the image file
187 @param[in] SourceSize Size of the source image file, if in memory.
188 @param[out] ImageHandle The handle that the base driver uses to decode
189 the handler. Unique among SMM handlers only,
190 not unique across DXE/EFI.
192 @retval EFI_SUCCESS The operation was successful.
193 @retval EFI_OUT_OF_RESOURCES There were no additional SMRAM resources to load the handler
194 @retval EFI_UNSUPPORTED Can not find its copy in normal memory.
195 @retval EFI_INVALID_PARAMETER The handlers was not the correct image type
199 IN EFI_HANDLE ParentImageHandle
,
200 IN EFI_DEVICE_PATH_PROTOCOL
*FilePath
,
201 IN VOID
*SourceBuffer
,
203 OUT EFI_HANDLE
*ImageHandle
209 EFI_PHYSICAL_ADDRESS DstBuffer
;
211 if (FilePath
== NULL
|| ImageHandle
== NULL
) {
212 return EFI_INVALID_PARAMETER
;
217 OrgPageCount
= PageCount
;
218 DstBuffer
= (UINTN
)-1;
219 Status
= gSmst
->SmmAllocatePages (
221 EfiRuntimeServicesCode
,
225 if (EFI_ERROR (Status
)) {
229 Status
= mLoadPe32Image
->LoadPeImage (
239 EFI_LOAD_PE_IMAGE_ATTRIBUTE_NONE
241 if (EFI_ERROR (Status
)) {
242 FreePages ((VOID
*)(UINTN
)DstBuffer
, OrgPageCount
);
244 } while (Status
== EFI_BUFFER_TOO_SMALL
);
246 if (!EFI_ERROR (Status
)) {
248 /// Update MP state in Framework SMST before transferring control to Framework SMM driver entry point
249 /// in case it may invoke AP
251 mFrameworkSmst
->CurrentlyExecutingCpu
= gSmst
->CurrentlyExecutingCpu
;
253 Status
= gBS
->StartImage (*ImageHandle
, NULL
, NULL
);
254 if (EFI_ERROR (Status
)) {
255 mLoadPe32Image
->UnLoadPeImage (mLoadPe32Image
, *ImageHandle
);
257 FreePages ((VOID
*)(UINTN
)DstBuffer
, PageCount
);
266 Thunk service of EFI_SMM_BASE_PROTOCOL.Register().
268 @param[in, out] FunctionData Pointer to SMMBASE_FUNCTION_DATA.
272 IN OUT SMMBASE_FUNCTION_DATA
*FunctionData
277 if (mLocked
|| FunctionData
->Args
.Register
.LegacyIA32Binary
) {
278 Status
= EFI_UNSUPPORTED
;
281 FunctionData
->SmmBaseImageHandle
,
282 FunctionData
->Args
.Register
.FilePath
,
283 FunctionData
->Args
.Register
.SourceBuffer
,
284 FunctionData
->Args
.Register
.SourceSize
,
285 FunctionData
->Args
.Register
.ImageHandle
288 FunctionData
->Status
= Status
;
292 Thunk service of EFI_SMM_BASE_PROTOCOL.UnRegister().
294 @param[in, out] FunctionData Pointer to SMMBASE_FUNCTION_DATA.
298 IN OUT SMMBASE_FUNCTION_DATA
*FunctionData
302 /// Unregister not supported now
304 FunctionData
->Status
= EFI_UNSUPPORTED
;
308 Search for Framework SMI handler information according to specific PI SMM dispatch handle.
310 @param[in] DispatchHandle The unique handle assigned by SmiHandlerRegister().
312 @return Pointer to CALLBACK_INFO. If NULL, no callback info record is found.
316 IN EFI_HANDLE DispatchHandle
321 Node
= GetFirstNode (&mCallbackInfoListHead
);
322 while (!IsNull (&mCallbackInfoListHead
, Node
)) {
323 if (((CALLBACK_INFO
*)Node
)->DispatchHandle
== DispatchHandle
) {
324 return (CALLBACK_INFO
*)Node
;
326 Node
= GetNextNode (&mCallbackInfoListHead
, Node
);
332 Callback thunk for Framework SMI handler.
334 This thunk functions calls the Framework SMI handler and converts the return value
335 defined from Framework SMI handlers to a correpsonding return value defined by PI SMM.
337 @param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
338 @param[in] Context Points to an optional handler context which was specified when the
339 handler was registered.
340 @param[in, out] CommBuffer A pointer to a collection of data in memory that will
341 be conveyed from a non-SMM environment into an SMM environment.
342 @param[in, out] CommBufferSize The size of the CommBuffer.
344 @retval EFI_SUCCESS The interrupt was handled and quiesced. No other handlers
345 should still be called.
346 @retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED The interrupt has been quiesced but other handlers should
348 @retval EFI_WARN_INTERRUPT_SOURCE_PENDING The interrupt is still pending and other handlers should still
350 @retval EFI_INTERRUPT_PENDING The interrupt could not be quiesced.
355 IN EFI_HANDLE DispatchHandle
,
356 IN CONST VOID
*Context OPTIONAL
,
357 IN OUT VOID
*CommBuffer OPTIONAL
,
358 IN OUT UINTN
*CommBufferSize OPTIONAL
362 CALLBACK_INFO
*CallbackInfo
;
365 EFI_SMM_CPU_STATE
*State
;
366 EFI_SMI_CPU_SAVE_STATE
*SaveState
;
369 /// Before transferring the control into the Framework SMI handler, update CPU Save States
370 /// and MP states in the Framework SMST.
373 for (CpuIndex
= 0; CpuIndex
< mNumberOfProcessors
; CpuIndex
++) {
374 State
= (EFI_SMM_CPU_STATE
*)gSmst
->CpuSaveState
[CpuIndex
];
375 SaveState
= &mFrameworkSmst
->CpuSaveState
[CpuIndex
].Ia32SaveState
;
377 if (State
->x86
.SMMRevId
< EFI_SMM_MIN_REV_ID_x64
) {
378 SaveState
->SMBASE
= State
->x86
.SMBASE
;
379 SaveState
->SMMRevId
= State
->x86
.SMMRevId
;
380 SaveState
->IORestart
= State
->x86
.IORestart
;
381 SaveState
->AutoHALTRestart
= State
->x86
.AutoHALTRestart
;
383 SaveState
->SMBASE
= State
->x64
.SMBASE
;
384 SaveState
->SMMRevId
= State
->x64
.SMMRevId
;
385 SaveState
->IORestart
= State
->x64
.IORestart
;
386 SaveState
->AutoHALTRestart
= State
->x64
.AutoHALTRestart
;
389 for (Index
= 0; Index
< sizeof (mCpuSaveStateConvTable
) / sizeof (CPU_SAVE_STATE_CONVERSION
); Index
++) {
391 /// Try to use SMM CPU Protocol to access CPU save states if possible
393 Status
= mSmmCpu
->ReadSaveState (
395 (UINTN
)sizeof (UINT32
),
396 mCpuSaveStateConvTable
[Index
].Register
,
398 ((UINT8
*)SaveState
) + mCpuSaveStateConvTable
[Index
].Offset
400 ASSERT_EFI_ERROR (Status
);
404 mFrameworkSmst
->SmmStartupThisAp
= gSmst
->SmmStartupThisAp
;
405 mFrameworkSmst
->NumberOfCpus
= mNumberOfProcessors
;
406 mFrameworkSmst
->CurrentlyExecutingCpu
= gSmst
->CurrentlyExecutingCpu
;
409 /// Search for Framework SMI handler information
411 CallbackInfo
= GetCallbackInfo (DispatchHandle
);
412 ASSERT (CallbackInfo
!= NULL
);
415 /// Thunk into original Framwork SMI handler
417 Status
= (CallbackInfo
->CallbackAddress
) (
418 CallbackInfo
->SmmImageHandle
,
419 CallbackInfo
->CommunicationBuffer
,
420 CallbackInfo
->SourceSize
423 /// Save CPU Save States in case any of them was modified
425 for (CpuIndex
= 0; CpuIndex
< mNumberOfProcessors
; CpuIndex
++) {
426 for (Index
= 0; Index
< sizeof (mCpuSaveStateConvTable
) / sizeof (CPU_SAVE_STATE_CONVERSION
); Index
++) {
427 Status
= mSmmCpu
->WriteSaveState (
429 (UINTN
)sizeof (UINT32
),
430 mCpuSaveStateConvTable
[Index
].Register
,
432 ((UINT8
*)&mFrameworkSmst
->CpuSaveState
[CpuIndex
].Ia32SaveState
) +
433 mCpuSaveStateConvTable
[Index
].Offset
439 /// Conversion of returned status code
442 case EFI_HANDLER_SUCCESS
:
443 Status
= EFI_WARN_INTERRUPT_SOURCE_QUIESCED
;
445 case EFI_HANDLER_CRITICAL_EXIT
:
446 case EFI_HANDLER_SOURCE_QUIESCED
:
447 Status
= EFI_SUCCESS
;
449 case EFI_HANDLER_SOURCE_PENDING
:
450 Status
= EFI_WARN_INTERRUPT_SOURCE_PENDING
;
457 Thunk service of EFI_SMM_BASE_PROTOCOL.RegisterCallback().
459 @param[in, out] FunctionData Pointer to SMMBASE_FUNCTION_DATA.
463 IN OUT SMMBASE_FUNCTION_DATA
*FunctionData
466 CALLBACK_INFO
*Buffer
;
469 FunctionData
->Status
= EFI_UNSUPPORTED
;
474 /// Note that MakeLast and FloatingPointSave options are not supported in PI SMM
478 /// Allocate buffer for callback thunk information
480 Buffer
= (CALLBACK_INFO
*)AllocateZeroPool (sizeof (CALLBACK_INFO
));
481 if (Buffer
== NULL
) {
482 FunctionData
->Status
= EFI_OUT_OF_RESOURCES
;
487 /// Fill SmmImageHandle and CallbackAddress into the thunk
489 Buffer
->SmmImageHandle
= FunctionData
->Args
.RegisterCallback
.SmmImageHandle
;
490 Buffer
->CallbackAddress
= FunctionData
->Args
.RegisterCallback
.CallbackAddress
;
493 /// Register the thunk code as a root SMI handler
495 FunctionData
->Status
= gSmst
->SmiHandlerRegister (
498 &Buffer
->DispatchHandle
500 if (EFI_ERROR (FunctionData
->Status
)) {
506 /// Save this callback info
508 InsertTailList (&mCallbackInfoListHead
, &Buffer
->Link
);
513 Thunk service of EFI_SMM_BASE_PROTOCOL.SmmAllocatePool().
515 @param[in, out] FunctionData Pointer to SMMBASE_FUNCTION_DATA.
519 IN OUT SMMBASE_FUNCTION_DATA
*FunctionData
523 FunctionData
->Status
= EFI_UNSUPPORTED
;
525 FunctionData
->Status
= gSmst
->SmmAllocatePool (
526 FunctionData
->Args
.AllocatePool
.PoolType
,
527 FunctionData
->Args
.AllocatePool
.Size
,
528 FunctionData
->Args
.AllocatePool
.Buffer
534 Thunk service of EFI_SMM_BASE_PROTOCOL.SmmFreePool().
536 @param[in, out] FunctionData Pointer to SMMBASE_FUNCTION_DATA.
540 IN OUT SMMBASE_FUNCTION_DATA
*FunctionData
544 FunctionData
->Status
= EFI_UNSUPPORTED
;
546 FreePool (FunctionData
->Args
.FreePool
.Buffer
);
547 FunctionData
->Status
= EFI_SUCCESS
;
552 Thunk service of EFI_SMM_BASE_PROTOCOL.Communicate().
554 @param[in, out] FunctionData Pointer to SMMBASE_FUNCTION_DATA.
558 IN OUT SMMBASE_FUNCTION_DATA
*FunctionData
562 CALLBACK_INFO
*CallbackInfo
;
564 if (FunctionData
->Args
.Communicate
.CommunicationBuffer
== NULL
) {
565 FunctionData
->Status
= EFI_INVALID_PARAMETER
;
569 Node
= GetFirstNode (&mCallbackInfoListHead
);
570 while (!IsNull (&mCallbackInfoListHead
, Node
)) {
571 CallbackInfo
= (CALLBACK_INFO
*)Node
;
573 if (FunctionData
->Args
.Communicate
.ImageHandle
== CallbackInfo
->SmmImageHandle
) {
574 CallbackInfo
->CommunicationBuffer
= FunctionData
->Args
.Communicate
.CommunicationBuffer
;
575 CallbackInfo
->SourceSize
= FunctionData
->Args
.Communicate
.SourceSize
;
578 /// The message was successfully posted.
580 FunctionData
->Status
= EFI_SUCCESS
;
583 Node
= GetNextNode (&mCallbackInfoListHead
, Node
);
586 FunctionData
->Status
= EFI_INVALID_PARAMETER
;
590 Communication service SMI Handler entry.
592 This SMI handler provides services for the SMM Base Thunk driver.
594 @param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
595 @param[in] RegisterContext Points to an optional handler context which was specified when the
596 handler was registered.
597 @param[in, out] CommBuffer A pointer to a collection of data in memory that will
598 be conveyed from a non-SMM environment into an SMM environment.
599 @param[in, out] CommBufferSize The size of the CommBuffer.
601 @retval EFI_SUCCESS The interrupt was handled and quiesced. No other handlers
602 should still be called.
603 @retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED The interrupt has been quiesced but other handlers should
605 @retval EFI_WARN_INTERRUPT_SOURCE_PENDING The interrupt is still pending and other handlers should still
607 @retval EFI_INTERRUPT_PENDING The interrupt could not be quiesced.
612 IN EFI_HANDLE DispatchHandle
,
613 IN CONST VOID
*RegisterContext
,
614 IN OUT VOID
*CommBuffer
,
615 IN OUT UINTN
*CommBufferSize
618 SMMBASE_FUNCTION_DATA
*FunctionData
;
620 ASSERT (CommBuffer
!= NULL
);
621 ASSERT (*CommBufferSize
== sizeof (SMMBASE_FUNCTION_DATA
));
623 FunctionData
= (SMMBASE_FUNCTION_DATA
*)CommBuffer
;
625 switch (FunctionData
->Function
) {
626 case SmmBaseFunctionRegister
:
627 Register (FunctionData
);
629 case SmmBaseFunctionUnregister
:
630 UnRegister (FunctionData
);
632 case SmmBaseFunctionRegisterCallback
:
633 RegisterCallback (FunctionData
);
635 case SmmBaseFunctionAllocatePool
:
636 HelperAllocatePool (FunctionData
);
638 case SmmBaseFunctionFreePool
:
639 HelperFreePool (FunctionData
);
641 case SmmBaseFunctionCommunicate
:
642 HelperCommunicate (FunctionData
);
646 FunctionData
->Status
= EFI_UNSUPPORTED
;
652 Smm Ready To Lock event notification handler.
654 It sets a flag indicating that SMRAM has been locked.
656 @param[in] Protocol Points to the protocol's unique identifier.
657 @param[in] Interface Points to the interface instance.
658 @param[in] Handle The handle on which the interface was installed.
660 @retval EFI_SUCCESS Notification handler runs successfully.
664 SmmReadyToLockEventNotify (
665 IN CONST EFI_GUID
*Protocol
,
675 Entry point function of the SMM Base Helper SMM driver.
677 @param[in] ImageHandle The firmware allocated handle for the EFI image.
678 @param[in] SystemTable A pointer to the EFI System Table.
680 @retval EFI_SUCCESS The entry point is executed successfully.
681 @retval other Some error occurs when executing this entry point.
686 IN EFI_HANDLE ImageHandle
,
687 IN EFI_SYSTEM_TABLE
*SystemTable
691 EFI_MP_SERVICES_PROTOCOL
*MpServices
;
693 UINTN NumberOfEnabledProcessors
;
698 /// Locate SMM CPU Protocol which is used later to retrieve/update CPU Save States
700 Status
= gSmst
->SmmLocateProtocol (&gEfiSmmCpuProtocolGuid
, NULL
, (VOID
**) &mSmmCpu
);
701 ASSERT_EFI_ERROR (Status
);
704 /// Locate PE32 Image Protocol which is used later to load Framework SMM driver
706 Status
= SystemTable
->BootServices
->LocateProtocol (&gEfiLoadPeImageProtocolGuid
, NULL
, (VOID
**) &mLoadPe32Image
);
707 ASSERT_EFI_ERROR (Status
);
710 // Get MP Services Protocol
712 Status
= SystemTable
->BootServices
->LocateProtocol (&gEfiMpServiceProtocolGuid
, NULL
, (VOID
**)&MpServices
);
713 ASSERT_EFI_ERROR (Status
);
716 // Use MP Services Protocol to retrieve the number of processors and number of enabled processors
718 Status
= MpServices
->GetNumberOfProcessors (MpServices
, &mNumberOfProcessors
, &NumberOfEnabledProcessors
);
719 ASSERT_EFI_ERROR (Status
);
722 /// Interface structure of SMM BASE Helper Ready Protocol is allocated from UEFI pool
723 /// instead of SMM pool so that SMM Base Thunk driver can access it in Non-SMM mode.
725 Status
= gBS
->AllocatePool (
727 sizeof (EFI_SMM_BASE_HELPER_READY_PROTOCOL
),
728 (VOID
**)&mSmmBaseHelperReady
730 ASSERT_EFI_ERROR (Status
);
733 /// Construct Framework SMST from PI SMST
735 mFrameworkSmst
= ConstructFrameworkSmst ();
736 mSmmBaseHelperReady
->FrameworkSmst
= mFrameworkSmst
;
737 mSmmBaseHelperReady
->ServiceEntry
= SmmHandlerEntry
;
740 // Register SMM Ready To Lock Protocol notification
742 Status
= gSmst
->SmmRegisterProtocolNotify (
743 &gEfiSmmReadyToLockProtocolGuid
,
744 SmmReadyToLockEventNotify
,
747 ASSERT_EFI_ERROR (Status
);
750 /// Register SMM Base Helper services for SMM Base Thunk driver
752 Status
= gSmst
->SmiHandlerRegister (SmmHandlerEntry
, &gEfiSmmBaseThunkCommunicationGuid
, &mDispatchHandle
);
753 ASSERT_EFI_ERROR (Status
);
756 /// Install EFI SMM Base Helper Protocol in the UEFI handle database
758 Status
= gBS
->InstallProtocolInterface (
760 &gEfiSmmBaseHelperReadyProtocolGuid
,
761 EFI_NATIVE_INTERFACE
,
764 ASSERT_EFI_ERROR (Status
);