summaryrefslogtreecommitdiff
path: root/src/arch/arm
diff options
context:
space:
mode:
authorAndreas Sandberg <andreas.sandberg@arm.com>2015-05-23 13:46:52 +0100
committerAndreas Sandberg <andreas.sandberg@arm.com>2015-05-23 13:46:52 +0100
commit65f3f097d3c270d2f28fc7d55651afaefb56ceed (patch)
tree099c9667e246b9e8197f292c1880d9f7a3af9159 /src/arch/arm
parent5435f25ec80ff691c4e42e06888c60a01848a31d (diff)
downloadgem5-65f3f097d3c270d2f28fc7d55651afaefb56ceed.tar.xz
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 (limited to 'src/arch/arm')
-rw-r--r--src/arch/arm/isa.cc132
-rw-r--r--src/arch/arm/isa.hh10
-rw-r--r--src/arch/arm/system.cc18
-rw-r--r--src/arch/arm/system.hh9
4 files changed, 36 insertions, 133 deletions
diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc
index 4358c8b2e..2120c56db 100644
--- a/src/arch/arm/isa.cc
+++ b/src/arch/arm/isa.cc
@@ -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 @@ ISA::readMiscReg(int misc_reg, ThreadContext *tc)
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 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
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 @@ ISA::tlbiMVA(ThreadContext *tc, MiscReg newVal, bool secure_lookup, bool hyp,
}
}
-::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 --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh
index fd9801ae2..11f25de6d 100644
--- a/src/arch/arm/isa.hh
+++ b/src/arch/arm/isa.hh
@@ -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 @@ namespace ArmISA
// 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 @@ namespace ArmISA
}
}
- ::GenericTimer::SystemCounter * getSystemCounter(ThreadContext *tc);
- ::GenericTimer::ArchTimer * getArchTimer(ThreadContext *tc,
- int cpu_id);
+ BaseISADevice &getGenericTimer(ThreadContext *tc);
private:
diff --git a/src/arch/arm/system.cc b/src/arch/arm/system.cc
index eebb220d8..a7db9ca1b 100644
--- a/src/arch/arm/system.cc
+++ b/src/arch/arm/system.cc
@@ -151,24 +151,6 @@ ArmSystem::initState()
}
}
-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 --git a/src/arch/arm/system.hh b/src/arch/arm/system.hh
index 0937f6376..3add01e61 100644
--- a/src/arch/arm/system.hh
+++ b/src/arch/arm/system.hh
@@ -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 @@ class ArmSystem : public System
_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) */