| /* | 
 |  * QTest testcase for the ARM MPTimer | 
 |  * | 
 |  * Copyright (c) 2016 Dmitry Osipenko <digetx@gmail.com> | 
 |  * | 
 |  * This work is licensed under the terms of the GNU GPL, version 2 or later. | 
 |  * See the COPYING file in the top-level directory. | 
 |  */ | 
 |  | 
 | #include "qemu/osdep.h" | 
 | #include "qemu/timer.h" | 
 | #include "libqtest-single.h" | 
 |  | 
 | #define TIMER_BLOCK_SCALE(s)    ((((s) & 0xff) + 1) * 10) | 
 |  | 
 | #define TIMER_BLOCK_STEP(scaler, steps_nb) \ | 
 |     clock_step(TIMER_BLOCK_SCALE(scaler) * (int64_t)(steps_nb) + 1) | 
 |  | 
 | #define TIMER_BASE_PHYS 0x1e000600 | 
 |  | 
 | #define TIMER_LOAD      0x00 | 
 | #define TIMER_COUNTER   0x04 | 
 | #define TIMER_CONTROL   0x08 | 
 | #define TIMER_INTSTAT   0x0C | 
 |  | 
 | #define TIMER_CONTROL_ENABLE        (1 << 0) | 
 | #define TIMER_CONTROL_PERIODIC      (1 << 1) | 
 | #define TIMER_CONTROL_IT_ENABLE     (1 << 2) | 
 | #define TIMER_CONTROL_PRESCALER(p)  (((p) & 0xff) << 8) | 
 |  | 
 | #define PERIODIC     1 | 
 | #define ONESHOT      0 | 
 | #define NOSCALE      0 | 
 |  | 
 | static int nonscaled = NOSCALE; | 
 | static int scaled = 122; | 
 |  | 
 | static void timer_load(uint32_t load) | 
 | { | 
 |     writel(TIMER_BASE_PHYS + TIMER_LOAD, load); | 
 | } | 
 |  | 
 | static void timer_start(int periodic, uint32_t scale) | 
 | { | 
 |     uint32_t ctl = TIMER_CONTROL_ENABLE | TIMER_CONTROL_PRESCALER(scale); | 
 |  | 
 |     if (periodic) { | 
 |         ctl |= TIMER_CONTROL_PERIODIC; | 
 |     } | 
 |  | 
 |     writel(TIMER_BASE_PHYS + TIMER_CONTROL, ctl); | 
 | } | 
 |  | 
 | static void timer_stop(void) | 
 | { | 
 |     writel(TIMER_BASE_PHYS + TIMER_CONTROL, 0); | 
 | } | 
 |  | 
 | static void timer_int_clr(void) | 
 | { | 
 |     writel(TIMER_BASE_PHYS + TIMER_INTSTAT, 1); | 
 | } | 
 |  | 
 | static void timer_reset(void) | 
 | { | 
 |     timer_stop(); | 
 |     timer_load(0); | 
 |     timer_int_clr(); | 
 | } | 
 |  | 
 | static uint32_t timer_get_and_clr_int_sts(void) | 
 | { | 
 |     uint32_t int_sts = readl(TIMER_BASE_PHYS + TIMER_INTSTAT); | 
 |  | 
 |     if (int_sts) { | 
 |         timer_int_clr(); | 
 |     } | 
 |  | 
 |     return int_sts; | 
 | } | 
 |  | 
 | static uint32_t timer_counter(void) | 
 | { | 
 |     return readl(TIMER_BASE_PHYS + TIMER_COUNTER); | 
 | } | 
 |  | 
 | static void timer_set_counter(uint32_t value) | 
 | { | 
 |     writel(TIMER_BASE_PHYS + TIMER_COUNTER, value); | 
 | } | 
 |  | 
 | static void test_timer_oneshot(gconstpointer arg) | 
 | { | 
 |     int scaler = *((int *) arg); | 
 |  | 
 |     timer_reset(); | 
 |     timer_load(9999999); | 
 |     timer_start(ONESHOT, scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 9999); | 
 |  | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |     g_assert_cmpuint(timer_counter(), ==, 9990000); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 9990000); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 9990000); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 | } | 
 |  | 
 | static void test_timer_pause(gconstpointer arg) | 
 | { | 
 |     int scaler = *((int *) arg); | 
 |  | 
 |     timer_reset(); | 
 |     timer_load(999999999); | 
 |     timer_start(ONESHOT, scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 999); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 999999000); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 9000); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 999990000); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |  | 
 |     timer_stop(); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 999990000); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 90000); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 999990000); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |  | 
 |     timer_start(ONESHOT, scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 999990000); | 
 |  | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 999990000); | 
 |  | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 | } | 
 |  | 
 | static void test_timer_reload(gconstpointer arg) | 
 | { | 
 |     int scaler = *((int *) arg); | 
 |  | 
 |     timer_reset(); | 
 |     timer_load(UINT32_MAX); | 
 |     timer_start(ONESHOT, scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 90000); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 90000); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |  | 
 |     timer_load(UINT32_MAX); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 90000); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 90000); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 | } | 
 |  | 
 | static void test_timer_periodic(gconstpointer arg) | 
 | { | 
 |     int scaler = *((int *) arg); | 
 |     int repeat = 10; | 
 |  | 
 |     timer_reset(); | 
 |     timer_load(100); | 
 |     timer_start(PERIODIC, scaler); | 
 |  | 
 |     while (repeat--) { | 
 |         clock_step(TIMER_BLOCK_SCALE(scaler) * (101 + repeat) + 1); | 
 |  | 
 |         g_assert_cmpuint(timer_counter(), ==, 100 - repeat); | 
 |         g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); | 
 |  | 
 |         clock_step(TIMER_BLOCK_SCALE(scaler) * (101 - repeat) - 1); | 
 |     } | 
 | } | 
 |  | 
 | static void test_timer_oneshot_to_periodic(gconstpointer arg) | 
 | { | 
 |     int scaler = *((int *) arg); | 
 |  | 
 |     timer_reset(); | 
 |     timer_load(10000); | 
 |     timer_start(ONESHOT, scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 1000); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 9000); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |  | 
 |     timer_start(PERIODIC, scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 14001); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 5000); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); | 
 | } | 
 |  | 
 | static void test_timer_periodic_to_oneshot(gconstpointer arg) | 
 | { | 
 |     int scaler = *((int *) arg); | 
 |  | 
 |     timer_reset(); | 
 |     timer_load(99999999); | 
 |     timer_start(PERIODIC, scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 999); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 99999000); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |  | 
 |     timer_start(ONESHOT, scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 99999009); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); | 
 | } | 
 |  | 
 | static void test_timer_prescaler(void) | 
 | { | 
 |     timer_reset(); | 
 |     timer_load(9999999); | 
 |     timer_start(ONESHOT, NOSCALE); | 
 |  | 
 |     TIMER_BLOCK_STEP(NOSCALE, 9999998); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 1); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |  | 
 |     TIMER_BLOCK_STEP(NOSCALE, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); | 
 |  | 
 |     timer_reset(); | 
 |     timer_load(9999999); | 
 |     timer_start(ONESHOT, 0xAB); | 
 |  | 
 |     TIMER_BLOCK_STEP(0xAB, 9999998); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 1); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |  | 
 |     TIMER_BLOCK_STEP(0xAB, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); | 
 | } | 
 |  | 
 | static void test_timer_prescaler_on_the_fly(void) | 
 | { | 
 |     timer_reset(); | 
 |     timer_load(9999999); | 
 |     timer_start(ONESHOT, NOSCALE); | 
 |  | 
 |     TIMER_BLOCK_STEP(NOSCALE, 999); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 9999000); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |  | 
 |     timer_start(ONESHOT, 0xAB); | 
 |  | 
 |     TIMER_BLOCK_STEP(0xAB, 9000); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 9990000); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 | } | 
 |  | 
 | static void test_timer_set_oneshot_counter_to_0(gconstpointer arg) | 
 | { | 
 |     int scaler = *((int *) arg); | 
 |  | 
 |     timer_reset(); | 
 |     timer_load(UINT32_MAX); | 
 |     timer_start(ONESHOT, scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 1); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |  | 
 |     timer_set_counter(0); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 10); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); | 
 | } | 
 |  | 
 | static void test_timer_set_periodic_counter_to_0(gconstpointer arg) | 
 | { | 
 |     int scaler = *((int *) arg); | 
 |  | 
 |     timer_reset(); | 
 |     timer_load(UINT32_MAX); | 
 |     timer_start(PERIODIC, scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 1); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |  | 
 |     timer_set_counter(0); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - (scaler ? 0 : 1)); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); | 
 |  | 
 |     timer_reset(); | 
 |     timer_set_counter(UINT32_MAX); | 
 |     timer_start(PERIODIC, scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 1); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |  | 
 |     timer_set_counter(0); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); | 
 | } | 
 |  | 
 | static void test_timer_noload_oneshot(gconstpointer arg) | 
 | { | 
 |     int scaler = *((int *) arg); | 
 |  | 
 |     timer_reset(); | 
 |     timer_start(ONESHOT, scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 | } | 
 |  | 
 | static void test_timer_noload_periodic(gconstpointer arg) | 
 | { | 
 |     int scaler = *((int *) arg); | 
 |  | 
 |     timer_reset(); | 
 |     timer_start(PERIODIC, scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); | 
 | } | 
 |  | 
 | static void test_timer_zero_load_oneshot(gconstpointer arg) | 
 | { | 
 |     int scaler = *((int *) arg); | 
 |  | 
 |     timer_reset(); | 
 |     timer_start(ONESHOT, scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |  | 
 |     timer_load(0); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 | } | 
 |  | 
 | static void test_timer_zero_load_periodic(gconstpointer arg) | 
 | { | 
 |     int scaler = *((int *) arg); | 
 |  | 
 |     timer_reset(); | 
 |     timer_start(PERIODIC, scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |  | 
 |     timer_load(0); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); | 
 | } | 
 |  | 
 | static void test_timer_zero_load_oneshot_to_nonzero(gconstpointer arg) | 
 | { | 
 |     int scaler = *((int *) arg); | 
 |  | 
 |     timer_reset(); | 
 |     timer_start(ONESHOT, scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); | 
 |  | 
 |     timer_load(0); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |  | 
 |     timer_load(999); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 1001); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); | 
 | } | 
 |  | 
 | static void test_timer_zero_load_periodic_to_nonzero(gconstpointer arg) | 
 | { | 
 |     int scaler = *((int *) arg); | 
 |     int i; | 
 |  | 
 |     timer_reset(); | 
 |     timer_start(PERIODIC, scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |  | 
 |     timer_load(0); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); | 
 |  | 
 |     timer_load(1999999); | 
 |  | 
 |     for (i = 1; i < 10; i++) { | 
 |         TIMER_BLOCK_STEP(scaler, 2000001); | 
 |  | 
 |         g_assert_cmpuint(timer_counter(), ==, 1999999 - i); | 
 |         g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); | 
 |         g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |     } | 
 | } | 
 |  | 
 | static void test_timer_nonzero_load_oneshot_to_zero(gconstpointer arg) | 
 | { | 
 |     int scaler = *((int *) arg); | 
 |  | 
 |     timer_reset(); | 
 |     timer_start(ONESHOT, scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |  | 
 |     timer_load(UINT32_MAX); | 
 |     timer_load(0); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 100); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); | 
 | } | 
 |  | 
 | static void test_timer_nonzero_load_periodic_to_zero(gconstpointer arg) | 
 | { | 
 |     int scaler = *((int *) arg); | 
 |  | 
 |     timer_reset(); | 
 |     timer_start(PERIODIC, scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); | 
 |  | 
 |     timer_load(UINT32_MAX); | 
 |     timer_load(0); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 100); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); | 
 | } | 
 |  | 
 | static void test_timer_set_periodic_counter_on_the_fly(gconstpointer arg) | 
 | { | 
 |     int scaler = *((int *) arg); | 
 |  | 
 |     timer_reset(); | 
 |     timer_load(UINT32_MAX / 2); | 
 |     timer_start(PERIODIC, scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 100); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, UINT32_MAX / 2 - 100); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |  | 
 |     timer_set_counter(UINT32_MAX); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 100); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 100); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 | } | 
 |  | 
 | static void test_timer_enable_and_set_counter(gconstpointer arg) | 
 | { | 
 |     int scaler = *((int *) arg); | 
 |  | 
 |     timer_reset(); | 
 |     timer_start(ONESHOT, scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); | 
 |  | 
 |     timer_set_counter(UINT32_MAX); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 100); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 100); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 | } | 
 |  | 
 | static void test_timer_set_counter_and_enable(gconstpointer arg) | 
 | { | 
 |     int scaler = *((int *) arg); | 
 |  | 
 |     timer_reset(); | 
 |     timer_set_counter(UINT32_MAX); | 
 |     timer_start(ONESHOT, scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 100); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 100); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 | } | 
 |  | 
 | static void test_timer_set_counter_disabled(void) | 
 | { | 
 |     timer_reset(); | 
 |     timer_set_counter(999999999); | 
 |  | 
 |     TIMER_BLOCK_STEP(NOSCALE, 100); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 999999999); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 | } | 
 |  | 
 | static void test_timer_load_disabled(void) | 
 | { | 
 |     timer_reset(); | 
 |     timer_load(999999999); | 
 |  | 
 |     TIMER_BLOCK_STEP(NOSCALE, 100); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 999999999); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 | } | 
 |  | 
 | static void test_timer_oneshot_with_counter_0_on_start(gconstpointer arg) | 
 | { | 
 |     int scaler = *((int *) arg); | 
 |  | 
 |     timer_reset(); | 
 |     timer_load(999); | 
 |     timer_set_counter(0); | 
 |     timer_start(ONESHOT, scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 100); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 100); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 | } | 
 |  | 
 | static void test_timer_periodic_with_counter_0_on_start(gconstpointer arg) | 
 | { | 
 |     int scaler = *((int *) arg); | 
 |     int i; | 
 |  | 
 |     timer_reset(); | 
 |     timer_load(UINT32_MAX); | 
 |     timer_set_counter(0); | 
 |  | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |  | 
 |     timer_start(PERIODIC, scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 100); | 
 |  | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); | 
 |     g_assert_cmpuint(timer_counter(), ==, UINT32_MAX + (scaler ? 1 : 0) - 100); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 100); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, UINT32_MAX + (scaler ? 1 : 0) - 200); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |  | 
 |     timer_reset(); | 
 |     timer_load(1999999); | 
 |     timer_set_counter(0); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |  | 
 |     timer_start(PERIODIC, scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); | 
 |  | 
 |     for (i = 2 - (!!scaler ? 1 : 0); i < 10; i++) { | 
 |         TIMER_BLOCK_STEP(scaler, 2000001); | 
 |  | 
 |         g_assert_cmpuint(timer_counter(), ==, 1999999 - i); | 
 |         g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); | 
 |         g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |     } | 
 | } | 
 |  | 
 | static void test_periodic_counter(gconstpointer arg) | 
 | { | 
 |     const int test_load = 10; | 
 |     int scaler = *((int *) arg); | 
 |     int test_val; | 
 |  | 
 |     timer_reset(); | 
 |     timer_load(test_load); | 
 |     timer_start(PERIODIC, scaler); | 
 |  | 
 |     clock_step(1); | 
 |  | 
 |     for (test_val = 0; test_val <= test_load; test_val++) { | 
 |         clock_step(TIMER_BLOCK_SCALE(scaler) * test_load); | 
 |         g_assert_cmpint(timer_counter(), ==, test_val); | 
 |     } | 
 | } | 
 |  | 
 | static void test_timer_set_counter_periodic_with_zero_load(gconstpointer arg) | 
 | { | 
 |     int scaler = *((int *) arg); | 
 |  | 
 |     timer_reset(); | 
 |     timer_start(PERIODIC, scaler); | 
 |     timer_load(0); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); | 
 |  | 
 |     timer_set_counter(999); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 999); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); | 
 | } | 
 |  | 
 | static void test_timer_set_oneshot_load_to_0(gconstpointer arg) | 
 | { | 
 |     int scaler = *((int *) arg); | 
 |  | 
 |     timer_reset(); | 
 |     timer_load(UINT32_MAX); | 
 |     timer_start(ONESHOT, scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 100); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 100); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |  | 
 |     timer_load(0); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 100); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 100); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 | } | 
 |  | 
 | static void test_timer_set_periodic_load_to_0(gconstpointer arg) | 
 | { | 
 |     int scaler = *((int *) arg); | 
 |  | 
 |     timer_reset(); | 
 |     timer_load(UINT32_MAX); | 
 |     timer_start(PERIODIC, scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 100); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 100); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |  | 
 |     timer_load(0); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 100); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 100); | 
 |  | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 | } | 
 |  | 
 | static void test_deferred_trigger(void) | 
 | { | 
 |     int mode = ONESHOT; | 
 |  | 
 | again: | 
 |     timer_reset(); | 
 |     timer_start(mode, 255); | 
 |  | 
 |     clock_step(100); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |  | 
 |     TIMER_BLOCK_STEP(255, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); | 
 |  | 
 |     timer_reset(); | 
 |     timer_load(2); | 
 |     timer_start(mode, 255); | 
 |  | 
 |     clock_step(100); | 
 |  | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |  | 
 |     TIMER_BLOCK_STEP(255, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |  | 
 |     TIMER_BLOCK_STEP(255, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); | 
 |  | 
 |     timer_reset(); | 
 |     timer_load(UINT32_MAX); | 
 |     timer_start(mode, 255); | 
 |  | 
 |     clock_step(100); | 
 |  | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |  | 
 |     timer_set_counter(0); | 
 |  | 
 |     clock_step(100); | 
 |  | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |  | 
 |     TIMER_BLOCK_STEP(255, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); | 
 |  | 
 |     timer_reset(); | 
 |     timer_load(UINT32_MAX); | 
 |     timer_start(mode, 255); | 
 |  | 
 |     clock_step(100); | 
 |  | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |  | 
 |     timer_load(0); | 
 |  | 
 |     clock_step(100); | 
 |  | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |  | 
 |     TIMER_BLOCK_STEP(255, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); | 
 |  | 
 |     if (mode == ONESHOT) { | 
 |         mode = PERIODIC; | 
 |         goto again; | 
 |     } | 
 | } | 
 |  | 
 | static void test_timer_zero_load_mode_switch(gconstpointer arg) | 
 | { | 
 |     int scaler = *((int *) arg); | 
 |  | 
 |     timer_reset(); | 
 |     timer_load(0); | 
 |     timer_start(PERIODIC, scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 1); | 
 |  | 
 |     timer_start(ONESHOT, scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 1); | 
 |  | 
 |     timer_start(PERIODIC, scaler); | 
 |  | 
 |     TIMER_BLOCK_STEP(scaler, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); | 
 | } | 
 |  | 
 | static void test_timer_zero_load_prescaled_periodic_to_nonscaled_oneshot(void) | 
 | { | 
 |     timer_reset(); | 
 |     timer_load(0); | 
 |     timer_start(PERIODIC, 255); | 
 |  | 
 |     TIMER_BLOCK_STEP(255, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |  | 
 |     TIMER_BLOCK_STEP(255, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |  | 
 |     TIMER_BLOCK_STEP(255, 1); | 
 |  | 
 |     timer_start(ONESHOT, NOSCALE); | 
 |  | 
 |     TIMER_BLOCK_STEP(NOSCALE, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |  | 
 |     TIMER_BLOCK_STEP(NOSCALE, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 | } | 
 |  | 
 | static void test_timer_zero_load_prescaled_oneshot_to_nonscaled_periodic(void) | 
 | { | 
 |     timer_reset(); | 
 |     timer_load(0); | 
 |     timer_start(ONESHOT, 255); | 
 |  | 
 |     TIMER_BLOCK_STEP(255, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |  | 
 |     timer_start(PERIODIC, NOSCALE); | 
 |  | 
 |     TIMER_BLOCK_STEP(NOSCALE, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 | } | 
 |  | 
 | static void test_timer_zero_load_nonscaled_oneshot_to_prescaled_periodic(void) | 
 | { | 
 |     timer_reset(); | 
 |     timer_load(0); | 
 |     timer_start(ONESHOT, NOSCALE); | 
 |  | 
 |     TIMER_BLOCK_STEP(NOSCALE, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |  | 
 |     timer_start(PERIODIC, 255); | 
 |  | 
 |     TIMER_BLOCK_STEP(255, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |  | 
 |     TIMER_BLOCK_STEP(255, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 | } | 
 |  | 
 | static void test_timer_zero_load_nonscaled_periodic_to_prescaled_oneshot(void) | 
 | { | 
 |     timer_reset(); | 
 |     timer_load(0); | 
 |     timer_start(PERIODIC, NOSCALE); | 
 |  | 
 |     TIMER_BLOCK_STEP(NOSCALE, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |  | 
 |     timer_start(ONESHOT, 255); | 
 |  | 
 |     TIMER_BLOCK_STEP(255, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 |  | 
 |     TIMER_BLOCK_STEP(255, 1); | 
 |  | 
 |     g_assert_cmpuint(timer_counter(), ==, 0); | 
 |     g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); | 
 | } | 
 |  | 
 | /* | 
 |  * Add a qtest test that comes in two versions: one with | 
 |  * a timer scaler setting, and one with the timer nonscaled. | 
 |  */ | 
 | static void add_scaler_test(const char *str, bool scale, | 
 |                             void (*fn)(const void *)) | 
 | { | 
 |     char *name; | 
 |     int *scaler = scale ? &scaled : &nonscaled; | 
 |  | 
 |     name = g_strdup_printf("%s=%d", str, *scaler); | 
 |     qtest_add_data_func(name, scaler, fn); | 
 |     g_free(name); | 
 | } | 
 |  | 
 | int main(int argc, char **argv) | 
 | { | 
 |     int ret; | 
 |     int scale; | 
 |  | 
 |     g_test_init(&argc, &argv, NULL); | 
 |  | 
 |     qtest_add_func("mptimer/deferred_trigger", test_deferred_trigger); | 
 |     qtest_add_func("mptimer/load_disabled", test_timer_load_disabled); | 
 |     qtest_add_func("mptimer/set_counter_disabled", test_timer_set_counter_disabled); | 
 |     qtest_add_func("mptimer/zero_load_prescaled_periodic_to_nonscaled_oneshot", | 
 |                    test_timer_zero_load_prescaled_periodic_to_nonscaled_oneshot); | 
 |     qtest_add_func("mptimer/zero_load_prescaled_oneshot_to_nonscaled_periodic", | 
 |                    test_timer_zero_load_prescaled_oneshot_to_nonscaled_periodic); | 
 |     qtest_add_func("mptimer/zero_load_nonscaled_oneshot_to_prescaled_periodic", | 
 |                    test_timer_zero_load_nonscaled_oneshot_to_prescaled_periodic); | 
 |     qtest_add_func("mptimer/zero_load_nonscaled_periodic_to_prescaled_oneshot", | 
 |                    test_timer_zero_load_nonscaled_periodic_to_prescaled_oneshot); | 
 |     qtest_add_func("mptimer/prescaler", test_timer_prescaler); | 
 |     qtest_add_func("mptimer/prescaler_on_the_fly", test_timer_prescaler_on_the_fly); | 
 |  | 
 |     for (scale = 0; scale < 2; scale++) { | 
 |         add_scaler_test("mptimer/oneshot scaler", | 
 |                         scale, test_timer_oneshot); | 
 |         add_scaler_test("mptimer/pause scaler", | 
 |                         scale, test_timer_pause); | 
 |         add_scaler_test("mptimer/reload scaler", | 
 |                         scale, test_timer_reload); | 
 |         add_scaler_test("mptimer/periodic scaler", | 
 |                         scale, test_timer_periodic); | 
 |         add_scaler_test("mptimer/oneshot_to_periodic scaler", | 
 |                         scale, test_timer_oneshot_to_periodic); | 
 |         add_scaler_test("mptimer/periodic_to_oneshot scaler", | 
 |                         scale, test_timer_periodic_to_oneshot); | 
 |         add_scaler_test("mptimer/set_oneshot_counter_to_0 scaler", | 
 |                         scale, test_timer_set_oneshot_counter_to_0); | 
 |         add_scaler_test("mptimer/set_periodic_counter_to_0 scaler", | 
 |                         scale, test_timer_set_periodic_counter_to_0); | 
 |         add_scaler_test("mptimer/noload_oneshot scaler", | 
 |                         scale, test_timer_noload_oneshot); | 
 |         add_scaler_test("mptimer/noload_periodic scaler", | 
 |                         scale, test_timer_noload_periodic); | 
 |         add_scaler_test("mptimer/zero_load_oneshot scaler", | 
 |                         scale, test_timer_zero_load_oneshot); | 
 |         add_scaler_test("mptimer/zero_load_periodic scaler", | 
 |                         scale, test_timer_zero_load_periodic); | 
 |         add_scaler_test("mptimer/zero_load_oneshot_to_nonzero scaler", | 
 |                         scale, test_timer_zero_load_oneshot_to_nonzero); | 
 |         add_scaler_test("mptimer/zero_load_periodic_to_nonzero scaler", | 
 |                         scale, test_timer_zero_load_periodic_to_nonzero); | 
 |         add_scaler_test("mptimer/nonzero_load_oneshot_to_zero scaler", | 
 |                         scale, test_timer_nonzero_load_oneshot_to_zero); | 
 |         add_scaler_test("mptimer/nonzero_load_periodic_to_zero scaler", | 
 |                         scale, test_timer_nonzero_load_periodic_to_zero); | 
 |         add_scaler_test("mptimer/set_periodic_counter_on_the_fly scaler", | 
 |                         scale, test_timer_set_periodic_counter_on_the_fly); | 
 |         add_scaler_test("mptimer/enable_and_set_counter scaler", | 
 |                         scale, test_timer_enable_and_set_counter); | 
 |         add_scaler_test("mptimer/set_counter_and_enable scaler", | 
 |                         scale, test_timer_set_counter_and_enable); | 
 |         add_scaler_test("mptimer/oneshot_with_counter_0_on_start scaler", | 
 |                         scale, test_timer_oneshot_with_counter_0_on_start); | 
 |         add_scaler_test("mptimer/periodic_with_counter_0_on_start scaler", | 
 |                         scale, test_timer_periodic_with_counter_0_on_start); | 
 |         add_scaler_test("mptimer/periodic_counter scaler", | 
 |                         scale, test_periodic_counter); | 
 |         add_scaler_test("mptimer/set_counter_periodic_with_zero_load scaler", | 
 |                         scale, test_timer_set_counter_periodic_with_zero_load); | 
 |         add_scaler_test("mptimer/set_oneshot_load_to_0 scaler", | 
 |                         scale, test_timer_set_oneshot_load_to_0); | 
 |         add_scaler_test("mptimer/set_periodic_load_to_0 scaler", | 
 |                         scale, test_timer_set_periodic_load_to_0); | 
 |         add_scaler_test("mptimer/zero_load_mode_switch scaler", | 
 |                         scale, test_timer_zero_load_mode_switch); | 
 |     } | 
 |  | 
 |     qtest_start("-machine vexpress-a9"); | 
 |     ret = g_test_run(); | 
 |     qtest_end(); | 
 |  | 
 |     return ret; | 
 | } |