From 720d3c5fb31b6b2df535f7a281d5d9d297c5eede Mon Sep 17 00:00:00 2001 From: mdkinney Date: Fri, 30 Jan 2009 00:45:13 +0000 Subject: Split out Synchronization Library from Base Library git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@7377 6f19259b-4bc3-4df7-8a09-765794883524 --- .../BaseSynchronizationLib.inf | 88 +++++ .../BaseSynchronizationLibInternals.h | 115 ++++++ .../BaseSynchronizationLib/Ebc/Synchronization.c | 116 ++++++ .../Ia32/InterlockedCompareExchange32.S | 41 +++ .../Ia32/InterlockedCompareExchange32.asm | 45 +++ .../Ia32/InterlockedCompareExchange32.c | 50 +++ .../Ia32/InterlockedCompareExchange64.S | 47 +++ .../Ia32/InterlockedCompareExchange64.asm | 47 +++ .../Ia32/InterlockedCompareExchange64.c | 50 +++ .../Ia32/InterlockedDecrement.S | 38 ++ .../Ia32/InterlockedDecrement.asm | 42 +++ .../Ia32/InterlockedDecrement.c | 42 +++ .../Ia32/InterlockedIncrement.S | 38 ++ .../Ia32/InterlockedIncrement.asm | 42 +++ .../Ia32/InterlockedIncrement.c | 43 +++ .../Ipf/InterlockedCompareExchange32.s | 29 ++ .../Ipf/InterlockedCompareExchange64.s | 28 ++ .../BaseSynchronizationLib/Ipf/Synchronization.c | 77 ++++ .../BaseSynchronizationLib/Synchronization.c | 387 ++++++++++++++++++++ .../BaseSynchronizationLib/SynchronizationGcc.c | 402 ++++++++++++++++++++ .../BaseSynchronizationLib/SynchronizationMsc.c | 405 +++++++++++++++++++++ .../X64/InterlockedCompareExchange32.S | 37 ++ .../X64/InterlockedCompareExchange32.asm | 41 +++ .../X64/InterlockedCompareExchange32.c | 54 +++ .../X64/InterlockedCompareExchange64.S | 39 ++ .../X64/InterlockedCompareExchange64.asm | 41 +++ .../X64/InterlockedCompareExchange64.c | 53 +++ .../X64/InterlockedDecrement.S | 36 ++ .../X64/InterlockedDecrement.asm | 39 ++ .../X64/InterlockedDecrement.c | 46 +++ .../X64/InterlockedIncrement.S | 36 ++ .../X64/InterlockedIncrement.asm | 39 ++ .../X64/InterlockedIncrement.c | 46 +++ 33 files changed, 2679 insertions(+) create mode 100644 MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf create mode 100644 MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange32.S create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange32.asm create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange32.c create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange64.S create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange64.asm create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange64.c create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedDecrement.S create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedDecrement.asm create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedDecrement.c create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedIncrement.S create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedIncrement.asm create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedIncrement.c create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange32.s create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange64.s create mode 100644 MdePkg/Library/BaseSynchronizationLib/Ipf/Synchronization.c create mode 100644 MdePkg/Library/BaseSynchronizationLib/Synchronization.c create mode 100644 MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c create mode 100644 MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c create mode 100644 MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange32.S create mode 100644 MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange32.asm create mode 100644 MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange32.c create mode 100644 MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange64.S create mode 100644 MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange64.asm create mode 100644 MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange64.c create mode 100644 MdePkg/Library/BaseSynchronizationLib/X64/InterlockedDecrement.S create mode 100644 MdePkg/Library/BaseSynchronizationLib/X64/InterlockedDecrement.asm create mode 100644 MdePkg/Library/BaseSynchronizationLib/X64/InterlockedDecrement.c create mode 100644 MdePkg/Library/BaseSynchronizationLib/X64/InterlockedIncrement.S create mode 100644 MdePkg/Library/BaseSynchronizationLib/X64/InterlockedIncrement.asm create mode 100644 MdePkg/Library/BaseSynchronizationLib/X64/InterlockedIncrement.c (limited to 'MdePkg/Library/BaseSynchronizationLib') diff --git a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf new file mode 100644 index 0000000000..66a74e37a2 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf @@ -0,0 +1,88 @@ +#/** @file +# Base Synchronization Library implementation. +# +# Copyright (c) 2007 - 2008, Intel Corporation. +# +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BaseSynchronizationLib + FILE_GUID = FC9990DF-C5FF-44cf-8799-CBB45B577F87 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = SynchronizationLib + +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources.Ia32] + Ia32/InterlockedCompareExchange64.c | MSFT + Ia32/InterlockedCompareExchange32.c | MSFT + Ia32/InterlockedDecrement.c | MSFT + Ia32/InterlockedIncrement.c | MSFT + SynchronizationMsc.c | MSFT + + Ia32/InterlockedCompareExchange64.asm | INTEL + Ia32/InterlockedCompareExchange32.asm | INTEL + Ia32/InterlockedDecrement.asm | INTEL + Ia32/InterlockedIncrement.asm | INTEL + Synchronization.c | INTEL + + Ia32/InterlockedCompareExchange64.S | GCC + Ia32/InterlockedCompareExchange32.S | GCC + Ia32/InterlockedDecrement.S | GCC + Ia32/InterlockedIncrement.S | GCC + SynchronizationGcc.c | GCC + +[Sources.X64] + X64/InterlockedCompareExchange64.asm + X64/InterlockedCompareExchange32.asm + + X64/InterlockedDecrement.c | MSFT + X64/InterlockedIncrement.c | MSFT + SynchronizationMsc.c | MSFT + + X64/InterlockedDecrement.asm | INTEL + X64/InterlockedIncrement.asm | INTEL + Synchronization.c | INTEL + + X64/InterlockedIncrement.S | GCC + X64/InterlockedDecrement.S | GCC + X64/InterlockedCompareExchange64.S | GCC + X64/InterlockedCompareExchange32.S | GCC + SynchronizationGcc.c | GCC + +[Sources.IPF] + Ipf/Synchronization.c + Ipf/InterlockedCompareExchange64.s + Ipf/InterlockedCompareExchange32.s + + Synchronization.c | INTEL + SynchronizationMsc.c | MSFT + SynchronizationGcc.c | GCC + +[Sources.EBC] + Synchronization.c + Ebc/Synchronization.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + PcdLib + TimerLib + DebugLib + BaseMemoryLib + +[Pcd.common] + gEfiMdePkgTokenSpaceGuid.PcdSpinLockTimeout diff --git a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h new file mode 100644 index 0000000000..9f05d06cfb --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h @@ -0,0 +1,115 @@ +/** @file + Declaration of internal functions in BaseLib. + + Copyright (c) 2006 - 2008, Intel Corporation
+ All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __BASE_LIB_INTERNALS__ +#define __BASE_LIB_INTERNALS__ + +#include +#include +#include +#include +#include +#include + +/** + 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 + ); + + +/** + 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 + ); + + +/** + 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 + ); + + +/** + 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 + ); + +#endif diff --git a/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c b/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c new file mode 100644 index 0000000000..dfae40b927 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c @@ -0,0 +1,116 @@ +/** @file + Implementation of synchronization functions on EBC. + + Copyright (c) 2006 - 2008, Intel Corporation
+ All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +/** + 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/Ia32/InterlockedCompareExchange32.S b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange32.S new file mode 100644 index 0000000000..767343d823 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange32.S @@ -0,0 +1,41 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2006 - 2008, Intel Corporation +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Module Name: +# +# InterlockedCompareExchange32.S +# +# Abstract: +# +# InternalSyncCompareExchange32 function +# +# Notes: +# +#------------------------------------------------------------------------------ + +.globl ASM_PFX(InternalSyncCompareExchange32) + +#------------------------------------------------------------------------------ +# UINT32 +# EFIAPI +# InternalSyncCompareExchange32 ( +# IN UINT32 *Value, +# IN UINT32 CompareValue, +# IN UINT32 ExchangeValue +# ); +#------------------------------------------------------------------------------ +ASM_PFX(InternalSyncCompareExchange32): + movl 4(%esp), %ecx + movl 8(%esp), %eax + movl 12(%esp), %edx + lock + cmpxchgl %edx, (%ecx) + ret diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange32.asm b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange32.asm new file mode 100644 index 0000000000..47d959fa6a --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange32.asm @@ -0,0 +1,45 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006, Intel Corporation +; All rights reserved. This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; InterlockedCompareExchange32.Asm +; +; Abstract: +; +; InterlockedCompareExchange32 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .486 + .model flat,C + .code + +;------------------------------------------------------------------------------ +; UINT32 +; EFIAPI +; InternalSyncCompareExchange32 ( +; IN UINT32 *Value, +; IN UINT32 CompareValue, +; IN UINT32 ExchangeValue +; ); +;------------------------------------------------------------------------------ +InternalSyncCompareExchange32 PROC + mov ecx, [esp + 4] + mov eax, [esp + 8] + mov edx, [esp + 12] + lock cmpxchg [ecx], edx + ret +InternalSyncCompareExchange32 ENDP + + END diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange32.c b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange32.c new file mode 100644 index 0000000000..abcb1ecc83 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange32.c @@ -0,0 +1,50 @@ +/** @file + InterlockedCompareExchange32 function + + Copyright (c) 2006 - 2008, Intel Corporation
+ All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + + + + +/** + 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 UINT32 *Value, + IN UINT32 CompareValue, + IN UINT32 ExchangeValue + ) +{ + _asm { + mov ecx, Value + mov eax, CompareValue + mov edx, ExchangeValue + lock cmpxchg [ecx], edx + } +} + diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange64.S b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange64.S new file mode 100644 index 0000000000..03aebff91d --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange64.S @@ -0,0 +1,47 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2006 - 2008, Intel Corporation +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Module Name: +# +# InterlockedCompareExchange64.S +# +# Abstract: +# +# InternalSyncCompareExchange64 function +# +# Notes: +# +#------------------------------------------------------------------------------ + +.globl ASM_PFX(InternalSyncCompareExchange64) + +#------------------------------------------------------------------------------ +# UINT64 +# EFIAPI +# InternalSyncCompareExchange64 ( +# IN UINT64 *Value, +# IN UINT64 CompareValue, +# IN UINT64 ExchangeValue +# ); +#------------------------------------------------------------------------------ +ASM_PFX(InternalSyncCompareExchange64): + push %esi + push %ebx + movl 12(%esp), %esi + movl 16(%esp), %eax + movl 20(%esp), %edx + movl 24(%esp), %ebx + movl 28(%esp), %ecx + lock + cmpxchg8b (%esi) + pop %ebx + pop %esi + ret diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange64.asm b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange64.asm new file mode 100644 index 0000000000..18311e77d3 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange64.asm @@ -0,0 +1,47 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006, Intel Corporation +; All rights reserved. This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; InterlockedCompareExchange64.Asm +; +; Abstract: +; +; InterlockedCompareExchange64 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .586P + .model flat,C + .code + +;------------------------------------------------------------------------------ +; UINT64 +; EFIAPI +; InternalSyncCompareExchange64 ( +; IN UINT64 *Value, +; IN UINT64 CompareValue, +; IN UINT64 ExchangeValue +; ); +;------------------------------------------------------------------------------ +InternalSyncCompareExchange64 PROC USES esi ebx + mov esi, [esp + 12] + mov eax, [esp + 16] + mov edx, [esp + 20] + mov ebx, [esp + 24] + mov ecx, [esp + 28] + lock cmpxchg8b qword ptr [esi] + ret +InternalSyncCompareExchange64 ENDP + + END diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange64.c b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange64.c new file mode 100644 index 0000000000..63aafda4b6 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange64.c @@ -0,0 +1,50 @@ +/** @file + InterlockedCompareExchange64 function + + Copyright (c) 2006 - 2008, Intel Corporation
+ All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + + + + +/** + 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 UINT64 *Value, + IN UINT64 CompareValue, + IN UINT64 ExchangeValue + ) +{ + _asm { + mov esi, Value + mov eax, dword ptr [CompareValue + 0] + mov edx, dword ptr [CompareValue + 4] + mov ebx, dword ptr [ExchangeValue + 0] + mov ecx, dword ptr [ExchangeValue + 4] + lock cmpxchg8b qword ptr [esi] + } +} diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedDecrement.S b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedDecrement.S new file mode 100644 index 0000000000..bea5ac1d74 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedDecrement.S @@ -0,0 +1,38 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2006 - 2008, Intel Corporation +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Module Name: +# +# InterlockedDecrement.S +# +# Abstract: +# +# InternalSyncDecrement function +# +# Notes: +# +#------------------------------------------------------------------------------ + +.globl ASM_PFX(InternalSyncDecrement) + +#------------------------------------------------------------------------------ +# UINT32 +# EFIAPI +# InternalSyncDecrement ( +# IN UINT32 *Value +# ); +#------------------------------------------------------------------------------ +ASM_PFX(InternalSyncDecrement): + movl 4(%esp), %eax + lock + decl (%eax) + movl (%eax), %eax + ret diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedDecrement.asm b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedDecrement.asm new file mode 100644 index 0000000000..082429e520 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedDecrement.asm @@ -0,0 +1,42 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006, Intel Corporation +; All rights reserved. This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; InterlockedDecrement.Asm +; +; Abstract: +; +; InterlockedDecrement function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .386 + .model flat,C + .code + +;------------------------------------------------------------------------------ +; UINT32 +; EFIAPI +; InternalSyncDecrement ( +; IN UINT32 *Value +; ); +;------------------------------------------------------------------------------ +InternalSyncDecrement PROC + mov eax, [esp + 4] + lock dec dword ptr [eax] + mov eax, [eax] + ret +InternalSyncDecrement ENDP + + END diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedDecrement.c b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedDecrement.c new file mode 100644 index 0000000000..d1f0868a83 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedDecrement.c @@ -0,0 +1,42 @@ +/** @file + InterlockedDecrement function + + Copyright (c) 2006 - 2008, Intel Corporation
+ All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + + + + +/** + 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 UINT32 *Value + ) +{ + _asm { + mov eax, Value + lock dec dword ptr [eax] + mov eax, [eax] + } +} diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedIncrement.S b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedIncrement.S new file mode 100644 index 0000000000..6efbcee5ea --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedIncrement.S @@ -0,0 +1,38 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2006 - 2008, Intel Corporation +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Module Name: +# +# InterlockedIncrement.S +# +# Abstract: +# +# InternalSyncIncrement function +# +# Notes: +# +#------------------------------------------------------------------------------ + +.globl ASM_PFX(InternalSyncIncrement) + +#------------------------------------------------------------------------------ +# UINT32 +# EFIAPI +# InternalSyncIncrement ( +# IN UINT32 *Value +# ); +#------------------------------------------------------------------------------ +ASM_PFX(InternalSyncIncrement): + movl 4(%esp), %eax + lock + incl (%eax) + movl (%eax), %eax + ret diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedIncrement.asm b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedIncrement.asm new file mode 100644 index 0000000000..ea27e666ca --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedIncrement.asm @@ -0,0 +1,42 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006, Intel Corporation +; All rights reserved. This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; InterlockedIncrement.Asm +; +; Abstract: +; +; InterlockedIncrement function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .386 + .model flat,C + .code + +;------------------------------------------------------------------------------ +; UINT32 +; EFIAPI +; InternalSyncIncrement ( +; IN UINT32 *Value +; ); +;------------------------------------------------------------------------------ +InternalSyncIncrement PROC + mov eax, [esp + 4] + lock inc dword ptr [eax] + mov eax, [eax] + ret +InternalSyncIncrement ENDP + + END diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedIncrement.c b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedIncrement.c new file mode 100644 index 0000000000..b1cc0c7332 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedIncrement.c @@ -0,0 +1,43 @@ +/** @file + InterLockedIncrement function + + Copyright (c) 2006 - 2008, Intel Corporation
+ All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + + + + +/** + 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 UINT32 *Value + ) +{ + _asm { + mov eax, Value + lock inc dword ptr [eax] + mov eax, [eax] + } +} + diff --git a/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange32.s b/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange32.s new file mode 100644 index 0000000000..de44573b0f --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange32.s @@ -0,0 +1,29 @@ +/// @file +/// Contains an implementation of InterlockedCompareExchange32 on Itanium- +/// based architecture. +/// +/// Copyright (c) 2006 - 2008, Intel Corporation +/// All rights reserved. This program and the accompanying materials +/// are licensed and made available under the terms and conditions of the BSD License +/// which accompanies this distribution. The full text of the license may be found at +/// http://opensource.org/licenses/bsd-license.php +/// +/// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +/// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +/// +/// Module Name: InterlockedCompareExchange32.s +/// +/// + +.auto +.text + +.proc InternalSyncCompareExchange32 +.type InternalSyncCompareExchange32, @function +InternalSyncCompareExchange32:: + zxt4 r33 = r33 + mov ar.ccv = r33 + cmpxchg4.rel r8 = [r32], r34 + mf + br.ret.sptk.many b0 +.endp InternalSyncCompareExchange32 diff --git a/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange64.s b/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange64.s new file mode 100644 index 0000000000..7fe33fbc34 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange64.s @@ -0,0 +1,28 @@ +/// @file +/// Contains an implementation of InterlockedCompareExchange64 on Itanium- +/// based architecture. +/// +/// Copyright (c) 2006 - 2008, Intel Corporation +/// All rights reserved. This program and the accompanying materials +/// are licensed and made available under the terms and conditions of the BSD License +/// which accompanies this distribution. The full text of the license may be found at +/// http://opensource.org/licenses/bsd-license.php +/// +/// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +/// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +/// +/// Module Name: InterlockedCompareExchange64.s +/// +/// + +.auto +.text + +.proc InternalSyncCompareExchange64 +.type InternalSyncCompareExchange64, @function +InternalSyncCompareExchange64:: + mov ar.ccv = r33 + cmpxchg8.rel r8 = [r32], r34 + mf + br.ret.sptk.many b0 +.endp InternalSyncCompareExchange64 diff --git a/MdePkg/Library/BaseSynchronizationLib/Ipf/Synchronization.c b/MdePkg/Library/BaseSynchronizationLib/Ipf/Synchronization.c new file mode 100644 index 0000000000..5620d8622f --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Ipf/Synchronization.c @@ -0,0 +1,77 @@ +/** @file + Implementation of synchronization functions on Itanium. + + Copyright (c) 2006, Intel Corporation
+ All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "BaseSynchronizationLibInternals.h" + +/** + 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 + ) +{ + UINT32 OriginalValue; + + do { + OriginalValue = *Value; + } while (OriginalValue != InternalSyncCompareExchange32 ( + Value, + OriginalValue, + OriginalValue + 1 + )); + return OriginalValue + 1; +} + +/** + 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 + ) +{ + UINT32 OriginalValue; + + do { + OriginalValue = *Value; + } while (OriginalValue != InternalSyncCompareExchange32 ( + Value, + OriginalValue, + OriginalValue - 1 + )); + return OriginalValue - 1; +} diff --git a/MdePkg/Library/BaseSynchronizationLib/Synchronization.c b/MdePkg/Library/BaseSynchronizationLib/Synchronization.c new file mode 100644 index 0000000000..722525177c --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/Synchronization.c @@ -0,0 +1,387 @@ +/** @file + Implementation of synchronization functions. + + Copyright (c) 2006 - 2008, Intel Corporation
+ All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "BaseSynchronizationLibInternals.h" + +#define SPIN_LOCK_RELEASED ((UINTN) 1) +#define SPIN_LOCK_ACQUIRED ((UINTN) 2) + +/** + Retrieves the architecture specific spin lock alignment requirements for + optimal spin lock performance. + + This function retrieves the spin lock alignment requirements for optimal + performance on a given CPU architecture. The spin lock alignment must be a + power of two and is returned by this function. If there are no alignment + requirements, then 1 must be returned. The spin lock synchronization + functions must function correctly if the spin lock size and alignment values + returned by this function are not used at all. These values are hints to the + consumers of the spin lock synchronization functions to obtain optimal spin + lock performance. + + @return The architecture specific spin lock alignment. + +**/ +UINTN +EFIAPI +GetSpinLockProperties ( + VOID + ) +{ + return 32; +} + +/** + Initializes a spin lock to the released state and returns the spin lock. + + This function initializes the spin lock specified by SpinLock to the released + state, and returns SpinLock. Optimal performance can be achieved by calling + GetSpinLockProperties() to determine the size and alignment requirements for + SpinLock. + + If SpinLock is NULL, then ASSERT(). + + @param SpinLock A pointer to the spin lock to initialize to the released + state. + + @return SpinLock in release state. + +**/ +SPIN_LOCK * +EFIAPI +InitializeSpinLock ( + OUT SPIN_LOCK *SpinLock + ) +{ + ASSERT (SpinLock != NULL); + *SpinLock = SPIN_LOCK_RELEASED; + return SpinLock; +} + +/** + Waits until a spin lock can be placed in the acquired state. + + This function checks the state of the spin lock specified by SpinLock. If + SpinLock is in the released state, then this function places SpinLock in the + acquired state and returns SpinLock. Otherwise, this function waits + indefinitely for the spin lock to be released, and then places it in the + acquired state and returns SpinLock. All state transitions of SpinLock must + be performed using MP safe mechanisms. + + If SpinLock is NULL, then ASSERT(). + If SpinLock was not initialized with InitializeSpinLock(), then ASSERT(). + If PcdSpinLockTimeout is not zero, and SpinLock is can not be acquired in + PcdSpinLockTimeout microseconds, then ASSERT(). + + @param SpinLock A pointer to the spin lock to place in the acquired state. + + @return SpinLock acquired lock. + +**/ +SPIN_LOCK * +EFIAPI +AcquireSpinLock ( + IN OUT SPIN_LOCK *SpinLock + ) +{ + UINT64 Current; + UINT64 Previous; + UINT64 Total; + UINT64 Start; + UINT64 End; + UINT64 Timeout; + INT64 Cycle; + INT64 Delta; + + if (PcdGet32 (PcdSpinLockTimeout) > 0) { + // + // Get the current timer value + // + Current = GetPerformanceCounter(); + + // + // Initialize local variables + // + Start = 0; + End = 0; + Total = 0; + + // + // Retrieve the performance counter properties and compute the number of performance + // counter ticks required to reach the timeout + // + Timeout = DivU64x32 ( + MultU64x32 ( + GetPerformanceCounterProperties (&Start, &End), + PcdGet32 (PcdSpinLockTimeout) + ), + 1000000 + ); + Cycle = End - Start; + if (Cycle < 0) { + Cycle = -Cycle; + } + Cycle++; + + while (!AcquireSpinLockOrFail (SpinLock)) { + CpuPause (); + Previous = Current; + Current = GetPerformanceCounter(); + Delta = (INT64) (Current - Previous); + if (Start > End) { + Delta = -Delta; + } + if (Delta < 0) { + Delta += Cycle; + } + Total += Delta; + ASSERT (Total < Timeout); + } + } else { + while (!AcquireSpinLockOrFail (SpinLock)) { + CpuPause (); + } + } + return SpinLock; +} + +/** + Attempts to place a spin lock in the acquired state. + + This function checks the state of the spin lock specified by SpinLock. If + SpinLock is in the released state, then this function places SpinLock in the + acquired state and returns TRUE. Otherwise, FALSE is returned. All state + transitions of SpinLock must be performed using MP safe mechanisms. + + If SpinLock is NULL, then ASSERT(). + If SpinLock was not initialized with InitializeSpinLock(), then ASSERT(). + + @param SpinLock A pointer to the spin lock to place in the acquired state. + + @retval TRUE SpinLock was placed in the acquired state. + @retval FALSE SpinLock could not be acquired. + +**/ +BOOLEAN +EFIAPI +AcquireSpinLockOrFail ( + IN OUT SPIN_LOCK *SpinLock + ) +{ + SPIN_LOCK LockValue; + + ASSERT (SpinLock != NULL); + + LockValue = *SpinLock; + ASSERT (SPIN_LOCK_ACQUIRED == LockValue || SPIN_LOCK_RELEASED == LockValue); + + return (BOOLEAN)( + InterlockedCompareExchangePointer ( + (VOID**)SpinLock, + (VOID*)SPIN_LOCK_RELEASED, + (VOID*)SPIN_LOCK_ACQUIRED + ) == (VOID*)SPIN_LOCK_RELEASED + ); +} + +/** + Releases a spin lock. + + This function places the spin lock specified by SpinLock in the release state + and returns SpinLock. + + If SpinLock is NULL, then ASSERT(). + If SpinLock was not initialized with InitializeSpinLock(), then ASSERT(). + + @param SpinLock A pointer to the spin lock to release. + + @return SpinLock released lock. + +**/ +SPIN_LOCK * +EFIAPI +ReleaseSpinLock ( + IN OUT SPIN_LOCK *SpinLock + ) +{ + SPIN_LOCK LockValue; + + ASSERT (SpinLock != NULL); + + LockValue = *SpinLock; + ASSERT (SPIN_LOCK_ACQUIRED == LockValue || SPIN_LOCK_RELEASED == LockValue); + + *SpinLock = SPIN_LOCK_RELEASED; + return SpinLock; +} + +/** + 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. + + If Value is NULL, then ASSERT(). + + @param Value A pointer to the 32-bit value to increment. + + @return The incremented value. + +**/ +UINT32 +EFIAPI +InterlockedIncrement ( + IN UINT32 *Value + ) +{ + ASSERT (Value != NULL); + return InternalSyncIncrement (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 decremented value. The decrement operation must be + performed using MP safe mechanisms. The state of the return value is not + guaranteed to be MP safe. + + If Value is NULL, then ASSERT(). + + @param Value A pointer to the 32-bit value to decrement. + + @return The decremented value. + +**/ +UINT32 +EFIAPI +InterlockedDecrement ( + IN UINT32 *Value + ) +{ + ASSERT (Value != NULL); + return InternalSyncDecrement (Value); +} + +/** + 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. + + If Value is NULL, then ASSERT(). + + @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 +InterlockedCompareExchange32 ( + IN OUT UINT32 *Value, + IN UINT32 CompareValue, + IN UINT32 ExchangeValue + ) +{ + ASSERT (Value != NULL); + return InternalSyncCompareExchange32 (Value, CompareValue, ExchangeValue); +} + +/** + 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. + + If Value is NULL, then ASSERT(). + + @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 +InterlockedCompareExchange64 ( + IN OUT UINT64 *Value, + IN UINT64 CompareValue, + IN UINT64 ExchangeValue + ) +{ + ASSERT (Value != NULL); + return InternalSyncCompareExchange64 (Value, CompareValue, ExchangeValue); +} + +/** + Performs an atomic compare exchange operation on a pointer value. + + Performs an atomic compare exchange operation on the pointer value 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 pointer value for the compare exchange + operation. + @param CompareValue Pointer value used in compare operation. + @param ExchangeValue Pointer value used in exchange operation. + + @return The original *Value before exchange. +**/ +VOID * +EFIAPI +InterlockedCompareExchangePointer ( + IN OUT VOID **Value, + IN VOID *CompareValue, + IN VOID *ExchangeValue + ) +{ + UINT8 SizeOfValue; + + SizeOfValue = sizeof (*Value); + + switch (SizeOfValue) { + case sizeof (UINT32): + return (VOID*)(UINTN)InterlockedCompareExchange32 ( + (UINT32*)Value, + (UINT32)(UINTN)CompareValue, + (UINT32)(UINTN)ExchangeValue + ); + case sizeof (UINT64): + return (VOID*)(UINTN)InterlockedCompareExchange64 ( + (UINT64*)Value, + (UINT64)(UINTN)CompareValue, + (UINT64)(UINTN)ExchangeValue + ); + default: + ASSERT (FALSE); + return NULL; + } +} diff --git a/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c b/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c new file mode 100644 index 0000000000..79bd5c4d2d --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c @@ -0,0 +1,402 @@ +/** @file + Implementation of synchronization functions. + + Copyright (c) 2006 - 2008, Intel Corporation
+ All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "BaseSynchronizationLibInternals.h" + +// +// GCC inline assembly for Read Write Barrier +// +#define _ReadWriteBarrier() do { asm volatile ("": : : "memory"); } while(0) + +#define SPIN_LOCK_RELEASED ((UINTN) 1) +#define SPIN_LOCK_ACQUIRED ((UINTN) 2) + +/** + Retrieves the architecture specific spin lock alignment requirements for + optimal spin lock performance. + + This function retrieves the spin lock alignment requirements for optimal + performance on a given CPU architecture. The spin lock alignment must be a + power of two and is returned by this function. If there are no alignment + requirements, then 1 must be returned. The spin lock synchronization + functions must function correctly if the spin lock size and alignment values + returned by this function are not used at all. These values are hints to the + consumers of the spin lock synchronization functions to obtain optimal spin + lock performance. + + @return The architecture specific spin lock alignment. + +**/ +UINTN +EFIAPI +GetSpinLockProperties ( + VOID + ) +{ + return 32; +} + +/** + Initializes a spin lock to the released state and returns the spin lock. + + This function initializes the spin lock specified by SpinLock to the released + state, and returns SpinLock. Optimal performance can be achieved by calling + GetSpinLockProperties() to determine the size and alignment requirements for + SpinLock. + + If SpinLock is NULL, then ASSERT(). + + @param SpinLock A pointer to the spin lock to initialize to the released + state. + + @return SpinLock in release state. + +**/ +SPIN_LOCK * +EFIAPI +InitializeSpinLock ( + OUT SPIN_LOCK *SpinLock + ) +{ + ASSERT (SpinLock != NULL); + + _ReadWriteBarrier(); + *SpinLock = SPIN_LOCK_RELEASED; + _ReadWriteBarrier(); + + return SpinLock; +} + +/** + Waits until a spin lock can be placed in the acquired state. + + This function checks the state of the spin lock specified by SpinLock. If + SpinLock is in the released state, then this function places SpinLock in the + acquired state and returns SpinLock. Otherwise, this function waits + indefinitely for the spin lock to be released, and then places it in the + acquired state and returns SpinLock. All state transitions of SpinLock must + be performed using MP safe mechanisms. + + If SpinLock is NULL, then ASSERT(). + If SpinLock was not initialized with InitializeSpinLock(), then ASSERT(). + If PcdSpinLockTimeout is not zero, and SpinLock is can not be acquired in + PcdSpinLockTimeout microseconds, then ASSERT(). + + @param SpinLock A pointer to the spin lock to place in the acquired state. + + @return SpinLock acquired lock. + +**/ +SPIN_LOCK * +EFIAPI +AcquireSpinLock ( + IN OUT SPIN_LOCK *SpinLock + ) +{ + UINT64 Current; + UINT64 Previous; + UINT64 Total; + UINT64 Start; + UINT64 End; + UINT64 Timeout; + INT64 Cycle; + INT64 Delta; + + if (PcdGet32 (PcdSpinLockTimeout) > 0) { + // + // Get the current timer value + // + Current = GetPerformanceCounter(); + + // + // Initialize local variables + // + Start = 0; + End = 0; + Total = 0; + + // + // Retrieve the performance counter properties and compute the number of performance + // counter ticks required to reach the timeout + // + Timeout = DivU64x32 ( + MultU64x32 ( + GetPerformanceCounterProperties (&Start, &End), + PcdGet32 (PcdSpinLockTimeout) + ), + 1000000 + ); + Cycle = End - Start; + if (Cycle < 0) { + Cycle = -Cycle; + } + Cycle++; + + while (!AcquireSpinLockOrFail (SpinLock)) { + CpuPause (); + Previous = Current; + Current = GetPerformanceCounter(); + Delta = (INT64) (Current - Previous); + if (Start > End) { + Delta = -Delta; + } + if (Delta < 0) { + Delta += Cycle; + } + Total += Delta; + ASSERT (Total < Timeout); + } + } else { + while (!AcquireSpinLockOrFail (SpinLock)) { + CpuPause (); + } + } + return SpinLock; +} + +/** + Attempts to place a spin lock in the acquired state. + + This function checks the state of the spin lock specified by SpinLock. If + SpinLock is in the released state, then this function places SpinLock in the + acquired state and returns TRUE. Otherwise, FALSE is returned. All state + transitions of SpinLock must be performed using MP safe mechanisms. + + If SpinLock is NULL, then ASSERT(). + If SpinLock was not initialized with InitializeSpinLock(), then ASSERT(). + + @param SpinLock A pointer to the spin lock to place in the acquired state. + + @retval TRUE SpinLock was placed in the acquired state. + @retval FALSE SpinLock could not be acquired. + +**/ +BOOLEAN +EFIAPI +AcquireSpinLockOrFail ( + IN OUT SPIN_LOCK *SpinLock + ) +{ + SPIN_LOCK LockValue; + VOID *Result; + + ASSERT (SpinLock != NULL); + + LockValue = *SpinLock; + ASSERT (LockValue == SPIN_LOCK_ACQUIRED || LockValue == SPIN_LOCK_RELEASED); + + _ReadWriteBarrier (); + Result = InterlockedCompareExchangePointer ( + (VOID**)SpinLock, + (VOID*)SPIN_LOCK_RELEASED, + (VOID*)SPIN_LOCK_ACQUIRED + ); + + _ReadWriteBarrier (); + return (BOOLEAN) (Result == (VOID*) SPIN_LOCK_RELEASED); +} + +/** + Releases a spin lock. + + This function places the spin lock specified by SpinLock in the release state + and returns SpinLock. + + If SpinLock is NULL, then ASSERT(). + If SpinLock was not initialized with InitializeSpinLock(), then ASSERT(). + + @param SpinLock A pointer to the spin lock to release. + + @return SpinLock released lock. + +**/ +SPIN_LOCK * +EFIAPI +ReleaseSpinLock ( + IN OUT SPIN_LOCK *SpinLock + ) +{ + SPIN_LOCK LockValue; + + ASSERT (SpinLock != NULL); + + LockValue = *SpinLock; + ASSERT (LockValue == SPIN_LOCK_ACQUIRED || LockValue == SPIN_LOCK_RELEASED); + + _ReadWriteBarrier (); + *SpinLock = SPIN_LOCK_RELEASED; + _ReadWriteBarrier (); + + return SpinLock; +} + +/** + 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. + + If Value is NULL, then ASSERT(). + + @param Value A pointer to the 32-bit value to increment. + + @return The incremented value. + +**/ +UINT32 +EFIAPI +InterlockedIncrement ( + IN UINT32 *Value + ) +{ + ASSERT (Value != NULL); + return InternalSyncIncrement (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 decremented value. The decrement operation must be + performed using MP safe mechanisms. The state of the return value is not + guaranteed to be MP safe. + + If Value is NULL, then ASSERT(). + + @param Value A pointer to the 32-bit value to decrement. + + @return The decremented value. + +**/ +UINT32 +EFIAPI +InterlockedDecrement ( + IN UINT32 *Value + ) +{ + ASSERT (Value != NULL); + return InternalSyncDecrement (Value); +} + +/** + 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. + + If Value is NULL, then ASSERT(). + + @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 +InterlockedCompareExchange32 ( + IN OUT UINT32 *Value, + IN UINT32 CompareValue, + IN UINT32 ExchangeValue + ) +{ + ASSERT (Value != NULL); + return InternalSyncCompareExchange32 (Value, CompareValue, ExchangeValue); +} + +/** + 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. + + If Value is NULL, then ASSERT(). + + @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 +InterlockedCompareExchange64 ( + IN OUT UINT64 *Value, + IN UINT64 CompareValue, + IN UINT64 ExchangeValue + ) +{ + ASSERT (Value != NULL); + return InternalSyncCompareExchange64 (Value, CompareValue, ExchangeValue); +} + +/** + Performs an atomic compare exchange operation on a pointer value. + + Performs an atomic compare exchange operation on the pointer value 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 pointer value for the compare exchange + operation. + @param CompareValue Pointer value used in compare operation. + @param ExchangeValue Pointer value used in exchange operation. + + @return The original *Value before exchange. +**/ +VOID * +EFIAPI +InterlockedCompareExchangePointer ( + IN OUT VOID **Value, + IN VOID *CompareValue, + IN VOID *ExchangeValue + ) +{ + UINT8 SizeOfValue; + + SizeOfValue = sizeof (*Value); + + switch (SizeOfValue) { + case sizeof (UINT32): + return (VOID*)(UINTN)InterlockedCompareExchange32 ( + (UINT32*)Value, + (UINT32)(UINTN)CompareValue, + (UINT32)(UINTN)ExchangeValue + ); + case sizeof (UINT64): + return (VOID*)(UINTN)InterlockedCompareExchange64 ( + (UINT64*)Value, + (UINT64)(UINTN)CompareValue, + (UINT64)(UINTN)ExchangeValue + ); + default: + ASSERT (FALSE); + return NULL; + } +} diff --git a/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c b/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c new file mode 100644 index 0000000000..5abfbefcf0 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c @@ -0,0 +1,405 @@ +/** @file + Implementation of synchronization functions. + + Copyright (c) 2006 - 2008, Intel Corporation
+ All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "BaseSynchronizationLibInternals.h" + +/** + Microsoft Visual Studio 7.1 Function Prototypes for read write barrier Intrinsics. +**/ + +void _ReadWriteBarrier (void); +#pragma intrinsic(_ReadWriteBarrier) + + +#define SPIN_LOCK_RELEASED ((UINTN) 1) +#define SPIN_LOCK_ACQUIRED ((UINTN) 2) + +/** + Retrieves the architecture specific spin lock alignment requirements for + optimal spin lock performance. + + This function retrieves the spin lock alignment requirements for optimal + performance on a given CPU architecture. The spin lock alignment must be a + power of two and is returned by this function. If there are no alignment + requirements, then 1 must be returned. The spin lock synchronization + functions must function correctly if the spin lock size and alignment values + returned by this function are not used at all. These values are hints to the + consumers of the spin lock synchronization functions to obtain optimal spin + lock performance. + + @return The architecture specific spin lock alignment. + +**/ +UINTN +EFIAPI +GetSpinLockProperties ( + VOID + ) +{ + return 32; +} + +/** + Initializes a spin lock to the released state and returns the spin lock. + + This function initializes the spin lock specified by SpinLock to the released + state, and returns SpinLock. Optimal performance can be achieved by calling + GetSpinLockProperties() to determine the size and alignment requirements for + SpinLock. + + If SpinLock is NULL, then ASSERT(). + + @param SpinLock A pointer to the spin lock to initialize to the released + state. + + @return SpinLock in release state. + +**/ +SPIN_LOCK * +EFIAPI +InitializeSpinLock ( + OUT SPIN_LOCK *SpinLock + ) +{ + ASSERT (SpinLock != NULL); + + _ReadWriteBarrier(); + *SpinLock = SPIN_LOCK_RELEASED; + _ReadWriteBarrier(); + + return SpinLock; +} + +/** + Waits until a spin lock can be placed in the acquired state. + + This function checks the state of the spin lock specified by SpinLock. If + SpinLock is in the released state, then this function places SpinLock in the + acquired state and returns SpinLock. Otherwise, this function waits + indefinitely for the spin lock to be released, and then places it in the + acquired state and returns SpinLock. All state transitions of SpinLock must + be performed using MP safe mechanisms. + + If SpinLock is NULL, then ASSERT(). + If SpinLock was not initialized with InitializeSpinLock(), then ASSERT(). + If PcdSpinLockTimeout is not zero, and SpinLock is can not be acquired in + PcdSpinLockTimeout microseconds, then ASSERT(). + + @param SpinLock A pointer to the spin lock to place in the acquired state. + + @return SpinLock acquired lock. + +**/ +SPIN_LOCK * +EFIAPI +AcquireSpinLock ( + IN OUT SPIN_LOCK *SpinLock + ) +{ + UINT64 Current; + UINT64 Previous; + UINT64 Total; + UINT64 Start; + UINT64 End; + UINT64 Timeout; + INT64 Cycle; + INT64 Delta; + + if (PcdGet32 (PcdSpinLockTimeout) > 0) { + // + // Get the current timer value + // + Current = GetPerformanceCounter(); + + // + // Initialize local variables + // + Start = 0; + End = 0; + Total = 0; + + // + // Retrieve the performance counter properties and compute the number of performance + // counter ticks required to reach the timeout + // + Timeout = DivU64x32 ( + MultU64x32 ( + GetPerformanceCounterProperties (&Start, &End), + PcdGet32 (PcdSpinLockTimeout) + ), + 1000000 + ); + Cycle = End - Start; + if (Cycle < 0) { + Cycle = -Cycle; + } + Cycle++; + + while (!AcquireSpinLockOrFail (SpinLock)) { + CpuPause (); + Previous = Current; + Current = GetPerformanceCounter(); + Delta = (INT64) (Current - Previous); + if (Start > End) { + Delta = -Delta; + } + if (Delta < 0) { + Delta += Cycle; + } + Total += Delta; + ASSERT (Total < Timeout); + } + } else { + while (!AcquireSpinLockOrFail (SpinLock)) { + CpuPause (); + } + } + return SpinLock; +} + +/** + Attempts to place a spin lock in the acquired state. + + This function checks the state of the spin lock specified by SpinLock. If + SpinLock is in the released state, then this function places SpinLock in the + acquired state and returns TRUE. Otherwise, FALSE is returned. All state + transitions of SpinLock must be performed using MP safe mechanisms. + + If SpinLock is NULL, then ASSERT(). + If SpinLock was not initialized with InitializeSpinLock(), then ASSERT(). + + @param SpinLock A pointer to the spin lock to place in the acquired state. + + @retval TRUE SpinLock was placed in the acquired state. + @retval FALSE SpinLock could not be acquired. + +**/ +BOOLEAN +EFIAPI +AcquireSpinLockOrFail ( + IN OUT SPIN_LOCK *SpinLock + ) +{ + SPIN_LOCK LockValue; + VOID *Result; + + ASSERT (SpinLock != NULL); + + LockValue = *SpinLock; + ASSERT (LockValue == SPIN_LOCK_ACQUIRED || LockValue == SPIN_LOCK_RELEASED); + + _ReadWriteBarrier (); + Result = InterlockedCompareExchangePointer ( + (VOID**)SpinLock, + (VOID*)SPIN_LOCK_RELEASED, + (VOID*)SPIN_LOCK_ACQUIRED + ); + + _ReadWriteBarrier (); + return (BOOLEAN) (Result == (VOID*) SPIN_LOCK_RELEASED); +} + +/** + Releases a spin lock. + + This function places the spin lock specified by SpinLock in the release state + and returns SpinLock. + + If SpinLock is NULL, then ASSERT(). + If SpinLock was not initialized with InitializeSpinLock(), then ASSERT(). + + @param SpinLock A pointer to the spin lock to release. + + @return SpinLock released lock. + +**/ +SPIN_LOCK * +EFIAPI +ReleaseSpinLock ( + IN OUT SPIN_LOCK *SpinLock + ) +{ + SPIN_LOCK LockValue; + + ASSERT (SpinLock != NULL); + + LockValue = *SpinLock; + ASSERT (LockValue == SPIN_LOCK_ACQUIRED || LockValue == SPIN_LOCK_RELEASED); + + _ReadWriteBarrier (); + *SpinLock = SPIN_LOCK_RELEASED; + _ReadWriteBarrier (); + + return SpinLock; +} + +/** + 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. + + If Value is NULL, then ASSERT(). + + @param Value A pointer to the 32-bit value to increment. + + @return The incremented value. + +**/ +UINT32 +EFIAPI +InterlockedIncrement ( + IN UINT32 *Value + ) +{ + ASSERT (Value != NULL); + return InternalSyncIncrement (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 decremented value. The decrement operation must be + performed using MP safe mechanisms. The state of the return value is not + guaranteed to be MP safe. + + If Value is NULL, then ASSERT(). + + @param Value A pointer to the 32-bit value to decrement. + + @return The decremented value. + +**/ +UINT32 +EFIAPI +InterlockedDecrement ( + IN UINT32 *Value + ) +{ + ASSERT (Value != NULL); + return InternalSyncDecrement (Value); +} + +/** + 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. + + If Value is NULL, then ASSERT(). + + @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 +InterlockedCompareExchange32 ( + IN OUT UINT32 *Value, + IN UINT32 CompareValue, + IN UINT32 ExchangeValue + ) +{ + ASSERT (Value != NULL); + return InternalSyncCompareExchange32 (Value, CompareValue, ExchangeValue); +} + +/** + 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. + + If Value is NULL, then ASSERT(). + + @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 +InterlockedCompareExchange64 ( + IN OUT UINT64 *Value, + IN UINT64 CompareValue, + IN UINT64 ExchangeValue + ) +{ + ASSERT (Value != NULL); + return InternalSyncCompareExchange64 (Value, CompareValue, ExchangeValue); +} + +/** + Performs an atomic compare exchange operation on a pointer value. + + Performs an atomic compare exchange operation on the pointer value 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 pointer value for the compare exchange + operation. + @param CompareValue Pointer value used in compare operation. + @param ExchangeValue Pointer value used in exchange operation. + + @return The original *Value before exchange. +**/ +VOID * +EFIAPI +InterlockedCompareExchangePointer ( + IN OUT VOID **Value, + IN VOID *CompareValue, + IN VOID *ExchangeValue + ) +{ + UINT8 SizeOfValue; + + SizeOfValue = sizeof (*Value); + + switch (SizeOfValue) { + case sizeof (UINT32): + return (VOID*)(UINTN)InterlockedCompareExchange32 ( + (UINT32*)Value, + (UINT32)(UINTN)CompareValue, + (UINT32)(UINTN)ExchangeValue + ); + case sizeof (UINT64): + return (VOID*)(UINTN)InterlockedCompareExchange64 ( + (UINT64*)Value, + (UINT64)(UINTN)CompareValue, + (UINT64)(UINTN)ExchangeValue + ); + default: + ASSERT (FALSE); + return NULL; + } +} diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange32.S b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange32.S new file mode 100644 index 0000000000..8faca8b7b1 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange32.S @@ -0,0 +1,37 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2006 - 2008, Intel Corporation +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Module Name: +# +# InterlockedCompareExchange32.S +# +# Abstract: +# +# InterlockedCompareExchange32 function +# +# Notes: +# +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# UINT32 +# EFIAPI +# InterlockedCompareExchange32 ( +# IN UINT32 *Value, +# IN UINT32 CompareValue, +# IN UINT32 ExchangeValue +# ); +#------------------------------------------------------------------------------ +.global ASM_PFX(InternalSyncCompareExchange32) +ASM_PFX(InternalSyncCompareExchange32): + mov %edx, %eax + lock cmpxchg %r8d, (%rcx) + ret diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange32.asm b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange32.asm new file mode 100644 index 0000000000..55b055453f --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange32.asm @@ -0,0 +1,41 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006, Intel Corporation +; All rights reserved. This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; InterlockedCompareExchange32.Asm +; +; Abstract: +; +; InterlockedCompareExchange32 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINT32 +; EFIAPI +; InterlockedCompareExchange32 ( +; IN UINT32 *Value, +; IN UINT32 CompareValue, +; IN UINT32 ExchangeValue +; ); +;------------------------------------------------------------------------------ +InternalSyncCompareExchange32 PROC + mov eax, edx + lock cmpxchg [rcx], r8d + ret +InternalSyncCompareExchange32 ENDP + + END diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange32.c b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange32.c new file mode 100644 index 0000000000..8efd994a6e --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange32.c @@ -0,0 +1,54 @@ +/** @file + InterlockedCompareExchange32 function + + Copyright (c) 2006 - 2008, Intel Corporation
+ All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +/** + Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics. +**/ + +long _InterlockedCompareExchange( + long volatile * Destination, + long Exchange, + long Comperand +); + +#pragma intrinsic(_InterlockedCompareExchange) + +/** + 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 UINT32 *Value, + IN UINT32 CompareValue, + IN UINT32 ExchangeValue + ) +{ + return _InterlockedCompareExchange (Value, ExchangeValue, CompareValue); +} + diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange64.S b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange64.S new file mode 100644 index 0000000000..5e6e163527 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange64.S @@ -0,0 +1,39 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2006 - 2008, Intel Corporation +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Module Name: +# +# InterlockedCompareExchange64.S +# +# Abstract: +# +# InterlockedCompareExchange64 function +# +# Notes: +# +#------------------------------------------------------------------------------ + + +#------------------------------------------------------------------------------ +# UINT64 +# EFIAPI +# InterlockedCompareExchange64 ( +# IN UINT64 *Value, +# IN UINT64 CompareValue, +# IN UINT64 ExchangeValue +# ); +#------------------------------------------------------------------------------ +.global ASM_PFX(InternalSyncCompareExchange64) +.align 16 +ASM_PFX(InternalSyncCompareExchange64): + mov %rdx, %rax + lock cmpxchg %r8,(%rcx) + ret diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange64.asm b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange64.asm new file mode 100644 index 0000000000..88c25a56de --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange64.asm @@ -0,0 +1,41 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006, Intel Corporation +; All rights reserved. This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; InterlockedCompareExchange64.Asm +; +; Abstract: +; +; InterlockedCompareExchange64 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINT64 +; EFIAPI +; InterlockedCompareExchange64 ( +; IN UINT64 *Value, +; IN UINT64 CompareValue, +; IN UINT64 ExchangeValue +; ); +;------------------------------------------------------------------------------ +InternalSyncCompareExchange64 PROC + mov rax, rdx + lock cmpxchg [rcx], r8 + ret +InternalSyncCompareExchange64 ENDP + + END diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange64.c b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange64.c new file mode 100644 index 0000000000..0a88eda2ea --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange64.c @@ -0,0 +1,53 @@ +/** @file + InterlockedCompareExchange64 function + + Copyright (c) 2006 - 2008, Intel Corporation
+ All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +/** + Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics. +**/ + +__int64 _InterlockedCompareExchange64( + __int64 volatile * Destination, + __int64 Exchange, + __int64 Comperand +); + +#pragma intrinsic(_InterlockedCompareExchange64) + +/** + 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 UINT64 *Value, + IN UINT64 CompareValue, + IN UINT64 ExchangeValue + ) +{ + return _InterlockedCompareExchange64 (Value, ExchangeValue, CompareValue); +} + diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedDecrement.S b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedDecrement.S new file mode 100644 index 0000000000..d06559bd25 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedDecrement.S @@ -0,0 +1,36 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2006 - 2008, Intel Corporation +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Module Name: +# +# InterlockedDecrement.S +# +# Abstract: +# +# InterlockedDecrement function +# +# Notes: +# +#------------------------------------------------------------------------------ + + +#------------------------------------------------------------------------------ +# UINT32 +# EFIAPI +# InterlockedDecrement ( +# IN UINT32 *Value +# ); +#------------------------------------------------------------------------------ +.global ASM_PFX(InternalSyncDecrement) +ASM_PFX(InternalSyncDecrement): + lock decl (%rcx) + mov (%rcx), %eax + ret diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedDecrement.asm b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedDecrement.asm new file mode 100644 index 0000000000..f907fed4a8 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedDecrement.asm @@ -0,0 +1,39 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006, Intel Corporation +; All rights reserved. This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; InterlockedDecrement.Asm +; +; Abstract: +; +; InterlockedDecrement function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINT32 +; EFIAPI +; InterlockedDecrement ( +; IN UINT32 *Value +; ); +;------------------------------------------------------------------------------ +InternalSyncDecrement PROC + lock dec dword ptr [rcx] + mov eax, [rcx] + ret +InternalSyncDecrement ENDP + + END diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedDecrement.c b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedDecrement.c new file mode 100644 index 0000000000..9e2e339aee --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedDecrement.c @@ -0,0 +1,46 @@ +/** @file + InterlockedDecrement function + + Copyright (c) 2006 - 2008, Intel Corporation
+ All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +/** + Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics. +**/ + +long _InterlockedDecrement( + long * lpAddend +); + +#pragma intrinsic(_InterlockedDecrement) + +/** + 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 UINT32 *Value + ) +{ + return _InterlockedDecrement (Value); +} + diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedIncrement.S b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedIncrement.S new file mode 100644 index 0000000000..0416dd7d2a --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedIncrement.S @@ -0,0 +1,36 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2006 - 2008, Intel Corporation +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Module Name: +# +# InterlockedIncrement.S +# +# Abstract: +# +# InterlockedIncrement function +# +# Notes: +# +#------------------------------------------------------------------------------ + + +#------------------------------------------------------------------------------ +# UINT32 +# EFIAPI +# InterlockedIncrement ( +# IN UINT32 *Value +# ); +#------------------------------------------------------------------------------ +.global ASM_PFX(InternalSyncIncrement) +ASM_PFX(InternalSyncIncrement): + lock incl (%rcx) + mov (%rcx), %eax + ret diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedIncrement.asm b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedIncrement.asm new file mode 100644 index 0000000000..f5a4130bf1 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedIncrement.asm @@ -0,0 +1,39 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006, Intel Corporation +; All rights reserved. This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; InterlockedIncrement.Asm +; +; Abstract: +; +; InterlockedIncrement function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINT32 +; EFIAPI +; InterlockedIncrement ( +; IN UINT32 *Value +; ); +;------------------------------------------------------------------------------ +InternalSyncIncrement PROC + lock inc dword ptr [rcx] + mov eax, [rcx] + ret +InternalSyncIncrement ENDP + + END diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedIncrement.c b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedIncrement.c new file mode 100644 index 0000000000..455fb453d4 --- /dev/null +++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedIncrement.c @@ -0,0 +1,46 @@ +/** @file + InterLockedIncrement function + + Copyright (c) 2006 - 2008, Intel Corporation
+ All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +/** + Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics. +**/ + +long _InterlockedIncrement( + long * lpAddend +); + +#pragma intrinsic(_InterlockedIncrement) + +/** + 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 UINT32 *Value + ) +{ + return _InterlockedIncrement (Value); +} + -- cgit v1.2.3