diff options
-rw-r--r-- | core/minute-ia/atomic.h | 29 |
1 files changed, 13 insertions, 16 deletions
diff --git a/core/minute-ia/atomic.h b/core/minute-ia/atomic.h index 696120ae1d..08f0888cdf 100644 --- a/core/minute-ia/atomic.h +++ b/core/minute-ia/atomic.h @@ -13,9 +13,9 @@ #define ATOMIC_OP(asm_op, a, v) do { \ __asm__ __volatile__ ( \ - "lock;" #asm_op " %0, %1\n" \ - : \ - : "r" (v), "m" (*a) \ + "lock;" #asm_op " %1, %0\n" \ + : "+m" (*a) \ + : "ir" (v) \ : "memory"); \ } while (0) @@ -24,10 +24,10 @@ static inline int bool_compare_and_swap_u32(uint32_t *var, uint32_t old_value, { uint32_t _old_value = old_value; - __asm__ __volatile__("cmpxchg %1, %2\n" - : "=a"(old_value) - : "r"(new_value), "m"(*var), "a" (old_value) - : "memory"); + __asm__ __volatile__("lock; cmpxchgl %2, %1" + : "=a" (old_value), "+m" (*var) + : "r" (new_value), "0" (old_value) + : "memory"); return (_old_value == old_value); } @@ -44,7 +44,7 @@ static inline void atomic_and_u8(uint8_t *addr, uint8_t bits) static inline void atomic_clear(uint32_t volatile *addr, uint32_t bits) { - ATOMIC_OP(btr, addr, bits >> 1); + ATOMIC_OP(andl, addr, ~bits); } static inline void atomic_or(uint32_t volatile *addr, uint32_t bits) @@ -69,19 +69,16 @@ static inline void atomic_sub(uint32_t volatile *addr, uint32_t value) static inline uint32_t atomic_read_clear(uint32_t volatile *addr) { - int loc = 0; + int ret = 0; if (*addr == 0) return 0; - asm volatile("bsr %1, %0\n" - "lock; btr %0, %1\n" - : "=&r" (loc) - : "m" (*addr) - : "memory" - ); + asm volatile("lock; xchgl %0, %1\n" + : "+r" (ret), "+m" (*addr) + : : "memory", "cc"); - return (1 << loc); + return ret; } #endif /* __CROS_EC_ATOMIC_H */ |