From 92b2e03d0d922d77ce59c677f010ff94772489bc Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Wed, 12 Feb 2014 23:11:11 -0600 Subject: [PATCH] arm: Add initial memory barrier functions * These likely need reviewed by someone better at arm assembly. (#10537) --- headers/private/kernel/arch/arm/arch_atomic.h | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 headers/private/kernel/arch/arm/arch_atomic.h diff --git a/headers/private/kernel/arch/arm/arch_atomic.h b/headers/private/kernel/arch/arm/arch_atomic.h new file mode 100644 index 0000000000..5d1005eb98 --- /dev/null +++ b/headers/private/kernel/arch/arm/arch_atomic.h @@ -0,0 +1,105 @@ +/* + * Copyright 2014, Paweł Dziepak, pdziepak@quarnos.org. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexander von Gluck IV + */ +#ifndef _KERNEL_ARCH_ARM_ATOMIC_H +#define _KERNEL_ARCH_ARM_ATOMIC_H + + +static inline void +memory_read_barrier_inline(void) +{ + // TODO Only ArmV7+? + asm volatile("dsb sy" : : : "memory"); +} + + +static inline void +memory_write_barrier_inline(void) +{ + // TODO Only ArmV7+? + asm volatile("dsb sy" : : : "memory"); +} + + +static inline void +memory_full_barrier_inline(void) +{ + // TODO Only ArmV7+? + asm volatile("dsb sy" : : : "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: ARM 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: ARM 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: ARM 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_ARM_ATOMIC_H