tests/qtest: variable defined by g_autofree need to be initialized
[qemu.git] / tests / qtest / npcm7xx_timer-test.c
1 /*
2 * QTest testcase for the Nuvoton NPCM7xx Timer
3 *
4 * Copyright 2020 Google LLC
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 "qemu/timer.h"
19 #include "libqtest-single.h"
20
21 #define TIM_REF_HZ (25000000)
22
23 /* Bits in TCSRx */
24 #define CEN BIT(30)
25 #define IE BIT(29)
26 #define MODE_ONESHOT (0 << 27)
27 #define MODE_PERIODIC (1 << 27)
28 #define CRST BIT(26)
29 #define CACT BIT(25)
30 #define PRESCALE(x) (x)
31
32 /* Registers shared between all timers in a module. */
33 #define TISR 0x18
34 #define WTCR 0x1c
35 # define WTCLK(x) ((x) << 10)
36
37 /* Power-on default; used to re-initialize timers before each test. */
38 #define TCSR_DEFAULT PRESCALE(5)
39
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;
45 } Timer;
46
47 /* A timer block containing 5 timers. */
48 typedef struct TimerBlock {
49 int irq_base;
50 uint64_t base_addr;
51 } TimerBlock;
52
53 /* Testdata for testing a particular timer within a timer block. */
54 typedef struct TestData {
55 const TimerBlock *tim;
56 const Timer *timer;
57 } TestData;
58
59 const TimerBlock timer_block[] = {
60 {
61 .irq_base = 32,
62 .base_addr = 0xf0008000,
63 },
64 {
65 .irq_base = 37,
66 .base_addr = 0xf0009000,
67 },
68 {
69 .irq_base = 42,
70 .base_addr = 0xf000a000,
71 },
72 };
73
74 const Timer timer[] = {
75 {
76 .tcsr_offset = 0x00,
77 .ticr_offset = 0x08,
78 .tdr_offset = 0x10,
79 }, {
80 .tcsr_offset = 0x04,
81 .ticr_offset = 0x0c,
82 .tdr_offset = 0x14,
83 }, {
84 .tcsr_offset = 0x20,
85 .ticr_offset = 0x28,
86 .tdr_offset = 0x30,
87 }, {
88 .tcsr_offset = 0x24,
89 .ticr_offset = 0x2c,
90 .tdr_offset = 0x34,
91 }, {
92 .tcsr_offset = 0x40,
93 .ticr_offset = 0x48,
94 .tdr_offset = 0x50,
95 },
96 };
97
98 /* Returns the index of the timer block. */
99 static int tim_index(const TimerBlock *tim)
100 {
101 ptrdiff_t diff = tim - timer_block;
102
103 g_assert(diff >= 0 && diff < ARRAY_SIZE(timer_block));
104
105 return diff;
106 }
107
108 /* Returns the index of a timer within a timer block. */
109 static int timer_index(const Timer *t)
110 {
111 ptrdiff_t diff = t - timer;
112
113 g_assert(diff >= 0 && diff < ARRAY_SIZE(timer));
114
115 return diff;
116 }
117
118 /* Returns the irq line for a given timer. */
119 static int tim_timer_irq(const TestData *td)
120 {
121 return td->tim->irq_base + timer_index(td->timer);
122 }
123
124 /* Register read/write accessors. */
125
126 static void tim_write(const TestData *td,
127 unsigned int offset, uint32_t value)
128 {
129 writel(td->tim->base_addr + offset, value);
130 }
131
132 static uint32_t tim_read(const TestData *td, unsigned int offset)
133 {
134 return readl(td->tim->base_addr + offset);
135 }
136
137 static void tim_write_tcsr(const TestData *td, uint32_t value)
138 {
139 tim_write(td, td->timer->tcsr_offset, value);
140 }
141
142 static uint32_t tim_read_tcsr(const TestData *td)
143 {
144 return tim_read(td, td->timer->tcsr_offset);
145 }
146
147 static void tim_write_ticr(const TestData *td, uint32_t value)
148 {
149 tim_write(td, td->timer->ticr_offset, value);
150 }
151
152 static uint32_t tim_read_ticr(const TestData *td)
153 {
154 return tim_read(td, td->timer->ticr_offset);
155 }
156
157 static uint32_t tim_read_tdr(const TestData *td)
158 {
159 return tim_read(td, td->timer->tdr_offset);
160 }
161
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)
164 {
165 return (1000000000LL / TIM_REF_HZ) * count * (prescale + 1);
166 }
167
168 /* Returns a bitmask corresponding to the timer under test. */
169 static uint32_t tim_timer_bit(const TestData *td)
170 {
171 return BIT(timer_index(td->timer));
172 }
173
174 /* Resets all timers to power-on defaults. */
175 static void tim_reset(const TestData *td)
176 {
177 int i, j;
178
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);
184 }
185 writel(timer_block[i].base_addr + TISR, -1);
186 }
187 }
188
189 /* Verifies the reset state of a timer. */
190 static void test_reset(gconstpointer test_data)
191 {
192 const TestData *td = test_data;
193
194 tim_reset(td);
195
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));
201 }
202
203 /* Verifies that CRST wins if both CEN and CRST are set. */
204 static void test_reset_overrides_enable(gconstpointer test_data)
205 {
206 const TestData *td = test_data;
207
208 tim_reset(td);
209
210 /* CRST should force CEN to 0 */
211 tim_write_tcsr(td, CEN | CRST | TCSR_DEFAULT);
212
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);
216 }
217
218 /* Verifies the behavior when CEN is set and then cleared. */
219 static void test_oneshot_enable_then_disable(gconstpointer test_data)
220 {
221 const TestData *td = test_data;
222
223 tim_reset(td);
224
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);
228
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)));
234 }
235
236 /* Verifies that a one-shot timer fires when expected with prescaler 5. */
237 static void test_oneshot_ps5(gconstpointer test_data)
238 {
239 const TestData *td = test_data;
240 unsigned int count = 256;
241 unsigned int ps = 5;
242
243 tim_reset(td);
244
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);
249
250 clock_step(tim_calculate_step(count, ps) - 1);
251
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);
255
256 clock_step(1);
257
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)));
262
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)));
267
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)));
272 }
273
274 /* Verifies that a one-shot timer fires when expected with prescaler 0. */
275 static void test_oneshot_ps0(gconstpointer test_data)
276 {
277 const TestData *td = test_data;
278 unsigned int count = 1;
279 unsigned int ps = 0;
280
281 tim_reset(td);
282
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);
287
288 clock_step(tim_calculate_step(count, ps) - 1);
289
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);
293
294 clock_step(1);
295
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)));
300 }
301
302 /* Verifies that a one-shot timer fires when expected with highest prescaler. */
303 static void test_oneshot_ps255(gconstpointer test_data)
304 {
305 const TestData *td = test_data;
306 unsigned int count = (1U << 24) - 1;
307 unsigned int ps = 255;
308
309 tim_reset(td);
310
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);
315
316 clock_step(tim_calculate_step(count, ps) - 1);
317
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);
321
322 clock_step(1);
323
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)));
328 }
329
330 /* Verifies that a oneshot timer fires an interrupt when expected. */
331 static void test_oneshot_interrupt(gconstpointer test_data)
332 {
333 const TestData *td = test_data;
334 unsigned int count = 256;
335 unsigned int ps = 7;
336
337 tim_reset(td);
338
339 tim_write_ticr(td, count);
340 tim_write_tcsr(td, IE | CEN | MODE_ONESHOT | PRESCALE(ps));
341
342 clock_step_next();
343
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)));
346 }
347
348 /*
349 * Verifies that the timer can be paused and later resumed, and it still fires
350 * at the right moment.
351 */
352 static void test_pause_resume(gconstpointer test_data)
353 {
354 const TestData *td = test_data;
355 unsigned int count = 256;
356 unsigned int ps = 1;
357
358 tim_reset(td);
359
360 tim_write_ticr(td, count);
361 tim_write_tcsr(td, IE | CEN | MODE_ONESHOT | PRESCALE(ps));
362
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);
367
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)));
373
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)));
380
381 /* Now, run the rest of the way and verify that the interrupt fires. */
382 clock_step(1);
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)));
385 }
386
387 /* Verifies that the prescaler can be changed while the timer is runnin. */
388 static void test_prescaler_change(gconstpointer test_data)
389 {
390 const TestData *td = test_data;
391 unsigned int count = 256;
392 unsigned int ps = 5;
393
394 tim_reset(td);
395
396 tim_write_ticr(td, count);
397 tim_write_tcsr(td, CEN | MODE_ONESHOT | PRESCALE(ps));
398
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);
402 ps = 2;
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);
406
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);
410 ps = 8;
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);
414
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);
418 ps = 0;
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);
422
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);
427
428 /* Now, run the rest of the way and verify that the timer fires. */
429 clock_step(1);
430 g_assert_cmphex(tim_read(td, TISR), ==, tim_timer_bit(td));
431 }
432
433 /* Verifies that a periodic timer automatically restarts after expiration. */
434 static void test_periodic_no_interrupt(gconstpointer test_data)
435 {
436 const TestData *td = test_data;
437 unsigned int count = 2;
438 unsigned int ps = 3;
439 int i;
440
441 tim_reset(td);
442
443 tim_write_ticr(td, count);
444 tim_write_tcsr(td, CEN | MODE_PERIODIC | PRESCALE(ps));
445
446 for (i = 0; i < 4; i++) {
447 clock_step_next();
448
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)));
451
452 tim_write(td, TISR, tim_timer_bit(td));
453
454 g_assert_cmphex(tim_read(td, TISR), ==, 0);
455 g_assert_false(qtest_get_irq(global_qtest, tim_timer_irq(td)));
456 }
457 }
458
459 /* Verifies that a periodict timer fires an interrupt every time it expires. */
460 static void test_periodic_interrupt(gconstpointer test_data)
461 {
462 const TestData *td = test_data;
463 unsigned int count = 65535;
464 unsigned int ps = 2;
465 int i;
466
467 tim_reset(td);
468
469 tim_write_ticr(td, count);
470 tim_write_tcsr(td, CEN | IE | MODE_PERIODIC | PRESCALE(ps));
471
472 for (i = 0; i < 4; i++) {
473 clock_step_next();
474
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)));
477
478 tim_write(td, TISR, tim_timer_bit(td));
479
480 g_assert_cmphex(tim_read(td, TISR), ==, 0);
481 g_assert_false(qtest_get_irq(global_qtest, tim_timer_irq(td)));
482 }
483 }
484
485 /*
486 * Verifies that the timer behaves correctly when disabled right before and
487 * exactly when it's supposed to expire.
488 */
489 static void test_disable_on_expiration(gconstpointer test_data)
490 {
491 const TestData *td = test_data;
492 unsigned int count = 8;
493 unsigned int ps = 255;
494
495 tim_reset(td);
496
497 tim_write_ticr(td, count);
498 tim_write_tcsr(td, CEN | MODE_ONESHOT | PRESCALE(ps));
499
500 clock_step(tim_calculate_step(count, ps) - 1);
501
502 tim_write_tcsr(td, MODE_ONESHOT | PRESCALE(ps));
503 tim_write_tcsr(td, CEN | MODE_ONESHOT | PRESCALE(ps));
504 clock_step(1);
505 tim_write_tcsr(td, MODE_ONESHOT | PRESCALE(ps));
506 g_assert_cmphex(tim_read(td, TISR), ==, tim_timer_bit(td));
507 }
508
509 /*
510 * Constructs a name that includes the timer block, timer and testcase name,
511 * and adds the test to the test suite.
512 */
513 static void tim_add_test(const char *name, const TestData *td, GTestDataFunc fn)
514 {
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);
519 }
520
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)
523
524 int main(int argc, char **argv)
525 {
526 TestData testdata[ARRAY_SIZE(timer_block) * ARRAY_SIZE(timer)];
527 int ret;
528 int i, j;
529
530 g_test_init(&argc, &argv, NULL);
531 g_test_set_nonfatal_assertions();
532
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];
538
539 add_test(reset, td);
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);
551 }
552 }
553
554 qtest_start("-machine npcm750-evb");
555 qtest_irq_intercept_in(global_qtest, "/machine/soc/a9mpcore/gic");
556 ret = g_test_run();
557 qtest_end();
558
559 return ret;
560 }