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

ptimer-test.c (25199B)


      1/*
      2 * QTest testcase for the ptimer
      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
     11#include "qemu/osdep.h"
     12#include <glib/gprintf.h>
     13
     14#include "qemu/main-loop.h"
     15#include "hw/ptimer.h"
     16
     17#include "ptimer-test.h"
     18
     19static bool triggered;
     20
     21static void ptimer_trigger(void *opaque)
     22{
     23    triggered = true;
     24}
     25
     26static void ptimer_test_expire_qemu_timers(int64_t expire_time,
     27                                           QEMUClockType type)
     28{
     29    QEMUTimerList *timer_list = main_loop_tlg.tl[type];
     30    QEMUTimer *t = timer_list->active_timers.next;
     31
     32    while (t != NULL) {
     33        if (t->expire_time == expire_time) {
     34            timer_del(t);
     35
     36            if (t->cb != NULL) {
     37                t->cb(t->opaque);
     38            }
     39        }
     40
     41        t = t->next;
     42    }
     43}
     44
     45static void ptimer_test_set_qemu_time_ns(int64_t ns)
     46{
     47    ptimer_test_time_ns = ns;
     48}
     49
     50static void qemu_clock_step(uint64_t ns)
     51{
     52    int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
     53                                                  QEMU_TIMER_ATTR_ALL);
     54    int64_t advanced_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ns;
     55
     56    while (deadline != -1 && deadline <= advanced_time) {
     57        ptimer_test_set_qemu_time_ns(deadline);
     58        ptimer_test_expire_qemu_timers(deadline, QEMU_CLOCK_VIRTUAL);
     59        deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
     60                                              QEMU_TIMER_ATTR_ALL);
     61    }
     62
     63    ptimer_test_set_qemu_time_ns(advanced_time);
     64}
     65
     66static void check_set_count(gconstpointer arg)
     67{
     68    const uint8_t *policy = arg;
     69    ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
     70
     71    triggered = false;
     72
     73    ptimer_transaction_begin(ptimer);
     74    ptimer_set_count(ptimer, 1000);
     75    ptimer_transaction_commit(ptimer);
     76    g_assert_cmpuint(ptimer_get_count(ptimer), ==, 1000);
     77    g_assert_false(triggered);
     78    ptimer_free(ptimer);
     79}
     80
     81static void check_set_limit(gconstpointer arg)
     82{
     83    const uint8_t *policy = arg;
     84    ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
     85
     86    triggered = false;
     87
     88    ptimer_transaction_begin(ptimer);
     89    ptimer_set_limit(ptimer, 1000, 0);
     90    ptimer_transaction_commit(ptimer);
     91    g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
     92    g_assert_cmpuint(ptimer_get_limit(ptimer), ==, 1000);
     93    g_assert_false(triggered);
     94
     95    ptimer_transaction_begin(ptimer);
     96    ptimer_set_limit(ptimer, 2000, 1);
     97    ptimer_transaction_commit(ptimer);
     98    g_assert_cmpuint(ptimer_get_count(ptimer), ==, 2000);
     99    g_assert_cmpuint(ptimer_get_limit(ptimer), ==, 2000);
    100    g_assert_false(triggered);
    101    ptimer_free(ptimer);
    102}
    103
    104static void check_oneshot(gconstpointer arg)
    105{
    106    const uint8_t *policy = arg;
    107    ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
    108    bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
    109
    110    triggered = false;
    111
    112    ptimer_transaction_begin(ptimer);
    113    ptimer_set_period(ptimer, 2000000);
    114    ptimer_set_count(ptimer, 10);
    115    ptimer_run(ptimer, 1);
    116    ptimer_transaction_commit(ptimer);
    117
    118    qemu_clock_step(2000000 * 2 + 1);
    119
    120    g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
    121    g_assert_false(triggered);
    122
    123    ptimer_transaction_begin(ptimer);
    124    ptimer_stop(ptimer);
    125    ptimer_transaction_commit(ptimer);
    126
    127    g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
    128    g_assert_false(triggered);
    129
    130    qemu_clock_step(2000000 * 11);
    131
    132    g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
    133    g_assert_false(triggered);
    134
    135    ptimer_transaction_begin(ptimer);
    136    ptimer_run(ptimer, 1);
    137    ptimer_transaction_commit(ptimer);
    138
    139    qemu_clock_step(2000000 * 7 + 1);
    140
    141    g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
    142
    143    if (no_round_down) {
    144        g_assert_false(triggered);
    145    } else {
    146        g_assert_true(triggered);
    147
    148        triggered = false;
    149    }
    150
    151    qemu_clock_step(2000000);
    152
    153    g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
    154
    155    if (no_round_down) {
    156        g_assert_true(triggered);
    157
    158        triggered = false;
    159    } else {
    160        g_assert_false(triggered);
    161    }
    162
    163    qemu_clock_step(4000000);
    164
    165    g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
    166    g_assert_false(triggered);
    167
    168    ptimer_transaction_begin(ptimer);
    169    ptimer_set_count(ptimer, 10);
    170    ptimer_transaction_commit(ptimer);
    171
    172    qemu_clock_step(20000000 + 1);
    173
    174    g_assert_cmpuint(ptimer_get_count(ptimer), ==, 10);
    175    g_assert_false(triggered);
    176
    177    ptimer_transaction_begin(ptimer);
    178    ptimer_set_limit(ptimer, 9, 1);
    179    ptimer_transaction_commit(ptimer);
    180
    181    qemu_clock_step(20000000 + 1);
    182
    183    g_assert_cmpuint(ptimer_get_count(ptimer), ==, 9);
    184    g_assert_false(triggered);
    185
    186    ptimer_transaction_begin(ptimer);
    187    ptimer_run(ptimer, 1);
    188    ptimer_transaction_commit(ptimer);
    189
    190    qemu_clock_step(2000000 + 1);
    191
    192    g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 8 : 7);
    193    g_assert_false(triggered);
    194
    195    ptimer_transaction_begin(ptimer);
    196    ptimer_set_count(ptimer, 20);
    197    ptimer_transaction_commit(ptimer);
    198
    199    qemu_clock_step(2000000 * 19 + 1);
    200
    201    g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
    202    g_assert_false(triggered);
    203
    204    qemu_clock_step(2000000);
    205
    206    g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
    207    g_assert_true(triggered);
    208
    209    ptimer_transaction_begin(ptimer);
    210    ptimer_stop(ptimer);
    211    ptimer_transaction_commit(ptimer);
    212
    213    triggered = false;
    214
    215    qemu_clock_step(2000000 * 12 + 1);
    216
    217    g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
    218    g_assert_false(triggered);
    219    ptimer_free(ptimer);
    220}
    221
    222static void check_periodic(gconstpointer arg)
    223{
    224    const uint8_t *policy = arg;
    225    ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
    226    bool wrap_policy = (*policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD);
    227    bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
    228    bool no_immediate_reload = (*policy & PTIMER_POLICY_NO_IMMEDIATE_RELOAD);
    229    bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
    230    bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
    231
    232    triggered = false;
    233
    234    ptimer_transaction_begin(ptimer);
    235    ptimer_set_period(ptimer, 2000000);
    236    ptimer_set_limit(ptimer, 10, 1);
    237    ptimer_run(ptimer, 0);
    238    ptimer_transaction_commit(ptimer);
    239
    240    g_assert_cmpuint(ptimer_get_count(ptimer), ==, 10);
    241    g_assert_false(triggered);
    242
    243    qemu_clock_step(1);
    244
    245    g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 10 : 9);
    246    g_assert_false(triggered);
    247
    248    qemu_clock_step(2000000 * 10 - 1);
    249
    250    g_assert_cmpuint(ptimer_get_count(ptimer), ==, wrap_policy ? 0 : 10);
    251    g_assert_true(triggered);
    252
    253    qemu_clock_step(1);
    254
    255    g_assert_cmpuint(ptimer_get_count(ptimer), ==,
    256                     wrap_policy ? 0 : (no_round_down ? 10 : 9));
    257    g_assert_true(triggered);
    258
    259    triggered = false;
    260
    261    qemu_clock_step(2000000);
    262
    263    g_assert_cmpuint(ptimer_get_count(ptimer), ==,
    264                    (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
    265    g_assert_false(triggered);
    266
    267    ptimer_transaction_begin(ptimer);
    268    ptimer_set_count(ptimer, 20);
    269    ptimer_transaction_commit(ptimer);
    270
    271    g_assert_cmpuint(ptimer_get_count(ptimer), ==, 20);
    272    g_assert_false(triggered);
    273
    274    qemu_clock_step(1);
    275
    276    g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 20 : 19);
    277    g_assert_false(triggered);
    278
    279    qemu_clock_step(2000000 * 11 + 1);
    280
    281    g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 9 : 8);
    282    g_assert_false(triggered);
    283
    284    qemu_clock_step(2000000 * 10);
    285
    286    g_assert_cmpuint(ptimer_get_count(ptimer), ==,
    287                    (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
    288    g_assert_true(triggered);
    289
    290    triggered = false;
    291
    292    ptimer_transaction_begin(ptimer);
    293    ptimer_set_count(ptimer, 3);
    294    ptimer_transaction_commit(ptimer);
    295
    296    g_assert_cmpuint(ptimer_get_count(ptimer), ==, 3);
    297    g_assert_false(triggered);
    298
    299    qemu_clock_step(1);
    300
    301    g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 3 : 2);
    302    g_assert_false(triggered);
    303
    304    qemu_clock_step(2000000 * 4);
    305
    306    g_assert_cmpuint(ptimer_get_count(ptimer), ==,
    307                    (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
    308    g_assert_true(triggered);
    309
    310    ptimer_transaction_begin(ptimer);
    311    ptimer_stop(ptimer);
    312    ptimer_transaction_commit(ptimer);
    313    triggered = false;
    314
    315    qemu_clock_step(2000000);
    316
    317    g_assert_cmpuint(ptimer_get_count(ptimer), ==,
    318                    (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
    319    g_assert_false(triggered);
    320
    321    ptimer_transaction_begin(ptimer);
    322    ptimer_set_count(ptimer, 3);
    323    ptimer_run(ptimer, 0);
    324    ptimer_transaction_commit(ptimer);
    325
    326    qemu_clock_step(2000000 * 3 + 1);
    327
    328    g_assert_cmpuint(ptimer_get_count(ptimer), ==,
    329                     wrap_policy ? 0 : (no_round_down ? 10 : 9));
    330    g_assert_true(triggered);
    331
    332    triggered = false;
    333
    334    qemu_clock_step(2000000);
    335
    336    g_assert_cmpuint(ptimer_get_count(ptimer), ==,
    337                    (no_round_down ? 9 : 8) + (wrap_policy ? 1 : 0));
    338    g_assert_false(triggered);
    339
    340    ptimer_transaction_begin(ptimer);
    341    ptimer_set_count(ptimer, 0);
    342    ptimer_transaction_commit(ptimer);
    343    g_assert_cmpuint(ptimer_get_count(ptimer), ==,
    344                     no_immediate_reload ? 0 : 10);
    345
    346    if (no_immediate_trigger || trig_only_on_dec) {
    347        g_assert_false(triggered);
    348    } else {
    349        g_assert_true(triggered);
    350    }
    351
    352    triggered = false;
    353
    354    qemu_clock_step(1);
    355
    356    if (no_immediate_reload) {
    357        g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
    358        g_assert_false(triggered);
    359
    360        qemu_clock_step(2000000);
    361
    362        if (no_immediate_trigger) {
    363            g_assert_true(triggered);
    364        } else {
    365            g_assert_false(triggered);
    366        }
    367
    368        triggered = false;
    369    }
    370
    371    g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 10 : 9);
    372    g_assert_false(triggered);
    373
    374    qemu_clock_step(2000000 * 12);
    375
    376    g_assert_cmpuint(ptimer_get_count(ptimer), ==,
    377                    (no_round_down ? 8 : 7) + (wrap_policy ? 1 : 0));
    378    g_assert_true(triggered);
    379
    380    ptimer_transaction_begin(ptimer);
    381    ptimer_stop(ptimer);
    382    ptimer_transaction_commit(ptimer);
    383
    384    triggered = false;
    385
    386    qemu_clock_step(2000000 * 10);
    387
    388    g_assert_cmpuint(ptimer_get_count(ptimer), ==,
    389                    (no_round_down ? 8 : 7) + (wrap_policy ? 1 : 0));
    390    g_assert_false(triggered);
    391
    392    ptimer_transaction_begin(ptimer);
    393    ptimer_run(ptimer, 0);
    394    ptimer_transaction_commit(ptimer);
    395
    396    ptimer_transaction_begin(ptimer);
    397    ptimer_set_period(ptimer, 0);
    398    ptimer_transaction_commit(ptimer);
    399
    400    qemu_clock_step(2000000 + 1);
    401
    402    g_assert_cmpuint(ptimer_get_count(ptimer), ==,
    403                    (no_round_down ? 8 : 7) + (wrap_policy ? 1 : 0));
    404    g_assert_false(triggered);
    405    ptimer_free(ptimer);
    406}
    407
    408static void check_on_the_fly_mode_change(gconstpointer arg)
    409{
    410    const uint8_t *policy = arg;
    411    ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
    412    bool wrap_policy = (*policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD);
    413    bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
    414
    415    triggered = false;
    416
    417    ptimer_transaction_begin(ptimer);
    418    ptimer_set_period(ptimer, 2000000);
    419    ptimer_set_limit(ptimer, 10, 1);
    420    ptimer_run(ptimer, 1);
    421    ptimer_transaction_commit(ptimer);
    422
    423    qemu_clock_step(2000000 * 9 + 1);
    424
    425    g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
    426    g_assert_false(triggered);
    427
    428    ptimer_transaction_begin(ptimer);
    429    ptimer_run(ptimer, 0);
    430    ptimer_transaction_commit(ptimer);
    431
    432    g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
    433    g_assert_false(triggered);
    434
    435    qemu_clock_step(2000000);
    436
    437    g_assert_cmpuint(ptimer_get_count(ptimer), ==,
    438                    wrap_policy ? 0 : (no_round_down ? 10 : 9));
    439    g_assert_true(triggered);
    440
    441    triggered = false;
    442
    443    qemu_clock_step(2000000 * 9);
    444
    445    ptimer_transaction_begin(ptimer);
    446    ptimer_run(ptimer, 1);
    447    ptimer_transaction_commit(ptimer);
    448
    449    g_assert_cmpuint(ptimer_get_count(ptimer), ==,
    450                     (no_round_down ? 1 : 0) + (wrap_policy ? 1 : 0));
    451    g_assert_false(triggered);
    452
    453    qemu_clock_step(2000000 * 3);
    454
    455    g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
    456    g_assert_true(triggered);
    457    ptimer_free(ptimer);
    458}
    459
    460static void check_on_the_fly_period_change(gconstpointer arg)
    461{
    462    const uint8_t *policy = arg;
    463    ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
    464    bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
    465
    466    triggered = false;
    467
    468    ptimer_transaction_begin(ptimer);
    469    ptimer_set_period(ptimer, 2000000);
    470    ptimer_set_limit(ptimer, 8, 1);
    471    ptimer_run(ptimer, 1);
    472    ptimer_transaction_commit(ptimer);
    473
    474    qemu_clock_step(2000000 * 4 + 1);
    475
    476    g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
    477    g_assert_false(triggered);
    478
    479    ptimer_transaction_begin(ptimer);
    480    ptimer_set_period(ptimer, 4000000);
    481    ptimer_transaction_commit(ptimer);
    482    g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
    483
    484    qemu_clock_step(4000000 * 2 + 1);
    485
    486    g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 2 : 0);
    487    g_assert_false(triggered);
    488
    489    qemu_clock_step(4000000 * 2);
    490
    491    g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
    492    g_assert_true(triggered);
    493    ptimer_free(ptimer);
    494}
    495
    496static void check_on_the_fly_freq_change(gconstpointer arg)
    497{
    498    const uint8_t *policy = arg;
    499    ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
    500    bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
    501
    502    triggered = false;
    503
    504    ptimer_transaction_begin(ptimer);
    505    ptimer_set_freq(ptimer, 500);
    506    ptimer_set_limit(ptimer, 8, 1);
    507    ptimer_run(ptimer, 1);
    508    ptimer_transaction_commit(ptimer);
    509
    510    qemu_clock_step(2000000 * 4 + 1);
    511
    512    g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
    513    g_assert_false(triggered);
    514
    515    ptimer_transaction_begin(ptimer);
    516    ptimer_set_freq(ptimer, 250);
    517    ptimer_transaction_commit(ptimer);
    518    g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 4 : 3);
    519
    520    qemu_clock_step(2000000 * 4 + 1);
    521
    522    g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 2 : 0);
    523    g_assert_false(triggered);
    524
    525    qemu_clock_step(2000000 * 4);
    526
    527    g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
    528    g_assert_true(triggered);
    529    ptimer_free(ptimer);
    530}
    531
    532static void check_run_with_period_0(gconstpointer arg)
    533{
    534    const uint8_t *policy = arg;
    535    ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
    536
    537    triggered = false;
    538
    539    ptimer_transaction_begin(ptimer);
    540    ptimer_set_count(ptimer, 99);
    541    ptimer_run(ptimer, 1);
    542    ptimer_transaction_commit(ptimer);
    543
    544    qemu_clock_step(10 * NANOSECONDS_PER_SECOND);
    545
    546    g_assert_cmpuint(ptimer_get_count(ptimer), ==, 99);
    547    g_assert_false(triggered);
    548    ptimer_free(ptimer);
    549}
    550
    551static void check_run_with_delta_0(gconstpointer arg)
    552{
    553    const uint8_t *policy = arg;
    554    ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
    555    bool wrap_policy = (*policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD);
    556    bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
    557    bool no_immediate_reload = (*policy & PTIMER_POLICY_NO_IMMEDIATE_RELOAD);
    558    bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
    559    bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
    560
    561    triggered = false;
    562
    563    ptimer_transaction_begin(ptimer);
    564    ptimer_set_period(ptimer, 2000000);
    565    ptimer_set_limit(ptimer, 99, 0);
    566    ptimer_run(ptimer, 1);
    567    ptimer_transaction_commit(ptimer);
    568    g_assert_cmpuint(ptimer_get_count(ptimer), ==,
    569                     no_immediate_reload ? 0 : 99);
    570
    571    if (no_immediate_trigger || trig_only_on_dec) {
    572        g_assert_false(triggered);
    573    } else {
    574        g_assert_true(triggered);
    575    }
    576
    577    triggered = false;
    578
    579    if (no_immediate_trigger || no_immediate_reload) {
    580        qemu_clock_step(2000000 + 1);
    581
    582        g_assert_cmpuint(ptimer_get_count(ptimer), ==,
    583                         no_immediate_reload ? 0 : (no_round_down ? 98 : 97));
    584
    585        if (no_immediate_trigger && no_immediate_reload) {
    586            g_assert_true(triggered);
    587
    588            triggered = false;
    589        } else {
    590            g_assert_false(triggered);
    591        }
    592
    593        ptimer_transaction_begin(ptimer);
    594        ptimer_set_count(ptimer, 99);
    595        ptimer_run(ptimer, 1);
    596        ptimer_transaction_commit(ptimer);
    597    }
    598
    599    qemu_clock_step(2000000 + 1);
    600
    601    g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 98 : 97);
    602    g_assert_false(triggered);
    603
    604    qemu_clock_step(2000000 * 97);
    605
    606    g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 1 : 0);
    607    g_assert_false(triggered);
    608
    609    qemu_clock_step(2000000 * 2);
    610
    611    g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
    612    g_assert_true(triggered);
    613
    614    triggered = false;
    615
    616    ptimer_transaction_begin(ptimer);
    617    ptimer_set_count(ptimer, 0);
    618    ptimer_run(ptimer, 0);
    619    ptimer_transaction_commit(ptimer);
    620    g_assert_cmpuint(ptimer_get_count(ptimer), ==,
    621                     no_immediate_reload ? 0 : 99);
    622
    623    if (no_immediate_trigger || trig_only_on_dec) {
    624        g_assert_false(triggered);
    625    } else {
    626        g_assert_true(triggered);
    627    }
    628
    629    triggered = false;
    630
    631    qemu_clock_step(1);
    632
    633    if (no_immediate_reload) {
    634        qemu_clock_step(2000000);
    635    }
    636
    637    g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 99 : 98);
    638
    639    if (no_immediate_reload && no_immediate_trigger) {
    640        g_assert_true(triggered);
    641    } else {
    642        g_assert_false(triggered);
    643    }
    644
    645    triggered = false;
    646
    647    qemu_clock_step(2000000);
    648
    649    g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_round_down ? 98 : 97);
    650    g_assert_false(triggered);
    651
    652    qemu_clock_step(2000000 * 98);
    653
    654    g_assert_cmpuint(ptimer_get_count(ptimer), ==,
    655                    wrap_policy ? 0 : (no_round_down ? 99 : 98));
    656    g_assert_true(triggered);
    657
    658    ptimer_transaction_begin(ptimer);
    659    ptimer_stop(ptimer);
    660    ptimer_transaction_commit(ptimer);
    661    ptimer_free(ptimer);
    662}
    663
    664static void check_periodic_with_load_0(gconstpointer arg)
    665{
    666    const uint8_t *policy = arg;
    667    ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
    668    bool continuous_trigger = (*policy & PTIMER_POLICY_CONTINUOUS_TRIGGER);
    669    bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
    670    bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
    671
    672    triggered = false;
    673
    674    ptimer_transaction_begin(ptimer);
    675    ptimer_set_period(ptimer, 2000000);
    676    ptimer_run(ptimer, 0);
    677    ptimer_transaction_commit(ptimer);
    678
    679    g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
    680
    681    if (no_immediate_trigger || trig_only_on_dec) {
    682        g_assert_false(triggered);
    683    } else {
    684        g_assert_true(triggered);
    685    }
    686
    687    triggered = false;
    688
    689    qemu_clock_step(2000000 + 1);
    690
    691    g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
    692
    693    if (continuous_trigger || no_immediate_trigger) {
    694        g_assert_true(triggered);
    695    } else {
    696        g_assert_false(triggered);
    697    }
    698
    699    triggered = false;
    700
    701    ptimer_transaction_begin(ptimer);
    702    ptimer_set_count(ptimer, 10);
    703    ptimer_run(ptimer, 0);
    704    ptimer_transaction_commit(ptimer);
    705
    706    qemu_clock_step(2000000 * 10 + 1);
    707
    708    g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
    709    g_assert_true(triggered);
    710
    711    triggered = false;
    712
    713    qemu_clock_step(2000000 + 1);
    714
    715    g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
    716
    717    if (continuous_trigger) {
    718        g_assert_true(triggered);
    719    } else {
    720        g_assert_false(triggered);
    721    }
    722
    723    ptimer_transaction_begin(ptimer);
    724    ptimer_stop(ptimer);
    725    ptimer_transaction_commit(ptimer);
    726    ptimer_free(ptimer);
    727}
    728
    729static void check_oneshot_with_load_0(gconstpointer arg)
    730{
    731    const uint8_t *policy = arg;
    732    ptimer_state *ptimer = ptimer_init(ptimer_trigger, NULL, *policy);
    733    bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
    734    bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
    735
    736    triggered = false;
    737
    738    ptimer_transaction_begin(ptimer);
    739    ptimer_set_period(ptimer, 2000000);
    740    ptimer_run(ptimer, 1);
    741    ptimer_transaction_commit(ptimer);
    742
    743    g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
    744
    745    if (no_immediate_trigger || trig_only_on_dec) {
    746        g_assert_false(triggered);
    747    } else {
    748        g_assert_true(triggered);
    749    }
    750
    751    triggered = false;
    752
    753    qemu_clock_step(2000000 + 1);
    754
    755    g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
    756
    757    if (no_immediate_trigger) {
    758        g_assert_true(triggered);
    759    } else {
    760        g_assert_false(triggered);
    761    }
    762
    763    ptimer_free(ptimer);
    764}
    765
    766static void add_ptimer_tests(uint8_t policy)
    767{
    768    char policy_name[256] = "";
    769    char *tmp;
    770
    771    if (policy == PTIMER_POLICY_DEFAULT) {
    772        g_sprintf(policy_name, "default");
    773    }
    774
    775    if (policy & PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD) {
    776        g_strlcat(policy_name, "wrap_after_one_period,", 256);
    777    }
    778
    779    if (policy & PTIMER_POLICY_CONTINUOUS_TRIGGER) {
    780        g_strlcat(policy_name, "continuous_trigger,", 256);
    781    }
    782
    783    if (policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER) {
    784        g_strlcat(policy_name, "no_immediate_trigger,", 256);
    785    }
    786
    787    if (policy & PTIMER_POLICY_NO_IMMEDIATE_RELOAD) {
    788        g_strlcat(policy_name, "no_immediate_reload,", 256);
    789    }
    790
    791    if (policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN) {
    792        g_strlcat(policy_name, "no_counter_rounddown,", 256);
    793    }
    794
    795    if (policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT) {
    796        g_strlcat(policy_name, "trigger_only_on_decrement,", 256);
    797    }
    798
    799    g_test_add_data_func_full(
    800        tmp = g_strdup_printf("/ptimer/set_count policy=%s", policy_name),
    801        g_memdup(&policy, 1), check_set_count, g_free);
    802    g_free(tmp);
    803
    804    g_test_add_data_func_full(
    805        tmp = g_strdup_printf("/ptimer/set_limit policy=%s", policy_name),
    806        g_memdup(&policy, 1), check_set_limit, g_free);
    807    g_free(tmp);
    808
    809    g_test_add_data_func_full(
    810        tmp = g_strdup_printf("/ptimer/oneshot policy=%s", policy_name),
    811        g_memdup(&policy, 1), check_oneshot, g_free);
    812    g_free(tmp);
    813
    814    g_test_add_data_func_full(
    815        tmp = g_strdup_printf("/ptimer/periodic policy=%s", policy_name),
    816        g_memdup(&policy, 1), check_periodic, g_free);
    817    g_free(tmp);
    818
    819    g_test_add_data_func_full(
    820        tmp = g_strdup_printf("/ptimer/on_the_fly_mode_change policy=%s",
    821                              policy_name),
    822        g_memdup(&policy, 1), check_on_the_fly_mode_change, g_free);
    823    g_free(tmp);
    824
    825    g_test_add_data_func_full(
    826        tmp = g_strdup_printf("/ptimer/on_the_fly_period_change policy=%s",
    827                              policy_name),
    828        g_memdup(&policy, 1), check_on_the_fly_period_change, g_free);
    829    g_free(tmp);
    830
    831    g_test_add_data_func_full(
    832        tmp = g_strdup_printf("/ptimer/on_the_fly_freq_change policy=%s",
    833                              policy_name),
    834        g_memdup(&policy, 1), check_on_the_fly_freq_change, g_free);
    835    g_free(tmp);
    836
    837    g_test_add_data_func_full(
    838        tmp = g_strdup_printf("/ptimer/run_with_period_0 policy=%s",
    839                              policy_name),
    840        g_memdup(&policy, 1), check_run_with_period_0, g_free);
    841    g_free(tmp);
    842
    843    g_test_add_data_func_full(
    844        tmp = g_strdup_printf("/ptimer/run_with_delta_0 policy=%s",
    845                              policy_name),
    846        g_memdup(&policy, 1), check_run_with_delta_0, g_free);
    847    g_free(tmp);
    848
    849    g_test_add_data_func_full(
    850        tmp = g_strdup_printf("/ptimer/periodic_with_load_0 policy=%s",
    851                              policy_name),
    852        g_memdup(&policy, 1), check_periodic_with_load_0, g_free);
    853    g_free(tmp);
    854
    855    g_test_add_data_func_full(
    856        tmp = g_strdup_printf("/ptimer/oneshot_with_load_0 policy=%s",
    857                              policy_name),
    858        g_memdup(&policy, 1), check_oneshot_with_load_0, g_free);
    859    g_free(tmp);
    860}
    861
    862static void add_all_ptimer_policies_comb_tests(void)
    863{
    864    int last_policy = PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT;
    865    int policy = PTIMER_POLICY_DEFAULT;
    866
    867    for (; policy < (last_policy << 1); policy++) {
    868        if ((policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT) &&
    869            (policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER)) {
    870            /* Incompatible policy flag settings -- don't try to test them */
    871            continue;
    872        }
    873        add_ptimer_tests(policy);
    874    }
    875}
    876
    877int main(int argc, char **argv)
    878{
    879    int i;
    880
    881    g_test_init(&argc, &argv, NULL);
    882
    883    for (i = 0; i < QEMU_CLOCK_MAX; i++) {
    884        main_loop_tlg.tl[i] = g_new0(QEMUTimerList, 1);
    885    }
    886
    887    add_all_ptimer_policies_comb_tests();
    888
    889    qtest_allowed = true;
    890
    891    return g_test_run();
    892}