From patchwork Thu Feb 12 11:19:06 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 44617 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-lb0-f197.google.com (mail-lb0-f197.google.com [209.85.217.197]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 04E8E2151D for ; Thu, 12 Feb 2015 11:21:00 +0000 (UTC) Received: by mail-lb0-f197.google.com with SMTP id w7sf6109721lbi.0 for ; Thu, 12 Feb 2015 03:20:59 -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:subject:precedence:reply-to:list-id:list-unsubscribe :list-archive:list-post:list-help:list-subscribe:mime-version :content-type:content-transfer-encoding:errors-to:x-original-sender :x-original-authentication-results:mailing-list; bh=1wE/q5ANsTMWgvqq/Rwv6aGfNMFOGCAKidj8XigI6pk=; b=gOiqXmS27La8F8YiUz2pebMB3veAHy3rZjoau2eJoMRlwduhLdLDobMWlXKd7QeYb8 db0Ap7beaHNKRk2yC8YoeOvmKIXnD+SCiNdezmK0EV+ercg+Dl3AXXaT+XBZQDdOS/UQ gVbjeqORVZUlD/GUYw4K8l3eW0t9EnwXmE3UY1vanx6QFU3MU8dm/6n7P8tW0lMSuUuP 1kQtbSz4sIXL+g0Jtlz+tgQBrhBJRnkXXIrurMPb+Feh52r/X0HwpqlvCxN5ro+SHvkC x56YYXxuhSgJXYOnFQb8fASIJe41q4gNGHdM2B/66EbxpiHXwVQvW+KZgCqX3IgAIn38 BY+w== X-Gm-Message-State: ALoCoQkXtJHleV7Gmmw5Xh69HiM9scj6KaVwekJxe6Km4UGq0Nx8eLC0LltQZpsl29pInBRJpK30 X-Received: by 10.112.143.167 with SMTP id sf7mr485970lbb.0.1423740058987; Thu, 12 Feb 2015 03:20:58 -0800 (PST) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.7.226 with SMTP id m2ls180644laa.82.gmail; Thu, 12 Feb 2015 03:20:58 -0800 (PST) X-Received: by 10.152.37.194 with SMTP id a2mr2659089lak.105.1423740058832; Thu, 12 Feb 2015 03:20:58 -0800 (PST) Received: from mail-lb0-f181.google.com (mail-lb0-f181.google.com. [209.85.217.181]) by mx.google.com with ESMTPS id m1si2733658lam.44.2015.02.12.03.20.58 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 12 Feb 2015 03:20:58 -0800 (PST) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.181 as permitted sender) client-ip=209.85.217.181; Received: by mail-lb0-f181.google.com with SMTP id b6so8817467lbj.12 for ; Thu, 12 Feb 2015 03:20:58 -0800 (PST) X-Received: by 10.152.116.18 with SMTP id js18mr1994343lab.106.1423740058599; Thu, 12 Feb 2015 03:20:58 -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 h5csp378532lbj; Thu, 12 Feb 2015 03:20:57 -0800 (PST) X-Received: by 10.43.66.9 with SMTP id xo9mr7893892icb.67.1423740055612; Thu, 12 Feb 2015 03:20:55 -0800 (PST) Received: from lists.sourceforge.net (lists.sourceforge.net. [216.34.181.88]) by mx.google.com with ESMTPS id i19si2763047iod.70.2015.02.12.03.20.54 (version=TLSv1 cipher=RC4-SHA bits=128/128); Thu, 12 Feb 2015 03:20:55 -0800 (PST) Received-SPF: pass (google.com: domain of edk2-devel-bounces@lists.sourceforge.net designates 216.34.181.88 as permitted sender) client-ip=216.34.181.88; Received: from localhost ([127.0.0.1] helo=sfs-ml-4.v29.ch3.sourceforge.com) by sfs-ml-4.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1YLrp8-0002TR-6j; Thu, 12 Feb 2015 11:20:46 +0000 Received: from sog-mx-1.v43.ch3.sourceforge.com ([172.29.43.191] helo=mx.sourceforge.net) by sfs-ml-4.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1YLrp7-0002TH-MH for edk2-devel@lists.sourceforge.net; Thu, 12 Feb 2015 11:20:45 +0000 Received-SPF: pass (sog-mx-1.v43.ch3.sourceforge.com: domain of linaro.org designates 209.85.192.170 as permitted sender) client-ip=209.85.192.170; envelope-from=ard.biesheuvel@linaro.org; helo=mail-pd0-f170.google.com; Received: from mail-pd0-f170.google.com ([209.85.192.170]) by sog-mx-1.v43.ch3.sourceforge.com with esmtps (TLSv1:RC4-SHA:128) (Exim 4.76) id 1YLrp5-0006rw-4N for edk2-devel@lists.sourceforge.net; Thu, 12 Feb 2015 11:20:45 +0000 Received: by pdev10 with SMTP id v10so11319468pde.10 for ; Thu, 12 Feb 2015 03:20:37 -0800 (PST) X-Received: by 10.70.41.134 with SMTP id f6mr5610305pdl.122.1423740037479; Thu, 12 Feb 2015 03:20:37 -0800 (PST) Received: from ards-macbook-pro.local ([210.177.145.249]) by mx.google.com with ESMTPSA id n4sm3554887pdl.12.2015.02.12.03.20.33 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 12 Feb 2015 03:20:36 -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, feng.tian@intel.com Date: Thu, 12 Feb 2015 19:19:06 +0800 Message-Id: <1423739961-5945-15-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org> References: <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org> X-Spam-Score: -1.5 (-) X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -1.5 SPF_CHECK_PASS SPF reports sender host as permitted sender for sender-domain -0.0 SPF_PASS SPF: sender matches SPF record X-Headers-End: 1YLrp5-0006rw-4N Subject: [edk2] [PATCH v4 14/29] MdePkg/BaseSynchronizationLib: implement 16-bit compare-exchange X-BeenThere: edk2-devel@lists.sourceforge.net X-Mailman-Version: 2.1.9 Precedence: list Reply-To: edk2-devel@lists.sourceforge.net List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , MIME-Version: 1.0 Errors-To: edk2-devel-bounces@lists.sourceforge.net 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.217.181 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 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 Signed-off-by: Ard Biesheuvel --- 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.
+; 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); +} +