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 EXPORT InternalSyncCompareExchange16 17 EXPORT InternalSyncCompareExchange32 18 EXPORT InternalSyncCompareExchange64 19 EXPORT InternalSyncIncrement 20 EXPORT InternalSyncDecrement 21 22 AREA ArmSynchronization, CODE, READONLY 23 24/** 25 Performs an atomic compare exchange operation on a 16-bit unsigned integer. 26 27 Performs an atomic compare exchange operation on the 16-bit unsigned integer 28 specified by Value. If Value is equal to CompareValue, then Value is set to 29 ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue, 30 then Value is returned. The compare exchange operation must be performed using 31 MP safe mechanisms. 32 33 @param Value A pointer to the 16-bit value for the compare exchange 34 operation. 35 @param CompareValue 16-bit value used in compare operation. 36 @param ExchangeValue 16-bit value used in exchange operation. 37 38 @return The original *Value before exchange. 39 40**/ 41//UINT16 42//EFIAPI 43//InternalSyncCompareExchange16 ( 44// IN volatile UINT16 *Value, 45// IN UINT16 CompareValue, 46// IN UINT16 ExchangeValue 47// ) 48InternalSyncCompareExchange16 49 dmb 50 51InternalSyncCompareExchange16Again 52 ldrexh r3, [r0] 53 cmp r3, r1 54 bne InternalSyncCompareExchange16Fail 55 56InternalSyncCompareExchange16Exchange 57 strexh ip, r2, [r0] 58 cmp ip, #0 59 bne InternalSyncCompareExchange16Again 60 61InternalSyncCompareExchange16Fail 62 dmb 63 mov r0, r3 64 bx lr 65 66/** 67 Performs an atomic compare exchange operation on a 32-bit unsigned integer. 68 69 Performs an atomic compare exchange operation on the 32-bit unsigned integer 70 specified by Value. If Value is equal to CompareValue, then Value is set to 71 ExchangeValue and CompareValue is returned. If Value is not equal to CompareValue, 72 then Value is returned. The compare exchange operation must be performed using 73 MP safe mechanisms. 74 75 @param Value A pointer to the 32-bit value for the compare exchange 76 operation. 77 @param CompareValue 32-bit value used in compare operation. 78 @param ExchangeValue 32-bit value used in exchange operation. 79 80 @return The original *Value before exchange. 81 82**/ 83//UINT32 84//EFIAPI 85//InternalSyncCompareExchange32 ( 86// IN volatile UINT32 *Value, 87// IN UINT32 CompareValue, 88// IN UINT32 ExchangeValue 89// ) 90InternalSyncCompareExchange32 91 dmb 92 93InternalSyncCompareExchange32Again 94 ldrex r3, [r0] 95 cmp r3, r1 96 bne InternalSyncCompareExchange32Fail 97 98InternalSyncCompareExchange32Exchange 99 strex ip, r2, [r0] 100 cmp ip, #0 101 bne InternalSyncCompareExchange32Again 102 103InternalSyncCompareExchange32Fail 104 dmb 105 mov r0, r3 106 bx lr 107 108/** 109 Performs an atomic compare exchange operation on a 64-bit unsigned integer. 110 111 Performs an atomic compare exchange operation on the 64-bit unsigned integer specified 112 by Value. If Value is equal to CompareValue, then Value is set to ExchangeValue and 113 CompareValue is returned. If Value is not equal to CompareValue, then Value is returned. 114 The compare exchange operation must be performed using MP safe mechanisms. 115 116 @param Value A pointer to the 64-bit value for the compare exchange 117 operation. 118 @param CompareValue 64-bit value used in compare operation. 119 @param ExchangeValue 64-bit value used in exchange operation. 120 121 @return The original *Value before exchange. 122 123**/ 124//UINT64 125//EFIAPI 126//InternalSyncCompareExchange64 ( 127// IN volatile UINT64 *Value, // r0 128// IN UINT64 CompareValue, // r2-r3 129// IN UINT64 ExchangeValue // stack 130// ) 131InternalSyncCompareExchange64 132 push { r4-r7 } 133 ldrd r4, r5, [sp, #16] 134 dmb 135 136InternalSyncCompareExchange64Again 137 ldrexd r6, r7, [r0] 138 cmp r6, r2 139 cmpeq r7, r3 140 bne InternalSyncCompareExchange64Fail 141 142InternalSyncCompareExchange64Exchange 143 strexd ip, r4, r5, [r0] 144 cmp ip, #0 145 bne InternalSyncCompareExchange64Again 146 147InternalSyncCompareExchange64Fail 148 dmb 149 mov r0, r6 150 mov r1, r7 151 pop { r4-r7 } 152 bx lr 153 154/** 155 Performs an atomic increment of an 32-bit unsigned integer. 156 157 Performs an atomic increment of the 32-bit unsigned integer specified by 158 Value and returns the incremented value. The increment operation must be 159 performed using MP safe mechanisms. The state of the return value is not 160 guaranteed to be MP safe. 161 162 @param Value A pointer to the 32-bit value to increment. 163 164 @return The incremented value. 165 166**/ 167//UINT32 168//EFIAPI 169//InternalSyncIncrement ( 170// IN volatile UINT32 *Value 171// ) 172InternalSyncIncrement 173 dmb 174TryInternalSyncIncrement 175 ldrex r1, [r0] 176 add r1, r1, #1 177 strex r2, r1, [r0] 178 cmp r2, #0 179 bne TryInternalSyncIncrement 180 dmb 181 mov r0, r1 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// ) 202InternalSyncDecrement 203 dmb 204TryInternalSyncDecrement 205 ldrex r1, [r0] 206 sub r1, r1, #1 207 strex r2, r1, [r0] 208 cmp r2, #0 209 bne TryInternalSyncDecrement 210 dmb 211 mov r0, r1 212 bx lr 213 214 END 215