xref: /qemu/tests/unit/ptimer-test.c (revision 91b37aea0e3f344aefec4d72faf12cbcac79d64e)
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 "libqtest.h"
185b262bb6SDmitry Osipenko #include "ptimer-test.h"
195b262bb6SDmitry Osipenko 
205b262bb6SDmitry Osipenko static bool triggered;
215b262bb6SDmitry Osipenko 
225b262bb6SDmitry Osipenko static void ptimer_trigger(void *opaque)
235b262bb6SDmitry Osipenko {
245b262bb6SDmitry Osipenko     triggered = true;
255b262bb6SDmitry Osipenko }
265b262bb6SDmitry Osipenko 
275b262bb6SDmitry Osipenko static void ptimer_test_expire_qemu_timers(int64_t expire_time,
285b262bb6SDmitry Osipenko                                            QEMUClockType type)
295b262bb6SDmitry Osipenko {
305b262bb6SDmitry Osipenko     QEMUTimerList *timer_list = main_loop_tlg.tl[type];
315b262bb6SDmitry Osipenko     QEMUTimer *t = timer_list->active_timers.next;
325b262bb6SDmitry Osipenko 
335b262bb6SDmitry Osipenko     while (t != NULL) {
345b262bb6SDmitry Osipenko         if (t->expire_time == expire_time) {
355b262bb6SDmitry Osipenko             timer_del(t);
365b262bb6SDmitry Osipenko 
375b262bb6SDmitry Osipenko             if (t->cb != NULL) {
385b262bb6SDmitry Osipenko                 t->cb(t->opaque);
395b262bb6SDmitry Osipenko             }
405b262bb6SDmitry Osipenko         }
415b262bb6SDmitry Osipenko 
425b262bb6SDmitry Osipenko         t = t->next;
435b262bb6SDmitry Osipenko     }
445b262bb6SDmitry Osipenko }
455b262bb6SDmitry Osipenko 
465b262bb6SDmitry Osipenko static void ptimer_test_set_qemu_time_ns(int64_t ns)
475b262bb6SDmitry Osipenko {
485b262bb6SDmitry Osipenko     ptimer_test_time_ns = ns;
495b262bb6SDmitry Osipenko }
505b262bb6SDmitry Osipenko 
515b262bb6SDmitry Osipenko static void qemu_clock_step(uint64_t ns)
525b262bb6SDmitry Osipenko {
53dcb15780SPavel Dovgalyuk     int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
54dcb15780SPavel Dovgalyuk                                                   QEMU_TIMER_ATTR_ALL);
555b262bb6SDmitry Osipenko     int64_t advanced_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ns;
565b262bb6SDmitry Osipenko 
575b262bb6SDmitry Osipenko     while (deadline != -1 && deadline <= advanced_time) {
585b262bb6SDmitry Osipenko         ptimer_test_set_qemu_time_ns(deadline);
595b262bb6SDmitry Osipenko         ptimer_test_expire_qemu_timers(deadline, QEMU_CLOCK_VIRTUAL);
60dcb15780SPavel Dovgalyuk         deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
61dcb15780SPavel Dovgalyuk                                               QEMU_TIMER_ATTR_ALL);
625b262bb6SDmitry Osipenko     }
635b262bb6SDmitry Osipenko 
645b262bb6SDmitry Osipenko     ptimer_test_set_qemu_time_ns(advanced_time);
655b262bb6SDmitry Osipenko }
665b262bb6SDmitry Osipenko 
675b262bb6SDmitry Osipenko static void check_set_count(gconstpointer arg)
685b262bb6SDmitry Osipenko {
695b262bb6SDmitry Osipenko     const uint8_t *policy = arg;
70*91b37aeaSPeter Maydell     ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
715b262bb6SDmitry Osipenko 
725b262bb6SDmitry Osipenko     triggered = false;
735b262bb6SDmitry Osipenko 
74*91b37aeaSPeter Maydell     ptimer_transaction_begin(ptimer);
755b262bb6SDmitry Osipenko     ptimer_set_count(ptimer, 1000);
76*91b37aeaSPeter Maydell     ptimer_transaction_commit(ptimer);
775b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 1000);
785b262bb6SDmitry Osipenko     g_assert_false(triggered);
79072bdb07SMarc-André Lureau     ptimer_free(ptimer);
805b262bb6SDmitry Osipenko }
815b262bb6SDmitry Osipenko 
825b262bb6SDmitry Osipenko static void check_set_limit(gconstpointer arg)
835b262bb6SDmitry Osipenko {
845b262bb6SDmitry Osipenko     const uint8_t *policy = arg;
85*91b37aeaSPeter Maydell     ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
865b262bb6SDmitry Osipenko 
875b262bb6SDmitry Osipenko     triggered = false;
885b262bb6SDmitry Osipenko 
89*91b37aeaSPeter Maydell     ptimer_transaction_begin(ptimer);
905b262bb6SDmitry Osipenko     ptimer_set_limit(ptimer, 1000, 0);
91*91b37aeaSPeter Maydell     ptimer_transaction_commit(ptimer);
925b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
935b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_limit(ptimer), ==, 1000);
945b262bb6SDmitry Osipenko     g_assert_false(triggered);
955b262bb6SDmitry Osipenko 
96*91b37aeaSPeter Maydell     ptimer_transaction_begin(ptimer);
975b262bb6SDmitry Osipenko     ptimer_set_limit(ptimer, 2000, 1);
98*91b37aeaSPeter Maydell     ptimer_transaction_commit(ptimer);
995b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 2000);
1005b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_limit(ptimer), ==, 2000);
1015b262bb6SDmitry Osipenko     g_assert_false(triggered);
102072bdb07SMarc-André Lureau     ptimer_free(ptimer);
1035b262bb6SDmitry Osipenko }
1045b262bb6SDmitry Osipenko 
1055b262bb6SDmitry Osipenko static void check_oneshot(gconstpointer arg)
1065b262bb6SDmitry Osipenko {
1075b262bb6SDmitry Osipenko     const uint8_t *policy = arg;
108*91b37aeaSPeter Maydell     ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
109057516feSDmitry Osipenko     bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
1105b262bb6SDmitry Osipenko 
1115b262bb6SDmitry Osipenko     triggered = false;
1125b262bb6SDmitry Osipenko 
113*91b37aeaSPeter Maydell     ptimer_transaction_begin(ptimer);
1145b262bb6SDmitry Osipenko     ptimer_set_period(ptimer, 2000000);
1155b262bb6SDmitry Osipenko     ptimer_set_count(ptimer, 10);
1165b262bb6SDmitry Osipenko     ptimer_run(ptimer, 1);
117*91b37aeaSPeter Maydell     ptimer_transaction_commit(ptimer);
1185b262bb6SDmitry Osipenko 
11933d44cdfSDmitry Osipenko     qemu_clock_step(2000000 * 2 + 1);
1205b262bb6SDmitry Osipenko 
121057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
1225b262bb6SDmitry Osipenko     g_assert_false(triggered);
1235b262bb6SDmitry Osipenko 
124*91b37aeaSPeter Maydell     ptimer_transaction_begin(ptimer);
1255b262bb6SDmitry Osipenko     ptimer_stop(ptimer);
126*91b37aeaSPeter Maydell     ptimer_transaction_commit(ptimer);
1275b262bb6SDmitry Osipenko 
128057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
1295b262bb6SDmitry Osipenko     g_assert_false(triggered);
1305b262bb6SDmitry Osipenko 
1315b262bb6SDmitry Osipenko     qemu_clock_step(2000000 * 11);
1325b262bb6SDmitry Osipenko 
133057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
1345b262bb6SDmitry Osipenko     g_assert_false(triggered);
1355b262bb6SDmitry Osipenko 
136*91b37aeaSPeter Maydell     ptimer_transaction_begin(ptimer);
1375b262bb6SDmitry Osipenko     ptimer_run(ptimer, 1);
138*91b37aeaSPeter Maydell     ptimer_transaction_commit(ptimer);
1395b262bb6SDmitry Osipenko 
14033d44cdfSDmitry Osipenko     qemu_clock_step(2000000 * 7 + 1);
1415b262bb6SDmitry Osipenko 
142057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
143057516feSDmitry Osipenko 
144057516feSDmitry Osipenko     if (no_round_down) {
145057516feSDmitry Osipenko         g_assert_false(triggered);
146057516feSDmitry Osipenko     } else {
1475b262bb6SDmitry Osipenko         g_assert_true(triggered);
1485b262bb6SDmitry Osipenko 
1495b262bb6SDmitry Osipenko         triggered = false;
150057516feSDmitry Osipenko     }
1515b262bb6SDmitry Osipenko 
1525b262bb6SDmitry Osipenko     qemu_clock_step(2000000);
1535b262bb6SDmitry Osipenko 
1545b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
155057516feSDmitry Osipenko 
156057516feSDmitry Osipenko     if (no_round_down) {
157057516feSDmitry Osipenko         g_assert_true(triggered);
158057516feSDmitry Osipenko 
159057516feSDmitry Osipenko         triggered = false;
160057516feSDmitry Osipenko     } else {
1615b262bb6SDmitry Osipenko         g_assert_false(triggered);
162057516feSDmitry Osipenko     }
1635b262bb6SDmitry Osipenko 
1645b262bb6SDmitry Osipenko     qemu_clock_step(4000000);
1655b262bb6SDmitry Osipenko 
1665b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
1675b262bb6SDmitry Osipenko     g_assert_false(triggered);
1685b262bb6SDmitry Osipenko 
169*91b37aeaSPeter Maydell     ptimer_transaction_begin(ptimer);
1705b262bb6SDmitry Osipenko     ptimer_set_count(ptimer, 10);
171*91b37aeaSPeter Maydell     ptimer_transaction_commit(ptimer);
1725b262bb6SDmitry Osipenko 
17333d44cdfSDmitry Osipenko     qemu_clock_step(20000000 + 1);
1745b262bb6SDmitry Osipenko 
1755b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 10);
1765b262bb6SDmitry Osipenko     g_assert_false(triggered);
1775b262bb6SDmitry Osipenko 
178*91b37aeaSPeter Maydell     ptimer_transaction_begin(ptimer);
1795b262bb6SDmitry Osipenko     ptimer_set_limit(ptimer, 9, 1);
180*91b37aeaSPeter Maydell     ptimer_transaction_commit(ptimer);
1815b262bb6SDmitry Osipenko 
18233d44cdfSDmitry Osipenko     qemu_clock_step(20000000 + 1);
1835b262bb6SDmitry Osipenko 
1845b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 9);
1855b262bb6SDmitry Osipenko     g_assert_false(triggered);
1865b262bb6SDmitry Osipenko 
187*91b37aeaSPeter Maydell     ptimer_transaction_begin(ptimer);
1885b262bb6SDmitry Osipenko     ptimer_run(ptimer, 1);
189*91b37aeaSPeter Maydell     ptimer_transaction_commit(ptimer);
1905b262bb6SDmitry Osipenko 
19133d44cdfSDmitry Osipenko     qemu_clock_step(2000000 + 1);
1925b262bb6SDmitry Osipenko 
193057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
1945b262bb6SDmitry Osipenko     g_assert_false(triggered);
1955b262bb6SDmitry Osipenko 
196*91b37aeaSPeter Maydell     ptimer_transaction_begin(ptimer);
1975b262bb6SDmitry Osipenko     ptimer_set_count(ptimer, 20);
198*91b37aeaSPeter Maydell     ptimer_transaction_commit(ptimer);
1995b262bb6SDmitry Osipenko 
20033d44cdfSDmitry Osipenko     qemu_clock_step(2000000 * 19 + 1);
2015b262bb6SDmitry Osipenko 
202057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
2035b262bb6SDmitry Osipenko     g_assert_false(triggered);
2045b262bb6SDmitry Osipenko 
2055b262bb6SDmitry Osipenko     qemu_clock_step(2000000);
2065b262bb6SDmitry Osipenko 
2075b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
2085b262bb6SDmitry Osipenko     g_assert_true(triggered);
2095b262bb6SDmitry Osipenko 
210*91b37aeaSPeter Maydell     ptimer_transaction_begin(ptimer);
2115b262bb6SDmitry Osipenko     ptimer_stop(ptimer);
212*91b37aeaSPeter Maydell     ptimer_transaction_commit(ptimer);
2135b262bb6SDmitry Osipenko 
2145b262bb6SDmitry Osipenko     triggered = false;
2155b262bb6SDmitry Osipenko 
21633d44cdfSDmitry Osipenko     qemu_clock_step(2000000 * 12 + 1);
2175b262bb6SDmitry Osipenko 
2185b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
2195b262bb6SDmitry Osipenko     g_assert_false(triggered);
220072bdb07SMarc-André Lureau     ptimer_free(ptimer);
2215b262bb6SDmitry Osipenko }
2225b262bb6SDmitry Osipenko 
2235b262bb6SDmitry Osipenko static void check_periodic(gconstpointer arg)
2245b262bb6SDmitry Osipenko {
2255b262bb6SDmitry Osipenko     const uint8_t *policy = arg;
226*91b37aeaSPeter Maydell     ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
227293130aaSDmitry Osipenko     bool wrap_policy = (*policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD);
228516deb42SDmitry Osipenko     bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
22956700e1aSDmitry Osipenko     bool no_immediate_reload = (*policy & PTIMER_POLICY_NO_IMMEDIATE_RELOAD);
230057516feSDmitry Osipenko     bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
231086ede32SPeter Maydell     bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
2325b262bb6SDmitry Osipenko 
2335b262bb6SDmitry Osipenko     triggered = false;
2345b262bb6SDmitry Osipenko 
235*91b37aeaSPeter Maydell     ptimer_transaction_begin(ptimer);
2365b262bb6SDmitry Osipenko     ptimer_set_period(ptimer, 2000000);
2375b262bb6SDmitry Osipenko     ptimer_set_limit(ptimer, 10, 1);
2385b262bb6SDmitry Osipenko     ptimer_run(ptimer, 0);
239*91b37aeaSPeter Maydell     ptimer_transaction_commit(ptimer);
2405b262bb6SDmitry Osipenko 
241293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 10);
242293130aaSDmitry Osipenko     g_assert_false(triggered);
243293130aaSDmitry Osipenko 
24433d44cdfSDmitry Osipenko     qemu_clock_step(1);
2455b262bb6SDmitry Osipenko 
246057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 10 : 9);
247293130aaSDmitry Osipenko     g_assert_false(triggered);
248293130aaSDmitry Osipenko 
24933d44cdfSDmitry Osipenko     qemu_clock_step(2000000 * 10 - 1);
250293130aaSDmitry Osipenko 
251293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, wrap_policy ? 0 : 10);
252293130aaSDmitry Osipenko     g_assert_true(triggered);
253293130aaSDmitry Osipenko 
25433d44cdfSDmitry Osipenko     qemu_clock_step(1);
255293130aaSDmitry Osipenko 
256057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==,
257057516feSDmitry Osipenko                      wrap_policy ? 0 : (no_round_down ? 10 : 9));
2585b262bb6SDmitry Osipenko     g_assert_true(triggered);
2595b262bb6SDmitry Osipenko 
2605b262bb6SDmitry Osipenko     triggered = false;
2615b262bb6SDmitry Osipenko 
2625b262bb6SDmitry Osipenko     qemu_clock_step(2000000);
2635b262bb6SDmitry Osipenko 
264057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==,
265057516feSDmitry Osipenko                     (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
2665b262bb6SDmitry Osipenko     g_assert_false(triggered);
2675b262bb6SDmitry Osipenko 
268*91b37aeaSPeter Maydell     ptimer_transaction_begin(ptimer);
2695b262bb6SDmitry Osipenko     ptimer_set_count(ptimer, 20);
270*91b37aeaSPeter Maydell     ptimer_transaction_commit(ptimer);
2715b262bb6SDmitry Osipenko 
272293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 20);
273293130aaSDmitry Osipenko     g_assert_false(triggered);
274293130aaSDmitry Osipenko 
27533d44cdfSDmitry Osipenko     qemu_clock_step(1);
276293130aaSDmitry Osipenko 
277057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 20 : 19);
278293130aaSDmitry Osipenko     g_assert_false(triggered);
279293130aaSDmitry Osipenko 
28033d44cdfSDmitry Osipenko     qemu_clock_step(2000000 * 11 + 1);
2815b262bb6SDmitry Osipenko 
282057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 9 : 8);
2835b262bb6SDmitry Osipenko     g_assert_false(triggered);
2845b262bb6SDmitry Osipenko 
2855b262bb6SDmitry Osipenko     qemu_clock_step(2000000 * 10);
2865b262bb6SDmitry Osipenko 
287057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==,
288057516feSDmitry Osipenko                     (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
289293130aaSDmitry Osipenko     g_assert_true(triggered);
290293130aaSDmitry Osipenko 
291293130aaSDmitry Osipenko     triggered = false;
292293130aaSDmitry Osipenko 
293*91b37aeaSPeter Maydell     ptimer_transaction_begin(ptimer);
294293130aaSDmitry Osipenko     ptimer_set_count(ptimer, 3);
295*91b37aeaSPeter Maydell     ptimer_transaction_commit(ptimer);
296293130aaSDmitry Osipenko 
297293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 3);
298293130aaSDmitry Osipenko     g_assert_false(triggered);
299293130aaSDmitry Osipenko 
30033d44cdfSDmitry Osipenko     qemu_clock_step(1);
301293130aaSDmitry Osipenko 
302057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 3 : 2);
303293130aaSDmitry Osipenko     g_assert_false(triggered);
304293130aaSDmitry Osipenko 
305293130aaSDmitry Osipenko     qemu_clock_step(2000000 * 4);
306293130aaSDmitry Osipenko 
307057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==,
308057516feSDmitry Osipenko                     (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
3095b262bb6SDmitry Osipenko     g_assert_true(triggered);
3105b262bb6SDmitry Osipenko 
311*91b37aeaSPeter Maydell     ptimer_transaction_begin(ptimer);
3125b262bb6SDmitry Osipenko     ptimer_stop(ptimer);
313*91b37aeaSPeter Maydell     ptimer_transaction_commit(ptimer);
3145b262bb6SDmitry Osipenko     triggered = false;
3155b262bb6SDmitry Osipenko 
3165b262bb6SDmitry Osipenko     qemu_clock_step(2000000);
3175b262bb6SDmitry Osipenko 
318057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==,
319057516feSDmitry Osipenko                     (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
3205b262bb6SDmitry Osipenko     g_assert_false(triggered);
3215b262bb6SDmitry Osipenko 
322*91b37aeaSPeter Maydell     ptimer_transaction_begin(ptimer);
3235b262bb6SDmitry Osipenko     ptimer_set_count(ptimer, 3);
3245b262bb6SDmitry Osipenko     ptimer_run(ptimer, 0);
325*91b37aeaSPeter Maydell     ptimer_transaction_commit(ptimer);
3265b262bb6SDmitry Osipenko 
32733d44cdfSDmitry Osipenko     qemu_clock_step(2000000 * 3 + 1);
3285b262bb6SDmitry Osipenko 
329057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==,
330057516feSDmitry Osipenko                      wrap_policy ? 0 : (no_round_down ? 10 : 9));
3315b262bb6SDmitry Osipenko     g_assert_true(triggered);
3325b262bb6SDmitry Osipenko 
3335b262bb6SDmitry Osipenko     triggered = false;
3345b262bb6SDmitry Osipenko 
3355b262bb6SDmitry Osipenko     qemu_clock_step(2000000);
3365b262bb6SDmitry Osipenko 
337057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==,
338057516feSDmitry Osipenko                     (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
3395b262bb6SDmitry Osipenko     g_assert_false(triggered);
3405b262bb6SDmitry Osipenko 
341*91b37aeaSPeter Maydell     ptimer_transaction_begin(ptimer);
3425b262bb6SDmitry Osipenko     ptimer_set_count(ptimer, 0);
343*91b37aeaSPeter Maydell     ptimer_transaction_commit(ptimer);
34456700e1aSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==,
34556700e1aSDmitry Osipenko                      no_immediate_reload ? 0 : 10);
346516deb42SDmitry Osipenko 
347086ede32SPeter Maydell     if (no_immediate_trigger || trig_only_on_dec) {
348516deb42SDmitry Osipenko         g_assert_false(triggered);
349516deb42SDmitry Osipenko     } else {
3505b262bb6SDmitry Osipenko         g_assert_true(triggered);
351516deb42SDmitry Osipenko     }
3525b262bb6SDmitry Osipenko 
3535b262bb6SDmitry Osipenko     triggered = false;
3545b262bb6SDmitry Osipenko 
35533d44cdfSDmitry Osipenko     qemu_clock_step(1);
3565b262bb6SDmitry Osipenko 
35756700e1aSDmitry Osipenko     if (no_immediate_reload) {
35856700e1aSDmitry Osipenko         g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
35956700e1aSDmitry Osipenko         g_assert_false(triggered);
36056700e1aSDmitry Osipenko 
36156700e1aSDmitry Osipenko         qemu_clock_step(2000000);
36256700e1aSDmitry Osipenko 
36356700e1aSDmitry Osipenko         if (no_immediate_trigger) {
36456700e1aSDmitry Osipenko             g_assert_true(triggered);
36556700e1aSDmitry Osipenko         } else {
36656700e1aSDmitry Osipenko             g_assert_false(triggered);
36756700e1aSDmitry Osipenko         }
36856700e1aSDmitry Osipenko 
36956700e1aSDmitry Osipenko         triggered = false;
37056700e1aSDmitry Osipenko     }
37156700e1aSDmitry Osipenko 
372057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 10 : 9);
373293130aaSDmitry Osipenko     g_assert_false(triggered);
374293130aaSDmitry Osipenko 
375293130aaSDmitry Osipenko     qemu_clock_step(2000000 * 12);
376293130aaSDmitry Osipenko 
377057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==,
378057516feSDmitry Osipenko                     (no_round_down ? 8 : 7) + (wrap_policy ? 1 : 0));
3795b262bb6SDmitry Osipenko     g_assert_true(triggered);
3805b262bb6SDmitry Osipenko 
381*91b37aeaSPeter Maydell     ptimer_transaction_begin(ptimer);
3825b262bb6SDmitry Osipenko     ptimer_stop(ptimer);
383*91b37aeaSPeter Maydell     ptimer_transaction_commit(ptimer);
3845b262bb6SDmitry Osipenko 
3855b262bb6SDmitry Osipenko     triggered = false;
3865b262bb6SDmitry Osipenko 
387293130aaSDmitry Osipenko     qemu_clock_step(2000000 * 10);
3885b262bb6SDmitry Osipenko 
389057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==,
390057516feSDmitry Osipenko                     (no_round_down ? 8 : 7) + (wrap_policy ? 1 : 0));
3915b262bb6SDmitry Osipenko     g_assert_false(triggered);
3925b262bb6SDmitry Osipenko 
393*91b37aeaSPeter Maydell     ptimer_transaction_begin(ptimer);
3945b262bb6SDmitry Osipenko     ptimer_run(ptimer, 0);
395*91b37aeaSPeter Maydell     ptimer_transaction_commit(ptimer);
396*91b37aeaSPeter Maydell 
397*91b37aeaSPeter Maydell     ptimer_transaction_begin(ptimer);
3985b262bb6SDmitry Osipenko     ptimer_set_period(ptimer, 0);
399*91b37aeaSPeter Maydell     ptimer_transaction_commit(ptimer);
4005b262bb6SDmitry Osipenko 
40133d44cdfSDmitry Osipenko     qemu_clock_step(2000000 + 1);
4025b262bb6SDmitry Osipenko 
403057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==,
404057516feSDmitry Osipenko                     (no_round_down ? 8 : 7) + (wrap_policy ? 1 : 0));
4055b262bb6SDmitry Osipenko     g_assert_false(triggered);
406072bdb07SMarc-André Lureau     ptimer_free(ptimer);
4075b262bb6SDmitry Osipenko }
4085b262bb6SDmitry Osipenko 
4095b262bb6SDmitry Osipenko static void check_on_the_fly_mode_change(gconstpointer arg)
4105b262bb6SDmitry Osipenko {
4115b262bb6SDmitry Osipenko     const uint8_t *policy = arg;
412*91b37aeaSPeter Maydell     ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
413293130aaSDmitry Osipenko     bool wrap_policy = (*policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD);
414057516feSDmitry Osipenko     bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
4155b262bb6SDmitry Osipenko 
4165b262bb6SDmitry Osipenko     triggered = false;
4175b262bb6SDmitry Osipenko 
418*91b37aeaSPeter Maydell     ptimer_transaction_begin(ptimer);
4195b262bb6SDmitry Osipenko     ptimer_set_period(ptimer, 2000000);
4205b262bb6SDmitry Osipenko     ptimer_set_limit(ptimer, 10, 1);
4215b262bb6SDmitry Osipenko     ptimer_run(ptimer, 1);
422*91b37aeaSPeter Maydell     ptimer_transaction_commit(ptimer);
4235b262bb6SDmitry Osipenko 
42433d44cdfSDmitry Osipenko     qemu_clock_step(2000000 * 9 + 1);
4255b262bb6SDmitry Osipenko 
426057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
427293130aaSDmitry Osipenko     g_assert_false(triggered);
428293130aaSDmitry Osipenko 
429*91b37aeaSPeter Maydell     ptimer_transaction_begin(ptimer);
4305b262bb6SDmitry Osipenko     ptimer_run(ptimer, 0);
431*91b37aeaSPeter Maydell     ptimer_transaction_commit(ptimer);
4325b262bb6SDmitry Osipenko 
433057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
4345b262bb6SDmitry Osipenko     g_assert_false(triggered);
4355b262bb6SDmitry Osipenko 
4365b262bb6SDmitry Osipenko     qemu_clock_step(2000000);
4375b262bb6SDmitry Osipenko 
438057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==,
439057516feSDmitry Osipenko                     wrap_policy ? 0 : (no_round_down ? 10 : 9));
4405b262bb6SDmitry Osipenko     g_assert_true(triggered);
4415b262bb6SDmitry Osipenko 
4425b262bb6SDmitry Osipenko     triggered = false;
4435b262bb6SDmitry Osipenko 
4445b262bb6SDmitry Osipenko     qemu_clock_step(2000000 * 9);
4455b262bb6SDmitry Osipenko 
446*91b37aeaSPeter Maydell     ptimer_transaction_begin(ptimer);
4475b262bb6SDmitry Osipenko     ptimer_run(ptimer, 1);
448*91b37aeaSPeter Maydell     ptimer_transaction_commit(ptimer);
4495b262bb6SDmitry Osipenko 
450057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==,
451057516feSDmitry Osipenko                      (no_round_down ? 1 : 0) + (wrap_policy ? 1 : 0));
4525b262bb6SDmitry Osipenko     g_assert_false(triggered);
4535b262bb6SDmitry Osipenko 
4545b262bb6SDmitry Osipenko     qemu_clock_step(2000000 * 3);
4555b262bb6SDmitry Osipenko 
4565b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
4575b262bb6SDmitry Osipenko     g_assert_true(triggered);
458072bdb07SMarc-André Lureau     ptimer_free(ptimer);
4595b262bb6SDmitry Osipenko }
4605b262bb6SDmitry Osipenko 
4615b262bb6SDmitry Osipenko static void check_on_the_fly_period_change(gconstpointer arg)
4625b262bb6SDmitry Osipenko {
4635b262bb6SDmitry Osipenko     const uint8_t *policy = arg;
464*91b37aeaSPeter Maydell     ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
465057516feSDmitry Osipenko     bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
4665b262bb6SDmitry Osipenko 
4675b262bb6SDmitry Osipenko     triggered = false;
4685b262bb6SDmitry Osipenko 
469*91b37aeaSPeter Maydell     ptimer_transaction_begin(ptimer);
4705b262bb6SDmitry Osipenko     ptimer_set_period(ptimer, 2000000);
4715b262bb6SDmitry Osipenko     ptimer_set_limit(ptimer, 8, 1);
4725b262bb6SDmitry Osipenko     ptimer_run(ptimer, 1);
473*91b37aeaSPeter Maydell     ptimer_transaction_commit(ptimer);
4745b262bb6SDmitry Osipenko 
47533d44cdfSDmitry Osipenko     qemu_clock_step(2000000 * 4 + 1);
4765b262bb6SDmitry Osipenko 
477057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
4785b262bb6SDmitry Osipenko     g_assert_false(triggered);
4795b262bb6SDmitry Osipenko 
480*91b37aeaSPeter Maydell     ptimer_transaction_begin(ptimer);
4815b262bb6SDmitry Osipenko     ptimer_set_period(ptimer, 4000000);
482*91b37aeaSPeter Maydell     ptimer_transaction_commit(ptimer);
483057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
4845b262bb6SDmitry Osipenko 
48533d44cdfSDmitry Osipenko     qemu_clock_step(4000000 * 2 + 1);
4865b262bb6SDmitry Osipenko 
487057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 2 : 0);
4885b262bb6SDmitry Osipenko     g_assert_false(triggered);
4895b262bb6SDmitry Osipenko 
4905b262bb6SDmitry Osipenko     qemu_clock_step(4000000 * 2);
4915b262bb6SDmitry Osipenko 
4925b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
4935b262bb6SDmitry Osipenko     g_assert_true(triggered);
494072bdb07SMarc-André Lureau     ptimer_free(ptimer);
4955b262bb6SDmitry Osipenko }
4965b262bb6SDmitry Osipenko 
4975b262bb6SDmitry Osipenko static void check_on_the_fly_freq_change(gconstpointer arg)
4985b262bb6SDmitry Osipenko {
4995b262bb6SDmitry Osipenko     const uint8_t *policy = arg;
500*91b37aeaSPeter Maydell     ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
501057516feSDmitry Osipenko     bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
5025b262bb6SDmitry Osipenko 
5035b262bb6SDmitry Osipenko     triggered = false;
5045b262bb6SDmitry Osipenko 
505*91b37aeaSPeter Maydell     ptimer_transaction_begin(ptimer);
5065b262bb6SDmitry Osipenko     ptimer_set_freq(ptimer, 500);
5075b262bb6SDmitry Osipenko     ptimer_set_limit(ptimer, 8, 1);
5085b262bb6SDmitry Osipenko     ptimer_run(ptimer, 1);
509*91b37aeaSPeter Maydell     ptimer_transaction_commit(ptimer);
5105b262bb6SDmitry Osipenko 
51133d44cdfSDmitry Osipenko     qemu_clock_step(2000000 * 4 + 1);
5125b262bb6SDmitry Osipenko 
513057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
5145b262bb6SDmitry Osipenko     g_assert_false(triggered);
5155b262bb6SDmitry Osipenko 
516*91b37aeaSPeter Maydell     ptimer_transaction_begin(ptimer);
5175b262bb6SDmitry Osipenko     ptimer_set_freq(ptimer, 250);
518*91b37aeaSPeter Maydell     ptimer_transaction_commit(ptimer);
519057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
5205b262bb6SDmitry Osipenko 
52133d44cdfSDmitry Osipenko     qemu_clock_step(2000000 * 4 + 1);
5225b262bb6SDmitry Osipenko 
523057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 2 : 0);
5245b262bb6SDmitry Osipenko     g_assert_false(triggered);
5255b262bb6SDmitry Osipenko 
5265b262bb6SDmitry Osipenko     qemu_clock_step(2000000 * 4);
5275b262bb6SDmitry Osipenko 
5285b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
5295b262bb6SDmitry Osipenko     g_assert_true(triggered);
530072bdb07SMarc-André Lureau     ptimer_free(ptimer);
5315b262bb6SDmitry Osipenko }
5325b262bb6SDmitry Osipenko 
5335b262bb6SDmitry Osipenko static void check_run_with_period_0(gconstpointer arg)
5345b262bb6SDmitry Osipenko {
5355b262bb6SDmitry Osipenko     const uint8_t *policy = arg;
536*91b37aeaSPeter Maydell     ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
5375b262bb6SDmitry Osipenko 
5385b262bb6SDmitry Osipenko     triggered = false;
5395b262bb6SDmitry Osipenko 
540*91b37aeaSPeter Maydell     ptimer_transaction_begin(ptimer);
5415b262bb6SDmitry Osipenko     ptimer_set_count(ptimer, 99);
5425b262bb6SDmitry Osipenko     ptimer_run(ptimer, 1);
543*91b37aeaSPeter Maydell     ptimer_transaction_commit(ptimer);
5445b262bb6SDmitry Osipenko 
5455b262bb6SDmitry Osipenko     qemu_clock_step(10 * NANOSECONDS_PER_SECOND);
5465b262bb6SDmitry Osipenko 
5475b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 99);
5485b262bb6SDmitry Osipenko     g_assert_false(triggered);
549072bdb07SMarc-André Lureau     ptimer_free(ptimer);
5505b262bb6SDmitry Osipenko }
5515b262bb6SDmitry Osipenko 
5525b262bb6SDmitry Osipenko static void check_run_with_delta_0(gconstpointer arg)
5535b262bb6SDmitry Osipenko {
5545b262bb6SDmitry Osipenko     const uint8_t *policy = arg;
555*91b37aeaSPeter Maydell     ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
556293130aaSDmitry Osipenko     bool wrap_policy = (*policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD);
557516deb42SDmitry Osipenko     bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
55856700e1aSDmitry Osipenko     bool no_immediate_reload = (*policy & PTIMER_POLICY_NO_IMMEDIATE_RELOAD);
559057516feSDmitry Osipenko     bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
560086ede32SPeter Maydell     bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
5615b262bb6SDmitry Osipenko 
5625b262bb6SDmitry Osipenko     triggered = false;
5635b262bb6SDmitry Osipenko 
564*91b37aeaSPeter Maydell     ptimer_transaction_begin(ptimer);
5655b262bb6SDmitry Osipenko     ptimer_set_period(ptimer, 2000000);
5665b262bb6SDmitry Osipenko     ptimer_set_limit(ptimer, 99, 0);
5675b262bb6SDmitry Osipenko     ptimer_run(ptimer, 1);
568*91b37aeaSPeter Maydell     ptimer_transaction_commit(ptimer);
56956700e1aSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==,
57056700e1aSDmitry Osipenko                      no_immediate_reload ? 0 : 99);
571516deb42SDmitry Osipenko 
572086ede32SPeter Maydell     if (no_immediate_trigger || trig_only_on_dec) {
573516deb42SDmitry Osipenko         g_assert_false(triggered);
574516deb42SDmitry Osipenko     } else {
5755b262bb6SDmitry Osipenko         g_assert_true(triggered);
576516deb42SDmitry Osipenko     }
5775b262bb6SDmitry Osipenko 
5785b262bb6SDmitry Osipenko     triggered = false;
5795b262bb6SDmitry Osipenko 
58056700e1aSDmitry Osipenko     if (no_immediate_trigger || no_immediate_reload) {
58133d44cdfSDmitry Osipenko         qemu_clock_step(2000000 + 1);
582516deb42SDmitry Osipenko 
58356700e1aSDmitry Osipenko         g_assert_cmpuint(ptimer_get_count(ptimer), ==,
584057516feSDmitry Osipenko                          no_immediate_reload ? 0 : (no_round_down ? 98 : 97));
58556700e1aSDmitry Osipenko 
58656700e1aSDmitry Osipenko         if (no_immediate_trigger && no_immediate_reload) {
58756700e1aSDmitry Osipenko             g_assert_true(triggered);
58856700e1aSDmitry Osipenko 
58956700e1aSDmitry Osipenko             triggered = false;
59056700e1aSDmitry Osipenko         } else {
591516deb42SDmitry Osipenko             g_assert_false(triggered);
59256700e1aSDmitry Osipenko         }
593516deb42SDmitry Osipenko 
594*91b37aeaSPeter Maydell         ptimer_transaction_begin(ptimer);
595516deb42SDmitry Osipenko         ptimer_set_count(ptimer, 99);
596516deb42SDmitry Osipenko         ptimer_run(ptimer, 1);
597*91b37aeaSPeter Maydell         ptimer_transaction_commit(ptimer);
598516deb42SDmitry Osipenko     }
599516deb42SDmitry Osipenko 
60033d44cdfSDmitry Osipenko     qemu_clock_step(2000000 + 1);
6015b262bb6SDmitry Osipenko 
602057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 98 : 97);
6035b262bb6SDmitry Osipenko     g_assert_false(triggered);
6045b262bb6SDmitry Osipenko 
6055b262bb6SDmitry Osipenko     qemu_clock_step(2000000 * 97);
6065b262bb6SDmitry Osipenko 
607057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
6085b262bb6SDmitry Osipenko     g_assert_false(triggered);
6095b262bb6SDmitry Osipenko 
6105b262bb6SDmitry Osipenko     qemu_clock_step(2000000 * 2);
6115b262bb6SDmitry Osipenko 
6125b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
6135b262bb6SDmitry Osipenko     g_assert_true(triggered);
6145b262bb6SDmitry Osipenko 
6155b262bb6SDmitry Osipenko     triggered = false;
6165b262bb6SDmitry Osipenko 
617*91b37aeaSPeter Maydell     ptimer_transaction_begin(ptimer);
6185b262bb6SDmitry Osipenko     ptimer_set_count(ptimer, 0);
6195b262bb6SDmitry Osipenko     ptimer_run(ptimer, 0);
620*91b37aeaSPeter Maydell     ptimer_transaction_commit(ptimer);
62156700e1aSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==,
62256700e1aSDmitry Osipenko                      no_immediate_reload ? 0 : 99);
623516deb42SDmitry Osipenko 
624086ede32SPeter Maydell     if (no_immediate_trigger || trig_only_on_dec) {
625516deb42SDmitry Osipenko         g_assert_false(triggered);
626516deb42SDmitry Osipenko     } else {
6275b262bb6SDmitry Osipenko         g_assert_true(triggered);
628516deb42SDmitry Osipenko     }
6295b262bb6SDmitry Osipenko 
6305b262bb6SDmitry Osipenko     triggered = false;
6315b262bb6SDmitry Osipenko 
63233d44cdfSDmitry Osipenko     qemu_clock_step(1);
633293130aaSDmitry Osipenko 
63456700e1aSDmitry Osipenko     if (no_immediate_reload) {
63556700e1aSDmitry Osipenko         qemu_clock_step(2000000);
63656700e1aSDmitry Osipenko     }
63756700e1aSDmitry Osipenko 
638057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 99 : 98);
63956700e1aSDmitry Osipenko 
64056700e1aSDmitry Osipenko     if (no_immediate_reload && no_immediate_trigger) {
64156700e1aSDmitry Osipenko         g_assert_true(triggered);
64256700e1aSDmitry Osipenko     } else {
643293130aaSDmitry Osipenko         g_assert_false(triggered);
64456700e1aSDmitry Osipenko     }
645293130aaSDmitry Osipenko 
646293130aaSDmitry Osipenko     triggered = false;
647293130aaSDmitry Osipenko 
648293130aaSDmitry Osipenko     qemu_clock_step(2000000);
6495b262bb6SDmitry Osipenko 
650057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 98 : 97);
6515b262bb6SDmitry Osipenko     g_assert_false(triggered);
6525b262bb6SDmitry Osipenko 
6535b262bb6SDmitry Osipenko     qemu_clock_step(2000000 * 98);
6545b262bb6SDmitry Osipenko 
655057516feSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==,
656057516feSDmitry Osipenko                     wrap_policy ? 0 : (no_round_down ? 99 : 98));
6575b262bb6SDmitry Osipenko     g_assert_true(triggered);
6585b262bb6SDmitry Osipenko 
659*91b37aeaSPeter Maydell     ptimer_transaction_begin(ptimer);
6605b262bb6SDmitry Osipenko     ptimer_stop(ptimer);
661*91b37aeaSPeter Maydell     ptimer_transaction_commit(ptimer);
662072bdb07SMarc-André Lureau     ptimer_free(ptimer);
6635b262bb6SDmitry Osipenko }
6645b262bb6SDmitry Osipenko 
6655b262bb6SDmitry Osipenko static void check_periodic_with_load_0(gconstpointer arg)
6665b262bb6SDmitry Osipenko {
6675b262bb6SDmitry Osipenko     const uint8_t *policy = arg;
668*91b37aeaSPeter Maydell     ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
6692e74583bSDmitry Osipenko     bool continuous_trigger = (*policy & PTIMER_POLICY_CONTINUOUS_TRIGGER);
670516deb42SDmitry Osipenko     bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
671086ede32SPeter Maydell     bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
6725b262bb6SDmitry Osipenko 
6735b262bb6SDmitry Osipenko     triggered = false;
6745b262bb6SDmitry Osipenko 
675*91b37aeaSPeter Maydell     ptimer_transaction_begin(ptimer);
6765b262bb6SDmitry Osipenko     ptimer_set_period(ptimer, 2000000);
6775b262bb6SDmitry Osipenko     ptimer_run(ptimer, 0);
678*91b37aeaSPeter Maydell     ptimer_transaction_commit(ptimer);
6795b262bb6SDmitry Osipenko 
6805b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
681516deb42SDmitry Osipenko 
682086ede32SPeter Maydell     if (no_immediate_trigger || trig_only_on_dec) {
683516deb42SDmitry Osipenko         g_assert_false(triggered);
684516deb42SDmitry Osipenko     } else {
6855b262bb6SDmitry Osipenko         g_assert_true(triggered);
686516deb42SDmitry Osipenko     }
6875b262bb6SDmitry Osipenko 
6885b262bb6SDmitry Osipenko     triggered = false;
6895b262bb6SDmitry Osipenko 
69033d44cdfSDmitry Osipenko     qemu_clock_step(2000000 + 1);
6915b262bb6SDmitry Osipenko 
6925b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
6932e74583bSDmitry Osipenko 
694516deb42SDmitry Osipenko     if (continuous_trigger || no_immediate_trigger) {
6952e74583bSDmitry Osipenko         g_assert_true(triggered);
6962e74583bSDmitry Osipenko     } else {
6975b262bb6SDmitry Osipenko         g_assert_false(triggered);
6982e74583bSDmitry Osipenko     }
6995b262bb6SDmitry Osipenko 
700293130aaSDmitry Osipenko     triggered = false;
701293130aaSDmitry Osipenko 
702*91b37aeaSPeter Maydell     ptimer_transaction_begin(ptimer);
703293130aaSDmitry Osipenko     ptimer_set_count(ptimer, 10);
704293130aaSDmitry Osipenko     ptimer_run(ptimer, 0);
705*91b37aeaSPeter Maydell     ptimer_transaction_commit(ptimer);
706293130aaSDmitry Osipenko 
70733d44cdfSDmitry Osipenko     qemu_clock_step(2000000 * 10 + 1);
708293130aaSDmitry Osipenko 
709293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
710293130aaSDmitry Osipenko     g_assert_true(triggered);
711293130aaSDmitry Osipenko 
712293130aaSDmitry Osipenko     triggered = false;
713293130aaSDmitry Osipenko 
71433d44cdfSDmitry Osipenko     qemu_clock_step(2000000 + 1);
715293130aaSDmitry Osipenko 
716293130aaSDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
7172e74583bSDmitry Osipenko 
7182e74583bSDmitry Osipenko     if (continuous_trigger) {
7192e74583bSDmitry Osipenko         g_assert_true(triggered);
7202e74583bSDmitry Osipenko     } else {
721293130aaSDmitry Osipenko         g_assert_false(triggered);
7222e74583bSDmitry Osipenko     }
723293130aaSDmitry Osipenko 
724*91b37aeaSPeter Maydell     ptimer_transaction_begin(ptimer);
7255b262bb6SDmitry Osipenko     ptimer_stop(ptimer);
726*91b37aeaSPeter Maydell     ptimer_transaction_commit(ptimer);
727072bdb07SMarc-André Lureau     ptimer_free(ptimer);
7285b262bb6SDmitry Osipenko }
7295b262bb6SDmitry Osipenko 
7305b262bb6SDmitry Osipenko static void check_oneshot_with_load_0(gconstpointer arg)
7315b262bb6SDmitry Osipenko {
7325b262bb6SDmitry Osipenko     const uint8_t *policy = arg;
733*91b37aeaSPeter Maydell     ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
734516deb42SDmitry Osipenko     bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
735086ede32SPeter Maydell     bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
7365b262bb6SDmitry Osipenko 
7375b262bb6SDmitry Osipenko     triggered = false;
7385b262bb6SDmitry Osipenko 
739*91b37aeaSPeter Maydell     ptimer_transaction_begin(ptimer);
7405b262bb6SDmitry Osipenko     ptimer_set_period(ptimer, 2000000);
7415b262bb6SDmitry Osipenko     ptimer_run(ptimer, 1);
742*91b37aeaSPeter Maydell     ptimer_transaction_commit(ptimer);
7435b262bb6SDmitry Osipenko 
7445b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
745516deb42SDmitry Osipenko 
746086ede32SPeter Maydell     if (no_immediate_trigger || trig_only_on_dec) {
747516deb42SDmitry Osipenko         g_assert_false(triggered);
748516deb42SDmitry Osipenko     } else {
7495b262bb6SDmitry Osipenko         g_assert_true(triggered);
750516deb42SDmitry Osipenko     }
7515b262bb6SDmitry Osipenko 
7525b262bb6SDmitry Osipenko     triggered = false;
7535b262bb6SDmitry Osipenko 
75433d44cdfSDmitry Osipenko     qemu_clock_step(2000000 + 1);
7555b262bb6SDmitry Osipenko 
7565b262bb6SDmitry Osipenko     g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
757516deb42SDmitry Osipenko 
758516deb42SDmitry Osipenko     if (no_immediate_trigger) {
759516deb42SDmitry Osipenko         g_assert_true(triggered);
760516deb42SDmitry Osipenko     } else {
7615b262bb6SDmitry Osipenko         g_assert_false(triggered);
7625b262bb6SDmitry Osipenko     }
763072bdb07SMarc-André Lureau 
764072bdb07SMarc-André Lureau     ptimer_free(ptimer);
765516deb42SDmitry Osipenko }
7665b262bb6SDmitry Osipenko 
7675b262bb6SDmitry Osipenko static void add_ptimer_tests(uint8_t policy)
7685b262bb6SDmitry Osipenko {
769072bdb07SMarc-André Lureau     char policy_name[256] = "";
770072bdb07SMarc-André Lureau     char *tmp;
7715b262bb6SDmitry Osipenko 
7725b262bb6SDmitry Osipenko     if (policy == PTIMER_POLICY_DEFAULT) {
7735b262bb6SDmitry Osipenko         g_sprintf(policy_name, "default");
7745b262bb6SDmitry Osipenko     }
7755b262bb6SDmitry Osipenko 
776293130aaSDmitry Osipenko     if (policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD) {
777293130aaSDmitry Osipenko         g_strlcat(policy_name, "wrap_after_one_period,", 256);
778293130aaSDmitry Osipenko     }
779293130aaSDmitry Osipenko 
7802e74583bSDmitry Osipenko     if (policy & PTIMER_POLICY_CONTINUOUS_TRIGGER) {
7812e74583bSDmitry Osipenko         g_strlcat(policy_name, "continuous_trigger,", 256);
7822e74583bSDmitry Osipenko     }
7832e74583bSDmitry Osipenko 
784516deb42SDmitry Osipenko     if (policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER) {
785516deb42SDmitry Osipenko         g_strlcat(policy_name, "no_immediate_trigger,", 256);
786516deb42SDmitry Osipenko     }
787516deb42SDmitry Osipenko 
78856700e1aSDmitry Osipenko     if (policy & PTIMER_POLICY_NO_IMMEDIATE_RELOAD) {
78956700e1aSDmitry Osipenko         g_strlcat(policy_name, "no_immediate_reload,", 256);
79056700e1aSDmitry Osipenko     }
79156700e1aSDmitry Osipenko 
792057516feSDmitry Osipenko     if (policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN) {
793057516feSDmitry Osipenko         g_strlcat(policy_name, "no_counter_rounddown,", 256);
794057516feSDmitry Osipenko     }
795057516feSDmitry Osipenko 
796086ede32SPeter Maydell     if (policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT) {
797086ede32SPeter Maydell         g_strlcat(policy_name, "trigger_only_on_decrement,", 256);
798086ede32SPeter Maydell     }
799086ede32SPeter Maydell 
800072bdb07SMarc-André Lureau     g_test_add_data_func_full(
801072bdb07SMarc-André Lureau         tmp = g_strdup_printf("/ptimer/set_count policy=%s", policy_name),
802072bdb07SMarc-André Lureau         g_memdup(&policy, 1), check_set_count, g_free);
803072bdb07SMarc-André Lureau     g_free(tmp);
8045b262bb6SDmitry Osipenko 
805072bdb07SMarc-André Lureau     g_test_add_data_func_full(
806072bdb07SMarc-André Lureau         tmp = g_strdup_printf("/ptimer/set_limit policy=%s", policy_name),
807072bdb07SMarc-André Lureau         g_memdup(&policy, 1), check_set_limit, g_free);
808072bdb07SMarc-André Lureau     g_free(tmp);
8095b262bb6SDmitry Osipenko 
810072bdb07SMarc-André Lureau     g_test_add_data_func_full(
811072bdb07SMarc-André Lureau         tmp = g_strdup_printf("/ptimer/oneshot policy=%s", policy_name),
812072bdb07SMarc-André Lureau         g_memdup(&policy, 1), check_oneshot, g_free);
813072bdb07SMarc-André Lureau     g_free(tmp);
8145b262bb6SDmitry Osipenko 
815072bdb07SMarc-André Lureau     g_test_add_data_func_full(
816072bdb07SMarc-André Lureau         tmp = g_strdup_printf("/ptimer/periodic policy=%s", policy_name),
817072bdb07SMarc-André Lureau         g_memdup(&policy, 1), check_periodic, g_free);
818072bdb07SMarc-André Lureau     g_free(tmp);
8195b262bb6SDmitry Osipenko 
820072bdb07SMarc-André Lureau     g_test_add_data_func_full(
821072bdb07SMarc-André Lureau         tmp = g_strdup_printf("/ptimer/on_the_fly_mode_change policy=%s",
822072bdb07SMarc-André Lureau                               policy_name),
823072bdb07SMarc-André Lureau         g_memdup(&policy, 1), check_on_the_fly_mode_change, g_free);
824072bdb07SMarc-André Lureau     g_free(tmp);
8255b262bb6SDmitry Osipenko 
826072bdb07SMarc-André Lureau     g_test_add_data_func_full(
827072bdb07SMarc-André Lureau         tmp = g_strdup_printf("/ptimer/on_the_fly_period_change policy=%s",
828072bdb07SMarc-André Lureau                               policy_name),
829072bdb07SMarc-André Lureau         g_memdup(&policy, 1), check_on_the_fly_period_change, g_free);
830072bdb07SMarc-André Lureau     g_free(tmp);
8315b262bb6SDmitry Osipenko 
832072bdb07SMarc-André Lureau     g_test_add_data_func_full(
833072bdb07SMarc-André Lureau         tmp = g_strdup_printf("/ptimer/on_the_fly_freq_change policy=%s",
834072bdb07SMarc-André Lureau                               policy_name),
835072bdb07SMarc-André Lureau         g_memdup(&policy, 1), check_on_the_fly_freq_change, g_free);
836072bdb07SMarc-André Lureau     g_free(tmp);
8375b262bb6SDmitry Osipenko 
838072bdb07SMarc-André Lureau     g_test_add_data_func_full(
839072bdb07SMarc-André Lureau         tmp = g_strdup_printf("/ptimer/run_with_period_0 policy=%s",
840072bdb07SMarc-André Lureau                               policy_name),
841072bdb07SMarc-André Lureau         g_memdup(&policy, 1), check_run_with_period_0, g_free);
842072bdb07SMarc-André Lureau     g_free(tmp);
8435b262bb6SDmitry Osipenko 
844072bdb07SMarc-André Lureau     g_test_add_data_func_full(
845072bdb07SMarc-André Lureau         tmp = g_strdup_printf("/ptimer/run_with_delta_0 policy=%s",
846072bdb07SMarc-André Lureau                               policy_name),
847072bdb07SMarc-André Lureau         g_memdup(&policy, 1), check_run_with_delta_0, g_free);
848072bdb07SMarc-André Lureau     g_free(tmp);
8495b262bb6SDmitry Osipenko 
850072bdb07SMarc-André Lureau     g_test_add_data_func_full(
851072bdb07SMarc-André Lureau         tmp = g_strdup_printf("/ptimer/periodic_with_load_0 policy=%s",
852072bdb07SMarc-André Lureau                               policy_name),
853072bdb07SMarc-André Lureau         g_memdup(&policy, 1), check_periodic_with_load_0, g_free);
854072bdb07SMarc-André Lureau     g_free(tmp);
8555b262bb6SDmitry Osipenko 
856072bdb07SMarc-André Lureau     g_test_add_data_func_full(
857072bdb07SMarc-André Lureau         tmp = g_strdup_printf("/ptimer/oneshot_with_load_0 policy=%s",
858072bdb07SMarc-André Lureau                               policy_name),
859072bdb07SMarc-André Lureau         g_memdup(&policy, 1), check_oneshot_with_load_0, g_free);
860072bdb07SMarc-André Lureau     g_free(tmp);
8615b262bb6SDmitry Osipenko }
8625b262bb6SDmitry Osipenko 
863293130aaSDmitry Osipenko static void add_all_ptimer_policies_comb_tests(void)
864293130aaSDmitry Osipenko {
865086ede32SPeter Maydell     int last_policy = PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT;
866293130aaSDmitry Osipenko     int policy = PTIMER_POLICY_DEFAULT;
867293130aaSDmitry Osipenko 
868293130aaSDmitry Osipenko     for (; policy < (last_policy << 1); policy++) {
869086ede32SPeter Maydell         if ((policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT) &&
870086ede32SPeter Maydell             (policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER)) {
871086ede32SPeter Maydell             /* Incompatible policy flag settings -- don't try to test them */
872086ede32SPeter Maydell             continue;
873086ede32SPeter Maydell         }
874293130aaSDmitry Osipenko         add_ptimer_tests(policy);
875293130aaSDmitry Osipenko     }
876293130aaSDmitry Osipenko }
877293130aaSDmitry Osipenko 
8785b262bb6SDmitry Osipenko int main(int argc, char **argv)
8795b262bb6SDmitry Osipenko {
8805b262bb6SDmitry Osipenko     int i;
8815b262bb6SDmitry Osipenko 
8825b262bb6SDmitry Osipenko     g_test_init(&argc, &argv, NULL);
8835b262bb6SDmitry Osipenko 
8845b262bb6SDmitry Osipenko     for (i = 0; i < QEMU_CLOCK_MAX; i++) {
8855b262bb6SDmitry Osipenko         main_loop_tlg.tl[i] = g_new0(QEMUTimerList, 1);
8865b262bb6SDmitry Osipenko     }
8875b262bb6SDmitry Osipenko 
888293130aaSDmitry Osipenko     add_all_ptimer_policies_comb_tests();
8895b262bb6SDmitry Osipenko 
8905b262bb6SDmitry Osipenko     qtest_allowed = true;
8915b262bb6SDmitry Osipenko 
8925b262bb6SDmitry Osipenko     return g_test_run();
8935b262bb6SDmitry Osipenko }
894