changeset 8551af601f75 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=8551af601f75
description:
        dev, arm: Refactor and clean up the generic timer model

        This changeset cleans up the generic timer a bit and moves most of the
        register juggling from the ISA code into a separate class in the same
        source file as the rest of the generic timer. It also removes the
        assumption that there is always 8 or fewer CPUs in the system. Instead
        of having a fixed limit, we now instantiate per-core timers as they
        are requested. This is all in preparation for other patches that add
        support for virtual timers and a memory mapped interface.

diffstat:

 src/arch/arm/isa.cc          |  132 +++------------
 src/arch/arm/isa.hh          |   10 +-
 src/arch/arm/system.cc       |   18 --
 src/arch/arm/system.hh       |    9 +-
 src/dev/arm/RealView.py      |    4 +-
 src/dev/arm/generic_timer.cc |  366 ++++++++++++++++++++++++++++++++++++------
 src/dev/arm/generic_timer.hh |  314 ++++++++++++++++++++++--------------
 7 files changed, 534 insertions(+), 319 deletions(-)

diffs (truncated from 1135 to 300 lines):

diff -r adec1cf1c300 -r 8551af601f75 src/arch/arm/isa.cc
--- a/src/arch/arm/isa.cc       Sat May 23 13:37:22 2015 +0100
+++ b/src/arch/arm/isa.cc       Sat May 23 13:46:52 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2014 ARM Limited
+ * Copyright (c) 2010-2015 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -45,6 +45,7 @@
 #include "cpu/base.hh"
 #include "debug/Arm.hh"
 #include "debug/MiscRegs.hh"
+#include "dev/arm/generic_timer.hh"
 #include "params/ArmISA.hh"
 #include "sim/faults.hh"
 #include "sim/stat_control.hh"
@@ -730,52 +731,14 @@
                 return readMiscRegNoEffect(MISCREG_SCR_EL3);
             }
         }
+
       // Generic Timer registers
-      case MISCREG_CNTFRQ:
-      case MISCREG_CNTFRQ_EL0:
-        inform_once("Read CNTFREQ_EL0 frequency\n");
-        return getSystemCounter(tc)->freq();
-      case MISCREG_CNTPCT:
-      case MISCREG_CNTPCT_EL0:
-        return getSystemCounter(tc)->value();
-      case MISCREG_CNTVCT:
-        return getSystemCounter(tc)->value();
-      case MISCREG_CNTVCT_EL0:
-        return getSystemCounter(tc)->value();
-      case MISCREG_CNTP_CVAL:
-      case MISCREG_CNTP_CVAL_EL0:
-        return getArchTimer(tc, tc->cpuId())->compareValue();
-      case MISCREG_CNTP_TVAL:
-      case MISCREG_CNTP_TVAL_EL0:
-        return getArchTimer(tc, tc->cpuId())->timerValue();
-      case MISCREG_CNTP_CTL:
-      case MISCREG_CNTP_CTL_EL0:
-        return getArchTimer(tc, tc->cpuId())->control();
-      // PL1 phys. timer, secure
-      //   AArch64
-      // case MISCREG_CNTPS_CVAL_EL1:
-      // case MISCREG_CNTPS_TVAL_EL1:
-      // case MISCREG_CNTPS_CTL_EL1:
-      // PL2 phys. timer, non-secure
-      //   AArch32
-      // case MISCREG_CNTHCTL:
-      // case MISCREG_CNTHP_CVAL:
-      // case MISCREG_CNTHP_TVAL:
-      // case MISCREG_CNTHP_CTL:
-      //   AArch64
-      // case MISCREG_CNTHCTL_EL2:
-      // case MISCREG_CNTHP_CVAL_EL2:
-      // case MISCREG_CNTHP_TVAL_EL2:
-      // case MISCREG_CNTHP_CTL_EL2:
-      // Virtual timer
-      //   AArch32
-      // case MISCREG_CNTV_CVAL:
-      // case MISCREG_CNTV_TVAL:
-      // case MISCREG_CNTV_CTL:
-      //   AArch64
-      // case MISCREG_CNTV_CVAL_EL2:
-      // case MISCREG_CNTV_TVAL_EL2:
-      // case MISCREG_CNTV_CTL_EL2:
+      case MISCREG_CNTFRQ ... MISCREG_CNTHP_CTL:
+      case MISCREG_CNTPCT ... MISCREG_CNTHP_CVAL:
+      case MISCREG_CNTKCTL_EL1 ... MISCREG_CNTV_CVAL_EL0:
+      case MISCREG_CNTVOFF_EL2 ... MISCREG_CNTPS_CVAL_EL1:
+        return getGenericTimer(tc).readMiscReg(misc_reg);
+
       default:
         break;
 
@@ -1853,47 +1816,11 @@
             break;
 
           // Generic Timer registers
-          case MISCREG_CNTFRQ:
-          case MISCREG_CNTFRQ_EL0:
-            getSystemCounter(tc)->setFreq(val);
-            break;
-          case MISCREG_CNTP_CVAL:
-          case MISCREG_CNTP_CVAL_EL0:
-            getArchTimer(tc, tc->cpuId())->setCompareValue(val);
-            break;
-          case MISCREG_CNTP_TVAL:
-          case MISCREG_CNTP_TVAL_EL0:
-            getArchTimer(tc, tc->cpuId())->setTimerValue(val);
-            break;
-          case MISCREG_CNTP_CTL:
-          case MISCREG_CNTP_CTL_EL0:
-            getArchTimer(tc, tc->cpuId())->setControl(val);
-            break;
-          // PL1 phys. timer, secure
-          //   AArch64
-          case MISCREG_CNTPS_CVAL_EL1:
-          case MISCREG_CNTPS_TVAL_EL1:
-          case MISCREG_CNTPS_CTL_EL1:
-          // PL2 phys. timer, non-secure
-          //   AArch32
-          case MISCREG_CNTHCTL:
-          case MISCREG_CNTHP_CVAL:
-          case MISCREG_CNTHP_TVAL:
-          case MISCREG_CNTHP_CTL:
-          //   AArch64
-          case MISCREG_CNTHCTL_EL2:
-          case MISCREG_CNTHP_CVAL_EL2:
-          case MISCREG_CNTHP_TVAL_EL2:
-          case MISCREG_CNTHP_CTL_EL2:
-          // Virtual timer
-          //   AArch32
-          case MISCREG_CNTV_CVAL:
-          case MISCREG_CNTV_TVAL:
-          case MISCREG_CNTV_CTL:
-          //   AArch64
-          // case MISCREG_CNTV_CVAL_EL2:
-          // case MISCREG_CNTV_TVAL_EL2:
-          // case MISCREG_CNTV_CTL_EL2:
+          case MISCREG_CNTFRQ ... MISCREG_CNTHP_CTL:
+          case MISCREG_CNTPCT ... MISCREG_CNTHP_CVAL:
+          case MISCREG_CNTKCTL_EL1 ... MISCREG_CNTV_CVAL_EL0:
+          case MISCREG_CNTVOFF_EL2 ... MISCREG_CNTPS_CVAL_EL1:
+            getGenericTimer(tc).setMiscReg(misc_reg, newVal);
             break;
         }
     }
@@ -1988,26 +1915,23 @@
     }
 }
 
-::GenericTimer::SystemCounter *
-ISA::getSystemCounter(ThreadContext *tc)
+BaseISADevice &
+ISA::getGenericTimer(ThreadContext *tc)
 {
-    ::GenericTimer::SystemCounter *cnt = ((ArmSystem *) tc->getSystemPtr())->
-        getSystemCounter();
-    if (cnt == NULL) {
-        panic("System counter not available\n");
+    // We only need to create an ISA interface the first time we try
+    // to access the timer.
+    if (timer)
+        return *timer.get();
+
+    assert(system);
+    GenericTimer *generic_timer(system->getGenericTimer());
+    if (!generic_timer) {
+        panic("Trying to get a generic timer from a system that hasn't "
+              "been configured to use a generic timer.\n");
     }
-    return cnt;
-}
 
-::GenericTimer::ArchTimer *
-ISA::getArchTimer(ThreadContext *tc, int cpu_id)
-{
-    ::GenericTimer::ArchTimer *timer = ((ArmSystem *) tc->getSystemPtr())->
-        getArchTimer(cpu_id);
-    if (timer == NULL) {
-        panic("Architected timer not available\n");
-    }
-    return timer;
+    timer.reset(new GenericTimerISA(*generic_timer, tc->cpuId()));
+    return *timer.get();
 }
 
 }
diff -r adec1cf1c300 -r 8551af601f75 src/arch/arm/isa.hh
--- a/src/arch/arm/isa.hh       Sat May 23 13:37:22 2015 +0100
+++ b/src/arch/arm/isa.hh       Sat May 23 13:46:52 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2012-2014 ARM Limited
+ * Copyright (c) 2010, 2012-2015 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -49,7 +49,6 @@
 #include "arch/arm/tlb.hh"
 #include "arch/arm/types.hh"
 #include "debug/Checkpoint.hh"
-#include "dev/arm/generic_timer.hh"
 #include "sim/sim_object.hh"
 
 struct ArmISAParams;
@@ -139,6 +138,9 @@
         // PMU belonging to this ISA
         BaseISADevice *pmu;
 
+        // Generic timer interface belonging to this ISA
+        std::unique_ptr<BaseISADevice> timer;
+
         // Cached copies of system-level properties
         bool haveSecurity;
         bool haveLPAE;
@@ -205,9 +207,7 @@
             }
         }
 
-        ::GenericTimer::SystemCounter * getSystemCounter(ThreadContext *tc);
-        ::GenericTimer::ArchTimer * getArchTimer(ThreadContext *tc,
-                                                 int cpu_id);
+        BaseISADevice &getGenericTimer(ThreadContext *tc);
 
 
       private:
diff -r adec1cf1c300 -r 8551af601f75 src/arch/arm/system.cc
--- a/src/arch/arm/system.cc    Sat May 23 13:37:22 2015 +0100
+++ b/src/arch/arm/system.cc    Sat May 23 13:46:52 2015 +0100
@@ -151,24 +151,6 @@
     }
 }
 
-GenericTimer::ArchTimer *
-ArmSystem::getArchTimer(int cpu_id) const
-{
-    if (_genericTimer) {
-        return _genericTimer->getArchTimer(cpu_id);
-    }
-    return NULL;
-}
-
-GenericTimer::SystemCounter *
-ArmSystem::getSystemCounter() const
-{
-    if (_genericTimer) {
-        return _genericTimer->getSystemCounter();
-    }
-    return NULL;
-}
-
 bool
 ArmSystem::haveSecurity(ThreadContext *tc)
 {
diff -r adec1cf1c300 -r 8551af601f75 src/arch/arm/system.hh
--- a/src/arch/arm/system.hh    Sat May 23 13:37:22 2015 +0100
+++ b/src/arch/arm/system.hh    Sat May 23 13:46:52 2015 +0100
@@ -46,13 +46,13 @@
 #include <string>
 #include <vector>
 
-#include "dev/arm/generic_timer.hh"
 #include "kern/linux/events.hh"
 #include "params/ArmSystem.hh"
 #include "params/GenericArmSystem.hh"
 #include "sim/sim_object.hh"
 #include "sim/system.hh"
 
+class GenericTimer;
 class ThreadContext;
 
 class ArmSystem : public System
@@ -166,11 +166,8 @@
         _genericTimer = generic_timer;
     }
 
-    /** Returns a pointer to the system counter. */
-    GenericTimer::SystemCounter *getSystemCounter() const;
-
-    /** Returns a pointer to the appropriate architected timer. */
-    GenericTimer::ArchTimer *getArchTimer(int cpu_id) const;
+    /** Get a pointer to the system's generic timer model */
+    GenericTimer *getGenericTimer() const { return _genericTimer; }
 
     /** Returns true if the register width of the highest implemented exception
      * level is 64 bits (ARMv8) */
diff -r adec1cf1c300 -r 8551af601f75 src/dev/arm/RealView.py
--- a/src/dev/arm/RealView.py   Sat May 23 13:37:22 2015 +0100
+++ b/src/dev/arm/RealView.py   Sat May 23 13:46:52 2015 +0100
@@ -136,7 +136,7 @@
     cxx_header = "dev/arm/generic_timer.hh"
     system = Param.System(Parent.any, "system")
     gic = Param.BaseGic(Parent.any, "GIC to use for interrupting")
-    int_num = Param.UInt32("Interrupt number used per-cpu to GIC")
+    int_phys = Param.UInt32("Interrupt number used per-cpu to GIC")
     # @todo: for now only one timer per CPU is supported, which is the
     # normal behaviour when Security and Virt. extensions are disabled.
 
@@ -457,7 +457,7 @@
                                idreg=0x02250000, pio_addr=0x1C010000)
     gic = Pl390(dist_addr=0x2C001000, cpu_addr=0x2C002000)
     local_cpu_timer = CpuLocalTimer(int_num_timer=29, int_num_watchdog=30, 
pio_addr=0x2C080000)
-    generic_timer = GenericTimer(int_num=29)
+    generic_timer = GenericTimer(int_phys=29)
     timer0 = Sp804(int_num0=34, int_num1=34, pio_addr=0x1C110000, 
clock0='1MHz', clock1='1MHz')
     timer1 = Sp804(int_num0=35, int_num1=35, pio_addr=0x1C120000, 
clock0='1MHz', clock1='1MHz')
     clcd   = Pl111(pio_addr=0x1c1f0000, int_num=46)
diff -r adec1cf1c300 -r 8551af601f75 src/dev/arm/generic_timer.cc
--- a/src/dev/arm/generic_timer.cc      Sat May 23 13:37:22 2015 +0100
+++ b/src/dev/arm/generic_timer.cc      Sat May 23 13:46:52 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013 ARM Limited
+ * Copyright (c) 2013, 2015 ARM Limited
  * All rights reserved.
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to