]>
Commit | Line | Data |
---|---|---|
3c991078 | 1 | /** @file |
2 | GCC inline implementation of BaseSynchronizationLib processor specific functions. | |
3 | ||
4 | Copyright (c) 2006 - 2009, Intel Corporation<BR> | |
5 | Portions copyright (c) 2008-2009 Apple Inc.<BR> | |
6 | All rights reserved. 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 | /** | |
57 | Performs an atomic decrement of an 32-bit unsigned integer. | |
58 | ||
59 | Performs an atomic decrement of the 32-bit unsigned integer specified by | |
60 | Value and returns the decremented value. The decrement operation must be | |
61 | performed using MP safe mechanisms. The state of the return value is not | |
62 | guaranteed to be MP safe. | |
63 | ||
64 | @param Value A pointer to the 32-bit value to decrement. | |
65 | ||
66 | @return The decremented value. | |
67 | ||
68 | **/ | |
69 | UINT32 | |
70 | EFIAPI | |
71 | InternalSyncDecrement ( | |
72 | IN volatile UINT32 *Value | |
73 | ) | |
74 | { | |
75 | UINT32 Result; | |
76 | ||
77 | __asm__ __volatile__ ( | |
78 | "lock \n\t" | |
79 | "decl %2 \n\t" | |
80 | "mov %2, %%eax " | |
81 | : "=a" (Result), // %0 | |
82 | "=m" (*Value) // %1 | |
83 | : "m" (*Value) // %2 | |
84 | : "memory", | |
85 | "cc" | |
86 | ); | |
87 | ||
88 | return Result; | |
89 | } | |
90 | ||
91 | ||
92 | /** | |
93 | Performs an atomic compare exchange operation on a 32-bit unsigned integer. | |
94 | ||
95 | Performs an atomic compare exchange operation on the 32-bit unsigned integer | |
96 | specified by Value. If Value is equal to CompareValue, then Value is set to | |
97 | ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue, | |
98 | then Value is returned. The compare exchange operation must be performed using | |
99 | MP safe mechanisms. | |
100 | ||
101 | ||
102 | @param Value A pointer to the 32-bit value for the compare exchange | |
103 | operation. | |
104 | @param CompareValue 32-bit value used in compare operation. | |
105 | @param ExchangeValue 32-bit value used in exchange operation. | |
106 | ||
107 | @return The original *Value before exchange. | |
108 | ||
109 | **/ | |
110 | UINT32 | |
111 | EFIAPI | |
112 | InternalSyncCompareExchange32 ( | |
113 | IN OUT volatile UINT32 *Value, | |
114 | IN UINT32 CompareValue, | |
115 | IN UINT32 ExchangeValue | |
116 | ) | |
117 | { | |
118 | // GCC 4.1 and forward supports atomic builtins | |
119 | #if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 1))) | |
120 | ||
121 | return __sync_val_compare_and_swap (Value, CompareValue, ExchangeValue); | |
122 | ||
123 | #else | |
124 | ||
125 | __asm__ __volatile__ ( | |
126 | "lock \n\t" | |
127 | "cmpxchgl %3, %1 " | |
128 | : "=a" (CompareValue), // %0 | |
129 | "=m" (*Value) // %1 | |
130 | : "a" (CompareValue), // %2 | |
131 | "r" (ExchangeValue), // %3 | |
132 | "m" (*Value) | |
133 | : "memory", | |
134 | "cc" | |
135 | ); | |
136 | ||
137 | return CompareValue; | |
138 | ||
139 | #endif | |
140 | } | |
141 | ||
142 | ||
143 | /** | |
144 | Performs an atomic compare exchange operation on a 64-bit unsigned integer. | |
145 | ||
146 | Performs an atomic compare exchange operation on the 64-bit unsigned integer specified | |
147 | by Value. If Value is equal to CompareValue, then Value is set to ExchangeValue and | |
148 | CompareValue is returned. If Value is not equal to CompareValue, then Value is returned. | |
149 | The compare exchange operation must be performed using MP safe mechanisms. | |
150 | ||
151 | ||
152 | @param Value A pointer to the 64-bit value for the compare exchange | |
153 | operation. | |
154 | @param CompareValue 64-bit value used in compare operation. | |
155 | @param ExchangeValue 64-bit value used in exchange operation. | |
156 | ||
157 | @return The original *Value before exchange. | |
158 | ||
159 | **/ | |
160 | UINT64 | |
161 | EFIAPI | |
162 | InternalSyncCompareExchange64 ( | |
163 | IN OUT volatile UINT64 *Value, | |
164 | IN UINT64 CompareValue, | |
165 | IN UINT64 ExchangeValue | |
166 | ) | |
167 | { | |
168 | // GCC 4.1 and forward supports atomic builtins | |
169 | #if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 1))) | |
170 | ||
171 | return __sync_val_compare_and_swap (Value, CompareValue, ExchangeValue); | |
172 | ||
173 | #else | |
174 | ||
175 | __asm__ __volatile__ ( | |
176 | "lock \n\t" | |
177 | "cmpxchgq %3, %1 " | |
178 | : "=a" (CompareValue), // %0 | |
179 | "=m" (*Value) // %1 | |
180 | : "a" (CompareValue), // %2 | |
181 | "r" (ExchangeValue), // %3 | |
182 | "m" (*Value) | |
183 | : "memory", | |
184 | "cc" | |
185 | ); | |
186 | ||
187 | return CompareValue; | |
188 | ||
189 | #endif | |
190 | } | |
191 | ||
192 |