summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHyungwoo Yang <hyungwoo.yang@intel.com>2018-10-29 10:16:28 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-12-23 19:19:34 -0800
commitdb9a02ec4110769b7300f45ade770205e70934de (patch)
tree3b0b45c037f3afc0b4306fa009539be2fbdb4c1c
parent90b6c047fbfc50b6c85b5a0fd85482b50b131b86 (diff)
downloadchrome-ec-db9a02ec4110769b7300f45ade770205e70934de.tar.gz
core/minute-ia: fix atomics
this fixes a few wrong implementation on atomic. atomic_read_clear() and atomic_clear() were functinally broken. Due to this, key control flow which rely on these functions were out of order. Also modified ATOMIC_OP() and bool_compare_and_swap_u32() to give more accurate directives to compiler. BUG=b:119628522 BRANCH=none TEST=tested on atlas Change-Id: Ide8397e4f7b754a7094c66326ecc2450ef2f0cc9 Reviewed-on: https://chromium-review.googlesource.com/1305118 Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com> Tested-by: Hyungwoo Yang <hyungwoo.yang@intel.com> Reviewed-by: Caveh Jalali <caveh@google.com> Reviewed-by: Jett Rink <jettrink@chromium.org>
-rw-r--r--core/minute-ia/atomic.h29
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 */