summaryrefslogtreecommitdiff
path: root/src/dev/arm/generic_timer.hh
diff options
context:
space:
mode:
authorAndreas Sandberg <andreas.sandberg@arm.com>2015-05-23 13:46:56 +0100
committerAndreas Sandberg <andreas.sandberg@arm.com>2015-05-23 13:46:56 +0100
commitf3f06e1684c6575e25b965ab0585473bb47e58cc (patch)
tree44323565da1216f180bef570762aa0f52249753a /src/dev/arm/generic_timer.hh
parent6533f2000bcd6d01f59655491198950b4ebff80b (diff)
downloadgem5-f3f06e1684c6575e25b965ab0585473bb47e58cc.tar.xz
arm, dev: Add support for a memory mapped generic timer
There are cases when we don't want to use a system register mapped generic timer, but can't use the SP804. For example, when using KVM on aarch64, we want to intercept accesses to the generic timer, but can't do so if it is using the system register interface. In such cases, we need to use a memory-mapped generic timer. This changeset adds a device model that implements the memory mapped generic timer interface. The current implementation only supports a single frame (i.e., one virtual timer and one physical timer).
Diffstat (limited to 'src/dev/arm/generic_timer.hh')
-rw-r--r--src/dev/arm/generic_timer.hh58
1 files changed, 58 insertions, 0 deletions
diff --git a/src/dev/arm/generic_timer.hh b/src/dev/arm/generic_timer.hh
index 7e6bd2af3..d8f7f54e2 100644
--- a/src/dev/arm/generic_timer.hh
+++ b/src/dev/arm/generic_timer.hh
@@ -54,6 +54,7 @@
class Checkpoint;
class GenericTimerParams;
+class GenericTimerMemParams;
/// Global system counter. It is shared by the architected timers.
/// @todo: implement memory-mapped controls
@@ -273,4 +274,61 @@ class GenericTimerISA : public ArmISA::BaseISADevice
unsigned cpu;
};
+class GenericTimerMem : public PioDevice
+{
+ public:
+ GenericTimerMem(GenericTimerMemParams *p);
+
+ void serialize(std::ostream &os) M5_ATTR_OVERRIDE;
+ void unserialize(Checkpoint *cp, const std::string &sec) M5_ATTR_OVERRIDE;
+
+ public: // PioDevice
+ AddrRangeList getAddrRanges() const M5_ATTR_OVERRIDE { return addrRanges; }
+ Tick read(PacketPtr pkt) M5_ATTR_OVERRIDE;
+ Tick write(PacketPtr pkt) M5_ATTR_OVERRIDE;
+
+ protected:
+ uint64_t ctrlRead(Addr addr, size_t size) const;
+ void ctrlWrite(Addr addr, size_t size, uint64_t value);
+
+ uint64_t timerRead(Addr addr, size_t size) const;
+ void timerWrite(Addr addr, size_t size, uint64_t value);
+
+ protected: // Registers
+ static const Addr CTRL_CNTFRQ = 0x000;
+ static const Addr CTRL_CNTNSAR = 0x004;
+ static const Addr CTRL_CNTTIDR = 0x008;
+ static const Addr CTRL_CNTACR_BASE = 0x040;
+ static const Addr CTRL_CNTVOFF_LO_BASE = 0x080;
+ static const Addr CTRL_CNTVOFF_HI_BASE = 0x084;
+
+ static const Addr TIMER_CNTPCT_LO = 0x000;
+ static const Addr TIMER_CNTPCT_HI = 0x004;
+ static const Addr TIMER_CNTVCT_LO = 0x008;
+ static const Addr TIMER_CNTVCT_HI = 0x00C;
+ static const Addr TIMER_CNTFRQ = 0x010;
+ static const Addr TIMER_CNTEL0ACR = 0x014;
+ static const Addr TIMER_CNTVOFF_LO = 0x018;
+ static const Addr TIMER_CNTVOFF_HI = 0x01C;
+ static const Addr TIMER_CNTP_CVAL_LO = 0x020;
+ static const Addr TIMER_CNTP_CVAL_HI = 0x024;
+ static const Addr TIMER_CNTP_TVAL = 0x028;
+ static const Addr TIMER_CNTP_CTL = 0x02C;
+ static const Addr TIMER_CNTV_CVAL_LO = 0x030;
+ static const Addr TIMER_CNTV_CVAL_HI = 0x034;
+ static const Addr TIMER_CNTV_TVAL = 0x038;
+ static const Addr TIMER_CNTV_CTL = 0x03C;
+
+ protected: // Params
+ const AddrRange ctrlRange;
+ const AddrRange timerRange;
+ const AddrRangeList addrRanges;
+
+ protected:
+ /// System counter.
+ SystemCounter systemCounter;
+ ArchTimer physTimer;
+ ArchTimer virtTimer;
+};
+
#endif // __DEV_ARM_GENERIC_TIMER_HH__