| /** @file | |
| LoongArch synchronization functions. | |
| Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR> | |
| SPDX-License-Identifier: BSD-2-Clause-Patent | |
| **/ | |
| #include <Library/DebugLib.h> | |
| UINT32 | |
| EFIAPI | |
| AsmInternalSyncCompareExchange16 ( | |
| IN volatile UINT32 *, | |
| IN UINT64, | |
| IN UINT64, | |
| IN UINT64 | |
| ); | |
| UINT32 | |
| EFIAPI | |
| AsmInternalSyncCompareExchange32 ( | |
| IN volatile UINT32 *, | |
| IN UINT64, | |
| IN UINT64 | |
| ); | |
| UINT64 | |
| EFIAPI | |
| AsmInternalSyncCompareExchange64 ( | |
| IN volatile UINT64 *, | |
| IN UINT64, | |
| IN UINT64 | |
| ); | |
| UINT32 | |
| EFIAPI | |
| AsmInternalSyncIncrement ( | |
| IN volatile UINT32 * | |
| ); | |
| UINT32 | |
| EFIAPI | |
| AsmInternalSyncDecrement ( | |
| IN volatile UINT32 * | |
| ); | |
| /** | |
| Performs an atomic compare exchange operation on a 16-bit | |
| unsigned integer. | |
| Performs an atomic compare exchange operation on the 16-bit | |
| unsigned integer specified by Value. If Value is equal to | |
| CompareValue, then Value is set to ExchangeValue and | |
| CompareValue is returned. If Value is not equal to | |
| CompareValue, then Value is returned. The compare exchange | |
| operation must be performed using MP safe mechanisms. | |
| @param[in] Value A pointer to the 16-bit value for the | |
| compare exchange operation. | |
| @param[in] CompareValue 16-bit value used in compare operation. | |
| @param[in] ExchangeValue 16-bit value used in exchange operation. | |
| @return The original *Value before exchange. | |
| **/ | |
| UINT16 | |
| EFIAPI | |
| InternalSyncCompareExchange16 ( | |
| IN volatile UINT16 *Value, | |
| IN UINT16 CompareValue, | |
| IN UINT16 ExchangeValue | |
| ) | |
| { | |
| UINT32 RetValue; | |
| UINT32 Shift; | |
| UINT64 Mask; | |
| UINT64 LocalCompareValue; | |
| UINT64 LocalExchangeValue; | |
| volatile UINT32 *Ptr32; | |
| /* Check that ptr is naturally aligned */ | |
| ASSERT (!((UINT64)Value & (sizeof (UINT16) - 1))); | |
| /* Mask inputs to the correct size. */ | |
| Mask = (((~0UL) - (1UL << (0)) + 1) & (~0UL >> (64 - 1 - ((sizeof (UINT16) * 8) - 1)))); | |
| LocalCompareValue = ((UINT64)CompareValue) & Mask; | |
| LocalExchangeValue = ((UINT64)ExchangeValue) & Mask; | |
| /* | |
| * Calculate a shift & mask that correspond to the value we wish to | |
| * compare & exchange within the naturally aligned 4 byte integer | |
| * that includes it. | |
| */ | |
| Shift = (UINT64)Value & 0x3; | |
| Shift *= 8; /* BITS_PER_BYTE */ | |
| LocalCompareValue <<= Shift; | |
| LocalExchangeValue <<= Shift; | |
| Mask <<= Shift; | |
| /* | |
| * Calculate a pointer to the naturally aligned 4 byte integer that | |
| * includes our byte of interest, and load its value. | |
| */ | |
| Ptr32 = (UINT32 *)((UINT64)Value & ~0x3); | |
| RetValue = AsmInternalSyncCompareExchange16 ( | |
| Ptr32, | |
| Mask, | |
| LocalCompareValue, | |
| LocalExchangeValue | |
| ); | |
| return (RetValue & Mask) >> Shift; | |
| } | |
| /** | |
| 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[in] Value A pointer to the 32-bit value for the | |
| compare exchange operation. | |
| @param[in] CompareValue 32-bit value used in compare operation. | |
| @param[in] 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 | |
| ) | |
| { | |
| UINT32 RetValue; | |
| RetValue = AsmInternalSyncCompareExchange32 ( | |
| Value, | |
| CompareValue, | |
| ExchangeValue | |
| ); | |
| return RetValue; | |
| } | |
| /** | |
| 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[in] Value A pointer to the 64-bit value for the compare exchange | |
| operation. | |
| @param[in] CompareValue 64-bit value used in compare operation. | |
| @param[in] 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 | |
| ) | |
| { | |
| UINT64 RetValue; | |
| RetValue = AsmInternalSyncCompareExchange64 ( | |
| Value, | |
| CompareValue, | |
| ExchangeValue | |
| ); | |
| return RetValue; | |
| } | |
| /** | |
| 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[in] Value A pointer to the 32-bit value to increment. | |
| @return The incremented value. | |
| **/ | |
| UINT32 | |
| EFIAPI | |
| InternalSyncIncrement ( | |
| IN volatile UINT32 *Value | |
| ) | |
| { | |
| return AsmInternalSyncIncrement (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[in] Value A pointer to the 32-bit value to decrement. | |
| @return The decrement value. | |
| **/ | |
| UINT32 | |
| EFIAPI | |
| InternalSyncDecrement ( | |
| IN volatile UINT32 *Value | |
| ) | |
| { | |
| return AsmInternalSyncDecrement (Value); | |
| } |