summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorDawid Niedzwiecki <dn@semihalf.com>2020-09-28 15:43:55 +0200
committerCommit Bot <commit-bot@chromium.org>2020-10-15 13:03:19 +0000
commitd31a8e4b5ac2def50650690a76cb13c3ec834bae (patch)
tree26fb27b1fc06a617758d109905de1b3f23bea3c6 /core
parent92f55b092e0a8b00496db89e3d129932aae0525a (diff)
downloadchrome-ec-d31a8e4b5ac2def50650690a76cb13c3ec834bae.tar.gz
core/cortex-m0: add Zephyr compatible atomic functions
Add atomic functions with prototypes equal to the ones in Zephyr. It is done as a part of porting to Zephyr, the next step is to use in the code atomic_* instead of deprecated_atomic_*. Some atomic functions in Zephyr return a value e.g. atomic_add - it returns the value of the variable before the add operation. To support such functionality the new ATOMIC_OP define is introduced. The "memory" clobber is added to the asm statement to inform compiler that memory pointed by the input parameter (a) is changed. This is needed, because atomic_* functions are inline. GCC builtin functions are not used, because those functions are not available for cortex-m0. BUG=b:169151160 BRANCH=none TEST=buildall Signed-off-by: Dawid Niedzwiecki <dn@semihalf.com> Change-Id: I713daf388cb279704ae1b3767bd84b71a255f7cd Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2438425 Reviewed-by: Aseda Aboagye <aaboagye@chromium.org> Reviewed-by: Jett Rink <jettrink@chromium.org> Reviewed-by: Jack Rosenthal <jrosenth@chromium.org>
Diffstat (limited to 'core')
-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 */