cpu, arm: Distinguish Float* and SimdFloat*, create FloatMem* opClass
[gem5.git] / src / cpu / kvm / timer.hh
1 /*
2 * Copyright (c) 2012 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Andreas Sandberg
38 */
39
40 #ifndef __CPU_KVM_TIMER_HH__
41 #define __CPU_KVM_TIMER_HH__
42
43 #include <ctime>
44
45 #include "cpu/kvm/perfevent.hh"
46 #include "sim/core.hh"
47
48 /**
49 * Timer functions to interrupt VM execution after a number of
50 * simulation ticks. The timer allows scaling of the host time to take
51 * performance differences between the simulated and real CPU into
52 * account.
53 *
54 * The performance scaling factor is ratio between the target's CPI
55 * and the host's CPI. It is larger than 1 if the host is faster than
56 * the target and lower than 1 if it is slower.
57 *
58 * When the timer times out, it sends a signal to the thread that
59 * started the timer. The signal forces KVM to drop out of the system
60 * call that started the guest and hands control to gem5.
61 */
62 class BaseKvmTimer
63 {
64 public:
65 /**
66 * Setup basic timer functionality shared by all timer
67 * implementations.
68 *
69 * @param signo Signal to deliver
70 * @param hostFactor Performance scaling factor
71 * @param hostFreq Clock frequency of the host
72 */
73 BaseKvmTimer(int signo, float hostFactor, Tick hostFreq)
74 : signo(signo), _resolution(0),
75 hostFactor(hostFactor), hostFreq(hostFreq) {};
76 virtual ~BaseKvmTimer() {};
77
78 /**
79 * Arm the timer so that it fires after a certain number of ticks.
80 *
81 * @note A timer implementation is free to convert between
82 * simulation ticks and virtualized time using any method it
83 * chooses. The accuracy of the timer therefore depends on what it
84 * measures, an accurate timer implementation should measure the
85 * number of cycles or instructions executed in the guest. If such
86 * counters are unavailable, it may fallback to wall clock time.
87 *
88 * @param ticks Number of ticks until the timer fires
89 */
90 virtual void arm(Tick ticks) = 0;
91 /**
92 * Disarm the timer.
93 *
94 * When this method has returned, the timer may no longer deliver
95 * signals upon timeout.
96 */
97 virtual void disarm() = 0;
98
99 /**
100 * Determine the resolution of the timer in ticks. This method is
101 * mainly used to determine the smallest number of ticks the timer
102 * can wait before triggering a signal.
103 *
104 * @return Minimum number of ticks the timer can resolve
105 */
106 Tick resolution() {
107 if (_resolution == 0)
108 _resolution = calcResolution();
109 return _resolution;
110 }
111
112 /**
113 * Convert cycles executed on the host into Ticks executed in the
114 * simulator. Scales the results using the hostFactor to take CPU
115 * performance differences into account.
116 *
117 * @return Host cycles executed in VM converted to simulation ticks
118 */
119 Tick ticksFromHostCycles(uint64_t cycles) {
120 return cycles * hostFactor * hostFreq;
121 }
122
123 /**
124 * Convert nanoseconds executed on the host into Ticks executed in
125 * the simulator. Scales the results using the hostFactor to take
126 * CPU performance differences into account.
127 *
128 * @return Nanoseconds executed in VM converted to simulation ticks
129 */
130 Tick ticksFromHostNs(uint64_t ns) {
131 return ns * hostFactor * SimClock::Float::ns;
132 }
133
134 protected:
135 /**
136 * Calculate the timer resolution, used by resolution() which
137 * caches the result.
138 *
139 * @return Minimum number of ticks the timer can resolve
140 */
141 virtual Tick calcResolution() = 0;
142
143 /**
144 * Convert a time in simulator ticks to host nanoseconds.
145 *
146 * @return Simulation ticks converted into nanoseconds on the host
147 */
148 uint64_t hostNs(Tick ticks) {
149 return ticks / (SimClock::Float::ns * hostFactor);
150 }
151
152 /**
153 * Convert a time in simulator ticks to host cycles
154 *
155 *
156 * @return Simulation ticks converted into CPU cycles on the host
157 */
158 uint64_t hostCycles(Tick ticks) {
159 return ticks / (hostFreq * hostFactor);
160 }
161
162 /** Signal to deliver when the timer times out */
163 int signo;
164
165 private:
166 /** Cached resolution */
167 mutable Tick _resolution;
168
169 /** Performance scaling factor */
170 float hostFactor;
171 /** Host frequency */
172 Tick hostFreq;
173 };
174
175 /**
176 * Timer based on standard POSIX timers. The POSIX timer API supports
177 * several different clock with different characteristics.
178 *
179 * @note It might be tempting to use
180 * CLOCK_(THREAD|PROCESS)_CPUTIME_ID, however, this clock usually has
181 * much lower resolution than the real-time clocks.
182 */
183 class PosixKvmTimer : public BaseKvmTimer
184 {
185 public:
186 /**
187 * @param signo Signal to deliver
188 * @param clockID ID of the clock to use
189 * @param hostFactor Performance scaling factor
190 * @param hostFreq Clock frequency of the host
191 */
192 PosixKvmTimer(int signo, clockid_t clockID,
193 float hostFactor, Tick hostFreq);
194 ~PosixKvmTimer();
195
196 void arm(Tick ticks);
197 void disarm();
198
199 protected:
200 Tick calcResolution();
201
202 private:
203 clockid_t clockID;
204 timer_t timer;
205 };
206
207 /**
208 * PerfEvent based timer using the host's CPU cycle counter.
209 *
210 * @warning There is a known problem in some versions of the PerfEvent
211 * API that prevents the counter overflow period from being updated
212 * reliably, which might break this timer. See PerfKvmCounter::period()
213 * for details.
214 */
215 class PerfKvmTimer : public BaseKvmTimer
216 {
217 public:
218 /**
219 * Create a timer that uses an existing hardware cycle counter.
220 *
221 * @note The performance counter must be configured for overflow
222 * sampling, which in practice means that it must have a non-zero
223 * sample period. The initial sample period is ignored since
224 * period will be updated when arm() is called.
225 *
226 * @param ctr Attached performance counter configured for overflow
227 * reporting.
228 * @param signo Signal to deliver
229 * @param hostFactor Performance scaling factor
230 * @param hostFreq Clock frequency of the host
231 */
232 PerfKvmTimer(PerfKvmCounter &ctr,
233 int signo,
234 float hostFactor, Tick hostFreq);
235 ~PerfKvmTimer();
236
237 void arm(Tick ticks);
238 void disarm();
239
240 protected:
241 Tick calcResolution();
242
243 private:
244 PerfKvmCounter &hwOverflow;
245 };
246
247 #endif