From patchwork Tue Feb 24 18:02:54 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 44969 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wi0-f199.google.com (mail-wi0-f199.google.com [209.85.212.199]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 06D4A2029F for ; Tue, 24 Feb 2015 18:06:02 +0000 (UTC) Received: by mail-wi0-f199.google.com with SMTP id bs8sf16311264wib.2 for ; Tue, 24 Feb 2015 10:06:01 -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=sqVNZdAARxRY/mCtGGQqKgiha4aFPN3iVF+HFKHOLgM=; b=RDvHPMHCPaPdBwAv47TjQQicmYVsggVGjDpXoMelxh/EpfHJSpQa5ho16wbZ8S/6ux puBqlOHvZgUfS/QC15NyK9F8trDgcBYBN81GCoZXxnN6BAlchlKLUBmzlcGNpI3y5RT7 D5yqjXFxaOIxwP9b6sWjHqJ06XYoRHIVGTI8MKCXd6QhGjh7lvM99Pr01ME/ZHXjH2LT jjSW2bta4664bw8/lxwPgJl1UiqJphDd+QqYK6sPac1juY3k9c26HCRbhdd0q5sOgb7V P4r+48MPBVI/FTds+xjrKzYotOnxglmI7YDb61E/yPzEQefrW25PyB+o37XkwjS3chi0 2kqQ== X-Gm-Message-State: ALoCoQmp1tFdw7e8qetJKOast2Idkps8xoqEloqFQwl7F6Nw7ulAlQRQDCFMXhgX1GTA9CkiGwu6 X-Received: by 10.112.168.104 with SMTP id zv8mr2310189lbb.10.1424801161302; Tue, 24 Feb 2015 10:06:01 -0800 (PST) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.205.99 with SMTP id lf3ls294665lac.4.gmail; Tue, 24 Feb 2015 10:06:01 -0800 (PST) X-Received: by 10.152.170.199 with SMTP id ao7mr1151156lac.27.1424801161132; Tue, 24 Feb 2015 10:06:01 -0800 (PST) Received: from mail-lb0-f178.google.com (mail-lb0-f178.google.com. [209.85.217.178]) by mx.google.com with ESMTPS id w3si26552654lbm.144.2015.02.24.10.06.00 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 24 Feb 2015 10:06:00 -0800 (PST) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.178 as permitted sender) client-ip=209.85.217.178; Received: by lbiw7 with SMTP id w7so26657817lbi.10 for ; Tue, 24 Feb 2015 10:06:00 -0800 (PST) X-Received: by 10.112.56.139 with SMTP id a11mr15419731lbq.36.1424801160796; Tue, 24 Feb 2015 10:06:00 -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 h5csp2078902lbj; Tue, 24 Feb 2015 10:05:59 -0800 (PST) X-Received: by 10.52.12.138 with SMTP id y10mr17046682vdb.35.1424801156980; Tue, 24 Feb 2015 10:05:56 -0800 (PST) Received: from lists.xen.org (lists.xen.org. [50.57.142.19]) by mx.google.com with ESMTPS id uk2si13033853vcb.68.2015.02.24.10.05.56 (version=TLSv1 cipher=RC4-SHA bits=128/128); Tue, 24 Feb 2015 10:05:56 -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 1YQJqq-0002Fi-CI; Tue, 24 Feb 2015 18:04:56 +0000 Received: from mail6.bemta4.messagelabs.com ([85.158.143.247]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1YQJqp-0002DN-0Y for xen-devel@lists.xen.org; Tue, 24 Feb 2015 18:04:55 +0000 Received: from [85.158.143.35] by server-2.bemta-4.messagelabs.com id E1/50-02830-64DBCE45; Tue, 24 Feb 2015 18:04:54 +0000 X-Env-Sender: ard.biesheuvel@linaro.org X-Msg-Ref: server-11.tower-21.messagelabs.com!1424801092!12843840!1 X-Originating-IP: [74.125.82.44] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 6.13.4; banners=-,-,- X-VirusChecked: Checked Received: (qmail 14490 invoked from network); 24 Feb 2015 18:04:52 -0000 Received: from mail-wg0-f44.google.com (HELO mail-wg0-f44.google.com) (74.125.82.44) by server-11.tower-21.messagelabs.com with RC4-SHA encrypted SMTP; 24 Feb 2015 18:04:52 -0000 Received: by wghl18 with SMTP id l18so6997780wgh.8 for ; Tue, 24 Feb 2015 10:04:52 -0800 (PST) X-Received: by 10.194.62.52 with SMTP id v20mr35009656wjr.137.1424801092701; Tue, 24 Feb 2015 10:04:52 -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.48 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 24 Feb 2015 10:04:50 -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:54 +0000 Message-Id: <1424800990-15777-14-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 13/29] MdePkg/BaseSynchronizationLib: Added proper support for ARM architecture 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.217.178 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 following synchronization primitives for AArch64 (GCC) and ARM (GCC & RVCT): InternalSyncCompareExchange32 InternalSyncCompareExchange64 InternalSyncIncrement InternalSyncDecrement Note: these functions are implemented using the exclusive monitor, which implies that they can only be used after the caches (and hence the MMU) have been enabled. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Olivier Martin Signed-off-by: Ard Biesheuvel --- .../AArch64/Synchronization.S | 159 +++++++++++++++++++ .../AArch64/Synchronization.c | 115 -------------- .../BaseSynchronizationLib/Arm/Synchronization.S | 167 ++++++++++++++++++++ .../BaseSynchronizationLib/Arm/Synchronization.asm | 168 +++++++++++++++++++++ .../BaseSynchronizationLib/Arm/Synchronization.c | 115 -------------- .../BaseSynchronizationLib.inf | 5 +- 6 files changed, 497 insertions(+), 232 deletions(-) create mode 100644 MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S delete mode 100644 MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.c create mode 100644 MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S create mode 100644 MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm delete mode 100644 MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.c mode change 100644 => 100755 MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf diff --git a/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S b/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S new file mode 100644 index 000000000000..601b00495f26 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S @@ -0,0 +1,159 @@ +// Implementation of synchronization functions for ARM architecture (AArch64) +// +// 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 +// 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. +// +// + +.text +.align 3 + +GCC_ASM_EXPORT(InternalSyncCompareExchange32) +GCC_ASM_EXPORT(InternalSyncCompareExchange64) +GCC_ASM_EXPORT(InternalSyncIncrement) +GCC_ASM_EXPORT(InternalSyncDecrement) + +/** + Performs an atomic compare exchange operation on a 32-bit unsigned integer. + + Performs an atomic compare exchange operation on the 32-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 32-bit value for the compare exchange + operation. + @param CompareValue 32-bit value used in compare operation. + @param ExchangeValue 32-bit value used in exchange operation. + + @return The original *Value before exchange. + +**/ +//UINT32 +//EFIAPI +//InternalSyncCompareExchange32 ( +// IN volatile UINT32 *Value, +// IN UINT32 CompareValue, +// IN UINT32 ExchangeValue +// ) +ASM_PFX(InternalSyncCompareExchange32): + dmb sy + +InternalSyncCompareExchange32Again: + ldxr w3, [x0] + cmp w3, w1 + bne InternalSyncCompareExchange32Fail + +InternalSyncCompareExchange32Exchange: + stxr w4, w2, [x0] + cbnz w4, InternalSyncCompareExchange32Again + +InternalSyncCompareExchange32Fail: + dmb sy + mov w0, w3 + ret + +/** + Performs an atomic compare exchange operation on a 64-bit unsigned integer. + + Performs an atomic compare exchange operation on the 64-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 64-bit value for the compare exchange + operation. + @param CompareValue 64-bit value used in compare operation. + @param ExchangeValue 64-bit value used in exchange operation. + + @return The original *Value before exchange. + +**/ +//UINT64 +//EFIAPI +//InternalSyncCompareExchange64 ( +// IN volatile UINT64 *Value, +// IN UINT64 CompareValue, +// IN UINT64 ExchangeValue +// ) +ASM_PFX(InternalSyncCompareExchange64): + dmb sy + +InternalSyncCompareExchange64Again: + ldxr x3, [x0] + cmp x3, x1 + bne InternalSyncCompareExchange64Fail + +InternalSyncCompareExchange64Exchange: + stxr w4, x2, [x0] + cbnz w4, InternalSyncCompareExchange64Again + +InternalSyncCompareExchange64Fail: + dmb sy + mov x0, x3 + ret + +/** + Performs an atomic increment of an 32-bit unsigned integer. + + Performs an atomic increment of the 32-bit unsigned integer specified by + Value and returns the incremented value. The increment operation must be + performed using MP safe mechanisms. The state of the return value is not + guaranteed to be MP safe. + + @param Value A pointer to the 32-bit value to increment. + + @return The incremented value. + +**/ +//UINT32 +//EFIAPI +//InternalSyncIncrement ( +// IN volatile UINT32 *Value +// ) +ASM_PFX(InternalSyncIncrement): + dmb sy +TryInternalSyncIncrement: + ldxr w1, [x0] + add w1, w1, #1 + stxr w2, w1, [x0] + cbnz w2, TryInternalSyncIncrement + dmb sy + ret + +/** + Performs an atomic decrement of an 32-bit unsigned integer. + + Performs an atomic decrement of the 32-bit unsigned integer specified by + Value and returns the decrement value. The decrement operation must be + performed using MP safe mechanisms. The state of the return value is not + guaranteed to be MP safe. + + @param Value A pointer to the 32-bit value to decrement. + + @return The decrement value. + +**/ +//UINT32 +//EFIAPI +//InternalSyncDecrement ( +// IN volatile UINT32 *Value +// ) +ASM_PFX(InternalSyncDecrement): + dmb sy +TryInternalSyncDecrement: + ldxr w1, [x0] + sub w1, w1, #1 + stxr w2, w1, [x0] + cbnz w2, TryInternalSyncDecrement + dmb sy + ret diff --git a/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.c b/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.c deleted file mode 100644 index 2e619ccf873f..000000000000 --- a/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.c +++ /dev/null @@ -1,115 +0,0 @@ -/** @file - Implementation of synchronization functions. Still needs to be ported - - Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
- Portions copyright (c) 2008 - 2009, Apple Inc. 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 32-bit unsigned integer. - - Performs an atomic compare exchange operation on the 32-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 32-bit value for the compare exchange - operation. - @param CompareValue 32-bit value used in compare operation. - @param ExchangeValue 32-bit value used in exchange operation. - - @return The original *Value before exchange. - -**/ -UINT32 -EFIAPI -InternalSyncCompareExchange32 ( - IN volatile UINT32 *Value, - IN UINT32 CompareValue, - IN UINT32 ExchangeValue - ) -{ - return *Value != CompareValue ? *Value : - ((*Value = ExchangeValue), CompareValue); -} - -/** - Performs an atomic compare exchange operation on a 64-bit unsigned integer. - - Performs an atomic compare exchange operation on the 64-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 64-bit value for the compare exchange - operation. - @param CompareValue 64-bit value used in compare operation. - @param ExchangeValue 64-bit value used in exchange operation. - - @return The original *Value before exchange. - -**/ -UINT64 -EFIAPI -InternalSyncCompareExchange64 ( - IN volatile UINT64 *Value, - IN UINT64 CompareValue, - IN UINT64 ExchangeValue - ) -{ - return *Value != CompareValue ? *Value : - ((*Value = ExchangeValue), CompareValue); -} - -/** - Performs an atomic increment of an 32-bit unsigned integer. - - Performs an atomic increment of the 32-bit unsigned integer specified by - Value and returns the incremented value. The increment operation must be - performed using MP safe mechanisms. The state of the return value is not - guaranteed to be MP safe. - - @param Value A pointer to the 32-bit value to increment. - - @return The incremented value. - -**/ -UINT32 -EFIAPI -InternalSyncIncrement ( - IN volatile UINT32 *Value - ) -{ - return ++*Value; -} - -/** - Performs an atomic decrement of an 32-bit unsigned integer. - - Performs an atomic decrement of the 32-bit unsigned integer specified by - Value and returns the decrement value. The decrement operation must be - performed using MP safe mechanisms. The state of the return value is not - guaranteed to be MP safe. - - @param Value A pointer to the 32-bit value to decrement. - - @return The decrement value. - -**/ -UINT32 -EFIAPI -InternalSyncDecrement ( - IN volatile UINT32 *Value - ) -{ - return --*Value; -} diff --git a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S new file mode 100644 index 000000000000..0128f8f016bd --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S @@ -0,0 +1,167 @@ +// Implementation of synchronization functions for ARM architecture +// +// Copyright (c) 2012-2015, ARM Limited. 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. +// +// + +.text +.align 3 + +GCC_ASM_EXPORT(InternalSyncCompareExchange32) +GCC_ASM_EXPORT(InternalSyncCompareExchange64) +GCC_ASM_EXPORT(InternalSyncIncrement) +GCC_ASM_EXPORT(InternalSyncDecrement) + +/** + Performs an atomic compare exchange operation on a 32-bit unsigned integer. + + Performs an atomic compare exchange operation on the 32-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 32-bit value for the compare exchange + operation. + @param CompareValue 32-bit value used in compare operation. + @param ExchangeValue 32-bit value used in exchange operation. + + @return The original *Value before exchange. + +**/ +//UINT32 +//EFIAPI +//InternalSyncCompareExchange32 ( +// IN volatile UINT32 *Value, +// IN UINT32 CompareValue, +// IN UINT32 ExchangeValue +// ) +ASM_PFX(InternalSyncCompareExchange32): + dmb + +InternalSyncCompareExchange32Again: + ldrex r3, [r0] + cmp r3, r1 + bne InternalSyncCompareExchange32Fail + +InternalSyncCompareExchange32Exchange: + strex ip, r2, [r0] + cmp ip, #0 + bne InternalSyncCompareExchange32Again + +InternalSyncCompareExchange32Fail: + dmb + mov r0, r3 + bx lr + +/** + Performs an atomic compare exchange operation on a 64-bit unsigned integer. + + Performs an atomic compare exchange operation on the 64-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 64-bit value for the compare exchange + operation. + @param CompareValue 64-bit value used in compare operation. + @param ExchangeValue 64-bit value used in exchange operation. + + @return The original *Value before exchange. + +**/ +//UINT64 +//EFIAPI +//InternalSyncCompareExchange64 ( +// IN volatile UINT64 *Value, // r0 +// IN UINT64 CompareValue, // r2-r3 +// IN UINT64 ExchangeValue // stack +// ) +ASM_PFX(InternalSyncCompareExchange64): + push { r4-r7 } + ldrd r4, r5, [sp, #16] + dmb + +InternalSyncCompareExchange64Again: + ldrexd r6, r7, [r0] + cmp r6, r2 + cmpeq r7, r3 + bne InternalSyncCompareExchange64Fail + +InternalSyncCompareExchange64Exchange: + strexd ip, r4, r5, [r0] + cmp ip, #0 + bne InternalSyncCompareExchange64Again + +InternalSyncCompareExchange64Fail: + dmb + mov r0, r6 + mov r1, r7 + pop { r4-r7 } + bx lr + +/** + Performs an atomic increment of an 32-bit unsigned integer. + + Performs an atomic increment of the 32-bit unsigned integer specified by + Value and returns the incremented value. The increment operation must be + performed using MP safe mechanisms. The state of the return value is not + guaranteed to be MP safe. + + @param Value A pointer to the 32-bit value to increment. + + @return The incremented value. + +**/ +//UINT32 +//EFIAPI +//InternalSyncIncrement ( +// IN volatile UINT32 *Value +// ) +ASM_PFX(InternalSyncIncrement): + dmb +TryInternalSyncIncrement: + ldrex r1, [r0] + add r1, r1, #1 + strex r2, r1, [r0] + cmp r2, #0 + bne TryInternalSyncIncrement + dmb + bx lr + +/** + Performs an atomic decrement of an 32-bit unsigned integer. + + Performs an atomic decrement of the 32-bit unsigned integer specified by + Value and returns the decrement value. The decrement operation must be + performed using MP safe mechanisms. The state of the return value is not + guaranteed to be MP safe. + + @param Value A pointer to the 32-bit value to decrement. + + @return The decrement value. + +**/ +//UINT32 +//EFIAPI +//InternalSyncDecrement ( +// IN volatile UINT32 *Value +// ) +ASM_PFX(InternalSyncDecrement): + dmb +TryInternalSyncDecrement: + ldrex r1, [r0] + sub r1, r1, #1 + strex r2, r1, [r0] + cmp r2, #0 + bne TryInternalSyncDecrement + dmb + bx lr diff --git a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm new file mode 100644 index 000000000000..f9f80737774a --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm @@ -0,0 +1,168 @@ +// Implementation of synchronization functions for ARM architecture +// +// Copyright (c) 2012-2015, ARM Limited. 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. +// +// + + EXPORT InternalSyncCompareExchange32 + EXPORT InternalSyncCompareExchange64 + EXPORT InternalSyncIncrement + EXPORT InternalSyncDecrement + + AREA ArmSynchronization, CODE, READONLY + +/** + Performs an atomic compare exchange operation on a 32-bit unsigned integer. + + Performs an atomic compare exchange operation on the 32-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 32-bit value for the compare exchange + operation. + @param CompareValue 32-bit value used in compare operation. + @param ExchangeValue 32-bit value used in exchange operation. + + @return The original *Value before exchange. + +**/ +//UINT32 +//EFIAPI +//InternalSyncCompareExchange32 ( +// IN volatile UINT32 *Value, +// IN UINT32 CompareValue, +// IN UINT32 ExchangeValue +// ) +InternalSyncCompareExchange32 + dmb + +InternalSyncCompareExchange32Again + ldrex r3, [r0] + cmp r3, r1 + bne InternalSyncCompareExchange32Fail + +InternalSyncCompareExchange32Exchange + strex ip, r2, [r0] + cmp ip, #0 + bne InternalSyncCompareExchange32Again + +InternalSyncCompareExchange32Fail + dmb + mov r0, r3 + bx lr + +/** + Performs an atomic compare exchange operation on a 64-bit unsigned integer. + + Performs an atomic compare exchange operation on the 64-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 64-bit value for the compare exchange + operation. + @param CompareValue 64-bit value used in compare operation. + @param ExchangeValue 64-bit value used in exchange operation. + + @return The original *Value before exchange. + +**/ +//UINT64 +//EFIAPI +//InternalSyncCompareExchange64 ( +// IN volatile UINT64 *Value, // r0 +// IN UINT64 CompareValue, // r2-r3 +// IN UINT64 ExchangeValue // stack +// ) +InternalSyncCompareExchange64 + push { r4-r7 } + ldrd r4, r5, [sp, #16] + dmb + +InternalSyncCompareExchange64Again + ldrexd r6, r7, [r0] + cmp r6, r2 + cmpeq r7, r3 + bne InternalSyncCompareExchange64Fail + +InternalSyncCompareExchange64Exchange + strexd ip, r4, r5, [r0] + cmp ip, #0 + bne InternalSyncCompareExchange64Again + +InternalSyncCompareExchange64Fail + dmb + mov r0, r6 + mov r1, r7 + pop { r4-r7 } + bx lr + +/** + Performs an atomic increment of an 32-bit unsigned integer. + + Performs an atomic increment of the 32-bit unsigned integer specified by + Value and returns the incremented value. The increment operation must be + performed using MP safe mechanisms. The state of the return value is not + guaranteed to be MP safe. + + @param Value A pointer to the 32-bit value to increment. + + @return The incremented value. + +**/ +//UINT32 +//EFIAPI +//InternalSyncIncrement ( +// IN volatile UINT32 *Value +// ) +InternalSyncIncrement + dmb +TryInternalSyncIncrement + ldrex r1, [r0] + add r1, r1, #1 + strex r2, r1, [r0] + cmp r2, #0 + bne TryInternalSyncIncrement + dmb + bx lr + +/** + Performs an atomic decrement of an 32-bit unsigned integer. + + Performs an atomic decrement of the 32-bit unsigned integer specified by + Value and returns the decrement value. The decrement operation must be + performed using MP safe mechanisms. The state of the return value is not + guaranteed to be MP safe. + + @param Value A pointer to the 32-bit value to decrement. + + @return The decrement value. + +**/ +//UINT32 +//EFIAPI +//InternalSyncDecrement ( +// IN volatile UINT32 *Value +// ) +InternalSyncDecrement + dmb +TryInternalSyncDecrement + ldrex r1, [r0] + sub r1, r1, #1 + strex r2, r1, [r0] + cmp r2, #0 + bne TryInternalSyncDecrement + dmb + bx lr + + END diff --git a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.c b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.c deleted file mode 100644 index 9ddaa098b22f..000000000000 --- a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.c +++ /dev/null @@ -1,115 +0,0 @@ -/** @file - Implementation of synchronization functions. Still needs to be ported - - Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
- Portions copyright (c) 2008 - 2009, Apple Inc. 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 32-bit unsigned integer. - - Performs an atomic compare exchange operation on the 32-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 32-bit value for the compare exchange - operation. - @param CompareValue 32-bit value used in compare operation. - @param ExchangeValue 32-bit value used in exchange operation. - - @return The original *Value before exchange. - -**/ -UINT32 -EFIAPI -InternalSyncCompareExchange32 ( - IN volatile UINT32 *Value, - IN UINT32 CompareValue, - IN UINT32 ExchangeValue - ) -{ - return *Value != CompareValue ? *Value : - ((*Value = ExchangeValue), CompareValue); -} - -/** - Performs an atomic compare exchange operation on a 64-bit unsigned integer. - - Performs an atomic compare exchange operation on the 64-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 64-bit value for the compare exchange - operation. - @param CompareValue 64-bit value used in compare operation. - @param ExchangeValue 64-bit value used in exchange operation. - - @return The original *Value before exchange. - -**/ -UINT64 -EFIAPI -InternalSyncCompareExchange64 ( - IN volatile UINT64 *Value, - IN UINT64 CompareValue, - IN UINT64 ExchangeValue - ) -{ - return *Value != CompareValue ? *Value : - ((*Value = ExchangeValue), CompareValue); -} - -/** - Performs an atomic increment of an 32-bit unsigned integer. - - Performs an atomic increment of the 32-bit unsigned integer specified by - Value and returns the incremented value. The increment operation must be - performed using MP safe mechanisms. The state of the return value is not - guaranteed to be MP safe. - - @param Value A pointer to the 32-bit value to increment. - - @return The incremented value. - -**/ -UINT32 -EFIAPI -InternalSyncIncrement ( - IN volatile UINT32 *Value - ) -{ - return ++*Value; -} - -/** - Performs an atomic decrement of an 32-bit unsigned integer. - - Performs an atomic decrement of the 32-bit unsigned integer specified by - Value and returns the decrement value. The decrement operation must be - performed using MP safe mechanisms. The state of the return value is not - guaranteed to be MP safe. - - @param Value A pointer to the 32-bit value to decrement. - - @return The decrement value. - -**/ -UINT32 -EFIAPI -InternalSyncDecrement ( - IN volatile UINT32 *Value - ) -{ - return --*Value; -} diff --git a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf old mode 100644 new mode 100755 index bf9cf67a85cc..5e3b4e6b9bf2 --- a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf +++ b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf @@ -78,11 +78,12 @@ [Sources.ARM] Synchronization.c - Arm/Synchronization.c + Arm/Synchronization.asm | RVCT + Arm/Synchronization.S | GCC [Sources.AARCH64] Synchronization.c - AArch64/Synchronization.c + AArch64/Synchronization.S [Packages] MdePkg/MdePkg.dec