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
