diff options
author | Andreas Sandberg <andreas.sandberg@arm.com> | 2015-05-23 13:46:53 +0100 |
---|---|---|
committer | Andreas Sandberg <andreas.sandberg@arm.com> | 2015-05-23 13:46:53 +0100 |
commit | 2278fec1d1064ec1622098153b20a773fb688e78 (patch) | |
tree | fcb7441fb487261ba3e9465fa30ad856e286f7ca /src/dev/arm/generic_timer.hh | |
parent | 65f3f097d3c270d2f28fc7d55651afaefb56ceed (diff) | |
download | gem5-2278fec1d1064ec1622098153b20a773fb688e78.tar.xz |
dev, arm: Add virtual timers to the generic timer model
The generic timer model currently does not support virtual
counters. Virtual and physical counters both tick with the same
frequency. However, virtual timers allow a hypervisor to set an offset
that is subtracted from the counter when it is read. This enables the
hypervisor to present a time base that ticks with virtual time in the
VM (i.e., doesn't tick when the VM isn't running). Modern Linux
kernels generally assume that virtual counters exist and try to use
them by default.
Diffstat (limited to 'src/dev/arm/generic_timer.hh')
-rw-r--r-- | src/dev/arm/generic_timer.hh | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/src/dev/arm/generic_timer.hh b/src/dev/arm/generic_timer.hh index 8dc921275..7e6bd2af3 100644 --- a/src/dev/arm/generic_timer.hh +++ b/src/dev/arm/generic_timer.hh @@ -145,6 +145,8 @@ class ArchTimer ArchTimerCtrl _control; /// Programmed limit value for the upcounter ({CNTP/CNTHP/CNTV}_CVAL). uint64_t _counterLimit; + /// Offset relative to the physical timer (CNTVOFF) + uint64_t _offset; /** * Timer settings or the offset has changed, re-evaluate @@ -180,6 +182,9 @@ class ArchTimer uint32_t control() const { return _control; } void setControl(uint32_t val); + uint64_t offset() const { return _offset; } + void setOffset(uint64_t val); + /// Returns the value of the counter which this timer relies on. uint64_t value() const; @@ -206,17 +211,24 @@ class GenericTimer : public SimObject protected: struct CoreTimers { CoreTimers(GenericTimer &parent, unsigned cpu, - unsigned _irqPhys) + unsigned _irqPhys, unsigned _irqVirt) : irqPhys(*parent.gic, _irqPhys, cpu), + irqVirt(*parent.gic, _irqVirt, cpu), // This should really be phys_timerN, but we are stuck with // arch_timer for backwards compatibility. phys(csprintf("%s.arch_timer%d", parent.name(), cpu), parent, parent.systemCounter, - irqPhys) + irqPhys), + virt(csprintf("%s.virt_timer%d", parent.name(), cpu), + parent, parent.systemCounter, + irqVirt) {} ArchTimer::Interrupt irqPhys; + ArchTimer::Interrupt irqVirt; + ArchTimer phys; + ArchTimer virt; private: // Disable copying @@ -238,6 +250,9 @@ class GenericTimer : public SimObject /// Physical timer interrupt const unsigned irqPhys; + + /// Virtual timer interrupt + const unsigned irqVirt; }; class GenericTimerISA : public ArmISA::BaseISADevice |