On 19:06 Thu 21 Jan , Peter Maydell wrote: > Now that the CMSDK APB watchdog uses its Clock input, it will > correctly respond when the system clock frequency is changed using > the RCC register on in the Stellaris board system registers. Test > that when the RCC register is written it causes the watchdog timer to > change speed. > > Signed-off-by: Peter Maydell <peter.mayd...@linaro.org>
Reviewed-by: Luc Michel <l...@lmichel.fr> > --- > tests/qtest/cmsdk-apb-watchdog-test.c | 52 +++++++++++++++++++++++++++ > 1 file changed, 52 insertions(+) > > diff --git a/tests/qtest/cmsdk-apb-watchdog-test.c > b/tests/qtest/cmsdk-apb-watchdog-test.c > index c6add1fee85..9a4873a8314 100644 > --- a/tests/qtest/cmsdk-apb-watchdog-test.c > +++ b/tests/qtest/cmsdk-apb-watchdog-test.c > @@ -15,6 +15,7 @@ > */ > > #include "qemu/osdep.h" > +#include "qemu/bitops.h" > #include "libqtest-single.h" > > /* > @@ -31,6 +32,11 @@ > #define WDOGMIS 0x14 > #define WDOGLOCK 0xc00 > > +#define SSYS_BASE 0x400fe000 > +#define RCC 0x60 > +#define SYSDIV_SHIFT 23 > +#define SYSDIV_LENGTH 4 > + > static void test_watchdog(void) > { > g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 0); > @@ -61,6 +67,50 @@ static void test_watchdog(void) > g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 0); > } > > +static void test_clock_change(void) > +{ > + uint32_t rcc; > + > + /* > + * Test that writing to the stellaris board's RCC register to > + * change the system clock frequency causes the watchdog > + * to change the speed it counts at. > + */ > + g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 0); > + > + writel(WDOG_BASE + WDOGCONTROL, 1); > + writel(WDOG_BASE + WDOGLOAD, 1000); > + > + /* Step to just past the 500th tick */ > + clock_step(80 * 500 + 1); > + g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 0); > + g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 500); > + > + /* Rewrite RCC.SYSDIV from 16 to 8, so the clock is now 40ns per tick */ > + rcc = readl(SSYS_BASE + RCC); > + g_assert_cmpuint(extract32(rcc, SYSDIV_SHIFT, SYSDIV_LENGTH), ==, 0xf); > + rcc = deposit32(rcc, SYSDIV_SHIFT, SYSDIV_LENGTH, 7); > + writel(SSYS_BASE + RCC, rcc); > + > + /* Just past the 1000th tick: timer should have fired */ > + clock_step(40 * 500); > + g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 1); > + > + g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 0); > + > + /* VALUE reloads at following tick */ > + clock_step(41); > + g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 1000); > + > + /* Writing any value to WDOGINTCLR clears the interrupt and reloads */ > + clock_step(40 * 500); > + g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 500); > + g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 1); > + writel(WDOG_BASE + WDOGINTCLR, 0); > + g_assert_cmpuint(readl(WDOG_BASE + WDOGVALUE), ==, 1000); > + g_assert_cmpuint(readl(WDOG_BASE + WDOGRIS), ==, 0); > +} > + > int main(int argc, char **argv) > { > QTestState *s; > @@ -71,6 +121,8 @@ int main(int argc, char **argv) > s = qtest_start("-machine lm3s811evb"); > > qtest_add_func("/cmsdk-apb-watchdog/watchdog", test_watchdog); > + qtest_add_func("/cmsdk-apb-watchdog/watchdog_clock_change", > + test_clock_change); > > r = g_test_run(); > > -- > 2.20.1 > --