From: Kevin Wolf <kwolf@redhat.com>
To: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Cc: jsnow@redhat.com, qemu-block@nongnu.org, qemu-devel@nongnu.org,
balaton@eik.bme.hu, philmd@linaro.org, shentey@gmail.com
Subject: Re: [PATCH v2 1/3] ide/pci.c: introduce pci_ide_update_mode() function
Date: Mon, 6 Nov 2023 15:12:27 +0100 [thread overview]
Message-ID: <ZUj0S6GqGhZ6kOp9@redhat.com> (raw)
In-Reply-To: <20231024224056.842607-2-mark.cave-ayland@ilande.co.uk>
Am 25.10.2023 um 00:40 hat Mark Cave-Ayland geschrieben:
> 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 <mark.cave-ayland@ilande.co.uk>
> Tested-by: BALATON Zoltan <balaton@eik.bme.hu>
> Tested-by: Bernhard Beschow <shentey@gmail.com>
> ---
> 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..5be643b460 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(),
> +};
This is duplicated from hw/ide/ioport.c. I think it would be better to
use the arrays already defined there, ideally by calling ioport.c
functions to setup and release the I/O ports.
> +void pci_ide_update_mode(PCIIDEState *s)
> +{
> + PCIDevice *d = PCI_DEVICE(s);
> + uint8_t mode = d->config[PCI_CLASS_PROG];
> +
> + switch (mode & 0xf) {
> + case 0xa:
> + /* Both channels legacy mode */
Why is it ok to handle only the case where both channels are set to the
same mode? The spec describes mixed-mode setups, too, and doesn't seem
to allow ignoring a mode change if it's only for one of the channels.
> +
> + /* 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);
Here I'm not sure what the spec really implies. Disabling the BAR (i.e.
making it read-only and returning 0) while in compatibility mode doesn't
necessarily mean that the value of the register is lost. In other words,
are we sure that a driver can't expect that the old value is still there
when it re-enables native mode?
> + /* Clear interrupt pin */
> + pci_config_set_interrupt_pin(d->config, 0);
Unlike for the BARs, I don't see anything in the spec that allows
disabling this byte. I doubt it hurts in practice, but did you see any
drivers requiring this? According to the spec, we just must not use the
PCI interrupt in compatbility mode, but the registers stay accessible.
As far as I can see, the whole PCI interrupt configuration is currently
unused anyway, and nothing in this series seems to change it. So won't
we incorrectly continue to use the legacy interrupt even in native mode?
(Actually, cmd646 seems to get it wrong the other way around and uses
the PCI interrupt even in compatibility mode.)
I think this means that BMDMAState needs to have two irq lines (a legacy
and a PCI one) and select the right one in bmdma_irq() depending on
which mode we're in currently.
> + /* 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;
This is essentially ide_init_ioport(), except that it handles the case
where it is already initialised. Let's reuse it.
> + case 0xf:
> + /* 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;
And this part could be an ioport.c function as well.
> + }
> +}
Kevin
next prev parent reply other threads:[~2023-11-06 14:13 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-24 22:40 [PATCH v2 0/3] ide: implement simple legacy/native mode switching for PCI IDE controllers Mark Cave-Ayland
2023-10-24 22:40 ` [PATCH v2 1/3] ide/pci.c: introduce pci_ide_update_mode() function Mark Cave-Ayland
2023-11-06 14:12 ` Kevin Wolf [this message]
2023-11-06 22:41 ` Mark Cave-Ayland
2023-11-07 11:11 ` Kevin Wolf
2023-11-13 21:24 ` Mark Cave-Ayland
2023-11-13 23:47 ` BALATON Zoltan
2023-11-14 17:59 ` Kevin Wolf
2023-10-24 22:40 ` [PATCH v2 2/3] ide/via: don't attempt to set default BAR addresses Mark Cave-Ayland
2023-10-24 23:06 ` BALATON Zoltan
2023-10-24 22:40 ` [PATCH v2 3/3] hw/ide/via: implement legacy/native mode switching Mark Cave-Ayland
2023-11-06 14:35 ` Kevin Wolf
2023-11-06 16:13 ` BALATON Zoltan
2023-11-07 10:43 ` Kevin Wolf
2023-11-13 20:45 ` Mark Cave-Ayland
2023-11-14 0:04 ` BALATON Zoltan
2023-11-01 10:49 ` [PATCH v2 0/3] ide: implement simple legacy/native mode switching for PCI IDE controllers BALATON Zoltan
2023-11-02 9:03 ` Bernhard Beschow
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ZUj0S6GqGhZ6kOp9@redhat.com \
--to=kwolf@redhat.com \
--cc=balaton@eik.bme.hu \
--cc=jsnow@redhat.com \
--cc=mark.cave-ayland@ilande.co.uk \
--cc=philmd@linaro.org \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=shentey@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).