changeset afeb5cdb3907 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=afeb5cdb3907
description:
        arm: Add a model of an ARM PMUv3

        This class implements a subset of the ARM PMU v3 specification as
        described in the ARMv8 reference manual. It supports most of the
        features of the PMU, however the following features are known to be
        missing:

         * Event filtering (e.g., from different privilege levels).
         * Access controls (the PMU currently ignores the execution level).
         * The chain counter (event no. 0x1E) is unimplemented.

        The PMU itself does not implement any events, it merely provides an
        interface for the configuration scripts to hook up probes that drive
        events. Configuration scripts should call addEventProbe() to configure
        custom events or high-level methods to configure architected
        events. The Python implementation of addEventProbe() automatically
        delays event type registration until after instantiation.

        In order to support CPU switching and some combined counters (e.g.,
        memory references synthesized from loads and stores), the PMU allows
        multiple probes per event type. When creating a system that switches
        between CPU models that share the same PMU, PMU events for all of the
        CPU models can be registered with the PMU.

        Kudos to Matt Horsnell for the initial gem5 implementation of the PMU.

diffstat:

 src/arch/arm/ArmISA.py     |    4 +
 src/arch/arm/ArmPMU.py     |   83 ++++++
 src/arch/arm/SConscript    |    4 +
 src/arch/arm/isa.cc        |   67 +++--
 src/arch/arm/isa.hh        |    8 +
 src/arch/arm/isa_device.cc |   62 ++++
 src/arch/arm/isa_device.hh |   99 +++++++
 src/arch/arm/pmu.cc        |  559 +++++++++++++++++++++++++++++++++++++++++++++
 src/arch/arm/pmu.hh        |  495 +++++++++++++++++++++++++++++++++++++++
 9 files changed, 1353 insertions(+), 28 deletions(-)

diffs (truncated from 1543 to 300 lines):

diff -r 20443473c68a -r afeb5cdb3907 src/arch/arm/ArmISA.py
--- a/src/arch/arm/ArmISA.py    Thu Oct 16 05:49:38 2014 -0400
+++ b/src/arch/arm/ArmISA.py    Thu Oct 16 05:49:39 2014 -0400
@@ -40,6 +40,8 @@
 from m5.proxy import *
 from m5.SimObject import SimObject
 
+from ArmPMU import ArmPMU
+
 class ArmISA(SimObject):
     type = 'ArmISA'
     cxx_class = 'ArmISA::ISA'
@@ -47,6 +49,8 @@
 
     system = Param.System(Parent.any, "System this ISA object belongs to")
 
+    pmu = Param.ArmPMU(NULL, "Performance Monitoring Unit")
+
     midr = Param.UInt32(0x410fc0f0, "MIDR value")
 
     # See section B4.1.93 - B4.1.94 of the ARM ARM
diff -r 20443473c68a -r afeb5cdb3907 src/arch/arm/ArmPMU.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/src/arch/arm/ArmPMU.py    Thu Oct 16 05:49:39 2014 -0400
@@ -0,0 +1,83 @@
+# -*- mode:python -*-
+# Copyright (c) 2009-2014 ARM Limited
+# All rights reserved.
+#
+# The license below extends only to copyright in the software and shall
+# not be construed as granting a license to any other intellectual
+# property including but not limited to intellectual property relating
+# to a hardware implementation of the functionality of the software
+# licensed hereunder.  You may use the software subject to the license
+# terms below provided that you ensure that this notice is replicated
+# unmodified and in its entirety in all distributions of the software,
+# modified or unmodified, in source code or in binary form.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Matt Horsnell
+#          Andreas Sandberg
+
+from m5.defines import buildEnv
+from m5.SimObject import SimObject
+from m5.params import *
+from m5.params import isNullPointer
+from m5.proxy import *
+
+class ArmPMU(SimObject):
+    type = 'ArmPMU'
+    cxx_class = 'ArmISA::PMU'
+    cxx_header = 'arch/arm/pmu.hh'
+
+    @classmethod
+    def export_methods(cls, code):
+        code('''
+      void addEventProbe(unsigned int id,
+                        SimObject *obj, const char *name);
+''')
+
+    # To prevent cycles in the configuration hierarchy, we don't keep
+    # a list of supported events as a configuration param. Instead, we
+    # keep them in a local list and register them using the
+    # addEventProbe interface when other SimObjects register their
+    # probe listeners.
+    _deferred_event_types = []
+    # Override the normal SimObject::regProbeListeners method and
+    # register deferred event handlers.
+    def regProbeListeners(self):
+        for event_id, obj, name in self._deferred_event_types:
+            self.getCCObject().addEventProbe(event_id, obj.getCCObject(), name)
+
+        self.getCCObject().regProbeListeners()
+
+    def addEventProbe(self, event_id, obj, *args):
+        """Add a probe-based event to the PMU if obj is not None."""
+
+        if obj is None:
+            return
+
+        for name in args:
+            self._deferred_event_types.append((event_id, obj, name))
+
+    platform = Param.Platform(Parent.any, "Platform this device is part of.")
+    eventCounters = Param.Int(31, "Number of supported PMU counters")
+    pmuInterrupt = Param.Int(68, "PMU GIC interrupt number")
diff -r 20443473c68a -r afeb5cdb3907 src/arch/arm/SConscript
--- a/src/arch/arm/SConscript   Thu Oct 16 05:49:38 2014 -0400
+++ b/src/arch/arm/SConscript   Thu Oct 16 05:49:39 2014 -0400
@@ -62,11 +62,13 @@
     Source('insts/fplib.cc')
     Source('interrupts.cc')
     Source('isa.cc')
+    Source('isa_device.cc')
     Source('linux/linux.cc')
     Source('linux/process.cc')
     Source('linux/system.cc')
     Source('miscregs.cc')
     Source('nativetrace.cc')
+    Source('pmu.cc')
     Source('process.cc')
     Source('remote_gdb.cc')
     Source('stacktrace.cc')
@@ -83,10 +85,12 @@
     SimObject('ArmNativeTrace.py')
     SimObject('ArmSystem.py')
     SimObject('ArmTLB.py')
+    SimObject('ArmPMU.py')
 
     DebugFlag('Arm')
     DebugFlag('Decoder', "Instructions returned by the predecoder")
     DebugFlag('Faults', "Trace Exceptions, interrupts, svc/swi")
+    DebugFlag('PMUVerbose', "Performance Monitor")
     DebugFlag('TLBVerbose')
 
     # Add files generated by the ISA description.
diff -r 20443473c68a -r afeb5cdb3907 src/arch/arm/isa.cc
--- a/src/arch/arm/isa.cc       Thu Oct 16 05:49:38 2014 -0400
+++ b/src/arch/arm/isa.cc       Thu Oct 16 05:49:39 2014 -0400
@@ -39,8 +39,10 @@
  */
 
 #include "arch/arm/isa.hh"
+#include "arch/arm/pmu.hh"
 #include "arch/arm/system.hh"
 #include "cpu/checker/cpu.hh"
+#include "cpu/base.hh"
 #include "debug/Arm.hh"
 #include "debug/MiscRegs.hh"
 #include "params/ArmISA.hh"
@@ -122,12 +124,21 @@
 
 
 ISA::ISA(Params *p)
-    : SimObject(p), system(NULL), lookUpMiscReg(NUM_MISCREGS, {0,0})
+    : SimObject(p),
+      system(NULL),
+      pmu(p->pmu),
+      lookUpMiscReg(NUM_MISCREGS, {0,0})
 {
     SCTLR sctlr;
     sctlr = 0;
     miscRegs[MISCREG_SCTLR_RST] = sctlr;
 
+    // Hook up a dummy device if we haven't been configured with a
+    // real PMU. By using a dummy device, we don't need to check that
+    // the PMU exist every time we try to access a PMU register.
+    if (!pmu)
+        pmu = &dummyDevice;
+
     system = dynamic_cast<ArmSystem *>(p->system);
     DPRINTFN("ISA system set to: %p %p\n", system, p->system);
 
@@ -356,7 +367,10 @@
     // Initialize configurable id registers
     miscRegs[MISCREG_ID_AA64AFR0_EL1] = p->id_aa64afr0_el1;
     miscRegs[MISCREG_ID_AA64AFR1_EL1] = p->id_aa64afr1_el1;
-    miscRegs[MISCREG_ID_AA64DFR0_EL1] = p->id_aa64dfr0_el1;
+    miscRegs[MISCREG_ID_AA64DFR0_EL1] =
+        (p->id_aa64dfr0_el1 & 0xfffffffffffff0ffULL) |
+        (p->pmu ?             0x0000000000000100ULL : 0); // Enable PMUv3
+
     miscRegs[MISCREG_ID_AA64DFR1_EL1] = p->id_aa64dfr1_el1;
     miscRegs[MISCREG_ID_AA64ISAR0_EL1] = p->id_aa64isar0_el1;
     miscRegs[MISCREG_ID_AA64ISAR1_EL1] = p->id_aa64isar1_el1;
@@ -365,6 +379,11 @@
     miscRegs[MISCREG_ID_AA64PFR0_EL1] = p->id_aa64pfr0_el1;
     miscRegs[MISCREG_ID_AA64PFR1_EL1] = p->id_aa64pfr1_el1;
 
+    miscRegs[MISCREG_ID_DFR0_EL1] =
+        (p->pmu ? 0x03000000ULL : 0); // Enable PMUv3
+
+    miscRegs[MISCREG_ID_DFR0] = miscRegs[MISCREG_ID_DFR0_EL1];
+
     // Enforce consistency with system-level settings...
 
     // EL3
@@ -491,7 +510,6 @@
         // top bit defined as RES1
         return readMiscRegNoEffect(misc_reg) | 0x80000000;
       case MISCREG_ID_AFR0: // not implemented, so alias MIDR
-      case MISCREG_ID_DFR0: // not implemented, so alias MIDR
       case MISCREG_REVIDR:  // not implemented, so alias MIDR
       case MISCREG_MIDR:
         cpsr = readMiscRegNoEffect(MISCREG_CPSR);
@@ -549,12 +567,13 @@
       case MISCREG_ACTLR:
         warn("Not doing anything for miscreg ACTLR\n");
         break;
-      case MISCREG_PMCR:
-      case MISCREG_PMCCNTR:
-      case MISCREG_PMSELR:
-        warn("Not doing anything for read to miscreg %s\n",
-                miscRegName[misc_reg]);
-        break;
+
+      case MISCREG_PMXEVTYPER_PMCCFILTR:
+      case MISCREG_PMINTENSET_EL1 ... MISCREG_PMOVSSET_EL0:
+      case MISCREG_PMEVCNTR0_EL0 ... MISCREG_PMEVTYPER5_EL0:
+      case MISCREG_PMCR ... MISCREG_PMOVSSET:
+        return pmu->readMiscReg(misc_reg);
+
       case MISCREG_CPSR_Q:
         panic("shouldn't be reading this register seperately\n");
       case MISCREG_FPSCR_QC:
@@ -640,9 +659,9 @@
         }
       case MISCREG_DBGDIDR:
         /* For now just implement the version number.
-         * Return 0 as we don't support debug architecture yet.
+         * ARMv7, v7.1 Debug architecture (0b0101 --> 0x5)
          */
-        return 0;
+        return 0x5 << 16;
       case MISCREG_DBGDSCRint:
         return 0;
       case MISCREG_ISR:
@@ -1112,6 +1131,7 @@
           case MISCREG_MIDR:
           case MISCREG_ID_PFR0:
           case MISCREG_ID_PFR1:
+          case MISCREG_ID_DFR0:
           case MISCREG_ID_MMFR0:
           case MISCREG_ID_MMFR1:
           case MISCREG_ID_MMFR2:
@@ -1443,24 +1463,15 @@
           case MISCREG_ACTLR:
             warn("Not doing anything for write of miscreg ACTLR\n");
             break;
-          case MISCREG_PMCR:
-            {
-              // Performance counters not implemented.  Instead, interpret
-              //   a reset command to this register to reset the simulator
-              //   statistics.
-              // PMCR_E | PMCR_P | PMCR_C
-              const int ResetAndEnableCounters = 0x7;
-              if (newVal == ResetAndEnableCounters) {
-                  inform("Resetting all simobject stats\n");
-                  Stats::schedStatEvent(false, true);
-                  break;
-              }
-            }
-          case MISCREG_PMCCNTR:
-          case MISCREG_PMSELR:
-            warn("Not doing anything for write to miscreg %s\n",
-                    miscRegName[misc_reg]);
+
+          case MISCREG_PMXEVTYPER_PMCCFILTR:
+          case MISCREG_PMINTENSET_EL1 ... MISCREG_PMOVSSET_EL0:
+          case MISCREG_PMEVCNTR0_EL0 ... MISCREG_PMEVTYPER5_EL0:
+          case MISCREG_PMCR ... MISCREG_PMOVSSET:
+            pmu->setMiscReg(misc_reg, newVal);
             break;
+
+
           case MISCREG_HSTR: // TJDBX, now redifined to be RES0
             {
                 HSTR hstrMask = 0;
diff -r 20443473c68a -r afeb5cdb3907 src/arch/arm/isa.hh
--- a/src/arch/arm/isa.hh       Thu Oct 16 05:49:38 2014 -0400
+++ b/src/arch/arm/isa.hh       Thu Oct 16 05:49:39 2014 -0400
@@ -43,6 +43,7 @@
 #ifndef __ARCH_ARM_ISA_HH__
 #define __ARCH_ARM_ISA_HH__
 
+#include "arch/arm/isa_device.hh"
 #include "arch/arm/registers.hh"
 #include "arch/arm/system.hh"
 #include "arch/arm/tlb.hh"
@@ -52,6 +53,7 @@
 #include "sim/sim_object.hh"
 
 struct ArmISAParams;
+struct DummyArmISADeviceParams;
 class ThreadContext;
 class Checkpoint;
 class EventManager;
@@ -131,6 +133,12 @@
_______________________________________________
gem5-dev mailing list
gem5-dev@gem5.org
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to