diff options
author | Atish Patra <atish.patra@wdc.com> | 2019-08-29 15:19:11 -0700 |
---|---|---|
committer | Anup Patel <anup@brainfault.org> | 2019-08-31 13:13:12 +0530 |
commit | 2e5cc9051b5daf0b164f0454e28e08c2b952089a (patch) | |
tree | f4f019563b5e6b6e79f30fd22eddcb1ac6571e4a /lib/utils/sys | |
parent | ffa6c5f457527a2e71f2e7bd643ed0dce383506d (diff) |
lib: Fix timer for 32 bit
To read 64bit time in 32 bit we have to read lower & upper half
separately and 'or' them together. However, upper half time may
have changed by the time we read lower half. Thus, the resultant
64 bit time may not be accurate.
Consider lower half time value only if upper half time value has
not changed.
Signed-off-by: Atish Patra <atish.patra@wdc.com>
Reviewed-by: Anup Patel <anup.patel@wdc.com>
Diffstat (limited to 'lib/utils/sys')
-rw-r--r-- | lib/utils/sys/clint.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/lib/utils/sys/clint.c b/lib/utils/sys/clint.c index d58e4e6..802d419 100644 --- a/lib/utils/sys/clint.c +++ b/lib/utils/sys/clint.c @@ -62,16 +62,24 @@ static volatile void *clint_time_base; static volatile u64 *clint_time_val; static volatile u64 *clint_time_cmp; +static inline u32 clint_time_read_hi() +{ + return readl_relaxed((u32 *)clint_time_val + 1); +} + u64 clint_timer_value(void) { #if __riscv_xlen == 64 return readq_relaxed(clint_time_val); #else - u64 tmp; - tmp = readl_relaxed((void *)clint_time_val + 0x04); - tmp <<= 32; - tmp |= readl_relaxed(clint_time_val); - return tmp; + u32 lo, hi; + + do { + hi = clint_time_read_hi(); + lo = readl_relaxed(clint_time_val); + } while (hi != clint_time_read_hi()); + + return ((u64)hi << 32) | (u64)lo; #endif } |