diff options
author | Nicolas Boichat <drinkcat@chromium.org> | 2018-12-12 11:02:04 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-12-23 14:46:08 -0800 |
commit | 9b9ca849029d804a3cc99bbe2854b22ae2cb0207 (patch) | |
tree | dbad9f0c9a1d8e93bb90273c11ff7ed5861d0730 | |
parent | 815c2463e1535eb4cf4b3e6d387d628c0ac66f2b (diff) | |
download | chrome-ec-9b9ca849029d804a3cc99bbe2854b22ae2cb0207.tar.gz |
mt_scp/hrtimer: Fix race condition in timer_read_raw_system
When the 32-bit bit timer @26Mhz wraps around, there is a short
amount of time when the 32-bit timer value (@1Mhz) is incorrect.
Fix this by manually adjusting sys_high if an interrupt is pending.
BRANCH=none
BUG=b:120173036
BUG=b:120763595
TEST=Boot kukui_scp, leave it running for 200 seconds
taskinfo "time in exceptions" look reasonable
Change-Id: I053972d018e3e5e9c46cb73a0edb16b0354d5c43
Signed-off-by: Nicolas Boichat <drinkcat@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1372871
Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Reviewed-by: Yilun Lin <yllin@chromium.org>
-rw-r--r-- | chip/mt_scp/hrtimer.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/chip/mt_scp/hrtimer.c b/chip/mt_scp/hrtimer.c index b0e72fd948..ca94f79785 100644 --- a/chip/mt_scp/hrtimer.c +++ b/chip/mt_scp/hrtimer.c @@ -36,8 +36,17 @@ static uint8_t event_high; /* Convert hardware countdown timer to 64bit countup ticks */ static inline uint64_t timer_read_raw_system(void) { - /* TODO(b/120173036): fix racing condition in read_raw */ - return OVERFLOW_TICKS - (((uint64_t)sys_high << 32) | + uint32_t timer_ctrl = SCP_TIMER_IRQ_CTRL(TIMER_SYSTEM); + uint32_t sys_high_adj = sys_high; + + /* + * If an IRQ is pending, but has not been serviced yet, adjust the + * sys_high value. + */ + if (timer_ctrl & TIMER_IRQ_STATUS) + sys_high_adj = sys_high ? (sys_high - 1) : 25; + + return OVERFLOW_TICKS - (((uint64_t)sys_high_adj << 32) | SCP_TIMER_VAL(TIMER_SYSTEM)); } |