Because of AcquireSpinLock()/ReleaseSpinLock() was not MP safe,
We should introduce CPU bus lock to replace them.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Chen Fan <[email protected]>
---
 UefiCpuPkg/CpuDxe/CpuDxe.inf      |  1 -
 UefiCpuPkg/CpuDxe/CpuMp.c         | 33 ++++++++++++++++-----------------
 UefiCpuPkg/CpuDxe/CpuMp.h         | 24 ++++++++++++++++++++++--
 UefiCpuPkg/CpuDxe/Ia32/MpAsm.nasm | 31 +++++++++++++++++++++++++++++++
 UefiCpuPkg/CpuDxe/X64/MpAsm.nasm  | 31 +++++++++++++++++++++++++++++++
 UefiCpuPkg/UefiCpuPkg.dsc         |  1 -
 6 files changed, 100 insertions(+), 21 deletions(-)

diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.inf b/UefiCpuPkg/CpuDxe/CpuDxe.inf
index ed90ff2..f73b845 100644
--- a/UefiCpuPkg/CpuDxe/CpuDxe.inf
+++ b/UefiCpuPkg/CpuDxe/CpuDxe.inf
@@ -41,7 +41,6 @@
   UefiCpuLib
   UefiLib
   CpuExceptionHandlerLib
-  SynchronizationLib
 
 [Sources]
   ApStartup.c
diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c
index 2ba1e28..bcf5106 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.c
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -78,9 +78,9 @@ GetApState (
 {
   CPU_STATE State;
 
-  AcquireSpinLock (&CpuData->CpuDataLock);
+  AsmApAcquireSpinLock ();
   State = CpuData->State;
-  ReleaseSpinLock (&CpuData->CpuDataLock);
+  AsmApReleaseSpinLock ();
 
   return State;
 }
@@ -98,9 +98,9 @@ SetApState (
   IN  CPU_STATE        State
   )
 {
-  AcquireSpinLock (&CpuData->CpuDataLock);
+  AsmApAcquireSpinLock ();
   CpuData->State = State;
-  ReleaseSpinLock (&CpuData->CpuDataLock);
+  AsmApReleaseSpinLock ();
 }
 
 /**
@@ -119,10 +119,10 @@ SetApProcedure (
   IN   VOID                  *ProcedureArgument
   )
 {
-  AcquireSpinLock (&CpuData->CpuDataLock);
+  AsmApAcquireSpinLock ();
   CpuData->Parameter  = ProcedureArgument;
   CpuData->Procedure  = Procedure;
-  ReleaseSpinLock (&CpuData->CpuDataLock);
+  AsmApReleaseSpinLock ();
 }
 
 /**
@@ -143,9 +143,9 @@ TestCpuStatusFlag (
 {
   UINT32 Ret;
 
-  AcquireSpinLock (&CpuData->CpuDataLock);
+  AsmApAcquireSpinLock ();
   Ret = CpuData->Info.StatusFlag & Flags;
-  ReleaseSpinLock (&CpuData->CpuDataLock);
+  AsmApReleaseSpinLock ();
 
   return !!(Ret);
 }
@@ -163,9 +163,9 @@ CpuStatusFlagOr (
   IN  UINT32          Flags
   )
 {
-  AcquireSpinLock (&CpuData->CpuDataLock);
+  AsmApAcquireSpinLock ();
   CpuData->Info.StatusFlag |= Flags;
-  ReleaseSpinLock (&CpuData->CpuDataLock);
+  AsmApReleaseSpinLock ();
 }
 
 /**
@@ -181,9 +181,9 @@ CpuStatusFlagAndNot (
   IN  UINT32          Flags
   )
 {
-  AcquireSpinLock (&CpuData->CpuDataLock);
+  AsmApAcquireSpinLock ();
   CpuData->Info.StatusFlag &= ~Flags;
-  ReleaseSpinLock (&CpuData->CpuDataLock);
+  AsmApReleaseSpinLock ();
 }
 
 /**
@@ -671,19 +671,19 @@ ApDoLoop (
   CpuData = (CPU_DATA_BLOCK *)Context;
 
   while (TRUE) {
-    AcquireSpinLock (&CpuData->CpuDataLock);
+    AsmApAcquireSpinLock ();
     ProcedureArgument = CpuData->Parameter;
     Procedure = CpuData->Procedure;
-    ReleaseSpinLock (&CpuData->CpuDataLock);
+    AsmApReleaseSpinLock ();
 
     if (Procedure != NULL) {
       SetApState (CpuData, CPU_STATE_BUSY);
 
       Procedure (ProcedureArgument);
 
-      AcquireSpinLock (&CpuData->CpuDataLock);
+      AsmApAcquireSpinLock ();
       CpuData->Procedure = NULL;
-      ReleaseSpinLock (&CpuData->CpuDataLock);
+      AsmApReleaseSpinLock ();
 
       SetApState (CpuData, CPU_STATE_FINISHED);
     }
@@ -766,7 +766,6 @@ InitMpSystemData (
       CpuData->Info.StatusFlag |= PROCESSOR_AS_BSP_BIT;
       CpuData->Info.ProcessorId = GetApicId ();
     }
-    InitializeSpinLock (&CpuData->CpuDataLock);
 
     Status = gBS->CreateEvent (
                     EVT_TIMER | EVT_NOTIFY_SIGNAL,
diff --git a/UefiCpuPkg/CpuDxe/CpuMp.h b/UefiCpuPkg/CpuDxe/CpuMp.h
index 411fe81..236fd22 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.h
+++ b/UefiCpuPkg/CpuDxe/CpuMp.h
@@ -16,7 +16,6 @@
 #define _CPU_MP_H_
 
 #include <Protocol/MpService.h>
-#include <Library/SynchronizationLib.h>
 
 #define AP_STACK_SIZE      SIZE_64KB
 
@@ -110,6 +109,28 @@ AsmApReleaseLock (
   VOID
   );
 
+/**
+  the function added a CPU bus lock to protect the same data location
+  in multi processors environment.
+
+**/
+VOID
+EFIAPI
+AsmApAcquireSpinLock (
+  VOID
+  );
+
+/**
+  release the CPU bus lock.
+
+**/
+VOID
+EFIAPI
+AsmApReleaseSpinLock (
+  VOID
+  );
+
+
 typedef enum {
   CPU_STATE_IDLE,
   CPU_STATE_BLOCKED,
@@ -124,7 +145,6 @@ typedef enum {
 **/
 typedef struct {
   EFI_PROCESSOR_INFORMATION      Info;
-  SPIN_LOCK                      CpuDataLock;
   CPU_STATE volatile             State;
 
   EFI_AP_PROCEDURE               Procedure;
diff --git a/UefiCpuPkg/CpuDxe/Ia32/MpAsm.nasm 
b/UefiCpuPkg/CpuDxe/Ia32/MpAsm.nasm
index 154b3a5..de7d3a4 100644
--- a/UefiCpuPkg/CpuDxe/Ia32/MpAsm.nasm
+++ b/UefiCpuPkg/CpuDxe/Ia32/MpAsm.nasm
@@ -24,6 +24,9 @@ extern ASM_PFX(mCpuExchangeData)
 ApStackLock:
     dd      0
 
+ApSpinLock:
+    dd      0
+
 ;------------------------------------------------------------------------------
 ; VOID
 ; EFIAPI
@@ -111,3 +114,31 @@ ASM_PFX(AsmApReleaseLock):
 lock btc  dword[ApStackLock], 0
     ret
 
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; AsmApAcquireSpinLock (
+;   VOID
+;   );
+;------------------------------------------------------------------------------
+global ASM_PFX(AsmApAcquireSpinLock)
+ASM_PFX(AsmApAcquireSpinLock):
+AsmApSpinLock:
+lock bts   dword[ApSpinLock], 0
+    pause
+    jc     AsmApSpinLock
+
+    ret
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; AsmApReleaseSpinLock (
+;   VOID
+;   );
+;------------------------------------------------------------------------------
+global ASM_PFX(AsmApReleaseSpinLock)
+ASM_PFX(AsmApReleaseSpinLock):
+lock btc  dword[ApSpinLock], 0
+    ret
+
diff --git a/UefiCpuPkg/CpuDxe/X64/MpAsm.nasm b/UefiCpuPkg/CpuDxe/X64/MpAsm.nasm
index 46ed107..dec9ee7 100644
--- a/UefiCpuPkg/CpuDxe/X64/MpAsm.nasm
+++ b/UefiCpuPkg/CpuDxe/X64/MpAsm.nasm
@@ -24,6 +24,9 @@ extern ASM_PFX(mCpuExchangeData)
 ApStackLock:
     dd      0
 
+ApSpinLock:
+    dd      0
+
 ;------------------------------------------------------------------------------
 ; VOID
 ; EFIAPI
@@ -109,3 +112,31 @@ ASM_PFX(AsmApReleaseLock):
 lock btc  dword[ApStackLock], 0
     ret
 
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; AsmApAcquireSpinLock (
+;   VOID
+;   );
+;------------------------------------------------------------------------------
+global ASM_PFX(AsmApAcquireSpinLock)
+ASM_PFX(AsmApAcquireSpinLock):
+AsmApSpinLock:
+lock bts   dword[ApSpinLock], 0
+    pause
+    jc     AsmApSpinLock
+
+    ret
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; AsmApReleaseSpinLock (
+;   VOID
+;   );
+;------------------------------------------------------------------------------
+global ASM_PFX(AsmApReleaseSpinLock)
+ASM_PFX(AsmApReleaseSpinLock):
+lock btc  dword[ApSpinLock], 0
+    ret
+
diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc
index 9fa9270..70d5bb0 100644
--- a/UefiCpuPkg/UefiCpuPkg.dsc
+++ b/UefiCpuPkg/UefiCpuPkg.dsc
@@ -52,7 +52,6 @@
   LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf
   
ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf
   
CpuExceptionHandlerLib|MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf
  
-  
SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
 
 [LibraryClasses.common.PEIM]
   
MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
-- 
1.9.3


------------------------------------------------------------------------------
Want excitement?
Manually upgrade your production database.
When you want reliability, choose Perforce
Perforce version control. Predictably reliable.
http://pubads.g.doubleclick.net/gampad/clk?id=157508191&iu=/4140/ostg.clktrk
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to