qemu-block
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 5/5] cmd646: move device-specific BMDMA registers to separate mem


From: Mark Cave-Ayland
Subject: [PATCH 5/5] cmd646: move device-specific BMDMA registers to separate memory region
Date: Fri, 9 Jun 2023 19:51:19 +0100

The aim here is to eliminate any device-specific registers from the main BMDMA
bar memory region so it can potentially be moved into the shared PCI IDE device.

For each BMDMA bus create a new cmd646-bmdma-specific memory region representing
the device-specific BMDMA registers and then map them using aliases onto the
existing BMDMAState memory region.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/ide/cmd646.c         | 111 +++++++++++++++++++++++++++++++---------
 include/hw/ide/cmd646.h |   4 ++
 2 files changed, 90 insertions(+), 25 deletions(-)

diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
index 9103da581f..dd495f2e1b 100644
--- a/hw/ide/cmd646.c
+++ b/hw/ide/cmd646.c
@@ -90,7 +90,6 @@ static uint64_t bmdma_read(void *opaque, hwaddr addr,
                            unsigned size)
 {
     BMDMAState *bm = opaque;
-    PCIDevice *pci_dev = PCI_DEVICE(bm->pci_dev);
     uint32_t val;
 
     if (size != 1) {
@@ -101,19 +100,9 @@ static uint64_t bmdma_read(void *opaque, hwaddr addr,
     case 0:
         val = bm->cmd;
         break;
-    case 1:
-        val = pci_dev->config[MRDMODE];
-        break;
     case 2:
         val = bm->status;
         break;
-    case 3:
-        if (bm == &bm->pci_dev->bmdma[0]) {
-            val = pci_dev->config[UDIDETCR0];
-        } else {
-            val = pci_dev->config[UDIDETCR1];
-        }
-        break;
     default:
         val = 0xff;
         break;
@@ -127,7 +116,6 @@ static void bmdma_write(void *opaque, hwaddr addr,
                         uint64_t val, unsigned size)
 {
     BMDMAState *bm = opaque;
-    PCIDevice *pci_dev = PCI_DEVICE(bm->pci_dev);
 
     if (size != 1) {
         return;
@@ -138,23 +126,10 @@ static void bmdma_write(void *opaque, hwaddr addr,
     case 0:
         bmdma_cmd_writeb(bm, val);
         break;
-    case 1:
-        pci_dev->config[MRDMODE] =
-            (pci_dev->config[MRDMODE] & ~0x30) | (val & 0x30);
-        cmd646_update_dma_interrupts(pci_dev);
-        cmd646_update_irq(pci_dev);
-        break;
     case 2:
         bm->status = (val & 0x60) | (bm->status & 1) |
                      (bm->status & ~val & 0x06);
         break;
-    case 3:
-        if (bm == &bm->pci_dev->bmdma[0]) {
-            pci_dev->config[UDIDETCR0] = val;
-        } else {
-            pci_dev->config[UDIDETCR1] = val;
-        }
-        break;
     }
 }
 
@@ -181,6 +156,91 @@ static void bmdma_setup_bar(PCIIDEState *d)
     }
 }
 
+static uint64_t cmd646_bmdma_read(void *opaque, hwaddr addr, unsigned size)
+{
+    BMDMAState *bm = opaque;
+    PCIDevice *pci_dev = PCI_DEVICE(bm->pci_dev);
+    uint32_t val;
+
+    if (size != 1) {
+        return ((uint64_t)1 << (size * 8)) - 1;
+    }
+
+    switch (addr & 3) {
+    case 1:
+        val = pci_dev->config[MRDMODE];
+        break;
+    case 3:
+        if (bm == &bm->pci_dev->bmdma[0]) {
+            val = pci_dev->config[UDIDETCR0];
+        } else {
+            val = pci_dev->config[UDIDETCR1];
+        }
+        break;
+    default:
+        val = 0xff;
+        break;
+    }
+
+    trace_bmdma_read_cmd646(addr, val);
+    return val;
+}
+
+static void cmd646_bmdma_write(void *opaque, hwaddr addr, uint64_t val,
+                               unsigned size)
+{
+    BMDMAState *bm = opaque;
+    PCIDevice *pci_dev = PCI_DEVICE(bm->pci_dev);
+
+    if (size != 1) {
+        return;
+    }
+
+    trace_bmdma_write_cmd646(addr, val);
+    switch (addr & 3) {
+    case 1:
+        pci_dev->config[MRDMODE] =
+            (pci_dev->config[MRDMODE] & ~0x30) | (val & 0x30);
+        cmd646_update_dma_interrupts(pci_dev);
+        cmd646_update_irq(pci_dev);
+        break;
+    case 3:
+        if (bm == &bm->pci_dev->bmdma[0]) {
+            pci_dev->config[UDIDETCR0] = val;
+        } else {
+            pci_dev->config[UDIDETCR1] = val;
+        }
+        break;
+    }
+}
+
+static const MemoryRegionOps cmd646_bmdma_ops = {
+    .read = cmd646_bmdma_read,
+    .write = cmd646_bmdma_write,
+};
+
+static void cmd646_bmdma_setup(PCIIDEState *d)
+{
+    CMD646IDEState *s = CMD646_IDE(d);
+    BMDMAState *bm;
+    int i;
+
+    /* Setup aliases for device-specific BMDMA registers */
+    for (i = 0; i < 2; i++) {
+        bm = &d->bmdma[i];
+        memory_region_init_io(&s->bmdma_mem[i], OBJECT(d), &cmd646_bmdma_ops,
+                              bm, "cmd646-bmdma", 4);
+        memory_region_init_alias(&s->bmdma_mem_alias[i][0], OBJECT(d),
+                                 "cmd646-bmdma[1]", &s->bmdma_mem[i], 0x1, 1);
+        memory_region_add_subregion(&bm->extra_io, 0x1,
+                                    &s->bmdma_mem_alias[i][0]);
+        memory_region_init_alias(&s->bmdma_mem_alias[i][1], OBJECT(d),
+                                 "cmd646-bmdma[3]", &s->bmdma_mem[i], 0x3, 1);
+        memory_region_add_subregion(&bm->extra_io, 0x3,
+                                    &s->bmdma_mem_alias[i][1]);
+    }
+}
+
 static void cmd646_update_irq(PCIDevice *pd)
 {
     int pci_level;
@@ -289,6 +349,7 @@ static void pci_cmd646_ide_realize(PCIDevice *dev, Error 
**errp)
 
     bmdma_setup_bar(d);
     pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
+    cmd646_bmdma_setup(d);
 
     /* TODO: RST# value should be 0 */
     pci_conf[PCI_INTERRUPT_PIN] = 0x01; /* interrupt on pin 1 */
diff --git a/include/hw/ide/cmd646.h b/include/hw/ide/cmd646.h
index 4780b1132c..5329964533 100644
--- a/include/hw/ide/cmd646.h
+++ b/include/hw/ide/cmd646.h
@@ -29,10 +29,14 @@
 #define TYPE_CMD646_IDE "cmd646-ide"
 OBJECT_DECLARE_SIMPLE_TYPE(CMD646IDEState, CMD646_IDE)
 
+#include "exec/memory.h"
 #include "hw/ide/pci.h"
 
 struct CMD646IDEState {
     PCIIDEState parent_obj;
+
+    MemoryRegion bmdma_mem[2];
+    MemoryRegion bmdma_mem_alias[2][2];
 };
 
 #endif
-- 
2.30.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]