Skip to content

Instantly share code, notes, and snippets.

@digetx
Last active July 20, 2016 17:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save digetx/dbd46109503b1a91941a to your computer and use it in GitHub Desktop.
Save digetx/dbd46109503b1a91941a to your computer and use it in GitHub Desktop.
ARM MPtimer tests
#ifdef __KERNEL__
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/module.h>
#define abort() {pr_err("%s: %d\n", __func__, __LINE__); errored = 1; return;}
#define assert(a) if (!(a)) abort()
#define msleep(d) mdelay(d)
#define sleep(d) mdelay((d) * 1000)
#define UINT32_MAX U32_MAX
#else
#define _GNU_SOURCE
#include <assert.h>
#include <fcntl.h>
#include <sched.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <unistd.h>
#define pr_info(...) printf(__VA_ARGS__)
#define pr_err(...) fprintf(stderr, __VA_ARGS__)
#define msleep(d) usleep((d) * 1000)
#endif
#define RUN_TEST(t) if (!errored) t;
// #define TIMER_BASE_PHYS 0x1e000620 /* VExpress WDT */
#define TIMER_BASE_PHYS 0x50040600
#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(v) (((v) & 0xff) << 8)
#define PERIODIC 1
#define ONESHOT 0
#define NOSCALE 0
static int errored;
static int log_enb = 1;
static int scaler_test = 0;
#ifdef __KERNEL__
static void __iomem *timer_base;
static uint32_t read_mem(u32 offset)
{
return readl(timer_base + offset);
}
static void write_mem(u32 offset, uint32_t value)
{
writel(value, timer_base + offset);
}
static void map_mem(u32 phys_address, u32 size)
{
timer_base = ioremap_nocache(phys_address, size);
}
#else
static uint32_t * volatile timer_base_virt;
static uint32_t read_mem(off_t offset)
{
return timer_base_virt[offset >> 2];
}
static void write_mem(off_t offset, uint32_t value)
{
timer_base_virt[offset >> 2] = value;
}
static void map_mem(off_t phys_address, off_t size)
{
off_t PageOffset, PageAddress;
size_t PagesSize;
int mem_dev;
mem_dev = open("/dev/mem", O_RDWR | O_SYNC);
assert(mem_dev != -1);
PageOffset = phys_address % getpagesize();
PageAddress = phys_address - PageOffset;
PagesSize = ((size / getpagesize()) + 1) * getpagesize();
timer_base_virt = mmap(NULL, PagesSize, PROT_READ | PROT_WRITE,
MAP_SHARED, mem_dev, PageAddress);
assert(timer_base_virt != MAP_FAILED);
timer_base_virt += PageOffset >> 2;
}
#endif
static void timer_load(uint32_t load)
{
if (log_enb) {
pr_info("%s: %u\n", __func__, load);
}
write_mem(TIMER_LOAD, load);
}
static void timer_start(int periodic, uint32_t scale)
{
uint32_t ctl = TIMER_CONTROL_ENABLE;
scale += scaler_test;
if (log_enb) {
pr_info("%s: periodic=%d, scale=%d\n",
__func__, periodic, scale);
}
if (periodic)
ctl |= TIMER_CONTROL_PERIODIC;
if (0)
ctl |= TIMER_CONTROL_IT_ENABLE;
ctl |= TIMER_CONTROL_PRESCALER(scale);
write_mem(TIMER_CONTROL, ctl);
}
static void timer_stop(void)
{
if (log_enb) {
pr_info("%s\n", __func__);
}
write_mem(TIMER_CONTROL, 0);
}
static void timer_int_clr(void)
{
if (log_enb) {
pr_info("%s\n", __func__);
}
write_mem(TIMER_INTSTAT, 1);
}
static void timer_reset(void)
{
if (log_enb) {
pr_info("%s: +\n", __func__);
}
timer_stop();
timer_load(0);
timer_int_clr();
if (log_enb) {
pr_info("%s: -\n", __func__);
}
}
static uint32_t timer_get_and_clr_int_sts(void)
{
uint32_t int_sts = read_mem(TIMER_INTSTAT);
if (log_enb) {
pr_info("%s: %u\n", __func__, int_sts);
}
if (int_sts) {
timer_int_clr();
}
return int_sts;
}
static uint32_t timer_counter(void)
{
uint32_t counter = read_mem(TIMER_COUNTER);
if (log_enb) {
pr_info("%s: %u\n", __func__, counter);
}
return counter;
}
static void timer_set_counter(uint32_t value)
{
if (log_enb) {
pr_info("%s: %u\n", __func__, value);
}
write_mem(TIMER_COUNTER, value);
}
static void test_timer_oneshot(void)
{
pr_info("### %s ###\n", __func__);
timer_reset();
timer_load(scaler_test ? 999999 : 9999999);
timer_start(ONESHOT, NOSCALE);
assert(timer_get_and_clr_int_sts() == 0);
while (timer_counter()) {
sleep(1);
}
assert(timer_get_and_clr_int_sts() == 1);
}
static void test_timer_pause(void)
{
uint32_t prev;
pr_info("### %s ###\n", __func__);
timer_reset();
timer_load(scaler_test ? 9999999 : 999999999);
timer_start(ONESHOT, NOSCALE);
sleep(1);
prev = timer_counter();
sleep(1);
timer_stop();
assert(prev < scaler_test ? 9999999 : 999999999);
assert(timer_counter() != 0);
assert(timer_counter() < prev);
assert(timer_counter() < scaler_test ? 9999999 : 999999999);
assert(timer_get_and_clr_int_sts() == 0);
prev = timer_counter();
sleep(1);
assert(timer_counter() == prev);
assert(timer_get_and_clr_int_sts() == 0);
timer_start(ONESHOT, NOSCALE);
do {
prev = timer_counter();
sleep(1);
assert(prev == 0 || prev > timer_counter() );
} while (timer_counter() != 0);
assert(timer_get_and_clr_int_sts() == 1);
assert(timer_counter() == 0);
sleep(1);
assert(timer_get_and_clr_int_sts() == 0);
assert(timer_counter() == 0);
}
static void test_timer_reload(void)
{
uint32_t prev;
pr_info("### %s ###\n", __func__);
timer_reset();
timer_load(UINT32_MAX);
timer_start(ONESHOT, NOSCALE);
sleep(2);
prev = timer_counter();
timer_load(UINT32_MAX);
sleep(1);
timer_stop();
assert(timer_counter() > prev);
assert(timer_counter() < UINT32_MAX);
assert(timer_get_and_clr_int_sts() == 0);
}
static void test_timer_periodic(void)
{
int repeat = 10;
int it_set = 0;
pr_info("### %s ###\n", __func__);
timer_reset();
timer_load(scaler_test ? 9999 : 999999);
timer_start(PERIODIC, NOSCALE);
do {
msleep(3);
timer_counter();
if (timer_get_and_clr_int_sts()) {
it_set++;
}
} while (repeat--);
timer_stop();
assert(it_set > 1);
}
static void test_timer_oneshot_to_periodic(void)
{
uint32_t prev;
int repeat = 10;
int passed = 0;
pr_info("### %s ###\n", __func__);
timer_reset();
timer_load(scaler_test ? 9999 : 999999);
timer_start(ONESHOT, NOSCALE);
msleep(100);
prev = timer_counter();
timer_start(PERIODIC, NOSCALE);
do {
msleep(3);
if (timer_counter() > prev) {
passed = 1;
break;
}
} while (repeat--);
timer_stop();
assert(passed == 1);
assert(timer_get_and_clr_int_sts() == 1);
}
static void test_timer_periodic_to_oneshot(void)
{
pr_info("### %s ###\n", __func__);
timer_reset();
timer_load(scaler_test ? 999999 : 99999999);
timer_start(PERIODIC, NOSCALE);
msleep(3);
timer_start(ONESHOT, NOSCALE);
sleep(5);
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == 1);
}
static void test_timer_prescaler(void)
{
pr_info("### %s ###\n", __func__);
timer_reset();
timer_load(9999999);
timer_start(ONESHOT, NOSCALE);
sleep(5);
timer_stop();
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == 1);
timer_reset();
timer_load(9999999);
timer_start(ONESHOT, 0xAB);
sleep(5);
timer_stop();
assert(timer_counter() != 0);
assert(timer_get_and_clr_int_sts() == 0);
}
static void test_timer_prescaler_on_the_fly(void)
{
pr_info("### %s ###\n", __func__);
timer_reset();
timer_load(9999999);
timer_start(ONESHOT, NOSCALE);
msleep(1);
timer_start(ONESHOT, 0xAB);
sleep(5);
timer_stop();
assert(timer_counter() != 0);
assert(timer_get_and_clr_int_sts() == 0);
}
static void test_timer_set_oneshot_count_to_0(void)
{
pr_info("### %s ###\n", __func__);
timer_reset();
timer_load(UINT32_MAX);
timer_start(ONESHOT, NOSCALE);
msleep(1);
assert(timer_counter() != 0);
assert(timer_get_and_clr_int_sts() == 0);
timer_set_counter(0);
msleep(3);
timer_stop();
msleep(3);
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == !!scaler_test);
}
static void test_timer_set_periodic_count_to_0(void)
{
pr_info("### %s ###\n", __func__);
timer_reset();
timer_load(UINT32_MAX);
timer_start(PERIODIC, NOSCALE);
msleep(1);
assert(timer_counter() != 0);
assert(timer_get_and_clr_int_sts() == 0);
timer_set_counter(0);
msleep(3);
timer_stop();
assert(timer_counter() != 0);
assert(timer_get_and_clr_int_sts() == !!scaler_test);
timer_reset();
timer_set_counter(UINT32_MAX);
timer_start(PERIODIC, NOSCALE);
msleep(1);
assert(timer_counter() != 0);
assert(timer_get_and_clr_int_sts() == 0);
timer_set_counter(0);
msleep(3);
timer_stop();
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == !!scaler_test);
}
static void test_timer_clean_start_oneshot(void)
{
pr_info("### %s ###\n", __func__);
timer_reset();
timer_start(ONESHOT, NOSCALE);
msleep(3);
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == !!scaler_test);
msleep(3);
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == 0);
}
static void test_timer_clean_start_periodic(void)
{
pr_info("### %s ###\n", __func__);
timer_reset();
timer_start(PERIODIC, NOSCALE);
msleep(3);
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == !!scaler_test);
msleep(3);
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == !!scaler_test);
}
static void test_timer_zero_load_oneshot(void)
{
pr_info("### %s ###\n", __func__);
timer_reset();
timer_start(ONESHOT, NOSCALE);
msleep(3);
assert(timer_get_and_clr_int_sts() == !!scaler_test);
timer_load(0);
msleep(3);
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == !!scaler_test);
msleep(3);
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == 0);
}
static void test_timer_zero_load_periodic(void)
{
pr_info("### %s ###\n", __func__);
timer_reset();
timer_start(PERIODIC, NOSCALE);
msleep(3);
assert(timer_get_and_clr_int_sts() == !!scaler_test);
timer_load(0);
sleep(3);
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == !!scaler_test);
sleep(3);
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == !!scaler_test);
}
static void test_timer_zero_load_oneshot_to_nonzero(void)
{
pr_info("### %s ###\n", __func__);
timer_reset();
timer_start(ONESHOT, NOSCALE);
msleep(3);
assert(timer_get_and_clr_int_sts() == !!scaler_test);
timer_load(0);
msleep(3);
assert(timer_get_and_clr_int_sts() == !!scaler_test);
timer_load(999);
sleep(3);
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == 1);
}
static void test_timer_zero_load_periodic_to_nonzero(void)
{
int repeat = 10;
int it_set = 0;
pr_info("### %s ###\n", __func__);
timer_reset();
timer_start(PERIODIC, NOSCALE);
msleep(3);
assert(timer_get_and_clr_int_sts() == !!scaler_test);
timer_load(0);
msleep(3);
assert(timer_get_and_clr_int_sts() == !!scaler_test);
timer_load(scaler_test ? 1999 : 199999);
do {
msleep(3);
timer_counter();
if (timer_get_and_clr_int_sts()) {
it_set++;
}
} while (repeat--);
timer_stop();
assert(it_set > 1);
}
static void test_timer_nonzero_load_oneshot_to_zero(void)
{
pr_info("### %s ###\n", __func__);
timer_reset();
timer_start(ONESHOT, NOSCALE);
msleep(3);
assert(timer_get_and_clr_int_sts() == !!scaler_test);
timer_load(UINT32_MAX);
timer_load(0);
msleep(3);
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == !!scaler_test);
}
static void test_timer_nonzero_load_periodic_to_zero(void)
{
pr_info("### %s ###\n", __func__);
timer_reset();
timer_start(PERIODIC, NOSCALE);
msleep(3);
assert(timer_get_and_clr_int_sts() == !!scaler_test);
timer_load(UINT32_MAX);
timer_load(0);
msleep(3);
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == !!scaler_test);
}
static void test_timer_set_periodic_count_on_the_fly(void)
{
pr_info("### %s ###\n", __func__);
timer_reset();
timer_load(UINT32_MAX / 2);
timer_start(PERIODIC, NOSCALE);
msleep(3);
assert(timer_counter() < UINT32_MAX / 2);
timer_set_counter(UINT32_MAX);
msleep(3);
timer_stop();
assert(timer_counter() > UINT32_MAX / 2);
assert(timer_counter() < UINT32_MAX);
}
static void test_timer_enable_and_set_count(void)
{
pr_info("### %s ###\n", __func__);
timer_reset();
timer_start(ONESHOT, NOSCALE);
msleep(3);
assert(timer_get_and_clr_int_sts() == !!scaler_test);
timer_set_counter(UINT32_MAX);
msleep(3);
timer_stop();
assert(timer_counter() > 0);
assert(timer_counter() < UINT32_MAX);
assert(timer_get_and_clr_int_sts() == 0);
}
static void test_timer_set_count_and_enable(void)
{
pr_info("### %s ###\n", __func__);
timer_reset();
timer_set_counter(UINT32_MAX);
timer_start(ONESHOT, NOSCALE);
sleep(1);
timer_stop();
assert(timer_counter() > 0);
assert(timer_counter() < UINT32_MAX);
assert(timer_get_and_clr_int_sts() == 0);
}
static void test_timer_set_count_disabled(void)
{
pr_info("### %s ###\n", __func__);
timer_reset();
timer_set_counter(999999999);
sleep(1);
assert(timer_counter() == 999999999);
assert(timer_get_and_clr_int_sts() == 0);
}
static void test_timer_set_load_disabled(void)
{
pr_info("### %s ###\n", __func__);
timer_reset();
timer_load(999999999);
sleep(1);
assert(timer_counter() == 999999999);
assert(timer_get_and_clr_int_sts() == 0);
}
static void test_timer_oneshot_with_count_0_on_start(void)
{
timer_reset();
timer_load(999);
timer_set_counter(0);
timer_start(ONESHOT, NOSCALE);
msleep(3);
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == !!scaler_test);
msleep(3);
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == 0);
}
static void test_timer_periodic_with_count_0_on_start(void)
{
int repeat = 10;
int it_set = 0;
pr_info("### %s ###\n", __func__);
timer_reset();
timer_load(UINT32_MAX);
timer_set_counter(0);
assert(timer_get_and_clr_int_sts() == 0);
timer_start(PERIODIC, NOSCALE);
msleep(3);
assert(timer_get_and_clr_int_sts() == !!scaler_test);
msleep(3);
timer_stop();
assert(timer_counter() != 0);
assert(timer_get_and_clr_int_sts() == 0);
timer_reset();
timer_load(scaler_test ? 1999 : 199999);
timer_set_counter(0);
msleep(3);
assert(timer_get_and_clr_int_sts() == 0);
timer_start(PERIODIC, NOSCALE);
assert(timer_get_and_clr_int_sts() == 0);
do {
msleep(3);
timer_counter();
if (timer_get_and_clr_int_sts()) {
it_set++;
}
} while (repeat--);
timer_stop();
assert(it_set > 1);
}
static void test_ptimer_limit_bug(void)
{
#define TEST_LOAD 10
int test_val;
pr_info("### %s ###\n", __func__);
timer_reset();
timer_load(TEST_LOAD);
timer_start(PERIODIC, NOSCALE);
for (test_val = 0; test_val <= TEST_LOAD; test_val++) {
int retries = 999;
uint32_t counter;
pr_info("checking %d ...\n", test_val);
do {
counter = timer_counter();
assert(counter <= TEST_LOAD);
msleep(3);
} while (counter != test_val && --retries);
assert(retries > 0);
}
timer_stop();
}
static void test_ptimer_freq_period_bug(void)
{
uint32_t counter;
pr_info("### %s ###\n", __func__);
timer_reset();
timer_load(UINT32_MAX);
timer_start(ONESHOT, NOSCALE);
msleep(3);
counter = timer_counter();
timer_start(ONESHOT, 1);
msleep(1);
assert(timer_counter() < counter);
timer_stop();
}
static void test_timer_set_count_periodic_with_zero_load(void)
{
pr_info("### %s ###\n", __func__);
timer_reset();
timer_start(PERIODIC, NOSCALE);
timer_load(0);
msleep(3);
assert(timer_get_and_clr_int_sts() == !!scaler_test);
msleep(3);
assert(timer_get_and_clr_int_sts() == !!scaler_test);
timer_set_counter(999);
sleep(1);
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == 1);
sleep(1);
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == !!scaler_test);
}
static void test_it_bit(void)
{
int mode = PERIODIC;
pr_info("### %s ###\n", __func__);
scaler_test = 0;
timer_reset();
timer_start(ONESHOT, 0);
msleep(3);
assert(timer_get_and_clr_int_sts() == 0);
timer_set_counter(0);
msleep(3);
assert(timer_get_and_clr_int_sts() == 0);
timer_set_counter(0);
msleep(3);
assert(timer_get_and_clr_int_sts() == 0);
timer_load(0);
msleep(3);
assert(timer_get_and_clr_int_sts() == 0);
timer_load(0);
msleep(3);
assert(timer_get_and_clr_int_sts() == 0);
timer_start(ONESHOT, 1);
msleep(3);
assert(timer_get_and_clr_int_sts() == 1);
msleep(3);
assert(timer_get_and_clr_int_sts() == 0);
msleep(3);
timer_set_counter(0);
msleep(3);
assert(timer_get_and_clr_int_sts() == 1);
msleep(3);
assert(timer_get_and_clr_int_sts() == 0);
msleep(3);
timer_load(0);
msleep(3);
assert(timer_get_and_clr_int_sts() == 1);
timer_reset();
timer_set_counter(UINT32_MAX);
timer_start(ONESHOT, 0);
timer_set_counter(0);
assert(timer_get_and_clr_int_sts() == 0);
msleep(3);
timer_set_counter(0);
assert(timer_get_and_clr_int_sts() == 0);
timer_reset();
timer_set_counter(UINT32_MAX);
timer_start(ONESHOT, 255);
timer_set_counter(0);
assert(timer_get_and_clr_int_sts() == 0);
timer_set_counter(0);
msleep(3);
assert(timer_get_and_clr_int_sts() == 1);
timer_reset();
timer_load(UINT32_MAX);
timer_start(ONESHOT, 0);
timer_load(0);
assert(timer_get_and_clr_int_sts() == 0);
timer_load(0);
msleep(3);
assert(timer_get_and_clr_int_sts() == 0);
timer_reset();
timer_load(UINT32_MAX);
timer_start(ONESHOT, 255);
timer_load(0);
assert(timer_get_and_clr_int_sts() == 0);
timer_load(0);
msleep(3);
assert(timer_get_and_clr_int_sts() == 1);
#define ASSERT(p) \
msleep(5); \
if (!(p)) { \
pr_err("scaler = 0x%X %s\n", scaler_test, \
mode == PERIODIC ? "periodic" : "oneshot"); \
assert(0); \
} \
msleep(5);
again:
for (scaler_test = 0; scaler_test <= 0xFF; scaler_test++) {
int sts_expected = !!scaler_test;
int o = (mode == ONESHOT);
timer_reset();
timer_start(mode, NOSCALE);
ASSERT(timer_get_and_clr_int_sts() == sts_expected);
ASSERT(timer_get_and_clr_int_sts() == (o ? 0 : sts_expected));
timer_load(0);
ASSERT(timer_get_and_clr_int_sts() == sts_expected);
ASSERT(timer_get_and_clr_int_sts() == (o ? 0 : sts_expected));
timer_start(mode, 1);
ASSERT(timer_get_and_clr_int_sts() == (!o ? 1 : (scaler_test != 0xFF)));
ASSERT(timer_get_and_clr_int_sts() == (o ? 0 : (scaler_test != 0xFF)));
timer_start(mode, 1);
ASSERT(timer_get_and_clr_int_sts() == (scaler_test != 0xFF));
timer_reset();
timer_start(mode, NOSCALE);
timer_set_counter(0);
ASSERT(timer_get_and_clr_int_sts() == sts_expected);
ASSERT(timer_get_and_clr_int_sts() == (o ? 0 : sts_expected));
timer_start(mode, 1);
ASSERT(timer_get_and_clr_int_sts() == (!o ? 1 : (scaler_test != 0xFF)));
ASSERT(timer_get_and_clr_int_sts() == (o ? 0 : (scaler_test != 0xFF)));
timer_start(mode, 1);
ASSERT(timer_get_and_clr_int_sts() == (scaler_test != 0xFF));
timer_reset();
timer_load(UINT32_MAX);
timer_start(mode, NOSCALE);
ASSERT(timer_counter() > 0);
ASSERT(timer_get_and_clr_int_sts() == 0);
timer_set_counter(0);
ASSERT(timer_get_and_clr_int_sts() == sts_expected);
ASSERT(timer_get_and_clr_int_sts() == 0);
timer_start(mode, 1);
ASSERT(timer_get_and_clr_int_sts() == (!o ? 0 : (scaler_test != 0xFF)));
ASSERT(timer_get_and_clr_int_sts() == 0);
timer_start(mode, 1);
ASSERT(timer_get_and_clr_int_sts() == (!o ? 0 : (scaler_test != 0xFF)));
timer_reset();
timer_set_counter(UINT32_MAX);
timer_start(mode, NOSCALE);
ASSERT(timer_get_and_clr_int_sts() == 0);
timer_load(0);
ASSERT(timer_get_and_clr_int_sts() == sts_expected);
ASSERT(timer_get_and_clr_int_sts() == (o ? 0 : sts_expected));
timer_start(mode, 1);
ASSERT(timer_get_and_clr_int_sts() == (!o ? 1 : (scaler_test != 0xFF)));
ASSERT(timer_get_and_clr_int_sts() == (o ? 0 : (scaler_test != 0xFF)));
timer_start(mode, 1);
ASSERT(timer_get_and_clr_int_sts() == (scaler_test != 0xFF));
timer_reset();
timer_start(mode, NOSCALE);
ASSERT(timer_get_and_clr_int_sts() == sts_expected);
ASSERT(timer_get_and_clr_int_sts() == (o ? 0 : sts_expected));
timer_start(!mode, NOSCALE);
ASSERT(timer_get_and_clr_int_sts() == (sts_expected));
ASSERT(timer_get_and_clr_int_sts() == (!o ? 0 : sts_expected));
timer_start(mode, 1);
ASSERT(timer_get_and_clr_int_sts() == (o ? 1 : (scaler_test != 0xFF)));
ASSERT(timer_get_and_clr_int_sts() == (o ? 0 : (scaler_test != 0xFF)));
timer_start(mode, 1);
ASSERT(timer_get_and_clr_int_sts() == (scaler_test != 0xFF));
timer_reset();
timer_start(mode, NOSCALE);
timer_load(0);
timer_set_counter(0);
ASSERT(timer_get_and_clr_int_sts() == sts_expected);
ASSERT(timer_get_and_clr_int_sts() == (o ? 0 : sts_expected));
timer_start(mode, 1);
ASSERT(timer_get_and_clr_int_sts() == (!o ? 1 : (scaler_test != 0xFF)));
ASSERT(timer_get_and_clr_int_sts() == (o ? 0 : (scaler_test != 0xFF)));
timer_start(mode, 1);
ASSERT(timer_get_and_clr_int_sts() == (scaler_test != 0xFF));
timer_reset();
timer_set_counter(UINT32_MAX);
timer_start(mode, NOSCALE);
timer_set_counter(0);
ASSERT(timer_get_and_clr_int_sts() == sts_expected);
ASSERT(timer_get_and_clr_int_sts() == (o ? 0 : sts_expected));
timer_start(mode, 1);
ASSERT(timer_get_and_clr_int_sts() == (!o ? 1 : (scaler_test != 0xFF)));
ASSERT(timer_get_and_clr_int_sts() == (o ? 0 : (scaler_test != 0xFF)));
timer_start(mode, 1);
ASSERT(timer_get_and_clr_int_sts() == (scaler_test != 0xFF));
timer_reset();
timer_set_counter(UINT32_MAX);
timer_start(mode, NOSCALE);
timer_load(0);
ASSERT(timer_get_and_clr_int_sts() == sts_expected);
ASSERT(timer_get_and_clr_int_sts() == (o ? 0 : sts_expected));
timer_start(mode, 1);
ASSERT(timer_get_and_clr_int_sts() == (!o ? 1 : (scaler_test != 0xFF)));
ASSERT(timer_get_and_clr_int_sts() == (o ? 0 : (scaler_test != 0xFF)));
timer_start(mode, 1);
ASSERT(timer_get_and_clr_int_sts() == (scaler_test != 0xFF));
}
#undef ASSERT
if (mode == PERIODIC) {
mode = ONESHOT;
goto again;
}
}
static void test_timer_set_oneshot_load_to_0(void)
{
pr_info("### %s ###\n", __func__);
timer_reset();
timer_load(UINT32_MAX);
timer_start(ONESHOT, NOSCALE);
msleep(3);
assert(timer_get_and_clr_int_sts() == 0);
timer_load(0);
msleep(3);
timer_stop();
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == !!scaler_test);
}
static void test_timer_set_periodic_load_to_0(void)
{
pr_info("### %s ###\n", __func__);
timer_reset();
timer_load(UINT32_MAX);
timer_start(PERIODIC, NOSCALE);
msleep(3);
timer_load(0);
msleep(3);
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == !!scaler_test);
msleep(3);
assert(timer_get_and_clr_int_sts() == !!scaler_test);
assert(timer_counter() == 0);
}
static void test_delayed_it_set_icount_only(void)
{
pr_info("### %s ###\n", __func__);
timer_reset();
timer_start(PERIODIC, 255);
msleep(3);
assert(timer_get_and_clr_int_sts() == 1);
msleep(3);
assert(timer_get_and_clr_int_sts() == 1);
}
static void test_delayed_it_set(void)
{
int mode = ONESHOT;
int tries, passed;
pr_info("### %s ###\n", __func__);
#define MAX_TRIES 5
again:
tries = MAX_TRIES;
passed = 0;
while (tries--) {
timer_reset();
timer_start(mode, 255);
if (timer_counter() == 0) {
passed = 1;
break;
}
}
msleep(3);
assert(passed == 1);
assert(timer_get_and_clr_int_sts() == 1);
tries = MAX_TRIES;
passed = 0;
while (tries--) {
timer_reset();
timer_load(2);
timer_start(mode, 255);
if (timer_counter() == 2) {
passed = 1;
break;
}
}
msleep(3);
assert(passed == 1);
assert(timer_get_and_clr_int_sts() == 1);
tries = MAX_TRIES;
passed = 1;
while (tries--) {
timer_reset();
timer_load(UINT32_MAX);
timer_start(mode, 255);
timer_set_counter(0);
if (timer_get_and_clr_int_sts() == 1) {
passed = 0;
break;
}
}
assert(passed == 1);
msleep(3);
assert(timer_get_and_clr_int_sts() == 1);
tries = MAX_TRIES;
passed = 1;
while (tries--) {
timer_reset();
timer_load(UINT32_MAX);
timer_start(mode, 255);
timer_load(0);
if (timer_get_and_clr_int_sts() == 1) {
passed = 0;
break;
}
}
assert(passed == 1);
msleep(3);
assert(timer_get_and_clr_int_sts() == 1);
if (mode == ONESHOT) {
mode = PERIODIC;
goto again;
}
}
static void test_timer_zero_load_mode_switch(void)
{
pr_info("### %s ###\n", __func__);
timer_reset();
timer_load(0);
timer_start(PERIODIC, NOSCALE);
msleep(3);
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == !!scaler_test);
msleep(3);
timer_start(ONESHOT, NOSCALE);
msleep(3);
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == !!scaler_test);
msleep(3);
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == 0);
msleep(3);
timer_start(PERIODIC, NOSCALE);
msleep(3);
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == !!scaler_test);
}
static void test_timer_zero_load_prescaled_periodic_to_nonscaled_oneshot(void)
{
pr_info("### %s ###\n", __func__);
timer_reset();
timer_load(0);
timer_start(PERIODIC, 255);
msleep(3);
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == 1);
msleep(3);
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == 1);
msleep(3);
timer_start(ONESHOT, NOSCALE);
msleep(3);
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == 1);
msleep(3);
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == 0);
}
static void test_timer_zero_load_prescaled_oneshot_to_nonscaled_periodic(void)
{
pr_info("### %s ###\n", __func__);
timer_reset();
timer_load(0);
timer_start(ONESHOT, 255);
msleep(3);
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == 1);
timer_start(PERIODIC, NOSCALE);
msleep(3);
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == 0);
}
static void test_timer_zero_load_nonscaled_oneshot_to_prescaled_periodic(void)
{
pr_info("### %s ###\n", __func__);
timer_reset();
timer_load(0);
timer_start(ONESHOT, NOSCALE);
msleep(3);
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == 0);
timer_start(PERIODIC, 255);
msleep(3);
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == 1);
msleep(3);
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == 1);
}
static void test_timer_zero_load_nonscaled_periodic_to_prescaled_oneshot(void)
{
pr_info("### %s ###\n", __func__);
timer_reset();
timer_load(0);
timer_start(PERIODIC, NOSCALE);
msleep(3);
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == 0);
timer_start(ONESHOT, 255);
msleep(3);
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == 1);
msleep(3);
assert(timer_counter() == 0);
assert(timer_get_and_clr_int_sts() == 0);
}
#ifndef __KERNEL__
static void set_cpu_affinity(void)
{
cpu_set_t mask;
CPU_ZERO(&mask);
CPU_SET(0, &mask);
assert(sched_setaffinity(0, sizeof(mask), &mask) == 0);
}
int main(void)
{
set_cpu_affinity();
#else
static int mptimer_tests(void)
{
#endif
map_mem(TIMER_BASE_PHYS, 0x10);
RUN_TEST( test_delayed_it_set_icount_only() );
RUN_TEST( test_ptimer_limit_bug() );
RUN_TEST( test_delayed_it_set() );
RUN_TEST( test_timer_zero_load_prescaled_periodic_to_nonscaled_oneshot() );
RUN_TEST( test_timer_zero_load_prescaled_oneshot_to_nonscaled_periodic() );
RUN_TEST( test_timer_zero_load_nonscaled_oneshot_to_prescaled_periodic() );
RUN_TEST( test_timer_zero_load_nonscaled_periodic_to_prescaled_oneshot() );
RUN_TEST( test_timer_prescaler() );
RUN_TEST( test_timer_prescaler_on_the_fly() );
start:
RUN_TEST( test_timer_set_count_disabled() );
RUN_TEST( test_timer_set_load_disabled() );
RUN_TEST( test_timer_oneshot() );
RUN_TEST( test_timer_pause() );
RUN_TEST( test_timer_reload() );
RUN_TEST( test_timer_periodic() );
RUN_TEST( test_timer_oneshot_to_periodic() );
RUN_TEST( test_timer_periodic_to_oneshot() );
RUN_TEST( test_timer_set_oneshot_count_to_0() );
RUN_TEST( test_timer_set_periodic_count_to_0() );
RUN_TEST( test_timer_clean_start_oneshot() );
RUN_TEST( test_timer_clean_start_periodic() );
RUN_TEST( test_timer_zero_load_oneshot() );
RUN_TEST( test_timer_zero_load_periodic() );
RUN_TEST( test_timer_zero_load_oneshot_to_nonzero() );
RUN_TEST( test_timer_zero_load_periodic_to_nonzero() );
RUN_TEST( test_timer_nonzero_load_oneshot_to_zero() );
RUN_TEST( test_timer_nonzero_load_periodic_to_zero() );
RUN_TEST( test_timer_set_periodic_count_on_the_fly() );
RUN_TEST( test_timer_enable_and_set_count() );
RUN_TEST( test_timer_set_count_and_enable() );
RUN_TEST( test_timer_oneshot_with_count_0_on_start() );
RUN_TEST( test_timer_periodic_with_count_0_on_start() );
RUN_TEST( test_ptimer_freq_period_bug() );
RUN_TEST( test_timer_set_count_periodic_with_zero_load() );
RUN_TEST( test_timer_set_oneshot_load_to_0() );
RUN_TEST( test_timer_set_periodic_load_to_0() );
RUN_TEST( test_timer_zero_load_mode_switch() );
if (scaler_test == 0) {
scaler_test = 122;
goto start;
}
RUN_TEST( test_it_bit() );
if (errored) {
pr_err("tests failed!!!\n");
} else {
pr_info("tests passed\n");
}
#ifdef __KERNEL__
return -1;
}
module_init(mptimer_tests);
MODULE_LICENSE("GPL");
#else
return 0;
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment