]> Git Repo - qemu.git/blobdiff - tests/rtc-test.c
iotests: Add preallocated growth test for qcow2
[qemu.git] / tests / rtc-test.c
index 9ab583b860135d8f89a8948bf63f6488345992cb..e78f701afb999bb412b497fbb4113f36dc726374 100644 (file)
  * See the COPYING file in the top-level directory.
  *
  */
-#include "libqtest.h"
-#include "hw/mc146818rtc_regs.h"
 
-#include <glib.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
+#include "qemu/osdep.h"
+
+#include "libqtest.h"
+#include "qemu/timer.h"
+#include "hw/timer/mc146818rtc_regs.h"
 
 static uint8_t base = 0x70;
 
@@ -545,6 +543,52 @@ static void register_b_set_flag(void)
     g_assert_cmpint(cmos_read(RTC_CENTURY), ==, 0x20);
 }
 
+#define RTC_PERIOD_CODE1    13   /* 8 Hz */
+#define RTC_PERIOD_CODE2    15   /* 2 Hz */
+
+#define RTC_PERIOD_TEST_NR  50
+
+static uint64_t wait_periodic_interrupt(uint64_t real_time)
+{
+    while (!get_irq(RTC_ISA_IRQ)) {
+        real_time = clock_step_next();
+    }
+
+    g_assert((cmos_read(RTC_REG_C) & REG_C_PF) != 0);
+    return real_time;
+}
+
+static void periodic_timer(void)
+{
+    int i;
+    uint64_t period_clocks, period_time, start_time, real_time;
+
+    /* disable all interrupts. */
+    cmos_write(RTC_REG_B, cmos_read(RTC_REG_B) &
+                                   ~(REG_B_PIE | REG_B_AIE | REG_B_UIE));
+    cmos_write(RTC_REG_A, RTC_PERIOD_CODE1);
+    /* enable periodic interrupt after properly configure the period. */
+    cmos_write(RTC_REG_B, cmos_read(RTC_REG_B) | REG_B_PIE);
+
+    start_time = real_time = clock_step_next();
+
+    for (i = 0; i < RTC_PERIOD_TEST_NR; i++) {
+        cmos_write(RTC_REG_A, RTC_PERIOD_CODE1);
+        real_time = wait_periodic_interrupt(real_time);
+        cmos_write(RTC_REG_A, RTC_PERIOD_CODE2);
+        real_time = wait_periodic_interrupt(real_time);
+    }
+
+    period_clocks = periodic_period_to_clock(RTC_PERIOD_CODE1) +
+                       periodic_period_to_clock(RTC_PERIOD_CODE2);
+    period_clocks *= RTC_PERIOD_TEST_NR;
+    period_time = periodic_clock_to_ns(period_clocks);
+
+    real_time -= start_time;
+    g_assert_cmpint(ABS((int64_t)(real_time - period_time)), <=,
+                    NANOSECONDS_PER_SECOND * 0.5);
+}
+
 int main(int argc, char **argv)
 {
     QTestState *s = NULL;
@@ -552,7 +596,7 @@ int main(int argc, char **argv)
 
     g_test_init(&argc, &argv, NULL);
 
-    s = qtest_start("-display none -rtc clock=vm");
+    s = qtest_start("-rtc clock=vm");
     qtest_irq_intercept_in(s, "ioapic");
 
     qtest_add_func("/rtc/check-time/bcd", bcd_check_time);
@@ -567,6 +611,8 @@ int main(int argc, char **argv)
     qtest_add_func("/rtc/set-year/1980", set_year_1980);
     qtest_add_func("/rtc/misc/register_b_set_flag", register_b_set_flag);
     qtest_add_func("/rtc/misc/fuzz-registers", fuzz_registers);
+    qtest_add_func("/rtc/periodic/interrupt", periodic_timer);
+
     ret = g_test_run();
 
     if (s) {
This page took 0.02504 seconds and 4 git commands to generate.