Hi Philippe,
On Thu, Sep 3, 2026 at 11:07 PM Philippe Mathieu-Daudé
<[email protected]> wrote:
>
> 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.
Have done that for my local QEMU repo.
>
>
> > +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?
Makes sense. Will fix in v2.
>
> > +#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;
> > +};
Regards,
Bin