1
2
3
4
5
6
7
8
9
10#include "qemu/osdep.h"
11#include "qemu/timer.h"
12#include "libqtest.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
35static int nonscaled = NOSCALE;
36static int scaled = 122;
37
38static void timer_load(uint32_t load)
39{
40 writel(TIMER_BASE_PHYS + TIMER_LOAD, load);
41}
42
43static 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
54static void timer_stop(void)
55{
56 writel(TIMER_BASE_PHYS + TIMER_CONTROL, 0);
57}
58
59static void timer_int_clr(void)
60{
61 writel(TIMER_BASE_PHYS + TIMER_INTSTAT, 1);
62}
63
64static void timer_reset(void)
65{
66 timer_stop();
67 timer_load(0);
68 timer_int_clr();
69}
70
71static 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
82static uint32_t timer_counter(void)
83{
84 return readl(TIMER_BASE_PHYS + TIMER_COUNTER);
85}
86
87static void timer_set_counter(uint32_t value)
88{
89 writel(TIMER_BASE_PHYS + TIMER_COUNTER, value);
90}
91
92static 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
116static 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
157static 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
178static 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
197static 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
218static 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
239static 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
270static 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
289static 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
310static 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
347static 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
365static 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
383static 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
408static 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
433static 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
460static 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
491static 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
512static 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
533static 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
554static 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
573static 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
587static 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
598static 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
609static 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
629static 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
679static 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
697static 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
726static 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
752static 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
778static void test_deferred_trigger(void)
779{
780 int mode = ONESHOT;
781
782again:
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
852static 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
889static 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
923static 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
943static 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
969static 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
994int main(int argc, char **argv)
995{
996 int *scaler = &nonscaled;
997 int ret;
998
999 g_test_init(&argc, &argv, NULL);
1000
1001 qtest_add_func("mptimer/deferred_trigger", test_deferred_trigger);
1002 qtest_add_func("mptimer/load_disabled", test_timer_load_disabled);
1003 qtest_add_func("mptimer/set_counter_disabled", test_timer_set_counter_disabled);
1004 qtest_add_func("mptimer/zero_load_prescaled_periodic_to_nonscaled_oneshot",
1005 test_timer_zero_load_prescaled_periodic_to_nonscaled_oneshot);
1006 qtest_add_func("mptimer/zero_load_prescaled_oneshot_to_nonscaled_periodic",
1007 test_timer_zero_load_prescaled_oneshot_to_nonscaled_periodic);
1008 qtest_add_func("mptimer/zero_load_nonscaled_oneshot_to_prescaled_periodic",
1009 test_timer_zero_load_nonscaled_oneshot_to_prescaled_periodic);
1010 qtest_add_func("mptimer/zero_load_nonscaled_periodic_to_prescaled_oneshot",
1011 test_timer_zero_load_nonscaled_periodic_to_prescaled_oneshot);
1012 qtest_add_func("mptimer/prescaler", test_timer_prescaler);
1013 qtest_add_func("mptimer/prescaler_on_the_fly", test_timer_prescaler_on_the_fly);
1014
1015tests_with_prescaler_arg:
1016 qtest_add_data_func(
1017 g_strdup_printf("mptimer/oneshot scaler=%d", *scaler),
1018 scaler, test_timer_oneshot);
1019 qtest_add_data_func(
1020 g_strdup_printf("mptimer/pause scaler=%d", *scaler),
1021 scaler, test_timer_pause);
1022 qtest_add_data_func(
1023 g_strdup_printf("mptimer/reload scaler=%d", *scaler),
1024 scaler, test_timer_reload);
1025 qtest_add_data_func(
1026 g_strdup_printf("mptimer/periodic scaler=%d", *scaler),
1027 scaler, test_timer_periodic);
1028 qtest_add_data_func(
1029 g_strdup_printf("mptimer/oneshot_to_periodic scaler=%d", *scaler),
1030 scaler, test_timer_oneshot_to_periodic);
1031 qtest_add_data_func(
1032 g_strdup_printf("mptimer/periodic_to_oneshot scaler=%d", *scaler),
1033 scaler, test_timer_periodic_to_oneshot);
1034 qtest_add_data_func(
1035 g_strdup_printf("mptimer/set_oneshot_counter_to_0 scaler=%d", *scaler),
1036 scaler, test_timer_set_oneshot_counter_to_0);
1037 qtest_add_data_func(
1038 g_strdup_printf("mptimer/set_periodic_counter_to_0 scaler=%d", *scaler),
1039 scaler, test_timer_set_periodic_counter_to_0);
1040 qtest_add_data_func(
1041 g_strdup_printf("mptimer/noload_oneshot scaler=%d", *scaler),
1042 scaler, test_timer_noload_oneshot);
1043 qtest_add_data_func(
1044 g_strdup_printf("mptimer/noload_periodic scaler=%d", *scaler),
1045 scaler, test_timer_noload_periodic);
1046 qtest_add_data_func(
1047 g_strdup_printf("mptimer/zero_load_oneshot scaler=%d", *scaler),
1048 scaler, test_timer_zero_load_oneshot);
1049 qtest_add_data_func(
1050 g_strdup_printf("mptimer/zero_load_periodic scaler=%d", *scaler),
1051 scaler, test_timer_zero_load_periodic);
1052 qtest_add_data_func(
1053 g_strdup_printf("mptimer/zero_load_oneshot_to_nonzero scaler=%d", *scaler),
1054 scaler, test_timer_zero_load_oneshot_to_nonzero);
1055 qtest_add_data_func(
1056 g_strdup_printf("mptimer/zero_load_periodic_to_nonzero scaler=%d", *scaler),
1057 scaler, test_timer_zero_load_periodic_to_nonzero);
1058 qtest_add_data_func(
1059 g_strdup_printf("mptimer/nonzero_load_oneshot_to_zero scaler=%d", *scaler),
1060 scaler, test_timer_nonzero_load_oneshot_to_zero);
1061 qtest_add_data_func(
1062 g_strdup_printf("mptimer/nonzero_load_periodic_to_zero scaler=%d", *scaler),
1063 scaler, test_timer_nonzero_load_periodic_to_zero);
1064 qtest_add_data_func(
1065 g_strdup_printf("mptimer/set_periodic_counter_on_the_fly scaler=%d", *scaler),
1066 scaler, test_timer_set_periodic_counter_on_the_fly);
1067 qtest_add_data_func(
1068 g_strdup_printf("mptimer/enable_and_set_counter scaler=%d", *scaler),
1069 scaler, test_timer_enable_and_set_counter);
1070 qtest_add_data_func(
1071 g_strdup_printf("mptimer/set_counter_and_enable scaler=%d", *scaler),
1072 scaler, test_timer_set_counter_and_enable);
1073 qtest_add_data_func(
1074 g_strdup_printf("mptimer/oneshot_with_counter_0_on_start scaler=%d", *scaler),
1075 scaler, test_timer_oneshot_with_counter_0_on_start);
1076 qtest_add_data_func(
1077 g_strdup_printf("mptimer/periodic_with_counter_0_on_start scaler=%d", *scaler),
1078 scaler, test_timer_periodic_with_counter_0_on_start);
1079 qtest_add_data_func(
1080 g_strdup_printf("mptimer/periodic_counter scaler=%d", *scaler),
1081 scaler, test_periodic_counter);
1082 qtest_add_data_func(
1083 g_strdup_printf("mptimer/set_counter_periodic_with_zero_load scaler=%d", *scaler),
1084 scaler, test_timer_set_counter_periodic_with_zero_load);
1085 qtest_add_data_func(
1086 g_strdup_printf("mptimer/set_oneshot_load_to_0 scaler=%d", *scaler),
1087 scaler, test_timer_set_oneshot_load_to_0);
1088 qtest_add_data_func(
1089 g_strdup_printf("mptimer/set_periodic_load_to_0 scaler=%d", *scaler),
1090 scaler, test_timer_set_periodic_load_to_0);
1091 qtest_add_data_func(
1092 g_strdup_printf("mptimer/zero_load_mode_switch scaler=%d", *scaler),
1093 scaler, test_timer_zero_load_mode_switch);
1094
1095 if (scaler == &nonscaled) {
1096 scaler = &scaled;
1097 goto tests_with_prescaler_arg;
1098 }
1099
1100 qtest_start("-machine vexpress-a9");
1101 ret = g_test_run();
1102 qtest_end();
1103
1104 return ret;
1105}
1106