From fd6d064aa07253183be812bcc80768ff7f1dcd71 Mon Sep 17 00:00:00 2001 From: Olivier Martin Date: Mon, 18 Jun 2012 12:29:15 +0100 Subject: [PATCH] MdePkg/BaseSynchronizationLib: Added proper support for ARM architecture Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Olivier Martin --- .../BaseSynchronizationLib/Arm/Synchronization.S | 174 ++++++++++++++++++++ .../BaseSynchronizationLib/Arm/Synchronization.asm | 175 +++++++++++++++++++++ .../BaseSynchronizationLib/Arm/Synchronization.c | 115 -------------- .../BaseSynchronizationLib.inf | 3 +- 4 files changed, 351 insertions(+), 116 deletions(-) create mode 100755 MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S create mode 100755 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/Arm/Synchronization.S b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S new file mode 100755 index 0000000..1a95299 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S @@ -0,0 +1,174 @@ +// 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): + push { r4 } + ldrex r3, [r0] + cmp r3, r1 + beq InternalSyncCompareExchange32Exchange + b InternalSyncCompareExchange32Fail + +InternalSyncCompareExchange32Exchange: + strex r4, r2, [r0] + cmp r4, #0 + bne InternalSyncCompareExchange32Fail + dsb + mov r0, r1 + pop { r4 } + bx lr + +InternalSyncCompareExchange32Fail: + mov r0, r3 + pop { r4 } + 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-r1 +// IN UINT64 CompareValue, // r2-r3 +// IN UINT64 ExchangeValue // r4-r5 +// ) +ASM_PFX(InternalSyncCompareExchange64): + push { r6-r8 } + ldrexd r6, r7, [r0] + cmp r6, r2 + cmpeq r7, r3 + bne InternalSyncCompareExchange64Fail + beq InternalSyncCompareExchange64Exchange + +InternalSyncCompareExchange64Exchange: + strexd r8, r4, r5, [r0] + cmp r8, #0 + bne InternalSyncCompareExchange64Fail + mov r0, r2 + mov r1, r3 + dsb + pop { r6-r8 } + bx lr + +InternalSyncCompareExchange64Fail: + mov r0, r6 + mov r1, r7 + pop { r6-r8 } + 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): + push { r1-r2 } +TryInternalSyncIncrement: + ldrex r1, [r0] + add r1, r1, #1 + strex r2, r1, [r0] + cmp r2, #0 + bne TryInternalSyncIncrement + dsb + pop { r1-r2 } + 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): + push { r1-r2 } +TryInternalSyncDecrement: + ldrex r1, [r0] + sub r1, r1, #1 + strex r2, r1, [r0] + cmp r2, #0 + bne TryInternalSyncDecrement + dsb + pop { r1-r2 } + bx lr diff --git a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm new file mode 100755 index 0000000..a0c7169 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm @@ -0,0 +1,175 @@ +// 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 + push { r4 } + ldrex r3, [r0] + cmp r3, r1 + beq InternalSyncCompareExchange32Exchange + b InternalSyncCompareExchange32Fail + +InternalSyncCompareExchange32Exchange + strex r4, r2, [r0] + cmp r4, #0 + bne InternalSyncCompareExchange32Fail + dsb + mov r0, r1 + pop { r4 } + bx lr + +InternalSyncCompareExchange32Fail + mov r0, r3 + pop { r4 } + 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-r1 +// IN UINT64 CompareValue, // r2-r3 +// IN UINT64 ExchangeValue // r4-r5 +// ) +InternalSyncCompareExchange64 + push { r6-r8 } + ldrexd r6, r7, [r0] + cmp r6, r2 + cmpeq r7, r3 + bne InternalSyncCompareExchange64Fail + beq InternalSyncCompareExchange64Exchange + +InternalSyncCompareExchange64Exchange + strexd r8, r4, r5, [r0] + cmp r8, #0 + bne InternalSyncCompareExchange64Fail + mov r0, r2 + mov r1, r3 + dsb + pop { r6-r8 } + bx lr + +InternalSyncCompareExchange64Fail + mov r0, r6 + mov r1, r7 + pop { r6-r8 } + 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 + push { r1-r2 } +TryInternalSyncIncrement + ldrex r1, [r0] + add r1, r1, #1 + strex r2, r1, [r0] + cmp r2, #0 + bne TryInternalSyncIncrement + dsb + pop { r1-r2 } + 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 + push { r1-r2 } +TryInternalSyncDecrement + ldrex r1, [r0] + sub r1, r1, #1 + strex r2, r1, [r0] + cmp r2, #0 + bne TryInternalSyncDecrement + dsb + pop { r1-r2 } + bx lr + + END diff --git a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.c b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.c deleted file mode 100644 index 9ddaa09..0000000 --- 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 bf9cf67..7a304b2 --- a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf +++ b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf @@ -78,7 +78,8 @@ [Sources.ARM] Synchronization.c - Arm/Synchronization.c + Arm/Synchronization.asm | RVCT + Arm/Synchronization.S | GCC [Sources.AARCH64] Synchronization.c -- 1.9.1