From 65f3f097d3c270d2f28fc7d55651afaefb56ceed Mon Sep 17 00:00:00 2001 From: Andreas Sandberg Date: Sat, 23 May 2015 13:46:52 +0100 Subject: 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. --- src/arch/arm/isa.cc | 132 +++++++++++-------------------------------------- src/arch/arm/isa.hh | 10 ++-- src/arch/arm/system.cc | 18 ------- src/arch/arm/system.hh | 9 ++-- 4 files changed, 36 insertions(+), 133 deletions(-) (limited to 'src/arch/arm') 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 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 #include -#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) */ -- cgit v1.2.3