From nobody Thu May 2 01:21:13 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 1629800122596106.60378686140314; Tue, 24 Aug 2021 03:15:22 -0700 (PDT) Received: from localhost ([::1]:34430 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mITSi-0000T7-JT for importer@patchew.org; Tue, 24 Aug 2021 06:15:20 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:51732) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mITRU-0006Vk-3a; Tue, 24 Aug 2021 06:14:04 -0400 Received: from wout2-smtp.messagingengine.com ([64.147.123.25]:33465) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mITRR-0003zJ-Ql; Tue, 24 Aug 2021 06:14:03 -0400 Received: from compute6.internal (compute6.nyi.internal [10.202.2.46]) by mailout.west.internal (Postfix) with ESMTP id 2C2E33200A03; Tue, 24 Aug 2021 06:13:57 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute6.internal (MEProxy); Tue, 24 Aug 2021 06:13:57 -0400 Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 24 Aug 2021 06:13:50 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:date:from:message-id:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; bh=lHThZXP+YuukjnZvYCGSbWqijVdDrotYHvxZjcthAfI=; b=ci868bDp OfUg8p7Ged8akJgeqiUEsdkmV7dSVy9puWRcR+GdP021peUVZFrivG/OsLv1wviP pnbfWMMoGGeUUD3iFICyFOSXT8tIT6CzjVaOevcYKh03gEt2Q7ZQjhS8lQFDB7nF xtZ8CWEQpLUE3Q3CTTHhMaOH1n+XHdy/bFyrNPtPCD7SB9t4PVfaNJxFio6J2b+k FW2b2PoYpTY5cNt1X2I3RFhWLPxEKNT4hHGbucJDnO2/eJ+u6ZydUPVZF3pfTyoN cSlJdiU/yqJGQfbaZToh4HVHHWrp/ZpVSEyqvNDD9YNp11CIN/LpAWSc1fWphUed yDRbVOyJOAeZKg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvtddruddtjedgvdehucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepkffhufffvfestddtredttddttdenucfhrhhomhephfhinhhnucfvhhgrihhn uceofhhthhgrihhnsehlihhnuhigqdhmieekkhdrohhrgheqnecuggftrfgrthhtvghrnh epgeffffegjefhueekhffhleeuleehtdehvddtieeufedvtdehjeevvefhgefgleevnecu ffhomhgrihhnpehkvghrnhgvlhdrohhrghdpghhithhhuhgsrdgtohhmnecuvehluhhsth gvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomhepfhhthhgrihhnsehlihhn uhigqdhmieekkhdrohhrgh X-ME-Proxy: Message-Id: From: Finn Thain Subject: [RFC 00/10] hw/mos6522: VIA timer emulation fixes and improvements Date: Tue, 24 Aug 2021 20:09:36 +1000 To: David Gibson , 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=64.147.123.25; envelope-from=fthain@linux-m68k.org; helo=wout2-smtp.messagingengine.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, 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: 1629800123948100001 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This is a patch series that I started last year. The aim was to try to=20 get a monotonic clocksource for Linux/m68k guests. That aim hasn't been=20 achieved yet (for q800 machines) but I'm submitting the patch series as=20 an RFC because, - It does improve 6522 emulation fidelity. - It allows Linux/m68k to make use of the additional timer that the=20 hardware indeed offers but which QEMU omits. This has several=20 benefits for Linux guests [1]. - 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 only because of the division operation in the timer count calculation. This patch series improves the fidelity of the emulated chip, but the=20 price is more division ops. I haven't tried to measure this yet. 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 6522 in=20 QEMU 6 wherein two consecutive accesses to a timer count register have=20 been observed to yield the same value. Linux is not particularly robust in the face of a 6522 that deviates=20 from the usual behaviour. The problem presently affecting a Linux guest=20 is that its 'via' clocksource is prone to monotonicity failure. That is,=20 the clocksource counter can jump backwards. This can be observed by=20 patching Linux like 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_tic= ks); +prev_ticks =3D ticks; local_irq_restore(flags); =20 return ticks; 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 at all and leads to clock drift.=20 This 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 5 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 GENERIC_CLOCKEVENTS adoption. [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. Finn Thain (10): 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: Don't clear T1 interrupt flag on latch write hw/mos6522: Implement oneshot mode 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/misc/mos6522.c | 232 +++++++++++++++++--------------------- hw/misc/trace-events | 2 +- include/hw/misc/mos6522.h | 9 ++ 3 files changed, 113 insertions(+), 130 deletions(-) --=20 2.26.3