]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S
MdePkg/BaseSynchronizationLib: fix AArch64 return values
[mirror_edk2.git] / MdePkg / Library / BaseSynchronizationLib / AArch64 / Synchronization.S
1 // Implementation of synchronization functions for ARM architecture (AArch64)
2 //
3 // Copyright (c) 2012-2015, ARM Limited. All rights reserved.
4 // Copyright (c) 2015, Linaro Limited. All rights reserved.
5 //
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 .text
17 .align 3
18
19 GCC_ASM_EXPORT(InternalSyncCompareExchange16)
20 GCC_ASM_EXPORT(InternalSyncCompareExchange32)
21 GCC_ASM_EXPORT(InternalSyncCompareExchange64)
22 GCC_ASM_EXPORT(InternalSyncIncrement)
23 GCC_ASM_EXPORT(InternalSyncDecrement)
24
25 /**
26 Performs an atomic compare exchange operation on a 16-bit unsigned integer.
27
28 Performs an atomic compare exchange operation on the 16-bit unsigned integer
29 specified by Value. If Value is equal to CompareValue, then Value is set to
30 ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
31 then Value is returned. The compare exchange operation must be performed using
32 MP safe mechanisms.
33
34 @param Value A pointer to the 16-bit value for the compare exchange
35 operation.
36 @param CompareValue 16-bit value used in compare operation.
37 @param ExchangeValue 16-bit value used in exchange operation.
38
39 @return The original *Value before exchange.
40
41 **/
42 //UINT16
43 //EFIAPI
44 //InternalSyncCompareExchange16 (
45 // IN volatile UINT16 *Value,
46 // IN UINT16 CompareValue,
47 // IN UINT16 ExchangeValue
48 // )
49 ASM_PFX(InternalSyncCompareExchange16):
50 uxth w1, w1
51 uxth w2, w2
52 dmb sy
53
54 InternalSyncCompareExchange16Again:
55 ldxrh w3, [x0]
56 cmp w3, w1
57 bne InternalSyncCompareExchange16Fail
58
59 InternalSyncCompareExchange16Exchange:
60 stxrh w4, w2, [x0]
61 cbnz w4, InternalSyncCompareExchange16Again
62
63 InternalSyncCompareExchange16Fail:
64 dmb sy
65 mov w0, w3
66 ret
67
68 /**
69 Performs an atomic compare exchange operation on a 32-bit unsigned integer.
70
71 Performs an atomic compare exchange operation on the 32-bit unsigned integer
72 specified by Value. If Value is equal to CompareValue, then Value is set to
73 ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
74 then Value is returned. The compare exchange operation must be performed using
75 MP safe mechanisms.
76
77 @param Value A pointer to the 32-bit value for the compare exchange
78 operation.
79 @param CompareValue 32-bit value used in compare operation.
80 @param ExchangeValue 32-bit value used in exchange operation.
81
82 @return The original *Value before exchange.
83
84 **/
85 //UINT32
86 //EFIAPI
87 //InternalSyncCompareExchange32 (
88 // IN volatile UINT32 *Value,
89 // IN UINT32 CompareValue,
90 // IN UINT32 ExchangeValue
91 // )
92 ASM_PFX(InternalSyncCompareExchange32):
93 dmb sy
94
95 InternalSyncCompareExchange32Again:
96 ldxr w3, [x0]
97 cmp w3, w1
98 bne InternalSyncCompareExchange32Fail
99
100 InternalSyncCompareExchange32Exchange:
101 stxr w4, w2, [x0]
102 cbnz w4, InternalSyncCompareExchange32Again
103
104 InternalSyncCompareExchange32Fail:
105 dmb sy
106 mov w0, w3
107 ret
108
109 /**
110 Performs an atomic compare exchange operation on a 64-bit unsigned integer.
111
112 Performs an atomic compare exchange operation on the 64-bit unsigned integer specified
113 by Value. If Value is equal to CompareValue, then Value is set to ExchangeValue and
114 CompareValue is returned. If Value is not equal to CompareValue, then Value is returned.
115 The compare exchange operation must be performed using MP safe mechanisms.
116
117 @param Value A pointer to the 64-bit value for the compare exchange
118 operation.
119 @param CompareValue 64-bit value used in compare operation.
120 @param ExchangeValue 64-bit value used in exchange operation.
121
122 @return The original *Value before exchange.
123
124 **/
125 //UINT64
126 //EFIAPI
127 //InternalSyncCompareExchange64 (
128 // IN volatile UINT64 *Value,
129 // IN UINT64 CompareValue,
130 // IN UINT64 ExchangeValue
131 // )
132 ASM_PFX(InternalSyncCompareExchange64):
133 dmb sy
134
135 InternalSyncCompareExchange64Again:
136 ldxr x3, [x0]
137 cmp x3, x1
138 bne InternalSyncCompareExchange64Fail
139
140 InternalSyncCompareExchange64Exchange:
141 stxr w4, x2, [x0]
142 cbnz w4, InternalSyncCompareExchange64Again
143
144 InternalSyncCompareExchange64Fail:
145 dmb sy
146 mov x0, x3
147 ret
148
149 /**
150 Performs an atomic increment of an 32-bit unsigned integer.
151
152 Performs an atomic increment of the 32-bit unsigned integer specified by
153 Value and returns the incremented value. The increment operation must be
154 performed using MP safe mechanisms. The state of the return value is not
155 guaranteed to be MP safe.
156
157 @param Value A pointer to the 32-bit value to increment.
158
159 @return The incremented value.
160
161 **/
162 //UINT32
163 //EFIAPI
164 //InternalSyncIncrement (
165 // IN volatile UINT32 *Value
166 // )
167 ASM_PFX(InternalSyncIncrement):
168 dmb sy
169 TryInternalSyncIncrement:
170 ldxr w1, [x0]
171 add w1, w1, #1
172 stxr w2, w1, [x0]
173 cbnz w2, TryInternalSyncIncrement
174 mov w0, w1
175 dmb sy
176 ret
177
178 /**
179 Performs an atomic decrement of an 32-bit unsigned integer.
180
181 Performs an atomic decrement of the 32-bit unsigned integer specified by
182 Value and returns the decrement value. The decrement operation must be
183 performed using MP safe mechanisms. The state of the return value is not
184 guaranteed to be MP safe.
185
186 @param Value A pointer to the 32-bit value to decrement.
187
188 @return The decrement value.
189
190 **/
191 //UINT32
192 //EFIAPI
193 //InternalSyncDecrement (
194 // IN volatile UINT32 *Value
195 // )
196 ASM_PFX(InternalSyncDecrement):
197 dmb sy
198 TryInternalSyncDecrement:
199 ldxr w1, [x0]
200 sub w1, w1, #1
201 stxr w2, w1, [x0]
202 cbnz w2, TryInternalSyncDecrement
203 mov w0, w1
204 dmb sy
205 ret