diff --git a/OvmfPkg/XenBusDxe/Ia32/InterlockedCompareExchange16.S b/OvmfPkg/XenBusDxe/Ia32/InterlockedCompareExchange16.S new file mode 100644 index 0000000000..5306448515 --- /dev/null +++ b/OvmfPkg/XenBusDxe/Ia32/InterlockedCompareExchange16.S @@ -0,0 +1,15 @@ +# UINT16 +# EFIAPI +# InternalSyncCompareExchange16 ( +# IN volatile UINT16 *Value, +# IN UINT16 CompareValue, +# IN UINT16 ExchangeValue +# ); +ASM_GLOBAL ASM_PFX(InternalSyncCompareExchange16) +ASM_PFX(InternalSyncCompareExchange16): + mov 4(%esp), %ecx + mov 8(%esp), %eax + mov 12(%esp), %edx + lock + cmpxchgw %dx, (%ecx) + ret diff --git a/OvmfPkg/XenBusDxe/Ia32/InterlockedCompareExchange16.asm b/OvmfPkg/XenBusDxe/Ia32/InterlockedCompareExchange16.asm new file mode 100644 index 0000000000..adcfbd080b --- /dev/null +++ b/OvmfPkg/XenBusDxe/Ia32/InterlockedCompareExchange16.asm @@ -0,0 +1,45 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; InterlockedCompareExchange16.Asm +; +; Abstract: +; +; InterlockedCompareExchange16 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .486 + .model flat,C + .code + +;------------------------------------------------------------------------------ +; UINT32 +; 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/OvmfPkg/XenBusDxe/InterlockedCompareExchange16.c b/OvmfPkg/XenBusDxe/InterlockedCompareExchange16.c new file mode 100644 index 0000000000..2b0fadd88d --- /dev/null +++ b/OvmfPkg/XenBusDxe/InterlockedCompareExchange16.c @@ -0,0 +1,33 @@ +#include +#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/InterlockedCompareExchange16.h b/OvmfPkg/XenBusDxe/InterlockedCompareExchange16.h new file mode 100644 index 0000000000..fd3f15b1c8 --- /dev/null +++ b/OvmfPkg/XenBusDxe/InterlockedCompareExchange16.h @@ -0,0 +1,38 @@ +/** + Assembly implementation of InterlockedCompareExchange16. + + Look at the documentation of InterlockedCompareExchange16. +**/ +UINT16 +EFIAPI +InternalSyncCompareExchange16 ( + IN volatile UINT16 *Value, + IN UINT16 CompareValue, + IN UINT16 ExchangeValue + ); + +/** + 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 + ); diff --git a/OvmfPkg/XenBusDxe/X64/InterlockedCompareExchange16.S b/OvmfPkg/XenBusDxe/X64/InterlockedCompareExchange16.S new file mode 100644 index 0000000000..23e08f3f6e --- /dev/null +++ b/OvmfPkg/XenBusDxe/X64/InterlockedCompareExchange16.S @@ -0,0 +1,13 @@ +# UINT16 +# EFIAPI +# InternalSyncCompareExchange16 ( +# IN volatile UINT16 *Value, +# IN UINT16 CompareValue, +# IN UINT16 ExchangeValue +# ); +ASM_GLOBAL ASM_PFX(InternalSyncCompareExchange16) +ASM_PFX(InternalSyncCompareExchange16): + mov %edx, %eax + lock + cmpxchgw %r8w, (%rcx) + ret diff --git a/OvmfPkg/XenBusDxe/X64/InterlockedCompareExchange16.asm b/OvmfPkg/XenBusDxe/X64/InterlockedCompareExchange16.asm new file mode 100644 index 0000000000..b23e421abc --- /dev/null +++ b/OvmfPkg/XenBusDxe/X64/InterlockedCompareExchange16.asm @@ -0,0 +1,41 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; InterlockedCompareExchange16.Asm +; +; Abstract: +; +; InterlockedCompareExchange16 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINT16 +; EFIAPI +; InterlockedCompareExchange16 ( +; IN UINT16 *Value, +; IN UINT16 CompareValue, +; IN UINT16 ExchangeValue +; ); +;------------------------------------------------------------------------------ +InternalSyncCompareExchange16 PROC + mov eax, edx + lock cmpxchg [rcx], r8w + ret +InternalSyncCompareExchange16 ENDP + + END diff --git a/OvmfPkg/XenBusDxe/XenBusDxe.inf b/OvmfPkg/XenBusDxe/XenBusDxe.inf index add85213c6..4e92a204f2 100644 --- a/OvmfPkg/XenBusDxe/XenBusDxe.inf +++ b/OvmfPkg/XenBusDxe/XenBusDxe.inf @@ -36,14 +36,20 @@ ComponentName.h XenHypercall.c XenHypercall.h + InterlockedCompareExchange16.c + InterlockedCompareExchange16.h [Sources.IA32] Ia32/hypercall.S Ia32/hypercall.asm + Ia32/InterlockedCompareExchange16.S + Ia32/InterlockedCompareExchange16.asm [Sources.X64] X64/hypercall.S X64/hypercall.asm + X64/InterlockedCompareExchange16.S + X64/InterlockedCompareExchange16.asm [LibraryClasses] UefiDriverEntryPoint