summaryrefslogtreecommitdiff
path: root/src/dev/arm/generic_timer.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/dev/arm/generic_timer.hh')
-rw-r--r--src/dev/arm/generic_timer.hh38
1 files changed, 33 insertions, 5 deletions
diff --git a/src/dev/arm/generic_timer.hh b/src/dev/arm/generic_timer.hh
index 3eec1d42e..ccfb1277f 100644
--- a/src/dev/arm/generic_timer.hh
+++ b/src/dev/arm/generic_timer.hh
@@ -42,6 +42,7 @@
#define __DEV_ARM_GENERIC_TIMER_HH__
#include "arch/arm/isa_device.hh"
+#include "arch/arm/system.hh"
#include "base/bitunion.hh"
#include "dev/arm/base_gic.hh"
#include "sim/core.hh"
@@ -159,6 +160,8 @@ class ArchTimer : public Serializable, public Drainable
void counterLimitReached();
EventFunctionWrapper _counterLimitReachedEvent;
+ virtual bool scheduleEvents() { return true; }
+
public:
ArchTimer(const std::string &name,
SimObject &parent,
@@ -201,6 +204,28 @@ class ArchTimer : public Serializable, public Drainable
ArchTimer(const ArchTimer &t);
};
+class ArchTimerKvm : public ArchTimer
+{
+ private:
+ ArmSystem &system;
+
+ public:
+ ArchTimerKvm(const std::string &name,
+ ArmSystem &system,
+ SimObject &parent,
+ SystemCounter &sysctr,
+ const Interrupt &interrupt)
+ : ArchTimer(name, parent, sysctr, interrupt), system(system) {}
+
+ protected:
+ // For ArchTimer's in a GenericTimerISA with Kvm execution about
+ // to begin, skip rescheduling the event.
+ // Otherwise, we should reschedule the event (if necessary).
+ bool scheduleEvents() override {
+ return !system.validKvmEnvironment();
+ }
+};
+
class GenericTimer : public SimObject
{
public:
@@ -215,25 +240,25 @@ class GenericTimer : public SimObject
protected:
struct CoreTimers {
- CoreTimers(GenericTimer &parent, unsigned cpu,
+ CoreTimers(GenericTimer &parent, ArmSystem &system, unsigned cpu,
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,
+ system, parent, parent.systemCounter,
irqPhys),
virt(csprintf("%s.virt_timer%d", parent.name(), cpu),
- parent, parent.systemCounter,
+ system, parent, parent.systemCounter,
irqVirt)
{}
ArchTimer::Interrupt irqPhys;
ArchTimer::Interrupt irqVirt;
- ArchTimer phys;
- ArchTimer virt;
+ ArchTimerKvm phys;
+ ArchTimerKvm virt;
private:
// Disable copying
@@ -250,6 +275,9 @@ class GenericTimer : public SimObject
std::vector<std::unique_ptr<CoreTimers>> timers;
protected: // Configuration
+ /// ARM system containing this timer
+ ArmSystem &system;
+
/// Pointer to the GIC, needed to trigger timer interrupts.
BaseGic *const gic;