1*30858dafSPeter Maydell /* 2*30858dafSPeter Maydell * QTest testcase for the CMSDK APB timer device 3*30858dafSPeter Maydell * 4*30858dafSPeter Maydell * Copyright (c) 2021 Linaro Limited 5*30858dafSPeter Maydell * 6*30858dafSPeter Maydell * This program is free software; you can redistribute it and/or modify it 7*30858dafSPeter Maydell * under the terms of the GNU General Public License as published by the 8*30858dafSPeter Maydell * Free Software Foundation; either version 2 of the License, or 9*30858dafSPeter Maydell * (at your option) any later version. 10*30858dafSPeter Maydell * 11*30858dafSPeter Maydell * This program is distributed in the hope that it will be useful, but WITHOUT 12*30858dafSPeter Maydell * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13*30858dafSPeter Maydell * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14*30858dafSPeter Maydell * for more details. 15*30858dafSPeter Maydell */ 16*30858dafSPeter Maydell 17*30858dafSPeter Maydell #include "qemu/osdep.h" 18*30858dafSPeter Maydell #include "libqtest-single.h" 19*30858dafSPeter Maydell 20*30858dafSPeter Maydell /* IoTKit/ARMSSE-200 timer0; driven at 25MHz in mps2-an385, so 40ns per tick */ 21*30858dafSPeter Maydell #define TIMER_BASE 0x40000000 22*30858dafSPeter Maydell 23*30858dafSPeter Maydell #define CTRL 0 24*30858dafSPeter Maydell #define VALUE 4 25*30858dafSPeter Maydell #define RELOAD 8 26*30858dafSPeter Maydell #define INTSTATUS 0xc 27*30858dafSPeter Maydell 28*30858dafSPeter Maydell static void test_timer(void) 29*30858dafSPeter Maydell { 30*30858dafSPeter Maydell g_assert_true(readl(TIMER_BASE + INTSTATUS) == 0); 31*30858dafSPeter Maydell 32*30858dafSPeter Maydell /* Start timer: will fire after 40 * 1000 == 40000 ns */ 33*30858dafSPeter Maydell writel(TIMER_BASE + RELOAD, 1000); 34*30858dafSPeter Maydell writel(TIMER_BASE + CTRL, 9); 35*30858dafSPeter Maydell 36*30858dafSPeter Maydell /* Step to just past the 500th tick and check VALUE */ 37*30858dafSPeter Maydell clock_step(40 * 500 + 1); 38*30858dafSPeter Maydell g_assert_cmpuint(readl(TIMER_BASE + INTSTATUS), ==, 0); 39*30858dafSPeter Maydell g_assert_cmpuint(readl(TIMER_BASE + VALUE), ==, 500); 40*30858dafSPeter Maydell 41*30858dafSPeter Maydell /* Just past the 1000th tick: timer should have fired */ 42*30858dafSPeter Maydell clock_step(40 * 500); 43*30858dafSPeter Maydell g_assert_cmpuint(readl(TIMER_BASE + INTSTATUS), ==, 1); 44*30858dafSPeter Maydell g_assert_cmpuint(readl(TIMER_BASE + VALUE), ==, 0); 45*30858dafSPeter Maydell 46*30858dafSPeter Maydell /* VALUE reloads at the following tick */ 47*30858dafSPeter Maydell clock_step(40); 48*30858dafSPeter Maydell g_assert_cmpuint(readl(TIMER_BASE + VALUE), ==, 1000); 49*30858dafSPeter Maydell 50*30858dafSPeter Maydell /* Check write-1-to-clear behaviour of INTSTATUS */ 51*30858dafSPeter Maydell writel(TIMER_BASE + INTSTATUS, 0); 52*30858dafSPeter Maydell g_assert_cmpuint(readl(TIMER_BASE + INTSTATUS), ==, 1); 53*30858dafSPeter Maydell writel(TIMER_BASE + INTSTATUS, 1); 54*30858dafSPeter Maydell g_assert_cmpuint(readl(TIMER_BASE + INTSTATUS), ==, 0); 55*30858dafSPeter Maydell 56*30858dafSPeter Maydell /* Turn off the timer */ 57*30858dafSPeter Maydell writel(TIMER_BASE + CTRL, 0); 58*30858dafSPeter Maydell } 59*30858dafSPeter Maydell 60*30858dafSPeter Maydell int main(int argc, char **argv) 61*30858dafSPeter Maydell { 62*30858dafSPeter Maydell int r; 63*30858dafSPeter Maydell 64*30858dafSPeter Maydell g_test_init(&argc, &argv, NULL); 65*30858dafSPeter Maydell 66*30858dafSPeter Maydell qtest_start("-machine mps2-an385"); 67*30858dafSPeter Maydell 68*30858dafSPeter Maydell qtest_add_func("/cmsdk-apb-timer/timer", test_timer); 69*30858dafSPeter Maydell 70*30858dafSPeter Maydell r = g_test_run(); 71*30858dafSPeter Maydell 72*30858dafSPeter Maydell qtest_end(); 73*30858dafSPeter Maydell 74*30858dafSPeter Maydell return r; 75*30858dafSPeter Maydell } 76