From patchwork Thu Oct 19 13:04: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: 13429127 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 C7525CDB465 for ; Thu, 19 Oct 2023 13:09:36 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qtSip-0006uU-J7; Thu, 19 Oct 2023 09:05: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 1qtSiA-0005sY-7C; Thu, 19 Oct 2023 09:05:15 -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 1qtSi6-0005h2-F9; Thu, 19 Oct 2023 09:05:13 -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=2gEit6liHFCMLibqTayVSsv8R4xIMILqlK3LCzt4uHc=; b=EKlU4Y5v6aNUDjxJox8amLxczC BlNSQ9ajtgjUtv4aU3YZ2MLmlETI2FTDZmQ5qvMVesc3Jfn+JxXDORGX76LFf5k8dgilfxgJbADB2 bhcilsioe5tWQ+Am5AHNsYt0ef24BJRPIjvb0cusOzyBsHJFZommuZQdxXw7EuXKxFGiwq9UbVX6n Cc7knNUFscYK2iVGL6wiwad/YUejvvC1GhRXKyQarA1k1+N4naJLgyXubcKDIHfbiW5tU2JQO5AQN wGtRN1ko00eUfZtz9Yd0ZndI+tEHFan+sS7I/G5KDcUq2P7SXGioGGzh3mI86kKh818u7wEZXOiP0 tGYSABb7RUvxKG+RpG2dExH++X/H8/sdNL62XsUy7ShGMAyogH864X74DsXgQIMJP725JwwjjN44Z 7vCIL5yNQXUftBZ5ybRDuRftYeHdrZuN/To+lBtqaSnW895ot5hczb2TBfBH9I4AjLONxfI4aoJw1 q+jFkEX2TB0vJpBVg/8dDR7pDkC+4JqHE1bzSGPE6Dd2OCoR7PjPWzs9SiZiZemK7UhiCm5bHHBEG BdTZ2MpmJY2xL8yJsEOsfC7jcGbMG8Gf3H8FFcsUcpf2OqxwnDq6brJRpjVBJTQC1GpdazDofI1B5 imTJo5eATA9G0RR5LEAPOV2OClgFgL8EhxMZDdWT4=; Received: from host86-130-37-248.range86-130.btcentralplus.com ([86.130.37.248] 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 1qtShw-0006iW-Lx; Thu, 19 Oct 2023 14:05:04 +0100 From: Mark Cave-Ayland To: jsnow@redhat.com, qemu-block@nongnu.org, qemu-devel@nongnu.org, balaton@eik.bme.hu, philmd@linaro.org, shentey@gmail.com Date: Thu, 19 Oct 2023 14:04:51 +0100 Message-Id: <20231019130452.508426-2-mark.cave-ayland@ilande.co.uk> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231019130452.508426-1-mark.cave-ayland@ilande.co.uk> References: <20231019130452.508426-1-mark.cave-ayland@ilande.co.uk> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 86.130.37.248 X-SA-Exim-Mail-From: mark.cave-ayland@ilande.co.uk Subject: [PATCH 1/2] ide/pci.c: introduce pci_ide_update_mode() function 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 function reads the value of the PCI_CLASS_PROG register for PCI IDE controllers and configures the PCI BARs and/or IDE ioports accordingly. In the case where we switch to legacy mode, the PCI BARs are set to return zero (as suggested in the "PCI IDE Controller" specification), the legacy IDE ioports are enabled, and the PCI interrupt pin cleared to indicate legacy IRQ routing. Conversely when we switch to native mode, the legacy IDE ioports are disabled and the PCI interrupt pin set to indicate native IRQ routing. The contents of the PCI BARs are unspecified, but this is not an issue since if a PCI IDE controller has been switched to native mode then its BARs will need to be programmed. Signed-off-by: Mark Cave-Ayland --- hw/ide/pci.c | 90 ++++++++++++++++++++++++++++++++++++++++++++ include/hw/ide/pci.h | 1 + 2 files changed, 91 insertions(+) diff --git a/hw/ide/pci.c b/hw/ide/pci.c index a25b352537..9eb30af632 100644 --- a/hw/ide/pci.c +++ b/hw/ide/pci.c @@ -104,6 +104,96 @@ const MemoryRegionOps pci_ide_data_le_ops = { .endianness = DEVICE_LITTLE_ENDIAN, }; +static const MemoryRegionPortio ide_portio_list[] = { + { 0, 8, 1, .read = ide_ioport_read, .write = ide_ioport_write }, + { 0, 1, 2, .read = ide_data_readw, .write = ide_data_writew }, + { 0, 1, 4, .read = ide_data_readl, .write = ide_data_writel }, + PORTIO_END_OF_LIST(), +}; + +static const MemoryRegionPortio ide_portio2_list[] = { + { 0, 1, 1, .read = ide_status_read, .write = ide_ctrl_write }, + PORTIO_END_OF_LIST(), +}; + +void pci_ide_update_mode(PCIIDEState *s) +{ + PCIDevice *d = PCI_DEVICE(s); + uint8_t mode = d->config[PCI_CLASS_PROG]; + + switch (mode) { + case 0x8a: + /* Both channels legacy mode */ + + /* Zero BARs */ + pci_set_long(d->config + PCI_BASE_ADDRESS_0, 0x0); + pci_set_long(d->config + PCI_BASE_ADDRESS_1, 0x0); + pci_set_long(d->config + PCI_BASE_ADDRESS_2, 0x0); + pci_set_long(d->config + PCI_BASE_ADDRESS_3, 0x0); + + /* Clear interrupt pin */ + pci_config_set_interrupt_pin(d->config, 0); + + /* Add legacy IDE ports */ + if (!s->bus[0].portio_list.owner) { + portio_list_init(&s->bus[0].portio_list, OBJECT(d), + ide_portio_list, &s->bus[0], "ide"); + portio_list_add(&s->bus[0].portio_list, + pci_address_space_io(d), 0x1f0); + } + + if (!s->bus[0].portio2_list.owner) { + portio_list_init(&s->bus[0].portio2_list, OBJECT(d), + ide_portio2_list, &s->bus[0], "ide"); + portio_list_add(&s->bus[0].portio2_list, + pci_address_space_io(d), 0x3f6); + } + + if (!s->bus[1].portio_list.owner) { + portio_list_init(&s->bus[1].portio_list, OBJECT(d), + ide_portio_list, &s->bus[1], "ide"); + portio_list_add(&s->bus[1].portio_list, + pci_address_space_io(d), 0x170); + } + + if (!s->bus[1].portio2_list.owner) { + portio_list_init(&s->bus[1].portio2_list, OBJECT(d), + ide_portio2_list, &s->bus[1], "ide"); + portio_list_add(&s->bus[1].portio2_list, + pci_address_space_io(d), 0x376); + } + break; + + case 0x8f: + /* Both channels native mode */ + + /* Set interrupt pin */ + pci_config_set_interrupt_pin(d->config, 1); + + /* Remove legacy IDE ports */ + if (s->bus[0].portio_list.owner) { + portio_list_del(&s->bus[0].portio_list); + portio_list_destroy(&s->bus[0].portio_list); + } + + if (s->bus[0].portio2_list.owner) { + portio_list_del(&s->bus[0].portio2_list); + portio_list_destroy(&s->bus[0].portio2_list); + } + + if (s->bus[1].portio_list.owner) { + portio_list_del(&s->bus[1].portio_list); + portio_list_destroy(&s->bus[1].portio_list); + } + + if (s->bus[1].portio2_list.owner) { + portio_list_del(&s->bus[1].portio2_list); + portio_list_destroy(&s->bus[1].portio2_list); + } + break; + } +} + static IDEState *bmdma_active_if(BMDMAState *bmdma) { assert(bmdma->bus->retry_unit != (uint8_t)-1); diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h index 1ff469de87..a814a0a7c3 100644 --- a/include/hw/ide/pci.h +++ b/include/hw/ide/pci.h @@ -61,6 +61,7 @@ void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val); void bmdma_status_writeb(BMDMAState *bm, uint32_t val); extern MemoryRegionOps bmdma_addr_ioport_ops; void pci_ide_create_devs(PCIDevice *dev); +void pci_ide_update_mode(PCIIDEState *s); extern const VMStateDescription vmstate_ide_pci; extern const MemoryRegionOps pci_ide_cmd_le_ops; From patchwork Thu Oct 19 13:04:52 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: 13429124 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 6FD7BCDB465 for ; Thu, 19 Oct 2023 13:08:24 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qtSiq-0006xi-5c; Thu, 19 Oct 2023 09:05: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 1qtSiD-00067h-NH; Thu, 19 Oct 2023 09:05: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 1qtSiB-0005hq-EP; Thu, 19 Oct 2023 09:05: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=VRRbRVpnG45VT30RoNT9iVwXDIgnElwwGsandZ69zOU=; b=RK0Bu0aRC3QPXbdGiXPlbMQGk9 ysHBpNi5DxZ+WapqUoBRJZT/x1Qh58uTOSyQgdIseTf9rcTzH5VKWtMkRrnzyzcjXFKL2+tl7rexf v/WV4FGv6w7t3DIJAhQwKj9vkqmr9hif+9MyCABymPFffFv7LVshYoeA77/YOJZP+/tRkcz2V/d7E 2fOCoyFl//kwJYawUxBzS9xg+EhZz/uzgt0Yi2D84FeJTVPQLdvpDglckqSJ0EUWr7PbuuOWTrfbE v3/dWX230XsqO96oree5cmPaeDN0/7pMVT8noQLEKs7EuYA06+ND/ha6FGXe2motzsgyyxYw17Jty spnMNFmA/dyeAAeUDYGsKtVIVYp2lmnoT8kxn0qxQpZN53EOR93R7fUXQKgmpi58KQfSpxnN7lTmM 1qTKCucP9QpISZrgEJuE5AT5vtc6A/6n9t3iXb/SXr15ECiStCVK4CZrkgZ09czB0BJiZkkO9ldF8 v6Cr6ueelgjz+L6HKfGNLyqGG4GLIsdgy5FRGTyhG7+Q7XKJGO9tOvjIOHfW+iD8rLWp//+ix9is/ awBmS6GNUC2nOqB3nquKiGY0UlPqZ49YUXKYwbEhmnC50aYgnU0pVJFMlYyYHbCDbxnDQMi3Lqcbh 1NT8FrkInFQGUwNyu+UKVb8VtE0BgCY+q0CRjXlTE=; Received: from host86-130-37-248.range86-130.btcentralplus.com ([86.130.37.248] 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 1qtSi1-0006iW-1k; Thu, 19 Oct 2023 14:05:09 +0100 From: Mark Cave-Ayland To: jsnow@redhat.com, qemu-block@nongnu.org, qemu-devel@nongnu.org, balaton@eik.bme.hu, philmd@linaro.org, shentey@gmail.com Date: Thu, 19 Oct 2023 14:04:52 +0100 Message-Id: <20231019130452.508426-3-mark.cave-ayland@ilande.co.uk> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231019130452.508426-1-mark.cave-ayland@ilande.co.uk> References: <20231019130452.508426-1-mark.cave-ayland@ilande.co.uk> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 86.130.37.248 X-SA-Exim-Mail-From: mark.cave-ayland@ilande.co.uk Subject: [PATCH 2/2] hw/ide/via: implement legacy/native mode switching 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 Allow the VIA IDE controller to switch between both legacy and native modes by calling pci_ide_update_mode() to reconfigure the device whenever PCI_CLASS_PROG is updated. This patch also moves the setting of PCI_CLASS_PROG from via_ide_realize() to via_ide_reset() and clears PCI_INTERRUPT_PIN to ensure that if a PCI device reset occurs then the device configuration is always consistent. Signed-off-by: Mark Cave-Ayland --- hw/ide/via.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/hw/ide/via.c b/hw/ide/via.c index fff23803a6..e6278dd419 100644 --- a/hw/ide/via.c +++ b/hw/ide/via.c @@ -28,6 +28,7 @@ #include "hw/pci/pci.h" #include "migration/vmstate.h" #include "qemu/module.h" +#include "qemu/range.h" #include "sysemu/dma.h" #include "hw/isa/vt82c686.h" #include "hw/ide/pci.h" @@ -128,6 +129,9 @@ static void via_ide_reset(DeviceState *dev) ide_bus_reset(&d->bus[i]); } + pci_config_set_prog_interface(pci_conf, 0x8a); /* legacy mode */ + pci_ide_update_mode(d); + pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_WAIT); pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_FAST_BACK | PCI_STATUS_DEVSEL_MEDIUM); @@ -137,7 +141,7 @@ static void via_ide_reset(DeviceState *dev) pci_set_long(pci_conf + PCI_BASE_ADDRESS_2, 0x00000170); pci_set_long(pci_conf + PCI_BASE_ADDRESS_3, 0x00000374); pci_set_long(pci_conf + PCI_BASE_ADDRESS_4, 0x0000cc01); /* BMIBA: 20-23h */ - pci_set_long(pci_conf + PCI_INTERRUPT_LINE, 0x0000010e); + pci_set_long(pci_conf + PCI_INTERRUPT_LINE, 0x0000000e); /* IDE chip enable, IDE configuration 1/2, IDE FIFO Configuration*/ pci_set_long(pci_conf + 0x40, 0x0a090600); @@ -159,6 +163,18 @@ static void via_ide_reset(DeviceState *dev) pci_set_long(pci_conf + 0xc0, 0x00020001); } +static void via_ide_cfg_write(PCIDevice *pd, uint32_t addr, + uint32_t val, int len) +{ + PCIIDEState *d = PCI_IDE(pd); + + pci_default_write_config(pd, addr, val, len); + + if (range_covers_byte(addr, len, PCI_CLASS_PROG)) { + pci_ide_update_mode(d); + } +} + static void via_ide_realize(PCIDevice *dev, Error **errp) { PCIIDEState *d = PCI_IDE(dev); @@ -166,7 +182,6 @@ static void via_ide_realize(PCIDevice *dev, Error **errp) uint8_t *pci_conf = dev->config; int i; - pci_config_set_prog_interface(pci_conf, 0x8a); /* legacy mode */ pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x000000c0); dev->wmask[PCI_INTERRUPT_LINE] = 0; dev->wmask[PCI_CLASS_PROG] = 5; @@ -221,6 +236,7 @@ static void via_ide_class_init(ObjectClass *klass, void *data) /* Reason: only works as function of VIA southbridge */ dc->user_creatable = false; + k->config_write = via_ide_cfg_write; k->realize = via_ide_realize; k->exit = via_ide_exitfn; k->vendor_id = PCI_VENDOR_ID_VIA;