From nobody Fri May 17 05:26:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1632442195110266.06426142720136; Thu, 23 Sep 2021 17:09:55 -0700 (PDT) Received: from localhost ([::1]:42280 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mTYmo-0002IY-2G for importer@patchew.org; Thu, 23 Sep 2021 20:09:54 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39754) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mTYgY-0001Yh-VP; Thu, 23 Sep 2021 20:03:27 -0400 Received: from out5-smtp.messagingengine.com ([66.111.4.29]:47023) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mTYgL-0005Yc-HR; Thu, 23 Sep 2021 20:03:26 -0400 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id 413935C0187; Thu, 23 Sep 2021 20:03:10 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute4.internal (MEProxy); Thu, 23 Sep 2021 20:03:10 -0400 Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 23 Sep 2021 20:03:07 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :date:from:message-id:mime-version:subject:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm3; bh=j6otoy 8ugqUz8D2g9GzsCuGBdE+MqAREYWAo8ooYVns=; b=NI4aP5wGfVfhUSZVN690YX EqlDlw7Cva1FtZjPB3uy5oWngmyivEvx6x+Zb4InKJKUgSUrzFmq0ivad7iVWAkt QHw+exrS1IzDKtqVxQJ6wJUxWnsS51/P9ji07oELc0y+cI1+rxMr7Ngj3BxVSg/Z K+iBcc3AVeZGzB69eI6m/SbD+hrveAGmqGBTopce5HFVIi8yHNUTHNS+jSEDqQdK KdA928uD+Csj3tqEH8FBuTAtAdu2wgc0jKWiVI5tDjzlN5Rl+wHCNZTYA8MYVIEo xt8tOguXlKqstzaE1ifsN1NeasLTozragoYyo9Vz+cCsE5VXhAx7kozyWLCpWAeg == X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvtddrudejtddgvdejucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepkffhufggtgfgfffvsehtkeertddttdejnecuhfhrohhmpefhihhnnhcuvfhh rghinhcuoehfthhhrghinheslhhinhhugidqmheikehkrdhorhhgqeenucggtffrrghtth gvrhhnpeffhfettdeileeftdehudektdfggeffvdegheehieelheeiteduvefhvdejueej jeenucffohhmrghinhepkhgvrhhnvghlrdhorhhgpdhgihhthhhusgdrtghomhenucevlh hushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehfthhhrghinhes lhhinhhugidqmheikehkrdhorhhg X-ME-Proxy: Message-Id: From: Finn Thain Subject: [PATCH v1 0/9] hw/mos6522: VIA timer emulation fixes and improvements MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Date: Fri, 24 Sep 2021 08:49:56 +1000 To: Greg Kurz , Mark Cave-Ayland Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=66.111.4.29; envelope-from=fthain@linux-m68k.org; helo=out5-smtp.messagingengine.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, SPF_HELO_PASS=-0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-ppc@nongnu.org, Laurent Vivier , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZM-MESSAGEID: 1632442196405100001 Content-Type: text/plain; charset="utf-8" This is a patch series for QEMU that I started last year. The aim was to=20 try to get a monotonic clocksource for Linux/m68k guests. That hasn't=20 been achieved yet (for q800 machines). I'm submitting the patch series=20 because, - it improves 6522 emulation fidelity, although slightly slower, and - it allows Linux/m68k to make use of the additional timer that the=20 hardware indeed offers, but which QEMU omits, and which may be of=20 benefit to Linux guests [1], and - I see that Mark has been working on timer emulation issues in his=20 github repo [2] and it seems likely that MacOS, NetBSD or A/UX guests=20 will also require better 6522 emulation. To make collaboration easier these patches can also be fetched from=20 github [3]. On a real Quadra, accesses to the SY6522 chips are slow because they are=20 synchronous with the 783360 Hz "phase 2" clock. In QEMU, they are slow=20 because of the division operation in the timer count calculation. This=20 patch series improves the fidelity of the emulated chip, but the price=20 is more division ops. The emulated 6522 still deviates from the behaviour of the real thing,=20 however. For example, two consecutive accesses to a real 6522 timer=20 counter can never yield the same value. This is not true of the emulated=20 6522 in QEMU 6, wherein two consecutive accesses to a timer count=20 register have been observed to yield the same value. Two problems presently affecting a Linux guest are clock drift and=20 monotonicity failure in the 'via' clocksource. That is, the clocksource=20 counter can jump backwards. This can be observed by patching Linux like=20 so, diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c --- a/arch/m68k/mac/via.c +++ b/arch/m68k/mac/via.c @@ -606,6 +606,8 @@ void __init via_init_clock(void) clocksource_register_hz(&mac_clk, VIA_CLOCK_FREQ); } =20 +static u32 prev_ticks; + static u64 mac_read_clk(struct clocksource *cs) { unsigned long flags; @@ -631,6 +633,8 @@ static u64 mac_read_clk(struct clocksource *cs) count =3D count_high << 8; ticks =3D VIA_TIMER_CYCLES - count; ticks +=3D clk_offset + clk_total; + if (ticks < prev_ticks) pr_warn("%s: %u < %u\n", __func__, ticks, prev_ti= cks); + prev_ticks =3D ticks; local_irq_restore(flags); =20 return ticks; Or just enable CONFIG_DEBUG_TIMEKEEPING: [ 1872.720000] INFO: timekeeping: Cycle offset (4294966426) is larger than = the 'via1' clock's 50% safety margin (2147483647) [ 1872.720000] timekeeping: Your kernel is still fine, but is feeling a bit= nervous=20 [ 1907.510000] INFO: timekeeping: Cycle offset (4294962989) is larger than = the 'via1' clock's 50% safety margin (2147483647)=20 [ 1907.510000] timekeeping: Your kernel is still fine, but is feeling a bit= nervous=20 [ 1907.900000] INFO: timekeeping: Cycle offset (4294963248) is larger than = the 'via1' clock's 50% safety margin (2147483647)=20 [ 1907.900000] timekeeping: Your kernel is still fine, but is feeling a bit= nervous This problem can be partly blamed on a 6522 design limitation, which is=20 that the timer counter has no overflow register. Hence, if a timer=20 counter wraps around and the kernel is late to handle the subsequent=20 interrupt, the kernel can't account for any missed ticks. On a real Quadra, the kernel mitigates this limitation by minimizing=20 interrupt latency. But on QEMU, interrupt latency is unbounded. This=20 can't be mitigated by the guest kernel and leads to clock drift. This latency can be observed by patching QEMU like so: diff --git a/hw/misc/mos6522.c b/hw/misc/mos6522.c --- a/hw/misc/mos6522.c +++ b/hw/misc/mos6522.c @@ -379,6 +379,12 @@ void mos6522_write(void *opaque, hwaddr addr, uint64_t= val, unsigned size) s->pcr =3D val; break; case VIA_REG_IFR: + if (val & T1_INT) { + static int64_t last_t1_int_cleared; + int64_t now =3D qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + if (now - last_t1_int_cleared > 20000000) printf("\t%s: t1 int= clear is late\n", __func__); + last_t1_int_cleared =3D now; + } /* reset bits */ s->ifr &=3D ~val; mos6522_update_irq(s); This logic asserts that, given that Linux/m68k sets CONFIG_HZ to 100,=20 the emulator will theoretically see each timer 1 interrupt cleared=20 within 20 ms of the previous one. But that deadline is often missed on=20 my QEMU host [4]. On real Mac hardware you could observe the same scenario if a high=20 priority interrupt were to sufficiently delay the timer interrupt=20 handler. (This is the reason why the VIA1 interrupt priority gets=20 increased from level 1 to level 6 when running on Quadras.) Anyway, for now, the clocksource monotonicity problem in Linux/mac68k=20 guests is still unresolved. Nonetheless, I think this patch series does=20 improve the situation. [1] I've also been working on some improvements to Linux/m68k based on=20 Arnd Bergman's clockevent RFC patch,=20 https://lore.kernel.org/linux-m68k/20201008154651.1901126-14-arnd@arndb.de/=20 The idea is to add a oneshot clockevent device by making use of the=20 second VIA1 timer. This approach should help mitigate the clock drift=20 problem as well as assist with CONFIG_GENERIC_CLOCKEVENTS adoption,=20 which would enable CONFIG_NO_HZ_IDLE etc. [2] https://github.com/mcayland/qemu/commits/q800.upstream [3] https://github.com/fthain/qemu/commits/via-timer [4] This theoretical 20 ms deadline is not missed prior to every=20 backwards jump in the clocksource counter. AFAICT, that's because the=20 true deadline is somewhat shorter than 20 ms. ---=20 Changed since RFC: - Added Reviewed-by tags. - Re-ordered some patches to make fixes available earlier in the series. - Dropped patch 5/10 "Don't clear T1 interrupt flag on latch write". - Rebased on v6.1.0 release. Finn Thain (9): hw/mos6522: Remove get_load_time() methods and functions hw/mos6522: Remove get_counter_value() methods and functions hw/mos6522: Remove redundant mos6522_timer1_update() calls hw/mos6522: Rename timer callback functions hw/mos6522: Fix initial timer counter reload hw/mos6522: Call mos6522_update_irq() when appropriate hw/mos6522: Avoid using discrepant QEMU clock values hw/mos6522: Synchronize timer interrupt and timer counter hw/mos6522: Implement oneshot mode hw/misc/mos6522.c | 245 ++++++++++++++++++-------------------- hw/misc/trace-events | 2 +- include/hw/misc/mos6522.h | 9 ++ 3 files changed, 123 insertions(+), 133 deletions(-) --=20 2.26.3