]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S
MdePkg/BaseSynchronizationLib: Add InterlockedCompareExchange16
[mirror_edk2.git] / MdePkg / Library / BaseSynchronizationLib / Arm / Synchronization.S
1 // Implementation of synchronization functions for ARM architecture
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 dmb
51
52 InternalSyncCompareExchange16Again:
53 ldrexh r3, [r0]
54 cmp r3, r1
55 bne InternalSyncCompareExchange16Fail
56
57 InternalSyncCompareExchange16Exchange:
58 strexh ip, r2, [r0]
59 cmp ip, #0
60 bne InternalSyncCompareExchange16Again
61
62 InternalSyncCompareExchange16Fail:
63 dmb
64 mov r0, r3
65 bx lr
66
67 /**
68 Performs an atomic compare exchange operation on a 32-bit unsigned integer.
69
70 Performs an atomic compare exchange operation on the 32-bit unsigned integer
71 specified by Value. If Value is equal to CompareValue, then Value is set to
72 ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
73 then Value is returned. The compare exchange operation must be performed using
74 MP safe mechanisms.
75
76 @param Value A pointer to the 32-bit value for the compare exchange
77 operation.
78 @param CompareValue 32-bit value used in compare operation.
79 @param ExchangeValue 32-bit value used in exchange operation.
80
81 @return The original *Value before exchange.
82
83 **/
84 //UINT32
85 //EFIAPI
86 //InternalSyncCompareExchange32 (
87 // IN volatile UINT32 *Value,
88 // IN UINT32 CompareValue,
89 // IN UINT32 ExchangeValue
90 // )
91 ASM_PFX(InternalSyncCompareExchange32):
92 dmb
93
94 InternalSyncCompareExchange32Again:
95 ldrex r3, [r0]
96 cmp r3, r1
97 bne InternalSyncCompareExchange32Fail
98
99 InternalSyncCompareExchange32Exchange:
100 strex ip, r2, [r0]
101 cmp ip, #0
102 bne InternalSyncCompareExchange32Again
103
104 InternalSyncCompareExchange32Fail:
105 dmb
106 mov r0, r3
107 bx lr
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, // r0
129 // IN UINT64 CompareValue, // r2-r3
130 // IN UINT64 ExchangeValue // stack
131 // )
132 ASM_PFX(InternalSyncCompareExchange64):
133 push { r4-r7 }
134 ldrd r4, r5, [sp, #16]
135 dmb
136
137 InternalSyncCompareExchange64Again:
138 ldrexd r6, r7, [r0]
139 cmp r6, r2
140 cmpeq r7, r3
141 bne InternalSyncCompareExchange64Fail
142
143 InternalSyncCompareExchange64Exchange:
144 strexd ip, r4, r5, [r0]
145 cmp ip, #0
146 bne InternalSyncCompareExchange64Again
147
148 InternalSyncCompareExchange64Fail:
149 dmb
150 mov r0, r6
151 mov r1, r7
152 pop { r4-r7 }
153 bx lr
154
155 /**
156 Performs an atomic increment of an 32-bit unsigned integer.
157
158 Performs an atomic increment of the 32-bit unsigned integer specified by
159 Value and returns the incremented value. The increment operation must be
160 performed using MP safe mechanisms. The state of the return value is not
161 guaranteed to be MP safe.
162
163 @param Value A pointer to the 32-bit value to increment.
164
165 @return The incremented value.
166
167 **/
168 //UINT32
169 //EFIAPI
170 //InternalSyncIncrement (
171 // IN volatile UINT32 *Value
172 // )
173 ASM_PFX(InternalSyncIncrement):
174 dmb
175 TryInternalSyncIncrement:
176 ldrex r1, [r0]
177 add r1, r1, #1
178 strex r2, r1, [r0]
179 cmp r2, #0
180 bne TryInternalSyncIncrement
181 dmb
182 bx lr
183
184 /**
185 Performs an atomic decrement of an 32-bit unsigned integer.
186
187 Performs an atomic decrement of the 32-bit unsigned integer specified by
188 Value and returns the decrement value. The decrement operation must be
189 performed using MP safe mechanisms. The state of the return value is not
190 guaranteed to be MP safe.
191
192 @param Value A pointer to the 32-bit value to decrement.
193
194 @return The decrement value.
195
196 **/
197 //UINT32
198 //EFIAPI
199 //InternalSyncDecrement (
200 // IN volatile UINT32 *Value
201 // )
202 ASM_PFX(InternalSyncDecrement):
203 dmb
204 TryInternalSyncDecrement:
205 ldrex r1, [r0]
206 sub r1, r1, #1
207 strex r2, r1, [r0]
208 cmp r2, #0
209 bne TryInternalSyncDecrement
210 dmb
211 bx lr