• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
InternalSyncIncrement(IN volatile UINT32 * Value)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
InternalSyncDecrement(IN volatile UINT32 * Value)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
InternalSyncCompareExchange16(IN OUT volatile UINT16 * Value,IN UINT16 CompareValue,IN UINT16 ExchangeValue)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
InternalSyncCompareExchange32(IN OUT volatile UINT32 * Value,IN UINT32 CompareValue,IN UINT32 ExchangeValue)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
InternalSyncCompareExchange64(IN OUT volatile UINT64 * Value,IN UINT64 CompareValue,IN UINT64 ExchangeValue)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