Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
[linux-2.6-microblaze.git] / arch / csky / kernel / atomic.S
1 /* SPDX-License-Identifier: GPL-2.0 */
2 // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
3
4 #include <linux/linkage.h>
5 #include <abi/entry.h>
6
7 .text
8
9 /*
10  * int csky_cmpxchg(int oldval, int newval, int *ptr)
11  *
12  * If *ptr != oldval && return 1,
13  * else *ptr = newval return 0.
14  */
15 ENTRY(csky_cmpxchg)
16         USPTOKSP
17
18         RD_MEH  a3
19         WR_MEH  a3
20
21         mfcr    a3, epc
22         addi    a3, TRAP0_SIZE
23
24         subi    sp, 16
25         stw     a3, (sp, 0)
26         mfcr    a3, epsr
27         stw     a3, (sp, 4)
28         mfcr    a3, usp
29         stw     a3, (sp, 8)
30
31         psrset  ee
32 #ifdef CONFIG_CPU_HAS_LDSTEX
33 1:
34         ldex    a3, (a2)
35         cmpne   a0, a3
36         bt16    2f
37         mov     a3, a1
38         stex    a3, (a2)
39         bez     a3, 1b
40 2:
41         sync.is
42 #else
43 GLOBAL(csky_cmpxchg_ldw)
44         ldw     a3, (a2)
45         cmpne   a0, a3
46         bt16    3f
47 GLOBAL(csky_cmpxchg_stw)
48         stw     a1, (a2)
49 3:
50 #endif
51         mvc     a0
52         ldw     a3, (sp, 0)
53         mtcr    a3, epc
54         ldw     a3, (sp, 4)
55         mtcr    a3, epsr
56         ldw     a3, (sp, 8)
57         mtcr    a3, usp
58         addi    sp, 16
59         KSPTOUSP
60         rte
61 END(csky_cmpxchg)