All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/2] hw/ide: implement ich6 ide controller support
@ 2022-02-18 20:41 Liav Albani
  2022-02-18 20:41 ` [PATCH v2 1/2] hw/ide: split bmdma read and write functions from piix.c Liav Albani
  2022-02-18 20:41 ` [PATCH v2 2/2] hw/ide: add ich6 ide controller device emulation Liav Albani
  0 siblings, 2 replies; 10+ messages in thread
From: Liav Albani @ 2022-02-18 20:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: jsnow, Liav Albani, qemu-block

This is version 2 of this patch, this time a patch series, after following
the suggestions from BALATON Zoltan. I implemented this device because I have an
old machine from 2009 which has the ICH7 south bridge in it, so when I tried to
run Linux on it, it booted just fine (as you might expect), but when I tried to
boot with the SerenityOS kernel, it struggled to initialize the IDE controller.
Therefore, upstreaming these changes might be beneficial to other OS developers
and hobbyists out there, and I will use this to fix the issues within the
SerenityOS kernel, without the need of preparing a bare metal setup each time I
need to test the code of the kernel.

Please keep in mind that while this is usable right now with the Q35 chipset,
when trying to boot with an i440FX machine, SeaBIOS doesn't handle this device
very well, so it tries no matter what type of IDE controller it sees to assign
the IO ports to legacy values. I have a patch I wrote locally which I gladly
will send to SeaBIOS, that fixes this problem by ensuring that when attaching a
storage device to this controller, SeaBIOS will relocate the IO ports to other
values so there's no collision with the default PIIX3/4 IDE controller. Even if
SeaBIOS didn't configure this device correctly, Linux will relocate the IO ports
and the user can still use the attached storage devices, given that the user
managed to boot from a storage device that is not attached to the ICH6 IDE
controller but to other storage controller in the system.

Liav Albani (2):
  hw/ide: split bmdma read and write functions from piix.c
  hw/ide: add ich6 ide controller device emulation

 hw/i386/Kconfig          |   2 +
 hw/ide/Kconfig           |   5 +
 hw/ide/bmdma.c           |  84 ++++++++++++++++
 hw/ide/ich6.c            | 204 +++++++++++++++++++++++++++++++++++++++
 hw/ide/meson.build       |   3 +-
 hw/ide/piix.c            |  51 +---------
 include/hw/ide/bmdma.h   |  34 +++++++
 include/hw/ide/pci.h     |   1 +
 include/hw/pci/pci_ids.h |   1 +
 9 files changed, 336 insertions(+), 49 deletions(-)
 create mode 100644 hw/ide/bmdma.c
 create mode 100644 hw/ide/ich6.c
 create mode 100644 include/hw/ide/bmdma.h

-- 
2.35.1



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

* [PATCH v2 1/2] hw/ide: split bmdma read and write functions from piix.c
  2022-02-18 20:41 [PATCH v2 0/2] hw/ide: implement ich6 ide controller support Liav Albani
@ 2022-02-18 20:41 ` Liav Albani
  2022-02-19  0:12   ` BALATON Zoltan
  2022-02-18 20:41 ` [PATCH v2 2/2] hw/ide: add ich6 ide controller device emulation Liav Albani
  1 sibling, 1 reply; 10+ messages in thread
From: Liav Albani @ 2022-02-18 20:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: jsnow, Liav Albani, qemu-block

This is a preparation before implementing another PCI IDE controller
that relies on these functions, so these can be shared between both
implementations.

Signed-off-by: Liav Albani <liavalb@gmail.com>
---
 hw/ide/bmdma.c         | 84 ++++++++++++++++++++++++++++++++++++++++++
 hw/ide/meson.build     |  2 +-
 hw/ide/piix.c          | 51 ++-----------------------
 include/hw/ide/bmdma.h | 34 +++++++++++++++++
 4 files changed, 122 insertions(+), 49 deletions(-)
 create mode 100644 hw/ide/bmdma.c
 create mode 100644 include/hw/ide/bmdma.h

diff --git a/hw/ide/bmdma.c b/hw/ide/bmdma.c
new file mode 100644
index 0000000000..d12ed730dd
--- /dev/null
+++ b/hw/ide/bmdma.c
@@ -0,0 +1,84 @@
+/*
+ * QEMU IDE Emulation: Intel PCI Bus master IDE support for PIIX3/4 and ICH6/7.
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ * Copyright (c) 2006 Openedhand Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/pci/pci.h"
+#include "migration/vmstate.h"
+#include "qapi/error.h"
+#include "qemu/module.h"
+#include "sysemu/block-backend.h"
+#include "sysemu/blockdev.h"
+#include "sysemu/dma.h"
+
+#include "hw/ide/bmdma.h"
+#include "hw/ide/pci.h"
+#include "trace.h"
+
+uint64_t intel_ide_bmdma_read(void *opaque, hwaddr addr, unsigned size)
+{
+    BMDMAState *bm = opaque;
+    uint32_t val;
+
+    if (size != 1) {
+        return ((uint64_t)1 << (size * 8)) - 1;
+    }
+
+    switch (addr & 3) {
+    case 0:
+        val = bm->cmd;
+        break;
+    case 2:
+        val = bm->status;
+        break;
+    default:
+        val = 0xff;
+        break;
+    }
+
+    trace_bmdma_read(addr, val);
+    return val;
+}
+
+void intel_ide_bmdma_write(void *opaque, hwaddr addr,
+                        uint64_t val, unsigned size)
+{
+    BMDMAState *bm = opaque;
+
+    if (size != 1) {
+        return;
+    }
+
+    trace_bmdma_write(addr, val);
+
+    switch (addr & 3) {
+    case 0:
+        bmdma_cmd_writeb(bm, val);
+        break;
+    case 2:
+        uint8_t cur_val = bm->status;
+        bm->status = (val & 0x60) | (cur_val & 1) | (cur_val & ~val & 0x06);
+        break;
+    }
+}
diff --git a/hw/ide/meson.build b/hw/ide/meson.build
index ddcb3b28d2..38f9ae7178 100644
--- a/hw/ide/meson.build
+++ b/hw/ide/meson.build
@@ -7,7 +7,7 @@ softmmu_ss.add(when: 'CONFIG_IDE_ISA', if_true: files('isa.c', 'ioport.c'))
 softmmu_ss.add(when: 'CONFIG_IDE_MACIO', if_true: files('macio.c'))
 softmmu_ss.add(when: 'CONFIG_IDE_MMIO', if_true: files('mmio.c'))
 softmmu_ss.add(when: 'CONFIG_IDE_PCI', if_true: files('pci.c'))
-softmmu_ss.add(when: 'CONFIG_IDE_PIIX', if_true: files('piix.c', 'ioport.c'))
+softmmu_ss.add(when: 'CONFIG_IDE_PIIX', if_true: files('piix.c', 'ioport.c', 'bmdma.c'))
 softmmu_ss.add(when: 'CONFIG_IDE_QDEV', if_true: files('qdev.c'))
 softmmu_ss.add(when: 'CONFIG_IDE_SII3112', if_true: files('sii3112.c'))
 softmmu_ss.add(when: 'CONFIG_IDE_VIA', if_true: files('via.c'))
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index ce89fd0aa3..8f94809eee 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -33,57 +33,12 @@
 #include "sysemu/dma.h"
 
 #include "hw/ide/pci.h"
+#include "hw/ide/bmdma.h"
 #include "trace.h"
 
-static uint64_t bmdma_read(void *opaque, hwaddr addr, unsigned size)
-{
-    BMDMAState *bm = opaque;
-    uint32_t val;
-
-    if (size != 1) {
-        return ((uint64_t)1 << (size * 8)) - 1;
-    }
-
-    switch(addr & 3) {
-    case 0:
-        val = bm->cmd;
-        break;
-    case 2:
-        val = bm->status;
-        break;
-    default:
-        val = 0xff;
-        break;
-    }
-
-    trace_bmdma_read(addr, val);
-    return val;
-}
-
-static void bmdma_write(void *opaque, hwaddr addr,
-                        uint64_t val, unsigned size)
-{
-    BMDMAState *bm = opaque;
-
-    if (size != 1) {
-        return;
-    }
-
-    trace_bmdma_write(addr, val);
-
-    switch(addr & 3) {
-    case 0:
-        bmdma_cmd_writeb(bm, val);
-        break;
-    case 2:
-        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
-        break;
-    }
-}
-
 static const MemoryRegionOps piix_bmdma_ops = {
-    .read = bmdma_read,
-    .write = bmdma_write,
+    .read = intel_ide_bmdma_read,
+    .write = intel_ide_bmdma_write,
 };
 
 static void bmdma_setup_bar(PCIIDEState *d)
diff --git a/include/hw/ide/bmdma.h b/include/hw/ide/bmdma.h
new file mode 100644
index 0000000000..ce76d395f5
--- /dev/null
+++ b/include/hw/ide/bmdma.h
@@ -0,0 +1,34 @@
+/*
+ * QEMU IDE Emulation: Intel PCI Bus master IDE support for PIIX3/4 and ICH6/7.
+ *
+ * Copyright (c) 2022 Liav Albani
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef HW_IDE_BMDMA_H
+#define HW_IDE_BMDMA_H
+
+#include "hw/ide/internal.h"
+
+uint64_t intel_ide_bmdma_read(void *opaque, hwaddr addr, unsigned size);
+void intel_ide_bmdma_write(void *opaque, hwaddr addr, uint64_t val,
+                           unsigned size);
+
+#endif
-- 
2.35.1



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

* [PATCH v2 2/2] hw/ide: add ich6 ide controller device emulation
  2022-02-18 20:41 [PATCH v2 0/2] hw/ide: implement ich6 ide controller support Liav Albani
  2022-02-18 20:41 ` [PATCH v2 1/2] hw/ide: split bmdma read and write functions from piix.c Liav Albani
@ 2022-02-18 20:41 ` Liav Albani
  2022-02-19  0:50   ` BALATON Zoltan
  1 sibling, 1 reply; 10+ messages in thread
From: Liav Albani @ 2022-02-18 20:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: jsnow, Liav Albani, qemu-block

This type of IDE controller has support for relocating the IO ports and
doesn't use IRQ 14 and 15 but one allocated PCI IRQ for the controller.

There's no x86 chipset in QEMU that will try to attach this device by
default. It is considered a legacy-free device in the aspect of PCI bus
resource management as the guest OS can relocate the IO ports as it sees
fit to its needs. However, this is still a legacy device that belongs to
chipsets from late 2000s.

Signed-off-by: Liav Albani <liavalb@gmail.com>
---
 hw/i386/Kconfig          |   2 +
 hw/ide/Kconfig           |   5 +
 hw/ide/ich6.c            | 204 +++++++++++++++++++++++++++++++++++++++
 hw/ide/meson.build       |   1 +
 include/hw/ide/pci.h     |   1 +
 include/hw/pci/pci_ids.h |   1 +
 6 files changed, 214 insertions(+)
 create mode 100644 hw/ide/ich6.c

diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig
index d22ac4a4b9..a18de2d962 100644
--- a/hw/i386/Kconfig
+++ b/hw/i386/Kconfig
@@ -75,6 +75,7 @@ config I440FX
     select PCI_I440FX
     select PIIX3
     select IDE_PIIX
+    select IDE_ICH6
     select DIMM
     select SMBIOS
     select FW_CFG_DMA
@@ -101,6 +102,7 @@ config Q35
     select PCI_EXPRESS_Q35
     select LPC_ICH9
     select AHCI_ICH9
+    select IDE_ICH6
     select DIMM
     select SMBIOS
     select FW_CFG_DMA
diff --git a/hw/ide/Kconfig b/hw/ide/Kconfig
index dd85fa3619..63304325a5 100644
--- a/hw/ide/Kconfig
+++ b/hw/ide/Kconfig
@@ -38,6 +38,11 @@ config IDE_VIA
     select IDE_PCI
     select IDE_QDEV
 
+config IDE_ICH6
+    bool
+    select IDE_PCI
+    select IDE_QDEV
+
 config MICRODRIVE
     bool
     select IDE_QDEV
diff --git a/hw/ide/ich6.c b/hw/ide/ich6.c
new file mode 100644
index 0000000000..8f46d3fce2
--- /dev/null
+++ b/hw/ide/ich6.c
@@ -0,0 +1,204 @@
+/*
+ * QEMU IDE Emulation: PCI ICH6/ICH7 IDE support.
+ *
+ * Copyright (c) 2022 Liav Albani
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/pci/pci.h"
+#include "migration/vmstate.h"
+#include "qapi/error.h"
+#include "qemu/module.h"
+#include "sysemu/block-backend.h"
+#include "sysemu/blockdev.h"
+#include "sysemu/dma.h"
+
+#include "hw/ide/pci.h"
+#include "hw/ide/bmdma.h"
+#include "trace.h"
+
+static const MemoryRegionOps ich6_bmdma_ops = {
+    .read = intel_ide_bmdma_read,
+    .write = intel_ide_bmdma_write,
+};
+
+static void bmdma_setup_bar(PCIIDEState *d)
+{
+    int i;
+
+    memory_region_init(&d->bmdma_bar, OBJECT(d), "ich6-bmdma-container", 16);
+    for (i = 0; i < 2; i++) {
+        BMDMAState *bm = &d->bmdma[i];
+
+        memory_region_init_io(&bm->extra_io, OBJECT(d), &ich6_bmdma_ops, bm,
+                              "ich6-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 ich6_pci_config_write(PCIDevice *d, uint32_t addr, uint32_t val,
+                                    int l)
+{
+    uint32_t i;
+
+    pci_default_write_config(d, addr, val, l);
+
+    for (i = addr; i < addr + l; i++) {
+        switch (i) {
+        case 0x40:
+            pci_default_write_config(d, i, 0x8000, 2);
+            continue;
+        case 0x42:
+            pci_default_write_config(d, i, 0x8000, 2);
+            continue;
+        }
+    }
+}
+
+static void ich6_ide_reset(DeviceState *dev)
+{
+    PCIIDEState *d = PCI_IDE(dev);
+    PCIDevice *pd = PCI_DEVICE(d);
+    uint8_t *pci_conf = pd->config;
+    int i;
+
+    for (i = 0; i < 2; i++) {
+        ide_bus_reset(&d->bus[i]);
+    }
+
+    /* TODO: this is the default. do not override. */
+    pci_conf[PCI_COMMAND] = 0x00;
+    /* TODO: this is the default. do not override. */
+    pci_conf[PCI_COMMAND + 1] = 0x00;
+    /* TODO: use pci_set_word */
+    pci_conf[PCI_STATUS] = PCI_STATUS_FAST_BACK;
+    pci_conf[PCI_STATUS + 1] = PCI_STATUS_DEVSEL_MEDIUM >> 8;
+    pci_conf[0x20] = 0x01; /* BMIBA: 20-23h */
+}
+
+static int pci_ich6_init_ports(PCIIDEState *d)
+{
+    int i;
+
+    for (i = 0; i < 2; i++) {
+        ide_bus_init(&d->bus[i], sizeof(d->bus[i]), DEVICE(d), i, 2);
+        ide_init2(&d->bus[i], d->native_irq);
+
+        bmdma_init(&d->bus[i], &d->bmdma[i], d);
+        d->bmdma[i].bus = &d->bus[i];
+        ide_register_restart_cb(&d->bus[i]);
+    }
+
+    return 0;
+}
+
+static void pci_ich6_ide_realize(PCIDevice *dev, Error **errp)
+{
+    PCIIDEState *d = PCI_IDE(dev);
+    uint8_t *pci_conf = dev->config;
+    int rc;
+
+    pci_conf[PCI_INTERRUPT_PIN] = 1; /* interrupt pin A */
+
+    /* PCI native mode-only controller, supports bus mastering */
+    pci_conf[PCI_CLASS_PROG] = 0x85;
+
+    bmdma_setup_bar(d);
+    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
+
+    d->native_irq = pci_allocate_irq(&d->parent_obj);
+    /* Address Map Register - Non Combined Mode, MAP.USCC = 0 */
+    pci_conf[0x90]   = 0;
+
+    /* IDE Decode enabled by default */
+    pci_set_long(pci_conf + 0x40, 0x80008000);
+
+    /* IDE Timing control - Disable UDMA controls */
+    pci_set_long(pci_conf + 0x48, 0x00000000);
+
+    vmstate_register(VMSTATE_IF(dev), 0, &vmstate_ide_pci, d);
+
+    memory_region_init_io(&d->data_bar[0], OBJECT(d), &pci_ide_data_le_ops,
+                          &d->bus[0], "ich6-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], "ich6-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], "ich6-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], "ich6-ide1-cmd", 4);
+    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[1]);
+
+    rc = pci_ich6_init_ports(d);
+    if (rc) {
+        error_setg_errno(errp, -rc, "Failed to realize %s",
+                         object_get_typename(OBJECT(dev)));
+    }
+}
+
+static void pci_ich6_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 void ich6_ide_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    dc->reset = ich6_ide_reset;
+    k->realize = pci_ich6_ide_realize;
+    k->exit = pci_ich6_ide_exitfn;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_82801GB;
+    k->class_id = PCI_CLASS_STORAGE_IDE;
+    k->config_read = pci_default_read_config;
+    k->config_write = ich6_pci_config_write;
+    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
+    dc->hotpluggable = false;
+}
+
+static const TypeInfo ich6_ide_info = {
+    .name          = "ich6-ide",
+    .parent        = TYPE_PCI_IDE,
+    .class_init    = ich6_ide_class_init,
+};
+
+static void ich6_ide_register_types(void)
+{
+    type_register_static(&ich6_ide_info);
+}
+
+type_init(ich6_ide_register_types)
diff --git a/hw/ide/meson.build b/hw/ide/meson.build
index 38f9ae7178..6899e082db 100644
--- a/hw/ide/meson.build
+++ b/hw/ide/meson.build
@@ -1,5 +1,6 @@
 softmmu_ss.add(when: 'CONFIG_AHCI', if_true: files('ahci.c'))
 softmmu_ss.add(when: 'CONFIG_AHCI_ICH9', if_true: files('ich.c'))
+softmmu_ss.add(when: 'CONFIG_IDE_ICH6', if_true: files('ich6.c', 'bmdma.c'))
 softmmu_ss.add(when: 'CONFIG_ALLWINNER_A10', if_true: files('ahci-allwinner.c'))
 softmmu_ss.add(when: 'CONFIG_IDE_CMD646', if_true: files('cmd646.c'))
 softmmu_ss.add(when: 'CONFIG_IDE_CORE', if_true: files('core.c', 'atapi.c'))
diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
index d8384e1c42..d8bf08e728 100644
--- a/include/hw/ide/pci.h
+++ b/include/hw/ide/pci.h
@@ -53,6 +53,7 @@ struct PCIIDEState {
     MemoryRegion bmdma_bar;
     MemoryRegion cmd_bar[2];
     MemoryRegion data_bar[2];
+    qemu_irq native_irq; /* used only for ich6-ide */
 };
 
 static inline IDEState *bmdma_active_if(BMDMAState *bmdma)
diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h
index 11abe22d46..cf8767977c 100644
--- a/include/hw/pci/pci_ids.h
+++ b/include/hw/pci/pci_ids.h
@@ -244,6 +244,7 @@
 #define PCI_DEVICE_ID_INTEL_82371AB      0x7111
 #define PCI_DEVICE_ID_INTEL_82371AB_2    0x7112
 #define PCI_DEVICE_ID_INTEL_82371AB_3    0x7113
+#define PCI_DEVICE_ID_INTEL_82801GB      0x27c0
 
 #define PCI_DEVICE_ID_INTEL_ICH9_0       0x2910
 #define PCI_DEVICE_ID_INTEL_ICH9_1       0x2917
-- 
2.35.1



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

* Re: [PATCH v2 1/2] hw/ide: split bmdma read and write functions from piix.c
  2022-02-18 20:41 ` [PATCH v2 1/2] hw/ide: split bmdma read and write functions from piix.c Liav Albani
@ 2022-02-19  0:12   ` BALATON Zoltan
  2022-02-19  6:43     ` Liav Albani
  0 siblings, 1 reply; 10+ messages in thread
From: BALATON Zoltan @ 2022-02-19  0:12 UTC (permalink / raw)
  To: Liav Albani; +Cc: jsnow, qemu-devel, qemu-block

On Fri, 18 Feb 2022, Liav Albani wrote:
> This is a preparation before implementing another PCI IDE controller
> that relies on these functions, so these can be shared between both
> implementations.
>
> Signed-off-by: Liav Albani <liavalb@gmail.com>
> ---
> hw/ide/bmdma.c         | 84 ++++++++++++++++++++++++++++++++++++++++++
> hw/ide/meson.build     |  2 +-
> hw/ide/piix.c          | 51 ++-----------------------
> include/hw/ide/bmdma.h | 34 +++++++++++++++++
> 4 files changed, 122 insertions(+), 49 deletions(-)
> create mode 100644 hw/ide/bmdma.c
> create mode 100644 include/hw/ide/bmdma.h
>
> diff --git a/hw/ide/bmdma.c b/hw/ide/bmdma.c
> new file mode 100644
> index 0000000000..d12ed730dd
> --- /dev/null
> +++ b/hw/ide/bmdma.c
> @@ -0,0 +1,84 @@
> +/*
> + * QEMU IDE Emulation: Intel PCI Bus master IDE support for PIIX3/4 and ICH6/7.
> + *
> + * Copyright (c) 2003 Fabrice Bellard
> + * Copyright (c) 2006 Openedhand Ltd.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a copy
> + * of this software and associated documentation files (the "Software"), to deal
> + * in the Software without restriction, including without limitation the rights
> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> + * copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> + * THE SOFTWARE.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/pci/pci.h"
> +#include "migration/vmstate.h"
> +#include "qapi/error.h"
> +#include "qemu/module.h"
> +#include "sysemu/block-backend.h"
> +#include "sysemu/blockdev.h"
> +#include "sysemu/dma.h"
> +
> +#include "hw/ide/bmdma.h"
> +#include "hw/ide/pci.h"
> +#include "trace.h"

Are you sure you need all these includes? I haven't checked but I think 
there may be some unneeded ones here. On the other hand I'm not sure 
putting these in a new file is worth it. There are already some bmdma_* 
functions in hw/ide/pci.c which are declared in include/hw/ide/pci.h so 
you could just move these there too then no new file, new header nor 
changes to meson.build is needed in this patch..

> +
> +uint64_t intel_ide_bmdma_read(void *opaque, hwaddr addr, unsigned size)

As I said before these aren't intel specific as the same functions also 
appear in other ide controllers such as via.c so maybe a better name would 
be bmdma_default_read and bmdma_default_write or somehting similar so 
these can be also reused by other non-intel devices too.

Regards,
BALATON Zoltan

> +{
> +    BMDMAState *bm = opaque;
> +    uint32_t val;
> +
> +    if (size != 1) {
> +        return ((uint64_t)1 << (size * 8)) - 1;
> +    }
> +
> +    switch (addr & 3) {
> +    case 0:
> +        val = bm->cmd;
> +        break;
> +    case 2:
> +        val = bm->status;
> +        break;
> +    default:
> +        val = 0xff;
> +        break;
> +    }
> +
> +    trace_bmdma_read(addr, val);
> +    return val;
> +}
> +
> +void intel_ide_bmdma_write(void *opaque, hwaddr addr,
> +                        uint64_t val, unsigned size)
> +{
> +    BMDMAState *bm = opaque;
> +
> +    if (size != 1) {
> +        return;
> +    }
> +
> +    trace_bmdma_write(addr, val);
> +
> +    switch (addr & 3) {
> +    case 0:
> +        bmdma_cmd_writeb(bm, val);
> +        break;
> +    case 2:
> +        uint8_t cur_val = bm->status;
> +        bm->status = (val & 0x60) | (cur_val & 1) | (cur_val & ~val & 0x06);
> +        break;
> +    }
> +}
> diff --git a/hw/ide/meson.build b/hw/ide/meson.build
> index ddcb3b28d2..38f9ae7178 100644
> --- a/hw/ide/meson.build
> +++ b/hw/ide/meson.build
> @@ -7,7 +7,7 @@ softmmu_ss.add(when: 'CONFIG_IDE_ISA', if_true: files('isa.c', 'ioport.c'))
> softmmu_ss.add(when: 'CONFIG_IDE_MACIO', if_true: files('macio.c'))
> softmmu_ss.add(when: 'CONFIG_IDE_MMIO', if_true: files('mmio.c'))
> softmmu_ss.add(when: 'CONFIG_IDE_PCI', if_true: files('pci.c'))
> -softmmu_ss.add(when: 'CONFIG_IDE_PIIX', if_true: files('piix.c', 'ioport.c'))
> +softmmu_ss.add(when: 'CONFIG_IDE_PIIX', if_true: files('piix.c', 'ioport.c', 'bmdma.c'))
> softmmu_ss.add(when: 'CONFIG_IDE_QDEV', if_true: files('qdev.c'))
> softmmu_ss.add(when: 'CONFIG_IDE_SII3112', if_true: files('sii3112.c'))
> softmmu_ss.add(when: 'CONFIG_IDE_VIA', if_true: files('via.c'))
> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
> index ce89fd0aa3..8f94809eee 100644
> --- a/hw/ide/piix.c
> +++ b/hw/ide/piix.c
> @@ -33,57 +33,12 @@
> #include "sysemu/dma.h"
>
> #include "hw/ide/pci.h"
> +#include "hw/ide/bmdma.h"
> #include "trace.h"
>
> -static uint64_t bmdma_read(void *opaque, hwaddr addr, unsigned size)
> -{
> -    BMDMAState *bm = opaque;
> -    uint32_t val;
> -
> -    if (size != 1) {
> -        return ((uint64_t)1 << (size * 8)) - 1;
> -    }
> -
> -    switch(addr & 3) {
> -    case 0:
> -        val = bm->cmd;
> -        break;
> -    case 2:
> -        val = bm->status;
> -        break;
> -    default:
> -        val = 0xff;
> -        break;
> -    }
> -
> -    trace_bmdma_read(addr, val);
> -    return val;
> -}
> -
> -static void bmdma_write(void *opaque, hwaddr addr,
> -                        uint64_t val, unsigned size)
> -{
> -    BMDMAState *bm = opaque;
> -
> -    if (size != 1) {
> -        return;
> -    }
> -
> -    trace_bmdma_write(addr, val);
> -
> -    switch(addr & 3) {
> -    case 0:
> -        bmdma_cmd_writeb(bm, val);
> -        break;
> -    case 2:
> -        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
> -        break;
> -    }
> -}
> -
> static const MemoryRegionOps piix_bmdma_ops = {
> -    .read = bmdma_read,
> -    .write = bmdma_write,
> +    .read = intel_ide_bmdma_read,
> +    .write = intel_ide_bmdma_write,
> };
>
> static void bmdma_setup_bar(PCIIDEState *d)
> diff --git a/include/hw/ide/bmdma.h b/include/hw/ide/bmdma.h
> new file mode 100644
> index 0000000000..ce76d395f5
> --- /dev/null
> +++ b/include/hw/ide/bmdma.h
> @@ -0,0 +1,34 @@
> +/*
> + * QEMU IDE Emulation: Intel PCI Bus master IDE support for PIIX3/4 and ICH6/7.
> + *
> + * Copyright (c) 2022 Liav Albani
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a copy
> + * of this software and associated documentation files (the "Software"), to deal
> + * in the Software without restriction, including without limitation the rights
> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> + * copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> + * THE SOFTWARE.
> + */
> +
> +#ifndef HW_IDE_BMDMA_H
> +#define HW_IDE_BMDMA_H
> +
> +#include "hw/ide/internal.h"
> +
> +uint64_t intel_ide_bmdma_read(void *opaque, hwaddr addr, unsigned size);
> +void intel_ide_bmdma_write(void *opaque, hwaddr addr, uint64_t val,
> +                           unsigned size);
> +
> +#endif
>


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

* Re: [PATCH v2 2/2] hw/ide: add ich6 ide controller device emulation
  2022-02-18 20:41 ` [PATCH v2 2/2] hw/ide: add ich6 ide controller device emulation Liav Albani
@ 2022-02-19  0:50   ` BALATON Zoltan
  2022-02-19  7:24     ` Liav Albani
  0 siblings, 1 reply; 10+ messages in thread
From: BALATON Zoltan @ 2022-02-19  0:50 UTC (permalink / raw)
  To: Liav Albani; +Cc: jsnow, qemu-devel, qemu-block

On Fri, 18 Feb 2022, Liav Albani wrote:
> This type of IDE controller has support for relocating the IO ports and
> doesn't use IRQ 14 and 15 but one allocated PCI IRQ for the controller.
>
> There's no x86 chipset in QEMU that will try to attach this device by
> default. It is considered a legacy-free device in the aspect of PCI bus
> resource management as the guest OS can relocate the IO ports as it sees
> fit to its needs. However, this is still a legacy device that belongs to
> chipsets from late 2000s.
>
> Signed-off-by: Liav Albani <liavalb@gmail.com>
> ---
> hw/i386/Kconfig          |   2 +
> hw/ide/Kconfig           |   5 +
> hw/ide/ich6.c            | 204 +++++++++++++++++++++++++++++++++++++++
> hw/ide/meson.build       |   1 +
> include/hw/ide/pci.h     |   1 +
> include/hw/pci/pci_ids.h |   1 +
> 6 files changed, 214 insertions(+)
> create mode 100644 hw/ide/ich6.c
>
> diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig
> index d22ac4a4b9..a18de2d962 100644
> --- a/hw/i386/Kconfig
> +++ b/hw/i386/Kconfig
> @@ -75,6 +75,7 @@ config I440FX
>     select PCI_I440FX
>     select PIIX3
>     select IDE_PIIX
> +    select IDE_ICH6
>     select DIMM
>     select SMBIOS
>     select FW_CFG_DMA
> @@ -101,6 +102,7 @@ config Q35
>     select PCI_EXPRESS_Q35
>     select LPC_ICH9
>     select AHCI_ICH9
> +    select IDE_ICH6
>     select DIMM
>     select SMBIOS
>     select FW_CFG_DMA
> diff --git a/hw/ide/Kconfig b/hw/ide/Kconfig
> index dd85fa3619..63304325a5 100644
> --- a/hw/ide/Kconfig
> +++ b/hw/ide/Kconfig
> @@ -38,6 +38,11 @@ config IDE_VIA
>     select IDE_PCI
>     select IDE_QDEV
>
> +config IDE_ICH6
> +    bool
> +    select IDE_PCI
> +    select IDE_QDEV
> +
> config MICRODRIVE
>     bool
>     select IDE_QDEV
> diff --git a/hw/ide/ich6.c b/hw/ide/ich6.c
> new file mode 100644
> index 0000000000..8f46d3fce2
> --- /dev/null
> +++ b/hw/ide/ich6.c
> @@ -0,0 +1,204 @@
> +/*
> + * QEMU IDE Emulation: PCI ICH6/ICH7 IDE support.

This is a small thing, but if these two are the same maybe keeping this 
comment but using the ich7 name everywhere else would make it less likely 
to get it confused with ich9. I mean ich6 and ich9 is easily confused, 
while ich7 is clearly distinct. But maybe it's just me, calling it ich6 is 
also correct and can be preferred by someone else.

> + *
> + * Copyright (c) 2022 Liav Albani
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a copy
> + * of this software and associated documentation files (the "Software"), to deal
> + * in the Software without restriction, including without limitation the rights
> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> + * copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> + * THE SOFTWARE.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/pci/pci.h"
> +#include "migration/vmstate.h"
> +#include "qapi/error.h"
> +#include "qemu/module.h"
> +#include "sysemu/block-backend.h"
> +#include "sysemu/blockdev.h"
> +#include "sysemu/dma.h"
> +
> +#include "hw/ide/pci.h"
> +#include "hw/ide/bmdma.h"
> +#include "trace.h"
> +
> +static const MemoryRegionOps ich6_bmdma_ops = {
> +    .read = intel_ide_bmdma_read,
> +    .write = intel_ide_bmdma_write,
> +};
> +
> +static void bmdma_setup_bar(PCIIDEState *d)
> +{
> +    int i;
> +
> +    memory_region_init(&d->bmdma_bar, OBJECT(d), "ich6-bmdma-container", 16);
> +    for (i = 0; i < 2; i++) {
> +        BMDMAState *bm = &d->bmdma[i];
> +
> +        memory_region_init_io(&bm->extra_io, OBJECT(d), &ich6_bmdma_ops, bm,
> +                              "ich6-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 ich6_pci_config_write(PCIDevice *d, uint32_t addr, uint32_t val,
> +                                    int l)
> +{
> +    uint32_t i;
> +
> +    pci_default_write_config(d, addr, val, l);
> +
> +    for (i = addr; i < addr + l; i++) {
> +        switch (i) {
> +        case 0x40:
> +            pci_default_write_config(d, i, 0x8000, 2);
> +            continue;
> +        case 0x42:
> +            pci_default_write_config(d, i, 0x8000, 2);
> +            continue;
> +        }
> +    }

I'm not sure what this tries to do but this for cycle looks suspicious 
here. It's also only calls pci_default_write_config() so why didn't the 
default worked and why was this override needed?

> +}
> +
> +static void ich6_ide_reset(DeviceState *dev)
> +{
> +    PCIIDEState *d = PCI_IDE(dev);
> +    PCIDevice *pd = PCI_DEVICE(d);
> +    uint8_t *pci_conf = pd->config;
> +    int i;
> +
> +    for (i = 0; i < 2; i++) {
> +        ide_bus_reset(&d->bus[i]);
> +    }
> +
> +    /* TODO: this is the default. do not override. */
> +    pci_conf[PCI_COMMAND] = 0x00;
> +    /* TODO: this is the default. do not override. */
> +    pci_conf[PCI_COMMAND + 1] = 0x00;
> +    /* TODO: use pci_set_word */
> +    pci_conf[PCI_STATUS] = PCI_STATUS_FAST_BACK;
> +    pci_conf[PCI_STATUS + 1] = PCI_STATUS_DEVSEL_MEDIUM >> 8;
> +    pci_conf[0x20] = 0x01; /* BMIBA: 20-23h */
> +}
> +
> +static int pci_ich6_init_ports(PCIIDEState *d)
> +{
> +    int i;
> +
> +    for (i = 0; i < 2; i++) {
> +        ide_bus_init(&d->bus[i], sizeof(d->bus[i]), DEVICE(d), i, 2);
> +        ide_init2(&d->bus[i], d->native_irq);
> +
> +        bmdma_init(&d->bus[i], &d->bmdma[i], d);
> +        d->bmdma[i].bus = &d->bus[i];
> +        ide_register_restart_cb(&d->bus[i]);
> +    }
> +
> +    return 0;
> +}
> +
> +static void pci_ich6_ide_realize(PCIDevice *dev, Error **errp)
> +{
> +    PCIIDEState *d = PCI_IDE(dev);
> +    uint8_t *pci_conf = dev->config;
> +    int rc;

All in all this device looks very similar to piix ide devices with only 
some differentces so I wonder if ir could be implemented as another device 
in piix.c. We already have 3 variants there: piix3-ide, piix3-ide-xen, and 
piix4-ide so maybe putting this device in piix.c could avoid some code 
duplication. In that case moving out bmdma_{read,write} were not needed 
either although maybe that's a good idea anyway to share it with other 
devices.

> +
> +    pci_conf[PCI_INTERRUPT_PIN] = 1; /* interrupt pin A */
> +
> +    /* PCI native mode-only controller, supports bus mastering */
> +    pci_conf[PCI_CLASS_PROG] = 0x85;
> +
> +    bmdma_setup_bar(d);
> +    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
> +
> +    d->native_irq = pci_allocate_irq(&d->parent_obj);

Is this irq and the new field in PCIIDEState really needed? If this device 
is using PCI interrupts could it do the same as CMD646 ide does instead?

That's all for now, I haven't checked the docs of these ide controllers so 
I'm not sure if these have switchable native and legacy modes like via has 
and we again getting the problem that we can't model that easily or these 
are really different with one having only legacy and the ich6/7 only 
native modes.

Regards.
BALATON Zoltan

> +    /* Address Map Register - Non Combined Mode, MAP.USCC = 0 */
> +    pci_conf[0x90]   = 0;
> +
> +    /* IDE Decode enabled by default */
> +    pci_set_long(pci_conf + 0x40, 0x80008000);
> +
> +    /* IDE Timing control - Disable UDMA controls */
> +    pci_set_long(pci_conf + 0x48, 0x00000000);
> +
> +    vmstate_register(VMSTATE_IF(dev), 0, &vmstate_ide_pci, d);
> +
> +    memory_region_init_io(&d->data_bar[0], OBJECT(d), &pci_ide_data_le_ops,
> +                          &d->bus[0], "ich6-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], "ich6-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], "ich6-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], "ich6-ide1-cmd", 4);
> +    pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd_bar[1]);
> +
> +    rc = pci_ich6_init_ports(d);
> +    if (rc) {
> +        error_setg_errno(errp, -rc, "Failed to realize %s",
> +                         object_get_typename(OBJECT(dev)));
> +    }
> +}
> +
> +static void pci_ich6_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 void ich6_ide_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
> +
> +    dc->reset = ich6_ide_reset;
> +    k->realize = pci_ich6_ide_realize;
> +    k->exit = pci_ich6_ide_exitfn;
> +    k->vendor_id = PCI_VENDOR_ID_INTEL;
> +    k->device_id = PCI_DEVICE_ID_INTEL_82801GB;
> +    k->class_id = PCI_CLASS_STORAGE_IDE;
> +    k->config_read = pci_default_read_config;
> +    k->config_write = ich6_pci_config_write;
> +    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
> +    dc->hotpluggable = false;
> +}
> +
> +static const TypeInfo ich6_ide_info = {
> +    .name          = "ich6-ide",
> +    .parent        = TYPE_PCI_IDE,
> +    .class_init    = ich6_ide_class_init,
> +};
> +
> +static void ich6_ide_register_types(void)
> +{
> +    type_register_static(&ich6_ide_info);
> +}
> +
> +type_init(ich6_ide_register_types)
> diff --git a/hw/ide/meson.build b/hw/ide/meson.build
> index 38f9ae7178..6899e082db 100644
> --- a/hw/ide/meson.build
> +++ b/hw/ide/meson.build
> @@ -1,5 +1,6 @@
> softmmu_ss.add(when: 'CONFIG_AHCI', if_true: files('ahci.c'))
> softmmu_ss.add(when: 'CONFIG_AHCI_ICH9', if_true: files('ich.c'))
> +softmmu_ss.add(when: 'CONFIG_IDE_ICH6', if_true: files('ich6.c', 'bmdma.c'))
> softmmu_ss.add(when: 'CONFIG_ALLWINNER_A10', if_true: files('ahci-allwinner.c'))
> softmmu_ss.add(when: 'CONFIG_IDE_CMD646', if_true: files('cmd646.c'))
> softmmu_ss.add(when: 'CONFIG_IDE_CORE', if_true: files('core.c', 'atapi.c'))
> diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h
> index d8384e1c42..d8bf08e728 100644
> --- a/include/hw/ide/pci.h
> +++ b/include/hw/ide/pci.h
> @@ -53,6 +53,7 @@ struct PCIIDEState {
>     MemoryRegion bmdma_bar;
>     MemoryRegion cmd_bar[2];
>     MemoryRegion data_bar[2];
> +    qemu_irq native_irq; /* used only for ich6-ide */
> };
>
> static inline IDEState *bmdma_active_if(BMDMAState *bmdma)
> diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h
> index 11abe22d46..cf8767977c 100644
> --- a/include/hw/pci/pci_ids.h
> +++ b/include/hw/pci/pci_ids.h
> @@ -244,6 +244,7 @@
> #define PCI_DEVICE_ID_INTEL_82371AB      0x7111
> #define PCI_DEVICE_ID_INTEL_82371AB_2    0x7112
> #define PCI_DEVICE_ID_INTEL_82371AB_3    0x7113
> +#define PCI_DEVICE_ID_INTEL_82801GB      0x27c0
>
> #define PCI_DEVICE_ID_INTEL_ICH9_0       0x2910
> #define PCI_DEVICE_ID_INTEL_ICH9_1       0x2917
>


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

* Re: [PATCH v2 1/2] hw/ide: split bmdma read and write functions from piix.c
  2022-02-19  0:12   ` BALATON Zoltan
@ 2022-02-19  6:43     ` Liav Albani
  0 siblings, 0 replies; 10+ messages in thread
From: Liav Albani @ 2022-02-19  6:43 UTC (permalink / raw)
  To: BALATON Zoltan; +Cc: jsnow, qemu-devel, qemu-block


On 2/19/22 02:12, BALATON Zoltan wrote:
> On Fri, 18 Feb 2022, Liav Albani wrote:
>> This is a preparation before implementing another PCI IDE controller
>> that relies on these functions, so these can be shared between both
>> implementations.
>>
>> Signed-off-by: Liav Albani <liavalb@gmail.com>
>> ---
>> hw/ide/bmdma.c         | 84 ++++++++++++++++++++++++++++++++++++++++++
>> hw/ide/meson.build     |  2 +-
>> hw/ide/piix.c          | 51 ++-----------------------
>> include/hw/ide/bmdma.h | 34 +++++++++++++++++
>> 4 files changed, 122 insertions(+), 49 deletions(-)
>> create mode 100644 hw/ide/bmdma.c
>> create mode 100644 include/hw/ide/bmdma.h
>>
>> diff --git a/hw/ide/bmdma.c b/hw/ide/bmdma.c
>> new file mode 100644
>> index 0000000000..d12ed730dd
>> --- /dev/null
>> +++ b/hw/ide/bmdma.c
>> @@ -0,0 +1,84 @@
>> +/*
>> + * QEMU IDE Emulation: Intel PCI Bus master IDE support for PIIX3/4 
>> and ICH6/7.
>> + *
>> + * Copyright (c) 2003 Fabrice Bellard
>> + * Copyright (c) 2006 Openedhand Ltd.
>> + *
>> + * Permission is hereby granted, free of charge, to any person 
>> obtaining a copy
>> + * of this software and associated documentation files (the 
>> "Software"), to deal
>> + * in the Software without restriction, including without limitation 
>> the rights
>> + * to use, copy, modify, merge, publish, distribute, sublicense, 
>> and/or sell
>> + * copies of the Software, and to permit persons to whom the 
>> Software is
>> + * furnished to do so, subject to the following conditions:
>> + *
>> + * The above copyright notice and this permission notice shall be 
>> included in
>> + * all copies or substantial portions of the Software.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
>> EXPRESS OR
>> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
>> MERCHANTABILITY,
>> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 
>> SHALL
>> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES 
>> OR OTHER
>> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
>> ARISING FROM,
>> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
>> DEALINGS IN
>> + * THE SOFTWARE.
>> + */
>> +
>> +#include "qemu/osdep.h"
>> +#include "hw/pci/pci.h"
>> +#include "migration/vmstate.h"
>> +#include "qapi/error.h"
>> +#include "qemu/module.h"
>> +#include "sysemu/block-backend.h"
>> +#include "sysemu/blockdev.h"
>> +#include "sysemu/dma.h"
>> +
>> +#include "hw/ide/bmdma.h"
>> +#include "hw/ide/pci.h"
>> +#include "trace.h"
>
> Are you sure you need all these includes? I haven't checked but I 
> think there may be some unneeded ones here. On the other hand I'm not 
> sure putting these in a new file is worth it. There are already some 
> bmdma_* functions in hw/ide/pci.c which are declared in 
> include/hw/ide/pci.h so you could just move these there too then no 
> new file, new header nor changes to meson.build is needed in this patch..
>
Good question, probably not. I'll try to build without them, adding only 
what seems necessary to complete the build. Also, I think adding those 
functions to hw/ide/pci.c is a very good idea as it will make the patch 
smaller and it also makes total sense to me - Bus Master capabilities 
only appear on PCI IDE controllers and not on the ISA IDE controller 
(AFAIK).

It will happen in v3 :)

>> +
>> +uint64_t intel_ide_bmdma_read(void *opaque, hwaddr addr, unsigned size)
>
> As I said before these aren't intel specific as the same functions 
> also appear in other ide controllers such as via.c so maybe a better 
> name would be bmdma_default_read and bmdma_default_write or somehting 
> similar so these can be also reused by other non-intel devices too.
>
Right, I see now that via.c uses the exact same functions... I'll change 
it in v3. The names bmdma_default_read and bmdma_default_write seem like 
a good choice to me.
> Regards,
> BALATON Zoltan
Thanks for the review!


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

* Re: [PATCH v2 2/2] hw/ide: add ich6 ide controller device emulation
  2022-02-19  0:50   ` BALATON Zoltan
@ 2022-02-19  7:24     ` Liav Albani
  2022-02-19 12:53       ` BALATON Zoltan
  0 siblings, 1 reply; 10+ messages in thread
From: Liav Albani @ 2022-02-19  7:24 UTC (permalink / raw)
  To: BALATON Zoltan; +Cc: jsnow, qemu-devel, qemu-block


On 2/19/22 02:50, BALATON Zoltan wrote:
>> +/*
>> + * QEMU IDE Emulation: PCI ICH6/ICH7 IDE support.
>
> This is a small thing, but if these two are the same maybe keeping 
> this comment but using the ich7 name everywhere else would make it 
> less likely to get it confused with ich9. I mean ich6 and ich9 is 
> easily confused, while ich7 is clearly distinct. But maybe it's just 
> me, calling it ich6 is also correct and can be preferred by someone else.
ICH6 and ICH7 IDE controllers are quite the same as far as I know. I 
could change it, but then one could argue that the name ich6-ide seems 
like "ich9-ide", so not sure if we can really go on this path.
>
>> +static void ich6_pci_config_write(PCIDevice *d, uint32_t addr, 
>> uint32_t val,
>> +                                    int l)
>> +{
>> +    uint32_t i;
>> +
>> +    pci_default_write_config(d, addr, val, l);
>> +
>> +    for (i = addr; i < addr + l; i++) {
>> +        switch (i) {
>> +        case 0x40:
>> +            pci_default_write_config(d, i, 0x8000, 2);
>> +            continue;
>> +        case 0x42:
>> +            pci_default_write_config(d, i, 0x8000, 2);
>> +            continue;
>> +        }
>> +    }
>
> I'm not sure what this tries to do but this for cycle looks suspicious 
> here. It's also only calls pci_default_write_config() so why didn't 
> the default worked and why was this override needed?
>
It's just a loop to ensure that if the guest OS tries to disable an IDE 
channel from the PCI config space, it seems "stuck" on enabled. I should 
probably put a comment on this to explain this, but I definitely don't 
want the guest OS to be able to disable any IDE channel for now (on real 
hardware, it does that, but I think we can either skip this feature or 
implement in a future patch, as Linux deals with the controller just fine).
>> +}
>> +
>> +static void ich6_ide_reset(DeviceState *dev)
>> +{
>> +    PCIIDEState *d = PCI_IDE(dev);
>> +    PCIDevice *pd = PCI_DEVICE(d);
>> +    uint8_t *pci_conf = pd->config;
>> +    int i;
>> +
>> +    for (i = 0; i < 2; i++) {
>> +        ide_bus_reset(&d->bus[i]);
>> +    }
>> +
>> +    /* TODO: this is the default. do not override. */
>> +    pci_conf[PCI_COMMAND] = 0x00;
>> +    /* TODO: this is the default. do not override. */
>> +    pci_conf[PCI_COMMAND + 1] = 0x00;
>> +    /* TODO: use pci_set_word */
>> +    pci_conf[PCI_STATUS] = PCI_STATUS_FAST_BACK;
>> +    pci_conf[PCI_STATUS + 1] = PCI_STATUS_DEVSEL_MEDIUM >> 8;
>> +    pci_conf[0x20] = 0x01; /* BMIBA: 20-23h */
>> +}
>> +
>> +static int pci_ich6_init_ports(PCIIDEState *d)
>> +{
>> +    int i;
>> +
>> +    for (i = 0; i < 2; i++) {
>> +        ide_bus_init(&d->bus[i], sizeof(d->bus[i]), DEVICE(d), i, 2);
>> +        ide_init2(&d->bus[i], d->native_irq);
>> +
>> +        bmdma_init(&d->bus[i], &d->bmdma[i], d);
>> +        d->bmdma[i].bus = &d->bus[i];
>> +        ide_register_restart_cb(&d->bus[i]);
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>> +static void pci_ich6_ide_realize(PCIDevice *dev, Error **errp)
>> +{
>> +    PCIIDEState *d = PCI_IDE(dev);
>> +    uint8_t *pci_conf = dev->config;
>> +    int rc;
>
> All in all this device looks very similar to piix ide devices with 
> only some differentces so I wonder if ir could be implemented as 
> another device in piix.c. We already have 3 variants there: piix3-ide, 
> piix3-ide-xen, and piix4-ide so maybe putting this device in piix.c 
> could avoid some code duplication. In that case moving out 
> bmdma_{read,write} were not needed either although maybe that's a good 
> idea anyway to share it with other devices.
>
As for putting the ich6-ide code in piix.c  - I'm not against it. 
Although, in the long run, if I send more patches to QEMU, I rather 
split the files a bit more in the /hw/ide directory as there's a lot of 
code duplication to solve.
So, what we could do instead, is to share more code between the devices 
and still keep them in separate files.

As for moving out the bmdma_{write,read} functions - I'm still in the 
previous mind that we need to move them out as via.c shares the same 
code but currently has code duplications for it, and that I want to 
solve as part of making the IDE code more clean and to add more features.

However, if it seems necessary to do this cleanup before implementing 
this ich6-ide controller, I'm more than happy to wait on this, send a 
patch to solve and clean up some issues in the IDE code, and then 
re-send this as v3.
I might even consider doing that now if nobody rejects this idea :)

>> +
>> +    pci_conf[PCI_INTERRUPT_PIN] = 1; /* interrupt pin A */
>> +
>> +    /* PCI native mode-only controller, supports bus mastering */
>> +    pci_conf[PCI_CLASS_PROG] = 0x85;
>> +
>> +    bmdma_setup_bar(d);
>> +    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
>> +
>> +    d->native_irq = pci_allocate_irq(&d->parent_obj);
>
> Is this irq and the new field in PCIIDEState really needed? If this 
> device is using PCI interrupts could it do the same as CMD646 ide does 
> instead?
>
I looked into how cmd646.c does that, but it creates that with the 
qdev_init_gpio_in function. The AHCI controller seems to use 
pci_allocate_irq function (in ich.c), as well as other hardware devices 
in QEMU, but the rtl8139 device doesn't have such field and still works, 
so not sure what to do and how to make it to work in the best, simple 
way here.
> That's all for now, I haven't checked the docs of these ide 
> controllers so I'm not sure if these have switchable native and legacy 
> modes like via has and we again getting the problem that we can't 
> model that easily or these are really different with one having only 
> legacy and the ich6/7 only native modes.

If I recall correctly, on my ICH7 test machine you can switch between 
native and legacy mode, but it doesn't mean that there couldn't be a 
device on some motherboard in 2009 that doesn't allow you to switch 
between legacy and native mode. However, I rather not put the option 
because I want software to deal with a PCI device that is free from 
legacy IO ports completely. Also, I am pretty sure that if I change the 
settings in the BIOS menu then it could be stuck to native mode (if for 
example, I enable both the PATA connector and the 4 SATA ports), but 
still not sure about this. This is a feature I'll look into it in the 
future, as I definitely want to improve on this and maybe allow the user 
to configure the ich6-ide device to have a different MAP register to 
simulate 4 SATA ports and 2 PATA connections.

I'll wait a few more days to let other people send comments on this 
before sending v3. Thanks again for the valuable comments :)

Best regards,
Liav

>
> Regards.
> BALATON Zoltan


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

* Re: [PATCH v2 2/2] hw/ide: add ich6 ide controller device emulation
  2022-02-19  7:24     ` Liav Albani
@ 2022-02-19 12:53       ` BALATON Zoltan
  2022-02-21 11:33         ` Gerd Hoffmann
  0 siblings, 1 reply; 10+ messages in thread
From: BALATON Zoltan @ 2022-02-19 12:53 UTC (permalink / raw)
  To: Liav Albani; +Cc: jsnow, qemu-devel, qemu-block

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

On Sat, 19 Feb 2022, Liav Albani wrote:
> On 2/19/22 02:50, BALATON Zoltan wrote:
>>> +/*
>>> + * QEMU IDE Emulation: PCI ICH6/ICH7 IDE support.
>> 
>> This is a small thing, but if these two are the same maybe keeping this 
>> comment but using the ich7 name everywhere else would make it less likely 
>> to get it confused with ich9. I mean ich6 and ich9 is easily confused, 
>> while ich7 is clearly distinct. But maybe it's just me, calling it ich6 is 
>> also correct and can be preferred by someone else.
> ICH6 and ICH7 IDE controllers are quite the same as far as I know. I could 
> change it, but then one could argue that the name ich6-ide seems like 
> "ich9-ide", so not sure if we can really go on this path.

I think we don't actually have ich9-ide, we only have piix3, piix4 and 
ahci, the latter is used by ich9. I just said that calling this new device 
ich7-ide instead of ich6-ide would make it more clear it has nothing to do 
with ich9. It's already clear with calling it ich6 unless somebody 
misreads that which is easier with 6 than 7. Also according to 
https://en.wikipedia.org/wiki/I/O_Controller_Hub the native mode PATA 
controller first appeared in ICH3 but that says limited so maybe it was 
changed later. I don't know anthing about these so can't tell which are 
similar. Also if your reference system you're emulating is actually an 
ICH7 then calling it that would make sense to me.

>>> +static void ich6_pci_config_write(PCIDevice *d, uint32_t addr, uint32_t 
>>> val,
>>> +                                    int l)
>>> +{
>>> +    uint32_t i;
>>> +
>>> +    pci_default_write_config(d, addr, val, l);
>>> +
>>> +    for (i = addr; i < addr + l; i++) {
>>> +        switch (i) {
>>> +        case 0x40:
>>> +            pci_default_write_config(d, i, 0x8000, 2);
>>> +            continue;
>>> +        case 0x42:
>>> +            pci_default_write_config(d, i, 0x8000, 2);
>>> +            continue;
>>> +        }
>>> +    }
>> 
>> I'm not sure what this tries to do but this for cycle looks suspicious 
>> here. It's also only calls pci_default_write_config() so why didn't the 
>> default worked and why was this override needed?
>> 
> It's just a loop to ensure that if the guest OS tries to disable an IDE 
> channel from the PCI config space, it seems "stuck" on enabled. I should 
> probably put a comment on this to explain this, but I definitely don't want 
> the guest OS to be able to disable any IDE channel for now (on real hardware, 
> it does that, but I think we can either skip this feature or implement in a 
> future patch, as Linux deals with the controller just fine).

I still don't get what this tries to achieve but I think it's very likely 
wrong so if it's not needed it's better to just drop it for now. It can 
also be addressed in a follow up patch later.

>>> +}
>>> +
>>> +static void ich6_ide_reset(DeviceState *dev)
>>> +{
>>> +    PCIIDEState *d = PCI_IDE(dev);
>>> +    PCIDevice *pd = PCI_DEVICE(d);
>>> +    uint8_t *pci_conf = pd->config;
>>> +    int i;
>>> +
>>> +    for (i = 0; i < 2; i++) {
>>> +        ide_bus_reset(&d->bus[i]);
>>> +    }
>>> +
>>> +    /* TODO: this is the default. do not override. */
>>> +    pci_conf[PCI_COMMAND] = 0x00;
>>> +    /* TODO: this is the default. do not override. */
>>> +    pci_conf[PCI_COMMAND + 1] = 0x00;
>>> +    /* TODO: use pci_set_word */
>>> +    pci_conf[PCI_STATUS] = PCI_STATUS_FAST_BACK;
>>> +    pci_conf[PCI_STATUS + 1] = PCI_STATUS_DEVSEL_MEDIUM >> 8;
>>> +    pci_conf[0x20] = 0x01; /* BMIBA: 20-23h */
>>> +}
>>> +
>>> +static int pci_ich6_init_ports(PCIIDEState *d)
>>> +{
>>> +    int i;
>>> +
>>> +    for (i = 0; i < 2; i++) {
>>> +        ide_bus_init(&d->bus[i], sizeof(d->bus[i]), DEVICE(d), i, 2);
>>> +        ide_init2(&d->bus[i], d->native_irq);
>>> +
>>> +        bmdma_init(&d->bus[i], &d->bmdma[i], d);
>>> +        d->bmdma[i].bus = &d->bus[i];
>>> +        ide_register_restart_cb(&d->bus[i]);
>>> +    }
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +static void pci_ich6_ide_realize(PCIDevice *dev, Error **errp)
>>> +{
>>> +    PCIIDEState *d = PCI_IDE(dev);
>>> +    uint8_t *pci_conf = dev->config;
>>> +    int rc;
>> 
>> All in all this device looks very similar to piix ide devices with only 
>> some differentces so I wonder if ir could be implemented as another device 
>> in piix.c. We already have 3 variants there: piix3-ide, piix3-ide-xen, and 
>> piix4-ide so maybe putting this device in piix.c could avoid some code 
>> duplication. In that case moving out bmdma_{read,write} were not needed 
>> either although maybe that's a good idea anyway to share it with other 
>> devices.
>> 
> As for putting the ich6-ide code in piix.c  - I'm not against it. Although,

The real question if this controller is similiar enough to piix or it's 
different just for this initial version it's reusing most code but this 
will change in the future. If the latter then putting it in a separate 
file is better, if it will stay like it then putting it in piix to share 
code already there is better.

> in the long run, if I send more patches to QEMU, I rather split the files a 
> bit more in the /hw/ide directory as there's a lot of code duplication to 
> solve.
> So, what we could do instead, is to share more code between the devices and 
> still keep them in separate files.

I just wanted to avoid more code duplication by adding new files that will 
look like the devices that's already there. But if this is just a first 
step and you'll send more patches to implement more features that will 
make it more different, then having it in a separate file is better. But I 
could only judge from the patch so far which is almost identical to piix, 
only differentce is irq and port handling so this could be a variant of 
piix then as well if that's all you want for this device.

> As for moving out the bmdma_{write,read} functions - I'm still in the 
> previous mind that we need to move them out as via.c shares the same code but 
> currently has code duplications for it, and that I want to solve as part of 
> making the IDE code more clean and to add more features.
>
> However, if it seems necessary to do this cleanup before implementing this 
> ich6-ide controller, I'm more than happy to wait on this, send a patch to 
> solve and clean up some issues in the IDE code, and then re-send this as v3.
> I might even consider doing that now if nobody rejects this idea :)

It can be in the same series but still good to have as separate patch so 
it can be reviewed independently and maybe also merged independently. The 
maintainer can always squash patches together later but separating them is 
usually only the original contributor can easily and best do.

>>> +
>>> +    pci_conf[PCI_INTERRUPT_PIN] = 1; /* interrupt pin A */
>>> +
>>> +    /* PCI native mode-only controller, supports bus mastering */
>>> +    pci_conf[PCI_CLASS_PROG] = 0x85;
>>> +
>>> +    bmdma_setup_bar(d);
>>> +    pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
>>> +
>>> +    d->native_irq = pci_allocate_irq(&d->parent_obj);
>> 
>> Is this irq and the new field in PCIIDEState really needed? If this device 
>> is using PCI interrupts could it do the same as CMD646 ide does instead?
>> 
> I looked into how cmd646.c does that, but it creates that with the 
> qdev_init_gpio_in function. The AHCI controller seems to use pci_allocate_irq 
> function (in ich.c), as well as other hardware devices in QEMU, but the 
> rtl8139 device doesn't have such field and still works, so not sure what to 
> do and how to make it to work in the best, simple way here.

The cmd646 is similar as it's a PCI device and shares the same PCIIDEState 
so I think doing the same is best for cnosistency and to avoid needing to 
change the shared PCIIDEState that should be a generic PCI IDE controller 
model but still has one cmd646 specific field. Using qdev_init_gpio_in 
attaches the irq to the device so it will be kept track of without needing 
to store it anywhere so I think it's not a bad way to do it for this case. 
AHCI has its own device state and stores the irq there, I don't know what 
rtl8139 does. There may be multiple correct ways to do it but following 
similar examples is probably a good idea.

>> That's all for now, I haven't checked the docs of these ide controllers so 
>> I'm not sure if these have switchable native and legacy modes like via has 
>> and we again getting the problem that we can't model that easily or these 
>> are really different with one having only legacy and the ich6/7 only native 
>> modes.
>
> If I recall correctly, on my ICH7 test machine you can switch between native 
> and legacy mode, but it doesn't mean that there couldn't be a device on some 
> motherboard in 2009 that doesn't allow you to switch between legacy and

OK so we probably again have a case we had with via-ide which also has 
legacy mode where it behaves like an ISA controller using legacy ports and 
irq 14-15 or a native mode where ports can be set by PCI BARs and irqs may 
or may not use PCI interrupt. Due to how ISA code is organised, which is 
an old part of QEMU we can't easily implement this (the main problem is 
once ISA ports are created we can't delete them so we're stuck in legacy 
mode) so what we have is only emulating one mode for these controller 
models. I think the cmd646 is completely PCI device (not sure it had a 
legacy mode), the via-ide is native mode but with ISA interrupts and piix 
is probably only legacy mode but not sure if it had a native mode. Maybe 
this ich-ide is the native mode of piix? In that case could it be modelled 
that way adding an option to piix so it can be set up in native mode or 
legacy mode? We would still not be able to switch between them from the 
guest as on real hardware but machines or users could decide when creating 
the device what mode they want. Or is the ich ide completely different 
from piix?

> native mode. However, I rather not put the option because I want software to 
> deal with a PCI device that is free from legacy IO ports completely. Also, I 
> am pretty sure that if I change the settings in the BIOS menu then it could 
> be stuck to native mode (if for example, I enable both the PATA connector and 
> the 4 SATA ports), but still not sure about this. This is a feature I'll look 
> into it in the future, as I definitely want to improve on this and maybe 
> allow the user to configure the ich6-ide device to have a different MAP 
> register to simulate 4 SATA ports and 2 PATA connections.

OK then it will probably be different from piix so maybe this justifies it 
putting it in a different file and code that is similar now will become 
more different in the future.

> I'll wait a few more days to let other people send comments on this before 
> sending v3. Thanks again for the valuable comments :)

That's probably a good idea, I hope others will have some time to comment 
as well. I'm trying to help but I can only give ideas, not definitive 
answers for your questions.

Regards.
BALATON Zoltan

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

* Re: [PATCH v2 2/2] hw/ide: add ich6 ide controller device emulation
  2022-02-19 12:53       ` BALATON Zoltan
@ 2022-02-21 11:33         ` Gerd Hoffmann
  2022-02-21 18:52           ` Liav Albani
  0 siblings, 1 reply; 10+ messages in thread
From: Gerd Hoffmann @ 2022-02-21 11:33 UTC (permalink / raw)
  To: BALATON Zoltan; +Cc: jsnow, Liav Albani, qemu-block, qemu-devel

  Hi,

> > ICH6 and ICH7 IDE controllers are quite the same as far as I know. I
> > could change it, but then one could argue that the name ich6-ide seems
> > like "ich9-ide", so not sure if we can really go on this path.
> 
> I think we don't actually have ich9-ide, we only have piix3, piix4 and ahci,
> the latter is used by ich9. I just said that calling this new device
> ich7-ide instead of ich6-ide would make it more clear it has nothing to do
> with ich9.

Well, there actually is ich9-ide in physical hardware.  And it's quite
simliar for all ich6 -> ich9 (and possibly more) physical hardware.

The hardware implements both ide and sata.  Typically the bios setup
offers to pick ide or sata mode for the storage controller, and on boot
the chipset is configured accordingly by the firmware.

qemu never bothered to implement ide mode for q35/ich9.  When a guest OS
is so old that it doesn't come with a sata driver there is the option to
just use the 'pc' machine type.  And usually that's the better choice
anyway because these old guests tend to have problems with other q35
components too.

So I'm wondering why you implement ich{6,7,9}-ide in the first place?
What is the use case / benefit?

take care,
  Gerd



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

* Re: [PATCH v2 2/2] hw/ide: add ich6 ide controller device emulation
  2022-02-21 11:33         ` Gerd Hoffmann
@ 2022-02-21 18:52           ` Liav Albani
  0 siblings, 0 replies; 10+ messages in thread
From: Liav Albani @ 2022-02-21 18:52 UTC (permalink / raw)
  To: Gerd Hoffmann, BALATON Zoltan; +Cc: jsnow, qemu-devel, qemu-block


On 2/21/22 13:33, Gerd Hoffmann wrote:
>    Hi,
>
>>> ICH6 and ICH7 IDE controllers are quite the same as far as I know. I
>>> could change it, but then one could argue that the name ich6-ide seems
>>> like "ich9-ide", so not sure if we can really go on this path.
>> I think we don't actually have ich9-ide, we only have piix3, piix4 and ahci,
>> the latter is used by ich9. I just said that calling this new device
>> ich7-ide instead of ich6-ide would make it more clear it has nothing to do
>> with ich9.
> Well, there actually is ich9-ide in physical hardware.  And it's quite
> simliar for all ich6 -> ich9 (and possibly more) physical hardware.
I know, but I based it on Intel documentation and the ICH7 machine I 
have from 2009. Also, according to libata in Linux, the enum of 
piix_controller_ids include ich5, ich6 and ich8 (and much more, these 
are more relevant in the list for this reason), and by looking into what 
ich6_sata is being used for, I can see it matches the IDE controller PCI 
ID on the ICH7 machine I use, so that's another reason to choose this name.
> The hardware implements both ide and sata.  Typically the bios setup
> offers to pick ide or sata mode for the storage controller, and on boot
> the chipset is configured accordingly by the firmware.
Yes, and then the BIOS configures the MAP register to indicate the setup 
that it was decided by the user in the BIOS configuration.
However, setting the MAP register to zero is a valid value - it 
indicates you have only SATA connectors in use (at least that's what 
Linux thinks), according to the Intel ICH5 Serial ATA Controller RPM.
> qemu never bothered to implement ide mode for q35/ich9.  When a guest OS
> is so old that it doesn't come with a sata driver there is the option to
> just use the 'pc' machine type.  And usually that's the better choice
> anyway because these old guests tend to have problems with other q35
> components too.
That's true if you care about giving emulation only for the benefits of 
the guest (so you only care about supporting what the guest OS can 
expect from standard IDE controller, not edge cases), but my approach is 
looking at a very different goal.
> So I'm wondering why you implement ich{6,7,9}-ide in the first place?
> What is the use case / benefit?

I talked about it in the last patch about this topic I've sent (v1 to be 
precise), but let me describe it again :)
I'm a SerenityOS developer, as you might remember or not, I've talked to 
you (Gerd) in the past about SeaBIOS topics related to the OS off-list.
As I said before in this mail, I tend to test the SerenityOS kernel on 
the ICH7 machine I have from 2009. That machine has 4 SATA ports and you 
can connect 2 PATA devices (as one parallel cable can be used to connect 
two devices at once, to one connector on the mainboard).

I've seen that the kernel struggled to use the IDE controller - the main 
problem we have is long timeouts because of some problematic pattern in 
our code. However, on regular QEMU PC and Q35 machines everything boots 
fine. When I wrote this emulation component, I saw the same problem I 
had on the bare metal machine, so it is a convenient feature for me to 
debug this problem without having to use the bare metal machine - it 
helps saving lots of time for me by avoiding the need to compile a 
kernel, put it on the SATA harddrive and try to boot it in the rapid 
compile-boot-test cycle I have here.

I thought it might be beneficial for other OS developers and hobbyists 
like me to have such component. For now, it's an IDE 
ICH5/6/7/9-compatible controller, supporting only PCI IDE native mode - 
which means you can relocate the resources to anything you want on the 
IO space, so it's a legacy-free device in the sense of PCI bus resource 
management, but still a legacy device that to use it on bare metal you 
need a machine from late 2000s.

Also, I do see a point in expanding this controller with more features. 
For example, some ICH6 IDE controllers had AHCI mode within them, so you 
could actually enable the AHCI mode and disable IDE mode if you know 
what you're doing - you will probably need to assign the IDE PCI BARs 
correctly first if you want IDE mode in such controller, or ignore it 
and go with AHCI mode instead. Also, this emulation component is only 
about PCI IDE native mode currently, but we can easily put it that you 
can switch channels between compatibility mode and native mode if wanted 
to. My ICH7 test machine has such controller - it allows you to switch 
between the two modes, so the OS can decide what to do with the IDE 
controller according to its needs.

> take care,
>    Gerd
>
Best regards,
Liav



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

end of thread, other threads:[~2022-02-21 18:57 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-18 20:41 [PATCH v2 0/2] hw/ide: implement ich6 ide controller support Liav Albani
2022-02-18 20:41 ` [PATCH v2 1/2] hw/ide: split bmdma read and write functions from piix.c Liav Albani
2022-02-19  0:12   ` BALATON Zoltan
2022-02-19  6:43     ` Liav Albani
2022-02-18 20:41 ` [PATCH v2 2/2] hw/ide: add ich6 ide controller device emulation Liav Albani
2022-02-19  0:50   ` BALATON Zoltan
2022-02-19  7:24     ` Liav Albani
2022-02-19 12:53       ` BALATON Zoltan
2022-02-21 11:33         ` Gerd Hoffmann
2022-02-21 18:52           ` Liav Albani

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.