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 12 static inline void 13 memory_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 23 static inline void 24 memory_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 34 static inline void 35 memory_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 46 static inline void 47 atomic_set_inline(int32* value, int32 newValue) 48 { 49 memory_write_barrier(); 50 *(volatile int32*)value = newValue; 51 } 52 53 54 static inline int32 55 atomic_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 66 static inline int32 67 atomic_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 78 static inline int32 79 atomic_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 90 static inline int32 91 atomic_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