sys_linux_arm.s raw

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