xref: /openbmc/qemu/tests/qtest/test-arm-mptimer.c (revision 3ab5a6ec)
1 /*
2  * QTest testcase for the ARM MPTimer
3  *
4  * Copyright (c) 2016 Dmitry Osipenko <digetx@gmail.com>
5  *
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 #include "qemu/osdep.h"
11 #include "qemu/timer.h"
12 #include "libqtest-single.h"
13 
14 #define TIMER_BLOCK_SCALE(s)    ((((s) & 0xff) + 1) * 10)
15 
16 #define TIMER_BLOCK_STEP(scaler, steps_nb) \
17     clock_step(TIMER_BLOCK_SCALE(scaler) * (int64_t)(steps_nb) + 1)
18 
19 #define TIMER_BASE_PHYS 0x1e000600
20 
21 #define TIMER_LOAD      0x00
22 #define TIMER_COUNTER   0x04
23 #define TIMER_CONTROL   0x08
24 #define TIMER_INTSTAT   0x0C
25 
26 #define TIMER_CONTROL_ENABLE        (1 << 0)
27 #define TIMER_CONTROL_PERIODIC      (1 << 1)
28 #define TIMER_CONTROL_IT_ENABLE     (1 << 2)
29 #define TIMER_CONTROL_PRESCALER(p)  (((p) & 0xff) << 8)
30 
31 #define PERIODIC     1
32 #define ONESHOT      0
33 #define NOSCALE      0
34 
35 static int nonscaled = NOSCALE;
36 static int scaled = 122;
37 
38 static void timer_load(uint32_t load)
39 {
40     writel(TIMER_BASE_PHYS + TIMER_LOAD, load);
41 }
42 
43 static void timer_start(int periodic, uint32_t scale)
44 {
45     uint32_t ctl = TIMER_CONTROL_ENABLE | TIMER_CONTROL_PRESCALER(scale);
46 
47     if (periodic) {
48         ctl |= TIMER_CONTROL_PERIODIC;
49     }
50 
51     writel(TIMER_BASE_PHYS + TIMER_CONTROL, ctl);
52 }
53 
54 static void timer_stop(void)
55 {
56     writel(TIMER_BASE_PHYS + TIMER_CONTROL, 0);
57 }
58 
59 static void timer_int_clr(void)
60 {
61     writel(TIMER_BASE_PHYS + TIMER_INTSTAT, 1);
62 }
63 
64 static void timer_reset(void)
65 {
66     timer_stop();
67     timer_load(0);
68     timer_int_clr();
69 }
70 
71 static uint32_t timer_get_and_clr_int_sts(void)
72 {
73     uint32_t int_sts = readl(TIMER_BASE_PHYS + TIMER_INTSTAT);
74 
75     if (int_sts) {
76         timer_int_clr();
77     }
78 
79     return int_sts;
80 }
81 
82 static uint32_t timer_counter(void)
83 {
84     return readl(TIMER_BASE_PHYS + TIMER_COUNTER);
85 }
86 
87 static void timer_set_counter(uint32_t value)
88 {
89     writel(TIMER_BASE_PHYS + TIMER_COUNTER, value);
90 }
91 
92 static void test_timer_oneshot(gconstpointer arg)
93 {
94     int scaler = *((int *) arg);
95 
96     timer_reset();
97     timer_load(9999999);
98     timer_start(ONESHOT, scaler);
99 
100     TIMER_BLOCK_STEP(scaler, 9999);
101 
102     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
103     g_assert_cmpuint(timer_counter(), ==, 9990000);
104 
105     TIMER_BLOCK_STEP(scaler, 9990000);
106 
107     g_assert_cmpuint(timer_counter(), ==, 0);
108     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
109 
110     TIMER_BLOCK_STEP(scaler, 9990000);
111 
112     g_assert_cmpuint(timer_counter(), ==, 0);
113     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
114 }
115 
116 static void test_timer_pause(gconstpointer arg)
117 {
118     int scaler = *((int *) arg);
119 
120     timer_reset();
121     timer_load(999999999);
122     timer_start(ONESHOT, scaler);
123 
124     TIMER_BLOCK_STEP(scaler, 999);
125 
126     g_assert_cmpuint(timer_counter(), ==, 999999000);
127     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
128 
129     TIMER_BLOCK_STEP(scaler, 9000);
130 
131     g_assert_cmpuint(timer_counter(), ==, 999990000);
132     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
133 
134     timer_stop();
135 
136     g_assert_cmpuint(timer_counter(), ==, 999990000);
137     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
138 
139     TIMER_BLOCK_STEP(scaler, 90000);
140 
141     g_assert_cmpuint(timer_counter(), ==, 999990000);
142     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
143 
144     timer_start(ONESHOT, scaler);
145 
146     TIMER_BLOCK_STEP(scaler, 999990000);
147 
148     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
149     g_assert_cmpuint(timer_counter(), ==, 0);
150 
151     TIMER_BLOCK_STEP(scaler, 999990000);
152 
153     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
154     g_assert_cmpuint(timer_counter(), ==, 0);
155 }
156 
157 static void test_timer_reload(gconstpointer arg)
158 {
159     int scaler = *((int *) arg);
160 
161     timer_reset();
162     timer_load(UINT32_MAX);
163     timer_start(ONESHOT, scaler);
164 
165     TIMER_BLOCK_STEP(scaler, 90000);
166 
167     g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 90000);
168     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
169 
170     timer_load(UINT32_MAX);
171 
172     TIMER_BLOCK_STEP(scaler, 90000);
173 
174     g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 90000);
175     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
176 }
177 
178 static void test_timer_periodic(gconstpointer arg)
179 {
180     int scaler = *((int *) arg);
181     int repeat = 10;
182 
183     timer_reset();
184     timer_load(100);
185     timer_start(PERIODIC, scaler);
186 
187     while (repeat--) {
188         clock_step(TIMER_BLOCK_SCALE(scaler) * (101 + repeat) + 1);
189 
190         g_assert_cmpuint(timer_counter(), ==, 100 - repeat);
191         g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
192 
193         clock_step(TIMER_BLOCK_SCALE(scaler) * (101 - repeat) - 1);
194     }
195 }
196 
197 static void test_timer_oneshot_to_periodic(gconstpointer arg)
198 {
199     int scaler = *((int *) arg);
200 
201     timer_reset();
202     timer_load(10000);
203     timer_start(ONESHOT, scaler);
204 
205     TIMER_BLOCK_STEP(scaler, 1000);
206 
207     g_assert_cmpuint(timer_counter(), ==, 9000);
208     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
209 
210     timer_start(PERIODIC, scaler);
211 
212     TIMER_BLOCK_STEP(scaler, 14001);
213 
214     g_assert_cmpuint(timer_counter(), ==, 5000);
215     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
216 }
217 
218 static void test_timer_periodic_to_oneshot(gconstpointer arg)
219 {
220     int scaler = *((int *) arg);
221 
222     timer_reset();
223     timer_load(99999999);
224     timer_start(PERIODIC, scaler);
225 
226     TIMER_BLOCK_STEP(scaler, 999);
227 
228     g_assert_cmpuint(timer_counter(), ==, 99999000);
229     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
230 
231     timer_start(ONESHOT, scaler);
232 
233     TIMER_BLOCK_STEP(scaler, 99999009);
234 
235     g_assert_cmpuint(timer_counter(), ==, 0);
236     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
237 }
238 
239 static void test_timer_prescaler(void)
240 {
241     timer_reset();
242     timer_load(9999999);
243     timer_start(ONESHOT, NOSCALE);
244 
245     TIMER_BLOCK_STEP(NOSCALE, 9999998);
246 
247     g_assert_cmpuint(timer_counter(), ==, 1);
248     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
249 
250     TIMER_BLOCK_STEP(NOSCALE, 1);
251 
252     g_assert_cmpuint(timer_counter(), ==, 0);
253     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
254 
255     timer_reset();
256     timer_load(9999999);
257     timer_start(ONESHOT, 0xAB);
258 
259     TIMER_BLOCK_STEP(0xAB, 9999998);
260 
261     g_assert_cmpuint(timer_counter(), ==, 1);
262     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
263 
264     TIMER_BLOCK_STEP(0xAB, 1);
265 
266     g_assert_cmpuint(timer_counter(), ==, 0);
267     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
268 }
269 
270 static void test_timer_prescaler_on_the_fly(void)
271 {
272     timer_reset();
273     timer_load(9999999);
274     timer_start(ONESHOT, NOSCALE);
275 
276     TIMER_BLOCK_STEP(NOSCALE, 999);
277 
278     g_assert_cmpuint(timer_counter(), ==, 9999000);
279     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
280 
281     timer_start(ONESHOT, 0xAB);
282 
283     TIMER_BLOCK_STEP(0xAB, 9000);
284 
285     g_assert_cmpuint(timer_counter(), ==, 9990000);
286     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
287 }
288 
289 static void test_timer_set_oneshot_counter_to_0(gconstpointer arg)
290 {
291     int scaler = *((int *) arg);
292 
293     timer_reset();
294     timer_load(UINT32_MAX);
295     timer_start(ONESHOT, scaler);
296 
297     TIMER_BLOCK_STEP(scaler, 1);
298 
299     g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 1);
300     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
301 
302     timer_set_counter(0);
303 
304     TIMER_BLOCK_STEP(scaler, 10);
305 
306     g_assert_cmpuint(timer_counter(), ==, 0);
307     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
308 }
309 
310 static void test_timer_set_periodic_counter_to_0(gconstpointer arg)
311 {
312     int scaler = *((int *) arg);
313 
314     timer_reset();
315     timer_load(UINT32_MAX);
316     timer_start(PERIODIC, scaler);
317 
318     TIMER_BLOCK_STEP(scaler, 1);
319 
320     g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 1);
321     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
322 
323     timer_set_counter(0);
324 
325     TIMER_BLOCK_STEP(scaler, 1);
326 
327     g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - (scaler ? 0 : 1));
328     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
329 
330     timer_reset();
331     timer_set_counter(UINT32_MAX);
332     timer_start(PERIODIC, scaler);
333 
334     TIMER_BLOCK_STEP(scaler, 1);
335 
336     g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 1);
337     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
338 
339     timer_set_counter(0);
340 
341     TIMER_BLOCK_STEP(scaler, 1);
342 
343     g_assert_cmpuint(timer_counter(), ==, 0);
344     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
345 }
346 
347 static void test_timer_noload_oneshot(gconstpointer arg)
348 {
349     int scaler = *((int *) arg);
350 
351     timer_reset();
352     timer_start(ONESHOT, scaler);
353 
354     TIMER_BLOCK_STEP(scaler, 1);
355 
356     g_assert_cmpuint(timer_counter(), ==, 0);
357     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
358 
359     TIMER_BLOCK_STEP(scaler, 1);
360 
361     g_assert_cmpuint(timer_counter(), ==, 0);
362     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
363 }
364 
365 static void test_timer_noload_periodic(gconstpointer arg)
366 {
367     int scaler = *((int *) arg);
368 
369     timer_reset();
370     timer_start(PERIODIC, scaler);
371 
372     TIMER_BLOCK_STEP(scaler, 1);
373 
374     g_assert_cmpuint(timer_counter(), ==, 0);
375     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
376 
377     TIMER_BLOCK_STEP(scaler, 1);
378 
379     g_assert_cmpuint(timer_counter(), ==, 0);
380     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
381 }
382 
383 static void test_timer_zero_load_oneshot(gconstpointer arg)
384 {
385     int scaler = *((int *) arg);
386 
387     timer_reset();
388     timer_start(ONESHOT, scaler);
389 
390     TIMER_BLOCK_STEP(scaler, 1);
391 
392     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
393     g_assert_cmpuint(timer_counter(), ==, 0);
394 
395     timer_load(0);
396 
397     TIMER_BLOCK_STEP(scaler, 1);
398 
399     g_assert_cmpuint(timer_counter(), ==, 0);
400     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
401 
402     TIMER_BLOCK_STEP(scaler, 1);
403 
404     g_assert_cmpuint(timer_counter(), ==, 0);
405     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
406 }
407 
408 static void test_timer_zero_load_periodic(gconstpointer arg)
409 {
410     int scaler = *((int *) arg);
411 
412     timer_reset();
413     timer_start(PERIODIC, scaler);
414 
415     TIMER_BLOCK_STEP(scaler, 1);
416 
417     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
418     g_assert_cmpuint(timer_counter(), ==, 0);
419 
420     timer_load(0);
421 
422     TIMER_BLOCK_STEP(scaler, 1);
423 
424     g_assert_cmpuint(timer_counter(), ==, 0);
425     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
426 
427     TIMER_BLOCK_STEP(scaler, 1);
428 
429     g_assert_cmpuint(timer_counter(), ==, 0);
430     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
431 }
432 
433 static void test_timer_zero_load_oneshot_to_nonzero(gconstpointer arg)
434 {
435     int scaler = *((int *) arg);
436 
437     timer_reset();
438     timer_start(ONESHOT, scaler);
439 
440     TIMER_BLOCK_STEP(scaler, 1);
441 
442     g_assert_cmpuint(timer_counter(), ==, 0);
443     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
444 
445     timer_load(0);
446 
447     TIMER_BLOCK_STEP(scaler, 1);
448 
449     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
450     g_assert_cmpuint(timer_counter(), ==, 0);
451 
452     timer_load(999);
453 
454     TIMER_BLOCK_STEP(scaler, 1001);
455 
456     g_assert_cmpuint(timer_counter(), ==, 0);
457     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
458 }
459 
460 static void test_timer_zero_load_periodic_to_nonzero(gconstpointer arg)
461 {
462     int scaler = *((int *) arg);
463     int i;
464 
465     timer_reset();
466     timer_start(PERIODIC, scaler);
467 
468     TIMER_BLOCK_STEP(scaler, 1);
469 
470     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
471     g_assert_cmpuint(timer_counter(), ==, 0);
472 
473     timer_load(0);
474 
475     TIMER_BLOCK_STEP(scaler, 1);
476 
477     g_assert_cmpuint(timer_counter(), ==, 0);
478     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
479 
480     timer_load(1999999);
481 
482     for (i = 1; i < 10; i++) {
483         TIMER_BLOCK_STEP(scaler, 2000001);
484 
485         g_assert_cmpuint(timer_counter(), ==, 1999999 - i);
486         g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
487         g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
488     }
489 }
490 
491 static void test_timer_nonzero_load_oneshot_to_zero(gconstpointer arg)
492 {
493     int scaler = *((int *) arg);
494 
495     timer_reset();
496     timer_start(ONESHOT, scaler);
497 
498     TIMER_BLOCK_STEP(scaler, 1);
499 
500     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
501     g_assert_cmpuint(timer_counter(), ==, 0);
502 
503     timer_load(UINT32_MAX);
504     timer_load(0);
505 
506     TIMER_BLOCK_STEP(scaler, 100);
507 
508     g_assert_cmpuint(timer_counter(), ==, 0);
509     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
510 }
511 
512 static void test_timer_nonzero_load_periodic_to_zero(gconstpointer arg)
513 {
514     int scaler = *((int *) arg);
515 
516     timer_reset();
517     timer_start(PERIODIC, scaler);
518 
519     TIMER_BLOCK_STEP(scaler, 1);
520 
521     g_assert_cmpuint(timer_counter(), ==, 0);
522     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
523 
524     timer_load(UINT32_MAX);
525     timer_load(0);
526 
527     TIMER_BLOCK_STEP(scaler, 100);
528 
529     g_assert_cmpuint(timer_counter(), ==, 0);
530     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
531 }
532 
533 static void test_timer_set_periodic_counter_on_the_fly(gconstpointer arg)
534 {
535     int scaler = *((int *) arg);
536 
537     timer_reset();
538     timer_load(UINT32_MAX / 2);
539     timer_start(PERIODIC, scaler);
540 
541     TIMER_BLOCK_STEP(scaler, 100);
542 
543     g_assert_cmpuint(timer_counter(), ==, UINT32_MAX / 2 - 100);
544     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
545 
546     timer_set_counter(UINT32_MAX);
547 
548     TIMER_BLOCK_STEP(scaler, 100);
549 
550     g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 100);
551     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
552 }
553 
554 static void test_timer_enable_and_set_counter(gconstpointer arg)
555 {
556     int scaler = *((int *) arg);
557 
558     timer_reset();
559     timer_start(ONESHOT, scaler);
560 
561     TIMER_BLOCK_STEP(scaler, 1);
562 
563     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
564 
565     timer_set_counter(UINT32_MAX);
566 
567     TIMER_BLOCK_STEP(scaler, 100);
568 
569     g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 100);
570     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
571 }
572 
573 static void test_timer_set_counter_and_enable(gconstpointer arg)
574 {
575     int scaler = *((int *) arg);
576 
577     timer_reset();
578     timer_set_counter(UINT32_MAX);
579     timer_start(ONESHOT, scaler);
580 
581     TIMER_BLOCK_STEP(scaler, 100);
582 
583     g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 100);
584     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
585 }
586 
587 static void test_timer_set_counter_disabled(void)
588 {
589     timer_reset();
590     timer_set_counter(999999999);
591 
592     TIMER_BLOCK_STEP(NOSCALE, 100);
593 
594     g_assert_cmpuint(timer_counter(), ==, 999999999);
595     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
596 }
597 
598 static void test_timer_load_disabled(void)
599 {
600     timer_reset();
601     timer_load(999999999);
602 
603     TIMER_BLOCK_STEP(NOSCALE, 100);
604 
605     g_assert_cmpuint(timer_counter(), ==, 999999999);
606     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
607 }
608 
609 static void test_timer_oneshot_with_counter_0_on_start(gconstpointer arg)
610 {
611     int scaler = *((int *) arg);
612 
613     timer_reset();
614     timer_load(999);
615     timer_set_counter(0);
616     timer_start(ONESHOT, scaler);
617 
618     TIMER_BLOCK_STEP(scaler, 100);
619 
620     g_assert_cmpuint(timer_counter(), ==, 0);
621     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
622 
623     TIMER_BLOCK_STEP(scaler, 100);
624 
625     g_assert_cmpuint(timer_counter(), ==, 0);
626     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
627 }
628 
629 static void test_timer_periodic_with_counter_0_on_start(gconstpointer arg)
630 {
631     int scaler = *((int *) arg);
632     int i;
633 
634     timer_reset();
635     timer_load(UINT32_MAX);
636     timer_set_counter(0);
637 
638     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
639     g_assert_cmpuint(timer_counter(), ==, 0);
640 
641     timer_start(PERIODIC, scaler);
642 
643     TIMER_BLOCK_STEP(scaler, 100);
644 
645     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
646     g_assert_cmpuint(timer_counter(), ==, UINT32_MAX + (scaler ? 1 : 0) - 100);
647 
648     TIMER_BLOCK_STEP(scaler, 100);
649 
650     g_assert_cmpuint(timer_counter(), ==, UINT32_MAX + (scaler ? 1 : 0) - 200);
651     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
652 
653     timer_reset();
654     timer_load(1999999);
655     timer_set_counter(0);
656 
657     g_assert_cmpuint(timer_counter(), ==, 0);
658     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
659 
660     TIMER_BLOCK_STEP(scaler, 1);
661 
662     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
663 
664     timer_start(PERIODIC, scaler);
665 
666     TIMER_BLOCK_STEP(scaler, 1);
667 
668     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
669 
670     for (i = 2 - (!!scaler ? 1 : 0); i < 10; i++) {
671         TIMER_BLOCK_STEP(scaler, 2000001);
672 
673         g_assert_cmpuint(timer_counter(), ==, 1999999 - i);
674         g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
675         g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
676     }
677 }
678 
679 static void test_periodic_counter(gconstpointer arg)
680 {
681     const int test_load = 10;
682     int scaler = *((int *) arg);
683     int test_val;
684 
685     timer_reset();
686     timer_load(test_load);
687     timer_start(PERIODIC, scaler);
688 
689     clock_step(1);
690 
691     for (test_val = 0; test_val <= test_load; test_val++) {
692         clock_step(TIMER_BLOCK_SCALE(scaler) * test_load);
693         g_assert_cmpint(timer_counter(), ==, test_val);
694     }
695 }
696 
697 static void test_timer_set_counter_periodic_with_zero_load(gconstpointer arg)
698 {
699     int scaler = *((int *) arg);
700 
701     timer_reset();
702     timer_start(PERIODIC, scaler);
703     timer_load(0);
704 
705     TIMER_BLOCK_STEP(scaler, 1);
706 
707     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
708 
709     TIMER_BLOCK_STEP(scaler, 1);
710 
711     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
712 
713     timer_set_counter(999);
714 
715     TIMER_BLOCK_STEP(scaler, 999);
716 
717     g_assert_cmpuint(timer_counter(), ==, 0);
718     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
719 
720     TIMER_BLOCK_STEP(scaler, 1);
721 
722     g_assert_cmpuint(timer_counter(), ==, 0);
723     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
724 }
725 
726 static void test_timer_set_oneshot_load_to_0(gconstpointer arg)
727 {
728     int scaler = *((int *) arg);
729 
730     timer_reset();
731     timer_load(UINT32_MAX);
732     timer_start(ONESHOT, scaler);
733 
734     TIMER_BLOCK_STEP(scaler, 100);
735 
736     g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 100);
737     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
738 
739     timer_load(0);
740 
741     TIMER_BLOCK_STEP(scaler, 100);
742 
743     g_assert_cmpuint(timer_counter(), ==, 0);
744     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
745 
746     TIMER_BLOCK_STEP(scaler, 100);
747 
748     g_assert_cmpuint(timer_counter(), ==, 0);
749     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
750 }
751 
752 static void test_timer_set_periodic_load_to_0(gconstpointer arg)
753 {
754     int scaler = *((int *) arg);
755 
756     timer_reset();
757     timer_load(UINT32_MAX);
758     timer_start(PERIODIC, scaler);
759 
760     TIMER_BLOCK_STEP(scaler, 100);
761 
762     g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 100);
763     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
764 
765     timer_load(0);
766 
767     TIMER_BLOCK_STEP(scaler, 100);
768 
769     g_assert_cmpuint(timer_counter(), ==, 0);
770     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
771 
772     TIMER_BLOCK_STEP(scaler, 100);
773 
774     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
775     g_assert_cmpuint(timer_counter(), ==, 0);
776 }
777 
778 static void test_deferred_trigger(void)
779 {
780     int mode = ONESHOT;
781 
782 again:
783     timer_reset();
784     timer_start(mode, 255);
785 
786     clock_step(100);
787 
788     g_assert_cmpuint(timer_counter(), ==, 0);
789 
790     TIMER_BLOCK_STEP(255, 1);
791 
792     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
793 
794     timer_reset();
795     timer_load(2);
796     timer_start(mode, 255);
797 
798     clock_step(100);
799 
800     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
801 
802     TIMER_BLOCK_STEP(255, 1);
803 
804     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
805 
806     TIMER_BLOCK_STEP(255, 1);
807 
808     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
809 
810     timer_reset();
811     timer_load(UINT32_MAX);
812     timer_start(mode, 255);
813 
814     clock_step(100);
815 
816     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
817 
818     timer_set_counter(0);
819 
820     clock_step(100);
821 
822     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
823 
824     TIMER_BLOCK_STEP(255, 1);
825 
826     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
827 
828     timer_reset();
829     timer_load(UINT32_MAX);
830     timer_start(mode, 255);
831 
832     clock_step(100);
833 
834     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
835 
836     timer_load(0);
837 
838     clock_step(100);
839 
840     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
841 
842     TIMER_BLOCK_STEP(255, 1);
843 
844     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
845 
846     if (mode == ONESHOT) {
847         mode = PERIODIC;
848         goto again;
849     }
850 }
851 
852 static void test_timer_zero_load_mode_switch(gconstpointer arg)
853 {
854     int scaler = *((int *) arg);
855 
856     timer_reset();
857     timer_load(0);
858     timer_start(PERIODIC, scaler);
859 
860     TIMER_BLOCK_STEP(scaler, 1);
861 
862     g_assert_cmpuint(timer_counter(), ==, 0);
863     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
864 
865     TIMER_BLOCK_STEP(scaler, 1);
866 
867     timer_start(ONESHOT, scaler);
868 
869     TIMER_BLOCK_STEP(scaler, 1);
870 
871     g_assert_cmpuint(timer_counter(), ==, 0);
872     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
873 
874     TIMER_BLOCK_STEP(scaler, 1);
875 
876     g_assert_cmpuint(timer_counter(), ==, 0);
877     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
878 
879     TIMER_BLOCK_STEP(scaler, 1);
880 
881     timer_start(PERIODIC, scaler);
882 
883     TIMER_BLOCK_STEP(scaler, 1);
884 
885     g_assert_cmpuint(timer_counter(), ==, 0);
886     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler);
887 }
888 
889 static void test_timer_zero_load_prescaled_periodic_to_nonscaled_oneshot(void)
890 {
891     timer_reset();
892     timer_load(0);
893     timer_start(PERIODIC, 255);
894 
895     TIMER_BLOCK_STEP(255, 1);
896 
897     g_assert_cmpuint(timer_counter(), ==, 0);
898     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
899     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
900 
901     TIMER_BLOCK_STEP(255, 1);
902 
903     g_assert_cmpuint(timer_counter(), ==, 0);
904     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
905     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
906 
907     TIMER_BLOCK_STEP(255, 1);
908 
909     timer_start(ONESHOT, NOSCALE);
910 
911     TIMER_BLOCK_STEP(NOSCALE, 1);
912 
913     g_assert_cmpuint(timer_counter(), ==, 0);
914     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
915     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
916 
917     TIMER_BLOCK_STEP(NOSCALE, 1);
918 
919     g_assert_cmpuint(timer_counter(), ==, 0);
920     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
921 }
922 
923 static void test_timer_zero_load_prescaled_oneshot_to_nonscaled_periodic(void)
924 {
925     timer_reset();
926     timer_load(0);
927     timer_start(ONESHOT, 255);
928 
929     TIMER_BLOCK_STEP(255, 1);
930 
931     g_assert_cmpuint(timer_counter(), ==, 0);
932     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
933     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
934 
935     timer_start(PERIODIC, NOSCALE);
936 
937     TIMER_BLOCK_STEP(NOSCALE, 1);
938 
939     g_assert_cmpuint(timer_counter(), ==, 0);
940     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
941 }
942 
943 static void test_timer_zero_load_nonscaled_oneshot_to_prescaled_periodic(void)
944 {
945     timer_reset();
946     timer_load(0);
947     timer_start(ONESHOT, NOSCALE);
948 
949     TIMER_BLOCK_STEP(NOSCALE, 1);
950 
951     g_assert_cmpuint(timer_counter(), ==, 0);
952     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
953 
954     timer_start(PERIODIC, 255);
955 
956     TIMER_BLOCK_STEP(255, 1);
957 
958     g_assert_cmpuint(timer_counter(), ==, 0);
959     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
960     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
961 
962     TIMER_BLOCK_STEP(255, 1);
963 
964     g_assert_cmpuint(timer_counter(), ==, 0);
965     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
966     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
967 }
968 
969 static void test_timer_zero_load_nonscaled_periodic_to_prescaled_oneshot(void)
970 {
971     timer_reset();
972     timer_load(0);
973     timer_start(PERIODIC, NOSCALE);
974 
975     TIMER_BLOCK_STEP(NOSCALE, 1);
976 
977     g_assert_cmpuint(timer_counter(), ==, 0);
978     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
979 
980     timer_start(ONESHOT, 255);
981 
982     TIMER_BLOCK_STEP(255, 1);
983 
984     g_assert_cmpuint(timer_counter(), ==, 0);
985     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1);
986     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
987 
988     TIMER_BLOCK_STEP(255, 1);
989 
990     g_assert_cmpuint(timer_counter(), ==, 0);
991     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0);
992 }
993 
994 /*
995  * Add a qtest test that comes in two versions: one with
996  * a timer scaler setting, and one with the timer nonscaled.
997  */
998 static void add_scaler_test(const char *str, bool scale,
999                             void (*fn)(const void *))
1000 {
1001     char *name;
1002     int *scaler = scale ? &scaled : &nonscaled;
1003 
1004     name = g_strdup_printf("%s=%d", str, *scaler);
1005     qtest_add_data_func(name, scaler, fn);
1006     g_free(name);
1007 }
1008 
1009 int main(int argc, char **argv)
1010 {
1011     int ret;
1012     int scale;
1013 
1014     g_test_init(&argc, &argv, NULL);
1015 
1016     qtest_add_func("mptimer/deferred_trigger", test_deferred_trigger);
1017     qtest_add_func("mptimer/load_disabled", test_timer_load_disabled);
1018     qtest_add_func("mptimer/set_counter_disabled", test_timer_set_counter_disabled);
1019     qtest_add_func("mptimer/zero_load_prescaled_periodic_to_nonscaled_oneshot",
1020                    test_timer_zero_load_prescaled_periodic_to_nonscaled_oneshot);
1021     qtest_add_func("mptimer/zero_load_prescaled_oneshot_to_nonscaled_periodic",
1022                    test_timer_zero_load_prescaled_oneshot_to_nonscaled_periodic);
1023     qtest_add_func("mptimer/zero_load_nonscaled_oneshot_to_prescaled_periodic",
1024                    test_timer_zero_load_nonscaled_oneshot_to_prescaled_periodic);
1025     qtest_add_func("mptimer/zero_load_nonscaled_periodic_to_prescaled_oneshot",
1026                    test_timer_zero_load_nonscaled_periodic_to_prescaled_oneshot);
1027     qtest_add_func("mptimer/prescaler", test_timer_prescaler);
1028     qtest_add_func("mptimer/prescaler_on_the_fly", test_timer_prescaler_on_the_fly);
1029 
1030     for (scale = 0; scale < 2; scale++) {
1031         add_scaler_test("mptimer/oneshot scaler",
1032                         scale, test_timer_oneshot);
1033         add_scaler_test("mptimer/pause scaler",
1034                         scale, test_timer_pause);
1035         add_scaler_test("mptimer/reload scaler",
1036                         scale, test_timer_reload);
1037         add_scaler_test("mptimer/periodic scaler",
1038                         scale, test_timer_periodic);
1039         add_scaler_test("mptimer/oneshot_to_periodic scaler",
1040                         scale, test_timer_oneshot_to_periodic);
1041         add_scaler_test("mptimer/periodic_to_oneshot scaler",
1042                         scale, test_timer_periodic_to_oneshot);
1043         add_scaler_test("mptimer/set_oneshot_counter_to_0 scaler",
1044                         scale, test_timer_set_oneshot_counter_to_0);
1045         add_scaler_test("mptimer/set_periodic_counter_to_0 scaler",
1046                         scale, test_timer_set_periodic_counter_to_0);
1047         add_scaler_test("mptimer/noload_oneshot scaler",
1048                         scale, test_timer_noload_oneshot);
1049         add_scaler_test("mptimer/noload_periodic scaler",
1050                         scale, test_timer_noload_periodic);
1051         add_scaler_test("mptimer/zero_load_oneshot scaler",
1052                         scale, test_timer_zero_load_oneshot);
1053         add_scaler_test("mptimer/zero_load_periodic scaler",
1054                         scale, test_timer_zero_load_periodic);
1055         add_scaler_test("mptimer/zero_load_oneshot_to_nonzero scaler",
1056                         scale, test_timer_zero_load_oneshot_to_nonzero);
1057         add_scaler_test("mptimer/zero_load_periodic_to_nonzero scaler",
1058                         scale, test_timer_zero_load_periodic_to_nonzero);
1059         add_scaler_test("mptimer/nonzero_load_oneshot_to_zero scaler",
1060                         scale, test_timer_nonzero_load_oneshot_to_zero);
1061         add_scaler_test("mptimer/nonzero_load_periodic_to_zero scaler",
1062                         scale, test_timer_nonzero_load_periodic_to_zero);
1063         add_scaler_test("mptimer/set_periodic_counter_on_the_fly scaler",
1064                         scale, test_timer_set_periodic_counter_on_the_fly);
1065         add_scaler_test("mptimer/enable_and_set_counter scaler",
1066                         scale, test_timer_enable_and_set_counter);
1067         add_scaler_test("mptimer/set_counter_and_enable scaler",
1068                         scale, test_timer_set_counter_and_enable);
1069         add_scaler_test("mptimer/oneshot_with_counter_0_on_start scaler",
1070                         scale, test_timer_oneshot_with_counter_0_on_start);
1071         add_scaler_test("mptimer/periodic_with_counter_0_on_start scaler",
1072                         scale, test_timer_periodic_with_counter_0_on_start);
1073         add_scaler_test("mptimer/periodic_counter scaler",
1074                         scale, test_periodic_counter);
1075         add_scaler_test("mptimer/set_counter_periodic_with_zero_load scaler",
1076                         scale, test_timer_set_counter_periodic_with_zero_load);
1077         add_scaler_test("mptimer/set_oneshot_load_to_0 scaler",
1078                         scale, test_timer_set_oneshot_load_to_0);
1079         add_scaler_test("mptimer/set_periodic_load_to_0 scaler",
1080                         scale, test_timer_set_periodic_load_to_0);
1081         add_scaler_test("mptimer/zero_load_mode_switch scaler",
1082                         scale, test_timer_zero_load_mode_switch);
1083     }
1084 
1085     qtest_start("-machine vexpress-a9");
1086     ret = g_test_run();
1087     qtest_end();
1088 
1089     return ret;
1090 }
1091