diff --git a/headers/private/kernel/arch/ppc/arch_atomic.h b/headers/private/kernel/arch/ppc/arch_atomic.h new file mode 100644 index 0000000000..2a4241ef32 --- /dev/null +++ b/headers/private/kernel/arch/ppc/arch_atomic.h @@ -0,0 +1,110 @@ +/* + * Copyright 2014, Paweł Dziepak, pdziepak@quarnos.org. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexander von Gluck IV + */ +#ifndef _KERNEL_ARCH_PPC_ATOMIC_H +#define _KERNEL_ARCH_PPC_ATOMIC_H + + +static inline void +memory_read_barrier_inline(void) +{ + #ifdef __powerpc64__ + asm volatile("lwsync" : : : "memory"); + #else + asm volatile("sync" : : : "memory"); + #endif +} + + +static inline void +memory_write_barrier_inline(void) +{ + #ifdef __powerpc64__ + asm volatile("lwsync" : : : "memory"); + #else + asm volatile("eieio" : : : "memory"); + #endif +} + + +static inline void +memory_full_barrier_inline(void) +{ + asm volatile("sync" : : : "memory"); +} + + +#define memory_read_barrier memory_read_barrier_inline +#define memory_write_barrier memory_write_barrier_inline +#define memory_full_barrier memory_full_barrier_inline + + +static inline void +atomic_set_inline(int32* value, int32 newValue) +{ + memory_write_barrier(); + *(volatile int32*)value = newValue; +} + + +static inline int32 +atomic_get_and_set_inline(int32* value, int32 newValue) +{ + // BIG TODO: PowerPC Atomic get and set +// asm volatile("xchgl %0, (%1)" +// : "+r" (newValue) +// : "r" (value) +// : "memory"); + return newValue; +} + + +static inline int32 +atomic_test_and_set_inline(int32* value, int32 newValue, int32 testAgainst) +{ + // BIG TODO: PowerPC Atomic test and set inline +// asm volatile("lock; cmpxchgl %2, (%3)" +// : "=a" (newValue) +// : "0" (testAgainst), "r" (newValue), "r" (value) +// : "memory"); + return newValue; +} + + +static inline int32 +atomic_add_inline(int32* value, int32 newValue) +{ + // BIG TODO: PowerPC Atomic add inline +// asm volatile("lock; xaddl %0, (%1)" +// : "+r" (newValue) +// : "r" (value) +// : "memory"); + return newValue; +} + + +static inline int32 +atomic_get_inline(int32* value) +{ + int32 newValue = *(volatile int32*)value; + memory_read_barrier(); + return newValue; +} + + +#define atomic_set atomic_set_inline +#define atomic_get_and_set atomic_get_and_set_inline +#ifndef atomic_test_and_set +# define atomic_test_and_set atomic_test_and_set_inline +#endif +#ifndef atomic_add +# define atomic_add atomic_add_inline +#endif +#define atomic_get atomic_get_inline + + +#endif // _KERNEL_ARCH_PPC_ATOMIC_H