1 /* 2 * QTest testcase for the ARM MPTimer 3 * 4 * Copyright (c) 2016 Dmitry Osipenko <digetx@gmail.com> 5 * 6 * This work is licensed under the terms of the GNU GPL, version 2 or later. 7 * See the COPYING file in the top-level directory. 8 */ 9 10 #include "qemu/osdep.h" 11 #include "qemu/timer.h" 12 #include "libqtest-single.h" 13 14 #define TIMER_BLOCK_SCALE(s) ((((s) & 0xff) + 1) * 10) 15 16 #define TIMER_BLOCK_STEP(scaler, steps_nb) \ 17 clock_step(TIMER_BLOCK_SCALE(scaler) * (int64_t)(steps_nb) + 1) 18 19 #define TIMER_BASE_PHYS 0x1e000600 20 21 #define TIMER_LOAD 0x00 22 #define TIMER_COUNTER 0x04 23 #define TIMER_CONTROL 0x08 24 #define TIMER_INTSTAT 0x0C 25 26 #define TIMER_CONTROL_ENABLE (1 << 0) 27 #define TIMER_CONTROL_PERIODIC (1 << 1) 28 #define TIMER_CONTROL_IT_ENABLE (1 << 2) 29 #define TIMER_CONTROL_PRESCALER(p) (((p) & 0xff) << 8) 30 31 #define PERIODIC 1 32 #define ONESHOT 0 33 #define NOSCALE 0 34 35 static int nonscaled = NOSCALE; 36 static int scaled = 122; 37 38 static void timer_load(uint32_t load) 39 { 40 writel(TIMER_BASE_PHYS + TIMER_LOAD, load); 41 } 42 43 static void timer_start(int periodic, uint32_t scale) 44 { 45 uint32_t ctl = TIMER_CONTROL_ENABLE | TIMER_CONTROL_PRESCALER(scale); 46 47 if (periodic) { 48 ctl |= TIMER_CONTROL_PERIODIC; 49 } 50 51 writel(TIMER_BASE_PHYS + TIMER_CONTROL, ctl); 52 } 53 54 static void timer_stop(void) 55 { 56 writel(TIMER_BASE_PHYS + TIMER_CONTROL, 0); 57 } 58 59 static void timer_int_clr(void) 60 { 61 writel(TIMER_BASE_PHYS + TIMER_INTSTAT, 1); 62 } 63 64 static void timer_reset(void) 65 { 66 timer_stop(); 67 timer_load(0); 68 timer_int_clr(); 69 } 70 71 static uint32_t timer_get_and_clr_int_sts(void) 72 { 73 uint32_t int_sts = readl(TIMER_BASE_PHYS + TIMER_INTSTAT); 74 75 if (int_sts) { 76 timer_int_clr(); 77 } 78 79 return int_sts; 80 } 81 82 static uint32_t timer_counter(void) 83 { 84 return readl(TIMER_BASE_PHYS + TIMER_COUNTER); 85 } 86 87 static void timer_set_counter(uint32_t value) 88 { 89 writel(TIMER_BASE_PHYS + TIMER_COUNTER, value); 90 } 91 92 static void test_timer_oneshot(gconstpointer arg) 93 { 94 int scaler = *((int *) arg); 95 96 timer_reset(); 97 timer_load(9999999); 98 timer_start(ONESHOT, scaler); 99 100 TIMER_BLOCK_STEP(scaler, 9999); 101 102 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 103 g_assert_cmpuint(timer_counter(), ==, 9990000); 104 105 TIMER_BLOCK_STEP(scaler, 9990000); 106 107 g_assert_cmpuint(timer_counter(), ==, 0); 108 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); 109 110 TIMER_BLOCK_STEP(scaler, 9990000); 111 112 g_assert_cmpuint(timer_counter(), ==, 0); 113 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 114 } 115 116 static void test_timer_pause(gconstpointer arg) 117 { 118 int scaler = *((int *) arg); 119 120 timer_reset(); 121 timer_load(999999999); 122 timer_start(ONESHOT, scaler); 123 124 TIMER_BLOCK_STEP(scaler, 999); 125 126 g_assert_cmpuint(timer_counter(), ==, 999999000); 127 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 128 129 TIMER_BLOCK_STEP(scaler, 9000); 130 131 g_assert_cmpuint(timer_counter(), ==, 999990000); 132 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 133 134 timer_stop(); 135 136 g_assert_cmpuint(timer_counter(), ==, 999990000); 137 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 138 139 TIMER_BLOCK_STEP(scaler, 90000); 140 141 g_assert_cmpuint(timer_counter(), ==, 999990000); 142 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 143 144 timer_start(ONESHOT, scaler); 145 146 TIMER_BLOCK_STEP(scaler, 999990000); 147 148 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); 149 g_assert_cmpuint(timer_counter(), ==, 0); 150 151 TIMER_BLOCK_STEP(scaler, 999990000); 152 153 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 154 g_assert_cmpuint(timer_counter(), ==, 0); 155 } 156 157 static void test_timer_reload(gconstpointer arg) 158 { 159 int scaler = *((int *) arg); 160 161 timer_reset(); 162 timer_load(UINT32_MAX); 163 timer_start(ONESHOT, scaler); 164 165 TIMER_BLOCK_STEP(scaler, 90000); 166 167 g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 90000); 168 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 169 170 timer_load(UINT32_MAX); 171 172 TIMER_BLOCK_STEP(scaler, 90000); 173 174 g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 90000); 175 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 176 } 177 178 static void test_timer_periodic(gconstpointer arg) 179 { 180 int scaler = *((int *) arg); 181 int repeat = 10; 182 183 timer_reset(); 184 timer_load(100); 185 timer_start(PERIODIC, scaler); 186 187 while (repeat--) { 188 clock_step(TIMER_BLOCK_SCALE(scaler) * (101 + repeat) + 1); 189 190 g_assert_cmpuint(timer_counter(), ==, 100 - repeat); 191 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); 192 193 clock_step(TIMER_BLOCK_SCALE(scaler) * (101 - repeat) - 1); 194 } 195 } 196 197 static void test_timer_oneshot_to_periodic(gconstpointer arg) 198 { 199 int scaler = *((int *) arg); 200 201 timer_reset(); 202 timer_load(10000); 203 timer_start(ONESHOT, scaler); 204 205 TIMER_BLOCK_STEP(scaler, 1000); 206 207 g_assert_cmpuint(timer_counter(), ==, 9000); 208 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 209 210 timer_start(PERIODIC, scaler); 211 212 TIMER_BLOCK_STEP(scaler, 14001); 213 214 g_assert_cmpuint(timer_counter(), ==, 5000); 215 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); 216 } 217 218 static void test_timer_periodic_to_oneshot(gconstpointer arg) 219 { 220 int scaler = *((int *) arg); 221 222 timer_reset(); 223 timer_load(99999999); 224 timer_start(PERIODIC, scaler); 225 226 TIMER_BLOCK_STEP(scaler, 999); 227 228 g_assert_cmpuint(timer_counter(), ==, 99999000); 229 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 230 231 timer_start(ONESHOT, scaler); 232 233 TIMER_BLOCK_STEP(scaler, 99999009); 234 235 g_assert_cmpuint(timer_counter(), ==, 0); 236 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); 237 } 238 239 static void test_timer_prescaler(void) 240 { 241 timer_reset(); 242 timer_load(9999999); 243 timer_start(ONESHOT, NOSCALE); 244 245 TIMER_BLOCK_STEP(NOSCALE, 9999998); 246 247 g_assert_cmpuint(timer_counter(), ==, 1); 248 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 249 250 TIMER_BLOCK_STEP(NOSCALE, 1); 251 252 g_assert_cmpuint(timer_counter(), ==, 0); 253 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); 254 255 timer_reset(); 256 timer_load(9999999); 257 timer_start(ONESHOT, 0xAB); 258 259 TIMER_BLOCK_STEP(0xAB, 9999998); 260 261 g_assert_cmpuint(timer_counter(), ==, 1); 262 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 263 264 TIMER_BLOCK_STEP(0xAB, 1); 265 266 g_assert_cmpuint(timer_counter(), ==, 0); 267 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); 268 } 269 270 static void test_timer_prescaler_on_the_fly(void) 271 { 272 timer_reset(); 273 timer_load(9999999); 274 timer_start(ONESHOT, NOSCALE); 275 276 TIMER_BLOCK_STEP(NOSCALE, 999); 277 278 g_assert_cmpuint(timer_counter(), ==, 9999000); 279 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 280 281 timer_start(ONESHOT, 0xAB); 282 283 TIMER_BLOCK_STEP(0xAB, 9000); 284 285 g_assert_cmpuint(timer_counter(), ==, 9990000); 286 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 287 } 288 289 static void test_timer_set_oneshot_counter_to_0(gconstpointer arg) 290 { 291 int scaler = *((int *) arg); 292 293 timer_reset(); 294 timer_load(UINT32_MAX); 295 timer_start(ONESHOT, scaler); 296 297 TIMER_BLOCK_STEP(scaler, 1); 298 299 g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 1); 300 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 301 302 timer_set_counter(0); 303 304 TIMER_BLOCK_STEP(scaler, 10); 305 306 g_assert_cmpuint(timer_counter(), ==, 0); 307 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); 308 } 309 310 static void test_timer_set_periodic_counter_to_0(gconstpointer arg) 311 { 312 int scaler = *((int *) arg); 313 314 timer_reset(); 315 timer_load(UINT32_MAX); 316 timer_start(PERIODIC, scaler); 317 318 TIMER_BLOCK_STEP(scaler, 1); 319 320 g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 1); 321 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 322 323 timer_set_counter(0); 324 325 TIMER_BLOCK_STEP(scaler, 1); 326 327 g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - (scaler ? 0 : 1)); 328 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); 329 330 timer_reset(); 331 timer_set_counter(UINT32_MAX); 332 timer_start(PERIODIC, scaler); 333 334 TIMER_BLOCK_STEP(scaler, 1); 335 336 g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 1); 337 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 338 339 timer_set_counter(0); 340 341 TIMER_BLOCK_STEP(scaler, 1); 342 343 g_assert_cmpuint(timer_counter(), ==, 0); 344 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); 345 } 346 347 static void test_timer_noload_oneshot(gconstpointer arg) 348 { 349 int scaler = *((int *) arg); 350 351 timer_reset(); 352 timer_start(ONESHOT, scaler); 353 354 TIMER_BLOCK_STEP(scaler, 1); 355 356 g_assert_cmpuint(timer_counter(), ==, 0); 357 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); 358 359 TIMER_BLOCK_STEP(scaler, 1); 360 361 g_assert_cmpuint(timer_counter(), ==, 0); 362 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 363 } 364 365 static void test_timer_noload_periodic(gconstpointer arg) 366 { 367 int scaler = *((int *) arg); 368 369 timer_reset(); 370 timer_start(PERIODIC, scaler); 371 372 TIMER_BLOCK_STEP(scaler, 1); 373 374 g_assert_cmpuint(timer_counter(), ==, 0); 375 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); 376 377 TIMER_BLOCK_STEP(scaler, 1); 378 379 g_assert_cmpuint(timer_counter(), ==, 0); 380 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); 381 } 382 383 static void test_timer_zero_load_oneshot(gconstpointer arg) 384 { 385 int scaler = *((int *) arg); 386 387 timer_reset(); 388 timer_start(ONESHOT, scaler); 389 390 TIMER_BLOCK_STEP(scaler, 1); 391 392 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); 393 g_assert_cmpuint(timer_counter(), ==, 0); 394 395 timer_load(0); 396 397 TIMER_BLOCK_STEP(scaler, 1); 398 399 g_assert_cmpuint(timer_counter(), ==, 0); 400 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); 401 402 TIMER_BLOCK_STEP(scaler, 1); 403 404 g_assert_cmpuint(timer_counter(), ==, 0); 405 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 406 } 407 408 static void test_timer_zero_load_periodic(gconstpointer arg) 409 { 410 int scaler = *((int *) arg); 411 412 timer_reset(); 413 timer_start(PERIODIC, scaler); 414 415 TIMER_BLOCK_STEP(scaler, 1); 416 417 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); 418 g_assert_cmpuint(timer_counter(), ==, 0); 419 420 timer_load(0); 421 422 TIMER_BLOCK_STEP(scaler, 1); 423 424 g_assert_cmpuint(timer_counter(), ==, 0); 425 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); 426 427 TIMER_BLOCK_STEP(scaler, 1); 428 429 g_assert_cmpuint(timer_counter(), ==, 0); 430 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); 431 } 432 433 static void test_timer_zero_load_oneshot_to_nonzero(gconstpointer arg) 434 { 435 int scaler = *((int *) arg); 436 437 timer_reset(); 438 timer_start(ONESHOT, scaler); 439 440 TIMER_BLOCK_STEP(scaler, 1); 441 442 g_assert_cmpuint(timer_counter(), ==, 0); 443 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); 444 445 timer_load(0); 446 447 TIMER_BLOCK_STEP(scaler, 1); 448 449 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); 450 g_assert_cmpuint(timer_counter(), ==, 0); 451 452 timer_load(999); 453 454 TIMER_BLOCK_STEP(scaler, 1001); 455 456 g_assert_cmpuint(timer_counter(), ==, 0); 457 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); 458 } 459 460 static void test_timer_zero_load_periodic_to_nonzero(gconstpointer arg) 461 { 462 int scaler = *((int *) arg); 463 int i; 464 465 timer_reset(); 466 timer_start(PERIODIC, scaler); 467 468 TIMER_BLOCK_STEP(scaler, 1); 469 470 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); 471 g_assert_cmpuint(timer_counter(), ==, 0); 472 473 timer_load(0); 474 475 TIMER_BLOCK_STEP(scaler, 1); 476 477 g_assert_cmpuint(timer_counter(), ==, 0); 478 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); 479 480 timer_load(1999999); 481 482 for (i = 1; i < 10; i++) { 483 TIMER_BLOCK_STEP(scaler, 2000001); 484 485 g_assert_cmpuint(timer_counter(), ==, 1999999 - i); 486 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); 487 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 488 } 489 } 490 491 static void test_timer_nonzero_load_oneshot_to_zero(gconstpointer arg) 492 { 493 int scaler = *((int *) arg); 494 495 timer_reset(); 496 timer_start(ONESHOT, scaler); 497 498 TIMER_BLOCK_STEP(scaler, 1); 499 500 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); 501 g_assert_cmpuint(timer_counter(), ==, 0); 502 503 timer_load(UINT32_MAX); 504 timer_load(0); 505 506 TIMER_BLOCK_STEP(scaler, 100); 507 508 g_assert_cmpuint(timer_counter(), ==, 0); 509 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); 510 } 511 512 static void test_timer_nonzero_load_periodic_to_zero(gconstpointer arg) 513 { 514 int scaler = *((int *) arg); 515 516 timer_reset(); 517 timer_start(PERIODIC, scaler); 518 519 TIMER_BLOCK_STEP(scaler, 1); 520 521 g_assert_cmpuint(timer_counter(), ==, 0); 522 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); 523 524 timer_load(UINT32_MAX); 525 timer_load(0); 526 527 TIMER_BLOCK_STEP(scaler, 100); 528 529 g_assert_cmpuint(timer_counter(), ==, 0); 530 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); 531 } 532 533 static void test_timer_set_periodic_counter_on_the_fly(gconstpointer arg) 534 { 535 int scaler = *((int *) arg); 536 537 timer_reset(); 538 timer_load(UINT32_MAX / 2); 539 timer_start(PERIODIC, scaler); 540 541 TIMER_BLOCK_STEP(scaler, 100); 542 543 g_assert_cmpuint(timer_counter(), ==, UINT32_MAX / 2 - 100); 544 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 545 546 timer_set_counter(UINT32_MAX); 547 548 TIMER_BLOCK_STEP(scaler, 100); 549 550 g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 100); 551 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 552 } 553 554 static void test_timer_enable_and_set_counter(gconstpointer arg) 555 { 556 int scaler = *((int *) arg); 557 558 timer_reset(); 559 timer_start(ONESHOT, scaler); 560 561 TIMER_BLOCK_STEP(scaler, 1); 562 563 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); 564 565 timer_set_counter(UINT32_MAX); 566 567 TIMER_BLOCK_STEP(scaler, 100); 568 569 g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 100); 570 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 571 } 572 573 static void test_timer_set_counter_and_enable(gconstpointer arg) 574 { 575 int scaler = *((int *) arg); 576 577 timer_reset(); 578 timer_set_counter(UINT32_MAX); 579 timer_start(ONESHOT, scaler); 580 581 TIMER_BLOCK_STEP(scaler, 100); 582 583 g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 100); 584 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 585 } 586 587 static void test_timer_set_counter_disabled(void) 588 { 589 timer_reset(); 590 timer_set_counter(999999999); 591 592 TIMER_BLOCK_STEP(NOSCALE, 100); 593 594 g_assert_cmpuint(timer_counter(), ==, 999999999); 595 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 596 } 597 598 static void test_timer_load_disabled(void) 599 { 600 timer_reset(); 601 timer_load(999999999); 602 603 TIMER_BLOCK_STEP(NOSCALE, 100); 604 605 g_assert_cmpuint(timer_counter(), ==, 999999999); 606 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 607 } 608 609 static void test_timer_oneshot_with_counter_0_on_start(gconstpointer arg) 610 { 611 int scaler = *((int *) arg); 612 613 timer_reset(); 614 timer_load(999); 615 timer_set_counter(0); 616 timer_start(ONESHOT, scaler); 617 618 TIMER_BLOCK_STEP(scaler, 100); 619 620 g_assert_cmpuint(timer_counter(), ==, 0); 621 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); 622 623 TIMER_BLOCK_STEP(scaler, 100); 624 625 g_assert_cmpuint(timer_counter(), ==, 0); 626 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 627 } 628 629 static void test_timer_periodic_with_counter_0_on_start(gconstpointer arg) 630 { 631 int scaler = *((int *) arg); 632 int i; 633 634 timer_reset(); 635 timer_load(UINT32_MAX); 636 timer_set_counter(0); 637 638 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 639 g_assert_cmpuint(timer_counter(), ==, 0); 640 641 timer_start(PERIODIC, scaler); 642 643 TIMER_BLOCK_STEP(scaler, 100); 644 645 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); 646 g_assert_cmpuint(timer_counter(), ==, UINT32_MAX + (scaler ? 1 : 0) - 100); 647 648 TIMER_BLOCK_STEP(scaler, 100); 649 650 g_assert_cmpuint(timer_counter(), ==, UINT32_MAX + (scaler ? 1 : 0) - 200); 651 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 652 653 timer_reset(); 654 timer_load(1999999); 655 timer_set_counter(0); 656 657 g_assert_cmpuint(timer_counter(), ==, 0); 658 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 659 660 TIMER_BLOCK_STEP(scaler, 1); 661 662 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 663 664 timer_start(PERIODIC, scaler); 665 666 TIMER_BLOCK_STEP(scaler, 1); 667 668 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); 669 670 for (i = 2 - (!!scaler ? 1 : 0); i < 10; i++) { 671 TIMER_BLOCK_STEP(scaler, 2000001); 672 673 g_assert_cmpuint(timer_counter(), ==, 1999999 - i); 674 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); 675 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 676 } 677 } 678 679 static void test_periodic_counter(gconstpointer arg) 680 { 681 const int test_load = 10; 682 int scaler = *((int *) arg); 683 int test_val; 684 685 timer_reset(); 686 timer_load(test_load); 687 timer_start(PERIODIC, scaler); 688 689 clock_step(1); 690 691 for (test_val = 0; test_val <= test_load; test_val++) { 692 clock_step(TIMER_BLOCK_SCALE(scaler) * test_load); 693 g_assert_cmpint(timer_counter(), ==, test_val); 694 } 695 } 696 697 static void test_timer_set_counter_periodic_with_zero_load(gconstpointer arg) 698 { 699 int scaler = *((int *) arg); 700 701 timer_reset(); 702 timer_start(PERIODIC, scaler); 703 timer_load(0); 704 705 TIMER_BLOCK_STEP(scaler, 1); 706 707 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); 708 709 TIMER_BLOCK_STEP(scaler, 1); 710 711 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); 712 713 timer_set_counter(999); 714 715 TIMER_BLOCK_STEP(scaler, 999); 716 717 g_assert_cmpuint(timer_counter(), ==, 0); 718 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); 719 720 TIMER_BLOCK_STEP(scaler, 1); 721 722 g_assert_cmpuint(timer_counter(), ==, 0); 723 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); 724 } 725 726 static void test_timer_set_oneshot_load_to_0(gconstpointer arg) 727 { 728 int scaler = *((int *) arg); 729 730 timer_reset(); 731 timer_load(UINT32_MAX); 732 timer_start(ONESHOT, scaler); 733 734 TIMER_BLOCK_STEP(scaler, 100); 735 736 g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 100); 737 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 738 739 timer_load(0); 740 741 TIMER_BLOCK_STEP(scaler, 100); 742 743 g_assert_cmpuint(timer_counter(), ==, 0); 744 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); 745 746 TIMER_BLOCK_STEP(scaler, 100); 747 748 g_assert_cmpuint(timer_counter(), ==, 0); 749 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 750 } 751 752 static void test_timer_set_periodic_load_to_0(gconstpointer arg) 753 { 754 int scaler = *((int *) arg); 755 756 timer_reset(); 757 timer_load(UINT32_MAX); 758 timer_start(PERIODIC, scaler); 759 760 TIMER_BLOCK_STEP(scaler, 100); 761 762 g_assert_cmpuint(timer_counter(), ==, UINT32_MAX - 100); 763 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 764 765 timer_load(0); 766 767 TIMER_BLOCK_STEP(scaler, 100); 768 769 g_assert_cmpuint(timer_counter(), ==, 0); 770 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); 771 772 TIMER_BLOCK_STEP(scaler, 100); 773 774 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); 775 g_assert_cmpuint(timer_counter(), ==, 0); 776 } 777 778 static void test_deferred_trigger(void) 779 { 780 int mode = ONESHOT; 781 782 again: 783 timer_reset(); 784 timer_start(mode, 255); 785 786 clock_step(100); 787 788 g_assert_cmpuint(timer_counter(), ==, 0); 789 790 TIMER_BLOCK_STEP(255, 1); 791 792 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); 793 794 timer_reset(); 795 timer_load(2); 796 timer_start(mode, 255); 797 798 clock_step(100); 799 800 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 801 802 TIMER_BLOCK_STEP(255, 1); 803 804 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 805 806 TIMER_BLOCK_STEP(255, 1); 807 808 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); 809 810 timer_reset(); 811 timer_load(UINT32_MAX); 812 timer_start(mode, 255); 813 814 clock_step(100); 815 816 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 817 818 timer_set_counter(0); 819 820 clock_step(100); 821 822 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 823 824 TIMER_BLOCK_STEP(255, 1); 825 826 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); 827 828 timer_reset(); 829 timer_load(UINT32_MAX); 830 timer_start(mode, 255); 831 832 clock_step(100); 833 834 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 835 836 timer_load(0); 837 838 clock_step(100); 839 840 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 841 842 TIMER_BLOCK_STEP(255, 1); 843 844 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); 845 846 if (mode == ONESHOT) { 847 mode = PERIODIC; 848 goto again; 849 } 850 } 851 852 static void test_timer_zero_load_mode_switch(gconstpointer arg) 853 { 854 int scaler = *((int *) arg); 855 856 timer_reset(); 857 timer_load(0); 858 timer_start(PERIODIC, scaler); 859 860 TIMER_BLOCK_STEP(scaler, 1); 861 862 g_assert_cmpuint(timer_counter(), ==, 0); 863 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); 864 865 TIMER_BLOCK_STEP(scaler, 1); 866 867 timer_start(ONESHOT, scaler); 868 869 TIMER_BLOCK_STEP(scaler, 1); 870 871 g_assert_cmpuint(timer_counter(), ==, 0); 872 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); 873 874 TIMER_BLOCK_STEP(scaler, 1); 875 876 g_assert_cmpuint(timer_counter(), ==, 0); 877 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 878 879 TIMER_BLOCK_STEP(scaler, 1); 880 881 timer_start(PERIODIC, scaler); 882 883 TIMER_BLOCK_STEP(scaler, 1); 884 885 g_assert_cmpuint(timer_counter(), ==, 0); 886 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, !!scaler); 887 } 888 889 static void test_timer_zero_load_prescaled_periodic_to_nonscaled_oneshot(void) 890 { 891 timer_reset(); 892 timer_load(0); 893 timer_start(PERIODIC, 255); 894 895 TIMER_BLOCK_STEP(255, 1); 896 897 g_assert_cmpuint(timer_counter(), ==, 0); 898 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); 899 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 900 901 TIMER_BLOCK_STEP(255, 1); 902 903 g_assert_cmpuint(timer_counter(), ==, 0); 904 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); 905 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 906 907 TIMER_BLOCK_STEP(255, 1); 908 909 timer_start(ONESHOT, NOSCALE); 910 911 TIMER_BLOCK_STEP(NOSCALE, 1); 912 913 g_assert_cmpuint(timer_counter(), ==, 0); 914 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); 915 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 916 917 TIMER_BLOCK_STEP(NOSCALE, 1); 918 919 g_assert_cmpuint(timer_counter(), ==, 0); 920 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 921 } 922 923 static void test_timer_zero_load_prescaled_oneshot_to_nonscaled_periodic(void) 924 { 925 timer_reset(); 926 timer_load(0); 927 timer_start(ONESHOT, 255); 928 929 TIMER_BLOCK_STEP(255, 1); 930 931 g_assert_cmpuint(timer_counter(), ==, 0); 932 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); 933 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 934 935 timer_start(PERIODIC, NOSCALE); 936 937 TIMER_BLOCK_STEP(NOSCALE, 1); 938 939 g_assert_cmpuint(timer_counter(), ==, 0); 940 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 941 } 942 943 static void test_timer_zero_load_nonscaled_oneshot_to_prescaled_periodic(void) 944 { 945 timer_reset(); 946 timer_load(0); 947 timer_start(ONESHOT, NOSCALE); 948 949 TIMER_BLOCK_STEP(NOSCALE, 1); 950 951 g_assert_cmpuint(timer_counter(), ==, 0); 952 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 953 954 timer_start(PERIODIC, 255); 955 956 TIMER_BLOCK_STEP(255, 1); 957 958 g_assert_cmpuint(timer_counter(), ==, 0); 959 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); 960 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 961 962 TIMER_BLOCK_STEP(255, 1); 963 964 g_assert_cmpuint(timer_counter(), ==, 0); 965 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); 966 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 967 } 968 969 static void test_timer_zero_load_nonscaled_periodic_to_prescaled_oneshot(void) 970 { 971 timer_reset(); 972 timer_load(0); 973 timer_start(PERIODIC, NOSCALE); 974 975 TIMER_BLOCK_STEP(NOSCALE, 1); 976 977 g_assert_cmpuint(timer_counter(), ==, 0); 978 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 979 980 timer_start(ONESHOT, 255); 981 982 TIMER_BLOCK_STEP(255, 1); 983 984 g_assert_cmpuint(timer_counter(), ==, 0); 985 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 1); 986 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 987 988 TIMER_BLOCK_STEP(255, 1); 989 990 g_assert_cmpuint(timer_counter(), ==, 0); 991 g_assert_cmpuint(timer_get_and_clr_int_sts(), ==, 0); 992 } 993 994 /* 995 * Add a qtest test that comes in two versions: one with 996 * a timer scaler setting, and one with the timer nonscaled. 997 */ 998 static void add_scaler_test(const char *str, bool scale, 999 void (*fn)(const void *)) 1000 { 1001 char *name; 1002 int *scaler = scale ? &scaled : &nonscaled; 1003 1004 name = g_strdup_printf("%s=%d", str, *scaler); 1005 qtest_add_data_func(name, scaler, fn); 1006 g_free(name); 1007 } 1008 1009 int main(int argc, char **argv) 1010 { 1011 int ret; 1012 int scale; 1013 1014 g_test_init(&argc, &argv, NULL); 1015 1016 qtest_add_func("mptimer/deferred_trigger", test_deferred_trigger); 1017 qtest_add_func("mptimer/load_disabled", test_timer_load_disabled); 1018 qtest_add_func("mptimer/set_counter_disabled", test_timer_set_counter_disabled); 1019 qtest_add_func("mptimer/zero_load_prescaled_periodic_to_nonscaled_oneshot", 1020 test_timer_zero_load_prescaled_periodic_to_nonscaled_oneshot); 1021 qtest_add_func("mptimer/zero_load_prescaled_oneshot_to_nonscaled_periodic", 1022 test_timer_zero_load_prescaled_oneshot_to_nonscaled_periodic); 1023 qtest_add_func("mptimer/zero_load_nonscaled_oneshot_to_prescaled_periodic", 1024 test_timer_zero_load_nonscaled_oneshot_to_prescaled_periodic); 1025 qtest_add_func("mptimer/zero_load_nonscaled_periodic_to_prescaled_oneshot", 1026 test_timer_zero_load_nonscaled_periodic_to_prescaled_oneshot); 1027 qtest_add_func("mptimer/prescaler", test_timer_prescaler); 1028 qtest_add_func("mptimer/prescaler_on_the_fly", test_timer_prescaler_on_the_fly); 1029 1030 for (scale = 0; scale < 2; scale++) { 1031 add_scaler_test("mptimer/oneshot scaler", 1032 scale, test_timer_oneshot); 1033 add_scaler_test("mptimer/pause scaler", 1034 scale, test_timer_pause); 1035 add_scaler_test("mptimer/reload scaler", 1036 scale, test_timer_reload); 1037 add_scaler_test("mptimer/periodic scaler", 1038 scale, test_timer_periodic); 1039 add_scaler_test("mptimer/oneshot_to_periodic scaler", 1040 scale, test_timer_oneshot_to_periodic); 1041 add_scaler_test("mptimer/periodic_to_oneshot scaler", 1042 scale, test_timer_periodic_to_oneshot); 1043 add_scaler_test("mptimer/set_oneshot_counter_to_0 scaler", 1044 scale, test_timer_set_oneshot_counter_to_0); 1045 add_scaler_test("mptimer/set_periodic_counter_to_0 scaler", 1046 scale, test_timer_set_periodic_counter_to_0); 1047 add_scaler_test("mptimer/noload_oneshot scaler", 1048 scale, test_timer_noload_oneshot); 1049 add_scaler_test("mptimer/noload_periodic scaler", 1050 scale, test_timer_noload_periodic); 1051 add_scaler_test("mptimer/zero_load_oneshot scaler", 1052 scale, test_timer_zero_load_oneshot); 1053 add_scaler_test("mptimer/zero_load_periodic scaler", 1054 scale, test_timer_zero_load_periodic); 1055 add_scaler_test("mptimer/zero_load_oneshot_to_nonzero scaler", 1056 scale, test_timer_zero_load_oneshot_to_nonzero); 1057 add_scaler_test("mptimer/zero_load_periodic_to_nonzero scaler", 1058 scale, test_timer_zero_load_periodic_to_nonzero); 1059 add_scaler_test("mptimer/nonzero_load_oneshot_to_zero scaler", 1060 scale, test_timer_nonzero_load_oneshot_to_zero); 1061 add_scaler_test("mptimer/nonzero_load_periodic_to_zero scaler", 1062 scale, test_timer_nonzero_load_periodic_to_zero); 1063 add_scaler_test("mptimer/set_periodic_counter_on_the_fly scaler", 1064 scale, test_timer_set_periodic_counter_on_the_fly); 1065 add_scaler_test("mptimer/enable_and_set_counter scaler", 1066 scale, test_timer_enable_and_set_counter); 1067 add_scaler_test("mptimer/set_counter_and_enable scaler", 1068 scale, test_timer_set_counter_and_enable); 1069 add_scaler_test("mptimer/oneshot_with_counter_0_on_start scaler", 1070 scale, test_timer_oneshot_with_counter_0_on_start); 1071 add_scaler_test("mptimer/periodic_with_counter_0_on_start scaler", 1072 scale, test_timer_periodic_with_counter_0_on_start); 1073 add_scaler_test("mptimer/periodic_counter scaler", 1074 scale, test_periodic_counter); 1075 add_scaler_test("mptimer/set_counter_periodic_with_zero_load scaler", 1076 scale, test_timer_set_counter_periodic_with_zero_load); 1077 add_scaler_test("mptimer/set_oneshot_load_to_0 scaler", 1078 scale, test_timer_set_oneshot_load_to_0); 1079 add_scaler_test("mptimer/set_periodic_load_to_0 scaler", 1080 scale, test_timer_set_periodic_load_to_0); 1081 add_scaler_test("mptimer/zero_load_mode_switch scaler", 1082 scale, test_timer_zero_load_mode_switch); 1083 } 1084 1085 qtest_start("-machine vexpress-a9"); 1086 ret = g_test_run(); 1087 qtest_end(); 1088 1089 return ret; 1090 } 1091