summaryrefslogtreecommitdiffstats
path: root/UefiCpuPkg/Library/SmmCpuRendezvousLib/SmmCpuRendezvousLib.c
diff options
context:
space:
mode:
Diffstat (limited to 'UefiCpuPkg/Library/SmmCpuRendezvousLib/SmmCpuRendezvousLib.c')
-rw-r--r--UefiCpuPkg/Library/SmmCpuRendezvousLib/SmmCpuRendezvousLib.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/UefiCpuPkg/Library/SmmCpuRendezvousLib/SmmCpuRendezvousLib.c b/UefiCpuPkg/Library/SmmCpuRendezvousLib/SmmCpuRendezvousLib.c
new file mode 100644
index 0000000000..e573c2ecfb
--- /dev/null
+++ b/UefiCpuPkg/Library/SmmCpuRendezvousLib/SmmCpuRendezvousLib.c
@@ -0,0 +1,103 @@
+/** @file
+ SMM CPU Rendezvous sevice implement.
+
+ Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MmServicesTableLib.h>
+#include <Protocol/SmmCpuService.h>
+#include <Library/SmmCpuRendezvousLib.h>
+
+STATIC EDKII_SMM_CPU_RENDEZVOUS_PROTOCOL *mSmmCpuRendezvous = NULL;
+STATIC VOID *mRegistration = NULL;
+
+/**
+ Callback function to wait Smm cpu rendezvous service located.
+
+ SmmCpuRendezvousLib need to support MM_STANDALONE and DXE_SMM_DRIVER driver.
+ So do not use library constructor to locate the protocol.
+
+ @param[in] Protocol Points to the protocol's unique identifier.
+ @param[in] Interface Points to the interface instance.
+ @param[in] Handle The handle on which the interface was installed.
+
+ @retval EFI_SUCCESS Notification runs successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+SmmCpuRendezvousProtocolNotify (
+ IN CONST EFI_GUID *Protocol,
+ IN VOID *Interface,
+ IN EFI_HANDLE Handle
+ )
+{
+ EFI_STATUS Status;
+
+ Status = gMmst->MmLocateProtocol (
+ &gEdkiiSmmCpuRendezvousProtocolGuid,
+ NULL,
+ (VOID **)&mSmmCpuRendezvous
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This routine wait for all AP processors to arrive in SMM.
+
+ @param[in] BlockingMode Blocking mode or non-blocking mode.
+
+ @retval EFI_SUCCESS All avaiable APs arrived.
+ @retval EFI_TIMEOUT Wait for all APs until timeout.
+ @retval OTHER Fail to register SMM CPU Rendezvous service Protocol.
+**/
+EFI_STATUS
+EFIAPI
+SmmWaitForAllProcessor (
+ IN BOOLEAN BlockingMode
+ )
+{
+ EFI_STATUS Status;
+
+ if ((mRegistration == NULL) && (mSmmCpuRendezvous == NULL)) {
+ //
+ // Locate SMM cpu rendezvous protocol for the first time execute the function.
+ //
+ Status = gMmst->MmLocateProtocol (
+ &gEdkiiSmmCpuRendezvousProtocolGuid,
+ NULL,
+ (VOID **)&mSmmCpuRendezvous
+ );
+ if (EFI_ERROR (Status)) {
+ Status = gMmst->MmRegisterProtocolNotify (
+ &gEdkiiSmmCpuRendezvousProtocolGuid,
+ SmmCpuRendezvousProtocolNotify,
+ &mRegistration
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+ }
+
+ //
+ // The platform have not set up. It doesn't need smm cpu rendezvous.
+ //
+ if (mSmmCpuRendezvous == NULL) {
+ return EFI_SUCCESS;
+ }
+
+ Status = mSmmCpuRendezvous->WaitForAllProcessor (
+ mSmmCpuRendezvous,
+ BlockingMode
+ );
+ return Status;
+}