From: Hsuan Hsu Date: Wed, 27 May 2020 07:41:39 +0000 (+0800) Subject: dev-arm: Make generic timer work with level-sensitive support X-Git-Tag: v20.1.0.0~491 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=5a55a242ab634c539af0ed4eb90f013b6d2b317d;p=gem5.git 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 --- 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