xref: /openbmc/qemu/tests/qtest/cmsdk-apb-watchdog-test.c (revision 9cf5eb29b24d0a620127e2b0b3a92d3d6ea8991a)
1 /*
2  * QTest testcase for the CMSDK APB watchdog device
3  *
4  * Copyright (c) 2021 Linaro Limited
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the
8  * Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14  * for more details.
15  */
16 
17 #include "qemu/osdep.h"
18 #include "libqtest-single.h"
19 
20 /*
21  * lm3s811evb watchdog; at board startup this runs at 200MHz / 16 == 12.5MHz,
22  * which is 80ns per tick.
23  */
24 #define WDOG_BASE 0x40000000
25 
26 #define WDOGLOAD 0
27 #define WDOGVALUE 4
28 #define WDOGCONTROL 8
29 #define WDOGINTCLR 0xc
30 #define WDOGRIS 0x10
31 #define WDOGMIS 0x14
32 #define WDOGLOCK 0xc00
33 
34 static void test_watchdog(void)
35 {
36     g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 0);
37 
38     writel(WDOG_BASE + WDOGCONTROL, 1);
39     writel(WDOG_BASE + WDOGLOAD, 1000);
40 
41     /* Step to just past the 500th tick */
42     clock_step(500 * 80 + 1);
43     g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 0);
44     g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 500);
45 
46     /* Just past the 1000th tick: timer should have fired */
47     clock_step(500 * 80);
48     g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 1);
49     g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 0);
50 
51     /* VALUE reloads at following tick */
52     clock_step(80);
53     g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 1000);
54 
55     /* Writing any value to WDOGINTCLR clears the interrupt and reloads */
56     clock_step(500 * 80);
57     g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 500);
58     g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 1);
59     writel(WDOG_BASE + WDOGINTCLR, 0);
60     g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 1000);
61     g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 0);
62 }
63 
64 int main(int argc, char **argv)
65 {
66     int r;
67 
68     g_test_init(&argc, &argv, NULL);
69 
70     qtest_start("-machine lm3s811evb");
71 
72     qtest_add_func("/cmsdk-apb-watchdog/watchdog", test_watchdog);
73 
74     r = g_test_run();
75 
76     qtest_end();
77 
78     return r;
79 }
80