arch-arm: Syncronize GIC CPU interface when changing EL

From the GIC architecture specification (ihi0069) [1]

"The assertion and de-assertion of IRQs and FIQs are affected by the
current Exception level and Security state of the PE. As part of the
Context Synchronization that occurs as the result of taking or returning
from an exception, the CPU interface ensures that IRQ and FIQ are both
appropriately asserted or deasserted for the Exception level and
Security state that the PE is entering."

Kudos to Quentin Forcioli for finding the bug

[1]: https://developer.arm.com/documentation/ihi0069/latest

Change-Id: I10444a3aad5c06aabc13e1cbd70a32192531a31d
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/50508
Reviewed-by: Quentin Forcioli <quentin.forcioli@telecom-paris.fr>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Giacomo Travaglini
2021-09-15 15:46:19 +01:00
parent 4000480a2f
commit 377155c10b
2 changed files with 28 additions and 5 deletions

View File

@@ -905,13 +905,12 @@ ISA::setMiscReg(int misc_reg, RegVal val)
CPSR old_cpsr = miscRegs[MISCREG_CPSR];
int old_mode = old_cpsr.mode;
CPSR cpsr = val;
if (old_mode != cpsr.mode || cpsr.il != old_cpsr.il) {
getMMUPtr(tc)->invalidateMiscReg();
}
if (cpsr.pan != old_cpsr.pan) {
getMMUPtr(tc)->invalidateMiscReg(MMU::D_TLBS);
}
if (cpsr.il != old_cpsr.il) {
getMMUPtr(tc)->invalidateMiscReg();
}
DPRINTF(Arm, "Updating CPSR from %#x to %#x f:%d i:%d a:%d mode:%#x\n",
miscRegs[misc_reg], cpsr, cpsr.f, cpsr.i, cpsr.a, cpsr.mode);
@@ -931,6 +930,24 @@ ISA::setMiscReg(int misc_reg, RegVal val)
} else {
tc->pcState(pc);
}
setMiscRegNoEffect(misc_reg, newVal);
if (old_mode != cpsr.mode) {
getMMUPtr(tc)->invalidateMiscReg();
if (gicv3CpuInterface) {
// The assertion and de-assertion of IRQs and FIQs are
// affected by the current Exception level and Security
// state of the PE. As part of the Context
// Synchronization that occurs as the result of taking
// or returning from an exception, the CPU interface
// ensures that IRQ and FIQ are both appropriately
// asserted or deasserted for the Exception level and
// Security state that the PE is entering.
static_cast<Gicv3CPUInterface&>(
getGICv3CPUInterface()).update();
}
}
} else {
#ifndef NDEBUG
if (!miscRegInfo[misc_reg][MISCREG_IMPLEMENTED]) {
@@ -2333,8 +2350,8 @@ ISA::setMiscReg(int misc_reg, RegVal val)
tc->getDecoderPtr()->setSveLen((getCurSveVecLenInBits() >> 7) - 1);
break;
}
setMiscRegNoEffect(misc_reg, newVal);
}
setMiscRegNoEffect(misc_reg, newVal);
}
BaseISADevice &

View File

@@ -50,12 +50,18 @@ namespace gem5
class Gicv3Distributor;
class Gicv3Redistributor;
namespace ArmISA
{
class ISA;
}
class Gicv3CPUInterface : public ArmISA::BaseISADevice, public Serializable
{
private:
friend class Gicv3Distributor;
friend class Gicv3Redistributor;
friend class ArmISA::ISA;
protected: