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:
@@ -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 &
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user