On 17 February 2015 at 18:40, Jordan Justen <jordan.l.jus...@intel.com> wrote: > Ard, > > For the subject, I think > MdePkg/BaseSynchronizationLib: Add InterlockedCompareExchange16 > would be better. >
OK > Acked-by: Jordan Justen <jordan.l.jus...@intel.com> > Thanks > Thanks for working to move this to a common location. > No problem > Mike, > > I think Anthony tested the IA32 and X64 implementations with Xen. For > IPF, I don't think it has been tested. > As mentioned in the other thread, Anthony seems to be incommunicado, and some other of the Xen guys have replied that Xen on OVMF/x86 is broken for other reasons so they cannot positively confirm that everything still works, even though the x86 changes other than the PCI/xenbus split are primarily refactoring of existing code. As far as IPF is concerned: I don't think Xen or Ovmf can be built for IPF anyway, but I think a build test and visual inspection of the .S file should be sufficient here? Thanks, Ard. > On 2015-02-12 03:19:06, Ard Biesheuvel wrote: >> This implements the function InterlockedCompareExchange16 () for all >> architectures, using architecture and toolchain specific intrinsics >> or primitive assembler instructions. >> >> Contributed-under: TianoCore Contribution Agreement 1.0 >> Reviewed-by: Olivier Martin <olivier.mar...@arm.com> >> Signed-off-by: Ard Biesheuvel <ard.biesheu...@linaro.org> >> --- >> MdePkg/Include/Library/SynchronizationLib.h >> | 26 ++++++++++++++++++++++++++ >> MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S >> | 44 ++++++++++++++++++++++++++++++++++++++++++++ >> MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S >> | 44 ++++++++++++++++++++++++++++++++++++++++++++ >> MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm >> | 44 ++++++++++++++++++++++++++++++++++++++++++++ >> MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf >> | 5 +++++ >> MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h >> | 26 ++++++++++++++++++++++++++ >> MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c >> | 31 +++++++++++++++++++++++++++++++ >> MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c >> | 42 ++++++++++++++++++++++++++++++++++++++++++ >> MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm >> | 46 ++++++++++++++++++++++++++++++++++++++++++++++ >> MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c >> | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ >> MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s >> | 30 ++++++++++++++++++++++++++++++ >> MdePkg/Library/BaseSynchronizationLib/Synchronization.c >> | 31 +++++++++++++++++++++++++++++++ >> MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c >> | 31 +++++++++++++++++++++++++++++++ >> MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c >> | 31 +++++++++++++++++++++++++++++++ >> MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c >> | 44 ++++++++++++++++++++++++++++++++++++++++++++ >> MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm >> | 42 ++++++++++++++++++++++++++++++++++++++++++ >> MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c >> | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ >> 17 files changed, 622 insertions(+) >> >> diff --git a/MdePkg/Include/Library/SynchronizationLib.h >> b/MdePkg/Include/Library/SynchronizationLib.h >> index f97569739914..7b97683ca0af 100644 >> --- a/MdePkg/Include/Library/SynchronizationLib.h >> +++ b/MdePkg/Include/Library/SynchronizationLib.h >> @@ -184,6 +184,32 @@ InterlockedDecrement ( >> >> >> /** >> + Performs an atomic compare exchange operation on a 16-bit unsigned >> integer. >> + >> + Performs an atomic compare exchange operation on the 16-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 16-bit value for the compare >> exchange >> + operation. >> + @param CompareValue 16-bit value used in compare operation. >> + @param ExchangeValue 16-bit value used in exchange operation. >> + >> + @return The original *Value before exchange. >> +**/ >> +UINT16 >> +EFIAPI >> +InterlockedCompareExchange16 ( >> + IN OUT UINT16 *Value, >> + IN UINT16 CompareValue, >> + IN UINT16 ExchangeValue >> + ); >> + >> +/** >> Performs an atomic compare exchange operation on a 32-bit unsigned >> integer. >> >> Performs an atomic compare exchange operation on the 32-bit unsigned >> integer >> diff --git a/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S >> b/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S >> index 601b00495f26..ecb87fc12755 100644 >> --- a/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S >> +++ b/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S >> @@ -16,12 +16,56 @@ >> .text >> .align 3 >> >> +GCC_ASM_EXPORT(InternalSyncCompareExchange16) >> GCC_ASM_EXPORT(InternalSyncCompareExchange32) >> GCC_ASM_EXPORT(InternalSyncCompareExchange64) >> GCC_ASM_EXPORT(InternalSyncIncrement) >> GCC_ASM_EXPORT(InternalSyncDecrement) >> >> /** >> + Performs an atomic compare exchange operation on a 16-bit unsigned >> integer. >> + >> + Performs an atomic compare exchange operation on the 16-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 16-bit value for the compare >> exchange >> + operation. >> + @param CompareValue 16-bit value used in compare operation. >> + @param ExchangeValue 16-bit value used in exchange operation. >> + >> + @return The original *Value before exchange. >> + >> +**/ >> +//UINT16 >> +//EFIAPI >> +//InternalSyncCompareExchange16 ( >> +// IN volatile UINT16 *Value, >> +// IN UINT16 CompareValue, >> +// IN UINT16 ExchangeValue >> +// ) >> +ASM_PFX(InternalSyncCompareExchange16): >> + uxth w1, w1 >> + uxth w2, w2 >> + dmb sy >> + >> +InternalSyncCompareExchange16Again: >> + ldxrh w3, [x0] >> + cmp w3, w1 >> + bne InternalSyncCompareExchange16Fail >> + >> +InternalSyncCompareExchange16Exchange: >> + stxrh w4, w2, [x0] >> + cbnz w4, InternalSyncCompareExchange16Again >> + >> +InternalSyncCompareExchange16Fail: >> + dmb sy >> + mov w0, w3 >> + ret >> + >> +/** >> Performs an atomic compare exchange operation on a 32-bit unsigned >> integer. >> >> Performs an atomic compare exchange operation on the 32-bit unsigned >> integer >> diff --git a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S >> b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S >> index 0128f8f016bd..d699eb40d2a2 100644 >> --- a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S >> +++ b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S >> @@ -1,6 +1,7 @@ >> // Implementation of synchronization functions for ARM architecture >> // >> // Copyright (c) 2012-2015, ARM Limited. All rights reserved. >> +// Copyright (c) 2015, Linaro Limited. All rights reserved. >> // >> // This program and the accompanying materials >> // are licensed and made available under the terms and conditions of the >> BSD License >> @@ -15,12 +16,55 @@ >> .text >> .align 3 >> >> +GCC_ASM_EXPORT(InternalSyncCompareExchange16) >> GCC_ASM_EXPORT(InternalSyncCompareExchange32) >> GCC_ASM_EXPORT(InternalSyncCompareExchange64) >> GCC_ASM_EXPORT(InternalSyncIncrement) >> GCC_ASM_EXPORT(InternalSyncDecrement) >> >> /** >> + Performs an atomic compare exchange operation on a 16-bit unsigned >> integer. >> + >> + Performs an atomic compare exchange operation on the 16-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 16-bit value for the compare >> exchange >> + operation. >> + @param CompareValue 16-bit value used in compare operation. >> + @param ExchangeValue 16-bit value used in exchange operation. >> + >> + @return The original *Value before exchange. >> + >> +**/ >> +//UINT16 >> +//EFIAPI >> +//InternalSyncCompareExchange16 ( >> +// IN volatile UINT16 *Value, >> +// IN UINT16 CompareValue, >> +// IN UINT16 ExchangeValue >> +// ) >> +ASM_PFX(InternalSyncCompareExchange16): >> + dmb >> + >> +InternalSyncCompareExchange16Again: >> + ldrexh r3, [r0] >> + cmp r3, r1 >> + bne InternalSyncCompareExchange16Fail >> + >> +InternalSyncCompareExchange16Exchange: >> + strexh ip, r2, [r0] >> + cmp ip, #0 >> + bne InternalSyncCompareExchange16Again >> + >> +InternalSyncCompareExchange16Fail: >> + dmb >> + mov r0, r3 >> + bx lr >> + >> +/** >> Performs an atomic compare exchange operation on a 32-bit unsigned >> integer. >> >> Performs an atomic compare exchange operation on the 32-bit unsigned >> integer >> diff --git a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm >> b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm >> index f9f80737774a..dbc599114093 100644 >> --- a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm >> +++ b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm >> @@ -1,6 +1,7 @@ >> // Implementation of synchronization functions for ARM architecture >> // >> // Copyright (c) 2012-2015, ARM Limited. All rights reserved. >> +// Copyright (c) 2015, Linaro Limited. All rights reserved. >> // >> // This program and the accompanying materials >> // are licensed and made available under the terms and conditions of the >> BSD License >> @@ -12,6 +13,7 @@ >> // >> // >> >> + EXPORT InternalSyncCompareExchange16 >> EXPORT InternalSyncCompareExchange32 >> EXPORT InternalSyncCompareExchange64 >> EXPORT InternalSyncIncrement >> @@ -20,6 +22,48 @@ >> AREA ArmSynchronization, CODE, READONLY >> >> /** >> + Performs an atomic compare exchange operation on a 16-bit unsigned >> integer. >> + >> + Performs an atomic compare exchange operation on the 16-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 16-bit value for the compare >> exchange >> + operation. >> + @param CompareValue 16-bit value used in compare operation. >> + @param ExchangeValue 16-bit value used in exchange operation. >> + >> + @return The original *Value before exchange. >> + >> +**/ >> +//UINT16 >> +//EFIAPI >> +//InternalSyncCompareExchange16 ( >> +// IN volatile UINT16 *Value, >> +// IN UINT16 CompareValue, >> +// IN UINT16 ExchangeValue >> +// ) >> +InternalSyncCompareExchange16 >> + dmb >> + >> +InternalSyncCompareExchange16Again >> + ldrexh r3, [r0] >> + cmp r3, r1 >> + bne InternalSyncCompareExchange16Fail >> + >> +InternalSyncCompareExchange16Exchange >> + strexh ip, r2, [r0] >> + cmp ip, #0 >> + bne InternalSyncCompareExchange16Again >> + >> +InternalSyncCompareExchange16Fail >> + dmb >> + mov r0, r3 >> + bx lr >> + >> +/** >> Performs an atomic compare exchange operation on a 32-bit unsigned >> integer. >> >> Performs an atomic compare exchange operation on the 32-bit unsigned >> integer >> diff --git >> a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf >> b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf >> index 5e3b4e6b9bf2..bd1bec3fb5e7 100755 >> --- a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf >> +++ b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf >> @@ -32,12 +32,14 @@ >> [Sources.IA32] >> Ia32/InterlockedCompareExchange64.c | MSFT >> Ia32/InterlockedCompareExchange32.c | MSFT >> + Ia32/InterlockedCompareExchange16.c | MSFT >> Ia32/InterlockedDecrement.c | MSFT >> Ia32/InterlockedIncrement.c | MSFT >> SynchronizationMsc.c | MSFT >> >> Ia32/InterlockedCompareExchange64.asm | INTEL >> Ia32/InterlockedCompareExchange32.asm | INTEL >> + Ia32/InterlockedCompareExchange16.asm | INTEL >> Ia32/InterlockedDecrement.asm | INTEL >> Ia32/InterlockedIncrement.asm | INTEL >> Synchronization.c | INTEL >> @@ -48,9 +50,11 @@ >> [Sources.X64] >> X64/InterlockedCompareExchange64.c | MSFT >> X64/InterlockedCompareExchange32.c | MSFT >> + X64/InterlockedCompareExchange16.c | MSFT >> >> X64/InterlockedCompareExchange64.asm | INTEL >> X64/InterlockedCompareExchange32.asm | INTEL >> + X64/InterlockedCompareExchange16.asm | INTEL >> >> X64/InterlockedDecrement.c | MSFT >> X64/InterlockedIncrement.c | MSFT >> @@ -67,6 +71,7 @@ >> Ipf/Synchronization.c >> Ipf/InterlockedCompareExchange64.s >> Ipf/InterlockedCompareExchange32.s >> + Ipf/InterlockedCompareExchange16.s >> >> Synchronization.c | INTEL >> SynchronizationMsc.c | MSFT >> diff --git >> a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h >> b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h >> index e42824c75d12..76f702324156 100644 >> --- a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h >> +++ b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h >> @@ -63,6 +63,32 @@ InternalSyncDecrement ( >> >> >> /** >> + Performs an atomic compare exchange operation on a 16-bit unsigned >> integer. >> + >> + Performs an atomic compare exchange operation on the 16-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 16-bit value for the compare >> exchange >> + operation. >> + @param CompareValue A 16-bit value used in compare operation. >> + @param ExchangeValue A 16-bit value used in exchange operation. >> + >> + @return The original *Value before exchange. >> + >> +**/ >> +UINT16 >> +EFIAPI >> +InternalSyncCompareExchange16 ( >> + IN volatile UINT16 *Value, >> + IN UINT16 CompareValue, >> + IN UINT16 ExchangeValue >> + ); >> + >> + >> +/** >> Performs an atomic compare exchange operation on a 32-bit unsigned >> integer. >> >> Performs an atomic compare exchange operation on the 32-bit unsigned >> integer >> diff --git a/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c >> b/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c >> index 9c34b9f128ed..a57860203b12 100644 >> --- a/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c >> +++ b/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c >> @@ -13,6 +13,37 @@ >> **/ >> >> /** >> + Performs an atomic compare exchange operation on a 16-bit >> + unsigned integer. >> + >> + Performs an atomic compare exchange operation on the 16-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 16-bit value for the >> + compare exchange operation. >> + @param CompareValue 16-bit value used in compare operation. >> + @param ExchangeValue 16-bit value used in exchange operation. >> + >> + @return The original *Value before exchange. >> + >> +**/ >> +UINT16 >> +EFIAPI >> +InternalSyncCompareExchange16 ( >> + IN volatile UINT16 *Value, >> + IN UINT16 CompareValue, >> + IN UINT16 ExchangeValue >> + ) >> +{ >> + return *Value != CompareValue ? *Value : >> + ((*Value = ExchangeValue), CompareValue); >> +} >> + >> +/** >> Performs an atomic compare exchange operation on a 32-bit >> unsigned integer. >> >> diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c >> b/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c >> index b5a7827fc0e8..bd81aad6c243 100644 >> --- a/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c >> +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c >> @@ -88,6 +88,48 @@ InternalSyncDecrement ( >> } >> >> /** >> + Performs an atomic compare exchange operation on a 16-bit unsigned >> integer. >> + >> + Performs an atomic compare exchange operation on the 16-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 16-bit value for the compare >> exchange >> + operation. >> + @param CompareValue 16-bit value used in compare operation. >> + @param ExchangeValue 16-bit value used in exchange operation. >> + >> + @return The original *Value before exchange. >> + >> +**/ >> +UINT16 >> +EFIAPI >> +InternalSyncCompareExchange16 ( >> + IN OUT volatile UINT16 *Value, >> + IN UINT16 CompareValue, >> + IN UINT16 ExchangeValue >> + ) >> +{ >> + >> + __asm__ __volatile__ ( >> + " \n " >> + "lock \n " >> + "cmpxchgw %1, %2 \n " >> + : "=a" (CompareValue) >> + : "q" (ExchangeValue), >> + "m" (*Value), >> + "0" (CompareValue) >> + : "memory", >> + "cc" >> + ); >> + >> + return CompareValue; >> +} >> + >> +/** >> Performs an atomic compare exchange operation on a 32-bit unsigned >> integer. >> >> Performs an atomic compare exchange operation on the 32-bit unsigned >> integer >> diff --git >> a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm >> >> b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm >> new file mode 100644 >> index 000000000000..f8705042661d >> --- /dev/null >> +++ >> b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm >> @@ -0,0 +1,46 @@ >> +;------------------------------------------------------------------------------ >> +; >> +; Copyright (c) 2006, Intel Corporation. All rights reserved.<BR> >> +; Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR> >> +; 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: >> +; >> +; InterlockedCompareExchange16.Asm >> +; >> +; Abstract: >> +; >> +; InterlockedCompareExchange16 function >> +; >> +; Notes: >> +; >> +;------------------------------------------------------------------------------ >> + >> + .486 >> + .model flat,C >> + .code >> + >> +;------------------------------------------------------------------------------ >> +; UINT16 >> +; EFIAPI >> +; InternalSyncCompareExchange16 ( >> +; IN UINT16 *Value, >> +; IN UINT16 CompareValue, >> +; IN UINT16 ExchangeValue >> +; ); >> +;------------------------------------------------------------------------------ >> +InternalSyncCompareExchange16 PROC >> + mov ecx, [esp + 4] >> + mov eax, [esp + 8] >> + mov edx, [esp + 12] >> + lock cmpxchg [ecx], dx >> + ret >> +InternalSyncCompareExchange16 ENDP >> + >> + END >> diff --git >> a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c >> b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c >> new file mode 100644 >> index 000000000000..3d06dd9baa63 >> --- /dev/null >> +++ >> b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c >> @@ -0,0 +1,51 @@ >> +/** @file >> + InterlockedCompareExchange16 function >> + >> + Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR> >> + Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR> >> + 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 16-bit unsigned >> integer. >> + >> + Performs an atomic compare exchange operation on the 16-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 16-bit value for the compare >> exchange >> + operation. >> + @param CompareValue 16-bit value used in compare operation. >> + @param ExchangeValue 16-bit value used in exchange operation. >> + >> + @return The original *Value before exchange. >> + >> +**/ >> +UINT16 >> +EFIAPI >> +InternalSyncCompareExchange16 ( >> + IN UINT16 *Value, >> + IN UINT16 CompareValue, >> + IN UINT16 ExchangeValue >> + ) >> +{ >> + _asm { >> + mov ecx, Value >> + mov eax, CompareValue >> + mov edx, ExchangeValue >> + lock cmpxchg [ecx], dx >> + } >> +} >> + >> diff --git >> a/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s >> b/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s >> new file mode 100644 >> index 000000000000..1e56942a98cb >> --- /dev/null >> +++ >> b/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s >> @@ -0,0 +1,30 @@ >> +/// @file >> +/// Contains an implementation of InterlockedCompareExchange16 on Itanium- >> +/// based architecture. >> +/// >> +/// Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR> >> +/// Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR> >> +/// 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: InterlockedCompareExchange16.s >> +/// >> +/// >> + >> +.auto >> +.text >> + >> +.proc InternalSyncCompareExchange16 >> +.type InternalSyncCompareExchange16, @function >> +InternalSyncCompareExchange16:: >> + zxt2 r33 = r33 >> + mov ar.ccv = r33 >> + cmpxchg2.rel r8 = [r32], r34 >> + mf >> + br.ret.sptk.many b0 >> +.endp InternalSyncCompareExchange16 >> diff --git a/MdePkg/Library/BaseSynchronizationLib/Synchronization.c >> b/MdePkg/Library/BaseSynchronizationLib/Synchronization.c >> index 0eea40ba1622..4218a265a0ec 100644 >> --- a/MdePkg/Library/BaseSynchronizationLib/Synchronization.c >> +++ b/MdePkg/Library/BaseSynchronizationLib/Synchronization.c >> @@ -277,6 +277,37 @@ InterlockedDecrement ( >> } >> >> /** >> + Performs an atomic compare exchange operation on a 16-bit unsigned >> integer. >> + >> + Performs an atomic compare exchange operation on the 16-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 16-bit value for the compare >> exchange >> + operation. >> + @param CompareValue 16-bit value used in compare operation. >> + @param ExchangeValue 16-bit value used in exchange operation. >> + >> + @return The original *Value before exchange. >> + >> +**/ >> +UINT16 >> +EFIAPI >> +InterlockedCompareExchange16 ( >> + IN OUT UINT16 *Value, >> + IN UINT16 CompareValue, >> + IN UINT16 ExchangeValue >> + ) >> +{ >> + ASSERT (Value != NULL); >> + return InternalSyncCompareExchange16 (Value, CompareValue, ExchangeValue); >> +} >> + >> +/** >> Performs an atomic compare exchange operation on a 32-bit unsigned >> integer. >> >> Performs an atomic compare exchange operation on the 32-bit unsigned >> integer >> diff --git a/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c >> b/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c >> index badf73c1a6ce..587f5a771c35 100644 >> --- a/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c >> +++ b/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c >> @@ -293,6 +293,37 @@ InterlockedDecrement ( >> } >> >> /** >> + Performs an atomic compare exchange operation on a 16-bit unsigned >> integer. >> + >> + Performs an atomic compare exchange operation on the 16-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 16-bit value for the compare >> exchange >> + operation. >> + @param CompareValue A 16-bit value used in compare operation. >> + @param ExchangeValue A 16-bit value used in exchange operation. >> + >> + @return The original *Value before exchange. >> + >> +**/ >> +UINT16 >> +EFIAPI >> +InterlockedCompareExchange16 ( >> + IN OUT UINT16 *Value, >> + IN UINT16 CompareValue, >> + IN UINT16 ExchangeValue >> + ) >> +{ >> + ASSERT (Value != NULL); >> + return InternalSyncCompareExchange16 (Value, CompareValue, ExchangeValue); >> +} >> + >> +/** >> Performs an atomic compare exchange operation on a 32-bit unsigned >> integer. >> >> Performs an atomic compare exchange operation on the 32-bit unsigned >> integer >> diff --git a/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c >> b/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c >> index 9b20236acfa6..ca21f5dccee5 100644 >> --- a/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c >> +++ b/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c >> @@ -295,6 +295,37 @@ InterlockedDecrement ( >> } >> >> /** >> + Performs an atomic compare exchange operation on a 16-bit unsigned >> integer. >> + >> + Performs an atomic compare exchange operation on the 16-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 16-bit value for the compare >> exchange >> + operation. >> + @param CompareValue A 16-bit value used in a compare operation. >> + @param ExchangeValue A 16-bit value used in an exchange operation. >> + >> + @return The original *Value before exchange. >> + >> +**/ >> +UINT16 >> +EFIAPI >> +InterlockedCompareExchange16 ( >> + IN OUT UINT16 *Value, >> + IN UINT16 CompareValue, >> + IN UINT16 ExchangeValue >> + ) >> +{ >> + ASSERT (Value != NULL); >> + return InternalSyncCompareExchange16 (Value, CompareValue, ExchangeValue); >> +} >> + >> +/** >> Performs an atomic compare exchange operation on a 32-bit unsigned >> integer. >> >> Performs an atomic compare exchange operation on the 32-bit unsigned >> integer >> diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c >> b/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c >> index ceb80aed94f8..6347073fee51 100644 >> --- a/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c >> +++ b/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c >> @@ -89,6 +89,50 @@ InternalSyncDecrement ( >> >> >> /** >> + Performs an atomic compare exchange operation on a 16-bit unsigned >> integer. >> + >> + Performs an atomic compare exchange operation on the 16-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 16-bit value for the compare >> exchange >> + operation. >> + @param CompareValue 16-bit value used in compare operation. >> + @param ExchangeValue 16-bit value used in exchange operation. >> + >> + @return The original *Value before exchange. >> + >> +**/ >> +UINT16 >> +EFIAPI >> +InternalSyncCompareExchange16 ( >> + IN OUT volatile UINT16 *Value, >> + IN UINT16 CompareValue, >> + IN UINT16 ExchangeValue >> + ) >> +{ >> + >> + >> + __asm__ __volatile__ ( >> + "lock \n " >> + "cmpxchgw %3, %1 " >> + : "=a" (CompareValue), >> + "=m" (*Value) >> + : "a" (CompareValue), >> + "r" (ExchangeValue), >> + "m" (*Value) >> + : "memory", >> + "cc" >> + ); >> + >> + return CompareValue; >> +} >> + >> + >> +/** >> Performs an atomic compare exchange operation on a 32-bit unsigned >> integer. >> >> Performs an atomic compare exchange operation on the 32-bit unsigned >> integer >> diff --git >> a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm >> b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm >> new file mode 100644 >> index 000000000000..8fe2aae1a28b >> --- /dev/null >> +++ >> b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm >> @@ -0,0 +1,42 @@ >> +;------------------------------------------------------------------------------ >> +; >> +; Copyright (c) 2006, Intel Corporation. All rights reserved.<BR> >> +; Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR> >> +; 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: >> +; >> +; InterlockedCompareExchange16.Asm >> +; >> +; Abstract: >> +; >> +; InterlockedCompareExchange16 function >> +; >> +; Notes: >> +; >> +;------------------------------------------------------------------------------ >> + >> + .code >> + >> +;------------------------------------------------------------------------------ >> +; UINT16 >> +; EFIAPI >> +; InterlockedCompareExchange16 ( >> +; IN UINT16 *Value, >> +; IN UINT16 CompareValue, >> +; IN UINT16 ExchangeValue >> +; ); >> +;------------------------------------------------------------------------------ >> +InternalSyncCompareExchange16 PROC >> + mov eax, edx >> + lock cmpxchg [rcx], r8w >> + ret >> +InternalSyncCompareExchange16 ENDP >> + >> + END >> diff --git >> a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c >> b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c >> new file mode 100644 >> index 000000000000..76aa6fbc0e81 >> --- /dev/null >> +++ >> b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c >> @@ -0,0 +1,54 @@ >> +/** @file >> + InterlockedCompareExchange16 function >> + >> + Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR> >> + Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR> >> + 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. >> +**/ >> + >> +__int16 _InterlockedCompareExchange16( >> + __int16 volatile * Destination, >> + __int16 Exchange, >> + __int16 Comperand >> +); >> + >> +#pragma intrinsic(_InterlockedCompareExchange16) >> + >> +/** >> + Performs an atomic compare exchange operation on a 16-bit unsigned >> integer. >> + >> + Performs an atomic compare exchange operation on the 16-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 16-bit value for the compare >> exchange >> + operation. >> + @param CompareValue 16-bit value used in compare operation. >> + @param ExchangeValue 16-bit value used in exchange operation. >> + >> + @return The original *Value before exchange. >> + >> +**/ >> +UINT16 >> +EFIAPI >> +InternalSyncCompareExchange16 ( >> + IN UINT16 *Value, >> + IN UINT16 CompareValue, >> + IN UINT16 ExchangeValue >> + ) >> +{ >> + return _InterlockedCompareExchange16 (Value, ExchangeValue, CompareValue); >> +} >> + >> -- >> 1.8.3.2 >> _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel