1da668aa1SThomas Huth /*
2da668aa1SThomas Huth * QTest testcase for the ptimer
3da668aa1SThomas Huth *
4da668aa1SThomas Huth * Copyright (c) 2016 Dmitry Osipenko <digetx@gmail.com>
5da668aa1SThomas Huth *
6da668aa1SThomas Huth * This work is licensed under the terms of the GNU GPL, version 2 or later.
7da668aa1SThomas Huth * See the COPYING file in the top-level directory.
8da668aa1SThomas Huth *
9da668aa1SThomas Huth */
10da668aa1SThomas Huth
11da668aa1SThomas Huth #include "qemu/osdep.h"
12da668aa1SThomas Huth #include <glib/gprintf.h>
13da668aa1SThomas Huth
14da668aa1SThomas Huth #include "qemu/main-loop.h"
15da668aa1SThomas Huth #include "hw/ptimer.h"
16da668aa1SThomas Huth
17da668aa1SThomas Huth #include "ptimer-test.h"
18da668aa1SThomas Huth
19da668aa1SThomas Huth static bool triggered;
20da668aa1SThomas Huth
ptimer_trigger(void * opaque)21da668aa1SThomas Huth static void ptimer_trigger(void *opaque)
22da668aa1SThomas Huth {
23da668aa1SThomas Huth triggered = true;
24da668aa1SThomas Huth }
25da668aa1SThomas Huth
ptimer_test_expire_qemu_timers(int64_t expire_time,QEMUClockType type)26da668aa1SThomas Huth static void ptimer_test_expire_qemu_timers(int64_t expire_time,
27da668aa1SThomas Huth QEMUClockType type)
28da668aa1SThomas Huth {
29da668aa1SThomas Huth QEMUTimerList *timer_list = main_loop_tlg.tl[type];
30da668aa1SThomas Huth QEMUTimer *t = timer_list->active_timers.next;
31da668aa1SThomas Huth
32da668aa1SThomas Huth while (t != NULL) {
33da668aa1SThomas Huth if (t->expire_time == expire_time) {
34da668aa1SThomas Huth timer_del(t);
35da668aa1SThomas Huth
36da668aa1SThomas Huth if (t->cb != NULL) {
37da668aa1SThomas Huth t->cb(t->opaque);
38da668aa1SThomas Huth }
39da668aa1SThomas Huth }
40da668aa1SThomas Huth
41da668aa1SThomas Huth t = t->next;
42da668aa1SThomas Huth }
43da668aa1SThomas Huth }
44da668aa1SThomas Huth
ptimer_test_set_qemu_time_ns(int64_t ns)45da668aa1SThomas Huth static void ptimer_test_set_qemu_time_ns(int64_t ns)
46da668aa1SThomas Huth {
47da668aa1SThomas Huth ptimer_test_time_ns = ns;
48da668aa1SThomas Huth }
49da668aa1SThomas Huth
qemu_clock_step(uint64_t ns)50da668aa1SThomas Huth static void qemu_clock_step(uint64_t ns)
51da668aa1SThomas Huth {
52da668aa1SThomas Huth int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
53da668aa1SThomas Huth QEMU_TIMER_ATTR_ALL);
54da668aa1SThomas Huth int64_t advanced_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ns;
55da668aa1SThomas Huth
56da668aa1SThomas Huth while (deadline != -1 && deadline <= advanced_time) {
57da668aa1SThomas Huth ptimer_test_set_qemu_time_ns(deadline);
58da668aa1SThomas Huth ptimer_test_expire_qemu_timers(deadline, QEMU_CLOCK_VIRTUAL);
59da668aa1SThomas Huth deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
60da668aa1SThomas Huth QEMU_TIMER_ATTR_ALL);
61da668aa1SThomas Huth }
62da668aa1SThomas Huth
63da668aa1SThomas Huth ptimer_test_set_qemu_time_ns(advanced_time);
64da668aa1SThomas Huth }
65da668aa1SThomas Huth
check_set_count(gconstpointer arg)66da668aa1SThomas Huth static void check_set_count(gconstpointer arg)
67da668aa1SThomas Huth {
68da668aa1SThomas Huth const uint8_t *policy = arg;
69da668aa1SThomas Huth ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
70da668aa1SThomas Huth
71da668aa1SThomas Huth triggered = false;
72da668aa1SThomas Huth
73da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
74da668aa1SThomas Huth ptimer_set_count(ptimer, 1000);
75da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
76da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, 1000);
77da668aa1SThomas Huth g_assert_false(triggered);
78da668aa1SThomas Huth ptimer_free(ptimer);
79da668aa1SThomas Huth }
80da668aa1SThomas Huth
check_set_limit(gconstpointer arg)81da668aa1SThomas Huth static void check_set_limit(gconstpointer arg)
82da668aa1SThomas Huth {
83da668aa1SThomas Huth const uint8_t *policy = arg;
84da668aa1SThomas Huth ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
85da668aa1SThomas Huth
86da668aa1SThomas Huth triggered = false;
87da668aa1SThomas Huth
88da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
89da668aa1SThomas Huth ptimer_set_limit(ptimer, 1000, 0);
90da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
91da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
92da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_limit(ptimer), ==, 1000);
93da668aa1SThomas Huth g_assert_false(triggered);
94da668aa1SThomas Huth
95da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
96da668aa1SThomas Huth ptimer_set_limit(ptimer, 2000, 1);
97da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
98da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, 2000);
99da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_limit(ptimer), ==, 2000);
100da668aa1SThomas Huth g_assert_false(triggered);
101da668aa1SThomas Huth ptimer_free(ptimer);
102da668aa1SThomas Huth }
103da668aa1SThomas Huth
check_oneshot(gconstpointer arg)104da668aa1SThomas Huth static void check_oneshot(gconstpointer arg)
105da668aa1SThomas Huth {
106da668aa1SThomas Huth const uint8_t *policy = arg;
107da668aa1SThomas Huth ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
108da668aa1SThomas Huth bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
109da668aa1SThomas Huth
110da668aa1SThomas Huth triggered = false;
111da668aa1SThomas Huth
112da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
113da668aa1SThomas Huth ptimer_set_period(ptimer, 2000000);
114da668aa1SThomas Huth ptimer_set_count(ptimer, 10);
115da668aa1SThomas Huth ptimer_run(ptimer, 1);
116da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
117da668aa1SThomas Huth
118da668aa1SThomas Huth qemu_clock_step(2000000 * 2 + 1);
119da668aa1SThomas Huth
120da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
121da668aa1SThomas Huth g_assert_false(triggered);
122da668aa1SThomas Huth
123da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
124da668aa1SThomas Huth ptimer_stop(ptimer);
125da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
126da668aa1SThomas Huth
127da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
128da668aa1SThomas Huth g_assert_false(triggered);
129da668aa1SThomas Huth
130da668aa1SThomas Huth qemu_clock_step(2000000 * 11);
131da668aa1SThomas Huth
132da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
133da668aa1SThomas Huth g_assert_false(triggered);
134da668aa1SThomas Huth
135da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
136da668aa1SThomas Huth ptimer_run(ptimer, 1);
137da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
138da668aa1SThomas Huth
139da668aa1SThomas Huth qemu_clock_step(2000000 * 7 + 1);
140da668aa1SThomas Huth
141da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
142da668aa1SThomas Huth
143da668aa1SThomas Huth if (no_round_down) {
144da668aa1SThomas Huth g_assert_false(triggered);
145da668aa1SThomas Huth } else {
146da668aa1SThomas Huth g_assert_true(triggered);
147da668aa1SThomas Huth
148da668aa1SThomas Huth triggered = false;
149da668aa1SThomas Huth }
150da668aa1SThomas Huth
151da668aa1SThomas Huth qemu_clock_step(2000000);
152da668aa1SThomas Huth
153da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
154da668aa1SThomas Huth
155da668aa1SThomas Huth if (no_round_down) {
156da668aa1SThomas Huth g_assert_true(triggered);
157da668aa1SThomas Huth
158da668aa1SThomas Huth triggered = false;
159da668aa1SThomas Huth } else {
160da668aa1SThomas Huth g_assert_false(triggered);
161da668aa1SThomas Huth }
162da668aa1SThomas Huth
163da668aa1SThomas Huth qemu_clock_step(4000000);
164da668aa1SThomas Huth
165da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
166da668aa1SThomas Huth g_assert_false(triggered);
167da668aa1SThomas Huth
168da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
169da668aa1SThomas Huth ptimer_set_count(ptimer, 10);
170da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
171da668aa1SThomas Huth
172da668aa1SThomas Huth qemu_clock_step(20000000 + 1);
173da668aa1SThomas Huth
174da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, 10);
175da668aa1SThomas Huth g_assert_false(triggered);
176da668aa1SThomas Huth
177da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
178da668aa1SThomas Huth ptimer_set_limit(ptimer, 9, 1);
179da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
180da668aa1SThomas Huth
181da668aa1SThomas Huth qemu_clock_step(20000000 + 1);
182da668aa1SThomas Huth
183da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, 9);
184da668aa1SThomas Huth g_assert_false(triggered);
185da668aa1SThomas Huth
186da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
187da668aa1SThomas Huth ptimer_run(ptimer, 1);
188da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
189da668aa1SThomas Huth
190da668aa1SThomas Huth qemu_clock_step(2000000 + 1);
191da668aa1SThomas Huth
192da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
193da668aa1SThomas Huth g_assert_false(triggered);
194da668aa1SThomas Huth
195da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
196da668aa1SThomas Huth ptimer_set_count(ptimer, 20);
197da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
198da668aa1SThomas Huth
199da668aa1SThomas Huth qemu_clock_step(2000000 * 19 + 1);
200da668aa1SThomas Huth
201da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
202da668aa1SThomas Huth g_assert_false(triggered);
203da668aa1SThomas Huth
204da668aa1SThomas Huth qemu_clock_step(2000000);
205da668aa1SThomas Huth
206da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
207da668aa1SThomas Huth g_assert_true(triggered);
208da668aa1SThomas Huth
209da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
210da668aa1SThomas Huth ptimer_stop(ptimer);
211da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
212da668aa1SThomas Huth
213da668aa1SThomas Huth triggered = false;
214da668aa1SThomas Huth
215da668aa1SThomas Huth qemu_clock_step(2000000 * 12 + 1);
216da668aa1SThomas Huth
217da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
218da668aa1SThomas Huth g_assert_false(triggered);
219da668aa1SThomas Huth ptimer_free(ptimer);
220da668aa1SThomas Huth }
221da668aa1SThomas Huth
check_periodic(gconstpointer arg)222da668aa1SThomas Huth static void check_periodic(gconstpointer arg)
223da668aa1SThomas Huth {
224da668aa1SThomas Huth const uint8_t *policy = arg;
225da668aa1SThomas Huth ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
226da668aa1SThomas Huth bool wrap_policy = (*policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD);
227da668aa1SThomas Huth bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
228da668aa1SThomas Huth bool no_immediate_reload = (*policy & PTIMER_POLICY_NO_IMMEDIATE_RELOAD);
229da668aa1SThomas Huth bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
230da668aa1SThomas Huth bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
231da668aa1SThomas Huth
232da668aa1SThomas Huth triggered = false;
233da668aa1SThomas Huth
234da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
235da668aa1SThomas Huth ptimer_set_period(ptimer, 2000000);
236da668aa1SThomas Huth ptimer_set_limit(ptimer, 10, 1);
237da668aa1SThomas Huth ptimer_run(ptimer, 0);
238da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
239da668aa1SThomas Huth
240da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, 10);
241da668aa1SThomas Huth g_assert_false(triggered);
242da668aa1SThomas Huth
243da668aa1SThomas Huth qemu_clock_step(1);
244da668aa1SThomas Huth
245da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 10 : 9);
246da668aa1SThomas Huth g_assert_false(triggered);
247da668aa1SThomas Huth
248da668aa1SThomas Huth qemu_clock_step(2000000 * 10 - 1);
249da668aa1SThomas Huth
250da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, wrap_policy ? 0 : 10);
251da668aa1SThomas Huth g_assert_true(triggered);
252da668aa1SThomas Huth
253da668aa1SThomas Huth qemu_clock_step(1);
254da668aa1SThomas Huth
255da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==,
256da668aa1SThomas Huth wrap_policy ? 0 : (no_round_down ? 10 : 9));
257da668aa1SThomas Huth g_assert_true(triggered);
258da668aa1SThomas Huth
259da668aa1SThomas Huth triggered = false;
260da668aa1SThomas Huth
261da668aa1SThomas Huth qemu_clock_step(2000000);
262da668aa1SThomas Huth
263da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==,
264da668aa1SThomas Huth (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
265da668aa1SThomas Huth g_assert_false(triggered);
266da668aa1SThomas Huth
267da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
268da668aa1SThomas Huth ptimer_set_count(ptimer, 20);
269da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
270da668aa1SThomas Huth
271da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, 20);
272da668aa1SThomas Huth g_assert_false(triggered);
273da668aa1SThomas Huth
274da668aa1SThomas Huth qemu_clock_step(1);
275da668aa1SThomas Huth
276da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 20 : 19);
277da668aa1SThomas Huth g_assert_false(triggered);
278da668aa1SThomas Huth
279da668aa1SThomas Huth qemu_clock_step(2000000 * 11 + 1);
280da668aa1SThomas Huth
281da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 9 : 8);
282da668aa1SThomas Huth g_assert_false(triggered);
283da668aa1SThomas Huth
284da668aa1SThomas Huth qemu_clock_step(2000000 * 10);
285da668aa1SThomas Huth
286da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==,
287da668aa1SThomas Huth (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
288da668aa1SThomas Huth g_assert_true(triggered);
289da668aa1SThomas Huth
290da668aa1SThomas Huth triggered = false;
291da668aa1SThomas Huth
292da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
293da668aa1SThomas Huth ptimer_set_count(ptimer, 3);
294da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
295da668aa1SThomas Huth
296da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, 3);
297da668aa1SThomas Huth g_assert_false(triggered);
298da668aa1SThomas Huth
299da668aa1SThomas Huth qemu_clock_step(1);
300da668aa1SThomas Huth
301da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 3 : 2);
302da668aa1SThomas Huth g_assert_false(triggered);
303da668aa1SThomas Huth
304da668aa1SThomas Huth qemu_clock_step(2000000 * 4);
305da668aa1SThomas Huth
306da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==,
307da668aa1SThomas Huth (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
308da668aa1SThomas Huth g_assert_true(triggered);
309da668aa1SThomas Huth
310da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
311da668aa1SThomas Huth ptimer_stop(ptimer);
312da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
313da668aa1SThomas Huth triggered = false;
314da668aa1SThomas Huth
315da668aa1SThomas Huth qemu_clock_step(2000000);
316da668aa1SThomas Huth
317da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==,
318da668aa1SThomas Huth (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
319da668aa1SThomas Huth g_assert_false(triggered);
320da668aa1SThomas Huth
321da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
322da668aa1SThomas Huth ptimer_set_count(ptimer, 3);
323da668aa1SThomas Huth ptimer_run(ptimer, 0);
324da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
325da668aa1SThomas Huth
326da668aa1SThomas Huth qemu_clock_step(2000000 * 3 + 1);
327da668aa1SThomas Huth
328da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==,
329da668aa1SThomas Huth wrap_policy ? 0 : (no_round_down ? 10 : 9));
330da668aa1SThomas Huth g_assert_true(triggered);
331da668aa1SThomas Huth
332da668aa1SThomas Huth triggered = false;
333da668aa1SThomas Huth
334da668aa1SThomas Huth qemu_clock_step(2000000);
335da668aa1SThomas Huth
336da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==,
337da668aa1SThomas Huth (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
338da668aa1SThomas Huth g_assert_false(triggered);
339da668aa1SThomas Huth
340da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
341da668aa1SThomas Huth ptimer_set_count(ptimer, 0);
342da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
343da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==,
344da668aa1SThomas Huth no_immediate_reload ? 0 : 10);
345da668aa1SThomas Huth
346da668aa1SThomas Huth if (no_immediate_trigger || trig_only_on_dec) {
347da668aa1SThomas Huth g_assert_false(triggered);
348da668aa1SThomas Huth } else {
349da668aa1SThomas Huth g_assert_true(triggered);
350da668aa1SThomas Huth }
351da668aa1SThomas Huth
352da668aa1SThomas Huth triggered = false;
353da668aa1SThomas Huth
354da668aa1SThomas Huth qemu_clock_step(1);
355da668aa1SThomas Huth
356da668aa1SThomas Huth if (no_immediate_reload) {
357da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
358da668aa1SThomas Huth g_assert_false(triggered);
359da668aa1SThomas Huth
360da668aa1SThomas Huth qemu_clock_step(2000000);
361da668aa1SThomas Huth
362da668aa1SThomas Huth if (no_immediate_trigger) {
363da668aa1SThomas Huth g_assert_true(triggered);
364da668aa1SThomas Huth } else {
365da668aa1SThomas Huth g_assert_false(triggered);
366da668aa1SThomas Huth }
367da668aa1SThomas Huth
368da668aa1SThomas Huth triggered = false;
369da668aa1SThomas Huth }
370da668aa1SThomas Huth
371da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 10 : 9);
372da668aa1SThomas Huth g_assert_false(triggered);
373da668aa1SThomas Huth
374da668aa1SThomas Huth qemu_clock_step(2000000 * 12);
375da668aa1SThomas Huth
376da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==,
377da668aa1SThomas Huth (no_round_down ? 8 : 7) + (wrap_policy ? 1 : 0));
378da668aa1SThomas Huth g_assert_true(triggered);
379da668aa1SThomas Huth
380da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
381da668aa1SThomas Huth ptimer_stop(ptimer);
382da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
383da668aa1SThomas Huth
384da668aa1SThomas Huth triggered = false;
385da668aa1SThomas Huth
386da668aa1SThomas Huth qemu_clock_step(2000000 * 10);
387da668aa1SThomas Huth
388da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==,
389da668aa1SThomas Huth (no_round_down ? 8 : 7) + (wrap_policy ? 1 : 0));
390da668aa1SThomas Huth g_assert_false(triggered);
391da668aa1SThomas Huth
392da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
393da668aa1SThomas Huth ptimer_run(ptimer, 0);
394da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
395da668aa1SThomas Huth
396da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
397da668aa1SThomas Huth ptimer_set_period(ptimer, 0);
398da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
399da668aa1SThomas Huth
400da668aa1SThomas Huth qemu_clock_step(2000000 + 1);
401da668aa1SThomas Huth
402da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==,
403da668aa1SThomas Huth (no_round_down ? 8 : 7) + (wrap_policy ? 1 : 0));
404da668aa1SThomas Huth g_assert_false(triggered);
405da668aa1SThomas Huth ptimer_free(ptimer);
406da668aa1SThomas Huth }
407da668aa1SThomas Huth
check_on_the_fly_mode_change(gconstpointer arg)408da668aa1SThomas Huth static void check_on_the_fly_mode_change(gconstpointer arg)
409da668aa1SThomas Huth {
410da668aa1SThomas Huth const uint8_t *policy = arg;
411da668aa1SThomas Huth ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
412da668aa1SThomas Huth bool wrap_policy = (*policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD);
413da668aa1SThomas Huth bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
414da668aa1SThomas Huth
415da668aa1SThomas Huth triggered = false;
416da668aa1SThomas Huth
417da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
418da668aa1SThomas Huth ptimer_set_period(ptimer, 2000000);
419da668aa1SThomas Huth ptimer_set_limit(ptimer, 10, 1);
420da668aa1SThomas Huth ptimer_run(ptimer, 1);
421da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
422da668aa1SThomas Huth
423da668aa1SThomas Huth qemu_clock_step(2000000 * 9 + 1);
424da668aa1SThomas Huth
425da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
426da668aa1SThomas Huth g_assert_false(triggered);
427da668aa1SThomas Huth
428da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
429da668aa1SThomas Huth ptimer_run(ptimer, 0);
430da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
431da668aa1SThomas Huth
432da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
433da668aa1SThomas Huth g_assert_false(triggered);
434da668aa1SThomas Huth
435da668aa1SThomas Huth qemu_clock_step(2000000);
436da668aa1SThomas Huth
437da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==,
438da668aa1SThomas Huth wrap_policy ? 0 : (no_round_down ? 10 : 9));
439da668aa1SThomas Huth g_assert_true(triggered);
440da668aa1SThomas Huth
441da668aa1SThomas Huth triggered = false;
442da668aa1SThomas Huth
443da668aa1SThomas Huth qemu_clock_step(2000000 * 9);
444da668aa1SThomas Huth
445da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
446da668aa1SThomas Huth ptimer_run(ptimer, 1);
447da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
448da668aa1SThomas Huth
449da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==,
450da668aa1SThomas Huth (no_round_down ? 1 : 0) + (wrap_policy ? 1 : 0));
451da668aa1SThomas Huth g_assert_false(triggered);
452da668aa1SThomas Huth
453da668aa1SThomas Huth qemu_clock_step(2000000 * 3);
454da668aa1SThomas Huth
455da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
456da668aa1SThomas Huth g_assert_true(triggered);
457da668aa1SThomas Huth ptimer_free(ptimer);
458da668aa1SThomas Huth }
459da668aa1SThomas Huth
check_on_the_fly_period_change(gconstpointer arg)460da668aa1SThomas Huth static void check_on_the_fly_period_change(gconstpointer arg)
461da668aa1SThomas Huth {
462da668aa1SThomas Huth const uint8_t *policy = arg;
463da668aa1SThomas Huth ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
464da668aa1SThomas Huth bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
465da668aa1SThomas Huth
466da668aa1SThomas Huth triggered = false;
467da668aa1SThomas Huth
468da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
469da668aa1SThomas Huth ptimer_set_period(ptimer, 2000000);
470da668aa1SThomas Huth ptimer_set_limit(ptimer, 8, 1);
471da668aa1SThomas Huth ptimer_run(ptimer, 1);
472da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
473da668aa1SThomas Huth
474da668aa1SThomas Huth qemu_clock_step(2000000 * 4 + 1);
475da668aa1SThomas Huth
476da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
477da668aa1SThomas Huth g_assert_false(triggered);
478da668aa1SThomas Huth
479da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
480da668aa1SThomas Huth ptimer_set_period(ptimer, 4000000);
481da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
482da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
483da668aa1SThomas Huth
484da668aa1SThomas Huth qemu_clock_step(4000000 * 2 + 1);
485da668aa1SThomas Huth
486da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 2 : 0);
487da668aa1SThomas Huth g_assert_false(triggered);
488da668aa1SThomas Huth
489da668aa1SThomas Huth qemu_clock_step(4000000 * 2);
490da668aa1SThomas Huth
491da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
492da668aa1SThomas Huth g_assert_true(triggered);
493da668aa1SThomas Huth ptimer_free(ptimer);
494da668aa1SThomas Huth }
495da668aa1SThomas Huth
check_on_the_fly_freq_change(gconstpointer arg)496da668aa1SThomas Huth static void check_on_the_fly_freq_change(gconstpointer arg)
497da668aa1SThomas Huth {
498da668aa1SThomas Huth const uint8_t *policy = arg;
499da668aa1SThomas Huth ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
500da668aa1SThomas Huth bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
501da668aa1SThomas Huth
502da668aa1SThomas Huth triggered = false;
503da668aa1SThomas Huth
504da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
505da668aa1SThomas Huth ptimer_set_freq(ptimer, 500);
506da668aa1SThomas Huth ptimer_set_limit(ptimer, 8, 1);
507da668aa1SThomas Huth ptimer_run(ptimer, 1);
508da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
509da668aa1SThomas Huth
510da668aa1SThomas Huth qemu_clock_step(2000000 * 4 + 1);
511da668aa1SThomas Huth
512da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
513da668aa1SThomas Huth g_assert_false(triggered);
514da668aa1SThomas Huth
515da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
516da668aa1SThomas Huth ptimer_set_freq(ptimer, 250);
517da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
518da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
519da668aa1SThomas Huth
520da668aa1SThomas Huth qemu_clock_step(2000000 * 4 + 1);
521da668aa1SThomas Huth
522da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 2 : 0);
523da668aa1SThomas Huth g_assert_false(triggered);
524da668aa1SThomas Huth
525da668aa1SThomas Huth qemu_clock_step(2000000 * 4);
526da668aa1SThomas Huth
527da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
528da668aa1SThomas Huth g_assert_true(triggered);
529da668aa1SThomas Huth ptimer_free(ptimer);
530da668aa1SThomas Huth }
531da668aa1SThomas Huth
check_run_with_period_0(gconstpointer arg)532da668aa1SThomas Huth static void check_run_with_period_0(gconstpointer arg)
533da668aa1SThomas Huth {
534da668aa1SThomas Huth const uint8_t *policy = arg;
535da668aa1SThomas Huth ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
536da668aa1SThomas Huth
537da668aa1SThomas Huth triggered = false;
538da668aa1SThomas Huth
539da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
540da668aa1SThomas Huth ptimer_set_count(ptimer, 99);
541da668aa1SThomas Huth ptimer_run(ptimer, 1);
542da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
543da668aa1SThomas Huth
544da668aa1SThomas Huth qemu_clock_step(10 * NANOSECONDS_PER_SECOND);
545da668aa1SThomas Huth
546da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, 99);
547da668aa1SThomas Huth g_assert_false(triggered);
548da668aa1SThomas Huth ptimer_free(ptimer);
549da668aa1SThomas Huth }
550da668aa1SThomas Huth
check_run_with_delta_0(gconstpointer arg)551da668aa1SThomas Huth static void check_run_with_delta_0(gconstpointer arg)
552da668aa1SThomas Huth {
553da668aa1SThomas Huth const uint8_t *policy = arg;
554da668aa1SThomas Huth ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
555da668aa1SThomas Huth bool wrap_policy = (*policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD);
556da668aa1SThomas Huth bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
557da668aa1SThomas Huth bool no_immediate_reload = (*policy & PTIMER_POLICY_NO_IMMEDIATE_RELOAD);
558da668aa1SThomas Huth bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
559da668aa1SThomas Huth bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
560da668aa1SThomas Huth
561da668aa1SThomas Huth triggered = false;
562da668aa1SThomas Huth
563da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
564da668aa1SThomas Huth ptimer_set_period(ptimer, 2000000);
565da668aa1SThomas Huth ptimer_set_limit(ptimer, 99, 0);
566da668aa1SThomas Huth ptimer_run(ptimer, 1);
567da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
568da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==,
569da668aa1SThomas Huth no_immediate_reload ? 0 : 99);
570da668aa1SThomas Huth
571da668aa1SThomas Huth if (no_immediate_trigger || trig_only_on_dec) {
572da668aa1SThomas Huth g_assert_false(triggered);
573da668aa1SThomas Huth } else {
574da668aa1SThomas Huth g_assert_true(triggered);
575da668aa1SThomas Huth }
576da668aa1SThomas Huth
577da668aa1SThomas Huth triggered = false;
578da668aa1SThomas Huth
579da668aa1SThomas Huth if (no_immediate_trigger || no_immediate_reload) {
580da668aa1SThomas Huth qemu_clock_step(2000000 + 1);
581da668aa1SThomas Huth
582da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==,
583da668aa1SThomas Huth no_immediate_reload ? 0 : (no_round_down ? 98 : 97));
584da668aa1SThomas Huth
585da668aa1SThomas Huth if (no_immediate_trigger && no_immediate_reload) {
586da668aa1SThomas Huth g_assert_true(triggered);
587da668aa1SThomas Huth
588da668aa1SThomas Huth triggered = false;
589da668aa1SThomas Huth } else {
590da668aa1SThomas Huth g_assert_false(triggered);
591da668aa1SThomas Huth }
592da668aa1SThomas Huth
593da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
594da668aa1SThomas Huth ptimer_set_count(ptimer, 99);
595da668aa1SThomas Huth ptimer_run(ptimer, 1);
596da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
597da668aa1SThomas Huth }
598da668aa1SThomas Huth
599da668aa1SThomas Huth qemu_clock_step(2000000 + 1);
600da668aa1SThomas Huth
601da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 98 : 97);
602da668aa1SThomas Huth g_assert_false(triggered);
603da668aa1SThomas Huth
604da668aa1SThomas Huth qemu_clock_step(2000000 * 97);
605da668aa1SThomas Huth
606da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
607da668aa1SThomas Huth g_assert_false(triggered);
608da668aa1SThomas Huth
609da668aa1SThomas Huth qemu_clock_step(2000000 * 2);
610da668aa1SThomas Huth
611da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
612da668aa1SThomas Huth g_assert_true(triggered);
613da668aa1SThomas Huth
614da668aa1SThomas Huth triggered = false;
615da668aa1SThomas Huth
616da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
617da668aa1SThomas Huth ptimer_set_count(ptimer, 0);
618da668aa1SThomas Huth ptimer_run(ptimer, 0);
619da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
620da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==,
621da668aa1SThomas Huth no_immediate_reload ? 0 : 99);
622da668aa1SThomas Huth
623da668aa1SThomas Huth if (no_immediate_trigger || trig_only_on_dec) {
624da668aa1SThomas Huth g_assert_false(triggered);
625da668aa1SThomas Huth } else {
626da668aa1SThomas Huth g_assert_true(triggered);
627da668aa1SThomas Huth }
628da668aa1SThomas Huth
629da668aa1SThomas Huth triggered = false;
630da668aa1SThomas Huth
631da668aa1SThomas Huth qemu_clock_step(1);
632da668aa1SThomas Huth
633da668aa1SThomas Huth if (no_immediate_reload) {
634da668aa1SThomas Huth qemu_clock_step(2000000);
635da668aa1SThomas Huth }
636da668aa1SThomas Huth
637da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 99 : 98);
638da668aa1SThomas Huth
639da668aa1SThomas Huth if (no_immediate_reload && no_immediate_trigger) {
640da668aa1SThomas Huth g_assert_true(triggered);
641da668aa1SThomas Huth } else {
642da668aa1SThomas Huth g_assert_false(triggered);
643da668aa1SThomas Huth }
644da668aa1SThomas Huth
645da668aa1SThomas Huth triggered = false;
646da668aa1SThomas Huth
647da668aa1SThomas Huth qemu_clock_step(2000000);
648da668aa1SThomas Huth
649da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 98 : 97);
650da668aa1SThomas Huth g_assert_false(triggered);
651da668aa1SThomas Huth
652da668aa1SThomas Huth qemu_clock_step(2000000 * 98);
653da668aa1SThomas Huth
654da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==,
655da668aa1SThomas Huth wrap_policy ? 0 : (no_round_down ? 99 : 98));
656da668aa1SThomas Huth g_assert_true(triggered);
657da668aa1SThomas Huth
658da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
659da668aa1SThomas Huth ptimer_stop(ptimer);
660da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
661da668aa1SThomas Huth ptimer_free(ptimer);
662da668aa1SThomas Huth }
663da668aa1SThomas Huth
check_periodic_with_load_0(gconstpointer arg)664da668aa1SThomas Huth static void check_periodic_with_load_0(gconstpointer arg)
665da668aa1SThomas Huth {
666da668aa1SThomas Huth const uint8_t *policy = arg;
667da668aa1SThomas Huth ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
668da668aa1SThomas Huth bool continuous_trigger = (*policy & PTIMER_POLICY_CONTINUOUS_TRIGGER);
669da668aa1SThomas Huth bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
670da668aa1SThomas Huth bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
671da668aa1SThomas Huth
672da668aa1SThomas Huth triggered = false;
673da668aa1SThomas Huth
674da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
675da668aa1SThomas Huth ptimer_set_period(ptimer, 2000000);
676da668aa1SThomas Huth ptimer_run(ptimer, 0);
677da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
678da668aa1SThomas Huth
679da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
680da668aa1SThomas Huth
681da668aa1SThomas Huth if (no_immediate_trigger || trig_only_on_dec) {
682da668aa1SThomas Huth g_assert_false(triggered);
683da668aa1SThomas Huth } else {
684da668aa1SThomas Huth g_assert_true(triggered);
685da668aa1SThomas Huth }
686da668aa1SThomas Huth
687da668aa1SThomas Huth triggered = false;
688da668aa1SThomas Huth
689da668aa1SThomas Huth qemu_clock_step(2000000 + 1);
690da668aa1SThomas Huth
691da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
692da668aa1SThomas Huth
693da668aa1SThomas Huth if (continuous_trigger || no_immediate_trigger) {
694da668aa1SThomas Huth g_assert_true(triggered);
695da668aa1SThomas Huth } else {
696da668aa1SThomas Huth g_assert_false(triggered);
697da668aa1SThomas Huth }
698da668aa1SThomas Huth
699da668aa1SThomas Huth triggered = false;
700da668aa1SThomas Huth
701da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
702da668aa1SThomas Huth ptimer_set_count(ptimer, 10);
703da668aa1SThomas Huth ptimer_run(ptimer, 0);
704da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
705da668aa1SThomas Huth
706da668aa1SThomas Huth qemu_clock_step(2000000 * 10 + 1);
707da668aa1SThomas Huth
708da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
709da668aa1SThomas Huth g_assert_true(triggered);
710da668aa1SThomas Huth
711da668aa1SThomas Huth triggered = false;
712da668aa1SThomas Huth
713da668aa1SThomas Huth qemu_clock_step(2000000 + 1);
714da668aa1SThomas Huth
715da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
716da668aa1SThomas Huth
717da668aa1SThomas Huth if (continuous_trigger) {
718da668aa1SThomas Huth g_assert_true(triggered);
719da668aa1SThomas Huth } else {
720da668aa1SThomas Huth g_assert_false(triggered);
721da668aa1SThomas Huth }
722da668aa1SThomas Huth
723da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
724da668aa1SThomas Huth ptimer_stop(ptimer);
725da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
726da668aa1SThomas Huth ptimer_free(ptimer);
727da668aa1SThomas Huth }
728da668aa1SThomas Huth
check_oneshot_with_load_0(gconstpointer arg)729da668aa1SThomas Huth static void check_oneshot_with_load_0(gconstpointer arg)
730da668aa1SThomas Huth {
731da668aa1SThomas Huth const uint8_t *policy = arg;
732da668aa1SThomas Huth ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
733da668aa1SThomas Huth bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
734da668aa1SThomas Huth bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
735da668aa1SThomas Huth
736da668aa1SThomas Huth triggered = false;
737da668aa1SThomas Huth
738da668aa1SThomas Huth ptimer_transaction_begin(ptimer);
739da668aa1SThomas Huth ptimer_set_period(ptimer, 2000000);
740da668aa1SThomas Huth ptimer_run(ptimer, 1);
741da668aa1SThomas Huth ptimer_transaction_commit(ptimer);
742da668aa1SThomas Huth
743da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
744da668aa1SThomas Huth
745da668aa1SThomas Huth if (no_immediate_trigger || trig_only_on_dec) {
746da668aa1SThomas Huth g_assert_false(triggered);
747da668aa1SThomas Huth } else {
748da668aa1SThomas Huth g_assert_true(triggered);
749da668aa1SThomas Huth }
750da668aa1SThomas Huth
751da668aa1SThomas Huth triggered = false;
752da668aa1SThomas Huth
753da668aa1SThomas Huth qemu_clock_step(2000000 + 1);
754da668aa1SThomas Huth
755da668aa1SThomas Huth g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
756da668aa1SThomas Huth
757da668aa1SThomas Huth if (no_immediate_trigger) {
758da668aa1SThomas Huth g_assert_true(triggered);
759da668aa1SThomas Huth } else {
760da668aa1SThomas Huth g_assert_false(triggered);
761da668aa1SThomas Huth }
762da668aa1SThomas Huth
763da668aa1SThomas Huth ptimer_free(ptimer);
764da668aa1SThomas Huth }
765da668aa1SThomas Huth
check_freq_more_than_1000M(gconstpointer arg)766*446e5e8bSJianzhou Yue static void check_freq_more_than_1000M(gconstpointer arg)
767*446e5e8bSJianzhou Yue {
768*446e5e8bSJianzhou Yue const uint8_t *policy = arg;
769*446e5e8bSJianzhou Yue ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
770*446e5e8bSJianzhou Yue bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
771*446e5e8bSJianzhou Yue
772*446e5e8bSJianzhou Yue triggered = false;
773*446e5e8bSJianzhou Yue
774*446e5e8bSJianzhou Yue ptimer_transaction_begin(ptimer);
775*446e5e8bSJianzhou Yue ptimer_set_freq(ptimer, 2000000000);
776*446e5e8bSJianzhou Yue ptimer_set_limit(ptimer, 8, 1);
777*446e5e8bSJianzhou Yue ptimer_run(ptimer, 1);
778*446e5e8bSJianzhou Yue ptimer_transaction_commit(ptimer);
779*446e5e8bSJianzhou Yue
780*446e5e8bSJianzhou Yue qemu_clock_step(3);
781*446e5e8bSJianzhou Yue
782*446e5e8bSJianzhou Yue g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 3 : 2);
783*446e5e8bSJianzhou Yue g_assert_false(triggered);
784*446e5e8bSJianzhou Yue
785*446e5e8bSJianzhou Yue qemu_clock_step(1);
786*446e5e8bSJianzhou Yue
787*446e5e8bSJianzhou Yue g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
788*446e5e8bSJianzhou Yue g_assert_true(triggered);
789*446e5e8bSJianzhou Yue
790*446e5e8bSJianzhou Yue ptimer_free(ptimer);
791*446e5e8bSJianzhou Yue }
792*446e5e8bSJianzhou Yue
add_ptimer_tests(uint8_t policy)793da668aa1SThomas Huth static void add_ptimer_tests(uint8_t policy)
794da668aa1SThomas Huth {
795da668aa1SThomas Huth char policy_name[256] = "";
796da668aa1SThomas Huth char *tmp;
797da668aa1SThomas Huth
7989598c1bbSPeter Maydell if (policy == PTIMER_POLICY_LEGACY) {
7999598c1bbSPeter Maydell g_sprintf(policy_name, "legacy");
800da668aa1SThomas Huth }
801da668aa1SThomas Huth
802da668aa1SThomas Huth if (policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD) {
803da668aa1SThomas Huth g_strlcat(policy_name, "wrap_after_one_period,", 256);
804da668aa1SThomas Huth }
805da668aa1SThomas Huth
806da668aa1SThomas Huth if (policy & PTIMER_POLICY_CONTINUOUS_TRIGGER) {
807da668aa1SThomas Huth g_strlcat(policy_name, "continuous_trigger,", 256);
808da668aa1SThomas Huth }
809da668aa1SThomas Huth
810da668aa1SThomas Huth if (policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER) {
811da668aa1SThomas Huth g_strlcat(policy_name, "no_immediate_trigger,", 256);
812da668aa1SThomas Huth }
813da668aa1SThomas Huth
814da668aa1SThomas Huth if (policy & PTIMER_POLICY_NO_IMMEDIATE_RELOAD) {
815da668aa1SThomas Huth g_strlcat(policy_name, "no_immediate_reload,", 256);
816da668aa1SThomas Huth }
817da668aa1SThomas Huth
818da668aa1SThomas Huth if (policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN) {
819da668aa1SThomas Huth g_strlcat(policy_name, "no_counter_rounddown,", 256);
820da668aa1SThomas Huth }
821da668aa1SThomas Huth
822da668aa1SThomas Huth if (policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT) {
823da668aa1SThomas Huth g_strlcat(policy_name, "trigger_only_on_decrement,", 256);
824da668aa1SThomas Huth }
825da668aa1SThomas Huth
826da668aa1SThomas Huth g_test_add_data_func_full(
827da668aa1SThomas Huth tmp = g_strdup_printf("/ptimer/set_count policy=%s", policy_name),
828c4f8ce24SPhilippe Mathieu-Daudé g_memdup2(&policy, 1), check_set_count, g_free);
829da668aa1SThomas Huth g_free(tmp);
830da668aa1SThomas Huth
831da668aa1SThomas Huth g_test_add_data_func_full(
832da668aa1SThomas Huth tmp = g_strdup_printf("/ptimer/set_limit policy=%s", policy_name),
833c4f8ce24SPhilippe Mathieu-Daudé g_memdup2(&policy, 1), check_set_limit, g_free);
834da668aa1SThomas Huth g_free(tmp);
835da668aa1SThomas Huth
836da668aa1SThomas Huth g_test_add_data_func_full(
837da668aa1SThomas Huth tmp = g_strdup_printf("/ptimer/oneshot policy=%s", policy_name),
838c4f8ce24SPhilippe Mathieu-Daudé g_memdup2(&policy, 1), check_oneshot, g_free);
839da668aa1SThomas Huth g_free(tmp);
840da668aa1SThomas Huth
841da668aa1SThomas Huth g_test_add_data_func_full(
842da668aa1SThomas Huth tmp = g_strdup_printf("/ptimer/periodic policy=%s", policy_name),
843c4f8ce24SPhilippe Mathieu-Daudé g_memdup2(&policy, 1), check_periodic, g_free);
844da668aa1SThomas Huth g_free(tmp);
845da668aa1SThomas Huth
846da668aa1SThomas Huth g_test_add_data_func_full(
847da668aa1SThomas Huth tmp = g_strdup_printf("/ptimer/on_the_fly_mode_change policy=%s",
848da668aa1SThomas Huth policy_name),
849c4f8ce24SPhilippe Mathieu-Daudé g_memdup2(&policy, 1), check_on_the_fly_mode_change, g_free);
850da668aa1SThomas Huth g_free(tmp);
851da668aa1SThomas Huth
852da668aa1SThomas Huth g_test_add_data_func_full(
853da668aa1SThomas Huth tmp = g_strdup_printf("/ptimer/on_the_fly_period_change policy=%s",
854da668aa1SThomas Huth policy_name),
855c4f8ce24SPhilippe Mathieu-Daudé g_memdup2(&policy, 1), check_on_the_fly_period_change, g_free);
856da668aa1SThomas Huth g_free(tmp);
857da668aa1SThomas Huth
858da668aa1SThomas Huth g_test_add_data_func_full(
859da668aa1SThomas Huth tmp = g_strdup_printf("/ptimer/on_the_fly_freq_change policy=%s",
860da668aa1SThomas Huth policy_name),
861c4f8ce24SPhilippe Mathieu-Daudé g_memdup2(&policy, 1), check_on_the_fly_freq_change, g_free);
862da668aa1SThomas Huth g_free(tmp);
863da668aa1SThomas Huth
864da668aa1SThomas Huth g_test_add_data_func_full(
865da668aa1SThomas Huth tmp = g_strdup_printf("/ptimer/run_with_period_0 policy=%s",
866da668aa1SThomas Huth policy_name),
867c4f8ce24SPhilippe Mathieu-Daudé g_memdup2(&policy, 1), check_run_with_period_0, g_free);
868da668aa1SThomas Huth g_free(tmp);
869da668aa1SThomas Huth
870da668aa1SThomas Huth g_test_add_data_func_full(
871da668aa1SThomas Huth tmp = g_strdup_printf("/ptimer/run_with_delta_0 policy=%s",
872da668aa1SThomas Huth policy_name),
873c4f8ce24SPhilippe Mathieu-Daudé g_memdup2(&policy, 1), check_run_with_delta_0, g_free);
874da668aa1SThomas Huth g_free(tmp);
875da668aa1SThomas Huth
876da668aa1SThomas Huth g_test_add_data_func_full(
877da668aa1SThomas Huth tmp = g_strdup_printf("/ptimer/periodic_with_load_0 policy=%s",
878da668aa1SThomas Huth policy_name),
879c4f8ce24SPhilippe Mathieu-Daudé g_memdup2(&policy, 1), check_periodic_with_load_0, g_free);
880da668aa1SThomas Huth g_free(tmp);
881da668aa1SThomas Huth
882da668aa1SThomas Huth g_test_add_data_func_full(
883da668aa1SThomas Huth tmp = g_strdup_printf("/ptimer/oneshot_with_load_0 policy=%s",
884da668aa1SThomas Huth policy_name),
885c4f8ce24SPhilippe Mathieu-Daudé g_memdup2(&policy, 1), check_oneshot_with_load_0, g_free);
886da668aa1SThomas Huth g_free(tmp);
887*446e5e8bSJianzhou Yue
888*446e5e8bSJianzhou Yue g_test_add_data_func_full(
889*446e5e8bSJianzhou Yue tmp = g_strdup_printf("/ptimer/freq_more_than_1000M policy=%s",
890*446e5e8bSJianzhou Yue policy_name),
891*446e5e8bSJianzhou Yue g_memdup2(&policy, 1), check_freq_more_than_1000M, g_free);
892*446e5e8bSJianzhou Yue g_free(tmp);
893da668aa1SThomas Huth }
894da668aa1SThomas Huth
add_all_ptimer_policies_comb_tests(void)895da668aa1SThomas Huth static void add_all_ptimer_policies_comb_tests(void)
896da668aa1SThomas Huth {
897da668aa1SThomas Huth int last_policy = PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT;
8989598c1bbSPeter Maydell int policy = PTIMER_POLICY_LEGACY;
899da668aa1SThomas Huth
900da668aa1SThomas Huth for (; policy < (last_policy << 1); policy++) {
901da668aa1SThomas Huth if ((policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT) &&
902da668aa1SThomas Huth (policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER)) {
903da668aa1SThomas Huth /* Incompatible policy flag settings -- don't try to test them */
904da668aa1SThomas Huth continue;
905da668aa1SThomas Huth }
906da668aa1SThomas Huth add_ptimer_tests(policy);
907da668aa1SThomas Huth }
908da668aa1SThomas Huth }
909da668aa1SThomas Huth
main(int argc,char ** argv)910da668aa1SThomas Huth int main(int argc, char **argv)
911da668aa1SThomas Huth {
912da668aa1SThomas Huth int i;
913da668aa1SThomas Huth
914da668aa1SThomas Huth g_test_init(&argc, &argv, NULL);
915da668aa1SThomas Huth
916da668aa1SThomas Huth for (i = 0; i < QEMU_CLOCK_MAX; i++) {
917da668aa1SThomas Huth main_loop_tlg.tl[i] = g_new0(QEMUTimerList, 1);
918da668aa1SThomas Huth }
919da668aa1SThomas Huth
920da668aa1SThomas Huth add_all_ptimer_policies_comb_tests();
921da668aa1SThomas Huth
922da668aa1SThomas Huth qtest_allowed = true;
923da668aa1SThomas Huth
924da668aa1SThomas Huth return g_test_run();
925da668aa1SThomas Huth }
926