Hello Andreas Sandberg,

I'd like you to do a code review. Please visit

    https://gem5-review.googlesource.com/c/public/gem5/+/12531

to review the following change.


Change subject: arch-arm: raise/clear IRQ when writing to PMOVSCLR/SET
......................................................................

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 <[email protected]>
Reviewed-by: Andreas Sandberg <[email protected]>
---
M src/arch/arm/pmu.cc
M src/arch/arm/pmu.hh
2 files changed, 45 insertions(+), 2 deletions(-)



diff --git a/src/arch/arm/pmu.cc b/src/arch/arm/pmu.cc
index 0bdae49..daf5648 100644
--- a/src/arch/arm/pmu.cc
+++ b/src/arch/arm/pmu.cc
@@ -205,7 +205,7 @@

       case MISCREG_PMOVSCLR_EL0:
       case MISCREG_PMOVSR:
-        reg_pmovsr &= ~val;
+        setOverflowStatus(reg_pmovsr & ~val);
         return;

       case MISCREG_PMSWINC_EL0:
@@ -277,7 +277,7 @@

       case MISCREG_PMOVSSET_EL0:
       case MISCREG_PMOVSSET:
-        reg_pmovsr |= val;
+        setOverflowStatus(reg_pmovsr | val);
         return;

       default:
@@ -636,6 +636,20 @@
 }

 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()
 {
     RealView *rv(dynamic_cast<RealView *>(platform));
@@ -649,6 +663,18 @@
 }

 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
 {
     DPRINTF(Checkpoint, "Serializing Arm PMU\n");
diff --git a/src/arch/arm/pmu.hh b/src/arch/arm/pmu.hh
index 7090b4a..5b89ffa 100644
--- a/src/arch/arm/pmu.hh
+++ b/src/arch/arm/pmu.hh
@@ -216,6 +216,11 @@
     void raiseInterrupt();

     /**
+     * Clear a PMU interrupt.
+     */
+    void clearInterrupt();
+
+    /**
      * Get the value of a performance counter.
      *
      * This method returns the value of a general purpose performance
@@ -266,6 +271,18 @@
      */
     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;


--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/12531
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-Change-Id: I2091456685a245712045cf7a4932ac36b7dded1d
Gerrit-Change-Number: 12531
Gerrit-PatchSet: 1
Gerrit-Owner: Giacomo Travaglini <[email protected]>
Gerrit-Reviewer: Andreas Sandberg <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to