Home | History | Annotate | Download | only in Ia32
      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   Performs an atomic increment of an 32-bit unsigned integer.
     20 
     21   Performs an atomic increment of the 32-bit unsigned integer specified by
     22   Value and returns the incremented value. The increment operation must be
     23   performed using MP safe mechanisms. The state of the return value is not
     24   guaranteed to be MP safe.
     25 
     26   @param  Value A pointer to the 32-bit value to increment.
     27 
     28   @return The incremented value.
     29 
     30 **/
     31 UINT32
     32 EFIAPI
     33 InternalSyncIncrement (
     34   IN      volatile UINT32    *Value
     35   )
     36 {
     37   UINT32  Result;
     38 
     39   __asm__ __volatile__ (
     40     "lock               \n\t"
     41     "incl    %2         \n\t"
     42     "movl    %2, %%eax      "
     43     : "=a" (Result),          // %0
     44       "=m" (*Value)           // %1
     45     : "m"  (*Value)           // %2
     46     : "memory",
     47       "cc"
     48     );
     49 
     50   return Result;
     51 
     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     "movl    %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   Performs an atomic compare exchange operation on a 16-bit unsigned integer.
     92 
     93   Performs an atomic compare exchange operation on the 16-bit unsigned integer
     94   specified by Value.  If Value is equal to CompareValue, then Value is set to
     95   ExchangeValue and CompareValue is returned.  If Value is not equal to CompareValue,
     96   then Value is returned.  The compare exchange operation must be performed using
     97   MP safe mechanisms.
     98 
     99 
    100   @param  Value         A pointer to the 16-bit value for the compare exchange
    101                         operation.
    102   @param  CompareValue  16-bit value used in compare operation.
    103   @param  ExchangeValue 16-bit value used in exchange operation.
    104 
    105   @return The original *Value before exchange.
    106 
    107 **/
    108 UINT16
    109 EFIAPI
    110 InternalSyncCompareExchange16 (
    111   IN OUT volatile  UINT16           *Value,
    112   IN      UINT16                    CompareValue,
    113   IN      UINT16                    ExchangeValue
    114   )
    115 {
    116 
    117   __asm__ __volatile__ (
    118     "                     \n\t"
    119     "lock                 \n\t"
    120     "cmpxchgw    %1, %2   \n\t"
    121     : "=a" (CompareValue)
    122     : "q"  (ExchangeValue),
    123       "m"  (*Value),
    124       "0"  (CompareValue)
    125     : "memory",
    126       "cc"
    127     );
    128 
    129   return CompareValue;
    130 }
    131 
    132 /**
    133   Performs an atomic compare exchange operation on a 32-bit unsigned integer.
    134 
    135   Performs an atomic compare exchange operation on the 32-bit unsigned integer
    136   specified by Value.  If Value is equal to CompareValue, then Value is set to
    137   ExchangeValue and CompareValue is returned.  If Value is not equal to CompareValue,
    138   then Value is returned.  The compare exchange operation must be performed using
    139   MP safe mechanisms.
    140 
    141 
    142   @param  Value         A pointer to the 32-bit value for the compare exchange
    143                         operation.
    144   @param  CompareValue  32-bit value used in compare operation.
    145   @param  ExchangeValue 32-bit value used in exchange operation.
    146 
    147   @return The original *Value before exchange.
    148 
    149 **/
    150 UINT32
    151 EFIAPI
    152 InternalSyncCompareExchange32 (
    153   IN OUT volatile  UINT32           *Value,
    154   IN      UINT32                    CompareValue,
    155   IN      UINT32                    ExchangeValue
    156   )
    157 {
    158 
    159   __asm__ __volatile__ (
    160     "                     \n\t"
    161     "lock                 \n\t"
    162     "cmpxchgl    %1, %2   \n\t"
    163     : "=a" (CompareValue)     // %0
    164     : "q"  (ExchangeValue),   // %1
    165       "m"  (*Value),          // %2
    166       "0"  (CompareValue)     // %4
    167     : "memory",
    168       "cc"
    169     );
    170 
    171   return CompareValue;
    172 }
    173 
    174 /**
    175   Performs an atomic compare exchange operation on a 64-bit unsigned integer.
    176 
    177   Performs an atomic compare exchange operation on the 64-bit unsigned integer specified
    178   by Value.  If Value is equal to CompareValue, then Value is set to ExchangeValue and
    179   CompareValue is returned.  If Value is not equal to CompareValue, then Value is returned.
    180   The compare exchange operation must be performed using MP safe mechanisms.
    181 
    182 
    183   @param  Value         A pointer to the 64-bit value for the compare exchange
    184                         operation.
    185   @param  CompareValue  64-bit value used in compare operation.
    186   @param  ExchangeValue 64-bit value used in exchange operation.
    187 
    188   @return The original *Value before exchange.
    189 
    190 **/
    191 UINT64
    192 EFIAPI
    193 InternalSyncCompareExchange64 (
    194   IN OUT  volatile UINT64           *Value,
    195   IN      UINT64                    CompareValue,
    196   IN      UINT64                    ExchangeValue
    197   )
    198 {
    199   __asm__ __volatile__ (
    200     "                       \n\t"
    201     "push        %%ebx      \n\t"
    202     "movl        %2,%%ebx   \n\t"
    203     "lock                   \n\t"
    204     "cmpxchg8b   (%1)       \n\t"
    205     "pop         %%ebx      \n\t"
    206     : "+A"  (CompareValue)                    // %0
    207     : "S"   (Value),                          // %1
    208       "r"   ((UINT32) ExchangeValue),         // %2
    209       "c"   ((UINT32) (ExchangeValue >> 32))  // %3
    210     : "memory",
    211       "cc"
    212     );
    213 
    214   return CompareValue;
    215 }
    216