1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090 |
- /*
- * 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;
- }
|