From patchwork Tue Feb 24 18:02:55 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 44972 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wi0-f198.google.com (mail-wi0-f198.google.com [209.85.212.198]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 9C51F2029F for ; Tue, 24 Feb 2015 18:06:14 +0000 (UTC) Received: by mail-wi0-f198.google.com with SMTP id h11sf16310367wiw.1 for ; Tue, 24 Feb 2015 10:06:13 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:date:message-id:in-reply-to :references:cc:subject:precedence:list-id:list-unsubscribe:list-post :list-help:list-subscribe:mime-version:content-type :content-transfer-encoding:sender:errors-to:x-original-sender :x-original-authentication-results:mailing-list:list-archive; bh=HRLBSwMWTfZY4tR07zO8Nj6uluOo7MlCffefhoxllkA=; b=OjWy5Abxu+Gp/HQAzihgm8OKpQBzqbL2njgc4j6HqLv4+bGatUDrTzPchqRkq4TH0d eKmmikEabtfUAhiwAi/dZqN338pHXK84l9sNdMPrIjIkCQ5qZlGaI8JZ0DV0NurvVnlr fZuPv9U+bveTRd7wIHLfWDASoo6sGeh1HTbRymD0hihzbrvczWl9P6sXDrKeWNeYhFzm tWdpB64um624lSOFcuciPBX6slkASr8R4oGioHmcDLGiNCD7YMqRDRxRi0uqKwyfmAwq w16r6fJ5kMHY9KTj1S3dkza7tw79rl4Nrhv+6wTaws5d1i5mDO/mVOrKBhKt+V0WBm9h htcg== X-Gm-Message-State: ALoCoQmeHAnKxrTZ9+b1vFztQNfzw+yDu56/HEyzaI9vwGEcDY+Wjlh46DzufCjgq0G0AOowzEFU X-Received: by 10.181.29.66 with SMTP id ju2mr2304315wid.1.1424801173919; Tue, 24 Feb 2015 10:06:13 -0800 (PST) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.242.132 with SMTP id wq4ls48362lac.30.gmail; Tue, 24 Feb 2015 10:06:13 -0800 (PST) X-Received: by 10.152.22.129 with SMTP id d1mr5113725laf.22.1424801173759; Tue, 24 Feb 2015 10:06:13 -0800 (PST) Received: from mail-la0-f51.google.com (mail-la0-f51.google.com. [209.85.215.51]) by mx.google.com with ESMTPS id pj4si26154409lbb.118.2015.02.24.10.06.13 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 24 Feb 2015 10:06:13 -0800 (PST) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.51 as permitted sender) client-ip=209.85.215.51; Received: by lams18 with SMTP id s18so27534718lam.11 for ; Tue, 24 Feb 2015 10:06:13 -0800 (PST) X-Received: by 10.112.64.193 with SMTP id q1mr15487461lbs.88.1424801173647; Tue, 24 Feb 2015 10:06:13 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.35.133 with SMTP id h5csp2079038lbj; Tue, 24 Feb 2015 10:06:11 -0800 (PST) X-Received: by 10.52.11.73 with SMTP id o9mr4713383vdb.70.1424801169339; Tue, 24 Feb 2015 10:06:09 -0800 (PST) Received: from lists.xen.org (lists.xen.org. [50.57.142.19]) by mx.google.com with ESMTPS id hf2si4978492vdb.41.2015.02.24.10.06.08 (version=TLSv1 cipher=RC4-SHA bits=128/128); Tue, 24 Feb 2015 10:06:09 -0800 (PST) Received-SPF: none (google.com: xen-devel-bounces@lists.xen.org does not designate permitted sender hosts) client-ip=50.57.142.19; Received: from localhost ([127.0.0.1] helo=lists.xen.org) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1YQJqx-0002NP-0Y; Tue, 24 Feb 2015 18:05:03 +0000 Received: from mail6.bemta14.messagelabs.com ([193.109.254.103]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1YQJqu-0002KT-LJ for xen-devel@lists.xen.org; Tue, 24 Feb 2015 18:05:01 +0000 Received: from [193.109.254.147] by server-2.bemta-14.messagelabs.com id 28/8B-31919-C4DBCE45; Tue, 24 Feb 2015 18:05:00 +0000 X-Env-Sender: ard.biesheuvel@linaro.org X-Msg-Ref: server-6.tower-27.messagelabs.com!1424801098!12545957!1 X-Originating-IP: [74.125.82.178] X-SpamReason: No, hits=0.5 required=7.0 tests=BODY_RANDOM_LONG X-StarScan-Received: X-StarScan-Version: 6.13.4; banners=-,-,- X-VirusChecked: Checked Received: (qmail 29992 invoked from network); 24 Feb 2015 18:04:58 -0000 Received: from mail-we0-f178.google.com (HELO mail-we0-f178.google.com) (74.125.82.178) by server-6.tower-27.messagelabs.com with RC4-SHA encrypted SMTP; 24 Feb 2015 18:04:58 -0000 Received: by wevk48 with SMTP id k48so26901041wev.3 for ; Tue, 24 Feb 2015 10:04:58 -0800 (PST) X-Received: by 10.180.21.162 with SMTP id w2mr32813259wie.42.1424801097882; Tue, 24 Feb 2015 10:04:57 -0800 (PST) Received: from ards-macbook-pro.lan (bl11-65-113.dsl.telepac.pt. [85.244.65.113]) by mx.google.com with ESMTPSA id w8sm12792521wja.4.2015.02.24.10.04.52 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 24 Feb 2015 10:04:56 -0800 (PST) From: Ard Biesheuvel To: edk2-devel@lists.sourceforge.net, olivier.martin@arm.com, lersek@redhat.com, roy.franz@linaro.org, leif.lindholm@linaro.org, stefano.stabellini@eu.citrix.com, ian.campbell@citrix.com, anthony.perard@citrix.com, xen-devel@lists.xen.org, julien.grall@linaro.org, jordan.l.justen@intel.com, michael.d.kinney@intel.com Date: Tue, 24 Feb 2015 18:02:55 +0000 Message-Id: <1424800990-15777-15-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1424800990-15777-1-git-send-email-ard.biesheuvel@linaro.org> References: <1424800990-15777-1-git-send-email-ard.biesheuvel@linaro.org> Cc: wei.liu2@citrix.com, Ard Biesheuvel Subject: [Xen-devel] [PATCH v5 14/29] MdePkg/BaseSynchronizationLib: Add InterlockedCompareExchange16 X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: List-Unsubscribe: , List-Post: , List-Help: , List-Subscribe: , MIME-Version: 1.0 Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: ard.biesheuvel@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.51 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Archive: 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 Acked-by: Jordan Justen Signed-off-by: Ard Biesheuvel --- MdePkg/Include/Library/SynchronizationLib.h | 26 +++++++++++ .../AArch64/Synchronization.S | 44 ++++++++++++++++++ .../BaseSynchronizationLib/Arm/Synchronization.S | 44 ++++++++++++++++++ .../BaseSynchronizationLib/Arm/Synchronization.asm | 44 ++++++++++++++++++ .../BaseSynchronizationLib.inf | 5 ++ .../BaseSynchronizationLibInternals.h | 26 +++++++++++ .../BaseSynchronizationLib/Ebc/Synchronization.c | 31 +++++++++++++ .../BaseSynchronizationLib/Ia32/GccInline.c | 42 +++++++++++++++++ .../Ia32/InterlockedCompareExchange16.asm | 46 ++++++++++++++++++ .../Ia32/InterlockedCompareExchange16.c | 51 ++++++++++++++++++++ .../Ipf/InterlockedCompareExchange16.s | 30 ++++++++++++ .../BaseSynchronizationLib/Synchronization.c | 31 +++++++++++++ .../BaseSynchronizationLib/SynchronizationGcc.c | 31 +++++++++++++ .../BaseSynchronizationLib/SynchronizationMsc.c | 31 +++++++++++++ .../Library/BaseSynchronizationLib/X64/GccInline.c | 44 ++++++++++++++++++ .../X64/InterlockedCompareExchange16.asm | 42 +++++++++++++++++ .../X64/InterlockedCompareExchange16.c | 54 ++++++++++++++++++++++ 17 files changed, 622 insertions(+) create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s create mode 100644 MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm create mode 100644 MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c 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.
+; Copyright (c) 2015, Linaro Ltd. 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 + +;------------------------------------------------------------------------------ +; 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.
+ Copyright (c) 2015, Linaro Ltd. 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. + +**/ + + + + +/** + 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.
+/// Copyright (c) 2015, Linaro Ltd. 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.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.
+; Copyright (c) 2015, Linaro Ltd. 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/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.
+ Copyright (c) 2015, Linaro Ltd. 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. + +**/ + +/** + 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); +} +