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 215b262bb6SDmitry Osipenko static void ptimer_trigger(void *opaque) 225b262bb6SDmitry Osipenko { 235b262bb6SDmitry Osipenko triggered = true; 245b262bb6SDmitry Osipenko } 255b262bb6SDmitry Osipenko 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 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 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 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 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 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 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 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 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 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 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 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 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 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 7665b262bb6SDmitry Osipenko static void add_ptimer_tests(uint8_t policy) 7675b262bb6SDmitry Osipenko { 768072bdb07SMarc-André Lureau char policy_name[256] = ""; 769072bdb07SMarc-André Lureau char *tmp; 7705b262bb6SDmitry Osipenko 7719598c1bbSPeter Maydell if (policy == PTIMER_POLICY_LEGACY) { 7729598c1bbSPeter Maydell g_sprintf(policy_name, "legacy"); 7735b262bb6SDmitry Osipenko } 7745b262bb6SDmitry Osipenko 775293130aaSDmitry Osipenko if (policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD) { 776293130aaSDmitry Osipenko g_strlcat(policy_name, "wrap_after_one_period,", 256); 777293130aaSDmitry Osipenko } 778293130aaSDmitry Osipenko 7792e74583bSDmitry Osipenko if (policy & PTIMER_POLICY_CONTINUOUS_TRIGGER) { 7802e74583bSDmitry Osipenko g_strlcat(policy_name, "continuous_trigger,", 256); 7812e74583bSDmitry Osipenko } 7822e74583bSDmitry Osipenko 783516deb42SDmitry Osipenko if (policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER) { 784516deb42SDmitry Osipenko g_strlcat(policy_name, "no_immediate_trigger,", 256); 785516deb42SDmitry Osipenko } 786516deb42SDmitry Osipenko 78756700e1aSDmitry Osipenko if (policy & PTIMER_POLICY_NO_IMMEDIATE_RELOAD) { 78856700e1aSDmitry Osipenko g_strlcat(policy_name, "no_immediate_reload,", 256); 78956700e1aSDmitry Osipenko } 79056700e1aSDmitry Osipenko 791057516feSDmitry Osipenko if (policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN) { 792057516feSDmitry Osipenko g_strlcat(policy_name, "no_counter_rounddown,", 256); 793057516feSDmitry Osipenko } 794057516feSDmitry Osipenko 795086ede32SPeter Maydell if (policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT) { 796086ede32SPeter Maydell g_strlcat(policy_name, "trigger_only_on_decrement,", 256); 797086ede32SPeter Maydell } 798086ede32SPeter Maydell 799072bdb07SMarc-André Lureau g_test_add_data_func_full( 800072bdb07SMarc-André Lureau tmp = g_strdup_printf("/ptimer/set_count policy=%s", policy_name), 801*c4f8ce24SPhilippe Mathieu-Daudé g_memdup2(&policy, 1), check_set_count, g_free); 802072bdb07SMarc-André Lureau g_free(tmp); 8035b262bb6SDmitry Osipenko 804072bdb07SMarc-André Lureau g_test_add_data_func_full( 805072bdb07SMarc-André Lureau tmp = g_strdup_printf("/ptimer/set_limit policy=%s", policy_name), 806*c4f8ce24SPhilippe Mathieu-Daudé g_memdup2(&policy, 1), check_set_limit, g_free); 807072bdb07SMarc-André Lureau g_free(tmp); 8085b262bb6SDmitry Osipenko 809072bdb07SMarc-André Lureau g_test_add_data_func_full( 810072bdb07SMarc-André Lureau tmp = g_strdup_printf("/ptimer/oneshot policy=%s", policy_name), 811*c4f8ce24SPhilippe Mathieu-Daudé g_memdup2(&policy, 1), check_oneshot, g_free); 812072bdb07SMarc-André Lureau g_free(tmp); 8135b262bb6SDmitry Osipenko 814072bdb07SMarc-André Lureau g_test_add_data_func_full( 815072bdb07SMarc-André Lureau tmp = g_strdup_printf("/ptimer/periodic policy=%s", policy_name), 816*c4f8ce24SPhilippe Mathieu-Daudé g_memdup2(&policy, 1), check_periodic, g_free); 817072bdb07SMarc-André Lureau g_free(tmp); 8185b262bb6SDmitry Osipenko 819072bdb07SMarc-André Lureau g_test_add_data_func_full( 820072bdb07SMarc-André Lureau tmp = g_strdup_printf("/ptimer/on_the_fly_mode_change policy=%s", 821072bdb07SMarc-André Lureau policy_name), 822*c4f8ce24SPhilippe Mathieu-Daudé g_memdup2(&policy, 1), check_on_the_fly_mode_change, g_free); 823072bdb07SMarc-André Lureau g_free(tmp); 8245b262bb6SDmitry Osipenko 825072bdb07SMarc-André Lureau g_test_add_data_func_full( 826072bdb07SMarc-André Lureau tmp = g_strdup_printf("/ptimer/on_the_fly_period_change policy=%s", 827072bdb07SMarc-André Lureau policy_name), 828*c4f8ce24SPhilippe Mathieu-Daudé g_memdup2(&policy, 1), check_on_the_fly_period_change, 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/on_the_fly_freq_change policy=%s", 833072bdb07SMarc-André Lureau policy_name), 834*c4f8ce24SPhilippe Mathieu-Daudé g_memdup2(&policy, 1), check_on_the_fly_freq_change, g_free); 835072bdb07SMarc-André Lureau g_free(tmp); 8365b262bb6SDmitry Osipenko 837072bdb07SMarc-André Lureau g_test_add_data_func_full( 838072bdb07SMarc-André Lureau tmp = g_strdup_printf("/ptimer/run_with_period_0 policy=%s", 839072bdb07SMarc-André Lureau policy_name), 840*c4f8ce24SPhilippe Mathieu-Daudé g_memdup2(&policy, 1), check_run_with_period_0, g_free); 841072bdb07SMarc-André Lureau g_free(tmp); 8425b262bb6SDmitry Osipenko 843072bdb07SMarc-André Lureau g_test_add_data_func_full( 844072bdb07SMarc-André Lureau tmp = g_strdup_printf("/ptimer/run_with_delta_0 policy=%s", 845072bdb07SMarc-André Lureau policy_name), 846*c4f8ce24SPhilippe Mathieu-Daudé g_memdup2(&policy, 1), check_run_with_delta_0, g_free); 847072bdb07SMarc-André Lureau g_free(tmp); 8485b262bb6SDmitry Osipenko 849072bdb07SMarc-André Lureau g_test_add_data_func_full( 850072bdb07SMarc-André Lureau tmp = g_strdup_printf("/ptimer/periodic_with_load_0 policy=%s", 851072bdb07SMarc-André Lureau policy_name), 852*c4f8ce24SPhilippe Mathieu-Daudé g_memdup2(&policy, 1), check_periodic_with_load_0, g_free); 853072bdb07SMarc-André Lureau g_free(tmp); 8545b262bb6SDmitry Osipenko 855072bdb07SMarc-André Lureau g_test_add_data_func_full( 856072bdb07SMarc-André Lureau tmp = g_strdup_printf("/ptimer/oneshot_with_load_0 policy=%s", 857072bdb07SMarc-André Lureau policy_name), 858*c4f8ce24SPhilippe Mathieu-Daudé g_memdup2(&policy, 1), check_oneshot_with_load_0, g_free); 859072bdb07SMarc-André Lureau g_free(tmp); 8605b262bb6SDmitry Osipenko } 8615b262bb6SDmitry Osipenko 862293130aaSDmitry Osipenko static void add_all_ptimer_policies_comb_tests(void) 863293130aaSDmitry Osipenko { 864086ede32SPeter Maydell int last_policy = PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT; 8659598c1bbSPeter Maydell int policy = PTIMER_POLICY_LEGACY; 866293130aaSDmitry Osipenko 867293130aaSDmitry Osipenko for (; policy < (last_policy << 1); policy++) { 868086ede32SPeter Maydell if ((policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT) && 869086ede32SPeter Maydell (policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER)) { 870086ede32SPeter Maydell /* Incompatible policy flag settings -- don't try to test them */ 871086ede32SPeter Maydell continue; 872086ede32SPeter Maydell } 873293130aaSDmitry Osipenko add_ptimer_tests(policy); 874293130aaSDmitry Osipenko } 875293130aaSDmitry Osipenko } 876293130aaSDmitry Osipenko 8775b262bb6SDmitry Osipenko int main(int argc, char **argv) 8785b262bb6SDmitry Osipenko { 8795b262bb6SDmitry Osipenko int i; 8805b262bb6SDmitry Osipenko 8815b262bb6SDmitry Osipenko g_test_init(&argc, &argv, NULL); 8825b262bb6SDmitry Osipenko 8835b262bb6SDmitry Osipenko for (i = 0; i < QEMU_CLOCK_MAX; i++) { 8845b262bb6SDmitry Osipenko main_loop_tlg.tl[i] = g_new0(QEMUTimerList, 1); 8855b262bb6SDmitry Osipenko } 8865b262bb6SDmitry Osipenko 887293130aaSDmitry Osipenko add_all_ptimer_policies_comb_tests(); 8885b262bb6SDmitry Osipenko 8895b262bb6SDmitry Osipenko qtest_allowed = true; 8905b262bb6SDmitry Osipenko 8915b262bb6SDmitry Osipenko return g_test_run(); 8925b262bb6SDmitry Osipenko } 893