summaryrefslogtreecommitdiff
path: root/src/cpu/kvm/timer.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/kvm/timer.hh')
-rw-r--r--src/cpu/kvm/timer.hh206
1 files changed, 206 insertions, 0 deletions
diff --git a/src/cpu/kvm/timer.hh b/src/cpu/kvm/timer.hh
new file mode 100644
index 000000000..a5105e7fa
--- /dev/null
+++ b/src/cpu/kvm/timer.hh
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2012 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Andreas Sandberg
+ */
+
+#ifndef __CPU_KVM_TIMER_HH__
+#define __CPU_KVM_TIMER_HH__
+
+#include <ctime>
+
+#include "sim/core.hh"
+
+/**
+ * Timer functions to interrupt VM execution after a number of
+ * simulation ticks. The timer allows scaling of the host time to take
+ * performance differences between the simulated and real CPU into
+ * account.
+ *
+ * The performance scaling factor is ratio between the target's CPI
+ * and the host's CPI. It is larger than 1 if the host is faster than
+ * the target and lower than 1 if it is slower.
+ *
+ * When the timer times out, it sends a signal to the thread that
+ * started the timer. The signal forces KVM to drop out of the system
+ * call that started the guest and hands control to gem5.
+ */
+class BaseKvmTimer
+{
+ public:
+ /**
+ * Setup basic timer functionality shared by all timer
+ * implementations.
+ *
+ * @param signo Signal to deliver
+ * @param hostFactor Performance scaling factor
+ * @param hostFreq Clock frequency of the host
+ */
+ BaseKvmTimer(int signo, float hostFactor, Tick hostFreq)
+ : signo(signo), _resolution(0),
+ hostFactor(hostFactor), hostFreq(hostFreq) {};
+ virtual ~BaseKvmTimer() {};
+
+ /**
+ * Arm the timer so that it fires after a certain number of ticks.
+ *
+ * @note A timer implementation is free to convert between
+ * simulation ticks and virtualized time using any method it
+ * chooses. The accuracy of the timer therefore depends on what it
+ * measures, an accurate timer implementation should measure the
+ * number of cycles or instructions executed in the guest. If such
+ * counters are unavailable, it may fallback to wall clock time.
+ *
+ * @param ticks Number of ticks until the timer fires
+ */
+ virtual void arm(Tick ticks) = 0;
+ /**
+ * Disarm the timer.
+ *
+ * When this method has returned, the timer may no longer deliver
+ * signals upon timeout.
+ */
+ virtual void disarm() = 0;
+
+ /**
+ * Determine the resolution of the timer in ticks. This method is
+ * mainly used to determine the smallest number of ticks the timer
+ * can wait before triggering a signal.
+ *
+ * @return Minimum number of ticks the timer can resolve
+ */
+ Tick resolution() {
+ if (_resolution == 0)
+ _resolution = calcResolution();
+ return _resolution;
+ }
+
+ /**
+ * Convert cycles executed on the host into Ticks executed in the
+ * simulator. Scales the results using the hostFactor to take CPU
+ * performance differences into account.
+ *
+ * @return Host cycles executed in VM converted to simulation ticks
+ */
+ Tick ticksFromHostCycles(uint64_t cycles) {
+ return cycles * hostFactor * hostFreq;
+ }
+
+ /**
+ * Convert nanoseconds executed on the host into Ticks executed in
+ * the simulator. Scales the results using the hostFactor to take
+ * CPU performance differences into account.
+ *
+ * @return Nanoseconds executed in VM converted to simulation ticks
+ */
+ Tick ticksFromHostNs(uint64_t ns) {
+ return ns * hostFactor * SimClock::Float::ns;
+ }
+
+ protected:
+ /**
+ * Calculate the timer resolution, used by resolution() which
+ * caches the result.
+ *
+ * @return Minimum number of ticks the timer can resolve
+ */
+ virtual Tick calcResolution() = 0;
+
+ /**
+ * Convert a time in simulator ticks to host nanoseconds.
+ *
+ * @return Simulation ticks converted into nanoseconds on the host
+ */
+ uint64_t hostNs(Tick ticks) {
+ return ticks / (SimClock::Float::ns * hostFactor);
+ }
+
+ /**
+ * Convert a time in simulator ticks to host cycles
+ *
+ *
+ * @return Simulation ticks converted into CPU cycles on the host
+ */
+ uint64_t hostCycles(Tick ticks) {
+ return ticks / (hostFreq * hostFactor);
+ }
+
+ /** Signal to deliver when the timer times out */
+ int signo;
+
+ private:
+ /** Cached resolution */
+ mutable Tick _resolution;
+
+ /** Performance scaling factor */
+ float hostFactor;
+ /** Host frequency */
+ Tick hostFreq;
+};
+
+/**
+ * Timer based on standard POSIX timers. The POSIX timer API supports
+ * several different clock with different characteristics.
+ *
+ * @note It might be tempting to use
+ * CLOCK_(THREAD|PROCESS)_CPUTIME_ID, however, this clock usually has
+ * much lower resolution than the real-time clocks.
+ */
+class PosixKvmTimer : public BaseKvmTimer
+{
+ public:
+ /**
+ * @param signo Signal to deliver
+ * @param clockID ID of the clock to use
+ * @param hostFactor Performance scaling factor
+ * @param hostFreq Clock frequency of the host
+ */
+ PosixKvmTimer(int signo, clockid_t clockID,
+ float hostFactor, Tick hostFreq);
+ ~PosixKvmTimer();
+
+ void arm(Tick ticks);
+ void disarm();
+
+ protected:
+ Tick calcResolution();
+
+ private:
+ clockid_t clockID;
+ timer_t timer;
+};
+
+#endif