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 <hsuan.hsu@mediatek.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/30916
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Hsuan Hsu
2020-05-27 15:41:39 +08:00
committed by Hsuan Hsu
parent 98ce167176
commit 5a55a242ab

View File

@@ -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