summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Boichat <drinkcat@chromium.org>2018-12-12 11:02:04 +0800
committerchrome-bot <chrome-bot@chromium.org>2018-12-23 14:46:08 -0800
commit9b9ca849029d804a3cc99bbe2854b22ae2cb0207 (patch)
treedbad9f0c9a1d8e93bb90273c11ff7ed5861d0730
parent815c2463e1535eb4cf4b3e6d387d628c0ac66f2b (diff)
downloadchrome-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.c13
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));
}