1 /*
2 * Atomics xchg/cmpxchg for PKUnity SoC and UniCore ISA
3 *
4 * Copyright (C) 2001-2012 GUAN Xue-tao
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10 #ifndef __UNICORE_CMPXCHG_H__
11 #define __UNICORE_CMPXCHG_H__
12
13 /*
14 * Generate a link failure on undefined symbol if the pointer points to a value
15 * of unsupported size.
16 */
17 extern void __xchg_bad_pointer(void);
18
__xchg(unsigned long x,volatile void * ptr,int size)19 static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
20 int size)
21 {
22 unsigned long ret;
23
24 switch (size) {
25 case 1:
26 asm volatile("swapb %0, %1, [%2]"
27 : "=&r" (ret)
28 : "r" (x), "r" (ptr)
29 : "memory", "cc");
30 break;
31 case 4:
32 asm volatile("swapw %0, %1, [%2]"
33 : "=&r" (ret)
34 : "r" (x), "r" (ptr)
35 : "memory", "cc");
36 break;
37 default:
38 __xchg_bad_pointer();
39 }
40
41 return ret;
42 }
43
44 #define xchg(ptr, x) \
45 ((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), sizeof(*(ptr))))
46
47 #include <asm-generic/cmpxchg-local.h>
48
49 /*
50 * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
51 * them available.
52 */
53 #define cmpxchg_local(ptr, o, n) \
54 ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), \
55 (unsigned long)(o), (unsigned long)(n), sizeof(*(ptr))))
56 #define cmpxchg64_local(ptr, o, n) \
57 __cmpxchg64_local_generic((ptr), (o), (n))
58
59 #include <asm-generic/cmpxchg.h>
60
61 #endif /* __UNICORE_CMPXCHG_H__ */
62