arch-arm: Allow ArmPPI usage for PMU

Differently from ArmSPIs, ArmPPI interrupts need to be instantiated by
giving a ThreadContext pointer in the ArmPPIGen::get() method. Since the
PMU is registering the ThreadContext only at ISA startup time, ArmPPI
generation in deferred until the PMU has a non NULL pointer.

Change-Id: I17daa6f0e355363b8778d707b440cab9f75aaea2
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/16204
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
diff --git a/src/arch/arm/pmu.cc b/src/arch/arm/pmu.cc
index 3042515..7d8892c 100644
--- a/src/arch/arm/pmu.cc
+++ b/src/arch/arm/pmu.cc
@@ -67,7 +67,7 @@
       cycleCounterEventId(p->cycleEventId),
       swIncrementEvent(nullptr),
       reg_pmcr_conf(0),
-      interrupt(p->interrupt->get())
+      interrupt(nullptr),
 {
     DPRINTF(PMUVerbose, "Initializing the PMU.\n");
 
@@ -76,7 +76,7 @@
               maximumCounterCount);
     }
 
-    warn_if(!interrupt, "ARM PMU: No interrupt specified, interrupt " \
+    warn_if(!p->interrupt, "ARM PMU: No interrupt specified, interrupt " \
             "delivery disabled.\n");
 
     /* Setup the performance counter ID registers */
@@ -97,8 +97,10 @@
 PMU::setThreadContext(ThreadContext *tc)
 {
     DPRINTF(PMUVerbose, "Assigning PMU to ContextID %i.\n", tc->contextId());
-    if (interrupt)
-        interrupt->setThreadContext(tc);
+    auto pmu_params = static_cast<const ArmPMUParams *>(params());
+
+    if (pmu_params->interrupt)
+        interrupt = pmu_params->interrupt->get(tc);
 }
 
 void
diff --git a/src/arch/arm/pmu.hh b/src/arch/arm/pmu.hh
index de931ee..f5f52133 100644
--- a/src/arch/arm/pmu.hh
+++ b/src/arch/arm/pmu.hh
@@ -619,7 +619,7 @@
     static const RegVal reg_pmcr_wr_mask;
 
     /** Performance monitor interrupt number */
-    ArmInterruptPin *const interrupt;
+    ArmInterruptPin *interrupt;
 
     /**
      * List of event types supported by this PMU.