This is a copy of InterlockedCompareExchange32 from the BaseSynchronizationLib.
The function will be used in the next patch. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Anthony PERARD <anthony.per...@citrix.com> --- Change in V2: - Add intel compilation code MSFT code is not compied over because I don't know how it works. --- OvmfPkg/XenBusDxe/InterlockedCompareExchange16.h | 15 ++++++++ .../XenBusDxe/InterlockedCompareExchange16Intel.c | 32 +++++++++++++++++ .../XenBusDxe/X64/InterlockedCompareExchange16.asm | 41 ++++++++++++++++++++++ .../XenBusDxe/X64/InterlockedCompareExchange16.c | 41 ++++++++++++++++++++++ OvmfPkg/XenBusDxe/XenBusDxe.inf | 4 +++ 5 files changed, 133 insertions(+) create mode 100644 OvmfPkg/XenBusDxe/InterlockedCompareExchange16.h create mode 100644 OvmfPkg/XenBusDxe/InterlockedCompareExchange16Intel.c create mode 100644 OvmfPkg/XenBusDxe/X64/InterlockedCompareExchange16.asm create mode 100644 OvmfPkg/XenBusDxe/X64/InterlockedCompareExchange16.c diff --git a/OvmfPkg/XenBusDxe/InterlockedCompareExchange16.h b/OvmfPkg/XenBusDxe/InterlockedCompareExchange16.h new file mode 100644 index 0000000..9067882 --- /dev/null +++ b/OvmfPkg/XenBusDxe/InterlockedCompareExchange16.h @@ -0,0 +1,15 @@ +UINT16 +EFIAPI +InternalSyncCompareExchange16 ( + IN UINT16 *Value, + IN UINT16 CompareValue, + IN UINT16 ExchangeValue + ); + +UINT16 +EFIAPI +InterlockedCompareExchange16 ( + IN OUT volatile UINT16 *Value, + IN UINT16 CompareValue, + IN UINT16 ExchangeValue + ); diff --git a/OvmfPkg/XenBusDxe/InterlockedCompareExchange16Intel.c b/OvmfPkg/XenBusDxe/InterlockedCompareExchange16Intel.c new file mode 100644 index 0000000..bb40e70 --- /dev/null +++ b/OvmfPkg/XenBusDxe/InterlockedCompareExchange16Intel.c @@ -0,0 +1,32 @@ +#include "InterlockedCompareExchange16.h" + +/** + 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); +} diff --git a/OvmfPkg/XenBusDxe/X64/InterlockedCompareExchange16.asm b/OvmfPkg/XenBusDxe/X64/InterlockedCompareExchange16.asm new file mode 100644 index 0000000..b23e421 --- /dev/null +++ b/OvmfPkg/XenBusDxe/X64/InterlockedCompareExchange16.asm @@ -0,0 +1,41 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006, Intel Corporation. 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/OvmfPkg/XenBusDxe/X64/InterlockedCompareExchange16.c b/OvmfPkg/XenBusDxe/X64/InterlockedCompareExchange16.c new file mode 100644 index 0000000..64962ba --- /dev/null +++ b/OvmfPkg/XenBusDxe/X64/InterlockedCompareExchange16.c @@ -0,0 +1,41 @@ +// Took from BaseSynchronizationLib, and replaced 32 by 16 +/** + 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 +InterlockedCompareExchange16 ( + IN OUT volatile UINT16 *Value, + IN UINT16 CompareValue, + IN UINT16 ExchangeValue + ) +{ + __asm__ __volatile__ ( + "lock \n\t" + "cmpxchgw %3, %1 " + : "=a" (CompareValue), // %0 + "=m" (*Value) // %1 + : "a" (CompareValue), // %2 + "r" (ExchangeValue), // %3 + "m" (*Value) + : "memory", + "cc" + ); + + return CompareValue; +} diff --git a/OvmfPkg/XenBusDxe/XenBusDxe.inf b/OvmfPkg/XenBusDxe/XenBusDxe.inf index aed2359..612c3db 100644 --- a/OvmfPkg/XenBusDxe/XenBusDxe.inf +++ b/OvmfPkg/XenBusDxe/XenBusDxe.inf @@ -33,10 +33,14 @@ ComponentName.h XenHypercall.c XenHypercall.h + InterlockedCompareExchange16.h [Sources.X64] X64/hypercall.S X64/hypercall.asm + X64/InterlockedCompareExchange16.c | GCC + X64/InterlockedCompareExchange16.asm | INTEL + InterlockedCompareExchange16Intel.c | INTEL [LibraryClasses] UefiDriverEntryPoint -- Anthony PERARD ------------------------------------------------------------------------------ Slashdot TV. Video for Nerds. Stuff that matters. http://tv.slashdot.org/ _______________________________________________ edk2-devel mailing list edk2-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/edk2-devel