1/*
2 * Copyright 2014, Paweł Dziepak, pdziepak@quarnos.org.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Alexander von Gluck IV <kallisti5@unixzen.com>
7 */
8#ifndef _KERNEL_ARCH_PPC_ATOMIC_H
9#define _KERNEL_ARCH_PPC_ATOMIC_H
10
11
12static inline void
13memory_read_barrier_inline(void)
14{
15	#ifdef __powerpc64__
16	asm volatile("lwsync" : : : "memory");
17	#else
18	asm volatile("sync" : : : "memory");
19	#endif
20}
21
22
23static inline void
24memory_write_barrier_inline(void)
25{
26	#ifdef __powerpc64__
27	asm volatile("lwsync" : : : "memory");
28	#else
29	asm volatile("eieio" : : : "memory");
30	#endif
31}
32
33
34static inline void
35memory_full_barrier_inline(void)
36{
37	asm volatile("sync" : : : "memory");
38}
39
40
41#define memory_read_barrier		memory_read_barrier_inline
42#define memory_write_barrier	memory_write_barrier_inline
43#define memory_full_barrier		memory_full_barrier_inline
44
45
46static inline void
47atomic_set_inline(int32* value, int32 newValue)
48{
49	memory_write_barrier();
50	*(volatile int32*)value = newValue;
51}
52
53
54static inline int32
55atomic_get_and_set_inline(int32* value, int32 newValue)
56{
57	// BIG TODO: PowerPC Atomic get and set
58//	asm volatile("xchgl %0, (%1)"
59//		: "+r" (newValue)
60//		: "r" (value)
61//		: "memory");
62	return newValue;
63}
64
65
66static inline int32
67atomic_test_and_set_inline(int32* value, int32 newValue, int32 testAgainst)
68{
69	// BIG TODO: PowerPC Atomic test and set inline
70//	asm volatile("lock; cmpxchgl %2, (%3)"
71//		: "=a" (newValue)
72//		: "0" (testAgainst), "r" (newValue), "r" (value)
73//		: "memory");
74	return newValue;
75}
76
77
78static inline int32
79atomic_add_inline(int32* value, int32 newValue)
80{
81	// BIG TODO: PowerPC Atomic add inline
82//	asm volatile("lock; xaddl %0, (%1)"
83//		: "+r" (newValue)
84//		: "r" (value)
85//		: "memory");
86	return newValue;
87}
88
89
90static inline int32
91atomic_get_inline(int32* value)
92{
93	int32 newValue = *(volatile int32*)value;
94	memory_read_barrier();
95	return newValue;
96}
97
98
99#define atomic_set				atomic_set_inline
100#define atomic_get_and_set		atomic_get_and_set_inline
101#ifndef atomic_test_and_set
102#	define atomic_test_and_set	atomic_test_and_set_inline
103#endif
104#ifndef atomic_add
105#	define atomic_add			atomic_add_inline
106#endif
107#define atomic_get				atomic_get_inline
108
109
110#endif	// _KERNEL_ARCH_PPC_ATOMIC_H
111