Home | History | Annotate | Download | only in AArch64
      1 //  Implementation of synchronization functions for ARM architecture (AArch64)
      2 //
      3 //  Copyright (c) 2012-2015, ARM Limited. All rights reserved.
      4 //  Copyright (c) 2015, Linaro Limited. All rights reserved.
      5 //
      6 //  This program and the accompanying materials
      7 //  are licensed and made available under the terms and conditions of the BSD License
      8 //  which accompanies this distribution.  The full text of the license may be found at
      9 //  http://opensource.org/licenses/bsd-license.php
     10 //
     11 //  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     12 //  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     13 //
     14 //
     15 
     16 .text
     17 .align 3
     18 
     19 GCC_ASM_EXPORT(InternalSyncCompareExchange16)
     20 GCC_ASM_EXPORT(InternalSyncCompareExchange32)
     21 GCC_ASM_EXPORT(InternalSyncCompareExchange64)
     22 GCC_ASM_EXPORT(InternalSyncIncrement)
     23 GCC_ASM_EXPORT(InternalSyncDecrement)
     24 
     25 /**
     26   Performs an atomic compare exchange operation on a 16-bit unsigned integer.
     27 
     28   Performs an atomic compare exchange operation on the 16-bit unsigned integer
     29   specified by Value.  If Value is equal to CompareValue, then Value is set to
     30   ExchangeValue and CompareValue is returned.  If Value is not equal to CompareValue,
     31   then Value is returned.  The compare exchange operation must be performed using
     32   MP safe mechanisms.
     33 
     34   @param  Value         A pointer to the 16-bit value for the compare exchange
     35                         operation.
     36   @param  CompareValue  16-bit value used in compare operation.
     37   @param  ExchangeValue 16-bit value used in exchange operation.
     38 
     39   @return The original *Value before exchange.
     40 
     41 **/
     42 //UINT16
     43 //EFIAPI
     44 //InternalSyncCompareExchange16 (
     45 //  IN      volatile UINT16           *Value,
     46 //  IN      UINT16                    CompareValue,
     47 //  IN      UINT16                    ExchangeValue
     48 //  )
     49 ASM_PFX(InternalSyncCompareExchange16):
     50   uxth    w1, w1
     51   uxth    w2, w2
     52   dmb     sy
     53 
     54 InternalSyncCompareExchange16Again:
     55   ldxrh   w3, [x0]
     56   cmp     w3, w1
     57   bne     InternalSyncCompareExchange16Fail
     58 
     59 InternalSyncCompareExchange16Exchange:
     60   stxrh   w4, w2, [x0]
     61   cbnz    w4, InternalSyncCompareExchange16Again
     62 
     63 InternalSyncCompareExchange16Fail:
     64   dmb     sy
     65   mov     w0, w3
     66   ret
     67 
     68 /**
     69   Performs an atomic compare exchange operation on a 32-bit unsigned integer.
     70 
     71   Performs an atomic compare exchange operation on the 32-bit unsigned integer
     72   specified by Value.  If Value is equal to CompareValue, then Value is set to
     73   ExchangeValue and CompareValue is returned.  If Value is not equal to CompareValue,
     74   then Value is returned.  The compare exchange operation must be performed using
     75   MP safe mechanisms.
     76 
     77   @param  Value         A pointer to the 32-bit value for the compare exchange
     78                         operation.
     79   @param  CompareValue  32-bit value used in compare operation.
     80   @param  ExchangeValue 32-bit value used in exchange operation.
     81 
     82   @return The original *Value before exchange.
     83 
     84 **/
     85 //UINT32
     86 //EFIAPI
     87 //InternalSyncCompareExchange32 (
     88 //  IN      volatile UINT32           *Value,
     89 //  IN      UINT32                    CompareValue,
     90 //  IN      UINT32                    ExchangeValue
     91 //  )
     92 ASM_PFX(InternalSyncCompareExchange32):
     93   dmb     sy
     94 
     95 InternalSyncCompareExchange32Again:
     96   ldxr    w3, [x0]
     97   cmp     w3, w1
     98   bne     InternalSyncCompareExchange32Fail
     99 
    100 InternalSyncCompareExchange32Exchange:
    101   stxr    w4, w2, [x0]
    102   cbnz    w4, InternalSyncCompareExchange32Again
    103 
    104 InternalSyncCompareExchange32Fail:
    105   dmb     sy
    106   mov     w0, w3
    107   ret
    108 
    109 /**
    110   Performs an atomic compare exchange operation on a 64-bit unsigned integer.
    111 
    112   Performs an atomic compare exchange operation on the 64-bit unsigned integer specified
    113   by Value.  If Value is equal to CompareValue, then Value is set to ExchangeValue and
    114   CompareValue is returned.  If Value is not equal to CompareValue, then Value is returned.
    115   The compare exchange operation must be performed using MP safe mechanisms.
    116 
    117   @param  Value         A pointer to the 64-bit value for the compare exchange
    118                         operation.
    119   @param  CompareValue  64-bit value used in compare operation.
    120   @param  ExchangeValue 64-bit value used in exchange operation.
    121 
    122   @return The original *Value before exchange.
    123 
    124 **/
    125 //UINT64
    126 //EFIAPI
    127 //InternalSyncCompareExchange64 (
    128 //  IN      volatile UINT64           *Value,
    129 //  IN      UINT64                    CompareValue,
    130 //  IN      UINT64                    ExchangeValue
    131 //  )
    132 ASM_PFX(InternalSyncCompareExchange64):
    133   dmb     sy
    134 
    135 InternalSyncCompareExchange64Again:
    136   ldxr    x3, [x0]
    137   cmp     x3, x1
    138   bne     InternalSyncCompareExchange64Fail
    139 
    140 InternalSyncCompareExchange64Exchange:
    141   stxr    w4, x2, [x0]
    142   cbnz    w4, InternalSyncCompareExchange64Again
    143 
    144 InternalSyncCompareExchange64Fail:
    145   dmb     sy
    146   mov     x0, x3
    147   ret
    148 
    149 /**
    150   Performs an atomic increment of an 32-bit unsigned integer.
    151 
    152   Performs an atomic increment of the 32-bit unsigned integer specified by
    153   Value and returns the incremented value. The increment operation must be
    154   performed using MP safe mechanisms. The state of the return value is not
    155   guaranteed to be MP safe.
    156 
    157   @param  Value A pointer to the 32-bit value to increment.
    158 
    159   @return The incremented value.
    160 
    161 **/
    162 //UINT32
    163 //EFIAPI
    164 //InternalSyncIncrement (
    165 //  IN      volatile UINT32           *Value
    166 //  )
    167 ASM_PFX(InternalSyncIncrement):
    168   dmb     sy
    169 TryInternalSyncIncrement:
    170   ldxr    w1, [x0]
    171   add     w1, w1, #1
    172   stxr    w2, w1, [x0]
    173   cbnz    w2, TryInternalSyncIncrement
    174   mov     w0, w1
    175   dmb     sy
    176   ret
    177 
    178 /**
    179   Performs an atomic decrement of an 32-bit unsigned integer.
    180 
    181   Performs an atomic decrement of the 32-bit unsigned integer specified by
    182   Value and returns the decrement value. The decrement operation must be
    183   performed using MP safe mechanisms. The state of the return value is not
    184   guaranteed to be MP safe.
    185 
    186   @param  Value A pointer to the 32-bit value to decrement.
    187 
    188   @return The decrement value.
    189 
    190 **/
    191 //UINT32
    192 //EFIAPI
    193 //InternalSyncDecrement (
    194 //  IN      volatile UINT32           *Value
    195 //  )
    196 ASM_PFX(InternalSyncDecrement):
    197   dmb     sy
    198 TryInternalSyncDecrement:
    199   ldxr    w1, [x0]
    200   sub     w1, w1, #1
    201   stxr    w2, w1, [x0]
    202   cbnz    w2, TryInternalSyncDecrement
    203   mov     w0, w1
    204   dmb     sy
    205   ret
    206