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")
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"
/*
- * 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
*
* Authors: Giacomo Gabrielli
* Andreas Sandberg
+ * Adrian Herrera
*/
#include "dev/arm/generic_timer.hh"
#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
GenericTimer::GenericTimer(GenericTimerParams *p)
: ClockedObject(p),
+ systemCounter(p->freqs),
system(*p->system)
{
fatal_if(!p->system, "No system specified, can't instantiate timer.\n");
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()),
*
* Authors: Giacomo Gabrielli
* Andreas Sandberg
+ * Adrian Herrera
*/
#ifndef __DEV_ARM_GENERIC_TIMER_HH__
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.
/// 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