From nobody Sat Sep 26 20:50:17 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=kernel.org ARC-Seal: i=1; a=rsa-sha256; t=1789680901; cv=none; d=zohomail.com; s=zohoarc; b=mR2CXNpqCUTzDT56f+mp9CT42viPZ4JF4xUntN4RULWXNewVjrnzdgDgkoyppEcOmqVFOSiD2TW9FzNK3JClQ3Qj4IBj4wlSzaRZZkTArGEiGQGBMcyeO5HyHyo0d/zCNtLeS7NaLZFeKwIrpw+kzJQSuYXYY4dVcZfDlcTGtyc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1789680901; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=fQRmR9lE14wGY1FrTI9fM5TiOsIeYq4zXoFKivHzOKQ=; b=YBUxsIjpbrNei2U3Da8FWeAfqLhAw4PnsIQi+eqUsv88rU1+15Xfoal5vOFrjM6bMgBusR4qrJSFjXTztVmAFnh5toIU5oxE35XOf3WYVnUAsHGRC9TV0iUqpz6bfNNLmHR1+TtccbOE9NDVrGvY7/bOrr71LWtjYa2KqCu5bcI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1789680900922116.84805428058223; Thu, 17 Sep 2026 14:35:00 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x7JkS-0007x3-8D; Thu, 17 Sep 2026 17:34:29 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x7JkN-0007vy-8a; Thu, 17 Sep 2026 17:34:23 -0400 Received: from sea.source.kernel.org ([2600:3c0a:e001:78e:0:1991:8:25]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x7JkI-0005uy-HN; Thu, 17 Sep 2026 17:34:22 -0400 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by sea.source.kernel.org (Postfix) with ESMTP id 02B1043E36; Thu, 17 Sep 2026 21:34:09 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0CF471F000FF; Thu, 17 Sep 2026 21:34:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1789680848; bh=fQRmR9lE14wGY1FrTI9fM5TiOsIeYq4zXoFKivHzOKQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=WFwYejFgfj7FLR0LxaZoJASoJ28lF9kLMEiRaNo1MiquKidekzGwP1nqv7DYuLE7z H65/dhvKQ1L8s6iLWzTQJxZRML+rO2lMPFrIiOf7szrOLI+RMCVPAXuUpF4URvAtMx JLOOQ13Rr9S76NyRG5MAlPqfoTBgBfolAIGOcsES/8v31pjSHxXjqsASKrMKK/y+vF MYkVJZxv42fBycCR0gPtlpjFwpfSwWjSA4QZlqnO5Y1PvOR7qGvGYZ5KAvt1fOdK44 H4hswz2PQWH3AUaRnTrefSf0s35fHZv6eXI7R+3j3KsacgvLsXWjtMHLSES4+Gztir iIPBy3pjd1k3w== From: Helge Deller To: qemu-devel@nongnu.org Cc: "Michael S. Tsirkin" , "Denis V. Lunev" , Helge Deller , John Snow , Richard Henderson , Paolo Bonzini , Abizer Lokhandwala , qemu-block@nongnu.org Subject: [PATCH 1/7] hw/pci/pci_ids: Add PCI vendor ID and IDs for NS chips Date: Thu, 17 Sep 2026 23:33:54 +0200 Message-ID: <20260917213402.3127-2-deller@kernel.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260917213402.3127-1-deller@kernel.org> References: <20260917213402.3127-1-deller@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2600:3c0a:e001:78e:0:1991:8:25; envelope-from=deller@kernel.org; helo=sea.source.kernel.org 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, DKIMWL_WL_HIGH=-0.001, 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: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @kernel.org) X-ZM-MESSAGEID: 1789680902941158500 Content-Type: text/plain; charset="utf-8" From: Helge Deller Some HP B- and C-class workstations used a PCI SuperIO chip from National Semiconductor for USB, serial, parallel and FDC. Add the relevant PCI IDs, = so that the QEMU driver can reuse the constants. Signed-off-by: Helge Deller --- include/hw/pci/pci_ids.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h index 16034aaa2c..477609ed62 100644 --- a/include/hw/pci/pci_ids.h +++ b/include/hw/pci/pci_ids.h @@ -168,6 +168,11 @@ #define PCI_DEVICE_ID_LSI_SAS1078 0x0060 #define PCI_DEVICE_ID_LSI_SAS0079 0x0079 =20 +#define PCI_VENDOR_ID_NS 0x100b +#define PCI_DEVICE_ID_NS_87415 0x0002 +#define PCI_DEVICE_ID_NS_87560_LIO 0x000e +#define PCI_DEVICE_ID_NS_87560_USB 0x0012 + #define PCI_VENDOR_ID_DEC 0x1011 #define PCI_DEVICE_ID_DEC_21143 0x0019 =20 --=20 2.54.0 From nobody Sat Sep 26 20:50:17 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=kernel.org ARC-Seal: i=1; a=rsa-sha256; t=1789680957; cv=none; d=zohomail.com; s=zohoarc; b=NSxnc5h1KE4/NLAJXwK9GyRmryZxqfLofMiISTgH2H/4QvuK3yyfH5DjHB1ScmJxs6lR6VIM2Cpy1opwQfHWB/3LXdFYt9Gx05Gw3qanz6tLvW4WrJc4vJ06WSz6AufB4s8s/vHEQdZVbUU2e5ez8s+1iJgC/GrYm8ry09/Sw1U= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1789680957; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=5O+/PRbJzzGFw9iphMcokzo5Gqr6sF1QivbA4bJcFUc=; b=BvKziuJ498P0L8I5rCdFCk1C3Uj2U2cysWOjdcKBiQn4jPAdYlM9dYFBnbFHEDty0aKpDXg7EEDZa7EPUWng6ifyLHlFIRgh+oSg8OGmlWNcBBDaRYPNZcrI8c93WG/6v5azUwzV3W3KnGgHUNx7wSfqz168H63qyIaC3G7YYwo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1789680957601384.3279863900914; Thu, 17 Sep 2026 14:35:57 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x7JkY-0007yI-2L; Thu, 17 Sep 2026 17:34:34 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x7JkS-0007xC-4Q; Thu, 17 Sep 2026 17:34:28 -0400 Received: from sea.source.kernel.org ([2600:3c0a:e001:78e:0:1991:8:25]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x7JkM-0005vC-QC; Thu, 17 Sep 2026 17:34:27 -0400 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by sea.source.kernel.org (Postfix) with ESMTP id 4A78143FD1; Thu, 17 Sep 2026 21:34:11 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5337F1F000FF; Thu, 17 Sep 2026 21:34:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1789680851; bh=5O+/PRbJzzGFw9iphMcokzo5Gqr6sF1QivbA4bJcFUc=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=B1v7lsGyktoveCzwbvvRbA2XhhfTekKQXuTeN0knGg2ndHwRup2PUS+Cm252jMN7F 8+C8CtCk8eU2UpBTpeZttDmshykfmEhMBIdJ+RN1YfE+BaVX/Ir3claNlALOGiWbuG u4YqegAcqKiD1fpH8WenrWAVLSkFIaZToiGxdmntpPr+ibs9r905BimvaxWXFYYzyS tg0l2UzmkRhbHtryLi+353xpDldzT8j41Y/FR4ODNDUpxNPsVONm5qeXEfWGCn0CLC nBEpggY85n01eK4uJOHIKvA5vg7CuvlgvtK3LmyBGRgrov0/Sj/3xBp+uBbPET4Klw DlUVV8oSFvpcw== From: Helge Deller To: qemu-devel@nongnu.org Cc: "Michael S. Tsirkin" , "Denis V. Lunev" , Helge Deller , John Snow , Richard Henderson , Paolo Bonzini , Abizer Lokhandwala , qemu-block@nongnu.org Subject: [PATCH 2/7] hw/isa/pc87560: Add main isa code for NS 87560 SuperIO chip Date: Thu, 17 Sep 2026 23:33:55 +0200 Message-ID: <20260917213402.3127-3-deller@kernel.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260917213402.3127-1-deller@kernel.org> References: <20260917213402.3127-1-deller@kernel.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2600:3c0a:e001:78e:0:1991:8:25; envelope-from=deller@kernel.org; helo=sea.source.kernel.org 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, DKIMWL_WL_HIGH=-0.001, 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: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @kernel.org) X-ZM-MESSAGEID: 1789680958955158500 From: Abizer Lokhandwala Add emulation of the core components (PCI function 1 aka I/O Peripherals) of the National Semiconductor SuperIO chip which was commonly used in HP PA-RISC B- and C-class workstations. This includes the PIC interrupt controller, the floppy controller, serial and parallel ports. Signed-off-by: Abizer Lokhandwala Signed-off-by: Helge Deller --- MAINTAINERS | 2 + hw/isa/Kconfig | 11 + hw/isa/pc87560.c | 510 +++++++++++++++++++++++++++++++++++++++ include/hw/isa/pc87560.h | 96 ++++++++ 4 files changed, 619 insertions(+) create mode 100644 hw/isa/pc87560.c create mode 100644 include/hw/isa/pc87560.h diff --git a/MAINTAINERS b/MAINTAINERS index e9b68c51f1..e3b1e80ad6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1355,6 +1355,8 @@ F: include/hw/pci-host/dino.h F: pc-bios/hppa-firmware.img F: roms/seabios-hppa/ F: tests/functional/hppa/ +F: hw/isa/pc87560.c +F: include/hw/isa/pc87560.h =20 Hexagon Machines ---------------- diff --git a/hw/isa/Kconfig b/hw/isa/Kconfig index 73c6470805..23d327e88c 100644 --- a/hw/isa/Kconfig +++ b/hw/isa/Kconfig @@ -67,6 +67,17 @@ config SMC37C669 bool select ISA_SUPERIO =20 +config PC87560 + bool + default y if PCI_DEVICES + depends on PCI + depends on HPPA + select ISA_BUS + select FDC_ISA + select SERIAL_ISA + select IDE_PCI + select USB_OHCI + config LPC_ICH9 bool # For historical reasons, SuperIO devices are created in the board diff --git a/hw/isa/pc87560.c b/hw/isa/pc87560.c new file mode 100644 index 0000000000..c13c54deb2 --- /dev/null +++ b/hw/isa/pc87560.c @@ -0,0 +1,510 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * NS PC87560 SuperI/O =E2=80=94 ISA emulation + * + * Copyright (c) 2026 Abizer abizerlokhandwalastd10@gmail.com + */ +#include "qemu/osdep.h" +#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" +#include "qapi/error.h" +#include "qemu/log.h" +#include "migration/vmstate.h" +#include "qemu/module.h" +#include "hw/core/irq.h" +#include "hw/core/qdev-properties.h" +#include "hw/core/qdev-properties-system.h" +#include "hw/char/serial.h" +#include "hw/char/parallel.h" +#include "hw/block/fdc-internal.h" +#include "hw/isa/pc87560.h" + +static uint64_t pc87560_pp_read(void *opaque, hwaddr addr, unsigned size) +{ + ParallelState *s =3D opaque; + switch (addr) { + case 0: return s->datar; + case 1: return s->status; + case 2: return s->control; + default: + qemu_log_mask(LOG_UNIMP, + "pc87560-pp: read offset 0x%" HWADDR_PRIx "\n", add= r); + return 0xFF; + } +} + +static int pic_highest_priority(int priority_base, uint8_t mask) +{ + int i; + for (i =3D 1; i <=3D 8; i++) { + int irq =3D (priority_base + i) & 7; + if (mask & (1 << irq)) { + return irq; + } + } + return -1; +} + +static void pic_update_irq(PC87560SuperioState *s) +{ + int base =3D s->pic.priority_base; + int first_irr =3D pic_highest_priority(base, s->pic.irr & ~s->pic.imr); + int first_isr =3D pic_highest_priority(base, s->pic.isr); + int pending =3D 0; + + if (first_irr !=3D -1) { + if (first_isr =3D=3D -1) { + pending =3D 1; + } else if (first_irr !=3D first_isr) { + int irr_lvl =3D (first_irr - s->pic.priority_base - 1) & 7; + int isr_lvl =3D (first_isr - s->pic.priority_base - 1) & 7; + if (irr_lvl < isr_lvl) { + pending =3D 1; + } + } + } + + if (pending !=3D s->pic.irq_level) { + s->pic.irq_level =3D pending; + qemu_set_irq(s->parent_irq, pending); + } +} + +static uint64_t pic1_read(void *opaque, hwaddr addr, unsigned size) +{ + PC87560SuperioState *s =3D opaque; + if (addr =3D=3D 0) { + if (s->pic.poll_mode) { + s->pic.poll_mode =3D false; + uint8_t pending_mask =3D s->pic.irr & ~s->pic.imr; + int irq =3D pic_highest_priority(s->pic.priority_base, pending= _mask); + if (irq =3D=3D -1) { + pic_update_irq(s); + return 0x00; + } + s->pic.isr |=3D (1 << irq); + pic_update_irq(s); + return 0x80 | irq; + } + return s->pic.read_isr ? s->pic.isr : s->pic.irr; + } + return s->pic.imr; +} + +static void pic1_write(void *opaque, hwaddr addr, uint64_t val, unsigned s= ize) +{ + PC87560SuperioState *s =3D opaque; + uint8_t v =3D (uint8_t)val; + + if (addr =3D=3D 1) { + if (s->pic.init_phase > 0) { + if (s->pic.init_phase =3D=3D 3) { + s->pic.init_phase =3D 0; + } else { + s->pic.init_phase++; + } + } else { + s->pic.imr =3D v; + pic_update_irq(s); + } + return; + } + + if (v & 0x10) { + s->pic.init_phase =3D 1; + s->pic.imr =3D 0xFF; + s->pic.irr =3D 0; + s->pic.isr =3D 0; + s->pic.poll_mode =3D false; + s->pic.priority_base =3D 7; + } else if (v & 0x08) { + if (v & 0x04) { + s->pic.poll_mode =3D true; + } + if (v & 0x02) { + s->pic.read_isr =3D (v & 0x01); + } + } else { + uint8_t cmd =3D (v >> 5) & 0x07; + uint8_t irq =3D v & 0x07; + switch (cmd) { + case 1: + case 5: { + int serviced =3D pic_highest_priority(s->pic.priority_base, + s->pic.isr); + if (serviced !=3D -1) { + s->pic.isr &=3D ~(1 << serviced); + if (cmd =3D=3D 5) { + s->pic.priority_base =3D serviced; + } + } + break; + } + case 3: + case 7: + s->pic.isr &=3D ~(1 << irq); + if (cmd =3D=3D 7) { + s->pic.priority_base =3D irq; + } + break; + case 6: + s->pic.priority_base =3D irq; + break; + } + pic_update_irq(s); + } +} + +static const MemoryRegionOps pc87560_pic1_ops =3D { + .read =3D pic1_read, + .write =3D pic1_write, + .endianness =3D DEVICE_LITTLE_ENDIAN, + .valid.min_access_size =3D 1, + .valid.max_access_size =3D 1, +}; + +static void pc87560_pic_irq_in(void *opaque, int irq_n, int level) +{ + PC87560SuperioState *s =3D opaque; + if (level) { + s->pic.irr |=3D (1 << irq_n); + } else { + s->pic.irr &=3D ~(1 << irq_n); + } + pic_update_irq(s); +} + + +static void pc87560_pp_write(void *opaque, hwaddr addr, uint64_t val, + unsigned size) +{ + ParallelState *s =3D opaque; + switch (addr) { + case 0: + s->dataw =3D (uint8_t)val; + if (qemu_chr_fe_backend_connected(&s->chr)) { + unsigned char ch =3D (uint8_t)val; + qemu_chr_fe_write_all(&s->chr, &ch, 1); + } + break; + case 2: + s->control =3D (uint8_t)(val & 0x1F); + if (!(s->control & 0x10)) { + qemu_irq_lower(s->irq); + } + break; + default: + qemu_log_mask(LOG_UNIMP, + "pc87560-pp: write offset 0x%" HWADDR_PRIx "\n", addr); + } +} +static const MemoryRegionOps pc87560_pp_ops =3D { + .read =3D pc87560_pp_read, + .write =3D pc87560_pp_write, + .endianness =3D DEVICE_LITTLE_ENDIAN, + .valid.min_access_size =3D 1, + .valid.max_access_size =3D 1, +}; + +/* + * Some features on the chip are disabled by default. If a guest + * reads or writes one of those registers, respond via this stub + * instead of faulting. + */ +static uint64_t pc87560_stub_read(void *opaque, hwaddr addr, unsigned size) +{ + qemu_log_mask(LOG_UNIMP, + "pc87560-superio: stub read 0x%" HWADDR_PRIx "\n", addr= ); + return 0xFF; +} +static void pc87560_stub_write(void *opaque, hwaddr addr, uint64_t val, + unsigned size) +{ + qemu_log_mask(LOG_UNIMP, + "pc87560-superio: stub write 0x%" HWADDR_PRIx + " =3D 0x%" PRIx64 "\n", addr, val); +} + +static const MemoryRegionOps pc87560_stub_ops =3D { + .read =3D pc87560_stub_read, + .write =3D pc87560_stub_write, + .endianness =3D DEVICE_LITTLE_ENDIAN, +}; + + +static uint64_t pc87560_fdc_read(void *opaque, hwaddr addr, unsigned size) +{ + return fdctrl_read(opaque, (uint32_t)addr); +} + +static void pc87560_fdc_write(void *opaque, hwaddr addr, uint64_t val, + unsigned size) +{ + fdctrl_write(opaque, (uint32_t)addr, (uint32_t)val); +} + +static const MemoryRegionOps pc87560_fdc_ops =3D { + .read =3D pc87560_fdc_read, + .write =3D pc87560_fdc_write, + .endianness =3D DEVICE_LITTLE_ENDIAN, + .valid.min_access_size =3D 1, + .valid.max_access_size =3D 1, +}; + +static void pc87560_map_region(PC87560SuperioState *s, MemoryRegion *mr, + bool *mapped, hwaddr base) +{ + MemoryRegion *io =3D pci_address_space_io(PCI_DEVICE(s)); + if (*mapped) { + memory_region_del_subregion(io, mr); + *mapped =3D false; + } + if (base) { + memory_region_add_subregion(io, base, mr); + *mapped =3D true; + } +} + +static void pc87560_apply_funcen(PC87560SuperioState *s) +{ + PCIDevice *pci =3D PCI_DEVICE(s); + uint16_t en =3D pci_get_word(pci->config + REG_FUNCEN); + + pc87560_map_region(s, &s->fdc_io, &s->fdc_mapped, (en & FUNCEN_FDC) + ? (pci_get_long(pci->config + REG_FDCBAR) & ~(hwaddr)0x7) : 0); + + pc87560_map_region(s, &s->sp1_io, &s->sp1_mapped, (en & FUNCEN_SP1) + ? (pci_get_long(pci->config + REG_SP1BAR) & ~(hwaddr)0x7) : 0); + + pc87560_map_region(s, &s->sp2_io, &s->sp2_mapped, (en & FUNCEN_SP2) + ? (pci_get_long(pci->config + REG_SP2BAR) & ~(hwaddr)0x7) : 0); + + pc87560_map_region(s, &s->pp_io, &s->pp_mapped, (en & FUNCEN_PP) + ? (pci_get_long(pci->config + REG_PPBAR) & ~(hwaddr)0x7) : 0); + + pc87560_map_region(s, &s->kbc_io, &s->kbc_mapped, (en & FUNCEN_KBC) + ? (pci_get_long(pci->config + REG_KBCBAR) & ~(hwaddr)0x7) : 0); +} + +static void pc87560_superio_config_write(PCIDevice *pci, + uint32_t addr, uint32_t val, int = len) +{ + PC87560SuperioState *s =3D PC87560_Superio(pci); + uint16_t funcen; + + pci_default_write_config(pci, addr, val, len); + funcen =3D pci_get_word(pci->config + REG_FUNCEN); + + if (ranges_overlap(addr, len, REG_FUNCEN, 2)) { + pc87560_apply_funcen(s); + } + + if (ranges_overlap(addr, len, REG_FDCBAR, 4)) { + if (funcen & FUNCEN_FDC) { + pc87560_map_region(s, &s->fdc_io, &s->fdc_mapped, + pci_get_long(pci->config + REG_FDCBAR) & ~(hwaddr)0x7); + } + } + + if (ranges_overlap(addr, len, REG_SP1BAR, 4)) { + if (funcen & FUNCEN_SP1) { + pc87560_map_region(s, &s->sp1_io, &s->sp1_mapped, + pci_get_long(pci->config + REG_SP1BAR) & ~(hwaddr)0x7); + } + } + + if (ranges_overlap(addr, len, REG_SP2BAR, 4)) { + if (funcen & FUNCEN_SP2) { + pc87560_map_region(s, &s->sp2_io, &s->sp2_mapped, + pci_get_long(pci->config + REG_SP2BAR) & ~(hwaddr)0x7); + } + } + + if (ranges_overlap(addr, len, REG_PPBAR, 4)) { + if (funcen & FUNCEN_PP) { + pc87560_map_region(s, &s->pp_io, &s->pp_mapped, + pci_get_long(pci->config + REG_PPBAR) & ~(hwaddr)0x7); + } + } + + if (ranges_overlap(addr, len, REG_KBCBAR, 4)) { + if (funcen & FUNCEN_KBC) { + pc87560_map_region(s, &s->kbc_io, &s->kbc_mapped, + pci_get_long(pci->config + REG_KBCBAR) & ~(hwaddr)0x7); + } + } + + if (ranges_overlap(addr, len, REG_ACPIBAR, 4)) { + uint32_t ab =3D pci_get_long(pci->config + REG_ACPIBAR); + pc87560_map_region(s, &s->acpi_io, &s->acpi_mapped, + (ab & 1) ? (ab & ~(hwaddr)0x1F) : 0); + } + + if (ranges_overlap(addr, len, REG_PMBAR, 4)) { + uint32_t pb =3D pci_get_long(pci->config + REG_PMBAR); + pc87560_map_region(s, &s->pm_io, &s->pm_mapped, + (pb & 1) ? (pb & ~(hwaddr)0xFF) : 0); + } + + if (ranges_overlap(addr, len, REG_RSVD_CFG, 1)) { + if ((pci->config[REG_RSVD_CFG] & 0x0F) !=3D 0x01) { + qemu_log_mask(LOG_GUEST_ERROR, + "pc87560-superio: offset 0x7E bits[3:0] must be 0x01\n"); + } + } +} + +static void pc87560_superio_realize(PCIDevice *pci, Error **errp) +{ + PC87560SuperioState *s =3D PC87560_Superio(pci); + MemoryRegion *io =3D pci_address_space_io(pci); + + pci_set_word(pci->config + REG_FUNCEN, FUNCEN_DEFAULT); + pci->config[REG_RSVD_CFG] =3D 0x01; + pci->config[REG_DMA_ROUTE1] =3D 0x67; + pci->config[REG_PPDID] =3D 0x10; + + pci_set_long(pci->config + REG_KBCBAR, 0x00000060); /* not usable */ + pci_set_long(pci->config + REG_ACPIBAR, 0x00004001); + pci_set_long(pci->config + REG_PMBAR, 0xFFFFFF01); + pci_set_long(pci->config + REG_FDCBAR, 0x000003F0); /* not usable */ + pci_set_long(pci->config + REG_SP1BAR, 0x000003F8); + pci_set_long(pci->config + REG_SP2BAR, 0x000002F8); + pci_set_long(pci->config + REG_PPBAR, 0x00000378); + + + pci_set_long(pci->wmask + REG_KBCBAR, 0xFFFFFFF8); /* not usable */ + pci_set_long(pci->wmask + REG_ACPIBAR, 0xFFFFFFE1); + pci_set_long(pci->wmask + REG_PMBAR, 0xFFFFFF01); + pci_set_long(pci->wmask + REG_FDCBAR, 0xFFFFFFF8); /* not usable */ + pci_set_long(pci->wmask + REG_SP1BAR, 0xFFFFFFF8); + pci_set_long(pci->wmask + REG_SP2BAR, 0xFFFFFFF8); + pci_set_long(pci->wmask + REG_PPBAR, 0xFFFFFFF8); + + pci->config[PCI_INTERRUPT_PIN] =3D 0x01; + + qdev_init_gpio_out_named(DEVICE(pci), &s->parent_irq, "pic-out", 1); + qdev_init_gpio_in_named(DEVICE(pci), pc87560_pic_irq_in, "pic-irq", 8); + + memory_region_init_io(&s->pic1_io, OBJECT(s), &pc87560_pic1_ops, + s, "pc87560-pic1", 2); + memory_region_add_subregion(io, IC_PIC1, &s->pic1_io); + + s->serial[0].irq =3D qemu_allocate_irq(pc87560_pic_irq_in, s, 3); + if (!qdev_realize(DEVICE(&s->serial[0]), NULL, errp)) { + return; + } + memory_region_init_io(&s->sp1_io, OBJECT(s), &serial_io_ops, + &s->serial[0], "pc87560-sp1", 8); + memory_region_add_subregion(io, 0x3F8, &s->sp1_io); + s->sp1_mapped =3D true; + + s->serial[1].irq =3D qemu_allocate_irq(pc87560_pic_irq_in, s, 4); + if (!qdev_realize(DEVICE(&s->serial[1]), NULL, errp)) { + return; + } + memory_region_init_io(&s->sp2_io, OBJECT(s), &serial_io_ops, + &s->serial[1], "pc87560-sp2", 8); + memory_region_add_subregion(io, 0x2F8, &s->sp2_io); + s->sp2_mapped =3D true; + + s->pp.irq =3D qemu_allocate_irq(pc87560_pic_irq_in, s, 5); + memory_region_init_io(&s->pp_io, OBJECT(s), &pc87560_pp_ops, + &s->pp, "pc87560-pp", 8); + memory_region_add_subregion(io, 0x378, &s->pp_io); + s->pp_mapped =3D true; + s->pic.irq_level =3D -1; + s->pic.priority_base =3D 7; + s->fdc.irq =3D qemu_allocate_irq(pc87560_pic_irq_in, s, 6); + s->fdc.dma_chann =3D -1; + s->fdc.dma =3D NULL; + s->fdc.fallback =3D FLOPPY_DRIVE_TYPE_144; + fdctrl_realize_common(DEVICE(pci), &s->fdc, errp); + if (*errp) { + return; + } + memory_region_init_io(&s->fdc_io, OBJECT(s), &pc87560_fdc_ops, + &s->fdc, "pc87560-fdc", 8); + memory_region_add_subregion(io, 0x3F0, &s->fdc_io); + s->fdc_mapped =3D true; + + memory_region_init_io(&s->kbc_io, OBJECT(s), &pc87560_stub_ops, + s, "pc87560-kbc", 8); + memory_region_add_subregion(io, 0x60, &s->kbc_io); + s->kbc_mapped =3D true; + + memory_region_init_io(&s->acpi_io, OBJECT(s), &pc87560_stub_ops, + s, "pc87560-acpi", 32); + memory_region_add_subregion(io, 0x4000, &s->acpi_io); + s->acpi_mapped =3D true; + + memory_region_init_io(&s->pm_io, OBJECT(s), &pc87560_stub_ops, + s, "pc87560-pm", 256); +} + +static void pc87560_superio_instance_init(Object *obj) +{ + PC87560SuperioState *s =3D PC87560_Superio(obj); + + object_initialize_child(obj, "serial[*]", &s->serial[0], TYPE_SERIAL); + object_initialize_child(obj, "serial[*]", &s->serial[1], TYPE_SERIAL); +} + +static const VMStateDescription vmstate_pc87560_superio =3D { + .name =3D "pc87560-superio", + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (const VMStateField[]) { + VMSTATE_PCI_DEVICE(parent_obj, PC87560SuperioState), + VMSTATE_STRUCT_ARRAY(serial, PC87560SuperioState, 2, 0, + vmstate_serial, SerialState), + VMSTATE_STRUCT(fdc, PC87560SuperioState, 0, vmstate_fdc, FDCtrl), + VMSTATE_END_OF_LIST() + }, +}; + +static const Property pc87560_superio_properties[] =3D { + DEFINE_PROP_CHR("serial0", PC87560SuperioState, serial[0].chr), + DEFINE_PROP_CHR("serial1", PC87560SuperioState, serial[1].chr), + DEFINE_PROP_CHR("parallel", PC87560SuperioState, pp.chr), +}; + +static void pc87560_superio_class_init(ObjectClass *oc, const void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(oc); + PCIDeviceClass *k =3D PCI_DEVICE_CLASS(oc); + + k->realize =3D pc87560_superio_realize; + k->config_write =3D pc87560_superio_config_write; + k->vendor_id =3D PCI_VENDOR_ID_NS; + k->device_id =3D PCI_DEVICE_ID_NS_87560_LIO; + k->class_id =3D 0x0680; + k->revision =3D 0x01; + k->subsystem_vendor_id =3D PCI_VENDOR_ID_HP; + k->subsystem_id =3D 0x10A7; + + dc->desc =3D "NS PC87560 SuperI/O Function 1 (I/O Peripheral= s)"; + dc->vmsd =3D &vmstate_pc87560_superio; + dc->user_creatable =3D false; + device_class_set_props(dc, pc87560_superio_properties); + set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); +} + +static const TypeInfo pc87560_superio_info =3D { + .name =3D TYPE_PC87560_Superio, + .parent =3D TYPE_PCI_DEVICE, + .instance_size =3D sizeof(PC87560SuperioState), + .instance_init =3D pc87560_superio_instance_init, + .class_init =3D pc87560_superio_class_init, + .interfaces =3D (InterfaceInfo[]) { + { INTERFACE_CONVENTIONAL_PCI_DEVICE }, + { }, + }, +}; + +static void pc87560_superio_register_types(void) +{ + type_register_static(&pc87560_superio_info); +} + +type_init(pc87560_superio_register_types) diff --git a/include/hw/isa/pc87560.h b/include/hw/isa/pc87560.h new file mode 100644 index 0000000000..72e317cc7b --- /dev/null +++ b/include/hw/isa/pc87560.h @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#ifndef HW_ISA_PC87560_H +#define HW_ISA_PC87560_H + +#define TYPE_PC87560_Superio "pc87560-superio" +OBJECT_DECLARE_SIMPLE_TYPE(PC87560SuperioState, PC87560_Superio) + +#define REG_FXBAR0 0x40 +#define REG_FXBAR1 0x44 +#define REG_FXBAR2 0x48 +#define REG_DDMA_BAR 0x4C +#define REG_FIR_BAR 0x50 +#define REG_SYSCFG 0x58 +#define REG_FUNCEN 0x5A +#define REG_SIOCFG 0x5C +#define REG_SPECFEN 0x5D +#define REG_PPDID 0x5E +#define REG_PPMODE 0x5F +#define REG_DMA_ROUTE4 0x61 +#define REG_ROMCFG 0x62 +#define REG_DMA_ROUTE1 0x63 +#define REG_DMA_ROUTE2 0x64 +#define REG_DMA_ROUTE3 0x65 +#define REG_DMA_CHAN 0x66 +#define REG_IRQ_TRIG 0x67 +#define REG_IRQ_ROUTE1 0x69 +#define REG_ARBCTL 0x72 +#define REG_FX_MASK2 0x74 +#define REG_FX_TIMING 0x76 +#define REG_FXCTL 0x78 +#define REG_GPIO_CFG 0x79 +#define REG_GPIO_DIR 0x7A +#define REG_SIRQ_CTL 0x7B +#define REG_SIRQ_EN 0x7C +#define REG_RSVD_CFG 0x7E +#define REG_AUDIOCS_EN 0x7F +#define REG_FXMEM_CTL1 0x80 +#define REG_KBCBAR 0x84 +#define REG_ACPIBAR 0x88 +#define REG_PMBAR 0x8C +#define REG_FDCBAR 0x90 +#define REG_SP1BAR 0x94 +#define REG_SP2BAR 0x98 +#define REG_PPBAR 0x9C +#define REG_TEST_CTL 0xFF + +#define FUNCEN_FDC (1 << 0) +#define FUNCEN_SP1 (1 << 1) +#define FUNCEN_SP2 (1 << 3) +#define FUNCEN_PP (1 << 5) +#define FUNCEN_KBC (1 << 13) + +#define FUNCEN_DEFAULT 0xFFBF + +#define IC_PIC1 0x20 + +typedef struct { + uint8_t imr; /* interrupt mask register (OCW1) */ + uint8_t irr; /* interrupt request register */ + uint8_t isr; /* in-service register */ + bool poll_mode; /* OCW3 POLL bit set */ + bool read_isr; /* OCW3: true=3DISR, false=3DIRR */ + int init_phase;/* 0=3Dnormal, 1-3=3DICW2/3/4 expected */ + int priority_base; + int irq_level; +} Pic8259; + +struct PC87560SuperioState { + PCIDevice parent_obj; + + qemu_irq parent_irq; + + SerialState serial[2]; + ParallelState pp; + FDCtrl fdc; + + MemoryRegion fdc_io; + MemoryRegion sp1_io; + MemoryRegion sp2_io; + MemoryRegion pp_io; + MemoryRegion kbc_io; + MemoryRegion acpi_io; + MemoryRegion pm_io; + MemoryRegion pic1_io; + + bool fdc_mapped; + bool sp1_mapped; + bool sp2_mapped; + bool pp_mapped; + bool kbc_mapped; + bool acpi_mapped; + bool pm_mapped; + Pic8259 pic; +}; + +#endif --=20 2.54.0 From nobody Sat Sep 26 20:50:17 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=kernel.org ARC-Seal: i=1; a=rsa-sha256; t=1789680947; cv=none; d=zohomail.com; s=zohoarc; b=FlIds8f8a3A5Nig0JV+JGbAE0SkTQuCWiEC3NVKppBKpvw6DI8CYfEcybBUdTCgfhIOVXM1PukagQEMfQOhR9bUjvsPBi8EtnC7N3L8g6wO7uf3o35FfXIP4SYQ8e9oy0XS2O/CvB46e2VakdPrtoWZ/GBXPDW1iSl4dMHbCqdo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1789680947; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=t4g5agFiRNfPbZXPOnNO6N7ceP6Sa/ds2pu3mKmfFxY=; b=DCb5cfNIPrqVgN/un2/hILzBKrHIAY5xeW8pBjsV/eKFz6tvlETjwz5fMJTthm195BiZ44pJNsKemofPElsXGYdRGQAyH8HTngyEuiwJ9oTI7BUrSNZzW5hqrHThXcn+kiK99jcV0bGZH4FKy8u/Y/JKu4z4MGyBdaQRRVPyxNU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1789680947979896.159800031699; Thu, 17 Sep 2026 14:35:47 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x7JkV-0007y1-L1; Thu, 17 Sep 2026 17:34:31 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x7JkN-0007vw-7X; Thu, 17 Sep 2026 17:34:23 -0400 Received: from tor.source.kernel.org ([172.105.4.254]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x7JkG-0005w4-Jn; Thu, 17 Sep 2026 17:34:19 -0400 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by tor.source.kernel.org (Postfix) with ESMTP id C26EC601EF; Thu, 17 Sep 2026 21:34:13 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9DE471F000FF; Thu, 17 Sep 2026 21:34:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1789680853; bh=t4g5agFiRNfPbZXPOnNO6N7ceP6Sa/ds2pu3mKmfFxY=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=cWQ53D3CybwnOsR+3NOzyso9FbiyrEbYWA5MvkWrXaQPJvBdJMOQvNk4k1hOiECeF JI3PrDk3o8+0wTBwXSvCRPeQ1v2CzTBcy8175kiVNTnaTz2oxx8em2H8bT0J9lXYrM Vq/IJ/46alGur69HNdSxqV1IPcYs6zTyS1aL85vxtCQT/cB8e+b0YzimrOAVho+kK+ KjA+ShZoBaSDqXaqCYQxjuYJPZw4sHjybic5BeEbK7avrgMzT3DdcBdWJUgs6sGlV3 8c4QGmSQsLlR/VWSMjKT+KvIygDQSAl/G+pIKmNjiTMbxYfCDRRMUnkzKx3WY2gafI C/Yw2iEBSvzZQ== From: Helge Deller To: qemu-devel@nongnu.org Cc: "Michael S. Tsirkin" , "Denis V. Lunev" , Helge Deller , John Snow , Richard Henderson , Paolo Bonzini , Abizer Lokhandwala , qemu-block@nongnu.org Subject: [PATCH 3/7] hw/ide/pc87560-ide: Add IDE emulation of NS 87560 SuperIO chip Date: Thu, 17 Sep 2026 23:33:56 +0200 Message-ID: <20260917213402.3127-4-deller@kernel.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260917213402.3127-1-deller@kernel.org> References: <20260917213402.3127-1-deller@kernel.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=172.105.4.254; envelope-from=deller@kernel.org; helo=tor.source.kernel.org 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, DKIMWL_WL_HIGH=-0.001, 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: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @kernel.org) X-ZM-MESSAGEID: 1789680948894158500 From: Abizer Lokhandwala Add emulation of the IDE ports of the NS SuperIO chip. Signed-off-by: Abizer Lokhandwala Signed-off-by: Helge Deller --- MAINTAINERS | 1 + hw/ide/pc87560-ide.c | 358 +++++++++++++++++++++++++++++++++++++++++++ hw/ide/trace-events | 4 + 3 files changed, 363 insertions(+) create mode 100644 hw/ide/pc87560-ide.c diff --git a/MAINTAINERS b/MAINTAINERS index e3b1e80ad6..2da2f00ff3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1356,6 +1356,7 @@ F: pc-bios/hppa-firmware.img F: roms/seabios-hppa/ F: tests/functional/hppa/ F: hw/isa/pc87560.c +F: hw/ide/pc87560-ide.c F: include/hw/isa/pc87560.h =20 Hexagon Machines diff --git a/hw/ide/pc87560-ide.c b/hw/ide/pc87560-ide.c new file mode 100644 index 0000000000..879b5f1234 --- /dev/null +++ b/hw/ide/pc87560-ide.c @@ -0,0 +1,358 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * NS PC87560 SuperI/O =E2=80=94 IDE emulation + * + * Copyright (c) 2026 Abizer abizerlokhandwalastd10@gmail.com + */ + +#include "qemu/osdep.h" +#include "hw/pci/pci.h" +#include "migration/vmstate.h" +#include "qemu/module.h" +#include "hw/isa/isa.h" +#include "hw/core/irq.h" +#include "hw/ide/pci.h" +#include "ide-internal.h" +#include "trace.h" + +#define PC87415_IDE_CHANNELS 2 + +/* PCI configuration space */ +#define PC87415_CTRL 0x40 +#define PC87415_WRITE_BUFFER_STATUS 0x43 + +/* CTRL register, byte 1 (PCI config offset 0x41) */ +#define PC87415_CTRL_CH1_INT_MASK BIT(0) +#define PC87415_CTRL_CH2_INT_MASK BIT(1) + +/* PCI programming interface */ +#define PC87415_PIF_CH1_PROGRAMMABLE BIT(1) +#define PC87415_PIF_CH2_PROGRAMMABLE BIT(3) +#define PC87415_PIF_MASTER_IDE BIT(7) + +#define PC87415_PIF_DEFAULT \ + (PC87415_PIF_CH1_PROGRAMMABLE | \ + PC87415_PIF_CH2_PROGRAMMABLE | \ + PC87415_PIF_MASTER_IDE) + +/* Per-device timing registers */ +#define PC87415_CH1_DEV1_READ_TIMING 0x44 +#define PC87415_CH1_DEV1_WRITE_TIMING 0x45 +#define PC87415_CH1_DEV2_READ_TIMING 0x48 +#define PC87415_CH1_DEV2_WRITE_TIMING 0x49 +#define PC87415_CH2_DEV1_READ_TIMING 0x4c +#define PC87415_CH2_DEV1_WRITE_TIMING 0x4d +#define PC87415_CH2_DEV2_READ_TIMING 0x50 +#define PC87415_CH2_DEV2_WRITE_TIMING 0x51 + +#define PC87415_CMD_TIMING 0x54 +#define PC87415_SECTOR_SIZE 0x55 + +/* PCI BARs */ +#define PC87415_BAR_CH1_DATA 0 +#define PC87415_BAR_CH1_CONTROL 1 +#define PC87415_BAR_CH2_DATA 2 +#define PC87415_BAR_CH2_CONTROL 3 +#define PC87415_BAR_BMDMA 4 + +/* Bus-master IDE registers */ +#define PC87415_BMDMA_CMD 0x00 +#define PC87415_BMDMA_STATUS 0x02 +#define PC87415_BMDMA_PRD 0x04 +#define PC87415_BMDMA_CHANNEL_SIZE 0x08 +#define PC87415_BMDMA_BAR_SIZE 0x10 + +/* + * Bus-master command register: + * bit 0 =3D start/stop + * bit 3 =3D read/write + */ +#define PC87415_BMDMA_CMD_START BIT(0) +#define PC87415_BMDMA_CMD_WRITE BIT(3) +#define PC87415_BMDMA_CMD_MASK \ + (PC87415_BMDMA_CMD_START | PC87415_BMDMA_CMD_WRITE) + +/* + * Bus-master status register: + * bit 1 =3D error + * bit 2 =3D interrupt + */ +#define PC87415_BMDMA_STATUS_ERROR BIT(1) +#define PC87415_BMDMA_STATUS_INT BIT(2) + +static qemu_irq pc87560_ide_irq_out; +static void pc87560_update_irq(PCIDevice *pd); + +static uint64_t bmdma_read(void *opaque, hwaddr addr, unsigned size) +{ + BMDMAState *bm =3D opaque; + uint32_t val; + + if (size !=3D 1) { + return ((uint64_t)1 << (size * 8)) - 1; + } + + switch (addr & 3) { + case 0: + val =3D bm->cmd; + break; + case 2: + val =3D bm->status; + break; + default: + val =3D 0xff; + break; + } + return val; +} + +static void bmdma_write(void *opaque, hwaddr addr, uint64_t val, unsigned = size) +{ + BMDMAState *bm =3D opaque; + PCIDevice *pd =3D PCI_DEVICE(bm->bus->qbus.parent); + + if (size !=3D 1) { + return; + } + + switch (addr & 3) { + case 0: { + /* + * NS87415 erratum: writing the command register also clears + * the error and interrupt status bits. + */ + uint8_t status_clear =3D val & (PC87415_BMDMA_STATUS_INT | + PC87415_BMDMA_STATUS_ERROR); + uint8_t real_cmd =3D val & PC87415_BMDMA_CMD_MASK; + /* only START(0) and WRITE(3) are real cmd bits */ + + bm->status &=3D ~status_clear; + + if (real_cmd !=3D (bm->cmd & 0x09)) { + bmdma_cmd_writeb(bm, real_cmd); + } + + pc87560_update_irq(pd); + break; + } + case 2: + bmdma_status_writeb(bm, val); + pc87560_update_irq(pd); + break; + default: + break; + } +} + +static void pc87560_update_irq(PCIDevice *pd) +{ + PCIIDEState *d =3D PCI_IDE(pd); + uint8_t ctrl1 =3D pd->config[PC87415_CTRL + 1]; + int level =3D 0; + + if (!(ctrl1 & PC87415_CTRL_CH1_INT_MASK)) { + level |=3D !!(d->bmdma[0].status & BM_STATUS_INT); + } + + if (!(ctrl1 & PC87415_CTRL_CH2_INT_MASK)) { + level |=3D !!(d->bmdma[1].status & BM_STATUS_INT); + } + + qemu_set_irq(pc87560_ide_irq_out, level); +} + +static const MemoryRegionOps pc87560_bmdma_ops =3D { + .read =3D bmdma_read, + .write =3D bmdma_write, + .endianness =3D DEVICE_LITTLE_ENDIAN, +}; + +static void bmdma_setup_bar(PCIIDEState *d) +{ + unsigned int i; + + memory_region_init(&d->bmdma_bar, OBJECT(d), "pc87415-bmdma", + PC87415_BMDMA_BAR_SIZE); + + for (i =3D 0; i < PC87415_IDE_CHANNELS; i++) { + BMDMAState *bm =3D &d->bmdma[i]; + + memory_region_init_io(&bm->extra_io, OBJECT(d), + &pc87560_bmdma_ops, bm, + "pc87415-bmdma-cmd-status", + 4); + memory_region_add_subregion(&d->bmdma_bar, + i * PC87415_BMDMA_CHANNEL_SIZE, + &bm->extra_io); + + memory_region_init_io(&bm->addr_ioport, OBJECT(d), + &bmdma_addr_ioport_ops, bm, + "pc87415-bmdma-prd", + 4); + memory_region_add_subregion(&d->bmdma_bar, + i * PC87415_BMDMA_CHANNEL_SIZE + + PC87415_BMDMA_PRD, + &bm->addr_ioport); + } +} + + +static void pc87560_set_irq(void *opaque, int channel, int level) +{ + PCIIDEState *d =3D opaque; + PCIDevice *pd =3D PCI_DEVICE(d); + + if (level) { + d->bmdma[channel].status |=3D BM_STATUS_INT; + } + pc87560_update_irq(pd); +} + + +static void pc87560_reset(Object *dev, ResetType type) +{ + PCIIDEState *d =3D PCI_IDE(dev); + unsigned int i; + + for (i =3D 0; i < 2; i++) { + ide_bus_reset(&d->bus[i], IDE_RESET_HARDWARE); + } +} + + +static void pc87560_pci_config_write(PCIDevice *d, uint32_t addr, uint32_t= val, + int len) +{ + pci_default_write_config(d, addr, val, len); + + if (ranges_overlap(addr, len, PC87415_CTRL + 1, 1)) { + pc87560_update_irq(d); + } +} + +static void pci_pc87560_ide_realize(PCIDevice *dev, Error **errp) +{ + + PCIIDEState *d =3D PCI_IDE(dev); + DeviceState *ds =3D DEVICE(dev); + uint8_t *pci_conf =3D dev->config; + int i; + + dev->cap_present |=3D QEMU_PCI_CAP_MULTIFUNCTION; + pci_conf[PCI_HEADER_TYPE] |=3D PCI_HEADER_TYPE_MULTI_FUNCTION; + + pci_conf[PCI_CLASS_PROG] =3D 0x8a; + dev->wmask[PCI_CLASS_PROG] =3D 0xff; + + pci_conf[PCI_INTERRUPT_PIN] =3D 0x01; + qdev_init_gpio_out(ds, &pc87560_ide_irq_out, 1); + + memset(&dev->wmask[PC87415_CTRL], 0xff, 3); + + dev->wmask[PC87415_CH1_DEV1_READ_TIMING] =3D 0xff; + dev->wmask[PC87415_CH1_DEV1_WRITE_TIMING] =3D 0xff; + + dev->wmask[PC87415_CH1_DEV2_READ_TIMING] =3D 0xff; + dev->wmask[PC87415_CH1_DEV2_WRITE_TIMING] =3D 0xff; + + dev->wmask[PC87415_CH2_DEV1_READ_TIMING] =3D 0xff; + dev->wmask[PC87415_CH2_DEV1_WRITE_TIMING] =3D 0xff; + + dev->wmask[PC87415_CH2_DEV2_READ_TIMING] =3D 0xff; + dev->wmask[PC87415_CH2_DEV2_WRITE_TIMING] =3D 0xff; + + dev->wmask[PC87415_CMD_TIMING] =3D 0xff; + dev->wmask[PC87415_SECTOR_SIZE] =3D 0xff; + + pci_conf[PC87415_CTRL + 0] =3D 0x00; + pci_conf[PC87415_CTRL + 1] =3D 0x00; + pci_conf[PC87415_CTRL + 2] =3D 0x00; + + pci_conf[PC87415_CH1_DEV1_READ_TIMING] =3D 0x85; + pci_conf[PC87415_CH1_DEV1_WRITE_TIMING] =3D 0x85; + pci_conf[PC87415_CH1_DEV2_READ_TIMING] =3D 0x85; + pci_conf[PC87415_CH1_DEV2_WRITE_TIMING] =3D 0x85; + pci_conf[PC87415_CH2_DEV1_READ_TIMING] =3D 0x85; + pci_conf[PC87415_CH2_DEV1_WRITE_TIMING] =3D 0x85; + pci_conf[PC87415_CH2_DEV2_READ_TIMING] =3D 0x85; + pci_conf[PC87415_CH2_DEV2_WRITE_TIMING] =3D 0x85; + + pci_conf[PC87415_CMD_TIMING] =3D 0xB7; + pci_conf[PC87415_SECTOR_SIZE] =3D 0xEE; + + memory_region_init_io(&d->data_bar[0], OBJECT(d), &pci_ide_data_le_ops, + &d->bus[0], "pc87560-data0", 8); + pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->data_bar[0]); + + memory_region_init_io(&d->cmd_bar[0], OBJECT(d), &pci_ide_cmd_le_ops, + &d->bus[0], "pc87560-cmd0", 4); + pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[0]); + + memory_region_init_io(&d->data_bar[1], OBJECT(d), &pci_ide_data_le_ops, + &d->bus[1], "pc87560-data1", 8); + pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &d->data_bar[1]); + + memory_region_init_io(&d->cmd_bar[1], OBJECT(d), &pci_ide_cmd_le_ops, + &d->bus[1], "pc87560-cmd1", 4); + pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[1]); + + bmdma_setup_bar(d); + pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar); + + qdev_init_gpio_in(ds, pc87560_set_irq, 2); + for (i =3D 0; i < 2; i++) { + ide_bus_init(&d->bus[i], sizeof(d->bus[i]), ds, i, 2); + ide_bus_init_output_irq(&d->bus[i], qdev_get_gpio_in(ds, i)); + + bmdma_init(&d->bus[i], &d->bmdma[i], d); + d->bmdma[i].bus =3D &d->bus[i]; + ide_bus_register_restart_cb(&d->bus[i]); + } +} + +static void pci_pc87560_ide_exitfn(PCIDevice *dev) +{ + PCIIDEState *d =3D PCI_IDE(dev); + unsigned int i; + + for (i =3D 0; i < 2; ++i) { + memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io); + memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_iopor= t); + } +} + + +static void pc87560_ide_class_init(ObjectClass *klass, const void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + PCIDeviceClass *k =3D PCI_DEVICE_CLASS(klass); + ResettableClass *rc =3D RESETTABLE_CLASS(klass); + + rc->phases.hold =3D pc87560_reset; + dc->vmsd =3D &vmstate_ide_pci; + dc->user_creatable =3D false; + k->realize =3D pci_pc87560_ide_realize; + k->exit =3D pci_pc87560_ide_exitfn; + k->vendor_id =3D PCI_VENDOR_ID_NS; + k->device_id =3D PCI_DEVICE_ID_NS_87415; + k->revision =3D 0x02; + k->subsystem_vendor_id =3D PCI_VENDOR_ID_HP; + k->subsystem_id =3D 0x10A7; + k->class_id =3D PCI_CLASS_STORAGE_IDE; + k->config_write =3D pc87560_pci_config_write; + set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); +} + + +static const TypeInfo pc87560_ide_info =3D { + .name =3D "pc87560-ide", + .parent =3D TYPE_PCI_IDE, + .class_init =3D pc87560_ide_class_init, +}; + +static void pc87560_ide_register_types(void) +{ + type_register_static(&pc87560_ide_info); +} + +type_init(pc87560_ide_register_types) diff --git a/hw/ide/trace-events b/hw/ide/trace-events index 3ab5e7bd1d..c44eec6c58 100644 --- a/hw/ide/trace-events +++ b/hw/ide/trace-events @@ -27,6 +27,10 @@ ide_dma_cb(void *s, int64_t sector_num, int n, const cha= r *dma) "IDEState %p; se bmdma_read_cmd646(uint64_t addr, uint32_t val) "bmdma: readb 0x%"PRIx64" := 0x%02x" bmdma_write_cmd646(uint64_t addr, uint64_t val) "bmdma: writeb 0x%"PRIx64"= : 0x%02"PRIx64 =20 +# hw/ide/pc87560.c +bmdma_read_pc87560(uint64_t addr, uint32_t val) "bmdma: readb 0x%"PRIx64" = : 0x%02x" +bmdma_write_pc87560(uint64_t addr, uint64_t val) "bmdma: writeb 0x%"PRIx64= " : 0x%02"PRIx64 + # pci.c bmdma_reset(void) "" bmdma_cmd_writeb(uint32_t val) "val: 0x%08x" --=20 2.54.0 From nobody Sat Sep 26 20:50:17 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=kernel.org ARC-Seal: i=1; a=rsa-sha256; t=1789680920; cv=none; d=zohomail.com; s=zohoarc; b=Z2Ebo++Z3YkUMfBsgc6Udr1g/ETlfS71xYadm01wsjDnMs74y0slSdboweh6A0x7WZrvfFE5joZtszdNhoS4VRGh2MkiMfe4isQG61+XBOo41qUoeomshG2XDQWmXmcIwXZqavhhC1cUKnjoj5AjJQ6Adh/gWcQgcaizjqhMvmg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1789680920; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=Ynlks6OjXe/uRxYnEgUbla/LudkyT55AVz8txJwfPoA=; b=OXXYWP6e7tnoxTK/F64Q4vnwCqyjQVmAzUgzQLYZxhtczWgD8V54gZUt4toYHDPbyowWnmZgxyW0Aslta8ps2eSuPDoIwwJvwUAlyEVv1lohhZlfkaUzCtcStBDmJbBp2wf657hDeyGg+TtWcILhoX28Q71dAmgoBcNhLFyxssM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1789680920219980.4312821580893; Thu, 17 Sep 2026 14:35:20 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x7JkV-0007xy-Jp; Thu, 17 Sep 2026 17:34:31 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x7JkN-0007vx-8M; Thu, 17 Sep 2026 17:34:23 -0400 Received: from tor.source.kernel.org ([172.105.4.254]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x7JkH-0005wp-W7; Thu, 17 Sep 2026 17:34:21 -0400 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by tor.source.kernel.org (Postfix) with ESMTP id 1071B60202; Thu, 17 Sep 2026 21:34:16 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id E43431F00898; Thu, 17 Sep 2026 21:34:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1789680855; bh=Ynlks6OjXe/uRxYnEgUbla/LudkyT55AVz8txJwfPoA=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=XPuF1wqAJYbJJ9XDA/ElpBh3sWi4LhsMmFb+kRmnYpfDQMc/hCJT2jdhbCTAR8PJl KFoFnauggFw8AEgNBtceZzSZox+2kUwwFpCHQl/MCQPbSVAHfyEQc4k5+YTDtHV6d2 VjBMUvPA7GrUfoilFSmj/mTagBSOjowaTi+Wq1P14t1e7mtSnxFUp0TMmOg1WcXDxL u5a240WfRRO/0LOVUdhWcR7jS+SlNCvfgdfNOD1tocb48dlX9zHh6bBvxks4Y41atG XxfhQEvkAh8yNKtaP9ZA1iyEeoE+oZCdwMSo34Q7JnE088rfhe0pALoi3zQohn1JZr ySec+g52Kosew== From: Helge Deller To: qemu-devel@nongnu.org Cc: "Michael S. Tsirkin" , "Denis V. Lunev" , Helge Deller , John Snow , Richard Henderson , Paolo Bonzini , Abizer Lokhandwala , qemu-block@nongnu.org Subject: [PATCH 4/7] hw/usb/hcd-ohci: Add big endian and consistency check support Date: Thu, 17 Sep 2026 23:33:57 +0200 Message-ID: <20260917213402.3127-5-deller@kernel.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260917213402.3127-1-deller@kernel.org> References: <20260917213402.3127-1-deller@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=172.105.4.254; envelope-from=deller@kernel.org; helo=tor.source.kernel.org 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, DKIMWL_WL_HIGH=-0.001, 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: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @kernel.org) X-ZM-MESSAGEID: 1789680920785158500 Content-Type: text/plain; charset="utf-8" From: Abizer Lokhandwala The OHCI controller allows running in big endian mode. If this mode is enab= led, swap the buffer contents before accessing them since we by default run OHCI in littl= e endian mode. Additionally add the architected consistency check which halts OHCI on erro= rs. Signed-off-by: Abizer Lokhandwala Signed-off-by: Helge Deller --- hw/usb/hcd-ohci.c | 35 +++++++++++++++++++++++++++++++++++ hw/usb/hcd-ohci.h | 5 +++++ 2 files changed, 40 insertions(+) diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c index 23990115ab..5e5fe41f47 100644 --- a/hw/usb/hcd-ohci.c +++ b/hw/usb/hcd-ohci.c @@ -74,6 +74,7 @@ struct ohci_hcca { /* Flags in the head field of an Endpoint Descriptor. */ #define OHCI_ED_H 1 #define OHCI_ED_C 2 +#define OHCI_ED_HEAD_RSVD (1 << 2 | 1 << 3) =20 /* Bitfields for the first word of a Transfer Descriptor. */ #define OHCI_TD_R (1 << 18) @@ -371,6 +372,8 @@ void ohci_hard_reset(OHCIState *ohci) ohci_soft_reset(ohci); ohci->ctl =3D 0; ohci_roothub_reset(ohci); + ohci->big_endian =3D false; + ohci->consistency_check =3D false; } =20 /* Get an array of dwords from main memory */ @@ -867,6 +870,18 @@ static void ohci_td_pkt(const char *msg, const uint8_t= *buf, size_t len) } } =20 +static void ohci_bswap_buf(uint8_t *buf, size_t len) +{ + uint32_t w; + while (len >=3D sizeof(w)) { + memcpy(&w, buf, sizeof(w)); + w =3D bswap32(w); + memcpy(buf, &w, sizeof(w)); + buf +=3D sizeof(w); + len -=3D sizeof(w); + } +} + /* * Service a transport descriptor. * Returns nonzero to terminate processing of this endpoint. @@ -975,6 +990,9 @@ static int ohci_service_td(OHCIState *ohci, struct ohci= _ed *ed) DMA_DIRECTION_TO_DEVICE)) { ohci_die(ohci); } + if (ohci->big_endian) { + ohci_bswap_buf(ohci->usb_buf, pktlen); + } } } } @@ -1024,6 +1042,9 @@ static int ohci_service_td(OHCIState *ohci, struct oh= ci_ed *ed) =20 if (ret >=3D 0) { if (dir =3D=3D OHCI_TD_DIR_IN) { + if (ohci->big_endian) { + ohci_bswap_buf(ohci->usb_buf, ret); + } if (ohci_copy_td(ohci, &td, ohci->usb_buf, ret, DMA_DIRECTION_FROM_DEVICE)) { ohci_die(ohci); @@ -1108,6 +1129,13 @@ static int ohci_service_td(OHCIState *ohci, struct o= hci_ed *ed) ohci->done_count =3D i; } exit_no_retire: + if (ohci->media_error) { + int cc =3D OHCI_BM(td.flags, TD_CC); + /* only these 2 errors will ever actually be possible in qemu */ + if (cc =3D=3D OHCI_CC_DEVICENOTRESPONDING || cc =3D=3D OHCI_CC_UND= EXPETEDPID) { + ohci->media_error(ohci); + } + } if (ohci_put_td(ohci, addr, &td)) { ohci_die(ohci); return 1; @@ -1136,6 +1164,13 @@ static int ohci_service_ed_list(OHCIState *ohci, uin= t32_t head) ohci_die(ohci); return 0; } + if (ohci->consistency_check && (ed.head & OHCI_ED_HEAD_RSVD)) { + if (ohci->descriptor_error) { + ohci->descriptor_error(ohci); + } + ohci_die(ohci); + return 0; + } =20 next_ed =3D ed.next & OHCI_DPTR_MASK; =20 diff --git a/hw/usb/hcd-ohci.h b/hw/usb/hcd-ohci.h index 243cd1f46a..d079f8d24e 100644 --- a/hw/usb/hcd-ohci.h +++ b/hw/usb/hcd-ohci.h @@ -93,6 +93,11 @@ struct OHCIState { bool async_complete; =20 void (*ohci_die)(OHCIState *ohci); + void (*media_error)(OHCIState *ohci); + void (*descriptor_error)(OHCIState *ohci); + + bool big_endian; + bool consistency_check; }; =20 #define TYPE_SYSBUS_OHCI "sysbus-ohci" --=20 2.54.0 From nobody Sat Sep 26 20:50:17 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=kernel.org ARC-Seal: i=1; a=rsa-sha256; t=1789680908; cv=none; d=zohomail.com; s=zohoarc; b=TL/Tx9D9AVROudZpZoM46pb+ZgUFGTzwrX3nxyA1jiBd21nONyOyY+45xVhspeyf+QsC8QmOSf7kcJbaPcGmlGk0GYuHcBfjXvTlWR/SgKe0DNbmoj0eIa+DvrwoKawqs6W1HgUE9JLSk4STkh3oP/6kv/9h7sUFyr1uoinRDL8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1789680908; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=HQ6E4+oLV7DMYAIsbqwuB+snz6Fo+Dd+3qEqXjmVwjI=; b=Rn5O4A3CQMIoZXg+1f8NeZwAzp2f1EbSw0VrybsjDl8hPgXUX9QEiWyOvZnuU6GJkatu/Q+449rt15TpbA1+9oUCc2XMUVgbQslzEIO6JNaYta6pKjMX8iS89v+gPmep5MrzdNpRS7AK3FDgI0pEAO2jmjZx6xw0ssJLjdeNB+4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1789680908906606.9360902821381; Thu, 17 Sep 2026 14:35:08 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x7JkX-0007yH-2F; Thu, 17 Sep 2026 17:34:33 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x7JkP-0007wj-Cz; Thu, 17 Sep 2026 17:34:25 -0400 Received: from tor.source.kernel.org ([2600:3c04:e001:324:0:1991:8:25]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x7JkJ-0005y2-BT; Thu, 17 Sep 2026 17:34:24 -0400 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by tor.source.kernel.org (Postfix) with ESMTP id 56B9760209; Thu, 17 Sep 2026 21:34:18 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 366BE1F00893; Thu, 17 Sep 2026 21:34:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1789680858; bh=HQ6E4+oLV7DMYAIsbqwuB+snz6Fo+Dd+3qEqXjmVwjI=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=cTrsEOiyHETD1ZqF8248HiCuqmxlAYtElE8j7v4xKLm8rzRoA+pXLzMUgWWmpxlGj l56PcNdAOCdNXHQRoiZ8zsPNcsp52DgMJBYJev1cEge4rJ2R2m8nzfRQGbcxdpKRkW ojTaTs7G5FHkartkj0YNDLPTScyVrCEL1wR7LnEmG0hKYeaRMEYCiDDZzY3eT+Ltor uGQNZQXyS7sI/6OtMAfacLbsyKQg2AO0lUs5Ygjeft6FLDeX4oMtUnLB0an/4TFq72 u30yNyH6yMFo1oU09yHAoXHWmES2oI9Cmy8HMHIZalm3f9qCH0YYRH5E0HdQ2JY++e xDbQAHOBi45BA== From: Helge Deller To: qemu-devel@nongnu.org Cc: "Michael S. Tsirkin" , "Denis V. Lunev" , Helge Deller , John Snow , Richard Henderson , Paolo Bonzini , Abizer Lokhandwala , qemu-block@nongnu.org Subject: [PATCH 5/7] hw/usb/pc87560-ohci: Add USB OHCI emulation of NS 87560 SuperIO chip Date: Thu, 17 Sep 2026 23:33:58 +0200 Message-ID: <20260917213402.3127-6-deller@kernel.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260917213402.3127-1-deller@kernel.org> References: <20260917213402.3127-1-deller@kernel.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2600:3c04:e001:324:0:1991:8:25; envelope-from=deller@kernel.org; helo=tor.source.kernel.org 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, DKIMWL_WL_HIGH=-0.001, 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: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @kernel.org) X-ZM-MESSAGEID: 1789680910670158501 From: Abizer Lokhandwala Add emulation of the USB OHCI portion of the NS SuperIO chip. Signed-off-by: Abizer Lokhandwala Signed-off-by: Helge Deller --- MAINTAINERS | 1 + hw/usb/pc87560-ohci.c | 355 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 356 insertions(+) create mode 100644 hw/usb/pc87560-ohci.c diff --git a/MAINTAINERS b/MAINTAINERS index 2da2f00ff3..e8c7030dec 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1357,6 +1357,7 @@ F: roms/seabios-hppa/ F: tests/functional/hppa/ F: hw/isa/pc87560.c F: hw/ide/pc87560-ide.c +F: hw/usb/pc87560-ohci.c F: include/hw/isa/pc87560.h =20 Hexagon Machines diff --git a/hw/usb/pc87560-ohci.c b/hw/usb/pc87560-ohci.c new file mode 100644 index 0000000000..cc00f6e936 --- /dev/null +++ b/hw/usb/pc87560-ohci.c @@ -0,0 +1,355 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * NS PC87560 SuperI/O =E2=80=94 USB OHCI emulation + * + * Copyright (c) 2026 Abizer abizerlokhandwalastd10@gmail.com + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu/timer.h" +#include "hw/usb/usb.h" +#include "migration/vmstate.h" +#include "hw/pci/pci_device.h" +#include "hw/core/sysbus.h" +#include "hw/core/irq.h" +#include "hw/core/qdev-properties.h" +#include "trace.h" +#include "hcd-ohci.h" +#include "qom/object.h" + +#define TYPE_NSC_PCI_OHCI "pc87560-ohci" +OBJECT_DECLARE_SIMPLE_TYPE(OHCIPCIState, NSC_PCI_OHCI) + +struct OHCIPCIState { + + PCIDevice parent_obj; + OHCIState state; + MemoryRegion nsc_bar; + char *masterbus; + uint32_t num_ports; + uint32_t firstport; + qemu_irq irq_out[1]; + + /* NSC (NUSSBAR) vendor-specific register state */ + uint32_t nsc_control; + uint32_t nsc_status; +}; + +#define NSC_CONTROL 0x00 +#define NSC_COMMAND_STATUS 0x04 +#define NSC_PORT_RX_STATUS 0x08 +#define NSC_ROOT_HUB_STATUS 0x34 +#define NSC_CTL_BIG_ENDIAN (1U << 0) +#define NSC_CTL_CCE (1U << 1) /* Consistency Check Enable= */ +#define NSC_CTL_WORDCOUNT (0x3fU << 2) /* bits 7:2 */ +#define NSC_CTL_MODE (0x3U << 8) /* bits 9:8 */ +#define NSC_CTL_LIMIT_CONTROL (1U << 16) +#define NSC_CTL_RISE_TIME (0xffU << 24) /* bits 31:24 */ +#define NSC_CTL_WRMASK (NSC_CTL_BIG_ENDIAN | NSC_CTL_CCE | NSC_CTL_WORDCO= UNT |\ + NSC_CTL_MODE | NSC_CTL_LIMIT_CONTROL | \ + NSC_CTL_RISE_TIME) +#define NSC_CONTROL_RESET 0x90000014U +#define NSC_CS_MEDIA_ERROR 0x00000fffU /* bits 11:0, 12-bit counte= r */ +#define NSC_CS_MEDIA_ERR_OVFL (1U << 16) +#define NSC_CS_UE_PCI (1U << 17) +#define NSC_CS_UE_DESCRIPTOR (1U << 18) +#define NSC_CS_UE_INTERNAL (1U << 19) +#define NSC_CS_SCHEDULE_ERROR (1U << 20) +#define NSC_CS_PHY_OVERRUN (1U << 21) +#define NSC_CS_W1C_MASK (NSC_CS_MEDIA_ERR_OVFL | NSC_CS_UE_PCI |\ + NSC_CS_UE_DESCRIPTOR | NSC_CS_UE_INTERNAL |\ + NSC_CS_SCHEDULE_ERROR | NSC_CS_PHY_OVERRUN) +#define NSC_OHCI_INTR_SO (1U << 0) +#define NSC_RHPORT_CCS (1U << 0) /* CurrentConnectStatus */ +#define NSC_RHPORT_PES (1U << 1) /* PortEnableStatus */ +#define NSC_RHPORT_PSS (1U << 2) /* PortSuspendStatus */ +#define NSC_RHPORT_PRS (1U << 4) /* PortResetStatus */ +#define NSC_RHPORT_PPS (1U << 8) /* PortPowerStatus */ + +static uint32_t nsc_hub_port_state(OHCIState *s, int port) +{ + uint32_t ctrl =3D s->rhport[port].ctrl; + + if (!(ctrl & NSC_RHPORT_PPS)) { + return 0x8; /* POWER OFF */ + } + if (!(ctrl & NSC_RHPORT_CCS)) { + return 0xa; /* DISCONNECTED */ + } + if (ctrl & NSC_RHPORT_PRS) { + return 0x2; /* RESET */ + } + if (ctrl & NSC_RHPORT_PSS) { + return 0xc; /* SUSPENDED */ + } + if (ctrl & NSC_RHPORT_PES) { + return 0xe; /* ENABLED, Idle */ + } + return 0xb; /* DISABLED */ +} + +static uint32_t nsc_root_hub_status(OHCIPCIState *ohci) +{ + OHCIState *s =3D &ohci->state; + uint32_t val =3D 0; + + if (s->num_ports >=3D 1) { + val |=3D nsc_hub_port_state(s, 0); /* Port 1 Status[3:0] */ + } + if (s->num_ports >=3D 2) { + val |=3D nsc_hub_port_state(s, 1) << 8; /* Port 2 Status[3:0] */ + } + return val; +} + +static void nsc_ohci_media_error(OHCIState *ohci) +{ + OHCIPCIState *dev =3D container_of(ohci, OHCIPCIState, state); + uint32_t count =3D dev->nsc_status & NSC_CS_MEDIA_ERROR; + + if (count =3D=3D NSC_CS_MEDIA_ERROR) { + dev->nsc_status |=3D NSC_CS_MEDIA_ERR_OVFL; + } else { + dev->nsc_status =3D (dev->nsc_status & ~NSC_CS_MEDIA_ERROR) | (cou= nt + 1); + } +} + +static void nsc_ohci_descriptor_error(OHCIState *ohci) +{ + OHCIPCIState *dev =3D container_of(ohci, OHCIPCIState, state); + dev->nsc_status |=3D NSC_CS_UE_DESCRIPTOR; +} + +static uint64_t nsc_usb_read(void *opaque, hwaddr addr, unsigned size) +{ + OHCIPCIState *ohci =3D opaque; + uint32_t val; + + switch (addr & ~3) { + case NSC_CONTROL: + val =3D ohci->nsc_control; + break; + case NSC_COMMAND_STATUS: + val =3D ohci->nsc_status; + if (ohci->state.intr_status & NSC_OHCI_INTR_SO) { + val |=3D NSC_CS_SCHEDULE_ERROR; + } + break; + case NSC_PORT_RX_STATUS: + val =3D 0; + break; + case NSC_ROOT_HUB_STATUS: + val =3D nsc_root_hub_status(ohci); + break; + default: + val =3D 0; + break; + } + + val >>=3D (addr & 3) * 8; + if (size < 4) { + val &=3D (1U << (size * 8)) - 1; + } + return val; +} + +static void pc87560_usb_irq_relay(void *opaque, int n, int level) +{ + OHCIPCIState *ohci =3D opaque; + qemu_set_irq(ohci->irq_out[0], level); +} + +static void nsc_usb_write(void *opaque, hwaddr addr, uint64_t val, + unsigned size) +{ + OHCIPCIState *ohci =3D opaque; + uint32_t shift =3D (addr & 3) * 8; + uint32_t lane =3D (size < 4) ? (((1U << (size * 8)) - 1) << shift) + : 0xffffffffU; + uint32_t wval =3D ((uint32_t)val << shift) & lane; + + switch (addr & ~3) { + case NSC_CONTROL: + ohci->nsc_control =3D (ohci->nsc_control & ~lane) | + (wval & NSC_CTL_WRMASK); + ohci->state.big_endian =3D (ohci->nsc_control & NSC_CTL_BIG_ENDIAN= ) !=3D 0; + ohci->state.consistency_check =3D (ohci->nsc_control & NSC_CTL_CCE= ) !=3D 0; + break; + + case NSC_COMMAND_STATUS: + if (wval & NSC_CS_MEDIA_ERROR) { + ohci->nsc_status &=3D ~NSC_CS_MEDIA_ERROR; + } + ohci->nsc_status &=3D ~(wval & NSC_CS_W1C_MASK); + if (wval & NSC_CS_SCHEDULE_ERROR) { + ohci->state.intr_status &=3D ~NSC_OHCI_INTR_SO; + } + break; + + case NSC_PORT_RX_STATUS: + case NSC_ROOT_HUB_STATUS: + break; + + default: + break; + } +} + +static const MemoryRegionOps nsc_usb_ops =3D { + .read =3D nsc_usb_read, + .write =3D nsc_usb_write, + .endianness =3D DEVICE_LITTLE_ENDIAN, + .valid =3D { + .min_access_size =3D 1, + .max_access_size =3D 4, + }, +}; + +static void ohci_pci_die(struct OHCIState *ohci) +{ + OHCIPCIState *dev =3D container_of(ohci, OHCIPCIState, state); + + ohci_sysbus_die(ohci); + + dev->nsc_status |=3D NSC_CS_UE_INTERNAL; + + pci_set_word(dev->parent_obj.config + PCI_STATUS, + PCI_STATUS_DETECTED_PARITY); +} + +static uint32_t pc87560_ohci_config_read(PCIDevice *pci, uint32_t addr, in= t len) +{ + uint32_t val =3D pci_default_read_config(pci, addr, len); + return val; +} + +static void pc87560_ohci_config_write(PCIDevice *pci, uint32_t addr, + uint32_t val, int len) +{ + pci_default_write_config(pci, addr, val, len); +} + +static void usb_ohci_realize_pci(PCIDevice *dev, Error **errp) +{ + Error *err =3D NULL; + OHCIPCIState *ohci =3D NSC_PCI_OHCI(dev); + + dev->config[PCI_CLASS_PROG] =3D 0x10; + dev->wmask[PCI_CLASS_PROG] =3D 0xff; + dev->config[PCI_INTERRUPT_PIN] =3D 0x01; + + qdev_init_gpio_out(DEVICE(dev), ohci->irq_out, 1); + ohci->state.irq =3D qemu_allocate_irq(pc87560_usb_irq_relay, ohci, 0); + + usb_ohci_init(&ohci->state, DEVICE(dev), ohci->num_ports, 0, + ohci->masterbus, ohci->firstport, + pci_get_address_space(dev), ohci_pci_die, &err); + if (err) { + error_propagate(errp, err); + return; + } + ohci->state.media_error =3D nsc_ohci_media_error; + ohci->state.descriptor_error =3D nsc_ohci_descriptor_error; + + pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &ohci->state.m= em); + + memory_region_init_io(&ohci->nsc_bar, OBJECT(dev), &nsc_usb_ops, ohci, + "nsc-usb", 0x1000); + pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &ohci->nsc_bar= ); +} + +static void usb_ohci_exit(PCIDevice *dev) +{ + OHCIPCIState *ohci =3D NSC_PCI_OHCI(dev); + OHCIState *s =3D &ohci->state; + + trace_usb_ohci_exit(s->name); + ohci_bus_stop(s); + + if (s->async_td) { + usb_cancel_packet(&s->usb_packet); + s->async_td =3D 0; + } + ohci_stop_endpoints(s); + + if (!ohci->masterbus) { + usb_bus_release(&s->bus); + } + + timer_free(s->eof_timer); +} + +static void usb_ohci_reset_pci(DeviceState *d) +{ + PCIDevice *dev =3D PCI_DEVICE(d); + OHCIPCIState *ohci =3D NSC_PCI_OHCI(dev); + OHCIState *s =3D &ohci->state; + + ohci_hard_reset(s); + + ohci->nsc_control =3D NSC_CONTROL_RESET; + ohci->nsc_status =3D 0; +} + +static const Property ohci_pci_properties[] =3D { + DEFINE_PROP_STRING("masterbus", OHCIPCIState, masterbus), + DEFINE_PROP_UINT32("num-ports", OHCIPCIState, num_ports, 3), + DEFINE_PROP_UINT32("firstport", OHCIPCIState, firstport, 0), +}; + +static const VMStateDescription vmstate_ohci =3D { + .name =3D "pc87560-ohci", + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (const VMStateField[]) { + VMSTATE_PCI_DEVICE(parent_obj, OHCIPCIState), + VMSTATE_STRUCT(state, OHCIPCIState, 1, vmstate_ohci_state, OHCISta= te), + VMSTATE_UINT32(nsc_control, OHCIPCIState), + VMSTATE_UINT32(nsc_status, OHCIPCIState), + VMSTATE_END_OF_LIST() + } +}; + +static void ohci_pci_class_init(ObjectClass *klass, const void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + PCIDeviceClass *k =3D PCI_DEVICE_CLASS(klass); + + k->realize =3D usb_ohci_realize_pci; + k->exit =3D usb_ohci_exit; + k->config_read =3D pc87560_ohci_config_read; + k->config_write =3D pc87560_ohci_config_write; + k->vendor_id =3D PCI_VENDOR_ID_NS; + k->device_id =3D PCI_DEVICE_ID_NS_87560_USB; + k->revision =3D 0x01; + k->class_id =3D PCI_CLASS_SERIAL_USB; + k->subsystem_vendor_id =3D PCI_VENDOR_ID_HP; + k->subsystem_id =3D 0x10A7; + + set_bit(DEVICE_CATEGORY_USB, dc->categories); + dc->desc =3D "National Semiconductor USB Controller"; + device_class_set_props(dc, ohci_pci_properties); + dc->hotpluggable =3D false; + dc->user_creatable =3D false; + dc->vmsd =3D &vmstate_ohci; + device_class_set_legacy_reset(dc, usb_ohci_reset_pci); +} + +static const TypeInfo ohci_pci_info =3D { + .name =3D TYPE_NSC_PCI_OHCI, + .parent =3D TYPE_PCI_DEVICE, + .instance_size =3D sizeof(OHCIPCIState), + .class_init =3D ohci_pci_class_init, + .interfaces =3D (const InterfaceInfo[]) { + { INTERFACE_CONVENTIONAL_PCI_DEVICE }, + { }, + }, +}; + +static void ohci_pci_register_types(void) +{ + type_register_static(&ohci_pci_info); +} + +type_init(ohci_pci_register_types) --=20 2.54.0 From nobody Sat Sep 26 20:50:17 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=kernel.org ARC-Seal: i=1; a=rsa-sha256; t=1789680956; cv=none; d=zohomail.com; s=zohoarc; b=GkAq5IDK3Ii+3qK/l6wWo4ZaYlc/m5mNaQG6PmOQYM6XgJms2uyNQfA+UDHWy5iAECfIbsZ+wwFUSLCIqnqSpZvOgDZGXb4BZVaAjgsaOsDFFEe0XFIYynNA8bjhdE1KXdLGAxq53czB40SsYBSIqCAQi1UKjCib2ZFrYjQ929U= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1789680956; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=9uo/+I4cswb4xdQvbLnSxCqgYRLjAK5uSCjQBc2QM44=; b=Rc4rpZA2tbNsGfUWO6MS3q20LuYlbNE0AhGUhmOIsShJDZHAeaJslPhd7gf55nVa3R11qwQhPBFr/5EgBYVE9YWw0MTEUqF+WMiw9nJeNAmMT/5F89WaQvl61lt+xs4YrOo7CFwc/DL5eCvU4A8D/Pq6uMsZ7cY2KFwBw9rjq54= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1789680956273850.6393071515981; Thu, 17 Sep 2026 14:35:56 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x7Jkb-0007zW-5g; Thu, 17 Sep 2026 17:34:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x7JkZ-0007yb-4u; Thu, 17 Sep 2026 17:34:35 -0400 Received: from sea.source.kernel.org ([172.234.252.31]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x7JkO-0005zA-JA; Thu, 17 Sep 2026 17:34:34 -0400 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by sea.source.kernel.org (Postfix) with ESMTP id 727B7435D7; Thu, 17 Sep 2026 21:34:20 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7C3B71F000FF; Thu, 17 Sep 2026 21:34:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1789680860; bh=9uo/+I4cswb4xdQvbLnSxCqgYRLjAK5uSCjQBc2QM44=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=emesaVW9coVHiLo/srwmMETgphlPwsS3GasziPikXoqv8mKzGzUTB3RQoKjpJZv/X /Ur38yqbkc0QjWEQpOf3F0jzyCbeQvXUTVOKymuF6jeSQpFk2myh/OGTFVdG2p3N0G 8Gjvj2EL0RThnMQeNVHLv9LEapObF1fCROg6Ah6LwwRpsPJEOxT6/DoI7sH3niNURO OezqFVfDjKYloKf5guAIXcgAx5FOsFn6wRpX12nRKqgIQoAeqBbSM/ZkwCGRvdUE90 j2Xub2hYoXzt2GRwjeAy7fN8lK4WK7zUApGsvDk1zUphqNhjaFSxvfL1zOIcVDYM59 /ZiMzsy9IPsyw== From: Helge Deller To: qemu-devel@nongnu.org Cc: "Michael S. Tsirkin" , "Denis V. Lunev" , Helge Deller , John Snow , Richard Henderson , Paolo Bonzini , Abizer Lokhandwala , qemu-block@nongnu.org Subject: [PATCH 6/7] hw/pc87560: Wire up emulation of NS 87560 SuperIO chip Date: Thu, 17 Sep 2026 23:33:59 +0200 Message-ID: <20260917213402.3127-7-deller@kernel.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260917213402.3127-1-deller@kernel.org> References: <20260917213402.3127-1-deller@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=172.234.252.31; envelope-from=deller@kernel.org; helo=sea.source.kernel.org 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, DKIMWL_WL_HIGH=-0.001, 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: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @kernel.org) X-ZM-MESSAGEID: 1789680957115158500 Content-Type: text/plain; charset="utf-8" From: Abizer Lokhandwala Put everything together and add the meson code to enable build of the IDE-, USB- and core portions of the NS SuperIO chip. Signed-off-by: Abizer Lokhandwala Signed-off-by: Helge Deller --- hw/ide/meson.build | 1 + hw/isa/meson.build | 1 + hw/usb/meson.build | 1 + 3 files changed, 3 insertions(+) diff --git a/hw/ide/meson.build b/hw/ide/meson.build index ddd7066040..be82ee8974 100644 --- a/hw/ide/meson.build +++ b/hw/ide/meson.build @@ -14,3 +14,4 @@ system_ss.add(when: 'CONFIG_IDE_PCI', if_true: files('pci= .c')) system_ss.add(when: 'CONFIG_IDE_PIIX', if_true: files('piix.c', 'ioport.c'= )) system_ss.add(when: 'CONFIG_IDE_SII3112', if_true: files('sii3112.c')) system_ss.add(when: 'CONFIG_IDE_VIA', if_true: files('via.c')) +system_ss.add(when: 'CONFIG_PC87560', if_true: files('pc87560-ide.c')) diff --git a/hw/isa/meson.build b/hw/isa/meson.build index 3219282217..1a150e7069 100644 --- a/hw/isa/meson.build +++ b/hw/isa/meson.build @@ -8,4 +8,5 @@ system_ss.add(when: 'CONFIG_PIIX', if_true: files('piix.c')) system_ss.add(when: 'CONFIG_SMC37C669', if_true: files('smc37c669-superio.= c')) system_ss.add(when: 'CONFIG_VT82C686', if_true: files('vt82c686.c')) =20 +specific_ss.add(when: 'CONFIG_PC87560', if_true: files('pc87560.c')) specific_ss.add(when: 'CONFIG_LPC_ICH9', if_true: files('lpc_ich9.c')) diff --git a/hw/usb/meson.build b/hw/usb/meson.build index d4ba60a91c..429dcd6a24 100644 --- a/hw/usb/meson.build +++ b/hw/usb/meson.build @@ -45,6 +45,7 @@ system_ss.add(when: 'CONFIG_USB_STORAGE_UAS', if_true: fi= les('dev-uas.c')) system_ss.add(when: 'CONFIG_USB_AUDIO', if_true: files('dev-audio.c')) system_ss.add(when: 'CONFIG_USB_SERIAL', if_true: files('dev-serial.c')) system_ss.add(when: 'CONFIG_USB_NETWORK', if_true: files('dev-network.c')) +system_ss.add(when: 'CONFIG_PC87560', if_true: files('pc87560-ohci.c')) if host_os !=3D 'windows' system_ss.add(when: 'CONFIG_USB_STORAGE_MTP', if_true: files('dev-mtp.c'= )) endif --=20 2.54.0 From nobody Sat Sep 26 20:50:17 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=kernel.org ARC-Seal: i=1; a=rsa-sha256; t=1789680966; cv=none; d=zohomail.com; s=zohoarc; b=E3t2y83rE8ZLqmUVrfxxuwqarh030UESclrOmIhj/sRNNoJpSK9+lGpSPCq/90HoieRGaJc1pFzyHdNl4acKztVrpPxCEM5xCOHQLKICGMR14de6F8+nd94ltm0HgRGFjBDin4aBsMG8BYnBco80PgYkUU4/z7UrDgp99lkiVaM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1789680966; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=FhRw3AtyOopeiazjNZ1pbw976Fvw+qCbMTto/y6m/4k=; b=jGTR0x3T4RNgIEZ8okKNJOrefu6Bniwo11phhkb2At6v2TiVqmS1rTkqhKlDoYEEItNybYzD2jo+hu2aFRC9JPLaBM9GgvEnX8w9x1gi+VYcBnmNayQ7aWoIE6mE/BPuCtZXc1xracJbtI/CyFo+kWk9u0k1JV0R0QsNPzq+bDI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1789680966230245.69204165031817; Thu, 17 Sep 2026 14:36:06 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x7Jkc-0007zq-JC; Thu, 17 Sep 2026 17:34:38 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x7JkZ-0007z4-V3; Thu, 17 Sep 2026 17:34:36 -0400 Received: from sea.source.kernel.org ([2600:3c0a:e001:78e:0:1991:8:25]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1x7JkO-00060X-HW; Thu, 17 Sep 2026 17:34:35 -0400 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by sea.source.kernel.org (Postfix) with ESMTP id B82FC41B32; Thu, 17 Sep 2026 21:34:22 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id C23351F000FF; Thu, 17 Sep 2026 21:34:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1789680862; bh=FhRw3AtyOopeiazjNZ1pbw976Fvw+qCbMTto/y6m/4k=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=Fg8fqrf7J9IuW+I7dPLoqArANxWQ9Ccnezi6o7raHhtdBnTW7YnIu6EX6kPfPwPb/ 6hzJWJxqiXaa8/0EsWz5Xd2Xbz9O0Oqh2rkl87MSHVvzNHCtitqaFcr8mwjBJwPaPB Ws/mX51nwboh80ohpeMp+dMJ8Eew7RCFvHUwzsFaGE7smct+HFBjR59c261sAY+QYB f+NRfgJYq42ynLtm5isSN3rXbKsIl9OBkBBxMDE+JXYbh9LUQ2TTjP4L4xhCkAxq1O g6KdFfPJNzuOoiatJTvjfxNLQkW71v2+Pmh0gKl3uP+E7aECisRaQ7No866sSRJZTC IVRfosifvwyYw== From: Helge Deller To: qemu-devel@nongnu.org Cc: "Michael S. Tsirkin" , "Denis V. Lunev" , Helge Deller , John Snow , Richard Henderson , Paolo Bonzini , Abizer Lokhandwala , qemu-block@nongnu.org Subject: [PATCH 7/7] hw/hppa: Add NS 87560 SuperIO chip to HP C3700 machine Date: Thu, 17 Sep 2026 23:34:00 +0200 Message-ID: <20260917213402.3127-8-deller@kernel.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260917213402.3127-1-deller@kernel.org> References: <20260917213402.3127-1-deller@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2600:3c0a:e001:78e:0:1991:8:25; envelope-from=deller@kernel.org; helo=sea.source.kernel.org 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, DKIMWL_WL_HIGH=-0.001, 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: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @kernel.org) X-ZM-MESSAGEID: 1789680967025158500 Content-Type: text/plain; charset="utf-8" From: Abizer Lokhandwala Due to the lack of the emulated NS 87560 SuperIO chip, we used until now the emulated serial ports of a Diva GSP management board as a temporary replacement. Since the NS SuperIO chip emulation was just added in the previous commits, switch over to use it which allows us to emulate the phys= ical hardware more closely. Signed-off-by: Abizer Lokhandwala Signed-off-by: Helge Deller --- hw/hppa/machine.c | 41 ++++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c index 98931481b2..96133f09ba 100644 --- a/hw/hppa/machine.c +++ b/hw/hppa/machine.c @@ -394,7 +394,7 @@ static TranslateFn *machine_HP_common_init_cpus(Machine= State *machine) * Last creation step: Add NICs, graphics & load firmware */ static void machine_HP_common_init_tail(MachineState *machine, PCIBus *pci= _bus, - TranslateFn *translate) + TranslateFn *translate, bool create_di= va) { const char *kernel_filename =3D machine->kernel_filename; MachineClass *mc =3D MACHINE_GET_CLASS(machine); @@ -426,7 +426,7 @@ static void machine_HP_common_init_tail(MachineState *m= achine, PCIBus *pci_bus, pci_init_nic_devices(pci_bus, mc->default_nic); } =20 - if (pci_bus && hppa_is_pa20(&cpu[0]->env)) { + if (pci_bus && hppa_is_pa20(&cpu[0]->env) && create_diva) { /* BMC board: HP Diva GSP PCI card */ pci_dev =3D pci_new_multifunction(PCI_DEVFN(2, 0), "diva-gsp"); if (!lasi_dev) { @@ -442,8 +442,9 @@ static void machine_HP_common_init_tail(MachineState *m= achine, PCIBus *pci_bus, /* create USB OHCI controller for USB keyboard & mouse on Astro machin= es */ if (!lasi_dev && machine->enable_graphics && defaults_enabled()) { USBBus *usb_bus; - - pci_create_simple(pci_bus, -1, "pci-ohci"); + if (create_diva) { + pci_create_simple(pci_bus, -1, "pci-ohci"); + } usb_bus =3D USB_BUS(object_resolve_type_unambiguous(TYPE_USB_BUS, &error_abort)); usb_create_simple(usb_bus, "usb-kbd"); @@ -647,7 +648,7 @@ static void machine_HP_715_init(MachineState *machine) } =20 /* Add NICs, graphics & load firmware */ - machine_HP_common_init_tail(machine, NULL, translate); + machine_HP_common_init_tail(machine, NULL, translate, false); } =20 /* @@ -726,7 +727,7 @@ static void machine_HP_B160L_init(MachineState *machine) } =20 /* Add NICs, graphics & load firmware */ - machine_HP_common_init_tail(machine, pci_bus, translate); + machine_HP_common_init_tail(machine, pci_bus, translate, false); } =20 static AstroState *astro_init(void) @@ -771,6 +772,32 @@ static void machine_HP_C3700_init(MachineState *machin= e) pci_bus =3D PCI_BUS(qdev_get_child_bus(DEVICE(astro->elroy[0]), "pci")= ); assert(pci_bus); =20 + /* The C3700 has a SuperIO chip, while the A400 hasn't. */ + MachineClass *mc =3D MACHINE_GET_CLASS(machine); + bool is_C3700 =3D strcmp(mc->name, "C3700") =3D=3D 0; + if (is_C3700) { + PCIDevice *ide_pdev =3D pci_create_simple(pci_bus, PCI_DEVFN(2, 0), + "pc87560-ide"); + PCIDevice *usb_pdev =3D pci_create_simple(pci_bus, PCI_DEVFN(2, 2), + "pc87560-ohci"); + PCIDevice *sio_pdev =3D pci_new(PCI_DEVFN(2, 1), "pc87560-superio"= ); + if (serial_hd(0)) { + qdev_prop_set_chr(DEVICE(sio_pdev), "serial0", serial_hd(0)); + } + if (serial_hd(1)) { + qdev_prop_set_chr(DEVICE(sio_pdev), "serial1", serial_hd(1)); + } + pci_realize_and_unref(sio_pdev, pci_bus, &error_fatal); + + qdev_connect_gpio_out(DEVICE(ide_pdev), 0, + qdev_get_gpio_in_named(DEVICE(sio_pdev), "pic-irq", 7)); + qdev_connect_gpio_out(DEVICE(usb_pdev), 0, + qdev_get_gpio_in_named(DEVICE(sio_pdev), "pic-irq", 1)); + + qdev_connect_gpio_out_named(DEVICE(sio_pdev), "pic-out", 0, + pci_allocate_irq(usb_pdev)); + } + /* SCSI disk setup. */ if (drive_get_max_bus(IF_SCSI) >=3D 0) { DeviceState *dev =3D DEVICE(pci_create_simple(pci_bus, -1, "lsi53c= 895a")); @@ -778,7 +805,7 @@ static void machine_HP_C3700_init(MachineState *machine) } =20 /* Add NICs, graphics & load firmware */ - machine_HP_common_init_tail(machine, pci_bus, translate); + machine_HP_common_init_tail(machine, pci_bus, translate, !is_C3700); } =20 /* --=20 2.54.0