summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dev/arm/RealView.py8
-rw-r--r--src/dev/arm/generic_timer.cc23
-rw-r--r--src/dev/arm/generic_timer.hh8
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