David Brazdil | 0f672f6 | 2019-12-10 10:32:29 +0000 | [diff] [blame^] | 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 | mfcr a3, epc |
| 18 | addi a3, TRAP0_SIZE |
| 19 | |
| 20 | subi sp, 8 |
| 21 | stw a3, (sp, 0) |
| 22 | mfcr a3, epsr |
| 23 | stw a3, (sp, 4) |
| 24 | |
| 25 | psrset ee |
| 26 | #ifdef CONFIG_CPU_HAS_LDSTEX |
| 27 | 1: |
| 28 | ldex a3, (a2) |
| 29 | cmpne a0, a3 |
| 30 | bt16 2f |
| 31 | mov a3, a1 |
| 32 | stex a3, (a2) |
| 33 | bez a3, 1b |
| 34 | 2: |
| 35 | sync.is |
| 36 | #else |
| 37 | 1: |
| 38 | ldw a3, (a2) |
| 39 | cmpne a0, a3 |
| 40 | bt16 3f |
| 41 | 2: |
| 42 | stw a1, (a2) |
| 43 | 3: |
| 44 | #endif |
| 45 | mvc a0 |
| 46 | ldw a3, (sp, 0) |
| 47 | mtcr a3, epc |
| 48 | ldw a3, (sp, 4) |
| 49 | mtcr a3, epsr |
| 50 | addi sp, 8 |
| 51 | KSPTOUSP |
| 52 | rte |
| 53 | END(csky_cmpxchg) |
| 54 | |
| 55 | #ifndef CONFIG_CPU_HAS_LDSTEX |
| 56 | /* |
| 57 | * Called from tlbmodified exception |
| 58 | */ |
| 59 | ENTRY(csky_cmpxchg_fixup) |
| 60 | mfcr a0, epc |
| 61 | lrw a1, 2b |
| 62 | cmpne a1, a0 |
| 63 | bt 1f |
| 64 | subi a1, (2b - 1b) |
| 65 | stw a1, (sp, LSAVE_PC) |
| 66 | 1: |
| 67 | rts |
| 68 | END(csky_cmpxchg_fixup) |
| 69 | #endif |