Hi Bin,
On 3/9/26 13:24, Bin Meng wrote:
The Synopsys DesignWare Mobile Storage Host predates SDHCI and uses
a distinct MCI programming interface. It is integrated by Samsung
Exynos, Rockchip, HiSilicon, and Altera/Intel SoCFPGA platforms,
among others.
Add a reusable controller model based on the DesignWare Mobile Storage
Host 2.40a databook. Cover command and response handling, PIO FIFO
aliases, reset and interrupt semantics, card state, and the standard
32-bit internal descriptor DMA engine. Also support the later 64-bit
descriptor layout used by vendor variants.
Expose class hooks and immutable configuration fields so vendor
extensions can reuse the common implementation.
Signed-off-by: Bin Meng <[email protected]>
---
MAINTAINERS | 2 +
hw/sd/Kconfig | 5 +
hw/sd/dw_mci.c | 1382 ++++++++++++++++++++++++++++++++++++++++
hw/sd/meson.build | 1 +
include/hw/sd/dw_mci.h | 74 +++
5 files changed, 1464 insertions(+)
create mode 100644 hw/sd/dw_mci.c
create mode 100644 include/hw/sd/dw_mci.h
Please enable scripts/git.orderfile to ease review.
+REG32(ENABLE_SHIFT, 0x110)
+static const VMStateDescription dw_mci_vmsd = {
+ .name = TYPE_DW_MCI,
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .post_load = dw_mci_post_load,
+ .fields = (const VMStateField[]) {
+ VMSTATE_UINT32_ARRAY(regs, DwMciState, DW_MCI_REG_COUNT),
+ VMSTATE_UINT8_ARRAY(fifo, DwMciState, DW_MCI_FIFO_MAX_BYTES),
+ VMSTATE_UINT32(fifo_head, DwMciState),
+ VMSTATE_UINT32(fifo_len, DwMciState),
+ VMSTATE_UINT32(transfer_remaining, DwMciState),
+ VMSTATE_UINT64(idmac_desc_addr, DwMciState),
+ VMSTATE_BOOL(transfer_active, DwMciState),
+ VMSTATE_BOOL(transfer_write, DwMciState),
+ VMSTATE_BOOL(transfer_send_stop, DwMciState),
+ VMSTATE_BOOL(idmac_suspended, DwMciState),
+ VMSTATE_BOOL(idmac_fatal, DwMciState),
+ VMSTATE_BOOL(card_inserted, DwMciState),
+ VMSTATE_BOOL(card_readonly, DwMciState),
+ VMSTATE_END_OF_LIST()
+ },
+};
+#define DW_MCI_MMIO_SIZE 0x1000
+#define DW_MCI_REG_COUNT (DW_MCI_MMIO_SIZE / sizeof(uint32_t))
At a glance, less than 70 registers are addressed but you
map and allocate more than 1000, which end being migrated.
Maybe we can start with fewer (96?) registers, still mapping
the whole 4K region?
+#define DW_MCI_FIFO_MAX_WORDS 2048
+#define DW_MCI_FIFO_MAX_BYTES (DW_MCI_FIFO_MAX_WORDS * sizeof(uint32_t))
+
+struct DwMciState {
+ SysBusDevice parent_obj;
+
+ MemoryRegion iomem;
+ SDBus sdbus;
+ qemu_irq irq;
+
+ uint32_t regs[DW_MCI_REG_COUNT];
+ RegisterInfo regs_info[DW_MCI_REG_COUNT];
+
+ uint8_t fifo[DW_MCI_FIFO_MAX_BYTES];
+ uint32_t fifo_head;
+ uint32_t fifo_len;
+ uint32_t transfer_remaining;
+ uint64_t idmac_desc_addr;
+ bool transfer_active;
+ bool transfer_write;
+ bool transfer_send_stop;
+ bool idmac_suspended;
+ bool idmac_fatal;
+ bool card_inserted;
+ bool card_readonly;
+
+ uint32_t verid;
+ uint32_t hcon;
+ uint32_t data_offset;
+ uint32_t fifo_depth;
+};