All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/13] Clean up PCI IDE device models
@ 2023-04-22 15:07 Bernhard Beschow
  2023-04-22 15:07 ` [PATCH 01/13] hw/ide/pci: Expose legacy interrupts as GPIOs Bernhard Beschow
                   ` (12 more replies)
  0 siblings, 13 replies; 77+ messages in thread
From: Bernhard Beschow @ 2023-04-22 15:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc, Bernhard Beschow

This series is yet another attempt to clean up the PCI IDE models. It is mainly
inspired the Mark's invaluable input from previous discussions. In particular,
this series attempts to follow the "PCI IDE controller specification" closer. As
a side effect, it also resolves usage of the isabus global in PIIX. Last but not
least it fixes the VIA IDE controller to not depend on its south bridge which
fixes a circular dependency.

The series is structured as follows: The first three commits resolve a circular
dependency between the VIA IDE controller and its south bridge, thereby
implementing legacy PCI IDE interrupt routing which was missing so far. The next
five patches factor out common code into the PCI IDE base class. The next two
patches resolve usage of the isabus global in PIIX by reusing now common code
from the base class. The same is then done for the SIL3112 controller. Finally,
a small convenience function is introduced which should hide some implementation
details in the PCI IDE base class.

Testing done:
* `make check`
* `make check-avocado`
* `qemu-system-ppc -machine pegasos2 -rtc base=localtime -device \
   ati-vga,guest_hwcursor=true,romfile="" -cdrom morphos-3.17.iso
   -kernel morphos-3.17/boot.img`
   The machine booted successfully and a startup sound was hearable
* `qemu-system-ppc -machine pegasos2 -rtc base=localtime -device \
   ati-vga,guest_hwcursor=true,romfile="" -cdrom morphos-3.17.iso
   -kernel morphos-3.17/boot.img`
   The machine booted successfully and applications could be started.
* qemu-system-x86_64 was used for hours during work

Bernhard Beschow (13):
  hw/ide/pci: Expose legacy interrupts as GPIOs
  hw/ide/via: Implement ISA IRQ routing
  hw/isa/vt82c686: Remove via_isa_set_irq()
  hw/ide: Extract IDEBus assignment into bmdma_init()
  hw/ide: Extract pci_ide_class_init()
  hw/ide: Extract bmdma_init_ops()
  hw/ide: Extract pci_ide_{cmd,data}_le_ops initialization into base
    class constructor
  hw/ide: Rename PCIIDEState::*_bar attributes
  hw/ide/piix: Disuse isa_get_irq()
  hw/ide/piix: Reuse PCIIDEState::{cmd,data}_ops
  hw/ide/sii3112: Reuse PCIIDEState::{cmd,data}_ops
  hw/ide/sii3112: Reuse PCIIDEState::bmdma_ops
  hw/ide: Extract bmdma_clear_status()

 include/hw/ide/pci.h      |  12 ++-
 include/hw/isa/vt82c686.h |   2 -
 hw/ide/cmd646.c           |  59 ++-------------
 hw/ide/pci.c              |  73 ++++++++++++++++++-
 hw/ide/piix.c             |  88 ++++++++--------------
 hw/ide/sii3112.c          | 150 +++++++++++++++++++-------------------
 hw/ide/via.c              |  64 +++-------------
 hw/isa/vt82c686.c         |  23 ++++--
 hw/ide/trace-events       |   7 +-
 9 files changed, 221 insertions(+), 257 deletions(-)

-- 
2.40.0



^ permalink raw reply	[flat|nested] 77+ messages in thread

* [PATCH 01/13] hw/ide/pci: Expose legacy interrupts as GPIOs
  2023-04-22 15:07 [PATCH 00/13] Clean up PCI IDE device models Bernhard Beschow
@ 2023-04-22 15:07 ` Bernhard Beschow
  2023-04-26 10:41   ` Mark Cave-Ayland
  2023-04-22 15:07 ` [PATCH 02/13] hw/ide/via: Implement ISA IRQ routing Bernhard Beschow
                   ` (11 subsequent siblings)
  12 siblings, 1 reply; 77+ messages in thread
From: Bernhard Beschow @ 2023-04-22 15:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc, Bernhard Beschow

Exposing the legacy IDE interrupts as GPIOs allows them to be connected in the
parent device through qdev_connect_gpio_out(), i.e. without accessing private
data of TYPE_PCI_IDE.

Signed-off-by: Bernhard Beschow <shentey@gmail.com>
---
 hw/ide/pci.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index fc9224bbc9..942e216b9b 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -522,10 +522,18 @@ void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d)
     bm->pci_dev = d;
 }
 
+static void pci_ide_init(Object *obj)
+{
+    PCIIDEState *d = PCI_IDE(obj);
+
+    qdev_init_gpio_out(DEVICE(d), d->isa_irq, ARRAY_SIZE(d->isa_irq));
+}
+
 static const TypeInfo pci_ide_type_info = {
     .name = TYPE_PCI_IDE,
     .parent = TYPE_PCI_DEVICE,
     .instance_size = sizeof(PCIIDEState),
+    .instance_init = pci_ide_init,
     .abstract = true,
     .interfaces = (InterfaceInfo[]) {
         { INTERFACE_CONVENTIONAL_PCI_DEVICE },
-- 
2.40.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 02/13] hw/ide/via: Implement ISA IRQ routing
  2023-04-22 15:07 [PATCH 00/13] Clean up PCI IDE device models Bernhard Beschow
  2023-04-22 15:07 ` [PATCH 01/13] hw/ide/pci: Expose legacy interrupts as GPIOs Bernhard Beschow
@ 2023-04-22 15:07 ` Bernhard Beschow
  2023-04-22 17:23   ` BALATON Zoltan
  2023-04-26 10:55   ` Mark Cave-Ayland
  2023-04-22 15:07 ` [PATCH 03/13] hw/isa/vt82c686: Remove via_isa_set_irq() Bernhard Beschow
                   ` (10 subsequent siblings)
  12 siblings, 2 replies; 77+ messages in thread
From: Bernhard Beschow @ 2023-04-22 15:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc, Bernhard Beschow

The VIA south bridge allows the legacy IDE interrupts to be routed to four
different ISA interrupts. This can be configured through the 0x4a register in
the PCI configuration space of the ISA function. The default routing matches
the legacy ISA IRQs, that is 14 and 15.

Implement this missing piece of the VIA south bridge.

Signed-off-by: Bernhard Beschow <shentey@gmail.com>
---
 hw/ide/via.c      |  6 ++++--
 hw/isa/vt82c686.c | 17 +++++++++++++++++
 2 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/hw/ide/via.c b/hw/ide/via.c
index 177baea9a7..0caae52276 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -31,6 +31,7 @@
 #include "sysemu/dma.h"
 #include "hw/isa/vt82c686.h"
 #include "hw/ide/pci.h"
+#include "hw/irq.h"
 #include "trace.h"
 
 static uint64_t bmdma_read(void *opaque, hwaddr addr,
@@ -104,7 +105,8 @@ static void bmdma_setup_bar(PCIIDEState *d)
 
 static void via_ide_set_irq(void *opaque, int n, int level)
 {
-    PCIDevice *d = PCI_DEVICE(opaque);
+    PCIIDEState *s = opaque;
+    PCIDevice *d = PCI_DEVICE(s);
 
     if (level) {
         d->config[0x70 + n * 8] |= 0x80;
@@ -112,7 +114,7 @@ static void via_ide_set_irq(void *opaque, int n, int level)
         d->config[0x70 + n * 8] &= ~0x80;
     }
 
-    via_isa_set_irq(pci_get_function_0(d), 14 + n, level);
+    qemu_set_irq(s->isa_irq[n], level);
 }
 
 static void via_ide_reset(DeviceState *dev)
diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index ca89119ce0..c7e29bb46a 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -568,9 +568,19 @@ static const VMStateDescription vmstate_via = {
     }
 };
 
+static void via_isa_set_ide_irq(void *opaque, int n, int level)
+{
+    static const uint8_t irqs[] = { 14, 15, 10, 11 };
+    ViaISAState *s = opaque;
+    uint8_t irq = irqs[(s->dev.config[0x4a] >> (n * 2)) & 0x3];
+
+    qemu_set_irq(s->isa_irqs_in[irq], level);
+}
+
 static void via_isa_init(Object *obj)
 {
     ViaISAState *s = VIA_ISA(obj);
+    DeviceState *dev = DEVICE(s);
 
     object_initialize_child(obj, "rtc", &s->rtc, TYPE_MC146818_RTC);
     object_initialize_child(obj, "ide", &s->ide, TYPE_VIA_IDE);
@@ -578,6 +588,8 @@ static void via_isa_init(Object *obj)
     object_initialize_child(obj, "uhci2", &s->uhci[1], TYPE_VT82C686B_USB_UHCI);
     object_initialize_child(obj, "ac97", &s->ac97, TYPE_VIA_AC97);
     object_initialize_child(obj, "mc97", &s->mc97, TYPE_VIA_MC97);
+
+    qdev_init_gpio_in_named(dev, via_isa_set_ide_irq, "ide", ARRAY_SIZE(s->ide.isa_irq));
 }
 
 static const TypeInfo via_isa_info = {
@@ -692,6 +704,10 @@ static void via_isa_realize(PCIDevice *d, Error **errp)
     if (!qdev_realize(DEVICE(&s->ide), BUS(pci_bus), errp)) {
         return;
     }
+    for (i = 0; i < 2; i++) {
+        qdev_connect_gpio_out(DEVICE(&s->ide), i,
+                              qdev_get_gpio_in_named(DEVICE(s), "ide", i));
+    }
 
     /* Functions 2-3: USB Ports */
     for (i = 0; i < ARRAY_SIZE(s->uhci); i++) {
@@ -814,6 +830,7 @@ static void vt8231_isa_reset(DeviceState *dev)
                  PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL);
     pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM);
 
+    pci_conf[0x4a] = 0x04; /* IDE interrupt Routing */
     pci_conf[0x58] = 0x40; /* Miscellaneous Control 0 */
     pci_conf[0x67] = 0x08; /* Fast IR Config */
     pci_conf[0x6b] = 0x01; /* Fast IR I/O Base */
-- 
2.40.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 03/13] hw/isa/vt82c686: Remove via_isa_set_irq()
  2023-04-22 15:07 [PATCH 00/13] Clean up PCI IDE device models Bernhard Beschow
  2023-04-22 15:07 ` [PATCH 01/13] hw/ide/pci: Expose legacy interrupts as GPIOs Bernhard Beschow
  2023-04-22 15:07 ` [PATCH 02/13] hw/ide/via: Implement ISA IRQ routing Bernhard Beschow
@ 2023-04-22 15:07 ` Bernhard Beschow
  2023-04-26 10:55   ` Mark Cave-Ayland
  2023-04-22 15:07 ` [PATCH 04/13] hw/ide: Extract IDEBus assignment into bmdma_init() Bernhard Beschow
                   ` (9 subsequent siblings)
  12 siblings, 1 reply; 77+ messages in thread
From: Bernhard Beschow @ 2023-04-22 15:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc, Bernhard Beschow

Now that via_isa_set_irq() is unused it can be removed.

Signed-off-by: Bernhard Beschow <shentey@gmail.com>
---
 include/hw/isa/vt82c686.h | 2 --
 hw/isa/vt82c686.c         | 6 ------
 2 files changed, 8 deletions(-)

diff --git a/include/hw/isa/vt82c686.h b/include/hw/isa/vt82c686.h
index da1722daf2..b6e95b2851 100644
--- a/include/hw/isa/vt82c686.h
+++ b/include/hw/isa/vt82c686.h
@@ -34,6 +34,4 @@ struct ViaAC97State {
     uint32_t ac97_cmd;
 };
 
-void via_isa_set_irq(PCIDevice *d, int n, int level);
-
 #endif
diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index c7e29bb46a..a69888a396 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -604,12 +604,6 @@ static const TypeInfo via_isa_info = {
     },
 };
 
-void via_isa_set_irq(PCIDevice *d, int n, int level)
-{
-    ViaISAState *s = VIA_ISA(d);
-    qemu_set_irq(s->isa_irqs_in[n], level);
-}
-
 static void via_isa_request_i8259_irq(void *opaque, int irq, int level)
 {
     ViaISAState *s = opaque;
-- 
2.40.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 04/13] hw/ide: Extract IDEBus assignment into bmdma_init()
  2023-04-22 15:07 [PATCH 00/13] Clean up PCI IDE device models Bernhard Beschow
                   ` (2 preceding siblings ...)
  2023-04-22 15:07 ` [PATCH 03/13] hw/isa/vt82c686: Remove via_isa_set_irq() Bernhard Beschow
@ 2023-04-22 15:07 ` Bernhard Beschow
  2023-04-22 17:31   ` BALATON Zoltan
                     ` (2 more replies)
  2023-04-22 15:07 ` [PATCH 05/13] hw/ide: Extract pci_ide_class_init() Bernhard Beschow
                   ` (8 subsequent siblings)
  12 siblings, 3 replies; 77+ messages in thread
From: Bernhard Beschow @ 2023-04-22 15:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc, Bernhard Beschow

Every invocation of bmdma_init() is followed by `d->bmdma[i].bus = &d->bus[i]`.
Resolve this redundancy by extracting it into bmdma_init().

Signed-off-by: Bernhard Beschow <shentey@gmail.com>
---
 hw/ide/cmd646.c  | 1 -
 hw/ide/pci.c     | 1 +
 hw/ide/piix.c    | 1 -
 hw/ide/sii3112.c | 1 -
 hw/ide/via.c     | 1 -
 5 files changed, 1 insertion(+), 4 deletions(-)

diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
index a68357c1c5..a094a6e12a 100644
--- a/hw/ide/cmd646.c
+++ b/hw/ide/cmd646.c
@@ -297,7 +297,6 @@ static void pci_cmd646_ide_realize(PCIDevice *dev, Error **errp)
         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 = &d->bus[i];
         ide_bus_register_restart_cb(&d->bus[i]);
     }
 }
diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index 942e216b9b..67e0998ff0 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -519,6 +519,7 @@ void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d)
     bus->dma = &bm->dma;
     bm->irq = bus->irq;
     bus->irq = qemu_allocate_irq(bmdma_irq, bm, 0);
+    bm->bus = bus;
     bm->pci_dev = d;
 }
 
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index 41d60921e3..a32f7ccece 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -144,7 +144,6 @@ static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, Error **errp)
     ide_bus_init_output_irq(&d->bus[i], isa_get_irq(NULL, port_info[i].isairq));
 
     bmdma_init(&d->bus[i], &d->bmdma[i], d);
-    d->bmdma[i].bus = &d->bus[i];
     ide_bus_register_restart_cb(&d->bus[i]);
 
     return true;
diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c
index f9becdff8e..5dd3d03c29 100644
--- a/hw/ide/sii3112.c
+++ b/hw/ide/sii3112.c
@@ -287,7 +287,6 @@ static void sii3112_pci_realize(PCIDevice *dev, Error **errp)
         ide_bus_init_output_irq(&s->bus[i], qdev_get_gpio_in(ds, i));
 
         bmdma_init(&s->bus[i], &s->bmdma[i], s);
-        s->bmdma[i].bus = &s->bus[i];
         ide_bus_register_restart_cb(&s->bus[i]);
     }
 }
diff --git a/hw/ide/via.c b/hw/ide/via.c
index 0caae52276..91253fa4ef 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -196,7 +196,6 @@ static void via_ide_realize(PCIDevice *dev, Error **errp)
         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 = &d->bus[i];
         ide_bus_register_restart_cb(&d->bus[i]);
     }
 }
-- 
2.40.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 05/13] hw/ide: Extract pci_ide_class_init()
  2023-04-22 15:07 [PATCH 00/13] Clean up PCI IDE device models Bernhard Beschow
                   ` (3 preceding siblings ...)
  2023-04-22 15:07 ` [PATCH 04/13] hw/ide: Extract IDEBus assignment into bmdma_init() Bernhard Beschow
@ 2023-04-22 15:07 ` Bernhard Beschow
  2023-04-22 17:34   ` BALATON Zoltan
                     ` (2 more replies)
  2023-04-22 15:07 ` [PATCH 06/13] hw/ide: Extract bmdma_init_ops() Bernhard Beschow
                   ` (7 subsequent siblings)
  12 siblings, 3 replies; 77+ messages in thread
From: Bernhard Beschow @ 2023-04-22 15:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc, Bernhard Beschow

Resolves redundant code in every PCI IDE device model.
---
 include/hw/ide/pci.h |  1 -
 hw/ide/cmd646.c      | 15 ---------------
 hw/ide/pci.c         | 25 ++++++++++++++++++++++++-
 hw/ide/piix.c        | 19 -------------------
 hw/ide/sii3112.c     |  3 ++-
 hw/ide/via.c         | 15 ---------------
 6 files changed, 26 insertions(+), 52 deletions(-)

diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
index 74c127e32f..7bc4e53d02 100644
--- a/include/hw/ide/pci.h
+++ b/include/hw/ide/pci.h
@@ -61,7 +61,6 @@ void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val);
 extern MemoryRegionOps bmdma_addr_ioport_ops;
 void pci_ide_create_devs(PCIDevice *dev);
 
-extern const VMStateDescription vmstate_ide_pci;
 extern const MemoryRegionOps pci_ide_cmd_le_ops;
 extern const MemoryRegionOps pci_ide_data_le_ops;
 #endif
diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
index a094a6e12a..9aabf80e52 100644
--- a/hw/ide/cmd646.c
+++ b/hw/ide/cmd646.c
@@ -301,17 +301,6 @@ static void pci_cmd646_ide_realize(PCIDevice *dev, Error **errp)
     }
 }
 
-static void pci_cmd646_ide_exitfn(PCIDevice *dev)
-{
-    PCIIDEState *d = PCI_IDE(dev);
-    unsigned i;
-
-    for (i = 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_ioport);
-    }
-}
-
 static Property cmd646_ide_properties[] = {
     DEFINE_PROP_UINT32("secondary", PCIIDEState, secondary, 0),
     DEFINE_PROP_END_OF_LIST(),
@@ -323,17 +312,13 @@ static void cmd646_ide_class_init(ObjectClass *klass, void *data)
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     dc->reset = cmd646_reset;
-    dc->vmsd = &vmstate_ide_pci;
     k->realize = pci_cmd646_ide_realize;
-    k->exit = pci_cmd646_ide_exitfn;
     k->vendor_id = PCI_VENDOR_ID_CMD;
     k->device_id = PCI_DEVICE_ID_CMD_646;
     k->revision = 0x07;
-    k->class_id = PCI_CLASS_STORAGE_IDE;
     k->config_read = cmd646_pci_config_read;
     k->config_write = cmd646_pci_config_write;
     device_class_set_props(dc, cmd646_ide_properties);
-    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
 }
 
 static const TypeInfo cmd646_ide_info = {
diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index 67e0998ff0..8bea92e394 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -467,7 +467,7 @@ static int ide_pci_post_load(void *opaque, int version_id)
     return 0;
 }
 
-const VMStateDescription vmstate_ide_pci = {
+static const VMStateDescription vmstate_ide_pci = {
     .name = "ide",
     .version_id = 3,
     .minimum_version_id = 0,
@@ -530,11 +530,34 @@ static void pci_ide_init(Object *obj)
     qdev_init_gpio_out(DEVICE(d), d->isa_irq, ARRAY_SIZE(d->isa_irq));
 }
 
+static void pci_ide_exitfn(PCIDevice *dev)
+{
+    PCIIDEState *d = PCI_IDE(dev);
+    unsigned i;
+
+    for (i = 0; i < ARRAY_SIZE(d->bmdma); ++i) {
+        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io);
+        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport);
+    }
+}
+
+static void pci_ide_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    dc->vmsd = &vmstate_ide_pci;
+    k->exit = pci_ide_exitfn;
+    k->class_id = PCI_CLASS_STORAGE_IDE;
+    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
+}
+
 static const TypeInfo pci_ide_type_info = {
     .name = TYPE_PCI_IDE,
     .parent = TYPE_PCI_DEVICE,
     .instance_size = sizeof(PCIIDEState),
     .instance_init = pci_ide_init,
+    .class_init = pci_ide_class_init,
     .abstract = true,
     .interfaces = (InterfaceInfo[]) {
         { INTERFACE_CONVENTIONAL_PCI_DEVICE },
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index a32f7ccece..4e6ca99123 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -159,8 +159,6 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
     bmdma_setup_bar(d);
     pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
 
-    vmstate_register(VMSTATE_IF(dev), 0, &vmstate_ide_pci, d);
-
     for (unsigned i = 0; i < 2; i++) {
         if (!pci_piix_init_bus(d, i, errp)) {
             return;
@@ -168,17 +166,6 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
     }
 }
 
-static void pci_piix_ide_exitfn(PCIDevice *dev)
-{
-    PCIIDEState *d = PCI_IDE(dev);
-    unsigned i;
-
-    for (i = 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_ioport);
-    }
-}
-
 /* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */
 static void piix3_ide_class_init(ObjectClass *klass, void *data)
 {
@@ -187,11 +174,8 @@ static void piix3_ide_class_init(ObjectClass *klass, void *data)
 
     dc->reset = piix_ide_reset;
     k->realize = pci_piix_ide_realize;
-    k->exit = pci_piix_ide_exitfn;
     k->vendor_id = PCI_VENDOR_ID_INTEL;
     k->device_id = PCI_DEVICE_ID_INTEL_82371SB_1;
-    k->class_id = PCI_CLASS_STORAGE_IDE;
-    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
     dc->hotpluggable = false;
 }
 
@@ -209,11 +193,8 @@ static void piix4_ide_class_init(ObjectClass *klass, void *data)
 
     dc->reset = piix_ide_reset;
     k->realize = pci_piix_ide_realize;
-    k->exit = pci_piix_ide_exitfn;
     k->vendor_id = PCI_VENDOR_ID_INTEL;
     k->device_id = PCI_DEVICE_ID_INTEL_82371AB;
-    k->class_id = PCI_CLASS_STORAGE_IDE;
-    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
     dc->hotpluggable = false;
 }
 
diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c
index 5dd3d03c29..0af897a9ef 100644
--- a/hw/ide/sii3112.c
+++ b/hw/ide/sii3112.c
@@ -301,9 +301,10 @@ static void sii3112_pci_class_init(ObjectClass *klass, void *data)
     pd->class_id = PCI_CLASS_STORAGE_RAID;
     pd->revision = 1;
     pd->realize = sii3112_pci_realize;
+    pd->exit = NULL;
     dc->reset = sii3112_reset;
+    dc->vmsd = NULL;
     dc->desc = "SiI3112A SATA controller";
-    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
 }
 
 static const TypeInfo sii3112_pci_info = {
diff --git a/hw/ide/via.c b/hw/ide/via.c
index 91253fa4ef..287143a005 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -200,34 +200,19 @@ static void via_ide_realize(PCIDevice *dev, Error **errp)
     }
 }
 
-static void via_ide_exitfn(PCIDevice *dev)
-{
-    PCIIDEState *d = PCI_IDE(dev);
-    unsigned i;
-
-    for (i = 0; i < ARRAY_SIZE(d->bmdma); ++i) {
-        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io);
-        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport);
-    }
-}
-
 static void via_ide_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     dc->reset = via_ide_reset;
-    dc->vmsd = &vmstate_ide_pci;
     /* Reason: only works as function of VIA southbridge */
     dc->user_creatable = false;
 
     k->realize = via_ide_realize;
-    k->exit = via_ide_exitfn;
     k->vendor_id = PCI_VENDOR_ID_VIA;
     k->device_id = PCI_DEVICE_ID_VIA_IDE;
     k->revision = 0x06;
-    k->class_id = PCI_CLASS_STORAGE_IDE;
-    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
 }
 
 static const TypeInfo via_ide_info = {
-- 
2.40.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 06/13] hw/ide: Extract bmdma_init_ops()
  2023-04-22 15:07 [PATCH 00/13] Clean up PCI IDE device models Bernhard Beschow
                   ` (4 preceding siblings ...)
  2023-04-22 15:07 ` [PATCH 05/13] hw/ide: Extract pci_ide_class_init() Bernhard Beschow
@ 2023-04-22 15:07 ` Bernhard Beschow
  2023-04-23 17:43   ` Philippe Mathieu-Daudé
  2023-04-26 11:14   ` Mark Cave-Ayland
  2023-04-22 15:07 ` [PATCH 07/13] hw/ide: Extract pci_ide_{cmd, data}_le_ops initialization into base class constructor Bernhard Beschow
                   ` (6 subsequent siblings)
  12 siblings, 2 replies; 77+ messages in thread
From: Bernhard Beschow @ 2023-04-22 15:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc, Bernhard Beschow

There are three private copies of bmdma_setup_bar() with small adaptions.
Consolidate them into one public implementation.

While at it rename the function to bmdma_init_ops() to reflect that the memory
regions being initialized represent BMDMA operations. The actual mapping as a
PCI BAR is still performed separately in each device.

Note that the bmdma_bar attribute will be renamed in a separate commit.

Signed-off-by: Bernhard Beschow <shentey@gmail.com>
---
 include/hw/ide/pci.h |  1 +
 hw/ide/cmd646.c      | 20 +-------------------
 hw/ide/pci.c         | 16 ++++++++++++++++
 hw/ide/piix.c        | 19 +------------------
 hw/ide/via.c         | 19 +------------------
 5 files changed, 20 insertions(+), 55 deletions(-)

diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
index 7bc4e53d02..597c77c7ad 100644
--- a/include/hw/ide/pci.h
+++ b/include/hw/ide/pci.h
@@ -57,6 +57,7 @@ struct PCIIDEState {
 };
 
 void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d);
+void bmdma_init_ops(PCIIDEState *d, const MemoryRegionOps *bmdma_ops);
 void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val);
 extern MemoryRegionOps bmdma_addr_ioport_ops;
 void pci_ide_create_devs(PCIDevice *dev);
diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
index 9aabf80e52..6fd09fe74e 100644
--- a/hw/ide/cmd646.c
+++ b/hw/ide/cmd646.c
@@ -161,24 +161,6 @@ static const MemoryRegionOps cmd646_bmdma_ops = {
     .write = bmdma_write,
 };
 
-static void bmdma_setup_bar(PCIIDEState *d)
-{
-    BMDMAState *bm;
-    int i;
-
-    memory_region_init(&d->bmdma_bar, OBJECT(d), "cmd646-bmdma", 16);
-    for(i = 0;i < 2; i++) {
-        bm = &d->bmdma[i];
-        memory_region_init_io(&bm->extra_io, OBJECT(d), &cmd646_bmdma_ops, bm,
-                              "cmd646-bmdma-bus", 4);
-        memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io);
-        memory_region_init_io(&bm->addr_ioport, OBJECT(d),
-                              &bmdma_addr_ioport_ops, bm,
-                              "cmd646-bmdma-ioport", 4);
-        memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport);
-    }
-}
-
 static void cmd646_update_irq(PCIDevice *pd)
 {
     int pci_level;
@@ -285,7 +267,7 @@ static void pci_cmd646_ide_realize(PCIDevice *dev, Error **errp)
                           &d->bus[1], "cmd646-cmd1", 4);
     pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[1]);
 
-    bmdma_setup_bar(d);
+    bmdma_init_ops(d, &cmd646_bmdma_ops);
     pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
 
     /* TODO: RST# value should be 0 */
diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index 8bea92e394..65ed6f7f72 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -523,6 +523,22 @@ void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d)
     bm->pci_dev = d;
 }
 
+void bmdma_init_ops(PCIIDEState *d, const MemoryRegionOps *bmdma_ops)
+{
+    size_t i;
+
+    memory_region_init(&d->bmdma_bar, OBJECT(d), "bmdma-container", 16);
+    for (i = 0; i < ARRAY_SIZE(d->bmdma); i++) {
+        BMDMAState *bm = &d->bmdma[i];
+
+        memory_region_init_io(&bm->extra_io, OBJECT(d), bmdma_ops, bm, "bmdma-ops", 4);
+        memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io);
+        memory_region_init_io(&bm->addr_ioport, OBJECT(d), &bmdma_addr_ioport_ops, bm,
+                              "bmdma-ioport-ops", 4);
+        memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport);
+    }
+}
+
 static void pci_ide_init(Object *obj)
 {
     PCIIDEState *d = PCI_IDE(obj);
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index 4e6ca99123..5611473d37 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -86,23 +86,6 @@ static const MemoryRegionOps piix_bmdma_ops = {
     .write = bmdma_write,
 };
 
-static void bmdma_setup_bar(PCIIDEState *d)
-{
-    int i;
-
-    memory_region_init(&d->bmdma_bar, OBJECT(d), "piix-bmdma-container", 16);
-    for(i = 0;i < 2; i++) {
-        BMDMAState *bm = &d->bmdma[i];
-
-        memory_region_init_io(&bm->extra_io, OBJECT(d), &piix_bmdma_ops, bm,
-                              "piix-bmdma", 4);
-        memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io);
-        memory_region_init_io(&bm->addr_ioport, OBJECT(d),
-                              &bmdma_addr_ioport_ops, bm, "bmdma", 4);
-        memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport);
-    }
-}
-
 static void piix_ide_reset(DeviceState *dev)
 {
     PCIIDEState *d = PCI_IDE(dev);
@@ -156,7 +139,7 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
 
     pci_conf[PCI_CLASS_PROG] = 0x80; // legacy ATA mode
 
-    bmdma_setup_bar(d);
+    bmdma_init_ops(d, &piix_bmdma_ops);
     pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
 
     for (unsigned i = 0; i < 2; i++) {
diff --git a/hw/ide/via.c b/hw/ide/via.c
index 287143a005..40704e2857 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -86,23 +86,6 @@ static const MemoryRegionOps via_bmdma_ops = {
     .write = bmdma_write,
 };
 
-static void bmdma_setup_bar(PCIIDEState *d)
-{
-    int i;
-
-    memory_region_init(&d->bmdma_bar, OBJECT(d), "via-bmdma-container", 16);
-    for (i = 0; i < ARRAY_SIZE(d->bmdma); i++) {
-        BMDMAState *bm = &d->bmdma[i];
-
-        memory_region_init_io(&bm->extra_io, OBJECT(d), &via_bmdma_ops, bm,
-                              "via-bmdma", 4);
-        memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io);
-        memory_region_init_io(&bm->addr_ioport, OBJECT(d),
-                              &bmdma_addr_ioport_ops, bm, "bmdma", 4);
-        memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport);
-    }
-}
-
 static void via_ide_set_irq(void *opaque, int n, int level)
 {
     PCIIDEState *s = opaque;
@@ -187,7 +170,7 @@ static void via_ide_realize(PCIDevice *dev, Error **errp)
                           &d->bus[1], "via-ide1-cmd", 4);
     pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[1]);
 
-    bmdma_setup_bar(d);
+    bmdma_init_ops(d, &via_bmdma_ops);
     pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
 
     qdev_init_gpio_in(ds, via_ide_set_irq, ARRAY_SIZE(d->bus));
-- 
2.40.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 07/13] hw/ide: Extract pci_ide_{cmd, data}_le_ops initialization into base class constructor
  2023-04-22 15:07 [PATCH 00/13] Clean up PCI IDE device models Bernhard Beschow
                   ` (5 preceding siblings ...)
  2023-04-22 15:07 ` [PATCH 06/13] hw/ide: Extract bmdma_init_ops() Bernhard Beschow
@ 2023-04-22 15:07 ` Bernhard Beschow
  2023-04-23 17:46   ` [PATCH 07/13] hw/ide: Extract pci_ide_{cmd,data}_le_ops " Philippe Mathieu-Daudé
  2023-04-26 11:16   ` [PATCH 07/13] hw/ide: Extract pci_ide_{cmd, data}_le_ops " Mark Cave-Ayland
  2023-04-22 15:07 ` [PATCH 08/13] hw/ide: Rename PCIIDEState::*_bar attributes Bernhard Beschow
                   ` (5 subsequent siblings)
  12 siblings, 2 replies; 77+ messages in thread
From: Bernhard Beschow @ 2023-04-22 15:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc, Bernhard Beschow

There is redundant code in cmd646 and via which can be extracted into the base
class. In case of piix and sii3112 this is currently unneccessary but shouldn't
interfere since the memory regions aren't mapped by those devices. In few
commits later this will be changed, i.e. those device models will also make use
of these memory regions.

Signed-off-by: Bernhard Beschow <shentey@gmail.com>
---
 hw/ide/cmd646.c | 11 -----------
 hw/ide/pci.c    | 10 ++++++++++
 hw/ide/via.c    | 11 -----------
 3 files changed, 10 insertions(+), 22 deletions(-)

diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
index 6fd09fe74e..85716aaf17 100644
--- a/hw/ide/cmd646.c
+++ b/hw/ide/cmd646.c
@@ -251,20 +251,9 @@ static void pci_cmd646_ide_realize(PCIDevice *dev, Error **errp)
     dev->wmask[MRDMODE] = 0x0;
     dev->w1cmask[MRDMODE] = MRDMODE_INTR_CH0 | MRDMODE_INTR_CH1;
 
-    memory_region_init_io(&d->data_bar[0], OBJECT(d), &pci_ide_data_le_ops,
-                          &d->bus[0], "cmd646-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], "cmd646-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], "cmd646-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], "cmd646-cmd1", 4);
     pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[1]);
 
     bmdma_init_ops(d, &cmd646_bmdma_ops);
diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index 65ed6f7f72..a9194313bd 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -543,6 +543,16 @@ static void pci_ide_init(Object *obj)
 {
     PCIIDEState *d = PCI_IDE(obj);
 
+    memory_region_init_io(&d->data_bar[0], OBJECT(d), &pci_ide_data_le_ops,
+                          &d->bus[0], "pci-ide0-data-ops", 8);
+    memory_region_init_io(&d->cmd_bar[0], OBJECT(d), &pci_ide_cmd_le_ops,
+                          &d->bus[0], "pci-ide0-cmd-ops", 4);
+
+    memory_region_init_io(&d->data_bar[1], OBJECT(d), &pci_ide_data_le_ops,
+                          &d->bus[1], "pci-ide1-data-ops", 8);
+    memory_region_init_io(&d->cmd_bar[1], OBJECT(d), &pci_ide_cmd_le_ops,
+                          &d->bus[1], "pci-ide1-cmd-ops", 4);
+
     qdev_init_gpio_out(DEVICE(d), d->isa_irq, ARRAY_SIZE(d->isa_irq));
 }
 
diff --git a/hw/ide/via.c b/hw/ide/via.c
index 40704e2857..704a8024cb 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -154,20 +154,9 @@ static void via_ide_realize(PCIDevice *dev, Error **errp)
     dev->wmask[PCI_INTERRUPT_LINE] = 0;
     dev->wmask[PCI_CLASS_PROG] = 5;
 
-    memory_region_init_io(&d->data_bar[0], OBJECT(d), &pci_ide_data_le_ops,
-                          &d->bus[0], "via-ide0-data", 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], "via-ide0-cmd", 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], "via-ide1-data", 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], "via-ide1-cmd", 4);
     pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[1]);
 
     bmdma_init_ops(d, &via_bmdma_ops);
-- 
2.40.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 08/13] hw/ide: Rename PCIIDEState::*_bar attributes
  2023-04-22 15:07 [PATCH 00/13] Clean up PCI IDE device models Bernhard Beschow
                   ` (6 preceding siblings ...)
  2023-04-22 15:07 ` [PATCH 07/13] hw/ide: Extract pci_ide_{cmd, data}_le_ops initialization into base class constructor Bernhard Beschow
@ 2023-04-22 15:07 ` Bernhard Beschow
  2023-04-22 17:53   ` BALATON Zoltan
  2023-04-26 11:21   ` Mark Cave-Ayland
  2023-04-22 15:07 ` [PATCH 09/13] hw/ide/piix: Disuse isa_get_irq() Bernhard Beschow
                   ` (4 subsequent siblings)
  12 siblings, 2 replies; 77+ messages in thread
From: Bernhard Beschow @ 2023-04-22 15:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc, Bernhard Beschow

The attributes represent memory regions containing operations which are mapped
by the device models into PCI BARs. Reflect this by changing the suffic into
"_ops".

Note that in a few commits piix will also use the {cmd,data}_ops but won't map
them into BARs. This further suggests that the "_bar" suffix doesn't match
very well.

Signed-off-by: Bernhard Beschow <shentey@gmail.com>
---
 include/hw/ide/pci.h |  6 +++---
 hw/ide/cmd646.c      | 10 +++++-----
 hw/ide/pci.c         | 18 +++++++++---------
 hw/ide/piix.c        |  2 +-
 hw/ide/via.c         | 10 +++++-----
 5 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
index 597c77c7ad..5025df5b82 100644
--- a/include/hw/ide/pci.h
+++ b/include/hw/ide/pci.h
@@ -51,9 +51,9 @@ struct PCIIDEState {
     BMDMAState bmdma[2];
     qemu_irq isa_irq[2];
     uint32_t secondary; /* used only for cmd646 */
-    MemoryRegion bmdma_bar;
-    MemoryRegion cmd_bar[2];
-    MemoryRegion data_bar[2];
+    MemoryRegion bmdma_ops;
+    MemoryRegion cmd_ops[2];
+    MemoryRegion data_ops[2];
 };
 
 void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d);
diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
index 85716aaf17..b9d005a357 100644
--- a/hw/ide/cmd646.c
+++ b/hw/ide/cmd646.c
@@ -251,13 +251,13 @@ static void pci_cmd646_ide_realize(PCIDevice *dev, Error **errp)
     dev->wmask[MRDMODE] = 0x0;
     dev->w1cmask[MRDMODE] = MRDMODE_INTR_CH0 | MRDMODE_INTR_CH1;
 
-    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->data_bar[0]);
-    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[0]);
-    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &d->data_bar[1]);
-    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[1]);
+    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->data_ops[0]);
+    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_ops[0]);
+    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &d->data_ops[1]);
+    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_ops[1]);
 
     bmdma_init_ops(d, &cmd646_bmdma_ops);
-    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
+    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_ops);
 
     /* TODO: RST# value should be 0 */
     pci_conf[PCI_INTERRUPT_PIN] = 0x01; // interrupt on pin 1
diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index a9194313bd..b2fcc00a64 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -527,15 +527,15 @@ void bmdma_init_ops(PCIIDEState *d, const MemoryRegionOps *bmdma_ops)
 {
     size_t i;
 
-    memory_region_init(&d->bmdma_bar, OBJECT(d), "bmdma-container", 16);
+    memory_region_init(&d->bmdma_ops, OBJECT(d), "bmdma-container", 16);
     for (i = 0; i < ARRAY_SIZE(d->bmdma); i++) {
         BMDMAState *bm = &d->bmdma[i];
 
         memory_region_init_io(&bm->extra_io, OBJECT(d), bmdma_ops, bm, "bmdma-ops", 4);
-        memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io);
+        memory_region_add_subregion(&d->bmdma_ops, i * 8, &bm->extra_io);
         memory_region_init_io(&bm->addr_ioport, OBJECT(d), &bmdma_addr_ioport_ops, bm,
                               "bmdma-ioport-ops", 4);
-        memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport);
+        memory_region_add_subregion(&d->bmdma_ops, i * 8 + 4, &bm->addr_ioport);
     }
 }
 
@@ -543,14 +543,14 @@ static void pci_ide_init(Object *obj)
 {
     PCIIDEState *d = PCI_IDE(obj);
 
-    memory_region_init_io(&d->data_bar[0], OBJECT(d), &pci_ide_data_le_ops,
+    memory_region_init_io(&d->data_ops[0], OBJECT(d), &pci_ide_data_le_ops,
                           &d->bus[0], "pci-ide0-data-ops", 8);
-    memory_region_init_io(&d->cmd_bar[0], OBJECT(d), &pci_ide_cmd_le_ops,
+    memory_region_init_io(&d->cmd_ops[0], OBJECT(d), &pci_ide_cmd_le_ops,
                           &d->bus[0], "pci-ide0-cmd-ops", 4);
 
-    memory_region_init_io(&d->data_bar[1], OBJECT(d), &pci_ide_data_le_ops,
+    memory_region_init_io(&d->data_ops[1], OBJECT(d), &pci_ide_data_le_ops,
                           &d->bus[1], "pci-ide1-data-ops", 8);
-    memory_region_init_io(&d->cmd_bar[1], OBJECT(d), &pci_ide_cmd_le_ops,
+    memory_region_init_io(&d->cmd_ops[1], OBJECT(d), &pci_ide_cmd_le_ops,
                           &d->bus[1], "pci-ide1-cmd-ops", 4);
 
     qdev_init_gpio_out(DEVICE(d), d->isa_irq, ARRAY_SIZE(d->isa_irq));
@@ -562,8 +562,8 @@ static void pci_ide_exitfn(PCIDevice *dev)
     unsigned i;
 
     for (i = 0; i < ARRAY_SIZE(d->bmdma); ++i) {
-        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io);
-        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport);
+        memory_region_del_subregion(&d->bmdma_ops, &d->bmdma[i].extra_io);
+        memory_region_del_subregion(&d->bmdma_ops, &d->bmdma[i].addr_ioport);
     }
 }
 
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index 5611473d37..6942b484f9 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -140,7 +140,7 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
     pci_conf[PCI_CLASS_PROG] = 0x80; // legacy ATA mode
 
     bmdma_init_ops(d, &piix_bmdma_ops);
-    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
+    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_ops);
 
     for (unsigned i = 0; i < 2; i++) {
         if (!pci_piix_init_bus(d, i, errp)) {
diff --git a/hw/ide/via.c b/hw/ide/via.c
index 704a8024cb..35dd97e49b 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -154,13 +154,13 @@ static void via_ide_realize(PCIDevice *dev, Error **errp)
     dev->wmask[PCI_INTERRUPT_LINE] = 0;
     dev->wmask[PCI_CLASS_PROG] = 5;
 
-    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->data_bar[0]);
-    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[0]);
-    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &d->data_bar[1]);
-    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[1]);
+    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->data_ops[0]);
+    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_ops[0]);
+    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &d->data_ops[1]);
+    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_ops[1]);
 
     bmdma_init_ops(d, &via_bmdma_ops);
-    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
+    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_ops);
 
     qdev_init_gpio_in(ds, via_ide_set_irq, ARRAY_SIZE(d->bus));
     for (i = 0; i < ARRAY_SIZE(d->bus); i++) {
-- 
2.40.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 09/13] hw/ide/piix: Disuse isa_get_irq()
  2023-04-22 15:07 [PATCH 00/13] Clean up PCI IDE device models Bernhard Beschow
                   ` (7 preceding siblings ...)
  2023-04-22 15:07 ` [PATCH 08/13] hw/ide: Rename PCIIDEState::*_bar attributes Bernhard Beschow
@ 2023-04-22 15:07 ` Bernhard Beschow
  2023-04-26 11:33   ` Mark Cave-Ayland
  2023-04-22 15:07 ` [PATCH 10/13] hw/ide/piix: Reuse PCIIDEState::{cmd,data}_ops Bernhard Beschow
                   ` (3 subsequent siblings)
  12 siblings, 1 reply; 77+ messages in thread
From: Bernhard Beschow @ 2023-04-22 15:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc, Bernhard Beschow

isa_get_irq() asks for an ISADevice which piix-ide doesn't provide.
Passing a NULL pointer works but causes the isabus global to be used
then. By fishing out TYPE_ISA_BUS from the QOM tree it is possible to
achieve the same as using isa_get_irq().

This is an alternative solution to commit 9405d87be25d 'hw/ide: Fix
crash when plugging a piix3-ide device into the x-remote machine' which
allows for cleaning up the ISA API while keeping PIIX IDE functions
user-createable.

Signed-off-by: Bernhard Beschow <shentey@gmail.com>
---
 hw/ide/piix.c | 23 ++++++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index 6942b484f9..a3a15dc7db 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -104,7 +104,8 @@ static void piix_ide_reset(DeviceState *dev)
     pci_set_byte(pci_conf + 0x20, 0x01);  /* BMIBA: 20-23h */
 }
 
-static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, Error **errp)
+static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, ISABus *isa_bus,
+                              Error **errp)
 {
     static const struct {
         int iobase;
@@ -124,7 +125,8 @@ static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, Error **errp)
                          object_get_typename(OBJECT(d)), i);
         return false;
     }
-    ide_bus_init_output_irq(&d->bus[i], isa_get_irq(NULL, port_info[i].isairq));
+    ide_bus_init_output_irq(&d->bus[i],
+                            isa_bus_get_irq(isa_bus, port_info[i].isairq));
 
     bmdma_init(&d->bus[i], &d->bmdma[i], d);
     ide_bus_register_restart_cb(&d->bus[i]);
@@ -136,14 +138,29 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
 {
     PCIIDEState *d = PCI_IDE(dev);
     uint8_t *pci_conf = dev->config;
+    ISABus *isa_bus;
+    bool ambiguous;
 
     pci_conf[PCI_CLASS_PROG] = 0x80; // legacy ATA mode
 
     bmdma_init_ops(d, &piix_bmdma_ops);
     pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_ops);
 
+    isa_bus = ISA_BUS(object_resolve_path_type("", TYPE_ISA_BUS, &ambiguous));
+    if (ambiguous) {
+        error_setg(errp,
+                   "More than one ISA bus found while %s supports only one",
+                   object_get_typename(OBJECT(d)));
+        return;
+    }
+    if (!isa_bus) {
+        error_setg(errp, "No ISA bus found while %s requires one",
+                   object_get_typename(OBJECT(d)));
+        return;
+    }
+
     for (unsigned i = 0; i < 2; i++) {
-        if (!pci_piix_init_bus(d, i, errp)) {
+        if (!pci_piix_init_bus(d, i, isa_bus, errp)) {
             return;
         }
     }
-- 
2.40.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 10/13] hw/ide/piix: Reuse PCIIDEState::{cmd,data}_ops
  2023-04-22 15:07 [PATCH 00/13] Clean up PCI IDE device models Bernhard Beschow
                   ` (8 preceding siblings ...)
  2023-04-22 15:07 ` [PATCH 09/13] hw/ide/piix: Disuse isa_get_irq() Bernhard Beschow
@ 2023-04-22 15:07 ` Bernhard Beschow
  2023-04-26 11:37   ` Mark Cave-Ayland
  2023-04-22 15:07 ` [PATCH 11/13] hw/ide/sii3112: " Bernhard Beschow
                   ` (2 subsequent siblings)
  12 siblings, 1 reply; 77+ messages in thread
From: Bernhard Beschow @ 2023-04-22 15:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc, Bernhard Beschow

Now that PCIIDEState::{cmd,data}_ops are initialized in the base class
constructor there is an opportunity for PIIX to reuse these attributes. This
resolves usage of ide_init_ioport() which would fall back internally to using
the isabus global due to NULL being passed as ISADevice by PIIX.

Signed-off-by: Bernhard Beschow <shentey@gmail.com>
---
 hw/ide/piix.c | 30 +++++++++++++-----------------
 1 file changed, 13 insertions(+), 17 deletions(-)

diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index a3a15dc7db..406a67fa0f 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -104,34 +104,32 @@ static void piix_ide_reset(DeviceState *dev)
     pci_set_byte(pci_conf + 0x20, 0x01);  /* BMIBA: 20-23h */
 }
 
-static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, ISABus *isa_bus,
-                              Error **errp)
+static void pci_piix_init_bus(PCIIDEState *d, unsigned i, ISABus *isa_bus)
 {
     static const struct {
         int iobase;
         int iobase2;
         int isairq;
     } port_info[] = {
-        {0x1f0, 0x3f6, 14},
-        {0x170, 0x376, 15},
+        {0x1f0, 0x3f4, 14},
+        {0x170, 0x374, 15},
     };
-    int ret;
+    MemoryRegion *address_space_io = pci_address_space_io(PCI_DEVICE(d));
 
     ide_bus_init(&d->bus[i], sizeof(d->bus[i]), DEVICE(d), i, 2);
-    ret = ide_init_ioport(&d->bus[i], NULL, port_info[i].iobase,
-                          port_info[i].iobase2);
-    if (ret) {
-        error_setg_errno(errp, -ret, "Failed to realize %s port %u",
-                         object_get_typename(OBJECT(d)), i);
-        return false;
-    }
+    memory_region_add_subregion(address_space_io, port_info[i].iobase,
+                                &d->data_ops[i]);
+    /*
+     * PIIX forwards the last byte of cmd_ops to ISA. Model this using a low
+     * prio so competing memory regions take precedence.
+     */
+    memory_region_add_subregion_overlap(address_space_io, port_info[i].iobase2,
+                                        &d->cmd_ops[i], -1);
     ide_bus_init_output_irq(&d->bus[i],
                             isa_bus_get_irq(isa_bus, port_info[i].isairq));
 
     bmdma_init(&d->bus[i], &d->bmdma[i], d);
     ide_bus_register_restart_cb(&d->bus[i]);
-
-    return true;
 }
 
 static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
@@ -160,9 +158,7 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
     }
 
     for (unsigned i = 0; i < 2; i++) {
-        if (!pci_piix_init_bus(d, i, isa_bus, errp)) {
-            return;
-        }
+        pci_piix_init_bus(d, i, isa_bus);
     }
 }
 
-- 
2.40.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 11/13] hw/ide/sii3112: Reuse PCIIDEState::{cmd,data}_ops
  2023-04-22 15:07 [PATCH 00/13] Clean up PCI IDE device models Bernhard Beschow
                   ` (9 preceding siblings ...)
  2023-04-22 15:07 ` [PATCH 10/13] hw/ide/piix: Reuse PCIIDEState::{cmd,data}_ops Bernhard Beschow
@ 2023-04-22 15:07 ` Bernhard Beschow
  2023-04-22 21:10   ` BALATON Zoltan
  2023-04-26 11:41   ` Mark Cave-Ayland
  2023-04-22 15:07 ` [PATCH 12/13] hw/ide/sii3112: Reuse PCIIDEState::bmdma_ops Bernhard Beschow
  2023-04-22 15:07 ` [PATCH 13/13] hw/ide: Extract bmdma_clear_status() Bernhard Beschow
  12 siblings, 2 replies; 77+ messages in thread
From: Bernhard Beschow @ 2023-04-22 15:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc, Bernhard Beschow

Allows to unexport pci_ide_{cmd,data}_le_ops and models TYPE_SII3112_PCI as a
standard-compliant PCI IDE device.

Signed-off-by: Bernhard Beschow <shentey@gmail.com>
---
 include/hw/ide/pci.h |  2 --
 hw/ide/pci.c         |  4 ++--
 hw/ide/sii3112.c     | 50 ++++++++++++++++----------------------------
 3 files changed, 20 insertions(+), 36 deletions(-)

diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
index 5025df5b82..dbb4b13161 100644
--- a/include/hw/ide/pci.h
+++ b/include/hw/ide/pci.h
@@ -62,6 +62,4 @@ void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val);
 extern MemoryRegionOps bmdma_addr_ioport_ops;
 void pci_ide_create_devs(PCIDevice *dev);
 
-extern const MemoryRegionOps pci_ide_cmd_le_ops;
-extern const MemoryRegionOps pci_ide_data_le_ops;
 #endif
diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index b2fcc00a64..97ccc75aa6 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -60,7 +60,7 @@ static void pci_ide_ctrl_write(void *opaque, hwaddr addr,
     ide_ctrl_write(bus, addr + 2, data);
 }
 
-const MemoryRegionOps pci_ide_cmd_le_ops = {
+static const MemoryRegionOps pci_ide_cmd_le_ops = {
     .read = pci_ide_status_read,
     .write = pci_ide_ctrl_write,
     .endianness = DEVICE_LITTLE_ENDIAN,
@@ -98,7 +98,7 @@ static void pci_ide_data_write(void *opaque, hwaddr addr,
     }
 }
 
-const MemoryRegionOps pci_ide_data_le_ops = {
+static const MemoryRegionOps pci_ide_data_le_ops = {
     .read = pci_ide_data_read,
     .write = pci_ide_data_write,
     .endianness = DEVICE_LITTLE_ENDIAN,
diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c
index 0af897a9ef..9cf920369f 100644
--- a/hw/ide/sii3112.c
+++ b/hw/ide/sii3112.c
@@ -88,21 +88,9 @@ static uint64_t sii3112_reg_read(void *opaque, hwaddr addr,
         val |= (d->regs[1].confstat & (1UL << 11) ? (1 << 4) : 0);
         val |= (uint32_t)d->i.bmdma[1].status << 16;
         break;
-    case 0x80 ... 0x87:
-        val = pci_ide_data_le_ops.read(&d->i.bus[0], addr - 0x80, size);
-        break;
-    case 0x8a:
-        val = pci_ide_cmd_le_ops.read(&d->i.bus[0], 2, size);
-        break;
     case 0xa0:
         val = d->regs[0].confstat;
         break;
-    case 0xc0 ... 0xc7:
-        val = pci_ide_data_le_ops.read(&d->i.bus[1], addr - 0xc0, size);
-        break;
-    case 0xca:
-        val = pci_ide_cmd_le_ops.read(&d->i.bus[1], 2, size);
-        break;
     case 0xe0:
         val = d->regs[1].confstat;
         break;
@@ -171,18 +159,6 @@ static void sii3112_reg_write(void *opaque, hwaddr addr,
     case 0x0c ... 0x0f:
         bmdma_addr_ioport_ops.write(&d->i.bmdma[1], addr - 12, val, size);
         break;
-    case 0x80 ... 0x87:
-        pci_ide_data_le_ops.write(&d->i.bus[0], addr - 0x80, val, size);
-        break;
-    case 0x8a:
-        pci_ide_cmd_le_ops.write(&d->i.bus[0], 2, val, size);
-        break;
-    case 0xc0 ... 0xc7:
-        pci_ide_data_le_ops.write(&d->i.bus[1], addr - 0xc0, val, size);
-        break;
-    case 0xca:
-        pci_ide_cmd_le_ops.write(&d->i.bus[1], 2, val, size);
-        break;
     case 0x100:
         d->regs[0].scontrol = val & 0xfff;
         if (val & 1) {
@@ -259,6 +235,11 @@ static void sii3112_pci_realize(PCIDevice *dev, Error **errp)
     pci_config_set_interrupt_pin(dev->config, 1);
     pci_set_byte(dev->config + PCI_CACHE_LINE_SIZE, 8);
 
+    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->data_ops[0]);
+    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->cmd_ops[0]);
+    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &s->data_ops[1]);
+    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &s->cmd_ops[1]);
+
     /* BAR5 is in PCI memory space */
     memory_region_init_io(&d->mmio, OBJECT(d), &sii3112_reg_ops, d,
                          "sii3112.bar5", 0x200);
@@ -266,17 +247,22 @@ static void sii3112_pci_realize(PCIDevice *dev, Error **errp)
 
     /* BAR0-BAR4 are PCI I/O space aliases into BAR5 */
     mr = g_new(MemoryRegion, 1);
-    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar0", &d->mmio, 0x80, 8);
-    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, mr);
+    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar0", &s->data_ops[0], 0,
+                             memory_region_size(&s->data_ops[0]));
+    memory_region_add_subregion_overlap(&d->mmio, 0x80, mr, 1);
     mr = g_new(MemoryRegion, 1);
-    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar1", &d->mmio, 0x88, 4);
-    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, mr);
+    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar1", &s->cmd_ops[0], 0,
+                             memory_region_size(&s->cmd_ops[0]));
+    memory_region_add_subregion_overlap(&d->mmio, 0x88, mr, 1);
     mr = g_new(MemoryRegion, 1);
-    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar2", &d->mmio, 0xc0, 8);
-    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, mr);
+    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar2", &s->data_ops[1], 0,
+                             memory_region_size(&s->data_ops[1]));
+    memory_region_add_subregion_overlap(&d->mmio, 0xc0, mr, 1);
     mr = g_new(MemoryRegion, 1);
-    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar3", &d->mmio, 0xc8, 4);
-    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, mr);
+    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar3", &s->cmd_ops[1], 0,
+                             memory_region_size(&s->cmd_ops[1]));
+    memory_region_add_subregion_overlap(&d->mmio, 0xc8, mr, 1);
+
     mr = g_new(MemoryRegion, 1);
     memory_region_init_alias(mr, OBJECT(d), "sii3112.bar4", &d->mmio, 0, 16);
     pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, mr);
-- 
2.40.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 12/13] hw/ide/sii3112: Reuse PCIIDEState::bmdma_ops
  2023-04-22 15:07 [PATCH 00/13] Clean up PCI IDE device models Bernhard Beschow
                   ` (10 preceding siblings ...)
  2023-04-22 15:07 ` [PATCH 11/13] hw/ide/sii3112: " Bernhard Beschow
@ 2023-04-22 15:07 ` Bernhard Beschow
  2023-04-26 11:44   ` Mark Cave-Ayland
  2023-04-22 15:07 ` [PATCH 13/13] hw/ide: Extract bmdma_clear_status() Bernhard Beschow
  12 siblings, 1 reply; 77+ messages in thread
From: Bernhard Beschow @ 2023-04-22 15:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc, Bernhard Beschow

Allows to unexport bmdma_addr_ioport_ops and models TYPE_SII3112_PCI as a
standard-compliant PCI IDE device.

Signed-off-by: Bernhard Beschow <shentey@gmail.com>
---
 include/hw/ide/pci.h |  1 -
 hw/ide/pci.c         |  2 +-
 hw/ide/sii3112.c     | 94 ++++++++++++++++++++++++++------------------
 hw/ide/trace-events  |  6 ++-
 4 files changed, 60 insertions(+), 43 deletions(-)

diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
index dbb4b13161..81e0370202 100644
--- a/include/hw/ide/pci.h
+++ b/include/hw/ide/pci.h
@@ -59,7 +59,6 @@ struct PCIIDEState {
 void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d);
 void bmdma_init_ops(PCIIDEState *d, const MemoryRegionOps *bmdma_ops);
 void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val);
-extern MemoryRegionOps bmdma_addr_ioport_ops;
 void pci_ide_create_devs(PCIDevice *dev);
 
 #endif
diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index 97ccc75aa6..3539b162b7 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -342,7 +342,7 @@ static void bmdma_addr_write(void *opaque, hwaddr addr,
     bm->addr |= ((data & mask) << shift) & ~3;
 }
 
-MemoryRegionOps bmdma_addr_ioport_ops = {
+static MemoryRegionOps bmdma_addr_ioport_ops = {
     .read = bmdma_addr_read,
     .write = bmdma_addr_write,
     .endianness = DEVICE_LITTLE_ENDIAN,
diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c
index 9cf920369f..373c0dd1ee 100644
--- a/hw/ide/sii3112.c
+++ b/hw/ide/sii3112.c
@@ -34,47 +34,73 @@ struct SiI3112PCIState {
     SiI3112Regs regs[2];
 };
 
-/* The sii3112_reg_read and sii3112_reg_write functions implement the
- * Internal Register Space - BAR5 (section 6.7 of the data sheet).
- */
-
-static uint64_t sii3112_reg_read(void *opaque, hwaddr addr,
-                                unsigned int size)
+static uint64_t sii3112_bmdma_read(void *opaque, hwaddr addr, unsigned int size)
 {
-    SiI3112PCIState *d = opaque;
+    BMDMAState *bm = opaque;
+    SiI3112PCIState *d = SII3112_PCI(bm->pci_dev);
+    int i = (bm == &bm->pci_dev->bmdma[0]) ? 0 : 1;
     uint64_t val;
 
     switch (addr) {
     case 0x00:
-        val = d->i.bmdma[0].cmd;
+        val = bm->cmd;
         break;
     case 0x01:
-        val = d->regs[0].swdata;
+        val = d->regs[i].swdata;
         break;
     case 0x02:
-        val = d->i.bmdma[0].status;
+        val = bm->status;
         break;
     case 0x03:
         val = 0;
         break;
-    case 0x04 ... 0x07:
-        val = bmdma_addr_ioport_ops.read(&d->i.bmdma[0], addr - 4, size);
-        break;
-    case 0x08:
-        val = d->i.bmdma[1].cmd;
+    default:
+        val = 0;
         break;
-    case 0x09:
-        val = d->regs[1].swdata;
+    }
+    trace_sii3112_bmdma_read(size, addr, val);
+    return val;
+}
+
+static void sii3112_bmdma_write(void *opaque, hwaddr addr,
+                                uint64_t val, unsigned int size)
+{
+    BMDMAState *bm = opaque;
+    SiI3112PCIState *d = SII3112_PCI(bm->pci_dev);
+    int i = (bm == &bm->pci_dev->bmdma[0]) ? 0 : 1;
+
+    trace_sii3112_bmdma_write(size, addr, val);
+    switch (addr) {
+    case 0x00:
+        bmdma_cmd_writeb(bm, val);
         break;
-    case 0x0a:
-        val = d->i.bmdma[1].status;
+    case 0x01:
+        d->regs[i].swdata = val & 0x3f;
         break;
-    case 0x0b:
-        val = 0;
+    case 0x02:
+        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 6);
         break;
-    case 0x0c ... 0x0f:
-        val = bmdma_addr_ioport_ops.read(&d->i.bmdma[1], addr - 12, size);
+    default:
         break;
+    }
+}
+
+static const MemoryRegionOps sii3112_bmdma_ops = {
+    .read = sii3112_bmdma_read,
+    .write = sii3112_bmdma_write,
+};
+
+/* The sii3112_reg_read and sii3112_reg_write functions implement the
+ * Internal Register Space - BAR5 (section 6.7 of the data sheet).
+ */
+
+static uint64_t sii3112_reg_read(void *opaque, hwaddr addr,
+                                unsigned int size)
+{
+    SiI3112PCIState *d = opaque;
+    uint64_t val;
+
+    switch (addr) {
     case 0x10:
         val = d->i.bmdma[0].cmd;
         val |= (d->regs[0].confstat & (1UL << 11) ? (1 << 4) : 0); /*SATAINT0*/
@@ -127,38 +153,26 @@ static void sii3112_reg_write(void *opaque, hwaddr addr,
 
     trace_sii3112_write(size, addr, val);
     switch (addr) {
-    case 0x00:
     case 0x10:
         bmdma_cmd_writeb(&d->i.bmdma[0], val);
         break;
-    case 0x01:
     case 0x11:
         d->regs[0].swdata = val & 0x3f;
         break;
-    case 0x02:
     case 0x12:
         d->i.bmdma[0].status = (val & 0x60) | (d->i.bmdma[0].status & 1) |
                                (d->i.bmdma[0].status & ~val & 6);
         break;
-    case 0x04 ... 0x07:
-        bmdma_addr_ioport_ops.write(&d->i.bmdma[0], addr - 4, val, size);
-        break;
-    case 0x08:
     case 0x18:
         bmdma_cmd_writeb(&d->i.bmdma[1], val);
         break;
-    case 0x09:
     case 0x19:
         d->regs[1].swdata = val & 0x3f;
         break;
-    case 0x0a:
     case 0x1a:
         d->i.bmdma[1].status = (val & 0x60) | (d->i.bmdma[1].status & 1) |
                                (d->i.bmdma[1].status & ~val & 6);
         break;
-    case 0x0c ... 0x0f:
-        bmdma_addr_ioport_ops.write(&d->i.bmdma[1], addr - 12, val, size);
-        break;
     case 0x100:
         d->regs[0].scontrol = val & 0xfff;
         if (val & 1) {
@@ -240,6 +254,9 @@ static void sii3112_pci_realize(PCIDevice *dev, Error **errp)
     pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &s->data_ops[1]);
     pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &s->cmd_ops[1]);
 
+    bmdma_init_ops(s, &sii3112_bmdma_ops);
+    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &s->bmdma_ops);
+
     /* BAR5 is in PCI memory space */
     memory_region_init_io(&d->mmio, OBJECT(d), &sii3112_reg_ops, d,
                          "sii3112.bar5", 0x200);
@@ -262,10 +279,10 @@ static void sii3112_pci_realize(PCIDevice *dev, Error **errp)
     memory_region_init_alias(mr, OBJECT(d), "sii3112.bar3", &s->cmd_ops[1], 0,
                              memory_region_size(&s->cmd_ops[1]));
     memory_region_add_subregion_overlap(&d->mmio, 0xc8, mr, 1);
-
     mr = g_new(MemoryRegion, 1);
-    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar4", &d->mmio, 0, 16);
-    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, mr);
+    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar4", &s->bmdma_ops, 0,
+                             memory_region_size(&s->bmdma_ops));
+    memory_region_add_subregion_overlap(&d->mmio, 0x0, mr, 1);
 
     qdev_init_gpio_in(ds, sii3112_set_irq, 2);
     for (i = 0; i < 2; i++) {
@@ -287,7 +304,6 @@ static void sii3112_pci_class_init(ObjectClass *klass, void *data)
     pd->class_id = PCI_CLASS_STORAGE_RAID;
     pd->revision = 1;
     pd->realize = sii3112_pci_realize;
-    pd->exit = NULL;
     dc->reset = sii3112_reset;
     dc->vmsd = NULL;
     dc->desc = "SiI3112A SATA controller";
diff --git a/hw/ide/trace-events b/hw/ide/trace-events
index 57042cafdd..a479525e38 100644
--- a/hw/ide/trace-events
+++ b/hw/ide/trace-events
@@ -38,8 +38,10 @@ bmdma_read(uint64_t addr, uint8_t val) "bmdma: readb 0x%"PRIx64" : 0x%02x"
 bmdma_write(uint64_t addr, uint64_t val) "bmdma: writeb 0x%"PRIx64" : 0x%02"PRIx64
 
 # sii3112.c
-sii3112_read(int size, uint64_t addr, uint64_t val) "bmdma: read (size %d) 0x%"PRIx64" : 0x%02"PRIx64
-sii3112_write(int size, uint64_t addr, uint64_t val) "bmdma: write (size %d) 0x%"PRIx64" : 0x%02"PRIx64
+sii3112_bmdma_read(int size, uint64_t addr, uint64_t val) "read (size %d) 0x%"PRIx64" : 0x%02"PRIx64
+sii3112_bmdma_write(int size, uint64_t addr, uint64_t val) "write (size %d) 0x%"PRIx64" : 0x%02"PRIx64
+sii3112_read(int size, uint64_t addr, uint64_t val) "read (size %d) 0x%"PRIx64" : 0x%02"PRIx64
+sii3112_write(int size, uint64_t addr, uint64_t val) "write (size %d) 0x%"PRIx64" : 0x%02"PRIx64
 sii3112_set_irq(int channel, int level) "channel %d level %d"
 
 # via.c
-- 
2.40.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 13/13] hw/ide: Extract bmdma_clear_status()
  2023-04-22 15:07 [PATCH 00/13] Clean up PCI IDE device models Bernhard Beschow
                   ` (11 preceding siblings ...)
  2023-04-22 15:07 ` [PATCH 12/13] hw/ide/sii3112: Reuse PCIIDEState::bmdma_ops Bernhard Beschow
@ 2023-04-22 15:07 ` Bernhard Beschow
  2023-04-22 21:26   ` BALATON Zoltan
                     ` (2 more replies)
  12 siblings, 3 replies; 77+ messages in thread
From: Bernhard Beschow @ 2023-04-22 15:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc, Bernhard Beschow

Extract bmdma_clear_status() mirroring bmdma_cmd_writeb().

Signed-off-by: Bernhard Beschow <shentey@gmail.com>
---
 include/hw/ide/pci.h |  1 +
 hw/ide/cmd646.c      |  2 +-
 hw/ide/pci.c         |  7 +++++++
 hw/ide/piix.c        |  2 +-
 hw/ide/sii3112.c     | 12 +++++-------
 hw/ide/via.c         |  2 +-
 hw/ide/trace-events  |  1 +
 7 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
index 81e0370202..6a286ad307 100644
--- a/include/hw/ide/pci.h
+++ b/include/hw/ide/pci.h
@@ -59,6 +59,7 @@ struct PCIIDEState {
 void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d);
 void bmdma_init_ops(PCIIDEState *d, const MemoryRegionOps *bmdma_ops);
 void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val);
+void bmdma_clear_status(BMDMAState *bm, uint32_t val);
 void pci_ide_create_devs(PCIDevice *dev);
 
 #endif
diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
index b9d005a357..973c3ff0dc 100644
--- a/hw/ide/cmd646.c
+++ b/hw/ide/cmd646.c
@@ -144,7 +144,7 @@ static void bmdma_write(void *opaque, hwaddr addr,
         cmd646_update_irq(pci_dev);
         break;
     case 2:
-        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
+        bmdma_clear_status(bm, val);
         break;
     case 3:
         if (bm == &bm->pci_dev->bmdma[0]) {
diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index 3539b162b7..4aa06be7c6 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -318,6 +318,13 @@ void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val)
     bm->cmd = val & 0x09;
 }
 
+void bmdma_clear_status(BMDMAState *bm, uint32_t val)
+{
+    trace_bmdma_update_status(val);
+
+    bm->status = (val & 0x60) | (bm->status & BM_STATUS_DMAING) | (bm->status & ~val & 0x06);
+}
+
 static uint64_t bmdma_addr_read(void *opaque, hwaddr addr,
                                 unsigned width)
 {
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index 406a67fa0f..9eab615e35 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -76,7 +76,7 @@ static void bmdma_write(void *opaque, hwaddr addr,
         bmdma_cmd_writeb(bm, val);
         break;
     case 2:
-        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
+        bmdma_clear_status(bm, val);
         break;
     }
 }
diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c
index 373c0dd1ee..1180ff55e7 100644
--- a/hw/ide/sii3112.c
+++ b/hw/ide/sii3112.c
@@ -66,7 +66,7 @@ static void sii3112_bmdma_write(void *opaque, hwaddr addr,
                                 uint64_t val, unsigned int size)
 {
     BMDMAState *bm = opaque;
-    SiI3112PCIState *d = SII3112_PCI(bm->pci_dev);
+    SiI3112PCIState *s = SII3112_PCI(bm->pci_dev);
     int i = (bm == &bm->pci_dev->bmdma[0]) ? 0 : 1;
 
     trace_sii3112_bmdma_write(size, addr, val);
@@ -75,10 +75,10 @@ static void sii3112_bmdma_write(void *opaque, hwaddr addr,
         bmdma_cmd_writeb(bm, val);
         break;
     case 0x01:
-        d->regs[i].swdata = val & 0x3f;
+        s->regs[i].swdata = val & 0x3f;
         break;
     case 0x02:
-        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 6);
+        bmdma_clear_status(bm, val);
         break;
     default:
         break;
@@ -160,8 +160,7 @@ static void sii3112_reg_write(void *opaque, hwaddr addr,
         d->regs[0].swdata = val & 0x3f;
         break;
     case 0x12:
-        d->i.bmdma[0].status = (val & 0x60) | (d->i.bmdma[0].status & 1) |
-                               (d->i.bmdma[0].status & ~val & 6);
+        bmdma_clear_status(&d->i.bmdma[0], val);
         break;
     case 0x18:
         bmdma_cmd_writeb(&d->i.bmdma[1], val);
@@ -170,8 +169,7 @@ static void sii3112_reg_write(void *opaque, hwaddr addr,
         d->regs[1].swdata = val & 0x3f;
         break;
     case 0x1a:
-        d->i.bmdma[1].status = (val & 0x60) | (d->i.bmdma[1].status & 1) |
-                               (d->i.bmdma[1].status & ~val & 6);
+        bmdma_clear_status(&d->i.bmdma[1], val);
         break;
     case 0x100:
         d->regs[0].scontrol = val & 0xfff;
diff --git a/hw/ide/via.c b/hw/ide/via.c
index 35dd97e49b..afb97f302a 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -75,7 +75,7 @@ static void bmdma_write(void *opaque, hwaddr addr,
         bmdma_cmd_writeb(bm, val);
         break;
     case 2:
-        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
+        bmdma_clear_status(bm, val);
         break;
     default:;
     }
diff --git a/hw/ide/trace-events b/hw/ide/trace-events
index a479525e38..d219c64b61 100644
--- a/hw/ide/trace-events
+++ b/hw/ide/trace-events
@@ -30,6 +30,7 @@ bmdma_write_cmd646(uint64_t addr, uint64_t val) "bmdma: writeb 0x%"PRIx64" : 0x%
 # pci.c
 bmdma_reset(void) ""
 bmdma_cmd_writeb(uint32_t val) "val: 0x%08x"
+bmdma_update_status(uint32_t val) "val: 0x%08x"
 bmdma_addr_read(uint64_t data) "data: 0x%016"PRIx64
 bmdma_addr_write(uint64_t data) "data: 0x%016"PRIx64
 
-- 
2.40.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* Re: [PATCH 02/13] hw/ide/via: Implement ISA IRQ routing
  2023-04-22 15:07 ` [PATCH 02/13] hw/ide/via: Implement ISA IRQ routing Bernhard Beschow
@ 2023-04-22 17:23   ` BALATON Zoltan
  2023-04-22 18:47     ` Bernhard Beschow
  2023-04-26 10:55   ` Mark Cave-Ayland
  1 sibling, 1 reply; 77+ messages in thread
From: BALATON Zoltan @ 2023-04-22 17:23 UTC (permalink / raw)
  To: Bernhard Beschow
  Cc: qemu-devel, qemu-block, Jiaxun Yang, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc

On Sat, 22 Apr 2023, Bernhard Beschow wrote:
> The VIA south bridge allows the legacy IDE interrupts to be routed to four
> different ISA interrupts. This can be configured through the 0x4a register in
> the PCI configuration space of the ISA function. The default routing matches
> the legacy ISA IRQs, that is 14 and 15.

On VT8231 0x4a is PCI Master Arbitration Control, IDE interrupt Routing is 
0x4c and only documents 14/15 as valid values. Not sure any guest would 
actually change this or 0x4a and if that could cause problems but you may 
need to handle this somehow. (Apart from testing with MorphOS with -kernel 
you should really be testing with pegasos2.rom with MorphOS and Linux, 
e.g. Debian 8.11 netinstall iso is known to boot.)

Regards,
BALATON Zoltan

> Implement this missing piece of the VIA south bridge.
>
> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
> ---
> hw/ide/via.c      |  6 ++++--
> hw/isa/vt82c686.c | 17 +++++++++++++++++
> 2 files changed, 21 insertions(+), 2 deletions(-)
>
> diff --git a/hw/ide/via.c b/hw/ide/via.c
> index 177baea9a7..0caae52276 100644
> --- a/hw/ide/via.c
> +++ b/hw/ide/via.c
> @@ -31,6 +31,7 @@
> #include "sysemu/dma.h"
> #include "hw/isa/vt82c686.h"
> #include "hw/ide/pci.h"
> +#include "hw/irq.h"
> #include "trace.h"
>
> static uint64_t bmdma_read(void *opaque, hwaddr addr,
> @@ -104,7 +105,8 @@ static void bmdma_setup_bar(PCIIDEState *d)
>
> static void via_ide_set_irq(void *opaque, int n, int level)
> {
> -    PCIDevice *d = PCI_DEVICE(opaque);
> +    PCIIDEState *s = opaque;
> +    PCIDevice *d = PCI_DEVICE(s);
>
>     if (level) {
>         d->config[0x70 + n * 8] |= 0x80;
> @@ -112,7 +114,7 @@ static void via_ide_set_irq(void *opaque, int n, int level)
>         d->config[0x70 + n * 8] &= ~0x80;
>     }
>
> -    via_isa_set_irq(pci_get_function_0(d), 14 + n, level);
> +    qemu_set_irq(s->isa_irq[n], level);
> }
>
> static void via_ide_reset(DeviceState *dev)
> diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
> index ca89119ce0..c7e29bb46a 100644
> --- a/hw/isa/vt82c686.c
> +++ b/hw/isa/vt82c686.c
> @@ -568,9 +568,19 @@ static const VMStateDescription vmstate_via = {
>     }
> };
>
> +static void via_isa_set_ide_irq(void *opaque, int n, int level)
> +{
> +    static const uint8_t irqs[] = { 14, 15, 10, 11 };
> +    ViaISAState *s = opaque;
> +    uint8_t irq = irqs[(s->dev.config[0x4a] >> (n * 2)) & 0x3];
> +
> +    qemu_set_irq(s->isa_irqs_in[irq], level);
> +}
> +
> static void via_isa_init(Object *obj)
> {
>     ViaISAState *s = VIA_ISA(obj);
> +    DeviceState *dev = DEVICE(s);
>
>     object_initialize_child(obj, "rtc", &s->rtc, TYPE_MC146818_RTC);
>     object_initialize_child(obj, "ide", &s->ide, TYPE_VIA_IDE);
> @@ -578,6 +588,8 @@ static void via_isa_init(Object *obj)
>     object_initialize_child(obj, "uhci2", &s->uhci[1], TYPE_VT82C686B_USB_UHCI);
>     object_initialize_child(obj, "ac97", &s->ac97, TYPE_VIA_AC97);
>     object_initialize_child(obj, "mc97", &s->mc97, TYPE_VIA_MC97);
> +
> +    qdev_init_gpio_in_named(dev, via_isa_set_ide_irq, "ide", ARRAY_SIZE(s->ide.isa_irq));
> }
>
> static const TypeInfo via_isa_info = {
> @@ -692,6 +704,10 @@ static void via_isa_realize(PCIDevice *d, Error **errp)
>     if (!qdev_realize(DEVICE(&s->ide), BUS(pci_bus), errp)) {
>         return;
>     }
> +    for (i = 0; i < 2; i++) {
> +        qdev_connect_gpio_out(DEVICE(&s->ide), i,
> +                              qdev_get_gpio_in_named(DEVICE(s), "ide", i));
> +    }
>
>     /* Functions 2-3: USB Ports */
>     for (i = 0; i < ARRAY_SIZE(s->uhci); i++) {
> @@ -814,6 +830,7 @@ static void vt8231_isa_reset(DeviceState *dev)
>                  PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL);
>     pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM);
>
> +    pci_conf[0x4a] = 0x04; /* IDE interrupt Routing */
>     pci_conf[0x58] = 0x40; /* Miscellaneous Control 0 */
>     pci_conf[0x67] = 0x08; /* Fast IR Config */
>     pci_conf[0x6b] = 0x01; /* Fast IR I/O Base */
>


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 04/13] hw/ide: Extract IDEBus assignment into bmdma_init()
  2023-04-22 15:07 ` [PATCH 04/13] hw/ide: Extract IDEBus assignment into bmdma_init() Bernhard Beschow
@ 2023-04-22 17:31   ` BALATON Zoltan
  2023-04-23 17:36   ` Philippe Mathieu-Daudé
  2023-04-26 10:56   ` Mark Cave-Ayland
  2 siblings, 0 replies; 77+ messages in thread
From: BALATON Zoltan @ 2023-04-22 17:31 UTC (permalink / raw)
  To: Bernhard Beschow
  Cc: qemu-devel, qemu-block, Jiaxun Yang, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc

On Sat, 22 Apr 2023, Bernhard Beschow wrote:
> Every invocation of bmdma_init() is followed by `d->bmdma[i].bus = &d->bus[i]`.
> Resolve this redundancy by extracting it into bmdma_init().
>
> Signed-off-by: Bernhard Beschow <shentey@gmail.com>

Reviewed-by: BALATON Zoltan <balaton@eik.bme.hu>


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 05/13] hw/ide: Extract pci_ide_class_init()
  2023-04-22 15:07 ` [PATCH 05/13] hw/ide: Extract pci_ide_class_init() Bernhard Beschow
@ 2023-04-22 17:34   ` BALATON Zoltan
  2023-04-22 18:59     ` Bernhard Beschow
  2023-04-23 17:41   ` Philippe Mathieu-Daudé
  2023-04-26 11:04   ` Mark Cave-Ayland
  2 siblings, 1 reply; 77+ messages in thread
From: BALATON Zoltan @ 2023-04-22 17:34 UTC (permalink / raw)
  To: Bernhard Beschow
  Cc: qemu-devel, qemu-block, Jiaxun Yang, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc

On Sat, 22 Apr 2023, Bernhard Beschow wrote:
> Resolves redundant code in every PCI IDE device model.

This patch could be broken up a bit more as it seems to do unrelated 
changes. Such as setting DEVICE_CATEGORY_STORAGE in a different way could 
be a separate patch to make it simpler to review.

Regards,
BALATON Zoltan

> ---
> include/hw/ide/pci.h |  1 -
> hw/ide/cmd646.c      | 15 ---------------
> hw/ide/pci.c         | 25 ++++++++++++++++++++++++-
> hw/ide/piix.c        | 19 -------------------
> hw/ide/sii3112.c     |  3 ++-
> hw/ide/via.c         | 15 ---------------
> 6 files changed, 26 insertions(+), 52 deletions(-)
>
> diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
> index 74c127e32f..7bc4e53d02 100644
> --- a/include/hw/ide/pci.h
> +++ b/include/hw/ide/pci.h
> @@ -61,7 +61,6 @@ void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val);
> extern MemoryRegionOps bmdma_addr_ioport_ops;
> void pci_ide_create_devs(PCIDevice *dev);
>
> -extern const VMStateDescription vmstate_ide_pci;
> extern const MemoryRegionOps pci_ide_cmd_le_ops;
> extern const MemoryRegionOps pci_ide_data_le_ops;
> #endif
> diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
> index a094a6e12a..9aabf80e52 100644
> --- a/hw/ide/cmd646.c
> +++ b/hw/ide/cmd646.c
> @@ -301,17 +301,6 @@ static void pci_cmd646_ide_realize(PCIDevice *dev, Error **errp)
>     }
> }
>
> -static void pci_cmd646_ide_exitfn(PCIDevice *dev)
> -{
> -    PCIIDEState *d = PCI_IDE(dev);
> -    unsigned i;
> -
> -    for (i = 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_ioport);
> -    }
> -}
> -
> static Property cmd646_ide_properties[] = {
>     DEFINE_PROP_UINT32("secondary", PCIIDEState, secondary, 0),
>     DEFINE_PROP_END_OF_LIST(),
> @@ -323,17 +312,13 @@ static void cmd646_ide_class_init(ObjectClass *klass, void *data)
>     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
>
>     dc->reset = cmd646_reset;
> -    dc->vmsd = &vmstate_ide_pci;
>     k->realize = pci_cmd646_ide_realize;
> -    k->exit = pci_cmd646_ide_exitfn;
>     k->vendor_id = PCI_VENDOR_ID_CMD;
>     k->device_id = PCI_DEVICE_ID_CMD_646;
>     k->revision = 0x07;
> -    k->class_id = PCI_CLASS_STORAGE_IDE;
>     k->config_read = cmd646_pci_config_read;
>     k->config_write = cmd646_pci_config_write;
>     device_class_set_props(dc, cmd646_ide_properties);
> -    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
> }
>
> static const TypeInfo cmd646_ide_info = {
> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
> index 67e0998ff0..8bea92e394 100644
> --- a/hw/ide/pci.c
> +++ b/hw/ide/pci.c
> @@ -467,7 +467,7 @@ static int ide_pci_post_load(void *opaque, int version_id)
>     return 0;
> }
>
> -const VMStateDescription vmstate_ide_pci = {
> +static const VMStateDescription vmstate_ide_pci = {
>     .name = "ide",
>     .version_id = 3,
>     .minimum_version_id = 0,
> @@ -530,11 +530,34 @@ static void pci_ide_init(Object *obj)
>     qdev_init_gpio_out(DEVICE(d), d->isa_irq, ARRAY_SIZE(d->isa_irq));
> }
>
> +static void pci_ide_exitfn(PCIDevice *dev)
> +{
> +    PCIIDEState *d = PCI_IDE(dev);
> +    unsigned i;
> +
> +    for (i = 0; i < ARRAY_SIZE(d->bmdma); ++i) {
> +        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io);
> +        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport);
> +    }
> +}
> +
> +static void pci_ide_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
> +
> +    dc->vmsd = &vmstate_ide_pci;
> +    k->exit = pci_ide_exitfn;
> +    k->class_id = PCI_CLASS_STORAGE_IDE;
> +    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
> +}
> +
> static const TypeInfo pci_ide_type_info = {
>     .name = TYPE_PCI_IDE,
>     .parent = TYPE_PCI_DEVICE,
>     .instance_size = sizeof(PCIIDEState),
>     .instance_init = pci_ide_init,
> +    .class_init = pci_ide_class_init,
>     .abstract = true,
>     .interfaces = (InterfaceInfo[]) {
>         { INTERFACE_CONVENTIONAL_PCI_DEVICE },
> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
> index a32f7ccece..4e6ca99123 100644
> --- a/hw/ide/piix.c
> +++ b/hw/ide/piix.c
> @@ -159,8 +159,6 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
>     bmdma_setup_bar(d);
>     pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
>
> -    vmstate_register(VMSTATE_IF(dev), 0, &vmstate_ide_pci, d);
> -
>     for (unsigned i = 0; i < 2; i++) {
>         if (!pci_piix_init_bus(d, i, errp)) {
>             return;
> @@ -168,17 +166,6 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
>     }
> }
>
> -static void pci_piix_ide_exitfn(PCIDevice *dev)
> -{
> -    PCIIDEState *d = PCI_IDE(dev);
> -    unsigned i;
> -
> -    for (i = 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_ioport);
> -    }
> -}
> -
> /* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */
> static void piix3_ide_class_init(ObjectClass *klass, void *data)
> {
> @@ -187,11 +174,8 @@ static void piix3_ide_class_init(ObjectClass *klass, void *data)
>
>     dc->reset = piix_ide_reset;
>     k->realize = pci_piix_ide_realize;
> -    k->exit = pci_piix_ide_exitfn;
>     k->vendor_id = PCI_VENDOR_ID_INTEL;
>     k->device_id = PCI_DEVICE_ID_INTEL_82371SB_1;
> -    k->class_id = PCI_CLASS_STORAGE_IDE;
> -    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
>     dc->hotpluggable = false;
> }
>
> @@ -209,11 +193,8 @@ static void piix4_ide_class_init(ObjectClass *klass, void *data)
>
>     dc->reset = piix_ide_reset;
>     k->realize = pci_piix_ide_realize;
> -    k->exit = pci_piix_ide_exitfn;
>     k->vendor_id = PCI_VENDOR_ID_INTEL;
>     k->device_id = PCI_DEVICE_ID_INTEL_82371AB;
> -    k->class_id = PCI_CLASS_STORAGE_IDE;
> -    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
>     dc->hotpluggable = false;
> }
>
> diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c
> index 5dd3d03c29..0af897a9ef 100644
> --- a/hw/ide/sii3112.c
> +++ b/hw/ide/sii3112.c
> @@ -301,9 +301,10 @@ static void sii3112_pci_class_init(ObjectClass *klass, void *data)
>     pd->class_id = PCI_CLASS_STORAGE_RAID;
>     pd->revision = 1;
>     pd->realize = sii3112_pci_realize;
> +    pd->exit = NULL;
>     dc->reset = sii3112_reset;
> +    dc->vmsd = NULL;
>     dc->desc = "SiI3112A SATA controller";
> -    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
> }
>
> static const TypeInfo sii3112_pci_info = {
> diff --git a/hw/ide/via.c b/hw/ide/via.c
> index 91253fa4ef..287143a005 100644
> --- a/hw/ide/via.c
> +++ b/hw/ide/via.c
> @@ -200,34 +200,19 @@ static void via_ide_realize(PCIDevice *dev, Error **errp)
>     }
> }
>
> -static void via_ide_exitfn(PCIDevice *dev)
> -{
> -    PCIIDEState *d = PCI_IDE(dev);
> -    unsigned i;
> -
> -    for (i = 0; i < ARRAY_SIZE(d->bmdma); ++i) {
> -        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io);
> -        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport);
> -    }
> -}
> -
> static void via_ide_class_init(ObjectClass *klass, void *data)
> {
>     DeviceClass *dc = DEVICE_CLASS(klass);
>     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
>
>     dc->reset = via_ide_reset;
> -    dc->vmsd = &vmstate_ide_pci;
>     /* Reason: only works as function of VIA southbridge */
>     dc->user_creatable = false;
>
>     k->realize = via_ide_realize;
> -    k->exit = via_ide_exitfn;
>     k->vendor_id = PCI_VENDOR_ID_VIA;
>     k->device_id = PCI_DEVICE_ID_VIA_IDE;
>     k->revision = 0x06;
> -    k->class_id = PCI_CLASS_STORAGE_IDE;
> -    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
> }
>
> static const TypeInfo via_ide_info = {
>


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 08/13] hw/ide: Rename PCIIDEState::*_bar attributes
  2023-04-22 15:07 ` [PATCH 08/13] hw/ide: Rename PCIIDEState::*_bar attributes Bernhard Beschow
@ 2023-04-22 17:53   ` BALATON Zoltan
  2023-04-26 11:21   ` Mark Cave-Ayland
  1 sibling, 0 replies; 77+ messages in thread
From: BALATON Zoltan @ 2023-04-22 17:53 UTC (permalink / raw)
  To: Bernhard Beschow
  Cc: qemu-devel, qemu-block, Jiaxun Yang, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc

On Sat, 22 Apr 2023, Bernhard Beschow wrote:
> The attributes represent memory regions containing operations which are mapped
> by the device models into PCI BARs. Reflect this by changing the suffic into
> "_ops".
>
> Note that in a few commits piix will also use the {cmd,data}_ops but won't map
> them into BARs. This further suggests that the "_bar" suffix doesn't match
> very well.

I'm not sure about this. Ops is typically used for read/write functions of 
an io MemeoryRegion while these are typically regions of a PCI IDE 
contoller that are mapped via BARs so calling them bar looks OK to me and 
this patch seems to be just code churn so I'd just drop this if there's no 
good reason to keep it.

Regards,
BALATON Zoltan

> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
> ---
> include/hw/ide/pci.h |  6 +++---
> hw/ide/cmd646.c      | 10 +++++-----
> hw/ide/pci.c         | 18 +++++++++---------
> hw/ide/piix.c        |  2 +-
> hw/ide/via.c         | 10 +++++-----
> 5 files changed, 23 insertions(+), 23 deletions(-)
>
> diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
> index 597c77c7ad..5025df5b82 100644
> --- a/include/hw/ide/pci.h
> +++ b/include/hw/ide/pci.h
> @@ -51,9 +51,9 @@ struct PCIIDEState {
>     BMDMAState bmdma[2];
>     qemu_irq isa_irq[2];
>     uint32_t secondary; /* used only for cmd646 */
> -    MemoryRegion bmdma_bar;
> -    MemoryRegion cmd_bar[2];
> -    MemoryRegion data_bar[2];
> +    MemoryRegion bmdma_ops;
> +    MemoryRegion cmd_ops[2];
> +    MemoryRegion data_ops[2];
> };
>
> void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d);
> diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
> index 85716aaf17..b9d005a357 100644
> --- a/hw/ide/cmd646.c
> +++ b/hw/ide/cmd646.c
> @@ -251,13 +251,13 @@ static void pci_cmd646_ide_realize(PCIDevice *dev, Error **errp)
>     dev->wmask[MRDMODE] = 0x0;
>     dev->w1cmask[MRDMODE] = MRDMODE_INTR_CH0 | MRDMODE_INTR_CH1;
>
> -    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->data_bar[0]);
> -    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[0]);
> -    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &d->data_bar[1]);
> -    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[1]);
> +    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->data_ops[0]);
> +    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_ops[0]);
> +    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &d->data_ops[1]);
> +    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_ops[1]);
>
>     bmdma_init_ops(d, &cmd646_bmdma_ops);
> -    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
> +    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_ops);
>
>     /* TODO: RST# value should be 0 */
>     pci_conf[PCI_INTERRUPT_PIN] = 0x01; // interrupt on pin 1
> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
> index a9194313bd..b2fcc00a64 100644
> --- a/hw/ide/pci.c
> +++ b/hw/ide/pci.c
> @@ -527,15 +527,15 @@ void bmdma_init_ops(PCIIDEState *d, const MemoryRegionOps *bmdma_ops)
> {
>     size_t i;
>
> -    memory_region_init(&d->bmdma_bar, OBJECT(d), "bmdma-container", 16);
> +    memory_region_init(&d->bmdma_ops, OBJECT(d), "bmdma-container", 16);
>     for (i = 0; i < ARRAY_SIZE(d->bmdma); i++) {
>         BMDMAState *bm = &d->bmdma[i];
>
>         memory_region_init_io(&bm->extra_io, OBJECT(d), bmdma_ops, bm, "bmdma-ops", 4);
> -        memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io);
> +        memory_region_add_subregion(&d->bmdma_ops, i * 8, &bm->extra_io);
>         memory_region_init_io(&bm->addr_ioport, OBJECT(d), &bmdma_addr_ioport_ops, bm,
>                               "bmdma-ioport-ops", 4);
> -        memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport);
> +        memory_region_add_subregion(&d->bmdma_ops, i * 8 + 4, &bm->addr_ioport);
>     }
> }
>
> @@ -543,14 +543,14 @@ static void pci_ide_init(Object *obj)
> {
>     PCIIDEState *d = PCI_IDE(obj);
>
> -    memory_region_init_io(&d->data_bar[0], OBJECT(d), &pci_ide_data_le_ops,
> +    memory_region_init_io(&d->data_ops[0], OBJECT(d), &pci_ide_data_le_ops,
>                           &d->bus[0], "pci-ide0-data-ops", 8);
> -    memory_region_init_io(&d->cmd_bar[0], OBJECT(d), &pci_ide_cmd_le_ops,
> +    memory_region_init_io(&d->cmd_ops[0], OBJECT(d), &pci_ide_cmd_le_ops,
>                           &d->bus[0], "pci-ide0-cmd-ops", 4);
>
> -    memory_region_init_io(&d->data_bar[1], OBJECT(d), &pci_ide_data_le_ops,
> +    memory_region_init_io(&d->data_ops[1], OBJECT(d), &pci_ide_data_le_ops,
>                           &d->bus[1], "pci-ide1-data-ops", 8);
> -    memory_region_init_io(&d->cmd_bar[1], OBJECT(d), &pci_ide_cmd_le_ops,
> +    memory_region_init_io(&d->cmd_ops[1], OBJECT(d), &pci_ide_cmd_le_ops,
>                           &d->bus[1], "pci-ide1-cmd-ops", 4);
>
>     qdev_init_gpio_out(DEVICE(d), d->isa_irq, ARRAY_SIZE(d->isa_irq));
> @@ -562,8 +562,8 @@ static void pci_ide_exitfn(PCIDevice *dev)
>     unsigned i;
>
>     for (i = 0; i < ARRAY_SIZE(d->bmdma); ++i) {
> -        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io);
> -        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport);
> +        memory_region_del_subregion(&d->bmdma_ops, &d->bmdma[i].extra_io);
> +        memory_region_del_subregion(&d->bmdma_ops, &d->bmdma[i].addr_ioport);
>     }
> }
>
> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
> index 5611473d37..6942b484f9 100644
> --- a/hw/ide/piix.c
> +++ b/hw/ide/piix.c
> @@ -140,7 +140,7 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
>     pci_conf[PCI_CLASS_PROG] = 0x80; // legacy ATA mode
>
>     bmdma_init_ops(d, &piix_bmdma_ops);
> -    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
> +    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_ops);
>
>     for (unsigned i = 0; i < 2; i++) {
>         if (!pci_piix_init_bus(d, i, errp)) {
> diff --git a/hw/ide/via.c b/hw/ide/via.c
> index 704a8024cb..35dd97e49b 100644
> --- a/hw/ide/via.c
> +++ b/hw/ide/via.c
> @@ -154,13 +154,13 @@ static void via_ide_realize(PCIDevice *dev, Error **errp)
>     dev->wmask[PCI_INTERRUPT_LINE] = 0;
>     dev->wmask[PCI_CLASS_PROG] = 5;
>
> -    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->data_bar[0]);
> -    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[0]);
> -    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &d->data_bar[1]);
> -    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[1]);
> +    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->data_ops[0]);
> +    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_ops[0]);
> +    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &d->data_ops[1]);
> +    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_ops[1]);
>
>     bmdma_init_ops(d, &via_bmdma_ops);
> -    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
> +    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_ops);
>
>     qdev_init_gpio_in(ds, via_ide_set_irq, ARRAY_SIZE(d->bus));
>     for (i = 0; i < ARRAY_SIZE(d->bus); i++) {
>


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 02/13] hw/ide/via: Implement ISA IRQ routing
  2023-04-22 17:23   ` BALATON Zoltan
@ 2023-04-22 18:47     ` Bernhard Beschow
  2023-04-22 19:21       ` BALATON Zoltan
  0 siblings, 1 reply; 77+ messages in thread
From: Bernhard Beschow @ 2023-04-22 18:47 UTC (permalink / raw)
  To: BALATON Zoltan
  Cc: qemu-devel, qemu-block, Jiaxun Yang, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc



Am 22. April 2023 17:23:56 UTC schrieb BALATON Zoltan <balaton@eik.bme.hu>:
>On Sat, 22 Apr 2023, Bernhard Beschow wrote:
>> The VIA south bridge allows the legacy IDE interrupts to be routed to four
>> different ISA interrupts. This can be configured through the 0x4a register in
>> the PCI configuration space of the ISA function. The default routing matches
>> the legacy ISA IRQs, that is 14 and 15.
>
>On VT8231 0x4a is PCI Master Arbitration Control, IDE interrupt Routing is 0x4c and only documents 14/15 as valid values.

In the datasheet titled "VT8231 South Bridge", preliminary revision 0.8, Oct. 29, 1999, page 60, the "IDE Interrupt Routing" register is located at offset 0x4a and offers the same four interrupts in the same order as in the code. Are we looking at the same datasheet?

>Not sure any guest would actually change this or 0x4a and if that could cause problems but you may need to handle this somehow. (Apart from testing with MorphOS with -kernel you should really be testing with pegasos2.rom with MorphOS and Linux, e.g. Debian 8.11 netinstall iso is known to boot.)

I've tested extensively with an x86 Linux guest on my pc-via branch which worked flawlessly.

As mentioned in the commit message the default routing of the chipset matches legacy behavior, that is interrupts 14 and 15. This is reflected by assigning [0x4a] = 4 in the code and that is how the code behaved before.

Best regards,
Bernhard

>
>Regards,
>BALATON Zoltan
>
>> Implement this missing piece of the VIA south bridge.
>> 
>> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
>> ---
>> hw/ide/via.c      |  6 ++++--
>> hw/isa/vt82c686.c | 17 +++++++++++++++++
>> 2 files changed, 21 insertions(+), 2 deletions(-)
>> 
>> diff --git a/hw/ide/via.c b/hw/ide/via.c
>> index 177baea9a7..0caae52276 100644
>> --- a/hw/ide/via.c
>> +++ b/hw/ide/via.c
>> @@ -31,6 +31,7 @@
>> #include "sysemu/dma.h"
>> #include "hw/isa/vt82c686.h"
>> #include "hw/ide/pci.h"
>> +#include "hw/irq.h"
>> #include "trace.h"
>> 
>> static uint64_t bmdma_read(void *opaque, hwaddr addr,
>> @@ -104,7 +105,8 @@ static void bmdma_setup_bar(PCIIDEState *d)
>> 
>> static void via_ide_set_irq(void *opaque, int n, int level)
>> {
>> -    PCIDevice *d = PCI_DEVICE(opaque);
>> +    PCIIDEState *s = opaque;
>> +    PCIDevice *d = PCI_DEVICE(s);
>> 
>>     if (level) {
>>         d->config[0x70 + n * 8] |= 0x80;
>> @@ -112,7 +114,7 @@ static void via_ide_set_irq(void *opaque, int n, int level)
>>         d->config[0x70 + n * 8] &= ~0x80;
>>     }
>> 
>> -    via_isa_set_irq(pci_get_function_0(d), 14 + n, level);
>> +    qemu_set_irq(s->isa_irq[n], level);
>> }
>> 
>> static void via_ide_reset(DeviceState *dev)
>> diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
>> index ca89119ce0..c7e29bb46a 100644
>> --- a/hw/isa/vt82c686.c
>> +++ b/hw/isa/vt82c686.c
>> @@ -568,9 +568,19 @@ static const VMStateDescription vmstate_via = {
>>     }
>> };
>> 
>> +static void via_isa_set_ide_irq(void *opaque, int n, int level)
>> +{
>> +    static const uint8_t irqs[] = { 14, 15, 10, 11 };
>> +    ViaISAState *s = opaque;
>> +    uint8_t irq = irqs[(s->dev.config[0x4a] >> (n * 2)) & 0x3];
>> +
>> +    qemu_set_irq(s->isa_irqs_in[irq], level);
>> +}
>> +
>> static void via_isa_init(Object *obj)
>> {
>>     ViaISAState *s = VIA_ISA(obj);
>> +    DeviceState *dev = DEVICE(s);
>> 
>>     object_initialize_child(obj, "rtc", &s->rtc, TYPE_MC146818_RTC);
>>     object_initialize_child(obj, "ide", &s->ide, TYPE_VIA_IDE);
>> @@ -578,6 +588,8 @@ static void via_isa_init(Object *obj)
>>     object_initialize_child(obj, "uhci2", &s->uhci[1], TYPE_VT82C686B_USB_UHCI);
>>     object_initialize_child(obj, "ac97", &s->ac97, TYPE_VIA_AC97);
>>     object_initialize_child(obj, "mc97", &s->mc97, TYPE_VIA_MC97);
>> +
>> +    qdev_init_gpio_in_named(dev, via_isa_set_ide_irq, "ide", ARRAY_SIZE(s->ide.isa_irq));
>> }
>> 
>> static const TypeInfo via_isa_info = {
>> @@ -692,6 +704,10 @@ static void via_isa_realize(PCIDevice *d, Error **errp)
>>     if (!qdev_realize(DEVICE(&s->ide), BUS(pci_bus), errp)) {
>>         return;
>>     }
>> +    for (i = 0; i < 2; i++) {
>> +        qdev_connect_gpio_out(DEVICE(&s->ide), i,
>> +                              qdev_get_gpio_in_named(DEVICE(s), "ide", i));
>> +    }
>> 
>>     /* Functions 2-3: USB Ports */
>>     for (i = 0; i < ARRAY_SIZE(s->uhci); i++) {
>> @@ -814,6 +830,7 @@ static void vt8231_isa_reset(DeviceState *dev)
>>                  PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL);
>>     pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM);
>> 
>> +    pci_conf[0x4a] = 0x04; /* IDE interrupt Routing */
>>     pci_conf[0x58] = 0x40; /* Miscellaneous Control 0 */
>>     pci_conf[0x67] = 0x08; /* Fast IR Config */
>>     pci_conf[0x6b] = 0x01; /* Fast IR I/O Base */
>> 


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 05/13] hw/ide: Extract pci_ide_class_init()
  2023-04-22 17:34   ` BALATON Zoltan
@ 2023-04-22 18:59     ` Bernhard Beschow
  0 siblings, 0 replies; 77+ messages in thread
From: Bernhard Beschow @ 2023-04-22 18:59 UTC (permalink / raw)
  To: BALATON Zoltan
  Cc: qemu-devel, qemu-block, Jiaxun Yang, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc



Am 22. April 2023 17:34:30 UTC schrieb BALATON Zoltan <balaton@eik.bme.hu>:
>On Sat, 22 Apr 2023, Bernhard Beschow wrote:
>> Resolves redundant code in every PCI IDE device model.
>
>This patch could be broken up a bit more as it seems to do unrelated changes. Such as setting DEVICE_CATEGORY_STORAGE in a different way could be a separate patch to make it simpler to review.

Okay, I'll slice this patch in the next iteration, moving each assignment separately.

Best regards,
Bernhard

>
>Regards,
>BALATON Zoltan
>
>> ---
>> include/hw/ide/pci.h |  1 -
>> hw/ide/cmd646.c      | 15 ---------------
>> hw/ide/pci.c         | 25 ++++++++++++++++++++++++-
>> hw/ide/piix.c        | 19 -------------------
>> hw/ide/sii3112.c     |  3 ++-
>> hw/ide/via.c         | 15 ---------------
>> 6 files changed, 26 insertions(+), 52 deletions(-)
>> 
>> diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
>> index 74c127e32f..7bc4e53d02 100644
>> --- a/include/hw/ide/pci.h
>> +++ b/include/hw/ide/pci.h
>> @@ -61,7 +61,6 @@ void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val);
>> extern MemoryRegionOps bmdma_addr_ioport_ops;
>> void pci_ide_create_devs(PCIDevice *dev);
>> 
>> -extern const VMStateDescription vmstate_ide_pci;
>> extern const MemoryRegionOps pci_ide_cmd_le_ops;
>> extern const MemoryRegionOps pci_ide_data_le_ops;
>> #endif
>> diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
>> index a094a6e12a..9aabf80e52 100644
>> --- a/hw/ide/cmd646.c
>> +++ b/hw/ide/cmd646.c
>> @@ -301,17 +301,6 @@ static void pci_cmd646_ide_realize(PCIDevice *dev, Error **errp)
>>     }
>> }
>> 
>> -static void pci_cmd646_ide_exitfn(PCIDevice *dev)
>> -{
>> -    PCIIDEState *d = PCI_IDE(dev);
>> -    unsigned i;
>> -
>> -    for (i = 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_ioport);
>> -    }
>> -}
>> -
>> static Property cmd646_ide_properties[] = {
>>     DEFINE_PROP_UINT32("secondary", PCIIDEState, secondary, 0),
>>     DEFINE_PROP_END_OF_LIST(),
>> @@ -323,17 +312,13 @@ static void cmd646_ide_class_init(ObjectClass *klass, void *data)
>>     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
>> 
>>     dc->reset = cmd646_reset;
>> -    dc->vmsd = &vmstate_ide_pci;
>>     k->realize = pci_cmd646_ide_realize;
>> -    k->exit = pci_cmd646_ide_exitfn;
>>     k->vendor_id = PCI_VENDOR_ID_CMD;
>>     k->device_id = PCI_DEVICE_ID_CMD_646;
>>     k->revision = 0x07;
>> -    k->class_id = PCI_CLASS_STORAGE_IDE;
>>     k->config_read = cmd646_pci_config_read;
>>     k->config_write = cmd646_pci_config_write;
>>     device_class_set_props(dc, cmd646_ide_properties);
>> -    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
>> }
>> 
>> static const TypeInfo cmd646_ide_info = {
>> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
>> index 67e0998ff0..8bea92e394 100644
>> --- a/hw/ide/pci.c
>> +++ b/hw/ide/pci.c
>> @@ -467,7 +467,7 @@ static int ide_pci_post_load(void *opaque, int version_id)
>>     return 0;
>> }
>> 
>> -const VMStateDescription vmstate_ide_pci = {
>> +static const VMStateDescription vmstate_ide_pci = {
>>     .name = "ide",
>>     .version_id = 3,
>>     .minimum_version_id = 0,
>> @@ -530,11 +530,34 @@ static void pci_ide_init(Object *obj)
>>     qdev_init_gpio_out(DEVICE(d), d->isa_irq, ARRAY_SIZE(d->isa_irq));
>> }
>> 
>> +static void pci_ide_exitfn(PCIDevice *dev)
>> +{
>> +    PCIIDEState *d = PCI_IDE(dev);
>> +    unsigned i;
>> +
>> +    for (i = 0; i < ARRAY_SIZE(d->bmdma); ++i) {
>> +        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io);
>> +        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport);
>> +    }
>> +}
>> +
>> +static void pci_ide_class_init(ObjectClass *klass, void *data)
>> +{
>> +    DeviceClass *dc = DEVICE_CLASS(klass);
>> +    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
>> +
>> +    dc->vmsd = &vmstate_ide_pci;
>> +    k->exit = pci_ide_exitfn;
>> +    k->class_id = PCI_CLASS_STORAGE_IDE;
>> +    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
>> +}
>> +
>> static const TypeInfo pci_ide_type_info = {
>>     .name = TYPE_PCI_IDE,
>>     .parent = TYPE_PCI_DEVICE,
>>     .instance_size = sizeof(PCIIDEState),
>>     .instance_init = pci_ide_init,
>> +    .class_init = pci_ide_class_init,
>>     .abstract = true,
>>     .interfaces = (InterfaceInfo[]) {
>>         { INTERFACE_CONVENTIONAL_PCI_DEVICE },
>> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
>> index a32f7ccece..4e6ca99123 100644
>> --- a/hw/ide/piix.c
>> +++ b/hw/ide/piix.c
>> @@ -159,8 +159,6 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
>>     bmdma_setup_bar(d);
>>     pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
>> 
>> -    vmstate_register(VMSTATE_IF(dev), 0, &vmstate_ide_pci, d);
>> -
>>     for (unsigned i = 0; i < 2; i++) {
>>         if (!pci_piix_init_bus(d, i, errp)) {
>>             return;
>> @@ -168,17 +166,6 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
>>     }
>> }
>> 
>> -static void pci_piix_ide_exitfn(PCIDevice *dev)
>> -{
>> -    PCIIDEState *d = PCI_IDE(dev);
>> -    unsigned i;
>> -
>> -    for (i = 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_ioport);
>> -    }
>> -}
>> -
>> /* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */
>> static void piix3_ide_class_init(ObjectClass *klass, void *data)
>> {
>> @@ -187,11 +174,8 @@ static void piix3_ide_class_init(ObjectClass *klass, void *data)
>> 
>>     dc->reset = piix_ide_reset;
>>     k->realize = pci_piix_ide_realize;
>> -    k->exit = pci_piix_ide_exitfn;
>>     k->vendor_id = PCI_VENDOR_ID_INTEL;
>>     k->device_id = PCI_DEVICE_ID_INTEL_82371SB_1;
>> -    k->class_id = PCI_CLASS_STORAGE_IDE;
>> -    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
>>     dc->hotpluggable = false;
>> }
>> 
>> @@ -209,11 +193,8 @@ static void piix4_ide_class_init(ObjectClass *klass, void *data)
>> 
>>     dc->reset = piix_ide_reset;
>>     k->realize = pci_piix_ide_realize;
>> -    k->exit = pci_piix_ide_exitfn;
>>     k->vendor_id = PCI_VENDOR_ID_INTEL;
>>     k->device_id = PCI_DEVICE_ID_INTEL_82371AB;
>> -    k->class_id = PCI_CLASS_STORAGE_IDE;
>> -    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
>>     dc->hotpluggable = false;
>> }
>> 
>> diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c
>> index 5dd3d03c29..0af897a9ef 100644
>> --- a/hw/ide/sii3112.c
>> +++ b/hw/ide/sii3112.c
>> @@ -301,9 +301,10 @@ static void sii3112_pci_class_init(ObjectClass *klass, void *data)
>>     pd->class_id = PCI_CLASS_STORAGE_RAID;
>>     pd->revision = 1;
>>     pd->realize = sii3112_pci_realize;
>> +    pd->exit = NULL;
>>     dc->reset = sii3112_reset;
>> +    dc->vmsd = NULL;
>>     dc->desc = "SiI3112A SATA controller";
>> -    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
>> }
>> 
>> static const TypeInfo sii3112_pci_info = {
>> diff --git a/hw/ide/via.c b/hw/ide/via.c
>> index 91253fa4ef..287143a005 100644
>> --- a/hw/ide/via.c
>> +++ b/hw/ide/via.c
>> @@ -200,34 +200,19 @@ static void via_ide_realize(PCIDevice *dev, Error **errp)
>>     }
>> }
>> 
>> -static void via_ide_exitfn(PCIDevice *dev)
>> -{
>> -    PCIIDEState *d = PCI_IDE(dev);
>> -    unsigned i;
>> -
>> -    for (i = 0; i < ARRAY_SIZE(d->bmdma); ++i) {
>> -        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io);
>> -        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport);
>> -    }
>> -}
>> -
>> static void via_ide_class_init(ObjectClass *klass, void *data)
>> {
>>     DeviceClass *dc = DEVICE_CLASS(klass);
>>     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
>> 
>>     dc->reset = via_ide_reset;
>> -    dc->vmsd = &vmstate_ide_pci;
>>     /* Reason: only works as function of VIA southbridge */
>>     dc->user_creatable = false;
>> 
>>     k->realize = via_ide_realize;
>> -    k->exit = via_ide_exitfn;
>>     k->vendor_id = PCI_VENDOR_ID_VIA;
>>     k->device_id = PCI_DEVICE_ID_VIA_IDE;
>>     k->revision = 0x06;
>> -    k->class_id = PCI_CLASS_STORAGE_IDE;
>> -    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
>> }
>> 
>> static const TypeInfo via_ide_info = {
>> 


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 02/13] hw/ide/via: Implement ISA IRQ routing
  2023-04-22 18:47     ` Bernhard Beschow
@ 2023-04-22 19:21       ` BALATON Zoltan
  2023-04-24  7:50         ` Bernhard Beschow
  0 siblings, 1 reply; 77+ messages in thread
From: BALATON Zoltan @ 2023-04-22 19:21 UTC (permalink / raw)
  To: Bernhard Beschow
  Cc: qemu-devel, qemu-block, Jiaxun Yang, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc

On Sat, 22 Apr 2023, Bernhard Beschow wrote:
> Am 22. April 2023 17:23:56 UTC schrieb BALATON Zoltan <balaton@eik.bme.hu>:
>> On Sat, 22 Apr 2023, Bernhard Beschow wrote:
>>> The VIA south bridge allows the legacy IDE interrupts to be routed to four
>>> different ISA interrupts. This can be configured through the 0x4a register in
>>> the PCI configuration space of the ISA function. The default routing matches
>>> the legacy ISA IRQs, that is 14 and 15.
>>
>> On VT8231 0x4a is PCI Master Arbitration Control, IDE interrupt Routing is 0x4c and only documents 14/15 as valid values.
>
> In the datasheet titled "VT8231 South Bridge", preliminary revision 0.8, 
> Oct. 29, 1999, page 60, the "IDE Interrupt Routing" register is located 
> at offset 0x4a and offers the same four interrupts in the same order as 
> in the code. Are we looking at the same datasheet?

Apparently not. The one I have says: Revision 2.32, May 10, 2004. Looks 
more authorative than a preliminary one.

>> Not sure any guest would actually change this or 0x4a and if that could cause problems but you may need to handle this somehow. (Apart from testing with MorphOS with -kernel you should really be testing with pegasos2.rom with MorphOS and Linux, e.g. Debian 8.11 netinstall iso is known to boot.)
>
> I've tested extensively with an x86 Linux guest on my pc-via branch which worked flawlessly.

That does not substitute testing Linux on pegasos2 though becuase there 
are some hacks in Linux kernel to handle some pecularities of the pegasos2 
including via ide on that machine and that can only be fully tested with 
pegasos2.rom and PPC Linux.

> As mentioned in the commit message the default routing of the chipset 
> matches legacy behavior, that is interrupts 14 and 15. This is reflected 
> by assigning [0x4a] = 4 in the code and that is how the code behaved 
> before.

And that's the only allowed value on VT8231, other bits are listed as 
reserved so I wonder if we want to model this at all if no guest is 
touching it anyway. So you could also just drop that part and keep it hard 
mapped to 14-15 as it is now, mentioning the config reg in a comment if we 
ever find a guest that needs it.

Regards,
BALATON Zoltan


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 11/13] hw/ide/sii3112: Reuse PCIIDEState::{cmd,data}_ops
  2023-04-22 15:07 ` [PATCH 11/13] hw/ide/sii3112: " Bernhard Beschow
@ 2023-04-22 21:10   ` BALATON Zoltan
  2023-04-23 22:19     ` Bernhard Beschow
  2023-04-26 11:41   ` Mark Cave-Ayland
  1 sibling, 1 reply; 77+ messages in thread
From: BALATON Zoltan @ 2023-04-22 21:10 UTC (permalink / raw)
  To: Bernhard Beschow
  Cc: qemu-devel, qemu-block, Jiaxun Yang, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc

On Sat, 22 Apr 2023, Bernhard Beschow wrote:
> Allows to unexport pci_ide_{cmd,data}_le_ops and models TYPE_SII3112_PCI as a
> standard-compliant PCI IDE device.
>
> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
> ---
> include/hw/ide/pci.h |  2 --
> hw/ide/pci.c         |  4 ++--
> hw/ide/sii3112.c     | 50 ++++++++++++++++----------------------------
> 3 files changed, 20 insertions(+), 36 deletions(-)
>
> diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
> index 5025df5b82..dbb4b13161 100644
> --- a/include/hw/ide/pci.h
> +++ b/include/hw/ide/pci.h
> @@ -62,6 +62,4 @@ void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val);
> extern MemoryRegionOps bmdma_addr_ioport_ops;
> void pci_ide_create_devs(PCIDevice *dev);
>
> -extern const MemoryRegionOps pci_ide_cmd_le_ops;
> -extern const MemoryRegionOps pci_ide_data_le_ops;
> #endif
> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
> index b2fcc00a64..97ccc75aa6 100644
> --- a/hw/ide/pci.c
> +++ b/hw/ide/pci.c
> @@ -60,7 +60,7 @@ static void pci_ide_ctrl_write(void *opaque, hwaddr addr,
>     ide_ctrl_write(bus, addr + 2, data);
> }
>
> -const MemoryRegionOps pci_ide_cmd_le_ops = {
> +static const MemoryRegionOps pci_ide_cmd_le_ops = {
>     .read = pci_ide_status_read,
>     .write = pci_ide_ctrl_write,
>     .endianness = DEVICE_LITTLE_ENDIAN,
> @@ -98,7 +98,7 @@ static void pci_ide_data_write(void *opaque, hwaddr addr,
>     }
> }
>
> -const MemoryRegionOps pci_ide_data_le_ops = {
> +static const MemoryRegionOps pci_ide_data_le_ops = {
>     .read = pci_ide_data_read,
>     .write = pci_ide_data_write,
>     .endianness = DEVICE_LITTLE_ENDIAN,
> diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c
> index 0af897a9ef..9cf920369f 100644
> --- a/hw/ide/sii3112.c
> +++ b/hw/ide/sii3112.c
> @@ -88,21 +88,9 @@ static uint64_t sii3112_reg_read(void *opaque, hwaddr addr,
>         val |= (d->regs[1].confstat & (1UL << 11) ? (1 << 4) : 0);
>         val |= (uint32_t)d->i.bmdma[1].status << 16;
>         break;
> -    case 0x80 ... 0x87:
> -        val = pci_ide_data_le_ops.read(&d->i.bus[0], addr - 0x80, size);
> -        break;
> -    case 0x8a:
> -        val = pci_ide_cmd_le_ops.read(&d->i.bus[0], 2, size);
> -        break;
>     case 0xa0:
>         val = d->regs[0].confstat;
>         break;
> -    case 0xc0 ... 0xc7:
> -        val = pci_ide_data_le_ops.read(&d->i.bus[1], addr - 0xc0, size);
> -        break;
> -    case 0xca:
> -        val = pci_ide_cmd_le_ops.read(&d->i.bus[1], 2, size);
> -        break;
>     case 0xe0:
>         val = d->regs[1].confstat;
>         break;
> @@ -171,18 +159,6 @@ static void sii3112_reg_write(void *opaque, hwaddr addr,
>     case 0x0c ... 0x0f:
>         bmdma_addr_ioport_ops.write(&d->i.bmdma[1], addr - 12, val, size);
>         break;
> -    case 0x80 ... 0x87:
> -        pci_ide_data_le_ops.write(&d->i.bus[0], addr - 0x80, val, size);
> -        break;
> -    case 0x8a:
> -        pci_ide_cmd_le_ops.write(&d->i.bus[0], 2, val, size);
> -        break;
> -    case 0xc0 ... 0xc7:
> -        pci_ide_data_le_ops.write(&d->i.bus[1], addr - 0xc0, val, size);
> -        break;
> -    case 0xca:
> -        pci_ide_cmd_le_ops.write(&d->i.bus[1], 2, val, size);
> -        break;
>     case 0x100:
>         d->regs[0].scontrol = val & 0xfff;
>         if (val & 1) {
> @@ -259,6 +235,11 @@ static void sii3112_pci_realize(PCIDevice *dev, Error **errp)
>     pci_config_set_interrupt_pin(dev->config, 1);
>     pci_set_byte(dev->config + PCI_CACHE_LINE_SIZE, 8);
>
> +    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->data_ops[0]);
> +    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->cmd_ops[0]);
> +    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &s->data_ops[1]);
> +    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &s->cmd_ops[1]);
> +
>     /* BAR5 is in PCI memory space */
>     memory_region_init_io(&d->mmio, OBJECT(d), &sii3112_reg_ops, d,
>                          "sii3112.bar5", 0x200);
> @@ -266,17 +247,22 @@ static void sii3112_pci_realize(PCIDevice *dev, Error **errp)
>
>     /* BAR0-BAR4 are PCI I/O space aliases into BAR5 */

This patch breaks the above comment but I think you should not mess with 
BAR0-4 at all and leave to to aliased into BAR5. These have the same 
registers mirrored and some guests access them via the memory mapped BAR5 
while others prefer the io mapped BAR0-4 so removing these from BAR5 would 
break some guests. If you want to remove something from BAR5 and map 
subregions implementing those instead then I think only BAR5 needs to be 
chnaged or I'm not getting what is happening here so a more detailed 
commit message would be needed.

Was this tested? A minimal test might be booting AROS and MorphOS on 
sam460ex.

Regards,
BALATON Zoltan

>     mr = g_new(MemoryRegion, 1);
> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar0", &d->mmio, 0x80, 8);
> -    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, mr);
> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar0", &s->data_ops[0], 0,
> +                             memory_region_size(&s->data_ops[0]));
> +    memory_region_add_subregion_overlap(&d->mmio, 0x80, mr, 1);
>     mr = g_new(MemoryRegion, 1);
> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar1", &d->mmio, 0x88, 4);
> -    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, mr);
> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar1", &s->cmd_ops[0], 0,
> +                             memory_region_size(&s->cmd_ops[0]));
> +    memory_region_add_subregion_overlap(&d->mmio, 0x88, mr, 1);
>     mr = g_new(MemoryRegion, 1);
> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar2", &d->mmio, 0xc0, 8);
> -    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, mr);
> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar2", &s->data_ops[1], 0,
> +                             memory_region_size(&s->data_ops[1]));
> +    memory_region_add_subregion_overlap(&d->mmio, 0xc0, mr, 1);
>     mr = g_new(MemoryRegion, 1);
> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar3", &d->mmio, 0xc8, 4);
> -    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, mr);
> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar3", &s->cmd_ops[1], 0,
> +                             memory_region_size(&s->cmd_ops[1]));
> +    memory_region_add_subregion_overlap(&d->mmio, 0xc8, mr, 1);
> +
>     mr = g_new(MemoryRegion, 1);
>     memory_region_init_alias(mr, OBJECT(d), "sii3112.bar4", &d->mmio, 0, 16);
>     pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, mr);
>


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 13/13] hw/ide: Extract bmdma_clear_status()
  2023-04-22 15:07 ` [PATCH 13/13] hw/ide: Extract bmdma_clear_status() Bernhard Beschow
@ 2023-04-22 21:26   ` BALATON Zoltan
  2023-04-23  7:48     ` Bernhard Beschow
  2023-04-22 22:46   ` BALATON Zoltan
  2023-04-26 11:48   ` Mark Cave-Ayland
  2 siblings, 1 reply; 77+ messages in thread
From: BALATON Zoltan @ 2023-04-22 21:26 UTC (permalink / raw)
  To: Bernhard Beschow
  Cc: qemu-devel, qemu-block, Jiaxun Yang, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc

On Sat, 22 Apr 2023, Bernhard Beschow wrote:
> Extract bmdma_clear_status() mirroring bmdma_cmd_writeb().

Is adding a trace point useful? This is called from places that already 
have traces so I don't think we need another separate trace point here. 
Also the names don't match but maybe rename function to 
bmdma_update_status instead as it is more what it does.

Regards,
BALATON Zoltan

> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
> ---
> include/hw/ide/pci.h |  1 +
> hw/ide/cmd646.c      |  2 +-
> hw/ide/pci.c         |  7 +++++++
> hw/ide/piix.c        |  2 +-
> hw/ide/sii3112.c     | 12 +++++-------
> hw/ide/via.c         |  2 +-
> hw/ide/trace-events  |  1 +
> 7 files changed, 17 insertions(+), 10 deletions(-)
>
> diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
> index 81e0370202..6a286ad307 100644
> --- a/include/hw/ide/pci.h
> +++ b/include/hw/ide/pci.h
> @@ -59,6 +59,7 @@ struct PCIIDEState {
> void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d);
> void bmdma_init_ops(PCIIDEState *d, const MemoryRegionOps *bmdma_ops);
> void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val);
> +void bmdma_clear_status(BMDMAState *bm, uint32_t val);
> void pci_ide_create_devs(PCIDevice *dev);
>
> #endif
> diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
> index b9d005a357..973c3ff0dc 100644
> --- a/hw/ide/cmd646.c
> +++ b/hw/ide/cmd646.c
> @@ -144,7 +144,7 @@ static void bmdma_write(void *opaque, hwaddr addr,
>         cmd646_update_irq(pci_dev);
>         break;
>     case 2:
> -        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
> +        bmdma_clear_status(bm, val);
>         break;
>     case 3:
>         if (bm == &bm->pci_dev->bmdma[0]) {
> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
> index 3539b162b7..4aa06be7c6 100644
> --- a/hw/ide/pci.c
> +++ b/hw/ide/pci.c
> @@ -318,6 +318,13 @@ void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val)
>     bm->cmd = val & 0x09;
> }
>
> +void bmdma_clear_status(BMDMAState *bm, uint32_t val)
> +{
> +    trace_bmdma_update_status(val);
> +
> +    bm->status = (val & 0x60) | (bm->status & BM_STATUS_DMAING) | (bm->status & ~val & 0x06);
> +}
> +
> static uint64_t bmdma_addr_read(void *opaque, hwaddr addr,
>                                 unsigned width)
> {
> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
> index 406a67fa0f..9eab615e35 100644
> --- a/hw/ide/piix.c
> +++ b/hw/ide/piix.c
> @@ -76,7 +76,7 @@ static void bmdma_write(void *opaque, hwaddr addr,
>         bmdma_cmd_writeb(bm, val);
>         break;
>     case 2:
> -        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
> +        bmdma_clear_status(bm, val);
>         break;
>     }
> }
> diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c
> index 373c0dd1ee..1180ff55e7 100644
> --- a/hw/ide/sii3112.c
> +++ b/hw/ide/sii3112.c
> @@ -66,7 +66,7 @@ static void sii3112_bmdma_write(void *opaque, hwaddr addr,
>                                 uint64_t val, unsigned int size)
> {
>     BMDMAState *bm = opaque;
> -    SiI3112PCIState *d = SII3112_PCI(bm->pci_dev);
> +    SiI3112PCIState *s = SII3112_PCI(bm->pci_dev);
>     int i = (bm == &bm->pci_dev->bmdma[0]) ? 0 : 1;
>
>     trace_sii3112_bmdma_write(size, addr, val);
> @@ -75,10 +75,10 @@ static void sii3112_bmdma_write(void *opaque, hwaddr addr,
>         bmdma_cmd_writeb(bm, val);
>         break;
>     case 0x01:
> -        d->regs[i].swdata = val & 0x3f;
> +        s->regs[i].swdata = val & 0x3f;
>         break;
>     case 0x02:
> -        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 6);
> +        bmdma_clear_status(bm, val);
>         break;
>     default:
>         break;
> @@ -160,8 +160,7 @@ static void sii3112_reg_write(void *opaque, hwaddr addr,
>         d->regs[0].swdata = val & 0x3f;
>         break;
>     case 0x12:
> -        d->i.bmdma[0].status = (val & 0x60) | (d->i.bmdma[0].status & 1) |
> -                               (d->i.bmdma[0].status & ~val & 6);
> +        bmdma_clear_status(&d->i.bmdma[0], val);
>         break;
>     case 0x18:
>         bmdma_cmd_writeb(&d->i.bmdma[1], val);
> @@ -170,8 +169,7 @@ static void sii3112_reg_write(void *opaque, hwaddr addr,
>         d->regs[1].swdata = val & 0x3f;
>         break;
>     case 0x1a:
> -        d->i.bmdma[1].status = (val & 0x60) | (d->i.bmdma[1].status & 1) |
> -                               (d->i.bmdma[1].status & ~val & 6);
> +        bmdma_clear_status(&d->i.bmdma[1], val);
>         break;
>     case 0x100:
>         d->regs[0].scontrol = val & 0xfff;
> diff --git a/hw/ide/via.c b/hw/ide/via.c
> index 35dd97e49b..afb97f302a 100644
> --- a/hw/ide/via.c
> +++ b/hw/ide/via.c
> @@ -75,7 +75,7 @@ static void bmdma_write(void *opaque, hwaddr addr,
>         bmdma_cmd_writeb(bm, val);
>         break;
>     case 2:
> -        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
> +        bmdma_clear_status(bm, val);
>         break;
>     default:;
>     }
> diff --git a/hw/ide/trace-events b/hw/ide/trace-events
> index a479525e38..d219c64b61 100644
> --- a/hw/ide/trace-events
> +++ b/hw/ide/trace-events
> @@ -30,6 +30,7 @@ bmdma_write_cmd646(uint64_t addr, uint64_t val) "bmdma: writeb 0x%"PRIx64" : 0x%
> # pci.c
> bmdma_reset(void) ""
> bmdma_cmd_writeb(uint32_t val) "val: 0x%08x"
> +bmdma_update_status(uint32_t val) "val: 0x%08x"
> bmdma_addr_read(uint64_t data) "data: 0x%016"PRIx64
> bmdma_addr_write(uint64_t data) "data: 0x%016"PRIx64
>
>


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 13/13] hw/ide: Extract bmdma_clear_status()
  2023-04-22 15:07 ` [PATCH 13/13] hw/ide: Extract bmdma_clear_status() Bernhard Beschow
  2023-04-22 21:26   ` BALATON Zoltan
@ 2023-04-22 22:46   ` BALATON Zoltan
  2023-04-23  7:35     ` Bernhard Beschow
  2023-04-26 11:48   ` Mark Cave-Ayland
  2 siblings, 1 reply; 77+ messages in thread
From: BALATON Zoltan @ 2023-04-22 22:46 UTC (permalink / raw)
  To: Bernhard Beschow
  Cc: qemu-devel, qemu-block, Jiaxun Yang, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc

On Sat, 22 Apr 2023, Bernhard Beschow wrote:
> Extract bmdma_clear_status() mirroring bmdma_cmd_writeb().
>
> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
> ---
> include/hw/ide/pci.h |  1 +
> hw/ide/cmd646.c      |  2 +-
> hw/ide/pci.c         |  7 +++++++
> hw/ide/piix.c        |  2 +-
> hw/ide/sii3112.c     | 12 +++++-------
> hw/ide/via.c         |  2 +-
> hw/ide/trace-events  |  1 +
> 7 files changed, 17 insertions(+), 10 deletions(-)
>
> diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
> index 81e0370202..6a286ad307 100644
> --- a/include/hw/ide/pci.h
> +++ b/include/hw/ide/pci.h
> @@ -59,6 +59,7 @@ struct PCIIDEState {
> void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d);
> void bmdma_init_ops(PCIIDEState *d, const MemoryRegionOps *bmdma_ops);
> void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val);
> +void bmdma_clear_status(BMDMAState *bm, uint32_t val);
> void pci_ide_create_devs(PCIDevice *dev);
>
> #endif
> diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
> index b9d005a357..973c3ff0dc 100644
> --- a/hw/ide/cmd646.c
> +++ b/hw/ide/cmd646.c
> @@ -144,7 +144,7 @@ static void bmdma_write(void *opaque, hwaddr addr,
>         cmd646_update_irq(pci_dev);
>         break;
>     case 2:
> -        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
> +        bmdma_clear_status(bm, val);
>         break;
>     case 3:
>         if (bm == &bm->pci_dev->bmdma[0]) {
> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
> index 3539b162b7..4aa06be7c6 100644
> --- a/hw/ide/pci.c
> +++ b/hw/ide/pci.c
> @@ -318,6 +318,13 @@ void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val)
>     bm->cmd = val & 0x09;
> }
>
> +void bmdma_clear_status(BMDMAState *bm, uint32_t val)
> +{
> +    trace_bmdma_update_status(val);
> +
> +    bm->status = (val & 0x60) | (bm->status & BM_STATUS_DMAING) | (bm->status & ~val & 0x06);
> +}
> +
> static uint64_t bmdma_addr_read(void *opaque, hwaddr addr,
>                                 unsigned width)
> {
> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
> index 406a67fa0f..9eab615e35 100644
> --- a/hw/ide/piix.c
> +++ b/hw/ide/piix.c
> @@ -76,7 +76,7 @@ static void bmdma_write(void *opaque, hwaddr addr,
>         bmdma_cmd_writeb(bm, val);
>         break;
>     case 2:
> -        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
> +        bmdma_clear_status(bm, val);
>         break;
>     }
> }
> diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c
> index 373c0dd1ee..1180ff55e7 100644
> --- a/hw/ide/sii3112.c
> +++ b/hw/ide/sii3112.c
> @@ -66,7 +66,7 @@ static void sii3112_bmdma_write(void *opaque, hwaddr addr,
>                                 uint64_t val, unsigned int size)
> {
>     BMDMAState *bm = opaque;
> -    SiI3112PCIState *d = SII3112_PCI(bm->pci_dev);
> +    SiI3112PCIState *s = SII3112_PCI(bm->pci_dev);

Also renaming local variable is an unrelated change. May be separate patch 
but wasn't it added in previous patch? Why not already done there?

Regards,
BALATON Zoltan

>     int i = (bm == &bm->pci_dev->bmdma[0]) ? 0 : 1;
>
>     trace_sii3112_bmdma_write(size, addr, val);
> @@ -75,10 +75,10 @@ static void sii3112_bmdma_write(void *opaque, hwaddr addr,
>         bmdma_cmd_writeb(bm, val);
>         break;
>     case 0x01:
> -        d->regs[i].swdata = val & 0x3f;
> +        s->regs[i].swdata = val & 0x3f;
>         break;
>     case 0x02:
> -        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 6);
> +        bmdma_clear_status(bm, val);
>         break;
>     default:
>         break;
> @@ -160,8 +160,7 @@ static void sii3112_reg_write(void *opaque, hwaddr addr,
>         d->regs[0].swdata = val & 0x3f;
>         break;
>     case 0x12:
> -        d->i.bmdma[0].status = (val & 0x60) | (d->i.bmdma[0].status & 1) |
> -                               (d->i.bmdma[0].status & ~val & 6);
> +        bmdma_clear_status(&d->i.bmdma[0], val);
>         break;
>     case 0x18:
>         bmdma_cmd_writeb(&d->i.bmdma[1], val);
> @@ -170,8 +169,7 @@ static void sii3112_reg_write(void *opaque, hwaddr addr,
>         d->regs[1].swdata = val & 0x3f;
>         break;
>     case 0x1a:
> -        d->i.bmdma[1].status = (val & 0x60) | (d->i.bmdma[1].status & 1) |
> -                               (d->i.bmdma[1].status & ~val & 6);
> +        bmdma_clear_status(&d->i.bmdma[1], val);
>         break;
>     case 0x100:
>         d->regs[0].scontrol = val & 0xfff;
> diff --git a/hw/ide/via.c b/hw/ide/via.c
> index 35dd97e49b..afb97f302a 100644
> --- a/hw/ide/via.c
> +++ b/hw/ide/via.c
> @@ -75,7 +75,7 @@ static void bmdma_write(void *opaque, hwaddr addr,
>         bmdma_cmd_writeb(bm, val);
>         break;
>     case 2:
> -        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
> +        bmdma_clear_status(bm, val);
>         break;
>     default:;
>     }
> diff --git a/hw/ide/trace-events b/hw/ide/trace-events
> index a479525e38..d219c64b61 100644
> --- a/hw/ide/trace-events
> +++ b/hw/ide/trace-events
> @@ -30,6 +30,7 @@ bmdma_write_cmd646(uint64_t addr, uint64_t val) "bmdma: writeb 0x%"PRIx64" : 0x%
> # pci.c
> bmdma_reset(void) ""
> bmdma_cmd_writeb(uint32_t val) "val: 0x%08x"
> +bmdma_update_status(uint32_t val) "val: 0x%08x"
> bmdma_addr_read(uint64_t data) "data: 0x%016"PRIx64
> bmdma_addr_write(uint64_t data) "data: 0x%016"PRIx64
>
>


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 13/13] hw/ide: Extract bmdma_clear_status()
  2023-04-22 22:46   ` BALATON Zoltan
@ 2023-04-23  7:35     ` Bernhard Beschow
  0 siblings, 0 replies; 77+ messages in thread
From: Bernhard Beschow @ 2023-04-23  7:35 UTC (permalink / raw)
  To: BALATON Zoltan
  Cc: qemu-devel, qemu-block, Jiaxun Yang, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc



Am 22. April 2023 22:46:08 UTC schrieb BALATON Zoltan <balaton@eik.bme.hu>:
>On Sat, 22 Apr 2023, Bernhard Beschow wrote:
>> Extract bmdma_clear_status() mirroring bmdma_cmd_writeb().
>> 
>> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
>> ---
>> include/hw/ide/pci.h |  1 +
>> hw/ide/cmd646.c      |  2 +-
>> hw/ide/pci.c         |  7 +++++++
>> hw/ide/piix.c        |  2 +-
>> hw/ide/sii3112.c     | 12 +++++-------
>> hw/ide/via.c         |  2 +-
>> hw/ide/trace-events  |  1 +
>> 7 files changed, 17 insertions(+), 10 deletions(-)
>> 
>> diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
>> index 81e0370202..6a286ad307 100644
>> --- a/include/hw/ide/pci.h
>> +++ b/include/hw/ide/pci.h
>> @@ -59,6 +59,7 @@ struct PCIIDEState {
>> void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d);
>> void bmdma_init_ops(PCIIDEState *d, const MemoryRegionOps *bmdma_ops);
>> void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val);
>> +void bmdma_clear_status(BMDMAState *bm, uint32_t val);
>> void pci_ide_create_devs(PCIDevice *dev);
>> 
>> #endif
>> diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
>> index b9d005a357..973c3ff0dc 100644
>> --- a/hw/ide/cmd646.c
>> +++ b/hw/ide/cmd646.c
>> @@ -144,7 +144,7 @@ static void bmdma_write(void *opaque, hwaddr addr,
>>         cmd646_update_irq(pci_dev);
>>         break;
>>     case 2:
>> -        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
>> +        bmdma_clear_status(bm, val);
>>         break;
>>     case 3:
>>         if (bm == &bm->pci_dev->bmdma[0]) {
>> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
>> index 3539b162b7..4aa06be7c6 100644
>> --- a/hw/ide/pci.c
>> +++ b/hw/ide/pci.c
>> @@ -318,6 +318,13 @@ void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val)
>>     bm->cmd = val & 0x09;
>> }
>> 
>> +void bmdma_clear_status(BMDMAState *bm, uint32_t val)
>> +{
>> +    trace_bmdma_update_status(val);
>> +
>> +    bm->status = (val & 0x60) | (bm->status & BM_STATUS_DMAING) | (bm->status & ~val & 0x06);
>> +}
>> +
>> static uint64_t bmdma_addr_read(void *opaque, hwaddr addr,
>>                                 unsigned width)
>> {
>> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
>> index 406a67fa0f..9eab615e35 100644
>> --- a/hw/ide/piix.c
>> +++ b/hw/ide/piix.c
>> @@ -76,7 +76,7 @@ static void bmdma_write(void *opaque, hwaddr addr,
>>         bmdma_cmd_writeb(bm, val);
>>         break;
>>     case 2:
>> -        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
>> +        bmdma_clear_status(bm, val);
>>         break;
>>     }
>> }
>> diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c
>> index 373c0dd1ee..1180ff55e7 100644
>> --- a/hw/ide/sii3112.c
>> +++ b/hw/ide/sii3112.c
>> @@ -66,7 +66,7 @@ static void sii3112_bmdma_write(void *opaque, hwaddr addr,
>>                                 uint64_t val, unsigned int size)
>> {
>>     BMDMAState *bm = opaque;
>> -    SiI3112PCIState *d = SII3112_PCI(bm->pci_dev);
>> +    SiI3112PCIState *s = SII3112_PCI(bm->pci_dev);
>
>Also renaming local variable is an unrelated change. May be separate patch but wasn't it added in previous patch? Why not already done there?

This change is unintented. I'll fix it. Thanks for catching!

Best regards,
Bernhard

>
>Regards,
>BALATON Zoltan
>
>>     int i = (bm == &bm->pci_dev->bmdma[0]) ? 0 : 1;
>> 
>>     trace_sii3112_bmdma_write(size, addr, val);
>> @@ -75,10 +75,10 @@ static void sii3112_bmdma_write(void *opaque, hwaddr addr,
>>         bmdma_cmd_writeb(bm, val);
>>         break;
>>     case 0x01:
>> -        d->regs[i].swdata = val & 0x3f;
>> +        s->regs[i].swdata = val & 0x3f;
>>         break;
>>     case 0x02:
>> -        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 6);
>> +        bmdma_clear_status(bm, val);
>>         break;
>>     default:
>>         break;
>> @@ -160,8 +160,7 @@ static void sii3112_reg_write(void *opaque, hwaddr addr,
>>         d->regs[0].swdata = val & 0x3f;
>>         break;
>>     case 0x12:
>> -        d->i.bmdma[0].status = (val & 0x60) | (d->i.bmdma[0].status & 1) |
>> -                               (d->i.bmdma[0].status & ~val & 6);
>> +        bmdma_clear_status(&d->i.bmdma[0], val);
>>         break;
>>     case 0x18:
>>         bmdma_cmd_writeb(&d->i.bmdma[1], val);
>> @@ -170,8 +169,7 @@ static void sii3112_reg_write(void *opaque, hwaddr addr,
>>         d->regs[1].swdata = val & 0x3f;
>>         break;
>>     case 0x1a:
>> -        d->i.bmdma[1].status = (val & 0x60) | (d->i.bmdma[1].status & 1) |
>> -                               (d->i.bmdma[1].status & ~val & 6);
>> +        bmdma_clear_status(&d->i.bmdma[1], val);
>>         break;
>>     case 0x100:
>>         d->regs[0].scontrol = val & 0xfff;
>> diff --git a/hw/ide/via.c b/hw/ide/via.c
>> index 35dd97e49b..afb97f302a 100644
>> --- a/hw/ide/via.c
>> +++ b/hw/ide/via.c
>> @@ -75,7 +75,7 @@ static void bmdma_write(void *opaque, hwaddr addr,
>>         bmdma_cmd_writeb(bm, val);
>>         break;
>>     case 2:
>> -        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
>> +        bmdma_clear_status(bm, val);
>>         break;
>>     default:;
>>     }
>> diff --git a/hw/ide/trace-events b/hw/ide/trace-events
>> index a479525e38..d219c64b61 100644
>> --- a/hw/ide/trace-events
>> +++ b/hw/ide/trace-events
>> @@ -30,6 +30,7 @@ bmdma_write_cmd646(uint64_t addr, uint64_t val) "bmdma: writeb 0x%"PRIx64" : 0x%
>> # pci.c
>> bmdma_reset(void) ""
>> bmdma_cmd_writeb(uint32_t val) "val: 0x%08x"
>> +bmdma_update_status(uint32_t val) "val: 0x%08x"
>> bmdma_addr_read(uint64_t data) "data: 0x%016"PRIx64
>> bmdma_addr_write(uint64_t data) "data: 0x%016"PRIx64
>> 
>> 


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 13/13] hw/ide: Extract bmdma_clear_status()
  2023-04-22 21:26   ` BALATON Zoltan
@ 2023-04-23  7:48     ` Bernhard Beschow
  2023-04-23 10:40       ` BALATON Zoltan
  0 siblings, 1 reply; 77+ messages in thread
From: Bernhard Beschow @ 2023-04-23  7:48 UTC (permalink / raw)
  To: BALATON Zoltan
  Cc: qemu-devel, qemu-block, Jiaxun Yang, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc



Am 22. April 2023 21:26:00 UTC schrieb BALATON Zoltan <balaton@eik.bme.hu>:
>On Sat, 22 Apr 2023, Bernhard Beschow wrote:
>> Extract bmdma_clear_status() mirroring bmdma_cmd_writeb().
>
>Is adding a trace point useful? This is called from places that already have traces so I don't think we need another separate trace point here.

Adding a trace point was my original motivation to have this function. Then I realized that extracting the code in a dedicated function is a merit in itself. The trace point is a leftover, so I'll remove it.

>Also the names don't match but maybe rename function to bmdma_update_status instead as it is more what it does.

The status attribute models a w1c-style register. Writing to it can only clear bits, hence the name. Indeed I originally named the function bmdma_update_status() but thought it was too vague. I'm open to suggestions though.

Best regards,
Bernhard

>
>Regards,
>BALATON Zoltan
>
>> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
>> ---
>> include/hw/ide/pci.h |  1 +
>> hw/ide/cmd646.c      |  2 +-
>> hw/ide/pci.c         |  7 +++++++
>> hw/ide/piix.c        |  2 +-
>> hw/ide/sii3112.c     | 12 +++++-------
>> hw/ide/via.c         |  2 +-
>> hw/ide/trace-events  |  1 +
>> 7 files changed, 17 insertions(+), 10 deletions(-)
>> 
>> diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
>> index 81e0370202..6a286ad307 100644
>> --- a/include/hw/ide/pci.h
>> +++ b/include/hw/ide/pci.h
>> @@ -59,6 +59,7 @@ struct PCIIDEState {
>> void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d);
>> void bmdma_init_ops(PCIIDEState *d, const MemoryRegionOps *bmdma_ops);
>> void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val);
>> +void bmdma_clear_status(BMDMAState *bm, uint32_t val);
>> void pci_ide_create_devs(PCIDevice *dev);
>> 
>> #endif
>> diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
>> index b9d005a357..973c3ff0dc 100644
>> --- a/hw/ide/cmd646.c
>> +++ b/hw/ide/cmd646.c
>> @@ -144,7 +144,7 @@ static void bmdma_write(void *opaque, hwaddr addr,
>>         cmd646_update_irq(pci_dev);
>>         break;
>>     case 2:
>> -        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
>> +        bmdma_clear_status(bm, val);
>>         break;
>>     case 3:
>>         if (bm == &bm->pci_dev->bmdma[0]) {
>> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
>> index 3539b162b7..4aa06be7c6 100644
>> --- a/hw/ide/pci.c
>> +++ b/hw/ide/pci.c
>> @@ -318,6 +318,13 @@ void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val)
>>     bm->cmd = val & 0x09;
>> }
>> 
>> +void bmdma_clear_status(BMDMAState *bm, uint32_t val)
>> +{
>> +    trace_bmdma_update_status(val);
>> +
>> +    bm->status = (val & 0x60) | (bm->status & BM_STATUS_DMAING) | (bm->status & ~val & 0x06);
>> +}
>> +
>> static uint64_t bmdma_addr_read(void *opaque, hwaddr addr,
>>                                 unsigned width)
>> {
>> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
>> index 406a67fa0f..9eab615e35 100644
>> --- a/hw/ide/piix.c
>> +++ b/hw/ide/piix.c
>> @@ -76,7 +76,7 @@ static void bmdma_write(void *opaque, hwaddr addr,
>>         bmdma_cmd_writeb(bm, val);
>>         break;
>>     case 2:
>> -        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
>> +        bmdma_clear_status(bm, val);
>>         break;
>>     }
>> }
>> diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c
>> index 373c0dd1ee..1180ff55e7 100644
>> --- a/hw/ide/sii3112.c
>> +++ b/hw/ide/sii3112.c
>> @@ -66,7 +66,7 @@ static void sii3112_bmdma_write(void *opaque, hwaddr addr,
>>                                 uint64_t val, unsigned int size)
>> {
>>     BMDMAState *bm = opaque;
>> -    SiI3112PCIState *d = SII3112_PCI(bm->pci_dev);
>> +    SiI3112PCIState *s = SII3112_PCI(bm->pci_dev);
>>     int i = (bm == &bm->pci_dev->bmdma[0]) ? 0 : 1;
>> 
>>     trace_sii3112_bmdma_write(size, addr, val);
>> @@ -75,10 +75,10 @@ static void sii3112_bmdma_write(void *opaque, hwaddr addr,
>>         bmdma_cmd_writeb(bm, val);
>>         break;
>>     case 0x01:
>> -        d->regs[i].swdata = val & 0x3f;
>> +        s->regs[i].swdata = val & 0x3f;
>>         break;
>>     case 0x02:
>> -        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 6);
>> +        bmdma_clear_status(bm, val);
>>         break;
>>     default:
>>         break;
>> @@ -160,8 +160,7 @@ static void sii3112_reg_write(void *opaque, hwaddr addr,
>>         d->regs[0].swdata = val & 0x3f;
>>         break;
>>     case 0x12:
>> -        d->i.bmdma[0].status = (val & 0x60) | (d->i.bmdma[0].status & 1) |
>> -                               (d->i.bmdma[0].status & ~val & 6);
>> +        bmdma_clear_status(&d->i.bmdma[0], val);
>>         break;
>>     case 0x18:
>>         bmdma_cmd_writeb(&d->i.bmdma[1], val);
>> @@ -170,8 +169,7 @@ static void sii3112_reg_write(void *opaque, hwaddr addr,
>>         d->regs[1].swdata = val & 0x3f;
>>         break;
>>     case 0x1a:
>> -        d->i.bmdma[1].status = (val & 0x60) | (d->i.bmdma[1].status & 1) |
>> -                               (d->i.bmdma[1].status & ~val & 6);
>> +        bmdma_clear_status(&d->i.bmdma[1], val);
>>         break;
>>     case 0x100:
>>         d->regs[0].scontrol = val & 0xfff;
>> diff --git a/hw/ide/via.c b/hw/ide/via.c
>> index 35dd97e49b..afb97f302a 100644
>> --- a/hw/ide/via.c
>> +++ b/hw/ide/via.c
>> @@ -75,7 +75,7 @@ static void bmdma_write(void *opaque, hwaddr addr,
>>         bmdma_cmd_writeb(bm, val);
>>         break;
>>     case 2:
>> -        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
>> +        bmdma_clear_status(bm, val);
>>         break;
>>     default:;
>>     }
>> diff --git a/hw/ide/trace-events b/hw/ide/trace-events
>> index a479525e38..d219c64b61 100644
>> --- a/hw/ide/trace-events
>> +++ b/hw/ide/trace-events
>> @@ -30,6 +30,7 @@ bmdma_write_cmd646(uint64_t addr, uint64_t val) "bmdma: writeb 0x%"PRIx64" : 0x%
>> # pci.c
>> bmdma_reset(void) ""
>> bmdma_cmd_writeb(uint32_t val) "val: 0x%08x"
>> +bmdma_update_status(uint32_t val) "val: 0x%08x"
>> bmdma_addr_read(uint64_t data) "data: 0x%016"PRIx64
>> bmdma_addr_write(uint64_t data) "data: 0x%016"PRIx64
>> 
>> 


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 13/13] hw/ide: Extract bmdma_clear_status()
  2023-04-23  7:48     ` Bernhard Beschow
@ 2023-04-23 10:40       ` BALATON Zoltan
  2023-04-23 21:53         ` Bernhard Beschow
  0 siblings, 1 reply; 77+ messages in thread
From: BALATON Zoltan @ 2023-04-23 10:40 UTC (permalink / raw)
  To: Bernhard Beschow
  Cc: qemu-devel, qemu-block, Jiaxun Yang, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc

On Sun, 23 Apr 2023, Bernhard Beschow wrote:
> Am 22. April 2023 21:26:00 UTC schrieb BALATON Zoltan <balaton@eik.bme.hu>:
>> On Sat, 22 Apr 2023, Bernhard Beschow wrote:
>>> Extract bmdma_clear_status() mirroring bmdma_cmd_writeb().
>>
>> Is adding a trace point useful? This is called from places that already have traces so I don't think we need another separate trace point here.
>
> Adding a trace point was my original motivation to have this function. Then I realized that extracting the code in a dedicated function is a merit in itself. The trace point is a leftover, so I'll remove it.
>
>> Also the names don't match but maybe rename function to bmdma_update_status instead as it is more what it does.
>
> The status attribute models a w1c-style register. Writing to it can only 
> clear bits, hence the name. Indeed I originally named the function 
> bmdma_update_status() but thought it was too vague. I'm open to 
> suggestions though.

The function seems to clear bits 1-2 but set bits 5-6 so it it has some 
write 1 to clear and some read write bits. Therefore naming the function 
clear when it can also set bits is not quite right so I think update is 
better.

Regards,
BALATON Zoltan

>>> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
>>> ---
>>> include/hw/ide/pci.h |  1 +
>>> hw/ide/cmd646.c      |  2 +-
>>> hw/ide/pci.c         |  7 +++++++
>>> hw/ide/piix.c        |  2 +-
>>> hw/ide/sii3112.c     | 12 +++++-------
>>> hw/ide/via.c         |  2 +-
>>> hw/ide/trace-events  |  1 +
>>> 7 files changed, 17 insertions(+), 10 deletions(-)
>>>
>>> diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
>>> index 81e0370202..6a286ad307 100644
>>> --- a/include/hw/ide/pci.h
>>> +++ b/include/hw/ide/pci.h
>>> @@ -59,6 +59,7 @@ struct PCIIDEState {
>>> void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d);
>>> void bmdma_init_ops(PCIIDEState *d, const MemoryRegionOps *bmdma_ops);
>>> void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val);
>>> +void bmdma_clear_status(BMDMAState *bm, uint32_t val);
>>> void pci_ide_create_devs(PCIDevice *dev);
>>>
>>> #endif
>>> diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
>>> index b9d005a357..973c3ff0dc 100644
>>> --- a/hw/ide/cmd646.c
>>> +++ b/hw/ide/cmd646.c
>>> @@ -144,7 +144,7 @@ static void bmdma_write(void *opaque, hwaddr addr,
>>>         cmd646_update_irq(pci_dev);
>>>         break;
>>>     case 2:
>>> -        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
>>> +        bmdma_clear_status(bm, val);
>>>         break;
>>>     case 3:
>>>         if (bm == &bm->pci_dev->bmdma[0]) {
>>> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
>>> index 3539b162b7..4aa06be7c6 100644
>>> --- a/hw/ide/pci.c
>>> +++ b/hw/ide/pci.c
>>> @@ -318,6 +318,13 @@ void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val)
>>>     bm->cmd = val & 0x09;
>>> }
>>>
>>> +void bmdma_clear_status(BMDMAState *bm, uint32_t val)
>>> +{
>>> +    trace_bmdma_update_status(val);
>>> +
>>> +    bm->status = (val & 0x60) | (bm->status & BM_STATUS_DMAING) | (bm->status & ~val & 0x06);
>>> +}
>>> +
>>> static uint64_t bmdma_addr_read(void *opaque, hwaddr addr,
>>>                                 unsigned width)
>>> {
>>> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
>>> index 406a67fa0f..9eab615e35 100644
>>> --- a/hw/ide/piix.c
>>> +++ b/hw/ide/piix.c
>>> @@ -76,7 +76,7 @@ static void bmdma_write(void *opaque, hwaddr addr,
>>>         bmdma_cmd_writeb(bm, val);
>>>         break;
>>>     case 2:
>>> -        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
>>> +        bmdma_clear_status(bm, val);
>>>         break;
>>>     }
>>> }
>>> diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c
>>> index 373c0dd1ee..1180ff55e7 100644
>>> --- a/hw/ide/sii3112.c
>>> +++ b/hw/ide/sii3112.c
>>> @@ -66,7 +66,7 @@ static void sii3112_bmdma_write(void *opaque, hwaddr addr,
>>>                                 uint64_t val, unsigned int size)
>>> {
>>>     BMDMAState *bm = opaque;
>>> -    SiI3112PCIState *d = SII3112_PCI(bm->pci_dev);
>>> +    SiI3112PCIState *s = SII3112_PCI(bm->pci_dev);
>>>     int i = (bm == &bm->pci_dev->bmdma[0]) ? 0 : 1;
>>>
>>>     trace_sii3112_bmdma_write(size, addr, val);
>>> @@ -75,10 +75,10 @@ static void sii3112_bmdma_write(void *opaque, hwaddr addr,
>>>         bmdma_cmd_writeb(bm, val);
>>>         break;
>>>     case 0x01:
>>> -        d->regs[i].swdata = val & 0x3f;
>>> +        s->regs[i].swdata = val & 0x3f;
>>>         break;
>>>     case 0x02:
>>> -        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 6);
>>> +        bmdma_clear_status(bm, val);
>>>         break;
>>>     default:
>>>         break;
>>> @@ -160,8 +160,7 @@ static void sii3112_reg_write(void *opaque, hwaddr addr,
>>>         d->regs[0].swdata = val & 0x3f;
>>>         break;
>>>     case 0x12:
>>> -        d->i.bmdma[0].status = (val & 0x60) | (d->i.bmdma[0].status & 1) |
>>> -                               (d->i.bmdma[0].status & ~val & 6);
>>> +        bmdma_clear_status(&d->i.bmdma[0], val);
>>>         break;
>>>     case 0x18:
>>>         bmdma_cmd_writeb(&d->i.bmdma[1], val);
>>> @@ -170,8 +169,7 @@ static void sii3112_reg_write(void *opaque, hwaddr addr,
>>>         d->regs[1].swdata = val & 0x3f;
>>>         break;
>>>     case 0x1a:
>>> -        d->i.bmdma[1].status = (val & 0x60) | (d->i.bmdma[1].status & 1) |
>>> -                               (d->i.bmdma[1].status & ~val & 6);
>>> +        bmdma_clear_status(&d->i.bmdma[1], val);
>>>         break;
>>>     case 0x100:
>>>         d->regs[0].scontrol = val & 0xfff;
>>> diff --git a/hw/ide/via.c b/hw/ide/via.c
>>> index 35dd97e49b..afb97f302a 100644
>>> --- a/hw/ide/via.c
>>> +++ b/hw/ide/via.c
>>> @@ -75,7 +75,7 @@ static void bmdma_write(void *opaque, hwaddr addr,
>>>         bmdma_cmd_writeb(bm, val);
>>>         break;
>>>     case 2:
>>> -        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
>>> +        bmdma_clear_status(bm, val);
>>>         break;
>>>     default:;
>>>     }
>>> diff --git a/hw/ide/trace-events b/hw/ide/trace-events
>>> index a479525e38..d219c64b61 100644
>>> --- a/hw/ide/trace-events
>>> +++ b/hw/ide/trace-events
>>> @@ -30,6 +30,7 @@ bmdma_write_cmd646(uint64_t addr, uint64_t val) "bmdma: writeb 0x%"PRIx64" : 0x%
>>> # pci.c
>>> bmdma_reset(void) ""
>>> bmdma_cmd_writeb(uint32_t val) "val: 0x%08x"
>>> +bmdma_update_status(uint32_t val) "val: 0x%08x"
>>> bmdma_addr_read(uint64_t data) "data: 0x%016"PRIx64
>>> bmdma_addr_write(uint64_t data) "data: 0x%016"PRIx64
>>>
>>>
>
>


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 04/13] hw/ide: Extract IDEBus assignment into bmdma_init()
  2023-04-22 15:07 ` [PATCH 04/13] hw/ide: Extract IDEBus assignment into bmdma_init() Bernhard Beschow
  2023-04-22 17:31   ` BALATON Zoltan
@ 2023-04-23 17:36   ` Philippe Mathieu-Daudé
  2023-04-26 10:56   ` Mark Cave-Ayland
  2 siblings, 0 replies; 77+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-04-23 17:36 UTC (permalink / raw)
  To: Bernhard Beschow, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	qemu-ppc

On 22/4/23 17:07, Bernhard Beschow wrote:
> Every invocation of bmdma_init() is followed by `d->bmdma[i].bus = &d->bus[i]`.
> Resolve this redundancy by extracting it into bmdma_init().
> 
> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
> ---
>   hw/ide/cmd646.c  | 1 -
>   hw/ide/pci.c     | 1 +
>   hw/ide/piix.c    | 1 -
>   hw/ide/sii3112.c | 1 -
>   hw/ide/via.c     | 1 -
>   5 files changed, 1 insertion(+), 4 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>



^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 05/13] hw/ide: Extract pci_ide_class_init()
  2023-04-22 15:07 ` [PATCH 05/13] hw/ide: Extract pci_ide_class_init() Bernhard Beschow
  2023-04-22 17:34   ` BALATON Zoltan
@ 2023-04-23 17:41   ` Philippe Mathieu-Daudé
  2023-04-23 22:11     ` Bernhard Beschow
  2023-04-26 11:04   ` Mark Cave-Ayland
  2 siblings, 1 reply; 77+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-04-23 17:41 UTC (permalink / raw)
  To: Bernhard Beschow, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	qemu-ppc

On 22/4/23 17:07, Bernhard Beschow wrote:
> Resolves redundant code in every PCI IDE device model.
> ---
>   include/hw/ide/pci.h |  1 -
>   hw/ide/cmd646.c      | 15 ---------------
>   hw/ide/pci.c         | 25 ++++++++++++++++++++++++-
>   hw/ide/piix.c        | 19 -------------------
>   hw/ide/sii3112.c     |  3 ++-
>   hw/ide/via.c         | 15 ---------------
>   6 files changed, 26 insertions(+), 52 deletions(-)


> diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c
> index 5dd3d03c29..0af897a9ef 100644
> --- a/hw/ide/sii3112.c
> +++ b/hw/ide/sii3112.c
> @@ -301,9 +301,10 @@ static void sii3112_pci_class_init(ObjectClass *klass, void *data)
>       pd->class_id = PCI_CLASS_STORAGE_RAID;
>       pd->revision = 1;
>       pd->realize = sii3112_pci_realize;
> +    pd->exit = NULL;
>       dc->reset = sii3112_reset;
> +    dc->vmsd = NULL;
>       dc->desc = "SiI3112A SATA controller";

The SiI3112A doesn't have these regions?


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 06/13] hw/ide: Extract bmdma_init_ops()
  2023-04-22 15:07 ` [PATCH 06/13] hw/ide: Extract bmdma_init_ops() Bernhard Beschow
@ 2023-04-23 17:43   ` Philippe Mathieu-Daudé
  2023-04-23 22:06     ` Bernhard Beschow
  2023-04-26 11:14   ` Mark Cave-Ayland
  1 sibling, 1 reply; 77+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-04-23 17:43 UTC (permalink / raw)
  To: Bernhard Beschow, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	qemu-ppc

On 22/4/23 17:07, Bernhard Beschow wrote:
> There are three private copies of bmdma_setup_bar() with small adaptions.
> Consolidate them into one public implementation.
> 
> While at it rename the function to bmdma_init_ops() to reflect that the memory
> regions being initialized represent BMDMA operations. The actual mapping as a
> PCI BAR is still performed separately in each device.
> 
> Note that the bmdma_bar attribute will be renamed in a separate commit.
> 
> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
> ---
>   include/hw/ide/pci.h |  1 +
>   hw/ide/cmd646.c      | 20 +-------------------
>   hw/ide/pci.c         | 16 ++++++++++++++++
>   hw/ide/piix.c        | 19 +------------------
>   hw/ide/via.c         | 19 +------------------
>   5 files changed, 20 insertions(+), 55 deletions(-)

Nice.

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>



^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 07/13] hw/ide: Extract pci_ide_{cmd,data}_le_ops initialization into base class constructor
  2023-04-22 15:07 ` [PATCH 07/13] hw/ide: Extract pci_ide_{cmd, data}_le_ops initialization into base class constructor Bernhard Beschow
@ 2023-04-23 17:46   ` Philippe Mathieu-Daudé
  2023-04-24  7:45     ` Bernhard Beschow
  2023-04-26 11:16   ` [PATCH 07/13] hw/ide: Extract pci_ide_{cmd, data}_le_ops " Mark Cave-Ayland
  1 sibling, 1 reply; 77+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-04-23 17:46 UTC (permalink / raw)
  To: Bernhard Beschow, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	qemu-ppc

On 22/4/23 17:07, Bernhard Beschow wrote:
> There is redundant code in cmd646 and via which can be extracted into the base
> class. In case of piix and sii3112 this is currently unneccessary but shouldn't
> interfere since the memory regions aren't mapped by those devices. In few
> commits later this will be changed, i.e. those device models will also make use
> of these memory regions.
> 
> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
> ---
>   hw/ide/cmd646.c | 11 -----------
>   hw/ide/pci.c    | 10 ++++++++++
>   hw/ide/via.c    | 11 -----------
>   3 files changed, 10 insertions(+), 22 deletions(-)


> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
> index 65ed6f7f72..a9194313bd 100644
> --- a/hw/ide/pci.c
> +++ b/hw/ide/pci.c
> @@ -543,6 +543,16 @@ static void pci_ide_init(Object *obj)
>   {
>       PCIIDEState *d = PCI_IDE(obj);
>   
> +    memory_region_init_io(&d->data_bar[0], OBJECT(d), &pci_ide_data_le_ops,
> +                          &d->bus[0], "pci-ide0-data-ops", 8);
> +    memory_region_init_io(&d->cmd_bar[0], OBJECT(d), &pci_ide_cmd_le_ops,
> +                          &d->bus[0], "pci-ide0-cmd-ops", 4);
> +
> +    memory_region_init_io(&d->data_bar[1], OBJECT(d), &pci_ide_data_le_ops,
> +                          &d->bus[1], "pci-ide1-data-ops", 8);
> +    memory_region_init_io(&d->cmd_bar[1], OBJECT(d), &pci_ide_cmd_le_ops,
> +                          &d->bus[1], "pci-ide1-cmd-ops", 4);

The trailing "-ops" just adds noise IMO.

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>



^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 13/13] hw/ide: Extract bmdma_clear_status()
  2023-04-23 10:40       ` BALATON Zoltan
@ 2023-04-23 21:53         ` Bernhard Beschow
  0 siblings, 0 replies; 77+ messages in thread
From: Bernhard Beschow @ 2023-04-23 21:53 UTC (permalink / raw)
  To: BALATON Zoltan
  Cc: qemu-devel, qemu-block, Jiaxun Yang, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc



Am 23. April 2023 10:40:50 UTC schrieb BALATON Zoltan <balaton@eik.bme.hu>:
>On Sun, 23 Apr 2023, Bernhard Beschow wrote:
>> Am 22. April 2023 21:26:00 UTC schrieb BALATON Zoltan <balaton@eik.bme.hu>:
>>> On Sat, 22 Apr 2023, Bernhard Beschow wrote:
>>>> Extract bmdma_clear_status() mirroring bmdma_cmd_writeb().
>>> 
>>> Is adding a trace point useful? This is called from places that already have traces so I don't think we need another separate trace point here.
>> 
>> Adding a trace point was my original motivation to have this function. Then I realized that extracting the code in a dedicated function is a merit in itself. The trace point is a leftover, so I'll remove it.
>> 
>>> Also the names don't match but maybe rename function to bmdma_update_status instead as it is more what it does.
>> 
>> The status attribute models a w1c-style register. Writing to it can only clear bits, hence the name. Indeed I originally named the function bmdma_update_status() but thought it was too vague. I'm open to suggestions though.
>
>The function seems to clear bits 1-2 but set bits 5-6 so it it has some write 1 to clear and some read write bits. Therefore naming the function clear when it can also set bits is not quite right so I think update is better.

Convinced. I'll rename to bmdma_update_status() in the next iteration.

Best regards,
Bernhard

>
>Regards,
>BALATON Zoltan
>
>>>> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
>>>> ---
>>>> include/hw/ide/pci.h |  1 +
>>>> hw/ide/cmd646.c      |  2 +-
>>>> hw/ide/pci.c         |  7 +++++++
>>>> hw/ide/piix.c        |  2 +-
>>>> hw/ide/sii3112.c     | 12 +++++-------
>>>> hw/ide/via.c         |  2 +-
>>>> hw/ide/trace-events  |  1 +
>>>> 7 files changed, 17 insertions(+), 10 deletions(-)
>>>> 
>>>> diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
>>>> index 81e0370202..6a286ad307 100644
>>>> --- a/include/hw/ide/pci.h
>>>> +++ b/include/hw/ide/pci.h
>>>> @@ -59,6 +59,7 @@ struct PCIIDEState {
>>>> void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d);
>>>> void bmdma_init_ops(PCIIDEState *d, const MemoryRegionOps *bmdma_ops);
>>>> void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val);
>>>> +void bmdma_clear_status(BMDMAState *bm, uint32_t val);
>>>> void pci_ide_create_devs(PCIDevice *dev);
>>>> 
>>>> #endif
>>>> diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
>>>> index b9d005a357..973c3ff0dc 100644
>>>> --- a/hw/ide/cmd646.c
>>>> +++ b/hw/ide/cmd646.c
>>>> @@ -144,7 +144,7 @@ static void bmdma_write(void *opaque, hwaddr addr,
>>>>         cmd646_update_irq(pci_dev);
>>>>         break;
>>>>     case 2:
>>>> -        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
>>>> +        bmdma_clear_status(bm, val);
>>>>         break;
>>>>     case 3:
>>>>         if (bm == &bm->pci_dev->bmdma[0]) {
>>>> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
>>>> index 3539b162b7..4aa06be7c6 100644
>>>> --- a/hw/ide/pci.c
>>>> +++ b/hw/ide/pci.c
>>>> @@ -318,6 +318,13 @@ void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val)
>>>>     bm->cmd = val & 0x09;
>>>> }
>>>> 
>>>> +void bmdma_clear_status(BMDMAState *bm, uint32_t val)
>>>> +{
>>>> +    trace_bmdma_update_status(val);
>>>> +
>>>> +    bm->status = (val & 0x60) | (bm->status & BM_STATUS_DMAING) | (bm->status & ~val & 0x06);
>>>> +}
>>>> +
>>>> static uint64_t bmdma_addr_read(void *opaque, hwaddr addr,
>>>>                                 unsigned width)
>>>> {
>>>> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
>>>> index 406a67fa0f..9eab615e35 100644
>>>> --- a/hw/ide/piix.c
>>>> +++ b/hw/ide/piix.c
>>>> @@ -76,7 +76,7 @@ static void bmdma_write(void *opaque, hwaddr addr,
>>>>         bmdma_cmd_writeb(bm, val);
>>>>         break;
>>>>     case 2:
>>>> -        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
>>>> +        bmdma_clear_status(bm, val);
>>>>         break;
>>>>     }
>>>> }
>>>> diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c
>>>> index 373c0dd1ee..1180ff55e7 100644
>>>> --- a/hw/ide/sii3112.c
>>>> +++ b/hw/ide/sii3112.c
>>>> @@ -66,7 +66,7 @@ static void sii3112_bmdma_write(void *opaque, hwaddr addr,
>>>>                                 uint64_t val, unsigned int size)
>>>> {
>>>>     BMDMAState *bm = opaque;
>>>> -    SiI3112PCIState *d = SII3112_PCI(bm->pci_dev);
>>>> +    SiI3112PCIState *s = SII3112_PCI(bm->pci_dev);
>>>>     int i = (bm == &bm->pci_dev->bmdma[0]) ? 0 : 1;
>>>> 
>>>>     trace_sii3112_bmdma_write(size, addr, val);
>>>> @@ -75,10 +75,10 @@ static void sii3112_bmdma_write(void *opaque, hwaddr addr,
>>>>         bmdma_cmd_writeb(bm, val);
>>>>         break;
>>>>     case 0x01:
>>>> -        d->regs[i].swdata = val & 0x3f;
>>>> +        s->regs[i].swdata = val & 0x3f;
>>>>         break;
>>>>     case 0x02:
>>>> -        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 6);
>>>> +        bmdma_clear_status(bm, val);
>>>>         break;
>>>>     default:
>>>>         break;
>>>> @@ -160,8 +160,7 @@ static void sii3112_reg_write(void *opaque, hwaddr addr,
>>>>         d->regs[0].swdata = val & 0x3f;
>>>>         break;
>>>>     case 0x12:
>>>> -        d->i.bmdma[0].status = (val & 0x60) | (d->i.bmdma[0].status & 1) |
>>>> -                               (d->i.bmdma[0].status & ~val & 6);
>>>> +        bmdma_clear_status(&d->i.bmdma[0], val);
>>>>         break;
>>>>     case 0x18:
>>>>         bmdma_cmd_writeb(&d->i.bmdma[1], val);
>>>> @@ -170,8 +169,7 @@ static void sii3112_reg_write(void *opaque, hwaddr addr,
>>>>         d->regs[1].swdata = val & 0x3f;
>>>>         break;
>>>>     case 0x1a:
>>>> -        d->i.bmdma[1].status = (val & 0x60) | (d->i.bmdma[1].status & 1) |
>>>> -                               (d->i.bmdma[1].status & ~val & 6);
>>>> +        bmdma_clear_status(&d->i.bmdma[1], val);
>>>>         break;
>>>>     case 0x100:
>>>>         d->regs[0].scontrol = val & 0xfff;
>>>> diff --git a/hw/ide/via.c b/hw/ide/via.c
>>>> index 35dd97e49b..afb97f302a 100644
>>>> --- a/hw/ide/via.c
>>>> +++ b/hw/ide/via.c
>>>> @@ -75,7 +75,7 @@ static void bmdma_write(void *opaque, hwaddr addr,
>>>>         bmdma_cmd_writeb(bm, val);
>>>>         break;
>>>>     case 2:
>>>> -        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
>>>> +        bmdma_clear_status(bm, val);
>>>>         break;
>>>>     default:;
>>>>     }
>>>> diff --git a/hw/ide/trace-events b/hw/ide/trace-events
>>>> index a479525e38..d219c64b61 100644
>>>> --- a/hw/ide/trace-events
>>>> +++ b/hw/ide/trace-events
>>>> @@ -30,6 +30,7 @@ bmdma_write_cmd646(uint64_t addr, uint64_t val) "bmdma: writeb 0x%"PRIx64" : 0x%
>>>> # pci.c
>>>> bmdma_reset(void) ""
>>>> bmdma_cmd_writeb(uint32_t val) "val: 0x%08x"
>>>> +bmdma_update_status(uint32_t val) "val: 0x%08x"
>>>> bmdma_addr_read(uint64_t data) "data: 0x%016"PRIx64
>>>> bmdma_addr_write(uint64_t data) "data: 0x%016"PRIx64
>>>> 
>>>> 
>> 
>> 


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 06/13] hw/ide: Extract bmdma_init_ops()
  2023-04-23 17:43   ` Philippe Mathieu-Daudé
@ 2023-04-23 22:06     ` Bernhard Beschow
  0 siblings, 0 replies; 77+ messages in thread
From: Bernhard Beschow @ 2023-04-23 22:06 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	qemu-ppc



Am 23. April 2023 17:43:22 UTC schrieb "Philippe Mathieu-Daudé" <philmd@linaro.org>:
>On 22/4/23 17:07, Bernhard Beschow wrote:
>> There are three private copies of bmdma_setup_bar() with small adaptions.
>> Consolidate them into one public implementation.
>> 
>> While at it rename the function to bmdma_init_ops() to reflect that the memory
>> regions being initialized represent BMDMA operations. The actual mapping as a
>> PCI BAR is still performed separately in each device.
>> 
>> Note that the bmdma_bar attribute will be renamed in a separate commit.
>> 
>> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
>> ---
>>   include/hw/ide/pci.h |  1 +
>>   hw/ide/cmd646.c      | 20 +-------------------
>>   hw/ide/pci.c         | 16 ++++++++++++++++
>>   hw/ide/piix.c        | 19 +------------------
>>   hw/ide/via.c         | 19 +------------------
>>   5 files changed, 20 insertions(+), 55 deletions(-)
>
>Nice.
>
>Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>

I'd rework this patch in the next iteration. I think that most of the memory region initialization can be moved to pci_ide_init(). Unlike realize methods, the nice thing about these instance_init() methods is that the parent implementation is called implicitly rather than being overridden by the child implementation, similar to C++ constructors. This allows for code reuse without much gymnastics.

Best regards,
Bernhard


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 05/13] hw/ide: Extract pci_ide_class_init()
  2023-04-23 17:41   ` Philippe Mathieu-Daudé
@ 2023-04-23 22:11     ` Bernhard Beschow
  2023-04-23 22:23       ` BALATON Zoltan
  0 siblings, 1 reply; 77+ messages in thread
From: Bernhard Beschow @ 2023-04-23 22:11 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	qemu-ppc



Am 23. April 2023 17:41:33 UTC schrieb "Philippe Mathieu-Daudé" <philmd@linaro.org>:
>On 22/4/23 17:07, Bernhard Beschow wrote:
>> Resolves redundant code in every PCI IDE device model.
>> ---
>>   include/hw/ide/pci.h |  1 -
>>   hw/ide/cmd646.c      | 15 ---------------
>>   hw/ide/pci.c         | 25 ++++++++++++++++++++++++-
>>   hw/ide/piix.c        | 19 -------------------
>>   hw/ide/sii3112.c     |  3 ++-
>>   hw/ide/via.c         | 15 ---------------
>>   6 files changed, 26 insertions(+), 52 deletions(-)
>
>
>> diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c
>> index 5dd3d03c29..0af897a9ef 100644
>> --- a/hw/ide/sii3112.c
>> +++ b/hw/ide/sii3112.c
>> @@ -301,9 +301,10 @@ static void sii3112_pci_class_init(ObjectClass *klass, void *data)
>>       pd->class_id = PCI_CLASS_STORAGE_RAID;
>>       pd->revision = 1;
>>       pd->realize = sii3112_pci_realize;
>> +    pd->exit = NULL;
>>       dc->reset = sii3112_reset;
>> +    dc->vmsd = NULL;
>>       dc->desc = "SiI3112A SATA controller";
>
>The SiI3112A doesn't have these regions?

Yeah, it ignores a lot of stuff in the base class. This gets changed in the last part of this series though. This seems why there is no exit method. Furthermore -- probably due to additional custom fields -- there is no migration description.

Best regards,
Bernhard


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 11/13] hw/ide/sii3112: Reuse PCIIDEState::{cmd,data}_ops
  2023-04-22 21:10   ` BALATON Zoltan
@ 2023-04-23 22:19     ` Bernhard Beschow
  2023-04-23 22:38       ` BALATON Zoltan
  0 siblings, 1 reply; 77+ messages in thread
From: Bernhard Beschow @ 2023-04-23 22:19 UTC (permalink / raw)
  To: BALATON Zoltan
  Cc: qemu-devel, qemu-block, Jiaxun Yang, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc



Am 22. April 2023 21:10:14 UTC schrieb BALATON Zoltan <balaton@eik.bme.hu>:
>On Sat, 22 Apr 2023, Bernhard Beschow wrote:
>> Allows to unexport pci_ide_{cmd,data}_le_ops and models TYPE_SII3112_PCI as a
>> standard-compliant PCI IDE device.
>> 
>> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
>> ---
>> include/hw/ide/pci.h |  2 --
>> hw/ide/pci.c         |  4 ++--
>> hw/ide/sii3112.c     | 50 ++++++++++++++++----------------------------
>> 3 files changed, 20 insertions(+), 36 deletions(-)
>> 
>> diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
>> index 5025df5b82..dbb4b13161 100644
>> --- a/include/hw/ide/pci.h
>> +++ b/include/hw/ide/pci.h
>> @@ -62,6 +62,4 @@ void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val);
>> extern MemoryRegionOps bmdma_addr_ioport_ops;
>> void pci_ide_create_devs(PCIDevice *dev);
>> 
>> -extern const MemoryRegionOps pci_ide_cmd_le_ops;
>> -extern const MemoryRegionOps pci_ide_data_le_ops;
>> #endif
>> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
>> index b2fcc00a64..97ccc75aa6 100644
>> --- a/hw/ide/pci.c
>> +++ b/hw/ide/pci.c
>> @@ -60,7 +60,7 @@ static void pci_ide_ctrl_write(void *opaque, hwaddr addr,
>>     ide_ctrl_write(bus, addr + 2, data);
>> }
>> 
>> -const MemoryRegionOps pci_ide_cmd_le_ops = {
>> +static const MemoryRegionOps pci_ide_cmd_le_ops = {
>>     .read = pci_ide_status_read,
>>     .write = pci_ide_ctrl_write,
>>     .endianness = DEVICE_LITTLE_ENDIAN,
>> @@ -98,7 +98,7 @@ static void pci_ide_data_write(void *opaque, hwaddr addr,
>>     }
>> }
>> 
>> -const MemoryRegionOps pci_ide_data_le_ops = {
>> +static const MemoryRegionOps pci_ide_data_le_ops = {
>>     .read = pci_ide_data_read,
>>     .write = pci_ide_data_write,
>>     .endianness = DEVICE_LITTLE_ENDIAN,
>> diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c
>> index 0af897a9ef..9cf920369f 100644
>> --- a/hw/ide/sii3112.c
>> +++ b/hw/ide/sii3112.c
>> @@ -88,21 +88,9 @@ static uint64_t sii3112_reg_read(void *opaque, hwaddr addr,
>>         val |= (d->regs[1].confstat & (1UL << 11) ? (1 << 4) : 0);
>>         val |= (uint32_t)d->i.bmdma[1].status << 16;
>>         break;
>> -    case 0x80 ... 0x87:
>> -        val = pci_ide_data_le_ops.read(&d->i.bus[0], addr - 0x80, size);
>> -        break;
>> -    case 0x8a:
>> -        val = pci_ide_cmd_le_ops.read(&d->i.bus[0], 2, size);
>> -        break;
>>     case 0xa0:
>>         val = d->regs[0].confstat;
>>         break;
>> -    case 0xc0 ... 0xc7:
>> -        val = pci_ide_data_le_ops.read(&d->i.bus[1], addr - 0xc0, size);
>> -        break;
>> -    case 0xca:
>> -        val = pci_ide_cmd_le_ops.read(&d->i.bus[1], 2, size);
>> -        break;
>>     case 0xe0:
>>         val = d->regs[1].confstat;
>>         break;
>> @@ -171,18 +159,6 @@ static void sii3112_reg_write(void *opaque, hwaddr addr,
>>     case 0x0c ... 0x0f:
>>         bmdma_addr_ioport_ops.write(&d->i.bmdma[1], addr - 12, val, size);
>>         break;
>> -    case 0x80 ... 0x87:
>> -        pci_ide_data_le_ops.write(&d->i.bus[0], addr - 0x80, val, size);
>> -        break;
>> -    case 0x8a:
>> -        pci_ide_cmd_le_ops.write(&d->i.bus[0], 2, val, size);
>> -        break;
>> -    case 0xc0 ... 0xc7:
>> -        pci_ide_data_le_ops.write(&d->i.bus[1], addr - 0xc0, val, size);
>> -        break;
>> -    case 0xca:
>> -        pci_ide_cmd_le_ops.write(&d->i.bus[1], 2, val, size);
>> -        break;
>>     case 0x100:
>>         d->regs[0].scontrol = val & 0xfff;
>>         if (val & 1) {
>> @@ -259,6 +235,11 @@ static void sii3112_pci_realize(PCIDevice *dev, Error **errp)
>>     pci_config_set_interrupt_pin(dev->config, 1);
>>     pci_set_byte(dev->config + PCI_CACHE_LINE_SIZE, 8);
>> 
>> +    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->data_ops[0]);
>> +    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->cmd_ops[0]);
>> +    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &s->data_ops[1]);
>> +    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &s->cmd_ops[1]);
>> +
>>     /* BAR5 is in PCI memory space */
>>     memory_region_init_io(&d->mmio, OBJECT(d), &sii3112_reg_ops, d,
>>                          "sii3112.bar5", 0x200);
>> @@ -266,17 +247,22 @@ static void sii3112_pci_realize(PCIDevice *dev, Error **errp)
>> 
>>     /* BAR0-BAR4 are PCI I/O space aliases into BAR5 */
>
>This patch breaks the above comment

Indeed. It's now the other way around.

>but I think you should not mess with BAR0-4 at all and leave to to aliased into BAR5. These have the same registers mirrored and some guests access them via the memory mapped BAR5 while others prefer the io mapped BAR0-4 so removing these from BAR5 would break some guests.

BARs 0-3 are the PCI-native BARs and BAR4 is the BMDMA BAR which are mapped by via and cmd646 already since they support these modes. SIL3112 supports these modes as well but had custom implementations so far while ignoring the attributes of the parent class. Now that the parent class already initializes these attributes we can just reuse them here which in addition makes it very obvious that SIL3112 supports these modes.

I'll split this patch and the next one to (hopefully) make more visible what happens.

> If you want to remove something from BAR5 and map subregions implementing those instead then I think only BAR5 needs to be chnaged or I'm not getting what is happening here so a more detailed commit message would be needed.

Agreed. I'll put wording similar to above into the commit message.

>
>Was this tested? A minimal test might be booting AROS and MorphOS on sam460ex.

I tested with MorphOS on sam460ex. The second ppc test case in the cover letter was actually supposed to show this.

Best regards,
Bernhard

>
>Regards,
>BALATON Zoltan
>
>>     mr = g_new(MemoryRegion, 1);
>> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar0", &d->mmio, 0x80, 8);
>> -    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, mr);
>> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar0", &s->data_ops[0], 0,
>> +                             memory_region_size(&s->data_ops[0]));
>> +    memory_region_add_subregion_overlap(&d->mmio, 0x80, mr, 1);
>>     mr = g_new(MemoryRegion, 1);
>> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar1", &d->mmio, 0x88, 4);
>> -    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, mr);
>> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar1", &s->cmd_ops[0], 0,
>> +                             memory_region_size(&s->cmd_ops[0]));
>> +    memory_region_add_subregion_overlap(&d->mmio, 0x88, mr, 1);
>>     mr = g_new(MemoryRegion, 1);
>> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar2", &d->mmio, 0xc0, 8);
>> -    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, mr);
>> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar2", &s->data_ops[1], 0,
>> +                             memory_region_size(&s->data_ops[1]));
>> +    memory_region_add_subregion_overlap(&d->mmio, 0xc0, mr, 1);
>>     mr = g_new(MemoryRegion, 1);
>> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar3", &d->mmio, 0xc8, 4);
>> -    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, mr);
>> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar3", &s->cmd_ops[1], 0,
>> +                             memory_region_size(&s->cmd_ops[1]));
>> +    memory_region_add_subregion_overlap(&d->mmio, 0xc8, mr, 1);
>> +
>>     mr = g_new(MemoryRegion, 1);
>>     memory_region_init_alias(mr, OBJECT(d), "sii3112.bar4", &d->mmio, 0, 16);
>>     pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, mr);
>> 


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 05/13] hw/ide: Extract pci_ide_class_init()
  2023-04-23 22:11     ` Bernhard Beschow
@ 2023-04-23 22:23       ` BALATON Zoltan
  0 siblings, 0 replies; 77+ messages in thread
From: BALATON Zoltan @ 2023-04-23 22:23 UTC (permalink / raw)
  To: Bernhard Beschow
  Cc: Philippe Mathieu-Daudé,
	qemu-devel, qemu-block, Jiaxun Yang, John Snow, Huacai Chen,
	qemu-ppc

[-- Attachment #1: Type: text/plain, Size: 2289 bytes --]

On Sun, 23 Apr 2023, Bernhard Beschow wrote:
> Am 23. April 2023 17:41:33 UTC schrieb "Philippe Mathieu-Daudé" <philmd@linaro.org>:
>> On 22/4/23 17:07, Bernhard Beschow wrote:
>>> Resolves redundant code in every PCI IDE device model.
>>> ---
>>>   include/hw/ide/pci.h |  1 -
>>>   hw/ide/cmd646.c      | 15 ---------------
>>>   hw/ide/pci.c         | 25 ++++++++++++++++++++++++-
>>>   hw/ide/piix.c        | 19 -------------------
>>>   hw/ide/sii3112.c     |  3 ++-
>>>   hw/ide/via.c         | 15 ---------------
>>>   6 files changed, 26 insertions(+), 52 deletions(-)
>>
>>
>>> diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c
>>> index 5dd3d03c29..0af897a9ef 100644
>>> --- a/hw/ide/sii3112.c
>>> +++ b/hw/ide/sii3112.c
>>> @@ -301,9 +301,10 @@ static void sii3112_pci_class_init(ObjectClass *klass, void *data)
>>>       pd->class_id = PCI_CLASS_STORAGE_RAID;
>>>       pd->revision = 1;
>>>       pd->realize = sii3112_pci_realize;
>>> +    pd->exit = NULL;
>>>       dc->reset = sii3112_reset;
>>> +    dc->vmsd = NULL;
>>>       dc->desc = "SiI3112A SATA controller";
>>
>> The SiI3112A doesn't have these regions?
>
> Yeah, it ignores a lot of stuff in the base class. This gets changed in 
> the last part of this series though. This seems why there is no exit 
> method. Furthermore -- probably due to additional custom fields -- there 
> is no migration description.

Probably there's no state descriptor because I did not bother to implement 
it back then when I did not even know how that worked. I've considered 
extending this to a 4 port version before adding migration/save support 
but that did not happen. This is only used on sam460ex by default and 
likely nobody wants to migrate that anyway.

However why do you need to explicitly set these to NULL? Aren't those 
structs allocated 0 filled so you'd only need to set non-NULL members.

As for ignoting stuff in the base class, this isn't really a PCI IDE 
controller. It's a SATA controller that for compatibility with older 
drivers looks a lot like an IDE controller but handles only one device per 
channel and has some additional SATA stuff that we mostly don't model. 
This way I could reuse code that was already there but still had some 
duplication that you're now resolving.

Regards,
BALATON Zoltan

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 11/13] hw/ide/sii3112: Reuse PCIIDEState::{cmd,data}_ops
  2023-04-23 22:19     ` Bernhard Beschow
@ 2023-04-23 22:38       ` BALATON Zoltan
  0 siblings, 0 replies; 77+ messages in thread
From: BALATON Zoltan @ 2023-04-23 22:38 UTC (permalink / raw)
  To: Bernhard Beschow
  Cc: qemu-devel, qemu-block, Jiaxun Yang, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc

On Sun, 23 Apr 2023, Bernhard Beschow wrote:
> Am 22. April 2023 21:10:14 UTC schrieb BALATON Zoltan <balaton@eik.bme.hu>:
>> On Sat, 22 Apr 2023, Bernhard Beschow wrote:
>>> Allows to unexport pci_ide_{cmd,data}_le_ops and models TYPE_SII3112_PCI as a
>>> standard-compliant PCI IDE device.
>>>
>>> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
>>> ---
>>> include/hw/ide/pci.h |  2 --
>>> hw/ide/pci.c         |  4 ++--
>>> hw/ide/sii3112.c     | 50 ++++++++++++++++----------------------------
>>> 3 files changed, 20 insertions(+), 36 deletions(-)
>>>
>>> diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
>>> index 5025df5b82..dbb4b13161 100644
>>> --- a/include/hw/ide/pci.h
>>> +++ b/include/hw/ide/pci.h
>>> @@ -62,6 +62,4 @@ void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val);
>>> extern MemoryRegionOps bmdma_addr_ioport_ops;
>>> void pci_ide_create_devs(PCIDevice *dev);
>>>
>>> -extern const MemoryRegionOps pci_ide_cmd_le_ops;
>>> -extern const MemoryRegionOps pci_ide_data_le_ops;
>>> #endif
>>> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
>>> index b2fcc00a64..97ccc75aa6 100644
>>> --- a/hw/ide/pci.c
>>> +++ b/hw/ide/pci.c
>>> @@ -60,7 +60,7 @@ static void pci_ide_ctrl_write(void *opaque, hwaddr addr,
>>>     ide_ctrl_write(bus, addr + 2, data);
>>> }
>>>
>>> -const MemoryRegionOps pci_ide_cmd_le_ops = {
>>> +static const MemoryRegionOps pci_ide_cmd_le_ops = {
>>>     .read = pci_ide_status_read,
>>>     .write = pci_ide_ctrl_write,
>>>     .endianness = DEVICE_LITTLE_ENDIAN,
>>> @@ -98,7 +98,7 @@ static void pci_ide_data_write(void *opaque, hwaddr addr,
>>>     }
>>> }
>>>
>>> -const MemoryRegionOps pci_ide_data_le_ops = {
>>> +static const MemoryRegionOps pci_ide_data_le_ops = {
>>>     .read = pci_ide_data_read,
>>>     .write = pci_ide_data_write,
>>>     .endianness = DEVICE_LITTLE_ENDIAN,
>>> diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c
>>> index 0af897a9ef..9cf920369f 100644
>>> --- a/hw/ide/sii3112.c
>>> +++ b/hw/ide/sii3112.c
>>> @@ -88,21 +88,9 @@ static uint64_t sii3112_reg_read(void *opaque, hwaddr addr,
>>>         val |= (d->regs[1].confstat & (1UL << 11) ? (1 << 4) : 0);
>>>         val |= (uint32_t)d->i.bmdma[1].status << 16;
>>>         break;
>>> -    case 0x80 ... 0x87:
>>> -        val = pci_ide_data_le_ops.read(&d->i.bus[0], addr - 0x80, size);
>>> -        break;
>>> -    case 0x8a:
>>> -        val = pci_ide_cmd_le_ops.read(&d->i.bus[0], 2, size);
>>> -        break;
>>>     case 0xa0:
>>>         val = d->regs[0].confstat;
>>>         break;
>>> -    case 0xc0 ... 0xc7:
>>> -        val = pci_ide_data_le_ops.read(&d->i.bus[1], addr - 0xc0, size);
>>> -        break;
>>> -    case 0xca:
>>> -        val = pci_ide_cmd_le_ops.read(&d->i.bus[1], 2, size);
>>> -        break;
>>>     case 0xe0:
>>>         val = d->regs[1].confstat;
>>>         break;
>>> @@ -171,18 +159,6 @@ static void sii3112_reg_write(void *opaque, hwaddr addr,
>>>     case 0x0c ... 0x0f:
>>>         bmdma_addr_ioport_ops.write(&d->i.bmdma[1], addr - 12, val, size);
>>>         break;
>>> -    case 0x80 ... 0x87:
>>> -        pci_ide_data_le_ops.write(&d->i.bus[0], addr - 0x80, val, size);
>>> -        break;
>>> -    case 0x8a:
>>> -        pci_ide_cmd_le_ops.write(&d->i.bus[0], 2, val, size);
>>> -        break;
>>> -    case 0xc0 ... 0xc7:
>>> -        pci_ide_data_le_ops.write(&d->i.bus[1], addr - 0xc0, val, size);
>>> -        break;
>>> -    case 0xca:
>>> -        pci_ide_cmd_le_ops.write(&d->i.bus[1], 2, val, size);
>>> -        break;
>>>     case 0x100:
>>>         d->regs[0].scontrol = val & 0xfff;
>>>         if (val & 1) {
>>> @@ -259,6 +235,11 @@ static void sii3112_pci_realize(PCIDevice *dev, Error **errp)
>>>     pci_config_set_interrupt_pin(dev->config, 1);
>>>     pci_set_byte(dev->config + PCI_CACHE_LINE_SIZE, 8);
>>>
>>> +    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->data_ops[0]);
>>> +    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->cmd_ops[0]);
>>> +    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &s->data_ops[1]);
>>> +    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &s->cmd_ops[1]);
>>> +
>>>     /* BAR5 is in PCI memory space */
>>>     memory_region_init_io(&d->mmio, OBJECT(d), &sii3112_reg_ops, d,
>>>                          "sii3112.bar5", 0x200);
>>> @@ -266,17 +247,22 @@ static void sii3112_pci_realize(PCIDevice *dev, Error **errp)
>>>
>>>     /* BAR0-BAR4 are PCI I/O space aliases into BAR5 */
>>
>> This patch breaks the above comment
>
> Indeed. It's now the other way around.

OK, then adjust comments as well, also the other one about BAR5 at the top 
which may not be true any more if you remove stuff from BAR5 and alias the 
other BARs instead. The idea here was to follow the data sheet which 
documents the memory space BAR5 and other io BARs are just io space 
aliases of parts of the memory mapped registers. Those are to support 
easily porting older drivers but other drivers may only map BAR5 where all 
the regs are available.

>> but I think you should not mess with BAR0-4 at all and leave to to 
>> aliased into BAR5. These have the same registers mirrored and some 
>> guests access them via the memory mapped BAR5 while others prefer the 
>> io mapped BAR0-4 so removing these from BAR5 would break some guests.
>
> BARs 0-3 are the PCI-native BARs and BAR4 is the BMDMA BAR which are 
> mapped by via and cmd646 already since they support these modes. SIL3112 
> supports these modes as well but had custom implementations so far while 
> ignoring the attributes of the parent class. Now that the parent class

Which attributes? Do those make sense for a SATA controller or does the 
sii3112 have those in BAR5? I'll wait for an updated version to review 
this further as that may clear up some things.

> already initializes these attributes we can just reuse them here which 
> in addition makes it very obvious that SIL3112 supports these modes.

By the way it's called SiI3112 for Silicon Image but the upper case I is 
often misread as a lower case l as these look similar.

Regards,
BALATON Zoltan

> I'll split this patch and the next one to (hopefully) make more visible what happens.
>
>> If you want to remove something from BAR5 and map subregions implementing those instead then I think only BAR5 needs to be chnaged or I'm not getting what is happening here so a more detailed commit message would be needed.
>
> Agreed. I'll put wording similar to above into the commit message.
>
>>
>> Was this tested? A minimal test might be booting AROS and MorphOS on sam460ex.
>
> I tested with MorphOS on sam460ex. The second ppc test case in the cover letter was actually supposed to show this.
>
> Best regards,
> Bernhard
>
>>
>> Regards,
>> BALATON Zoltan
>>
>>>     mr = g_new(MemoryRegion, 1);
>>> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar0", &d->mmio, 0x80, 8);
>>> -    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, mr);
>>> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar0", &s->data_ops[0], 0,
>>> +                             memory_region_size(&s->data_ops[0]));
>>> +    memory_region_add_subregion_overlap(&d->mmio, 0x80, mr, 1);
>>>     mr = g_new(MemoryRegion, 1);
>>> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar1", &d->mmio, 0x88, 4);
>>> -    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, mr);
>>> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar1", &s->cmd_ops[0], 0,
>>> +                             memory_region_size(&s->cmd_ops[0]));
>>> +    memory_region_add_subregion_overlap(&d->mmio, 0x88, mr, 1);
>>>     mr = g_new(MemoryRegion, 1);
>>> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar2", &d->mmio, 0xc0, 8);
>>> -    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, mr);
>>> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar2", &s->data_ops[1], 0,
>>> +                             memory_region_size(&s->data_ops[1]));
>>> +    memory_region_add_subregion_overlap(&d->mmio, 0xc0, mr, 1);
>>>     mr = g_new(MemoryRegion, 1);
>>> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar3", &d->mmio, 0xc8, 4);
>>> -    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, mr);
>>> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar3", &s->cmd_ops[1], 0,
>>> +                             memory_region_size(&s->cmd_ops[1]));
>>> +    memory_region_add_subregion_overlap(&d->mmio, 0xc8, mr, 1);
>>> +
>>>     mr = g_new(MemoryRegion, 1);
>>>     memory_region_init_alias(mr, OBJECT(d), "sii3112.bar4", &d->mmio, 0, 16);
>>>     pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, mr);
>>>
>
>


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 07/13] hw/ide: Extract pci_ide_{cmd,data}_le_ops initialization into base class constructor
  2023-04-23 17:46   ` [PATCH 07/13] hw/ide: Extract pci_ide_{cmd,data}_le_ops " Philippe Mathieu-Daudé
@ 2023-04-24  7:45     ` Bernhard Beschow
  0 siblings, 0 replies; 77+ messages in thread
From: Bernhard Beschow @ 2023-04-24  7:45 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	qemu-ppc



Am 23. April 2023 17:46:18 UTC schrieb "Philippe Mathieu-Daudé" <philmd@linaro.org>:
>On 22/4/23 17:07, Bernhard Beschow wrote:
>> There is redundant code in cmd646 and via which can be extracted into the base
>> class. In case of piix and sii3112 this is currently unneccessary but shouldn't
>> interfere since the memory regions aren't mapped by those devices. In few
>> commits later this will be changed, i.e. those device models will also make use
>> of these memory regions.
>> 
>> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
>> ---
>>   hw/ide/cmd646.c | 11 -----------
>>   hw/ide/pci.c    | 10 ++++++++++
>>   hw/ide/via.c    | 11 -----------
>>   3 files changed, 10 insertions(+), 22 deletions(-)
>
>
>> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
>> index 65ed6f7f72..a9194313bd 100644
>> --- a/hw/ide/pci.c
>> +++ b/hw/ide/pci.c
>> @@ -543,6 +543,16 @@ static void pci_ide_init(Object *obj)
>>   {
>>       PCIIDEState *d = PCI_IDE(obj);
>>   +    memory_region_init_io(&d->data_bar[0], OBJECT(d), &pci_ide_data_le_ops,
>> +                          &d->bus[0], "pci-ide0-data-ops", 8);
>> +    memory_region_init_io(&d->cmd_bar[0], OBJECT(d), &pci_ide_cmd_le_ops,
>> +                          &d->bus[0], "pci-ide0-cmd-ops", 4);
>> +
>> +    memory_region_init_io(&d->data_bar[1], OBJECT(d), &pci_ide_data_le_ops,
>> +                          &d->bus[1], "pci-ide1-data-ops", 8);
>> +    memory_region_init_io(&d->cmd_bar[1], OBJECT(d), &pci_ide_cmd_le_ops,
>> +                          &d->bus[1], "pci-ide1-cmd-ops", 4);
>
>The trailing "-ops" just adds noise IMO.

I'll remove them in the next iteration.

Best regards,
Bernhard

>
>Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
>


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 02/13] hw/ide/via: Implement ISA IRQ routing
  2023-04-22 19:21       ` BALATON Zoltan
@ 2023-04-24  7:50         ` Bernhard Beschow
  2023-04-24 10:10           ` BALATON Zoltan
  0 siblings, 1 reply; 77+ messages in thread
From: Bernhard Beschow @ 2023-04-24  7:50 UTC (permalink / raw)
  To: BALATON Zoltan
  Cc: qemu-devel, qemu-block, Jiaxun Yang, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc



Am 22. April 2023 19:21:12 UTC schrieb BALATON Zoltan <balaton@eik.bme.hu>:
>On Sat, 22 Apr 2023, Bernhard Beschow wrote:
>> Am 22. April 2023 17:23:56 UTC schrieb BALATON Zoltan <balaton@eik.bme.hu>:
>>> On Sat, 22 Apr 2023, Bernhard Beschow wrote:
>>>> The VIA south bridge allows the legacy IDE interrupts to be routed to four
>>>> different ISA interrupts. This can be configured through the 0x4a register in
>>>> the PCI configuration space of the ISA function. The default routing matches
>>>> the legacy ISA IRQs, that is 14 and 15.
>>> 
>>> On VT8231 0x4a is PCI Master Arbitration Control, IDE interrupt Routing is 0x4c and only documents 14/15 as valid values.
>> 
>> In the datasheet titled "VT8231 South Bridge", preliminary revision 0.8, Oct. 29, 1999, page 60, the "IDE Interrupt Routing" register is located at offset 0x4a and offers the same four interrupts in the same order as in the code. Are we looking at the same datasheet?
>
>Apparently not. The one I have says: Revision 2.32, May 10, 2004. Looks more authorative than a preliminary one.

Indeed. I've updated my copy of the datasheet.

>
>>> Not sure any guest would actually change this or 0x4a and if that could cause problems but you may need to handle this somehow. (Apart from testing with MorphOS with -kernel you should really be testing with pegasos2.rom with MorphOS and Linux, e.g. Debian 8.11 netinstall iso is known to boot.)
>> 
>> I've tested extensively with an x86 Linux guest on my pc-via branch which worked flawlessly.
>
>That does not substitute testing Linux on pegasos2 though becuase there are some hacks in Linux kernel to handle some pecularities of the pegasos2 including via ide on that machine and that can only be fully tested with pegasos2.rom and PPC Linux.

I'll try to find the Debian ISO to test with pegasos2.rom.

>
>> As mentioned in the commit message the default routing of the chipset matches legacy behavior, that is interrupts 14 and 15. This is reflected by assigning [0x4a] = 4 in the code and that is how the code behaved before.
>
>And that's the only allowed value on VT8231, other bits are listed as reserved so I wonder if we want to model this at all if no guest is touching it anyway. So you could also just drop that part and keep it hard mapped to 14-15 as it is now, mentioning the config reg in a comment if we ever find a guest that needs it.

I see it now. I'll use hardcoded IRQs 14 and 15 then.

Best regards,
Bernhard

>
>Regards,
>BALATON Zoltan


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 02/13] hw/ide/via: Implement ISA IRQ routing
  2023-04-24  7:50         ` Bernhard Beschow
@ 2023-04-24 10:10           ` BALATON Zoltan
  0 siblings, 0 replies; 77+ messages in thread
From: BALATON Zoltan @ 2023-04-24 10:10 UTC (permalink / raw)
  To: Bernhard Beschow
  Cc: qemu-devel, qemu-block, Jiaxun Yang, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc

On Mon, 24 Apr 2023, Bernhard Beschow wrote:
> Am 22. April 2023 19:21:12 UTC schrieb BALATON Zoltan <balaton@eik.bme.hu>:
>> On Sat, 22 Apr 2023, Bernhard Beschow wrote:
>>> Am 22. April 2023 17:23:56 UTC schrieb BALATON Zoltan <balaton@eik.bme.hu>:
>>>> On Sat, 22 Apr 2023, Bernhard Beschow wrote:
>>>>> The VIA south bridge allows the legacy IDE interrupts to be routed to four
>>>>> different ISA interrupts. This can be configured through the 0x4a register in
>>>>> the PCI configuration space of the ISA function. The default routing matches
>>>>> the legacy ISA IRQs, that is 14 and 15.
>>>>
>>>> On VT8231 0x4a is PCI Master Arbitration Control, IDE interrupt Routing is 0x4c and only documents 14/15 as valid values.
>>>
>>> In the datasheet titled "VT8231 South Bridge", preliminary revision 0.8, Oct. 29, 1999, page 60, the "IDE Interrupt Routing" register is located at offset 0x4a and offers the same four interrupts in the same order as in the code. Are we looking at the same datasheet?
>>
>> Apparently not. The one I have says: Revision 2.32, May 10, 2004. Looks more authorative than a preliminary one.
>
> Indeed. I've updated my copy of the datasheet.
>
>>
>>>> Not sure any guest would actually change this or 0x4a and if that could cause problems but you may need to handle this somehow. (Apart from testing with MorphOS with -kernel you should really be testing with pegasos2.rom with MorphOS and Linux, e.g. Debian 8.11 netinstall iso is known to boot.)
>>>
>>> I've tested extensively with an x86 Linux guest on my pc-via branch which worked flawlessly.
>>
>> That does not substitute testing Linux on pegasos2 though becuase there are some hacks in Linux kernel to handle some pecularities of the pegasos2 including via ide on that machine and that can only be fully tested with pegasos2.rom and PPC Linux.
>
> I'll try to find the Debian ISO to test with pegasos2.rom.

It should be here I think:
https://www.debian.org/releases/jessie/debian-installer/

Regards,
BALATON Zoltan

>>
>>> As mentioned in the commit message the default routing of the chipset matches legacy behavior, that is interrupts 14 and 15. This is reflected by assigning [0x4a] = 4 in the code and that is how the code behaved before.
>>
>> And that's the only allowed value on VT8231, other bits are listed as reserved so I wonder if we want to model this at all if no guest is touching it anyway. So you could also just drop that part and keep it hard mapped to 14-15 as it is now, mentioning the config reg in a comment if we ever find a guest that needs it.
>
> I see it now. I'll use hardcoded IRQs 14 and 15 then.
>
> Best regards,
> Bernhard
>
>>
>> Regards,
>> BALATON Zoltan
>
>


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 01/13] hw/ide/pci: Expose legacy interrupts as GPIOs
  2023-04-22 15:07 ` [PATCH 01/13] hw/ide/pci: Expose legacy interrupts as GPIOs Bernhard Beschow
@ 2023-04-26 10:41   ` Mark Cave-Ayland
  2023-04-26 19:26     ` Bernhard Beschow
  0 siblings, 1 reply; 77+ messages in thread
From: Mark Cave-Ayland @ 2023-04-26 10:41 UTC (permalink / raw)
  To: Bernhard Beschow, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc

On 22/04/2023 16:07, Bernhard Beschow wrote:

> Exposing the legacy IDE interrupts as GPIOs allows them to be connected in the
> parent device through qdev_connect_gpio_out(), i.e. without accessing private
> data of TYPE_PCI_IDE.
> 
> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
> ---
>   hw/ide/pci.c | 8 ++++++++
>   1 file changed, 8 insertions(+)
> 
> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
> index fc9224bbc9..942e216b9b 100644
> --- a/hw/ide/pci.c
> +++ b/hw/ide/pci.c
> @@ -522,10 +522,18 @@ void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d)
>       bm->pci_dev = d;
>   }
>   
> +static void pci_ide_init(Object *obj)
> +{
> +    PCIIDEState *d = PCI_IDE(obj);
> +
> +    qdev_init_gpio_out(DEVICE(d), d->isa_irq, ARRAY_SIZE(d->isa_irq));

Just one minor nit: can we make this qdev_init_gpio_out_named() and call it "isa-irq" 
to match? This is for 2 reasons: firstly these are PCI devices and so an unnamed 
IRQ/gpio could be considered to belong to PCI, and secondly it gives the gpio the 
same name as the struct field.

 From my previous email I think this should supercede Phil's patch at 
https://patchew.org/QEMU/20230302224058.43315-1-philmd@linaro.org/20230302224058.43315-2-philmd@linaro.org/.

> +}
> +
>   static const TypeInfo pci_ide_type_info = {
>       .name = TYPE_PCI_IDE,
>       .parent = TYPE_PCI_DEVICE,
>       .instance_size = sizeof(PCIIDEState),
> +    .instance_init = pci_ide_init,
>       .abstract = true,
>       .interfaces = (InterfaceInfo[]) {
>           { INTERFACE_CONVENTIONAL_PCI_DEVICE },

Otherwise:

Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>


ATB,

Mark.


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 02/13] hw/ide/via: Implement ISA IRQ routing
  2023-04-22 15:07 ` [PATCH 02/13] hw/ide/via: Implement ISA IRQ routing Bernhard Beschow
  2023-04-22 17:23   ` BALATON Zoltan
@ 2023-04-26 10:55   ` Mark Cave-Ayland
  1 sibling, 0 replies; 77+ messages in thread
From: Mark Cave-Ayland @ 2023-04-26 10:55 UTC (permalink / raw)
  To: Bernhard Beschow, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc

On 22/04/2023 16:07, Bernhard Beschow wrote:

> The VIA south bridge allows the legacy IDE interrupts to be routed to four
> different ISA interrupts. This can be configured through the 0x4a register in
> the PCI configuration space of the ISA function. The default routing matches
> the legacy ISA IRQs, that is 14 and 15.
> 
> Implement this missing piece of the VIA south bridge.
> 
> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
> ---
>   hw/ide/via.c      |  6 ++++--
>   hw/isa/vt82c686.c | 17 +++++++++++++++++
>   2 files changed, 21 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/ide/via.c b/hw/ide/via.c
> index 177baea9a7..0caae52276 100644
> --- a/hw/ide/via.c
> +++ b/hw/ide/via.c
> @@ -31,6 +31,7 @@
>   #include "sysemu/dma.h"
>   #include "hw/isa/vt82c686.h"
>   #include "hw/ide/pci.h"
> +#include "hw/irq.h"
>   #include "trace.h"
>   
>   static uint64_t bmdma_read(void *opaque, hwaddr addr,
> @@ -104,7 +105,8 @@ static void bmdma_setup_bar(PCIIDEState *d)
>   
>   static void via_ide_set_irq(void *opaque, int n, int level)
>   {
> -    PCIDevice *d = PCI_DEVICE(opaque);
> +    PCIIDEState *s = opaque;
> +    PCIDevice *d = PCI_DEVICE(s);
>   
>       if (level) {
>           d->config[0x70 + n * 8] |= 0x80;
> @@ -112,7 +114,7 @@ static void via_ide_set_irq(void *opaque, int n, int level)
>           d->config[0x70 + n * 8] &= ~0x80;
>       }
>   
> -    via_isa_set_irq(pci_get_function_0(d), 14 + n, level);
> +    qemu_set_irq(s->isa_irq[n], level);
>   }
>   
>   static void via_ide_reset(DeviceState *dev)
> diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
> index ca89119ce0..c7e29bb46a 100644
> --- a/hw/isa/vt82c686.c
> +++ b/hw/isa/vt82c686.c
> @@ -568,9 +568,19 @@ static const VMStateDescription vmstate_via = {
>       }
>   };
>   
> +static void via_isa_set_ide_irq(void *opaque, int n, int level)
> +{
> +    static const uint8_t irqs[] = { 14, 15, 10, 11 };
> +    ViaISAState *s = opaque;
> +    uint8_t irq = irqs[(s->dev.config[0x4a] >> (n * 2)) & 0x3];
> +
> +    qemu_set_irq(s->isa_irqs_in[irq], level);
> +}
> +
>   static void via_isa_init(Object *obj)
>   {
>       ViaISAState *s = VIA_ISA(obj);
> +    DeviceState *dev = DEVICE(s);
>   
>       object_initialize_child(obj, "rtc", &s->rtc, TYPE_MC146818_RTC);
>       object_initialize_child(obj, "ide", &s->ide, TYPE_VIA_IDE);
> @@ -578,6 +588,8 @@ static void via_isa_init(Object *obj)
>       object_initialize_child(obj, "uhci2", &s->uhci[1], TYPE_VT82C686B_USB_UHCI);
>       object_initialize_child(obj, "ac97", &s->ac97, TYPE_VIA_AC97);
>       object_initialize_child(obj, "mc97", &s->mc97, TYPE_VIA_MC97);
> +
> +    qdev_init_gpio_in_named(dev, via_isa_set_ide_irq, "ide", ARRAY_SIZE(s->ide.isa_irq));
>   }
>   
>   static const TypeInfo via_isa_info = {
> @@ -692,6 +704,10 @@ static void via_isa_realize(PCIDevice *d, Error **errp)
>       if (!qdev_realize(DEVICE(&s->ide), BUS(pci_bus), errp)) {
>           return;
>       }
> +    for (i = 0; i < 2; i++) {
> +        qdev_connect_gpio_out(DEVICE(&s->ide), i,
> +                              qdev_get_gpio_in_named(DEVICE(s), "ide", i));
> +    }
>   
>       /* Functions 2-3: USB Ports */
>       for (i = 0; i < ARRAY_SIZE(s->uhci); i++) {
> @@ -814,6 +830,7 @@ static void vt8231_isa_reset(DeviceState *dev)
>                    PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL);
>       pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM);
>   
> +    pci_conf[0x4a] = 0x04; /* IDE interrupt Routing */
>       pci_conf[0x58] = 0x40; /* Miscellaneous Control 0 */
>       pci_conf[0x67] = 0x08; /* Fast IR Config */
>       pci_conf[0x6b] = 0x01; /* Fast IR I/O Base */

I see there is still some further discussion on the exact datasheet being used, 
however the basic mechanism of wiring up the IDE IRQs using 
qdev_connect_gpio_out{_named}() in via_isa_realize():

Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>


ATB,

Mark.


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 03/13] hw/isa/vt82c686: Remove via_isa_set_irq()
  2023-04-22 15:07 ` [PATCH 03/13] hw/isa/vt82c686: Remove via_isa_set_irq() Bernhard Beschow
@ 2023-04-26 10:55   ` Mark Cave-Ayland
  0 siblings, 0 replies; 77+ messages in thread
From: Mark Cave-Ayland @ 2023-04-26 10:55 UTC (permalink / raw)
  To: Bernhard Beschow, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc

On 22/04/2023 16:07, Bernhard Beschow wrote:

> Now that via_isa_set_irq() is unused it can be removed.
> 
> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
> ---
>   include/hw/isa/vt82c686.h | 2 --
>   hw/isa/vt82c686.c         | 6 ------
>   2 files changed, 8 deletions(-)
> 
> diff --git a/include/hw/isa/vt82c686.h b/include/hw/isa/vt82c686.h
> index da1722daf2..b6e95b2851 100644
> --- a/include/hw/isa/vt82c686.h
> +++ b/include/hw/isa/vt82c686.h
> @@ -34,6 +34,4 @@ struct ViaAC97State {
>       uint32_t ac97_cmd;
>   };
>   
> -void via_isa_set_irq(PCIDevice *d, int n, int level);
> -
>   #endif
> diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
> index c7e29bb46a..a69888a396 100644
> --- a/hw/isa/vt82c686.c
> +++ b/hw/isa/vt82c686.c
> @@ -604,12 +604,6 @@ static const TypeInfo via_isa_info = {
>       },
>   };
>   
> -void via_isa_set_irq(PCIDevice *d, int n, int level)
> -{
> -    ViaISAState *s = VIA_ISA(d);
> -    qemu_set_irq(s->isa_irqs_in[n], level);
> -}
> -
>   static void via_isa_request_i8259_irq(void *opaque, int irq, int level)
>   {
>       ViaISAState *s = opaque;

Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>


ATB,

Mark.


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 04/13] hw/ide: Extract IDEBus assignment into bmdma_init()
  2023-04-22 15:07 ` [PATCH 04/13] hw/ide: Extract IDEBus assignment into bmdma_init() Bernhard Beschow
  2023-04-22 17:31   ` BALATON Zoltan
  2023-04-23 17:36   ` Philippe Mathieu-Daudé
@ 2023-04-26 10:56   ` Mark Cave-Ayland
  2 siblings, 0 replies; 77+ messages in thread
From: Mark Cave-Ayland @ 2023-04-26 10:56 UTC (permalink / raw)
  To: Bernhard Beschow, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc

On 22/04/2023 16:07, Bernhard Beschow wrote:

> Every invocation of bmdma_init() is followed by `d->bmdma[i].bus = &d->bus[i]`.
> Resolve this redundancy by extracting it into bmdma_init().
> 
> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
> ---
>   hw/ide/cmd646.c  | 1 -
>   hw/ide/pci.c     | 1 +
>   hw/ide/piix.c    | 1 -
>   hw/ide/sii3112.c | 1 -
>   hw/ide/via.c     | 1 -
>   5 files changed, 1 insertion(+), 4 deletions(-)
> 
> diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
> index a68357c1c5..a094a6e12a 100644
> --- a/hw/ide/cmd646.c
> +++ b/hw/ide/cmd646.c
> @@ -297,7 +297,6 @@ static void pci_cmd646_ide_realize(PCIDevice *dev, Error **errp)
>           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 = &d->bus[i];
>           ide_bus_register_restart_cb(&d->bus[i]);
>       }
>   }
> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
> index 942e216b9b..67e0998ff0 100644
> --- a/hw/ide/pci.c
> +++ b/hw/ide/pci.c
> @@ -519,6 +519,7 @@ void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d)
>       bus->dma = &bm->dma;
>       bm->irq = bus->irq;
>       bus->irq = qemu_allocate_irq(bmdma_irq, bm, 0);
> +    bm->bus = bus;
>       bm->pci_dev = d;
>   }
>   
> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
> index 41d60921e3..a32f7ccece 100644
> --- a/hw/ide/piix.c
> +++ b/hw/ide/piix.c
> @@ -144,7 +144,6 @@ static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, Error **errp)
>       ide_bus_init_output_irq(&d->bus[i], isa_get_irq(NULL, port_info[i].isairq));
>   
>       bmdma_init(&d->bus[i], &d->bmdma[i], d);
> -    d->bmdma[i].bus = &d->bus[i];
>       ide_bus_register_restart_cb(&d->bus[i]);
>   
>       return true;
> diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c
> index f9becdff8e..5dd3d03c29 100644
> --- a/hw/ide/sii3112.c
> +++ b/hw/ide/sii3112.c
> @@ -287,7 +287,6 @@ static void sii3112_pci_realize(PCIDevice *dev, Error **errp)
>           ide_bus_init_output_irq(&s->bus[i], qdev_get_gpio_in(ds, i));
>   
>           bmdma_init(&s->bus[i], &s->bmdma[i], s);
> -        s->bmdma[i].bus = &s->bus[i];
>           ide_bus_register_restart_cb(&s->bus[i]);
>       }
>   }
> diff --git a/hw/ide/via.c b/hw/ide/via.c
> index 0caae52276..91253fa4ef 100644
> --- a/hw/ide/via.c
> +++ b/hw/ide/via.c
> @@ -196,7 +196,6 @@ static void via_ide_realize(PCIDevice *dev, Error **errp)
>           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 = &d->bus[i];
>           ide_bus_register_restart_cb(&d->bus[i]);
>       }
>   }

Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>


ATB,

Mark.


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 05/13] hw/ide: Extract pci_ide_class_init()
  2023-04-22 15:07 ` [PATCH 05/13] hw/ide: Extract pci_ide_class_init() Bernhard Beschow
  2023-04-22 17:34   ` BALATON Zoltan
  2023-04-23 17:41   ` Philippe Mathieu-Daudé
@ 2023-04-26 11:04   ` Mark Cave-Ayland
  2023-04-26 18:32     ` Bernhard Beschow
  2 siblings, 1 reply; 77+ messages in thread
From: Mark Cave-Ayland @ 2023-04-26 11:04 UTC (permalink / raw)
  To: Bernhard Beschow, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc

On 22/04/2023 16:07, Bernhard Beschow wrote:

> Resolves redundant code in every PCI IDE device model.

I think this needs to mention that it's moving the PCIDeviceClass::exit() function 
from all of the PCI IDE controller implementations to a common implementation in the 
parent PCI_IDE type.

> ---
>   include/hw/ide/pci.h |  1 -
>   hw/ide/cmd646.c      | 15 ---------------
>   hw/ide/pci.c         | 25 ++++++++++++++++++++++++-
>   hw/ide/piix.c        | 19 -------------------
>   hw/ide/sii3112.c     |  3 ++-
>   hw/ide/via.c         | 15 ---------------
>   6 files changed, 26 insertions(+), 52 deletions(-)
> 
> diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
> index 74c127e32f..7bc4e53d02 100644
> --- a/include/hw/ide/pci.h
> +++ b/include/hw/ide/pci.h
> @@ -61,7 +61,6 @@ void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val);
>   extern MemoryRegionOps bmdma_addr_ioport_ops;
>   void pci_ide_create_devs(PCIDevice *dev);
>   
> -extern const VMStateDescription vmstate_ide_pci;
>   extern const MemoryRegionOps pci_ide_cmd_le_ops;
>   extern const MemoryRegionOps pci_ide_data_le_ops;
>   #endif
> diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
> index a094a6e12a..9aabf80e52 100644
> --- a/hw/ide/cmd646.c
> +++ b/hw/ide/cmd646.c
> @@ -301,17 +301,6 @@ static void pci_cmd646_ide_realize(PCIDevice *dev, Error **errp)
>       }
>   }
>   
> -static void pci_cmd646_ide_exitfn(PCIDevice *dev)
> -{
> -    PCIIDEState *d = PCI_IDE(dev);
> -    unsigned i;
> -
> -    for (i = 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_ioport);
> -    }
> -}
> -
>   static Property cmd646_ide_properties[] = {
>       DEFINE_PROP_UINT32("secondary", PCIIDEState, secondary, 0),
>       DEFINE_PROP_END_OF_LIST(),
> @@ -323,17 +312,13 @@ static void cmd646_ide_class_init(ObjectClass *klass, void *data)
>       PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
>   
>       dc->reset = cmd646_reset;
> -    dc->vmsd = &vmstate_ide_pci;
>       k->realize = pci_cmd646_ide_realize;
> -    k->exit = pci_cmd646_ide_exitfn;
>       k->vendor_id = PCI_VENDOR_ID_CMD;
>       k->device_id = PCI_DEVICE_ID_CMD_646;
>       k->revision = 0x07;
> -    k->class_id = PCI_CLASS_STORAGE_IDE;
>       k->config_read = cmd646_pci_config_read;
>       k->config_write = cmd646_pci_config_write;
>       device_class_set_props(dc, cmd646_ide_properties);
> -    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
>   }
>   
>   static const TypeInfo cmd646_ide_info = {
> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
> index 67e0998ff0..8bea92e394 100644
> --- a/hw/ide/pci.c
> +++ b/hw/ide/pci.c
> @@ -467,7 +467,7 @@ static int ide_pci_post_load(void *opaque, int version_id)
>       return 0;
>   }
>   
> -const VMStateDescription vmstate_ide_pci = {
> +static const VMStateDescription vmstate_ide_pci = {
>       .name = "ide",
>       .version_id = 3,
>       .minimum_version_id = 0,
> @@ -530,11 +530,34 @@ static void pci_ide_init(Object *obj)
>       qdev_init_gpio_out(DEVICE(d), d->isa_irq, ARRAY_SIZE(d->isa_irq));
>   }
>   
> +static void pci_ide_exitfn(PCIDevice *dev)
> +{
> +    PCIIDEState *d = PCI_IDE(dev);
> +    unsigned i;
> +
> +    for (i = 0; i < ARRAY_SIZE(d->bmdma); ++i) {
> +        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io);
> +        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport);
> +    }
> +}
> +
> +static void pci_ide_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
> +
> +    dc->vmsd = &vmstate_ide_pci;
> +    k->exit = pci_ide_exitfn;
> +    k->class_id = PCI_CLASS_STORAGE_IDE;
> +    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
> +}
> +
>   static const TypeInfo pci_ide_type_info = {
>       .name = TYPE_PCI_IDE,
>       .parent = TYPE_PCI_DEVICE,
>       .instance_size = sizeof(PCIIDEState),
>       .instance_init = pci_ide_init,
> +    .class_init = pci_ide_class_init,
>       .abstract = true,
>       .interfaces = (InterfaceInfo[]) {
>           { INTERFACE_CONVENTIONAL_PCI_DEVICE },
> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
> index a32f7ccece..4e6ca99123 100644
> --- a/hw/ide/piix.c
> +++ b/hw/ide/piix.c
> @@ -159,8 +159,6 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
>       bmdma_setup_bar(d);
>       pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
>   
> -    vmstate_register(VMSTATE_IF(dev), 0, &vmstate_ide_pci, d);
> -

Presumably this still survives migration between a pre-series and post-series QEMU 
using the PIIX IDE controller?

>       for (unsigned i = 0; i < 2; i++) {
>           if (!pci_piix_init_bus(d, i, errp)) {
>               return;
> @@ -168,17 +166,6 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
>       }
>   }
>   
> -static void pci_piix_ide_exitfn(PCIDevice *dev)
> -{
> -    PCIIDEState *d = PCI_IDE(dev);
> -    unsigned i;
> -
> -    for (i = 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_ioport);
> -    }
> -}
> -
>   /* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */
>   static void piix3_ide_class_init(ObjectClass *klass, void *data)
>   {
> @@ -187,11 +174,8 @@ static void piix3_ide_class_init(ObjectClass *klass, void *data)
>   
>       dc->reset = piix_ide_reset;
>       k->realize = pci_piix_ide_realize;
> -    k->exit = pci_piix_ide_exitfn;
>       k->vendor_id = PCI_VENDOR_ID_INTEL;
>       k->device_id = PCI_DEVICE_ID_INTEL_82371SB_1;
> -    k->class_id = PCI_CLASS_STORAGE_IDE;
> -    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
>       dc->hotpluggable = false;
>   }
>   
> @@ -209,11 +193,8 @@ static void piix4_ide_class_init(ObjectClass *klass, void *data)
>   
>       dc->reset = piix_ide_reset;
>       k->realize = pci_piix_ide_realize;
> -    k->exit = pci_piix_ide_exitfn;
>       k->vendor_id = PCI_VENDOR_ID_INTEL;
>       k->device_id = PCI_DEVICE_ID_INTEL_82371AB;
> -    k->class_id = PCI_CLASS_STORAGE_IDE;
> -    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
>       dc->hotpluggable = false;
>   }
>   
> diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c
> index 5dd3d03c29..0af897a9ef 100644
> --- a/hw/ide/sii3112.c
> +++ b/hw/ide/sii3112.c
> @@ -301,9 +301,10 @@ static void sii3112_pci_class_init(ObjectClass *klass, void *data)
>       pd->class_id = PCI_CLASS_STORAGE_RAID;
>       pd->revision = 1;
>       pd->realize = sii3112_pci_realize;
> +    pd->exit = NULL;
>       dc->reset = sii3112_reset;
> +    dc->vmsd = NULL;
>       dc->desc = "SiI3112A SATA controller";
> -    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
>   }

No need to set explicit NULLs here: class/object structures are all zeroed before 
init (unless you're deliberately trying to prevent the common PCIDeviceClass::exit() 
function from being called here temporarily?)

>   static const TypeInfo sii3112_pci_info = {
> diff --git a/hw/ide/via.c b/hw/ide/via.c
> index 91253fa4ef..287143a005 100644
> --- a/hw/ide/via.c
> +++ b/hw/ide/via.c
> @@ -200,34 +200,19 @@ static void via_ide_realize(PCIDevice *dev, Error **errp)
>       }
>   }
>   
> -static void via_ide_exitfn(PCIDevice *dev)
> -{
> -    PCIIDEState *d = PCI_IDE(dev);
> -    unsigned i;
> -
> -    for (i = 0; i < ARRAY_SIZE(d->bmdma); ++i) {
> -        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io);
> -        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport);
> -    }
> -}
> -
>   static void via_ide_class_init(ObjectClass *klass, void *data)
>   {
>       DeviceClass *dc = DEVICE_CLASS(klass);
>       PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
>   
>       dc->reset = via_ide_reset;
> -    dc->vmsd = &vmstate_ide_pci;
>       /* Reason: only works as function of VIA southbridge */
>       dc->user_creatable = false;
>   
>       k->realize = via_ide_realize;
> -    k->exit = via_ide_exitfn;
>       k->vendor_id = PCI_VENDOR_ID_VIA;
>       k->device_id = PCI_DEVICE_ID_VIA_IDE;
>       k->revision = 0x06;
> -    k->class_id = PCI_CLASS_STORAGE_IDE;
> -    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
>   }
>   
>   static const TypeInfo via_ide_info = {

A couple of queries, but generally looks good to me.


ATB,

Mark.


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 06/13] hw/ide: Extract bmdma_init_ops()
  2023-04-22 15:07 ` [PATCH 06/13] hw/ide: Extract bmdma_init_ops() Bernhard Beschow
  2023-04-23 17:43   ` Philippe Mathieu-Daudé
@ 2023-04-26 11:14   ` Mark Cave-Ayland
  1 sibling, 0 replies; 77+ messages in thread
From: Mark Cave-Ayland @ 2023-04-26 11:14 UTC (permalink / raw)
  To: Bernhard Beschow, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc

On 22/04/2023 16:07, Bernhard Beschow wrote:

> There are three private copies of bmdma_setup_bar() with small adaptions.
> Consolidate them into one public implementation.
> 
> While at it rename the function to bmdma_init_ops() to reflect that the memory
> regions being initialized represent BMDMA operations. The actual mapping as a
> PCI BAR is still performed separately in each device.
> 
> Note that the bmdma_bar attribute will be renamed in a separate commit.
> 
> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
> ---
>   include/hw/ide/pci.h |  1 +
>   hw/ide/cmd646.c      | 20 +-------------------
>   hw/ide/pci.c         | 16 ++++++++++++++++
>   hw/ide/piix.c        | 19 +------------------
>   hw/ide/via.c         | 19 +------------------
>   5 files changed, 20 insertions(+), 55 deletions(-)
> 
> diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
> index 7bc4e53d02..597c77c7ad 100644
> --- a/include/hw/ide/pci.h
> +++ b/include/hw/ide/pci.h
> @@ -57,6 +57,7 @@ struct PCIIDEState {
>   };
>   
>   void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d);
> +void bmdma_init_ops(PCIIDEState *d, const MemoryRegionOps *bmdma_ops);
>   void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val);
>   extern MemoryRegionOps bmdma_addr_ioport_ops;
>   void pci_ide_create_devs(PCIDevice *dev);
> diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
> index 9aabf80e52..6fd09fe74e 100644
> --- a/hw/ide/cmd646.c
> +++ b/hw/ide/cmd646.c
> @@ -161,24 +161,6 @@ static const MemoryRegionOps cmd646_bmdma_ops = {
>       .write = bmdma_write,
>   };
>   
> -static void bmdma_setup_bar(PCIIDEState *d)
> -{
> -    BMDMAState *bm;
> -    int i;
> -
> -    memory_region_init(&d->bmdma_bar, OBJECT(d), "cmd646-bmdma", 16);
> -    for(i = 0;i < 2; i++) {
> -        bm = &d->bmdma[i];
> -        memory_region_init_io(&bm->extra_io, OBJECT(d), &cmd646_bmdma_ops, bm,
> -                              "cmd646-bmdma-bus", 4);
> -        memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io);
> -        memory_region_init_io(&bm->addr_ioport, OBJECT(d),
> -                              &bmdma_addr_ioport_ops, bm,
> -                              "cmd646-bmdma-ioport", 4);
> -        memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport);
> -    }
> -}
> -
>   static void cmd646_update_irq(PCIDevice *pd)
>   {
>       int pci_level;
> @@ -285,7 +267,7 @@ static void pci_cmd646_ide_realize(PCIDevice *dev, Error **errp)
>                             &d->bus[1], "cmd646-cmd1", 4);
>       pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[1]);
>   
> -    bmdma_setup_bar(d);
> +    bmdma_init_ops(d, &cmd646_bmdma_ops);
>       pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
>   
>       /* TODO: RST# value should be 0 */
> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
> index 8bea92e394..65ed6f7f72 100644
> --- a/hw/ide/pci.c
> +++ b/hw/ide/pci.c
> @@ -523,6 +523,22 @@ void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d)
>       bm->pci_dev = d;
>   }
>   
> +void bmdma_init_ops(PCIIDEState *d, const MemoryRegionOps *bmdma_ops)
> +{
> +    size_t i;
> +
> +    memory_region_init(&d->bmdma_bar, OBJECT(d), "bmdma-container", 16);
> +    for (i = 0; i < ARRAY_SIZE(d->bmdma); i++) {
> +        BMDMAState *bm = &d->bmdma[i];
> +
> +        memory_region_init_io(&bm->extra_io, OBJECT(d), bmdma_ops, bm, "bmdma-ops", 4);
> +        memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io);
> +        memory_region_init_io(&bm->addr_ioport, OBJECT(d), &bmdma_addr_ioport_ops, bm,
> +                              "bmdma-ioport-ops", 4);
> +        memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport);
> +    }
> +}
> +
>   static void pci_ide_init(Object *obj)
>   {
>       PCIIDEState *d = PCI_IDE(obj);
> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
> index 4e6ca99123..5611473d37 100644
> --- a/hw/ide/piix.c
> +++ b/hw/ide/piix.c
> @@ -86,23 +86,6 @@ static const MemoryRegionOps piix_bmdma_ops = {
>       .write = bmdma_write,
>   };
>   
> -static void bmdma_setup_bar(PCIIDEState *d)
> -{
> -    int i;
> -
> -    memory_region_init(&d->bmdma_bar, OBJECT(d), "piix-bmdma-container", 16);
> -    for(i = 0;i < 2; i++) {
> -        BMDMAState *bm = &d->bmdma[i];
> -
> -        memory_region_init_io(&bm->extra_io, OBJECT(d), &piix_bmdma_ops, bm,
> -                              "piix-bmdma", 4);
> -        memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io);
> -        memory_region_init_io(&bm->addr_ioport, OBJECT(d),
> -                              &bmdma_addr_ioport_ops, bm, "bmdma", 4);
> -        memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport);
> -    }
> -}
> -
>   static void piix_ide_reset(DeviceState *dev)
>   {
>       PCIIDEState *d = PCI_IDE(dev);
> @@ -156,7 +139,7 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
>   
>       pci_conf[PCI_CLASS_PROG] = 0x80; // legacy ATA mode
>   
> -    bmdma_setup_bar(d);
> +    bmdma_init_ops(d, &piix_bmdma_ops);
>       pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
>   
>       for (unsigned i = 0; i < 2; i++) {
> diff --git a/hw/ide/via.c b/hw/ide/via.c
> index 287143a005..40704e2857 100644
> --- a/hw/ide/via.c
> +++ b/hw/ide/via.c
> @@ -86,23 +86,6 @@ static const MemoryRegionOps via_bmdma_ops = {
>       .write = bmdma_write,
>   };
>   
> -static void bmdma_setup_bar(PCIIDEState *d)
> -{
> -    int i;
> -
> -    memory_region_init(&d->bmdma_bar, OBJECT(d), "via-bmdma-container", 16);
> -    for (i = 0; i < ARRAY_SIZE(d->bmdma); i++) {
> -        BMDMAState *bm = &d->bmdma[i];
> -
> -        memory_region_init_io(&bm->extra_io, OBJECT(d), &via_bmdma_ops, bm,
> -                              "via-bmdma", 4);
> -        memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io);
> -        memory_region_init_io(&bm->addr_ioport, OBJECT(d),
> -                              &bmdma_addr_ioport_ops, bm, "bmdma", 4);
> -        memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport);
> -    }
> -}
> -
>   static void via_ide_set_irq(void *opaque, int n, int level)
>   {
>       PCIIDEState *s = opaque;
> @@ -187,7 +170,7 @@ static void via_ide_realize(PCIDevice *dev, Error **errp)
>                             &d->bus[1], "via-ide1-cmd", 4);
>       pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[1]);
>   
> -    bmdma_setup_bar(d);
> +    bmdma_init_ops(d, &via_bmdma_ops);
>       pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
>   
>       qdev_init_gpio_in(ds, via_ide_set_irq, ARRAY_SIZE(d->bus));

Nice! In actual fact, with some more refactoring of the CMD646 device I believe you 
could remove the per-implementation ops and move everything into hw/ide/pci.c.

The main reason this is a bit difficult now is because of the "Device specific" 
registers intertwined with the BMDMA registers, but there's no reason that CMD646 
couldn't manually attach a fallback MemoryRegion to PCIIDEState::bmdma_bar and 
implement its device-specific registers there.

Unfortunately this isn't just a cut/paste job because there is also some mirroring of 
the BMDMA in PCI configuration space which will need some extra untangling: let's 
leave this as-is for now since it makes it easier for a follow-up patch to improve 
this later. On that basis:

Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>


ATB,

Mark.


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 07/13] hw/ide: Extract pci_ide_{cmd, data}_le_ops initialization into base class constructor
  2023-04-22 15:07 ` [PATCH 07/13] hw/ide: Extract pci_ide_{cmd, data}_le_ops initialization into base class constructor Bernhard Beschow
  2023-04-23 17:46   ` [PATCH 07/13] hw/ide: Extract pci_ide_{cmd,data}_le_ops " Philippe Mathieu-Daudé
@ 2023-04-26 11:16   ` Mark Cave-Ayland
  1 sibling, 0 replies; 77+ messages in thread
From: Mark Cave-Ayland @ 2023-04-26 11:16 UTC (permalink / raw)
  To: Bernhard Beschow, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc

On 22/04/2023 16:07, Bernhard Beschow wrote:

> There is redundant code in cmd646 and via which can be extracted into the base
> class. In case of piix and sii3112 this is currently unneccessary but shouldn't
> interfere since the memory regions aren't mapped by those devices. In few
> commits later this will be changed, i.e. those device models will also make use
> of these memory regions.
> 
> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
> ---
>   hw/ide/cmd646.c | 11 -----------
>   hw/ide/pci.c    | 10 ++++++++++
>   hw/ide/via.c    | 11 -----------
>   3 files changed, 10 insertions(+), 22 deletions(-)
> 
> diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
> index 6fd09fe74e..85716aaf17 100644
> --- a/hw/ide/cmd646.c
> +++ b/hw/ide/cmd646.c
> @@ -251,20 +251,9 @@ static void pci_cmd646_ide_realize(PCIDevice *dev, Error **errp)
>       dev->wmask[MRDMODE] = 0x0;
>       dev->w1cmask[MRDMODE] = MRDMODE_INTR_CH0 | MRDMODE_INTR_CH1;
>   
> -    memory_region_init_io(&d->data_bar[0], OBJECT(d), &pci_ide_data_le_ops,
> -                          &d->bus[0], "cmd646-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], "cmd646-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], "cmd646-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], "cmd646-cmd1", 4);
>       pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[1]);
>   
>       bmdma_init_ops(d, &cmd646_bmdma_ops);
> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
> index 65ed6f7f72..a9194313bd 100644
> --- a/hw/ide/pci.c
> +++ b/hw/ide/pci.c
> @@ -543,6 +543,16 @@ static void pci_ide_init(Object *obj)
>   {
>       PCIIDEState *d = PCI_IDE(obj);
>   
> +    memory_region_init_io(&d->data_bar[0], OBJECT(d), &pci_ide_data_le_ops,
> +                          &d->bus[0], "pci-ide0-data-ops", 8);
> +    memory_region_init_io(&d->cmd_bar[0], OBJECT(d), &pci_ide_cmd_le_ops,
> +                          &d->bus[0], "pci-ide0-cmd-ops", 4);
> +
> +    memory_region_init_io(&d->data_bar[1], OBJECT(d), &pci_ide_data_le_ops,
> +                          &d->bus[1], "pci-ide1-data-ops", 8);
> +    memory_region_init_io(&d->cmd_bar[1], OBJECT(d), &pci_ide_cmd_le_ops,
> +                          &d->bus[1], "pci-ide1-cmd-ops", 4);
> +
>       qdev_init_gpio_out(DEVICE(d), d->isa_irq, ARRAY_SIZE(d->isa_irq));
>   }
>   
> diff --git a/hw/ide/via.c b/hw/ide/via.c
> index 40704e2857..704a8024cb 100644
> --- a/hw/ide/via.c
> +++ b/hw/ide/via.c
> @@ -154,20 +154,9 @@ static void via_ide_realize(PCIDevice *dev, Error **errp)
>       dev->wmask[PCI_INTERRUPT_LINE] = 0;
>       dev->wmask[PCI_CLASS_PROG] = 5;
>   
> -    memory_region_init_io(&d->data_bar[0], OBJECT(d), &pci_ide_data_le_ops,
> -                          &d->bus[0], "via-ide0-data", 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], "via-ide0-cmd", 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], "via-ide1-data", 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], "via-ide1-cmd", 4);
>       pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[1]);
>   
>       bmdma_init_ops(d, &via_bmdma_ops);

I'd also be inclined to agree with Phil/Zoltan re: dropping the trailing "-ops" in 
the name, otherwise:

Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>


ATB,

Mark.


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 08/13] hw/ide: Rename PCIIDEState::*_bar attributes
  2023-04-22 15:07 ` [PATCH 08/13] hw/ide: Rename PCIIDEState::*_bar attributes Bernhard Beschow
  2023-04-22 17:53   ` BALATON Zoltan
@ 2023-04-26 11:21   ` Mark Cave-Ayland
  2023-04-26 18:29     ` Bernhard Beschow
  1 sibling, 1 reply; 77+ messages in thread
From: Mark Cave-Ayland @ 2023-04-26 11:21 UTC (permalink / raw)
  To: Bernhard Beschow, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc

On 22/04/2023 16:07, Bernhard Beschow wrote:

> The attributes represent memory regions containing operations which are mapped
> by the device models into PCI BARs. Reflect this by changing the suffic into
> "_ops".
> 
> Note that in a few commits piix will also use the {cmd,data}_ops but won't map
> them into BARs. This further suggests that the "_bar" suffix doesn't match
> very well.
> 
> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
> ---
>   include/hw/ide/pci.h |  6 +++---
>   hw/ide/cmd646.c      | 10 +++++-----
>   hw/ide/pci.c         | 18 +++++++++---------
>   hw/ide/piix.c        |  2 +-
>   hw/ide/via.c         | 10 +++++-----
>   5 files changed, 23 insertions(+), 23 deletions(-)
> 
> diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
> index 597c77c7ad..5025df5b82 100644
> --- a/include/hw/ide/pci.h
> +++ b/include/hw/ide/pci.h
> @@ -51,9 +51,9 @@ struct PCIIDEState {
>       BMDMAState bmdma[2];
>       qemu_irq isa_irq[2];
>       uint32_t secondary; /* used only for cmd646 */
> -    MemoryRegion bmdma_bar;
> -    MemoryRegion cmd_bar[2];
> -    MemoryRegion data_bar[2];
> +    MemoryRegion bmdma_ops;
> +    MemoryRegion cmd_ops[2];
> +    MemoryRegion data_ops[2];
>   };
>   
>   void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d);
> diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
> index 85716aaf17..b9d005a357 100644
> --- a/hw/ide/cmd646.c
> +++ b/hw/ide/cmd646.c
> @@ -251,13 +251,13 @@ static void pci_cmd646_ide_realize(PCIDevice *dev, Error **errp)
>       dev->wmask[MRDMODE] = 0x0;
>       dev->w1cmask[MRDMODE] = MRDMODE_INTR_CH0 | MRDMODE_INTR_CH1;
>   
> -    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->data_bar[0]);
> -    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[0]);
> -    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &d->data_bar[1]);
> -    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[1]);
> +    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->data_ops[0]);
> +    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_ops[0]);
> +    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &d->data_ops[1]);
> +    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_ops[1]);
>   
>       bmdma_init_ops(d, &cmd646_bmdma_ops);
> -    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
> +    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_ops);
>   
>       /* TODO: RST# value should be 0 */
>       pci_conf[PCI_INTERRUPT_PIN] = 0x01; // interrupt on pin 1
> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
> index a9194313bd..b2fcc00a64 100644
> --- a/hw/ide/pci.c
> +++ b/hw/ide/pci.c
> @@ -527,15 +527,15 @@ void bmdma_init_ops(PCIIDEState *d, const MemoryRegionOps *bmdma_ops)
>   {
>       size_t i;
>   
> -    memory_region_init(&d->bmdma_bar, OBJECT(d), "bmdma-container", 16);
> +    memory_region_init(&d->bmdma_ops, OBJECT(d), "bmdma-container", 16);
>       for (i = 0; i < ARRAY_SIZE(d->bmdma); i++) {
>           BMDMAState *bm = &d->bmdma[i];
>   
>           memory_region_init_io(&bm->extra_io, OBJECT(d), bmdma_ops, bm, "bmdma-ops", 4);
> -        memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io);
> +        memory_region_add_subregion(&d->bmdma_ops, i * 8, &bm->extra_io);
>           memory_region_init_io(&bm->addr_ioport, OBJECT(d), &bmdma_addr_ioport_ops, bm,
>                                 "bmdma-ioport-ops", 4);
> -        memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport);
> +        memory_region_add_subregion(&d->bmdma_ops, i * 8 + 4, &bm->addr_ioport);
>       }
>   }
>   
> @@ -543,14 +543,14 @@ static void pci_ide_init(Object *obj)
>   {
>       PCIIDEState *d = PCI_IDE(obj);
>   
> -    memory_region_init_io(&d->data_bar[0], OBJECT(d), &pci_ide_data_le_ops,
> +    memory_region_init_io(&d->data_ops[0], OBJECT(d), &pci_ide_data_le_ops,
>                             &d->bus[0], "pci-ide0-data-ops", 8);
> -    memory_region_init_io(&d->cmd_bar[0], OBJECT(d), &pci_ide_cmd_le_ops,
> +    memory_region_init_io(&d->cmd_ops[0], OBJECT(d), &pci_ide_cmd_le_ops,
>                             &d->bus[0], "pci-ide0-cmd-ops", 4);
>   
> -    memory_region_init_io(&d->data_bar[1], OBJECT(d), &pci_ide_data_le_ops,
> +    memory_region_init_io(&d->data_ops[1], OBJECT(d), &pci_ide_data_le_ops,
>                             &d->bus[1], "pci-ide1-data-ops", 8);
> -    memory_region_init_io(&d->cmd_bar[1], OBJECT(d), &pci_ide_cmd_le_ops,
> +    memory_region_init_io(&d->cmd_ops[1], OBJECT(d), &pci_ide_cmd_le_ops,
>                             &d->bus[1], "pci-ide1-cmd-ops", 4);
>   
>       qdev_init_gpio_out(DEVICE(d), d->isa_irq, ARRAY_SIZE(d->isa_irq));
> @@ -562,8 +562,8 @@ static void pci_ide_exitfn(PCIDevice *dev)
>       unsigned i;
>   
>       for (i = 0; i < ARRAY_SIZE(d->bmdma); ++i) {
> -        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io);
> -        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport);
> +        memory_region_del_subregion(&d->bmdma_ops, &d->bmdma[i].extra_io);
> +        memory_region_del_subregion(&d->bmdma_ops, &d->bmdma[i].addr_ioport);
>       }
>   }
>   
> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
> index 5611473d37..6942b484f9 100644
> --- a/hw/ide/piix.c
> +++ b/hw/ide/piix.c
> @@ -140,7 +140,7 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
>       pci_conf[PCI_CLASS_PROG] = 0x80; // legacy ATA mode
>   
>       bmdma_init_ops(d, &piix_bmdma_ops);
> -    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
> +    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_ops);
>   
>       for (unsigned i = 0; i < 2; i++) {
>           if (!pci_piix_init_bus(d, i, errp)) {
> diff --git a/hw/ide/via.c b/hw/ide/via.c
> index 704a8024cb..35dd97e49b 100644
> --- a/hw/ide/via.c
> +++ b/hw/ide/via.c
> @@ -154,13 +154,13 @@ static void via_ide_realize(PCIDevice *dev, Error **errp)
>       dev->wmask[PCI_INTERRUPT_LINE] = 0;
>       dev->wmask[PCI_CLASS_PROG] = 5;
>   
> -    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->data_bar[0]);
> -    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[0]);
> -    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &d->data_bar[1]);
> -    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[1]);
> +    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->data_ops[0]);
> +    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_ops[0]);
> +    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &d->data_ops[1]);
> +    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_ops[1]);
>   
>       bmdma_init_ops(d, &via_bmdma_ops);
> -    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
> +    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_ops);
>   
>       qdev_init_gpio_in(ds, via_ide_set_irq, ARRAY_SIZE(d->bus));
>       for (i = 0; i < ARRAY_SIZE(d->bus); i++) {

I don't really feel strongly either way on this one, so I'm happy to go along with 
the silent majority here - I see that Zoltan has expressed a preference for it to 
stay as-is.


ATB,

Mark.


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 09/13] hw/ide/piix: Disuse isa_get_irq()
  2023-04-22 15:07 ` [PATCH 09/13] hw/ide/piix: Disuse isa_get_irq() Bernhard Beschow
@ 2023-04-26 11:33   ` Mark Cave-Ayland
  2023-04-26 18:25     ` Bernhard Beschow
  0 siblings, 1 reply; 77+ messages in thread
From: Mark Cave-Ayland @ 2023-04-26 11:33 UTC (permalink / raw)
  To: Bernhard Beschow, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc

On 22/04/2023 16:07, Bernhard Beschow wrote:

> isa_get_irq() asks for an ISADevice which piix-ide doesn't provide.
> Passing a NULL pointer works but causes the isabus global to be used
> then. By fishing out TYPE_ISA_BUS from the QOM tree it is possible to
> achieve the same as using isa_get_irq().
> 
> This is an alternative solution to commit 9405d87be25d 'hw/ide: Fix
> crash when plugging a piix3-ide device into the x-remote machine' which
> allows for cleaning up the ISA API while keeping PIIX IDE functions
> user-createable.
> 
> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
> ---
>   hw/ide/piix.c | 23 ++++++++++++++++++++---
>   1 file changed, 20 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
> index 6942b484f9..a3a15dc7db 100644
> --- a/hw/ide/piix.c
> +++ b/hw/ide/piix.c
> @@ -104,7 +104,8 @@ static void piix_ide_reset(DeviceState *dev)
>       pci_set_byte(pci_conf + 0x20, 0x01);  /* BMIBA: 20-23h */
>   }
>   
> -static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, Error **errp)
> +static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, ISABus *isa_bus,
> +                              Error **errp)
>   {
>       static const struct {
>           int iobase;
> @@ -124,7 +125,8 @@ static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, Error **errp)
>                            object_get_typename(OBJECT(d)), i);
>           return false;
>       }
> -    ide_bus_init_output_irq(&d->bus[i], isa_get_irq(NULL, port_info[i].isairq));
> +    ide_bus_init_output_irq(&d->bus[i],
> +                            isa_bus_get_irq(isa_bus, port_info[i].isairq));

I don't think is the right solution here, since ultimately we want to move the IRQ 
routing out of the device itself and into the PCI-ISA bridge. I'd go for the same 
solution as you've done for VIA IDE in patch 2, i.e. update the PIIX interrupt 
handler to set the legacy_irqs in PCIIDEState, and then wire them up to the ISA IRQs 
14 and 15 similar to as Phil as done in his patches:

https://patchew.org/QEMU/20230302224058.43315-1-philmd@linaro.org/20230302224058.43315-4-philmd@linaro.org/

https://patchew.org/QEMU/20230302224058.43315-1-philmd@linaro.org/20230302224058.43315-5-philmd@linaro.org/

This also reminds me, given that the first patch above is doing wiring in pc_init1() 
then we are still missing part of your tidy-up series :/

>       bmdma_init(&d->bus[i], &d->bmdma[i], d);
>       ide_bus_register_restart_cb(&d->bus[i]);
> @@ -136,14 +138,29 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
>   {
>       PCIIDEState *d = PCI_IDE(dev);
>       uint8_t *pci_conf = dev->config;
> +    ISABus *isa_bus;
> +    bool ambiguous;
>   
>       pci_conf[PCI_CLASS_PROG] = 0x80; // legacy ATA mode
>   
>       bmdma_init_ops(d, &piix_bmdma_ops);
>       pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_ops);
>   
> +    isa_bus = ISA_BUS(object_resolve_path_type("", TYPE_ISA_BUS, &ambiguous));
> +    if (ambiguous) {
> +        error_setg(errp,
> +                   "More than one ISA bus found while %s supports only one",
> +                   object_get_typename(OBJECT(d)));
> +        return;
> +    }
> +    if (!isa_bus) {
> +        error_setg(errp, "No ISA bus found while %s requires one",
> +                   object_get_typename(OBJECT(d)));
> +        return;
> +    }

Again I think this should go away with using PCIIDEState's legacy_irqs, since you 
simply let the board wire them up to the ISABus (or not) as required.

>       for (unsigned i = 0; i < 2; i++) {
> -        if (!pci_piix_init_bus(d, i, errp)) {
> +        if (!pci_piix_init_bus(d, i, isa_bus, errp)) {
>               return;
>           }
>       }


ATB,

Mark.


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 10/13] hw/ide/piix: Reuse PCIIDEState::{cmd,data}_ops
  2023-04-22 15:07 ` [PATCH 10/13] hw/ide/piix: Reuse PCIIDEState::{cmd,data}_ops Bernhard Beschow
@ 2023-04-26 11:37   ` Mark Cave-Ayland
  2023-04-26 18:18     ` Bernhard Beschow
  0 siblings, 1 reply; 77+ messages in thread
From: Mark Cave-Ayland @ 2023-04-26 11:37 UTC (permalink / raw)
  To: Bernhard Beschow, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc

On 22/04/2023 16:07, Bernhard Beschow wrote:

> Now that PCIIDEState::{cmd,data}_ops are initialized in the base class
> constructor there is an opportunity for PIIX to reuse these attributes. This
> resolves usage of ide_init_ioport() which would fall back internally to using
> the isabus global due to NULL being passed as ISADevice by PIIX.
> 
> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
> ---
>   hw/ide/piix.c | 30 +++++++++++++-----------------
>   1 file changed, 13 insertions(+), 17 deletions(-)
> 
> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
> index a3a15dc7db..406a67fa0f 100644
> --- a/hw/ide/piix.c
> +++ b/hw/ide/piix.c
> @@ -104,34 +104,32 @@ static void piix_ide_reset(DeviceState *dev)
>       pci_set_byte(pci_conf + 0x20, 0x01);  /* BMIBA: 20-23h */
>   }
>   
> -static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, ISABus *isa_bus,
> -                              Error **errp)
> +static void pci_piix_init_bus(PCIIDEState *d, unsigned i, ISABus *isa_bus)
>   {
>       static const struct {
>           int iobase;
>           int iobase2;
>           int isairq;
>       } port_info[] = {
> -        {0x1f0, 0x3f6, 14},
> -        {0x170, 0x376, 15},
> +        {0x1f0, 0x3f4, 14},
> +        {0x170, 0x374, 15},
>       };
> -    int ret;
> +    MemoryRegion *address_space_io = pci_address_space_io(PCI_DEVICE(d));
>   
>       ide_bus_init(&d->bus[i], sizeof(d->bus[i]), DEVICE(d), i, 2);
> -    ret = ide_init_ioport(&d->bus[i], NULL, port_info[i].iobase,
> -                          port_info[i].iobase2);
> -    if (ret) {
> -        error_setg_errno(errp, -ret, "Failed to realize %s port %u",
> -                         object_get_typename(OBJECT(d)), i);
> -        return false;
> -    }
> +    memory_region_add_subregion(address_space_io, port_info[i].iobase,
> +                                &d->data_ops[i]);
> +    /*
> +     * PIIX forwards the last byte of cmd_ops to ISA. Model this using a low
> +     * prio so competing memory regions take precedence.
> +     */
> +    memory_region_add_subregion_overlap(address_space_io, port_info[i].iobase2,
> +                                        &d->cmd_ops[i], -1);

Interesting. Is this behaviour documented somewhere and/or used in one of your test 
images at all? If I'd have seen this myself, I probably thought that the addresses 
were a typo...

>       ide_bus_init_output_irq(&d->bus[i],
>                               isa_bus_get_irq(isa_bus, port_info[i].isairq));
>   
>       bmdma_init(&d->bus[i], &d->bmdma[i], d);
>       ide_bus_register_restart_cb(&d->bus[i]);
> -
> -    return true;
>   }
>   
>   static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
> @@ -160,9 +158,7 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
>       }
>   
>       for (unsigned i = 0; i < 2; i++) {
> -        if (!pci_piix_init_bus(d, i, isa_bus, errp)) {
> -            return;
> -        }
> +        pci_piix_init_bus(d, i, isa_bus);
>       }
>   }
>   


ATB,

Mark.


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 11/13] hw/ide/sii3112: Reuse PCIIDEState::{cmd,data}_ops
  2023-04-22 15:07 ` [PATCH 11/13] hw/ide/sii3112: " Bernhard Beschow
  2023-04-22 21:10   ` BALATON Zoltan
@ 2023-04-26 11:41   ` Mark Cave-Ayland
  2023-04-26 20:24     ` Bernhard Beschow
  1 sibling, 1 reply; 77+ messages in thread
From: Mark Cave-Ayland @ 2023-04-26 11:41 UTC (permalink / raw)
  To: Bernhard Beschow, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc

On 22/04/2023 16:07, Bernhard Beschow wrote:

> Allows to unexport pci_ide_{cmd,data}_le_ops and models TYPE_SII3112_PCI as a
> standard-compliant PCI IDE device.
> 
> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
> ---
>   include/hw/ide/pci.h |  2 --
>   hw/ide/pci.c         |  4 ++--
>   hw/ide/sii3112.c     | 50 ++++++++++++++++----------------------------
>   3 files changed, 20 insertions(+), 36 deletions(-)
> 
> diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
> index 5025df5b82..dbb4b13161 100644
> --- a/include/hw/ide/pci.h
> +++ b/include/hw/ide/pci.h
> @@ -62,6 +62,4 @@ void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val);
>   extern MemoryRegionOps bmdma_addr_ioport_ops;
>   void pci_ide_create_devs(PCIDevice *dev);
>   
> -extern const MemoryRegionOps pci_ide_cmd_le_ops;
> -extern const MemoryRegionOps pci_ide_data_le_ops;
>   #endif
> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
> index b2fcc00a64..97ccc75aa6 100644
> --- a/hw/ide/pci.c
> +++ b/hw/ide/pci.c
> @@ -60,7 +60,7 @@ static void pci_ide_ctrl_write(void *opaque, hwaddr addr,
>       ide_ctrl_write(bus, addr + 2, data);
>   }
>   
> -const MemoryRegionOps pci_ide_cmd_le_ops = {
> +static const MemoryRegionOps pci_ide_cmd_le_ops = {
>       .read = pci_ide_status_read,
>       .write = pci_ide_ctrl_write,
>       .endianness = DEVICE_LITTLE_ENDIAN,
> @@ -98,7 +98,7 @@ static void pci_ide_data_write(void *opaque, hwaddr addr,
>       }
>   }
>   
> -const MemoryRegionOps pci_ide_data_le_ops = {
> +static const MemoryRegionOps pci_ide_data_le_ops = {
>       .read = pci_ide_data_read,
>       .write = pci_ide_data_write,
>       .endianness = DEVICE_LITTLE_ENDIAN,
> diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c
> index 0af897a9ef..9cf920369f 100644
> --- a/hw/ide/sii3112.c
> +++ b/hw/ide/sii3112.c
> @@ -88,21 +88,9 @@ static uint64_t sii3112_reg_read(void *opaque, hwaddr addr,
>           val |= (d->regs[1].confstat & (1UL << 11) ? (1 << 4) : 0);
>           val |= (uint32_t)d->i.bmdma[1].status << 16;
>           break;
> -    case 0x80 ... 0x87:
> -        val = pci_ide_data_le_ops.read(&d->i.bus[0], addr - 0x80, size);
> -        break;
> -    case 0x8a:
> -        val = pci_ide_cmd_le_ops.read(&d->i.bus[0], 2, size);
> -        break;
>       case 0xa0:
>           val = d->regs[0].confstat;
>           break;
> -    case 0xc0 ... 0xc7:
> -        val = pci_ide_data_le_ops.read(&d->i.bus[1], addr - 0xc0, size);
> -        break;
> -    case 0xca:
> -        val = pci_ide_cmd_le_ops.read(&d->i.bus[1], 2, size);
> -        break;
>       case 0xe0:
>           val = d->regs[1].confstat;
>           break;
> @@ -171,18 +159,6 @@ static void sii3112_reg_write(void *opaque, hwaddr addr,
>       case 0x0c ... 0x0f:
>           bmdma_addr_ioport_ops.write(&d->i.bmdma[1], addr - 12, val, size);
>           break;
> -    case 0x80 ... 0x87:
> -        pci_ide_data_le_ops.write(&d->i.bus[0], addr - 0x80, val, size);
> -        break;
> -    case 0x8a:
> -        pci_ide_cmd_le_ops.write(&d->i.bus[0], 2, val, size);
> -        break;
> -    case 0xc0 ... 0xc7:
> -        pci_ide_data_le_ops.write(&d->i.bus[1], addr - 0xc0, val, size);
> -        break;
> -    case 0xca:
> -        pci_ide_cmd_le_ops.write(&d->i.bus[1], 2, val, size);
> -        break;
>       case 0x100:
>           d->regs[0].scontrol = val & 0xfff;
>           if (val & 1) {
> @@ -259,6 +235,11 @@ static void sii3112_pci_realize(PCIDevice *dev, Error **errp)
>       pci_config_set_interrupt_pin(dev->config, 1);
>       pci_set_byte(dev->config + PCI_CACHE_LINE_SIZE, 8);
>   
> +    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->data_ops[0]);
> +    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->cmd_ops[0]);
> +    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &s->data_ops[1]);
> +    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &s->cmd_ops[1]);
> +
>       /* BAR5 is in PCI memory space */
>       memory_region_init_io(&d->mmio, OBJECT(d), &sii3112_reg_ops, d,
>                            "sii3112.bar5", 0x200);
> @@ -266,17 +247,22 @@ static void sii3112_pci_realize(PCIDevice *dev, Error **errp)
>   
>       /* BAR0-BAR4 are PCI I/O space aliases into BAR5 */
>       mr = g_new(MemoryRegion, 1);
> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar0", &d->mmio, 0x80, 8);
> -    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, mr);
> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar0", &s->data_ops[0], 0,
> +                             memory_region_size(&s->data_ops[0]));
> +    memory_region_add_subregion_overlap(&d->mmio, 0x80, mr, 1);
>       mr = g_new(MemoryRegion, 1);
> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar1", &d->mmio, 0x88, 4);
> -    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, mr);
> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar1", &s->cmd_ops[0], 0,
> +                             memory_region_size(&s->cmd_ops[0]));
> +    memory_region_add_subregion_overlap(&d->mmio, 0x88, mr, 1);
>       mr = g_new(MemoryRegion, 1);
> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar2", &d->mmio, 0xc0, 8);
> -    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, mr);
> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar2", &s->data_ops[1], 0,
> +                             memory_region_size(&s->data_ops[1]));
> +    memory_region_add_subregion_overlap(&d->mmio, 0xc0, mr, 1);
>       mr = g_new(MemoryRegion, 1);
> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar3", &d->mmio, 0xc8, 4);
> -    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, mr);
> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar3", &s->cmd_ops[1], 0,
> +                             memory_region_size(&s->cmd_ops[1]));
> +    memory_region_add_subregion_overlap(&d->mmio, 0xc8, mr, 1);
> +
>       mr = g_new(MemoryRegion, 1);
>       memory_region_init_alias(mr, OBJECT(d), "sii3112.bar4", &d->mmio, 0, 16);
>       pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, mr);

So if I read this right, this is now switching the aliases over on BAR5 to allow 
re-use of the common IDE/BMDMA BARs in PCIIDEState? If that's correct then I think 
the commit message needs a bit more detail, otherwise:

Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>


ATB,

Mark.


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 12/13] hw/ide/sii3112: Reuse PCIIDEState::bmdma_ops
  2023-04-22 15:07 ` [PATCH 12/13] hw/ide/sii3112: Reuse PCIIDEState::bmdma_ops Bernhard Beschow
@ 2023-04-26 11:44   ` Mark Cave-Ayland
  2023-04-26 20:26     ` Bernhard Beschow
  0 siblings, 1 reply; 77+ messages in thread
From: Mark Cave-Ayland @ 2023-04-26 11:44 UTC (permalink / raw)
  To: Bernhard Beschow, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc

On 22/04/2023 16:07, Bernhard Beschow wrote:

> Allows to unexport bmdma_addr_ioport_ops and models TYPE_SII3112_PCI as a
> standard-compliant PCI IDE device.

Nice! I think it's worth adding a brief mention that you've added BMDMA trace-events, 
but otherwise looks sensible to me.

> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
> ---
>   include/hw/ide/pci.h |  1 -
>   hw/ide/pci.c         |  2 +-
>   hw/ide/sii3112.c     | 94 ++++++++++++++++++++++++++------------------
>   hw/ide/trace-events  |  6 ++-
>   4 files changed, 60 insertions(+), 43 deletions(-)
> 
> diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
> index dbb4b13161..81e0370202 100644
> --- a/include/hw/ide/pci.h
> +++ b/include/hw/ide/pci.h
> @@ -59,7 +59,6 @@ struct PCIIDEState {
>   void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d);
>   void bmdma_init_ops(PCIIDEState *d, const MemoryRegionOps *bmdma_ops);
>   void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val);
> -extern MemoryRegionOps bmdma_addr_ioport_ops;
>   void pci_ide_create_devs(PCIDevice *dev);
>   
>   #endif
> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
> index 97ccc75aa6..3539b162b7 100644
> --- a/hw/ide/pci.c
> +++ b/hw/ide/pci.c
> @@ -342,7 +342,7 @@ static void bmdma_addr_write(void *opaque, hwaddr addr,
>       bm->addr |= ((data & mask) << shift) & ~3;
>   }
>   
> -MemoryRegionOps bmdma_addr_ioport_ops = {
> +static MemoryRegionOps bmdma_addr_ioport_ops = {
>       .read = bmdma_addr_read,
>       .write = bmdma_addr_write,
>       .endianness = DEVICE_LITTLE_ENDIAN,
> diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c
> index 9cf920369f..373c0dd1ee 100644
> --- a/hw/ide/sii3112.c
> +++ b/hw/ide/sii3112.c
> @@ -34,47 +34,73 @@ struct SiI3112PCIState {
>       SiI3112Regs regs[2];
>   };
>   
> -/* The sii3112_reg_read and sii3112_reg_write functions implement the
> - * Internal Register Space - BAR5 (section 6.7 of the data sheet).
> - */
> -
> -static uint64_t sii3112_reg_read(void *opaque, hwaddr addr,
> -                                unsigned int size)
> +static uint64_t sii3112_bmdma_read(void *opaque, hwaddr addr, unsigned int size)
>   {
> -    SiI3112PCIState *d = opaque;
> +    BMDMAState *bm = opaque;
> +    SiI3112PCIState *d = SII3112_PCI(bm->pci_dev);
> +    int i = (bm == &bm->pci_dev->bmdma[0]) ? 0 : 1;
>       uint64_t val;
>   
>       switch (addr) {
>       case 0x00:
> -        val = d->i.bmdma[0].cmd;
> +        val = bm->cmd;
>           break;
>       case 0x01:
> -        val = d->regs[0].swdata;
> +        val = d->regs[i].swdata;
>           break;
>       case 0x02:
> -        val = d->i.bmdma[0].status;
> +        val = bm->status;
>           break;
>       case 0x03:
>           val = 0;
>           break;
> -    case 0x04 ... 0x07:
> -        val = bmdma_addr_ioport_ops.read(&d->i.bmdma[0], addr - 4, size);
> -        break;
> -    case 0x08:
> -        val = d->i.bmdma[1].cmd;
> +    default:
> +        val = 0;
>           break;
> -    case 0x09:
> -        val = d->regs[1].swdata;
> +    }
> +    trace_sii3112_bmdma_read(size, addr, val);
> +    return val;
> +}
> +
> +static void sii3112_bmdma_write(void *opaque, hwaddr addr,
> +                                uint64_t val, unsigned int size)
> +{
> +    BMDMAState *bm = opaque;
> +    SiI3112PCIState *d = SII3112_PCI(bm->pci_dev);
> +    int i = (bm == &bm->pci_dev->bmdma[0]) ? 0 : 1;
> +
> +    trace_sii3112_bmdma_write(size, addr, val);
> +    switch (addr) {
> +    case 0x00:
> +        bmdma_cmd_writeb(bm, val);
>           break;
> -    case 0x0a:
> -        val = d->i.bmdma[1].status;
> +    case 0x01:
> +        d->regs[i].swdata = val & 0x3f;
>           break;
> -    case 0x0b:
> -        val = 0;
> +    case 0x02:
> +        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 6);
>           break;
> -    case 0x0c ... 0x0f:
> -        val = bmdma_addr_ioport_ops.read(&d->i.bmdma[1], addr - 12, size);
> +    default:
>           break;
> +    }
> +}
> +
> +static const MemoryRegionOps sii3112_bmdma_ops = {
> +    .read = sii3112_bmdma_read,
> +    .write = sii3112_bmdma_write,
> +};
> +
> +/* The sii3112_reg_read and sii3112_reg_write functions implement the
> + * Internal Register Space - BAR5 (section 6.7 of the data sheet).
> + */
> +
> +static uint64_t sii3112_reg_read(void *opaque, hwaddr addr,
> +                                unsigned int size)
> +{
> +    SiI3112PCIState *d = opaque;
> +    uint64_t val;
> +
> +    switch (addr) {
>       case 0x10:
>           val = d->i.bmdma[0].cmd;
>           val |= (d->regs[0].confstat & (1UL << 11) ? (1 << 4) : 0); /*SATAINT0*/
> @@ -127,38 +153,26 @@ static void sii3112_reg_write(void *opaque, hwaddr addr,
>   
>       trace_sii3112_write(size, addr, val);
>       switch (addr) {
> -    case 0x00:
>       case 0x10:
>           bmdma_cmd_writeb(&d->i.bmdma[0], val);
>           break;
> -    case 0x01:
>       case 0x11:
>           d->regs[0].swdata = val & 0x3f;
>           break;
> -    case 0x02:
>       case 0x12:
>           d->i.bmdma[0].status = (val & 0x60) | (d->i.bmdma[0].status & 1) |
>                                  (d->i.bmdma[0].status & ~val & 6);
>           break;
> -    case 0x04 ... 0x07:
> -        bmdma_addr_ioport_ops.write(&d->i.bmdma[0], addr - 4, val, size);
> -        break;
> -    case 0x08:
>       case 0x18:
>           bmdma_cmd_writeb(&d->i.bmdma[1], val);
>           break;
> -    case 0x09:
>       case 0x19:
>           d->regs[1].swdata = val & 0x3f;
>           break;
> -    case 0x0a:
>       case 0x1a:
>           d->i.bmdma[1].status = (val & 0x60) | (d->i.bmdma[1].status & 1) |
>                                  (d->i.bmdma[1].status & ~val & 6);
>           break;
> -    case 0x0c ... 0x0f:
> -        bmdma_addr_ioport_ops.write(&d->i.bmdma[1], addr - 12, val, size);
> -        break;
>       case 0x100:
>           d->regs[0].scontrol = val & 0xfff;
>           if (val & 1) {
> @@ -240,6 +254,9 @@ static void sii3112_pci_realize(PCIDevice *dev, Error **errp)
>       pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &s->data_ops[1]);
>       pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &s->cmd_ops[1]);
>   
> +    bmdma_init_ops(s, &sii3112_bmdma_ops);
> +    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &s->bmdma_ops);
> +
>       /* BAR5 is in PCI memory space */
>       memory_region_init_io(&d->mmio, OBJECT(d), &sii3112_reg_ops, d,
>                            "sii3112.bar5", 0x200);
> @@ -262,10 +279,10 @@ static void sii3112_pci_realize(PCIDevice *dev, Error **errp)
>       memory_region_init_alias(mr, OBJECT(d), "sii3112.bar3", &s->cmd_ops[1], 0,
>                                memory_region_size(&s->cmd_ops[1]));
>       memory_region_add_subregion_overlap(&d->mmio, 0xc8, mr, 1);
> -
>       mr = g_new(MemoryRegion, 1);
> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar4", &d->mmio, 0, 16);
> -    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, mr);
> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar4", &s->bmdma_ops, 0,
> +                             memory_region_size(&s->bmdma_ops));
> +    memory_region_add_subregion_overlap(&d->mmio, 0x0, mr, 1);
>   
>       qdev_init_gpio_in(ds, sii3112_set_irq, 2);
>       for (i = 0; i < 2; i++) {
> @@ -287,7 +304,6 @@ static void sii3112_pci_class_init(ObjectClass *klass, void *data)
>       pd->class_id = PCI_CLASS_STORAGE_RAID;
>       pd->revision = 1;
>       pd->realize = sii3112_pci_realize;
> -    pd->exit = NULL;
>       dc->reset = sii3112_reset;
>       dc->vmsd = NULL;
>       dc->desc = "SiI3112A SATA controller";
> diff --git a/hw/ide/trace-events b/hw/ide/trace-events
> index 57042cafdd..a479525e38 100644
> --- a/hw/ide/trace-events
> +++ b/hw/ide/trace-events
> @@ -38,8 +38,10 @@ bmdma_read(uint64_t addr, uint8_t val) "bmdma: readb 0x%"PRIx64" : 0x%02x"
>   bmdma_write(uint64_t addr, uint64_t val) "bmdma: writeb 0x%"PRIx64" : 0x%02"PRIx64
>   
>   # sii3112.c
> -sii3112_read(int size, uint64_t addr, uint64_t val) "bmdma: read (size %d) 0x%"PRIx64" : 0x%02"PRIx64
> -sii3112_write(int size, uint64_t addr, uint64_t val) "bmdma: write (size %d) 0x%"PRIx64" : 0x%02"PRIx64
> +sii3112_bmdma_read(int size, uint64_t addr, uint64_t val) "read (size %d) 0x%"PRIx64" : 0x%02"PRIx64
> +sii3112_bmdma_write(int size, uint64_t addr, uint64_t val) "write (size %d) 0x%"PRIx64" : 0x%02"PRIx64
> +sii3112_read(int size, uint64_t addr, uint64_t val) "read (size %d) 0x%"PRIx64" : 0x%02"PRIx64
> +sii3112_write(int size, uint64_t addr, uint64_t val) "write (size %d) 0x%"PRIx64" : 0x%02"PRIx64
>   sii3112_set_irq(int channel, int level) "channel %d level %d"
>   
>   # via.c

Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>


ATB,

Mark.


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 13/13] hw/ide: Extract bmdma_clear_status()
  2023-04-22 15:07 ` [PATCH 13/13] hw/ide: Extract bmdma_clear_status() Bernhard Beschow
  2023-04-22 21:26   ` BALATON Zoltan
  2023-04-22 22:46   ` BALATON Zoltan
@ 2023-04-26 11:48   ` Mark Cave-Ayland
  2 siblings, 0 replies; 77+ messages in thread
From: Mark Cave-Ayland @ 2023-04-26 11:48 UTC (permalink / raw)
  To: Bernhard Beschow, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc

On 22/04/2023 16:07, Bernhard Beschow wrote:

> Extract bmdma_clear_status() mirroring bmdma_cmd_writeb().
> 
> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
> ---
>   include/hw/ide/pci.h |  1 +
>   hw/ide/cmd646.c      |  2 +-
>   hw/ide/pci.c         |  7 +++++++
>   hw/ide/piix.c        |  2 +-
>   hw/ide/sii3112.c     | 12 +++++-------
>   hw/ide/via.c         |  2 +-
>   hw/ide/trace-events  |  1 +
>   7 files changed, 17 insertions(+), 10 deletions(-)
> 
> diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
> index 81e0370202..6a286ad307 100644
> --- a/include/hw/ide/pci.h
> +++ b/include/hw/ide/pci.h
> @@ -59,6 +59,7 @@ struct PCIIDEState {
>   void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d);
>   void bmdma_init_ops(PCIIDEState *d, const MemoryRegionOps *bmdma_ops);
>   void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val);
> +void bmdma_clear_status(BMDMAState *bm, uint32_t val);
>   void pci_ide_create_devs(PCIDevice *dev);
>   
>   #endif
> diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
> index b9d005a357..973c3ff0dc 100644
> --- a/hw/ide/cmd646.c
> +++ b/hw/ide/cmd646.c
> @@ -144,7 +144,7 @@ static void bmdma_write(void *opaque, hwaddr addr,
>           cmd646_update_irq(pci_dev);
>           break;
>       case 2:
> -        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
> +        bmdma_clear_status(bm, val);
>           break;
>       case 3:
>           if (bm == &bm->pci_dev->bmdma[0]) {
> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
> index 3539b162b7..4aa06be7c6 100644
> --- a/hw/ide/pci.c
> +++ b/hw/ide/pci.c
> @@ -318,6 +318,13 @@ void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val)
>       bm->cmd = val & 0x09;
>   }
>   
> +void bmdma_clear_status(BMDMAState *bm, uint32_t val)
> +{
> +    trace_bmdma_update_status(val);
> +
> +    bm->status = (val & 0x60) | (bm->status & BM_STATUS_DMAING) | (bm->status & ~val & 0x06);
> +}
> +
>   static uint64_t bmdma_addr_read(void *opaque, hwaddr addr,
>                                   unsigned width)
>   {
> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
> index 406a67fa0f..9eab615e35 100644
> --- a/hw/ide/piix.c
> +++ b/hw/ide/piix.c
> @@ -76,7 +76,7 @@ static void bmdma_write(void *opaque, hwaddr addr,
>           bmdma_cmd_writeb(bm, val);
>           break;
>       case 2:
> -        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
> +        bmdma_clear_status(bm, val);
>           break;
>       }
>   }
> diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c
> index 373c0dd1ee..1180ff55e7 100644
> --- a/hw/ide/sii3112.c
> +++ b/hw/ide/sii3112.c
> @@ -66,7 +66,7 @@ static void sii3112_bmdma_write(void *opaque, hwaddr addr,
>                                   uint64_t val, unsigned int size)
>   {
>       BMDMAState *bm = opaque;
> -    SiI3112PCIState *d = SII3112_PCI(bm->pci_dev);
> +    SiI3112PCIState *s = SII3112_PCI(bm->pci_dev);
>       int i = (bm == &bm->pci_dev->bmdma[0]) ? 0 : 1;
>   
>       trace_sii3112_bmdma_write(size, addr, val);
> @@ -75,10 +75,10 @@ static void sii3112_bmdma_write(void *opaque, hwaddr addr,
>           bmdma_cmd_writeb(bm, val);
>           break;
>       case 0x01:
> -        d->regs[i].swdata = val & 0x3f;
> +        s->regs[i].swdata = val & 0x3f;
>           break;
>       case 0x02:
> -        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 6);
> +        bmdma_clear_status(bm, val);
>           break;
>       default:
>           break;
> @@ -160,8 +160,7 @@ static void sii3112_reg_write(void *opaque, hwaddr addr,
>           d->regs[0].swdata = val & 0x3f;
>           break;
>       case 0x12:
> -        d->i.bmdma[0].status = (val & 0x60) | (d->i.bmdma[0].status & 1) |
> -                               (d->i.bmdma[0].status & ~val & 6);
> +        bmdma_clear_status(&d->i.bmdma[0], val);
>           break;
>       case 0x18:
>           bmdma_cmd_writeb(&d->i.bmdma[1], val);
> @@ -170,8 +169,7 @@ static void sii3112_reg_write(void *opaque, hwaddr addr,
>           d->regs[1].swdata = val & 0x3f;
>           break;
>       case 0x1a:
> -        d->i.bmdma[1].status = (val & 0x60) | (d->i.bmdma[1].status & 1) |
> -                               (d->i.bmdma[1].status & ~val & 6);
> +        bmdma_clear_status(&d->i.bmdma[1], val);
>           break;
>       case 0x100:
>           d->regs[0].scontrol = val & 0xfff;
> diff --git a/hw/ide/via.c b/hw/ide/via.c
> index 35dd97e49b..afb97f302a 100644
> --- a/hw/ide/via.c
> +++ b/hw/ide/via.c
> @@ -75,7 +75,7 @@ static void bmdma_write(void *opaque, hwaddr addr,
>           bmdma_cmd_writeb(bm, val);
>           break;
>       case 2:
> -        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
> +        bmdma_clear_status(bm, val);
>           break;
>       default:;
>       }
> diff --git a/hw/ide/trace-events b/hw/ide/trace-events
> index a479525e38..d219c64b61 100644
> --- a/hw/ide/trace-events
> +++ b/hw/ide/trace-events
> @@ -30,6 +30,7 @@ bmdma_write_cmd646(uint64_t addr, uint64_t val) "bmdma: writeb 0x%"PRIx64" : 0x%
>   # pci.c
>   bmdma_reset(void) ""
>   bmdma_cmd_writeb(uint32_t val) "val: 0x%08x"
> +bmdma_update_status(uint32_t val) "val: 0x%08x"
>   bmdma_addr_read(uint64_t data) "data: 0x%016"PRIx64
>   bmdma_addr_write(uint64_t data) "data: 0x%016"PRIx64

I see there has been further discussion related to naming of the function: FWIW my 
preference would be bmdma_status_writeb() since it matches the existing convention 
for bmdma_cmd_writeb() and is pretty clear that it handles byte-only BMDMA status 
register writes.

I don't mind either way regarding the extra trace-event, although generally if 
someone has added it then it means they have found it useful. Otherwise LGTM, but 
I'll wait to see what the final outcome is before adding an R-B.


ATB,

Mark.


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 10/13] hw/ide/piix: Reuse PCIIDEState::{cmd,data}_ops
  2023-04-26 11:37   ` Mark Cave-Ayland
@ 2023-04-26 18:18     ` Bernhard Beschow
  2023-04-26 20:14       ` Bernhard Beschow
  0 siblings, 1 reply; 77+ messages in thread
From: Bernhard Beschow @ 2023-04-26 18:18 UTC (permalink / raw)
  To: Mark Cave-Ayland, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc



Am 26. April 2023 11:37:48 UTC schrieb Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>:
>On 22/04/2023 16:07, Bernhard Beschow wrote:
>
>> Now that PCIIDEState::{cmd,data}_ops are initialized in the base class
>> constructor there is an opportunity for PIIX to reuse these attributes. This
>> resolves usage of ide_init_ioport() which would fall back internally to using
>> the isabus global due to NULL being passed as ISADevice by PIIX.
>> 
>> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
>> ---
>>   hw/ide/piix.c | 30 +++++++++++++-----------------
>>   1 file changed, 13 insertions(+), 17 deletions(-)
>> 
>> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
>> index a3a15dc7db..406a67fa0f 100644
>> --- a/hw/ide/piix.c
>> +++ b/hw/ide/piix.c
>> @@ -104,34 +104,32 @@ static void piix_ide_reset(DeviceState *dev)
>>       pci_set_byte(pci_conf + 0x20, 0x01);  /* BMIBA: 20-23h */
>>   }
>>   -static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, ISABus *isa_bus,
>> -                              Error **errp)
>> +static void pci_piix_init_bus(PCIIDEState *d, unsigned i, ISABus *isa_bus)
>>   {
>>       static const struct {
>>           int iobase;
>>           int iobase2;
>>           int isairq;
>>       } port_info[] = {
>> -        {0x1f0, 0x3f6, 14},
>> -        {0x170, 0x376, 15},
>> +        {0x1f0, 0x3f4, 14},
>> +        {0x170, 0x374, 15},
>>       };
>> -    int ret;
>> +    MemoryRegion *address_space_io = pci_address_space_io(PCI_DEVICE(d));
>>         ide_bus_init(&d->bus[i], sizeof(d->bus[i]), DEVICE(d), i, 2);
>> -    ret = ide_init_ioport(&d->bus[i], NULL, port_info[i].iobase,
>> -                          port_info[i].iobase2);
>> -    if (ret) {
>> -        error_setg_errno(errp, -ret, "Failed to realize %s port %u",
>> -                         object_get_typename(OBJECT(d)), i);
>> -        return false;
>> -    }
>> +    memory_region_add_subregion(address_space_io, port_info[i].iobase,
>> +                                &d->data_ops[i]);
>> +    /*
>> +     * PIIX forwards the last byte of cmd_ops to ISA. Model this using a low
>> +     * prio so competing memory regions take precedence.
>> +     */
>> +    memory_region_add_subregion_overlap(address_space_io, port_info[i].iobase2,
>> +                                        &d->cmd_ops[i], -1);
>
>Interesting. Is this behaviour documented somewhere and/or used in one of your test images at all? If I'd have seen this myself, I probably thought that the addresses were a typo...

I first  stumbled upon this and wondered why this code was working with VIA_IDE (through my pc-via branch). Then I found the correct offsets there which are confirmed in the piix datasheet, e.g.: "Secondary Control Block Offset: 0374h"

>
>>       ide_bus_init_output_irq(&d->bus[i],
>>                               isa_bus_get_irq(isa_bus, port_info[i].isairq));
>>         bmdma_init(&d->bus[i], &d->bmdma[i], d);
>>       ide_bus_register_restart_cb(&d->bus[i]);
>> -
>> -    return true;
>>   }
>>     static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
>> @@ -160,9 +158,7 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
>>       }
>>         for (unsigned i = 0; i < 2; i++) {
>> -        if (!pci_piix_init_bus(d, i, isa_bus, errp)) {
>> -            return;
>> -        }
>> +        pci_piix_init_bus(d, i, isa_bus);
>>       }
>>   }
>>   
>
>
>ATB,
>
>Mark.


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 09/13] hw/ide/piix: Disuse isa_get_irq()
  2023-04-26 11:33   ` Mark Cave-Ayland
@ 2023-04-26 18:25     ` Bernhard Beschow
  2023-04-27 12:31       ` Mark Cave-Ayland
  0 siblings, 1 reply; 77+ messages in thread
From: Bernhard Beschow @ 2023-04-26 18:25 UTC (permalink / raw)
  To: Mark Cave-Ayland, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc



Am 26. April 2023 11:33:40 UTC schrieb Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>:
>On 22/04/2023 16:07, Bernhard Beschow wrote:
>
>> isa_get_irq() asks for an ISADevice which piix-ide doesn't provide.
>> Passing a NULL pointer works but causes the isabus global to be used
>> then. By fishing out TYPE_ISA_BUS from the QOM tree it is possible to
>> achieve the same as using isa_get_irq().
>> 
>> This is an alternative solution to commit 9405d87be25d 'hw/ide: Fix
>> crash when plugging a piix3-ide device into the x-remote machine' which
>> allows for cleaning up the ISA API while keeping PIIX IDE functions
>> user-createable.
>> 
>> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
>> ---
>>   hw/ide/piix.c | 23 ++++++++++++++++++++---
>>   1 file changed, 20 insertions(+), 3 deletions(-)
>> 
>> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
>> index 6942b484f9..a3a15dc7db 100644
>> --- a/hw/ide/piix.c
>> +++ b/hw/ide/piix.c
>> @@ -104,7 +104,8 @@ static void piix_ide_reset(DeviceState *dev)
>>       pci_set_byte(pci_conf + 0x20, 0x01);  /* BMIBA: 20-23h */
>>   }
>>   -static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, Error **errp)
>> +static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, ISABus *isa_bus,
>> +                              Error **errp)
>>   {
>>       static const struct {
>>           int iobase;
>> @@ -124,7 +125,8 @@ static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, Error **errp)
>>                            object_get_typename(OBJECT(d)), i);
>>           return false;
>>       }
>> -    ide_bus_init_output_irq(&d->bus[i], isa_get_irq(NULL, port_info[i].isairq));
>> +    ide_bus_init_output_irq(&d->bus[i],
>> +                            isa_bus_get_irq(isa_bus, port_info[i].isairq));
>
>I don't think is the right solution here, since ultimately we want to move the IRQ routing out of the device itself and into the PCI-ISA bridge. I'd go for the same solution as you've done for VIA IDE in patch 2, i.e. update the PIIX interrupt handler to set the legacy_irqs in PCIIDEState, and then wire them up to the ISA IRQs 14 and 15 similar to as Phil as done in his patches:

The problem is user-creatable PIIX-IDE. IMO we should stick to our deprecation process before going this step because this will break it.

>
>https://patchew.org/QEMU/20230302224058.43315-1-philmd@linaro.org/20230302224058.43315-4-philmd@linaro.org/
>
>https://patchew.org/QEMU/20230302224058.43315-1-philmd@linaro.org/20230302224058.43315-5-philmd@linaro.org/
>
>This also reminds me, given that the first patch above is doing wiring in pc_init1() then we are still missing part of your tidy-up series :/
>
>>       bmdma_init(&d->bus[i], &d->bmdma[i], d);
>>       ide_bus_register_restart_cb(&d->bus[i]);
>> @@ -136,14 +138,29 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
>>   {
>>       PCIIDEState *d = PCI_IDE(dev);
>>       uint8_t *pci_conf = dev->config;
>> +    ISABus *isa_bus;
>> +    bool ambiguous;
>>         pci_conf[PCI_CLASS_PROG] = 0x80; // legacy ATA mode
>>         bmdma_init_ops(d, &piix_bmdma_ops);
>>       pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_ops);
>>   +    isa_bus = ISA_BUS(object_resolve_path_type("", TYPE_ISA_BUS, &ambiguous));
>> +    if (ambiguous) {
>> +        error_setg(errp,
>> +                   "More than one ISA bus found while %s supports only one",
>> +                   object_get_typename(OBJECT(d)));
>> +        return;
>> +    }
>> +    if (!isa_bus) {
>> +        error_setg(errp, "No ISA bus found while %s requires one",
>> +                   object_get_typename(OBJECT(d)));
>> +        return;
>> +    }
>
>Again I think this should go away with using PCIIDEState's legacy_irqs, since you simply let the board wire them up to the ISABus (or not) as required.

Same here: This breaks user-creatable PIIX-IDE.

>
>>       for (unsigned i = 0; i < 2; i++) {
>> -        if (!pci_piix_init_bus(d, i, errp)) {
>> +        if (!pci_piix_init_bus(d, i, isa_bus, errp)) {
>>               return;
>>           }
>>       }
>
>
>ATB,
>
>Mark.


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 08/13] hw/ide: Rename PCIIDEState::*_bar attributes
  2023-04-26 11:21   ` Mark Cave-Ayland
@ 2023-04-26 18:29     ` Bernhard Beschow
  2023-04-27 11:07       ` Mark Cave-Ayland
  0 siblings, 1 reply; 77+ messages in thread
From: Bernhard Beschow @ 2023-04-26 18:29 UTC (permalink / raw)
  To: Mark Cave-Ayland, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc



Am 26. April 2023 11:21:28 UTC schrieb Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>:
>On 22/04/2023 16:07, Bernhard Beschow wrote:
>
>> The attributes represent memory regions containing operations which are mapped
>> by the device models into PCI BARs. Reflect this by changing the suffic into
>> "_ops".
>> 
>> Note that in a few commits piix will also use the {cmd,data}_ops but won't map
>> them into BARs. This further suggests that the "_bar" suffix doesn't match
>> very well.
>> 
>> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
>> ---
>>   include/hw/ide/pci.h |  6 +++---
>>   hw/ide/cmd646.c      | 10 +++++-----
>>   hw/ide/pci.c         | 18 +++++++++---------
>>   hw/ide/piix.c        |  2 +-
>>   hw/ide/via.c         | 10 +++++-----
>>   5 files changed, 23 insertions(+), 23 deletions(-)
>> 
>> diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
>> index 597c77c7ad..5025df5b82 100644
>> --- a/include/hw/ide/pci.h
>> +++ b/include/hw/ide/pci.h
>> @@ -51,9 +51,9 @@ struct PCIIDEState {
>>       BMDMAState bmdma[2];
>>       qemu_irq isa_irq[2];
>>       uint32_t secondary; /* used only for cmd646 */
>> -    MemoryRegion bmdma_bar;
>> -    MemoryRegion cmd_bar[2];
>> -    MemoryRegion data_bar[2];
>> +    MemoryRegion bmdma_ops;
>> +    MemoryRegion cmd_ops[2];
>> +    MemoryRegion data_ops[2];
>>   };
>>     void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d);
>> diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
>> index 85716aaf17..b9d005a357 100644
>> --- a/hw/ide/cmd646.c
>> +++ b/hw/ide/cmd646.c
>> @@ -251,13 +251,13 @@ static void pci_cmd646_ide_realize(PCIDevice *dev, Error **errp)
>>       dev->wmask[MRDMODE] = 0x0;
>>       dev->w1cmask[MRDMODE] = MRDMODE_INTR_CH0 | MRDMODE_INTR_CH1;
>>   -    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->data_bar[0]);
>> -    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[0]);
>> -    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &d->data_bar[1]);
>> -    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[1]);
>> +    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->data_ops[0]);
>> +    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_ops[0]);
>> +    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &d->data_ops[1]);
>> +    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_ops[1]);
>>         bmdma_init_ops(d, &cmd646_bmdma_ops);
>> -    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
>> +    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_ops);
>>         /* TODO: RST# value should be 0 */
>>       pci_conf[PCI_INTERRUPT_PIN] = 0x01; // interrupt on pin 1
>> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
>> index a9194313bd..b2fcc00a64 100644
>> --- a/hw/ide/pci.c
>> +++ b/hw/ide/pci.c
>> @@ -527,15 +527,15 @@ void bmdma_init_ops(PCIIDEState *d, const MemoryRegionOps *bmdma_ops)
>>   {
>>       size_t i;
>>   -    memory_region_init(&d->bmdma_bar, OBJECT(d), "bmdma-container", 16);
>> +    memory_region_init(&d->bmdma_ops, OBJECT(d), "bmdma-container", 16);
>>       for (i = 0; i < ARRAY_SIZE(d->bmdma); i++) {
>>           BMDMAState *bm = &d->bmdma[i];
>>             memory_region_init_io(&bm->extra_io, OBJECT(d), bmdma_ops, bm, "bmdma-ops", 4);
>> -        memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io);
>> +        memory_region_add_subregion(&d->bmdma_ops, i * 8, &bm->extra_io);
>>           memory_region_init_io(&bm->addr_ioport, OBJECT(d), &bmdma_addr_ioport_ops, bm,
>>                                 "bmdma-ioport-ops", 4);
>> -        memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport);
>> +        memory_region_add_subregion(&d->bmdma_ops, i * 8 + 4, &bm->addr_ioport);
>>       }
>>   }
>>   @@ -543,14 +543,14 @@ static void pci_ide_init(Object *obj)
>>   {
>>       PCIIDEState *d = PCI_IDE(obj);
>>   -    memory_region_init_io(&d->data_bar[0], OBJECT(d), &pci_ide_data_le_ops,
>> +    memory_region_init_io(&d->data_ops[0], OBJECT(d), &pci_ide_data_le_ops,
>>                             &d->bus[0], "pci-ide0-data-ops", 8);
>> -    memory_region_init_io(&d->cmd_bar[0], OBJECT(d), &pci_ide_cmd_le_ops,
>> +    memory_region_init_io(&d->cmd_ops[0], OBJECT(d), &pci_ide_cmd_le_ops,
>>                             &d->bus[0], "pci-ide0-cmd-ops", 4);
>>   -    memory_region_init_io(&d->data_bar[1], OBJECT(d), &pci_ide_data_le_ops,
>> +    memory_region_init_io(&d->data_ops[1], OBJECT(d), &pci_ide_data_le_ops,
>>                             &d->bus[1], "pci-ide1-data-ops", 8);
>> -    memory_region_init_io(&d->cmd_bar[1], OBJECT(d), &pci_ide_cmd_le_ops,
>> +    memory_region_init_io(&d->cmd_ops[1], OBJECT(d), &pci_ide_cmd_le_ops,
>>                             &d->bus[1], "pci-ide1-cmd-ops", 4);
>>         qdev_init_gpio_out(DEVICE(d), d->isa_irq, ARRAY_SIZE(d->isa_irq));
>> @@ -562,8 +562,8 @@ static void pci_ide_exitfn(PCIDevice *dev)
>>       unsigned i;
>>         for (i = 0; i < ARRAY_SIZE(d->bmdma); ++i) {
>> -        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io);
>> -        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport);
>> +        memory_region_del_subregion(&d->bmdma_ops, &d->bmdma[i].extra_io);
>> +        memory_region_del_subregion(&d->bmdma_ops, &d->bmdma[i].addr_ioport);
>>       }
>>   }
>>   diff --git a/hw/ide/piix.c b/hw/ide/piix.c
>> index 5611473d37..6942b484f9 100644
>> --- a/hw/ide/piix.c
>> +++ b/hw/ide/piix.c
>> @@ -140,7 +140,7 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
>>       pci_conf[PCI_CLASS_PROG] = 0x80; // legacy ATA mode
>>         bmdma_init_ops(d, &piix_bmdma_ops);
>> -    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
>> +    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_ops);
>>         for (unsigned i = 0; i < 2; i++) {
>>           if (!pci_piix_init_bus(d, i, errp)) {
>> diff --git a/hw/ide/via.c b/hw/ide/via.c
>> index 704a8024cb..35dd97e49b 100644
>> --- a/hw/ide/via.c
>> +++ b/hw/ide/via.c
>> @@ -154,13 +154,13 @@ static void via_ide_realize(PCIDevice *dev, Error **errp)
>>       dev->wmask[PCI_INTERRUPT_LINE] = 0;
>>       dev->wmask[PCI_CLASS_PROG] = 5;
>>   -    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->data_bar[0]);
>> -    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[0]);
>> -    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &d->data_bar[1]);
>> -    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[1]);
>> +    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->data_ops[0]);
>> +    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_ops[0]);
>> +    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &d->data_ops[1]);
>> +    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_ops[1]);
>>         bmdma_init_ops(d, &via_bmdma_ops);
>> -    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
>> +    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_ops);
>>         qdev_init_gpio_in(ds, via_ide_set_irq, ARRAY_SIZE(d->bus));
>>       for (i = 0; i < ARRAY_SIZE(d->bus); i++) {
>
>I don't really feel strongly either way on this one, so I'm happy to go along with the silent majority here - I see that Zoltan has expressed a preference for it to stay as-is.

Doesn't it look off in PIIX-IDE where we don't map these regions via BARs? Don't these memory regions only become "BARs" by mapping them as such?

>
>
>ATB,
>
>Mark.


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 05/13] hw/ide: Extract pci_ide_class_init()
  2023-04-26 11:04   ` Mark Cave-Ayland
@ 2023-04-26 18:32     ` Bernhard Beschow
  0 siblings, 0 replies; 77+ messages in thread
From: Bernhard Beschow @ 2023-04-26 18:32 UTC (permalink / raw)
  To: Mark Cave-Ayland, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc



Am 26. April 2023 11:04:30 UTC schrieb Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>:
>On 22/04/2023 16:07, Bernhard Beschow wrote:
>
>> Resolves redundant code in every PCI IDE device model.
>
>I think this needs to mention that it's moving the PCIDeviceClass::exit() function from all of the PCI IDE controller implementations to a common implementation in the parent PCI_IDE type.

I'll completely rework this patch.

>
>> ---
>>   include/hw/ide/pci.h |  1 -
>>   hw/ide/cmd646.c      | 15 ---------------
>>   hw/ide/pci.c         | 25 ++++++++++++++++++++++++-
>>   hw/ide/piix.c        | 19 -------------------
>>   hw/ide/sii3112.c     |  3 ++-
>>   hw/ide/via.c         | 15 ---------------
>>   6 files changed, 26 insertions(+), 52 deletions(-)
>> 
>> diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
>> index 74c127e32f..7bc4e53d02 100644
>> --- a/include/hw/ide/pci.h
>> +++ b/include/hw/ide/pci.h
>> @@ -61,7 +61,6 @@ void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val);
>>   extern MemoryRegionOps bmdma_addr_ioport_ops;
>>   void pci_ide_create_devs(PCIDevice *dev);
>>   -extern const VMStateDescription vmstate_ide_pci;
>>   extern const MemoryRegionOps pci_ide_cmd_le_ops;
>>   extern const MemoryRegionOps pci_ide_data_le_ops;
>>   #endif
>> diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
>> index a094a6e12a..9aabf80e52 100644
>> --- a/hw/ide/cmd646.c
>> +++ b/hw/ide/cmd646.c
>> @@ -301,17 +301,6 @@ static void pci_cmd646_ide_realize(PCIDevice *dev, Error **errp)
>>       }
>>   }
>>   -static void pci_cmd646_ide_exitfn(PCIDevice *dev)
>> -{
>> -    PCIIDEState *d = PCI_IDE(dev);
>> -    unsigned i;
>> -
>> -    for (i = 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_ioport);
>> -    }
>> -}
>> -
>>   static Property cmd646_ide_properties[] = {
>>       DEFINE_PROP_UINT32("secondary", PCIIDEState, secondary, 0),
>>       DEFINE_PROP_END_OF_LIST(),
>> @@ -323,17 +312,13 @@ static void cmd646_ide_class_init(ObjectClass *klass, void *data)
>>       PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
>>         dc->reset = cmd646_reset;
>> -    dc->vmsd = &vmstate_ide_pci;
>>       k->realize = pci_cmd646_ide_realize;
>> -    k->exit = pci_cmd646_ide_exitfn;
>>       k->vendor_id = PCI_VENDOR_ID_CMD;
>>       k->device_id = PCI_DEVICE_ID_CMD_646;
>>       k->revision = 0x07;
>> -    k->class_id = PCI_CLASS_STORAGE_IDE;
>>       k->config_read = cmd646_pci_config_read;
>>       k->config_write = cmd646_pci_config_write;
>>       device_class_set_props(dc, cmd646_ide_properties);
>> -    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
>>   }
>>     static const TypeInfo cmd646_ide_info = {
>> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
>> index 67e0998ff0..8bea92e394 100644
>> --- a/hw/ide/pci.c
>> +++ b/hw/ide/pci.c
>> @@ -467,7 +467,7 @@ static int ide_pci_post_load(void *opaque, int version_id)
>>       return 0;
>>   }
>>   -const VMStateDescription vmstate_ide_pci = {
>> +static const VMStateDescription vmstate_ide_pci = {
>>       .name = "ide",
>>       .version_id = 3,
>>       .minimum_version_id = 0,
>> @@ -530,11 +530,34 @@ static void pci_ide_init(Object *obj)
>>       qdev_init_gpio_out(DEVICE(d), d->isa_irq, ARRAY_SIZE(d->isa_irq));
>>   }
>>   +static void pci_ide_exitfn(PCIDevice *dev)
>> +{
>> +    PCIIDEState *d = PCI_IDE(dev);
>> +    unsigned i;
>> +
>> +    for (i = 0; i < ARRAY_SIZE(d->bmdma); ++i) {
>> +        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io);
>> +        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport);
>> +    }
>> +}
>> +
>> +static void pci_ide_class_init(ObjectClass *klass, void *data)
>> +{
>> +    DeviceClass *dc = DEVICE_CLASS(klass);
>> +    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
>> +
>> +    dc->vmsd = &vmstate_ide_pci;
>> +    k->exit = pci_ide_exitfn;
>> +    k->class_id = PCI_CLASS_STORAGE_IDE;
>> +    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
>> +}
>> +
>>   static const TypeInfo pci_ide_type_info = {
>>       .name = TYPE_PCI_IDE,
>>       .parent = TYPE_PCI_DEVICE,
>>       .instance_size = sizeof(PCIIDEState),
>>       .instance_init = pci_ide_init,
>> +    .class_init = pci_ide_class_init,
>>       .abstract = true,
>>       .interfaces = (InterfaceInfo[]) {
>>           { INTERFACE_CONVENTIONAL_PCI_DEVICE },
>> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
>> index a32f7ccece..4e6ca99123 100644
>> --- a/hw/ide/piix.c
>> +++ b/hw/ide/piix.c
>> @@ -159,8 +159,6 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
>>       bmdma_setup_bar(d);
>>       pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
>>   -    vmstate_register(VMSTATE_IF(dev), 0, &vmstate_ide_pci, d);
>> -
>
>Presumably this still survives migration between a pre-series and post-series QEMU using the PIIX IDE controller?
>
>>       for (unsigned i = 0; i < 2; i++) {
>>           if (!pci_piix_init_bus(d, i, errp)) {
>>               return;
>> @@ -168,17 +166,6 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
>>       }
>>   }
>>   -static void pci_piix_ide_exitfn(PCIDevice *dev)
>> -{
>> -    PCIIDEState *d = PCI_IDE(dev);
>> -    unsigned i;
>> -
>> -    for (i = 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_ioport);
>> -    }
>> -}
>> -
>>   /* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */
>>   static void piix3_ide_class_init(ObjectClass *klass, void *data)
>>   {
>> @@ -187,11 +174,8 @@ static void piix3_ide_class_init(ObjectClass *klass, void *data)
>>         dc->reset = piix_ide_reset;
>>       k->realize = pci_piix_ide_realize;
>> -    k->exit = pci_piix_ide_exitfn;
>>       k->vendor_id = PCI_VENDOR_ID_INTEL;
>>       k->device_id = PCI_DEVICE_ID_INTEL_82371SB_1;
>> -    k->class_id = PCI_CLASS_STORAGE_IDE;
>> -    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
>>       dc->hotpluggable = false;
>>   }
>>   @@ -209,11 +193,8 @@ static void piix4_ide_class_init(ObjectClass *klass, void *data)
>>         dc->reset = piix_ide_reset;
>>       k->realize = pci_piix_ide_realize;
>> -    k->exit = pci_piix_ide_exitfn;
>>       k->vendor_id = PCI_VENDOR_ID_INTEL;
>>       k->device_id = PCI_DEVICE_ID_INTEL_82371AB;
>> -    k->class_id = PCI_CLASS_STORAGE_IDE;
>> -    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
>>       dc->hotpluggable = false;
>>   }
>>   diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c
>> index 5dd3d03c29..0af897a9ef 100644
>> --- a/hw/ide/sii3112.c
>> +++ b/hw/ide/sii3112.c
>> @@ -301,9 +301,10 @@ static void sii3112_pci_class_init(ObjectClass *klass, void *data)
>>       pd->class_id = PCI_CLASS_STORAGE_RAID;
>>       pd->revision = 1;
>>       pd->realize = sii3112_pci_realize;
>> +    pd->exit = NULL;
>>       dc->reset = sii3112_reset;
>> +    dc->vmsd = NULL;
>>       dc->desc = "SiI3112A SATA controller";
>> -    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
>>   }
>
>No need to set explicit NULLs here: class/object structures are all zeroed before init (unless you're deliberately trying to prevent the common PCIDeviceClass::exit() function from being called here temporarily?)
>
>>   static const TypeInfo sii3112_pci_info = {
>> diff --git a/hw/ide/via.c b/hw/ide/via.c
>> index 91253fa4ef..287143a005 100644
>> --- a/hw/ide/via.c
>> +++ b/hw/ide/via.c
>> @@ -200,34 +200,19 @@ static void via_ide_realize(PCIDevice *dev, Error **errp)
>>       }
>>   }
>>   -static void via_ide_exitfn(PCIDevice *dev)
>> -{
>> -    PCIIDEState *d = PCI_IDE(dev);
>> -    unsigned i;
>> -
>> -    for (i = 0; i < ARRAY_SIZE(d->bmdma); ++i) {
>> -        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io);
>> -        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport);
>> -    }
>> -}
>> -
>>   static void via_ide_class_init(ObjectClass *klass, void *data)
>>   {
>>       DeviceClass *dc = DEVICE_CLASS(klass);
>>       PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
>>         dc->reset = via_ide_reset;
>> -    dc->vmsd = &vmstate_ide_pci;
>>       /* Reason: only works as function of VIA southbridge */
>>       dc->user_creatable = false;
>>         k->realize = via_ide_realize;
>> -    k->exit = via_ide_exitfn;
>>       k->vendor_id = PCI_VENDOR_ID_VIA;
>>       k->device_id = PCI_DEVICE_ID_VIA_IDE;
>>       k->revision = 0x06;
>> -    k->class_id = PCI_CLASS_STORAGE_IDE;
>> -    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
>>   }
>>     static const TypeInfo via_ide_info = {
>
>A couple of queries, but generally looks good to me.
>
>
>ATB,
>
>Mark.


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 01/13] hw/ide/pci: Expose legacy interrupts as GPIOs
  2023-04-26 10:41   ` Mark Cave-Ayland
@ 2023-04-26 19:26     ` Bernhard Beschow
  0 siblings, 0 replies; 77+ messages in thread
From: Bernhard Beschow @ 2023-04-26 19:26 UTC (permalink / raw)
  To: Mark Cave-Ayland, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc



Am 26. April 2023 10:41:30 UTC schrieb Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>:
>On 22/04/2023 16:07, Bernhard Beschow wrote:
>
>> Exposing the legacy IDE interrupts as GPIOs allows them to be connected in the
>> parent device through qdev_connect_gpio_out(), i.e. without accessing private
>> data of TYPE_PCI_IDE.
>> 
>> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
>> ---
>>   hw/ide/pci.c | 8 ++++++++
>>   1 file changed, 8 insertions(+)
>> 
>> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
>> index fc9224bbc9..942e216b9b 100644
>> --- a/hw/ide/pci.c
>> +++ b/hw/ide/pci.c
>> @@ -522,10 +522,18 @@ void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d)
>>       bm->pci_dev = d;
>>   }
>>   +static void pci_ide_init(Object *obj)
>> +{
>> +    PCIIDEState *d = PCI_IDE(obj);
>> +
>> +    qdev_init_gpio_out(DEVICE(d), d->isa_irq, ARRAY_SIZE(d->isa_irq));
>
>Just one minor nit: can we make this qdev_init_gpio_out_named() and call it "isa-irq" to match? This is for 2 reasons: firstly these are PCI devices and so an unnamed IRQ/gpio could be considered to belong to PCI, and secondly it gives the gpio the same name as the struct field.

Yes, makes sense.

>
>From my previous email I think this should supercede Phil's patch at https://patchew.org/QEMU/20230302224058.43315-1-philmd@linaro.org/20230302224058.43315-2-philmd@linaro.org/.
>
>> +}
>> +
>>   static const TypeInfo pci_ide_type_info = {
>>       .name = TYPE_PCI_IDE,
>>       .parent = TYPE_PCI_DEVICE,
>>       .instance_size = sizeof(PCIIDEState),
>> +    .instance_init = pci_ide_init,
>>       .abstract = true,
>>       .interfaces = (InterfaceInfo[]) {
>>           { INTERFACE_CONVENTIONAL_PCI_DEVICE },
>
>Otherwise:
>
>Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
>
>
>ATB,
>
>Mark.


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 10/13] hw/ide/piix: Reuse PCIIDEState::{cmd,data}_ops
  2023-04-26 18:18     ` Bernhard Beschow
@ 2023-04-26 20:14       ` Bernhard Beschow
  2023-04-27 10:52         ` Mark Cave-Ayland
  0 siblings, 1 reply; 77+ messages in thread
From: Bernhard Beschow @ 2023-04-26 20:14 UTC (permalink / raw)
  To: Mark Cave-Ayland, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc



Am 26. April 2023 18:18:35 UTC schrieb Bernhard Beschow <shentey@gmail.com>:
>
>
>Am 26. April 2023 11:37:48 UTC schrieb Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>:
>>On 22/04/2023 16:07, Bernhard Beschow wrote:
>>
>>> Now that PCIIDEState::{cmd,data}_ops are initialized in the base class
>>> constructor there is an opportunity for PIIX to reuse these attributes. This
>>> resolves usage of ide_init_ioport() which would fall back internally to using
>>> the isabus global due to NULL being passed as ISADevice by PIIX.
>>> 
>>> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
>>> ---
>>>   hw/ide/piix.c | 30 +++++++++++++-----------------
>>>   1 file changed, 13 insertions(+), 17 deletions(-)
>>> 
>>> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
>>> index a3a15dc7db..406a67fa0f 100644
>>> --- a/hw/ide/piix.c
>>> +++ b/hw/ide/piix.c
>>> @@ -104,34 +104,32 @@ static void piix_ide_reset(DeviceState *dev)
>>>       pci_set_byte(pci_conf + 0x20, 0x01);  /* BMIBA: 20-23h */
>>>   }
>>>   -static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, ISABus *isa_bus,
>>> -                              Error **errp)
>>> +static void pci_piix_init_bus(PCIIDEState *d, unsigned i, ISABus *isa_bus)
>>>   {
>>>       static const struct {
>>>           int iobase;
>>>           int iobase2;
>>>           int isairq;
>>>       } port_info[] = {
>>> -        {0x1f0, 0x3f6, 14},
>>> -        {0x170, 0x376, 15},
>>> +        {0x1f0, 0x3f4, 14},
>>> +        {0x170, 0x374, 15},
>>>       };
>>> -    int ret;
>>> +    MemoryRegion *address_space_io = pci_address_space_io(PCI_DEVICE(d));
>>>         ide_bus_init(&d->bus[i], sizeof(d->bus[i]), DEVICE(d), i, 2);
>>> -    ret = ide_init_ioport(&d->bus[i], NULL, port_info[i].iobase,
>>> -                          port_info[i].iobase2);
>>> -    if (ret) {
>>> -        error_setg_errno(errp, -ret, "Failed to realize %s port %u",
>>> -                         object_get_typename(OBJECT(d)), i);
>>> -        return false;
>>> -    }
>>> +    memory_region_add_subregion(address_space_io, port_info[i].iobase,
>>> +                                &d->data_ops[i]);
>>> +    /*
>>> +     * PIIX forwards the last byte of cmd_ops to ISA. Model this using a low
>>> +     * prio so competing memory regions take precedence.
>>> +     */
>>> +    memory_region_add_subregion_overlap(address_space_io, port_info[i].iobase2,
>>> +                                        &d->cmd_ops[i], -1);
>>
>>Interesting. Is this behaviour documented somewhere and/or used in one of your test images at all? If I'd have seen this myself, I probably thought that the addresses were a typo...
>
>I first  stumbled upon this and wondered why this code was working with VIA_IDE (through my pc-via branch). Then I found the correct offsets there which are confirmed in the piix datasheet, e.g.: "Secondary Control Block Offset: 0374h"

In case you were wondering about the forwarding of the last byte the datasheet says: "Accesses to byte 3 of the Control Block are forwarded to ISA where the floppy disk controller responds."

>
>>
>>>       ide_bus_init_output_irq(&d->bus[i],
>>>                               isa_bus_get_irq(isa_bus, port_info[i].isairq));
>>>         bmdma_init(&d->bus[i], &d->bmdma[i], d);
>>>       ide_bus_register_restart_cb(&d->bus[i]);
>>> -
>>> -    return true;
>>>   }
>>>     static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
>>> @@ -160,9 +158,7 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
>>>       }
>>>         for (unsigned i = 0; i < 2; i++) {
>>> -        if (!pci_piix_init_bus(d, i, isa_bus, errp)) {
>>> -            return;
>>> -        }
>>> +        pci_piix_init_bus(d, i, isa_bus);
>>>       }
>>>   }
>>>   
>>
>>
>>ATB,
>>
>>Mark.


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 11/13] hw/ide/sii3112: Reuse PCIIDEState::{cmd,data}_ops
  2023-04-26 11:41   ` Mark Cave-Ayland
@ 2023-04-26 20:24     ` Bernhard Beschow
  2023-04-26 23:24       ` BALATON Zoltan
  0 siblings, 1 reply; 77+ messages in thread
From: Bernhard Beschow @ 2023-04-26 20:24 UTC (permalink / raw)
  To: Mark Cave-Ayland, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc

Am 26. April 2023 11:41:54 UTC schrieb Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>:
>On 22/04/2023 16:07, Bernhard Beschow wrote:
>
>> Allows to unexport pci_ide_{cmd,data}_le_ops and models TYPE_SII3112_PCI as a
>> standard-compliant PCI IDE device.
>> 
>> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
>> ---
>>   include/hw/ide/pci.h |  2 --
>>   hw/ide/pci.c         |  4 ++--
>>   hw/ide/sii3112.c     | 50 ++++++++++++++++----------------------------
>>   3 files changed, 20 insertions(+), 36 deletions(-)
>> 
>> diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
>> index 5025df5b82..dbb4b13161 100644
>> --- a/include/hw/ide/pci.h
>> +++ b/include/hw/ide/pci.h
>> @@ -62,6 +62,4 @@ void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val);
>>   extern MemoryRegionOps bmdma_addr_ioport_ops;
>>   void pci_ide_create_devs(PCIDevice *dev);
>>   -extern const MemoryRegionOps pci_ide_cmd_le_ops;
>> -extern const MemoryRegionOps pci_ide_data_le_ops;
>>   #endif
>> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
>> index b2fcc00a64..97ccc75aa6 100644
>> --- a/hw/ide/pci.c
>> +++ b/hw/ide/pci.c
>> @@ -60,7 +60,7 @@ static void pci_ide_ctrl_write(void *opaque, hwaddr addr,
>>       ide_ctrl_write(bus, addr + 2, data);
>>   }
>>   -const MemoryRegionOps pci_ide_cmd_le_ops = {
>> +static const MemoryRegionOps pci_ide_cmd_le_ops = {
>>       .read = pci_ide_status_read,
>>       .write = pci_ide_ctrl_write,
>>       .endianness = DEVICE_LITTLE_ENDIAN,
>> @@ -98,7 +98,7 @@ static void pci_ide_data_write(void *opaque, hwaddr addr,
>>       }
>>   }
>>   -const MemoryRegionOps pci_ide_data_le_ops = {
>> +static const MemoryRegionOps pci_ide_data_le_ops = {
>>       .read = pci_ide_data_read,
>>       .write = pci_ide_data_write,
>>       .endianness = DEVICE_LITTLE_ENDIAN,
>> diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c
>> index 0af897a9ef..9cf920369f 100644
>> --- a/hw/ide/sii3112.c
>> +++ b/hw/ide/sii3112.c
>> @@ -88,21 +88,9 @@ static uint64_t sii3112_reg_read(void *opaque, hwaddr addr,
>>           val |= (d->regs[1].confstat & (1UL << 11) ? (1 << 4) : 0);
>>           val |= (uint32_t)d->i.bmdma[1].status << 16;
>>           break;
>> -    case 0x80 ... 0x87:
>> -        val = pci_ide_data_le_ops.read(&d->i.bus[0], addr - 0x80, size);
>> -        break;
>> -    case 0x8a:
>> -        val = pci_ide_cmd_le_ops.read(&d->i.bus[0], 2, size);
>> -        break;
>>       case 0xa0:
>>           val = d->regs[0].confstat;
>>           break;
>> -    case 0xc0 ... 0xc7:
>> -        val = pci_ide_data_le_ops.read(&d->i.bus[1], addr - 0xc0, size);
>> -        break;
>> -    case 0xca:
>> -        val = pci_ide_cmd_le_ops.read(&d->i.bus[1], 2, size);
>> -        break;
>>       case 0xe0:
>>           val = d->regs[1].confstat;
>>           break;
>> @@ -171,18 +159,6 @@ static void sii3112_reg_write(void *opaque, hwaddr addr,
>>       case 0x0c ... 0x0f:
>>           bmdma_addr_ioport_ops.write(&d->i.bmdma[1], addr - 12, val, size);
>>           break;
>> -    case 0x80 ... 0x87:
>> -        pci_ide_data_le_ops.write(&d->i.bus[0], addr - 0x80, val, size);
>> -        break;
>> -    case 0x8a:
>> -        pci_ide_cmd_le_ops.write(&d->i.bus[0], 2, val, size);
>> -        break;
>> -    case 0xc0 ... 0xc7:
>> -        pci_ide_data_le_ops.write(&d->i.bus[1], addr - 0xc0, val, size);
>> -        break;
>> -    case 0xca:
>> -        pci_ide_cmd_le_ops.write(&d->i.bus[1], 2, val, size);
>> -        break;
>>       case 0x100:
>>           d->regs[0].scontrol = val & 0xfff;
>>           if (val & 1) {
>> @@ -259,6 +235,11 @@ static void sii3112_pci_realize(PCIDevice *dev, Error **errp)
>>       pci_config_set_interrupt_pin(dev->config, 1);
>>       pci_set_byte(dev->config + PCI_CACHE_LINE_SIZE, 8);
>>   +    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->data_ops[0]);
>> +    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->cmd_ops[0]);
>> +    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &s->data_ops[1]);
>> +    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &s->cmd_ops[1]);
>> +
>>       /* BAR5 is in PCI memory space */
>>       memory_region_init_io(&d->mmio, OBJECT(d), &sii3112_reg_ops, d,
>>                            "sii3112.bar5", 0x200);
>> @@ -266,17 +247,22 @@ static void sii3112_pci_realize(PCIDevice *dev, Error **errp)
>>         /* BAR0-BAR4 are PCI I/O space aliases into BAR5 */
>>       mr = g_new(MemoryRegion, 1);
>> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar0", &d->mmio, 0x80, 8);
>> -    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, mr);
>> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar0", &s->data_ops[0], 0,
>> +                             memory_region_size(&s->data_ops[0]));
>> +    memory_region_add_subregion_overlap(&d->mmio, 0x80, mr, 1);
>>       mr = g_new(MemoryRegion, 1);
>> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar1", &d->mmio, 0x88, 4);
>> -    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, mr);
>> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar1", &s->cmd_ops[0], 0,
>> +                             memory_region_size(&s->cmd_ops[0]));
>> +    memory_region_add_subregion_overlap(&d->mmio, 0x88, mr, 1);
>>       mr = g_new(MemoryRegion, 1);
>> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar2", &d->mmio, 0xc0, 8);
>> -    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, mr);
>> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar2", &s->data_ops[1], 0,
>> +                             memory_region_size(&s->data_ops[1]));
>> +    memory_region_add_subregion_overlap(&d->mmio, 0xc0, mr, 1);
>>       mr = g_new(MemoryRegion, 1);
>> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar3", &d->mmio, 0xc8, 4);
>> -    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, mr);
>> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar3", &s->cmd_ops[1], 0,
>> +                             memory_region_size(&s->cmd_ops[1]));
>> +    memory_region_add_subregion_overlap(&d->mmio, 0xc8, mr, 1);
>> +
>>       mr = g_new(MemoryRegion, 1);
>>       memory_region_init_alias(mr, OBJECT(d), "sii3112.bar4", &d->mmio, 0, 16);
>>       pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, mr);
>
>So if I read this right, this is now switching the aliases over on BAR5 to allow re-use of the common IDE/BMDMA BARs in PCIIDEState? If that's correct then I think the commit message needs a bit more detail, otherwise:

That's correct. Besides improving the commit message I'll additonally split this patch into two to show what's going on.

Furthermore, I'd init the memory regions in sii3112's init method rather than in realize(). This will be more consistent with the other PCI IDE device models and with the other memory regions.

Best regards,
Bernhard

>
>Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
>
>
>ATB,
>
>Mark.


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 12/13] hw/ide/sii3112: Reuse PCIIDEState::bmdma_ops
  2023-04-26 11:44   ` Mark Cave-Ayland
@ 2023-04-26 20:26     ` Bernhard Beschow
  0 siblings, 0 replies; 77+ messages in thread
From: Bernhard Beschow @ 2023-04-26 20:26 UTC (permalink / raw)
  To: Mark Cave-Ayland, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc



Am 26. April 2023 11:44:29 UTC schrieb Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>:
>On 22/04/2023 16:07, Bernhard Beschow wrote:
>
>> Allows to unexport bmdma_addr_ioport_ops and models TYPE_SII3112_PCI as a
>> standard-compliant PCI IDE device.
>
>Nice! I think it's worth adding a brief mention that you've added BMDMA trace-events, but otherwise looks sensible to me.

Will do. I'd also split this patch into two.

Best regards,
Bernhard

>
>> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
>> ---
>>   include/hw/ide/pci.h |  1 -
>>   hw/ide/pci.c         |  2 +-
>>   hw/ide/sii3112.c     | 94 ++++++++++++++++++++++++++------------------
>>   hw/ide/trace-events  |  6 ++-
>>   4 files changed, 60 insertions(+), 43 deletions(-)
>> 
>> diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
>> index dbb4b13161..81e0370202 100644
>> --- a/include/hw/ide/pci.h
>> +++ b/include/hw/ide/pci.h
>> @@ -59,7 +59,6 @@ struct PCIIDEState {
>>   void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d);
>>   void bmdma_init_ops(PCIIDEState *d, const MemoryRegionOps *bmdma_ops);
>>   void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val);
>> -extern MemoryRegionOps bmdma_addr_ioport_ops;
>>   void pci_ide_create_devs(PCIDevice *dev);
>>     #endif
>> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
>> index 97ccc75aa6..3539b162b7 100644
>> --- a/hw/ide/pci.c
>> +++ b/hw/ide/pci.c
>> @@ -342,7 +342,7 @@ static void bmdma_addr_write(void *opaque, hwaddr addr,
>>       bm->addr |= ((data & mask) << shift) & ~3;
>>   }
>>   -MemoryRegionOps bmdma_addr_ioport_ops = {
>> +static MemoryRegionOps bmdma_addr_ioport_ops = {
>>       .read = bmdma_addr_read,
>>       .write = bmdma_addr_write,
>>       .endianness = DEVICE_LITTLE_ENDIAN,
>> diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c
>> index 9cf920369f..373c0dd1ee 100644
>> --- a/hw/ide/sii3112.c
>> +++ b/hw/ide/sii3112.c
>> @@ -34,47 +34,73 @@ struct SiI3112PCIState {
>>       SiI3112Regs regs[2];
>>   };
>>   -/* The sii3112_reg_read and sii3112_reg_write functions implement the
>> - * Internal Register Space - BAR5 (section 6.7 of the data sheet).
>> - */
>> -
>> -static uint64_t sii3112_reg_read(void *opaque, hwaddr addr,
>> -                                unsigned int size)
>> +static uint64_t sii3112_bmdma_read(void *opaque, hwaddr addr, unsigned int size)
>>   {
>> -    SiI3112PCIState *d = opaque;
>> +    BMDMAState *bm = opaque;
>> +    SiI3112PCIState *d = SII3112_PCI(bm->pci_dev);
>> +    int i = (bm == &bm->pci_dev->bmdma[0]) ? 0 : 1;
>>       uint64_t val;
>>         switch (addr) {
>>       case 0x00:
>> -        val = d->i.bmdma[0].cmd;
>> +        val = bm->cmd;
>>           break;
>>       case 0x01:
>> -        val = d->regs[0].swdata;
>> +        val = d->regs[i].swdata;
>>           break;
>>       case 0x02:
>> -        val = d->i.bmdma[0].status;
>> +        val = bm->status;
>>           break;
>>       case 0x03:
>>           val = 0;
>>           break;
>> -    case 0x04 ... 0x07:
>> -        val = bmdma_addr_ioport_ops.read(&d->i.bmdma[0], addr - 4, size);
>> -        break;
>> -    case 0x08:
>> -        val = d->i.bmdma[1].cmd;
>> +    default:
>> +        val = 0;
>>           break;
>> -    case 0x09:
>> -        val = d->regs[1].swdata;
>> +    }
>> +    trace_sii3112_bmdma_read(size, addr, val);
>> +    return val;
>> +}
>> +
>> +static void sii3112_bmdma_write(void *opaque, hwaddr addr,
>> +                                uint64_t val, unsigned int size)
>> +{
>> +    BMDMAState *bm = opaque;
>> +    SiI3112PCIState *d = SII3112_PCI(bm->pci_dev);
>> +    int i = (bm == &bm->pci_dev->bmdma[0]) ? 0 : 1;
>> +
>> +    trace_sii3112_bmdma_write(size, addr, val);
>> +    switch (addr) {
>> +    case 0x00:
>> +        bmdma_cmd_writeb(bm, val);
>>           break;
>> -    case 0x0a:
>> -        val = d->i.bmdma[1].status;
>> +    case 0x01:
>> +        d->regs[i].swdata = val & 0x3f;
>>           break;
>> -    case 0x0b:
>> -        val = 0;
>> +    case 0x02:
>> +        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 6);
>>           break;
>> -    case 0x0c ... 0x0f:
>> -        val = bmdma_addr_ioport_ops.read(&d->i.bmdma[1], addr - 12, size);
>> +    default:
>>           break;
>> +    }
>> +}
>> +
>> +static const MemoryRegionOps sii3112_bmdma_ops = {
>> +    .read = sii3112_bmdma_read,
>> +    .write = sii3112_bmdma_write,
>> +};
>> +
>> +/* The sii3112_reg_read and sii3112_reg_write functions implement the
>> + * Internal Register Space - BAR5 (section 6.7 of the data sheet).
>> + */
>> +
>> +static uint64_t sii3112_reg_read(void *opaque, hwaddr addr,
>> +                                unsigned int size)
>> +{
>> +    SiI3112PCIState *d = opaque;
>> +    uint64_t val;
>> +
>> +    switch (addr) {
>>       case 0x10:
>>           val = d->i.bmdma[0].cmd;
>>           val |= (d->regs[0].confstat & (1UL << 11) ? (1 << 4) : 0); /*SATAINT0*/
>> @@ -127,38 +153,26 @@ static void sii3112_reg_write(void *opaque, hwaddr addr,
>>         trace_sii3112_write(size, addr, val);
>>       switch (addr) {
>> -    case 0x00:
>>       case 0x10:
>>           bmdma_cmd_writeb(&d->i.bmdma[0], val);
>>           break;
>> -    case 0x01:
>>       case 0x11:
>>           d->regs[0].swdata = val & 0x3f;
>>           break;
>> -    case 0x02:
>>       case 0x12:
>>           d->i.bmdma[0].status = (val & 0x60) | (d->i.bmdma[0].status & 1) |
>>                                  (d->i.bmdma[0].status & ~val & 6);
>>           break;
>> -    case 0x04 ... 0x07:
>> -        bmdma_addr_ioport_ops.write(&d->i.bmdma[0], addr - 4, val, size);
>> -        break;
>> -    case 0x08:
>>       case 0x18:
>>           bmdma_cmd_writeb(&d->i.bmdma[1], val);
>>           break;
>> -    case 0x09:
>>       case 0x19:
>>           d->regs[1].swdata = val & 0x3f;
>>           break;
>> -    case 0x0a:
>>       case 0x1a:
>>           d->i.bmdma[1].status = (val & 0x60) | (d->i.bmdma[1].status & 1) |
>>                                  (d->i.bmdma[1].status & ~val & 6);
>>           break;
>> -    case 0x0c ... 0x0f:
>> -        bmdma_addr_ioport_ops.write(&d->i.bmdma[1], addr - 12, val, size);
>> -        break;
>>       case 0x100:
>>           d->regs[0].scontrol = val & 0xfff;
>>           if (val & 1) {
>> @@ -240,6 +254,9 @@ static void sii3112_pci_realize(PCIDevice *dev, Error **errp)
>>       pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &s->data_ops[1]);
>>       pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &s->cmd_ops[1]);
>>   +    bmdma_init_ops(s, &sii3112_bmdma_ops);
>> +    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &s->bmdma_ops);
>> +
>>       /* BAR5 is in PCI memory space */
>>       memory_region_init_io(&d->mmio, OBJECT(d), &sii3112_reg_ops, d,
>>                            "sii3112.bar5", 0x200);
>> @@ -262,10 +279,10 @@ static void sii3112_pci_realize(PCIDevice *dev, Error **errp)
>>       memory_region_init_alias(mr, OBJECT(d), "sii3112.bar3", &s->cmd_ops[1], 0,
>>                                memory_region_size(&s->cmd_ops[1]));
>>       memory_region_add_subregion_overlap(&d->mmio, 0xc8, mr, 1);
>> -
>>       mr = g_new(MemoryRegion, 1);
>> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar4", &d->mmio, 0, 16);
>> -    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, mr);
>> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar4", &s->bmdma_ops, 0,
>> +                             memory_region_size(&s->bmdma_ops));
>> +    memory_region_add_subregion_overlap(&d->mmio, 0x0, mr, 1);
>>         qdev_init_gpio_in(ds, sii3112_set_irq, 2);
>>       for (i = 0; i < 2; i++) {
>> @@ -287,7 +304,6 @@ static void sii3112_pci_class_init(ObjectClass *klass, void *data)
>>       pd->class_id = PCI_CLASS_STORAGE_RAID;
>>       pd->revision = 1;
>>       pd->realize = sii3112_pci_realize;
>> -    pd->exit = NULL;
>>       dc->reset = sii3112_reset;
>>       dc->vmsd = NULL;
>>       dc->desc = "SiI3112A SATA controller";
>> diff --git a/hw/ide/trace-events b/hw/ide/trace-events
>> index 57042cafdd..a479525e38 100644
>> --- a/hw/ide/trace-events
>> +++ b/hw/ide/trace-events
>> @@ -38,8 +38,10 @@ bmdma_read(uint64_t addr, uint8_t val) "bmdma: readb 0x%"PRIx64" : 0x%02x"
>>   bmdma_write(uint64_t addr, uint64_t val) "bmdma: writeb 0x%"PRIx64" : 0x%02"PRIx64
>>     # sii3112.c
>> -sii3112_read(int size, uint64_t addr, uint64_t val) "bmdma: read (size %d) 0x%"PRIx64" : 0x%02"PRIx64
>> -sii3112_write(int size, uint64_t addr, uint64_t val) "bmdma: write (size %d) 0x%"PRIx64" : 0x%02"PRIx64
>> +sii3112_bmdma_read(int size, uint64_t addr, uint64_t val) "read (size %d) 0x%"PRIx64" : 0x%02"PRIx64
>> +sii3112_bmdma_write(int size, uint64_t addr, uint64_t val) "write (size %d) 0x%"PRIx64" : 0x%02"PRIx64
>> +sii3112_read(int size, uint64_t addr, uint64_t val) "read (size %d) 0x%"PRIx64" : 0x%02"PRIx64
>> +sii3112_write(int size, uint64_t addr, uint64_t val) "write (size %d) 0x%"PRIx64" : 0x%02"PRIx64
>>   sii3112_set_irq(int channel, int level) "channel %d level %d"
>>     # via.c
>
>Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
>
>
>ATB,
>
>Mark.


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 11/13] hw/ide/sii3112: Reuse PCIIDEState::{cmd,data}_ops
  2023-04-26 20:24     ` Bernhard Beschow
@ 2023-04-26 23:24       ` BALATON Zoltan
  2023-04-27 11:15         ` Mark Cave-Ayland
  0 siblings, 1 reply; 77+ messages in thread
From: BALATON Zoltan @ 2023-04-26 23:24 UTC (permalink / raw)
  To: Bernhard Beschow
  Cc: Mark Cave-Ayland, qemu-devel, qemu-block, Jiaxun Yang, John Snow,
	Huacai Chen, Philippe Mathieu-Daudé,
	qemu-ppc

On Wed, 26 Apr 2023, Bernhard Beschow wrote:
> Am 26. April 2023 11:41:54 UTC schrieb Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>:
>> On 22/04/2023 16:07, Bernhard Beschow wrote:
>>
>>> Allows to unexport pci_ide_{cmd,data}_le_ops and models TYPE_SII3112_PCI as a
>>> standard-compliant PCI IDE device.
>>>
>>> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
>>> ---
>>>   include/hw/ide/pci.h |  2 --
>>>   hw/ide/pci.c         |  4 ++--
>>>   hw/ide/sii3112.c     | 50 ++++++++++++++++----------------------------
>>>   3 files changed, 20 insertions(+), 36 deletions(-)
>>>
>>> diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
>>> index 5025df5b82..dbb4b13161 100644
>>> --- a/include/hw/ide/pci.h
>>> +++ b/include/hw/ide/pci.h
>>> @@ -62,6 +62,4 @@ void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val);
>>>   extern MemoryRegionOps bmdma_addr_ioport_ops;
>>>   void pci_ide_create_devs(PCIDevice *dev);
>>>   -extern const MemoryRegionOps pci_ide_cmd_le_ops;
>>> -extern const MemoryRegionOps pci_ide_data_le_ops;
>>>   #endif
>>> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
>>> index b2fcc00a64..97ccc75aa6 100644
>>> --- a/hw/ide/pci.c
>>> +++ b/hw/ide/pci.c
>>> @@ -60,7 +60,7 @@ static void pci_ide_ctrl_write(void *opaque, hwaddr addr,
>>>       ide_ctrl_write(bus, addr + 2, data);
>>>   }
>>>   -const MemoryRegionOps pci_ide_cmd_le_ops = {
>>> +static const MemoryRegionOps pci_ide_cmd_le_ops = {
>>>       .read = pci_ide_status_read,
>>>       .write = pci_ide_ctrl_write,
>>>       .endianness = DEVICE_LITTLE_ENDIAN,
>>> @@ -98,7 +98,7 @@ static void pci_ide_data_write(void *opaque, hwaddr addr,
>>>       }
>>>   }
>>>   -const MemoryRegionOps pci_ide_data_le_ops = {
>>> +static const MemoryRegionOps pci_ide_data_le_ops = {
>>>       .read = pci_ide_data_read,
>>>       .write = pci_ide_data_write,
>>>       .endianness = DEVICE_LITTLE_ENDIAN,
>>> diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c
>>> index 0af897a9ef..9cf920369f 100644
>>> --- a/hw/ide/sii3112.c
>>> +++ b/hw/ide/sii3112.c
>>> @@ -88,21 +88,9 @@ static uint64_t sii3112_reg_read(void *opaque, hwaddr addr,
>>>           val |= (d->regs[1].confstat & (1UL << 11) ? (1 << 4) : 0);
>>>           val |= (uint32_t)d->i.bmdma[1].status << 16;
>>>           break;
>>> -    case 0x80 ... 0x87:
>>> -        val = pci_ide_data_le_ops.read(&d->i.bus[0], addr - 0x80, size);
>>> -        break;
>>> -    case 0x8a:
>>> -        val = pci_ide_cmd_le_ops.read(&d->i.bus[0], 2, size);
>>> -        break;
>>>       case 0xa0:
>>>           val = d->regs[0].confstat;
>>>           break;
>>> -    case 0xc0 ... 0xc7:
>>> -        val = pci_ide_data_le_ops.read(&d->i.bus[1], addr - 0xc0, size);
>>> -        break;
>>> -    case 0xca:
>>> -        val = pci_ide_cmd_le_ops.read(&d->i.bus[1], 2, size);
>>> -        break;
>>>       case 0xe0:
>>>           val = d->regs[1].confstat;
>>>           break;
>>> @@ -171,18 +159,6 @@ static void sii3112_reg_write(void *opaque, hwaddr addr,
>>>       case 0x0c ... 0x0f:
>>>           bmdma_addr_ioport_ops.write(&d->i.bmdma[1], addr - 12, val, size);
>>>           break;
>>> -    case 0x80 ... 0x87:
>>> -        pci_ide_data_le_ops.write(&d->i.bus[0], addr - 0x80, val, size);
>>> -        break;
>>> -    case 0x8a:
>>> -        pci_ide_cmd_le_ops.write(&d->i.bus[0], 2, val, size);
>>> -        break;
>>> -    case 0xc0 ... 0xc7:
>>> -        pci_ide_data_le_ops.write(&d->i.bus[1], addr - 0xc0, val, size);
>>> -        break;
>>> -    case 0xca:
>>> -        pci_ide_cmd_le_ops.write(&d->i.bus[1], 2, val, size);
>>> -        break;
>>>       case 0x100:
>>>           d->regs[0].scontrol = val & 0xfff;
>>>           if (val & 1) {
>>> @@ -259,6 +235,11 @@ static void sii3112_pci_realize(PCIDevice *dev, Error **errp)
>>>       pci_config_set_interrupt_pin(dev->config, 1);
>>>       pci_set_byte(dev->config + PCI_CACHE_LINE_SIZE, 8);
>>>   +    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->data_ops[0]);
>>> +    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->cmd_ops[0]);
>>> +    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &s->data_ops[1]);
>>> +    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &s->cmd_ops[1]);
>>> +
>>>       /* BAR5 is in PCI memory space */
>>>       memory_region_init_io(&d->mmio, OBJECT(d), &sii3112_reg_ops, d,
>>>                            "sii3112.bar5", 0x200);
>>> @@ -266,17 +247,22 @@ static void sii3112_pci_realize(PCIDevice *dev, Error **errp)
>>>         /* BAR0-BAR4 are PCI I/O space aliases into BAR5 */
>>>       mr = g_new(MemoryRegion, 1);
>>> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar0", &d->mmio, 0x80, 8);
>>> -    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, mr);
>>> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar0", &s->data_ops[0], 0,
>>> +                             memory_region_size(&s->data_ops[0]));
>>> +    memory_region_add_subregion_overlap(&d->mmio, 0x80, mr, 1);
>>>       mr = g_new(MemoryRegion, 1);
>>> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar1", &d->mmio, 0x88, 4);
>>> -    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, mr);
>>> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar1", &s->cmd_ops[0], 0,
>>> +                             memory_region_size(&s->cmd_ops[0]));
>>> +    memory_region_add_subregion_overlap(&d->mmio, 0x88, mr, 1);
>>>       mr = g_new(MemoryRegion, 1);
>>> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar2", &d->mmio, 0xc0, 8);
>>> -    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, mr);
>>> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar2", &s->data_ops[1], 0,
>>> +                             memory_region_size(&s->data_ops[1]));
>>> +    memory_region_add_subregion_overlap(&d->mmio, 0xc0, mr, 1);
>>>       mr = g_new(MemoryRegion, 1);
>>> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar3", &d->mmio, 0xc8, 4);
>>> -    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, mr);
>>> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar3", &s->cmd_ops[1], 0,
>>> +                             memory_region_size(&s->cmd_ops[1]));
>>> +    memory_region_add_subregion_overlap(&d->mmio, 0xc8, mr, 1);
>>> +
>>>       mr = g_new(MemoryRegion, 1);
>>>       memory_region_init_alias(mr, OBJECT(d), "sii3112.bar4", &d->mmio, 0, 16);
>>>       pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, mr);
>>
>> So if I read this right, this is now switching the aliases over on BAR5 to allow re-use of the common IDE/BMDMA BARs in PCIIDEState? If that's correct then I think the commit message needs a bit more detail, otherwise:
>
> That's correct. Besides improving the commit message I'll additonally split this patch into two to show what's going on.
>
> Furthermore, I'd init the memory regions in sii3112's init method rather 
> than in realize(). This will be more consistent with the other PCI IDE 
> device models and with the other memory regions.

Why is an init method meeded? If it's not needed why add it? Just keep it 
simple. My view on these methods is that usually only a realize method is 
needed which is the normal constructor of the object, but sometimes we 
need some properties or something else to be available that can configure 
the object before realising which is when an init method is needed. 
Sometimes QEMU creates an object then destroys it without realising (I 
think e.g. when using help to query device properties) so then memory 
regions would be created and destroyed pointlessly. So unless there's a 
good reason to have an init method I'd leave this device without one to 
keep it simple. That other devices have an init method does not explain 
why this one should have one. Maybe those devices need it for some 
properties or they are just old code and not properly QOM'ified.

Regards,
BALATON Zoltan


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 10/13] hw/ide/piix: Reuse PCIIDEState::{cmd,data}_ops
  2023-04-26 20:14       ` Bernhard Beschow
@ 2023-04-27 10:52         ` Mark Cave-Ayland
  2023-04-27 18:15           ` Bernhard Beschow
  0 siblings, 1 reply; 77+ messages in thread
From: Mark Cave-Ayland @ 2023-04-27 10:52 UTC (permalink / raw)
  To: Bernhard Beschow, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc

On 26/04/2023 21:14, Bernhard Beschow wrote:

> Am 26. April 2023 18:18:35 UTC schrieb Bernhard Beschow <shentey@gmail.com>:
>>
>>
>> Am 26. April 2023 11:37:48 UTC schrieb Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>:
>>> On 22/04/2023 16:07, Bernhard Beschow wrote:
>>>
>>>> Now that PCIIDEState::{cmd,data}_ops are initialized in the base class
>>>> constructor there is an opportunity for PIIX to reuse these attributes. This
>>>> resolves usage of ide_init_ioport() which would fall back internally to using
>>>> the isabus global due to NULL being passed as ISADevice by PIIX.
>>>>
>>>> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
>>>> ---
>>>>    hw/ide/piix.c | 30 +++++++++++++-----------------
>>>>    1 file changed, 13 insertions(+), 17 deletions(-)
>>>>
>>>> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
>>>> index a3a15dc7db..406a67fa0f 100644
>>>> --- a/hw/ide/piix.c
>>>> +++ b/hw/ide/piix.c
>>>> @@ -104,34 +104,32 @@ static void piix_ide_reset(DeviceState *dev)
>>>>        pci_set_byte(pci_conf + 0x20, 0x01);  /* BMIBA: 20-23h */
>>>>    }
>>>>    -static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, ISABus *isa_bus,
>>>> -                              Error **errp)
>>>> +static void pci_piix_init_bus(PCIIDEState *d, unsigned i, ISABus *isa_bus)
>>>>    {
>>>>        static const struct {
>>>>            int iobase;
>>>>            int iobase2;
>>>>            int isairq;
>>>>        } port_info[] = {
>>>> -        {0x1f0, 0x3f6, 14},
>>>> -        {0x170, 0x376, 15},
>>>> +        {0x1f0, 0x3f4, 14},
>>>> +        {0x170, 0x374, 15},
>>>>        };
>>>> -    int ret;
>>>> +    MemoryRegion *address_space_io = pci_address_space_io(PCI_DEVICE(d));
>>>>          ide_bus_init(&d->bus[i], sizeof(d->bus[i]), DEVICE(d), i, 2);
>>>> -    ret = ide_init_ioport(&d->bus[i], NULL, port_info[i].iobase,
>>>> -                          port_info[i].iobase2);
>>>> -    if (ret) {
>>>> -        error_setg_errno(errp, -ret, "Failed to realize %s port %u",
>>>> -                         object_get_typename(OBJECT(d)), i);
>>>> -        return false;
>>>> -    }
>>>> +    memory_region_add_subregion(address_space_io, port_info[i].iobase,
>>>> +                                &d->data_ops[i]);
>>>> +    /*
>>>> +     * PIIX forwards the last byte of cmd_ops to ISA. Model this using a low
>>>> +     * prio so competing memory regions take precedence.
>>>> +     */
>>>> +    memory_region_add_subregion_overlap(address_space_io, port_info[i].iobase2,
>>>> +                                        &d->cmd_ops[i], -1);
>>>
>>> Interesting. Is this behaviour documented somewhere and/or used in one of your test images at all? If I'd have seen this myself, I probably thought that the addresses were a typo...
>>
>> I first  stumbled upon this and wondered why this code was working with VIA_IDE (through my pc-via branch). Then I found the correct offsets there which are confirmed in the piix datasheet, e.g.: "Secondary Control Block Offset: 0374h"
> 
> In case you were wondering about the forwarding of the last byte the datasheet says: "Accesses to byte 3 of the Control Block are forwarded to ISA where the floppy disk controller responds."

Ahhh okay okay I see what's happening here: the PIIX IDE is assuming that the legacy 
ioport semantics are in operation here, which as you note above is where the FDC 
controller is also accessed via the above byte in the IDE control block. This is also 
why you need to change the address above from 0x3f6/0x376 to 0x3f4/0x374 when trying 
to use the MemoryRegions used for the PCI BARs since the PCI IDE controller 
specification requires a 4 byte allocation for the Control Block - see sections 2.0 
and 2.2.

And that's fine, because the portio_lists used in ide_init_ioport() set up the legacy 
IDE ioports so that FDC accesses done in this way can succeed, and the PIIX IDE is 
hard-coded to legacy mode. So in fact PIIX IDE should keep using ide_init_ioport() 
rather than trying to re-use the BAR MemoryRegions so I think this patch should just 
be dropped.

>>>
>>>>        ide_bus_init_output_irq(&d->bus[i],
>>>>                                isa_bus_get_irq(isa_bus, port_info[i].isairq));
>>>>          bmdma_init(&d->bus[i], &d->bmdma[i], d);
>>>>        ide_bus_register_restart_cb(&d->bus[i]);
>>>> -
>>>> -    return true;
>>>>    }
>>>>      static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
>>>> @@ -160,9 +158,7 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
>>>>        }
>>>>          for (unsigned i = 0; i < 2; i++) {
>>>> -        if (!pci_piix_init_bus(d, i, isa_bus, errp)) {
>>>> -            return;
>>>> -        }
>>>> +        pci_piix_init_bus(d, i, isa_bus);
>>>>        }
>>>>    }


ATB,

Mark.


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 08/13] hw/ide: Rename PCIIDEState::*_bar attributes
  2023-04-26 18:29     ` Bernhard Beschow
@ 2023-04-27 11:07       ` Mark Cave-Ayland
  0 siblings, 0 replies; 77+ messages in thread
From: Mark Cave-Ayland @ 2023-04-27 11:07 UTC (permalink / raw)
  To: Bernhard Beschow, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc

On 26/04/2023 19:29, Bernhard Beschow wrote:

> Am 26. April 2023 11:21:28 UTC schrieb Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>:
>> On 22/04/2023 16:07, Bernhard Beschow wrote:
>>
>>> The attributes represent memory regions containing operations which are mapped
>>> by the device models into PCI BARs. Reflect this by changing the suffic into
>>> "_ops".
>>>
>>> Note that in a few commits piix will also use the {cmd,data}_ops but won't map
>>> them into BARs. This further suggests that the "_bar" suffix doesn't match
>>> very well.
>>>
>>> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
>>> ---
>>>    include/hw/ide/pci.h |  6 +++---
>>>    hw/ide/cmd646.c      | 10 +++++-----
>>>    hw/ide/pci.c         | 18 +++++++++---------
>>>    hw/ide/piix.c        |  2 +-
>>>    hw/ide/via.c         | 10 +++++-----
>>>    5 files changed, 23 insertions(+), 23 deletions(-)
>>>
>>> diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
>>> index 597c77c7ad..5025df5b82 100644
>>> --- a/include/hw/ide/pci.h
>>> +++ b/include/hw/ide/pci.h
>>> @@ -51,9 +51,9 @@ struct PCIIDEState {
>>>        BMDMAState bmdma[2];
>>>        qemu_irq isa_irq[2];
>>>        uint32_t secondary; /* used only for cmd646 */
>>> -    MemoryRegion bmdma_bar;
>>> -    MemoryRegion cmd_bar[2];
>>> -    MemoryRegion data_bar[2];
>>> +    MemoryRegion bmdma_ops;
>>> +    MemoryRegion cmd_ops[2];
>>> +    MemoryRegion data_ops[2];
>>>    };
>>>      void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d);
>>> diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
>>> index 85716aaf17..b9d005a357 100644
>>> --- a/hw/ide/cmd646.c
>>> +++ b/hw/ide/cmd646.c
>>> @@ -251,13 +251,13 @@ static void pci_cmd646_ide_realize(PCIDevice *dev, Error **errp)
>>>        dev->wmask[MRDMODE] = 0x0;
>>>        dev->w1cmask[MRDMODE] = MRDMODE_INTR_CH0 | MRDMODE_INTR_CH1;
>>>    -    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->data_bar[0]);
>>> -    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[0]);
>>> -    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &d->data_bar[1]);
>>> -    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[1]);
>>> +    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->data_ops[0]);
>>> +    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_ops[0]);
>>> +    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &d->data_ops[1]);
>>> +    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_ops[1]);
>>>          bmdma_init_ops(d, &cmd646_bmdma_ops);
>>> -    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
>>> +    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_ops);
>>>          /* TODO: RST# value should be 0 */
>>>        pci_conf[PCI_INTERRUPT_PIN] = 0x01; // interrupt on pin 1
>>> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
>>> index a9194313bd..b2fcc00a64 100644
>>> --- a/hw/ide/pci.c
>>> +++ b/hw/ide/pci.c
>>> @@ -527,15 +527,15 @@ void bmdma_init_ops(PCIIDEState *d, const MemoryRegionOps *bmdma_ops)
>>>    {
>>>        size_t i;
>>>    -    memory_region_init(&d->bmdma_bar, OBJECT(d), "bmdma-container", 16);
>>> +    memory_region_init(&d->bmdma_ops, OBJECT(d), "bmdma-container", 16);
>>>        for (i = 0; i < ARRAY_SIZE(d->bmdma); i++) {
>>>            BMDMAState *bm = &d->bmdma[i];
>>>              memory_region_init_io(&bm->extra_io, OBJECT(d), bmdma_ops, bm, "bmdma-ops", 4);
>>> -        memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io);
>>> +        memory_region_add_subregion(&d->bmdma_ops, i * 8, &bm->extra_io);
>>>            memory_region_init_io(&bm->addr_ioport, OBJECT(d), &bmdma_addr_ioport_ops, bm,
>>>                                  "bmdma-ioport-ops", 4);
>>> -        memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport);
>>> +        memory_region_add_subregion(&d->bmdma_ops, i * 8 + 4, &bm->addr_ioport);
>>>        }
>>>    }
>>>    @@ -543,14 +543,14 @@ static void pci_ide_init(Object *obj)
>>>    {
>>>        PCIIDEState *d = PCI_IDE(obj);
>>>    -    memory_region_init_io(&d->data_bar[0], OBJECT(d), &pci_ide_data_le_ops,
>>> +    memory_region_init_io(&d->data_ops[0], OBJECT(d), &pci_ide_data_le_ops,
>>>                              &d->bus[0], "pci-ide0-data-ops", 8);
>>> -    memory_region_init_io(&d->cmd_bar[0], OBJECT(d), &pci_ide_cmd_le_ops,
>>> +    memory_region_init_io(&d->cmd_ops[0], OBJECT(d), &pci_ide_cmd_le_ops,
>>>                              &d->bus[0], "pci-ide0-cmd-ops", 4);
>>>    -    memory_region_init_io(&d->data_bar[1], OBJECT(d), &pci_ide_data_le_ops,
>>> +    memory_region_init_io(&d->data_ops[1], OBJECT(d), &pci_ide_data_le_ops,
>>>                              &d->bus[1], "pci-ide1-data-ops", 8);
>>> -    memory_region_init_io(&d->cmd_bar[1], OBJECT(d), &pci_ide_cmd_le_ops,
>>> +    memory_region_init_io(&d->cmd_ops[1], OBJECT(d), &pci_ide_cmd_le_ops,
>>>                              &d->bus[1], "pci-ide1-cmd-ops", 4);
>>>          qdev_init_gpio_out(DEVICE(d), d->isa_irq, ARRAY_SIZE(d->isa_irq));
>>> @@ -562,8 +562,8 @@ static void pci_ide_exitfn(PCIDevice *dev)
>>>        unsigned i;
>>>          for (i = 0; i < ARRAY_SIZE(d->bmdma); ++i) {
>>> -        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io);
>>> -        memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport);
>>> +        memory_region_del_subregion(&d->bmdma_ops, &d->bmdma[i].extra_io);
>>> +        memory_region_del_subregion(&d->bmdma_ops, &d->bmdma[i].addr_ioport);
>>>        }
>>>    }
>>>    diff --git a/hw/ide/piix.c b/hw/ide/piix.c
>>> index 5611473d37..6942b484f9 100644
>>> --- a/hw/ide/piix.c
>>> +++ b/hw/ide/piix.c
>>> @@ -140,7 +140,7 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
>>>        pci_conf[PCI_CLASS_PROG] = 0x80; // legacy ATA mode
>>>          bmdma_init_ops(d, &piix_bmdma_ops);
>>> -    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
>>> +    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_ops);
>>>          for (unsigned i = 0; i < 2; i++) {
>>>            if (!pci_piix_init_bus(d, i, errp)) {
>>> diff --git a/hw/ide/via.c b/hw/ide/via.c
>>> index 704a8024cb..35dd97e49b 100644
>>> --- a/hw/ide/via.c
>>> +++ b/hw/ide/via.c
>>> @@ -154,13 +154,13 @@ static void via_ide_realize(PCIDevice *dev, Error **errp)
>>>        dev->wmask[PCI_INTERRUPT_LINE] = 0;
>>>        dev->wmask[PCI_CLASS_PROG] = 5;
>>>    -    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->data_bar[0]);
>>> -    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[0]);
>>> -    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &d->data_bar[1]);
>>> -    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[1]);
>>> +    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->data_ops[0]);
>>> +    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_ops[0]);
>>> +    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &d->data_ops[1]);
>>> +    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_ops[1]);
>>>          bmdma_init_ops(d, &via_bmdma_ops);
>>> -    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
>>> +    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_ops);
>>>          qdev_init_gpio_in(ds, via_ide_set_irq, ARRAY_SIZE(d->bus));
>>>        for (i = 0; i < ARRAY_SIZE(d->bus); i++) {
>>
>> I don't really feel strongly either way on this one, so I'm happy to go along with the silent majority here - I see that Zoltan has expressed a preference for it to stay as-is.
> 
> Doesn't it look off in PIIX-IDE where we don't map these regions via BARs? Don't these memory regions only become "BARs" by mapping them as such?

Following on from my previous reply, I'm fairly sure we sholdn't be doing this at all 
for PCI IDE controllers in legacy mode such as PIIX so it shouldn't be an issue.


ATB,

Mark.


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 11/13] hw/ide/sii3112: Reuse PCIIDEState::{cmd,data}_ops
  2023-04-26 23:24       ` BALATON Zoltan
@ 2023-04-27 11:15         ` Mark Cave-Ayland
  2023-04-27 12:55           ` BALATON Zoltan
  0 siblings, 1 reply; 77+ messages in thread
From: Mark Cave-Ayland @ 2023-04-27 11:15 UTC (permalink / raw)
  To: BALATON Zoltan, Bernhard Beschow
  Cc: qemu-devel, qemu-block, Jiaxun Yang, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc

On 27/04/2023 00:24, BALATON Zoltan wrote:

> On Wed, 26 Apr 2023, Bernhard Beschow wrote:
>> Am 26. April 2023 11:41:54 UTC schrieb Mark Cave-Ayland 
>> <mark.cave-ayland@ilande.co.uk>:
>>> On 22/04/2023 16:07, Bernhard Beschow wrote:
>>>
>>>> Allows to unexport pci_ide_{cmd,data}_le_ops and models TYPE_SII3112_PCI as a
>>>> standard-compliant PCI IDE device.
>>>>
>>>> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
>>>> ---
>>>>   include/hw/ide/pci.h |  2 --
>>>>   hw/ide/pci.c         |  4 ++--
>>>>   hw/ide/sii3112.c     | 50 ++++++++++++++++----------------------------
>>>>   3 files changed, 20 insertions(+), 36 deletions(-)
>>>>
>>>> diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
>>>> index 5025df5b82..dbb4b13161 100644
>>>> --- a/include/hw/ide/pci.h
>>>> +++ b/include/hw/ide/pci.h
>>>> @@ -62,6 +62,4 @@ void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val);
>>>>   extern MemoryRegionOps bmdma_addr_ioport_ops;
>>>>   void pci_ide_create_devs(PCIDevice *dev);
>>>>   -extern const MemoryRegionOps pci_ide_cmd_le_ops;
>>>> -extern const MemoryRegionOps pci_ide_data_le_ops;
>>>>   #endif
>>>> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
>>>> index b2fcc00a64..97ccc75aa6 100644
>>>> --- a/hw/ide/pci.c
>>>> +++ b/hw/ide/pci.c
>>>> @@ -60,7 +60,7 @@ static void pci_ide_ctrl_write(void *opaque, hwaddr addr,
>>>>       ide_ctrl_write(bus, addr + 2, data);
>>>>   }
>>>>   -const MemoryRegionOps pci_ide_cmd_le_ops = {
>>>> +static const MemoryRegionOps pci_ide_cmd_le_ops = {
>>>>       .read = pci_ide_status_read,
>>>>       .write = pci_ide_ctrl_write,
>>>>       .endianness = DEVICE_LITTLE_ENDIAN,
>>>> @@ -98,7 +98,7 @@ static void pci_ide_data_write(void *opaque, hwaddr addr,
>>>>       }
>>>>   }
>>>>   -const MemoryRegionOps pci_ide_data_le_ops = {
>>>> +static const MemoryRegionOps pci_ide_data_le_ops = {
>>>>       .read = pci_ide_data_read,
>>>>       .write = pci_ide_data_write,
>>>>       .endianness = DEVICE_LITTLE_ENDIAN,
>>>> diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c
>>>> index 0af897a9ef..9cf920369f 100644
>>>> --- a/hw/ide/sii3112.c
>>>> +++ b/hw/ide/sii3112.c
>>>> @@ -88,21 +88,9 @@ static uint64_t sii3112_reg_read(void *opaque, hwaddr addr,
>>>>           val |= (d->regs[1].confstat & (1UL << 11) ? (1 << 4) : 0);
>>>>           val |= (uint32_t)d->i.bmdma[1].status << 16;
>>>>           break;
>>>> -    case 0x80 ... 0x87:
>>>> -        val = pci_ide_data_le_ops.read(&d->i.bus[0], addr - 0x80, size);
>>>> -        break;
>>>> -    case 0x8a:
>>>> -        val = pci_ide_cmd_le_ops.read(&d->i.bus[0], 2, size);
>>>> -        break;
>>>>       case 0xa0:
>>>>           val = d->regs[0].confstat;
>>>>           break;
>>>> -    case 0xc0 ... 0xc7:
>>>> -        val = pci_ide_data_le_ops.read(&d->i.bus[1], addr - 0xc0, size);
>>>> -        break;
>>>> -    case 0xca:
>>>> -        val = pci_ide_cmd_le_ops.read(&d->i.bus[1], 2, size);
>>>> -        break;
>>>>       case 0xe0:
>>>>           val = d->regs[1].confstat;
>>>>           break;
>>>> @@ -171,18 +159,6 @@ static void sii3112_reg_write(void *opaque, hwaddr addr,
>>>>       case 0x0c ... 0x0f:
>>>>           bmdma_addr_ioport_ops.write(&d->i.bmdma[1], addr - 12, val, size);
>>>>           break;
>>>> -    case 0x80 ... 0x87:
>>>> -        pci_ide_data_le_ops.write(&d->i.bus[0], addr - 0x80, val, size);
>>>> -        break;
>>>> -    case 0x8a:
>>>> -        pci_ide_cmd_le_ops.write(&d->i.bus[0], 2, val, size);
>>>> -        break;
>>>> -    case 0xc0 ... 0xc7:
>>>> -        pci_ide_data_le_ops.write(&d->i.bus[1], addr - 0xc0, val, size);
>>>> -        break;
>>>> -    case 0xca:
>>>> -        pci_ide_cmd_le_ops.write(&d->i.bus[1], 2, val, size);
>>>> -        break;
>>>>       case 0x100:
>>>>           d->regs[0].scontrol = val & 0xfff;
>>>>           if (val & 1) {
>>>> @@ -259,6 +235,11 @@ static void sii3112_pci_realize(PCIDevice *dev, Error **errp)
>>>>       pci_config_set_interrupt_pin(dev->config, 1);
>>>>       pci_set_byte(dev->config + PCI_CACHE_LINE_SIZE, 8);
>>>>   +    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->data_ops[0]);
>>>> +    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->cmd_ops[0]);
>>>> +    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &s->data_ops[1]);
>>>> +    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &s->cmd_ops[1]);
>>>> +
>>>>       /* BAR5 is in PCI memory space */
>>>>       memory_region_init_io(&d->mmio, OBJECT(d), &sii3112_reg_ops, d,
>>>>                            "sii3112.bar5", 0x200);
>>>> @@ -266,17 +247,22 @@ static void sii3112_pci_realize(PCIDevice *dev, Error **errp)
>>>>         /* BAR0-BAR4 are PCI I/O space aliases into BAR5 */
>>>>       mr = g_new(MemoryRegion, 1);
>>>> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar0", &d->mmio, 0x80, 8);
>>>> -    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, mr);
>>>> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar0", &s->data_ops[0], 0,
>>>> +                             memory_region_size(&s->data_ops[0]));
>>>> +    memory_region_add_subregion_overlap(&d->mmio, 0x80, mr, 1);
>>>>       mr = g_new(MemoryRegion, 1);
>>>> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar1", &d->mmio, 0x88, 4);
>>>> -    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, mr);
>>>> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar1", &s->cmd_ops[0], 0,
>>>> +                             memory_region_size(&s->cmd_ops[0]));
>>>> +    memory_region_add_subregion_overlap(&d->mmio, 0x88, mr, 1);
>>>>       mr = g_new(MemoryRegion, 1);
>>>> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar2", &d->mmio, 0xc0, 8);
>>>> -    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, mr);
>>>> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar2", &s->data_ops[1], 0,
>>>> +                             memory_region_size(&s->data_ops[1]));
>>>> +    memory_region_add_subregion_overlap(&d->mmio, 0xc0, mr, 1);
>>>>       mr = g_new(MemoryRegion, 1);
>>>> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar3", &d->mmio, 0xc8, 4);
>>>> -    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, mr);
>>>> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar3", &s->cmd_ops[1], 0,
>>>> +                             memory_region_size(&s->cmd_ops[1]));
>>>> +    memory_region_add_subregion_overlap(&d->mmio, 0xc8, mr, 1);
>>>> +
>>>>       mr = g_new(MemoryRegion, 1);
>>>>       memory_region_init_alias(mr, OBJECT(d), "sii3112.bar4", &d->mmio, 0, 16);
>>>>       pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, mr);
>>>
>>> So if I read this right, this is now switching the aliases over on BAR5 to allow 
>>> re-use of the common IDE/BMDMA BARs in PCIIDEState? If that's correct then I think 
>>> the commit message needs a bit more detail, otherwise:
>>
>> That's correct. Besides improving the commit message I'll additonally split this 
>> patch into two to show what's going on.
>>
>> Furthermore, I'd init the memory regions in sii3112's init method rather than in 
>> realize(). This will be more consistent with the other PCI IDE device models and 
>> with the other memory regions.
> 
> Why is an init method meeded? If it's not needed why add it? Just keep it simple. My 
> view on these methods is that usually only a realize method is needed which is the 
> normal constructor of the object, but sometimes we need some properties or something 
> else to be available that can configure the object before realising which is when an 
> init method is needed. Sometimes QEMU creates an object then destroys it without 
> realising (I think e.g. when using help to query device properties) so then memory 
> regions would be created and destroyed pointlessly. So unless there's a good reason 
> to have an init method I'd leave this device without one to keep it simple. That 
> other devices have an init method does not explain why this one should have one. 
> Maybe those devices need it for some properties or they are just old code and not 
> properly QOM'ified.

 From memory one of the QOM developer guides recommends that all initialisation 
should be placed in .instance_init, except for objects that depend on properties 
which are set after .instance_init but before .realize().

Certainly there is some flexibility around this for legacy code, however quite a few 
reviewers have picked up on previous series I have posted when I have forgotten to 
move something from .realize() to .instance_init() when allowed after refactoring.


ATB,

Mark.


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 09/13] hw/ide/piix: Disuse isa_get_irq()
  2023-04-26 18:25     ` Bernhard Beschow
@ 2023-04-27 12:31       ` Mark Cave-Ayland
  2023-05-13 11:53         ` Bernhard Beschow
  0 siblings, 1 reply; 77+ messages in thread
From: Mark Cave-Ayland @ 2023-04-27 12:31 UTC (permalink / raw)
  To: Bernhard Beschow, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc, Thomas Huth

On 26/04/2023 19:25, Bernhard Beschow wrote:

> Am 26. April 2023 11:33:40 UTC schrieb Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>:
>> On 22/04/2023 16:07, Bernhard Beschow wrote:
>>
>>> isa_get_irq() asks for an ISADevice which piix-ide doesn't provide.
>>> Passing a NULL pointer works but causes the isabus global to be used
>>> then. By fishing out TYPE_ISA_BUS from the QOM tree it is possible to
>>> achieve the same as using isa_get_irq().
>>>
>>> This is an alternative solution to commit 9405d87be25d 'hw/ide: Fix
>>> crash when plugging a piix3-ide device into the x-remote machine' which
>>> allows for cleaning up the ISA API while keeping PIIX IDE functions
>>> user-createable.
>>>
>>> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
>>> ---
>>>    hw/ide/piix.c | 23 ++++++++++++++++++++---
>>>    1 file changed, 20 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
>>> index 6942b484f9..a3a15dc7db 100644
>>> --- a/hw/ide/piix.c
>>> +++ b/hw/ide/piix.c
>>> @@ -104,7 +104,8 @@ static void piix_ide_reset(DeviceState *dev)
>>>        pci_set_byte(pci_conf + 0x20, 0x01);  /* BMIBA: 20-23h */
>>>    }
>>>    -static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, Error **errp)
>>> +static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, ISABus *isa_bus,
>>> +                              Error **errp)
>>>    {
>>>        static const struct {
>>>            int iobase;
>>> @@ -124,7 +125,8 @@ static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, Error **errp)
>>>                             object_get_typename(OBJECT(d)), i);
>>>            return false;
>>>        }
>>> -    ide_bus_init_output_irq(&d->bus[i], isa_get_irq(NULL, port_info[i].isairq));
>>> +    ide_bus_init_output_irq(&d->bus[i],
>>> +                            isa_bus_get_irq(isa_bus, port_info[i].isairq));
>>
>> I don't think is the right solution here, since ultimately we want to move the IRQ routing out of the device itself and into the PCI-ISA bridge. I'd go for the same solution as you've done for VIA IDE in patch 2, i.e. update the PIIX interrupt handler to set the legacy_irqs in PCIIDEState, and then wire them up to the ISA IRQs 14 and 15 similar to as Phil as done in his patches:
> 
> The problem is user-creatable PIIX-IDE. IMO we should stick to our deprecation process before going this step because this will break it.

Thomas posted some links from previous discussions where it seems that this hack is 
still in use:

https://lists.nongnu.org/archive/html/qemu-block/2019-07/msg00780.html
https://lists.gnu.org/archive/html/qemu-block/2021-04/msg00746.html

So it seems we can't even deprecate this, as it's working around missing 
functionality in q35 :(

Certainly it seems that we should add a check that will fail the machine if there is 
more than one -device piix3-ide on the command line, since I can't see that could 
ever work properly.

I'm leaning towards adding a device property that must be set to enabled in order for 
PIIX IDE realize() to succeed, leave it disabled by default and only enable it for 
the q35 machine. Does that seem like a reasonable solution?

>> https://patchew.org/QEMU/20230302224058.43315-1-philmd@linaro.org/20230302224058.43315-4-philmd@linaro.org/
>>
>> https://patchew.org/QEMU/20230302224058.43315-1-philmd@linaro.org/20230302224058.43315-5-philmd@linaro.org/
>>
>> This also reminds me, given that the first patch above is doing wiring in pc_init1() then we are still missing part of your tidy-up series :/
>>
>>>        bmdma_init(&d->bus[i], &d->bmdma[i], d);
>>>        ide_bus_register_restart_cb(&d->bus[i]);
>>> @@ -136,14 +138,29 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
>>>    {
>>>        PCIIDEState *d = PCI_IDE(dev);
>>>        uint8_t *pci_conf = dev->config;
>>> +    ISABus *isa_bus;
>>> +    bool ambiguous;
>>>          pci_conf[PCI_CLASS_PROG] = 0x80; // legacy ATA mode
>>>          bmdma_init_ops(d, &piix_bmdma_ops);
>>>        pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_ops);
>>>    +    isa_bus = ISA_BUS(object_resolve_path_type("", TYPE_ISA_BUS, &ambiguous));
>>> +    if (ambiguous) {
>>> +        error_setg(errp,
>>> +                   "More than one ISA bus found while %s supports only one",
>>> +                   object_get_typename(OBJECT(d)));
>>> +        return;
>>> +    }
>>> +    if (!isa_bus) {
>>> +        error_setg(errp, "No ISA bus found while %s requires one",
>>> +                   object_get_typename(OBJECT(d)));
>>> +        return;
>>> +    }
>>
>> Again I think this should go away with using PCIIDEState's legacy_irqs, since you simply let the board wire them up to the ISABus (or not) as required.
> 
> Same here: This breaks user-creatable PIIX-IDE.
> 
>>
>>>        for (unsigned i = 0; i < 2; i++) {
>>> -        if (!pci_piix_init_bus(d, i, errp)) {
>>> +        if (!pci_piix_init_bus(d, i, isa_bus, errp)) {
>>>                return;
>>>            }
>>>        }


ATB,

Mark.


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 11/13] hw/ide/sii3112: Reuse PCIIDEState::{cmd,data}_ops
  2023-04-27 11:15         ` Mark Cave-Ayland
@ 2023-04-27 12:55           ` BALATON Zoltan
  2023-05-03 20:25             ` Mark Cave-Ayland
  0 siblings, 1 reply; 77+ messages in thread
From: BALATON Zoltan @ 2023-04-27 12:55 UTC (permalink / raw)
  To: Mark Cave-Ayland
  Cc: Bernhard Beschow, qemu-devel, qemu-block, Jiaxun Yang, John Snow,
	Huacai Chen, Philippe Mathieu-Daudé,
	qemu-ppc

[-- Attachment #1: Type: text/plain, Size: 10945 bytes --]

On Thu, 27 Apr 2023, Mark Cave-Ayland wrote:
> On 27/04/2023 00:24, BALATON Zoltan wrote:
>> On Wed, 26 Apr 2023, Bernhard Beschow wrote:
>>> Am 26. April 2023 11:41:54 UTC schrieb Mark Cave-Ayland 
>>> <mark.cave-ayland@ilande.co.uk>:
>>>> On 22/04/2023 16:07, Bernhard Beschow wrote:
>>>> 
>>>>> Allows to unexport pci_ide_{cmd,data}_le_ops and models TYPE_SII3112_PCI 
>>>>> as a
>>>>> standard-compliant PCI IDE device.
>>>>> 
>>>>> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
>>>>> ---
>>>>>   include/hw/ide/pci.h |  2 --
>>>>>   hw/ide/pci.c         |  4 ++--
>>>>>   hw/ide/sii3112.c     | 50 ++++++++++++++++----------------------------
>>>>>   3 files changed, 20 insertions(+), 36 deletions(-)
>>>>> 
>>>>> diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
>>>>> index 5025df5b82..dbb4b13161 100644
>>>>> --- a/include/hw/ide/pci.h
>>>>> +++ b/include/hw/ide/pci.h
>>>>> @@ -62,6 +62,4 @@ void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val);
>>>>>   extern MemoryRegionOps bmdma_addr_ioport_ops;
>>>>>   void pci_ide_create_devs(PCIDevice *dev);
>>>>>   -extern const MemoryRegionOps pci_ide_cmd_le_ops;
>>>>> -extern const MemoryRegionOps pci_ide_data_le_ops;
>>>>>   #endif
>>>>> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
>>>>> index b2fcc00a64..97ccc75aa6 100644
>>>>> --- a/hw/ide/pci.c
>>>>> +++ b/hw/ide/pci.c
>>>>> @@ -60,7 +60,7 @@ static void pci_ide_ctrl_write(void *opaque, hwaddr 
>>>>> addr,
>>>>>       ide_ctrl_write(bus, addr + 2, data);
>>>>>   }
>>>>>   -const MemoryRegionOps pci_ide_cmd_le_ops = {
>>>>> +static const MemoryRegionOps pci_ide_cmd_le_ops = {
>>>>>       .read = pci_ide_status_read,
>>>>>       .write = pci_ide_ctrl_write,
>>>>>       .endianness = DEVICE_LITTLE_ENDIAN,
>>>>> @@ -98,7 +98,7 @@ static void pci_ide_data_write(void *opaque, hwaddr 
>>>>> addr,
>>>>>       }
>>>>>   }
>>>>>   -const MemoryRegionOps pci_ide_data_le_ops = {
>>>>> +static const MemoryRegionOps pci_ide_data_le_ops = {
>>>>>       .read = pci_ide_data_read,
>>>>>       .write = pci_ide_data_write,
>>>>>       .endianness = DEVICE_LITTLE_ENDIAN,
>>>>> diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c
>>>>> index 0af897a9ef..9cf920369f 100644
>>>>> --- a/hw/ide/sii3112.c
>>>>> +++ b/hw/ide/sii3112.c
>>>>> @@ -88,21 +88,9 @@ static uint64_t sii3112_reg_read(void *opaque, hwaddr 
>>>>> addr,
>>>>>           val |= (d->regs[1].confstat & (1UL << 11) ? (1 << 4) : 0);
>>>>>           val |= (uint32_t)d->i.bmdma[1].status << 16;
>>>>>           break;
>>>>> -    case 0x80 ... 0x87:
>>>>> -        val = pci_ide_data_le_ops.read(&d->i.bus[0], addr - 0x80, 
>>>>> size);
>>>>> -        break;
>>>>> -    case 0x8a:
>>>>> -        val = pci_ide_cmd_le_ops.read(&d->i.bus[0], 2, size);
>>>>> -        break;
>>>>>       case 0xa0:
>>>>>           val = d->regs[0].confstat;
>>>>>           break;
>>>>> -    case 0xc0 ... 0xc7:
>>>>> -        val = pci_ide_data_le_ops.read(&d->i.bus[1], addr - 0xc0, 
>>>>> size);
>>>>> -        break;
>>>>> -    case 0xca:
>>>>> -        val = pci_ide_cmd_le_ops.read(&d->i.bus[1], 2, size);
>>>>> -        break;
>>>>>       case 0xe0:
>>>>>           val = d->regs[1].confstat;
>>>>>           break;
>>>>> @@ -171,18 +159,6 @@ static void sii3112_reg_write(void *opaque, hwaddr 
>>>>> addr,
>>>>>       case 0x0c ... 0x0f:
>>>>>           bmdma_addr_ioport_ops.write(&d->i.bmdma[1], addr - 12, val, 
>>>>> size);
>>>>>           break;
>>>>> -    case 0x80 ... 0x87:
>>>>> -        pci_ide_data_le_ops.write(&d->i.bus[0], addr - 0x80, val, 
>>>>> size);
>>>>> -        break;
>>>>> -    case 0x8a:
>>>>> -        pci_ide_cmd_le_ops.write(&d->i.bus[0], 2, val, size);
>>>>> -        break;
>>>>> -    case 0xc0 ... 0xc7:
>>>>> -        pci_ide_data_le_ops.write(&d->i.bus[1], addr - 0xc0, val, 
>>>>> size);
>>>>> -        break;
>>>>> -    case 0xca:
>>>>> -        pci_ide_cmd_le_ops.write(&d->i.bus[1], 2, val, size);
>>>>> -        break;
>>>>>       case 0x100:
>>>>>           d->regs[0].scontrol = val & 0xfff;
>>>>>           if (val & 1) {
>>>>> @@ -259,6 +235,11 @@ static void sii3112_pci_realize(PCIDevice *dev, 
>>>>> Error **errp)
>>>>>       pci_config_set_interrupt_pin(dev->config, 1);
>>>>>       pci_set_byte(dev->config + PCI_CACHE_LINE_SIZE, 8);
>>>>>   +    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, 
>>>>> &s->data_ops[0]);
>>>>> +    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, 
>>>>> &s->cmd_ops[0]);
>>>>> +    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, 
>>>>> &s->data_ops[1]);
>>>>> +    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, 
>>>>> &s->cmd_ops[1]);
>>>>> +
>>>>>       /* BAR5 is in PCI memory space */
>>>>>       memory_region_init_io(&d->mmio, OBJECT(d), &sii3112_reg_ops, d,
>>>>>                            "sii3112.bar5", 0x200);
>>>>> @@ -266,17 +247,22 @@ static void sii3112_pci_realize(PCIDevice *dev, 
>>>>> Error **errp)
>>>>>         /* BAR0-BAR4 are PCI I/O space aliases into BAR5 */
>>>>>       mr = g_new(MemoryRegion, 1);
>>>>> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar0", &d->mmio, 
>>>>> 0x80, 8);
>>>>> -    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, mr);
>>>>> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar0", 
>>>>> &s->data_ops[0], 0,
>>>>> +                             memory_region_size(&s->data_ops[0]));
>>>>> +    memory_region_add_subregion_overlap(&d->mmio, 0x80, mr, 1);
>>>>>       mr = g_new(MemoryRegion, 1);
>>>>> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar1", &d->mmio, 
>>>>> 0x88, 4);
>>>>> -    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, mr);
>>>>> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar1", 
>>>>> &s->cmd_ops[0], 0,
>>>>> +                             memory_region_size(&s->cmd_ops[0]));
>>>>> +    memory_region_add_subregion_overlap(&d->mmio, 0x88, mr, 1);
>>>>>       mr = g_new(MemoryRegion, 1);
>>>>> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar2", &d->mmio, 
>>>>> 0xc0, 8);
>>>>> -    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, mr);
>>>>> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar2", 
>>>>> &s->data_ops[1], 0,
>>>>> +                             memory_region_size(&s->data_ops[1]));
>>>>> +    memory_region_add_subregion_overlap(&d->mmio, 0xc0, mr, 1);
>>>>>       mr = g_new(MemoryRegion, 1);
>>>>> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar3", &d->mmio, 
>>>>> 0xc8, 4);
>>>>> -    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, mr);
>>>>> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar3", 
>>>>> &s->cmd_ops[1], 0,
>>>>> +                             memory_region_size(&s->cmd_ops[1]));
>>>>> +    memory_region_add_subregion_overlap(&d->mmio, 0xc8, mr, 1);
>>>>> +
>>>>>       mr = g_new(MemoryRegion, 1);
>>>>>       memory_region_init_alias(mr, OBJECT(d), "sii3112.bar4", &d->mmio, 
>>>>> 0, 16);
>>>>>       pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, mr);
>>>> 
>>>> So if I read this right, this is now switching the aliases over on BAR5 
>>>> to allow re-use of the common IDE/BMDMA BARs in PCIIDEState? If that's 
>>>> correct then I think the commit message needs a bit more detail, 
>>>> otherwise:
>>> 
>>> That's correct. Besides improving the commit message I'll additonally 
>>> split this patch into two to show what's going on.
>>> 
>>> Furthermore, I'd init the memory regions in sii3112's init method rather 
>>> than in realize(). This will be more consistent with the other PCI IDE 
>>> device models and with the other memory regions.
>> 
>> Why is an init method meeded? If it's not needed why add it? Just keep it 
>> simple. My view on these methods is that usually only a realize method is 
>> needed which is the normal constructor of the object, but sometimes we need 
>> some properties or something else to be available that can configure the 
>> object before realising which is when an init method is needed. Sometimes 
>> QEMU creates an object then destroys it without realising (I think e.g. 
>> when using help to query device properties) so then memory regions would be 
>> created and destroyed pointlessly. So unless there's a good reason to have 
>> an init method I'd leave this device without one to keep it simple. That 
>> other devices have an init method does not explain why this one should have 
>> one. Maybe those devices need it for some properties or they are just old 
>> code and not properly QOM'ified.
>
> From memory one of the QOM developer guides recommends that all 
> initialisation should be placed in .instance_init, except for objects that 
> depend on properties which are set after .instance_init but before 
> .realize().

Any pointer to that doc? I've tried to find it but I couldn't. The 
docs/devel/qom.rst does not say anything about this, The older collection 
of docs here: https://habkost.net/posts/2016/11/incomplete-list-of-qemu-apis.html
also does not have anything useful either, those mostly talk about 
properties instead. The header include/hw/qdev-core.h has some info but it 
only says that "Trivial field initializations should go into 
#TypeInfo.instance_init. Operations depending on @props static properties 
should go into @realize." So I don't see a clear guide on what should go 
where unless something is needed before the device is realized.

> Certainly there is some flexibility around this for legacy code, however 
> quite a few reviewers have picked up on previous series I have posted when I 
> have forgotten to move something from .realize() to .instance_init() when 
> allowed after refactoring.

I don't mind if things are done in init or realize as long as we have only 
one of these unless we really need both. Having object init split into two 
functions for no good reason just makes it mode confusing so I'd like to 
keep it at a single place for simlicity. Between init and realize the 
latter seems to be more appropriate for creating the things that are only 
needed when the object is really created and init is for those that may be 
needed when the object is not fully up yet, e.g. for introspection or 
working with connected objects. But for simple devices like sii3112 having 
more than a realize method probably does not make much sense. If you have 
examples of those reviews you refer to maybe that explains this more. I 
just want to avoid unneded complexity.

Regards,
BALATON Zoltan

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 10/13] hw/ide/piix: Reuse PCIIDEState::{cmd,data}_ops
  2023-04-27 10:52         ` Mark Cave-Ayland
@ 2023-04-27 18:15           ` Bernhard Beschow
  2023-04-28 15:58             ` Bernhard Beschow
  2023-05-03 19:52             ` Mark Cave-Ayland
  0 siblings, 2 replies; 77+ messages in thread
From: Bernhard Beschow @ 2023-04-27 18:15 UTC (permalink / raw)
  To: Mark Cave-Ayland, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc



Am 27. April 2023 10:52:17 UTC schrieb Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>:
>On 26/04/2023 21:14, Bernhard Beschow wrote:
>
>> Am 26. April 2023 18:18:35 UTC schrieb Bernhard Beschow <shentey@gmail.com>:
>>> 
>>> 
>>> Am 26. April 2023 11:37:48 UTC schrieb Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>:
>>>> On 22/04/2023 16:07, Bernhard Beschow wrote:
>>>> 
>>>>> Now that PCIIDEState::{cmd,data}_ops are initialized in the base class
>>>>> constructor there is an opportunity for PIIX to reuse these attributes. This
>>>>> resolves usage of ide_init_ioport() which would fall back internally to using
>>>>> the isabus global due to NULL being passed as ISADevice by PIIX.
>>>>> 
>>>>> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
>>>>> ---
>>>>>    hw/ide/piix.c | 30 +++++++++++++-----------------
>>>>>    1 file changed, 13 insertions(+), 17 deletions(-)
>>>>> 
>>>>> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
>>>>> index a3a15dc7db..406a67fa0f 100644
>>>>> --- a/hw/ide/piix.c
>>>>> +++ b/hw/ide/piix.c
>>>>> @@ -104,34 +104,32 @@ static void piix_ide_reset(DeviceState *dev)
>>>>>        pci_set_byte(pci_conf + 0x20, 0x01);  /* BMIBA: 20-23h */
>>>>>    }
>>>>>    -static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, ISABus *isa_bus,
>>>>> -                              Error **errp)
>>>>> +static void pci_piix_init_bus(PCIIDEState *d, unsigned i, ISABus *isa_bus)
>>>>>    {
>>>>>        static const struct {
>>>>>            int iobase;
>>>>>            int iobase2;
>>>>>            int isairq;
>>>>>        } port_info[] = {
>>>>> -        {0x1f0, 0x3f6, 14},
>>>>> -        {0x170, 0x376, 15},
>>>>> +        {0x1f0, 0x3f4, 14},
>>>>> +        {0x170, 0x374, 15},
>>>>>        };
>>>>> -    int ret;
>>>>> +    MemoryRegion *address_space_io = pci_address_space_io(PCI_DEVICE(d));
>>>>>          ide_bus_init(&d->bus[i], sizeof(d->bus[i]), DEVICE(d), i, 2);
>>>>> -    ret = ide_init_ioport(&d->bus[i], NULL, port_info[i].iobase,
>>>>> -                          port_info[i].iobase2);
>>>>> -    if (ret) {
>>>>> -        error_setg_errno(errp, -ret, "Failed to realize %s port %u",
>>>>> -                         object_get_typename(OBJECT(d)), i);
>>>>> -        return false;
>>>>> -    }
>>>>> +    memory_region_add_subregion(address_space_io, port_info[i].iobase,
>>>>> +                                &d->data_ops[i]);
>>>>> +    /*
>>>>> +     * PIIX forwards the last byte of cmd_ops to ISA. Model this using a low
>>>>> +     * prio so competing memory regions take precedence.
>>>>> +     */
>>>>> +    memory_region_add_subregion_overlap(address_space_io, port_info[i].iobase2,
>>>>> +                                        &d->cmd_ops[i], -1);
>>>> 
>>>> Interesting. Is this behaviour documented somewhere and/or used in one of your test images at all? If I'd have seen this myself, I probably thought that the addresses were a typo...
>>> 
>>> I first  stumbled upon this and wondered why this code was working with VIA_IDE (through my pc-via branch). Then I found the correct offsets there which are confirmed in the piix datasheet, e.g.: "Secondary Control Block Offset: 0374h"
>> 
>> In case you were wondering about the forwarding of the last byte the datasheet says: "Accesses to byte 3 of the Control Block are forwarded to ISA where the floppy disk controller responds."
>
>Ahhh okay okay I see what's happening here: the PIIX IDE is assuming that the legacy ioport semantics are in operation here, which as you note above is where the FDC controller is also accessed via the above byte in the IDE control block. This is also why you need to change the address above from 0x3f6/0x376 to 0x3f4/0x374 when trying to use the MemoryRegions used for the PCI BARs since the PCI IDE controller specification requires a 4 byte allocation for the Control Block - see sections 2.0 and 2.2.

Yes, PIIX assuming that might be the case. Why does it contradict the PCI IDE specification? PIIX seems to apply the apprppriate "workarounds" here.

>
>And that's fine, because the portio_lists used in ide_init_ioport() set up the legacy IDE ioports so that FDC accesses done in this way can succeed, and the PIIX IDE is hard-coded to legacy mode. So in fact PIIX IDE should keep using ide_init_ioport() rather than trying to re-use the BAR MemoryRegions so I think this patch should just be dropped.

I was hoping to keep that patch...

Best regards,
Bernhard

>
>>>> 
>>>>>        ide_bus_init_output_irq(&d->bus[i],
>>>>>                                isa_bus_get_irq(isa_bus, port_info[i].isairq));
>>>>>          bmdma_init(&d->bus[i], &d->bmdma[i], d);
>>>>>        ide_bus_register_restart_cb(&d->bus[i]);
>>>>> -
>>>>> -    return true;
>>>>>    }
>>>>>      static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
>>>>> @@ -160,9 +158,7 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
>>>>>        }
>>>>>          for (unsigned i = 0; i < 2; i++) {
>>>>> -        if (!pci_piix_init_bus(d, i, isa_bus, errp)) {
>>>>> -            return;
>>>>> -        }
>>>>> +        pci_piix_init_bus(d, i, isa_bus);
>>>>>        }
>>>>>    }
>
>
>ATB,
>
>Mark.


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 10/13] hw/ide/piix: Reuse PCIIDEState::{cmd,data}_ops
  2023-04-27 18:15           ` Bernhard Beschow
@ 2023-04-28 15:58             ` Bernhard Beschow
  2023-04-28 17:00               ` BALATON Zoltan
  2023-05-03 19:52             ` Mark Cave-Ayland
  1 sibling, 1 reply; 77+ messages in thread
From: Bernhard Beschow @ 2023-04-28 15:58 UTC (permalink / raw)
  To: Mark Cave-Ayland, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc



Am 27. April 2023 18:15:24 UTC schrieb Bernhard Beschow <shentey@gmail.com>:
>
>
>Am 27. April 2023 10:52:17 UTC schrieb Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>:
>>On 26/04/2023 21:14, Bernhard Beschow wrote:
>>
>>> Am 26. April 2023 18:18:35 UTC schrieb Bernhard Beschow <shentey@gmail.com>:
>>>> 
>>>> 
>>>> Am 26. April 2023 11:37:48 UTC schrieb Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>:
>>>>> On 22/04/2023 16:07, Bernhard Beschow wrote:
>>>>> 
>>>>>> Now that PCIIDEState::{cmd,data}_ops are initialized in the base class
>>>>>> constructor there is an opportunity for PIIX to reuse these attributes. This
>>>>>> resolves usage of ide_init_ioport() which would fall back internally to using
>>>>>> the isabus global due to NULL being passed as ISADevice by PIIX.
>>>>>> 
>>>>>> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
>>>>>> ---
>>>>>>    hw/ide/piix.c | 30 +++++++++++++-----------------
>>>>>>    1 file changed, 13 insertions(+), 17 deletions(-)
>>>>>> 
>>>>>> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
>>>>>> index a3a15dc7db..406a67fa0f 100644
>>>>>> --- a/hw/ide/piix.c
>>>>>> +++ b/hw/ide/piix.c
>>>>>> @@ -104,34 +104,32 @@ static void piix_ide_reset(DeviceState *dev)
>>>>>>        pci_set_byte(pci_conf + 0x20, 0x01);  /* BMIBA: 20-23h */
>>>>>>    }
>>>>>>    -static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, ISABus *isa_bus,
>>>>>> -                              Error **errp)
>>>>>> +static void pci_piix_init_bus(PCIIDEState *d, unsigned i, ISABus *isa_bus)
>>>>>>    {
>>>>>>        static const struct {
>>>>>>            int iobase;
>>>>>>            int iobase2;
>>>>>>            int isairq;
>>>>>>        } port_info[] = {
>>>>>> -        {0x1f0, 0x3f6, 14},
>>>>>> -        {0x170, 0x376, 15},
>>>>>> +        {0x1f0, 0x3f4, 14},
>>>>>> +        {0x170, 0x374, 15},
>>>>>>        };
>>>>>> -    int ret;
>>>>>> +    MemoryRegion *address_space_io = pci_address_space_io(PCI_DEVICE(d));
>>>>>>          ide_bus_init(&d->bus[i], sizeof(d->bus[i]), DEVICE(d), i, 2);
>>>>>> -    ret = ide_init_ioport(&d->bus[i], NULL, port_info[i].iobase,
>>>>>> -                          port_info[i].iobase2);
>>>>>> -    if (ret) {
>>>>>> -        error_setg_errno(errp, -ret, "Failed to realize %s port %u",
>>>>>> -                         object_get_typename(OBJECT(d)), i);
>>>>>> -        return false;
>>>>>> -    }
>>>>>> +    memory_region_add_subregion(address_space_io, port_info[i].iobase,
>>>>>> +                                &d->data_ops[i]);
>>>>>> +    /*
>>>>>> +     * PIIX forwards the last byte of cmd_ops to ISA. Model this using a low
>>>>>> +     * prio so competing memory regions take precedence.
>>>>>> +     */
>>>>>> +    memory_region_add_subregion_overlap(address_space_io, port_info[i].iobase2,
>>>>>> +                                        &d->cmd_ops[i], -1);
>>>>> 
>>>>> Interesting. Is this behaviour documented somewhere and/or used in one of your test images at all? If I'd have seen this myself, I probably thought that the addresses were a typo...
>>>> 
>>>> I first  stumbled upon this and wondered why this code was working with VIA_IDE (through my pc-via branch). Then I found the correct offsets there which are confirmed in the piix datasheet, e.g.: "Secondary Control Block Offset: 0374h"
>>> 
>>> In case you were wondering about the forwarding of the last byte the datasheet says: "Accesses to byte 3 of the Control Block are forwarded to ISA where the floppy disk controller responds."
>>
>>Ahhh okay okay I see what's happening here: the PIIX IDE is assuming that the legacy ioport semantics are in operation here, which as you note above is where the FDC controller is also accessed via the above byte in the IDE control block. This is also why you need to change the address above from 0x3f6/0x376 to 0x3f4/0x374 when trying to use the MemoryRegions used for the PCI BARs since the PCI IDE controller specification requires a 4 byte allocation for the Control Block - see sections 2.0 and 2.2.
>
>Yes, PIIX assuming that might be the case. Why does it contradict the PCI IDE specification? PIIX seems to apply the apprppriate "workarounds" here.
>
>>
>>And that's fine, because the portio_lists used in ide_init_ioport() set up the legacy IDE ioports so that FDC accesses done in this way can succeed, and the PIIX IDE is hard-coded to legacy mode. So in fact PIIX IDE should keep using ide_init_ioport() rather than trying to re-use the BAR MemoryRegions so I think this patch should just be dropped.
>
>I was hoping to keep that patch...

The whole paragraph reads: "PIIX4 claims all accesses to these ranges, if enabled. The byte enables do not have to be externally decoded to assert DEVSEL#. Accesses to byte 3 of the Control Block are forwarded to ISA where the floppy disk controller responds." So PIIX doesn't look at the individual io ports but rather at the whole blocks covering them.

To me, this sounds like PIIX is applying the PCI IDE controller specification without the native option. In QEMU the block part of the specification is implemented by cmd_bar and data_bar. I think that reusing the blocks here in fact models the PIIX datasheet closer than the current implementation. I'd therefore keep this patch.

Best regards,
Bernhard

>
>Best regards,
>Bernhard
>
>>
>>>>> 
>>>>>>        ide_bus_init_output_irq(&d->bus[i],
>>>>>>                                isa_bus_get_irq(isa_bus, port_info[i].isairq));
>>>>>>          bmdma_init(&d->bus[i], &d->bmdma[i], d);
>>>>>>        ide_bus_register_restart_cb(&d->bus[i]);
>>>>>> -
>>>>>> -    return true;
>>>>>>    }
>>>>>>      static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
>>>>>> @@ -160,9 +158,7 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
>>>>>>        }
>>>>>>          for (unsigned i = 0; i < 2; i++) {
>>>>>> -        if (!pci_piix_init_bus(d, i, isa_bus, errp)) {
>>>>>> -            return;
>>>>>> -        }
>>>>>> +        pci_piix_init_bus(d, i, isa_bus);
>>>>>>        }
>>>>>>    }
>>
>>
>>ATB,
>>
>>Mark.


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 10/13] hw/ide/piix: Reuse PCIIDEState::{cmd,data}_ops
  2023-04-28 15:58             ` Bernhard Beschow
@ 2023-04-28 17:00               ` BALATON Zoltan
  0 siblings, 0 replies; 77+ messages in thread
From: BALATON Zoltan @ 2023-04-28 17:00 UTC (permalink / raw)
  To: Bernhard Beschow
  Cc: Mark Cave-Ayland, qemu-devel, qemu-block, Jiaxun Yang, John Snow,
	Huacai Chen, Philippe Mathieu-Daudé,
	qemu-ppc

On Fri, 28 Apr 2023, Bernhard Beschow wrote:
> Am 27. April 2023 18:15:24 UTC schrieb Bernhard Beschow <shentey@gmail.com>:
>> Am 27. April 2023 10:52:17 UTC schrieb Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>:
>>> On 26/04/2023 21:14, Bernhard Beschow wrote:
>>>> Am 26. April 2023 18:18:35 UTC schrieb Bernhard Beschow <shentey@gmail.com>:
>>>>> Am 26. April 2023 11:37:48 UTC schrieb Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>:
>>>>>> On 22/04/2023 16:07, Bernhard Beschow wrote:
>>>>>>> Now that PCIIDEState::{cmd,data}_ops are initialized in the base class
>>>>>>> constructor there is an opportunity for PIIX to reuse these attributes. This
>>>>>>> resolves usage of ide_init_ioport() which would fall back internally to using
>>>>>>> the isabus global due to NULL being passed as ISADevice by PIIX.
>>>>>>>
>>>>>>> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
>>>>>>> ---
>>>>>>>    hw/ide/piix.c | 30 +++++++++++++-----------------
>>>>>>>    1 file changed, 13 insertions(+), 17 deletions(-)
>>>>>>>
>>>>>>> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
>>>>>>> index a3a15dc7db..406a67fa0f 100644
>>>>>>> --- a/hw/ide/piix.c
>>>>>>> +++ b/hw/ide/piix.c
>>>>>>> @@ -104,34 +104,32 @@ static void piix_ide_reset(DeviceState *dev)
>>>>>>>        pci_set_byte(pci_conf + 0x20, 0x01);  /* BMIBA: 20-23h */
>>>>>>>    }
>>>>>>>    -static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, ISABus *isa_bus,
>>>>>>> -                              Error **errp)
>>>>>>> +static void pci_piix_init_bus(PCIIDEState *d, unsigned i, ISABus *isa_bus)
>>>>>>>    {
>>>>>>>        static const struct {
>>>>>>>            int iobase;
>>>>>>>            int iobase2;
>>>>>>>            int isairq;
>>>>>>>        } port_info[] = {
>>>>>>> -        {0x1f0, 0x3f6, 14},
>>>>>>> -        {0x170, 0x376, 15},
>>>>>>> +        {0x1f0, 0x3f4, 14},
>>>>>>> +        {0x170, 0x374, 15},
>>>>>>>        };
>>>>>>> -    int ret;
>>>>>>> +    MemoryRegion *address_space_io = pci_address_space_io(PCI_DEVICE(d));
>>>>>>>          ide_bus_init(&d->bus[i], sizeof(d->bus[i]), DEVICE(d), i, 2);
>>>>>>> -    ret = ide_init_ioport(&d->bus[i], NULL, port_info[i].iobase,
>>>>>>> -                          port_info[i].iobase2);
>>>>>>> -    if (ret) {
>>>>>>> -        error_setg_errno(errp, -ret, "Failed to realize %s port %u",
>>>>>>> -                         object_get_typename(OBJECT(d)), i);
>>>>>>> -        return false;
>>>>>>> -    }
>>>>>>> +    memory_region_add_subregion(address_space_io, port_info[i].iobase,
>>>>>>> +                                &d->data_ops[i]);
>>>>>>> +    /*
>>>>>>> +     * PIIX forwards the last byte of cmd_ops to ISA. Model this using a low
>>>>>>> +     * prio so competing memory regions take precedence.
>>>>>>> +     */
>>>>>>> +    memory_region_add_subregion_overlap(address_space_io, port_info[i].iobase2,
>>>>>>> +                                        &d->cmd_ops[i], -1);
>>>>>>
>>>>>> Interesting. Is this behaviour documented somewhere and/or used in one of your test images at all? If I'd have seen this myself, I probably thought that the addresses were a typo...
>>>>>
>>>>> I first  stumbled upon this and wondered why this code was working with VIA_IDE (through my pc-via branch). Then I found the correct offsets there which are confirmed in the piix datasheet, e.g.: "Secondary Control Block Offset: 0374h"
>>>>
>>>> In case you were wondering about the forwarding of the last byte the datasheet says: "Accesses to byte 3 of the Control Block are forwarded to ISA where the floppy disk controller responds."
>>>
>>> Ahhh okay okay I see what's happening here: the PIIX IDE is assuming that the legacy ioport semantics are in operation here, which as you note above is where the FDC controller is also accessed via the above byte in the IDE control block. This is also why you need to change the address above from 0x3f6/0x376 to 0x3f4/0x374 when trying to use the MemoryRegions used for the PCI BARs since the PCI IDE controller specification requires a 4 byte allocation for the Control Block - see sections 2.0 and 2.2.
>>
>> Yes, PIIX assuming that might be the case. Why does it contradict the PCI IDE specification? PIIX seems to apply the apprppriate "workarounds" here.
>>
>>>
>>> And that's fine, because the portio_lists used in ide_init_ioport() set up the legacy IDE ioports so that FDC accesses done in this way can succeed, and the PIIX IDE is hard-coded to legacy mode. So in fact PIIX IDE should keep using ide_init_ioport() rather than trying to re-use the BAR MemoryRegions so I think this patch should just be dropped.
>>
>> I was hoping to keep that patch...
>
> The whole paragraph reads: "PIIX4 claims all accesses to these ranges, 
> if enabled. The byte enables do not have to be externally decoded to 
> assert DEVSEL#. Accesses to byte 3 of the Control Block are forwarded to 
> ISA where the floppy disk controller responds." So PIIX doesn't look at 
> the individual io ports but rather at the whole blocks covering them.

I don't mind either way if this patch is dropped or not, I could imagine 
there could be reasons for both decisions. Also this is changing piix 
which I'm not concerned with but still commenting on this hoping to help 
to reach a decision.

> To me, this sounds like PIIX is applying the PCI IDE controller 
> specification without the native option.

What is that? Isn't "PCI IDE without native option" just legacy IDE i.e. 
fixed io regions and 14/15 IRQs? If so then it could be either modelled 
with ISA functions as it is now or you could reuse code from PCI IDE which 
would normally allow to set these io regions via BARs but not using thar 
here and just hard coding it to legacy ports.

> In QEMU the block part of the 
> specification is implemented by cmd_bar and data_bar. I think that 
> reusing the blocks here in fact models the PIIX datasheet closer than 
> the current implementation. I'd therefore keep this patch.

I'm not sure PIIX follows the PCI IDE spec and you may just try too hard 
to reuse code from an unrelated model here that happens to match as both 
are following legacy ISA IDE for compatibility. That's not necessarily a 
problem, but just call it what it is and keep the naming consistent to PCI 
IDE where these are BARs but are not used as such here. You can add a 
comment to note this if it disturbs you to explain why these are 
hardcoded here.

On the other hand if we consider this a legacy device that should be 
modelled accordingly then this patch may not be needed which is I think 
what Mark pointed out.

Now the question is if we want to reduce the use of legacy ISA IDE 
functions hoping we could get rid of it eventually so we go with reusing a 
slightly unrelated PCI IDE model which would work here and would allow 
more code sharing; or we want to reduce code churn and keep the model as 
it is which is already modelling the device as legacy IDE.

I can't decide on that. Dropping the patch reduces code churn and may be 
slighly cleaner but keeping it may allow more code reuse and potentially 
removing some legacy ISA stuff which may allow simplifying that part, even 
if it may need a comment here to explain that more here. Both sides have 
merrits and don't know who could be the one to make a decison. Maybe the 
maintainer of the code part? (Oops, it does not really have one... Then 
no idea.)

I don't know this well and did not follow it too deeply so in case I've 
completely misunderstood it or missed an important detail then just 
disregard all of the above.

Regards,
BALATON Zoltan


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 10/13] hw/ide/piix: Reuse PCIIDEState::{cmd,data}_ops
  2023-04-27 18:15           ` Bernhard Beschow
  2023-04-28 15:58             ` Bernhard Beschow
@ 2023-05-03 19:52             ` Mark Cave-Ayland
  2023-05-13 12:21               ` Bernhard Beschow
  1 sibling, 1 reply; 77+ messages in thread
From: Mark Cave-Ayland @ 2023-05-03 19:52 UTC (permalink / raw)
  To: Bernhard Beschow, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc

On 27/04/2023 19:15, Bernhard Beschow wrote:

> Am 27. April 2023 10:52:17 UTC schrieb Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>:
>> On 26/04/2023 21:14, Bernhard Beschow wrote:
>>
>>> Am 26. April 2023 18:18:35 UTC schrieb Bernhard Beschow <shentey@gmail.com>:
>>>>
>>>>
>>>> Am 26. April 2023 11:37:48 UTC schrieb Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>:
>>>>> On 22/04/2023 16:07, Bernhard Beschow wrote:
>>>>>
>>>>>> Now that PCIIDEState::{cmd,data}_ops are initialized in the base class
>>>>>> constructor there is an opportunity for PIIX to reuse these attributes. This
>>>>>> resolves usage of ide_init_ioport() which would fall back internally to using
>>>>>> the isabus global due to NULL being passed as ISADevice by PIIX.
>>>>>>
>>>>>> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
>>>>>> ---
>>>>>>     hw/ide/piix.c | 30 +++++++++++++-----------------
>>>>>>     1 file changed, 13 insertions(+), 17 deletions(-)
>>>>>>
>>>>>> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
>>>>>> index a3a15dc7db..406a67fa0f 100644
>>>>>> --- a/hw/ide/piix.c
>>>>>> +++ b/hw/ide/piix.c
>>>>>> @@ -104,34 +104,32 @@ static void piix_ide_reset(DeviceState *dev)
>>>>>>         pci_set_byte(pci_conf + 0x20, 0x01);  /* BMIBA: 20-23h */
>>>>>>     }
>>>>>>     -static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, ISABus *isa_bus,
>>>>>> -                              Error **errp)
>>>>>> +static void pci_piix_init_bus(PCIIDEState *d, unsigned i, ISABus *isa_bus)
>>>>>>     {
>>>>>>         static const struct {
>>>>>>             int iobase;
>>>>>>             int iobase2;
>>>>>>             int isairq;
>>>>>>         } port_info[] = {
>>>>>> -        {0x1f0, 0x3f6, 14},
>>>>>> -        {0x170, 0x376, 15},
>>>>>> +        {0x1f0, 0x3f4, 14},
>>>>>> +        {0x170, 0x374, 15},
>>>>>>         };
>>>>>> -    int ret;
>>>>>> +    MemoryRegion *address_space_io = pci_address_space_io(PCI_DEVICE(d));
>>>>>>           ide_bus_init(&d->bus[i], sizeof(d->bus[i]), DEVICE(d), i, 2);
>>>>>> -    ret = ide_init_ioport(&d->bus[i], NULL, port_info[i].iobase,
>>>>>> -                          port_info[i].iobase2);
>>>>>> -    if (ret) {
>>>>>> -        error_setg_errno(errp, -ret, "Failed to realize %s port %u",
>>>>>> -                         object_get_typename(OBJECT(d)), i);
>>>>>> -        return false;
>>>>>> -    }
>>>>>> +    memory_region_add_subregion(address_space_io, port_info[i].iobase,
>>>>>> +                                &d->data_ops[i]);
>>>>>> +    /*
>>>>>> +     * PIIX forwards the last byte of cmd_ops to ISA. Model this using a low
>>>>>> +     * prio so competing memory regions take precedence.
>>>>>> +     */
>>>>>> +    memory_region_add_subregion_overlap(address_space_io, port_info[i].iobase2,
>>>>>> +                                        &d->cmd_ops[i], -1);
>>>>>
>>>>> Interesting. Is this behaviour documented somewhere and/or used in one of your test images at all? If I'd have seen this myself, I probably thought that the addresses were a typo...
>>>>
>>>> I first  stumbled upon this and wondered why this code was working with VIA_IDE (through my pc-via branch). Then I found the correct offsets there which are confirmed in the piix datasheet, e.g.: "Secondary Control Block Offset: 0374h"
>>>
>>> In case you were wondering about the forwarding of the last byte the datasheet says: "Accesses to byte 3 of the Control Block are forwarded to ISA where the floppy disk controller responds."
>>
>> Ahhh okay okay I see what's happening here: the PIIX IDE is assuming that the legacy ioport semantics are in operation here, which as you note above is where the FDC controller is also accessed via the above byte in the IDE control block. This is also why you need to change the address above from 0x3f6/0x376 to 0x3f4/0x374 when trying to use the MemoryRegions used for the PCI BARs since the PCI IDE controller specification requires a 4 byte allocation for the Control Block - see sections 2.0 and 2.2.
> 
> Yes, PIIX assuming that might be the case. Why does it contradict the PCI IDE specification? PIIX seems to apply the apprppriate "workarounds" here.

Can you explain a bit more about where you see the contradiction? At first glance it 
looks okay to me.

>> And that's fine, because the portio_lists used in ide_init_ioport() set up the legacy IDE ioports so that FDC accesses done in this way can succeed, and the PIIX IDE is hard-coded to legacy mode. So in fact PIIX IDE should keep using ide_init_ioport() rather than trying to re-use the BAR MemoryRegions so I think this patch should just be dropped.
> 
> I was hoping to keep that patch...

Perhaps a different way to think about it is that from QEMU's perspective a BAR is a 
MemoryRegion that can be dynamically assigned/updated and cannot overlap, whereas the 
portio_list implementation also handles unaligned accesses and overlapping sparse 
accesses. Since the latter is the exact case here with the IDE/FDC then it seems the 
existing portio_list solution already does the "right thing" instead of having to 
manually emulate the overlapping dispatch.


ATB,

Mark.



^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 11/13] hw/ide/sii3112: Reuse PCIIDEState::{cmd,data}_ops
  2023-04-27 12:55           ` BALATON Zoltan
@ 2023-05-03 20:25             ` Mark Cave-Ayland
  0 siblings, 0 replies; 77+ messages in thread
From: Mark Cave-Ayland @ 2023-05-03 20:25 UTC (permalink / raw)
  To: BALATON Zoltan
  Cc: Bernhard Beschow, qemu-devel, qemu-block, Jiaxun Yang, John Snow,
	Huacai Chen, Philippe Mathieu-Daudé,
	qemu-ppc

On 27/04/2023 13:55, BALATON Zoltan wrote:

> On Thu, 27 Apr 2023, Mark Cave-Ayland wrote:
>> On 27/04/2023 00:24, BALATON Zoltan wrote:
>>> On Wed, 26 Apr 2023, Bernhard Beschow wrote:
>>>> Am 26. April 2023 11:41:54 UTC schrieb Mark Cave-Ayland 
>>>> <mark.cave-ayland@ilande.co.uk>:
>>>>> On 22/04/2023 16:07, Bernhard Beschow wrote:
>>>>>
>>>>>> Allows to unexport pci_ide_{cmd,data}_le_ops and models TYPE_SII3112_PCI as a
>>>>>> standard-compliant PCI IDE device.
>>>>>>
>>>>>> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
>>>>>> ---
>>>>>>   include/hw/ide/pci.h |  2 --
>>>>>>   hw/ide/pci.c         |  4 ++--
>>>>>>   hw/ide/sii3112.c     | 50 ++++++++++++++++----------------------------
>>>>>>   3 files changed, 20 insertions(+), 36 deletions(-)
>>>>>>
>>>>>> diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
>>>>>> index 5025df5b82..dbb4b13161 100644
>>>>>> --- a/include/hw/ide/pci.h
>>>>>> +++ b/include/hw/ide/pci.h
>>>>>> @@ -62,6 +62,4 @@ void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val);
>>>>>>   extern MemoryRegionOps bmdma_addr_ioport_ops;
>>>>>>   void pci_ide_create_devs(PCIDevice *dev);
>>>>>>   -extern const MemoryRegionOps pci_ide_cmd_le_ops;
>>>>>> -extern const MemoryRegionOps pci_ide_data_le_ops;
>>>>>>   #endif
>>>>>> diff --git a/hw/ide/pci.c b/hw/ide/pci.c
>>>>>> index b2fcc00a64..97ccc75aa6 100644
>>>>>> --- a/hw/ide/pci.c
>>>>>> +++ b/hw/ide/pci.c
>>>>>> @@ -60,7 +60,7 @@ static void pci_ide_ctrl_write(void *opaque, hwaddr addr,
>>>>>>       ide_ctrl_write(bus, addr + 2, data);
>>>>>>   }
>>>>>>   -const MemoryRegionOps pci_ide_cmd_le_ops = {
>>>>>> +static const MemoryRegionOps pci_ide_cmd_le_ops = {
>>>>>>       .read = pci_ide_status_read,
>>>>>>       .write = pci_ide_ctrl_write,
>>>>>>       .endianness = DEVICE_LITTLE_ENDIAN,
>>>>>> @@ -98,7 +98,7 @@ static void pci_ide_data_write(void *opaque, hwaddr addr,
>>>>>>       }
>>>>>>   }
>>>>>>   -const MemoryRegionOps pci_ide_data_le_ops = {
>>>>>> +static const MemoryRegionOps pci_ide_data_le_ops = {
>>>>>>       .read = pci_ide_data_read,
>>>>>>       .write = pci_ide_data_write,
>>>>>>       .endianness = DEVICE_LITTLE_ENDIAN,
>>>>>> diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c
>>>>>> index 0af897a9ef..9cf920369f 100644
>>>>>> --- a/hw/ide/sii3112.c
>>>>>> +++ b/hw/ide/sii3112.c
>>>>>> @@ -88,21 +88,9 @@ static uint64_t sii3112_reg_read(void *opaque, hwaddr addr,
>>>>>>           val |= (d->regs[1].confstat & (1UL << 11) ? (1 << 4) : 0);
>>>>>>           val |= (uint32_t)d->i.bmdma[1].status << 16;
>>>>>>           break;
>>>>>> -    case 0x80 ... 0x87:
>>>>>> -        val = pci_ide_data_le_ops.read(&d->i.bus[0], addr - 0x80, size);
>>>>>> -        break;
>>>>>> -    case 0x8a:
>>>>>> -        val = pci_ide_cmd_le_ops.read(&d->i.bus[0], 2, size);
>>>>>> -        break;
>>>>>>       case 0xa0:
>>>>>>           val = d->regs[0].confstat;
>>>>>>           break;
>>>>>> -    case 0xc0 ... 0xc7:
>>>>>> -        val = pci_ide_data_le_ops.read(&d->i.bus[1], addr - 0xc0, size);
>>>>>> -        break;
>>>>>> -    case 0xca:
>>>>>> -        val = pci_ide_cmd_le_ops.read(&d->i.bus[1], 2, size);
>>>>>> -        break;
>>>>>>       case 0xe0:
>>>>>>           val = d->regs[1].confstat;
>>>>>>           break;
>>>>>> @@ -171,18 +159,6 @@ static void sii3112_reg_write(void *opaque, hwaddr addr,
>>>>>>       case 0x0c ... 0x0f:
>>>>>>           bmdma_addr_ioport_ops.write(&d->i.bmdma[1], addr - 12, val, size);
>>>>>>           break;
>>>>>> -    case 0x80 ... 0x87:
>>>>>> -        pci_ide_data_le_ops.write(&d->i.bus[0], addr - 0x80, val, size);
>>>>>> -        break;
>>>>>> -    case 0x8a:
>>>>>> -        pci_ide_cmd_le_ops.write(&d->i.bus[0], 2, val, size);
>>>>>> -        break;
>>>>>> -    case 0xc0 ... 0xc7:
>>>>>> -        pci_ide_data_le_ops.write(&d->i.bus[1], addr - 0xc0, val, size);
>>>>>> -        break;
>>>>>> -    case 0xca:
>>>>>> -        pci_ide_cmd_le_ops.write(&d->i.bus[1], 2, val, size);
>>>>>> -        break;
>>>>>>       case 0x100:
>>>>>>           d->regs[0].scontrol = val & 0xfff;
>>>>>>           if (val & 1) {
>>>>>> @@ -259,6 +235,11 @@ static void sii3112_pci_realize(PCIDevice *dev, Error **errp)
>>>>>>       pci_config_set_interrupt_pin(dev->config, 1);
>>>>>>       pci_set_byte(dev->config + PCI_CACHE_LINE_SIZE, 8);
>>>>>>   +    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->data_ops[0]);
>>>>>> +    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->cmd_ops[0]);
>>>>>> +    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &s->data_ops[1]);
>>>>>> +    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &s->cmd_ops[1]);
>>>>>> +
>>>>>>       /* BAR5 is in PCI memory space */
>>>>>>       memory_region_init_io(&d->mmio, OBJECT(d), &sii3112_reg_ops, d,
>>>>>>                            "sii3112.bar5", 0x200);
>>>>>> @@ -266,17 +247,22 @@ static void sii3112_pci_realize(PCIDevice *dev, Error 
>>>>>> **errp)
>>>>>>         /* BAR0-BAR4 are PCI I/O space aliases into BAR5 */
>>>>>>       mr = g_new(MemoryRegion, 1);
>>>>>> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar0", &d->mmio, 0x80, 8);
>>>>>> -    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, mr);
>>>>>> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar0", &s->data_ops[0], 0,
>>>>>> +                             memory_region_size(&s->data_ops[0]));
>>>>>> +    memory_region_add_subregion_overlap(&d->mmio, 0x80, mr, 1);
>>>>>>       mr = g_new(MemoryRegion, 1);
>>>>>> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar1", &d->mmio, 0x88, 4);
>>>>>> -    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, mr);
>>>>>> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar1", &s->cmd_ops[0], 0,
>>>>>> +                             memory_region_size(&s->cmd_ops[0]));
>>>>>> +    memory_region_add_subregion_overlap(&d->mmio, 0x88, mr, 1);
>>>>>>       mr = g_new(MemoryRegion, 1);
>>>>>> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar2", &d->mmio, 0xc0, 8);
>>>>>> -    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, mr);
>>>>>> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar2", &s->data_ops[1], 0,
>>>>>> +                             memory_region_size(&s->data_ops[1]));
>>>>>> +    memory_region_add_subregion_overlap(&d->mmio, 0xc0, mr, 1);
>>>>>>       mr = g_new(MemoryRegion, 1);
>>>>>> -    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar3", &d->mmio, 0xc8, 4);
>>>>>> -    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, mr);
>>>>>> +    memory_region_init_alias(mr, OBJECT(d), "sii3112.bar3", &s->cmd_ops[1], 0,
>>>>>> +                             memory_region_size(&s->cmd_ops[1]));
>>>>>> +    memory_region_add_subregion_overlap(&d->mmio, 0xc8, mr, 1);
>>>>>> +
>>>>>>       mr = g_new(MemoryRegion, 1);
>>>>>>       memory_region_init_alias(mr, OBJECT(d), "sii3112.bar4", &d->mmio, 0, 16);
>>>>>>       pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, mr);
>>>>>
>>>>> So if I read this right, this is now switching the aliases over on BAR5 to allow 
>>>>> re-use of the common IDE/BMDMA BARs in PCIIDEState? If that's correct then I 
>>>>> think the commit message needs a bit more detail, otherwise:
>>>>
>>>> That's correct. Besides improving the commit message I'll additonally split this 
>>>> patch into two to show what's going on.
>>>>
>>>> Furthermore, I'd init the memory regions in sii3112's init method rather than in 
>>>> realize(). This will be more consistent with the other PCI IDE device models and 
>>>> with the other memory regions.
>>>
>>> Why is an init method meeded? If it's not needed why add it? Just keep it simple. 
>>> My view on these methods is that usually only a realize method is needed which is 
>>> the normal constructor of the object, but sometimes we need some properties or 
>>> something else to be available that can configure the object before realising 
>>> which is when an init method is needed. Sometimes QEMU creates an object then 
>>> destroys it without realising (I think e.g. when using help to query device 
>>> properties) so then memory regions would be created and destroyed pointlessly. So 
>>> unless there's a good reason to have an init method I'd leave this device without 
>>> one to keep it simple. That other devices have an init method does not explain why 
>>> this one should have one. Maybe those devices need it for some properties or they 
>>> are just old code and not properly QOM'ified.
>>
>> From memory one of the QOM developer guides recommends that all initialisation 
>> should be placed in .instance_init, except for objects that depend on properties 
>> which are set after .instance_init but before .realize().
> 
> Any pointer to that doc? I've tried to find it but I couldn't. The docs/devel/qom.rst 
> does not say anything about this, The older collection of docs here: 
> https://habkost.net/posts/2016/11/incomplete-list-of-qemu-apis.html
> also does not have anything useful either, those mostly talk about properties 
> instead. The header include/hw/qdev-core.h has some info but it only says that 
> "Trivial field initializations should go into #TypeInfo.instance_init. Operations 
> depending on @props static properties should go into @realize." So I don't see a 
> clear guide on what should go where unless something is needed before the device is 
> realized.

I found a reference to this in Anthony's original documentation at 
https://lists.nongnu.org/archive/html/qemu-devel/2012-08/msg02271.html (see the 
section "Using Instance Initialization").

>> Certainly there is some flexibility around this for legacy code, however quite a 
>> few reviewers have picked up on previous series I have posted when I have forgotten 
>> to move something from .realize() to .instance_init() when allowed after refactoring.
> 
> I don't mind if things are done in init or realize as long as we have only one of 
> these unless we really need both. Having object init split into two functions for no 
> good reason just makes it mode confusing so I'd like to keep it at a single place for 
> simlicity. Between init and realize the latter seems to be more appropriate for 
> creating the things that are only needed when the object is really created and init 
> is for those that may be needed when the object is not fully up yet, e.g. for 
> introspection or working with connected objects. But for simple devices like sii3112 
> having more than a realize method probably does not make much sense. If you have 
> examples of those reviews you refer to maybe that explains this more. I just want to 
> avoid unneded complexity.

Note that the concept of realisation only exists for devices i.e. things derived from 
TYPE_DEVICE as opposed to things derived from TYPE_OBJECT.


ATB,

Mark.



^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 09/13] hw/ide/piix: Disuse isa_get_irq()
  2023-04-27 12:31       ` Mark Cave-Ayland
@ 2023-05-13 11:53         ` Bernhard Beschow
  2023-05-14 12:43           ` Mark Cave-Ayland
  0 siblings, 1 reply; 77+ messages in thread
From: Bernhard Beschow @ 2023-05-13 11:53 UTC (permalink / raw)
  To: Mark Cave-Ayland, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc, Thomas Huth



Am 27. April 2023 12:31:10 UTC schrieb Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>:
>On 26/04/2023 19:25, Bernhard Beschow wrote:
>
>> Am 26. April 2023 11:33:40 UTC schrieb Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>:
>>> On 22/04/2023 16:07, Bernhard Beschow wrote:
>>> 
>>>> isa_get_irq() asks for an ISADevice which piix-ide doesn't provide.
>>>> Passing a NULL pointer works but causes the isabus global to be used
>>>> then. By fishing out TYPE_ISA_BUS from the QOM tree it is possible to
>>>> achieve the same as using isa_get_irq().
>>>> 
>>>> This is an alternative solution to commit 9405d87be25d 'hw/ide: Fix
>>>> crash when plugging a piix3-ide device into the x-remote machine' which
>>>> allows for cleaning up the ISA API while keeping PIIX IDE functions
>>>> user-createable.
>>>> 
>>>> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
>>>> ---
>>>>    hw/ide/piix.c | 23 ++++++++++++++++++++---
>>>>    1 file changed, 20 insertions(+), 3 deletions(-)
>>>> 
>>>> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
>>>> index 6942b484f9..a3a15dc7db 100644
>>>> --- a/hw/ide/piix.c
>>>> +++ b/hw/ide/piix.c
>>>> @@ -104,7 +104,8 @@ static void piix_ide_reset(DeviceState *dev)
>>>>        pci_set_byte(pci_conf + 0x20, 0x01);  /* BMIBA: 20-23h */
>>>>    }
>>>>    -static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, Error **errp)
>>>> +static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, ISABus *isa_bus,
>>>> +                              Error **errp)
>>>>    {
>>>>        static const struct {
>>>>            int iobase;
>>>> @@ -124,7 +125,8 @@ static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, Error **errp)
>>>>                             object_get_typename(OBJECT(d)), i);
>>>>            return false;
>>>>        }
>>>> -    ide_bus_init_output_irq(&d->bus[i], isa_get_irq(NULL, port_info[i].isairq));
>>>> +    ide_bus_init_output_irq(&d->bus[i],
>>>> +                            isa_bus_get_irq(isa_bus, port_info[i].isairq));
>>> 
>>> I don't think is the right solution here, since ultimately we want to move the IRQ routing out of the device itself and into the PCI-ISA bridge. I'd go for the same solution as you've done for VIA IDE in patch 2, i.e. update the PIIX interrupt handler to set the legacy_irqs in PCIIDEState, and then wire them up to the ISA IRQs 14 and 15 similar to as Phil as done in his patches:
>> 
>> The problem is user-creatable PIIX-IDE. IMO we should stick to our deprecation process before going this step because this will break it.
>
>Thomas posted some links from previous discussions where it seems that this hack is still in use:
>
>https://lists.nongnu.org/archive/html/qemu-block/2019-07/msg00780.html
>https://lists.gnu.org/archive/html/qemu-block/2021-04/msg00746.html
>
>So it seems we can't even deprecate this, as it's working around missing functionality in q35 :(
>
>Certainly it seems that we should add a check that will fail the machine if there is more than one -device piix3-ide on the command line, since I can't see that could ever work properly.
>
>I'm leaning towards adding a device property that must be set to enabled in order for PIIX IDE realize() to succeed, leave it disabled by default and only enable it for the q35 machine. Does that seem like a reasonable solution?

I'd rather declare this to be out of scope of this series. First, this series contains a lot of material already. Second, this patch attempts to preserve current behavior.

This patch is actually a preparation for the next one. In the next patch the (non-obvious) check for presence of the ISABus get removed so we need this patch to preserve behavior. Otherwise machines without an ISA bus will crash if piix3-ide gets user-created. One machine that would crash is the "remote" machine IIRC.

Best regards,
Bernhard

>
>>> https://patchew.org/QEMU/20230302224058.43315-1-philmd@linaro.org/20230302224058.43315-4-philmd@linaro.org/
>>> 
>>> https://patchew.org/QEMU/20230302224058.43315-1-philmd@linaro.org/20230302224058.43315-5-philmd@linaro.org/
>>> 
>>> This also reminds me, given that the first patch above is doing wiring in pc_init1() then we are still missing part of your tidy-up series :/
>>> 
>>>>        bmdma_init(&d->bus[i], &d->bmdma[i], d);
>>>>        ide_bus_register_restart_cb(&d->bus[i]);
>>>> @@ -136,14 +138,29 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
>>>>    {
>>>>        PCIIDEState *d = PCI_IDE(dev);
>>>>        uint8_t *pci_conf = dev->config;
>>>> +    ISABus *isa_bus;
>>>> +    bool ambiguous;
>>>>          pci_conf[PCI_CLASS_PROG] = 0x80; // legacy ATA mode
>>>>          bmdma_init_ops(d, &piix_bmdma_ops);
>>>>        pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_ops);
>>>>    +    isa_bus = ISA_BUS(object_resolve_path_type("", TYPE_ISA_BUS, &ambiguous));
>>>> +    if (ambiguous) {
>>>> +        error_setg(errp,
>>>> +                   "More than one ISA bus found while %s supports only one",
>>>> +                   object_get_typename(OBJECT(d)));
>>>> +        return;
>>>> +    }
>>>> +    if (!isa_bus) {
>>>> +        error_setg(errp, "No ISA bus found while %s requires one",
>>>> +                   object_get_typename(OBJECT(d)));
>>>> +        return;
>>>> +    }
>>> 
>>> Again I think this should go away with using PCIIDEState's legacy_irqs, since you simply let the board wire them up to the ISABus (or not) as required.
>> 
>> Same here: This breaks user-creatable PIIX-IDE.
>> 
>>> 
>>>>        for (unsigned i = 0; i < 2; i++) {
>>>> -        if (!pci_piix_init_bus(d, i, errp)) {
>>>> +        if (!pci_piix_init_bus(d, i, isa_bus, errp)) {
>>>>                return;
>>>>            }
>>>>        }
>
>
>ATB,
>
>Mark.


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 10/13] hw/ide/piix: Reuse PCIIDEState::{cmd,data}_ops
  2023-05-03 19:52             ` Mark Cave-Ayland
@ 2023-05-13 12:21               ` Bernhard Beschow
  2023-05-18 14:53                 ` Mark Cave-Ayland
  0 siblings, 1 reply; 77+ messages in thread
From: Bernhard Beschow @ 2023-05-13 12:21 UTC (permalink / raw)
  To: Mark Cave-Ayland, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc



Am 3. Mai 2023 19:52:41 UTC schrieb Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>:
>On 27/04/2023 19:15, Bernhard Beschow wrote:
>
>> Am 27. April 2023 10:52:17 UTC schrieb Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>:
>>> On 26/04/2023 21:14, Bernhard Beschow wrote:
>>> 
>>>> Am 26. April 2023 18:18:35 UTC schrieb Bernhard Beschow <shentey@gmail.com>:
>>>>> 
>>>>> 
>>>>> Am 26. April 2023 11:37:48 UTC schrieb Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>:
>>>>>> On 22/04/2023 16:07, Bernhard Beschow wrote:
>>>>>> 
>>>>>>> Now that PCIIDEState::{cmd,data}_ops are initialized in the base class
>>>>>>> constructor there is an opportunity for PIIX to reuse these attributes. This
>>>>>>> resolves usage of ide_init_ioport() which would fall back internally to using
>>>>>>> the isabus global due to NULL being passed as ISADevice by PIIX.
>>>>>>> 
>>>>>>> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
>>>>>>> ---
>>>>>>>     hw/ide/piix.c | 30 +++++++++++++-----------------
>>>>>>>     1 file changed, 13 insertions(+), 17 deletions(-)
>>>>>>> 
>>>>>>> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
>>>>>>> index a3a15dc7db..406a67fa0f 100644
>>>>>>> --- a/hw/ide/piix.c
>>>>>>> +++ b/hw/ide/piix.c
>>>>>>> @@ -104,34 +104,32 @@ static void piix_ide_reset(DeviceState *dev)
>>>>>>>         pci_set_byte(pci_conf + 0x20, 0x01);  /* BMIBA: 20-23h */
>>>>>>>     }
>>>>>>>     -static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, ISABus *isa_bus,
>>>>>>> -                              Error **errp)
>>>>>>> +static void pci_piix_init_bus(PCIIDEState *d, unsigned i, ISABus *isa_bus)
>>>>>>>     {
>>>>>>>         static const struct {
>>>>>>>             int iobase;
>>>>>>>             int iobase2;
>>>>>>>             int isairq;
>>>>>>>         } port_info[] = {
>>>>>>> -        {0x1f0, 0x3f6, 14},
>>>>>>> -        {0x170, 0x376, 15},
>>>>>>> +        {0x1f0, 0x3f4, 14},
>>>>>>> +        {0x170, 0x374, 15},
>>>>>>>         };
>>>>>>> -    int ret;
>>>>>>> +    MemoryRegion *address_space_io = pci_address_space_io(PCI_DEVICE(d));
>>>>>>>           ide_bus_init(&d->bus[i], sizeof(d->bus[i]), DEVICE(d), i, 2);
>>>>>>> -    ret = ide_init_ioport(&d->bus[i], NULL, port_info[i].iobase,
>>>>>>> -                          port_info[i].iobase2);
>>>>>>> -    if (ret) {
>>>>>>> -        error_setg_errno(errp, -ret, "Failed to realize %s port %u",
>>>>>>> -                         object_get_typename(OBJECT(d)), i);
>>>>>>> -        return false;
>>>>>>> -    }
>>>>>>> +    memory_region_add_subregion(address_space_io, port_info[i].iobase,
>>>>>>> +                                &d->data_ops[i]);
>>>>>>> +    /*
>>>>>>> +     * PIIX forwards the last byte of cmd_ops to ISA. Model this using a low
>>>>>>> +     * prio so competing memory regions take precedence.
>>>>>>> +     */
>>>>>>> +    memory_region_add_subregion_overlap(address_space_io, port_info[i].iobase2,
>>>>>>> +                                        &d->cmd_ops[i], -1);
>>>>>> 
>>>>>> Interesting. Is this behaviour documented somewhere and/or used in one of your test images at all? If I'd have seen this myself, I probably thought that the addresses were a typo...
>>>>> 
>>>>> I first  stumbled upon this and wondered why this code was working with VIA_IDE (through my pc-via branch). Then I found the correct offsets there which are confirmed in the piix datasheet, e.g.: "Secondary Control Block Offset: 0374h"
>>>> 
>>>> In case you were wondering about the forwarding of the last byte the datasheet says: "Accesses to byte 3 of the Control Block are forwarded to ISA where the floppy disk controller responds."
>>> 
>>> Ahhh okay okay I see what's happening here: the PIIX IDE is assuming that the legacy ioport semantics are in operation here, which as you note above is where the FDC controller is also accessed via the above byte in the IDE control block. This is also why you need to change the address above from 0x3f6/0x376 to 0x3f4/0x374 when trying to use the MemoryRegions used for the PCI BARs since the PCI IDE controller specification requires a 4 byte allocation for the Control Block - see sections 2.0 and 2.2.
>> 
>> Yes, PIIX assuming that might be the case. Why does it contradict the PCI IDE specification? PIIX seems to apply the apprppriate "workarounds" here.
>
>Can you explain a bit more about where you see the contradiction? At first glance it looks okay to me.
>
>>> And that's fine, because the portio_lists used in ide_init_ioport() set up the legacy IDE ioports so that FDC accesses done in this way can succeed, and the PIIX IDE is hard-coded to legacy mode. So in fact PIIX IDE should keep using ide_init_ioport() rather than trying to re-use the BAR MemoryRegions so I think this patch should just be dropped.
>> 
>> I was hoping to keep that patch...
>
>Perhaps a different way to think about it is that from QEMU's perspective a BAR is a MemoryRegion that can be dynamically assigned/updated and cannot overlap, whereas the portio_list implementation also handles unaligned accesses and overlapping sparse accesses. Since the latter is the exact case here with the IDE/FDC then it seems the existing portio_list solution already does the "right thing" instead of having to manually emulate the overlapping dispatch.

I've had another look into the "PCI IDE Controller Specification Revision 1.0" which says:

"The Control Block registers consist of two bytes used for control/status of the IDE device. The second byte of this pair is read-only and has the interesting quirk where the top bit of this byte is shared with the floppy controller when the IDE device is mapped at 'compatibility' locations. It turns out that software controlling IDE devices (BIOS, drivers, etc.) does not use this register at all.

The exception for PCI IDE controllers to the ATA Standard is that only the first of the two bytes defined in the Control Block registers is implemented. This byte provides Alternate Status on reads and Device Control on writes. Accesses to the second byte of the Control Block registers (Drive Address) should be ignored by the PCI IDE controller."

So in fact the real PIIX does adhere to this standard and there is no reason to reject the idea behind this patch -- which is to make our PIIX device model implement this standard.

It's just that all our other PCI-IDE implementations need to implement this quirk as long as they implement the standard. And according to the Linux kernel they all do -- see its CONFIG_ATA_SFF.

Since this patch actually uncovered a small bug in the other device models I'd rather fix those, too. One way I could do this is to decrease the size of the memory region or to map with lower priority. What is the preferred fix? Any other ideas?

Note that this and the next patch resolve the last dependencies on the "isabus" global. So after this series we could apply some small patches posted before and get rid of the global entirely... And have as many ISA and LPC buses as we want!

Best regards,
Bernhard

>
>
>ATB,
>
>Mark.
>


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 09/13] hw/ide/piix: Disuse isa_get_irq()
  2023-05-13 11:53         ` Bernhard Beschow
@ 2023-05-14 12:43           ` Mark Cave-Ayland
  0 siblings, 0 replies; 77+ messages in thread
From: Mark Cave-Ayland @ 2023-05-14 12:43 UTC (permalink / raw)
  To: Bernhard Beschow, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc, Thomas Huth

On 13/05/2023 12:53, Bernhard Beschow wrote:

> Am 27. April 2023 12:31:10 UTC schrieb Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>:
>> On 26/04/2023 19:25, Bernhard Beschow wrote:
>>
>>> Am 26. April 2023 11:33:40 UTC schrieb Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>:
>>>> On 22/04/2023 16:07, Bernhard Beschow wrote:
>>>>
>>>>> isa_get_irq() asks for an ISADevice which piix-ide doesn't provide.
>>>>> Passing a NULL pointer works but causes the isabus global to be used
>>>>> then. By fishing out TYPE_ISA_BUS from the QOM tree it is possible to
>>>>> achieve the same as using isa_get_irq().
>>>>>
>>>>> This is an alternative solution to commit 9405d87be25d 'hw/ide: Fix
>>>>> crash when plugging a piix3-ide device into the x-remote machine' which
>>>>> allows for cleaning up the ISA API while keeping PIIX IDE functions
>>>>> user-createable.
>>>>>
>>>>> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
>>>>> ---
>>>>>     hw/ide/piix.c | 23 ++++++++++++++++++++---
>>>>>     1 file changed, 20 insertions(+), 3 deletions(-)
>>>>>
>>>>> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
>>>>> index 6942b484f9..a3a15dc7db 100644
>>>>> --- a/hw/ide/piix.c
>>>>> +++ b/hw/ide/piix.c
>>>>> @@ -104,7 +104,8 @@ static void piix_ide_reset(DeviceState *dev)
>>>>>         pci_set_byte(pci_conf + 0x20, 0x01);  /* BMIBA: 20-23h */
>>>>>     }
>>>>>     -static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, Error **errp)
>>>>> +static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, ISABus *isa_bus,
>>>>> +                              Error **errp)
>>>>>     {
>>>>>         static const struct {
>>>>>             int iobase;
>>>>> @@ -124,7 +125,8 @@ static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, Error **errp)
>>>>>                              object_get_typename(OBJECT(d)), i);
>>>>>             return false;
>>>>>         }
>>>>> -    ide_bus_init_output_irq(&d->bus[i], isa_get_irq(NULL, port_info[i].isairq));
>>>>> +    ide_bus_init_output_irq(&d->bus[i],
>>>>> +                            isa_bus_get_irq(isa_bus, port_info[i].isairq));
>>>>
>>>> I don't think is the right solution here, since ultimately we want to move the IRQ routing out of the device itself and into the PCI-ISA bridge. I'd go for the same solution as you've done for VIA IDE in patch 2, i.e. update the PIIX interrupt handler to set the legacy_irqs in PCIIDEState, and then wire them up to the ISA IRQs 14 and 15 similar to as Phil as done in his patches:
>>>
>>> The problem is user-creatable PIIX-IDE. IMO we should stick to our deprecation process before going this step because this will break it.
>>
>> Thomas posted some links from previous discussions where it seems that this hack is still in use:
>>
>> https://lists.nongnu.org/archive/html/qemu-block/2019-07/msg00780.html
>> https://lists.gnu.org/archive/html/qemu-block/2021-04/msg00746.html
>>
>> So it seems we can't even deprecate this, as it's working around missing functionality in q35 :(
>>
>> Certainly it seems that we should add a check that will fail the machine if there is more than one -device piix3-ide on the command line, since I can't see that could ever work properly.
>>
>> I'm leaning towards adding a device property that must be set to enabled in order for PIIX IDE realize() to succeed, leave it disabled by default and only enable it for the q35 machine. Does that seem like a reasonable solution?
> 
> I'd rather declare this to be out of scope of this series. First, this series contains a lot of material already. Second, this patch attempts to preserve current behavior.
> 
> This patch is actually a preparation for the next one. In the next patch the (non-obvious) check for presence of the ISABus get removed so we need this patch to preserve behavior. Otherwise machines without an ISA bus will crash if piix3-ide gets user-created. One machine that would crash is the "remote" machine IIRC.

Hmmm. At the moment we seem to have a circular dependency around all the various IDE 
tidy-up series around :/  If we decide that this series should go first then I prefer 
this solution to Phil's proposal which breaks the contract that 
qdev_connect_gpio_out() should always occur after realize.

Phil, how are things looking for your time re: these IDE changes - are you able to 
spend time looking at them?

Alternatively if you are happy for me to pick up the IDE stuff, pull everything 
together into a series proposal, and then submit the final PR then I'm happy to do 
that too.

> Best regards,
> Bernhard
> 
>>
>>>> https://patchew.org/QEMU/20230302224058.43315-1-philmd@linaro.org/20230302224058.43315-4-philmd@linaro.org/
>>>>
>>>> https://patchew.org/QEMU/20230302224058.43315-1-philmd@linaro.org/20230302224058.43315-5-philmd@linaro.org/
>>>>
>>>> This also reminds me, given that the first patch above is doing wiring in pc_init1() then we are still missing part of your tidy-up series :/
>>>>
>>>>>         bmdma_init(&d->bus[i], &d->bmdma[i], d);
>>>>>         ide_bus_register_restart_cb(&d->bus[i]);
>>>>> @@ -136,14 +138,29 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
>>>>>     {
>>>>>         PCIIDEState *d = PCI_IDE(dev);
>>>>>         uint8_t *pci_conf = dev->config;
>>>>> +    ISABus *isa_bus;
>>>>> +    bool ambiguous;
>>>>>           pci_conf[PCI_CLASS_PROG] = 0x80; // legacy ATA mode
>>>>>           bmdma_init_ops(d, &piix_bmdma_ops);
>>>>>         pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_ops);
>>>>>     +    isa_bus = ISA_BUS(object_resolve_path_type("", TYPE_ISA_BUS, &ambiguous));
>>>>> +    if (ambiguous) {
>>>>> +        error_setg(errp,
>>>>> +                   "More than one ISA bus found while %s supports only one",
>>>>> +                   object_get_typename(OBJECT(d)));
>>>>> +        return;
>>>>> +    }
>>>>> +    if (!isa_bus) {
>>>>> +        error_setg(errp, "No ISA bus found while %s requires one",
>>>>> +                   object_get_typename(OBJECT(d)));
>>>>> +        return;
>>>>> +    }
>>>>
>>>> Again I think this should go away with using PCIIDEState's legacy_irqs, since you simply let the board wire them up to the ISABus (or not) as required.
>>>
>>> Same here: This breaks user-creatable PIIX-IDE.
>>>
>>>>
>>>>>         for (unsigned i = 0; i < 2; i++) {
>>>>> -        if (!pci_piix_init_bus(d, i, errp)) {
>>>>> +        if (!pci_piix_init_bus(d, i, isa_bus, errp)) {
>>>>>                 return;
>>>>>             }
>>>>>         }


ATB,

Mark.



^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 10/13] hw/ide/piix: Reuse PCIIDEState::{cmd,data}_ops
  2023-05-13 12:21               ` Bernhard Beschow
@ 2023-05-18 14:53                 ` Mark Cave-Ayland
  2023-05-19 17:09                   ` Bernhard Beschow
  0 siblings, 1 reply; 77+ messages in thread
From: Mark Cave-Ayland @ 2023-05-18 14:53 UTC (permalink / raw)
  To: Bernhard Beschow, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc

On 13/05/2023 13:21, Bernhard Beschow wrote:

> Am 3. Mai 2023 19:52:41 UTC schrieb Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>:
>> On 27/04/2023 19:15, Bernhard Beschow wrote:
>>
>>> Am 27. April 2023 10:52:17 UTC schrieb Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>:
>>>> On 26/04/2023 21:14, Bernhard Beschow wrote:
>>>>
>>>>> Am 26. April 2023 18:18:35 UTC schrieb Bernhard Beschow <shentey@gmail.com>:
>>>>>>
>>>>>>
>>>>>> Am 26. April 2023 11:37:48 UTC schrieb Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>:
>>>>>>> On 22/04/2023 16:07, Bernhard Beschow wrote:
>>>>>>>
>>>>>>>> Now that PCIIDEState::{cmd,data}_ops are initialized in the base class
>>>>>>>> constructor there is an opportunity for PIIX to reuse these attributes. This
>>>>>>>> resolves usage of ide_init_ioport() which would fall back internally to using
>>>>>>>> the isabus global due to NULL being passed as ISADevice by PIIX.
>>>>>>>>
>>>>>>>> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
>>>>>>>> ---
>>>>>>>>      hw/ide/piix.c | 30 +++++++++++++-----------------
>>>>>>>>      1 file changed, 13 insertions(+), 17 deletions(-)
>>>>>>>>
>>>>>>>> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
>>>>>>>> index a3a15dc7db..406a67fa0f 100644
>>>>>>>> --- a/hw/ide/piix.c
>>>>>>>> +++ b/hw/ide/piix.c
>>>>>>>> @@ -104,34 +104,32 @@ static void piix_ide_reset(DeviceState *dev)
>>>>>>>>          pci_set_byte(pci_conf + 0x20, 0x01);  /* BMIBA: 20-23h */
>>>>>>>>      }
>>>>>>>>      -static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, ISABus *isa_bus,
>>>>>>>> -                              Error **errp)
>>>>>>>> +static void pci_piix_init_bus(PCIIDEState *d, unsigned i, ISABus *isa_bus)
>>>>>>>>      {
>>>>>>>>          static const struct {
>>>>>>>>              int iobase;
>>>>>>>>              int iobase2;
>>>>>>>>              int isairq;
>>>>>>>>          } port_info[] = {
>>>>>>>> -        {0x1f0, 0x3f6, 14},
>>>>>>>> -        {0x170, 0x376, 15},
>>>>>>>> +        {0x1f0, 0x3f4, 14},
>>>>>>>> +        {0x170, 0x374, 15},
>>>>>>>>          };
>>>>>>>> -    int ret;
>>>>>>>> +    MemoryRegion *address_space_io = pci_address_space_io(PCI_DEVICE(d));
>>>>>>>>            ide_bus_init(&d->bus[i], sizeof(d->bus[i]), DEVICE(d), i, 2);
>>>>>>>> -    ret = ide_init_ioport(&d->bus[i], NULL, port_info[i].iobase,
>>>>>>>> -                          port_info[i].iobase2);
>>>>>>>> -    if (ret) {
>>>>>>>> -        error_setg_errno(errp, -ret, "Failed to realize %s port %u",
>>>>>>>> -                         object_get_typename(OBJECT(d)), i);
>>>>>>>> -        return false;
>>>>>>>> -    }
>>>>>>>> +    memory_region_add_subregion(address_space_io, port_info[i].iobase,
>>>>>>>> +                                &d->data_ops[i]);
>>>>>>>> +    /*
>>>>>>>> +     * PIIX forwards the last byte of cmd_ops to ISA. Model this using a low
>>>>>>>> +     * prio so competing memory regions take precedence.
>>>>>>>> +     */
>>>>>>>> +    memory_region_add_subregion_overlap(address_space_io, port_info[i].iobase2,
>>>>>>>> +                                        &d->cmd_ops[i], -1);
>>>>>>>
>>>>>>> Interesting. Is this behaviour documented somewhere and/or used in one of your test images at all? If I'd have seen this myself, I probably thought that the addresses were a typo...
>>>>>>
>>>>>> I first  stumbled upon this and wondered why this code was working with VIA_IDE (through my pc-via branch). Then I found the correct offsets there which are confirmed in the piix datasheet, e.g.: "Secondary Control Block Offset: 0374h"
>>>>>
>>>>> In case you were wondering about the forwarding of the last byte the datasheet says: "Accesses to byte 3 of the Control Block are forwarded to ISA where the floppy disk controller responds."
>>>>
>>>> Ahhh okay okay I see what's happening here: the PIIX IDE is assuming that the legacy ioport semantics are in operation here, which as you note above is where the FDC controller is also accessed via the above byte in the IDE control block. This is also why you need to change the address above from 0x3f6/0x376 to 0x3f4/0x374 when trying to use the MemoryRegions used for the PCI BARs since the PCI IDE controller specification requires a 4 byte allocation for the Control Block - see sections 2.0 and 2.2.
>>>
>>> Yes, PIIX assuming that might be the case. Why does it contradict the PCI IDE specification? PIIX seems to apply the apprppriate "workarounds" here.
>>
>> Can you explain a bit more about where you see the contradiction? At first glance it looks okay to me.
>>
>>>> And that's fine, because the portio_lists used in ide_init_ioport() set up the legacy IDE ioports so that FDC accesses done in this way can succeed, and the PIIX IDE is hard-coded to legacy mode. So in fact PIIX IDE should keep using ide_init_ioport() rather than trying to re-use the BAR MemoryRegions so I think this patch should just be dropped.
>>>
>>> I was hoping to keep that patch...
>>
>> Perhaps a different way to think about it is that from QEMU's perspective a BAR is a MemoryRegion that can be dynamically assigned/updated and cannot overlap, whereas the portio_list implementation also handles unaligned accesses and overlapping sparse accesses. Since the latter is the exact case here with the IDE/FDC then it seems the existing portio_list solution already does the "right thing" instead of having to manually emulate the overlapping dispatch.
> 
> I've had another look into the "PCI IDE Controller Specification Revision 1.0" which says:

Interesting: it looks as if we are getting different conclusions from the same document.

> "The Control Block registers consist of two bytes used for control/status of the IDE device. The second byte of this pair is read-only and has the interesting quirk where the top bit of this byte is shared with the floppy controller when the IDE device is mapped at 'compatibility' locations. It turns out that software controlling IDE devices (BIOS, drivers, etc.) does not use this register at all.

Just before this section the start of the paragraph reads "The ATA Standard defines 
two sets of registers known as Control Block Registers and Command Block Registers." 
which reads to me that the paragraph quoted above is describing the original ATA 
Standard behaviour, i.e. the expected behaviour for pre-PCI controllers or PCI IDE 
controllers in compatibility mode.

> The exception for PCI IDE controllers to the ATA Standard is that only the first of the two bytes defined in the Control Block registers is implemented. This byte provides Alternate Status on reads and Device Control on writes. Accesses to the second byte of the Control Block registers (Drive Address) should be ignored by the PCI IDE controller."

And this paragraph then leads onto the differences for PCI IDE controllers which are 
that the second (shared) byte in the Control Block is ignored, which again makes 
sense from a PCI perspective since PCI BARs cannot overlap. But that doesn't matter 
in PCI native mode because the BIOS/OS will have moved the BAR to a suitable memory 
address that doesn't clash with the floppy drive.

> So in fact the real PIIX does adhere to this standard and there is no reason to reject the idea behind this patch -- which is to make our PIIX device model implement this standard.
> 
> It's just that all our other PCI-IDE implementations need to implement this quirk as long as they implement the standard. And according to the Linux kernel they all do -- see its CONFIG_ATA_SFF.

Another couple of hints that the registers in PCI IDE controllers in compatibility 
mode aren't accessed through PCI BARs can also be found: i) the table in section 2.1 
for compatibility mode uses fixed addresses whilst the table in section 2.2 
references BAs and ii) section 2.4 suggests that PCI controllers in compatibility 
mode always ignore the BARs.

Now it could be that the description in the PIIX datasheet indicates that the PCI IO 
address is hardcoded and then the second byte (re)dispatched to the ISA bus, but then 
I would argue that this is an implementation detail: from QEMU's perspective there is 
zero difference between this and the existing IDE portio_list, and as a bonus the 
existing compatibility behaviour is completely unaffected by any PCI BARs.

> Since this patch actually uncovered a small bug in the other device models I'd rather fix those, too. One way I could do this is to decrease the size of the memory region or to map with lower priority. What is the preferred fix? Any other ideas?
> 
> Note that this and the next patch resolve the last dependencies on the "isabus" global. So after this series we could apply some small patches posted before and get rid of the global entirely... And have as many ISA and LPC buses as we want!

This is the part I think we can do better with: both Phil and I have patches that 
remove the isabus reference from the IDE ioports e.g. 
https://patchew.org/QEMU/20230302224058.43315-1-philmd@linaro.org/20230302224058.43315-9-philmd@linaro.org/ 
so dropping this patch shouldn't affect our ability to remove the isabus global.

Do you have an example of a use-case you have for multiple ISA buses? I'm fairly sure 
that this wouldn't work on x86 PC machines with a single PCI root bus for example.


ATB,

Mark.



^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 10/13] hw/ide/piix: Reuse PCIIDEState::{cmd,data}_ops
  2023-05-18 14:53                 ` Mark Cave-Ayland
@ 2023-05-19 17:09                   ` Bernhard Beschow
  0 siblings, 0 replies; 77+ messages in thread
From: Bernhard Beschow @ 2023-05-19 17:09 UTC (permalink / raw)
  To: Mark Cave-Ayland, qemu-devel
  Cc: qemu-block, Jiaxun Yang, BALATON Zoltan, John Snow, Huacai Chen,
	Philippe Mathieu-Daudé,
	qemu-ppc



Am 18. Mai 2023 14:53:26 UTC schrieb Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>:
>On 13/05/2023 13:21, Bernhard Beschow wrote:
>
>> Am 3. Mai 2023 19:52:41 UTC schrieb Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>:
>>> On 27/04/2023 19:15, Bernhard Beschow wrote:
>>> 
>>>> Am 27. April 2023 10:52:17 UTC schrieb Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>:
>>>>> On 26/04/2023 21:14, Bernhard Beschow wrote:
>>>>> 
>>>>>> Am 26. April 2023 18:18:35 UTC schrieb Bernhard Beschow <shentey@gmail.com>:
>>>>>>> 
>>>>>>> 
>>>>>>> Am 26. April 2023 11:37:48 UTC schrieb Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>:
>>>>>>>> On 22/04/2023 16:07, Bernhard Beschow wrote:
>>>>>>>> 
>>>>>>>>> Now that PCIIDEState::{cmd,data}_ops are initialized in the base class
>>>>>>>>> constructor there is an opportunity for PIIX to reuse these attributes. This
>>>>>>>>> resolves usage of ide_init_ioport() which would fall back internally to using
>>>>>>>>> the isabus global due to NULL being passed as ISADevice by PIIX.
>>>>>>>>> 
>>>>>>>>> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
>>>>>>>>> ---
>>>>>>>>>      hw/ide/piix.c | 30 +++++++++++++-----------------
>>>>>>>>>      1 file changed, 13 insertions(+), 17 deletions(-)
>>>>>>>>> 
>>>>>>>>> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
>>>>>>>>> index a3a15dc7db..406a67fa0f 100644
>>>>>>>>> --- a/hw/ide/piix.c
>>>>>>>>> +++ b/hw/ide/piix.c
>>>>>>>>> @@ -104,34 +104,32 @@ static void piix_ide_reset(DeviceState *dev)
>>>>>>>>>          pci_set_byte(pci_conf + 0x20, 0x01);  /* BMIBA: 20-23h */
>>>>>>>>>      }
>>>>>>>>>      -static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, ISABus *isa_bus,
>>>>>>>>> -                              Error **errp)
>>>>>>>>> +static void pci_piix_init_bus(PCIIDEState *d, unsigned i, ISABus *isa_bus)
>>>>>>>>>      {
>>>>>>>>>          static const struct {
>>>>>>>>>              int iobase;
>>>>>>>>>              int iobase2;
>>>>>>>>>              int isairq;
>>>>>>>>>          } port_info[] = {
>>>>>>>>> -        {0x1f0, 0x3f6, 14},
>>>>>>>>> -        {0x170, 0x376, 15},
>>>>>>>>> +        {0x1f0, 0x3f4, 14},
>>>>>>>>> +        {0x170, 0x374, 15},
>>>>>>>>>          };
>>>>>>>>> -    int ret;
>>>>>>>>> +    MemoryRegion *address_space_io = pci_address_space_io(PCI_DEVICE(d));
>>>>>>>>>            ide_bus_init(&d->bus[i], sizeof(d->bus[i]), DEVICE(d), i, 2);
>>>>>>>>> -    ret = ide_init_ioport(&d->bus[i], NULL, port_info[i].iobase,
>>>>>>>>> -                          port_info[i].iobase2);
>>>>>>>>> -    if (ret) {
>>>>>>>>> -        error_setg_errno(errp, -ret, "Failed to realize %s port %u",
>>>>>>>>> -                         object_get_typename(OBJECT(d)), i);
>>>>>>>>> -        return false;
>>>>>>>>> -    }
>>>>>>>>> +    memory_region_add_subregion(address_space_io, port_info[i].iobase,
>>>>>>>>> +                                &d->data_ops[i]);
>>>>>>>>> +    /*
>>>>>>>>> +     * PIIX forwards the last byte of cmd_ops to ISA. Model this using a low
>>>>>>>>> +     * prio so competing memory regions take precedence.
>>>>>>>>> +     */
>>>>>>>>> +    memory_region_add_subregion_overlap(address_space_io, port_info[i].iobase2,
>>>>>>>>> +                                        &d->cmd_ops[i], -1);
>>>>>>>> 
>>>>>>>> Interesting. Is this behaviour documented somewhere and/or used in one of your test images at all? If I'd have seen this myself, I probably thought that the addresses were a typo...
>>>>>>> 
>>>>>>> I first  stumbled upon this and wondered why this code was working with VIA_IDE (through my pc-via branch). Then I found the correct offsets there which are confirmed in the piix datasheet, e.g.: "Secondary Control Block Offset: 0374h"
>>>>>> 
>>>>>> In case you were wondering about the forwarding of the last byte the datasheet says: "Accesses to byte 3 of the Control Block are forwarded to ISA where the floppy disk controller responds."
>>>>> 
>>>>> Ahhh okay okay I see what's happening here: the PIIX IDE is assuming that the legacy ioport semantics are in operation here, which as you note above is where the FDC controller is also accessed via the above byte in the IDE control block. This is also why you need to change the address above from 0x3f6/0x376 to 0x3f4/0x374 when trying to use the MemoryRegions used for the PCI BARs since the PCI IDE controller specification requires a 4 byte allocation for the Control Block - see sections 2.0 and 2.2.
>>>> 
>>>> Yes, PIIX assuming that might be the case. Why does it contradict the PCI IDE specification? PIIX seems to apply the apprppriate "workarounds" here.
>>> 
>>> Can you explain a bit more about where you see the contradiction? At first glance it looks okay to me.
>>> 
>>>>> And that's fine, because the portio_lists used in ide_init_ioport() set up the legacy IDE ioports so that FDC accesses done in this way can succeed, and the PIIX IDE is hard-coded to legacy mode. So in fact PIIX IDE should keep using ide_init_ioport() rather than trying to re-use the BAR MemoryRegions so I think this patch should just be dropped.
>>>> 
>>>> I was hoping to keep that patch...
>>> 
>>> Perhaps a different way to think about it is that from QEMU's perspective a BAR is a MemoryRegion that can be dynamically assigned/updated and cannot overlap, whereas the portio_list implementation also handles unaligned accesses and overlapping sparse accesses. Since the latter is the exact case here with the IDE/FDC then it seems the existing portio_list solution already does the "right thing" instead of having to manually emulate the overlapping dispatch.
>> 
>> I've had another look into the "PCI IDE Controller Specification Revision 1.0" which says:
>
>Interesting: it looks as if we are getting different conclusions from the same document.
>
>> "The Control Block registers consist of two bytes used for control/status of the IDE device. The second byte of this pair is read-only and has the interesting quirk where the top bit of this byte is shared with the floppy controller when the IDE device is mapped at 'compatibility' locations. It turns out that software controlling IDE devices (BIOS, drivers, etc.) does not use this register at all.
>
>Just before this section the start of the paragraph reads "The ATA Standard defines two sets of registers known as Control Block Registers and Command Block Registers." which reads to me that the paragraph quoted above is describing the original ATA Standard behaviour, i.e. the expected behaviour for pre-PCI controllers or PCI IDE controllers in compatibility mode.
>
>> The exception for PCI IDE controllers to the ATA Standard is that only the first of the two bytes defined in the Control Block registers is implemented. This byte provides Alternate Status on reads and Device Control on writes. Accesses to the second byte of the Control Block registers (Drive Address) should be ignored by the PCI IDE controller."
>
>And this paragraph then leads onto the differences for PCI IDE controllers which are that the second (shared) byte in the Control Block is ignored, which again makes sense from a PCI perspective since PCI BARs cannot overlap. But that doesn't matter in PCI native mode because the BIOS/OS will have moved the BAR to a suitable memory address that doesn't clash with the floppy drive.
>
>> So in fact the real PIIX does adhere to this standard and there is no reason to reject the idea behind this patch -- which is to make our PIIX device model implement this standard.
>> 
>> It's just that all our other PCI-IDE implementations need to implement this quirk as long as they implement the standard. And according to the Linux kernel they all do -- see its CONFIG_ATA_SFF.
>
>Another couple of hints that the registers in PCI IDE controllers in compatibility mode aren't accessed through PCI BARs can also be found: i) the table in section 2.1 for compatibility mode uses fixed addresses whilst the table in section 2.2 references BAs and ii) section 2.4 suggests that PCI controllers in compatibility mode always ignore the BARs.
>
>Now it could be that the description in the PIIX datasheet indicates that the PCI IO address is hardcoded and then the second byte (re)dispatched to the ISA bus, but then I would argue that this is an implementation detail: from QEMU's perspective there is zero difference between this and the existing IDE portio_list, and as a bonus the existing compatibility behaviour is completely unaffected by any PCI BARs.

Right, that was my idea: Trading one implementation detail in PIIX with another to have a common "theory" accross all our TYPE_PCI_IDE devices which all implement the PCI IDE controller standard. At the same time quite a bit of redundant code could be removed.

We could of course extend this theory to consider compatibility and PCI native modes to have different implementations. That is, compatibility mode would use portio_list semantics while PCI native woulde use the BARs semantics. Then we'd have to make at least TYPE_VIA_IDE use portio_list since it is currently hardcoded to operate in compatibility mode. Same for cmd646 if it can switch modes. And then there is also sil3112...

I guess I'll split this series and only ship the first four patches in v2. Meanwhile we can discuss here further on the topic of the PCI IDE controller specification which the rest of this series addresses.

>
>> Since this patch actually uncovered a small bug in the other device models I'd rather fix those, too. One way I could do this is to decrease the size of the memory region or to map with lower priority. What is the preferred fix? Any other ideas?
>> 
>> Note that this and the next patch resolve the last dependencies on the "isabus" global. So after this series we could apply some small patches posted before and get rid of the global entirely... And have as many ISA and LPC buses as we want!
>
>This is the part I think we can do better with: both Phil and I have patches that remove the isabus reference from the IDE ioports e.g. https://patchew.org/QEMU/20230302224058.43315-1-philmd@linaro.org/20230302224058.43315-9-philmd@linaro.org/ so dropping this patch shouldn't affect our ability to remove the isabus global.
>
>Do you have an example of a use-case you have for multiple ISA buses? I'm fairly sure that this wouldn't work on x86 PC machines with a single PCI root bus for example.

The ICH0 (82801AA & 82801AB) datasheet depicts in the "system block diagram" an LPC bus for the Super I/O devices and an optional PCI-ISA bridge connected to the PCI bus. I guess the use case is for connecting ISA cards while the ICH made the switch to the more modern LPC bus. Of course one could attach an ISA "card" to the LPC bus in QEMU since they look the same from software. I'd assume though that above two buses would be visible somehow.

Other than that I don't see a real use case. It's just a property of a clean software design to avoid imposing any artificial limits onto callers and instead give them maximum control. ISABus currently assumes that there can only be one ISA bus in a QEMU process and above example seems like a counter example. Moreover, ISABus not being a singleton may make its testing more convenient and who knows, maybe it helps in moving towards heterogenious architectures.

Best regards,
Bernhard

>
>
>ATB,
>
>Mark.
>


^ permalink raw reply	[flat|nested] 77+ messages in thread

end of thread, other threads:[~2023-05-19 17:10 UTC | newest]

Thread overview: 77+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-22 15:07 [PATCH 00/13] Clean up PCI IDE device models Bernhard Beschow
2023-04-22 15:07 ` [PATCH 01/13] hw/ide/pci: Expose legacy interrupts as GPIOs Bernhard Beschow
2023-04-26 10:41   ` Mark Cave-Ayland
2023-04-26 19:26     ` Bernhard Beschow
2023-04-22 15:07 ` [PATCH 02/13] hw/ide/via: Implement ISA IRQ routing Bernhard Beschow
2023-04-22 17:23   ` BALATON Zoltan
2023-04-22 18:47     ` Bernhard Beschow
2023-04-22 19:21       ` BALATON Zoltan
2023-04-24  7:50         ` Bernhard Beschow
2023-04-24 10:10           ` BALATON Zoltan
2023-04-26 10:55   ` Mark Cave-Ayland
2023-04-22 15:07 ` [PATCH 03/13] hw/isa/vt82c686: Remove via_isa_set_irq() Bernhard Beschow
2023-04-26 10:55   ` Mark Cave-Ayland
2023-04-22 15:07 ` [PATCH 04/13] hw/ide: Extract IDEBus assignment into bmdma_init() Bernhard Beschow
2023-04-22 17:31   ` BALATON Zoltan
2023-04-23 17:36   ` Philippe Mathieu-Daudé
2023-04-26 10:56   ` Mark Cave-Ayland
2023-04-22 15:07 ` [PATCH 05/13] hw/ide: Extract pci_ide_class_init() Bernhard Beschow
2023-04-22 17:34   ` BALATON Zoltan
2023-04-22 18:59     ` Bernhard Beschow
2023-04-23 17:41   ` Philippe Mathieu-Daudé
2023-04-23 22:11     ` Bernhard Beschow
2023-04-23 22:23       ` BALATON Zoltan
2023-04-26 11:04   ` Mark Cave-Ayland
2023-04-26 18:32     ` Bernhard Beschow
2023-04-22 15:07 ` [PATCH 06/13] hw/ide: Extract bmdma_init_ops() Bernhard Beschow
2023-04-23 17:43   ` Philippe Mathieu-Daudé
2023-04-23 22:06     ` Bernhard Beschow
2023-04-26 11:14   ` Mark Cave-Ayland
2023-04-22 15:07 ` [PATCH 07/13] hw/ide: Extract pci_ide_{cmd, data}_le_ops initialization into base class constructor Bernhard Beschow
2023-04-23 17:46   ` [PATCH 07/13] hw/ide: Extract pci_ide_{cmd,data}_le_ops " Philippe Mathieu-Daudé
2023-04-24  7:45     ` Bernhard Beschow
2023-04-26 11:16   ` [PATCH 07/13] hw/ide: Extract pci_ide_{cmd, data}_le_ops " Mark Cave-Ayland
2023-04-22 15:07 ` [PATCH 08/13] hw/ide: Rename PCIIDEState::*_bar attributes Bernhard Beschow
2023-04-22 17:53   ` BALATON Zoltan
2023-04-26 11:21   ` Mark Cave-Ayland
2023-04-26 18:29     ` Bernhard Beschow
2023-04-27 11:07       ` Mark Cave-Ayland
2023-04-22 15:07 ` [PATCH 09/13] hw/ide/piix: Disuse isa_get_irq() Bernhard Beschow
2023-04-26 11:33   ` Mark Cave-Ayland
2023-04-26 18:25     ` Bernhard Beschow
2023-04-27 12:31       ` Mark Cave-Ayland
2023-05-13 11:53         ` Bernhard Beschow
2023-05-14 12:43           ` Mark Cave-Ayland
2023-04-22 15:07 ` [PATCH 10/13] hw/ide/piix: Reuse PCIIDEState::{cmd,data}_ops Bernhard Beschow
2023-04-26 11:37   ` Mark Cave-Ayland
2023-04-26 18:18     ` Bernhard Beschow
2023-04-26 20:14       ` Bernhard Beschow
2023-04-27 10:52         ` Mark Cave-Ayland
2023-04-27 18:15           ` Bernhard Beschow
2023-04-28 15:58             ` Bernhard Beschow
2023-04-28 17:00               ` BALATON Zoltan
2023-05-03 19:52             ` Mark Cave-Ayland
2023-05-13 12:21               ` Bernhard Beschow
2023-05-18 14:53                 ` Mark Cave-Ayland
2023-05-19 17:09                   ` Bernhard Beschow
2023-04-22 15:07 ` [PATCH 11/13] hw/ide/sii3112: " Bernhard Beschow
2023-04-22 21:10   ` BALATON Zoltan
2023-04-23 22:19     ` Bernhard Beschow
2023-04-23 22:38       ` BALATON Zoltan
2023-04-26 11:41   ` Mark Cave-Ayland
2023-04-26 20:24     ` Bernhard Beschow
2023-04-26 23:24       ` BALATON Zoltan
2023-04-27 11:15         ` Mark Cave-Ayland
2023-04-27 12:55           ` BALATON Zoltan
2023-05-03 20:25             ` Mark Cave-Ayland
2023-04-22 15:07 ` [PATCH 12/13] hw/ide/sii3112: Reuse PCIIDEState::bmdma_ops Bernhard Beschow
2023-04-26 11:44   ` Mark Cave-Ayland
2023-04-26 20:26     ` Bernhard Beschow
2023-04-22 15:07 ` [PATCH 13/13] hw/ide: Extract bmdma_clear_status() Bernhard Beschow
2023-04-22 21:26   ` BALATON Zoltan
2023-04-23  7:48     ` Bernhard Beschow
2023-04-23 10:40       ` BALATON Zoltan
2023-04-23 21:53         ` Bernhard Beschow
2023-04-22 22:46   ` BALATON Zoltan
2023-04-23  7:35     ` Bernhard Beschow
2023-04-26 11:48   ` Mark Cave-Ayland

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.