From 5a55a242ab634c539af0ed4eb90f013b6d2b317d Mon Sep 17 00:00:00 2001 From: Hsuan Hsu Date: Wed, 27 May 2020 15:41:39 +0800 Subject: [PATCH] dev-arm: Make generic timer work with level-sensitive support Support for level-sensitive PPIs and SPIs has been added to GICv2 now. It is therefore the timer's responsibility to notify GICv2 to clear its interrupt pending state. Without doing this, the guest will get stuck in just a single round of the interrupt handler because GICv2 does not clear the pending state, and eventually make the guest treat this interrupt as problematic and then just disable it. JIRA: https://gem5.atlassian.net/browse/GEM5-663 Change-Id: Ia8fd96bf00b28e91aa440274e6f8bb000446fbe3 Signed-off-by: Hsuan Hsu Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/30916 Reviewed-by: Giacomo Travaglini Reviewed-by: Andreas Sandberg Maintainer: Giacomo Travaglini Maintainer: Andreas Sandberg Tested-by: kokoro --- src/dev/arm/generic_timer.cc | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/dev/arm/generic_timer.cc b/src/dev/arm/generic_timer.cc index 1b7572838..42b03adfa 100644 --- a/src/dev/arm/generic_timer.cc +++ b/src/dev/arm/generic_timer.cc @@ -281,7 +281,11 @@ ArchTimer::updateCounter() if (value() >= _counterLimit) { counterLimitReached(); } else { - _control.istatus = 0; + if (_control.istatus) { + DPRINTF(Timer, "Clearing interrupt\n"); + _interrupt->clear(); + _control.istatus = 0; + } if (scheduleEvents()) { _parent.schedule(_counterLimitReachedEvent, whenValue(_counterLimit)); @@ -313,8 +317,13 @@ ArchTimer::setControl(uint32_t val) if (!old_ctl.enable && new_ctl.enable) updateCounter(); // Timer disabled - else if (old_ctl.enable && !new_ctl.enable) - _control.istatus = 0; + else if (old_ctl.enable && !new_ctl.enable) { + if (_control.istatus) { + DPRINTF(Timer, "Clearing interrupt\n"); + _interrupt->clear(); + _control.istatus = 0; + } + } } void -- 2.30.2