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