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