]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S
MdePkg/BaseSynchronizationLib: Added proper support for ARM architecture
[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 //
5 // This program and the accompanying materials
6 // are licensed and made available under the terms and conditions of the BSD License
7 // which accompanies this distribution. The full text of the license may be found at
8 // http://opensource.org/licenses/bsd-license.php
9 //
10 // THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 //
13 //
14
15 .text
16 .align 3
17
18 GCC_ASM_EXPORT(InternalSyncCompareExchange32)
19 GCC_ASM_EXPORT(InternalSyncCompareExchange64)
20 GCC_ASM_EXPORT(InternalSyncIncrement)
21 GCC_ASM_EXPORT(InternalSyncDecrement)
22
23 /**
24 Performs an atomic compare exchange operation on a 32-bit unsigned integer.
25
26 Performs an atomic compare exchange operation on the 32-bit unsigned integer
27 specified by Value. If Value is equal to CompareValue, then Value is set to
28 ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue,
29 then Value is returned. The compare exchange operation must be performed using
30 MP safe mechanisms.
31
32 @param Value A pointer to the 32-bit value for the compare exchange
33 operation.
34 @param CompareValue 32-bit value used in compare operation.
35 @param ExchangeValue 32-bit value used in exchange operation.
36
37 @return The original *Value before exchange.
38
39 **/
40 //UINT32
41 //EFIAPI
42 //InternalSyncCompareExchange32 (
43 // IN volatile UINT32 *Value,
44 // IN UINT32 CompareValue,
45 // IN UINT32 ExchangeValue
46 // )
47 ASM_PFX(InternalSyncCompareExchange32):
48 dmb
49
50 InternalSyncCompareExchange32Again:
51 ldrex r3, [r0]
52 cmp r3, r1
53 bne InternalSyncCompareExchange32Fail
54
55 InternalSyncCompareExchange32Exchange:
56 strex ip, r2, [r0]
57 cmp ip, #0
58 bne InternalSyncCompareExchange32Again
59
60 InternalSyncCompareExchange32Fail:
61 dmb
62 mov r0, r3
63 bx lr
64
65 /**
66 Performs an atomic compare exchange operation on a 64-bit unsigned integer.
67
68 Performs an atomic compare exchange operation on the 64-bit unsigned integer specified
69 by Value. If Value is equal to CompareValue, then Value is set to ExchangeValue and
70 CompareValue is returned. If Value is not equal to CompareValue, then Value is returned.
71 The compare exchange operation must be performed using MP safe mechanisms.
72
73 @param Value A pointer to the 64-bit value for the compare exchange
74 operation.
75 @param CompareValue 64-bit value used in compare operation.
76 @param ExchangeValue 64-bit value used in exchange operation.
77
78 @return The original *Value before exchange.
79
80 **/
81 //UINT64
82 //EFIAPI
83 //InternalSyncCompareExchange64 (
84 // IN volatile UINT64 *Value, // r0
85 // IN UINT64 CompareValue, // r2-r3
86 // IN UINT64 ExchangeValue // stack
87 // )
88 ASM_PFX(InternalSyncCompareExchange64):
89 push { r4-r7 }
90 ldrd r4, r5, [sp, #16]
91 dmb
92
93 InternalSyncCompareExchange64Again:
94 ldrexd r6, r7, [r0]
95 cmp r6, r2
96 cmpeq r7, r3
97 bne InternalSyncCompareExchange64Fail
98
99 InternalSyncCompareExchange64Exchange:
100 strexd ip, r4, r5, [r0]
101 cmp ip, #0
102 bne InternalSyncCompareExchange64Again
103
104 InternalSyncCompareExchange64Fail:
105 dmb
106 mov r0, r6
107 mov r1, r7
108 pop { r4-r7 }
109 bx lr
110
111 /**
112 Performs an atomic increment of an 32-bit unsigned integer.
113
114 Performs an atomic increment of the 32-bit unsigned integer specified by
115 Value and returns the incremented value. The increment operation must be
116 performed using MP safe mechanisms. The state of the return value is not
117 guaranteed to be MP safe.
118
119 @param Value A pointer to the 32-bit value to increment.
120
121 @return The incremented value.
122
123 **/
124 //UINT32
125 //EFIAPI
126 //InternalSyncIncrement (
127 // IN volatile UINT32 *Value
128 // )
129 ASM_PFX(InternalSyncIncrement):
130 dmb
131 TryInternalSyncIncrement:
132 ldrex r1, [r0]
133 add r1, r1, #1
134 strex r2, r1, [r0]
135 cmp r2, #0
136 bne TryInternalSyncIncrement
137 dmb
138 bx lr
139
140 /**
141 Performs an atomic decrement of an 32-bit unsigned integer.
142
143 Performs an atomic decrement of the 32-bit unsigned integer specified by
144 Value and returns the decrement value. The decrement operation must be
145 performed using MP safe mechanisms. The state of the return value is not
146 guaranteed to be MP safe.
147
148 @param Value A pointer to the 32-bit value to decrement.
149
150 @return The decrement value.
151
152 **/
153 //UINT32
154 //EFIAPI
155 //InternalSyncDecrement (
156 // IN volatile UINT32 *Value
157 // )
158 ASM_PFX(InternalSyncDecrement):
159 dmb
160 TryInternalSyncDecrement:
161 ldrex r1, [r0]
162 sub r1, r1, #1
163 strex r2, r1, [r0]
164 cmp r2, #0
165 bne TryInternalSyncDecrement
166 dmb
167 bx lr