qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

rtc-test: introduce more update tests

Test divider reset and UIP behavior.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

+81 -1
+81 -1
tests/rtc-test.c
··· 325 325 cmos_write(RTC_DAY_OF_MONTH, d); 326 326 } 327 327 328 + static void set_datetime_dec(int h, int min, int s, int d, int m, int y) 329 + { 330 + cmos_write(RTC_HOURS, h); 331 + cmos_write(RTC_MINUTES, min); 332 + cmos_write(RTC_SECONDS, s); 333 + cmos_write(RTC_YEAR, y % 100); 334 + cmos_write(RTC_CENTURY, y / 100); 335 + cmos_write(RTC_MONTH, m); 336 + cmos_write(RTC_DAY_OF_MONTH, d); 337 + } 338 + 339 + static void set_datetime(int mode, int h, int min, int s, int d, int m, int y) 340 + { 341 + cmos_write(RTC_REG_B, mode); 342 + 343 + cmos_write(RTC_REG_A, 0x76); 344 + if (mode & REG_B_DM) { 345 + set_datetime_dec(h, min, s, d, m, y); 346 + } else { 347 + set_datetime_bcd(h, min, s, d, m, y); 348 + } 349 + cmos_write(RTC_REG_A, 0x26); 350 + } 351 + 328 352 #define assert_time(h, m, s) \ 329 353 do { \ 330 354 g_assert_cmpint(cmos_read(RTC_HOURS), ==, h); \ ··· 559 583 assert_datetime_bcd(0x02, 0x04, 0x59, 0x02, 0x02, 0x2011); 560 584 } 561 585 586 + static void divider_reset(void) 587 + { 588 + /* Enable binary-coded decimal (BCD) mode in Register B*/ 589 + cmos_write(RTC_REG_B, REG_B_24H); 590 + 591 + /* Enter divider reset */ 592 + cmos_write(RTC_REG_A, 0x76); 593 + set_datetime_bcd(0x02, 0x04, 0x58, 0x02, 0x02, 0x2011); 594 + 595 + assert_datetime_bcd(0x02, 0x04, 0x58, 0x02, 0x02, 0x2011); 596 + 597 + /* Since divider reset flag is still enabled, these are equality checks. */ 598 + clock_step(1000000000LL); 599 + assert_datetime_bcd(0x02, 0x04, 0x58, 0x02, 0x02, 0x2011); 600 + 601 + /* The first update ends 500 ms after divider reset */ 602 + cmos_write(RTC_REG_A, 0x26); 603 + clock_step(500000000LL - UIP_HOLD_LENGTH - 1); 604 + g_assert_cmpint(cmos_read(RTC_REG_A) & REG_A_UIP, ==, 0); 605 + assert_datetime_bcd(0x02, 0x04, 0x58, 0x02, 0x02, 0x2011); 606 + 607 + clock_step(1); 608 + g_assert_cmpint(cmos_read(RTC_REG_A) & REG_A_UIP, !=, 0); 609 + clock_step(UIP_HOLD_LENGTH); 610 + g_assert_cmpint(cmos_read(RTC_REG_A) & REG_A_UIP, ==, 0); 611 + 612 + assert_datetime_bcd(0x02, 0x04, 0x59, 0x02, 0x02, 0x2011); 613 + } 614 + 615 + static void uip_stuck(void) 616 + { 617 + set_datetime(REG_B_24H, 0x02, 0x04, 0x58, 0x02, 0x02, 0x2011); 618 + 619 + /* The first update ends 500 ms after divider reset */ 620 + (void)cmos_read(RTC_REG_C); 621 + clock_step(500000000LL); 622 + g_assert_cmpint(cmos_read(RTC_REG_A) & REG_A_UIP, ==, 0); 623 + assert_datetime_bcd(0x02, 0x04, 0x59, 0x02, 0x02, 0x2011); 624 + 625 + /* UF is now set. */ 626 + cmos_write(RTC_HOURS_ALARM, 0x02); 627 + cmos_write(RTC_MINUTES_ALARM, 0xC0); 628 + cmos_write(RTC_SECONDS_ALARM, 0xC0); 629 + 630 + /* Because the alarm will fire soon, reading register A will latch UIP. */ 631 + clock_step(1000000000LL - UIP_HOLD_LENGTH / 2); 632 + g_assert_cmpint(cmos_read(RTC_REG_A) & REG_A_UIP, !=, 0); 633 + 634 + /* Move the alarm far away. This must not cause UIP to remain stuck! */ 635 + cmos_write(RTC_HOURS_ALARM, 0x03); 636 + clock_step(UIP_HOLD_LENGTH); 637 + g_assert_cmpint(cmos_read(RTC_REG_A) & REG_A_UIP, ==, 0); 638 + } 639 + 562 640 #define RTC_PERIOD_CODE1 13 /* 8 Hz */ 563 641 #define RTC_PERIOD_CODE2 15 /* 2 Hz */ 564 642 ··· 625 703 qtest_add_func("/rtc/basic/bcd-12h", basic_12h_bcd); 626 704 qtest_add_func("/rtc/set-year/20xx", set_year_20xx); 627 705 qtest_add_func("/rtc/set-year/1980", set_year_1980); 628 - qtest_add_func("/rtc/misc/register_b_set_flag", register_b_set_flag); 706 + qtest_add_func("/rtc/update/register_b_set_flag", register_b_set_flag); 707 + qtest_add_func("/rtc/update/divider-reset", divider_reset); 708 + qtest_add_func("/rtc/update/uip-stuck", uip_stuck); 629 709 qtest_add_func("/rtc/misc/fuzz-registers", fuzz_registers); 630 710 qtest_add_func("/rtc/periodic/interrupt", periodic_timer); 631 711