Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
[qemu/ar7.git] / hw / core / ptimer.c
blob59ccb0055080f488c1df870e6cdaf5c8f845e2e9
1 /*
2 * General purpose implementation of a simple periodic countdown timer.
4 * Copyright (c) 2007 CodeSourcery.
6 * This code is licensed under the GNU LGPL.
7 */
8 #include "qemu/osdep.h"
9 #include "hw/hw.h"
10 #include "qemu/timer.h"
11 #include "hw/ptimer.h"
12 #include "qemu/host-utils.h"
13 #include "sysemu/replay.h"
14 #include "sysemu/qtest.h"
15 #include "block/aio.h"
17 #define DELTA_ADJUST 1
18 #define DELTA_NO_ADJUST -1
20 struct ptimer_state
22 uint8_t enabled; /* 0 = disabled, 1 = periodic, 2 = oneshot. */
23 uint64_t limit;
24 uint64_t delta;
25 uint32_t period_frac;
26 int64_t period;
27 int64_t last_event;
28 int64_t next_event;
29 uint8_t policy_mask;
30 QEMUBH *bh;
31 QEMUTimer *timer;
34 /* Use a bottom-half routine to avoid reentrancy issues. */
35 static void ptimer_trigger(ptimer_state *s)
37 if (s->bh) {
38 replay_bh_schedule_event(s->bh);
42 static void ptimer_reload(ptimer_state *s, int delta_adjust)
44 uint32_t period_frac = s->period_frac;
45 uint64_t period = s->period;
46 uint64_t delta = s->delta;
48 if (delta == 0 && !(s->policy_mask & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER)) {
49 ptimer_trigger(s);
52 if (delta == 0 && !(s->policy_mask & PTIMER_POLICY_NO_IMMEDIATE_RELOAD)) {
53 delta = s->delta = s->limit;
56 if (s->period == 0) {
57 if (!qtest_enabled()) {
58 fprintf(stderr, "Timer with period zero, disabling\n");
60 timer_del(s->timer);
61 s->enabled = 0;
62 return;
65 if (s->policy_mask & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD) {
66 if (delta_adjust != DELTA_NO_ADJUST) {
67 delta += delta_adjust;
71 if (delta == 0 && (s->policy_mask & PTIMER_POLICY_CONTINUOUS_TRIGGER)) {
72 if (s->enabled == 1 && s->limit == 0) {
73 delta = 1;
77 if (delta == 0 && (s->policy_mask & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER)) {
78 if (delta_adjust != DELTA_NO_ADJUST) {
79 delta = 1;
83 if (delta == 0 && (s->policy_mask & PTIMER_POLICY_NO_IMMEDIATE_RELOAD)) {
84 if (s->enabled == 1 && s->limit != 0) {
85 delta = 1;
89 if (delta == 0) {
90 if (!qtest_enabled()) {
91 fprintf(stderr, "Timer with delta zero, disabling\n");
93 timer_del(s->timer);
94 s->enabled = 0;
95 return;
99 * Artificially limit timeout rate to something
100 * achievable under QEMU. Otherwise, QEMU spends all
101 * its time generating timer interrupts, and there
102 * is no forward progress.
103 * About ten microseconds is the fastest that really works
104 * on the current generation of host machines.
107 if (s->enabled == 1 && (delta * period < 10000) && !use_icount) {
108 period = 10000 / delta;
109 period_frac = 0;
112 s->last_event = s->next_event;
113 s->next_event = s->last_event + delta * period;
114 if (period_frac) {
115 s->next_event += ((int64_t)period_frac * delta) >> 32;
117 timer_mod(s->timer, s->next_event);
120 static void ptimer_tick(void *opaque)
122 ptimer_state *s = (ptimer_state *)opaque;
123 bool trigger = true;
125 if (s->enabled == 2) {
126 s->delta = 0;
127 s->enabled = 0;
128 } else {
129 int delta_adjust = DELTA_ADJUST;
131 if (s->delta == 0 || s->limit == 0) {
132 /* If a "continuous trigger" policy is not used and limit == 0,
133 we should error out. delta == 0 means that this tick is
134 caused by a "no immediate reload" policy, so it shouldn't
135 be adjusted. */
136 delta_adjust = DELTA_NO_ADJUST;
139 if (!(s->policy_mask & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER)) {
140 /* Avoid re-trigger on deferred reload if "no immediate trigger"
141 policy isn't used. */
142 trigger = (delta_adjust == DELTA_ADJUST);
145 s->delta = s->limit;
147 ptimer_reload(s, delta_adjust);
150 if (trigger) {
151 ptimer_trigger(s);
155 uint64_t ptimer_get_count(ptimer_state *s)
157 uint64_t counter;
159 if (s->enabled && s->delta != 0) {
160 int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
161 int64_t next = s->next_event;
162 int64_t last = s->last_event;
163 bool expired = (now - next >= 0);
164 bool oneshot = (s->enabled == 2);
166 /* Figure out the current counter value. */
167 if (expired) {
168 /* Prevent timer underflowing if it should already have
169 triggered. */
170 counter = 0;
171 } else {
172 uint64_t rem;
173 uint64_t div;
174 int clz1, clz2;
175 int shift;
176 uint32_t period_frac = s->period_frac;
177 uint64_t period = s->period;
179 if (!oneshot && (s->delta * period < 10000) && !use_icount) {
180 period = 10000 / s->delta;
181 period_frac = 0;
184 /* We need to divide time by period, where time is stored in
185 rem (64-bit integer) and period is stored in period/period_frac
186 (64.32 fixed point).
188 Doing full precision division is hard, so scale values and
189 do a 64-bit division. The result should be rounded down,
190 so that the rounding error never causes the timer to go
191 backwards.
194 rem = next - now;
195 div = period;
197 clz1 = clz64(rem);
198 clz2 = clz64(div);
199 shift = clz1 < clz2 ? clz1 : clz2;
201 rem <<= shift;
202 div <<= shift;
203 if (shift >= 32) {
204 div |= ((uint64_t)period_frac << (shift - 32));
205 } else {
206 if (shift != 0)
207 div |= (period_frac >> (32 - shift));
208 /* Look at remaining bits of period_frac and round div up if
209 necessary. */
210 if ((uint32_t)(period_frac << shift))
211 div += 1;
213 counter = rem / div;
215 if (s->policy_mask & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD) {
216 /* Before wrapping around, timer should stay with counter = 0
217 for a one period. */
218 if (!oneshot && s->delta == s->limit) {
219 if (now == last) {
220 /* Counter == delta here, check whether it was
221 adjusted and if it was, then right now it is
222 that "one period". */
223 if (counter == s->limit + DELTA_ADJUST) {
224 return 0;
226 } else if (counter == s->limit) {
227 /* Since the counter is rounded down and now != last,
228 the counter == limit means that delta was adjusted
229 by +1 and right now it is that adjusted period. */
230 return 0;
236 if (s->policy_mask & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN) {
237 /* If now == last then delta == limit, i.e. the counter already
238 represents the correct value. It would be rounded down a 1ns
239 later. */
240 if (now != last) {
241 counter += 1;
244 } else {
245 counter = s->delta;
247 return counter;
250 void ptimer_set_count(ptimer_state *s, uint64_t count)
252 s->delta = count;
253 if (s->enabled) {
254 s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
255 ptimer_reload(s, 0);
259 void ptimer_run(ptimer_state *s, int oneshot)
261 bool was_disabled = !s->enabled;
263 if (was_disabled && s->period == 0) {
264 if (!qtest_enabled()) {
265 fprintf(stderr, "Timer with period zero, disabling\n");
267 return;
269 s->enabled = oneshot ? 2 : 1;
270 if (was_disabled) {
271 s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
272 ptimer_reload(s, 0);
276 /* Pause a timer. Note that this may cause it to "lose" time, even if it
277 is immediately restarted. */
278 void ptimer_stop(ptimer_state *s)
280 if (!s->enabled)
281 return;
283 s->delta = ptimer_get_count(s);
284 timer_del(s->timer);
285 s->enabled = 0;
288 /* Set counter increment interval in nanoseconds. */
289 void ptimer_set_period(ptimer_state *s, int64_t period)
291 s->delta = ptimer_get_count(s);
292 s->period = period;
293 s->period_frac = 0;
294 if (s->enabled) {
295 s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
296 ptimer_reload(s, 0);
300 /* Set counter frequency in Hz. */
301 void ptimer_set_freq(ptimer_state *s, uint32_t freq)
303 s->delta = ptimer_get_count(s);
304 s->period = 1000000000ll / freq;
305 s->period_frac = (1000000000ll << 32) / freq;
306 if (s->enabled) {
307 s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
308 ptimer_reload(s, 0);
312 /* Set the initial countdown value. If reload is nonzero then also set
313 count = limit. */
314 void ptimer_set_limit(ptimer_state *s, uint64_t limit, int reload)
316 s->limit = limit;
317 if (reload)
318 s->delta = limit;
319 if (s->enabled && reload) {
320 s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
321 ptimer_reload(s, 0);
325 uint64_t ptimer_get_limit(ptimer_state *s)
327 return s->limit;
330 const VMStateDescription vmstate_ptimer = {
331 .name = "ptimer",
332 .version_id = 1,
333 .minimum_version_id = 1,
334 .fields = (VMStateField[]) {
335 VMSTATE_UINT8(enabled, ptimer_state),
336 VMSTATE_UINT64(limit, ptimer_state),
337 VMSTATE_UINT64(delta, ptimer_state),
338 VMSTATE_UINT32(period_frac, ptimer_state),
339 VMSTATE_INT64(period, ptimer_state),
340 VMSTATE_INT64(last_event, ptimer_state),
341 VMSTATE_INT64(next_event, ptimer_state),
342 VMSTATE_TIMER_PTR(timer, ptimer_state),
343 VMSTATE_END_OF_LIST()
347 ptimer_state *ptimer_init(QEMUBH *bh, uint8_t policy_mask)
349 ptimer_state *s;
351 s = (ptimer_state *)g_malloc0(sizeof(ptimer_state));
352 s->bh = bh;
353 s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ptimer_tick, s);
354 s->policy_mask = policy_mask;
355 return s;
358 void ptimer_free(ptimer_state *s)
360 qemu_bh_delete(s->bh);
361 timer_free(s->timer);
362 g_free(s);