]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdePkg/BaseSynchronizationLib: Add InterlockedCompareExchange16
authorArd Biesheuvel <ard.biesheuvel@linaro.org>
Sat, 28 Feb 2015 20:31:54 +0000 (20:31 +0000)
committerlersek <lersek@Edk2>
Sat, 28 Feb 2015 20:31:54 +0000 (20:31 +0000)
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@arm.com>
Acked-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Michael Kinney <michael.d.kinney@intel.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16966 6f19259b-4bc3-4df7-8a09-765794883524

17 files changed:
MdePkg/Include/Library/SynchronizationLib.h
MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S
MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S
MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm
MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h
MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c
MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c
MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm [new file with mode: 0644]
MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c [new file with mode: 0644]
MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s [new file with mode: 0644]
MdePkg/Library/BaseSynchronizationLib/Synchronization.c
MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c
MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c
MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c
MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm [new file with mode: 0644]
MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c [new file with mode: 0644]

index f9756973991471e5cd32c7ff745aacc3173f846d..7b97683ca0af769af04ed5c90a0d15376bb43ce5 100644 (file)
@@ -183,6 +183,32 @@ InterlockedDecrement (
   );\r
 \r
 \r
+/**\r
+  Performs an atomic compare exchange operation on a 16-bit unsigned integer.\r
+\r
+  Performs an atomic compare exchange operation on the 16-bit unsigned integer\r
+  specified by Value.  If Value is equal to CompareValue, then Value is set to\r
+  ExchangeValue and CompareValue is returned.  If Value is not equal to CompareValue,\r
+  then Value is returned.  The compare exchange operation must be performed using\r
+  MP safe mechanisms.\r
+\r
+  If Value is NULL, then ASSERT().\r
+\r
+  @param  Value         A pointer to the 16-bit value for the compare exchange\r
+                        operation.\r
+  @param  CompareValue  16-bit value used in compare operation.\r
+  @param  ExchangeValue 16-bit value used in exchange operation.\r
+\r
+  @return The original *Value before exchange.\r
+**/\r
+UINT16\r
+EFIAPI\r
+InterlockedCompareExchange16 (\r
+  IN OUT  UINT16                    *Value,\r
+  IN      UINT16                    CompareValue,\r
+  IN      UINT16                    ExchangeValue\r
+  );\r
+\r
 /**\r
   Performs an atomic compare exchange operation on a 32-bit unsigned integer.\r
 \r
index 601b00495f268d4d384f92d3bbd5ca96908c5b8f..ecb87fc127556df03e84d9bb22ca4faf9888088c 100644 (file)
 .text\r
 .align 3\r
 \r
+GCC_ASM_EXPORT(InternalSyncCompareExchange16)\r
 GCC_ASM_EXPORT(InternalSyncCompareExchange32)\r
 GCC_ASM_EXPORT(InternalSyncCompareExchange64)\r
 GCC_ASM_EXPORT(InternalSyncIncrement)\r
 GCC_ASM_EXPORT(InternalSyncDecrement)\r
 \r
+/**\r
+  Performs an atomic compare exchange operation on a 16-bit unsigned integer.\r
+\r
+  Performs an atomic compare exchange operation on the 16-bit unsigned integer\r
+  specified by Value.  If Value is equal to CompareValue, then Value is set to\r
+  ExchangeValue and CompareValue is returned.  If Value is not equal to CompareValue,\r
+  then Value is returned.  The compare exchange operation must be performed using\r
+  MP safe mechanisms.\r
+\r
+  @param  Value         A pointer to the 16-bit value for the compare exchange\r
+                        operation.\r
+  @param  CompareValue  16-bit value used in compare operation.\r
+  @param  ExchangeValue 16-bit value used in exchange operation.\r
+\r
+  @return The original *Value before exchange.\r
+\r
+**/\r
+//UINT16\r
+//EFIAPI\r
+//InternalSyncCompareExchange16 (\r
+//  IN      volatile UINT16           *Value,\r
+//  IN      UINT16                    CompareValue,\r
+//  IN      UINT16                    ExchangeValue\r
+//  )\r
+ASM_PFX(InternalSyncCompareExchange16):\r
+  uxth    w1, w1\r
+  uxth    w2, w2\r
+  dmb     sy\r
+\r
+InternalSyncCompareExchange16Again:\r
+  ldxrh   w3, [x0]\r
+  cmp     w3, w1\r
+  bne     InternalSyncCompareExchange16Fail\r
+\r
+InternalSyncCompareExchange16Exchange:\r
+  stxrh   w4, w2, [x0]\r
+  cbnz    w4, InternalSyncCompareExchange16Again\r
+\r
+InternalSyncCompareExchange16Fail:\r
+  dmb     sy\r
+  mov     w0, w3\r
+  ret\r
+\r
 /**\r
   Performs an atomic compare exchange operation on a 32-bit unsigned integer.\r
 \r
index 0128f8f016bdd7085d3bc23f29a108f7fb5e7ad8..d699eb40d2a26bd1ea582f455b2eb3932cdde809 100644 (file)
@@ -1,6 +1,7 @@
 //  Implementation of synchronization functions for ARM architecture\r
 //\r
 //  Copyright (c) 2012-2015, ARM Limited. All rights reserved.\r
+//  Copyright (c) 2015, Linaro Limited. All rights reserved.\r
 //\r
 //  This program and the accompanying materials\r
 //  are licensed and made available under the terms and conditions of the BSD License\r
 .text\r
 .align 3\r
 \r
+GCC_ASM_EXPORT(InternalSyncCompareExchange16)\r
 GCC_ASM_EXPORT(InternalSyncCompareExchange32)\r
 GCC_ASM_EXPORT(InternalSyncCompareExchange64)\r
 GCC_ASM_EXPORT(InternalSyncIncrement)\r
 GCC_ASM_EXPORT(InternalSyncDecrement)\r
 \r
+/**\r
+  Performs an atomic compare exchange operation on a 16-bit unsigned integer.\r
+\r
+  Performs an atomic compare exchange operation on the 16-bit unsigned integer\r
+  specified by Value.  If Value is equal to CompareValue, then Value is set to\r
+  ExchangeValue and CompareValue is returned.  If Value is not equal to CompareValue,\r
+  then Value is returned.  The compare exchange operation must be performed using\r
+  MP safe mechanisms.\r
+\r
+  @param  Value         A pointer to the 16-bit value for the compare exchange\r
+                        operation.\r
+  @param  CompareValue  16-bit value used in compare operation.\r
+  @param  ExchangeValue 16-bit value used in exchange operation.\r
+\r
+  @return The original *Value before exchange.\r
+\r
+**/\r
+//UINT16\r
+//EFIAPI\r
+//InternalSyncCompareExchange16 (\r
+//  IN      volatile UINT16           *Value,\r
+//  IN      UINT16                    CompareValue,\r
+//  IN      UINT16                    ExchangeValue\r
+//  )\r
+ASM_PFX(InternalSyncCompareExchange16):\r
+  dmb\r
+\r
+InternalSyncCompareExchange16Again:\r
+  ldrexh  r3, [r0]\r
+  cmp     r3, r1\r
+  bne     InternalSyncCompareExchange16Fail\r
+\r
+InternalSyncCompareExchange16Exchange:\r
+  strexh  ip, r2, [r0]\r
+  cmp     ip, #0\r
+  bne     InternalSyncCompareExchange16Again\r
+\r
+InternalSyncCompareExchange16Fail:\r
+  dmb\r
+  mov     r0, r3\r
+  bx      lr\r
+\r
 /**\r
   Performs an atomic compare exchange operation on a 32-bit unsigned integer.\r
 \r
index f9f80737774adce4816722e391694d3e7d3dc3ff..dbc59911409386e633b9958a3d0d468f6eddceb8 100644 (file)
@@ -1,6 +1,7 @@
 //  Implementation of synchronization functions for ARM architecture\r
 //\r
 //  Copyright (c) 2012-2015, ARM Limited. All rights reserved.\r
+//  Copyright (c) 2015, Linaro Limited. All rights reserved.\r
 //\r
 //  This program and the accompanying materials\r
 //  are licensed and made available under the terms and conditions of the BSD License\r
@@ -12,6 +13,7 @@
 //\r
 //\r
 \r
+    EXPORT  InternalSyncCompareExchange16\r
     EXPORT  InternalSyncCompareExchange32\r
     EXPORT  InternalSyncCompareExchange64\r
     EXPORT  InternalSyncIncrement\r
 \r
     AREA   ArmSynchronization, CODE, READONLY\r
 \r
+/**\r
+  Performs an atomic compare exchange operation on a 16-bit unsigned integer.\r
+\r
+  Performs an atomic compare exchange operation on the 16-bit unsigned integer\r
+  specified by Value.  If Value is equal to CompareValue, then Value is set to\r
+  ExchangeValue and CompareValue is returned.  If Value is not equal to CompareValue,\r
+  then Value is returned.  The compare exchange operation must be performed using\r
+  MP safe mechanisms.\r
+\r
+  @param  Value         A pointer to the 16-bit value for the compare exchange\r
+                        operation.\r
+  @param  CompareValue  16-bit value used in compare operation.\r
+  @param  ExchangeValue 16-bit value used in exchange operation.\r
+\r
+  @return The original *Value before exchange.\r
+\r
+**/\r
+//UINT16\r
+//EFIAPI\r
+//InternalSyncCompareExchange16 (\r
+//  IN      volatile UINT16           *Value,\r
+//  IN      UINT16                    CompareValue,\r
+//  IN      UINT16                    ExchangeValue\r
+//  )\r
+InternalSyncCompareExchange16\r
+  dmb\r
+\r
+InternalSyncCompareExchange16Again\r
+  ldrexh  r3, [r0]\r
+  cmp     r3, r1\r
+  bne     InternalSyncCompareExchange16Fail\r
+\r
+InternalSyncCompareExchange16Exchange\r
+  strexh  ip, r2, [r0]\r
+  cmp     ip, #0\r
+  bne     InternalSyncCompareExchange16Again\r
+\r
+InternalSyncCompareExchange16Fail\r
+  dmb\r
+  mov     r0, r3\r
+  bx      lr\r
+\r
 /**\r
   Performs an atomic compare exchange operation on a 32-bit unsigned integer.\r
 \r
index 5e3b4e6b9bf2b55d7f0b9e2ce6d04c6ecdd7fde6..bd1bec3fb5e76a3bc545423af14a31046101c955 100755 (executable)
 [Sources.IA32]\r
   Ia32/InterlockedCompareExchange64.c | MSFT \r
   Ia32/InterlockedCompareExchange32.c | MSFT \r
+  Ia32/InterlockedCompareExchange16.c | MSFT\r
   Ia32/InterlockedDecrement.c | MSFT \r
   Ia32/InterlockedIncrement.c | MSFT \r
   SynchronizationMsc.c  | MSFT\r
 \r
   Ia32/InterlockedCompareExchange64.asm | INTEL \r
   Ia32/InterlockedCompareExchange32.asm | INTEL \r
+  Ia32/InterlockedCompareExchange16.asm | INTEL\r
   Ia32/InterlockedDecrement.asm | INTEL \r
   Ia32/InterlockedIncrement.asm | INTEL \r
   Synchronization.c | INTEL\r
 [Sources.X64]\r
   X64/InterlockedCompareExchange64.c | MSFT\r
   X64/InterlockedCompareExchange32.c | MSFT\r
+  X64/InterlockedCompareExchange16.c | MSFT\r
   \r
   X64/InterlockedCompareExchange64.asm | INTEL\r
   X64/InterlockedCompareExchange32.asm | INTEL\r
+  X64/InterlockedCompareExchange16.asm | INTEL\r
   \r
   X64/InterlockedDecrement.c | MSFT \r
   X64/InterlockedIncrement.c | MSFT \r
@@ -67,6 +71,7 @@
   Ipf/Synchronization.c\r
   Ipf/InterlockedCompareExchange64.s\r
   Ipf/InterlockedCompareExchange32.s\r
+  Ipf/InterlockedCompareExchange16.s\r
 \r
   Synchronization.c     | INTEL \r
   SynchronizationMsc.c  | MSFT \r
index e42824c75d12152b246432b9fd19631d5fe8e0ef..76f7023241560f416e510f09523d89103b53477b 100644 (file)
@@ -62,6 +62,32 @@ InternalSyncDecrement (
   );\r
 \r
 \r
+/**\r
+  Performs an atomic compare exchange operation on a 16-bit unsigned integer.\r
+\r
+  Performs an atomic compare exchange operation on the 16-bit unsigned integer\r
+  specified by Value.  If Value is equal to CompareValue, then Value is set to\r
+  ExchangeValue and CompareValue is returned.  If Value is not equal to CompareValue,\r
+  then Value is returned.  The compare exchange operation must be performed using\r
+  MP safe mechanisms.\r
+\r
+  @param  Value         A pointer to the 16-bit value for the compare exchange\r
+                        operation.\r
+  @param  CompareValue  A 16-bit value used in compare operation.\r
+  @param  ExchangeValue A 16-bit value used in exchange operation.\r
+\r
+  @return The original *Value before exchange.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+InternalSyncCompareExchange16 (\r
+  IN      volatile UINT16           *Value,\r
+  IN      UINT16                    CompareValue,\r
+  IN      UINT16                    ExchangeValue\r
+  );\r
+\r
+\r
 /**\r
   Performs an atomic compare exchange operation on a 32-bit unsigned integer.\r
 \r
index 9c34b9f128eda761fae8801d7b7ae438671f5a49..a57860203b120268898c085770a60e489d699fe4 100644 (file)
 \r
 **/\r
 \r
+/**\r
+  Performs an atomic compare exchange operation on a 16-bit\r
+  unsigned integer.\r
+\r
+  Performs an atomic compare exchange operation on the 16-bit\r
+  unsigned integer specified by Value.  If Value is equal to\r
+  CompareValue, then Value is set to ExchangeValue and\r
+  CompareValue is returned.  If Value is not equal to\r
+  CompareValue, then Value is returned. The compare exchange\r
+  operation must be performed using MP safe mechanisms.\r
+\r
+  @param  Value         A pointer to the 16-bit value for the\r
+                        compare exchange operation.\r
+  @param  CompareValue  16-bit value used in compare operation.\r
+  @param  ExchangeValue 16-bit value used in exchange operation.\r
+\r
+  @return The original *Value before exchange.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+InternalSyncCompareExchange16 (\r
+  IN      volatile UINT16           *Value,\r
+  IN      UINT16                    CompareValue,\r
+  IN      UINT16                    ExchangeValue\r
+  )\r
+{\r
+  return *Value != CompareValue ? *Value :\r
+           ((*Value = ExchangeValue), CompareValue);\r
+}\r
+\r
 /**\r
   Performs an atomic compare exchange operation on a 32-bit\r
   unsigned integer.\r
index b5a7827fc0e87e6db19eba8fdc528575f4685b08..bd81aad6c243622d3e88782d3d66ba45068a8624 100644 (file)
@@ -87,6 +87,48 @@ InternalSyncDecrement (
   return Result;\r
 }\r
 \r
+/**\r
+  Performs an atomic compare exchange operation on a 16-bit unsigned integer.\r
+\r
+  Performs an atomic compare exchange operation on the 16-bit unsigned integer\r
+  specified by Value.  If Value is equal to CompareValue, then Value is set to\r
+  ExchangeValue and CompareValue is returned.  If Value is not equal to CompareValue,\r
+  then Value is returned.  The compare exchange operation must be performed using\r
+  MP safe mechanisms.\r
+\r
+\r
+  @param  Value         A pointer to the 16-bit value for the compare exchange\r
+                        operation.\r
+  @param  CompareValue  16-bit value used in compare operation.\r
+  @param  ExchangeValue 16-bit value used in exchange operation.\r
+\r
+  @return The original *Value before exchange.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+InternalSyncCompareExchange16 (\r
+  IN OUT volatile  UINT16           *Value,\r
+  IN      UINT16                    CompareValue,\r
+  IN      UINT16                    ExchangeValue\r
+  )\r
+{\r
+\r
+  __asm__ __volatile__ (\r
+    "                     \n\t"\r
+    "lock                 \n\t"\r
+    "cmpxchgw    %1, %2   \n\t"\r
+    : "=a" (CompareValue)\r
+    : "q"  (ExchangeValue),\r
+      "m"  (*Value),\r
+      "0"  (CompareValue)\r
+    : "memory",\r
+      "cc"\r
+    );\r
+\r
+  return CompareValue;\r
+}\r
+\r
 /**\r
   Performs an atomic compare exchange operation on a 32-bit unsigned integer.\r
 \r
diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm
new file mode 100644 (file)
index 0000000..7d14e8e
--- /dev/null
@@ -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     ax, [esp + 8]
+    mov     dx, [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 (file)
index 0000000..102173b
--- /dev/null
@@ -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     ax, CompareValue
+    mov     dx, 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 (file)
index 0000000..1e56942
--- /dev/null
@@ -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
index 0eea40ba1622bb2dfa4a87f023b1cd2451375618..4218a265a0ec37d0668647bc5f12c5bcbbf27dda 100644 (file)
@@ -276,6 +276,37 @@ InterlockedDecrement (
   return InternalSyncDecrement (Value);\r
 }\r
 \r
+/**\r
+  Performs an atomic compare exchange operation on a 16-bit unsigned integer.\r
+\r
+  Performs an atomic compare exchange operation on the 16-bit unsigned integer\r
+  specified by Value.  If Value is equal to CompareValue, then Value is set to\r
+  ExchangeValue and CompareValue is returned.  If Value is not equal to CompareValue,\r
+  then Value is returned.  The compare exchange operation must be performed using\r
+  MP safe mechanisms.\r
+\r
+  If Value is NULL, then ASSERT().\r
+\r
+  @param  Value         A pointer to the 16-bit value for the compare exchange\r
+                        operation.\r
+  @param  CompareValue  16-bit value used in compare operation.\r
+  @param  ExchangeValue 16-bit value used in exchange operation.\r
+\r
+  @return The original *Value before exchange.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+InterlockedCompareExchange16 (\r
+  IN OUT  UINT16                    *Value,\r
+  IN      UINT16                    CompareValue,\r
+  IN      UINT16                    ExchangeValue\r
+  )\r
+{\r
+  ASSERT (Value != NULL);\r
+  return InternalSyncCompareExchange16 (Value, CompareValue, ExchangeValue);\r
+}\r
+\r
 /**\r
   Performs an atomic compare exchange operation on a 32-bit unsigned integer.\r
 \r
index badf73c1a6ce674707f7f7622bb3b0bb0fe9f41c..587f5a771c353b3070e3160fa22eb52abce74bf4 100644 (file)
@@ -292,6 +292,37 @@ InterlockedDecrement (
   return InternalSyncDecrement (Value);\r
 }\r
 \r
+/**\r
+  Performs an atomic compare exchange operation on a 16-bit unsigned integer.\r
+\r
+  Performs an atomic compare exchange operation on the 16-bit unsigned integer\r
+  specified by Value.  If Value is equal to CompareValue, then Value is set to\r
+  ExchangeValue and CompareValue is returned.  If Value is not equal to CompareValue,\r
+  then Value is returned.  The compare exchange operation must be performed using\r
+  MP safe mechanisms.\r
+\r
+  If Value is NULL, then ASSERT().\r
+\r
+  @param  Value         A pointer to the 16-bit value for the compare exchange\r
+                        operation.\r
+  @param  CompareValue  A 16-bit value used in compare operation.\r
+  @param  ExchangeValue A 16-bit value used in exchange operation.\r
+\r
+  @return The original *Value before exchange.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+InterlockedCompareExchange16 (\r
+  IN OUT  UINT16                    *Value,\r
+  IN      UINT16                    CompareValue,\r
+  IN      UINT16                    ExchangeValue\r
+  )\r
+{\r
+  ASSERT (Value != NULL);\r
+  return InternalSyncCompareExchange16 (Value, CompareValue, ExchangeValue);\r
+}\r
+\r
 /**\r
   Performs an atomic compare exchange operation on a 32-bit unsigned integer.\r
 \r
index 9b20236acfa6f9deda460d7f4bf11b5024d6438a..ca21f5dccee52d53ad381b9221a13a50482c776f 100644 (file)
@@ -294,6 +294,37 @@ InterlockedDecrement (
   return InternalSyncDecrement (Value);\r
 }\r
 \r
+/**\r
+  Performs an atomic compare exchange operation on a 16-bit unsigned integer.\r
+\r
+  Performs an atomic compare exchange operation on the 16-bit unsigned integer\r
+  specified by Value.  If Value is equal to CompareValue, then Value is set to\r
+  ExchangeValue and CompareValue is returned.  If Value is not equal to CompareValue,\r
+  then Value is returned.  The compare exchange operation must be performed using\r
+  MP safe mechanisms.\r
+\r
+  If Value is NULL, then ASSERT().\r
+\r
+  @param  Value         A pointer to the 16-bit value for the compare exchange\r
+                        operation.\r
+  @param  CompareValue  A 16-bit value used in a compare operation.\r
+  @param  ExchangeValue A 16-bit value used in an exchange operation.\r
+\r
+  @return The original *Value before exchange.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+InterlockedCompareExchange16 (\r
+  IN OUT  UINT16                    *Value,\r
+  IN      UINT16                    CompareValue,\r
+  IN      UINT16                    ExchangeValue\r
+  )\r
+{\r
+  ASSERT (Value != NULL);\r
+  return InternalSyncCompareExchange16 (Value, CompareValue, ExchangeValue);\r
+}\r
+\r
 /**\r
   Performs an atomic compare exchange operation on a 32-bit unsigned integer.\r
 \r
index ceb80aed94f8aeba8e02bda19e41384d4a607178..6347073fee510c2fb9f14ee9440ac34dad9bfcc0 100644 (file)
@@ -88,6 +88,50 @@ InternalSyncDecrement (
 }\r
 \r
 \r
+/**\r
+  Performs an atomic compare exchange operation on a 16-bit unsigned integer.\r
+\r
+  Performs an atomic compare exchange operation on the 16-bit unsigned integer\r
+  specified by Value.  If Value is equal to CompareValue, then Value is set to\r
+  ExchangeValue and CompareValue is returned.  If Value is not equal to CompareValue,\r
+  then Value is returned.  The compare exchange operation must be performed using\r
+  MP safe mechanisms.\r
+\r
+\r
+  @param  Value         A pointer to the 16-bit value for the compare exchange\r
+                        operation.\r
+  @param  CompareValue  16-bit value used in compare operation.\r
+  @param  ExchangeValue 16-bit value used in exchange operation.\r
+\r
+  @return The original *Value before exchange.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+InternalSyncCompareExchange16 (\r
+  IN OUT volatile  UINT16           *Value,\r
+  IN      UINT16                    CompareValue,\r
+  IN      UINT16                    ExchangeValue\r
+  )\r
+{\r
+\r
+\r
+  __asm__ __volatile__ (\r
+    "lock                 \n\t"\r
+    "cmpxchgw    %3, %1       "\r
+    : "=a" (CompareValue),\r
+      "=m" (*Value)\r
+    : "a"  (CompareValue),\r
+      "r"  (ExchangeValue),\r
+      "m"  (*Value)\r
+    : "memory",\r
+      "cc"\r
+    );\r
+\r
+  return CompareValue;\r
+}\r
+\r
+\r
 /**\r
   Performs an atomic compare exchange operation on a 32-bit unsigned integer.\r
 \r
diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm
new file mode 100644 (file)
index 0000000..e01e9fa
--- /dev/null
@@ -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     ax, dx
+    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 (file)
index 0000000..76aa6fb
--- /dev/null
@@ -0,0 +1,54 @@
+/** @file\r
+  InterlockedCompareExchange16 function\r
+\r
+  Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+/**\r
+  Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics.\r
+**/\r
+\r
+__int16 _InterlockedCompareExchange16(\r
+   __int16 volatile * Destination,\r
+   __int16 Exchange,\r
+   __int16 Comperand\r
+);\r
+\r
+#pragma intrinsic(_InterlockedCompareExchange16)\r
+\r
+/**\r
+  Performs an atomic compare exchange operation on a 16-bit unsigned integer.\r
+\r
+  Performs an atomic compare exchange operation on the 16-bit unsigned integer specified\r
+  by Value.  If Value is equal to CompareValue, then Value is set to ExchangeValue and\r
+  CompareValue is returned.  If Value is not equal to CompareValue, then Value is returned.\r
+  The compare exchange operation must be performed using MP safe mechanisms.\r
+\r
+  @param  Value         A pointer to the 16-bit value for the compare exchange\r
+                        operation.\r
+  @param  CompareValue  16-bit value used in compare operation.\r
+  @param  ExchangeValue 16-bit value used in exchange operation.\r
+\r
+  @return The original *Value before exchange.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+InternalSyncCompareExchange16 (\r
+  IN      UINT16                    *Value,\r
+  IN      UINT16                    CompareValue,\r
+  IN      UINT16                    ExchangeValue\r
+  )\r
+{\r
+  return _InterlockedCompareExchange16 (Value, ExchangeValue, CompareValue);\r
+}\r
+\r