From nobody Wed Nov 5 19:07:36 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1496333225551578.6712801674809; Thu, 1 Jun 2017 09:07:05 -0700 (PDT) Received: from localhost ([::1]:45560 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dGSco-0001dn-1D for importer@patchew.org; Thu, 01 Jun 2017 12:07:02 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39486) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dGSZo-0007fx-DZ for qemu-devel@nongnu.org; Thu, 01 Jun 2017 12:03:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dGSZn-00006C-1s for qemu-devel@nongnu.org; Thu, 01 Jun 2017 12:03:56 -0400 Received: from mx1.redhat.com ([209.132.183.28]:41690) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dGSZm-00005N-Oz for qemu-devel@nongnu.org; Thu, 01 Jun 2017 12:03:54 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B08713B712; Thu, 1 Jun 2017 16:03:53 +0000 (UTC) Received: from donizetti.redhat.com (ovpn-117-20.ams2.redhat.com [10.36.117.20]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v51G3oKv013334; Thu, 1 Jun 2017 12:03:52 -0400 DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com B08713B712 Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=pbonzini@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com B08713B712 From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Thu, 1 Jun 2017 18:03:49 +0200 Message-Id: <20170601160350.10767-2-pbonzini@redhat.com> In-Reply-To: <20170601160350.10767-1-pbonzini@redhat.com> References: <20170601160350.10767-1-pbonzini@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Thu, 01 Jun 2017 16:03:53 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 06/34] qtest: add rtc periodic timer test X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Xiao Guangrong Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Xiao Guangrong It tests the accuracy of rtc periodic timer which is recently improved & fixed by commit 7ffcb539a3 ("mc146818rtc: precisely count the clock for periodic timer", 2017-05-19). Signed-off-by: Xiao Guangrong Message-Id: <20170527025301.23499-1-xiaoguangrong@tencent.com> Signed-off-by: Paolo Bonzini --- hw/timer/mc146818rtc.c | 15 +++--------- include/hw/timer/mc146818rtc_regs.h | 20 +++++++++++++++ tests/rtc-test.c | 49 +++++++++++++++++++++++++++++++++= ++++ 3 files changed, 72 insertions(+), 12 deletions(-) diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c index 542cd09bc1..1b8d3d7d4c 100644 --- a/hw/timer/mc146818rtc.c +++ b/hw/timer/mc146818rtc.c @@ -120,7 +120,7 @@ static void rtc_coalesced_timer_update(RTCState *s) /* divide each RTC interval to 2 - 8 smaller intervals */ int c =3D MIN(s->irq_coalesced, 7) + 1;=20 int64_t next_clock =3D qemu_clock_get_ns(rtc_clock) + - muldiv64(s->period / c, NANOSECONDS_PER_SECOND, RTC_CLOCK_RATE= ); + periodic_clock_to_ns(s->period / c); timer_mod(s->coalesced_timer, next_clock); } } @@ -178,16 +178,8 @@ static uint32_t rtc_periodic_clock_ticks(RTCState *s) } =20 period_code =3D s->cmos_data[RTC_REG_A] & 0x0f; - if (!period_code) { - return 0; - } - - if (period_code <=3D 2) { - period_code +=3D 7; - } =20 - /* period in 32 Khz cycles */ - return 1 << (period_code - 1); + return periodic_period_to_clock(period_code); } =20 /* @@ -260,8 +252,7 @@ periodic_timer_update(RTCState *s, int64_t current_time= , uint32_t old_period) assert(lost_clock >=3D 0 && lost_clock <=3D period); =20 next_irq_clock =3D cur_clock + period - lost_clock; - s->next_periodic_time =3D muldiv64(next_irq_clock, NANOSECONDS_PER= _SECOND, - RTC_CLOCK_RATE) + 1; + s->next_periodic_time =3D periodic_clock_to_ns(next_irq_clock) + 1; timer_mod(s->periodic_timer, s->next_periodic_time); } else { s->irq_coalesced =3D 0; diff --git a/include/hw/timer/mc146818rtc_regs.h b/include/hw/timer/mc14681= 8rtc_regs.h index 6ede6c832e..c62f17bf2d 100644 --- a/include/hw/timer/mc146818rtc_regs.h +++ b/include/hw/timer/mc146818rtc_regs.h @@ -65,4 +65,24 @@ #define REG_C_AF 0x20 #define REG_C_MASK 0x70 =20 +static inline uint32_t periodic_period_to_clock(int period_code) +{ + if (!period_code) { + return 0; + } + + if (period_code <=3D 2) { + period_code +=3D 7; + } + /* period in 32 Khz cycles */ + return 1 << (period_code - 1); +} + +#define RTC_CLOCK_RATE 32768 + +static inline int64_t periodic_clock_to_ns(int64_t clocks) +{ + return muldiv64(clocks, NANOSECONDS_PER_SECOND, RTC_CLOCK_RATE); +} + #endif diff --git a/tests/rtc-test.c b/tests/rtc-test.c index a086efd120..e78f701afb 100644 --- a/tests/rtc-test.c +++ b/tests/rtc-test.c @@ -14,6 +14,7 @@ #include "qemu/osdep.h" =20 #include "libqtest.h" +#include "qemu/timer.h" #include "hw/timer/mc146818rtc_regs.h" =20 static uint8_t base =3D 0x70; @@ -542,6 +543,52 @@ static void register_b_set_flag(void) g_assert_cmpint(cmos_read(RTC_CENTURY), =3D=3D, 0x20); } =20 +#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 =3D clock_step_next(); + } + + g_assert((cmos_read(RTC_REG_C) & REG_C_PF) !=3D 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 =3D real_time =3D clock_step_next(); + + for (i =3D 0; i < RTC_PERIOD_TEST_NR; i++) { + cmos_write(RTC_REG_A, RTC_PERIOD_CODE1); + real_time =3D wait_periodic_interrupt(real_time); + cmos_write(RTC_REG_A, RTC_PERIOD_CODE2); + real_time =3D wait_periodic_interrupt(real_time); + } + + period_clocks =3D periodic_period_to_clock(RTC_PERIOD_CODE1) + + periodic_period_to_clock(RTC_PERIOD_CODE2); + period_clocks *=3D RTC_PERIOD_TEST_NR; + period_time =3D periodic_clock_to_ns(period_clocks); + + real_time -=3D start_time; + g_assert_cmpint(ABS((int64_t)(real_time - period_time)), <=3D, + NANOSECONDS_PER_SECOND * 0.5); +} + int main(int argc, char **argv) { QTestState *s =3D NULL; @@ -564,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 =3D g_test_run(); =20 if (s) { --=20 2.13.0