From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jordan Justen Subject: Re: [PATCH v4 14/29] MdePkg/BaseSynchronizationLib: implement 16-bit compare-exchange Date: Tue, 17 Feb 2015 09:40:47 -0800 Message-ID: <20150217174047.8141.17529__5443.38729600913$1424195036$gmane$org@jljusten-ivy> References: <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org> <1423739961-5945-15-git-send-email-ard.biesheuvel@linaro.org> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1423739961-5945-15-git-send-email-ard.biesheuvel@linaro.org> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: edk2-devel@lists.sourceforge.net, olivier.martin@arm.com, lersek@redhat.com, roy.franz@linaro.org, leif.lindholm@linaro.org, stefano.stabellini@eu.citrix.com, ian.campbell@citrix.com, anthony.perard@citrix.com, xen-devel@lists.xen.org, julien.grall@linaro.org, michael.d.kinney@intel.com, feng.tian@intel.com Cc: Ard Biesheuvel List-Id: xen-devel@lists.xenproject.org Ard, For the subject, I think MdePkg/BaseSynchronizationLib: Add InterlockedCompareExchange16 would be better. Acked-by: Jordan Justen Thanks for working to move this to a common location. Mike, I think Anthony tested the IA32 and X64 implementations with Xen. For IPF, I don't think it has been tested. -Jordan 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 > Signed-off-by: Ard Biesheuvel > --- > 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.
> +; Copyright (c) 2015, Linaro Ltd. 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: > +; > +; 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.
> + Copyright (c) 2015, Linaro Ltd. 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 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.
> +/// Copyright (c) 2015, Linaro Ltd. 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: 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.
> +; Copyright (c) 2015, Linaro Ltd. 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: > +; > +; 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.
> + Copyright (c) 2015, Linaro Ltd. 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. > +**/ > + > +__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 >