• 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 /**
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
InternalSyncIncrement(IN volatile UINT32 * Value)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
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     "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
InternalSyncCompareExchange16(IN OUT volatile UINT16 * Value,IN UINT16 CompareValue,IN UINT16 ExchangeValue)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
InternalSyncCompareExchange32(IN OUT volatile UINT32 * Value,IN UINT32 CompareValue,IN UINT32 ExchangeValue)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
InternalSyncCompareExchange64(IN OUT volatile UINT64 * Value,IN UINT64 CompareValue,IN UINT64 ExchangeValue)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