From f441a25204a3e6b1b8e3a1d788c6dd3767d62273 Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Mon, 20 Jul 2020 10:39:44 +0100 Subject: [PATCH] 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 --- src/dev/arm/gic_v3_cpu_interface.cc | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) 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) { -- 2.30.2