github.com/primecitizens/pcz/std@v0.2.1/core/atomic/sys_linux_arm.s (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright 2023 The Prime Citizens 3 // 4 // Copyright 2015 The Go Authors. All rights reserved. 5 // Use of this source code is governed by a BSD-style 6 // license that can be found in the LICENSE file. 7 8 //go:build arm && linux 9 10 #include "textflag.h" 11 12 // Linux/ARM atomic operations. 13 14 // Because there is so much variation in ARM devices, 15 // the Linux kernel provides an appropriate compare-and-swap 16 // implementation at address 0xffff0fc0. Caller sets: 17 // R0 = old value 18 // R1 = new value 19 // R2 = addr 20 // LR = return address 21 // The function returns with CS true if the swap happened. 22 // http://lxr.linux.no/linux+v2.6.37.2/arch/arm/kernel/entry-armv.S#L850 23 // 24 // https://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=b49c0f24cf6744a3f4fd09289fe7cade349dead5 25 // 26 TEXT cas<>(SB),NOSPLIT,$0 27 MOVW $0xffff0fc0, R15 // R15 is hardware PC. 28 29 TEXT ·Cas(SB),NOSPLIT|NOFRAME,$0 30 MOVB runtime·goarm(SB), R11 31 CMP $7, R11 32 BLT 2(PC) 33 JMP ·armcas(SB) 34 JMP kernelcas<>(SB) 35 36 TEXT kernelcas<>(SB),NOSPLIT,$0 37 MOVW ptr+0(FP), R2 38 // trigger potential paging fault here, 39 // because we don't know how to traceback through __kuser_cmpxchg 40 MOVW (R2), R0 41 MOVW old+4(FP), R0 42 MOVW new+8(FP), R1 43 BL cas<>(SB) 44 BCC ret0 45 MOVW $1, R0 46 MOVB R0, ret+12(FP) 47 RET 48 ret0: 49 MOVW $0, R0 50 MOVB R0, ret+12(FP) 51 RET 52 53 // As for cas, memory barriers are complicated on ARM, but the kernel 54 // provides a user helper. ARMv5 does not support SMP and has no 55 // memory barrier instruction at all. ARMv6 added SMP support and has 56 // a memory barrier, but it requires writing to a coprocessor 57 // register. ARMv7 introduced the DMB instruction, but it's expensive 58 // even on single-core devices. The kernel helper takes care of all of 59 // this for us. 60 61 // Use kernel helper version of memory_barrier, when compiled with GOARM < 7. 62 TEXT memory_barrier<>(SB),NOSPLIT|NOFRAME,$0 63 MOVW $0xffff0fa0, R15 // R15 is hardware PC. 64 65 TEXT ·Load32(SB),NOSPLIT,$0-8 66 MOVW addr+0(FP), R0 67 MOVW (R0), R1 68 69 MOVB runtime·goarm(SB), R11 70 CMP $7, R11 71 BGE native_barrier 72 BL memory_barrier<>(SB) 73 B end 74 native_barrier: 75 DMB MB_ISH 76 end: 77 MOVW R1, ret+4(FP) 78 RET 79 80 TEXT ·Store(SB),NOSPLIT,$0-8 81 MOVW addr+0(FP), R1 82 MOVW v+4(FP), R2 83 84 MOVB runtime·goarm(SB), R8 85 CMP $7, R8 86 BGE native_barrier 87 BL memory_barrier<>(SB) 88 B store 89 native_barrier: 90 DMB MB_ISH 91 92 store: 93 MOVW R2, (R1) 94 95 CMP $7, R8 96 BGE native_barrier2 97 BL memory_barrier<>(SB) 98 RET 99 native_barrier2: 100 DMB MB_ISH 101 RET 102 103 TEXT ·Load8(SB),NOSPLIT,$0-5 104 MOVW addr+0(FP), R0 105 MOVB (R0), R1 106 107 MOVB runtime·goarm(SB), R11 108 CMP $7, R11 109 BGE native_barrier 110 BL memory_barrier<>(SB) 111 B end 112 native_barrier: 113 DMB MB_ISH 114 end: 115 MOVB R1, ret+4(FP) 116 RET 117 118 TEXT ·Store8(SB),NOSPLIT,$0-5 119 MOVW addr+0(FP), R1 120 MOVB v+4(FP), R2 121 122 MOVB runtime·goarm(SB), R8 123 CMP $7, R8 124 BGE native_barrier 125 BL memory_barrier<>(SB) 126 B store 127 native_barrier: 128 DMB MB_ISH 129 130 store: 131 MOVB R2, (R1) 132 133 CMP $7, R8 134 BGE native_barrier2 135 BL memory_barrier<>(SB) 136 RET 137 native_barrier2: 138 DMB MB_ISH 139 RET