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
19GCC_ASM_EXPORT(InternalSyncCompareExchange16)
20GCC_ASM_EXPORT(InternalSyncCompareExchange32)
21GCC_ASM_EXPORT(InternalSyncCompareExchange64)
22GCC_ASM_EXPORT(InternalSyncIncrement)
23GCC_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//  )
49ASM_PFX(InternalSyncCompareExchange16):
50  uxth    w1, w1
51  uxth    w2, w2
52  dmb     sy
53
54InternalSyncCompareExchange16Again:
55  ldxrh   w3, [x0]
56  cmp     w3, w1
57  bne     InternalSyncCompareExchange16Fail
58
59InternalSyncCompareExchange16Exchange:
60  stxrh   w4, w2, [x0]
61  cbnz    w4, InternalSyncCompareExchange16Again
62
63InternalSyncCompareExchange16Fail:
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//  )
92ASM_PFX(InternalSyncCompareExchange32):
93  dmb     sy
94
95InternalSyncCompareExchange32Again:
96  ldxr    w3, [x0]
97  cmp     w3, w1
98  bne     InternalSyncCompareExchange32Fail
99
100InternalSyncCompareExchange32Exchange:
101  stxr    w4, w2, [x0]
102  cbnz    w4, InternalSyncCompareExchange32Again
103
104InternalSyncCompareExchange32Fail:
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//  )
132ASM_PFX(InternalSyncCompareExchange64):
133  dmb     sy
134
135InternalSyncCompareExchange64Again:
136  ldxr    x3, [x0]
137  cmp     x3, x1
138  bne     InternalSyncCompareExchange64Fail
139
140InternalSyncCompareExchange64Exchange:
141  stxr    w4, x2, [x0]
142  cbnz    w4, InternalSyncCompareExchange64Again
143
144InternalSyncCompareExchange64Fail:
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//  )
167ASM_PFX(InternalSyncIncrement):
168  dmb     sy
169TryInternalSyncIncrement:
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//  )
196ASM_PFX(InternalSyncDecrement):
197  dmb     sy
198TryInternalSyncDecrement:
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
206