diff options
-rw-r--r-- | src/dev/arm/RealView.py | 8 | ||||
-rw-r--r-- | src/dev/arm/generic_timer.cc | 23 | ||||
-rw-r--r-- | src/dev/arm/generic_timer.hh | 8 |
3 files changed, 33 insertions, 6 deletions
diff --git a/src/dev/arm/RealView.py b/src/dev/arm/RealView.py index 6e8630a96..37cf72ede 100644 --- a/src/dev/arm/RealView.py +++ b/src/dev/arm/RealView.py @@ -404,6 +404,10 @@ class GenericTimer(ClockedObject): int_virt = Param.ArmPPI("Virtual timer interrupt") int_hyp = Param.ArmPPI("Hypervisor timer interrupt") + freqs = VectorParam.UInt32([0x01800000], "Frequencies available for the " + "system counter (in Hz). First element is the base frequency, " + "following are alternative lower ones which must be exact divisors") + def generateDeviceTree(self, state): node = FdtNode("timer") @@ -430,6 +434,10 @@ class GenericTimerMem(PioDevice): int_phys = Param.ArmSPI("Physical Interrupt") int_virt = Param.ArmSPI("Virtual Interrupt") + freqs = VectorParam.UInt32([0x01800000], "Frequencies available for the " + "system counter (in Hz). First element is the base frequency, " + "following are alternative lower ones which must be exact divisors") + class PL031(AmbaIntDevice): type = 'PL031' cxx_header = "dev/arm/rtc_pl031.hh" diff --git a/src/dev/arm/generic_timer.cc b/src/dev/arm/generic_timer.cc index 430b4ebfa..7c1f09add 100644 --- a/src/dev/arm/generic_timer.cc +++ b/src/dev/arm/generic_timer.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2015, 2017-2018 ARM Limited + * Copyright (c) 2013, 2015, 2017-2018, 2019 ARM Limited * All rights reserved. * * The license below extends only to copyright in the software and shall @@ -36,6 +36,7 @@ * * Authors: Giacomo Gabrielli * Andreas Sandberg + * Adrian Herrera */ #include "dev/arm/generic_timer.hh" @@ -47,10 +48,21 @@ #include "params/GenericTimer.hh" #include "params/GenericTimerMem.hh" -SystemCounter::SystemCounter() - : _freq(0), _period(0), _resetTick(0), _regCntkctl(0) +SystemCounter::SystemCounter(std::vector<uint32_t> &freqs) + : _freqTable(freqs), + _resetTick(0), + _regCntkctl(0) { - setFreq(0x01800000); + fatal_if(_freqTable.empty(), "SystemCounter::SystemCounter: Base " + "frequency not provided\n"); + // Store the table end marker as a 32-bit zero word + _freqTable.push_back(0); + fatal_if(_freqTable.size() > MAX_FREQ_ENTRIES, + "SystemCounter::SystemCounter: Architecture states a maximum of 1004 " + "frequency table entries, limit surpassed\n"); + // Set the active frequency to be the base + _freq = freqs.front(); + _period = (1.0 / _freq) * SimClock::Frequency; } void @@ -221,6 +233,7 @@ ArchTimer::drainResume() GenericTimer::GenericTimer(GenericTimerParams *p) : ClockedObject(p), + systemCounter(p->freqs), system(*p->system) { fatal_if(!p->system, "No system specified, can't instantiate timer.\n"); @@ -528,7 +541,7 @@ GenericTimerMem::GenericTimerMem(GenericTimerMemParams *p) timerRange(RangeSize(p->base + sys->getPageBytes(), sys->getPageBytes())), addrRanges{ctrlRange, timerRange}, - systemCounter(), + systemCounter(p->freqs), physTimer(csprintf("%s.phys_timer0", name()), *this, systemCounter, p->int_phys->get()), diff --git a/src/dev/arm/generic_timer.hh b/src/dev/arm/generic_timer.hh index 9a7f162e7..5e1965baf 100644 --- a/src/dev/arm/generic_timer.hh +++ b/src/dev/arm/generic_timer.hh @@ -36,6 +36,7 @@ * * Authors: Giacomo Gabrielli * Andreas Sandberg + * Adrian Herrera */ #ifndef __DEV_ARM_GENERIC_TIMER_HH__ @@ -64,6 +65,8 @@ class SystemCounter : public Serializable protected: /// Counter frequency (as specified by CNTFRQ). uint32_t _freq; + /// Frequency modes table with all possible frequencies for the counter + std::vector<uint32_t> _freqTable; /// Cached copy of the counter period (inverse of the frequency). Tick _period; /// Tick when the counter was reset. @@ -74,8 +77,11 @@ class SystemCounter : public Serializable /// Hypervisor event stream control register uint32_t _regCnthctl; + /// Maximum architectural number of frequency table entries + static constexpr size_t MAX_FREQ_ENTRIES = 1004; + public: - SystemCounter(); + SystemCounter(std::vector<uint32_t> &freqs); /// Returns the current value of the physical counter. uint64_t value() const |