qemu/tests/test-arm-mptimer.c
<<
>>
Prefs
   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.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
 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 */
 998static 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
1009int 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