2 * QTest testcase for the Nuvoton NPCM7xx Timer
4 * Copyright 2020 Google LLC
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.
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
17 #include "qemu/osdep.h"
18 #include "qemu/timer.h"
19 #include "libqtest-single.h"
21 #define TIM_REF_HZ (25000000)
26 #define MODE_ONESHOT (0 << 27)
27 #define MODE_PERIODIC (1 << 27)
30 #define PRESCALE(x) (x)
32 /* Registers shared between all timers in a module. */
35 # define WTCLK(x) ((x) << 10)
37 /* Power-on default; used to re-initialize timers before each test. */
38 #define TCSR_DEFAULT PRESCALE(5)
40 /* Register offsets for a timer within a timer block. */
41 typedef struct Timer
{
42 unsigned int tcsr_offset
;
43 unsigned int ticr_offset
;
44 unsigned int tdr_offset
;
47 /* A timer block containing 5 timers. */
48 typedef struct TimerBlock
{
53 /* Testdata for testing a particular timer within a timer block. */
54 typedef struct TestData
{
55 const TimerBlock
*tim
;
59 const TimerBlock timer_block
[] = {
62 .base_addr
= 0xf0008000,
66 .base_addr
= 0xf0009000,
70 .base_addr
= 0xf000a000,
74 const Timer timer
[] = {
98 /* Returns the index of the timer block. */
99 static int tim_index(const TimerBlock
*tim
)
101 ptrdiff_t diff
= tim
- timer_block
;
103 g_assert(diff
>= 0 && diff
< ARRAY_SIZE(timer_block
));
108 /* Returns the index of a timer within a timer block. */
109 static int timer_index(const Timer
*t
)
111 ptrdiff_t diff
= t
- timer
;
113 g_assert(diff
>= 0 && diff
< ARRAY_SIZE(timer
));
118 /* Returns the irq line for a given timer. */
119 static int tim_timer_irq(const TestData
*td
)
121 return td
->tim
->irq_base
+ timer_index(td
->timer
);
124 /* Register read/write accessors. */
126 static void tim_write(const TestData
*td
,
127 unsigned int offset
, uint32_t value
)
129 writel(td
->tim
->base_addr
+ offset
, value
);
132 static uint32_t tim_read(const TestData
*td
, unsigned int offset
)
134 return readl(td
->tim
->base_addr
+ offset
);
137 static void tim_write_tcsr(const TestData
*td
, uint32_t value
)
139 tim_write(td
, td
->timer
->tcsr_offset
, value
);
142 static uint32_t tim_read_tcsr(const TestData
*td
)
144 return tim_read(td
, td
->timer
->tcsr_offset
);
147 static void tim_write_ticr(const TestData
*td
, uint32_t value
)
149 tim_write(td
, td
->timer
->ticr_offset
, value
);
152 static uint32_t tim_read_ticr(const TestData
*td
)
154 return tim_read(td
, td
->timer
->ticr_offset
);
157 static uint32_t tim_read_tdr(const TestData
*td
)
159 return tim_read(td
, td
->timer
->tdr_offset
);
162 /* Returns the number of nanoseconds to count the given number of cycles. */
163 static int64_t tim_calculate_step(uint32_t count
, uint32_t prescale
)
165 return (1000000000LL / TIM_REF_HZ
) * count
* (prescale
+ 1);
168 /* Returns a bitmask corresponding to the timer under test. */
169 static uint32_t tim_timer_bit(const TestData
*td
)
171 return BIT(timer_index(td
->timer
));
174 /* Resets all timers to power-on defaults. */
175 static void tim_reset(const TestData
*td
)
179 /* Reset all the timers, in case a previous test left a timer running. */
180 for (i
= 0; i
< ARRAY_SIZE(timer_block
); i
++) {
181 for (j
= 0; j
< ARRAY_SIZE(timer
); j
++) {
182 writel(timer_block
[i
].base_addr
+ timer
[j
].tcsr_offset
,
183 CRST
| TCSR_DEFAULT
);
185 writel(timer_block
[i
].base_addr
+ TISR
, -1);
189 /* Verifies the reset state of a timer. */
190 static void test_reset(gconstpointer test_data
)
192 const TestData
*td
= test_data
;
196 g_assert_cmphex(tim_read_tcsr(td
), ==, TCSR_DEFAULT
);
197 g_assert_cmphex(tim_read_ticr(td
), ==, 0);
198 g_assert_cmphex(tim_read_tdr(td
), ==, 0);
199 g_assert_cmphex(tim_read(td
, TISR
), ==, 0);
200 g_assert_cmphex(tim_read(td
, WTCR
), ==, WTCLK(1));
203 /* Verifies that CRST wins if both CEN and CRST are set. */
204 static void test_reset_overrides_enable(gconstpointer test_data
)
206 const TestData
*td
= test_data
;
210 /* CRST should force CEN to 0 */
211 tim_write_tcsr(td
, CEN
| CRST
| TCSR_DEFAULT
);
213 g_assert_cmphex(tim_read_tcsr(td
), ==, TCSR_DEFAULT
);
214 g_assert_cmphex(tim_read_tdr(td
), ==, 0);
215 g_assert_cmphex(tim_read(td
, TISR
), ==, 0);
218 /* Verifies the behavior when CEN is set and then cleared. */
219 static void test_oneshot_enable_then_disable(gconstpointer test_data
)
221 const TestData
*td
= test_data
;
225 /* Enable the timer with zero initial count, then disable it again. */
226 tim_write_tcsr(td
, CEN
| TCSR_DEFAULT
);
227 tim_write_tcsr(td
, TCSR_DEFAULT
);
229 g_assert_cmphex(tim_read_tcsr(td
), ==, TCSR_DEFAULT
);
230 g_assert_cmphex(tim_read_tdr(td
), ==, 0);
231 /* Timer interrupt flag should be set, but interrupts are not enabled. */
232 g_assert_cmphex(tim_read(td
, TISR
), ==, tim_timer_bit(td
));
233 g_assert_false(qtest_get_irq(global_qtest
, tim_timer_irq(td
)));
236 /* Verifies that a one-shot timer fires when expected with prescaler 5. */
237 static void test_oneshot_ps5(gconstpointer test_data
)
239 const TestData
*td
= test_data
;
240 unsigned int count
= 256;
245 tim_write_ticr(td
, count
);
246 tim_write_tcsr(td
, CEN
| PRESCALE(ps
));
247 g_assert_cmphex(tim_read_tcsr(td
), ==, CEN
| CACT
| PRESCALE(ps
));
248 g_assert_cmpuint(tim_read_tdr(td
), ==, count
);
250 clock_step(tim_calculate_step(count
, ps
) - 1);
252 g_assert_cmphex(tim_read_tcsr(td
), ==, CEN
| CACT
| PRESCALE(ps
));
253 g_assert_cmpuint(tim_read_tdr(td
), <, count
);
254 g_assert_cmphex(tim_read(td
, TISR
), ==, 0);
258 g_assert_cmphex(tim_read_tcsr(td
), ==, PRESCALE(ps
));
259 g_assert_cmpuint(tim_read_tdr(td
), ==, count
);
260 g_assert_cmphex(tim_read(td
, TISR
), ==, tim_timer_bit(td
));
261 g_assert_false(qtest_get_irq(global_qtest
, tim_timer_irq(td
)));
263 /* Clear the interrupt flag. */
264 tim_write(td
, TISR
, tim_timer_bit(td
));
265 g_assert_cmphex(tim_read(td
, TISR
), ==, 0);
266 g_assert_false(qtest_get_irq(global_qtest
, tim_timer_irq(td
)));
268 /* Verify that this isn't a periodic timer. */
269 clock_step(2 * tim_calculate_step(count
, ps
));
270 g_assert_cmphex(tim_read(td
, TISR
), ==, 0);
271 g_assert_false(qtest_get_irq(global_qtest
, tim_timer_irq(td
)));
274 /* Verifies that a one-shot timer fires when expected with prescaler 0. */
275 static void test_oneshot_ps0(gconstpointer test_data
)
277 const TestData
*td
= test_data
;
278 unsigned int count
= 1;
283 tim_write_ticr(td
, count
);
284 tim_write_tcsr(td
, CEN
| PRESCALE(ps
));
285 g_assert_cmphex(tim_read_tcsr(td
), ==, CEN
| CACT
| PRESCALE(ps
));
286 g_assert_cmpuint(tim_read_tdr(td
), ==, count
);
288 clock_step(tim_calculate_step(count
, ps
) - 1);
290 g_assert_cmphex(tim_read_tcsr(td
), ==, CEN
| CACT
| PRESCALE(ps
));
291 g_assert_cmpuint(tim_read_tdr(td
), <, count
);
292 g_assert_cmphex(tim_read(td
, TISR
), ==, 0);
296 g_assert_cmphex(tim_read_tcsr(td
), ==, PRESCALE(ps
));
297 g_assert_cmpuint(tim_read_tdr(td
), ==, count
);
298 g_assert_cmphex(tim_read(td
, TISR
), ==, tim_timer_bit(td
));
299 g_assert_false(qtest_get_irq(global_qtest
, tim_timer_irq(td
)));
302 /* Verifies that a one-shot timer fires when expected with highest prescaler. */
303 static void test_oneshot_ps255(gconstpointer test_data
)
305 const TestData
*td
= test_data
;
306 unsigned int count
= (1U << 24) - 1;
307 unsigned int ps
= 255;
311 tim_write_ticr(td
, count
);
312 tim_write_tcsr(td
, CEN
| PRESCALE(ps
));
313 g_assert_cmphex(tim_read_tcsr(td
), ==, CEN
| CACT
| PRESCALE(ps
));
314 g_assert_cmpuint(tim_read_tdr(td
), ==, count
);
316 clock_step(tim_calculate_step(count
, ps
) - 1);
318 g_assert_cmphex(tim_read_tcsr(td
), ==, CEN
| CACT
| PRESCALE(ps
));
319 g_assert_cmpuint(tim_read_tdr(td
), <, count
);
320 g_assert_cmphex(tim_read(td
, TISR
), ==, 0);
324 g_assert_cmphex(tim_read_tcsr(td
), ==, PRESCALE(ps
));
325 g_assert_cmpuint(tim_read_tdr(td
), ==, count
);
326 g_assert_cmphex(tim_read(td
, TISR
), ==, tim_timer_bit(td
));
327 g_assert_false(qtest_get_irq(global_qtest
, tim_timer_irq(td
)));
330 /* Verifies that a oneshot timer fires an interrupt when expected. */
331 static void test_oneshot_interrupt(gconstpointer test_data
)
333 const TestData
*td
= test_data
;
334 unsigned int count
= 256;
339 tim_write_ticr(td
, count
);
340 tim_write_tcsr(td
, IE
| CEN
| MODE_ONESHOT
| PRESCALE(ps
));
344 g_assert_cmphex(tim_read(td
, TISR
), ==, tim_timer_bit(td
));
345 g_assert_true(qtest_get_irq(global_qtest
, tim_timer_irq(td
)));
349 * Verifies that the timer can be paused and later resumed, and it still fires
350 * at the right moment.
352 static void test_pause_resume(gconstpointer test_data
)
354 const TestData
*td
= test_data
;
355 unsigned int count
= 256;
360 tim_write_ticr(td
, count
);
361 tim_write_tcsr(td
, IE
| CEN
| MODE_ONESHOT
| PRESCALE(ps
));
363 /* Pause the timer halfway to expiration. */
364 clock_step(tim_calculate_step(count
/ 2, ps
));
365 tim_write_tcsr(td
, IE
| MODE_ONESHOT
| PRESCALE(ps
));
366 g_assert_cmpuint(tim_read_tdr(td
), ==, count
/ 2);
368 /* Counter should not advance during the following step. */
369 clock_step(2 * tim_calculate_step(count
, ps
));
370 g_assert_cmpuint(tim_read_tdr(td
), ==, count
/ 2);
371 g_assert_cmphex(tim_read(td
, TISR
), ==, 0);
372 g_assert_false(qtest_get_irq(global_qtest
, tim_timer_irq(td
)));
374 /* Resume the timer and run _almost_ to expiration. */
375 tim_write_tcsr(td
, IE
| CEN
| MODE_ONESHOT
| PRESCALE(ps
));
376 clock_step(tim_calculate_step(count
/ 2, ps
) - 1);
377 g_assert_cmpuint(tim_read_tdr(td
), <, count
);
378 g_assert_cmphex(tim_read(td
, TISR
), ==, 0);
379 g_assert_false(qtest_get_irq(global_qtest
, tim_timer_irq(td
)));
381 /* Now, run the rest of the way and verify that the interrupt fires. */
383 g_assert_cmphex(tim_read(td
, TISR
), ==, tim_timer_bit(td
));
384 g_assert_true(qtest_get_irq(global_qtest
, tim_timer_irq(td
)));
387 /* Verifies that the prescaler can be changed while the timer is running. */
388 static void test_prescaler_change(gconstpointer test_data
)
390 const TestData
*td
= test_data
;
391 unsigned int count
= 256;
396 tim_write_ticr(td
, count
);
397 tim_write_tcsr(td
, CEN
| MODE_ONESHOT
| PRESCALE(ps
));
399 /* Run a quarter of the way, and change the prescaler. */
400 clock_step(tim_calculate_step(count
/ 4, ps
));
401 g_assert_cmpuint(tim_read_tdr(td
), ==, 3 * count
/ 4);
403 tim_write_tcsr(td
, CEN
| MODE_ONESHOT
| PRESCALE(ps
));
404 /* The counter must not change. */
405 g_assert_cmpuint(tim_read_tdr(td
), ==, 3 * count
/ 4);
407 /* Run another quarter of the way, and change the prescaler again. */
408 clock_step(tim_calculate_step(count
/ 4, ps
));
409 g_assert_cmpuint(tim_read_tdr(td
), ==, count
/ 2);
411 tim_write_tcsr(td
, CEN
| MODE_ONESHOT
| PRESCALE(ps
));
412 /* The counter must not change. */
413 g_assert_cmpuint(tim_read_tdr(td
), ==, count
/ 2);
415 /* Run another quarter of the way, and change the prescaler again. */
416 clock_step(tim_calculate_step(count
/ 4, ps
));
417 g_assert_cmpuint(tim_read_tdr(td
), ==, count
/ 4);
419 tim_write_tcsr(td
, CEN
| MODE_ONESHOT
| PRESCALE(ps
));
420 /* The counter must not change. */
421 g_assert_cmpuint(tim_read_tdr(td
), ==, count
/ 4);
423 /* Run almost to expiration, and verify the timer didn't fire yet. */
424 clock_step(tim_calculate_step(count
/ 4, ps
) - 1);
425 g_assert_cmpuint(tim_read_tdr(td
), <, count
);
426 g_assert_cmphex(tim_read(td
, TISR
), ==, 0);
428 /* Now, run the rest of the way and verify that the timer fires. */
430 g_assert_cmphex(tim_read(td
, TISR
), ==, tim_timer_bit(td
));
433 /* Verifies that a periodic timer automatically restarts after expiration. */
434 static void test_periodic_no_interrupt(gconstpointer test_data
)
436 const TestData
*td
= test_data
;
437 unsigned int count
= 2;
443 tim_write_ticr(td
, count
);
444 tim_write_tcsr(td
, CEN
| MODE_PERIODIC
| PRESCALE(ps
));
446 for (i
= 0; i
< 4; i
++) {
449 g_assert_cmphex(tim_read(td
, TISR
), ==, tim_timer_bit(td
));
450 g_assert_false(qtest_get_irq(global_qtest
, tim_timer_irq(td
)));
452 tim_write(td
, TISR
, tim_timer_bit(td
));
454 g_assert_cmphex(tim_read(td
, TISR
), ==, 0);
455 g_assert_false(qtest_get_irq(global_qtest
, tim_timer_irq(td
)));
459 /* Verifies that a periodict timer fires an interrupt every time it expires. */
460 static void test_periodic_interrupt(gconstpointer test_data
)
462 const TestData
*td
= test_data
;
463 unsigned int count
= 65535;
469 tim_write_ticr(td
, count
);
470 tim_write_tcsr(td
, CEN
| IE
| MODE_PERIODIC
| PRESCALE(ps
));
472 for (i
= 0; i
< 4; i
++) {
475 g_assert_cmphex(tim_read(td
, TISR
), ==, tim_timer_bit(td
));
476 g_assert_true(qtest_get_irq(global_qtest
, tim_timer_irq(td
)));
478 tim_write(td
, TISR
, tim_timer_bit(td
));
480 g_assert_cmphex(tim_read(td
, TISR
), ==, 0);
481 g_assert_false(qtest_get_irq(global_qtest
, tim_timer_irq(td
)));
486 * Verifies that the timer behaves correctly when disabled right before and
487 * exactly when it's supposed to expire.
489 static void test_disable_on_expiration(gconstpointer test_data
)
491 const TestData
*td
= test_data
;
492 unsigned int count
= 8;
493 unsigned int ps
= 255;
497 tim_write_ticr(td
, count
);
498 tim_write_tcsr(td
, CEN
| MODE_ONESHOT
| PRESCALE(ps
));
500 clock_step(tim_calculate_step(count
, ps
) - 1);
502 tim_write_tcsr(td
, MODE_ONESHOT
| PRESCALE(ps
));
503 tim_write_tcsr(td
, CEN
| MODE_ONESHOT
| PRESCALE(ps
));
505 tim_write_tcsr(td
, MODE_ONESHOT
| PRESCALE(ps
));
506 g_assert_cmphex(tim_read(td
, TISR
), ==, tim_timer_bit(td
));
510 * Constructs a name that includes the timer block, timer and testcase name,
511 * and adds the test to the test suite.
513 static void tim_add_test(const char *name
, const TestData
*td
, GTestDataFunc fn
)
515 g_autofree
char *full_name
= g_strdup_printf(
516 "npcm7xx_timer/tim[%d]/timer[%d]/%s", tim_index(td
->tim
),
517 timer_index(td
->timer
), name
);
518 qtest_add_data_func(full_name
, td
, fn
);
521 /* Convenience macro for adding a test with a predictable function name. */
522 #define add_test(name, td) tim_add_test(#name, td, test_##name)
524 int main(int argc
, char **argv
)
526 TestData testdata
[ARRAY_SIZE(timer_block
) * ARRAY_SIZE(timer
)];
530 g_test_init(&argc
, &argv
, NULL
);
531 g_test_set_nonfatal_assertions();
533 for (i
= 0; i
< ARRAY_SIZE(timer_block
); i
++) {
534 for (j
= 0; j
< ARRAY_SIZE(timer
); j
++) {
535 TestData
*td
= &testdata
[i
* ARRAY_SIZE(timer
) + j
];
536 td
->tim
= &timer_block
[i
];
537 td
->timer
= &timer
[j
];
540 add_test(reset_overrides_enable
, td
);
541 add_test(oneshot_enable_then_disable
, td
);
542 add_test(oneshot_ps5
, td
);
543 add_test(oneshot_ps0
, td
);
544 add_test(oneshot_ps255
, td
);
545 add_test(oneshot_interrupt
, td
);
546 add_test(pause_resume
, td
);
547 add_test(prescaler_change
, td
);
548 add_test(periodic_no_interrupt
, td
);
549 add_test(periodic_interrupt
, td
);
550 add_test(disable_on_expiration
, td
);
554 qtest_start("-machine npcm750-evb");
555 qtest_irq_intercept_in(global_qtest
, "/machine/soc/a9mpcore/gic");