diff options
author | Dawid Niedzwiecki <dn@semihalf.com> | 2020-09-28 15:43:55 +0200 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-10-15 13:03:19 +0000 |
commit | d31a8e4b5ac2def50650690a76cb13c3ec834bae (patch) | |
tree | 26fb27b1fc06a617758d109905de1b3f23bea3c6 /core/cortex-m0 | |
parent | 92f55b092e0a8b00496db89e3d129932aae0525a (diff) | |
download | chrome-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/cortex-m0')
-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 */ |