]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S
MdePkg: BaseSynchronizationLib: fix Increment/Decrement retvals for ARM
[mirror_edk2.git] / MdePkg / Library / BaseSynchronizationLib / Arm / Synchronization.S
CommitLineData
cc310428
OM
1// Implementation of synchronization functions for ARM architecture\r
2//\r
3// Copyright (c) 2012-2015, ARM Limited. All rights reserved.\r
9b89163e 4// Copyright (c) 2015, Linaro Limited. All rights reserved.\r
cc310428
OM
5//\r
6// This program and the accompanying materials\r
7// are licensed and made available under the terms and conditions of the BSD License\r
8// which accompanies this distribution. The full text of the license may be found at\r
9// http://opensource.org/licenses/bsd-license.php\r
10//\r
11// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13//\r
14//\r
15\r
16.text\r
17.align 3\r
18\r
9b89163e 19GCC_ASM_EXPORT(InternalSyncCompareExchange16)\r
cc310428
OM
20GCC_ASM_EXPORT(InternalSyncCompareExchange32)\r
21GCC_ASM_EXPORT(InternalSyncCompareExchange64)\r
22GCC_ASM_EXPORT(InternalSyncIncrement)\r
23GCC_ASM_EXPORT(InternalSyncDecrement)\r
24\r
9b89163e
AB
25/**\r
26 Performs an atomic compare exchange operation on a 16-bit unsigned integer.\r
27\r
28 Performs an atomic compare exchange operation on the 16-bit unsigned integer\r
29 specified by Value. If Value is equal to CompareValue, then Value is set to\r
30 ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,\r
31 then Value is returned. The compare exchange operation must be performed using\r
32 MP safe mechanisms.\r
33\r
34 @param Value A pointer to the 16-bit value for the compare exchange\r
35 operation.\r
36 @param CompareValue 16-bit value used in compare operation.\r
37 @param ExchangeValue 16-bit value used in exchange operation.\r
38\r
39 @return The original *Value before exchange.\r
40\r
41**/\r
42//UINT16\r
43//EFIAPI\r
44//InternalSyncCompareExchange16 (\r
45// IN volatile UINT16 *Value,\r
46// IN UINT16 CompareValue,\r
47// IN UINT16 ExchangeValue\r
48// )\r
49ASM_PFX(InternalSyncCompareExchange16):\r
50 dmb\r
51\r
52InternalSyncCompareExchange16Again:\r
53 ldrexh r3, [r0]\r
54 cmp r3, r1\r
55 bne InternalSyncCompareExchange16Fail\r
56\r
57InternalSyncCompareExchange16Exchange:\r
58 strexh ip, r2, [r0]\r
59 cmp ip, #0\r
60 bne InternalSyncCompareExchange16Again\r
61\r
62InternalSyncCompareExchange16Fail:\r
63 dmb\r
64 mov r0, r3\r
65 bx lr\r
66\r
cc310428
OM
67/**\r
68 Performs an atomic compare exchange operation on a 32-bit unsigned integer.\r
69\r
70 Performs an atomic compare exchange operation on the 32-bit unsigned integer\r
71 specified by Value. If Value is equal to CompareValue, then Value is set to\r
72 ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,\r
73 then Value is returned. The compare exchange operation must be performed using\r
74 MP safe mechanisms.\r
75\r
76 @param Value A pointer to the 32-bit value for the compare exchange\r
77 operation.\r
78 @param CompareValue 32-bit value used in compare operation.\r
79 @param ExchangeValue 32-bit value used in exchange operation.\r
80\r
81 @return The original *Value before exchange.\r
82\r
83**/\r
84//UINT32\r
85//EFIAPI\r
86//InternalSyncCompareExchange32 (\r
87// IN volatile UINT32 *Value,\r
88// IN UINT32 CompareValue,\r
89// IN UINT32 ExchangeValue\r
90// )\r
91ASM_PFX(InternalSyncCompareExchange32):\r
92 dmb\r
93\r
94InternalSyncCompareExchange32Again:\r
95 ldrex r3, [r0]\r
96 cmp r3, r1\r
97 bne InternalSyncCompareExchange32Fail\r
98\r
99InternalSyncCompareExchange32Exchange:\r
100 strex ip, r2, [r0]\r
101 cmp ip, #0\r
102 bne InternalSyncCompareExchange32Again\r
103\r
104InternalSyncCompareExchange32Fail:\r
105 dmb\r
106 mov r0, r3\r
107 bx lr\r
108\r
109/**\r
110 Performs an atomic compare exchange operation on a 64-bit unsigned integer.\r
111\r
112 Performs an atomic compare exchange operation on the 64-bit unsigned integer specified\r
113 by Value. If Value is equal to CompareValue, then Value is set to ExchangeValue and\r
114 CompareValue is returned. If Value is not equal to CompareValue, then Value is returned.\r
115 The compare exchange operation must be performed using MP safe mechanisms.\r
116\r
117 @param Value A pointer to the 64-bit value for the compare exchange\r
118 operation.\r
119 @param CompareValue 64-bit value used in compare operation.\r
120 @param ExchangeValue 64-bit value used in exchange operation.\r
121\r
122 @return The original *Value before exchange.\r
123\r
124**/\r
125//UINT64\r
126//EFIAPI\r
127//InternalSyncCompareExchange64 (\r
128// IN volatile UINT64 *Value, // r0\r
129// IN UINT64 CompareValue, // r2-r3\r
130// IN UINT64 ExchangeValue // stack\r
131// )\r
132ASM_PFX(InternalSyncCompareExchange64):\r
133 push { r4-r7 }\r
134 ldrd r4, r5, [sp, #16]\r
135 dmb\r
136\r
137InternalSyncCompareExchange64Again:\r
138 ldrexd r6, r7, [r0]\r
139 cmp r6, r2\r
140 cmpeq r7, r3\r
141 bne InternalSyncCompareExchange64Fail\r
142\r
143InternalSyncCompareExchange64Exchange:\r
144 strexd ip, r4, r5, [r0]\r
145 cmp ip, #0\r
146 bne InternalSyncCompareExchange64Again\r
147\r
148InternalSyncCompareExchange64Fail:\r
149 dmb\r
150 mov r0, r6\r
151 mov r1, r7\r
152 pop { r4-r7 }\r
153 bx lr\r
154\r
155/**\r
156 Performs an atomic increment of an 32-bit unsigned integer.\r
157\r
158 Performs an atomic increment of the 32-bit unsigned integer specified by\r
159 Value and returns the incremented value. The increment operation must be\r
160 performed using MP safe mechanisms. The state of the return value is not\r
161 guaranteed to be MP safe.\r
162\r
163 @param Value A pointer to the 32-bit value to increment.\r
164\r
165 @return The incremented value.\r
166\r
167**/\r
168//UINT32\r
169//EFIAPI\r
170//InternalSyncIncrement (\r
171// IN volatile UINT32 *Value\r
172// )\r
173ASM_PFX(InternalSyncIncrement):\r
174 dmb\r
175TryInternalSyncIncrement:\r
176 ldrex r1, [r0]\r
177 add r1, r1, #1\r
178 strex r2, r1, [r0]\r
179 cmp r2, #0\r
180 bne TryInternalSyncIncrement\r
181 dmb\r
f61762d0 182 mov r0, r1\r
cc310428
OM
183 bx lr\r
184\r
185/**\r
186 Performs an atomic decrement of an 32-bit unsigned integer.\r
187\r
188 Performs an atomic decrement of the 32-bit unsigned integer specified by\r
189 Value and returns the decrement value. The decrement operation must be\r
190 performed using MP safe mechanisms. The state of the return value is not\r
191 guaranteed to be MP safe.\r
192\r
193 @param Value A pointer to the 32-bit value to decrement.\r
194\r
195 @return The decrement value.\r
196\r
197**/\r
198//UINT32\r
199//EFIAPI\r
200//InternalSyncDecrement (\r
201// IN volatile UINT32 *Value\r
202// )\r
203ASM_PFX(InternalSyncDecrement):\r
204 dmb\r
205TryInternalSyncDecrement:\r
206 ldrex r1, [r0]\r
207 sub r1, r1, #1\r
208 strex r2, r1, [r0]\r
209 cmp r2, #0\r
210 bne TryInternalSyncDecrement\r
211 dmb\r
f61762d0 212 mov r0, r1\r
cc310428 213 bx lr\r