From patchwork Wed Oct 4 08:37:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Mark Cave-Ayland X-Patchwork-Id: 13408373 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5863EE8FDDA for ; Wed, 4 Oct 2023 08:38:57 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qnxOn-0003gq-OA; Wed, 04 Oct 2023 04:38:29 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxOm-0003fN-9q for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:38:28 -0400 Received: from mail.ilande.co.uk ([2001:41c9:1:41f::167]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxOd-0007TS-Ft for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:38:28 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=ilande.co.uk; s=20220518; h=Subject:Content-Transfer-Encoding:Content-Type: MIME-Version:References:In-Reply-To:Message-Id:Date:To:From:Sender:Reply-To: Cc:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=Q4mmGHnfiavEqSDdzInQ/yDZyYd5aVbeL7az8KljSZE=; b=QySo1Rgl630IcT1pHswOmbvLE9 Kc45anPH9i/jQBf7YsVsoNqZBk/X0RnKfiuLOyikIwmoVXN6JFX3gCd2kv8VwxPzNKPC2R2RzB2Kx 6Pu5Cj+OxBi3yQklrZ2TRGu2wNlHjnd8jEZEiWhN4puUK1QuCAWKFRdUxooTUEfRBf4a5UBiyYRIz N5Rkc55aIwUE/E9JnDws0+wjGO1fi3J5SwKJ1MDiKt2BZfAZgIntDDGz/UWXqelUfy4hlaRppVYss +yeG8vwJi+WbZP5ubBgjPqFHiUcgJV3Wne6iOKYCy7d3IEnSgtZItcaEv/8zQKpI8MKzww8GQ48+D p2h9/VpSITWOM2msWJcAZ7KeEPz7JkqPaHMy7v8X3QnDdyDCqij1vpzxMEJo5xmOaEeLVT8h7RnLm TYZbvvqOg5lYZ1677IVNFIVgqW1LA6DPXhEy/PMPx0bBQ7cDVxtVuaLkVFifjASqMqxtuc5vDz/0Q LlRoUYSbXsufkjR5nsbzSn/I2K8O08kO0tE8IehmQZrZ48D2mGBiG7/Gu5XpTO3KEmXJP8r2EPANs wBkGBG+9e6kqL9jAnETGMv2/DI6RCtTZwMyaJE85D/u8FerKgMCZwwxIhMMNAqNKjkajNvc1CmUUD cZJ2QkuECSHuI3g0A0CNqPy4tIJT0Hgttkcb5MYZk=; Received: from host86-159-123-68.range86-159.btcentralplus.com ([86.159.123.68] helo=localhost.localdomain) by mail.ilande.co.uk with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qnxON-0006za-MI; Wed, 04 Oct 2023 09:38:08 +0100 From: Mark Cave-Ayland To: laurent@vivier.eu, qemu-devel@nongnu.org Date: Wed, 4 Oct 2023 09:37:47 +0100 Message-Id: <20231004083806.757242-2-mark.cave-ayland@ilande.co.uk> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> References: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 86.159.123.68 X-SA-Exim-Mail-From: mark.cave-ayland@ilande.co.uk Subject: [PATCH v4 01/20] q800-glue.c: convert to Resettable interface X-SA-Exim-Version: 4.2.1 (built Wed, 08 May 2019 21:11:16 +0000) X-SA-Exim-Scanned: Yes (on mail.ilande.co.uk) Received-SPF: pass client-ip=2001:41c9:1:41f::167; envelope-from=mark.cave-ayland@ilande.co.uk; helo=mail.ilande.co.uk X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Convert the GLUE device to 3-phase reset. The legacy method doesn't do anything that's invalid in the hold phase, so the conversion is simple and not a behaviour change. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Laurent Vivier --- hw/m68k/q800-glue.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/hw/m68k/q800-glue.c b/hw/m68k/q800-glue.c index 34c4f0e987..710a5c331e 100644 --- a/hw/m68k/q800-glue.c +++ b/hw/m68k/q800-glue.c @@ -166,9 +166,9 @@ static void glue_nmi_release(void *opaque) GLUE_set_irq(s, GLUE_IRQ_IN_NMI, 0); } -static void glue_reset(DeviceState *dev) +static void glue_reset_hold(Object *obj) { - GLUEState *s = GLUE(dev); + GLUEState *s = GLUE(obj); s->ipr = 0; s->auxmode = 0; @@ -223,11 +223,12 @@ static void glue_init(Object *obj) static void glue_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + ResettableClass *rc = RESETTABLE_CLASS(klass); NMIClass *nc = NMI_CLASS(klass); dc->vmsd = &vmstate_glue; - dc->reset = glue_reset; device_class_set_props(dc, glue_properties); + rc->phases.hold = glue_reset_hold; nc->nmi_monitor_handler = glue_nmi; } From patchwork Wed Oct 4 08:37:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Mark Cave-Ayland X-Patchwork-Id: 13408376 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 9DE8DE8FDDB for ; Wed, 4 Oct 2023 08:39:21 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qnxOm-0003g4-KC; Wed, 04 Oct 2023 04:38:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxOk-0003ep-Vj for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:38:27 -0400 Received: from mail.ilande.co.uk ([2001:41c9:1:41f::167]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxOi-0007Ty-Re for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:38:26 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=ilande.co.uk; s=20220518; h=Subject:Content-Transfer-Encoding:Content-Type: MIME-Version:References:In-Reply-To:Message-Id:Date:To:From:Sender:Reply-To: Cc:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=G8Eo0E09oZspzZE0O+yelbvXEVPBsoyk6JWZU4UiYi8=; b=gtnp/2THRuW4lStrJGyguVLtST Eskrgen9jA5+srmatdsryQKYYU5LTOVGiYkJwAONGQW9OkDirtb9p7L7DT/lRM6W3bFepai5yb7rz Y7F8/Dj8D8taAG1eQxFwERtz5kE/q5gBc/9OiXPYGmRHGz423QkgpvxXiEwGks67Ee0HhYacedZO5 +pJTdiqHU8nEp6s1B+9C3BlgbGLGfWUv6Xc0j5Jx5bbQXlPlGlJdevBETd19wQX59Y3LX04LcH8xB a8zAFcOcgxyoPOCc4qU3KLFIheXaKfc6CzSkT+fwLtDkcyGB5Eqj+aXPEtlCDvt4zQEYN0Mup3ukA qkU9dSxnRFkYXshgT3iOrtnPTzWkiqPX1Dg/s8fQZ8skSglbaGH3U8C20eb4AUEf+ScNcssulZSzi SpswNyy9Sx4wBy+VpVOvCK0XHFA2FzIjnpiH/3QrmyegC151Y+7DJsGKeUxMy8kEldFI6PfKAWJ1X 0HgOV0m1TCaWzjiGk+r2PaeJ477pjZZYn9hAMbgvn76DpyDwZxCbi/KH1nzSGFZ6IUfGjtMz1OTV0 INSHWKMYGW0bw+FkB8U5mOCHm5eXaVT+Pp6NrUlo145rBctHqpD1ZdD+yjLSyqLRhIbz8//DHhHSk HJv3W4pgKSbVqvok+PYbuhKcP4NImoaWqWr6zvcu0=; Received: from host86-159-123-68.range86-159.btcentralplus.com ([86.159.123.68] helo=localhost.localdomain) by mail.ilande.co.uk with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qnxOS-0006za-Dn; Wed, 04 Oct 2023 09:38:12 +0100 From: Mark Cave-Ayland To: laurent@vivier.eu, qemu-devel@nongnu.org Date: Wed, 4 Oct 2023 09:37:48 +0100 Message-Id: <20231004083806.757242-3-mark.cave-ayland@ilande.co.uk> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> References: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 86.159.123.68 X-SA-Exim-Mail-From: mark.cave-ayland@ilande.co.uk Subject: [PATCH v4 02/20] q800: add djMEMC memory controller X-SA-Exim-Version: 4.2.1 (built Wed, 08 May 2019 21:11:16 +0000) X-SA-Exim-Scanned: Yes (on mail.ilande.co.uk) Received-SPF: pass client-ip=2001:41c9:1:41f::167; envelope-from=mark.cave-ayland@ilande.co.uk; helo=mail.ilande.co.uk X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org The djMEMC controller is used to store information related to the physical memory configuration. Co-developed-by: Laurent Vivier Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé --- MAINTAINERS | 2 + hw/m68k/Kconfig | 1 + hw/m68k/q800.c | 10 +++ hw/misc/Kconfig | 3 + hw/misc/djmemc.c | 135 +++++++++++++++++++++++++++++++++++++++ hw/misc/meson.build | 1 + hw/misc/trace-events | 4 ++ include/hw/m68k/q800.h | 2 + include/hw/misc/djmemc.h | 30 +++++++++ 9 files changed, 188 insertions(+) create mode 100644 hw/misc/djmemc.c create mode 100644 include/hw/misc/djmemc.h diff --git a/MAINTAINERS b/MAINTAINERS index 81625f036b..4ceb200c39 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1228,6 +1228,7 @@ F: hw/misc/mac_via.c F: hw/nubus/* F: hw/display/macfb.c F: hw/block/swim.c +F: hw/misc/djmemc.c F: hw/m68k/bootinfo.h F: include/standard-headers/asm-m68k/bootinfo.h F: include/standard-headers/asm-m68k/bootinfo-mac.h @@ -1237,6 +1238,7 @@ F: include/hw/display/macfb.h F: include/hw/block/swim.h F: include/hw/m68k/q800.h F: include/hw/m68k/q800-glue.h +F: include/hw/misc/djmemc.h virt M: Laurent Vivier diff --git a/hw/m68k/Kconfig b/hw/m68k/Kconfig index f839f8a030..330cfdfa2d 100644 --- a/hw/m68k/Kconfig +++ b/hw/m68k/Kconfig @@ -23,6 +23,7 @@ config Q800 select ESP select DP8393X select OR_IRQ + select DJMEMC config M68K_VIRT bool diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c index b770b71d54..f9ecc1fbb0 100644 --- a/hw/m68k/q800.c +++ b/hw/m68k/q800.c @@ -40,6 +40,7 @@ #include "hw/m68k/q800.h" #include "hw/m68k/q800-glue.h" #include "hw/misc/mac_via.h" +#include "hw/misc/djmemc.h" #include "hw/input/adb.h" #include "hw/nubus/mac-nubus-bridge.h" #include "hw/display/macfb.h" @@ -66,6 +67,7 @@ #define SONIC_PROM_BASE (IO_BASE + 0x08000) #define SONIC_BASE (IO_BASE + 0x0a000) #define SCC_BASE (IO_BASE + 0x0c020) +#define DJMEMC_BASE (IO_BASE + 0x0e000) #define ESP_BASE (IO_BASE + 0x10000) #define ESP_PDMA (IO_BASE + 0x10100) #define ASC_BASE (IO_BASE + 0x14000) @@ -257,6 +259,14 @@ static void q800_machine_init(MachineState *machine) &error_abort); sysbus_realize(SYS_BUS_DEVICE(&m->glue), &error_fatal); + /* djMEMC memory controller */ + object_initialize_child(OBJECT(machine), "djmemc", &m->djmemc, + TYPE_DJMEMC); + sysbus = SYS_BUS_DEVICE(&m->djmemc); + sysbus_realize_and_unref(sysbus, &error_fatal); + memory_region_add_subregion(&m->macio, DJMEMC_BASE - IO_BASE, + sysbus_mmio_get_region(sysbus, 0)); + /* VIA 1 */ object_initialize_child(OBJECT(machine), "via1", &m->via1, TYPE_MOS6522_Q800_VIA1); diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig index 6996d265e4..cb7857e3ed 100644 --- a/hw/misc/Kconfig +++ b/hw/misc/Kconfig @@ -186,4 +186,7 @@ config AXP2XX_PMU bool depends on I2C +config DJMEMC + bool + source macio/Kconfig diff --git a/hw/misc/djmemc.c b/hw/misc/djmemc.c new file mode 100644 index 0000000000..fd02640838 --- /dev/null +++ b/hw/misc/djmemc.c @@ -0,0 +1,135 @@ +/* + * djMEMC, macintosh memory and interrupt controller + * (Quadra 610/650/800 & Centris 610/650) + * + * https://mac68k.info/wiki/display/mac68k/djMEMC+Information + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "migration/vmstate.h" +#include "hw/misc/djmemc.h" +#include "hw/qdev-properties.h" +#include "trace.h" + + +#define DJMEMC_INTERLEAVECONF 0x0 +#define DJMEMC_BANK0CONF 0x4 +#define DJMEMC_BANK1CONF 0x8 +#define DJMEMC_BANK2CONF 0xc +#define DJMEMC_BANK3CONF 0x10 +#define DJMEMC_BANK4CONF 0x14 +#define DJMEMC_BANK5CONF 0x18 +#define DJMEMC_BANK6CONF 0x1c +#define DJMEMC_BANK7CONF 0x20 +#define DJMEMC_BANK8CONF 0x24 +#define DJMEMC_BANK9CONF 0x28 +#define DJMEMC_MEMTOP 0x2c +#define DJMEMC_CONFIG 0x30 +#define DJMEMC_REFRESH 0x34 + + +static uint64_t djmemc_read(void *opaque, hwaddr addr, unsigned size) +{ + DJMEMCState *s = opaque; + uint64_t val = 0; + + switch (addr) { + case DJMEMC_INTERLEAVECONF: + case DJMEMC_BANK0CONF ... DJMEMC_BANK9CONF: + case DJMEMC_MEMTOP: + case DJMEMC_CONFIG: + case DJMEMC_REFRESH: + val = s->regs[addr >> 2]; + break; + default: + qemu_log_mask(LOG_UNIMP, "djMEMC: unimplemented read addr=0x%"PRIx64 + " val=0x%"PRIx64 " size=%d\n", + addr, val, size); + } + + trace_djmemc_read(addr, val, size); + return val; +} + +static void djmemc_write(void *opaque, hwaddr addr, uint64_t val, + unsigned size) +{ + DJMEMCState *s = opaque; + + trace_djmemc_write(addr, val, size); + + switch (addr) { + case DJMEMC_INTERLEAVECONF: + case DJMEMC_BANK0CONF ... DJMEMC_BANK9CONF: + case DJMEMC_MEMTOP: + case DJMEMC_CONFIG: + case DJMEMC_REFRESH: + s->regs[addr >> 2] = val; + break; + default: + qemu_log_mask(LOG_UNIMP, "djMEMC: unimplemented write addr=0x%"PRIx64 + " val=0x%"PRIx64 " size=%d\n", + addr, val, size); + } +} + +static const MemoryRegionOps djmemc_mmio_ops = { + .read = djmemc_read, + .write = djmemc_write, + .impl = { + .min_access_size = 4, + .max_access_size = 4, + }, + .endianness = DEVICE_BIG_ENDIAN, +}; + +static void djmemc_init(Object *obj) +{ + DJMEMCState *s = DJMEMC(obj); + SysBusDevice *sbd = SYS_BUS_DEVICE(obj); + + memory_region_init_io(&s->mem_regs, obj, &djmemc_mmio_ops, s, "djMEMC", + DJMEMC_SIZE); + sysbus_init_mmio(sbd, &s->mem_regs); +} + +static void djmemc_reset_hold(Object *obj) +{ + DJMEMCState *s = DJMEMC(obj); + + memset(s->regs, 0, sizeof(s->regs)); +} + +static const VMStateDescription vmstate_djmemc = { + .name = "djMEMC", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT32_ARRAY(regs, DJMEMCState, DJMEMC_NUM_REGS), + VMSTATE_END_OF_LIST() + } +}; + +static void djmemc_class_init(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + ResettableClass *rc = RESETTABLE_CLASS(oc); + + dc->vmsd = &vmstate_djmemc; + rc->phases.hold = djmemc_reset_hold; +} + +static const TypeInfo djmemc_info_types[] = { + { + .name = TYPE_DJMEMC, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(DJMEMCState), + .instance_init = djmemc_init, + .class_init = djmemc_class_init, + }, +}; + +DEFINE_TYPES(djmemc_info_types) diff --git a/hw/misc/meson.build b/hw/misc/meson.build index 88ecab8392..ee5ee37648 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -20,6 +20,7 @@ system_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('armv7m_ras.c')) # Mac devices system_ss.add(when: 'CONFIG_MOS6522', if_true: files('mos6522.c')) +system_ss.add(when: 'CONFIG_DJMEMC', if_true: files('djmemc.c')) # virt devices system_ss.add(when: 'CONFIG_VIRT_CTRL', if_true: files('virt_ctrl.c')) diff --git a/hw/misc/trace-events b/hw/misc/trace-events index bc87cd3670..c71a47d288 100644 --- a/hw/misc/trace-events +++ b/hw/misc/trace-events @@ -301,3 +301,7 @@ virt_ctrl_instance_init(void *dev) "ctrl: %p" lasi_chip_mem_valid(uint64_t addr, uint32_t val) "access to addr 0x%"PRIx64" is %d" lasi_chip_read(uint64_t addr, uint32_t val) "addr 0x%"PRIx64" val 0x%08x" lasi_chip_write(uint64_t addr, uint32_t val) "addr 0x%"PRIx64" val 0x%08x" + +# djmemc.c +djmemc_read(int reg, uint64_t value, unsigned int size) "reg=0x%x value=0x%"PRIx64" size=%u" +djmemc_write(int reg, uint64_t value, unsigned int size) "reg=0x%x value=0x%"PRIx64" size=%u" diff --git a/include/hw/m68k/q800.h b/include/hw/m68k/q800.h index b3d77f1cba..f6ae4c1c4f 100644 --- a/include/hw/m68k/q800.h +++ b/include/hw/m68k/q800.h @@ -36,6 +36,7 @@ #include "hw/block/swim.h" #include "hw/nubus/mac-nubus-bridge.h" #include "hw/display/macfb.h" +#include "hw/misc/djmemc.h" /* * The main Q800 machine @@ -56,6 +57,7 @@ struct Q800MachineState { Swim swim; MacNubusBridge mac_nubus_bridge; MacfbNubusState macfb; + DJMEMCState djmemc; MemoryRegion macio; MemoryRegion macio_alias; }; diff --git a/include/hw/misc/djmemc.h b/include/hw/misc/djmemc.h new file mode 100644 index 0000000000..82d4e4a2fe --- /dev/null +++ b/include/hw/misc/djmemc.h @@ -0,0 +1,30 @@ +/* + * djMEMC, macintosh memory and interrupt controller + * (Quadra 610/650/800 & Centris 610/650) + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_MISC_DJMEMC_H +#define HW_MISC_DJMEMC_H + +#include "hw/sysbus.h" + +#define DJMEMC_SIZE 0x2000 +#define DJMEMC_NUM_REGS (0x38 / sizeof(uint32_t)) + +#define DJMEMC_MAXBANKS 10 + +struct DJMEMCState { + SysBusDevice parent_obj; + + MemoryRegion mem_regs; + + /* Memory controller */ + uint32_t regs[DJMEMC_NUM_REGS]; +}; + +#define TYPE_DJMEMC "djMEMC" +OBJECT_DECLARE_SIMPLE_TYPE(DJMEMCState, DJMEMC); + +#endif From patchwork Wed Oct 4 08:37:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Mark Cave-Ayland X-Patchwork-Id: 13408374 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 593C4E8FDDA for ; Wed, 4 Oct 2023 08:39:09 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qnxOp-0003h7-Dm; Wed, 04 Oct 2023 04:38:31 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxOn-0003gk-JM for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:38:29 -0400 Received: from mail.ilande.co.uk ([2001:41c9:1:41f::167]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxOl-0007UT-VV for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:38:29 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=ilande.co.uk; s=20220518; h=Subject:Content-Transfer-Encoding:Content-Type: MIME-Version:References:In-Reply-To:Message-Id:Date:To:From:Sender:Reply-To: Cc:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=IDLFcl0e5ItObYwnhkzeKKRrhamJk4a+C90DzoJf2qs=; b=R3j4hCTxYkXUPtxololnuB4am2 qy/V8tjlnMIpQJ+Et1YWvLgwa3b8IBE0u9qltYmcLV165d9Dt1HUmY39O5wc6OdAt/zS2tf0aA36B JCdtjr5b26aJXSJjs7WKksU4317FRHkIWk6uRK8c2W6lNTgKLp9amQ9l6gcJXwpLf3/sPKT67up/2 V7BFbjIMVUPuaRf+GpETYdtik5/7h4lVJp2QPjZMe6WSzO5OsuVS2rfkq42W9UfWbJ/7bWqX8CEku UnA+5AnSlBFtUsZQFrnGdIaqPkPrSp0OG5H7EaNqx1mmEQ0XXNj55/Ss94UyIRabQbRHz5t5HVaBP SQqHetiAFa/I5I7vrQ+pd4eQs6kNxBbJzYnG9MAPItzgCRdqT0sHlYQAbqEl7HwYGfokMwUESohfh 70yurnyVEMQ610dpHBnnlRtLcEqj8lvAKUESKiqP2GKZ9YWUxlYj8Kp2303G2w/SGQmEsclJista/ xakw5wPVI10snFK/j+izJP5w0f9UVibB9Q9/YcDWMNCe21TqU2jebbqH46QpJoOt179iEKfhG6nVf 80UJ+q6a1/wFzbLvMSWfGvQbY1rMK0g167PxMD6c9CWn4laor4gVtvBxDy8tDRo9PKg/Uib6r3tl1 vUAAJ3fpbMDz6VpP93NlPK2d1UDo1YEpz4p3P7pvs=; Received: from host86-159-123-68.range86-159.btcentralplus.com ([86.159.123.68] helo=localhost.localdomain) by mail.ilande.co.uk with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qnxOW-0006za-KR; Wed, 04 Oct 2023 09:38:16 +0100 From: Mark Cave-Ayland To: laurent@vivier.eu, qemu-devel@nongnu.org Date: Wed, 4 Oct 2023 09:37:49 +0100 Message-Id: <20231004083806.757242-4-mark.cave-ayland@ilande.co.uk> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> References: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 86.159.123.68 X-SA-Exim-Mail-From: mark.cave-ayland@ilande.co.uk Subject: [PATCH v4 03/20] q800: add machine id register X-SA-Exim-Version: 4.2.1 (built Wed, 08 May 2019 21:11:16 +0000) X-SA-Exim-Scanned: Yes (on mail.ilande.co.uk) Received-SPF: pass client-ip=2001:41c9:1:41f::167; envelope-from=mark.cave-ayland@ilande.co.uk; helo=mail.ilande.co.uk X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org MacOS reads this address to identify the hardware. This is a basic implementation returning the ID of Quadra 800. Details: http://mess.redump.net/mess/driver_info/mac_technical_notes "There are 3 ID schemes [...] The third and most scalable is a machine ID register at 0x5ffffffc. The top word must be 0xa55a to be valid. Then bits 15-11 are 0 for consumer Macs, 1 for portables, 2 for high-end 68k, and 3 for high-end PowerPC. Bit 10 is 1 if additional ID bits appear elsewhere (e.g. in VIA1). The rest of the bits are a per-model identifier. Model Lower 16 bits of ID ... Quadra/Centris 610/650/800 0x2BAD" Co-developed-by: Laurent Vivier Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé --- hw/m68k/q800.c | 29 +++++++++++++++++++++++++++++ include/hw/m68k/q800.h | 1 + 2 files changed, 30 insertions(+) diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c index f9ecc1fbb0..ac8509ba6f 100644 --- a/hw/m68k/q800.c +++ b/hw/m68k/q800.c @@ -91,6 +91,9 @@ #define Q800_NUBUS_SLOTS_AVAILABLE (BIT(0x9) | BIT(0xc) | BIT(0xd) | \ BIT(0xe)) +/* Quadra 800 machine ID */ +#define Q800_MACHINE_ID 0xa55a2bad + static void main_cpu_reset(void *opaque) { @@ -192,6 +195,27 @@ static const MemoryRegionOps macio_alias_ops = { }, }; +static uint64_t machine_id_read(void *opaque, hwaddr addr, unsigned size) +{ + return Q800_MACHINE_ID; +} + +static void machine_id_write(void *opaque, hwaddr addr, uint64_t val, + unsigned size) +{ + return; +} + +static const MemoryRegionOps machine_id_ops = { + .read = machine_id_read, + .write = machine_id_write, + .endianness = DEVICE_BIG_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4, + }, +}; + static void q800_machine_init(MachineState *machine) { Q800MachineState *m = Q800_MACHINE(machine); @@ -253,6 +277,11 @@ static void q800_machine_init(MachineState *machine) memory_region_add_subregion(get_system_memory(), IO_BASE + IO_SLICE, &m->macio_alias); + memory_region_init_io(&m->machine_id, NULL, &machine_id_ops, NULL, + "Machine ID", 4); + memory_region_add_subregion(get_system_memory(), 0x5ffffffc, + &m->machine_id); + /* IRQ Glue */ object_initialize_child(OBJECT(machine), "glue", &m->glue, TYPE_GLUE); object_property_set_link(OBJECT(&m->glue), "cpu", OBJECT(&m->cpu), diff --git a/include/hw/m68k/q800.h b/include/hw/m68k/q800.h index f6ae4c1c4f..dd7d7a6f2c 100644 --- a/include/hw/m68k/q800.h +++ b/include/hw/m68k/q800.h @@ -60,6 +60,7 @@ struct Q800MachineState { DJMEMCState djmemc; MemoryRegion macio; MemoryRegion macio_alias; + MemoryRegion machine_id; }; #define TYPE_Q800_MACHINE MACHINE_TYPE_NAME("q800") From patchwork Wed Oct 4 08:37:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Mark Cave-Ayland X-Patchwork-Id: 13408378 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A7E06E8FDDA for ; Wed, 4 Oct 2023 08:39:29 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qnxOq-0003ij-WC; Wed, 04 Oct 2023 04:38:33 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxOo-0003gz-Tk for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:38:30 -0400 Received: from mail.ilande.co.uk ([2001:41c9:1:41f::167]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxOn-0007Ui-E4 for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:38:30 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=ilande.co.uk; s=20220518; h=Subject:Content-Transfer-Encoding:Content-Type: MIME-Version:References:In-Reply-To:Message-Id:Date:To:From:Sender:Reply-To: Cc:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=Yq4FVlsatCpO1BqFxeAfy1d7RPiheuwvpjbMMHlmwno=; b=Sps4aHHFcO8UUmRsNXHjf6YVtK lFdjnnu1mwxX9RzTvKvG/g/Iw9Y7ZDZZPqXVkUNaFy+rWtuIXMV6YRYyDE3tasYgR7l21ByCGohex 8/CHc0CJ/v2/MhPUafQnYAwDnMLTCyK2Bl5D7GpLQIxQSsPfbKXgXPGbN19gg+ZLru+aoNVj4Rg9b ivS3UE6cGbUPN3c+48rMKrC3+TQpnxF8tqSQT0qDQglyVAJTb+gxeSkIwR5lUPd4nVBc/UXediIGs 5nDDyVl+RdUZgXDUV50TU/K/W3HiqD0ivauZttC+eNdp1iOJj6Kk3FBOBitsj7cfqRZKE+7XBJqob JE4vlhJjLRy5jAZJRj+5OLSKHD4F/jMFn12OzAHjhl3tIAQUay4WuOe2MsnWGEpdjlYpD8rLyTd1V bmj7nTHidaX1C62sbxIg/JeDZIR+BtbPvR/fjHzbtxdZnTB1xZAoHooE6+C3oHztw/nZKmVdPeHnT dDG9lRpQxXzE+ZRtbuSoiM6ulJqxap5/GR+8N8RbpfuoWN1s/gzsG8VWOLz1+bvq8rstbYZcC0pQV VsP/GgdEHRR5GSClUQAfnE3JiZYKgBFXQ+2qfA0HGuLb9vRP7HKtgxRF83QIJzCY8bdtLJ0lkSJhF t1girxQPmIjAk0w/7/xtIU8tmGdrjq4eoGmbT9TOg=; Received: from host86-159-123-68.range86-159.btcentralplus.com ([86.159.123.68] helo=localhost.localdomain) by mail.ilande.co.uk with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qnxOb-0006za-0U; Wed, 04 Oct 2023 09:38:18 +0100 From: Mark Cave-Ayland To: laurent@vivier.eu, qemu-devel@nongnu.org Date: Wed, 4 Oct 2023 09:37:50 +0100 Message-Id: <20231004083806.757242-5-mark.cave-ayland@ilande.co.uk> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> References: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 86.159.123.68 X-SA-Exim-Mail-From: mark.cave-ayland@ilande.co.uk Subject: [PATCH v4 04/20] q800: implement additional machine id bits on VIA1 port A X-SA-Exim-Version: 4.2.1 (built Wed, 08 May 2019 21:11:16 +0000) X-SA-Exim-Scanned: Yes (on mail.ilande.co.uk) Received-SPF: pass client-ip=2001:41c9:1:41f::167; envelope-from=mark.cave-ayland@ilande.co.uk; helo=mail.ilande.co.uk X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Co-developed-by: Laurent Vivier Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé --- hw/misc/mac_via.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c index f84cc68849..e87a1b82d8 100644 --- a/hw/misc/mac_via.c +++ b/hw/misc/mac_via.c @@ -114,6 +114,9 @@ #define VIA1A_CPUID1 0x04 /* CPU id bit 0 on RBV, others */ #define VIA1A_CPUID2 0x10 /* CPU id bit 0 on RBV, others */ #define VIA1A_CPUID3 0x40 /* CPU id bit 0 on RBV, others */ +#define VIA1A_CPUID_MASK (VIA1A_CPUID0 | VIA1A_CPUID1 | \ + VIA1A_CPUID2 | VIA1A_CPUID3) +#define VIA1A_CPUID_Q800 (VIA1A_CPUID0 | VIA1A_CPUID2) /* * Info on VIA1B is from Macintosh Family Hardware & MkLinux. @@ -872,9 +875,18 @@ static uint64_t mos6522_q800_via1_read(void *opaque, hwaddr addr, unsigned size) { MOS6522Q800VIA1State *s = MOS6522_Q800_VIA1(opaque); MOS6522State *ms = MOS6522(s); + uint64_t ret; addr = (addr >> 9) & 0xf; - return mos6522_read(ms, addr, size); + ret = mos6522_read(ms, addr, size); + switch (addr) { + case VIA_REG_A: + case VIA_REG_ANH: + /* Quadra 800 Id */ + ret = (ret & ~VIA1A_CPUID_MASK) | VIA1A_CPUID_Q800; + break; + } + return ret; } static void mos6522_q800_via1_write(void *opaque, hwaddr addr, uint64_t val, From patchwork Wed Oct 4 08:37:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Cave-Ayland X-Patchwork-Id: 13408388 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B486BE8FDDB for ; Wed, 4 Oct 2023 08:41:00 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qnxOv-0003mh-Ld; Wed, 04 Oct 2023 04:38:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxOu-0003jQ-0M for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:38:36 -0400 Received: from mail.ilande.co.uk ([2001:41c9:1:41f::167]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxOs-0007Vb-3i for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:38:35 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=ilande.co.uk; s=20220518; h=Subject:Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:To:From:Sender:Reply-To:Cc: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=cJOQ2MDWyBPk/Q5v33d5Eyj0EhV7UlXM2SOqyZntYHU=; b=ZAUN3VLh5wEY2RW4GDOj69qUZM 4+b8/3cd1YF+cd0TnAoLlpHFL7OLSM6Ytej9BU5YTwAO0n/e3L3VV1bGuGUPwQynSCV2aW4yuceC9 YK32zGbAKvE7C+tXk4qUVPnmeiTmC5EXCrGQ4FHf1X1O/oXcWngX3H8puR/ZxetJ9o5ZSCJjEqOPi LWP/jJOzHSFPHUyT0FQLbZII4SgsAbptobYOfSJiEzqCANw7Uw39OAwmKccC9SD4ail4vq6BsmIrQ Hh3pBbtHKQBFx2USn5fhoosNPTEJ8V5GsAYMjQWLMH/QGcdknhdxb8BzrATIhJZL5XtfMKEhr+U98 f6gJngDr0y6fl68ne21o0RYEuMnxROenpBuH943FbdZwdCVJ8RM0lMqMySz4hfN6LVa7uwuY9+5OT wmN9w648amk9fgbpOlqy2a6+cxcDT6rTZAjRlG/ksjYHGGYJmTT5KeKMYeSds/aK5Eu1nc8y/SdQq mLNy730Lbae0TLPDAcrUgAr70mgC7eLVABFlkJpkYkTR4QgKQZrPjpY+/ohx2GaURsRktD/3xGB8s 8b37izt5DF9Gb8P+xi5TJc1yDTYg9ag6JYcDfV/CE8PLt+C7tPkjkVB7qNOMchtYi6PwQibSNJfnX nrG1AkGGN2cWQ+cLBH/Qb0IO0vooqyk5zqyf2touM=; Received: from host86-159-123-68.range86-159.btcentralplus.com ([86.159.123.68] helo=localhost.localdomain) by mail.ilande.co.uk with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qnxOc-0006za-F2; Wed, 04 Oct 2023 09:38:22 +0100 From: Mark Cave-Ayland To: laurent@vivier.eu, qemu-devel@nongnu.org Date: Wed, 4 Oct 2023 09:37:51 +0100 Message-Id: <20231004083806.757242-6-mark.cave-ayland@ilande.co.uk> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> References: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 86.159.123.68 X-SA-Exim-Mail-From: mark.cave-ayland@ilande.co.uk Subject: [PATCH v4 05/20] q800: add IOSB subsystem X-SA-Exim-Version: 4.2.1 (built Wed, 08 May 2019 21:11:16 +0000) X-SA-Exim-Scanned: Yes (on mail.ilande.co.uk) Received-SPF: pass client-ip=2001:41c9:1:41f::167; envelope-from=mark.cave-ayland@ilande.co.uk; helo=mail.ilande.co.uk X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org It is needed because it defines the BIOSConfig area. Co-developed-by: Laurent Vivier Signed-off-by: Mark Cave-Ayland Reviewed-by: BALATON Zoltan --- MAINTAINERS | 2 + hw/m68k/Kconfig | 1 + hw/m68k/q800.c | 9 +++ hw/misc/Kconfig | 3 + hw/misc/iosb.c | 133 +++++++++++++++++++++++++++++++++++++++++ hw/misc/meson.build | 1 + hw/misc/trace-events | 4 ++ include/hw/m68k/q800.h | 2 + include/hw/misc/iosb.h | 25 ++++++++ 9 files changed, 180 insertions(+) create mode 100644 hw/misc/iosb.c create mode 100644 include/hw/misc/iosb.h diff --git a/MAINTAINERS b/MAINTAINERS index 4ceb200c39..371a983b5a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1229,6 +1229,7 @@ F: hw/nubus/* F: hw/display/macfb.c F: hw/block/swim.c F: hw/misc/djmemc.c +F: hw/misc/iosb.c F: hw/m68k/bootinfo.h F: include/standard-headers/asm-m68k/bootinfo.h F: include/standard-headers/asm-m68k/bootinfo-mac.h @@ -1239,6 +1240,7 @@ F: include/hw/block/swim.h F: include/hw/m68k/q800.h F: include/hw/m68k/q800-glue.h F: include/hw/misc/djmemc.h +F: include/hw/misc/iosb.h virt M: Laurent Vivier diff --git a/hw/m68k/Kconfig b/hw/m68k/Kconfig index 330cfdfa2d..64fa70a0db 100644 --- a/hw/m68k/Kconfig +++ b/hw/m68k/Kconfig @@ -24,6 +24,7 @@ config Q800 select DP8393X select OR_IRQ select DJMEMC + select IOSB config M68K_VIRT bool diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c index ac8509ba6f..081b95e9cf 100644 --- a/hw/m68k/q800.c +++ b/hw/m68k/q800.c @@ -41,6 +41,7 @@ #include "hw/m68k/q800-glue.h" #include "hw/misc/mac_via.h" #include "hw/misc/djmemc.h" +#include "hw/misc/iosb.h" #include "hw/input/adb.h" #include "hw/nubus/mac-nubus-bridge.h" #include "hw/display/macfb.h" @@ -71,6 +72,7 @@ #define ESP_BASE (IO_BASE + 0x10000) #define ESP_PDMA (IO_BASE + 0x10100) #define ASC_BASE (IO_BASE + 0x14000) +#define IOSB_BASE (IO_BASE + 0x18000) #define SWIM_BASE (IO_BASE + 0x1E000) #define SONIC_PROM_SIZE 0x1000 @@ -296,6 +298,13 @@ static void q800_machine_init(MachineState *machine) memory_region_add_subregion(&m->macio, DJMEMC_BASE - IO_BASE, sysbus_mmio_get_region(sysbus, 0)); + /* IOSB subsystem */ + object_initialize_child(OBJECT(machine), "iosb", &m->iosb, TYPE_IOSB); + sysbus = SYS_BUS_DEVICE(&m->iosb); + sysbus_realize_and_unref(sysbus, &error_fatal); + memory_region_add_subregion(&m->macio, IOSB_BASE - IO_BASE, + sysbus_mmio_get_region(sysbus, 0)); + /* VIA 1 */ object_initialize_child(OBJECT(machine), "via1", &m->via1, TYPE_MOS6522_Q800_VIA1); diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig index cb7857e3ed..858277bb60 100644 --- a/hw/misc/Kconfig +++ b/hw/misc/Kconfig @@ -189,4 +189,7 @@ config AXP2XX_PMU config DJMEMC bool +config IOSB + bool + source macio/Kconfig diff --git a/hw/misc/iosb.c b/hw/misc/iosb.c new file mode 100644 index 0000000000..e7e9dcca47 --- /dev/null +++ b/hw/misc/iosb.c @@ -0,0 +1,133 @@ +/* + * QEMU IOSB emulation + * + * Copyright (c) 2019 Laurent Vivier + * Copyright (c) 2022 Mark Cave-Ayland + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "migration/vmstate.h" +#include "hw/sysbus.h" +#include "hw/misc/iosb.h" +#include "trace.h" + +#define IOSB_SIZE 0x2000 + +#define IOSB_CONFIG 0x0 +#define IOSB_CONFIG2 0x100 +#define IOSB_SONIC_SCSI 0x200 +#define IOSB_REVISION 0x300 +#define IOSB_SCSI_RESID 0x400 +#define IOSB_BRIGHTNESS 0x500 +#define IOSB_TIMEOUT 0x600 + + +static uint64_t iosb_read(void *opaque, hwaddr addr, + unsigned size) +{ + IOSBState *s = IOSB(opaque); + uint64_t val = 0; + + switch (addr) { + case IOSB_CONFIG: + case IOSB_CONFIG2: + case IOSB_SONIC_SCSI: + case IOSB_REVISION: + case IOSB_SCSI_RESID: + case IOSB_BRIGHTNESS: + case IOSB_TIMEOUT: + val = s->regs[addr >> 8]; + break; + default: + qemu_log_mask(LOG_UNIMP, "IOSB: unimplemented read addr=0x%"PRIx64 + " val=0x%"PRIx64 " size=%d\n", + addr, val, size); + } + + trace_iosb_read(addr, val, size); + return val; +} + +static void iosb_write(void *opaque, hwaddr addr, uint64_t val, + unsigned size) +{ + IOSBState *s = IOSB(opaque); + + switch (addr) { + case IOSB_CONFIG: + case IOSB_CONFIG2: + case IOSB_SONIC_SCSI: + case IOSB_REVISION: + case IOSB_SCSI_RESID: + case IOSB_BRIGHTNESS: + case IOSB_TIMEOUT: + s->regs[addr >> 8] = val; + break; + default: + qemu_log_mask(LOG_UNIMP, "IOSB: unimplemented write addr=0x%"PRIx64 + " val=0x%"PRIx64 " size=%d\n", + addr, val, size); + } + + trace_iosb_write(addr, val, size); +} + +static const MemoryRegionOps iosb_mmio_ops = { + .read = iosb_read, + .write = iosb_write, + .endianness = DEVICE_BIG_ENDIAN, +}; + +static void iosb_reset_hold(Object *obj) +{ + IOSBState *s = IOSB(obj); + + memset(s->regs, 0, sizeof(s->regs)); + + /* BCLK 33 MHz */ + s->regs[IOSB_CONFIG >> 8] = 1; +} + +static void iosb_init(Object *obj) +{ + IOSBState *s = IOSB(obj); + SysBusDevice *sbd = SYS_BUS_DEVICE(obj); + + memory_region_init_io(&s->mem_regs, obj, &iosb_mmio_ops, s, "IOSB", + IOSB_SIZE); + sysbus_init_mmio(sbd, &s->mem_regs); +} + +static const VMStateDescription vmstate_iosb = { + .name = "IOSB", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT32_ARRAY(regs, IOSBState, IOSB_REGS), + VMSTATE_END_OF_LIST() + } +}; + +static void iosb_class_init(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + ResettableClass *rc = RESETTABLE_CLASS(oc); + + dc->vmsd = &vmstate_iosb; + rc->phases.hold = iosb_reset_hold; +} + +static const TypeInfo iosb_info_types[] = { + { + .name = TYPE_IOSB, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(IOSBState), + .instance_init = iosb_init, + .class_init = iosb_class_init, + }, +}; + +DEFINE_TYPES(iosb_info_types) diff --git a/hw/misc/meson.build b/hw/misc/meson.build index ee5ee37648..33659313b4 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -21,6 +21,7 @@ system_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('armv7m_ras.c')) # Mac devices system_ss.add(when: 'CONFIG_MOS6522', if_true: files('mos6522.c')) system_ss.add(when: 'CONFIG_DJMEMC', if_true: files('djmemc.c')) +system_ss.add(when: 'CONFIG_IOSB', if_true: files('iosb.c')) # virt devices system_ss.add(when: 'CONFIG_VIRT_CTRL', if_true: files('virt_ctrl.c')) diff --git a/hw/misc/trace-events b/hw/misc/trace-events index c71a47d288..29bc531d4d 100644 --- a/hw/misc/trace-events +++ b/hw/misc/trace-events @@ -305,3 +305,7 @@ lasi_chip_write(uint64_t addr, uint32_t val) "addr 0x%"PRIx64" val 0x%08x" # djmemc.c djmemc_read(int reg, uint64_t value, unsigned int size) "reg=0x%x value=0x%"PRIx64" size=%u" djmemc_write(int reg, uint64_t value, unsigned int size) "reg=0x%x value=0x%"PRIx64" size=%u" + +# iosb.c +iosb_read(int reg, uint64_t value, unsigned int size) "reg=0x%x value=0x%"PRIx64" size=%u" +iosb_write(int reg, uint64_t value, unsigned int size) "reg=0x%x value=0x%"PRIx64" size=%u" diff --git a/include/hw/m68k/q800.h b/include/hw/m68k/q800.h index dd7d7a6f2c..98097165d9 100644 --- a/include/hw/m68k/q800.h +++ b/include/hw/m68k/q800.h @@ -37,6 +37,7 @@ #include "hw/nubus/mac-nubus-bridge.h" #include "hw/display/macfb.h" #include "hw/misc/djmemc.h" +#include "hw/misc/iosb.h" /* * The main Q800 machine @@ -58,6 +59,7 @@ struct Q800MachineState { MacNubusBridge mac_nubus_bridge; MacfbNubusState macfb; DJMEMCState djmemc; + IOSBState iosb; MemoryRegion macio; MemoryRegion macio_alias; MemoryRegion machine_id; diff --git a/include/hw/misc/iosb.h b/include/hw/misc/iosb.h new file mode 100644 index 0000000000..377f8ca7e2 --- /dev/null +++ b/include/hw/misc/iosb.h @@ -0,0 +1,25 @@ +/* + * QEMU IOSB emulation + * + * Copyright (c) 2019 Laurent Vivier + * Copyright (c) 2022 Mark Cave-Ayland + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_MEM_IOSB_H +#define HW_MEM_IOSB_H + +#define IOSB_REGS 7 + +struct IOSBState { + SysBusDevice parent_obj; + + MemoryRegion mem_regs; + uint32_t regs[IOSB_REGS]; +}; + +#define TYPE_IOSB "IOSB" +OBJECT_DECLARE_SIMPLE_TYPE(IOSBState, IOSB); + +#endif From patchwork Wed Oct 4 08:37:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Mark Cave-Ayland X-Patchwork-Id: 13408386 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 6DA78E8FDDA for ; Wed, 4 Oct 2023 08:40:33 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qnxOx-0003rU-JZ; Wed, 04 Oct 2023 04:38:39 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxOw-0003oy-Gq for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:38:38 -0400 Received: from mail.ilande.co.uk ([2001:41c9:1:41f::167]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxOu-0007Vx-W1 for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:38:38 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=ilande.co.uk; s=20220518; h=Subject:Content-Transfer-Encoding:Content-Type: MIME-Version:References:In-Reply-To:Message-Id:Date:To:From:Sender:Reply-To: Cc:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=Jy6K0cKwB1zQ7ttHjHuJHcM4wAstBU3zagIKsjH/jMQ=; b=1ZEPtgj+T6s3a9+dS104TfA2Fe EASp9UFiHK6rrUdLGznwR9wJvufYIDcPvvHjTjC1xrSRl3KbUn3TFblKLxzfLAofx0zVLzNRRMsqC stC4dgWxbYwrtCuIdNFsfBTZF5m/kEXsFuHYZUx3NSMQ03PaJZ8c9j/L11YjbZt2sqinTC+vNdcS3 U7MBVo/NkI33btamqYowMx6g0aZLqnWPvDkeCiukAW/C9qbpMq29k+3DznnLeWhK54rYCVYihbo3v EMl+m9+2g89G56yY1QBciDKYSfAyRM1xreNMXQY6tPi9JqG/XQGJURBTZDBxahxQIFl+Lud10EaUA NEsvmaLKsWqUPquEUh74FGCJ2oJkTgKGvg4rcusFi7+v8pNJCwXCshoXVholAEUhjyar8y42FxAnL q4w+ZxPr6RsFDGlI8R/rkoEiSwPG9mooEGaSN2KzT6EdJGRlQBVcwGRKrHr0C/suJ8Ygvas2NIHUC YAJuTxqNPQv2W2vGWjbH6QBgI/3yn9GL41DEwljz/utmPUs424dH4GyG8hxn3TyeRIsumPzkYAzSy +rJejIQ9juA2IAO5RhSBhRLf6vXkctL4bg6I6Lew7vDUYTsDwypnxz8P0QF29sLteAhNjPUaMOcDr G1LZ8koefJ0VXROlRx8HdlwIPf52q8EI4jXdJQMrY=; Received: from host86-159-123-68.range86-159.btcentralplus.com ([86.159.123.68] helo=localhost.localdomain) by mail.ilande.co.uk with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qnxOg-0006za-NB; Wed, 04 Oct 2023 09:38:26 +0100 From: Mark Cave-Ayland To: laurent@vivier.eu, qemu-devel@nongnu.org Date: Wed, 4 Oct 2023 09:37:52 +0100 Message-Id: <20231004083806.757242-7-mark.cave-ayland@ilande.co.uk> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> References: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 86.159.123.68 X-SA-Exim-Mail-From: mark.cave-ayland@ilande.co.uk Subject: [PATCH v4 06/20] q800: allow accesses to RAM area even if less memory is available X-SA-Exim-Version: 4.2.1 (built Wed, 08 May 2019 21:11:16 +0000) X-SA-Exim-Scanned: Yes (on mail.ilande.co.uk) Received-SPF: pass client-ip=2001:41c9:1:41f::167; envelope-from=mark.cave-ayland@ilande.co.uk; helo=mail.ilande.co.uk X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org MacOS attempts a series of writes and reads over the entire RAM area in order to determine the amount of RAM within the machine. Allow accesses to the entire RAM area ignoring writes and always reading zero for areas where there is no physical RAM installed to allow MacOS to detect the memory size without faulting. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Laurent Vivier --- hw/m68k/q800.c | 30 +++++++++++++++++++++++++++++- include/hw/m68k/q800.h | 1 + 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c index 081b95e9cf..3209309173 100644 --- a/hw/m68k/q800.c +++ b/hw/m68k/q800.c @@ -86,6 +86,9 @@ #define MAC_CLOCK 3686418 +/* Size of whole RAM area */ +#define RAM_SIZE 0x40000000 + /* * Slot 0x9 is reserved for use by the in-built framebuffer whilst only * slots 0xc, 0xd and 0xe physically exist on the Quadra 800 @@ -218,6 +221,27 @@ static const MemoryRegionOps machine_id_ops = { }, }; +static uint64_t ramio_read(void *opaque, hwaddr addr, unsigned size) +{ + return 0x0; +} + +static void ramio_write(void *opaque, hwaddr addr, uint64_t val, + unsigned size) +{ + return; +} + +static const MemoryRegionOps ramio_ops = { + .read = ramio_read, + .write = ramio_write, + .endianness = DEVICE_BIG_ENDIAN, + .valid = { + .min_access_size = 1, + .max_access_size = 4, + }, +}; + static void q800_machine_init(MachineState *machine) { Q800MachineState *m = Q800_MACHINE(machine); @@ -262,7 +286,11 @@ static void q800_machine_init(MachineState *machine) qemu_register_reset(main_cpu_reset, &m->cpu); /* RAM */ - memory_region_add_subregion(get_system_memory(), 0, machine->ram); + memory_region_init_io(&m->ramio, OBJECT(machine), &ramio_ops, &m->ramio, + "ram", RAM_SIZE); + memory_region_add_subregion(get_system_memory(), 0x0, &m->ramio); + + memory_region_add_subregion(&m->ramio, 0, machine->ram); /* * Create container for all IO devices diff --git a/include/hw/m68k/q800.h b/include/hw/m68k/q800.h index 98097165d9..04e4e0bce3 100644 --- a/include/hw/m68k/q800.h +++ b/include/hw/m68k/q800.h @@ -60,6 +60,7 @@ struct Q800MachineState { MacfbNubusState macfb; DJMEMCState djmemc; IOSBState iosb; + MemoryRegion ramio; MemoryRegion macio; MemoryRegion macio_alias; MemoryRegion machine_id; From patchwork Wed Oct 4 08:37:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Mark Cave-Ayland X-Patchwork-Id: 13408391 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B3F35E8FDDC for ; Wed, 4 Oct 2023 08:41:15 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qnxP4-0003xB-7M; Wed, 04 Oct 2023 04:38:46 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxP2-0003w8-IQ for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:38:44 -0400 Received: from mail.ilande.co.uk ([2001:41c9:1:41f::167]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxOz-0007YK-Gq for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:38:44 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=ilande.co.uk; s=20220518; h=Subject:Content-Transfer-Encoding:Content-Type: MIME-Version:References:In-Reply-To:Message-Id:Date:To:From:Sender:Reply-To: Cc:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=c7oN6ssm4EPmhMGqYqs3ExKtIUCAn3yIdy1PvTLLl0Y=; b=GDrLrosL+w7J8yylBvvuUuJoMw nmlohp3UgEszc9w5p+EZSctZSR1rEE1jrzkrF7jONdS3ELBNKmSKx3e1a9l3z+zGUWwzvJ4bFv8dx bK+gZ/MI015SCtnNuXEP+R0/xQgxyIAMIKqjE+PNCX9sFa7BdJ2IuNUX6J91GsEEey83htEyn2yjj EdZZUmroDLBaHZq3P5zeUM6XFC/9G0FdMvcAnoa842dLyffLfWzYCC5Fpg0pEpwUKWP6yjglj+tPJ a+cfy7IF/F28B49sl84HhDRMtCPrmOGIi+WMu33tLABoVAEnI0KSGoW8C3DN7vXZhGe5qbzZ1Nv+q kuhhnZjBIzOJst1+K/YxUO9wlaWrrSjSqwsbDJdRzWcwr7BtrHq2QY9KpeJw4q9pKEzHRbjo9SJcO TjmwPVOwfHw5jzLNAl1eUJT2XLgIZEZANZGpzFfGKE0Dbt9pLraqrcZOMS1I2VDY8fg4HoXn3/y15 T9wvqz13mOLyZwjDMp88rRML5FhvcR7UuvKw0GBGMjO3KiexVCY6wSnipUf7ofaM9NU0X7jL8FVMs 0kMPSry0TC7TNNRTj8CWn3SUvJJZ01bmKI3JVMko5xH9uzdru1zBM1gP8tv1xOufxZpXrmh5bPPsp fLkgHvO7k7FHvIwRUbjzce7eVOvkxyTlLZQujf5dM=; Received: from host86-159-123-68.range86-159.btcentralplus.com ([86.159.123.68] helo=localhost.localdomain) by mail.ilande.co.uk with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qnxOk-0006za-8w; Wed, 04 Oct 2023 09:38:30 +0100 From: Mark Cave-Ayland To: laurent@vivier.eu, qemu-devel@nongnu.org Date: Wed, 4 Oct 2023 09:37:53 +0100 Message-Id: <20231004083806.757242-8-mark.cave-ayland@ilande.co.uk> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> References: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 86.159.123.68 X-SA-Exim-Mail-From: mark.cave-ayland@ilande.co.uk Subject: [PATCH v4 07/20] audio: add Apple Sound Chip (ASC) emulation X-SA-Exim-Version: 4.2.1 (built Wed, 08 May 2019 21:11:16 +0000) X-SA-Exim-Scanned: Yes (on mail.ilande.co.uk) Received-SPF: pass client-ip=2001:41c9:1:41f::167; envelope-from=mark.cave-ayland@ilande.co.uk; helo=mail.ilande.co.uk X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org The Apple Sound Chip was primarily used by the Macintosh II to generate sound in hardware which was previously handled by the toolbox ROM with software interrupts. Implement both the standard ASC and also the enhanced ASC (EASC) functionality which is used in the Quadra 800. Note that whilst real ASC hardware uses AUDIO_FORMAT_S8, this implementation uses AUDIO_FORMAT_U8 instead because AUDIO_FORMAT_S8 is rarely used and not supported by some audio backends like PulseAudio and DirectSound when played directly with -audiodev out.mixing-engine=off. Co-developed-by: Laurent Vivier Co-developed-by: Volker Rümelin Signed-off-by: Mark Cave-Ayland --- MAINTAINERS | 2 + hw/audio/Kconfig | 3 + hw/audio/asc.c | 708 +++++++++++++++++++++++++++++++++++++++++ hw/audio/meson.build | 1 + hw/audio/trace-events | 10 + hw/m68k/Kconfig | 1 + include/hw/audio/asc.h | 84 +++++ 7 files changed, 809 insertions(+) create mode 100644 hw/audio/asc.c create mode 100644 include/hw/audio/asc.h diff --git a/MAINTAINERS b/MAINTAINERS index 371a983b5a..134535cfeb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1230,6 +1230,7 @@ F: hw/display/macfb.c F: hw/block/swim.c F: hw/misc/djmemc.c F: hw/misc/iosb.c +F: hw/audio/asc.c F: hw/m68k/bootinfo.h F: include/standard-headers/asm-m68k/bootinfo.h F: include/standard-headers/asm-m68k/bootinfo-mac.h @@ -1241,6 +1242,7 @@ F: include/hw/m68k/q800.h F: include/hw/m68k/q800-glue.h F: include/hw/misc/djmemc.h F: include/hw/misc/iosb.h +F: include/hw/audio/asc.h virt M: Laurent Vivier diff --git a/hw/audio/Kconfig b/hw/audio/Kconfig index e76c69ca7e..d0993514a1 100644 --- a/hw/audio/Kconfig +++ b/hw/audio/Kconfig @@ -47,3 +47,6 @@ config PL041 config CS4231 bool + +config ASC + bool diff --git a/hw/audio/asc.c b/hw/audio/asc.c new file mode 100644 index 0000000000..9084708eaf --- /dev/null +++ b/hw/audio/asc.c @@ -0,0 +1,708 @@ +/* + * QEMU Apple Sound Chip emulation + * + * Apple Sound Chip (ASC) 344S0063 + * Enhanced Apple Sound Chip (EASC) 343S1063 + * + * Copyright (c) 2012-2018 Laurent Vivier + * Copyright (c) 2022 Mark Cave-Ayland + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/timer.h" +#include "hw/sysbus.h" +#include "hw/irq.h" +#include "audio/audio.h" +#include "hw/audio/asc.h" +#include "hw/qdev-properties.h" +#include "migration/vmstate.h" +#include "trace.h" + +/* + * Linux doesn't provide information about ASC, see arch/m68k/mac/macboing.c + * and arch/m68k/include/asm/mac_asc.h + * + * best information is coming from MAME: + * https://github.com/mamedev/mame/blob/master/src/devices/sound/asc.h + * https://github.com/mamedev/mame/blob/master/src/devices/sound/asc.cpp + * Emulation by R. Belmont + * or MESS: + * http://mess.redump.net/mess/driver_info/easc + * + * 0x800: VERSION + * 0x801: MODE + * 1=FIFO mode, + * 2=wavetable mode + * 0x802: CONTROL + * bit 0=analog or PWM output, + * 1=stereo/mono, + * 7=processing time exceeded + * 0x803: FIFO MODE + * bit 7=clear FIFO, + * bit 1="non-ROM companding", + * bit 0="ROM companding") + * 0x804: FIFO IRQ STATUS + * bit 0=ch A 1/2 full, + * 1=ch A full, + * 2=ch B 1/2 full, + * 3=ch B full) + * 0x805: WAVETABLE CONTROL + * bits 0-3 wavetables 0-3 start + * 0x806: VOLUME + * bits 2-4 = 3 bit internal ASC volume, + * bits 5-7 = volume control sent to Sony sound chip + * 0x807: CLOCK RATE + * 0 = Mac 22257 Hz, + * 1 = undefined, + * 2 = 22050 Hz, + * 3 = 44100 Hz + * 0x80a: PLAY REC A + * 0x80f: TEST + * bits 6-7 = digital test, + * bits 4-5 = analog test + * 0x810: WAVETABLE 0 PHASE + * big-endian 9.15 fixed-point, only 24 bits valid + * 0x814: WAVETABLE 0 INCREMENT + * big-endian 9.15 fixed-point, only 24 bits valid + * 0x818: WAVETABLE 1 PHASE + * 0x81C: WAVETABLE 1 INCREMENT + * 0x820: WAVETABLE 2 PHASE + * 0x824: WAVETABLE 2 INCREMENT + * 0x828: WAVETABLE 3 PHASE + * 0x82C: WAVETABLE 3 INCREMENT + * 0x830: UNKNOWN START + * NetBSD writes Wavetable data here (are there more + * wavetables/channels than we know about?) + * 0x857: UNKNOWN END + */ + +#define ASC_SIZE 0x2000 + +enum { + ASC_VERSION = 0x00, + ASC_MODE = 0x01, + ASC_CONTROL = 0x02, + ASC_FIFOMODE = 0x03, + ASC_FIFOIRQ = 0x04, + ASC_WAVECTRL = 0x05, + ASC_VOLUME = 0x06, + ASC_CLOCK = 0x07, + ASC_PLAYRECA = 0x0a, + ASC_TEST = 0x0f, + ASC_WAVETABLE = 0x10 +}; + +#define ASC_FIFO_STATUS_HALF_FULL 1 +#define ASC_FIFO_STATUS_FULL_EMPTY 2 + +#define ASC_EXTREGS_FIFOCTRL 0x8 +#define ASC_EXTREGS_INTCTRL 0x9 +#define ASC_EXTREGS_CDXA_DECOMP_FILT 0x10 + +#define ASC_FIFO_CYCLE_TIME ((NANOSECONDS_PER_SECOND / ASC_FREQ) * \ + 0x400) + +static void asc_raise_irq(ASCState *s) +{ + qemu_set_irq(s->irq, 1); +} + +static void asc_lower_irq(ASCState *s) +{ + qemu_set_irq(s->irq, 0); +} + +static uint8_t asc_fifo_get(ASCFIFOState *fs) +{ + ASCState *s = container_of(fs, ASCState, fifos[fs->index]); + bool fifo_half_irq_enabled = fs->extregs[ASC_EXTREGS_INTCTRL] & 1; + uint8_t val; + + assert(fs->cnt); + + val = fs->fifo[fs->rptr]; + trace_asc_fifo_get('A' + fs->index, fs->rptr, fs->cnt, val); + + fs->rptr++; + fs->rptr &= 0x3ff; + fs->cnt--; + + if (fs->cnt <= 0x1ff) { + /* FIFO less than half full */ + fs->int_status |= ASC_FIFO_STATUS_HALF_FULL; + } else { + /* FIFO more than half full */ + fs->int_status &= ~ASC_FIFO_STATUS_HALF_FULL; + } + + if (fs->cnt == 0x1ff && fifo_half_irq_enabled) { + /* Raise FIFO half full IRQ */ + asc_raise_irq(s); + } + + if (fs->cnt == 0) { + /* Raise FIFO empty IRQ */ + fs->int_status |= ASC_FIFO_STATUS_FULL_EMPTY; + asc_raise_irq(s); + } + + return val; +} + +static int generate_fifo(ASCState *s, int maxsamples) +{ + int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + uint8_t *buf = s->mixbuf; + int i, wcount = 0; + + while (wcount < maxsamples) { + uint8_t val; + int16_t d, f0, f1; + int32_t t; + int shift, filter; + bool hasdata = false; + + for (i = 0; i < 2; i++) { + ASCFIFOState *fs = &s->fifos[i]; + + switch (fs->extregs[ASC_EXTREGS_FIFOCTRL] & 0x83) { + case 0x82: + /* + * CD-XA BRR mode: decompress 15 bytes into 28 16-bit + * samples + */ + if (!fs->cnt) { + val = 0x80; + break; + } + + if (fs->xa_cnt == -1) { + /* Start of packet, get flags */ + fs->xa_flags = asc_fifo_get(fs); + fs->xa_cnt = 0; + } + + shift = fs->xa_flags & 0xf; + filter = fs->xa_flags >> 4; + f0 = (int8_t)fs->extregs[ASC_EXTREGS_CDXA_DECOMP_FILT + + (filter << 1) + 1]; + f1 = (int8_t)fs->extregs[ASC_EXTREGS_CDXA_DECOMP_FILT + + (filter << 1)]; + + if ((fs->xa_cnt & 1) == 0) { + if (!fs->cnt) { + val = 0x80; + break; + } + + fs->xa_val = asc_fifo_get(fs); + d = (fs->xa_val & 0xf) << 12; + } else { + d = (fs->xa_val & 0xf0) << 8; + } + t = (d >> shift) + (((fs->xa_last[0] * f0) + + (fs->xa_last[1] * f1) + 32) >> 6); + if (t < -32768) { + t = -32768; + } else if (t > 32767) { + t = 32767; + } + + /* + * CD-XA BRR generates 16-bit signed output, so convert to + * 8-bit before writing to buffer. Does real hardware do the + * same? + */ + val = (uint8_t)(t / 256) ^ 0x80; + hasdata = true; + fs->xa_cnt++; + + fs->xa_last[1] = fs->xa_last[0]; + fs->xa_last[0] = (int16_t)t; + + if (fs->xa_cnt == 28) { + /* End of packet */ + fs->xa_cnt = -1; + } + break; + + default: + /* fallthrough */ + case 0x80: + /* Raw mode */ + if (fs->cnt) { + val = asc_fifo_get(fs); + hasdata = true; + } else { + val = 0x80; + } + break; + } + + buf[wcount * 2 + i] = val; + } + + if (!hasdata) { + break; + } + + wcount++; + } + + /* + * MacOS (un)helpfully leaves the FIFO engine running even when it has + * finished writing out samples, but still expects the FIFO empty + * interrupts to be generated for each FIFO cycle (without these interrupts + * MacOS will freeze) + */ + if (s->fifos[0].cnt == 0 && s->fifos[1].cnt == 0) { + if (!s->fifo_empty_ns) { + /* FIFO has completed first empty cycle */ + s->fifo_empty_ns = now; + } else if (now > (s->fifo_empty_ns + ASC_FIFO_CYCLE_TIME)) { + /* FIFO has completed entire cycle with no data */ + s->fifos[0].int_status |= ASC_FIFO_STATUS_HALF_FULL | + ASC_FIFO_STATUS_FULL_EMPTY; + s->fifos[1].int_status |= ASC_FIFO_STATUS_HALF_FULL | + ASC_FIFO_STATUS_FULL_EMPTY; + s->fifo_empty_ns = now; + asc_raise_irq(s); + } + } else { + /* FIFO contains data, reset empty time */ + s->fifo_empty_ns = 0; + } + + return wcount; +} + +static int generate_wavetable(ASCState *s, int maxsamples) +{ + uint8_t *buf = s->mixbuf; + int channel, count = 0; + + while (count < maxsamples) { + uint32_t left = 0, right = 0; + uint8_t sample; + + for (channel = 0; channel < 4; channel++) { + ASCFIFOState *fs = &s->fifos[channel >> 1]; + int chanreg = ASC_WAVETABLE + (channel << 3); + uint32_t phase, incr, offset; + + phase = ldl_be_p(&s->regs[chanreg]); + incr = ldl_be_p(&s->regs[chanreg + sizeof(uint32_t)]); + + phase += incr; + offset = (phase >> 15) & 0x1ff; + sample = fs->fifo[0x200 * (channel >> 1) + offset]; + + stl_be_p(&s->regs[chanreg], phase); + + left += sample; + right += sample; + } + + buf[count * 2] = left >> 2; + buf[count * 2 + 1] = right >> 2; + + count++; + } + + return count; +} + +static void asc_out_cb(void *opaque, int free_b) +{ + ASCState *s = opaque; + int samples, generated; + + if (free_b == 0) { + return; + } + + samples = MIN(s->samples, free_b >> s->shift); + + switch (s->regs[ASC_MODE] & 3) { + default: + /* Off */ + generated = 0; + break; + case 1: + /* FIFO mode */ + generated = generate_fifo(s, samples); + break; + case 2: + /* Wave table mode */ + generated = generate_wavetable(s, samples); + break; + } + + if (!generated) { + return; + } + + AUD_write(s->voice, s->mixbuf, generated << s->shift); +} + +static uint64_t asc_fifo_read(void *opaque, hwaddr addr, + unsigned size) +{ + ASCFIFOState *fs = opaque; + + trace_asc_read_fifo('A' + fs->index, addr, size, fs->fifo[addr]); + return fs->fifo[addr]; +} + +static void asc_fifo_write(void *opaque, hwaddr addr, uint64_t value, + unsigned size) +{ + ASCFIFOState *fs = opaque; + ASCState *s = container_of(fs, ASCState, fifos[fs->index]); + bool fifo_half_irq_enabled = fs->extregs[ASC_EXTREGS_INTCTRL] & 1; + + trace_asc_write_fifo('A' + fs->index, addr, size, fs->wptr, fs->cnt, value); + + if (s->regs[ASC_MODE] == 1) { + fs->fifo[fs->wptr++] = value; + fs->wptr &= 0x3ff; + fs->cnt++; + + if (fs->cnt <= 0x1ff) { + /* FIFO less than half full */ + fs->int_status |= ASC_FIFO_STATUS_HALF_FULL; + } else { + /* FIFO at least half full */ + fs->int_status &= ~ASC_FIFO_STATUS_HALF_FULL; + } + + if (fs->cnt == 0x200 && fifo_half_irq_enabled) { + /* Raise FIFO half full interrupt */ + asc_raise_irq(s); + } + + if (fs->cnt == 0x3ff) { + /* Raise FIFO full interrupt */ + fs->int_status |= ASC_FIFO_STATUS_FULL_EMPTY; + asc_raise_irq(s); + } + } else { + fs->fifo[addr] = value; + } + return; +} + +static const MemoryRegionOps asc_fifo_ops = { + .read = asc_fifo_read, + .write = asc_fifo_write, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, + .endianness = DEVICE_BIG_ENDIAN, +}; + +static void asc_fifo_reset(ASCFIFOState *fs); + +static uint64_t asc_read(void *opaque, hwaddr addr, + unsigned size) +{ + ASCState *s = opaque; + uint64_t prev, value; + + switch (addr) { + case ASC_VERSION: + switch (s->type) { + default: + case ASC_TYPE_ASC: + value = 0; + break; + case ASC_TYPE_EASC: + value = 0xb0; + break; + } + break; + case ASC_FIFOIRQ: + prev = (s->fifos[0].int_status & 0x3) | + (s->fifos[1].int_status & 0x3) << 2; + + s->fifos[0].int_status = 0; + s->fifos[1].int_status = 0; + asc_lower_irq(s); + value = prev; + break; + default: + value = s->regs[addr]; + break; + } + + trace_asc_read_reg(addr, size, value); + return value; +} + +static void asc_write(void *opaque, hwaddr addr, uint64_t value, + unsigned size) +{ + ASCState *s = opaque; + + switch (addr) { + case ASC_MODE: + value &= 3; + if (value != s->regs[ASC_MODE]) { + asc_fifo_reset(&s->fifos[0]); + asc_fifo_reset(&s->fifos[1]); + asc_lower_irq(s); + if (value != 0) { + AUD_set_active_out(s->voice, 1); + } else { + AUD_set_active_out(s->voice, 0); + } + } + break; + case ASC_FIFOMODE: + if (value & 0x80) { + asc_fifo_reset(&s->fifos[0]); + asc_fifo_reset(&s->fifos[1]); + asc_lower_irq(s); + } + break; + case ASC_WAVECTRL: + break; + case ASC_VOLUME: + { + int vol = (value & 0xe0); + + AUD_set_volume_out(s->voice, 0, vol, vol); + break; + } + } + + trace_asc_write_reg(addr, size, value); + s->regs[addr] = value; +} + +static const MemoryRegionOps asc_regs_ops = { + .read = asc_read, + .write = asc_write, + .endianness = DEVICE_BIG_ENDIAN, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + } +}; + +static uint64_t asc_ext_read(void *opaque, hwaddr addr, + unsigned size) +{ + ASCFIFOState *fs = opaque; + uint64_t value; + + value = fs->extregs[addr]; + + trace_asc_read_extreg('A' + fs->index, addr, size, value); + return value; +} + +static void asc_ext_write(void *opaque, hwaddr addr, uint64_t value, + unsigned size) +{ + ASCFIFOState *fs = opaque; + + trace_asc_write_extreg('A' + fs->index, addr, size, value); + + fs->extregs[addr] = value; +} + +static const MemoryRegionOps asc_extregs_ops = { + .read = asc_ext_read, + .write = asc_ext_write, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, + .endianness = DEVICE_BIG_ENDIAN, +}; + +static int asc_post_load(void *opaque, int version) +{ + ASCState *s = ASC(opaque); + + if (s->regs[ASC_MODE] != 0) { + AUD_set_active_out(s->voice, 1); + } + + return 0; +} + +static const VMStateDescription vmstate_asc_fifo = { + .name = "apple-sound-chip.fifo", + .version_id = 0, + .minimum_version_id = 0, + .fields = (VMStateField[]) { + VMSTATE_UINT8_ARRAY(fifo, ASCFIFOState, ASC_FIFO_SIZE), + VMSTATE_UINT8(int_status, ASCFIFOState), + VMSTATE_INT32(cnt, ASCFIFOState), + VMSTATE_INT32(wptr, ASCFIFOState), + VMSTATE_INT32(rptr, ASCFIFOState), + VMSTATE_UINT8_ARRAY(extregs, ASCFIFOState, ASC_EXTREG_SIZE), + VMSTATE_INT32(xa_cnt, ASCFIFOState), + VMSTATE_UINT8(xa_val, ASCFIFOState), + VMSTATE_UINT8(xa_flags, ASCFIFOState), + VMSTATE_INT16_ARRAY(xa_last, ASCFIFOState, 2), + VMSTATE_END_OF_LIST() + } +}; + +static const VMStateDescription vmstate_asc = { + .name = "apple-sound-chip", + .version_id = 0, + .minimum_version_id = 0, + .post_load = asc_post_load, + .fields = (VMStateField[]) { + VMSTATE_STRUCT_ARRAY(fifos, ASCState, 2, 0, vmstate_asc_fifo, + ASCFIFOState), + VMSTATE_UINT8_ARRAY(regs, ASCState, ASC_REG_SIZE), + VMSTATE_INT64(fifo_empty_ns, ASCState), + VMSTATE_END_OF_LIST() + } +}; + +static void asc_fifo_reset(ASCFIFOState *fs) +{ + fs->wptr = 0; + fs->rptr = 0; + fs->cnt = 0; + fs->xa_cnt = -1; + fs->int_status = 0; +} + +static void asc_fifo_init(ASCFIFOState *fs, int index) +{ + ASCState *s = container_of(fs, ASCState, fifos[index]); + char *name; + + fs->index = index; + name = g_strdup_printf("asc.fifo%c", 'A' + index); + memory_region_init_io(&fs->mem_fifo, OBJECT(s), &asc_fifo_ops, fs, + name, ASC_FIFO_SIZE); + g_free(name); + + name = g_strdup_printf("asc.extregs%c", 'A' + index); + memory_region_init_io(&fs->mem_extregs, OBJECT(s), &asc_extregs_ops, + fs, name, ASC_EXTREG_SIZE); + g_free(name); +} + +static void asc_reset_hold(Object *obj) +{ + ASCState *s = ASC(obj); + + AUD_set_active_out(s->voice, 0); + + memset(s->regs, 0, sizeof(s->regs)); + asc_fifo_reset(&s->fifos[0]); + asc_fifo_reset(&s->fifos[1]); + s->fifo_empty_ns = 0; + + if (s->type == ASC_TYPE_ASC) { + /* FIFO half full IRQs enabled by default */ + s->fifos[0].extregs[ASC_EXTREGS_INTCTRL] = 1; + s->fifos[1].extregs[ASC_EXTREGS_INTCTRL] = 1; + } +} + +static void asc_unrealize(DeviceState *dev) +{ + ASCState *s = ASC(dev); + + g_free(s->mixbuf); + + AUD_remove_card(&s->card); +} + +static void asc_realize(DeviceState *dev, Error **errp) +{ + ASCState *s = ASC(dev); + struct audsettings as; + + if (!AUD_register_card("Apple Sound Chip", &s->card, errp)) { + return; + } + + as.freq = ASC_FREQ; + as.nchannels = 2; + as.fmt = AUDIO_FORMAT_U8; + as.endianness = AUDIO_HOST_ENDIANNESS; + + s->voice = AUD_open_out(&s->card, s->voice, "asc.out", s, asc_out_cb, + &as); + s->shift = 1; + s->samples = AUD_get_buffer_size_out(s->voice) >> s->shift; + s->mixbuf = g_malloc0(s->samples << s->shift); + + /* Add easc registers if required */ + if (s->type == ASC_TYPE_EASC) { + memory_region_add_subregion(&s->asc, ASC_EXTREG_OFFSET, + &s->fifos[0].mem_extregs); + memory_region_add_subregion(&s->asc, + ASC_EXTREG_OFFSET + ASC_EXTREG_SIZE, + &s->fifos[1].mem_extregs); + } +} + +static void asc_init(Object *obj) +{ + ASCState *s = ASC(obj); + SysBusDevice *sbd = SYS_BUS_DEVICE(obj); + + memory_region_init(&s->asc, OBJECT(obj), "asc", ASC_SIZE); + + asc_fifo_init(&s->fifos[0], 0); + asc_fifo_init(&s->fifos[1], 1); + + memory_region_add_subregion(&s->asc, ASC_FIFO_OFFSET, + &s->fifos[0].mem_fifo); + memory_region_add_subregion(&s->asc, + ASC_FIFO_OFFSET + ASC_FIFO_SIZE, + &s->fifos[1].mem_fifo); + + memory_region_init_io(&s->mem_regs, OBJECT(obj), &asc_regs_ops, s, + "asc.regs", ASC_REG_SIZE); + memory_region_add_subregion(&s->asc, ASC_REG_OFFSET, &s->mem_regs); + + sysbus_init_irq(sbd, &s->irq); + sysbus_init_mmio(sbd, &s->asc); +} + +static Property asc_properties[] = { + DEFINE_AUDIO_PROPERTIES(ASCState, card), + DEFINE_PROP_UINT8("asctype", ASCState, type, ASC_TYPE_ASC), + DEFINE_PROP_END_OF_LIST(), +}; + +static void asc_class_init(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + ResettableClass *rc = RESETTABLE_CLASS(oc); + + dc->realize = asc_realize; + dc->unrealize = asc_unrealize; + set_bit(DEVICE_CATEGORY_SOUND, dc->categories); + dc->vmsd = &vmstate_asc; + device_class_set_props(dc, asc_properties); + rc->phases.hold = asc_reset_hold; +} + +static const TypeInfo asc_info_types[] = { + { + .name = TYPE_ASC, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(ASCState), + .instance_init = asc_init, + .class_init = asc_class_init, + }, +}; + +DEFINE_TYPES(asc_info_types) diff --git a/hw/audio/meson.build b/hw/audio/meson.build index d0fda1009e..8805322f5c 100644 --- a/hw/audio/meson.build +++ b/hw/audio/meson.build @@ -1,6 +1,7 @@ system_ss.add(files('soundhw.c')) system_ss.add(when: 'CONFIG_AC97', if_true: files('ac97.c')) system_ss.add(when: 'CONFIG_ADLIB', if_true: files('fmopl.c', 'adlib.c')) +system_ss.add(when: 'CONFIG_ASC', if_true: files('asc.c')) system_ss.add(when: 'CONFIG_CS4231', if_true: files('cs4231.c')) system_ss.add(when: 'CONFIG_CS4231A', if_true: files('cs4231a.c')) system_ss.add(when: 'CONFIG_ES1370', if_true: files('es1370.c')) diff --git a/hw/audio/trace-events b/hw/audio/trace-events index 4dec48a4fd..89ef2996e5 100644 --- a/hw/audio/trace-events +++ b/hw/audio/trace-events @@ -17,3 +17,13 @@ via_ac97_codec_write(uint8_t addr, uint16_t val) "0x%x <- 0x%x" via_ac97_sgd_fetch(uint32_t curr, uint32_t addr, char stop, char eol, char flag, uint32_t len) "curr=0x%x addr=0x%x %c%c%c len=%d" via_ac97_sgd_read(uint64_t addr, unsigned size, uint64_t val) "0x%"PRIx64" %d -> 0x%"PRIx64 via_ac97_sgd_write(uint64_t addr, unsigned size, uint64_t val) "0x%"PRIx64" %d <- 0x%"PRIx64 + +# asc.c +asc_read_fifo(const char fifo, int reg, unsigned size, uint64_t value) "fifo %c reg=0x%03x size=%u value=0x%"PRIx64 +asc_read_reg(int reg, unsigned size, uint64_t value) "reg=0x%03x size=%u value=0x%"PRIx64 +asc_read_extreg(const char fifo, int reg, unsigned size, uint64_t value) "fifo %c reg=0x%03x size=%u value=0x%"PRIx64 +asc_fifo_get(const char fifo, int rptr, int cnt, uint64_t value) "fifo %c rptr=0x%x cnt=0x%x value=0x%"PRIx64 +asc_write_fifo(const char fifo, int reg, unsigned size, int wrptr, int cnt, uint64_t value) "fifo %c reg=0x%03x size=%u wptr=0x%x cnt=0x%x value=0x%"PRIx64 +asc_write_reg(int reg, unsigned size, uint64_t value) "reg=0x%03x size=%u value=0x%"PRIx64 +asc_write_extreg(const char fifo, int reg, unsigned size, uint64_t value) "fifo %c reg=0x%03x size=%u value=0x%"PRIx64 +asc_update_irq(int irq, int a, int b) "set IRQ to %d (A: 0x%x B: 0x%x)" diff --git a/hw/m68k/Kconfig b/hw/m68k/Kconfig index 64fa70a0db..d88741ec9d 100644 --- a/hw/m68k/Kconfig +++ b/hw/m68k/Kconfig @@ -25,6 +25,7 @@ config Q800 select OR_IRQ select DJMEMC select IOSB + select ASC config M68K_VIRT bool diff --git a/include/hw/audio/asc.h b/include/hw/audio/asc.h new file mode 100644 index 0000000000..d9412815c3 --- /dev/null +++ b/include/hw/audio/asc.h @@ -0,0 +1,84 @@ +/* + * QEMU Apple Sound Chip emulation + * + * Apple Sound Chip (ASC) 344S0063 + * Enhanced Apple Sound Chip (EASC) 343S1063 + * + * Copyright (c) 2012-2018 Laurent Vivier + * Copyright (c) 2022 Mark Cave-Ayland + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_AUDIO_ASC_H +#define HW_AUDIO_ASC_H + +#include "qemu/osdep.h" +#include "hw/sysbus.h" +#include "audio/audio.h" + +#define ASC_FREQ 22257 + +enum { + ASC_TYPE_ASC = 0, /* original discrete Apple Sound Chip */ + ASC_TYPE_EASC = 1 /* discrete Enhanced Apple Sound Chip */ +}; + +#define ASC_FIFO_OFFSET 0x0 +#define ASC_FIFO_SIZE 0x400 + +#define ASC_REG_OFFSET 0x800 +#define ASC_REG_SIZE 0x60 + +#define ASC_EXTREG_OFFSET 0xf00 +#define ASC_EXTREG_SIZE 0x20 + +typedef struct ASCFIFOState { + int index; + + MemoryRegion mem_fifo; + uint8_t fifo[ASC_FIFO_SIZE]; + uint8_t int_status; + + int cnt; + int wptr; + int rptr; + + MemoryRegion mem_extregs; + uint8_t extregs[ASC_EXTREG_SIZE]; + + int xa_cnt; + uint8_t xa_val; + uint8_t xa_flags; + int16_t xa_last[2]; +} ASCFIFOState; + +struct ASCState { + SysBusDevice parent_obj; + + uint8_t type; + MemoryRegion asc; + MemoryRegion mem_fifo; + MemoryRegion mem_regs; + MemoryRegion mem_extregs; + + QEMUSoundCard card; + SWVoiceOut *voice; + uint8_t *mixbuf; + int samples; + int shift; + + /* Time when we were last able to generate samples */ + int64_t fifo_empty_ns; + + qemu_irq irq; + + ASCFIFOState fifos[2]; + + uint8_t regs[ASC_REG_SIZE]; +}; + +#define TYPE_ASC "apple-sound-chip" +OBJECT_DECLARE_SIMPLE_TYPE(ASCState, ASC) + +#endif From patchwork Wed Oct 4 08:37:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Cave-Ayland X-Patchwork-Id: 13408381 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id EDBDFE8FDDA for ; Wed, 4 Oct 2023 08:39:49 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qnxP6-0003xx-4Y; Wed, 04 Oct 2023 04:38:48 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxP4-0003xW-Si for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:38:46 -0400 Received: from mail.ilande.co.uk ([2001:41c9:1:41f::167]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxP3-0007bI-Aj for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:38:46 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=ilande.co.uk; s=20220518; h=Subject:Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:To:From:Sender:Reply-To:Cc: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=gZ86OMPpMlnB3D4ENs44jqarXK1astQH1B1zhzFrNbM=; b=kEXvufS79XOYWgdD9NBRlQHiCt tKZl4U5H1mdMAlDViP9N1FnimLyw9qQeLIQH1EeVS8gpOE7t7QJp61rXCNAgA0DTTS4r4TN3HoJMJ mrZXtN62JeFux4mQN0SvUMxTFot3mblP4PAuMRG+ddHAsBMr52IyxyOyR+ROjy0/jgXpSg0gPQipE vXFk7RepJK57UQmvVCA2jxmt+hibITjaUJrzXw5DmlE3n56gcjttQy+rff5sdUr432yieailhF1vN M25PppBavISg+e8G/TRSbID4QaRfUWdHPvpHY0MqlFxsdahZfJNYiW/JVSZlNMuk8U1Cv9zkLFX+a 1qqSN6hx+S+dQw6dE0ZXFWaLh4CFwiAxAgnqD7FCxe4yjSGgHir/N3P1NPOTa7EamscNY79VUxSYN rzG0cidDm845fzjjXbDkvhahK4Nxz64684EZgD554Q7uoFXXq5Z01zBvVN5Pa1lpqzPuPxAHCL86t ckoU6Y5B53rWNE9NR54AzTKaHE5HiWlRag7V+OgOxXOQylAR7TMqLBDhqlCKucETpm3FJv5R2TWhP YE5bUuSrPMeZ6Pbeu1kWMYk0XNeiN1dtSENbB3RID1xbpk3rgYV5LKe9BsJ6x45UiREoj5idOrvXI J86CXSlq48iR7Cg2Bq4sAbSmjOfpNmvLnZI0zn6K0=; Received: from host86-159-123-68.range86-159.btcentralplus.com ([86.159.123.68] helo=localhost.localdomain) by mail.ilande.co.uk with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qnxOo-0006za-GD; Wed, 04 Oct 2023 09:38:34 +0100 From: Mark Cave-Ayland To: laurent@vivier.eu, qemu-devel@nongnu.org Date: Wed, 4 Oct 2023 09:37:54 +0100 Message-Id: <20231004083806.757242-9-mark.cave-ayland@ilande.co.uk> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> References: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 86.159.123.68 X-SA-Exim-Mail-From: mark.cave-ayland@ilande.co.uk Subject: [PATCH v4 08/20] asc: generate silence if FIFO empty but engine still running X-SA-Exim-Version: 4.2.1 (built Wed, 08 May 2019 21:11:16 +0000) X-SA-Exim-Scanned: Yes (on mail.ilande.co.uk) Received-SPF: pass client-ip=2001:41c9:1:41f::167; envelope-from=mark.cave-ayland@ilande.co.uk; helo=mail.ilande.co.uk X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org MacOS (un)helpfully leaves the FIFO engine running even when all the samples have been written to the hardware, and expects the FIFO status flags and IRQ to be updated continuously. There is an additional problem in that not all audio backends guarantee an all-zero output when there is no FIFO data available, in particular the Windows dsound backend which re-uses its internal circular buffer causing the last played sound to loop indefinitely. Whilst this is effectively a bug in the Windows dsound backend, work around it for now using a simple heuristic: if the FIFO remains empty for half a cycle (~23ms) then continuously fill the generated buffer with empty silence. Signed-off-by: Mark Cave-Ayland Reviewed-by: Laurent Vivier --- hw/audio/asc.c | 19 +++++++++++++++++++ include/hw/audio/asc.h | 2 ++ 2 files changed, 21 insertions(+) diff --git a/hw/audio/asc.c b/hw/audio/asc.c index 9084708eaf..0f36b4ce9b 100644 --- a/hw/audio/asc.c +++ b/hw/audio/asc.c @@ -341,6 +341,21 @@ static void asc_out_cb(void *opaque, int free_b) } if (!generated) { + /* Workaround for audio underflow bug on Windows dsound backend */ + int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + int silent_samples = muldiv64(now - s->fifo_empty_ns, + NANOSECONDS_PER_SECOND, ASC_FREQ); + + if (silent_samples > ASC_FIFO_CYCLE_TIME / 2) { + /* + * No new FIFO data within half a cycle time (~23ms) so fill the + * entire available buffer with silence. This prevents an issue + * with the Windows dsound backend whereby the sound appears to + * loop because the FIFO has run out of data, and the driver + * reuses the stale content in its circular audio buffer. + */ + AUD_write(s->voice, s->silentbuf, samples << s->shift); + } return; } @@ -618,6 +633,7 @@ static void asc_unrealize(DeviceState *dev) ASCState *s = ASC(dev); g_free(s->mixbuf); + g_free(s->silentbuf); AUD_remove_card(&s->card); } @@ -642,6 +658,9 @@ static void asc_realize(DeviceState *dev, Error **errp) s->samples = AUD_get_buffer_size_out(s->voice) >> s->shift; s->mixbuf = g_malloc0(s->samples << s->shift); + s->silentbuf = g_malloc0(s->samples << s->shift); + memset(s->silentbuf, 0x80, s->samples << s->shift); + /* Add easc registers if required */ if (s->type == ASC_TYPE_EASC) { memory_region_add_subregion(&s->asc, ASC_EXTREG_OFFSET, diff --git a/include/hw/audio/asc.h b/include/hw/audio/asc.h index d9412815c3..4741f92c46 100644 --- a/include/hw/audio/asc.h +++ b/include/hw/audio/asc.h @@ -68,6 +68,8 @@ struct ASCState { int samples; int shift; + uint8_t *silentbuf; + /* Time when we were last able to generate samples */ int64_t fifo_empty_ns; From patchwork Wed Oct 4 08:37:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Cave-Ayland X-Patchwork-Id: 13408392 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 6D076E8FDDB for ; Wed, 4 Oct 2023 08:41:38 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qnxPA-00041l-9U; Wed, 04 Oct 2023 04:38:52 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxP9-00041K-EA for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:38:51 -0400 Received: from mail.ilande.co.uk ([2001:41c9:1:41f::167]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxP7-0007eX-Pl for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:38:51 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=ilande.co.uk; s=20220518; h=Subject:Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:To:From:Sender:Reply-To:Cc: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=5eqP4+bjn5EBbpgBK2NdpBicOTGK9gRZVvWgDw65dOU=; b=jd0SMb09ZTLTAA3kEhNUZ0P4H4 ZsnK27KKl8hne+o57cxyrLN2IyHj1u1vmNAVpOBr9JyvPbKEN2/G9QAFU6S+EVI6RpjXTpyCMyu30 2CSlfSE9j0NlQPKTYgpd9YtsmVbxn3VFCRwS+unpbmO5A/0YiIAztotfKSQAMLooSAH71ZeO+gEBK sBfiWkjGTqZadOt50Qmiy0OT5UCOxgsoX52kNI3XcVLCD5nYViubLwFF8vT+2XvGQm51V9JDultZP 78ZWiL5VH/Ib1Y9VVqcocfld0J+pDG4q6k+D5PMKB1or++FbC/PFSodTTjQkJv5VIA4HF0GlCANvZ i2aiK1rORqJyZ3k+rKNBp+RigHHIeq9k+U43ZK6tJcGGNoWqztS56SW9ZMsyo11hwnL6aXVc7q8Xg i69hEwF8Tm4bke6N99qClDjmMtyYooAb3252CSmFzjwQAVgMcyuW13mdjGdt/ewhAKdGPOTnA7rtW WGwpnPA7v3xMO1eV6MfQ5ZhrsF7HcevXwBMyGaJVJGbjUedFGL9aM6Ijp4l5ejIRAlBl+VxZcfHJH sRGI4uZu1l3JyM68HrSkJMV9daxh5ljAuufAikcknSgUNbts0E+g3ve2obghpuH28XzRVI/ppZgTJ MUItYZvJOeR0BF31lHUjbz8FCOyJ3lCgdlqfH2e3s=; Received: from host86-159-123-68.range86-159.btcentralplus.com ([86.159.123.68] helo=localhost.localdomain) by mail.ilande.co.uk with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qnxOs-0006za-HR; Wed, 04 Oct 2023 09:38:38 +0100 From: Mark Cave-Ayland To: laurent@vivier.eu, qemu-devel@nongnu.org Date: Wed, 4 Oct 2023 09:37:55 +0100 Message-Id: <20231004083806.757242-10-mark.cave-ayland@ilande.co.uk> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> References: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 86.159.123.68 X-SA-Exim-Mail-From: mark.cave-ayland@ilande.co.uk Subject: [PATCH v4 09/20] q800: add Apple Sound Chip (ASC) audio to machine X-SA-Exim-Version: 4.2.1 (built Wed, 08 May 2019 21:11:16 +0000) X-SA-Exim-Scanned: Yes (on mail.ilande.co.uk) Received-SPF: pass client-ip=2001:41c9:1:41f::167; envelope-from=mark.cave-ayland@ilande.co.uk; helo=mail.ilande.co.uk X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org The Quadra 800 has the enhanced ASC (EASC) audio chip which supports both the legacy IRQ routing through VIA2 and also "A/UX" mode routing direct to the CPU. Co-developed-by: Laurent Vivier Signed-off-by: Mark Cave-Ayland --- hw/m68k/q800-glue.c | 11 ++++++++++- hw/m68k/q800.c | 21 +++++++++++++++++++++ include/hw/m68k/q800-glue.h | 4 +++- include/hw/m68k/q800.h | 2 ++ 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/hw/m68k/q800-glue.c b/hw/m68k/q800-glue.c index 710a5c331e..f413b1599a 100644 --- a/hw/m68k/q800-glue.c +++ b/hw/m68k/q800-glue.c @@ -97,6 +97,11 @@ static void GLUE_set_irq(void *opaque, int irq, int level) irq = 6; break; + case GLUE_IRQ_IN_ASC: + /* Route to VIA2 instead, negative edge-triggered */ + qemu_set_irq(s->irqs[GLUE_IRQ_ASC], !level); + return; + default: g_assert_not_reached(); } @@ -123,6 +128,10 @@ static void GLUE_set_irq(void *opaque, int irq, int level) irq = 6; break; + case GLUE_IRQ_IN_ASC: + irq = 4; + break; + default: g_assert_not_reached(); } @@ -214,7 +223,7 @@ static void glue_init(Object *obj) qdev_init_gpio_in(dev, GLUE_set_irq, 8); qdev_init_gpio_in_named(dev, glue_auxmode_set_irq, "auxmode", 1); - qdev_init_gpio_out(dev, s->irqs, 1); + qdev_init_gpio_out(dev, s->irqs, 2); /* NMI release timer */ s->nmi_release = timer_new_ms(QEMU_CLOCK_VIRTUAL, glue_nmi_release, s); diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c index 3209309173..249fedde7a 100644 --- a/hw/m68k/q800.c +++ b/hw/m68k/q800.c @@ -43,6 +43,7 @@ #include "hw/misc/djmemc.h" #include "hw/misc/iosb.h" #include "hw/input/adb.h" +#include "hw/audio/asc.h" #include "hw/nubus/mac-nubus-bridge.h" #include "hw/display/macfb.h" #include "hw/block/swim.h" @@ -480,6 +481,25 @@ static void q800_machine_init(MachineState *machine) scsi_bus_legacy_handle_cmdline(&esp->bus); + /* Apple Sound Chip */ + + object_initialize_child(OBJECT(machine), "asc", &m->asc, TYPE_ASC); + qdev_prop_set_uint8(DEVICE(&m->asc), "asctype", ASC_TYPE_EASC); + if (machine->audiodev) { + qdev_prop_set_string(DEVICE(&m->asc), "audiodev", machine->audiodev); + } + sysbus = SYS_BUS_DEVICE(&m->asc); + sysbus_realize_and_unref(sysbus, &error_fatal); + memory_region_add_subregion(&m->macio, ASC_BASE - IO_BASE, + sysbus_mmio_get_region(sysbus, 0)); + sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(DEVICE(&m->glue), + GLUE_IRQ_IN_ASC)); + + /* Wire ASC IRQ via GLUE for use in classic mode */ + qdev_connect_gpio_out(DEVICE(&m->glue), GLUE_IRQ_ASC, + qdev_get_gpio_in(DEVICE(&m->via2), + VIA2_IRQ_ASC_BIT)); + /* SWIM floppy controller */ object_initialize_child(OBJECT(machine), "swim", &m->swim, @@ -688,6 +708,7 @@ static void q800_machine_class_init(ObjectClass *oc, void *data) mc->max_cpus = 1; mc->block_default_type = IF_SCSI; mc->default_ram_id = "m68k_mac.ram"; + machine_add_audiodev_property(mc); compat_props_add(mc->compat_props, hw_compat_q800, hw_compat_q800_len); } diff --git a/include/hw/m68k/q800-glue.h b/include/hw/m68k/q800-glue.h index a35efc1c53..ceb916d16c 100644 --- a/include/hw/m68k/q800-glue.h +++ b/include/hw/m68k/q800-glue.h @@ -35,7 +35,7 @@ struct GLUEState { M68kCPU *cpu; uint8_t ipr; uint8_t auxmode; - qemu_irq irqs[1]; + qemu_irq irqs[2]; QEMUTimer *nmi_release; }; @@ -44,7 +44,9 @@ struct GLUEState { #define GLUE_IRQ_IN_SONIC 2 #define GLUE_IRQ_IN_ESCC 3 #define GLUE_IRQ_IN_NMI 4 +#define GLUE_IRQ_IN_ASC 5 #define GLUE_IRQ_NUBUS_9 0 +#define GLUE_IRQ_ASC 1 #endif diff --git a/include/hw/m68k/q800.h b/include/hw/m68k/q800.h index 04e4e0bce3..790cf433f3 100644 --- a/include/hw/m68k/q800.h +++ b/include/hw/m68k/q800.h @@ -38,6 +38,7 @@ #include "hw/display/macfb.h" #include "hw/misc/djmemc.h" #include "hw/misc/iosb.h" +#include "hw/audio/asc.h" /* * The main Q800 machine @@ -60,6 +61,7 @@ struct Q800MachineState { MacfbNubusState macfb; DJMEMCState djmemc; IOSBState iosb; + ASCState asc; MemoryRegion ramio; MemoryRegion macio; MemoryRegion macio_alias; From patchwork Wed Oct 4 08:37:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Mark Cave-Ayland X-Patchwork-Id: 13408379 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 7101CE8FDDB for ; Wed, 4 Oct 2023 08:39:38 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qnxPE-000457-Ng; Wed, 04 Oct 2023 04:38:56 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxPD-00042M-Gs for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:38:55 -0400 Received: from mail.ilande.co.uk ([2001:41c9:1:41f::167]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxPB-0007f4-2R for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:38:54 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=ilande.co.uk; s=20220518; h=Subject:Content-Transfer-Encoding:Content-Type: MIME-Version:References:In-Reply-To:Message-Id:Date:To:From:Sender:Reply-To: Cc:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=1YYmerWrP1fexZav6nISrGNLIh0dqGrzl0rAYflDWKk=; b=X4vQ8lvw5gTmiCUmrnW56rPcsh i6OdGahQ/mXAt9ZevrjWaJHZQVq9Q6lOwejmLIfsKkvloQ/sWrLUxOYRtyG+OeFbbx7H4rgdKl5kj Oc7ZLsvAu2i8YRSiv83Ssd1phNBe82+/pQ6zn4ceK3sGhJ8ZKHUS7KE/cxCXC/b0cf8E/Ddmtjs45 akCIoiQ/XRkkTZ1HTuT+o2mYytKtyLjpNPnuBlb4pIuVR92E+HpHjcFz5IGsyISuotSAsc4i+/D1q dOLTPiq2ltym+uY54RP/qYYNcIoY6YK5Iudfql09WAHLCieA9P8CkHdq17w6kK1aXqfLy4UiOTzDU gCfU1ilfkq5wT1HePJfwc6ngtnLaCDrulIvo2k5epn8bY7SRtY7dZnfRtE8ojb9ilfv4fepANdyH8 0Cl9iUplV5np7bjLbD1Px+pm4llUbl5hKoV5MCVv6UXKu5xLRLbYQhShYeFsvTh7KvXCZCw1w8N/r mvVHcDUC3IfyHjpIxkb0oL35sJv1g1KFx6BVvcKtAGDaETJrwb9MYPAQvgFzzPLDH4w9I4twoTnUy MGWUbwz+hVhNh6zghu/pUm97OsQakQo5h1T73Dz9UgOI/n6QAL1zvj8A6Ca9dbWqykf2WXNeCzJDw 2FodwQKaISwRu886hO3MQGORtRzdnZZCORh1V9Tdk=; Received: from host86-159-123-68.range86-159.btcentralplus.com ([86.159.123.68] helo=localhost.localdomain) by mail.ilande.co.uk with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qnxOw-0006za-NP; Wed, 04 Oct 2023 09:38:42 +0100 From: Mark Cave-Ayland To: laurent@vivier.eu, qemu-devel@nongnu.org Date: Wed, 4 Oct 2023 09:37:56 +0100 Message-Id: <20231004083806.757242-11-mark.cave-ayland@ilande.co.uk> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> References: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 86.159.123.68 X-SA-Exim-Mail-From: mark.cave-ayland@ilande.co.uk Subject: [PATCH v4 10/20] q800: add easc bool machine class property to switch between ASC and EASC X-SA-Exim-Version: 4.2.1 (built Wed, 08 May 2019 21:11:16 +0000) X-SA-Exim-Scanned: Yes (on mail.ilande.co.uk) Received-SPF: pass client-ip=2001:41c9:1:41f::167; envelope-from=mark.cave-ayland@ilande.co.uk; helo=mail.ilande.co.uk X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org This determines whether the Apple Sound Chip (ASC) is set to enhanced mode (default) or to original mode. The real Q800 hardware used an EASC chip however a lot of older software only works with the older ASC chip. Adding this as a machine parameter allows QEMU to be used as an developer aid for testing and migrating code from ASC to EASC. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Laurent Vivier --- hw/m68k/q800.c | 30 +++++++++++++++++++++++++++++- include/hw/m68k/q800.h | 1 + 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c index 249fedde7a..ac3115d328 100644 --- a/hw/m68k/q800.c +++ b/hw/m68k/q800.c @@ -484,7 +484,8 @@ static void q800_machine_init(MachineState *machine) /* Apple Sound Chip */ object_initialize_child(OBJECT(machine), "asc", &m->asc, TYPE_ASC); - qdev_prop_set_uint8(DEVICE(&m->asc), "asctype", ASC_TYPE_EASC); + qdev_prop_set_uint8(DEVICE(&m->asc), "asctype", m->easc ? ASC_TYPE_EASC + : ASC_TYPE_ASC); if (machine->audiodev) { qdev_prop_set_string(DEVICE(&m->asc), "audiodev", machine->audiodev); } @@ -677,6 +678,28 @@ static void q800_machine_init(MachineState *machine) } } +static bool q800_get_easc(Object *obj, Error **errp) +{ + Q800MachineState *ms = Q800_MACHINE(obj); + + return ms->easc; +} + +static void q800_set_easc(Object *obj, bool value, Error **errp) +{ + Q800MachineState *ms = Q800_MACHINE(obj); + + ms->easc = value; +} + +static void q800_init(Object *obj) +{ + Q800MachineState *ms = Q800_MACHINE(obj); + + /* Default to EASC */ + ms->easc = true; +} + static GlobalProperty hw_compat_q800[] = { { "scsi-hd", "quirk_mode_page_vendor_specific_apple", "on" }, { "scsi-hd", "vendor", " SEAGATE" }, @@ -710,11 +733,16 @@ static void q800_machine_class_init(ObjectClass *oc, void *data) mc->default_ram_id = "m68k_mac.ram"; machine_add_audiodev_property(mc); compat_props_add(mc->compat_props, hw_compat_q800, hw_compat_q800_len); + + object_class_property_add_bool(oc, "easc", q800_get_easc, q800_set_easc); + object_class_property_set_description(oc, "easc", + "Set to off to use ASC rather than EASC"); } static const TypeInfo q800_machine_typeinfo = { .name = MACHINE_TYPE_NAME("q800"), .parent = TYPE_MACHINE, + .instance_init = q800_init, .instance_size = sizeof(Q800MachineState), .class_init = q800_machine_class_init, }; diff --git a/include/hw/m68k/q800.h b/include/hw/m68k/q800.h index 790cf433f3..fbaacd88bd 100644 --- a/include/hw/m68k/q800.h +++ b/include/hw/m68k/q800.h @@ -47,6 +47,7 @@ struct Q800MachineState { MachineState parent_obj; + bool easc; M68kCPU cpu; MemoryRegion rom; GLUEState glue; From patchwork Wed Oct 4 08:37:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Cave-Ayland X-Patchwork-Id: 13408393 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 156BDE8FDDB for ; Wed, 4 Oct 2023 08:41:55 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qnxPI-0004Bd-Tb; Wed, 04 Oct 2023 04:39:00 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxPG-0004Al-RS for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:38:58 -0400 Received: from mail.ilande.co.uk ([2001:41c9:1:41f::167]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxPF-0007fo-9b for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:38:58 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=ilande.co.uk; s=20220518; h=Subject:Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:To:From:Sender:Reply-To:Cc: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=EeJUdGQriujDLVWAuyFisLNH+ZEjrZeVSKeIvh0lhw8=; b=OdMXC/J04qrwImEUm/WN7i3iPh wCkwYFJ1zYU7HMtlalYMtC6OALO1wHCiN86Ok1iBZ0fpNTDQZF6lqaa8mfJZRlal56lYmNGtAGhXJ N5RN43M/6E5CPxDFSsMTKMmreg6IvC8kpdlgpYxuNdWQIJudUvrSwcin0WdLmKAaIzx/b/pE3I78o rDDLb2fQCH4+J6MG4hRmflxea8atGIB2XwguG9RTwfwKQ3OqLJLRmglbeyIJ6UO/IHv3+xBDaOR6w KrC23q1+PlGABr3QBRnKcxG3XnGIV417Gp2+IAf8ru/rxND+zQyKzvXctbsWlRL2xPaQhtc44A1xe yufPjIjvJ4mLgqbYO10JWcjfTfqNzw14uTCyrsKGwADUaX2FWXVTeS5oALQd3SLdR1NbWJdqXQSpI Pdg877MUXvyxpMpOKyk9zXMDCWSsXd0KXSxi6tUDV38EQiw+UxhgF4Ok4WLFpo6MPu9fUcKOTyGkB 2AUlSHymEaFLsb4XhkovE+Dtl8n1zRMP4RK4X8e51zFbVmy8s3NbBAV1i62aJlX/L1L+klVYupR4Y gOTOu3hLOf8o3cZKPlg8POjrpB7V/x7YYjOrjsB5X4pfYwJ+EFWfjaMYzpFvCBSxvAGXdKR+sq8xP 8uRZZVgFT9DaFxCjU9tba5BthSWyuRJ4rPnMnn6Io=; Received: from host86-159-123-68.range86-159.btcentralplus.com ([86.159.123.68] helo=localhost.localdomain) by mail.ilande.co.uk with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qnxP0-0006za-98; Wed, 04 Oct 2023 09:38:46 +0100 From: Mark Cave-Ayland To: laurent@vivier.eu, qemu-devel@nongnu.org Date: Wed, 4 Oct 2023 09:37:57 +0100 Message-Id: <20231004083806.757242-12-mark.cave-ayland@ilande.co.uk> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> References: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 86.159.123.68 X-SA-Exim-Mail-From: mark.cave-ayland@ilande.co.uk Subject: [PATCH v4 11/20] swim: add trace events for IWM and ISM registers X-SA-Exim-Version: 4.2.1 (built Wed, 08 May 2019 21:11:16 +0000) X-SA-Exim-Scanned: Yes (on mail.ilande.co.uk) Received-SPF: pass client-ip=2001:41c9:1:41f::167; envelope-from=mark.cave-ayland@ilande.co.uk; helo=mail.ilande.co.uk X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Signed-off-by: Mark Cave-Ayland Reviewed-by: Laurent Vivier --- hw/block/swim.c | 14 ++++++++++++++ hw/block/trace-events | 7 +++++++ 2 files changed, 21 insertions(+) diff --git a/hw/block/swim.c b/hw/block/swim.c index 333da08ce0..7df36ea139 100644 --- a/hw/block/swim.c +++ b/hw/block/swim.c @@ -19,6 +19,7 @@ #include "hw/block/block.h" #include "hw/block/swim.h" #include "hw/qdev-properties.h" +#include "trace.h" /* IWM registers */ @@ -125,6 +126,13 @@ #define SWIM_HEDSEL 0x20 #define SWIM_MOTON 0x80 +static const char *swim_reg_names[] = { + "WRITE_DATA", "WRITE_MARK", "WRITE_CRC", "WRITE_PARAMETER", + "WRITE_PHASE", "WRITE_SETUP", "WRITE_MODE0", "WRITE_MODE1", + "READ_DATA", "READ_MARK", "READ_ERROR", "READ_PARAMETER", + "READ_PHASE", "READ_SETUP", "READ_STATUS", "READ_HANDSHAKE" +}; + static void fd_recalibrate(FDrive *drive) { } @@ -267,6 +275,7 @@ static void iwmctrl_write(void *opaque, hwaddr reg, uint64_t value, reg >>= REG_SHIFT; swimctrl->regs[reg >> 1] = reg & 1; + trace_swim_iwmctrl_write((reg >> 1), size, (reg & 1)); if (swimctrl->regs[IWM_Q6] && swimctrl->regs[IWM_Q7]) { @@ -297,6 +306,7 @@ static void iwmctrl_write(void *opaque, hwaddr reg, uint64_t value, if (value == 0x57) { swimctrl->mode = SWIM_MODE_SWIM; swimctrl->iwm_switch = 0; + trace_swim_iwm_switch(); } break; } @@ -312,6 +322,7 @@ static uint64_t iwmctrl_read(void *opaque, hwaddr reg, unsigned size) swimctrl->regs[reg >> 1] = reg & 1; + trace_swim_iwmctrl_read((reg >> 1), size, (reg & 1)); return 0; } @@ -327,6 +338,8 @@ static void swimctrl_write(void *opaque, hwaddr reg, uint64_t value, reg >>= REG_SHIFT; + trace_swim_swimctrl_write(reg, swim_reg_names[reg], size, value); + switch (reg) { case SWIM_WRITE_PHASE: swimctrl->swim_phase = value; @@ -376,6 +389,7 @@ static uint64_t swimctrl_read(void *opaque, hwaddr reg, unsigned size) break; } + trace_swim_swimctrl_read(reg, swim_reg_names[reg], size, value); return value; } diff --git a/hw/block/trace-events b/hw/block/trace-events index 34be8b9135..c041ec45e3 100644 --- a/hw/block/trace-events +++ b/hw/block/trace-events @@ -90,3 +90,10 @@ m25p80_read_data(void *s, uint32_t pos, uint8_t v) "[%p] Read data 0x%"PRIx32"=0 m25p80_read_sfdp(void *s, uint32_t addr, uint8_t v) "[%p] Read SFDP 0x%"PRIx32"=0x%"PRIx8 m25p80_binding(void *s) "[%p] Binding to IF_MTD drive" m25p80_binding_no_bdrv(void *s) "[%p] No BDRV - binding to RAM" + +# swim.c +swim_swimctrl_read(int reg, const char *name, unsigned size, uint64_t value) "reg=%d [%s] size=%u value=0x%"PRIx64 +swim_swimctrl_write(int reg, const char *name, unsigned size, uint64_t value) "reg=%d [%s] size=%u value=0x%"PRIx64 +swim_iwmctrl_read(int reg, unsigned size, uint64_t value) "reg=%d size=%u value=0x%"PRIx64 +swim_iwmctrl_write(int reg, unsigned size, uint64_t value) "reg=%d size=%u value=0x%"PRIx64 +swim_iwm_switch(void) "switch from IWM to SWIM mode" From patchwork Wed Oct 4 08:37:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Cave-Ayland X-Patchwork-Id: 13408377 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 51D22E8FDDC for ; Wed, 4 Oct 2023 08:39:23 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qnxPM-0004C6-Gs; Wed, 04 Oct 2023 04:39:04 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxPL-0004Bq-5W for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:39:03 -0400 Received: from mail.ilande.co.uk ([2001:41c9:1:41f::167]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxPJ-0007ge-6n for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:39:02 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=ilande.co.uk; s=20220518; h=Subject:Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:To:From:Sender:Reply-To:Cc: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=T9uaQHDJxlwyXQUN9dzuctOvnyxrYWdc+3sCGFNuGBk=; b=IfaIjpRMY8Vf5nBW/H+tgxPEkU u/7JXSFlNjWM1cQqaijT5IqV/IU4UufWNPsy+dTHi78jdq76GP3xv/m96aaaJflfDt/XlL3M9Fwps wVlVPgyMhBcF05XKwCnmP4E2OFwG+Y2r0WjYRGpUQag9bQUXmzYKeHUjIveraULz3sPsUoTML7Q+y uECDyj0fi82TS3bpz0s8GUJKDAG12q/GYKq94o7QDgBaL8qDfcUdSPjm0xWpuc/pAEqn4PdJunu+m GL6s0cR7CFE5dYehbd1ic61pUHlt8jqTnjS54eJKA2qAo5dbrccFJlzc8llvJTCO7HEl0L4iTjBTx E3RwKAPWB4wTFFDRmPCac9avjvXr5zs0IOOBMijxZTFamEAoIHowy+ogF72hH9rdGFOxeQI8pNOhm xi+bckUlj31+FRUUY4ucbm7yD5o3z+Xll8+q63pQPe0xqLPKMUK+wXOpG3vnzJoj2UCLwYWWcqCCp aq7AaMqqs58XUvKqXQcd9fqbEZrd7ZMoM9zC1h6HRNY/QfTTRtTWxE6NNjV4WH9tecsvX/MSNDo0r ctDKBL62IHkBdLoD2SIrArktpVQGyPRCOBRSuh+AkyKB+2Q/heXONrXSdp52PEwpRvAnIao1r7i8G QRAWQK2/zs1QJ/mJPg2t+0OQ6P+nE5sPi2nciG81c=; Received: from host86-159-123-68.range86-159.btcentralplus.com ([86.159.123.68] helo=localhost.localdomain) by mail.ilande.co.uk with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qnxP4-0006za-Ff; Wed, 04 Oct 2023 09:38:50 +0100 From: Mark Cave-Ayland To: laurent@vivier.eu, qemu-devel@nongnu.org Date: Wed, 4 Oct 2023 09:37:58 +0100 Message-Id: <20231004083806.757242-13-mark.cave-ayland@ilande.co.uk> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> References: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 86.159.123.68 X-SA-Exim-Mail-From: mark.cave-ayland@ilande.co.uk Subject: [PATCH v4 12/20] swim: split into separate IWM and ISM register blocks X-SA-Exim-Version: 4.2.1 (built Wed, 08 May 2019 21:11:16 +0000) X-SA-Exim-Scanned: Yes (on mail.ilande.co.uk) Received-SPF: pass client-ip=2001:41c9:1:41f::167; envelope-from=mark.cave-ayland@ilande.co.uk; helo=mail.ilande.co.uk X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org The swim chip provides an implementation of both Apple's IWM and ISM floppy disk controllers. Split the existing implementation into separate register banks for each controller, whilst also switching the IWM registers from 16-bit to 8-bit as implemented in real hardware. Signed-off-by: Mark Cave-Ayland Reviewed-by: Laurent Vivier --- hw/block/swim.c | 85 ++++++++++++++++++++++++----------------- hw/block/trace-events | 4 +- include/hw/block/swim.h | 15 +++----- 3 files changed, 58 insertions(+), 46 deletions(-) diff --git a/hw/block/swim.c b/hw/block/swim.c index 7df36ea139..505718bdae 100644 --- a/hw/block/swim.c +++ b/hw/block/swim.c @@ -126,7 +126,14 @@ #define SWIM_HEDSEL 0x20 #define SWIM_MOTON 0x80 -static const char *swim_reg_names[] = { +static const char *iwm_reg_names[] = { + "PH0L", "PH0H", "PH1L", "PH1H", + "PH2L", "PH2H", "PH3L", "PH3H", + "MTROFF", "MTRON", "INTDRIVE", "EXTDRIVE", + "Q6L", "Q6H", "Q7L", "Q7H" +}; + +static const char *ism_reg_names[] = { "WRITE_DATA", "WRITE_MARK", "WRITE_CRC", "WRITE_PARAMETER", "WRITE_PHASE", "WRITE_SETUP", "WRITE_MODE0", "WRITE_MODE1", "READ_DATA", "READ_MARK", "READ_ERROR", "READ_PARAMETER", @@ -274,12 +281,11 @@ static void iwmctrl_write(void *opaque, hwaddr reg, uint64_t value, reg >>= REG_SHIFT; - swimctrl->regs[reg >> 1] = reg & 1; - trace_swim_iwmctrl_write((reg >> 1), size, (reg & 1)); + swimctrl->iwmregs[reg] = value; + trace_swim_iwmctrl_write(reg, iwm_reg_names[reg], size, value); - if (swimctrl->regs[IWM_Q6] && - swimctrl->regs[IWM_Q7]) { - if (swimctrl->regs[IWM_MTR]) { + if (swimctrl->iwmregs[IWM_Q7H]) { + if (swimctrl->iwmregs[IWM_MTRON]) { /* data register */ swimctrl->iwm_data = value; } else { @@ -307,6 +313,12 @@ static void iwmctrl_write(void *opaque, hwaddr reg, uint64_t value, swimctrl->mode = SWIM_MODE_SWIM; swimctrl->iwm_switch = 0; trace_swim_iwm_switch(); + + /* Switch to ISM registers */ + memory_region_del_subregion(&swimctrl->swim, + &swimctrl->iwm); + memory_region_add_subregion(&swimctrl->swim, 0x0, + &swimctrl->ism); } break; } @@ -317,28 +329,30 @@ static void iwmctrl_write(void *opaque, hwaddr reg, uint64_t value, static uint64_t iwmctrl_read(void *opaque, hwaddr reg, unsigned size) { SWIMCtrl *swimctrl = opaque; + uint8_t value; reg >>= REG_SHIFT; - swimctrl->regs[reg >> 1] = reg & 1; + value = swimctrl->iwmregs[reg]; + trace_swim_iwmctrl_read(reg, iwm_reg_names[reg], size, value); - trace_swim_iwmctrl_read((reg >> 1), size, (reg & 1)); - return 0; + return value; } -static void swimctrl_write(void *opaque, hwaddr reg, uint64_t value, - unsigned size) +static const MemoryRegionOps swimctrl_iwm_ops = { + .write = iwmctrl_write, + .read = iwmctrl_read, + .endianness = DEVICE_BIG_ENDIAN, +}; + +static void ismctrl_write(void *opaque, hwaddr reg, uint64_t value, + unsigned size) { SWIMCtrl *swimctrl = opaque; - if (swimctrl->mode == SWIM_MODE_IWM) { - iwmctrl_write(opaque, reg, value, size); - return; - } - reg >>= REG_SHIFT; - trace_swim_swimctrl_write(reg, swim_reg_names[reg], size, value); + trace_swim_swimctrl_write(reg, ism_reg_names[reg], size, value); switch (reg) { case SWIM_WRITE_PHASE: @@ -359,15 +373,11 @@ static void swimctrl_write(void *opaque, hwaddr reg, uint64_t value, } } -static uint64_t swimctrl_read(void *opaque, hwaddr reg, unsigned size) +static uint64_t ismctrl_read(void *opaque, hwaddr reg, unsigned size) { SWIMCtrl *swimctrl = opaque; uint32_t value = 0; - if (swimctrl->mode == SWIM_MODE_IWM) { - return iwmctrl_read(opaque, reg, size); - } - reg >>= REG_SHIFT; switch (reg) { @@ -389,14 +399,14 @@ static uint64_t swimctrl_read(void *opaque, hwaddr reg, unsigned size) break; } - trace_swim_swimctrl_read(reg, swim_reg_names[reg], size, value); + trace_swim_swimctrl_read(reg, ism_reg_names[reg], size, value); return value; } -static const MemoryRegionOps swimctrl_mem_ops = { - .write = swimctrl_write, - .read = swimctrl_read, - .endianness = DEVICE_NATIVE_ENDIAN, +static const MemoryRegionOps swimctrl_ism_ops = { + .write = ismctrl_write, + .read = ismctrl_read, + .endianness = DEVICE_BIG_ENDIAN, }; static void sysbus_swim_reset(DeviceState *d) @@ -407,13 +417,13 @@ static void sysbus_swim_reset(DeviceState *d) ctrl->mode = 0; ctrl->iwm_switch = 0; - for (i = 0; i < 8; i++) { - ctrl->regs[i] = 0; - } ctrl->iwm_data = 0; ctrl->iwm_mode = 0; + memset(ctrl->iwmregs, 0, 16); + ctrl->swim_phase = 0; ctrl->swim_mode = 0; + memset(ctrl->ismregs, 0, 16); for (i = 0; i < SWIM_MAX_FD; i++) { fd_recalibrate(&ctrl->drives[i]); } @@ -425,9 +435,12 @@ static void sysbus_swim_init(Object *obj) Swim *sbs = SWIM(obj); SWIMCtrl *swimctrl = &sbs->ctrl; - memory_region_init_io(&swimctrl->iomem, obj, &swimctrl_mem_ops, swimctrl, - "swim", 0x2000); - sysbus_init_mmio(sbd, &swimctrl->iomem); + memory_region_init(&swimctrl->swim, obj, "swim", 0x2000); + memory_region_init_io(&swimctrl->iwm, obj, &swimctrl_iwm_ops, swimctrl, + "iwm", 0x2000); + memory_region_init_io(&swimctrl->ism, obj, &swimctrl_ism_ops, swimctrl, + "ism", 0x2000); + sysbus_init_mmio(sbd, &swimctrl->swim); } static void sysbus_swim_realize(DeviceState *dev, Error **errp) @@ -437,6 +450,9 @@ static void sysbus_swim_realize(DeviceState *dev, Error **errp) qbus_init(&swimctrl->bus, sizeof(SWIMBus), TYPE_SWIM_BUS, dev, NULL); swimctrl->bus.ctrl = swimctrl; + + /* Default register set is IWM */ + memory_region_add_subregion(&swimctrl->swim, 0x0, &swimctrl->iwm); } static const VMStateDescription vmstate_fdrive = { @@ -456,10 +472,11 @@ static const VMStateDescription vmstate_swim = { VMSTATE_INT32(mode, SWIMCtrl), /* IWM mode */ VMSTATE_INT32(iwm_switch, SWIMCtrl), - VMSTATE_UINT16_ARRAY(regs, SWIMCtrl, 8), + VMSTATE_UINT8_ARRAY(iwmregs, SWIMCtrl, 16), VMSTATE_UINT8(iwm_data, SWIMCtrl), VMSTATE_UINT8(iwm_mode, SWIMCtrl), /* SWIM mode */ + VMSTATE_UINT8_ARRAY(ismregs, SWIMCtrl, 16), VMSTATE_UINT8(swim_phase, SWIMCtrl), VMSTATE_UINT8(swim_mode, SWIMCtrl), /* Drives */ diff --git a/hw/block/trace-events b/hw/block/trace-events index c041ec45e3..ea84ad6c77 100644 --- a/hw/block/trace-events +++ b/hw/block/trace-events @@ -94,6 +94,6 @@ m25p80_binding_no_bdrv(void *s) "[%p] No BDRV - binding to RAM" # swim.c swim_swimctrl_read(int reg, const char *name, unsigned size, uint64_t value) "reg=%d [%s] size=%u value=0x%"PRIx64 swim_swimctrl_write(int reg, const char *name, unsigned size, uint64_t value) "reg=%d [%s] size=%u value=0x%"PRIx64 -swim_iwmctrl_read(int reg, unsigned size, uint64_t value) "reg=%d size=%u value=0x%"PRIx64 -swim_iwmctrl_write(int reg, unsigned size, uint64_t value) "reg=%d size=%u value=0x%"PRIx64 +swim_iwmctrl_read(int reg, const char *name, unsigned size, uint64_t value) "reg=%d [%s] size=%u value=0x%"PRIx64 +swim_iwmctrl_write(int reg, const char *name, unsigned size, uint64_t value) "reg=%d [%s] size=%u value=0x%"PRIx64 swim_iwm_switch(void) "switch from IWM to SWIM mode" diff --git a/include/hw/block/swim.h b/include/hw/block/swim.h index 9b3dcb029d..1bc7635d02 100644 --- a/include/hw/block/swim.h +++ b/include/hw/block/swim.h @@ -43,23 +43,18 @@ typedef struct FDrive { } FDrive; struct SWIMCtrl { - MemoryRegion iomem; + MemoryRegion swim; + MemoryRegion iwm; + MemoryRegion ism; FDrive drives[SWIM_MAX_FD]; int mode; /* IWM mode */ int iwm_switch; - uint16_t regs[8]; -#define IWM_PH0 0 -#define IWM_PH1 1 -#define IWM_PH2 2 -#define IWM_PH3 3 -#define IWM_MTR 4 -#define IWM_DRIVE 5 -#define IWM_Q6 6 -#define IWM_Q7 7 + uint8_t iwmregs[16]; uint8_t iwm_data; uint8_t iwm_mode; /* SWIM mode */ + uint8_t ismregs[16]; uint8_t swim_phase; uint8_t swim_mode; SWIMBus bus; From patchwork Wed Oct 4 08:37:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Cave-Ayland X-Patchwork-Id: 13408394 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 3599EE8FDDA for ; Wed, 4 Oct 2023 08:42:13 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qnxPV-0004lt-6Q; Wed, 04 Oct 2023 04:39:13 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxPS-0004d3-Cc for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:39:10 -0400 Received: from mail.ilande.co.uk ([2001:41c9:1:41f::167]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxPO-0007hU-3T for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:39:08 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=ilande.co.uk; s=20220518; h=Subject:Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:To:From:Sender:Reply-To:Cc: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=zScWBfSeF8NjGOzhJ3JXem9u+umxQIC8mup10AVmOQY=; b=ycWONwL5y9BAQNlLIVpfL7VYiy VRc3pNxNDSWC79HLmfmjWYKfC3tmAdGIzh5l1n4t9V+X4vGoeA5wB+yECKZSftKgCJvDYckUHFZgs Hc0qv6AaBLa15gdkHR0UwmjumI/6zktlndkJEadti55rYl/VWB5OJZ41+769tcnvJUl8V0x+DaHZw JRzZGV5Np6OcfuBBsMAS8c/HtsPf0Z3Doopad9zqrOBJWnBZANer08SoNH5laUJNnf/HcZ/4ZL1ou su9QHpBOMlwRwbF80qsxUuHM2mxblIlSCY2sMpaCeJu9kiLdDMj+thv7k6cMhoHYrIMQnJDB8ew85 dm4faEwEh4whAWy20wY3aesCHmI+b6Duo1F6U3hN0q48a9fNKxBRjgFUwpeCED5rHi8prMmvt7prh 8ag+E1UgtCkDg9U6syqSF61eRY9zVhg7N6LAY96iiy/ET7UzuAAOi2nHMO9wkQ/p/nxISHEkTG3U0 2VYqkgejcABLEp4XV2N7TMOd65tK1n0B0R+cyzefjKODRkXobEwoXvKSo9EKlWfc2Uvt3Tk30PGeD pwJ+6TsODMB4zJFLlvqPde7NyfAYbQdpbjJ375wMkXWAFI+T/AA42iTcC0+BU/5yo82o04G23nz7z qxRsgUKW3bTerjwsdSTF/jqgvBslkKbg+aiKxlQAY=; Received: from host86-159-123-68.range86-159.btcentralplus.com ([86.159.123.68] helo=localhost.localdomain) by mail.ilande.co.uk with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qnxP8-0006za-AY; Wed, 04 Oct 2023 09:38:55 +0100 From: Mark Cave-Ayland To: laurent@vivier.eu, qemu-devel@nongnu.org Date: Wed, 4 Oct 2023 09:37:59 +0100 Message-Id: <20231004083806.757242-14-mark.cave-ayland@ilande.co.uk> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> References: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 86.159.123.68 X-SA-Exim-Mail-From: mark.cave-ayland@ilande.co.uk Subject: [PATCH v4 13/20] swim: update IWM/ISM register block decoding X-SA-Exim-Version: 4.2.1 (built Wed, 08 May 2019 21:11:16 +0000) X-SA-Exim-Scanned: Yes (on mail.ilande.co.uk) Received-SPF: pass client-ip=2001:41c9:1:41f::167; envelope-from=mark.cave-ayland@ilande.co.uk; helo=mail.ilande.co.uk X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Update the IWM/ISM register block decoding to match the description given in the "SWIM Chip Users Reference". This allows us to validate the device response to the guest OS which currently only does just enough to indicate that the floppy drive is unavailable. Signed-off-by: Mark Cave-Ayland Reviewed-by: Laurent Vivier --- hw/block/swim.c | 212 +++++++++++++++++++++++++--------------- hw/block/trace-events | 7 +- include/hw/block/swim.h | 8 +- 3 files changed, 143 insertions(+), 84 deletions(-) diff --git a/hw/block/swim.c b/hw/block/swim.c index 505718bdae..fd65c59f8a 100644 --- a/hw/block/swim.c +++ b/hw/block/swim.c @@ -21,24 +21,28 @@ #include "hw/qdev-properties.h" #include "trace.h" + +/* IWM latch bits */ + +#define IWMLB_PHASE0 0 +#define IWMLB_PHASE1 1 +#define IWMLB_PHASE2 2 +#define IWMLB_PHASE3 3 +#define IWMLB_MOTORON 4 +#define IWMLB_DRIVESEL 5 +#define IWMLB_L6 6 +#define IWMLB_L7 7 + /* IWM registers */ -#define IWM_PH0L 0 -#define IWM_PH0H 1 -#define IWM_PH1L 2 -#define IWM_PH1H 3 -#define IWM_PH2L 4 -#define IWM_PH2H 5 -#define IWM_PH3L 6 -#define IWM_PH3H 7 -#define IWM_MTROFF 8 -#define IWM_MTRON 9 -#define IWM_INTDRIVE 10 -#define IWM_EXTDRIVE 11 -#define IWM_Q6L 12 -#define IWM_Q6H 13 -#define IWM_Q7L 14 -#define IWM_Q7H 15 +#define IWM_READALLONES 0 +#define IWM_READDATA 1 +#define IWM_READSTATUS0 2 +#define IWM_READSTATUS1 3 +#define IWM_READWHANDSHAKE0 4 +#define IWM_READWHANDSHAKE1 5 +#define IWM_WRITESETMODE 6 +#define IWM_WRITEDATA 7 /* SWIM registers */ @@ -62,8 +66,9 @@ #define REG_SHIFT 9 -#define SWIM_MODE_IWM 0 -#define SWIM_MODE_SWIM 1 +#define SWIM_MODE_STATUS_BIT 6 +#define SWIM_MODE_IWM 0 +#define SWIM_MODE_ISM 1 /* bits in phase register */ @@ -127,10 +132,8 @@ #define SWIM_MOTON 0x80 static const char *iwm_reg_names[] = { - "PH0L", "PH0H", "PH1L", "PH1H", - "PH2L", "PH2H", "PH3L", "PH3H", - "MTROFF", "MTRON", "INTDRIVE", "EXTDRIVE", - "Q6L", "Q6H", "Q7L", "Q7H" + "READALLONES", "READDATA", "READSTATUS0", "READSTATUS1", + "READWHANDSHAKE0", "READWHANDSHAKE1", "WRITESETMODE", "WRITEDATA" }; static const char *ism_reg_names[] = { @@ -274,68 +277,99 @@ static const TypeInfo swim_bus_info = { .instance_size = sizeof(SWIMBus), }; -static void iwmctrl_write(void *opaque, hwaddr reg, uint64_t value, +static void iwmctrl_write(void *opaque, hwaddr addr, uint64_t value, unsigned size) { SWIMCtrl *swimctrl = opaque; + uint8_t latch, reg, ism_bit; - reg >>= REG_SHIFT; + addr >>= REG_SHIFT; + + /* A3-A1 select a latch, A0 specifies the value */ + latch = (addr >> 1) & 7; + if (addr & 1) { + swimctrl->iwm_latches |= (1 << latch); + } else { + swimctrl->iwm_latches &= ~(1 << latch); + } + + reg = (swimctrl->iwm_latches & 0xc0) >> 5 | + (swimctrl->iwm_latches & 0x10) >> 4; swimctrl->iwmregs[reg] = value; trace_swim_iwmctrl_write(reg, iwm_reg_names[reg], size, value); - if (swimctrl->iwmregs[IWM_Q7H]) { - if (swimctrl->iwmregs[IWM_MTRON]) { - /* data register */ - swimctrl->iwm_data = value; - } else { - /* mode register */ - swimctrl->iwm_mode = value; - /* detect sequence to switch from IWM mode to SWIM mode */ - switch (swimctrl->iwm_switch) { - case 0: - if (value == 0x57) { - swimctrl->iwm_switch++; - } - break; - case 1: - if (value == 0x17) { - swimctrl->iwm_switch++; - } - break; - case 2: - if (value == 0x57) { - swimctrl->iwm_switch++; - } - break; - case 3: - if (value == 0x57) { - swimctrl->mode = SWIM_MODE_SWIM; - swimctrl->iwm_switch = 0; - trace_swim_iwm_switch(); - - /* Switch to ISM registers */ - memory_region_del_subregion(&swimctrl->swim, - &swimctrl->iwm); - memory_region_add_subregion(&swimctrl->swim, 0x0, - &swimctrl->ism); - } - break; + switch (reg) { + case IWM_WRITESETMODE: + /* detect sequence to switch from IWM mode to SWIM mode */ + ism_bit = (value & (1 << SWIM_MODE_STATUS_BIT)); + + switch (swimctrl->iwm_switch) { + case 0: + if (ism_bit) { /* 1 */ + swimctrl->iwm_switch++; + } + break; + case 1: + if (!ism_bit) { /* 0 */ + swimctrl->iwm_switch++; + } + break; + case 2: + if (ism_bit) { /* 1 */ + swimctrl->iwm_switch++; } + break; + case 3: + if (ism_bit) { /* 1 */ + swimctrl->iwm_switch++; + + swimctrl->mode = SWIM_MODE_ISM; + swimctrl->swim_mode |= (1 << SWIM_MODE_STATUS_BIT); + swimctrl->iwm_switch = 0; + trace_swim_switch_to_ism(); + + /* Switch to ISM registers */ + memory_region_del_subregion(&swimctrl->swim, &swimctrl->iwm); + memory_region_add_subregion(&swimctrl->swim, 0x0, + &swimctrl->ism); + } + break; } + break; + default: + break; } } -static uint64_t iwmctrl_read(void *opaque, hwaddr reg, unsigned size) +static uint64_t iwmctrl_read(void *opaque, hwaddr addr, unsigned size) { SWIMCtrl *swimctrl = opaque; - uint8_t value; + uint8_t latch, reg, value; - reg >>= REG_SHIFT; + addr >>= REG_SHIFT; - value = swimctrl->iwmregs[reg]; - trace_swim_iwmctrl_read(reg, iwm_reg_names[reg], size, value); + /* A3-A1 select a latch, A0 specifies the value */ + latch = (addr >> 1) & 7; + if (addr & 1) { + swimctrl->iwm_latches |= (1 << latch); + } else { + swimctrl->iwm_latches &= ~(1 << latch); + } + + reg = (swimctrl->iwm_latches & 0xc0) >> 5 | + (swimctrl->iwm_latches & 0x10) >> 4; + + switch (reg) { + case IWM_READALLONES: + value = 0xff; + break; + default: + value = 0; + break; + } + trace_swim_iwmctrl_read(reg, iwm_reg_names[reg], size, value); return value; } @@ -352,7 +386,7 @@ static void ismctrl_write(void *opaque, hwaddr reg, uint64_t value, reg >>= REG_SHIFT; - trace_swim_swimctrl_write(reg, ism_reg_names[reg], size, value); + trace_swim_ismctrl_write(reg, ism_reg_names[reg], size, value); switch (reg) { case SWIM_WRITE_PHASE: @@ -360,14 +394,31 @@ static void ismctrl_write(void *opaque, hwaddr reg, uint64_t value, break; case SWIM_WRITE_MODE0: swimctrl->swim_mode &= ~value; + /* Any access to MODE0 register resets PRAM index */ + swimctrl->pram_idx = 0; + + if (!(swimctrl->swim_mode & (1 << SWIM_MODE_STATUS_BIT))) { + /* Clearing the mode bit switches to IWM mode */ + swimctrl->mode = SWIM_MODE_IWM; + swimctrl->iwm_latches = 0; + trace_swim_switch_to_iwm(); + + /* Switch to IWM registers */ + memory_region_del_subregion(&swimctrl->swim, &swimctrl->ism); + memory_region_add_subregion(&swimctrl->swim, 0x0, + &swimctrl->iwm); + } break; case SWIM_WRITE_MODE1: swimctrl->swim_mode |= value; break; + case SWIM_WRITE_PARAMETER: + swimctrl->pram[swimctrl->pram_idx++] = value; + swimctrl->pram_idx &= 0xf; + break; case SWIM_WRITE_DATA: case SWIM_WRITE_MARK: case SWIM_WRITE_CRC: - case SWIM_WRITE_PARAMETER: case SWIM_WRITE_SETUP: break; } @@ -390,16 +441,24 @@ static uint64_t ismctrl_read(void *opaque, hwaddr reg, unsigned size) value = SWIM_SENSE; } break; + case SWIM_READ_PARAMETER: + value = swimctrl->pram[swimctrl->pram_idx++]; + swimctrl->pram_idx &= 0xf; + break; + case SWIM_READ_STATUS: + value = swimctrl->swim_status & ~(1 << SWIM_MODE_STATUS_BIT); + if (swimctrl->swim_mode == SWIM_MODE_ISM) { + value |= (1 << SWIM_MODE_STATUS_BIT); + } + break; case SWIM_READ_DATA: case SWIM_READ_MARK: case SWIM_READ_ERROR: - case SWIM_READ_PARAMETER: case SWIM_READ_SETUP: - case SWIM_READ_STATUS: break; } - trace_swim_swimctrl_read(reg, ism_reg_names[reg], size, value); + trace_swim_ismctrl_read(reg, ism_reg_names[reg], size, value); return value; } @@ -417,13 +476,11 @@ static void sysbus_swim_reset(DeviceState *d) ctrl->mode = 0; ctrl->iwm_switch = 0; - ctrl->iwm_data = 0; - ctrl->iwm_mode = 0; - memset(ctrl->iwmregs, 0, 16); + memset(ctrl->iwmregs, 0, sizeof(ctrl->iwmregs)); ctrl->swim_phase = 0; ctrl->swim_mode = 0; - memset(ctrl->ismregs, 0, 16); + memset(ctrl->ismregs, 0, sizeof(ctrl->ismregs)); for (i = 0; i < SWIM_MAX_FD; i++) { fd_recalibrate(&ctrl->drives[i]); } @@ -472,9 +529,8 @@ static const VMStateDescription vmstate_swim = { VMSTATE_INT32(mode, SWIMCtrl), /* IWM mode */ VMSTATE_INT32(iwm_switch, SWIMCtrl), - VMSTATE_UINT8_ARRAY(iwmregs, SWIMCtrl, 16), - VMSTATE_UINT8(iwm_data, SWIMCtrl), - VMSTATE_UINT8(iwm_mode, SWIMCtrl), + VMSTATE_UINT8(iwm_latches, SWIMCtrl), + VMSTATE_UINT8_ARRAY(iwmregs, SWIMCtrl, 8), /* SWIM mode */ VMSTATE_UINT8_ARRAY(ismregs, SWIMCtrl, 16), VMSTATE_UINT8(swim_phase, SWIMCtrl), diff --git a/hw/block/trace-events b/hw/block/trace-events index ea84ad6c77..bab21d3a1c 100644 --- a/hw/block/trace-events +++ b/hw/block/trace-events @@ -92,8 +92,9 @@ m25p80_binding(void *s) "[%p] Binding to IF_MTD drive" m25p80_binding_no_bdrv(void *s) "[%p] No BDRV - binding to RAM" # swim.c -swim_swimctrl_read(int reg, const char *name, unsigned size, uint64_t value) "reg=%d [%s] size=%u value=0x%"PRIx64 -swim_swimctrl_write(int reg, const char *name, unsigned size, uint64_t value) "reg=%d [%s] size=%u value=0x%"PRIx64 +swim_ismctrl_read(int reg, const char *name, unsigned size, uint64_t value) "reg=%d [%s] size=%u value=0x%"PRIx64 +swim_ismctrl_write(int reg, const char *name, unsigned size, uint64_t value) "reg=%d [%s] size=%u value=0x%"PRIx64 swim_iwmctrl_read(int reg, const char *name, unsigned size, uint64_t value) "reg=%d [%s] size=%u value=0x%"PRIx64 swim_iwmctrl_write(int reg, const char *name, unsigned size, uint64_t value) "reg=%d [%s] size=%u value=0x%"PRIx64 -swim_iwm_switch(void) "switch from IWM to SWIM mode" +swim_switch_to_ism(void) "switch from IWM to ISM mode" +swim_switch_to_iwm(void) "switch from ISM to IWM mode" diff --git a/include/hw/block/swim.h b/include/hw/block/swim.h index 1bc7635d02..5f567e8d59 100644 --- a/include/hw/block/swim.h +++ b/include/hw/block/swim.h @@ -50,13 +50,15 @@ struct SWIMCtrl { int mode; /* IWM mode */ int iwm_switch; - uint8_t iwmregs[16]; - uint8_t iwm_data; - uint8_t iwm_mode; + uint8_t iwm_latches; + uint8_t iwmregs[8]; /* SWIM mode */ uint8_t ismregs[16]; uint8_t swim_phase; uint8_t swim_mode; + uint8_t swim_status; + uint8_t pram[16]; + uint8_t pram_idx; SWIMBus bus; }; From patchwork Wed Oct 4 08:38:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Cave-Ayland X-Patchwork-Id: 13408389 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 848F6E8FDDA for ; Wed, 4 Oct 2023 08:41:07 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qnxPY-0004wm-EB; Wed, 04 Oct 2023 04:39:16 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxPU-0004lN-MY for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:39:13 -0400 Received: from mail.ilande.co.uk ([2001:41c9:1:41f::167]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxPS-0007iS-Nx for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:39:12 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=ilande.co.uk; s=20220518; h=Subject:Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:To:From:Sender:Reply-To:Cc: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=HNSsg9W015GHn8O4DJQUIfZYim9fHWmcUO3YSEGY3G8=; b=mx/1FsVMsucngy4RiEs3Ws+NYv UTeTtfI9TRt3i+iBjyD+siQCDEW5cMkxQgL6Eq8gytjRYK7puInO1Sfd+yX6OHYpEtWJmRXNJrbKO RBplOLPhu98Z7FfSCS0Anzc8gTvewDw3zcMxcmgFybDWOb0+/v+nEeqBHjXoOa8BOkDcs5r9AcyPs amHHcYHNi+jgOyTiG50P6Pg4bGuk9LvDrgsW0qxCfinw0hLsL83AZ3Ftuv2wSaabDMLlqhYyBK/A/ W1ds5JXFCEgzl4Te45JTqqA+WPpKweS6mJH/Q9HWGmilPUGkafHE+YbETtCwaLM/9oEUxPByyjyyr Yy+gQ68airoK+R9n/zqNKWTeYEnHvHsBt8Wj3Ol00YT/vfz1ewrdVqF08go5Tv7roUUKThlDq7yVp zh0s9Jq/aH0fagafa0wyfqo4i5FLIpB4Ru9eiOcp/QATXdTRDnIkEZxJdFc884LU27lmC2pdG5L7G JX0++WwV5vXayl414bvFVdVg9vYKriGcl88S0CgvdSvBocpesyvokRZV7mc7a0xgRVOZx+/O5qo3X zGKsU+Y6G5s3/8XQfftT+yrYLEtB72pWWXp832AYj7lVOo0bR+YTxiHR23wAl86DeVTqG6hJ+2WFu Qmxin7TWcJO9KDGGWQBzJcUFIe0e38KU5NLutrSU0=; Received: from host86-159-123-68.range86-159.btcentralplus.com ([86.159.123.68] helo=localhost.localdomain) by mail.ilande.co.uk with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qnxPD-0006za-4p; Wed, 04 Oct 2023 09:38:59 +0100 From: Mark Cave-Ayland To: laurent@vivier.eu, qemu-devel@nongnu.org Date: Wed, 4 Oct 2023 09:38:00 +0100 Message-Id: <20231004083806.757242-15-mark.cave-ayland@ilande.co.uk> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> References: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 86.159.123.68 X-SA-Exim-Mail-From: mark.cave-ayland@ilande.co.uk Subject: [PATCH v4 14/20] mac_via: work around underflow in TimeDBRA timing loop in SETUPTIMEK X-SA-Exim-Version: 4.2.1 (built Wed, 08 May 2019 21:11:16 +0000) X-SA-Exim-Scanned: Yes (on mail.ilande.co.uk) Received-SPF: pass client-ip=2001:41c9:1:41f::167; envelope-from=mark.cave-ayland@ilande.co.uk; helo=mail.ilande.co.uk X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org The MacOS toolbox ROM calculates the number of branches that can be executed per millisecond as part of its timer calibration. Since modern hosts are considerably quicker than original hardware, the negative counter reaches zero before the calibration completes leading to division by zero later in CALCULATESLOD. Instead of trying to fudge the timing loop (which won't work for TimeDBRA/TimeSCCDB anyhow), use the pattern of access to the VIA1 registers to detect when SETUPTIMEK has finished executing and write some well-known good timer values to TimeDBRA and TimeSCCDB taken from real hardware with a suitable scaling factor. Signed-off-by: Mark Cave-Ayland Reviewed-by: Laurent Vivier --- hw/misc/mac_via.c | 115 ++++++++++++++++++++++++++++++++++++++ hw/misc/trace-events | 1 + include/hw/misc/mac_via.h | 3 + 3 files changed, 119 insertions(+) diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c index e87a1b82d8..f2ccb12d64 100644 --- a/hw/misc/mac_via.c +++ b/hw/misc/mac_via.c @@ -16,6 +16,7 @@ */ #include "qemu/osdep.h" +#include "exec/address-spaces.h" #include "migration/vmstate.h" #include "hw/sysbus.h" #include "hw/irq.h" @@ -871,6 +872,112 @@ static void via1_auxmode_update(MOS6522Q800VIA1State *v1s) } } +/* + * Addresses and real values for TimeDBRA/TimeSCCB to allow timer calibration + * to succeed (NOTE: both values have been multiplied by 3 to cope with the + * speed of QEMU execution on a modern host + */ +#define MACOS_TIMEDBRA 0xd00 +#define MACOS_TIMESCCB 0xd02 + +#define MACOS_TIMEDBRA_VALUE (0x2a00 * 3) +#define MACOS_TIMESCCB_VALUE (0x079d * 3) + +static bool via1_is_toolbox_timer_calibrated(void) +{ + /* + * Indicate whether the MacOS toolbox has been calibrated by checking + * for the value of our magic constants + */ + uint16_t timedbra = lduw_be_phys(&address_space_memory, MACOS_TIMEDBRA); + uint16_t timesccdb = lduw_be_phys(&address_space_memory, MACOS_TIMESCCB); + + return (timedbra == MACOS_TIMEDBRA_VALUE && + timesccdb == MACOS_TIMESCCB_VALUE); +} + +static void via1_timer_calibration_hack(MOS6522Q800VIA1State *v1s, int addr, + uint64_t val, int size) +{ + /* + * Work around timer calibration to ensure we that we have non-zero and + * known good values for TIMEDRBA and TIMESCCDB. + * + * This works by attempting to detect the reset and calibration sequence + * of writes to VIA1 + */ + int old_timer_hack_state = v1s->timer_hack_state; + + switch (v1s->timer_hack_state) { + case 0: + if (addr == VIA_REG_PCR && val == 0x22) { + /* VIA_REG_PCR: configure VIA1 edge triggering */ + v1s->timer_hack_state = 1; + } + break; + case 1: + if (addr == VIA_REG_T2CL && val == 0xc) { + /* VIA_REG_T2CL: low byte of 1ms counter */ + if (!via1_is_toolbox_timer_calibrated()) { + v1s->timer_hack_state = 2; + } else { + v1s->timer_hack_state = 0; + } + } + break; + case 2: + if (addr == VIA_REG_T2CH && val == 0x3) { + /* + * VIA_REG_T2CH: high byte of 1ms counter (very likely at the + * start of SETUPTIMEK) + */ + if (!via1_is_toolbox_timer_calibrated()) { + v1s->timer_hack_state = 3; + } else { + v1s->timer_hack_state = 0; + } + } + break; + case 3: + if (addr == VIA_REG_IER && val == 0x20) { + /* + * VIA_REG_IER: update at end of SETUPTIMEK + * + * Timer calibration has finished: unfortunately the values in + * TIMEDBRA (0xd00) and TIMESCCDB (0xd02) are so far out they + * cause divide by zero errors. + * + * Update them with values obtained from a real Q800 but with + * a x3 scaling factor which seems to work well + */ + stw_be_phys(&address_space_memory, MACOS_TIMEDBRA, + MACOS_TIMEDBRA_VALUE); + stw_be_phys(&address_space_memory, MACOS_TIMESCCB, + MACOS_TIMESCCB_VALUE); + + v1s->timer_hack_state = 4; + } + break; + case 4: + /* + * This is the normal post-calibration timer state: we should + * generally remain here unless we detect the A/UX calibration + * loop, or a write to VIA_REG_PCR suggesting a reset + */ + if (addr == VIA_REG_PCR && val == 0x22) { + /* Looks like there has been a reset? */ + v1s->timer_hack_state = 1; + } + break; + default: + g_assert_not_reached(); + } + + if (old_timer_hack_state != v1s->timer_hack_state) { + trace_via1_timer_hack_state(v1s->timer_hack_state); + } +} + static uint64_t mos6522_q800_via1_read(void *opaque, hwaddr addr, unsigned size) { MOS6522Q800VIA1State *s = MOS6522_Q800_VIA1(opaque); @@ -896,6 +1003,9 @@ static void mos6522_q800_via1_write(void *opaque, hwaddr addr, uint64_t val, MOS6522State *ms = MOS6522(v1s); addr = (addr >> 9) & 0xf; + + via1_timer_calibration_hack(v1s, addr, val, size); + mos6522_write(ms, addr, val, size); switch (addr) { @@ -1008,6 +1118,9 @@ static void mos6522_q800_via1_reset_hold(Object *obj) adb_set_autopoll_enabled(adb_bus, true); v1s->cmd = REG_EMPTY; v1s->alt = REG_EMPTY; + + /* Timer calibration hack */ + v1s->timer_hack_state = 0; } static void mos6522_q800_via1_realize(DeviceState *dev, Error **errp) @@ -1100,6 +1213,8 @@ static const VMStateDescription vmstate_q800_via1 = { VMSTATE_INT64(next_second, MOS6522Q800VIA1State), VMSTATE_TIMER_PTR(sixty_hz_timer, MOS6522Q800VIA1State), VMSTATE_INT64(next_sixty_hz, MOS6522Q800VIA1State), + /* Timer hack */ + VMSTATE_INT32(timer_hack_state, MOS6522Q800VIA1State), VMSTATE_END_OF_LIST() } }; diff --git a/hw/misc/trace-events b/hw/misc/trace-events index 29bc531d4d..5a998f5e4e 100644 --- a/hw/misc/trace-events +++ b/hw/misc/trace-events @@ -272,6 +272,7 @@ via1_adb_send(const char *state, uint8_t data, const char *vadbint) "state %s da via1_adb_receive(const char *state, uint8_t data, const char *vadbint, int status, int index, int size) "state %s data=0x%02x vADBInt=%s status=0x%x index=%d size=%d" via1_adb_poll(uint8_t data, const char *vadbint, int status, int index, int size) "data=0x%02x vADBInt=%s status=0x%x index=%d size=%d" via1_auxmode(int mode) "setting auxmode to %d" +via1_timer_hack_state(int state) "setting timer_hack_state to %d" # grlib_ahb_apb_pnp.c grlib_ahb_pnp_read(uint64_t addr, unsigned size, uint32_t value) "AHB PnP read addr:0x%03"PRIx64" size:%u data:0x%08x" diff --git a/include/hw/misc/mac_via.h b/include/hw/misc/mac_via.h index 422da43bf9..63cdcf7c69 100644 --- a/include/hw/misc/mac_via.h +++ b/include/hw/misc/mac_via.h @@ -74,6 +74,9 @@ struct MOS6522Q800VIA1State { int64_t next_second; QEMUTimer *sixty_hz_timer; int64_t next_sixty_hz; + + /* SETUPTIMEK hack */ + int timer_hack_state; }; From patchwork Wed Oct 4 08:38:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Cave-Ayland X-Patchwork-Id: 13408380 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0227FE8FDDB for ; Wed, 4 Oct 2023 08:39:47 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qnxPc-00052u-BG; Wed, 04 Oct 2023 04:39:20 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxPZ-0004yl-PS for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:39:18 -0400 Received: from mail.ilande.co.uk ([2001:41c9:1:41f::167]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxPX-0007jB-Qe for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:39:17 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=ilande.co.uk; s=20220518; h=Subject:Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:To:From:Sender:Reply-To:Cc: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=3cK7mneHmXDNy7JJNlaYZg+pj4RJY5qtD7UyWcf/zd4=; b=00vLPv3lcAOH3ihG4/1rovrpWm DUZ3DVUhIJV5FXQaJ8L+HKbPj6RnyesoFdNzXmZ5x1TRj+PT3Tx1jiK3ty1GTDGrZ98XjaMS5iAq1 aVdpQwXg2QO5jmG42dmxBdQ4QfCJzAuzqW3jssmKcq8maLezMmYl56vHWrP5j17HctNnh9l6l2pHg iH9RAZKYGws/wq36mbRPHewIoSB71AvkQPXMYoSVCd1tmiF9+GMMV8812hztng1R2MQtps75Syb+i WHQnyu5wE5DcQfBGTSugbqO2Deb5l0n9ge66ZI4Z5CVF5+N6abJFp+qdYAAQkgmZliV1YLjZnaGG0 BmQSshr0piKh1VR/HQiWHs7fnxA/t7Zt6/+pfXGQ51gZUKiBfab8Z7nnAfslXCmx7PEXEz5bc2Zlg SMclVgSnSXtOycOU9WoZxEw9sWRCfUuz0mzK4axf1KzGijDC/lgyO7sAic8S6yG9qnFmGOLaqu3rL 03i2vr5ngIHePxWxD3Srr3oVsg62k4zC++F/avFJ6KPdVkZm7lpuMtSe6t48eIss53xX/dTL8kVXs gZjXk1HDRYLZDsk8hy9rF9xoyoawWRsE+JdQhWR8lA8oJoI8ysm+E9Eqwu8nBqQ6q1nePZ86wJcYc zhSKRxs49OaZdP3Ozo3qzTt+2z+GDxhnRtmzL5qUw=; Received: from host86-159-123-68.range86-159.btcentralplus.com ([86.159.123.68] helo=localhost.localdomain) by mail.ilande.co.uk with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qnxPH-0006za-Tb; Wed, 04 Oct 2023 09:39:03 +0100 From: Mark Cave-Ayland To: laurent@vivier.eu, qemu-devel@nongnu.org Date: Wed, 4 Oct 2023 09:38:01 +0100 Message-Id: <20231004083806.757242-16-mark.cave-ayland@ilande.co.uk> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> References: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 86.159.123.68 X-SA-Exim-Mail-From: mark.cave-ayland@ilande.co.uk Subject: [PATCH v4 15/20] mac_via: workaround NetBSD ADB bus enumeration issue X-SA-Exim-Version: 4.2.1 (built Wed, 08 May 2019 21:11:16 +0000) X-SA-Exim-Scanned: Yes (on mail.ilande.co.uk) Received-SPF: pass client-ip=2001:41c9:1:41f::167; envelope-from=mark.cave-ayland@ilande.co.uk; helo=mail.ilande.co.uk X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org NetBSD assumes it can send its first ADB command after sending the ADB_BUSRESET command in ADB_STATE_NEW without changing the state back to ADB_STATE_IDLE first as detailed in the ADB protocol. Add a workaround to detect this condition at the start of ADB enumeration and send the next command written to SR after a ADB_BUSRESET onto the bus regardless, even if we don't detect a state transition to ADB_STATE_NEW. Signed-off-by: Mark Cave-Ayland Reviewed-by: Laurent Vivier --- hw/misc/mac_via.c | 34 ++++++++++++++++++++++++++++++++++ hw/misc/trace-events | 1 + 2 files changed, 35 insertions(+) diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c index f2ccb12d64..9f9c2815d0 100644 --- a/hw/misc/mac_via.c +++ b/hw/misc/mac_via.c @@ -1001,6 +1001,8 @@ static void mos6522_q800_via1_write(void *opaque, hwaddr addr, uint64_t val, { MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(opaque); MOS6522State *ms = MOS6522(v1s); + int oldstate, state; + int oldsr = ms->sr; addr = (addr >> 9) & 0xf; @@ -1016,6 +1018,38 @@ static void mos6522_q800_via1_write(void *opaque, hwaddr addr, uint64_t val, v1s->last_b = ms->b; break; + + case VIA_REG_SR: + { + /* + * NetBSD assumes it can send its first ADB command after sending + * the ADB_BUSRESET command in ADB_STATE_NEW without changing the + * state back to ADB_STATE_IDLE first as detailed in the ADB + * protocol. + * + * Add a workaround to detect this condition at the start of ADB + * enumeration and send the next command written to SR after a + * ADB_BUSRESET onto the bus regardless, even if we don't detect a + * state transition to ADB_STATE_NEW. + * + * Note that in my tests the NetBSD state machine takes one ADB + * operation to recover which means the probe for an ADB device at + * address 1 always fails. However since the first device is at + * address 2 then this will work fine, without having to come up + * with a more complicated and invasive solution. + */ + oldstate = (v1s->last_b & VIA1B_vADB_StateMask) >> + VIA1B_vADB_StateShift; + state = (ms->b & VIA1B_vADB_StateMask) >> VIA1B_vADB_StateShift; + + if (oldstate == ADB_STATE_NEW && state == ADB_STATE_NEW && + (ms->acr & VIA1ACR_vShiftOut) && + oldsr == 0 /* ADB_BUSRESET */) { + trace_via1_adb_netbsd_enum_hack(); + adb_via_send(v1s, state, ms->sr); + } + } + break; } } diff --git a/hw/misc/trace-events b/hw/misc/trace-events index 5a998f5e4e..24ba7cc4d0 100644 --- a/hw/misc/trace-events +++ b/hw/misc/trace-events @@ -271,6 +271,7 @@ via1_rtc_cmd_pram_sect_write(int sector, int offset, int addr, int value) "secto via1_adb_send(const char *state, uint8_t data, const char *vadbint) "state %s data=0x%02x vADBInt=%s" via1_adb_receive(const char *state, uint8_t data, const char *vadbint, int status, int index, int size) "state %s data=0x%02x vADBInt=%s status=0x%x index=%d size=%d" via1_adb_poll(uint8_t data, const char *vadbint, int status, int index, int size) "data=0x%02x vADBInt=%s status=0x%x index=%d size=%d" +via1_adb_netbsd_enum_hack(void) "using NetBSD enum hack" via1_auxmode(int mode) "setting auxmode to %d" via1_timer_hack_state(int state) "setting timer_hack_state to %d" From patchwork Wed Oct 4 08:38:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Cave-Ayland X-Patchwork-Id: 13408390 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A7124E8FDDB for ; Wed, 4 Oct 2023 08:41:15 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qnxPi-0005Cn-MH; Wed, 04 Oct 2023 04:39:26 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxPg-0005CN-V6 for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:39:25 -0400 Received: from mail.ilande.co.uk ([2001:41c9:1:41f::167]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxPc-0007jy-A6 for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:39:24 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=ilande.co.uk; s=20220518; h=Subject:Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:To:From:Sender:Reply-To:Cc: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=wj1kRK2UFSUTjJkP3sSSNCXThjQ7dL0dyJS9XEJSezI=; b=XRRQqZPEkI/Rm4GW52k03i7BXL eiIWir5CePRsVXlGVl0HKuCoMTaSSYwPqqVuDh5VoUoc657FVzu9P/SHYKznABWOvRM+VZagDsNIl FY9Z5ANCI188r5cvPYsTMH9M3lK7rHLIZwrTr34yA9/rCOmZ7+m8vlW/rIZCNONyHIQq+RNamjK1u az4IXpIgmkWq7RxXhXAmokdqEiawx/dteu2mK+f6AdXt1fR5BWOexygHJU0e9p0mpTbrF48r1l4ix 4hHn65Y1kR7BayykfQ3fkZvb61o3ibS6S+xogeevBjwZKMOQe4hXgmnQP68K7NXU2YGJBRt3Fn6o9 8dqD315kU2DH5BA/uaqzgp/Mh6p6MiNQMWj8NxOeCZghVWwvGWwBQZ+SLR1TaRGYTPnEEIvmpyvWk 6rUVxsohpwBM56qAY2Z3mQI8K1cpWOiJW4C5Ef4HTR3ZxuXAh1O6VjMLMNwxxxZ76dix95FB2e+iN yo8950YxNLtrZ3J8jpniuVjalCWxTkZU4imFdtMy4wn51OwiByw6ahcHK64zvxKJ3p4NzNEICE4Ku c2pKhDr9i2wJskxbkGOF3StSWmAeRdDZ3Ruqo+LxnqUGIfbsyCL03RWDmFU+vbzDmyY9WgK1F/mIY Oc7wHl/7Cs5cgY912TPZbmwwcywN5jFUF95eBMJbY=; Received: from host86-159-123-68.range86-159.btcentralplus.com ([86.159.123.68] helo=localhost.localdomain) by mail.ilande.co.uk with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qnxPL-0006za-Pd; Wed, 04 Oct 2023 09:39:09 +0100 From: Mark Cave-Ayland To: laurent@vivier.eu, qemu-devel@nongnu.org Date: Wed, 4 Oct 2023 09:38:02 +0100 Message-Id: <20231004083806.757242-17-mark.cave-ayland@ilande.co.uk> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> References: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 86.159.123.68 X-SA-Exim-Mail-From: mark.cave-ayland@ilande.co.uk Subject: [PATCH v4 16/20] mac_via: implement ADB_STATE_IDLE state if shift register in input mode X-SA-Exim-Version: 4.2.1 (built Wed, 08 May 2019 21:11:16 +0000) X-SA-Exim-Scanned: Yes (on mail.ilande.co.uk) Received-SPF: pass client-ip=2001:41c9:1:41f::167; envelope-from=mark.cave-ayland@ilande.co.uk; helo=mail.ilande.co.uk X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org NetBSD switches directly to IDLE state without switching the shift register to input mode. Duplicate the existing ADB_STATE_IDLE logic in input mode from when the shift register is in output mode which allows the ADB autopoll handler to handle the response. Signed-off-by: Mark Cave-Ayland Reviewed-by: Laurent Vivier --- hw/misc/mac_via.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c index 9f9c2815d0..3c41d6263d 100644 --- a/hw/misc/mac_via.c +++ b/hw/misc/mac_via.c @@ -702,6 +702,12 @@ static void adb_via_send(MOS6522Q800VIA1State *v1s, int state, uint8_t data) break; case ADB_STATE_IDLE: + ms->b |= VIA1B_vADBInt; + adb_autopoll_unblock(adb_bus); + + trace_via1_adb_send("IDLE", data, + (ms->b & VIA1B_vADBInt) ? "+" : "-"); + return; } From patchwork Wed Oct 4 08:38:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Cave-Ayland X-Patchwork-Id: 13408385 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 35292E8FDDA for ; Wed, 4 Oct 2023 08:40:05 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qnxPq-0006Ff-89; Wed, 04 Oct 2023 04:39:34 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxPo-00061Y-KE for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:39:32 -0400 Received: from mail.ilande.co.uk ([2001:41c9:1:41f::167]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxPm-0007k7-OO for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:39:32 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=ilande.co.uk; s=20220518; h=Subject:Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:To:From:Sender:Reply-To:Cc: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=9zLC/uDHsvUmDFmACSVAKRdOeabbtND1MoQn3tvMvYk=; b=NZVmEetjGWcw8fwg0ixjYCiIPL h24AdBsTO0AI3Dm7m5u30SXcjrNi+aOHcgbDYCU+qWnXZ8i+2gc5ShBlNi1ZAoBf84FIduYNQERA+ jqDJcea59yDoIFgvbHVUbIHgb0j6GSxNXPBZkVnYLGYXoLOnRjXX9dovhAbsIpAtBjDe60wuCRL7S f3iHjdj6caF2UnsZd0+Bw4JvxdOhk0eoNVLRmSIXUdCkR57mA6yrj/5m+OYpxIdCYAOX4Yuqm+Xt8 CQAh879HGdZxUksiMnFJM25Ha8AeyZ0Pi9F9/jwcsfb5yiJuBubOlcsnPb5GXAKPoPZaQV86834Qw wkCzYMThSu+D1zL5QqAUupJiSYPh2Pp7LDkIaqOJsoJ9zmQziUv5OCWb45jdW/AAJf6ZvhUGw67xM CymLnStibP8mTRmWLXWZ87PZm9oCT0VXt12hJN1o5PGrGPcks/CTs4Hy8ifzC8NTCkB67sqB18AWg 2rBcnMzQ6nYAmdmP0odU1WPXOcRkB5S6BS1+7Jej5l/09wwG+yBhE+A5DZqgQvpaWiJRLZMK/d69g LLUC4niiOAnNk42d9v6Q8cQ/QNl1FBRqfO4+m+rwsMPLFMz29+lJBaWAU/jIDqaco00PzJ2O6APBo sT79hrYu8+q6SASwIrSsH6PU18MkV5tjj03qURmXI=; Received: from host86-159-123-68.range86-159.btcentralplus.com ([86.159.123.68] helo=localhost.localdomain) by mail.ilande.co.uk with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qnxPR-0006za-Lj; Wed, 04 Oct 2023 09:39:09 +0100 From: Mark Cave-Ayland To: laurent@vivier.eu, qemu-devel@nongnu.org Date: Wed, 4 Oct 2023 09:38:03 +0100 Message-Id: <20231004083806.757242-18-mark.cave-ayland@ilande.co.uk> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> References: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 86.159.123.68 X-SA-Exim-Mail-From: mark.cave-ayland@ilande.co.uk Subject: [PATCH v4 17/20] mac_via: always clear ADB interrupt when switching to A/UX mode X-SA-Exim-Version: 4.2.1 (built Wed, 08 May 2019 21:11:16 +0000) X-SA-Exim-Scanned: Yes (on mail.ilande.co.uk) Received-SPF: pass client-ip=2001:41c9:1:41f::167; envelope-from=mark.cave-ayland@ilande.co.uk; helo=mail.ilande.co.uk X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org When the NetBSD kernel initialises it can leave the ADB interrupt asserted depending upon where in the ADB poll cycle the MacOS ADB interrupt handler is when the NetBSD kernel disables interrupts. The NetBSD ADB driver uses the ADB interrupt state to determine if the ADB is busy and refuses to send ADB commands unless it is clear. To ensure that this doesn't happen, always clear the ADB interrupt when switching to A/UX mode to ensure that the bus enumeration always occurs. Signed-off-by: Mark Cave-Ayland Reviewed-by: Laurent Vivier --- hw/misc/mac_via.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c index 3c41d6263d..500ece5872 100644 --- a/hw/misc/mac_via.c +++ b/hw/misc/mac_via.c @@ -875,6 +875,15 @@ static void via1_auxmode_update(MOS6522Q800VIA1State *v1s) if (irq != oldirq) { trace_via1_auxmode(irq); qemu_set_irq(v1s->auxmode_irq, irq); + + /* + * Clear the ADB interrupt. MacOS can leave VIA1B_vADBInt asserted + * (low) if a poll sequence doesn't complete before NetBSD disables + * interrupts upon boot. Fortunately NetBSD switches to the so-called + * "A/UX" interrupt mode after it initialises, so we can use this as + * a convenient place to clear the ADB interrupt for now. + */ + s->b |= VIA1B_vADBInt; } } From patchwork Wed Oct 4 08:38:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Cave-Ayland X-Patchwork-Id: 13408384 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 94F61E8FDDC for ; Wed, 4 Oct 2023 08:40:04 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qnxQB-0007Kf-KR; Wed, 04 Oct 2023 04:39:55 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxPx-0006q0-5u for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:39:42 -0400 Received: from mail.ilande.co.uk ([2001:41c9:1:41f::167]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxPr-0007kw-62 for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:39:39 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=ilande.co.uk; s=20220518; h=Subject:Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:To:From:Sender:Reply-To:Cc: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=vIBVr7O9C9b85FSdLczRJGzm8rZtijmZ/GEQoWrr164=; b=x2rH3DuDkX2fNihGLbU9SYXaMh cnr5uBRlvkSIfwZoXEbH8sK0KBOaIHExs+bc6MeXrNeXCPtwBu0D+U7DjDNGndZ37EVhudUTArMFs TiQiRrYsWAyqZ9K0d6KHDtKv/nA1yGO1G0ZxMQ+gsgvSj5WrjhikmPy36OnD6NpVDQU7d5Sb0c6sg YyIA1D3kNDkibkJPZIzTlrkDyKKHQCSZExgbo74nKH8t4L2DBuAGWg6L8Q8KaHsefrreRZkOZXyw/ ISCQFNSoEwKsNPQi0uGiufhKZMgKoUOyjmfiVayp1lmkup4vfMXiLbYdxvC4ybyseM+AjMqPlMz9r Z316hzh1pbvBEE7WeBlPabyVRw8f1ELAm7TCvhBffsbbhgI1laXLrXJJ/Iqj8dHYs9wUFXS53z+TF Y/bXJRJyanBvDeDzJ+zYL/ISifKdhUrZMKjcrjYq8H8ZMt4wkOxf+nJqeTMlbqb3hYPhPlEjsxlKW Vy8J5LvqUJNuKc52ZcVDvbIPgf39O+zGzfCRSXGWvla97zc1cRqN10Dwu8pYtKcF3EwzL5wCF/nss 8raSBIPL99hK2fySlptufKdc6teuHOO5JcVuEuHhAOu1uMdDBCQbKh18lqcOET9ZibDwq1SZDOeDg EXUmSOajiSBi2aZ9s11VmpsL6n9JkeR6jWD0rOaTA=; Received: from host86-159-123-68.range86-159.btcentralplus.com ([86.159.123.68] helo=localhost.localdomain) by mail.ilande.co.uk with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qnxPR-0006za-VT; Wed, 04 Oct 2023 09:39:14 +0100 From: Mark Cave-Ayland To: laurent@vivier.eu, qemu-devel@nongnu.org Date: Wed, 4 Oct 2023 09:38:04 +0100 Message-Id: <20231004083806.757242-19-mark.cave-ayland@ilande.co.uk> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> References: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 86.159.123.68 X-SA-Exim-Mail-From: mark.cave-ayland@ilande.co.uk Subject: [PATCH v4 18/20] q800: add ESCC alias at 0xc000 X-SA-Exim-Version: 4.2.1 (built Wed, 08 May 2019 21:11:16 +0000) X-SA-Exim-Scanned: Yes (on mail.ilande.co.uk) Received-SPF: pass client-ip=2001:41c9:1:41f::167; envelope-from=mark.cave-ayland@ilande.co.uk; helo=mail.ilande.co.uk X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Tests on real Q800 hardware show that the ESCC is addressable at multiple locations within the ESCC memory region - at least 0xc000, 0xc020 (as expected by the MacOS toolbox ROM) and 0xc040. All released NetBSD kernels before 10 use the 0xc000 address which causes a fatal error when running the MacOS booter. Add a single memory region alias at 0xc000 to enable NetBSD kernels to start booting under QEMU. Signed-off-by: Mark Cave-Ayland Reviewed-by: Laurent Vivier --- hw/m68k/q800.c | 6 ++++++ include/hw/m68k/q800.h | 1 + 2 files changed, 7 insertions(+) diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c index ac3115d328..27a0b3c08a 100644 --- a/hw/m68k/q800.c +++ b/hw/m68k/q800.c @@ -451,6 +451,12 @@ static void q800_machine_init(MachineState *machine) memory_region_add_subregion(&m->macio, SCC_BASE - IO_BASE, sysbus_mmio_get_region(sysbus, 0)); + /* Create alias for NetBSD */ + memory_region_init_alias(&m->escc_alias, OBJECT(machine), "escc-alias", + sysbus_mmio_get_region(sysbus, 0), 0, 0x8); + memory_region_add_subregion(&m->macio, SCC_BASE - IO_BASE - 0x20, + &m->escc_alias); + /* SCSI */ object_initialize_child(OBJECT(machine), "esp", &m->esp, diff --git a/include/hw/m68k/q800.h b/include/hw/m68k/q800.h index fbaacd88bd..348eaf4703 100644 --- a/include/hw/m68k/q800.h +++ b/include/hw/m68k/q800.h @@ -67,6 +67,7 @@ struct Q800MachineState { MemoryRegion macio; MemoryRegion macio_alias; MemoryRegion machine_id; + MemoryRegion escc_alias; }; #define TYPE_Q800_MACHINE MACHINE_TYPE_NAME("q800") From patchwork Wed Oct 4 08:38:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Cave-Ayland X-Patchwork-Id: 13408387 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0509EE8FDDB for ; Wed, 4 Oct 2023 08:40:35 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qnxQD-0007Zk-Nt; Wed, 04 Oct 2023 04:39:57 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxQ2-0006uy-QE for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:39:51 -0400 Received: from mail.ilande.co.uk ([2001:41c9:1:41f::167]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxPr-0007l3-JB for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:39:45 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=ilande.co.uk; s=20220518; h=Subject:Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:To:From:Sender:Reply-To:Cc: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=LDAnj05b9ISTPE8LDHJnawABkQ9209MrO7Qu4Ieiarw=; b=iOpiCZzSL+XjsYFnREPp7dVGhV 5bIm/Sw0plCsNvDEGMgY52B2ZLVaCVeuwcUvNP2u3WIWSSDFD9Bk27nbTiqlZIMqRyKX3tUjMmM6v DD4Q08Ku07BbeQtTAklVVFMUFlVIdIhR2BBw6y+KFSoz63Zx/vcXJOe7TNtkSfMbtcYVA393aUPWG z64OqOheQxk6vh0JbXdsvB8kAhJF3opTAV+Ko9wAaURaMmP4KBUIUafF8mzFE/5mVLKhIbIMKqC4C SOJo7lPOKgzwnS9K0kEFmb4wgx59PBzsJX9Yyrn3fsQnJicXcda9t3wgvru4mP13f3/3uO/+ViqXP ya80TYGftG9BewuqR1W7XJHlEe7nLACEGJq9TIZ8YLQQashtbNUfFKkJLTDW5cNL1d8WUiVfGoM+U 2mS0cWpYHBkVib4xfwOL3h+Ey20keWyu3Rs6MBBWRFC4B4ysyIeU9OMm0l+deinPMhL5+I/eEY+hc cwbfcKJoJdPCep5b3rBOYjRup+Wjn87vZHoET/LjVdYUUyZa1I8Vp8H3ZyqMFybzaOO2GZwpsfHgK 9BXgtLCvVR73MQRxA6E6S8T/Xn/U+B81mS9x/FbXPxAl/53WbHcDHFqfNujTxI8Wgzft7z+Gh3uxD v16J0p+lSmxL/0qlRGfOQpZ7vf1+41x7dCauh1UYg=; Received: from host86-159-123-68.range86-159.btcentralplus.com ([86.159.123.68] helo=localhost.localdomain) by mail.ilande.co.uk with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qnxPW-0006za-4u; Wed, 04 Oct 2023 09:39:14 +0100 From: Mark Cave-Ayland To: laurent@vivier.eu, qemu-devel@nongnu.org Date: Wed, 4 Oct 2023 09:38:05 +0100 Message-Id: <20231004083806.757242-20-mark.cave-ayland@ilande.co.uk> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> References: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 86.159.123.68 X-SA-Exim-Mail-From: mark.cave-ayland@ilande.co.uk Subject: [PATCH v4 19/20] q800: add alias for MacOS toolbox ROM at 0x40000000 X-SA-Exim-Version: 4.2.1 (built Wed, 08 May 2019 21:11:16 +0000) X-SA-Exim-Scanned: Yes (on mail.ilande.co.uk) Received-SPF: pass client-ip=2001:41c9:1:41f::167; envelope-from=mark.cave-ayland@ilande.co.uk; helo=mail.ilande.co.uk X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_PASS=-0.001, T_SPF_HELO_TEMPERROR=0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org According to the Apple Quadra 800 Developer Note document, the Quadra 800 ROM consists of 2 ROM code sections based at offsets 0x0 and 0x800000. A/UX attempts to access the toolbox ROM at the lower offset during startup, so provide a memory alias to allow the access to succeed. Signed-off-by: Mark Cave-Ayland Reviewed-by: Laurent Vivier --- hw/m68k/q800.c | 5 +++++ include/hw/m68k/q800.h | 1 + 2 files changed, 6 insertions(+) diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c index 27a0b3c08a..1d7cd5ff1c 100644 --- a/hw/m68k/q800.c +++ b/hw/m68k/q800.c @@ -660,6 +660,11 @@ static void q800_machine_init(MachineState *machine) filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); memory_region_add_subregion(get_system_memory(), MACROM_ADDR, &m->rom); + memory_region_init_alias(&m->rom_alias, NULL, "m68k_mac.rom-alias", + &m->rom, 0, MACROM_SIZE); + memory_region_add_subregion(get_system_memory(), 0x40000000, + &m->rom_alias); + /* Load MacROM binary */ if (filename) { bios_size = load_image_targphys(filename, MACROM_ADDR, MACROM_SIZE); diff --git a/include/hw/m68k/q800.h b/include/hw/m68k/q800.h index 348eaf4703..a9661f65f6 100644 --- a/include/hw/m68k/q800.h +++ b/include/hw/m68k/q800.h @@ -50,6 +50,7 @@ struct Q800MachineState { bool easc; M68kCPU cpu; MemoryRegion rom; + MemoryRegion rom_alias; GLUEState glue; MOS6522Q800VIA1State via1; MOS6522Q800VIA2State via2; From patchwork Wed Oct 4 08:38:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Cave-Ayland X-Patchwork-Id: 13408383 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 2597DE8FDDB for ; Wed, 4 Oct 2023 08:40:04 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qnxQF-0007pa-CK; Wed, 04 Oct 2023 04:39:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxQ2-0006v5-QP for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:39:51 -0400 Received: from mail.ilande.co.uk ([2001:41c9:1:41f::167]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qnxPr-0007lU-Uf for qemu-devel@nongnu.org; Wed, 04 Oct 2023 04:39:46 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=ilande.co.uk; s=20220518; h=Subject:Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:To:From:Sender:Reply-To:Cc: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=ceP4YhNUPMLYSAHn4R7ae6JZr9zikMQNDBraYKRwoQY=; b=gUm0mAkHdWdepsv3cjkHLE0Oao i4RXd24xE4YRo8g0gY7kff8/LpoyP1I3np1gGH0gVqWNbRwTNma/DRZezXHVuIMYJo4CL1eFRcYlb MScZnAtPPaeYRi5B1PlgEytP/I+3LmTDYZ2FY//2tFAijaYvE0nuZNApxX7ceLTbwV1NtUx1upcI5 BYmphCdoYxupkBjGyPVP65LRBkIl3+FqcgNA/2Vu5fr6U12rqDIWShlzQD+woIOT0VAXmdUAwVVXW ibYSpwGSU8qUz+VyP8BOC2kRBiaNpYZayPTQZt4Tpc+2M+A+RuL51ek6opn+gl2vE81oQgAeahwiY Niez5p7Pa5HC34b3VT6u6Ri5nh2dCsYB1XGyQDyjSpjkPVtW+R8GvjlPSso0Hs1F7ESm3sWl+nlHZ o3/Q7t6k4Lk7VHQOw3vtKflSgzodr3DToBYpc2gf3cjupqFXtKabF8cF0wqq8AJXuZmObLzumAXks gT2QZWpPLNidiXrEUnkffX0l13yvUeHvaY5J3CdfILUwSnAJ3rW+CmqqyfNs+N8FkDocvSwxBmJoG xbLCC22WXu7a+Vfj56d8dz+cPGBc2XF0nN/DxSYSbcrYVQDrpXU7+mOmkA97QXsE2dIXc97N7BQ21 4/PTAl8R2d1pycNyITG3hTqpnUYMq0PkUMNrhQOq0=; Received: from host86-159-123-68.range86-159.btcentralplus.com ([86.159.123.68] helo=localhost.localdomain) by mail.ilande.co.uk with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qnxPW-0006za-S3; Wed, 04 Oct 2023 09:39:15 +0100 From: Mark Cave-Ayland To: laurent@vivier.eu, qemu-devel@nongnu.org Date: Wed, 4 Oct 2023 09:38:06 +0100 Message-Id: <20231004083806.757242-21-mark.cave-ayland@ilande.co.uk> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> References: <20231004083806.757242-1-mark.cave-ayland@ilande.co.uk> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 86.159.123.68 X-SA-Exim-Mail-From: mark.cave-ayland@ilande.co.uk Subject: [PATCH v4 20/20] mac_via: extend timer calibration hack to work with A/UX X-SA-Exim-Version: 4.2.1 (built Wed, 08 May 2019 21:11:16 +0000) X-SA-Exim-Scanned: Yes (on mail.ilande.co.uk) Received-SPF: pass client-ip=2001:41c9:1:41f::167; envelope-from=mark.cave-ayland@ilande.co.uk; helo=mail.ilande.co.uk X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_PASS=-0.001, T_SPF_HELO_TEMPERROR=0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org The A/UX timer calibration loop runs continuously until 2 consecutive iterations differ by at least 0x492 timer ticks. Modern hosts execute the timer calibration loop so fast that this situation never occurs causing a hang on boot. Use a similar method to Shoebill which is to randomly add 0x500 to the T2 counter value during calibration to enable it to eventually succeed. Signed-off-by: Mark Cave-Ayland Reviewed-by: Laurent Vivier --- hw/misc/mac_via.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c index 500ece5872..b6206ef73c 100644 --- a/hw/misc/mac_via.c +++ b/hw/misc/mac_via.c @@ -983,6 +983,44 @@ static void via1_timer_calibration_hack(MOS6522Q800VIA1State *v1s, int addr, /* Looks like there has been a reset? */ v1s->timer_hack_state = 1; } + + if (addr == VIA_REG_T2CL && val == 0xf0) { + /* VIA_REG_T2CL: low byte of counter (A/UX) */ + v1s->timer_hack_state = 5; + } + break; + case 5: + if (addr == VIA_REG_T2CH && val == 0x3c) { + /* + * VIA_REG_T2CH: high byte of counter (A/UX). We are now extremely + * likely to be in the A/UX timer calibration routine, so move to + * the next state where we enable the calibration hack. + */ + v1s->timer_hack_state = 6; + } else if ((addr == VIA_REG_IER && val == 0x20) || + addr == VIA_REG_T2CH) { + /* We're doing something else with the timer, not calibration */ + v1s->timer_hack_state = 0; + } + break; + case 6: + if ((addr == VIA_REG_IER && val == 0x20) || addr == VIA_REG_T2CH) { + /* End of A/UX timer calibration routine, or another write */ + v1s->timer_hack_state = 7; + } else { + v1s->timer_hack_state = 0; + } + break; + case 7: + /* + * This is the normal post-calibration timer state once both the + * MacOS toolbox and A/UX have been calibrated, until we see a write + * to VIA_REG_PCR to suggest a reset + */ + if (addr == VIA_REG_PCR && val == 0x22) { + /* Looks like there has been a reset? */ + v1s->timer_hack_state = 1; + } break; default: g_assert_not_reached(); @@ -998,6 +1036,7 @@ static uint64_t mos6522_q800_via1_read(void *opaque, hwaddr addr, unsigned size) MOS6522Q800VIA1State *s = MOS6522_Q800_VIA1(opaque); MOS6522State *ms = MOS6522(s); uint64_t ret; + int64_t now; addr = (addr >> 9) & 0xf; ret = mos6522_read(ms, addr, size); @@ -1007,6 +1046,23 @@ static uint64_t mos6522_q800_via1_read(void *opaque, hwaddr addr, unsigned size) /* Quadra 800 Id */ ret = (ret & ~VIA1A_CPUID_MASK) | VIA1A_CPUID_Q800; break; + case VIA_REG_T2CH: + if (s->timer_hack_state == 6) { + /* + * The A/UX timer calibration loop runs continuously until 2 + * consecutive iterations differ by at least 0x492 timer ticks. + * Modern hosts execute the timer calibration loop so fast that + * this situation never occurs causing a hang on boot. Use a + * similar method to Shoebill which is to randomly add 0x500 to + * the T2 counter value during calibration to enable it to + * eventually succeed. + */ + now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + if (now & 1) { + ret += 0x5; + } + } + break; } return ret; }