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

Reply via email to