From 720d3c5fb31b6b2df535f7a281d5d9d297c5eede Mon Sep 17 00:00:00 2001 From: mdkinney Date: Fri, 30 Jan 2009 00:45:13 +0000 Subject: [PATCH] Split out Synchronization Library from Base Library git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@7377 6f19259b-4bc3-4df7-8a09-765794883524 --- MdePkg/Include/Library/BaseLib.h | 254 ----------- MdePkg/Include/Library/SynchronizationLib.h | 269 ++++++++++++ MdePkg/Library/BaseLib/BaseLib.inf | 40 -- MdePkg/Library/BaseLib/BaseLibInternals.h | 93 ---- .../BaseSynchronizationLib.inf | 88 ++++ .../BaseSynchronizationLibInternals.h | 115 +++++ .../Ebc/Synchronization.c | 116 +++++ .../Ia32/InterlockedCompareExchange32.S | 41 ++ .../Ia32/InterlockedCompareExchange32.asm | 45 ++ .../Ia32/InterlockedCompareExchange32.c | 50 +++ .../Ia32/InterlockedCompareExchange64.S | 47 ++ .../Ia32/InterlockedCompareExchange64.asm | 47 ++ .../Ia32/InterlockedCompareExchange64.c | 50 +++ .../Ia32/InterlockedDecrement.S | 38 ++ .../Ia32/InterlockedDecrement.asm | 42 ++ .../Ia32/InterlockedDecrement.c | 42 ++ .../Ia32/InterlockedIncrement.S | 38 ++ .../Ia32/InterlockedIncrement.asm | 42 ++ .../Ia32/InterlockedIncrement.c | 43 ++ .../Ipf/InterlockedCompareExchange32.s | 29 ++ .../Ipf/InterlockedCompareExchange64.s | 28 ++ .../Ipf/Synchronization.c | 77 ++++ .../BaseSynchronizationLib/Synchronization.c | 387 +++++++++++++++++ .../SynchronizationGcc.c | 402 +++++++++++++++++ .../SynchronizationMsc.c | 405 ++++++++++++++++++ .../X64/InterlockedCompareExchange32.S | 37 ++ .../X64/InterlockedCompareExchange32.asm | 41 ++ .../X64/InterlockedCompareExchange32.c | 54 +++ .../X64/InterlockedCompareExchange64.S | 39 ++ .../X64/InterlockedCompareExchange64.asm | 41 ++ .../X64/InterlockedCompareExchange64.c | 53 +++ .../X64/InterlockedDecrement.S | 36 ++ .../X64/InterlockedDecrement.asm | 39 ++ .../X64/InterlockedDecrement.c | 46 ++ .../X64/InterlockedIncrement.S | 36 ++ .../X64/InterlockedIncrement.asm | 39 ++ .../X64/InterlockedIncrement.c | 46 ++ MdePkg/MdePkg.dec | 4 + MdePkg/MdePkg.dsc | 1 + 39 files changed, 2953 insertions(+), 387 deletions(-) create mode 100644 MdePkg/Include/Library/SynchronizationLib.h create mode 100644 MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf create mode 100644 MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange32.S create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange32.asm create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange32.c create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange64.S create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange64.asm create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange64.c create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedDecrement.S create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedDecrement.asm create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedDecrement.c create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedIncrement.S create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedIncrement.asm create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedIncrement.c create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange32.s create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange64.s create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ipf/Synchronization.c create mode 100644 MdePkg/Library/BaseSynchronizationLib/Synchronization.c create mode 100644 MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c create mode 100644 MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c create mode 100644 MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange32.S create mode 100644 MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange32.asm create mode 100644 MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange32.c create mode 100644 MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange64.S create mode 100644 MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange64.asm create mode 100644 MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange64.c create mode 100644 MdePkg/Library/BaseSynchronizationLib/X64/InterlockedDecrement.S create mode 100644 MdePkg/Library/BaseSynchronizationLib/X64/InterlockedDecrement.asm create mode 100644 MdePkg/Library/BaseSynchronizationLib/X64/InterlockedDecrement.c create mode 100644 MdePkg/Library/BaseSynchronizationLib/X64/InterlockedIncrement.S create mode 100644 MdePkg/Library/BaseSynchronizationLib/X64/InterlockedIncrement.asm create mode 100644 MdePkg/Library/BaseSynchronizationLib/X64/InterlockedIncrement.c diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h index 72ac6f47ed..6f25f236bc 100644 --- a/MdePkg/Include/Library/BaseLib.h +++ b/MdePkg/Include/Library/BaseLib.h @@ -16,11 +16,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #ifndef __BASE_LIB__ #define __BASE_LIB__ -/// -/// Definitions for SPIN_LOCK -/// -typedef volatile UINTN SPIN_LOCK; - // // Definitions for architecture specific types // @@ -2890,255 +2885,6 @@ BitFieldAndThenOr64 ( IN UINT64 OrData ); - -// -// Base Library Synchronization Functions -// - -/** - Retrieves the architecture specific spin lock alignment requirements for - optimal spin lock performance. - - This function retrieves the spin lock alignment requirements for optimal - performance on a given CPU architecture. The spin lock alignment must be a - power of two and is returned by this function. If there are no alignment - requirements, then 1 must be returned. The spin lock synchronization - functions must function correctly if the spin lock size and alignment values - returned by this function are not used at all. These values are hints to the - consumers of the spin lock synchronization functions to obtain optimal spin - lock performance. - - @return The architecture specific spin lock alignment. - -**/ -UINTN -EFIAPI -GetSpinLockProperties ( - VOID - ); - - -/** - Initializes a spin lock to the released state and returns the spin lock. - - This function initializes the spin lock specified by SpinLock to the released - state, and returns SpinLock. Optimal performance can be achieved by calling - GetSpinLockProperties() to determine the size and alignment requirements for - SpinLock. - - If SpinLock is NULL, then ASSERT(). - - @param SpinLock A pointer to the spin lock to initialize to the released - state. - - @return SpinLock in release state. - -**/ -SPIN_LOCK * -EFIAPI -InitializeSpinLock ( - OUT SPIN_LOCK *SpinLock - ); - - -/** - Waits until a spin lock can be placed in the acquired state. - - This function checks the state of the spin lock specified by SpinLock. If - SpinLock is in the released state, then this function places SpinLock in the - acquired state and returns SpinLock. Otherwise, this function waits - indefinitely for the spin lock to be released, and then places it in the - acquired state and returns SpinLock. All state transitions of SpinLock must - be performed using MP safe mechanisms. - - If SpinLock is NULL, then ASSERT(). - If SpinLock was not initialized with InitializeSpinLock(), then ASSERT(). - If PcdSpinLockTimeout is not zero, and SpinLock is can not be acquired in - PcdSpinLockTimeout microseconds, then ASSERT(). - - @param SpinLock A pointer to the spin lock to place in the acquired state. - - @return SpinLock acquired lock. - -**/ -SPIN_LOCK * -EFIAPI -AcquireSpinLock ( - IN OUT SPIN_LOCK *SpinLock - ); - - -/** - Attempts to place a spin lock in the acquired state. - - This function checks the state of the spin lock specified by SpinLock. If - SpinLock is in the released state, then this function places SpinLock in the - acquired state and returns TRUE. Otherwise, FALSE is returned. All state - transitions of SpinLock must be performed using MP safe mechanisms. - - If SpinLock is NULL, then ASSERT(). - If SpinLock was not initialized with InitializeSpinLock(), then ASSERT(). - - @param SpinLock A pointer to the spin lock to place in the acquired state. - - @retval TRUE SpinLock was placed in the acquired state. - @retval FALSE SpinLock could not be acquired. - -**/ -BOOLEAN -EFIAPI -AcquireSpinLockOrFail ( - IN OUT SPIN_LOCK *SpinLock - ); - - -/** - Releases a spin lock. - - This function places the spin lock specified by SpinLock in the release state - and returns SpinLock. - - If SpinLock is NULL, then ASSERT(). - If SpinLock was not initialized with InitializeSpinLock(), then ASSERT(). - - @param SpinLock A pointer to the spin lock to release. - - @return SpinLock released lock. - -**/ -SPIN_LOCK * -EFIAPI -ReleaseSpinLock ( - IN OUT SPIN_LOCK *SpinLock - ); - - -/** - Performs an atomic increment of an 32-bit unsigned integer. - - Performs an atomic increment of the 32-bit unsigned integer specified by - Value and returns the incremented value. The increment operation must be - performed using MP safe mechanisms. The state of the return value is not - guaranteed to be MP safe. - - If Value is NULL, then ASSERT(). - - @param Value A pointer to the 32-bit value to increment. - - @return The incremented value. - -**/ -UINT32 -EFIAPI -InterlockedIncrement ( - IN UINT32 *Value - ); - - -/** - Performs an atomic decrement of an 32-bit unsigned integer. - - Performs an atomic decrement of the 32-bit unsigned integer specified by - Value and returns the decremented value. The decrement operation must be - performed using MP safe mechanisms. The state of the return value is not - guaranteed to be MP safe. - - If Value is NULL, then ASSERT(). - - @param Value A pointer to the 32-bit value to decrement. - - @return The decremented value. - -**/ -UINT32 -EFIAPI -InterlockedDecrement ( - IN UINT32 *Value - ); - - -/** - Performs an atomic compare exchange operation on a 32-bit unsigned integer. - - Performs an atomic compare exchange operation on the 32-bit unsigned integer - specified by Value. If Value is equal to CompareValue, then Value is set to - ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue, - then Value is returned. The compare exchange operation must be performed using - MP safe mechanisms. - - If Value is NULL, then ASSERT(). - - @param Value A pointer to the 32-bit value for the compare exchange - operation. - @param CompareValue 32-bit value used in compare operation. - @param ExchangeValue 32-bit value used in exchange operation. - - @return The original *Value before exchange. - -**/ -UINT32 -EFIAPI -InterlockedCompareExchange32 ( - IN OUT UINT32 *Value, - IN UINT32 CompareValue, - IN UINT32 ExchangeValue - ); - - -/** - Performs an atomic compare exchange operation on a 64-bit unsigned integer. - - Performs an atomic compare exchange operation on the 64-bit unsigned integer specified - by Value. If Value is equal to CompareValue, then Value is set to ExchangeValue and - CompareValue is returned. If Value is not equal to CompareValue, then Value is returned. - The compare exchange operation must be performed using MP safe mechanisms. - - If Value is NULL, then ASSERT(). - - @param Value A pointer to the 64-bit value for the compare exchange - operation. - @param CompareValue 64-bit value used in compare operation. - @param ExchangeValue 64-bit value used in exchange operation. - - @return The original *Value before exchange. - -**/ -UINT64 -EFIAPI -InterlockedCompareExchange64 ( - IN OUT UINT64 *Value, - IN UINT64 CompareValue, - IN UINT64 ExchangeValue - ); - - -/** - Performs an atomic compare exchange operation on a pointer value. - - Performs an atomic compare exchange operation on the pointer value specified - by Value. If Value is equal to CompareValue, then Value is set to - ExchangeValue and CompareValue is returned. If Value is not equal to - CompareValue, then Value is returned. The compare exchange operation must be - performed using MP safe mechanisms. - - If Value is NULL, then ASSERT(). - - @param Value A pointer to the pointer value for the compare exchange - operation. - @param CompareValue Pointer value used in compare operation. - @param ExchangeValue Pointer value used in exchange operation. - - @return The original *Value before exchange. -**/ -VOID * -EFIAPI -InterlockedCompareExchangePointer ( - IN OUT VOID **Value, - IN VOID *CompareValue, - IN VOID *ExchangeValue - ); - - // // Base Library Checksum Functions // diff --git a/MdePkg/Include/Library/SynchronizationLib.h b/MdePkg/Include/Library/SynchronizationLib.h new file mode 100644 index 0000000000..bf92ca1d7a --- /dev/null +++ b/MdePkg/Include/Library/SynchronizationLib.h @@ -0,0 +1,269 @@ +/** @file + Provides synchronization functions. + +Copyright (c) 2006 - 2008, Intel Corporation
+All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __SYNCHRONIZATION_LIB__ +#define __SYNCHRONIZATION_LIB__ + +/// +/// Definitions for SPIN_LOCK +/// +typedef volatile UINTN SPIN_LOCK; + + +/** + Retrieves the architecture specific spin lock alignment requirements for + optimal spin lock performance. + + This function retrieves the spin lock alignment requirements for optimal + performance on a given CPU architecture. The spin lock alignment must be a + power of two and is returned by this function. If there are no alignment + requirements, then 1 must be returned. The spin lock synchronization + functions must function correctly if the spin lock size and alignment values + returned by this function are not used at all. These values are hints to the + consumers of the spin lock synchronization functions to obtain optimal spin + lock performance. + + @return The architecture specific spin lock alignment. + +**/ +UINTN +EFIAPI +GetSpinLockProperties ( + VOID + ); + + +/** + Initializes a spin lock to the released state and returns the spin lock. + + This function initializes the spin lock specified by SpinLock to the released + state, and returns SpinLock. Optimal performance can be achieved by calling + GetSpinLockProperties() to determine the size and alignment requirements for + SpinLock. + + If SpinLock is NULL, then ASSERT(). + + @param SpinLock A pointer to the spin lock to initialize to the released + state. + + @return SpinLock in release state. + +**/ +SPIN_LOCK * +EFIAPI +InitializeSpinLock ( + OUT SPIN_LOCK *SpinLock + ); + + +/** + Waits until a spin lock can be placed in the acquired state. + + This function checks the state of the spin lock specified by SpinLock. If + SpinLock is in the released state, then this function places SpinLock in the + acquired state and returns SpinLock. Otherwise, this function waits + indefinitely for the spin lock to be released, and then places it in the + acquired state and returns SpinLock. All state transitions of SpinLock must + be performed using MP safe mechanisms. + + If SpinLock is NULL, then ASSERT(). + If SpinLock was not initialized with InitializeSpinLock(), then ASSERT(). + If PcdSpinLockTimeout is not zero, and SpinLock is can not be acquired in + PcdSpinLockTimeout microseconds, then ASSERT(). + + @param SpinLock A pointer to the spin lock to place in the acquired state. + + @return SpinLock acquired lock. + +**/ +SPIN_LOCK * +EFIAPI +AcquireSpinLock ( + IN OUT SPIN_LOCK *SpinLock + ); + + +/** + Attempts to place a spin lock in the acquired state. + + This function checks the state of the spin lock specified by SpinLock. If + SpinLock is in the released state, then this function places SpinLock in the + acquired state and returns TRUE. Otherwise, FALSE is returned. All state + transitions of SpinLock must be performed using MP safe mechanisms. + + If SpinLock is NULL, then ASSERT(). + If SpinLock was not initialized with InitializeSpinLock(), then ASSERT(). + + @param SpinLock A pointer to the spin lock to place in the acquired state. + + @retval TRUE SpinLock was placed in the acquired state. + @retval FALSE SpinLock could not be acquired. + +**/ +BOOLEAN +EFIAPI +AcquireSpinLockOrFail ( + IN OUT SPIN_LOCK *SpinLock + ); + + +/** + Releases a spin lock. + + This function places the spin lock specified by SpinLock in the release state + and returns SpinLock. + + If SpinLock is NULL, then ASSERT(). + If SpinLock was not initialized with InitializeSpinLock(), then ASSERT(). + + @param SpinLock A pointer to the spin lock to release. + + @return SpinLock released lock. + +**/ +SPIN_LOCK * +EFIAPI +ReleaseSpinLock ( + IN OUT SPIN_LOCK *SpinLock + ); + + +/** + Performs an atomic increment of an 32-bit unsigned integer. + + Performs an atomic increment of the 32-bit unsigned integer specified by + Value and returns the incremented value. The increment operation must be + performed using MP safe mechanisms. The state of the return value is not + guaranteed to be MP safe. + + If Value is NULL, then ASSERT(). + + @param Value A pointer to the 32-bit value to increment. + + @return The incremented value. + +**/ +UINT32 +EFIAPI +InterlockedIncrement ( + IN UINT32 *Value + ); + + +/** + Performs an atomic decrement of an 32-bit unsigned integer. + + Performs an atomic decrement of the 32-bit unsigned integer specified by + Value and returns the decremented value. The decrement operation must be + performed using MP safe mechanisms. The state of the return value is not + guaranteed to be MP safe. + + If Value is NULL, then ASSERT(). + + @param Value A pointer to the 32-bit value to decrement. + + @return The decremented value. + +**/ +UINT32 +EFIAPI +InterlockedDecrement ( + IN UINT32 *Value + ); + + +/** + Performs an atomic compare exchange operation on a 32-bit unsigned integer. + + Performs an atomic compare exchange operation on the 32-bit unsigned integer + specified by Value. If Value is equal to CompareValue, then Value is set to + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue, + then Value is returned. The compare exchange operation must be performed using + MP safe mechanisms. + + If Value is NULL, then ASSERT(). + + @param Value A pointer to the 32-bit value for the compare exchange + operation. + @param CompareValue 32-bit value used in compare operation. + @param ExchangeValue 32-bit value used in exchange operation. + + @return The original *Value before exchange. + +**/ +UINT32 +EFIAPI +InterlockedCompareExchange32 ( + IN OUT UINT32 *Value, + IN UINT32 CompareValue, + IN UINT32 ExchangeValue + ); + + +/** + Performs an atomic compare exchange operation on a 64-bit unsigned integer. + + Performs an atomic compare exchange operation on the 64-bit unsigned integer specified + by Value. If Value is equal to CompareValue, then Value is set to ExchangeValue and + CompareValue is returned. If Value is not equal to CompareValue, then Value is returned. + The compare exchange operation must be performed using MP safe mechanisms. + + If Value is NULL, then ASSERT(). + + @param Value A pointer to the 64-bit value for the compare exchange + operation. + @param CompareValue 64-bit value used in compare operation. + @param ExchangeValue 64-bit value used in exchange operation. + + @return The original *Value before exchange. + +**/ +UINT64 +EFIAPI +InterlockedCompareExchange64 ( + IN OUT UINT64 *Value, + IN UINT64 CompareValue, + IN UINT64 ExchangeValue + ); + + +/** + Performs an atomic compare exchange operation on a pointer value. + + Performs an atomic compare exchange operation on the pointer value specified + by Value. If Value is equal to CompareValue, then Value is set to + ExchangeValue and CompareValue is returned. If Value is not equal to + CompareValue, then Value is returned. The compare exchange operation must be + performed using MP safe mechanisms. + + If Value is NULL, then ASSERT(). + + @param Value A pointer to the pointer value for the compare exchange + operation. + @param CompareValue Pointer value used in compare operation. + @param ExchangeValue Pointer value used in exchange operation. + + @return The original *Value before exchange. +**/ +VOID * +EFIAPI +InterlockedCompareExchangePointer ( + IN OUT VOID **Value, + IN VOID *CompareValue, + IN VOID *ExchangeValue + ); + +#endif + + diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf index c4915f8b8f..71c1950dda 100644 --- a/MdePkg/Library/BaseLib/BaseLib.inf +++ b/MdePkg/Library/BaseLib/BaseLib.inf @@ -134,10 +134,6 @@ Ia32/LRotU64.c | MSFT Ia32/LongJump.c | MSFT Ia32/Invd.c | MSFT - Ia32/InterlockedCompareExchange64.c | MSFT - Ia32/InterlockedCompareExchange32.c | MSFT - Ia32/InterlockedDecrement.c | MSFT - Ia32/InterlockedIncrement.c | MSFT Ia32/FxRestore.c | MSFT Ia32/FxSave.c | MSFT Ia32/FlushCacheLine.c | MSFT @@ -158,7 +154,6 @@ Ia32/EnablePaging64.asm | MSFT Ia32/EnableCache.c | MSFT Ia32/DisableCache.c | MSFT - SynchronizationMsc.c | MSFT Ia32/Wbinvd.asm | INTEL Ia32/WriteMm7.asm | INTEL @@ -232,10 +227,6 @@ Ia32/LRotU64.asm | INTEL Ia32/LongJump.asm | INTEL Ia32/Invd.asm | INTEL - Ia32/InterlockedCompareExchange64.asm | INTEL - Ia32/InterlockedCompareExchange32.asm | INTEL - Ia32/InterlockedDecrement.asm | INTEL - Ia32/InterlockedIncrement.asm | INTEL Ia32/FxRestore.asm | INTEL Ia32/FxSave.asm | INTEL Ia32/FlushCacheLine.asm | INTEL @@ -256,7 +247,6 @@ Ia32/EnablePaging64.asm | INTEL Ia32/EnableCache.asm | INTEL Ia32/DisableCache.asm | INTEL - Synchronization.c | INTEL Ia32/Thunk16.S | GCC Ia32/CpuBreakpoint.S | GCC @@ -264,10 +254,6 @@ Ia32/EnableDisableInterrupts.S | GCC Ia32/DisableInterrupts.S | GCC Ia32/EnableInterrupts.S | GCC - Ia32/InterlockedCompareExchange64.S | GCC - Ia32/InterlockedCompareExchange32.S | GCC - Ia32/InterlockedDecrement.S | GCC - Ia32/InterlockedIncrement.S | GCC Ia32/FlushCacheLine.S | GCC Ia32/Invd.S | GCC Ia32/Wbinvd.S | GCC @@ -354,7 +340,6 @@ Ia32/LShiftU64.S | GCC Ia32/EnableCache.S | GCC Ia32/DisableCache.S | GCC - SynchronizationGcc.c | GCC Ia32/DivS64x64Remainder.c Ia32/InternalSwitchStack.c @@ -451,24 +436,16 @@ X64/LongJump.asm X64/SetJump.asm X64/SwitchStack.asm - X64/InterlockedCompareExchange64.asm - X64/InterlockedCompareExchange32.asm X64/EnableCache.asm X64/DisableCache.asm - X64/InterlockedDecrement.c | MSFT - X64/InterlockedIncrement.c | MSFT X64/CpuBreakpoint.c | MSFT X64/WriteMsr64.c | MSFT X64/ReadMsr64.c | MSFT - SynchronizationMsc.c | MSFT - X64/InterlockedDecrement.asm | INTEL - X64/InterlockedIncrement.asm | INTEL X64/CpuBreakpoint.asm | INTEL X64/WriteMsr64.asm | INTEL X64/ReadMsr64.asm | INTEL - Synchronization.c | INTEL X64/Non-existing.c Math64.c @@ -553,10 +530,6 @@ X64/Monitor.S | GCC X64/LongJump.S | GCC X64/Invd.S | GCC - X64/InterlockedIncrement.S | GCC - X64/InterlockedDecrement.S | GCC - X64/InterlockedCompareExchange64.S | GCC - X64/InterlockedCompareExchange32.S | GCC X64/FxSave.S | GCC X64/FxRestore.S | GCC X64/FlushCacheLine.S | GCC @@ -569,7 +542,6 @@ X64/CpuId.S | GCC X64/CpuIdEx.S | GCC X64/CpuBreakpoint.S | GCC - SynchronizationGcc.c | GCC X64/EnableCache.S | GCC X64/DisableCache.S | GCC ChkStkGcc.c | GCC @@ -592,9 +564,6 @@ Ipf/InternalSwitchStack.c Ipf/GetInterruptState.s Ipf/CpuPause.s - Ipf/Synchronization.c - Ipf/InterlockedCompareExchange64.s - Ipf/InterlockedCompareExchange32.s Ipf/CpuBreakpoint.c | INTEL Ipf/CpuBreakpointMsc.c | MSFT Ipf/AsmCpuMisc.s | GCC @@ -607,13 +576,8 @@ Ipf/Ia64gen.h Ipf/Asm.h Math64.c - Synchronization.c | INTEL - SynchronizationMsc.c | MSFT - SynchronizationGcc.c | GCC [Sources.EBC] - Synchronization.c - Ebc/Synchronization.c Ebc/CpuBreakpoint.c Ebc/SetJumpLongJump.c Ebc/SwitchStack.c @@ -623,16 +587,12 @@ [Packages] MdePkg/MdePkg.dec - [LibraryClasses] PcdLib - TimerLib DebugLib BaseMemoryLib - [Pcd.common] - gEfiMdePkgTokenSpaceGuid.PcdSpinLockTimeout gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength diff --git a/MdePkg/Library/BaseLib/BaseLibInternals.h b/MdePkg/Library/BaseLib/BaseLibInternals.h index 3223de55ac..19ed01beda 100644 --- a/MdePkg/Library/BaseLib/BaseLibInternals.h +++ b/MdePkg/Library/BaseLib/BaseLibInternals.h @@ -19,7 +19,6 @@ #include #include #include -#include #include // @@ -368,98 +367,6 @@ IsNodeInList ( IN CONST LIST_ENTRY *Node ); - -/** - Performs an atomic increment of an 32-bit unsigned integer. - - Performs an atomic increment of the 32-bit unsigned integer specified by - Value and returns the incremented value. The increment operation must be - performed using MP safe mechanisms. The state of the return value is not - guaranteed to be MP safe. - - @param Value A pointer to the 32-bit value to increment. - - @return The incremented value. - -**/ -UINT32 -EFIAPI -InternalSyncIncrement ( - IN volatile UINT32 *Value - ); - - -/** - Performs an atomic decrement of an 32-bit unsigned integer. - - Performs an atomic decrement of the 32-bit unsigned integer specified by - Value and returns the decrement value. The decrement operation must be - performed using MP safe mechanisms. The state of the return value is not - guaranteed to be MP safe. - - @param Value A pointer to the 32-bit value to decrement. - - @return The decrement value. - -**/ -UINT32 -EFIAPI -InternalSyncDecrement ( - IN volatile UINT32 *Value - ); - - -/** - Performs an atomic compare exchange operation on a 32-bit unsigned integer. - - Performs an atomic compare exchange operation on the 32-bit unsigned integer - specified by Value. If Value is equal to CompareValue, then Value is set to - ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue, - then Value is returned. The compare exchange operation must be performed using - MP safe mechanisms. - - @param Value A pointer to the 32-bit value for the compare exchange - operation. - @param CompareValue 32-bit value used in compare operation. - @param ExchangeValue 32-bit value used in exchange operation. - - @return The original *Value before exchange. - -**/ -UINT32 -EFIAPI -InternalSyncCompareExchange32 ( - IN volatile UINT32 *Value, - IN UINT32 CompareValue, - IN UINT32 ExchangeValue - ); - - -/** - Performs an atomic compare exchange operation on a 64-bit unsigned integer. - - Performs an atomic compare exchange operation on the 64-bit unsigned integer specified - by Value. If Value is equal to CompareValue, then Value is set to ExchangeValue and - CompareValue is returned. If Value is not equal to CompareValue, then Value is returned. - The compare exchange operation must be performed using MP safe mechanisms. - - @param Value A pointer to the 64-bit value for the compare exchange - operation. - @param CompareValue 64-bit value used in compare operation. - @param ExchangeValue 64-bit value used in exchange operation. - - @return The original *Value before exchange. - -**/ -UINT64 -EFIAPI -InternalSyncCompareExchange64 ( - IN volatile UINT64 *Value, - IN UINT64 CompareValue, - IN UINT64 ExchangeValue - ); - - /** Worker function that returns a bit field from Operand. diff --git a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf new file mode 100644 index 0000000000..66a74e37a2 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf @@ -0,0 +1,88 @@ +#/** @file +# Base Synchronization Library implementation. +# +# Copyright (c) 2007 - 2008, Intel Corporation. +# +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BaseSynchronizationLib + FILE_GUID = FC9990DF-C5FF-44cf-8799-CBB45B577F87 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = SynchronizationLib + +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources.Ia32] + Ia32/InterlockedCompareExchange64.c | MSFT + Ia32/InterlockedCompareExchange32.c | MSFT + Ia32/InterlockedDecrement.c | MSFT + Ia32/InterlockedIncrement.c | MSFT + SynchronizationMsc.c | MSFT + + Ia32/InterlockedCompareExchange64.asm | INTEL + Ia32/InterlockedCompareExchange32.asm | INTEL + Ia32/InterlockedDecrement.asm | INTEL + Ia32/InterlockedIncrement.asm | INTEL + Synchronization.c | INTEL + + Ia32/InterlockedCompareExchange64.S | GCC + Ia32/InterlockedCompareExchange32.S | GCC + Ia32/InterlockedDecrement.S | GCC + Ia32/InterlockedIncrement.S | GCC + SynchronizationGcc.c | GCC + +[Sources.X64] + X64/InterlockedCompareExchange64.asm + X64/InterlockedCompareExchange32.asm + + X64/InterlockedDecrement.c | MSFT + X64/InterlockedIncrement.c | MSFT + SynchronizationMsc.c | MSFT + + X64/InterlockedDecrement.asm | INTEL + X64/InterlockedIncrement.asm | INTEL + Synchronization.c | INTEL + + X64/InterlockedIncrement.S | GCC + X64/InterlockedDecrement.S | GCC + X64/InterlockedCompareExchange64.S | GCC + X64/InterlockedCompareExchange32.S | GCC + SynchronizationGcc.c | GCC + +[Sources.IPF] + Ipf/Synchronization.c + Ipf/InterlockedCompareExchange64.s + Ipf/InterlockedCompareExchange32.s + + Synchronization.c | INTEL + SynchronizationMsc.c | MSFT + SynchronizationGcc.c | GCC + +[Sources.EBC] + Synchronization.c + Ebc/Synchronization.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + PcdLib + TimerLib + DebugLib + BaseMemoryLib + +[Pcd.common] + gEfiMdePkgTokenSpaceGuid.PcdSpinLockTimeout diff --git a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h new file mode 100644 index 0000000000..9f05d06cfb --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h @@ -0,0 +1,115 @@ +/** @file + Declaration of internal functions in BaseLib. + + Copyright (c) 2006 - 2008, Intel Corporation
+ All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __BASE_LIB_INTERNALS__ +#define __BASE_LIB_INTERNALS__ + +#include +#include +#include +#include +#include +#include + +/** + Performs an atomic increment of an 32-bit unsigned integer. + + Performs an atomic increment of the 32-bit unsigned integer specified by + Value and returns the incremented value. The increment operation must be + performed using MP safe mechanisms. The state of the return value is not + guaranteed to be MP safe. + + @param Value A pointer to the 32-bit value to increment. + + @return The incremented value. + +**/ +UINT32 +EFIAPI +InternalSyncIncrement ( + IN volatile UINT32 *Value + ); + + +/** + Performs an atomic decrement of an 32-bit unsigned integer. + + Performs an atomic decrement of the 32-bit unsigned integer specified by + Value and returns the decrement value. The decrement operation must be + performed using MP safe mechanisms. The state of the return value is not + guaranteed to be MP safe. + + @param Value A pointer to the 32-bit value to decrement. + + @return The decrement value. + +**/ +UINT32 +EFIAPI +InternalSyncDecrement ( + IN volatile UINT32 *Value + ); + + +/** + Performs an atomic compare exchange operation on a 32-bit unsigned integer. + + Performs an atomic compare exchange operation on the 32-bit unsigned integer + specified by Value. If Value is equal to CompareValue, then Value is set to + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue, + then Value is returned. The compare exchange operation must be performed using + MP safe mechanisms. + + @param Value A pointer to the 32-bit value for the compare exchange + operation. + @param CompareValue 32-bit value used in compare operation. + @param ExchangeValue 32-bit value used in exchange operation. + + @return The original *Value before exchange. + +**/ +UINT32 +EFIAPI +InternalSyncCompareExchange32 ( + IN volatile UINT32 *Value, + IN UINT32 CompareValue, + IN UINT32 ExchangeValue + ); + + +/** + Performs an atomic compare exchange operation on a 64-bit unsigned integer. + + Performs an atomic compare exchange operation on the 64-bit unsigned integer specified + by Value. If Value is equal to CompareValue, then Value is set to ExchangeValue and + CompareValue is returned. If Value is not equal to CompareValue, then Value is returned. + The compare exchange operation must be performed using MP safe mechanisms. + + @param Value A pointer to the 64-bit value for the compare exchange + operation. + @param CompareValue 64-bit value used in compare operation. + @param ExchangeValue 64-bit value used in exchange operation. + + @return The original *Value before exchange. + +**/ +UINT64 +EFIAPI +InternalSyncCompareExchange64 ( + IN volatile UINT64 *Value, + IN UINT64 CompareValue, + IN UINT64 ExchangeValue + ); + +#endif diff --git a/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c b/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c new file mode 100644 index 0000000000..dfae40b927 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c @@ -0,0 +1,116 @@ +/** @file + Implementation of synchronization functions on EBC. + + Copyright (c) 2006 - 2008, Intel Corporation
+ All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +/** + Performs an atomic compare exchange operation on a 32-bit + unsigned integer. + + Performs an atomic compare exchange operation on the 32-bit + unsigned integer specified by Value. If Value is equal to + CompareValue, then Value is set to ExchangeValue and + CompareValue is returned. If Value is not equal to + CompareValue, then Value is returned. The compare exchange + operation must be performed using MP safe mechanisms. + + @param Value A pointer to the 32-bit value for the + compare exchange operation. + @param CompareValue 32-bit value used in compare operation. + @param ExchangeValue 32-bit value used in exchange operation. + + @return The original *Value before exchange. + +**/ +UINT32 +EFIAPI +InternalSyncCompareExchange32 ( + IN volatile UINT32 *Value, + IN UINT32 CompareValue, + IN UINT32 ExchangeValue + ) +{ + return *Value != CompareValue ? *Value : + ((*Value = ExchangeValue), CompareValue); +} + +/** + Performs an atomic compare exchange operation on a 64-bit unsigned integer. + + Performs an atomic compare exchange operation on the 64-bit unsigned integer specified + by Value. If Value is equal to CompareValue, then Value is set to ExchangeValue and + CompareValue is returned. If Value is not equal to CompareValue, then Value is returned. + The compare exchange operation must be performed using MP safe mechanisms. + + @param Value A pointer to the 64-bit value for the compare exchange + operation. + @param CompareValue 64-bit value used in compare operation. + @param ExchangeValue 64-bit value used in exchange operation. + + @return The original *Value before exchange. + +**/ +UINT64 +EFIAPI +InternalSyncCompareExchange64 ( + IN volatile UINT64 *Value, + IN UINT64 CompareValue, + IN UINT64 ExchangeValue + ) +{ + return *Value != CompareValue ? *Value : + ((*Value = ExchangeValue), CompareValue); +} + +/** + Performs an atomic increment of an 32-bit unsigned integer. + + Performs an atomic increment of the 32-bit unsigned integer specified by + Value and returns the incremented value. The increment operation must be + performed using MP safe mechanisms. The state of the return value is not + guaranteed to be MP safe. + + @param Value A pointer to the 32-bit value to increment. + + @return The incremented value. + +**/ +UINT32 +EFIAPI +InternalSyncIncrement ( + IN volatile UINT32 *Value + ) +{ + return ++*Value; +} + +/** + Performs an atomic decrement of an 32-bit unsigned integer. + + Performs an atomic decrement of the 32-bit unsigned integer specified by + Value and returns the decrement value. The decrement operation must be + performed using MP safe mechanisms. The state of the return value is not + guaranteed to be MP safe. + + @param Value A pointer to the 32-bit value to decrement. + + @return The decrement value. + +**/ +UINT32 +EFIAPI +InternalSyncDecrement ( + IN volatile UINT32 *Value + ) +{ + return --*Value; +} diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange32.S b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange32.S new file mode 100644 index 0000000000..767343d823 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange32.S @@ -0,0 +1,41 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2006 - 2008, Intel Corporation +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Module Name: +# +# InterlockedCompareExchange32.S +# +# Abstract: +# +# InternalSyncCompareExchange32 function +# +# Notes: +# +#------------------------------------------------------------------------------ + +.globl ASM_PFX(InternalSyncCompareExchange32) + +#------------------------------------------------------------------------------ +# UINT32 +# EFIAPI +# InternalSyncCompareExchange32 ( +# IN UINT32 *Value, +# IN UINT32 CompareValue, +# IN UINT32 ExchangeValue +# ); +#------------------------------------------------------------------------------ +ASM_PFX(InternalSyncCompareExchange32): + movl 4(%esp), %ecx + movl 8(%esp), %eax + movl 12(%esp), %edx + lock + cmpxchgl %edx, (%ecx) + ret diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange32.asm b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange32.asm new file mode 100644 index 0000000000..47d959fa6a --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange32.asm @@ -0,0 +1,45 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006, Intel Corporation +; All rights reserved. This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; InterlockedCompareExchange32.Asm +; +; Abstract: +; +; InterlockedCompareExchange32 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .486 + .model flat,C + .code + +;------------------------------------------------------------------------------ +; UINT32 +; EFIAPI +; InternalSyncCompareExchange32 ( +; IN UINT32 *Value, +; IN UINT32 CompareValue, +; IN UINT32 ExchangeValue +; ); +;------------------------------------------------------------------------------ +InternalSyncCompareExchange32 PROC + mov ecx, [esp + 4] + mov eax, [esp + 8] + mov edx, [esp + 12] + lock cmpxchg [ecx], edx + ret +InternalSyncCompareExchange32 ENDP + + END diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange32.c b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange32.c new file mode 100644 index 0000000000..abcb1ecc83 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange32.c @@ -0,0 +1,50 @@ +/** @file + InterlockedCompareExchange32 function + + Copyright (c) 2006 - 2008, Intel Corporation
+ All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + + + + +/** + Performs an atomic compare exchange operation on a 32-bit unsigned integer. + + Performs an atomic compare exchange operation on the 32-bit unsigned integer + specified by Value. If Value is equal to CompareValue, then Value is set to + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue, + then Value is returned. The compare exchange operation must be performed using + MP safe mechanisms. + + @param Value A pointer to the 32-bit value for the compare exchange + operation. + @param CompareValue 32-bit value used in compare operation. + @param ExchangeValue 32-bit value used in exchange operation. + + @return The original *Value before exchange. + +**/ +UINT32 +EFIAPI +InternalSyncCompareExchange32 ( + IN UINT32 *Value, + IN UINT32 CompareValue, + IN UINT32 ExchangeValue + ) +{ + _asm { + mov ecx, Value + mov eax, CompareValue + mov edx, ExchangeValue + lock cmpxchg [ecx], edx + } +} + diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange64.S b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange64.S new file mode 100644 index 0000000000..03aebff91d --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange64.S @@ -0,0 +1,47 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2006 - 2008, Intel Corporation +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Module Name: +# +# InterlockedCompareExchange64.S +# +# Abstract: +# +# InternalSyncCompareExchange64 function +# +# Notes: +# +#------------------------------------------------------------------------------ + +.globl ASM_PFX(InternalSyncCompareExchange64) + +#------------------------------------------------------------------------------ +# UINT64 +# EFIAPI +# InternalSyncCompareExchange64 ( +# IN UINT64 *Value, +# IN UINT64 CompareValue, +# IN UINT64 ExchangeValue +# ); +#------------------------------------------------------------------------------ +ASM_PFX(InternalSyncCompareExchange64): + push %esi + push %ebx + movl 12(%esp), %esi + movl 16(%esp), %eax + movl 20(%esp), %edx + movl 24(%esp), %ebx + movl 28(%esp), %ecx + lock + cmpxchg8b (%esi) + pop %ebx + pop %esi + ret diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange64.asm b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange64.asm new file mode 100644 index 0000000000..18311e77d3 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange64.asm @@ -0,0 +1,47 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006, Intel Corporation +; All rights reserved. This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; InterlockedCompareExchange64.Asm +; +; Abstract: +; +; InterlockedCompareExchange64 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .586P + .model flat,C + .code + +;------------------------------------------------------------------------------ +; UINT64 +; EFIAPI +; InternalSyncCompareExchange64 ( +; IN UINT64 *Value, +; IN UINT64 CompareValue, +; IN UINT64 ExchangeValue +; ); +;------------------------------------------------------------------------------ +InternalSyncCompareExchange64 PROC USES esi ebx + mov esi, [esp + 12] + mov eax, [esp + 16] + mov edx, [esp + 20] + mov ebx, [esp + 24] + mov ecx, [esp + 28] + lock cmpxchg8b qword ptr [esi] + ret +InternalSyncCompareExchange64 ENDP + + END diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange64.c b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange64.c new file mode 100644 index 0000000000..63aafda4b6 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange64.c @@ -0,0 +1,50 @@ +/** @file + InterlockedCompareExchange64 function + + Copyright (c) 2006 - 2008, Intel Corporation
+ All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + + + + +/** + Performs an atomic compare exchange operation on a 64-bit unsigned integer. + + Performs an atomic compare exchange operation on the 64-bit unsigned integer specified + by Value. If Value is equal to CompareValue, then Value is set to ExchangeValue and + CompareValue is returned. If Value is not equal to CompareValue, then Value is returned. + The compare exchange operation must be performed using MP safe mechanisms. + + @param Value A pointer to the 64-bit value for the compare exchange + operation. + @param CompareValue 64-bit value used in compare operation. + @param ExchangeValue 64-bit value used in exchange operation. + + @return The original *Value before exchange. + +**/ +UINT64 +EFIAPI +InternalSyncCompareExchange64 ( + IN UINT64 *Value, + IN UINT64 CompareValue, + IN UINT64 ExchangeValue + ) +{ + _asm { + mov esi, Value + mov eax, dword ptr [CompareValue + 0] + mov edx, dword ptr [CompareValue + 4] + mov ebx, dword ptr [ExchangeValue + 0] + mov ecx, dword ptr [ExchangeValue + 4] + lock cmpxchg8b qword ptr [esi] + } +} diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedDecrement.S b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedDecrement.S new file mode 100644 index 0000000000..bea5ac1d74 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedDecrement.S @@ -0,0 +1,38 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2006 - 2008, Intel Corporation +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Module Name: +# +# InterlockedDecrement.S +# +# Abstract: +# +# InternalSyncDecrement function +# +# Notes: +# +#------------------------------------------------------------------------------ + +.globl ASM_PFX(InternalSyncDecrement) + +#------------------------------------------------------------------------------ +# UINT32 +# EFIAPI +# InternalSyncDecrement ( +# IN UINT32 *Value +# ); +#------------------------------------------------------------------------------ +ASM_PFX(InternalSyncDecrement): + movl 4(%esp), %eax + lock + decl (%eax) + movl (%eax), %eax + ret diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedDecrement.asm b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedDecrement.asm new file mode 100644 index 0000000000..082429e520 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedDecrement.asm @@ -0,0 +1,42 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006, Intel Corporation +; All rights reserved. This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; InterlockedDecrement.Asm +; +; Abstract: +; +; InterlockedDecrement function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .386 + .model flat,C + .code + +;------------------------------------------------------------------------------ +; UINT32 +; EFIAPI +; InternalSyncDecrement ( +; IN UINT32 *Value +; ); +;------------------------------------------------------------------------------ +InternalSyncDecrement PROC + mov eax, [esp + 4] + lock dec dword ptr [eax] + mov eax, [eax] + ret +InternalSyncDecrement ENDP + + END diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedDecrement.c b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedDecrement.c new file mode 100644 index 0000000000..d1f0868a83 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedDecrement.c @@ -0,0 +1,42 @@ +/** @file + InterlockedDecrement function + + Copyright (c) 2006 - 2008, Intel Corporation
+ All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + + + + +/** + Performs an atomic decrement of an 32-bit unsigned integer. + + Performs an atomic decrement of the 32-bit unsigned integer specified by + Value and returns the decrement value. The decrement operation must be + performed using MP safe mechanisms. The state of the return value is not + guaranteed to be MP safe. + + @param Value A pointer to the 32-bit value to decrement. + + @return The decrement value. + +**/ +UINT32 +EFIAPI +InternalSyncDecrement ( + IN UINT32 *Value + ) +{ + _asm { + mov eax, Value + lock dec dword ptr [eax] + mov eax, [eax] + } +} diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedIncrement.S b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedIncrement.S new file mode 100644 index 0000000000..6efbcee5ea --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedIncrement.S @@ -0,0 +1,38 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2006 - 2008, Intel Corporation +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Module Name: +# +# InterlockedIncrement.S +# +# Abstract: +# +# InternalSyncIncrement function +# +# Notes: +# +#------------------------------------------------------------------------------ + +.globl ASM_PFX(InternalSyncIncrement) + +#------------------------------------------------------------------------------ +# UINT32 +# EFIAPI +# InternalSyncIncrement ( +# IN UINT32 *Value +# ); +#------------------------------------------------------------------------------ +ASM_PFX(InternalSyncIncrement): + movl 4(%esp), %eax + lock + incl (%eax) + movl (%eax), %eax + ret diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedIncrement.asm b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedIncrement.asm new file mode 100644 index 0000000000..ea27e666ca --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedIncrement.asm @@ -0,0 +1,42 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006, Intel Corporation +; All rights reserved. This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; InterlockedIncrement.Asm +; +; Abstract: +; +; InterlockedIncrement function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .386 + .model flat,C + .code + +;------------------------------------------------------------------------------ +; UINT32 +; EFIAPI +; InternalSyncIncrement ( +; IN UINT32 *Value +; ); +;------------------------------------------------------------------------------ +InternalSyncIncrement PROC + mov eax, [esp + 4] + lock inc dword ptr [eax] + mov eax, [eax] + ret +InternalSyncIncrement ENDP + + END diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedIncrement.c b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedIncrement.c new file mode 100644 index 0000000000..b1cc0c7332 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedIncrement.c @@ -0,0 +1,43 @@ +/** @file + InterLockedIncrement function + + Copyright (c) 2006 - 2008, Intel Corporation
+ All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + + + + +/** + Performs an atomic increment of an 32-bit unsigned integer. + + Performs an atomic increment of the 32-bit unsigned integer specified by + Value and returns the incremented value. The increment operation must be + performed using MP safe mechanisms. The state of the return value is not + guaranteed to be MP safe. + + @param Value A pointer to the 32-bit value to increment. + + @return The incremented value. + +**/ +UINT32 +EFIAPI +InternalSyncIncrement ( + IN UINT32 *Value + ) +{ + _asm { + mov eax, Value + lock inc dword ptr [eax] + mov eax, [eax] + } +} + diff --git a/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange32.s b/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange32.s new file mode 100644 index 0000000000..de44573b0f --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange32.s @@ -0,0 +1,29 @@ +/// @file +/// Contains an implementation of InterlockedCompareExchange32 on Itanium- +/// based architecture. +/// +/// Copyright (c) 2006 - 2008, Intel Corporation +/// All rights reserved. This program and the accompanying materials +/// are licensed and made available under the terms and conditions of the BSD License +/// which accompanies this distribution. The full text of the license may be found at +/// http://opensource.org/licenses/bsd-license.php +/// +/// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +/// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +/// +/// Module Name: InterlockedCompareExchange32.s +/// +/// + +.auto +.text + +.proc InternalSyncCompareExchange32 +.type InternalSyncCompareExchange32, @function +InternalSyncCompareExchange32:: + zxt4 r33 = r33 + mov ar.ccv = r33 + cmpxchg4.rel r8 = [r32], r34 + mf + br.ret.sptk.many b0 +.endp InternalSyncCompareExchange32 diff --git a/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange64.s b/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange64.s new file mode 100644 index 0000000000..7fe33fbc34 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange64.s @@ -0,0 +1,28 @@ +/// @file +/// Contains an implementation of InterlockedCompareExchange64 on Itanium- +/// based architecture. +/// +/// Copyright (c) 2006 - 2008, Intel Corporation +/// All rights reserved. This program and the accompanying materials +/// are licensed and made available under the terms and conditions of the BSD License +/// which accompanies this distribution. The full text of the license may be found at +/// http://opensource.org/licenses/bsd-license.php +/// +/// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +/// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +/// +/// Module Name: InterlockedCompareExchange64.s +/// +/// + +.auto +.text + +.proc InternalSyncCompareExchange64 +.type InternalSyncCompareExchange64, @function +InternalSyncCompareExchange64:: + mov ar.ccv = r33 + cmpxchg8.rel r8 = [r32], r34 + mf + br.ret.sptk.many b0 +.endp InternalSyncCompareExchange64 diff --git a/MdePkg/Library/BaseSynchronizationLib/Ipf/Synchronization.c b/MdePkg/Library/BaseSynchronizationLib/Ipf/Synchronization.c new file mode 100644 index 0000000000..5620d8622f --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Ipf/Synchronization.c @@ -0,0 +1,77 @@ +/** @file + Implementation of synchronization functions on Itanium. + + Copyright (c) 2006, Intel Corporation
+ All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "BaseSynchronizationLibInternals.h" + +/** + Performs an atomic increment of an 32-bit unsigned integer. + + Performs an atomic increment of the 32-bit unsigned integer specified by + Value and returns the incremented value. The increment operation must be + performed using MP safe mechanisms. The state of the return value is not + guaranteed to be MP safe. + + @param Value A pointer to the 32-bit value to increment. + + @return The incremented value. + +**/ +UINT32 +EFIAPI +InternalSyncIncrement ( + IN volatile UINT32 *Value + ) +{ + UINT32 OriginalValue; + + do { + OriginalValue = *Value; + } while (OriginalValue != InternalSyncCompareExchange32 ( + Value, + OriginalValue, + OriginalValue + 1 + )); + return OriginalValue + 1; +} + +/** + Performs an atomic decrement of an 32-bit unsigned integer. + + Performs an atomic decrement of the 32-bit unsigned integer specified by + Value and returns the decrement value. The decrement operation must be + performed using MP safe mechanisms. The state of the return value is not + guaranteed to be MP safe. + + @param Value A pointer to the 32-bit value to decrement. + + @return The decrement value. + +**/ +UINT32 +EFIAPI +InternalSyncDecrement ( + IN volatile UINT32 *Value + ) +{ + UINT32 OriginalValue; + + do { + OriginalValue = *Value; + } while (OriginalValue != InternalSyncCompareExchange32 ( + Value, + OriginalValue, + OriginalValue - 1 + )); + return OriginalValue - 1; +} diff --git a/MdePkg/Library/BaseSynchronizationLib/Synchronization.c b/MdePkg/Library/BaseSynchronizationLib/Synchronization.c new file mode 100644 index 0000000000..722525177c --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Synchronization.c @@ -0,0 +1,387 @@ +/** @file + Implementation of synchronization functions. + + Copyright (c) 2006 - 2008, Intel Corporation
+ All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "BaseSynchronizationLibInternals.h" + +#define SPIN_LOCK_RELEASED ((UINTN) 1) +#define SPIN_LOCK_ACQUIRED ((UINTN) 2) + +/** + Retrieves the architecture specific spin lock alignment requirements for + optimal spin lock performance. + + This function retrieves the spin lock alignment requirements for optimal + performance on a given CPU architecture. The spin lock alignment must be a + power of two and is returned by this function. If there are no alignment + requirements, then 1 must be returned. The spin lock synchronization + functions must function correctly if the spin lock size and alignment values + returned by this function are not used at all. These values are hints to the + consumers of the spin lock synchronization functions to obtain optimal spin + lock performance. + + @return The architecture specific spin lock alignment. + +**/ +UINTN +EFIAPI +GetSpinLockProperties ( + VOID + ) +{ + return 32; +} + +/** + Initializes a spin lock to the released state and returns the spin lock. + + This function initializes the spin lock specified by SpinLock to the released + state, and returns SpinLock. Optimal performance can be achieved by calling + GetSpinLockProperties() to determine the size and alignment requirements for + SpinLock. + + If SpinLock is NULL, then ASSERT(). + + @param SpinLock A pointer to the spin lock to initialize to the released + state. + + @return SpinLock in release state. + +**/ +SPIN_LOCK * +EFIAPI +InitializeSpinLock ( + OUT SPIN_LOCK *SpinLock + ) +{ + ASSERT (SpinLock != NULL); + *SpinLock = SPIN_LOCK_RELEASED; + return SpinLock; +} + +/** + Waits until a spin lock can be placed in the acquired state. + + This function checks the state of the spin lock specified by SpinLock. If + SpinLock is in the released state, then this function places SpinLock in the + acquired state and returns SpinLock. Otherwise, this function waits + indefinitely for the spin lock to be released, and then places it in the + acquired state and returns SpinLock. All state transitions of SpinLock must + be performed using MP safe mechanisms. + + If SpinLock is NULL, then ASSERT(). + If SpinLock was not initialized with InitializeSpinLock(), then ASSERT(). + If PcdSpinLockTimeout is not zero, and SpinLock is can not be acquired in + PcdSpinLockTimeout microseconds, then ASSERT(). + + @param SpinLock A pointer to the spin lock to place in the acquired state. + + @return SpinLock acquired lock. + +**/ +SPIN_LOCK * +EFIAPI +AcquireSpinLock ( + IN OUT SPIN_LOCK *SpinLock + ) +{ + UINT64 Current; + UINT64 Previous; + UINT64 Total; + UINT64 Start; + UINT64 End; + UINT64 Timeout; + INT64 Cycle; + INT64 Delta; + + if (PcdGet32 (PcdSpinLockTimeout) > 0) { + // + // Get the current timer value + // + Current = GetPerformanceCounter(); + + // + // Initialize local variables + // + Start = 0; + End = 0; + Total = 0; + + // + // Retrieve the performance counter properties and compute the number of performance + // counter ticks required to reach the timeout + // + Timeout = DivU64x32 ( + MultU64x32 ( + GetPerformanceCounterProperties (&Start, &End), + PcdGet32 (PcdSpinLockTimeout) + ), + 1000000 + ); + Cycle = End - Start; + if (Cycle < 0) { + Cycle = -Cycle; + } + Cycle++; + + while (!AcquireSpinLockOrFail (SpinLock)) { + CpuPause (); + Previous = Current; + Current = GetPerformanceCounter(); + Delta = (INT64) (Current - Previous); + if (Start > End) { + Delta = -Delta; + } + if (Delta < 0) { + Delta += Cycle; + } + Total += Delta; + ASSERT (Total < Timeout); + } + } else { + while (!AcquireSpinLockOrFail (SpinLock)) { + CpuPause (); + } + } + return SpinLock; +} + +/** + Attempts to place a spin lock in the acquired state. + + This function checks the state of the spin lock specified by SpinLock. If + SpinLock is in the released state, then this function places SpinLock in the + acquired state and returns TRUE. Otherwise, FALSE is returned. All state + transitions of SpinLock must be performed using MP safe mechanisms. + + If SpinLock is NULL, then ASSERT(). + If SpinLock was not initialized with InitializeSpinLock(), then ASSERT(). + + @param SpinLock A pointer to the spin lock to place in the acquired state. + + @retval TRUE SpinLock was placed in the acquired state. + @retval FALSE SpinLock could not be acquired. + +**/ +BOOLEAN +EFIAPI +AcquireSpinLockOrFail ( + IN OUT SPIN_LOCK *SpinLock + ) +{ + SPIN_LOCK LockValue; + + ASSERT (SpinLock != NULL); + + LockValue = *SpinLock; + ASSERT (SPIN_LOCK_ACQUIRED == LockValue || SPIN_LOCK_RELEASED == LockValue); + + return (BOOLEAN)( + InterlockedCompareExchangePointer ( + (VOID**)SpinLock, + (VOID*)SPIN_LOCK_RELEASED, + (VOID*)SPIN_LOCK_ACQUIRED + ) == (VOID*)SPIN_LOCK_RELEASED + ); +} + +/** + Releases a spin lock. + + This function places the spin lock specified by SpinLock in the release state + and returns SpinLock. + + If SpinLock is NULL, then ASSERT(). + If SpinLock was not initialized with InitializeSpinLock(), then ASSERT(). + + @param SpinLock A pointer to the spin lock to release. + + @return SpinLock released lock. + +**/ +SPIN_LOCK * +EFIAPI +ReleaseSpinLock ( + IN OUT SPIN_LOCK *SpinLock + ) +{ + SPIN_LOCK LockValue; + + ASSERT (SpinLock != NULL); + + LockValue = *SpinLock; + ASSERT (SPIN_LOCK_ACQUIRED == LockValue || SPIN_LOCK_RELEASED == LockValue); + + *SpinLock = SPIN_LOCK_RELEASED; + return SpinLock; +} + +/** + Performs an atomic increment of an 32-bit unsigned integer. + + Performs an atomic increment of the 32-bit unsigned integer specified by + Value and returns the incremented value. The increment operation must be + performed using MP safe mechanisms. The state of the return value is not + guaranteed to be MP safe. + + If Value is NULL, then ASSERT(). + + @param Value A pointer to the 32-bit value to increment. + + @return The incremented value. + +**/ +UINT32 +EFIAPI +InterlockedIncrement ( + IN UINT32 *Value + ) +{ + ASSERT (Value != NULL); + return InternalSyncIncrement (Value); +} + +/** + Performs an atomic decrement of an 32-bit unsigned integer. + + Performs an atomic decrement of the 32-bit unsigned integer specified by + Value and returns the decremented value. The decrement operation must be + performed using MP safe mechanisms. The state of the return value is not + guaranteed to be MP safe. + + If Value is NULL, then ASSERT(). + + @param Value A pointer to the 32-bit value to decrement. + + @return The decremented value. + +**/ +UINT32 +EFIAPI +InterlockedDecrement ( + IN UINT32 *Value + ) +{ + ASSERT (Value != NULL); + return InternalSyncDecrement (Value); +} + +/** + Performs an atomic compare exchange operation on a 32-bit unsigned integer. + + Performs an atomic compare exchange operation on the 32-bit unsigned integer + specified by Value. If Value is equal to CompareValue, then Value is set to + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue, + then Value is returned. The compare exchange operation must be performed using + MP safe mechanisms. + + If Value is NULL, then ASSERT(). + + @param Value A pointer to the 32-bit value for the compare exchange + operation. + @param CompareValue 32-bit value used in compare operation. + @param ExchangeValue 32-bit value used in exchange operation. + + @return The original *Value before exchange. + +**/ +UINT32 +EFIAPI +InterlockedCompareExchange32 ( + IN OUT UINT32 *Value, + IN UINT32 CompareValue, + IN UINT32 ExchangeValue + ) +{ + ASSERT (Value != NULL); + return InternalSyncCompareExchange32 (Value, CompareValue, ExchangeValue); +} + +/** + Performs an atomic compare exchange operation on a 64-bit unsigned integer. + + Performs an atomic compare exchange operation on the 64-bit unsigned integer specified + by Value. If Value is equal to CompareValue, then Value is set to ExchangeValue and + CompareValue is returned. If Value is not equal to CompareValue, then Value is returned. + The compare exchange operation must be performed using MP safe mechanisms. + + If Value is NULL, then ASSERT(). + + @param Value A pointer to the 64-bit value for the compare exchange + operation. + @param CompareValue 64-bit value used in compare operation. + @param ExchangeValue 64-bit value used in exchange operation. + + @return The original *Value before exchange. + +**/ +UINT64 +EFIAPI +InterlockedCompareExchange64 ( + IN OUT UINT64 *Value, + IN UINT64 CompareValue, + IN UINT64 ExchangeValue + ) +{ + ASSERT (Value != NULL); + return InternalSyncCompareExchange64 (Value, CompareValue, ExchangeValue); +} + +/** + Performs an atomic compare exchange operation on a pointer value. + + Performs an atomic compare exchange operation on the pointer value specified + by Value. If Value is equal to CompareValue, then Value is set to + ExchangeValue and CompareValue is returned. If Value is not equal to + CompareValue, then Value is returned. The compare exchange operation must be + performed using MP safe mechanisms. + + If Value is NULL, then ASSERT(). + + @param Value A pointer to the pointer value for the compare exchange + operation. + @param CompareValue Pointer value used in compare operation. + @param ExchangeValue Pointer value used in exchange operation. + + @return The original *Value before exchange. +**/ +VOID * +EFIAPI +InterlockedCompareExchangePointer ( + IN OUT VOID **Value, + IN VOID *CompareValue, + IN VOID *ExchangeValue + ) +{ + UINT8 SizeOfValue; + + SizeOfValue = sizeof (*Value); + + switch (SizeOfValue) { + case sizeof (UINT32): + return (VOID*)(UINTN)InterlockedCompareExchange32 ( + (UINT32*)Value, + (UINT32)(UINTN)CompareValue, + (UINT32)(UINTN)ExchangeValue + ); + case sizeof (UINT64): + return (VOID*)(UINTN)InterlockedCompareExchange64 ( + (UINT64*)Value, + (UINT64)(UINTN)CompareValue, + (UINT64)(UINTN)ExchangeValue + ); + default: + ASSERT (FALSE); + return NULL; + } +} diff --git a/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c b/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c new file mode 100644 index 0000000000..79bd5c4d2d --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c @@ -0,0 +1,402 @@ +/** @file + Implementation of synchronization functions. + + Copyright (c) 2006 - 2008, Intel Corporation
+ All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "BaseSynchronizationLibInternals.h" + +// +// GCC inline assembly for Read Write Barrier +// +#define _ReadWriteBarrier() do { asm volatile ("": : : "memory"); } while(0) + +#define SPIN_LOCK_RELEASED ((UINTN) 1) +#define SPIN_LOCK_ACQUIRED ((UINTN) 2) + +/** + Retrieves the architecture specific spin lock alignment requirements for + optimal spin lock performance. + + This function retrieves the spin lock alignment requirements for optimal + performance on a given CPU architecture. The spin lock alignment must be a + power of two and is returned by this function. If there are no alignment + requirements, then 1 must be returned. The spin lock synchronization + functions must function correctly if the spin lock size and alignment values + returned by this function are not used at all. These values are hints to the + consumers of the spin lock synchronization functions to obtain optimal spin + lock performance. + + @return The architecture specific spin lock alignment. + +**/ +UINTN +EFIAPI +GetSpinLockProperties ( + VOID + ) +{ + return 32; +} + +/** + Initializes a spin lock to the released state and returns the spin lock. + + This function initializes the spin lock specified by SpinLock to the released + state, and returns SpinLock. Optimal performance can be achieved by calling + GetSpinLockProperties() to determine the size and alignment requirements for + SpinLock. + + If SpinLock is NULL, then ASSERT(). + + @param SpinLock A pointer to the spin lock to initialize to the released + state. + + @return SpinLock in release state. + +**/ +SPIN_LOCK * +EFIAPI +InitializeSpinLock ( + OUT SPIN_LOCK *SpinLock + ) +{ + ASSERT (SpinLock != NULL); + + _ReadWriteBarrier(); + *SpinLock = SPIN_LOCK_RELEASED; + _ReadWriteBarrier(); + + return SpinLock; +} + +/** + Waits until a spin lock can be placed in the acquired state. + + This function checks the state of the spin lock specified by SpinLock. If + SpinLock is in the released state, then this function places SpinLock in the + acquired state and returns SpinLock. Otherwise, this function waits + indefinitely for the spin lock to be released, and then places it in the + acquired state and returns SpinLock. All state transitions of SpinLock must + be performed using MP safe mechanisms. + + If SpinLock is NULL, then ASSERT(). + If SpinLock was not initialized with InitializeSpinLock(), then ASSERT(). + If PcdSpinLockTimeout is not zero, and SpinLock is can not be acquired in + PcdSpinLockTimeout microseconds, then ASSERT(). + + @param SpinLock A pointer to the spin lock to place in the acquired state. + + @return SpinLock acquired lock. + +**/ +SPIN_LOCK * +EFIAPI +AcquireSpinLock ( + IN OUT SPIN_LOCK *SpinLock + ) +{ + UINT64 Current; + UINT64 Previous; + UINT64 Total; + UINT64 Start; + UINT64 End; + UINT64 Timeout; + INT64 Cycle; + INT64 Delta; + + if (PcdGet32 (PcdSpinLockTimeout) > 0) { + // + // Get the current timer value + // + Current = GetPerformanceCounter(); + + // + // Initialize local variables + // + Start = 0; + End = 0; + Total = 0; + + // + // Retrieve the performance counter properties and compute the number of performance + // counter ticks required to reach the timeout + // + Timeout = DivU64x32 ( + MultU64x32 ( + GetPerformanceCounterProperties (&Start, &End), + PcdGet32 (PcdSpinLockTimeout) + ), + 1000000 + ); + Cycle = End - Start; + if (Cycle < 0) { + Cycle = -Cycle; + } + Cycle++; + + while (!AcquireSpinLockOrFail (SpinLock)) { + CpuPause (); + Previous = Current; + Current = GetPerformanceCounter(); + Delta = (INT64) (Current - Previous); + if (Start > End) { + Delta = -Delta; + } + if (Delta < 0) { + Delta += Cycle; + } + Total += Delta; + ASSERT (Total < Timeout); + } + } else { + while (!AcquireSpinLockOrFail (SpinLock)) { + CpuPause (); + } + } + return SpinLock; +} + +/** + Attempts to place a spin lock in the acquired state. + + This function checks the state of the spin lock specified by SpinLock. If + SpinLock is in the released state, then this function places SpinLock in the + acquired state and returns TRUE. Otherwise, FALSE is returned. All state + transitions of SpinLock must be performed using MP safe mechanisms. + + If SpinLock is NULL, then ASSERT(). + If SpinLock was not initialized with InitializeSpinLock(), then ASSERT(). + + @param SpinLock A pointer to the spin lock to place in the acquired state. + + @retval TRUE SpinLock was placed in the acquired state. + @retval FALSE SpinLock could not be acquired. + +**/ +BOOLEAN +EFIAPI +AcquireSpinLockOrFail ( + IN OUT SPIN_LOCK *SpinLock + ) +{ + SPIN_LOCK LockValue; + VOID *Result; + + ASSERT (SpinLock != NULL); + + LockValue = *SpinLock; + ASSERT (LockValue == SPIN_LOCK_ACQUIRED || LockValue == SPIN_LOCK_RELEASED); + + _ReadWriteBarrier (); + Result = InterlockedCompareExchangePointer ( + (VOID**)SpinLock, + (VOID*)SPIN_LOCK_RELEASED, + (VOID*)SPIN_LOCK_ACQUIRED + ); + + _ReadWriteBarrier (); + return (BOOLEAN) (Result == (VOID*) SPIN_LOCK_RELEASED); +} + +/** + Releases a spin lock. + + This function places the spin lock specified by SpinLock in the release state + and returns SpinLock. + + If SpinLock is NULL, then ASSERT(). + If SpinLock was not initialized with InitializeSpinLock(), then ASSERT(). + + @param SpinLock A pointer to the spin lock to release. + + @return SpinLock released lock. + +**/ +SPIN_LOCK * +EFIAPI +ReleaseSpinLock ( + IN OUT SPIN_LOCK *SpinLock + ) +{ + SPIN_LOCK LockValue; + + ASSERT (SpinLock != NULL); + + LockValue = *SpinLock; + ASSERT (LockValue == SPIN_LOCK_ACQUIRED || LockValue == SPIN_LOCK_RELEASED); + + _ReadWriteBarrier (); + *SpinLock = SPIN_LOCK_RELEASED; + _ReadWriteBarrier (); + + return SpinLock; +} + +/** + Performs an atomic increment of an 32-bit unsigned integer. + + Performs an atomic increment of the 32-bit unsigned integer specified by + Value and returns the incremented value. The increment operation must be + performed using MP safe mechanisms. The state of the return value is not + guaranteed to be MP safe. + + If Value is NULL, then ASSERT(). + + @param Value A pointer to the 32-bit value to increment. + + @return The incremented value. + +**/ +UINT32 +EFIAPI +InterlockedIncrement ( + IN UINT32 *Value + ) +{ + ASSERT (Value != NULL); + return InternalSyncIncrement (Value); +} + +/** + Performs an atomic decrement of an 32-bit unsigned integer. + + Performs an atomic decrement of the 32-bit unsigned integer specified by + Value and returns the decremented value. The decrement operation must be + performed using MP safe mechanisms. The state of the return value is not + guaranteed to be MP safe. + + If Value is NULL, then ASSERT(). + + @param Value A pointer to the 32-bit value to decrement. + + @return The decremented value. + +**/ +UINT32 +EFIAPI +InterlockedDecrement ( + IN UINT32 *Value + ) +{ + ASSERT (Value != NULL); + return InternalSyncDecrement (Value); +} + +/** + Performs an atomic compare exchange operation on a 32-bit unsigned integer. + + Performs an atomic compare exchange operation on the 32-bit unsigned integer + specified by Value. If Value is equal to CompareValue, then Value is set to + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue, + then Value is returned. The compare exchange operation must be performed using + MP safe mechanisms. + + If Value is NULL, then ASSERT(). + + @param Value A pointer to the 32-bit value for the compare exchange + operation. + @param CompareValue 32-bit value used in compare operation. + @param ExchangeValue 32-bit value used in exchange operation. + + @return The original *Value before exchange. + +**/ +UINT32 +EFIAPI +InterlockedCompareExchange32 ( + IN OUT UINT32 *Value, + IN UINT32 CompareValue, + IN UINT32 ExchangeValue + ) +{ + ASSERT (Value != NULL); + return InternalSyncCompareExchange32 (Value, CompareValue, ExchangeValue); +} + +/** + Performs an atomic compare exchange operation on a 64-bit unsigned integer. + + Performs an atomic compare exchange operation on the 64-bit unsigned integer specified + by Value. If Value is equal to CompareValue, then Value is set to ExchangeValue and + CompareValue is returned. If Value is not equal to CompareValue, then Value is returned. + The compare exchange operation must be performed using MP safe mechanisms. + + If Value is NULL, then ASSERT(). + + @param Value A pointer to the 64-bit value for the compare exchange + operation. + @param CompareValue 64-bit value used in compare operation. + @param ExchangeValue 64-bit value used in exchange operation. + + @return The original *Value before exchange. + +**/ +UINT64 +EFIAPI +InterlockedCompareExchange64 ( + IN OUT UINT64 *Value, + IN UINT64 CompareValue, + IN UINT64 ExchangeValue + ) +{ + ASSERT (Value != NULL); + return InternalSyncCompareExchange64 (Value, CompareValue, ExchangeValue); +} + +/** + Performs an atomic compare exchange operation on a pointer value. + + Performs an atomic compare exchange operation on the pointer value specified + by Value. If Value is equal to CompareValue, then Value is set to + ExchangeValue and CompareValue is returned. If Value is not equal to + CompareValue, then Value is returned. The compare exchange operation must be + performed using MP safe mechanisms. + + If Value is NULL, then ASSERT(). + + @param Value A pointer to the pointer value for the compare exchange + operation. + @param CompareValue Pointer value used in compare operation. + @param ExchangeValue Pointer value used in exchange operation. + + @return The original *Value before exchange. +**/ +VOID * +EFIAPI +InterlockedCompareExchangePointer ( + IN OUT VOID **Value, + IN VOID *CompareValue, + IN VOID *ExchangeValue + ) +{ + UINT8 SizeOfValue; + + SizeOfValue = sizeof (*Value); + + switch (SizeOfValue) { + case sizeof (UINT32): + return (VOID*)(UINTN)InterlockedCompareExchange32 ( + (UINT32*)Value, + (UINT32)(UINTN)CompareValue, + (UINT32)(UINTN)ExchangeValue + ); + case sizeof (UINT64): + return (VOID*)(UINTN)InterlockedCompareExchange64 ( + (UINT64*)Value, + (UINT64)(UINTN)CompareValue, + (UINT64)(UINTN)ExchangeValue + ); + default: + ASSERT (FALSE); + return NULL; + } +} diff --git a/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c b/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c new file mode 100644 index 0000000000..5abfbefcf0 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c @@ -0,0 +1,405 @@ +/** @file + Implementation of synchronization functions. + + Copyright (c) 2006 - 2008, Intel Corporation
+ All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "BaseSynchronizationLibInternals.h" + +/** + Microsoft Visual Studio 7.1 Function Prototypes for read write barrier Intrinsics. +**/ + +void _ReadWriteBarrier (void); +#pragma intrinsic(_ReadWriteBarrier) + + +#define SPIN_LOCK_RELEASED ((UINTN) 1) +#define SPIN_LOCK_ACQUIRED ((UINTN) 2) + +/** + Retrieves the architecture specific spin lock alignment requirements for + optimal spin lock performance. + + This function retrieves the spin lock alignment requirements for optimal + performance on a given CPU architecture. The spin lock alignment must be a + power of two and is returned by this function. If there are no alignment + requirements, then 1 must be returned. The spin lock synchronization + functions must function correctly if the spin lock size and alignment values + returned by this function are not used at all. These values are hints to the + consumers of the spin lock synchronization functions to obtain optimal spin + lock performance. + + @return The architecture specific spin lock alignment. + +**/ +UINTN +EFIAPI +GetSpinLockProperties ( + VOID + ) +{ + return 32; +} + +/** + Initializes a spin lock to the released state and returns the spin lock. + + This function initializes the spin lock specified by SpinLock to the released + state, and returns SpinLock. Optimal performance can be achieved by calling + GetSpinLockProperties() to determine the size and alignment requirements for + SpinLock. + + If SpinLock is NULL, then ASSERT(). + + @param SpinLock A pointer to the spin lock to initialize to the released + state. + + @return SpinLock in release state. + +**/ +SPIN_LOCK * +EFIAPI +InitializeSpinLock ( + OUT SPIN_LOCK *SpinLock + ) +{ + ASSERT (SpinLock != NULL); + + _ReadWriteBarrier(); + *SpinLock = SPIN_LOCK_RELEASED; + _ReadWriteBarrier(); + + return SpinLock; +} + +/** + Waits until a spin lock can be placed in the acquired state. + + This function checks the state of the spin lock specified by SpinLock. If + SpinLock is in the released state, then this function places SpinLock in the + acquired state and returns SpinLock. Otherwise, this function waits + indefinitely for the spin lock to be released, and then places it in the + acquired state and returns SpinLock. All state transitions of SpinLock must + be performed using MP safe mechanisms. + + If SpinLock is NULL, then ASSERT(). + If SpinLock was not initialized with InitializeSpinLock(), then ASSERT(). + If PcdSpinLockTimeout is not zero, and SpinLock is can not be acquired in + PcdSpinLockTimeout microseconds, then ASSERT(). + + @param SpinLock A pointer to the spin lock to place in the acquired state. + + @return SpinLock acquired lock. + +**/ +SPIN_LOCK * +EFIAPI +AcquireSpinLock ( + IN OUT SPIN_LOCK *SpinLock + ) +{ + UINT64 Current; + UINT64 Previous; + UINT64 Total; + UINT64 Start; + UINT64 End; + UINT64 Timeout; + INT64 Cycle; + INT64 Delta; + + if (PcdGet32 (PcdSpinLockTimeout) > 0) { + // + // Get the current timer value + // + Current = GetPerformanceCounter(); + + // + // Initialize local variables + // + Start = 0; + End = 0; + Total = 0; + + // + // Retrieve the performance counter properties and compute the number of performance + // counter ticks required to reach the timeout + // + Timeout = DivU64x32 ( + MultU64x32 ( + GetPerformanceCounterProperties (&Start, &End), + PcdGet32 (PcdSpinLockTimeout) + ), + 1000000 + ); + Cycle = End - Start; + if (Cycle < 0) { + Cycle = -Cycle; + } + Cycle++; + + while (!AcquireSpinLockOrFail (SpinLock)) { + CpuPause (); + Previous = Current; + Current = GetPerformanceCounter(); + Delta = (INT64) (Current - Previous); + if (Start > End) { + Delta = -Delta; + } + if (Delta < 0) { + Delta += Cycle; + } + Total += Delta; + ASSERT (Total < Timeout); + } + } else { + while (!AcquireSpinLockOrFail (SpinLock)) { + CpuPause (); + } + } + return SpinLock; +} + +/** + Attempts to place a spin lock in the acquired state. + + This function checks the state of the spin lock specified by SpinLock. If + SpinLock is in the released state, then this function places SpinLock in the + acquired state and returns TRUE. Otherwise, FALSE is returned. All state + transitions of SpinLock must be performed using MP safe mechanisms. + + If SpinLock is NULL, then ASSERT(). + If SpinLock was not initialized with InitializeSpinLock(), then ASSERT(). + + @param SpinLock A pointer to the spin lock to place in the acquired state. + + @retval TRUE SpinLock was placed in the acquired state. + @retval FALSE SpinLock could not be acquired. + +**/ +BOOLEAN +EFIAPI +AcquireSpinLockOrFail ( + IN OUT SPIN_LOCK *SpinLock + ) +{ + SPIN_LOCK LockValue; + VOID *Result; + + ASSERT (SpinLock != NULL); + + LockValue = *SpinLock; + ASSERT (LockValue == SPIN_LOCK_ACQUIRED || LockValue == SPIN_LOCK_RELEASED); + + _ReadWriteBarrier (); + Result = InterlockedCompareExchangePointer ( + (VOID**)SpinLock, + (VOID*)SPIN_LOCK_RELEASED, + (VOID*)SPIN_LOCK_ACQUIRED + ); + + _ReadWriteBarrier (); + return (BOOLEAN) (Result == (VOID*) SPIN_LOCK_RELEASED); +} + +/** + Releases a spin lock. + + This function places the spin lock specified by SpinLock in the release state + and returns SpinLock. + + If SpinLock is NULL, then ASSERT(). + If SpinLock was not initialized with InitializeSpinLock(), then ASSERT(). + + @param SpinLock A pointer to the spin lock to release. + + @return SpinLock released lock. + +**/ +SPIN_LOCK * +EFIAPI +ReleaseSpinLock ( + IN OUT SPIN_LOCK *SpinLock + ) +{ + SPIN_LOCK LockValue; + + ASSERT (SpinLock != NULL); + + LockValue = *SpinLock; + ASSERT (LockValue == SPIN_LOCK_ACQUIRED || LockValue == SPIN_LOCK_RELEASED); + + _ReadWriteBarrier (); + *SpinLock = SPIN_LOCK_RELEASED; + _ReadWriteBarrier (); + + return SpinLock; +} + +/** + Performs an atomic increment of an 32-bit unsigned integer. + + Performs an atomic increment of the 32-bit unsigned integer specified by + Value and returns the incremented value. The increment operation must be + performed using MP safe mechanisms. The state of the return value is not + guaranteed to be MP safe. + + If Value is NULL, then ASSERT(). + + @param Value A pointer to the 32-bit value to increment. + + @return The incremented value. + +**/ +UINT32 +EFIAPI +InterlockedIncrement ( + IN UINT32 *Value + ) +{ + ASSERT (Value != NULL); + return InternalSyncIncrement (Value); +} + +/** + Performs an atomic decrement of an 32-bit unsigned integer. + + Performs an atomic decrement of the 32-bit unsigned integer specified by + Value and returns the decremented value. The decrement operation must be + performed using MP safe mechanisms. The state of the return value is not + guaranteed to be MP safe. + + If Value is NULL, then ASSERT(). + + @param Value A pointer to the 32-bit value to decrement. + + @return The decremented value. + +**/ +UINT32 +EFIAPI +InterlockedDecrement ( + IN UINT32 *Value + ) +{ + ASSERT (Value != NULL); + return InternalSyncDecrement (Value); +} + +/** + Performs an atomic compare exchange operation on a 32-bit unsigned integer. + + Performs an atomic compare exchange operation on the 32-bit unsigned integer + specified by Value. If Value is equal to CompareValue, then Value is set to + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue, + then Value is returned. The compare exchange operation must be performed using + MP safe mechanisms. + + If Value is NULL, then ASSERT(). + + @param Value A pointer to the 32-bit value for the compare exchange + operation. + @param CompareValue 32-bit value used in compare operation. + @param ExchangeValue 32-bit value used in exchange operation. + + @return The original *Value before exchange. + +**/ +UINT32 +EFIAPI +InterlockedCompareExchange32 ( + IN OUT UINT32 *Value, + IN UINT32 CompareValue, + IN UINT32 ExchangeValue + ) +{ + ASSERT (Value != NULL); + return InternalSyncCompareExchange32 (Value, CompareValue, ExchangeValue); +} + +/** + Performs an atomic compare exchange operation on a 64-bit unsigned integer. + + Performs an atomic compare exchange operation on the 64-bit unsigned integer specified + by Value. If Value is equal to CompareValue, then Value is set to ExchangeValue and + CompareValue is returned. If Value is not equal to CompareValue, then Value is returned. + The compare exchange operation must be performed using MP safe mechanisms. + + If Value is NULL, then ASSERT(). + + @param Value A pointer to the 64-bit value for the compare exchange + operation. + @param CompareValue 64-bit value used in compare operation. + @param ExchangeValue 64-bit value used in exchange operation. + + @return The original *Value before exchange. + +**/ +UINT64 +EFIAPI +InterlockedCompareExchange64 ( + IN OUT UINT64 *Value, + IN UINT64 CompareValue, + IN UINT64 ExchangeValue + ) +{ + ASSERT (Value != NULL); + return InternalSyncCompareExchange64 (Value, CompareValue, ExchangeValue); +} + +/** + Performs an atomic compare exchange operation on a pointer value. + + Performs an atomic compare exchange operation on the pointer value specified + by Value. If Value is equal to CompareValue, then Value is set to + ExchangeValue and CompareValue is returned. If Value is not equal to + CompareValue, then Value is returned. The compare exchange operation must be + performed using MP safe mechanisms. + + If Value is NULL, then ASSERT(). + + @param Value A pointer to the pointer value for the compare exchange + operation. + @param CompareValue Pointer value used in compare operation. + @param ExchangeValue Pointer value used in exchange operation. + + @return The original *Value before exchange. +**/ +VOID * +EFIAPI +InterlockedCompareExchangePointer ( + IN OUT VOID **Value, + IN VOID *CompareValue, + IN VOID *ExchangeValue + ) +{ + UINT8 SizeOfValue; + + SizeOfValue = sizeof (*Value); + + switch (SizeOfValue) { + case sizeof (UINT32): + return (VOID*)(UINTN)InterlockedCompareExchange32 ( + (UINT32*)Value, + (UINT32)(UINTN)CompareValue, + (UINT32)(UINTN)ExchangeValue + ); + case sizeof (UINT64): + return (VOID*)(UINTN)InterlockedCompareExchange64 ( + (UINT64*)Value, + (UINT64)(UINTN)CompareValue, + (UINT64)(UINTN)ExchangeValue + ); + default: + ASSERT (FALSE); + return NULL; + } +} diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange32.S b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange32.S new file mode 100644 index 0000000000..8faca8b7b1 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange32.S @@ -0,0 +1,37 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2006 - 2008, Intel Corporation +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Module Name: +# +# InterlockedCompareExchange32.S +# +# Abstract: +# +# InterlockedCompareExchange32 function +# +# Notes: +# +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# UINT32 +# EFIAPI +# InterlockedCompareExchange32 ( +# IN UINT32 *Value, +# IN UINT32 CompareValue, +# IN UINT32 ExchangeValue +# ); +#------------------------------------------------------------------------------ +.global ASM_PFX(InternalSyncCompareExchange32) +ASM_PFX(InternalSyncCompareExchange32): + mov %edx, %eax + lock cmpxchg %r8d, (%rcx) + ret diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange32.asm b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange32.asm new file mode 100644 index 0000000000..55b055453f --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange32.asm @@ -0,0 +1,41 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006, Intel Corporation +; All rights reserved. This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; InterlockedCompareExchange32.Asm +; +; Abstract: +; +; InterlockedCompareExchange32 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINT32 +; EFIAPI +; InterlockedCompareExchange32 ( +; IN UINT32 *Value, +; IN UINT32 CompareValue, +; IN UINT32 ExchangeValue +; ); +;------------------------------------------------------------------------------ +InternalSyncCompareExchange32 PROC + mov eax, edx + lock cmpxchg [rcx], r8d + ret +InternalSyncCompareExchange32 ENDP + + END diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange32.c b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange32.c new file mode 100644 index 0000000000..8efd994a6e --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange32.c @@ -0,0 +1,54 @@ +/** @file + InterlockedCompareExchange32 function + + Copyright (c) 2006 - 2008, Intel Corporation
+ All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +/** + Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics. +**/ + +long _InterlockedCompareExchange( + long volatile * Destination, + long Exchange, + long Comperand +); + +#pragma intrinsic(_InterlockedCompareExchange) + +/** + Performs an atomic compare exchange operation on a 32-bit unsigned integer. + + Performs an atomic compare exchange operation on the 32-bit unsigned integer + specified by Value. If Value is equal to CompareValue, then Value is set to + ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue, + then Value is returned. The compare exchange operation must be performed using + MP safe mechanisms. + + @param Value A pointer to the 32-bit value for the compare exchange + operation. + @param CompareValue 32-bit value used in compare operation. + @param ExchangeValue 32-bit value used in exchange operation. + + @return The original *Value before exchange. + +**/ +UINT32 +EFIAPI +InternalSyncCompareExchange32 ( + IN UINT32 *Value, + IN UINT32 CompareValue, + IN UINT32 ExchangeValue + ) +{ + return _InterlockedCompareExchange (Value, ExchangeValue, CompareValue); +} + diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange64.S b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange64.S new file mode 100644 index 0000000000..5e6e163527 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange64.S @@ -0,0 +1,39 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2006 - 2008, Intel Corporation +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Module Name: +# +# InterlockedCompareExchange64.S +# +# Abstract: +# +# InterlockedCompareExchange64 function +# +# Notes: +# +#------------------------------------------------------------------------------ + + +#------------------------------------------------------------------------------ +# UINT64 +# EFIAPI +# InterlockedCompareExchange64 ( +# IN UINT64 *Value, +# IN UINT64 CompareValue, +# IN UINT64 ExchangeValue +# ); +#------------------------------------------------------------------------------ +.global ASM_PFX(InternalSyncCompareExchange64) +.align 16 +ASM_PFX(InternalSyncCompareExchange64): + mov %rdx, %rax + lock cmpxchg %r8,(%rcx) + ret diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange64.asm b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange64.asm new file mode 100644 index 0000000000..88c25a56de --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange64.asm @@ -0,0 +1,41 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006, Intel Corporation +; All rights reserved. This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; InterlockedCompareExchange64.Asm +; +; Abstract: +; +; InterlockedCompareExchange64 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINT64 +; EFIAPI +; InterlockedCompareExchange64 ( +; IN UINT64 *Value, +; IN UINT64 CompareValue, +; IN UINT64 ExchangeValue +; ); +;------------------------------------------------------------------------------ +InternalSyncCompareExchange64 PROC + mov rax, rdx + lock cmpxchg [rcx], r8 + ret +InternalSyncCompareExchange64 ENDP + + END diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange64.c b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange64.c new file mode 100644 index 0000000000..0a88eda2ea --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange64.c @@ -0,0 +1,53 @@ +/** @file + InterlockedCompareExchange64 function + + Copyright (c) 2006 - 2008, Intel Corporation
+ All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +/** + Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics. +**/ + +__int64 _InterlockedCompareExchange64( + __int64 volatile * Destination, + __int64 Exchange, + __int64 Comperand +); + +#pragma intrinsic(_InterlockedCompareExchange64) + +/** + Performs an atomic compare exchange operation on a 64-bit unsigned integer. + + Performs an atomic compare exchange operation on the 64-bit unsigned integer specified + by Value. If Value is equal to CompareValue, then Value is set to ExchangeValue and + CompareValue is returned. If Value is not equal to CompareValue, then Value is returned. + The compare exchange operation must be performed using MP safe mechanisms. + + @param Value A pointer to the 64-bit value for the compare exchange + operation. + @param CompareValue 64-bit value used in compare operation. + @param ExchangeValue 64-bit value used in exchange operation. + + @return The original *Value before exchange. + +**/ +UINT64 +EFIAPI +InternalSyncCompareExchange64 ( + IN UINT64 *Value, + IN UINT64 CompareValue, + IN UINT64 ExchangeValue + ) +{ + return _InterlockedCompareExchange64 (Value, ExchangeValue, CompareValue); +} + diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedDecrement.S b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedDecrement.S new file mode 100644 index 0000000000..d06559bd25 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedDecrement.S @@ -0,0 +1,36 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2006 - 2008, Intel Corporation +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Module Name: +# +# InterlockedDecrement.S +# +# Abstract: +# +# InterlockedDecrement function +# +# Notes: +# +#------------------------------------------------------------------------------ + + +#------------------------------------------------------------------------------ +# UINT32 +# EFIAPI +# InterlockedDecrement ( +# IN UINT32 *Value +# ); +#------------------------------------------------------------------------------ +.global ASM_PFX(InternalSyncDecrement) +ASM_PFX(InternalSyncDecrement): + lock decl (%rcx) + mov (%rcx), %eax + ret diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedDecrement.asm b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedDecrement.asm new file mode 100644 index 0000000000..f907fed4a8 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedDecrement.asm @@ -0,0 +1,39 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006, Intel Corporation +; All rights reserved. This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; InterlockedDecrement.Asm +; +; Abstract: +; +; InterlockedDecrement function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINT32 +; EFIAPI +; InterlockedDecrement ( +; IN UINT32 *Value +; ); +;------------------------------------------------------------------------------ +InternalSyncDecrement PROC + lock dec dword ptr [rcx] + mov eax, [rcx] + ret +InternalSyncDecrement ENDP + + END diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedDecrement.c b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedDecrement.c new file mode 100644 index 0000000000..9e2e339aee --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedDecrement.c @@ -0,0 +1,46 @@ +/** @file + InterlockedDecrement function + + Copyright (c) 2006 - 2008, Intel Corporation
+ All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +/** + Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics. +**/ + +long _InterlockedDecrement( + long * lpAddend +); + +#pragma intrinsic(_InterlockedDecrement) + +/** + Performs an atomic decrement of an 32-bit unsigned integer. + + Performs an atomic decrement of the 32-bit unsigned integer specified by + Value and returns the decrement value. The decrement operation must be + performed using MP safe mechanisms. The state of the return value is not + guaranteed to be MP safe. + + @param Value A pointer to the 32-bit value to decrement. + + @return The decrement value. + +**/ +UINT32 +EFIAPI +InternalSyncDecrement ( + IN UINT32 *Value + ) +{ + return _InterlockedDecrement (Value); +} + diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedIncrement.S b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedIncrement.S new file mode 100644 index 0000000000..0416dd7d2a --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedIncrement.S @@ -0,0 +1,36 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2006 - 2008, Intel Corporation +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Module Name: +# +# InterlockedIncrement.S +# +# Abstract: +# +# InterlockedIncrement function +# +# Notes: +# +#------------------------------------------------------------------------------ + + +#------------------------------------------------------------------------------ +# UINT32 +# EFIAPI +# InterlockedIncrement ( +# IN UINT32 *Value +# ); +#------------------------------------------------------------------------------ +.global ASM_PFX(InternalSyncIncrement) +ASM_PFX(InternalSyncIncrement): + lock incl (%rcx) + mov (%rcx), %eax + ret diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedIncrement.asm b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedIncrement.asm new file mode 100644 index 0000000000..f5a4130bf1 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedIncrement.asm @@ -0,0 +1,39 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006, Intel Corporation +; All rights reserved. This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; InterlockedIncrement.Asm +; +; Abstract: +; +; InterlockedIncrement function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINT32 +; EFIAPI +; InterlockedIncrement ( +; IN UINT32 *Value +; ); +;------------------------------------------------------------------------------ +InternalSyncIncrement PROC + lock inc dword ptr [rcx] + mov eax, [rcx] + ret +InternalSyncIncrement ENDP + + END diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedIncrement.c b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedIncrement.c new file mode 100644 index 0000000000..455fb453d4 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedIncrement.c @@ -0,0 +1,46 @@ +/** @file + InterLockedIncrement function + + Copyright (c) 2006 - 2008, Intel Corporation
+ All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +/** + Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics. +**/ + +long _InterlockedIncrement( + long * lpAddend +); + +#pragma intrinsic(_InterlockedIncrement) + +/** + Performs an atomic increment of an 32-bit unsigned integer. + + Performs an atomic increment of the 32-bit unsigned integer specified by + Value and returns the incremented value. The increment operation must be + performed using MP safe mechanisms. The state of the return value is not + guaranteed to be MP safe. + + @param Value A pointer to the 32-bit value to increment. + + @return The incremented value. + +**/ +UINT32 +EFIAPI +InternalSyncIncrement ( + IN UINT32 *Value + ) +{ + return _InterlockedIncrement (Value); +} + diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index 4ae678ecb0..cadb7f6af7 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -181,6 +181,10 @@ ## @libraryclass Provides a set of PI library functions and macros for DXE phase. DxeServicesLib|Include/Library/DxeServicesLib.h + ## @libraryclass Provides synchronization functions. + ## + SynchronizationLib|Include/Library/SynchronizationLib.h + [LibraryClasses.IPF] ## @libraryclass The SAL Library provides a service to make a SAL CALL. SalLib|Include/Library/SalLib.h diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc index f945151b0c..56234a151a 100644 --- a/MdePkg/MdePkg.dsc +++ b/MdePkg/MdePkg.dsc @@ -67,6 +67,7 @@ MdePkg/Library/BasePostCodeLibPort80/BasePostCodeLibPort80.inf MdePkg/Library/BasePrintLib/BasePrintLib.inf MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf + MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf -- 2.39.2