[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v4 14/29] MdePkg/BaseSynchronizationLib: implement 16-bit compare-exchange



On 25 February 2015 at 21:56, Kinney, Michael D
<michael.d.kinney@xxxxxxxxx> wrote:
> Ard Biesheuvel,
>
> Thank you for providing the implementation of this new function for all 
> supported CPU architectures.  The one for IPF looks correct and passes builds.

Good. Thanks for confirming that.

> However, I am seeing some build breaks and some issues with the IA32 and X64 
> versions.  The following changes are required to your patch to build with 
> VS20xx compilers and for the code generated by asm/Inline asm to match code 
> generated by VS20xx compiler intrinsics.

OK, I will update the patch with your suggested changes.

> I have not built and disassembled GCC yet, but I think GCC inline asm should 
> generate the expected 16-bit register load operations that have been 
> addressed here.
>

This is what I get for X64 and IA32, respectively:

Disassembly of section .text.InternalSyncCompareExchange16:

0000000000000000 <InternalSyncCompareExchange16>:
   0: 55                   push   %rbp
   1: 48 89 e5             mov    %rsp,%rbp
   4: 48 89 4d 10           mov    %rcx,0x10(%rbp)
   8: 89 d0                 mov    %edx,%eax
   a: 44 89 c2             mov    %r8d,%edx
   d: 66 89 45 18           mov    %ax,0x18(%rbp)
  11: 66 89 55 20           mov    %dx,0x20(%rbp)
  15: 4c 8b 45 10           mov    0x10(%rbp),%r8
  19: 0f b7 45 18           movzwl 0x18(%rbp),%eax
  1d: 0f b7 55 20           movzwl 0x20(%rbp),%edx
  21: 48 8b 4d 10           mov    0x10(%rbp),%rcx
  25: f0 66 41 0f b1 10     lock cmpxchg %dx,(%r8)
  2b: 66 89 45 18           mov    %ax,0x18(%rbp)
  2f: 0f b7 45 18           movzwl 0x18(%rbp),%eax
  33: 5d                   pop    %rbp
  34: c3                   retq

Disassembly of section .text.InternalSyncCompareExchange16:

00000000 <InternalSyncCompareExchange16>:
   0: 55                   push   %ebp
   1: 89 e5                 mov    %esp,%ebp
   3: 8b 45 0c             mov    0xc(%ebp),%eax
   6: 8b 55 10             mov    0x10(%ebp),%edx
   9: 8b 4d 08             mov    0x8(%ebp),%ecx
   c: f0 66 0f b1 11       lock cmpxchg %dx,(%ecx)
  11: 5d                   pop    %ebp
  12: c3                   ret

The latter looks equivalent to me, but perhaps you could confirm that
the former does the right thing?

Thanks a lot for taking the time,
Ard.



> --- Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm      
>   Mon Jan 19 14:26:36 1970
> +++ Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm      
>   Mon Jan 19 14:26:36 1970
> @@ -37,8 +37,8 @@
>  
> ;------------------------------------------------------------------------------
>  InternalSyncCompareExchange16   PROC
>      mov     ecx, [esp + 4]
> -    mov     eax, [esp + 8]
> -    mov     edx, [esp + 12]
> +    mov     ax, [esp + 8]
> +    mov     dx, [esp + 12]
>      lock    cmpxchg [ecx], dx
>      ret
>  InternalSyncCompareExchange16   ENDP
> --- Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c  Mon 
> Jan 19 14:26:36 1970
> +++ Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c  Mon 
> Jan 19 14:26:36 1970
> @@ -43,8 +43,8 @@
>  {
>    _asm {
>      mov     ecx, Value
> -    mov     eax, CompareValue
> -    mov     edx, ExchangeValue
> +    mov     ax, CompareValue
> +    mov     dx, ExchangeValue
>      lock    cmpxchg [ecx], dx
>    }
>  }
> --- Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm Mon 
> Jan 19 14:26:36 1970
> +++ Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm Mon 
> Jan 19 14:26:36 1970
> @@ -34,7 +34,7 @@
>  ;   );
>  
> ;------------------------------------------------------------------------------
>  InternalSyncCompareExchange16   PROC
> -    mov     eax, edx
> +    mov     ax, dx
>      lock    cmpxchg [rcx], r8w
>      ret
>  InternalSyncCompareExchange16   ENDP
>
> Best regards,
>
> Mike
>
> -----Original Message-----
> From: Ard Biesheuvel [mailto:ard.biesheuvel@xxxxxxxxxx]
> Sent: Thursday, February 12, 2015 3:19 AM
> To: edk2-devel@xxxxxxxxxxxxxxxxxxxxx; olivier.martin@xxxxxxx; 
> lersek@xxxxxxxxxx; roy.franz@xxxxxxxxxx; leif.lindholm@xxxxxxxxxx; 
> stefano.stabellini@xxxxxxxxxxxxx; ian.campbell@xxxxxxxxxx; 
> anthony.perard@xxxxxxxxxx; xen-devel@xxxxxxxxxxxxx; julien.grall@xxxxxxxxxx; 
> Justen, Jordan L; Kinney, Michael D; Tian, Feng
> Cc: Ard Biesheuvel
> Subject: [PATCH v4 14/29] MdePkg/BaseSynchronizationLib: implement 16-bit 
> compare-exchange
>
> 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.martin@xxxxxxx>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@xxxxxxxxxx>
> ---
>  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\t"
> +    "lock                 \n\t"
> +    "cmpxchgw    %1, %2   \n\t"
> +    : "=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\t"
> +    "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@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.