diff options
-rw-r--r-- | core/cortex-m0/atomic.h | 64 |
1 files changed, 60 insertions, 4 deletions
diff --git a/core/cortex-m0/atomic.h b/core/cortex-m0/atomic.h index 78ac91a676..539117a672 100644 --- a/core/cortex-m0/atomic.h +++ b/core/cortex-m0/atomic.h @@ -10,12 +10,15 @@ #include "common.h" +typedef int atomic_t; +typedef atomic_t atomic_val_t; + /** * Implements atomic arithmetic operations on 32-bit integers. * * There is no load/store exclusive on ARMv6-M, just disable interrupts */ -#define ATOMIC_OP(asm_op, a, v) do { \ +#define DEPRECATED_ATOMIC_OP(asm_op, a, v) do { \ uint32_t reg0; \ \ __asm__ __volatile__(" cpsid i\n" \ @@ -27,6 +30,22 @@ : "b" (a), "r" (v) : "cc"); \ } while (0) +#define ATOMIC_OP(asm_op, a, v) \ +({ \ + uint32_t reg0, reg1; \ + \ + __asm__ __volatile__(" cpsid i\n" \ + " ldr %0, [%2]\n" \ + " mov %1, %0\n" \ + #asm_op" %0, %0, %3\n" \ + " str %0, [%2]\n" \ + " cpsie i\n" \ + : "=&b"(reg0), "=&b"(reg1) \ + : "b"(a), "r"(v) \ + : "cc", "memory"); \ + reg1; \ +}) + /* * The atomic_* functions are marked as deprecated as a part of the process of * transaction to Zephyr compatible atomic functions. These prefixes will be @@ -36,24 +55,44 @@ static inline void deprecated_atomic_clear_bits(uint32_t volatile *addr, uint32_t bits) { + DEPRECATED_ATOMIC_OP(bic, addr, bits); +} + +static inline void atomic_clear_bits(atomic_t *addr, atomic_val_t bits) +{ ATOMIC_OP(bic, addr, bits); } static inline void deprecated_atomic_or(uint32_t volatile *addr, uint32_t bits) { - ATOMIC_OP(orr, addr, bits); + DEPRECATED_ATOMIC_OP(orr, addr, bits); +} + +static inline atomic_val_t atomic_or(atomic_t *addr, atomic_val_t bits) +{ + return ATOMIC_OP(orr, addr, bits); } static inline void deprecated_atomic_add(uint32_t volatile *addr, uint32_t value) { - ATOMIC_OP(add, addr, value); + DEPRECATED_ATOMIC_OP(add, addr, value); +} + +static inline atomic_val_t atomic_add(atomic_t *addr, atomic_val_t value) +{ + return ATOMIC_OP(add, addr, value); } static inline void deprecated_atomic_sub(uint32_t volatile *addr, uint32_t value) { - ATOMIC_OP(sub, addr, value); + DEPRECATED_ATOMIC_OP(sub, addr, value); +} + +static inline atomic_val_t atomic_sub(atomic_t *addr, atomic_val_t value) +{ + return ATOMIC_OP(sub, addr, value); } static inline uint32_t deprecated_atomic_read_clear(uint32_t volatile *addr) @@ -70,4 +109,21 @@ static inline uint32_t deprecated_atomic_read_clear(uint32_t volatile *addr) return ret; } + +static inline atomic_val_t atomic_read_clear(atomic_t *addr) +{ + atomic_t ret; + + __asm__ __volatile__(" mov %2, #0\n" + " cpsid i\n" + " ldr %0, [%1]\n" + " str %2, [%1]\n" + " cpsie i\n" + : "=&b" (ret) + : "b" (addr), "r" (0) + : "cc", "memory"); + + return ret; +} + #endif /* __CROS_EC_ATOMIC_H */ |