blob: 04b5f4e3d03148010748956bf894c4db3cb55b0f [file] [log] [blame]
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +01001/*
2 * QTest testcase for the ptimer
3 *
Dmitry Osipenko673c7e82016-10-24 16:26:53 +01004 * Copyright (c) 2016 Dmitry Osipenko <digetx@gmail.com>
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +01005 *
6 * This work is licensed under the terms of the GNU GPL, version 2 or later.
7 * See the COPYING file in the top-level directory.
8 *
9 */
10
Markus Armbruster8f0a3712018-02-01 12:18:29 +010011#include "qemu/osdep.h"
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +010012#include <glib/gprintf.h>
13
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +010014#include "qemu/main-loop.h"
15#include "hw/ptimer.h"
16
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +010017#include "ptimer-test.h"
18
19static bool triggered;
20
21static void ptimer_trigger(void *opaque)
22{
23 triggered = true;
24}
25
26static void ptimer_test_expire_qemu_timers(int64_t expire_time,
27 QEMUClockType type)
28{
29 QEMUTimerList *timer_list = main_loop_tlg.tl[type];
30 QEMUTimer *t = timer_list->active_timers.next;
31
32 while (t != NULL) {
33 if (t->expire_time == expire_time) {
34 timer_del(t);
35
36 if (t->cb != NULL) {
37 t->cb(t->opaque);
38 }
39 }
40
41 t = t->next;
42 }
43}
44
45static void ptimer_test_set_qemu_time_ns(int64_t ns)
46{
47 ptimer_test_time_ns = ns;
48}
49
50static void qemu_clock_step(uint64_t ns)
51{
Pavel Dovgalyukdcb15782019-07-25 11:44:26 +030052 int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
53 QEMU_TIMER_ATTR_ALL);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +010054 int64_t advanced_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ns;
55
56 while (deadline != -1 && deadline <= advanced_time) {
57 ptimer_test_set_qemu_time_ns(deadline);
58 ptimer_test_expire_qemu_timers(deadline, QEMU_CLOCK_VIRTUAL);
Pavel Dovgalyukdcb15782019-07-25 11:44:26 +030059 deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
60 QEMU_TIMER_ATTR_ALL);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +010061 }
62
63 ptimer_test_set_qemu_time_ns(advanced_time);
64}
65
66static void check_set_count(gconstpointer arg)
67{
68 const uint8_t *policy = arg;
Peter Maydell91b37ae2019-10-08 18:17:22 +010069 ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +010070
71 triggered = false;
72
Peter Maydell91b37ae2019-10-08 18:17:22 +010073 ptimer_transaction_begin(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +010074 ptimer_set_count(ptimer, 1000);
Peter Maydell91b37ae2019-10-08 18:17:22 +010075 ptimer_transaction_commit(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +010076 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 1000);
77 g_assert_false(triggered);
Marc-André Lureau072bdb02017-01-27 12:55:51 +040078 ptimer_free(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +010079}
80
81static void check_set_limit(gconstpointer arg)
82{
83 const uint8_t *policy = arg;
Peter Maydell91b37ae2019-10-08 18:17:22 +010084 ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +010085
86 triggered = false;
87
Peter Maydell91b37ae2019-10-08 18:17:22 +010088 ptimer_transaction_begin(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +010089 ptimer_set_limit(ptimer, 1000, 0);
Peter Maydell91b37ae2019-10-08 18:17:22 +010090 ptimer_transaction_commit(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +010091 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
92 g_assert_cmpuint(ptimer_get_limit(ptimer), ==, 1000);
93 g_assert_false(triggered);
94
Peter Maydell91b37ae2019-10-08 18:17:22 +010095 ptimer_transaction_begin(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +010096 ptimer_set_limit(ptimer, 2000, 1);
Peter Maydell91b37ae2019-10-08 18:17:22 +010097 ptimer_transaction_commit(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +010098 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 2000);
99 g_assert_cmpuint(ptimer_get_limit(ptimer), ==, 2000);
100 g_assert_false(triggered);
Marc-André Lureau072bdb02017-01-27 12:55:51 +0400101 ptimer_free(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100102}
103
104static void check_oneshot(gconstpointer arg)
105{
106 const uint8_t *policy = arg;
Peter Maydell91b37ae2019-10-08 18:17:22 +0100107 ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100108 bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100109
110 triggered = false;
111
Peter Maydell91b37ae2019-10-08 18:17:22 +0100112 ptimer_transaction_begin(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100113 ptimer_set_period(ptimer, 2000000);
114 ptimer_set_count(ptimer, 10);
115 ptimer_run(ptimer, 1);
Peter Maydell91b37ae2019-10-08 18:17:22 +0100116 ptimer_transaction_commit(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100117
Dmitry Osipenko33d44cd2016-10-24 16:26:53 +0100118 qemu_clock_step(2000000 * 2 + 1);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100119
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100120 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100121 g_assert_false(triggered);
122
Peter Maydell91b37ae2019-10-08 18:17:22 +0100123 ptimer_transaction_begin(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100124 ptimer_stop(ptimer);
Peter Maydell91b37ae2019-10-08 18:17:22 +0100125 ptimer_transaction_commit(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100126
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100127 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100128 g_assert_false(triggered);
129
130 qemu_clock_step(2000000 * 11);
131
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100132 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100133 g_assert_false(triggered);
134
Peter Maydell91b37ae2019-10-08 18:17:22 +0100135 ptimer_transaction_begin(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100136 ptimer_run(ptimer, 1);
Peter Maydell91b37ae2019-10-08 18:17:22 +0100137 ptimer_transaction_commit(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100138
Dmitry Osipenko33d44cd2016-10-24 16:26:53 +0100139 qemu_clock_step(2000000 * 7 + 1);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100140
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100141 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100142
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100143 if (no_round_down) {
144 g_assert_false(triggered);
145 } else {
146 g_assert_true(triggered);
147
148 triggered = false;
149 }
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100150
151 qemu_clock_step(2000000);
152
153 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100154
155 if (no_round_down) {
156 g_assert_true(triggered);
157
158 triggered = false;
159 } else {
160 g_assert_false(triggered);
161 }
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100162
163 qemu_clock_step(4000000);
164
165 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
166 g_assert_false(triggered);
167
Peter Maydell91b37ae2019-10-08 18:17:22 +0100168 ptimer_transaction_begin(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100169 ptimer_set_count(ptimer, 10);
Peter Maydell91b37ae2019-10-08 18:17:22 +0100170 ptimer_transaction_commit(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100171
Dmitry Osipenko33d44cd2016-10-24 16:26:53 +0100172 qemu_clock_step(20000000 + 1);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100173
174 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 10);
175 g_assert_false(triggered);
176
Peter Maydell91b37ae2019-10-08 18:17:22 +0100177 ptimer_transaction_begin(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100178 ptimer_set_limit(ptimer, 9, 1);
Peter Maydell91b37ae2019-10-08 18:17:22 +0100179 ptimer_transaction_commit(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100180
Dmitry Osipenko33d44cd2016-10-24 16:26:53 +0100181 qemu_clock_step(20000000 + 1);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100182
183 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 9);
184 g_assert_false(triggered);
185
Peter Maydell91b37ae2019-10-08 18:17:22 +0100186 ptimer_transaction_begin(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100187 ptimer_run(ptimer, 1);
Peter Maydell91b37ae2019-10-08 18:17:22 +0100188 ptimer_transaction_commit(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100189
Dmitry Osipenko33d44cd2016-10-24 16:26:53 +0100190 qemu_clock_step(2000000 + 1);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100191
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100192 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100193 g_assert_false(triggered);
194
Peter Maydell91b37ae2019-10-08 18:17:22 +0100195 ptimer_transaction_begin(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100196 ptimer_set_count(ptimer, 20);
Peter Maydell91b37ae2019-10-08 18:17:22 +0100197 ptimer_transaction_commit(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100198
Dmitry Osipenko33d44cd2016-10-24 16:26:53 +0100199 qemu_clock_step(2000000 * 19 + 1);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100200
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100201 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100202 g_assert_false(triggered);
203
204 qemu_clock_step(2000000);
205
206 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
207 g_assert_true(triggered);
208
Peter Maydell91b37ae2019-10-08 18:17:22 +0100209 ptimer_transaction_begin(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100210 ptimer_stop(ptimer);
Peter Maydell91b37ae2019-10-08 18:17:22 +0100211 ptimer_transaction_commit(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100212
213 triggered = false;
214
Dmitry Osipenko33d44cd2016-10-24 16:26:53 +0100215 qemu_clock_step(2000000 * 12 + 1);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100216
217 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
218 g_assert_false(triggered);
Marc-André Lureau072bdb02017-01-27 12:55:51 +0400219 ptimer_free(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100220}
221
222static void check_periodic(gconstpointer arg)
223{
224 const uint8_t *policy = arg;
Peter Maydell91b37ae2019-10-08 18:17:22 +0100225 ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
Dmitry Osipenko293130a2016-10-24 16:26:51 +0100226 bool wrap_policy = (*policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD);
Dmitry Osipenko516deb42016-10-24 16:26:52 +0100227 bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
Dmitry Osipenko56700e12016-10-24 16:26:52 +0100228 bool no_immediate_reload = (*policy & PTIMER_POLICY_NO_IMMEDIATE_RELOAD);
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100229 bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
Peter Maydell086ede32018-07-09 14:51:34 +0100230 bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100231
232 triggered = false;
233
Peter Maydell91b37ae2019-10-08 18:17:22 +0100234 ptimer_transaction_begin(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100235 ptimer_set_period(ptimer, 2000000);
236 ptimer_set_limit(ptimer, 10, 1);
237 ptimer_run(ptimer, 0);
Peter Maydell91b37ae2019-10-08 18:17:22 +0100238 ptimer_transaction_commit(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100239
Dmitry Osipenko293130a2016-10-24 16:26:51 +0100240 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 10);
241 g_assert_false(triggered);
242
Dmitry Osipenko33d44cd2016-10-24 16:26:53 +0100243 qemu_clock_step(1);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100244
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100245 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 10 : 9);
Dmitry Osipenko293130a2016-10-24 16:26:51 +0100246 g_assert_false(triggered);
247
Dmitry Osipenko33d44cd2016-10-24 16:26:53 +0100248 qemu_clock_step(2000000 * 10 - 1);
Dmitry Osipenko293130a2016-10-24 16:26:51 +0100249
250 g_assert_cmpuint(ptimer_get_count(ptimer), ==, wrap_policy ? 0 : 10);
251 g_assert_true(triggered);
252
Dmitry Osipenko33d44cd2016-10-24 16:26:53 +0100253 qemu_clock_step(1);
Dmitry Osipenko293130a2016-10-24 16:26:51 +0100254
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100255 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
256 wrap_policy ? 0 : (no_round_down ? 10 : 9));
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100257 g_assert_true(triggered);
258
259 triggered = false;
260
261 qemu_clock_step(2000000);
262
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100263 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
264 (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100265 g_assert_false(triggered);
266
Peter Maydell91b37ae2019-10-08 18:17:22 +0100267 ptimer_transaction_begin(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100268 ptimer_set_count(ptimer, 20);
Peter Maydell91b37ae2019-10-08 18:17:22 +0100269 ptimer_transaction_commit(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100270
Dmitry Osipenko293130a2016-10-24 16:26:51 +0100271 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 20);
272 g_assert_false(triggered);
273
Dmitry Osipenko33d44cd2016-10-24 16:26:53 +0100274 qemu_clock_step(1);
Dmitry Osipenko293130a2016-10-24 16:26:51 +0100275
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100276 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 20 : 19);
Dmitry Osipenko293130a2016-10-24 16:26:51 +0100277 g_assert_false(triggered);
278
Dmitry Osipenko33d44cd2016-10-24 16:26:53 +0100279 qemu_clock_step(2000000 * 11 + 1);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100280
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100281 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 9 : 8);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100282 g_assert_false(triggered);
283
284 qemu_clock_step(2000000 * 10);
285
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100286 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
287 (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
Dmitry Osipenko293130a2016-10-24 16:26:51 +0100288 g_assert_true(triggered);
289
290 triggered = false;
291
Peter Maydell91b37ae2019-10-08 18:17:22 +0100292 ptimer_transaction_begin(ptimer);
Dmitry Osipenko293130a2016-10-24 16:26:51 +0100293 ptimer_set_count(ptimer, 3);
Peter Maydell91b37ae2019-10-08 18:17:22 +0100294 ptimer_transaction_commit(ptimer);
Dmitry Osipenko293130a2016-10-24 16:26:51 +0100295
296 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 3);
297 g_assert_false(triggered);
298
Dmitry Osipenko33d44cd2016-10-24 16:26:53 +0100299 qemu_clock_step(1);
Dmitry Osipenko293130a2016-10-24 16:26:51 +0100300
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100301 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 3 : 2);
Dmitry Osipenko293130a2016-10-24 16:26:51 +0100302 g_assert_false(triggered);
303
304 qemu_clock_step(2000000 * 4);
305
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100306 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
307 (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100308 g_assert_true(triggered);
309
Peter Maydell91b37ae2019-10-08 18:17:22 +0100310 ptimer_transaction_begin(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100311 ptimer_stop(ptimer);
Peter Maydell91b37ae2019-10-08 18:17:22 +0100312 ptimer_transaction_commit(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100313 triggered = false;
314
315 qemu_clock_step(2000000);
316
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100317 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
318 (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100319 g_assert_false(triggered);
320
Peter Maydell91b37ae2019-10-08 18:17:22 +0100321 ptimer_transaction_begin(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100322 ptimer_set_count(ptimer, 3);
323 ptimer_run(ptimer, 0);
Peter Maydell91b37ae2019-10-08 18:17:22 +0100324 ptimer_transaction_commit(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100325
Dmitry Osipenko33d44cd2016-10-24 16:26:53 +0100326 qemu_clock_step(2000000 * 3 + 1);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100327
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100328 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
329 wrap_policy ? 0 : (no_round_down ? 10 : 9));
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100330 g_assert_true(triggered);
331
332 triggered = false;
333
334 qemu_clock_step(2000000);
335
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100336 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
337 (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100338 g_assert_false(triggered);
339
Peter Maydell91b37ae2019-10-08 18:17:22 +0100340 ptimer_transaction_begin(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100341 ptimer_set_count(ptimer, 0);
Peter Maydell91b37ae2019-10-08 18:17:22 +0100342 ptimer_transaction_commit(ptimer);
Dmitry Osipenko56700e12016-10-24 16:26:52 +0100343 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
344 no_immediate_reload ? 0 : 10);
Dmitry Osipenko516deb42016-10-24 16:26:52 +0100345
Peter Maydell086ede32018-07-09 14:51:34 +0100346 if (no_immediate_trigger || trig_only_on_dec) {
Dmitry Osipenko516deb42016-10-24 16:26:52 +0100347 g_assert_false(triggered);
348 } else {
349 g_assert_true(triggered);
350 }
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100351
352 triggered = false;
353
Dmitry Osipenko33d44cd2016-10-24 16:26:53 +0100354 qemu_clock_step(1);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100355
Dmitry Osipenko56700e12016-10-24 16:26:52 +0100356 if (no_immediate_reload) {
357 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
358 g_assert_false(triggered);
359
360 qemu_clock_step(2000000);
361
362 if (no_immediate_trigger) {
363 g_assert_true(triggered);
364 } else {
365 g_assert_false(triggered);
366 }
367
368 triggered = false;
369 }
370
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100371 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 10 : 9);
Dmitry Osipenko293130a2016-10-24 16:26:51 +0100372 g_assert_false(triggered);
373
374 qemu_clock_step(2000000 * 12);
375
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100376 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
377 (no_round_down ? 8 : 7) + (wrap_policy ? 1 : 0));
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100378 g_assert_true(triggered);
379
Peter Maydell91b37ae2019-10-08 18:17:22 +0100380 ptimer_transaction_begin(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100381 ptimer_stop(ptimer);
Peter Maydell91b37ae2019-10-08 18:17:22 +0100382 ptimer_transaction_commit(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100383
384 triggered = false;
385
Dmitry Osipenko293130a2016-10-24 16:26:51 +0100386 qemu_clock_step(2000000 * 10);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100387
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100388 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
389 (no_round_down ? 8 : 7) + (wrap_policy ? 1 : 0));
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100390 g_assert_false(triggered);
391
Peter Maydell91b37ae2019-10-08 18:17:22 +0100392 ptimer_transaction_begin(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100393 ptimer_run(ptimer, 0);
Peter Maydell91b37ae2019-10-08 18:17:22 +0100394 ptimer_transaction_commit(ptimer);
395
396 ptimer_transaction_begin(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100397 ptimer_set_period(ptimer, 0);
Peter Maydell91b37ae2019-10-08 18:17:22 +0100398 ptimer_transaction_commit(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100399
Dmitry Osipenko33d44cd2016-10-24 16:26:53 +0100400 qemu_clock_step(2000000 + 1);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100401
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100402 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
403 (no_round_down ? 8 : 7) + (wrap_policy ? 1 : 0));
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100404 g_assert_false(triggered);
Marc-André Lureau072bdb02017-01-27 12:55:51 +0400405 ptimer_free(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100406}
407
408static void check_on_the_fly_mode_change(gconstpointer arg)
409{
410 const uint8_t *policy = arg;
Peter Maydell91b37ae2019-10-08 18:17:22 +0100411 ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
Dmitry Osipenko293130a2016-10-24 16:26:51 +0100412 bool wrap_policy = (*policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD);
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100413 bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100414
415 triggered = false;
416
Peter Maydell91b37ae2019-10-08 18:17:22 +0100417 ptimer_transaction_begin(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100418 ptimer_set_period(ptimer, 2000000);
419 ptimer_set_limit(ptimer, 10, 1);
420 ptimer_run(ptimer, 1);
Peter Maydell91b37ae2019-10-08 18:17:22 +0100421 ptimer_transaction_commit(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100422
Dmitry Osipenko33d44cd2016-10-24 16:26:53 +0100423 qemu_clock_step(2000000 * 9 + 1);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100424
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100425 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
Dmitry Osipenko293130a2016-10-24 16:26:51 +0100426 g_assert_false(triggered);
427
Peter Maydell91b37ae2019-10-08 18:17:22 +0100428 ptimer_transaction_begin(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100429 ptimer_run(ptimer, 0);
Peter Maydell91b37ae2019-10-08 18:17:22 +0100430 ptimer_transaction_commit(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100431
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100432 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100433 g_assert_false(triggered);
434
435 qemu_clock_step(2000000);
436
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100437 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
438 wrap_policy ? 0 : (no_round_down ? 10 : 9));
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100439 g_assert_true(triggered);
440
441 triggered = false;
442
443 qemu_clock_step(2000000 * 9);
444
Peter Maydell91b37ae2019-10-08 18:17:22 +0100445 ptimer_transaction_begin(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100446 ptimer_run(ptimer, 1);
Peter Maydell91b37ae2019-10-08 18:17:22 +0100447 ptimer_transaction_commit(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100448
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100449 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
450 (no_round_down ? 1 : 0) + (wrap_policy ? 1 : 0));
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100451 g_assert_false(triggered);
452
453 qemu_clock_step(2000000 * 3);
454
455 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
456 g_assert_true(triggered);
Marc-André Lureau072bdb02017-01-27 12:55:51 +0400457 ptimer_free(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100458}
459
460static void check_on_the_fly_period_change(gconstpointer arg)
461{
462 const uint8_t *policy = arg;
Peter Maydell91b37ae2019-10-08 18:17:22 +0100463 ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100464 bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100465
466 triggered = false;
467
Peter Maydell91b37ae2019-10-08 18:17:22 +0100468 ptimer_transaction_begin(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100469 ptimer_set_period(ptimer, 2000000);
470 ptimer_set_limit(ptimer, 8, 1);
471 ptimer_run(ptimer, 1);
Peter Maydell91b37ae2019-10-08 18:17:22 +0100472 ptimer_transaction_commit(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100473
Dmitry Osipenko33d44cd2016-10-24 16:26:53 +0100474 qemu_clock_step(2000000 * 4 + 1);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100475
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100476 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100477 g_assert_false(triggered);
478
Peter Maydell91b37ae2019-10-08 18:17:22 +0100479 ptimer_transaction_begin(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100480 ptimer_set_period(ptimer, 4000000);
Peter Maydell91b37ae2019-10-08 18:17:22 +0100481 ptimer_transaction_commit(ptimer);
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100482 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100483
Dmitry Osipenko33d44cd2016-10-24 16:26:53 +0100484 qemu_clock_step(4000000 * 2 + 1);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100485
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100486 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 2 : 0);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100487 g_assert_false(triggered);
488
489 qemu_clock_step(4000000 * 2);
490
491 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
492 g_assert_true(triggered);
Marc-André Lureau072bdb02017-01-27 12:55:51 +0400493 ptimer_free(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100494}
495
496static void check_on_the_fly_freq_change(gconstpointer arg)
497{
498 const uint8_t *policy = arg;
Peter Maydell91b37ae2019-10-08 18:17:22 +0100499 ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100500 bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100501
502 triggered = false;
503
Peter Maydell91b37ae2019-10-08 18:17:22 +0100504 ptimer_transaction_begin(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100505 ptimer_set_freq(ptimer, 500);
506 ptimer_set_limit(ptimer, 8, 1);
507 ptimer_run(ptimer, 1);
Peter Maydell91b37ae2019-10-08 18:17:22 +0100508 ptimer_transaction_commit(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100509
Dmitry Osipenko33d44cd2016-10-24 16:26:53 +0100510 qemu_clock_step(2000000 * 4 + 1);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100511
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100512 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100513 g_assert_false(triggered);
514
Peter Maydell91b37ae2019-10-08 18:17:22 +0100515 ptimer_transaction_begin(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100516 ptimer_set_freq(ptimer, 250);
Peter Maydell91b37ae2019-10-08 18:17:22 +0100517 ptimer_transaction_commit(ptimer);
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100518 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100519
Dmitry Osipenko33d44cd2016-10-24 16:26:53 +0100520 qemu_clock_step(2000000 * 4 + 1);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100521
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100522 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 2 : 0);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100523 g_assert_false(triggered);
524
525 qemu_clock_step(2000000 * 4);
526
527 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
528 g_assert_true(triggered);
Marc-André Lureau072bdb02017-01-27 12:55:51 +0400529 ptimer_free(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100530}
531
532static void check_run_with_period_0(gconstpointer arg)
533{
534 const uint8_t *policy = arg;
Peter Maydell91b37ae2019-10-08 18:17:22 +0100535 ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100536
537 triggered = false;
538
Peter Maydell91b37ae2019-10-08 18:17:22 +0100539 ptimer_transaction_begin(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100540 ptimer_set_count(ptimer, 99);
541 ptimer_run(ptimer, 1);
Peter Maydell91b37ae2019-10-08 18:17:22 +0100542 ptimer_transaction_commit(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100543
544 qemu_clock_step(10 * NANOSECONDS_PER_SECOND);
545
546 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 99);
547 g_assert_false(triggered);
Marc-André Lureau072bdb02017-01-27 12:55:51 +0400548 ptimer_free(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100549}
550
551static void check_run_with_delta_0(gconstpointer arg)
552{
553 const uint8_t *policy = arg;
Peter Maydell91b37ae2019-10-08 18:17:22 +0100554 ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
Dmitry Osipenko293130a2016-10-24 16:26:51 +0100555 bool wrap_policy = (*policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD);
Dmitry Osipenko516deb42016-10-24 16:26:52 +0100556 bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
Dmitry Osipenko56700e12016-10-24 16:26:52 +0100557 bool no_immediate_reload = (*policy & PTIMER_POLICY_NO_IMMEDIATE_RELOAD);
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100558 bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
Peter Maydell086ede32018-07-09 14:51:34 +0100559 bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100560
561 triggered = false;
562
Peter Maydell91b37ae2019-10-08 18:17:22 +0100563 ptimer_transaction_begin(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100564 ptimer_set_period(ptimer, 2000000);
565 ptimer_set_limit(ptimer, 99, 0);
566 ptimer_run(ptimer, 1);
Peter Maydell91b37ae2019-10-08 18:17:22 +0100567 ptimer_transaction_commit(ptimer);
Dmitry Osipenko56700e12016-10-24 16:26:52 +0100568 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
569 no_immediate_reload ? 0 : 99);
Dmitry Osipenko516deb42016-10-24 16:26:52 +0100570
Peter Maydell086ede32018-07-09 14:51:34 +0100571 if (no_immediate_trigger || trig_only_on_dec) {
Dmitry Osipenko516deb42016-10-24 16:26:52 +0100572 g_assert_false(triggered);
573 } else {
574 g_assert_true(triggered);
575 }
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100576
577 triggered = false;
578
Dmitry Osipenko56700e12016-10-24 16:26:52 +0100579 if (no_immediate_trigger || no_immediate_reload) {
Dmitry Osipenko33d44cd2016-10-24 16:26:53 +0100580 qemu_clock_step(2000000 + 1);
Dmitry Osipenko516deb42016-10-24 16:26:52 +0100581
Dmitry Osipenko56700e12016-10-24 16:26:52 +0100582 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100583 no_immediate_reload ? 0 : (no_round_down ? 98 : 97));
Dmitry Osipenko56700e12016-10-24 16:26:52 +0100584
585 if (no_immediate_trigger && no_immediate_reload) {
586 g_assert_true(triggered);
587
588 triggered = false;
589 } else {
590 g_assert_false(triggered);
591 }
Dmitry Osipenko516deb42016-10-24 16:26:52 +0100592
Peter Maydell91b37ae2019-10-08 18:17:22 +0100593 ptimer_transaction_begin(ptimer);
Dmitry Osipenko516deb42016-10-24 16:26:52 +0100594 ptimer_set_count(ptimer, 99);
595 ptimer_run(ptimer, 1);
Peter Maydell91b37ae2019-10-08 18:17:22 +0100596 ptimer_transaction_commit(ptimer);
Dmitry Osipenko516deb42016-10-24 16:26:52 +0100597 }
598
Dmitry Osipenko33d44cd2016-10-24 16:26:53 +0100599 qemu_clock_step(2000000 + 1);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100600
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100601 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 98 : 97);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100602 g_assert_false(triggered);
603
604 qemu_clock_step(2000000 * 97);
605
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100606 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100607 g_assert_false(triggered);
608
609 qemu_clock_step(2000000 * 2);
610
611 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
612 g_assert_true(triggered);
613
614 triggered = false;
615
Peter Maydell91b37ae2019-10-08 18:17:22 +0100616 ptimer_transaction_begin(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100617 ptimer_set_count(ptimer, 0);
618 ptimer_run(ptimer, 0);
Peter Maydell91b37ae2019-10-08 18:17:22 +0100619 ptimer_transaction_commit(ptimer);
Dmitry Osipenko56700e12016-10-24 16:26:52 +0100620 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
621 no_immediate_reload ? 0 : 99);
Dmitry Osipenko516deb42016-10-24 16:26:52 +0100622
Peter Maydell086ede32018-07-09 14:51:34 +0100623 if (no_immediate_trigger || trig_only_on_dec) {
Dmitry Osipenko516deb42016-10-24 16:26:52 +0100624 g_assert_false(triggered);
625 } else {
626 g_assert_true(triggered);
627 }
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100628
629 triggered = false;
630
Dmitry Osipenko33d44cd2016-10-24 16:26:53 +0100631 qemu_clock_step(1);
Dmitry Osipenko293130a2016-10-24 16:26:51 +0100632
Dmitry Osipenko56700e12016-10-24 16:26:52 +0100633 if (no_immediate_reload) {
634 qemu_clock_step(2000000);
635 }
636
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100637 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 99 : 98);
Dmitry Osipenko56700e12016-10-24 16:26:52 +0100638
639 if (no_immediate_reload && no_immediate_trigger) {
640 g_assert_true(triggered);
641 } else {
642 g_assert_false(triggered);
643 }
Dmitry Osipenko293130a2016-10-24 16:26:51 +0100644
645 triggered = false;
646
647 qemu_clock_step(2000000);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100648
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100649 g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 98 : 97);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100650 g_assert_false(triggered);
651
652 qemu_clock_step(2000000 * 98);
653
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100654 g_assert_cmpuint(ptimer_get_count(ptimer), ==,
655 wrap_policy ? 0 : (no_round_down ? 99 : 98));
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100656 g_assert_true(triggered);
657
Peter Maydell91b37ae2019-10-08 18:17:22 +0100658 ptimer_transaction_begin(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100659 ptimer_stop(ptimer);
Peter Maydell91b37ae2019-10-08 18:17:22 +0100660 ptimer_transaction_commit(ptimer);
Marc-André Lureau072bdb02017-01-27 12:55:51 +0400661 ptimer_free(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100662}
663
664static void check_periodic_with_load_0(gconstpointer arg)
665{
666 const uint8_t *policy = arg;
Peter Maydell91b37ae2019-10-08 18:17:22 +0100667 ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
Dmitry Osipenko2e745832016-10-24 16:26:51 +0100668 bool continuous_trigger = (*policy & PTIMER_POLICY_CONTINUOUS_TRIGGER);
Dmitry Osipenko516deb42016-10-24 16:26:52 +0100669 bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
Peter Maydell086ede32018-07-09 14:51:34 +0100670 bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100671
672 triggered = false;
673
Peter Maydell91b37ae2019-10-08 18:17:22 +0100674 ptimer_transaction_begin(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100675 ptimer_set_period(ptimer, 2000000);
676 ptimer_run(ptimer, 0);
Peter Maydell91b37ae2019-10-08 18:17:22 +0100677 ptimer_transaction_commit(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100678
679 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
Dmitry Osipenko516deb42016-10-24 16:26:52 +0100680
Peter Maydell086ede32018-07-09 14:51:34 +0100681 if (no_immediate_trigger || trig_only_on_dec) {
Dmitry Osipenko516deb42016-10-24 16:26:52 +0100682 g_assert_false(triggered);
683 } else {
684 g_assert_true(triggered);
685 }
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100686
687 triggered = false;
688
Dmitry Osipenko33d44cd2016-10-24 16:26:53 +0100689 qemu_clock_step(2000000 + 1);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100690
691 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
Dmitry Osipenko2e745832016-10-24 16:26:51 +0100692
Dmitry Osipenko516deb42016-10-24 16:26:52 +0100693 if (continuous_trigger || no_immediate_trigger) {
Dmitry Osipenko2e745832016-10-24 16:26:51 +0100694 g_assert_true(triggered);
695 } else {
696 g_assert_false(triggered);
697 }
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100698
Dmitry Osipenko293130a2016-10-24 16:26:51 +0100699 triggered = false;
700
Peter Maydell91b37ae2019-10-08 18:17:22 +0100701 ptimer_transaction_begin(ptimer);
Dmitry Osipenko293130a2016-10-24 16:26:51 +0100702 ptimer_set_count(ptimer, 10);
703 ptimer_run(ptimer, 0);
Peter Maydell91b37ae2019-10-08 18:17:22 +0100704 ptimer_transaction_commit(ptimer);
Dmitry Osipenko293130a2016-10-24 16:26:51 +0100705
Dmitry Osipenko33d44cd2016-10-24 16:26:53 +0100706 qemu_clock_step(2000000 * 10 + 1);
Dmitry Osipenko293130a2016-10-24 16:26:51 +0100707
708 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
709 g_assert_true(triggered);
710
711 triggered = false;
712
Dmitry Osipenko33d44cd2016-10-24 16:26:53 +0100713 qemu_clock_step(2000000 + 1);
Dmitry Osipenko293130a2016-10-24 16:26:51 +0100714
715 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
Dmitry Osipenko2e745832016-10-24 16:26:51 +0100716
717 if (continuous_trigger) {
718 g_assert_true(triggered);
719 } else {
720 g_assert_false(triggered);
721 }
Dmitry Osipenko293130a2016-10-24 16:26:51 +0100722
Peter Maydell91b37ae2019-10-08 18:17:22 +0100723 ptimer_transaction_begin(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100724 ptimer_stop(ptimer);
Peter Maydell91b37ae2019-10-08 18:17:22 +0100725 ptimer_transaction_commit(ptimer);
Marc-André Lureau072bdb02017-01-27 12:55:51 +0400726 ptimer_free(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100727}
728
729static void check_oneshot_with_load_0(gconstpointer arg)
730{
731 const uint8_t *policy = arg;
Peter Maydell91b37ae2019-10-08 18:17:22 +0100732 ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
Dmitry Osipenko516deb42016-10-24 16:26:52 +0100733 bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
Peter Maydell086ede32018-07-09 14:51:34 +0100734 bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100735
736 triggered = false;
737
Peter Maydell91b37ae2019-10-08 18:17:22 +0100738 ptimer_transaction_begin(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100739 ptimer_set_period(ptimer, 2000000);
740 ptimer_run(ptimer, 1);
Peter Maydell91b37ae2019-10-08 18:17:22 +0100741 ptimer_transaction_commit(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100742
743 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
Dmitry Osipenko516deb42016-10-24 16:26:52 +0100744
Peter Maydell086ede32018-07-09 14:51:34 +0100745 if (no_immediate_trigger || trig_only_on_dec) {
Dmitry Osipenko516deb42016-10-24 16:26:52 +0100746 g_assert_false(triggered);
747 } else {
748 g_assert_true(triggered);
749 }
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100750
751 triggered = false;
752
Dmitry Osipenko33d44cd2016-10-24 16:26:53 +0100753 qemu_clock_step(2000000 + 1);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100754
755 g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
Dmitry Osipenko516deb42016-10-24 16:26:52 +0100756
757 if (no_immediate_trigger) {
758 g_assert_true(triggered);
759 } else {
760 g_assert_false(triggered);
761 }
Marc-André Lureau072bdb02017-01-27 12:55:51 +0400762
763 ptimer_free(ptimer);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100764}
765
766static void add_ptimer_tests(uint8_t policy)
767{
Marc-André Lureau072bdb02017-01-27 12:55:51 +0400768 char policy_name[256] = "";
769 char *tmp;
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100770
Peter Maydell9598c1b2022-05-16 11:30:58 +0100771 if (policy == PTIMER_POLICY_LEGACY) {
772 g_sprintf(policy_name, "legacy");
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100773 }
774
Dmitry Osipenko293130a2016-10-24 16:26:51 +0100775 if (policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD) {
776 g_strlcat(policy_name, "wrap_after_one_period,", 256);
777 }
778
Dmitry Osipenko2e745832016-10-24 16:26:51 +0100779 if (policy & PTIMER_POLICY_CONTINUOUS_TRIGGER) {
780 g_strlcat(policy_name, "continuous_trigger,", 256);
781 }
782
Dmitry Osipenko516deb42016-10-24 16:26:52 +0100783 if (policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER) {
784 g_strlcat(policy_name, "no_immediate_trigger,", 256);
785 }
786
Dmitry Osipenko56700e12016-10-24 16:26:52 +0100787 if (policy & PTIMER_POLICY_NO_IMMEDIATE_RELOAD) {
788 g_strlcat(policy_name, "no_immediate_reload,", 256);
789 }
790
Dmitry Osipenko057516f2016-10-24 16:26:53 +0100791 if (policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN) {
792 g_strlcat(policy_name, "no_counter_rounddown,", 256);
793 }
794
Peter Maydell086ede32018-07-09 14:51:34 +0100795 if (policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT) {
796 g_strlcat(policy_name, "trigger_only_on_decrement,", 256);
797 }
798
Marc-André Lureau072bdb02017-01-27 12:55:51 +0400799 g_test_add_data_func_full(
800 tmp = g_strdup_printf("/ptimer/set_count policy=%s", policy_name),
Philippe Mathieu-Daudéc4f8ce22021-09-03 19:45:05 +0200801 g_memdup2(&policy, 1), check_set_count, g_free);
Marc-André Lureau072bdb02017-01-27 12:55:51 +0400802 g_free(tmp);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100803
Marc-André Lureau072bdb02017-01-27 12:55:51 +0400804 g_test_add_data_func_full(
805 tmp = g_strdup_printf("/ptimer/set_limit policy=%s", policy_name),
Philippe Mathieu-Daudéc4f8ce22021-09-03 19:45:05 +0200806 g_memdup2(&policy, 1), check_set_limit, g_free);
Marc-André Lureau072bdb02017-01-27 12:55:51 +0400807 g_free(tmp);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100808
Marc-André Lureau072bdb02017-01-27 12:55:51 +0400809 g_test_add_data_func_full(
810 tmp = g_strdup_printf("/ptimer/oneshot policy=%s", policy_name),
Philippe Mathieu-Daudéc4f8ce22021-09-03 19:45:05 +0200811 g_memdup2(&policy, 1), check_oneshot, g_free);
Marc-André Lureau072bdb02017-01-27 12:55:51 +0400812 g_free(tmp);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100813
Marc-André Lureau072bdb02017-01-27 12:55:51 +0400814 g_test_add_data_func_full(
815 tmp = g_strdup_printf("/ptimer/periodic policy=%s", policy_name),
Philippe Mathieu-Daudéc4f8ce22021-09-03 19:45:05 +0200816 g_memdup2(&policy, 1), check_periodic, g_free);
Marc-André Lureau072bdb02017-01-27 12:55:51 +0400817 g_free(tmp);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100818
Marc-André Lureau072bdb02017-01-27 12:55:51 +0400819 g_test_add_data_func_full(
820 tmp = g_strdup_printf("/ptimer/on_the_fly_mode_change policy=%s",
821 policy_name),
Philippe Mathieu-Daudéc4f8ce22021-09-03 19:45:05 +0200822 g_memdup2(&policy, 1), check_on_the_fly_mode_change, g_free);
Marc-André Lureau072bdb02017-01-27 12:55:51 +0400823 g_free(tmp);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100824
Marc-André Lureau072bdb02017-01-27 12:55:51 +0400825 g_test_add_data_func_full(
826 tmp = g_strdup_printf("/ptimer/on_the_fly_period_change policy=%s",
827 policy_name),
Philippe Mathieu-Daudéc4f8ce22021-09-03 19:45:05 +0200828 g_memdup2(&policy, 1), check_on_the_fly_period_change, g_free);
Marc-André Lureau072bdb02017-01-27 12:55:51 +0400829 g_free(tmp);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100830
Marc-André Lureau072bdb02017-01-27 12:55:51 +0400831 g_test_add_data_func_full(
832 tmp = g_strdup_printf("/ptimer/on_the_fly_freq_change policy=%s",
833 policy_name),
Philippe Mathieu-Daudéc4f8ce22021-09-03 19:45:05 +0200834 g_memdup2(&policy, 1), check_on_the_fly_freq_change, g_free);
Marc-André Lureau072bdb02017-01-27 12:55:51 +0400835 g_free(tmp);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100836
Marc-André Lureau072bdb02017-01-27 12:55:51 +0400837 g_test_add_data_func_full(
838 tmp = g_strdup_printf("/ptimer/run_with_period_0 policy=%s",
839 policy_name),
Philippe Mathieu-Daudéc4f8ce22021-09-03 19:45:05 +0200840 g_memdup2(&policy, 1), check_run_with_period_0, g_free);
Marc-André Lureau072bdb02017-01-27 12:55:51 +0400841 g_free(tmp);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100842
Marc-André Lureau072bdb02017-01-27 12:55:51 +0400843 g_test_add_data_func_full(
844 tmp = g_strdup_printf("/ptimer/run_with_delta_0 policy=%s",
845 policy_name),
Philippe Mathieu-Daudéc4f8ce22021-09-03 19:45:05 +0200846 g_memdup2(&policy, 1), check_run_with_delta_0, g_free);
Marc-André Lureau072bdb02017-01-27 12:55:51 +0400847 g_free(tmp);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100848
Marc-André Lureau072bdb02017-01-27 12:55:51 +0400849 g_test_add_data_func_full(
850 tmp = g_strdup_printf("/ptimer/periodic_with_load_0 policy=%s",
851 policy_name),
Philippe Mathieu-Daudéc4f8ce22021-09-03 19:45:05 +0200852 g_memdup2(&policy, 1), check_periodic_with_load_0, g_free);
Marc-André Lureau072bdb02017-01-27 12:55:51 +0400853 g_free(tmp);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100854
Marc-André Lureau072bdb02017-01-27 12:55:51 +0400855 g_test_add_data_func_full(
856 tmp = g_strdup_printf("/ptimer/oneshot_with_load_0 policy=%s",
857 policy_name),
Philippe Mathieu-Daudéc4f8ce22021-09-03 19:45:05 +0200858 g_memdup2(&policy, 1), check_oneshot_with_load_0, g_free);
Marc-André Lureau072bdb02017-01-27 12:55:51 +0400859 g_free(tmp);
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100860}
861
Dmitry Osipenko293130a2016-10-24 16:26:51 +0100862static void add_all_ptimer_policies_comb_tests(void)
863{
Peter Maydell086ede32018-07-09 14:51:34 +0100864 int last_policy = PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT;
Peter Maydell9598c1b2022-05-16 11:30:58 +0100865 int policy = PTIMER_POLICY_LEGACY;
Dmitry Osipenko293130a2016-10-24 16:26:51 +0100866
867 for (; policy < (last_policy << 1); policy++) {
Peter Maydell086ede32018-07-09 14:51:34 +0100868 if ((policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT) &&
869 (policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER)) {
870 /* Incompatible policy flag settings -- don't try to test them */
871 continue;
872 }
Dmitry Osipenko293130a2016-10-24 16:26:51 +0100873 add_ptimer_tests(policy);
874 }
875}
876
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100877int main(int argc, char **argv)
878{
879 int i;
880
881 g_test_init(&argc, &argv, NULL);
882
883 for (i = 0; i < QEMU_CLOCK_MAX; i++) {
884 main_loop_tlg.tl[i] = g_new0(QEMUTimerList, 1);
885 }
886
Dmitry Osipenko293130a2016-10-24 16:26:51 +0100887 add_all_ptimer_policies_comb_tests();
Dmitry Osipenko5b262bb2016-09-22 18:13:07 +0100888
889 qtest_allowed = true;
890
891 return g_test_run();
892}