Home | History | Annotate | Download | only in X64
      1 /** @file
      2   GCC inline implementation of BaseSynchronizationLib processor specific functions.
      3 
      4   Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
      5   Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
      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 
     17 
     18 
     19 /**
     20   Performs an atomic increment of an 32-bit unsigned integer.
     21 
     22   Performs an atomic increment of the 32-bit unsigned integer specified by
     23   Value and returns the incremented value. The increment operation must be
     24   performed using MP safe mechanisms. The state of the return value is not
     25   guaranteed to be MP safe.
     26 
     27   @param  Value A pointer to the 32-bit value to increment.
     28 
     29   @return The incremented value.
     30 
     31 **/
     32 UINT32
     33 EFIAPI
     34 InternalSyncIncrement (
     35   IN      volatile UINT32    *Value
     36   )
     37 {
     38   UINT32  Result;
     39 
     40   __asm__ __volatile__ (
     41     "lock               \n\t"
     42     "incl    %2         \n\t"
     43     "mov     %2, %%eax      "
     44     : "=a" (Result),          // %0
     45       "=m" (*Value)           // %1
     46     : "m"  (*Value)           // %2
     47     : "memory",
     48       "cc"
     49     );
     50 
     51   return Result;
     52 }
     53 
     54 
     55 /**
     56   Performs an atomic decrement of an 32-bit unsigned integer.
     57 
     58   Performs an atomic decrement of the 32-bit unsigned integer specified by
     59   Value and returns the decremented value. The decrement operation must be
     60   performed using MP safe mechanisms. The state of the return value is not
     61   guaranteed to be MP safe.
     62 
     63   @param  Value A pointer to the 32-bit value to decrement.
     64 
     65   @return The decremented value.
     66 
     67 **/
     68 UINT32
     69 EFIAPI
     70 InternalSyncDecrement (
     71   IN      volatile UINT32       *Value
     72   )
     73 {
     74    UINT32  Result;
     75 
     76   __asm__ __volatile__ (
     77     "lock               \n\t"
     78     "decl    %2         \n\t"
     79     "mov     %2, %%eax      "
     80     : "=a" (Result),          // %0
     81       "=m" (*Value)           // %1
     82     : "m"  (*Value)           // %2
     83     : "memory",
     84       "cc"
     85     );
     86 
     87   return Result;
     88 }
     89 
     90 
     91 /**
     92   Performs an atomic compare exchange operation on a 16-bit unsigned integer.
     93 
     94   Performs an atomic compare exchange operation on the 16-bit unsigned integer
     95   specified by Value.  If Value is equal to CompareValue, then Value is set to
     96   ExchangeValue and CompareValue is returned.  If Value is not equal to CompareValue,
     97   then Value is returned.  The compare exchange operation must be performed using
     98   MP safe mechanisms.
     99 
    100 
    101   @param  Value         A pointer to the 16-bit value for the compare exchange
    102                         operation.
    103   @param  CompareValue  16-bit value used in compare operation.
    104   @param  ExchangeValue 16-bit value used in exchange operation.
    105 
    106   @return The original *Value before exchange.
    107 
    108 **/
    109 UINT16
    110 EFIAPI
    111 InternalSyncCompareExchange16 (
    112   IN OUT volatile  UINT16           *Value,
    113   IN      UINT16                    CompareValue,
    114   IN      UINT16                    ExchangeValue
    115   )
    116 {
    117 
    118 
    119   __asm__ __volatile__ (
    120     "lock                 \n\t"
    121     "cmpxchgw    %3, %1       "
    122     : "=a" (CompareValue),
    123       "=m" (*Value)
    124     : "a"  (CompareValue),
    125       "r"  (ExchangeValue),
    126       "m"  (*Value)
    127     : "memory",
    128       "cc"
    129     );
    130 
    131   return CompareValue;
    132 }
    133 
    134 
    135 /**
    136   Performs an atomic compare exchange operation on a 32-bit unsigned integer.
    137 
    138   Performs an atomic compare exchange operation on the 32-bit unsigned integer
    139   specified by Value.  If Value is equal to CompareValue, then Value is set to
    140   ExchangeValue and CompareValue is returned.  If Value is not equal to CompareValue,
    141   then Value is returned.  The compare exchange operation must be performed using
    142   MP safe mechanisms.
    143 
    144 
    145   @param  Value         A pointer to the 32-bit value for the compare exchange
    146                         operation.
    147   @param  CompareValue  32-bit value used in compare operation.
    148   @param  ExchangeValue 32-bit value used in exchange operation.
    149 
    150   @return The original *Value before exchange.
    151 
    152 **/
    153 UINT32
    154 EFIAPI
    155 InternalSyncCompareExchange32 (
    156   IN OUT volatile  UINT32           *Value,
    157   IN      UINT32                    CompareValue,
    158   IN      UINT32                    ExchangeValue
    159   )
    160 {
    161 
    162 
    163   __asm__ __volatile__ (
    164     "lock                 \n\t"
    165     "cmpxchgl    %3, %1       "
    166     : "=a" (CompareValue),    // %0
    167       "=m" (*Value)           // %1
    168     : "a"  (CompareValue),    // %2
    169       "r"  (ExchangeValue),   // %3
    170       "m"  (*Value)
    171     : "memory",
    172       "cc"
    173     );
    174 
    175   return CompareValue;
    176 }
    177 
    178 
    179 /**
    180   Performs an atomic compare exchange operation on a 64-bit unsigned integer.
    181 
    182   Performs an atomic compare exchange operation on the 64-bit unsigned integer specified
    183   by Value.  If Value is equal to CompareValue, then Value is set to ExchangeValue and
    184   CompareValue is returned.  If Value is not equal to CompareValue, then Value is returned.
    185   The compare exchange operation must be performed using MP safe mechanisms.
    186 
    187 
    188   @param  Value         A pointer to the 64-bit value for the compare exchange
    189                         operation.
    190   @param  CompareValue  64-bit value used in compare operation.
    191   @param  ExchangeValue 64-bit value used in exchange operation.
    192 
    193   @return The original *Value before exchange.
    194 
    195 **/
    196 UINT64
    197 EFIAPI
    198 InternalSyncCompareExchange64 (
    199   IN OUT  volatile UINT64           *Value,
    200   IN      UINT64                    CompareValue,
    201   IN      UINT64                    ExchangeValue
    202   )
    203 {
    204 
    205   __asm__ __volatile__ (
    206     "lock                 \n\t"
    207     "cmpxchgq    %3, %1       "
    208     : "=a" (CompareValue),    // %0
    209       "=m" (*Value)           // %1
    210     : "a"  (CompareValue),    // %2
    211       "r"  (ExchangeValue),   // %3
    212       "m"  (*Value)
    213     : "memory",
    214       "cc"
    215     );
    216 
    217   return CompareValue;
    218 }
    219 
    220 
    221