On Thu, Sep 15, 2022 at 11:30 PM Bernhard Beschow <shen...@gmail.com> wrote: > > Will allow e500 boards to access SD cards using just their own devices. > > Signed-off-by: Bernhard Beschow <shen...@gmail.com> > --- > hw/sd/sdhci.c | 147 +++++++++++++++++++++++++++++++++++++++++- > include/hw/sd/sdhci.h | 3 + > 2 files changed, 149 insertions(+), 1 deletion(-) > > diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c > index 7a5996caad..09285ccfa1 100644 > --- a/hw/sd/sdhci.c > +++ b/hw/sd/sdhci.c > @@ -1369,6 +1369,7 @@ void sdhci_initfn(SDHCIState *s) > s->transfer_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, > sdhci_data_transfer, s); > > s->io_ops = &sdhci_mmio_ops; > + s->io_registers_map_size = SDHC_REGISTERS_MAP_SIZE; > } > > void sdhci_uninitfn(SDHCIState *s) > @@ -1392,7 +1393,7 @@ void sdhci_common_realize(SDHCIState *s, Error **errp) > s->fifo_buffer = g_malloc0(s->buf_maxsz); > > memory_region_init_io(&s->iomem, OBJECT(s), s->io_ops, s, "sdhci", > - SDHC_REGISTERS_MAP_SIZE); > + s->io_registers_map_size); > } > > void sdhci_common_unrealize(SDHCIState *s) > @@ -1575,6 +1576,149 @@ static const TypeInfo sdhci_bus_info = { > .class_init = sdhci_bus_class_init, > }; > > +/* --- qdev Freescale eSDHC --- */ > + > +/* Host Controller Capabilities Register 2 */ > +#define ESDHC_CAPABILITIES_1 0x114 > + > +/* Control Register for DMA transfer */ > +#define ESDHC_DMA_SYSCTL 0x40c > +#define ESDHC_PERIPHERAL_CLK_SEL 0x00080000 > +#define ESDHC_FLUSH_ASYNC_FIFO 0x00040000 > +#define ESDHC_DMA_SNOOP 0x00000040
It looks the above 3 bit fields are not used? > + > +#define ESDHC_REGISTERS_MAP_SIZE 0x410 > + > +static uint64_t esdhci_read(void *opaque, hwaddr offset, unsigned size) > +{ > + uint64_t ret; > + > + if (size != 4) { > + qemu_log_mask(LOG_GUEST_ERROR, "ESDHC rd_%ub @0x%02" HWADDR_PRIx > + " wrong size\n", size, offset); > + return 0; > + } > + > + if (offset & 0x3) { > + qemu_log_mask(LOG_GUEST_ERROR, "ESDHC rd_%ub @0x%02" HWADDR_PRIx > + " unaligned\n", size, offset); > + return 0; > + } > + > + switch (offset) { > + case SDHC_SYSAD: > + case SDHC_BLKSIZE: > + case SDHC_ARGUMENT: > + case SDHC_TRNMOD: > + case SDHC_RSPREG0: > + case SDHC_RSPREG1: > + case SDHC_RSPREG2: > + case SDHC_RSPREG3: > + case SDHC_BDATA: > + case SDHC_PRNSTS: > + case SDHC_HOSTCTL: > + case SDHC_CLKCON: > + case SDHC_NORINTSTS: > + case SDHC_NORINTSTSEN: > + case SDHC_NORINTSIGEN: > + case SDHC_ACMD12ERRSTS: > + case SDHC_CAPAB: > + case SDHC_SLOT_INT_STATUS: > + ret = sdhci_read(opaque, offset, size); > + break; > + > + case ESDHC_DMA_SYSCTL: > + case 0x44: Can we define a macro for this offset? > + ret = 0; > + qemu_log_mask(LOG_UNIMP, "ESDHC rd_%ub @0x%02" HWADDR_PRIx > + " not implemented\n", size, offset); > + break; > + > + default: > + ret = 0; > + qemu_log_mask(LOG_GUEST_ERROR, "ESDHC rd_%ub @0x%02" HWADDR_PRIx > + " unknown offset\n", size, offset); > + break; > + } > + > + return ret; > +} > + > +static void esdhci_write(void *opaque, hwaddr offset, uint64_t val, > + unsigned size) > +{ > + if (size != 4) { > + qemu_log_mask(LOG_GUEST_ERROR, "ESDHC wr_%ub @0x%02" HWADDR_PRIx > + " <- 0x%08lx wrong size\n", size, offset, val); > + return; > + } > + > + if (offset & 0x3) { > + qemu_log_mask(LOG_GUEST_ERROR, "ESDHC wr_%ub @0x%02" HWADDR_PRIx > + " <- 0x%08lx unaligned\n", size, offset, val); > + return; > + } > + > + switch (offset) { > + case SDHC_SYSAD: > + case SDHC_BLKSIZE: > + case SDHC_ARGUMENT: > + case SDHC_TRNMOD: > + case SDHC_BDATA: > + case SDHC_HOSTCTL: > + case SDHC_CLKCON: > + case SDHC_NORINTSTS: > + case SDHC_NORINTSTSEN: > + case SDHC_NORINTSIGEN: > + case SDHC_FEAER: > + sdhci_write(opaque, offset, val, size); > + break; > + > + case ESDHC_DMA_SYSCTL: > + case 0x44: ditto > + qemu_log_mask(LOG_UNIMP, "ESDHC wr_%ub @0x%02" HWADDR_PRIx " <- > 0x%08lx " > + "not implemented\n", size, offset, val); > + break; > + > + default: > + qemu_log_mask(LOG_GUEST_ERROR, "ESDHC wr_%ub @0x%02" HWADDR_PRIx > + " <- 0x%08lx unknown offset\n", size, offset, val); > + break; > + } > +} > + > +static const MemoryRegionOps esdhc_mmio_ops = { > + .read = esdhci_read, > + .write = esdhci_write, > + .valid = { > + .min_access_size = 1, > + .max_access_size = 4, > + .unaligned = false > + }, > + .endianness = DEVICE_BIG_ENDIAN, > +}; > + > +static void esdhci_init(Object *obj) > +{ > + DeviceState *dev = DEVICE(obj); > + SDHCIState *s = SYSBUS_SDHCI(obj); > + > + s->io_ops = &esdhc_mmio_ops; > + s->io_registers_map_size = ESDHC_REGISTERS_MAP_SIZE; > + > + /* > + * Compatible with: > + * - SD Host Controller Specification Version 2.0 Part A2 > + */ > + qdev_prop_set_uint8(dev, "sd-spec-version", 2); > +} > + > +static const TypeInfo esdhc_info = { > + .name = TYPE_FSL_ESDHC, > + .parent = TYPE_SYSBUS_SDHCI, > + .instance_init = esdhci_init, > +}; > + > /* --- qdev i.MX eSDHC --- */ > > #define USDHC_MIX_CTRL 0x48 > @@ -1907,6 +2051,7 @@ static void sdhci_register_types(void) > { > type_register_static(&sdhci_sysbus_info); > type_register_static(&sdhci_bus_info); > + type_register_static(&esdhc_info); > type_register_static(&imx_usdhc_info); > type_register_static(&sdhci_s3c_info); > } > diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h > index 01a64c5442..5b32e83eee 100644 > --- a/include/hw/sd/sdhci.h > +++ b/include/hw/sd/sdhci.h > @@ -45,6 +45,7 @@ struct SDHCIState { > AddressSpace *dma_as; > MemoryRegion *dma_mr; > const MemoryRegionOps *io_ops; > + uint64_t io_registers_map_size; > > QEMUTimer *insert_timer; /* timer for 'changing' sd card. */ > QEMUTimer *transfer_timer; > @@ -122,6 +123,8 @@ DECLARE_INSTANCE_CHECKER(SDHCIState, PCI_SDHCI, > DECLARE_INSTANCE_CHECKER(SDHCIState, SYSBUS_SDHCI, > TYPE_SYSBUS_SDHCI) > > +#define TYPE_FSL_ESDHC "fsl-esdhc" > + > #define TYPE_IMX_USDHC "imx-usdhc" > > #define TYPE_S3C_SDHCI "s3c-sdhci" > -- Regards, Bin