summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/cortex-m0/atomic.h64
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 */