From: Giacomo Travaglini Date: Mon, 20 Jul 2020 09:39:44 +0000 (+0100) Subject: dev-arm: Gicv3 maintenance interrupt never cleared X-Git-Tag: v20.1.0.0~405 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f441a25204a3e6b1b8e3a1d788c6dd3767d62273;p=gem5.git dev-arm: Gicv3 maintenance interrupt never cleared The maintenance interrupt is a level sensitive interrupt though it has been treated as edge triggered so far. In order to be level sensitive, it needs to be cleared once the condition which led to its generation are not valid anymore. Change-Id: I9af9f4bf27622a7961393b00a145d6c9835d738b Signed-off-by: Giacomo Travaglini Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/31614 Reviewed-by: Andreas Sandberg Maintainer: Andreas Sandberg Tested-by: kokoro --- diff --git a/src/dev/arm/gic_v3_cpu_interface.cc b/src/dev/arm/gic_v3_cpu_interface.cc index 5e1f8719e..5499e386d 100644 --- a/src/dev/arm/gic_v3_cpu_interface.cc +++ b/src/dev/arm/gic_v3_cpu_interface.cc @@ -79,6 +79,8 @@ void Gicv3CPUInterface::setThreadContext(ThreadContext *tc) { maintenanceInterrupt = gic->params()->maint_int->get(tc); + fatal_if(maintenanceInterrupt->num() >= redistributor->irqPending.size(), + "Invalid maintenance interrupt number\n"); } bool @@ -2078,10 +2080,13 @@ Gicv3CPUInterface::virtualUpdate() ICH_HCR_EL2 ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2); - if (ich_hcr_el2.En) { - if (maintenanceInterruptStatus()) { - maintenanceInterrupt->raise(); - } + const bool maint_pending = redistributor->irqPending[ + maintenanceInterrupt->num()]; + + if (ich_hcr_el2.En && !maint_pending && maintenanceInterruptStatus()) { + maintenanceInterrupt->raise(); + } else if (maint_pending) { + maintenanceInterrupt->clear(); } if (signal_IRQ) {