15b262bb6SDmitry Osipenko /*
25b262bb6SDmitry Osipenko * QTest testcase for the ptimer
35b262bb6SDmitry Osipenko *
4673c7e89SDmitry Osipenko * Copyright (c) 2016 Dmitry Osipenko <digetx@gmail.com>
55b262bb6SDmitry Osipenko *
65b262bb6SDmitry Osipenko * This work is licensed under the terms of the GNU GPL, version 2 or later.
75b262bb6SDmitry Osipenko * See the COPYING file in the top-level directory.
85b262bb6SDmitry Osipenko *
95b262bb6SDmitry Osipenko */
105b262bb6SDmitry Osipenko
118f0a3716SMarkus Armbruster #include "qemu/osdep.h"
125b262bb6SDmitry Osipenko #include <glib/gprintf.h>
135b262bb6SDmitry Osipenko
145b262bb6SDmitry Osipenko #include "qemu/main-loop.h"
155b262bb6SDmitry Osipenko #include "hw/ptimer.h"
165b262bb6SDmitry Osipenko
175b262bb6SDmitry Osipenko #include "ptimer-test.h"
185b262bb6SDmitry Osipenko
195b262bb6SDmitry Osipenko static bool triggered;
205b262bb6SDmitry Osipenko
ptimer_trigger(void * opaque)215b262bb6SDmitry Osipenko static void ptimer_trigger(void *opaque)
225b262bb6SDmitry Osipenko {
235b262bb6SDmitry Osipenko triggered = true;
245b262bb6SDmitry Osipenko }
255b262bb6SDmitry Osipenko
ptimer_test_expire_qemu_timers(int64_t expire_time,QEMUClockType type)265b262bb6SDmitry Osipenko static void ptimer_test_expire_qemu_timers(int64_t expire_time,
275b262bb6SDmitry Osipenko QEMUClockType type)
285b262bb6SDmitry Osipenko {
295b262bb6SDmitry Osipenko QEMUTimerList *timer_list = main_loop_tlg.tl[type];
305b262bb6SDmitry Osipenko QEMUTimer *t = timer_list->active_timers.next;
315b262bb6SDmitry Osipenko
325b262bb6SDmitry Osipenko while (t != NULL) {
335b262bb6SDmitry Osipenko if (t->expire_time == expire_time) {
345b262bb6SDmitry Osipenko timer_del(t);
355b262bb6SDmitry Osipenko
365b262bb6SDmitry Osipenko if (t->cb != NULL) {
375b262bb6SDmitry Osipenko t->cb(t->opaque);
385b262bb6SDmitry Osipenko }
395b262bb6SDmitry Osipenko }
405b262bb6SDmitry Osipenko
415b262bb6SDmitry Osipenko t = t->next;
425b262bb6SDmitry Osipenko }
435b262bb6SDmitry Osipenko }
445b262bb6SDmitry Osipenko
ptimer_test_set_qemu_time_ns(int64_t ns)455b262bb6SDmitry Osipenko static void ptimer_test_set_qemu_time_ns(int64_t ns)
465b262bb6SDmitry Osipenko {
475b262bb6SDmitry Osipenko ptimer_test_time_ns = ns;
485b262bb6SDmitry Osipenko }
495b262bb6SDmitry Osipenko
qemu_clock_step(uint64_t ns)505b262bb6SDmitry Osipenko static void qemu_clock_step(uint64_t ns)
515b262bb6SDmitry Osipenko {
52dcb15780SPavel Dovgalyuk int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
53dcb15780SPavel Dovgalyuk QEMU_TIMER_ATTR_ALL);
545b262bb6SDmitry Osipenko int64_t advanced_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ns;
555b262bb6SDmitry Osipenko
565b262bb6SDmitry Osipenko while (deadline != -1 && deadline <= advanced_time) {
575b262bb6SDmitry Osipenko ptimer_test_set_qemu_time_ns(deadline);
585b262bb6SDmitry Osipenko ptimer_test_expire_qemu_timers(deadline, QEMU_CLOCK_VIRTUAL);
59dcb15780SPavel Dovgalyuk deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
60dcb15780SPavel Dovgalyuk QEMU_TIMER_ATTR_ALL);
615b262bb6SDmitry Osipenko }
625b262bb6SDmitry Osipenko
635b262bb6SDmitry Osipenko ptimer_test_set_qemu_time_ns(advanced_time);
645b262bb6SDmitry Osipenko }
655b262bb6SDmitry Osipenko
check_set_count(gconstpointer arg)665b262bb6SDmitry Osipenko static void check_set_count(gconstpointer arg)
675b262bb6SDmitry Osipenko {
685b262bb6SDmitry Osipenko const uint8_t *policy = arg;
6991b37aeaSPeter Maydell ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
705b262bb6SDmitry Osipenko
715b262bb6SDmitry Osipenko triggered = false;
725b262bb6SDmitry Osipenko
7391b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
745b262bb6SDmitry Osipenko ptimer_set_count(ptimer, 1000);
7591b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
765b262bb6SDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, 1000);
775b262bb6SDmitry Osipenko g_assert_false(triggered);
78072bdb07SMarc-André Lureau ptimer_free(ptimer);
795b262bb6SDmitry Osipenko }
805b262bb6SDmitry Osipenko
check_set_limit(gconstpointer arg)815b262bb6SDmitry Osipenko static void check_set_limit(gconstpointer arg)
825b262bb6SDmitry Osipenko {
835b262bb6SDmitry Osipenko const uint8_t *policy = arg;
8491b37aeaSPeter Maydell ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
855b262bb6SDmitry Osipenko
865b262bb6SDmitry Osipenko triggered = false;
875b262bb6SDmitry Osipenko
8891b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
895b262bb6SDmitry Osipenko ptimer_set_limit(ptimer, 1000, 0);
9091b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
915b262bb6SDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
925b262bb6SDmitry Osipenko g_assert_cmpuint(ptimer_get_limit(ptimer), ==, 1000);
935b262bb6SDmitry Osipenko g_assert_false(triggered);
945b262bb6SDmitry Osipenko
9591b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
965b262bb6SDmitry Osipenko ptimer_set_limit(ptimer, 2000, 1);
9791b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
985b262bb6SDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, 2000);
995b262bb6SDmitry Osipenko g_assert_cmpuint(ptimer_get_limit(ptimer), ==, 2000);
1005b262bb6SDmitry Osipenko g_assert_false(triggered);
101072bdb07SMarc-André Lureau ptimer_free(ptimer);
1025b262bb6SDmitry Osipenko }
1035b262bb6SDmitry Osipenko
check_oneshot(gconstpointer arg)1045b262bb6SDmitry Osipenko static void check_oneshot(gconstpointer arg)
1055b262bb6SDmitry Osipenko {
1065b262bb6SDmitry Osipenko const uint8_t *policy = arg;
10791b37aeaSPeter Maydell ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
108057516feSDmitry Osipenko bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
1095b262bb6SDmitry Osipenko
1105b262bb6SDmitry Osipenko triggered = false;
1115b262bb6SDmitry Osipenko
11291b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
1135b262bb6SDmitry Osipenko ptimer_set_period(ptimer, 2000000);
1145b262bb6SDmitry Osipenko ptimer_set_count(ptimer, 10);
1155b262bb6SDmitry Osipenko ptimer_run(ptimer, 1);
11691b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
1175b262bb6SDmitry Osipenko
11833d44cdfSDmitry Osipenko qemu_clock_step(2000000 * 2 + 1);
1195b262bb6SDmitry Osipenko
120057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
1215b262bb6SDmitry Osipenko g_assert_false(triggered);
1225b262bb6SDmitry Osipenko
12391b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
1245b262bb6SDmitry Osipenko ptimer_stop(ptimer);
12591b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
1265b262bb6SDmitry Osipenko
127057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
1285b262bb6SDmitry Osipenko g_assert_false(triggered);
1295b262bb6SDmitry Osipenko
1305b262bb6SDmitry Osipenko qemu_clock_step(2000000 * 11);
1315b262bb6SDmitry Osipenko
132057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
1335b262bb6SDmitry Osipenko g_assert_false(triggered);
1345b262bb6SDmitry Osipenko
13591b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
1365b262bb6SDmitry Osipenko ptimer_run(ptimer, 1);
13791b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
1385b262bb6SDmitry Osipenko
13933d44cdfSDmitry Osipenko qemu_clock_step(2000000 * 7 + 1);
1405b262bb6SDmitry Osipenko
141057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
142057516feSDmitry Osipenko
143057516feSDmitry Osipenko if (no_round_down) {
144057516feSDmitry Osipenko g_assert_false(triggered);
145057516feSDmitry Osipenko } else {
1465b262bb6SDmitry Osipenko g_assert_true(triggered);
1475b262bb6SDmitry Osipenko
1485b262bb6SDmitry Osipenko triggered = false;
149057516feSDmitry Osipenko }
1505b262bb6SDmitry Osipenko
1515b262bb6SDmitry Osipenko qemu_clock_step(2000000);
1525b262bb6SDmitry Osipenko
1535b262bb6SDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
154057516feSDmitry Osipenko
155057516feSDmitry Osipenko if (no_round_down) {
156057516feSDmitry Osipenko g_assert_true(triggered);
157057516feSDmitry Osipenko
158057516feSDmitry Osipenko triggered = false;
159057516feSDmitry Osipenko } else {
1605b262bb6SDmitry Osipenko g_assert_false(triggered);
161057516feSDmitry Osipenko }
1625b262bb6SDmitry Osipenko
1635b262bb6SDmitry Osipenko qemu_clock_step(4000000);
1645b262bb6SDmitry Osipenko
1655b262bb6SDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
1665b262bb6SDmitry Osipenko g_assert_false(triggered);
1675b262bb6SDmitry Osipenko
16891b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
1695b262bb6SDmitry Osipenko ptimer_set_count(ptimer, 10);
17091b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
1715b262bb6SDmitry Osipenko
17233d44cdfSDmitry Osipenko qemu_clock_step(20000000 + 1);
1735b262bb6SDmitry Osipenko
1745b262bb6SDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, 10);
1755b262bb6SDmitry Osipenko g_assert_false(triggered);
1765b262bb6SDmitry Osipenko
17791b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
1785b262bb6SDmitry Osipenko ptimer_set_limit(ptimer, 9, 1);
17991b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
1805b262bb6SDmitry Osipenko
18133d44cdfSDmitry Osipenko qemu_clock_step(20000000 + 1);
1825b262bb6SDmitry Osipenko
1835b262bb6SDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, 9);
1845b262bb6SDmitry Osipenko g_assert_false(triggered);
1855b262bb6SDmitry Osipenko
18691b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
1875b262bb6SDmitry Osipenko ptimer_run(ptimer, 1);
18891b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
1895b262bb6SDmitry Osipenko
19033d44cdfSDmitry Osipenko qemu_clock_step(2000000 + 1);
1915b262bb6SDmitry Osipenko
192057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
1935b262bb6SDmitry Osipenko g_assert_false(triggered);
1945b262bb6SDmitry Osipenko
19591b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
1965b262bb6SDmitry Osipenko ptimer_set_count(ptimer, 20);
19791b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
1985b262bb6SDmitry Osipenko
19933d44cdfSDmitry Osipenko qemu_clock_step(2000000 * 19 + 1);
2005b262bb6SDmitry Osipenko
201057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
2025b262bb6SDmitry Osipenko g_assert_false(triggered);
2035b262bb6SDmitry Osipenko
2045b262bb6SDmitry Osipenko qemu_clock_step(2000000);
2055b262bb6SDmitry Osipenko
2065b262bb6SDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
2075b262bb6SDmitry Osipenko g_assert_true(triggered);
2085b262bb6SDmitry Osipenko
20991b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
2105b262bb6SDmitry Osipenko ptimer_stop(ptimer);
21191b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
2125b262bb6SDmitry Osipenko
2135b262bb6SDmitry Osipenko triggered = false;
2145b262bb6SDmitry Osipenko
21533d44cdfSDmitry Osipenko qemu_clock_step(2000000 * 12 + 1);
2165b262bb6SDmitry Osipenko
2175b262bb6SDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
2185b262bb6SDmitry Osipenko g_assert_false(triggered);
219072bdb07SMarc-André Lureau ptimer_free(ptimer);
2205b262bb6SDmitry Osipenko }
2215b262bb6SDmitry Osipenko
check_periodic(gconstpointer arg)2225b262bb6SDmitry Osipenko static void check_periodic(gconstpointer arg)
2235b262bb6SDmitry Osipenko {
2245b262bb6SDmitry Osipenko const uint8_t *policy = arg;
22591b37aeaSPeter Maydell ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
226293130aaSDmitry Osipenko bool wrap_policy = (*policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD);
227516deb42SDmitry Osipenko bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
22856700e1aSDmitry Osipenko bool no_immediate_reload = (*policy & PTIMER_POLICY_NO_IMMEDIATE_RELOAD);
229057516feSDmitry Osipenko bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
230086ede32SPeter Maydell bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
2315b262bb6SDmitry Osipenko
2325b262bb6SDmitry Osipenko triggered = false;
2335b262bb6SDmitry Osipenko
23491b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
2355b262bb6SDmitry Osipenko ptimer_set_period(ptimer, 2000000);
2365b262bb6SDmitry Osipenko ptimer_set_limit(ptimer, 10, 1);
2375b262bb6SDmitry Osipenko ptimer_run(ptimer, 0);
23891b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
2395b262bb6SDmitry Osipenko
240293130aaSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, 10);
241293130aaSDmitry Osipenko g_assert_false(triggered);
242293130aaSDmitry Osipenko
24333d44cdfSDmitry Osipenko qemu_clock_step(1);
2445b262bb6SDmitry Osipenko
245057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 10 : 9);
246293130aaSDmitry Osipenko g_assert_false(triggered);
247293130aaSDmitry Osipenko
24833d44cdfSDmitry Osipenko qemu_clock_step(2000000 * 10 - 1);
249293130aaSDmitry Osipenko
250293130aaSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, wrap_policy ? 0 : 10);
251293130aaSDmitry Osipenko g_assert_true(triggered);
252293130aaSDmitry Osipenko
25333d44cdfSDmitry Osipenko qemu_clock_step(1);
254293130aaSDmitry Osipenko
255057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==,
256057516feSDmitry Osipenko wrap_policy ? 0 : (no_round_down ? 10 : 9));
2575b262bb6SDmitry Osipenko g_assert_true(triggered);
2585b262bb6SDmitry Osipenko
2595b262bb6SDmitry Osipenko triggered = false;
2605b262bb6SDmitry Osipenko
2615b262bb6SDmitry Osipenko qemu_clock_step(2000000);
2625b262bb6SDmitry Osipenko
263057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==,
264057516feSDmitry Osipenko (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
2655b262bb6SDmitry Osipenko g_assert_false(triggered);
2665b262bb6SDmitry Osipenko
26791b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
2685b262bb6SDmitry Osipenko ptimer_set_count(ptimer, 20);
26991b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
2705b262bb6SDmitry Osipenko
271293130aaSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, 20);
272293130aaSDmitry Osipenko g_assert_false(triggered);
273293130aaSDmitry Osipenko
27433d44cdfSDmitry Osipenko qemu_clock_step(1);
275293130aaSDmitry Osipenko
276057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 20 : 19);
277293130aaSDmitry Osipenko g_assert_false(triggered);
278293130aaSDmitry Osipenko
27933d44cdfSDmitry Osipenko qemu_clock_step(2000000 * 11 + 1);
2805b262bb6SDmitry Osipenko
281057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 9 : 8);
2825b262bb6SDmitry Osipenko g_assert_false(triggered);
2835b262bb6SDmitry Osipenko
2845b262bb6SDmitry Osipenko qemu_clock_step(2000000 * 10);
2855b262bb6SDmitry Osipenko
286057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==,
287057516feSDmitry Osipenko (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
288293130aaSDmitry Osipenko g_assert_true(triggered);
289293130aaSDmitry Osipenko
290293130aaSDmitry Osipenko triggered = false;
291293130aaSDmitry Osipenko
29291b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
293293130aaSDmitry Osipenko ptimer_set_count(ptimer, 3);
29491b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
295293130aaSDmitry Osipenko
296293130aaSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, 3);
297293130aaSDmitry Osipenko g_assert_false(triggered);
298293130aaSDmitry Osipenko
29933d44cdfSDmitry Osipenko qemu_clock_step(1);
300293130aaSDmitry Osipenko
301057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 3 : 2);
302293130aaSDmitry Osipenko g_assert_false(triggered);
303293130aaSDmitry Osipenko
304293130aaSDmitry Osipenko qemu_clock_step(2000000 * 4);
305293130aaSDmitry Osipenko
306057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==,
307057516feSDmitry Osipenko (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
3085b262bb6SDmitry Osipenko g_assert_true(triggered);
3095b262bb6SDmitry Osipenko
31091b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
3115b262bb6SDmitry Osipenko ptimer_stop(ptimer);
31291b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
3135b262bb6SDmitry Osipenko triggered = false;
3145b262bb6SDmitry Osipenko
3155b262bb6SDmitry Osipenko qemu_clock_step(2000000);
3165b262bb6SDmitry Osipenko
317057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==,
318057516feSDmitry Osipenko (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
3195b262bb6SDmitry Osipenko g_assert_false(triggered);
3205b262bb6SDmitry Osipenko
32191b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
3225b262bb6SDmitry Osipenko ptimer_set_count(ptimer, 3);
3235b262bb6SDmitry Osipenko ptimer_run(ptimer, 0);
32491b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
3255b262bb6SDmitry Osipenko
32633d44cdfSDmitry Osipenko qemu_clock_step(2000000 * 3 + 1);
3275b262bb6SDmitry Osipenko
328057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==,
329057516feSDmitry Osipenko wrap_policy ? 0 : (no_round_down ? 10 : 9));
3305b262bb6SDmitry Osipenko g_assert_true(triggered);
3315b262bb6SDmitry Osipenko
3325b262bb6SDmitry Osipenko triggered = false;
3335b262bb6SDmitry Osipenko
3345b262bb6SDmitry Osipenko qemu_clock_step(2000000);
3355b262bb6SDmitry Osipenko
336057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==,
337057516feSDmitry Osipenko (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
3385b262bb6SDmitry Osipenko g_assert_false(triggered);
3395b262bb6SDmitry Osipenko
34091b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
3415b262bb6SDmitry Osipenko ptimer_set_count(ptimer, 0);
34291b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
34356700e1aSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==,
34456700e1aSDmitry Osipenko no_immediate_reload ? 0 : 10);
345516deb42SDmitry Osipenko
346086ede32SPeter Maydell if (no_immediate_trigger || trig_only_on_dec) {
347516deb42SDmitry Osipenko g_assert_false(triggered);
348516deb42SDmitry Osipenko } else {
3495b262bb6SDmitry Osipenko g_assert_true(triggered);
350516deb42SDmitry Osipenko }
3515b262bb6SDmitry Osipenko
3525b262bb6SDmitry Osipenko triggered = false;
3535b262bb6SDmitry Osipenko
35433d44cdfSDmitry Osipenko qemu_clock_step(1);
3555b262bb6SDmitry Osipenko
35656700e1aSDmitry Osipenko if (no_immediate_reload) {
35756700e1aSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
35856700e1aSDmitry Osipenko g_assert_false(triggered);
35956700e1aSDmitry Osipenko
36056700e1aSDmitry Osipenko qemu_clock_step(2000000);
36156700e1aSDmitry Osipenko
36256700e1aSDmitry Osipenko if (no_immediate_trigger) {
36356700e1aSDmitry Osipenko g_assert_true(triggered);
36456700e1aSDmitry Osipenko } else {
36556700e1aSDmitry Osipenko g_assert_false(triggered);
36656700e1aSDmitry Osipenko }
36756700e1aSDmitry Osipenko
36856700e1aSDmitry Osipenko triggered = false;
36956700e1aSDmitry Osipenko }
37056700e1aSDmitry Osipenko
371057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 10 : 9);
372293130aaSDmitry Osipenko g_assert_false(triggered);
373293130aaSDmitry Osipenko
374293130aaSDmitry Osipenko qemu_clock_step(2000000 * 12);
375293130aaSDmitry Osipenko
376057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==,
377057516feSDmitry Osipenko (no_round_down ? 8 : 7) + (wrap_policy ? 1 : 0));
3785b262bb6SDmitry Osipenko g_assert_true(triggered);
3795b262bb6SDmitry Osipenko
38091b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
3815b262bb6SDmitry Osipenko ptimer_stop(ptimer);
38291b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
3835b262bb6SDmitry Osipenko
3845b262bb6SDmitry Osipenko triggered = false;
3855b262bb6SDmitry Osipenko
386293130aaSDmitry Osipenko qemu_clock_step(2000000 * 10);
3875b262bb6SDmitry Osipenko
388057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==,
389057516feSDmitry Osipenko (no_round_down ? 8 : 7) + (wrap_policy ? 1 : 0));
3905b262bb6SDmitry Osipenko g_assert_false(triggered);
3915b262bb6SDmitry Osipenko
39291b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
3935b262bb6SDmitry Osipenko ptimer_run(ptimer, 0);
39491b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
39591b37aeaSPeter Maydell
39691b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
3975b262bb6SDmitry Osipenko ptimer_set_period(ptimer, 0);
39891b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
3995b262bb6SDmitry Osipenko
40033d44cdfSDmitry Osipenko qemu_clock_step(2000000 + 1);
4015b262bb6SDmitry Osipenko
402057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==,
403057516feSDmitry Osipenko (no_round_down ? 8 : 7) + (wrap_policy ? 1 : 0));
4045b262bb6SDmitry Osipenko g_assert_false(triggered);
405072bdb07SMarc-André Lureau ptimer_free(ptimer);
4065b262bb6SDmitry Osipenko }
4075b262bb6SDmitry Osipenko
check_on_the_fly_mode_change(gconstpointer arg)4085b262bb6SDmitry Osipenko static void check_on_the_fly_mode_change(gconstpointer arg)
4095b262bb6SDmitry Osipenko {
4105b262bb6SDmitry Osipenko const uint8_t *policy = arg;
41191b37aeaSPeter Maydell ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
412293130aaSDmitry Osipenko bool wrap_policy = (*policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD);
413057516feSDmitry Osipenko bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
4145b262bb6SDmitry Osipenko
4155b262bb6SDmitry Osipenko triggered = false;
4165b262bb6SDmitry Osipenko
41791b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
4185b262bb6SDmitry Osipenko ptimer_set_period(ptimer, 2000000);
4195b262bb6SDmitry Osipenko ptimer_set_limit(ptimer, 10, 1);
4205b262bb6SDmitry Osipenko ptimer_run(ptimer, 1);
42191b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
4225b262bb6SDmitry Osipenko
42333d44cdfSDmitry Osipenko qemu_clock_step(2000000 * 9 + 1);
4245b262bb6SDmitry Osipenko
425057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
426293130aaSDmitry Osipenko g_assert_false(triggered);
427293130aaSDmitry Osipenko
42891b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
4295b262bb6SDmitry Osipenko ptimer_run(ptimer, 0);
43091b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
4315b262bb6SDmitry Osipenko
432057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
4335b262bb6SDmitry Osipenko g_assert_false(triggered);
4345b262bb6SDmitry Osipenko
4355b262bb6SDmitry Osipenko qemu_clock_step(2000000);
4365b262bb6SDmitry Osipenko
437057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==,
438057516feSDmitry Osipenko wrap_policy ? 0 : (no_round_down ? 10 : 9));
4395b262bb6SDmitry Osipenko g_assert_true(triggered);
4405b262bb6SDmitry Osipenko
4415b262bb6SDmitry Osipenko triggered = false;
4425b262bb6SDmitry Osipenko
4435b262bb6SDmitry Osipenko qemu_clock_step(2000000 * 9);
4445b262bb6SDmitry Osipenko
44591b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
4465b262bb6SDmitry Osipenko ptimer_run(ptimer, 1);
44791b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
4485b262bb6SDmitry Osipenko
449057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==,
450057516feSDmitry Osipenko (no_round_down ? 1 : 0) + (wrap_policy ? 1 : 0));
4515b262bb6SDmitry Osipenko g_assert_false(triggered);
4525b262bb6SDmitry Osipenko
4535b262bb6SDmitry Osipenko qemu_clock_step(2000000 * 3);
4545b262bb6SDmitry Osipenko
4555b262bb6SDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
4565b262bb6SDmitry Osipenko g_assert_true(triggered);
457072bdb07SMarc-André Lureau ptimer_free(ptimer);
4585b262bb6SDmitry Osipenko }
4595b262bb6SDmitry Osipenko
check_on_the_fly_period_change(gconstpointer arg)4605b262bb6SDmitry Osipenko static void check_on_the_fly_period_change(gconstpointer arg)
4615b262bb6SDmitry Osipenko {
4625b262bb6SDmitry Osipenko const uint8_t *policy = arg;
46391b37aeaSPeter Maydell ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
464057516feSDmitry Osipenko bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
4655b262bb6SDmitry Osipenko
4665b262bb6SDmitry Osipenko triggered = false;
4675b262bb6SDmitry Osipenko
46891b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
4695b262bb6SDmitry Osipenko ptimer_set_period(ptimer, 2000000);
4705b262bb6SDmitry Osipenko ptimer_set_limit(ptimer, 8, 1);
4715b262bb6SDmitry Osipenko ptimer_run(ptimer, 1);
47291b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
4735b262bb6SDmitry Osipenko
47433d44cdfSDmitry Osipenko qemu_clock_step(2000000 * 4 + 1);
4755b262bb6SDmitry Osipenko
476057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
4775b262bb6SDmitry Osipenko g_assert_false(triggered);
4785b262bb6SDmitry Osipenko
47991b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
4805b262bb6SDmitry Osipenko ptimer_set_period(ptimer, 4000000);
48191b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
482057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
4835b262bb6SDmitry Osipenko
48433d44cdfSDmitry Osipenko qemu_clock_step(4000000 * 2 + 1);
4855b262bb6SDmitry Osipenko
486057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 2 : 0);
4875b262bb6SDmitry Osipenko g_assert_false(triggered);
4885b262bb6SDmitry Osipenko
4895b262bb6SDmitry Osipenko qemu_clock_step(4000000 * 2);
4905b262bb6SDmitry Osipenko
4915b262bb6SDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
4925b262bb6SDmitry Osipenko g_assert_true(triggered);
493072bdb07SMarc-André Lureau ptimer_free(ptimer);
4945b262bb6SDmitry Osipenko }
4955b262bb6SDmitry Osipenko
check_on_the_fly_freq_change(gconstpointer arg)4965b262bb6SDmitry Osipenko static void check_on_the_fly_freq_change(gconstpointer arg)
4975b262bb6SDmitry Osipenko {
4985b262bb6SDmitry Osipenko const uint8_t *policy = arg;
49991b37aeaSPeter Maydell ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
500057516feSDmitry Osipenko bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
5015b262bb6SDmitry Osipenko
5025b262bb6SDmitry Osipenko triggered = false;
5035b262bb6SDmitry Osipenko
50491b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
5055b262bb6SDmitry Osipenko ptimer_set_freq(ptimer, 500);
5065b262bb6SDmitry Osipenko ptimer_set_limit(ptimer, 8, 1);
5075b262bb6SDmitry Osipenko ptimer_run(ptimer, 1);
50891b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
5095b262bb6SDmitry Osipenko
51033d44cdfSDmitry Osipenko qemu_clock_step(2000000 * 4 + 1);
5115b262bb6SDmitry Osipenko
512057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
5135b262bb6SDmitry Osipenko g_assert_false(triggered);
5145b262bb6SDmitry Osipenko
51591b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
5165b262bb6SDmitry Osipenko ptimer_set_freq(ptimer, 250);
51791b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
518057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
5195b262bb6SDmitry Osipenko
52033d44cdfSDmitry Osipenko qemu_clock_step(2000000 * 4 + 1);
5215b262bb6SDmitry Osipenko
522057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 2 : 0);
5235b262bb6SDmitry Osipenko g_assert_false(triggered);
5245b262bb6SDmitry Osipenko
5255b262bb6SDmitry Osipenko qemu_clock_step(2000000 * 4);
5265b262bb6SDmitry Osipenko
5275b262bb6SDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
5285b262bb6SDmitry Osipenko g_assert_true(triggered);
529072bdb07SMarc-André Lureau ptimer_free(ptimer);
5305b262bb6SDmitry Osipenko }
5315b262bb6SDmitry Osipenko
check_run_with_period_0(gconstpointer arg)5325b262bb6SDmitry Osipenko static void check_run_with_period_0(gconstpointer arg)
5335b262bb6SDmitry Osipenko {
5345b262bb6SDmitry Osipenko const uint8_t *policy = arg;
53591b37aeaSPeter Maydell ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
5365b262bb6SDmitry Osipenko
5375b262bb6SDmitry Osipenko triggered = false;
5385b262bb6SDmitry Osipenko
53991b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
5405b262bb6SDmitry Osipenko ptimer_set_count(ptimer, 99);
5415b262bb6SDmitry Osipenko ptimer_run(ptimer, 1);
54291b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
5435b262bb6SDmitry Osipenko
5445b262bb6SDmitry Osipenko qemu_clock_step(10 * NANOSECONDS_PER_SECOND);
5455b262bb6SDmitry Osipenko
5465b262bb6SDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, 99);
5475b262bb6SDmitry Osipenko g_assert_false(triggered);
548072bdb07SMarc-André Lureau ptimer_free(ptimer);
5495b262bb6SDmitry Osipenko }
5505b262bb6SDmitry Osipenko
check_run_with_delta_0(gconstpointer arg)5515b262bb6SDmitry Osipenko static void check_run_with_delta_0(gconstpointer arg)
5525b262bb6SDmitry Osipenko {
5535b262bb6SDmitry Osipenko const uint8_t *policy = arg;
55491b37aeaSPeter Maydell ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
555293130aaSDmitry Osipenko bool wrap_policy = (*policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD);
556516deb42SDmitry Osipenko bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
55756700e1aSDmitry Osipenko bool no_immediate_reload = (*policy & PTIMER_POLICY_NO_IMMEDIATE_RELOAD);
558057516feSDmitry Osipenko bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
559086ede32SPeter Maydell bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
5605b262bb6SDmitry Osipenko
5615b262bb6SDmitry Osipenko triggered = false;
5625b262bb6SDmitry Osipenko
56391b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
5645b262bb6SDmitry Osipenko ptimer_set_period(ptimer, 2000000);
5655b262bb6SDmitry Osipenko ptimer_set_limit(ptimer, 99, 0);
5665b262bb6SDmitry Osipenko ptimer_run(ptimer, 1);
56791b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
56856700e1aSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==,
56956700e1aSDmitry Osipenko no_immediate_reload ? 0 : 99);
570516deb42SDmitry Osipenko
571086ede32SPeter Maydell if (no_immediate_trigger || trig_only_on_dec) {
572516deb42SDmitry Osipenko g_assert_false(triggered);
573516deb42SDmitry Osipenko } else {
5745b262bb6SDmitry Osipenko g_assert_true(triggered);
575516deb42SDmitry Osipenko }
5765b262bb6SDmitry Osipenko
5775b262bb6SDmitry Osipenko triggered = false;
5785b262bb6SDmitry Osipenko
57956700e1aSDmitry Osipenko if (no_immediate_trigger || no_immediate_reload) {
58033d44cdfSDmitry Osipenko qemu_clock_step(2000000 + 1);
581516deb42SDmitry Osipenko
58256700e1aSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==,
583057516feSDmitry Osipenko no_immediate_reload ? 0 : (no_round_down ? 98 : 97));
58456700e1aSDmitry Osipenko
58556700e1aSDmitry Osipenko if (no_immediate_trigger && no_immediate_reload) {
58656700e1aSDmitry Osipenko g_assert_true(triggered);
58756700e1aSDmitry Osipenko
58856700e1aSDmitry Osipenko triggered = false;
58956700e1aSDmitry Osipenko } else {
590516deb42SDmitry Osipenko g_assert_false(triggered);
59156700e1aSDmitry Osipenko }
592516deb42SDmitry Osipenko
59391b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
594516deb42SDmitry Osipenko ptimer_set_count(ptimer, 99);
595516deb42SDmitry Osipenko ptimer_run(ptimer, 1);
59691b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
597516deb42SDmitry Osipenko }
598516deb42SDmitry Osipenko
59933d44cdfSDmitry Osipenko qemu_clock_step(2000000 + 1);
6005b262bb6SDmitry Osipenko
601057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 98 : 97);
6025b262bb6SDmitry Osipenko g_assert_false(triggered);
6035b262bb6SDmitry Osipenko
6045b262bb6SDmitry Osipenko qemu_clock_step(2000000 * 97);
6055b262bb6SDmitry Osipenko
606057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
6075b262bb6SDmitry Osipenko g_assert_false(triggered);
6085b262bb6SDmitry Osipenko
6095b262bb6SDmitry Osipenko qemu_clock_step(2000000 * 2);
6105b262bb6SDmitry Osipenko
6115b262bb6SDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
6125b262bb6SDmitry Osipenko g_assert_true(triggered);
6135b262bb6SDmitry Osipenko
6145b262bb6SDmitry Osipenko triggered = false;
6155b262bb6SDmitry Osipenko
61691b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
6175b262bb6SDmitry Osipenko ptimer_set_count(ptimer, 0);
6185b262bb6SDmitry Osipenko ptimer_run(ptimer, 0);
61991b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
62056700e1aSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==,
62156700e1aSDmitry Osipenko no_immediate_reload ? 0 : 99);
622516deb42SDmitry Osipenko
623086ede32SPeter Maydell if (no_immediate_trigger || trig_only_on_dec) {
624516deb42SDmitry Osipenko g_assert_false(triggered);
625516deb42SDmitry Osipenko } else {
6265b262bb6SDmitry Osipenko g_assert_true(triggered);
627516deb42SDmitry Osipenko }
6285b262bb6SDmitry Osipenko
6295b262bb6SDmitry Osipenko triggered = false;
6305b262bb6SDmitry Osipenko
63133d44cdfSDmitry Osipenko qemu_clock_step(1);
632293130aaSDmitry Osipenko
63356700e1aSDmitry Osipenko if (no_immediate_reload) {
63456700e1aSDmitry Osipenko qemu_clock_step(2000000);
63556700e1aSDmitry Osipenko }
63656700e1aSDmitry Osipenko
637057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 99 : 98);
63856700e1aSDmitry Osipenko
63956700e1aSDmitry Osipenko if (no_immediate_reload && no_immediate_trigger) {
64056700e1aSDmitry Osipenko g_assert_true(triggered);
64156700e1aSDmitry Osipenko } else {
642293130aaSDmitry Osipenko g_assert_false(triggered);
64356700e1aSDmitry Osipenko }
644293130aaSDmitry Osipenko
645293130aaSDmitry Osipenko triggered = false;
646293130aaSDmitry Osipenko
647293130aaSDmitry Osipenko qemu_clock_step(2000000);
6485b262bb6SDmitry Osipenko
649057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 98 : 97);
6505b262bb6SDmitry Osipenko g_assert_false(triggered);
6515b262bb6SDmitry Osipenko
6525b262bb6SDmitry Osipenko qemu_clock_step(2000000 * 98);
6535b262bb6SDmitry Osipenko
654057516feSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==,
655057516feSDmitry Osipenko wrap_policy ? 0 : (no_round_down ? 99 : 98));
6565b262bb6SDmitry Osipenko g_assert_true(triggered);
6575b262bb6SDmitry Osipenko
65891b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
6595b262bb6SDmitry Osipenko ptimer_stop(ptimer);
66091b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
661072bdb07SMarc-André Lureau ptimer_free(ptimer);
6625b262bb6SDmitry Osipenko }
6635b262bb6SDmitry Osipenko
check_periodic_with_load_0(gconstpointer arg)6645b262bb6SDmitry Osipenko static void check_periodic_with_load_0(gconstpointer arg)
6655b262bb6SDmitry Osipenko {
6665b262bb6SDmitry Osipenko const uint8_t *policy = arg;
66791b37aeaSPeter Maydell ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
6682e74583bSDmitry Osipenko bool continuous_trigger = (*policy & PTIMER_POLICY_CONTINUOUS_TRIGGER);
669516deb42SDmitry Osipenko bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
670086ede32SPeter Maydell bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
6715b262bb6SDmitry Osipenko
6725b262bb6SDmitry Osipenko triggered = false;
6735b262bb6SDmitry Osipenko
67491b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
6755b262bb6SDmitry Osipenko ptimer_set_period(ptimer, 2000000);
6765b262bb6SDmitry Osipenko ptimer_run(ptimer, 0);
67791b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
6785b262bb6SDmitry Osipenko
6795b262bb6SDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
680516deb42SDmitry Osipenko
681086ede32SPeter Maydell if (no_immediate_trigger || trig_only_on_dec) {
682516deb42SDmitry Osipenko g_assert_false(triggered);
683516deb42SDmitry Osipenko } else {
6845b262bb6SDmitry Osipenko g_assert_true(triggered);
685516deb42SDmitry Osipenko }
6865b262bb6SDmitry Osipenko
6875b262bb6SDmitry Osipenko triggered = false;
6885b262bb6SDmitry Osipenko
68933d44cdfSDmitry Osipenko qemu_clock_step(2000000 + 1);
6905b262bb6SDmitry Osipenko
6915b262bb6SDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
6922e74583bSDmitry Osipenko
693516deb42SDmitry Osipenko if (continuous_trigger || no_immediate_trigger) {
6942e74583bSDmitry Osipenko g_assert_true(triggered);
6952e74583bSDmitry Osipenko } else {
6965b262bb6SDmitry Osipenko g_assert_false(triggered);
6972e74583bSDmitry Osipenko }
6985b262bb6SDmitry Osipenko
699293130aaSDmitry Osipenko triggered = false;
700293130aaSDmitry Osipenko
70191b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
702293130aaSDmitry Osipenko ptimer_set_count(ptimer, 10);
703293130aaSDmitry Osipenko ptimer_run(ptimer, 0);
70491b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
705293130aaSDmitry Osipenko
70633d44cdfSDmitry Osipenko qemu_clock_step(2000000 * 10 + 1);
707293130aaSDmitry Osipenko
708293130aaSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
709293130aaSDmitry Osipenko g_assert_true(triggered);
710293130aaSDmitry Osipenko
711293130aaSDmitry Osipenko triggered = false;
712293130aaSDmitry Osipenko
71333d44cdfSDmitry Osipenko qemu_clock_step(2000000 + 1);
714293130aaSDmitry Osipenko
715293130aaSDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
7162e74583bSDmitry Osipenko
7172e74583bSDmitry Osipenko if (continuous_trigger) {
7182e74583bSDmitry Osipenko g_assert_true(triggered);
7192e74583bSDmitry Osipenko } else {
720293130aaSDmitry Osipenko g_assert_false(triggered);
7212e74583bSDmitry Osipenko }
722293130aaSDmitry Osipenko
72391b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
7245b262bb6SDmitry Osipenko ptimer_stop(ptimer);
72591b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
726072bdb07SMarc-André Lureau ptimer_free(ptimer);
7275b262bb6SDmitry Osipenko }
7285b262bb6SDmitry Osipenko
check_oneshot_with_load_0(gconstpointer arg)7295b262bb6SDmitry Osipenko static void check_oneshot_with_load_0(gconstpointer arg)
7305b262bb6SDmitry Osipenko {
7315b262bb6SDmitry Osipenko const uint8_t *policy = arg;
73291b37aeaSPeter Maydell ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
733516deb42SDmitry Osipenko bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
734086ede32SPeter Maydell bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
7355b262bb6SDmitry Osipenko
7365b262bb6SDmitry Osipenko triggered = false;
7375b262bb6SDmitry Osipenko
73891b37aeaSPeter Maydell ptimer_transaction_begin(ptimer);
7395b262bb6SDmitry Osipenko ptimer_set_period(ptimer, 2000000);
7405b262bb6SDmitry Osipenko ptimer_run(ptimer, 1);
74191b37aeaSPeter Maydell ptimer_transaction_commit(ptimer);
7425b262bb6SDmitry Osipenko
7435b262bb6SDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
744516deb42SDmitry Osipenko
745086ede32SPeter Maydell if (no_immediate_trigger || trig_only_on_dec) {
746516deb42SDmitry Osipenko g_assert_false(triggered);
747516deb42SDmitry Osipenko } else {
7485b262bb6SDmitry Osipenko g_assert_true(triggered);
749516deb42SDmitry Osipenko }
7505b262bb6SDmitry Osipenko
7515b262bb6SDmitry Osipenko triggered = false;
7525b262bb6SDmitry Osipenko
75333d44cdfSDmitry Osipenko qemu_clock_step(2000000 + 1);
7545b262bb6SDmitry Osipenko
7555b262bb6SDmitry Osipenko g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
756516deb42SDmitry Osipenko
757516deb42SDmitry Osipenko if (no_immediate_trigger) {
758516deb42SDmitry Osipenko g_assert_true(triggered);
759516deb42SDmitry Osipenko } else {
7605b262bb6SDmitry Osipenko g_assert_false(triggered);
7615b262bb6SDmitry Osipenko }
762072bdb07SMarc-André Lureau
763072bdb07SMarc-André Lureau ptimer_free(ptimer);
764516deb42SDmitry Osipenko }
7655b262bb6SDmitry Osipenko
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)7935b262bb6SDmitry Osipenko static void add_ptimer_tests(uint8_t policy)
7945b262bb6SDmitry Osipenko {
795072bdb07SMarc-André Lureau char policy_name[256] = "";
796072bdb07SMarc-André Lureau char *tmp;
7975b262bb6SDmitry Osipenko
7989598c1bbSPeter Maydell if (policy == PTIMER_POLICY_LEGACY) {
7999598c1bbSPeter Maydell g_sprintf(policy_name, "legacy");
8005b262bb6SDmitry Osipenko }
8015b262bb6SDmitry Osipenko
802293130aaSDmitry Osipenko if (policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD) {
803293130aaSDmitry Osipenko g_strlcat(policy_name, "wrap_after_one_period,", 256);
804293130aaSDmitry Osipenko }
805293130aaSDmitry Osipenko
8062e74583bSDmitry Osipenko if (policy & PTIMER_POLICY_CONTINUOUS_TRIGGER) {
8072e74583bSDmitry Osipenko g_strlcat(policy_name, "continuous_trigger,", 256);
8082e74583bSDmitry Osipenko }
8092e74583bSDmitry Osipenko
810516deb42SDmitry Osipenko if (policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER) {
811516deb42SDmitry Osipenko g_strlcat(policy_name, "no_immediate_trigger,", 256);
812516deb42SDmitry Osipenko }
813516deb42SDmitry Osipenko
81456700e1aSDmitry Osipenko if (policy & PTIMER_POLICY_NO_IMMEDIATE_RELOAD) {
81556700e1aSDmitry Osipenko g_strlcat(policy_name, "no_immediate_reload,", 256);
81656700e1aSDmitry Osipenko }
81756700e1aSDmitry Osipenko
818057516feSDmitry Osipenko if (policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN) {
819057516feSDmitry Osipenko g_strlcat(policy_name, "no_counter_rounddown,", 256);
820057516feSDmitry Osipenko }
821057516feSDmitry Osipenko
822086ede32SPeter Maydell if (policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT) {
823086ede32SPeter Maydell g_strlcat(policy_name, "trigger_only_on_decrement,", 256);
824086ede32SPeter Maydell }
825086ede32SPeter Maydell
826072bdb07SMarc-André Lureau g_test_add_data_func_full(
827072bdb07SMarc-André Lureau tmp = g_strdup_printf("/ptimer/set_count policy=%s", policy_name),
828c4f8ce24SPhilippe Mathieu-Daudé g_memdup2(&policy, 1), check_set_count, g_free);
829072bdb07SMarc-André Lureau g_free(tmp);
8305b262bb6SDmitry Osipenko
831072bdb07SMarc-André Lureau g_test_add_data_func_full(
832072bdb07SMarc-André Lureau tmp = g_strdup_printf("/ptimer/set_limit policy=%s", policy_name),
833c4f8ce24SPhilippe Mathieu-Daudé g_memdup2(&policy, 1), check_set_limit, g_free);
834072bdb07SMarc-André Lureau g_free(tmp);
8355b262bb6SDmitry Osipenko
836072bdb07SMarc-André Lureau g_test_add_data_func_full(
837072bdb07SMarc-André Lureau tmp = g_strdup_printf("/ptimer/oneshot policy=%s", policy_name),
838c4f8ce24SPhilippe Mathieu-Daudé g_memdup2(&policy, 1), check_oneshot, g_free);
839072bdb07SMarc-André Lureau g_free(tmp);
8405b262bb6SDmitry Osipenko
841072bdb07SMarc-André Lureau g_test_add_data_func_full(
842072bdb07SMarc-André Lureau tmp = g_strdup_printf("/ptimer/periodic policy=%s", policy_name),
843c4f8ce24SPhilippe Mathieu-Daudé g_memdup2(&policy, 1), check_periodic, g_free);
844072bdb07SMarc-André Lureau g_free(tmp);
8455b262bb6SDmitry Osipenko
846072bdb07SMarc-André Lureau g_test_add_data_func_full(
847072bdb07SMarc-André Lureau tmp = g_strdup_printf("/ptimer/on_the_fly_mode_change policy=%s",
848072bdb07SMarc-André Lureau policy_name),
849c4f8ce24SPhilippe Mathieu-Daudé g_memdup2(&policy, 1), check_on_the_fly_mode_change, g_free);
850072bdb07SMarc-André Lureau g_free(tmp);
8515b262bb6SDmitry Osipenko
852072bdb07SMarc-André Lureau g_test_add_data_func_full(
853072bdb07SMarc-André Lureau tmp = g_strdup_printf("/ptimer/on_the_fly_period_change policy=%s",
854072bdb07SMarc-André Lureau policy_name),
855c4f8ce24SPhilippe Mathieu-Daudé g_memdup2(&policy, 1), check_on_the_fly_period_change, g_free);
856072bdb07SMarc-André Lureau g_free(tmp);
8575b262bb6SDmitry Osipenko
858072bdb07SMarc-André Lureau g_test_add_data_func_full(
859072bdb07SMarc-André Lureau tmp = g_strdup_printf("/ptimer/on_the_fly_freq_change policy=%s",
860072bdb07SMarc-André Lureau policy_name),
861c4f8ce24SPhilippe Mathieu-Daudé g_memdup2(&policy, 1), check_on_the_fly_freq_change, g_free);
862072bdb07SMarc-André Lureau g_free(tmp);
8635b262bb6SDmitry Osipenko
864072bdb07SMarc-André Lureau g_test_add_data_func_full(
865072bdb07SMarc-André Lureau tmp = g_strdup_printf("/ptimer/run_with_period_0 policy=%s",
866072bdb07SMarc-André Lureau policy_name),
867c4f8ce24SPhilippe Mathieu-Daudé g_memdup2(&policy, 1), check_run_with_period_0, g_free);
868072bdb07SMarc-André Lureau g_free(tmp);
8695b262bb6SDmitry Osipenko
870072bdb07SMarc-André Lureau g_test_add_data_func_full(
871072bdb07SMarc-André Lureau tmp = g_strdup_printf("/ptimer/run_with_delta_0 policy=%s",
872072bdb07SMarc-André Lureau policy_name),
873c4f8ce24SPhilippe Mathieu-Daudé g_memdup2(&policy, 1), check_run_with_delta_0, g_free);
874072bdb07SMarc-André Lureau g_free(tmp);
8755b262bb6SDmitry Osipenko
876072bdb07SMarc-André Lureau g_test_add_data_func_full(
877072bdb07SMarc-André Lureau tmp = g_strdup_printf("/ptimer/periodic_with_load_0 policy=%s",
878072bdb07SMarc-André Lureau policy_name),
879c4f8ce24SPhilippe Mathieu-Daudé g_memdup2(&policy, 1), check_periodic_with_load_0, g_free);
880072bdb07SMarc-André Lureau g_free(tmp);
8815b262bb6SDmitry Osipenko
882072bdb07SMarc-André Lureau g_test_add_data_func_full(
883072bdb07SMarc-André Lureau tmp = g_strdup_printf("/ptimer/oneshot_with_load_0 policy=%s",
884072bdb07SMarc-André Lureau policy_name),
885c4f8ce24SPhilippe Mathieu-Daudé g_memdup2(&policy, 1), check_oneshot_with_load_0, g_free);
886072bdb07SMarc-André Lureau 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);
8935b262bb6SDmitry Osipenko }
8945b262bb6SDmitry Osipenko
add_all_ptimer_policies_comb_tests(void)895293130aaSDmitry Osipenko static void add_all_ptimer_policies_comb_tests(void)
896293130aaSDmitry Osipenko {
897086ede32SPeter Maydell int last_policy = PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT;
8989598c1bbSPeter Maydell int policy = PTIMER_POLICY_LEGACY;
899293130aaSDmitry Osipenko
900293130aaSDmitry Osipenko for (; policy < (last_policy << 1); policy++) {
901086ede32SPeter Maydell if ((policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT) &&
902086ede32SPeter Maydell (policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER)) {
903086ede32SPeter Maydell /* Incompatible policy flag settings -- don't try to test them */
904086ede32SPeter Maydell continue;
905086ede32SPeter Maydell }
906293130aaSDmitry Osipenko add_ptimer_tests(policy);
907293130aaSDmitry Osipenko }
908293130aaSDmitry Osipenko }
909293130aaSDmitry Osipenko
main(int argc,char ** argv)9105b262bb6SDmitry Osipenko int main(int argc, char **argv)
9115b262bb6SDmitry Osipenko {
9125b262bb6SDmitry Osipenko int i;
9135b262bb6SDmitry Osipenko
9145b262bb6SDmitry Osipenko g_test_init(&argc, &argv, NULL);
9155b262bb6SDmitry Osipenko
9165b262bb6SDmitry Osipenko for (i = 0; i < QEMU_CLOCK_MAX; i++) {
9175b262bb6SDmitry Osipenko main_loop_tlg.tl[i] = g_new0(QEMUTimerList, 1);
9185b262bb6SDmitry Osipenko }
9195b262bb6SDmitry Osipenko
920293130aaSDmitry Osipenko add_all_ptimer_policies_comb_tests();
9215b262bb6SDmitry Osipenko
9225b262bb6SDmitry Osipenko qtest_allowed = true;
9235b262bb6SDmitry Osipenko
9245b262bb6SDmitry Osipenko return g_test_run();
9255b262bb6SDmitry Osipenko }
926