arch-arm: raise/clear IRQ when writing to PMOVSCLR/SET
Writing a 1 to the Overflow Flag Status register should trigger an interrupt raise/clear depending on the register we are currently using (PMOVSCLR for clearing and PMOVSSET for raising). Change-Id: I2091456685a245712045cf7a4932ac36b7dded1d Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com> Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Reviewed-on: https://gem5-review.googlesource.com/12531 Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
This commit is contained in:
@@ -214,7 +214,7 @@ PMU::setMiscReg(int misc_reg, MiscReg val)
|
||||
|
||||
case MISCREG_PMOVSCLR_EL0:
|
||||
case MISCREG_PMOVSR:
|
||||
reg_pmovsr &= ~val;
|
||||
setOverflowStatus(reg_pmovsr & ~val);
|
||||
return;
|
||||
|
||||
case MISCREG_PMSWINC_EL0:
|
||||
@@ -286,7 +286,7 @@ PMU::setMiscReg(int misc_reg, MiscReg val)
|
||||
|
||||
case MISCREG_PMOVSSET_EL0:
|
||||
case MISCREG_PMOVSSET:
|
||||
reg_pmovsr |= val;
|
||||
setOverflowStatus(reg_pmovsr | val);
|
||||
return;
|
||||
|
||||
default:
|
||||
@@ -644,6 +644,20 @@ PMU::setCounterTypeRegister(CounterId id, PMEVTYPER_t val)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PMU::setOverflowStatus(MiscReg new_val)
|
||||
{
|
||||
const bool int_old = reg_pmovsr != 0;
|
||||
const bool int_new = new_val != 0;
|
||||
|
||||
reg_pmovsr = new_val;
|
||||
if (int_old && !int_new) {
|
||||
clearInterrupt();
|
||||
} else if (!int_old && int_new && (reg_pminten & reg_pmovsr)) {
|
||||
raiseInterrupt();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PMU::raiseInterrupt()
|
||||
{
|
||||
@@ -656,6 +670,18 @@ PMU::raiseInterrupt()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PMU::clearInterrupt()
|
||||
{
|
||||
if (interrupt) {
|
||||
DPRINTF(PMUVerbose, "Clearing PMU interrupt.\n");
|
||||
interrupt->clear();
|
||||
} else {
|
||||
warn_once("Dropping PMU interrupt as no interrupt has "
|
||||
"been specified\n");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PMU::serialize(CheckpointOut &cp) const
|
||||
{
|
||||
|
||||
@@ -218,6 +218,11 @@ class PMU : public SimObject, public ArmISA::BaseISADevice {
|
||||
*/
|
||||
void raiseInterrupt();
|
||||
|
||||
/**
|
||||
* Clear a PMU interrupt.
|
||||
*/
|
||||
void clearInterrupt();
|
||||
|
||||
/**
|
||||
* Get the value of a performance counter.
|
||||
*
|
||||
@@ -269,6 +274,18 @@ class PMU : public SimObject, public ArmISA::BaseISADevice {
|
||||
*/
|
||||
void setCounterTypeRegister(CounterId id, PMEVTYPER_t type);
|
||||
|
||||
/**
|
||||
* Used for writing the Overflow Flag Status Register (SET/CLR)
|
||||
*
|
||||
* This method implements a write to the PMOVSSET/PMOVSCLR registers.
|
||||
* It is capturing change of state in the register bits so that
|
||||
* the overflow interrupt can be raised/cleared as a side effect
|
||||
* of the write.
|
||||
*
|
||||
* @param new_val New value of the Overflow Status Register
|
||||
*/
|
||||
void setOverflowStatus(MiscReg new_val);
|
||||
|
||||
protected: /* Probe handling and counter state */
|
||||
struct CounterState;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user