cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

test-arm-mptimer.c (29231B)


      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
     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}