Re: [PATCH 10/11] hw/sd/sdhci: Implement Freescale eSDHC device model
Am 16. September 2022 15:15:03 UTC schrieb Bin Meng : >On Thu, Sep 15, 2022 at 11:30 PM Bernhard Beschow wrote: >> >> Will allow e500 boards to access SD cards using just their own devices. >> >> Signed-off-by: Bernhard Beschow >> --- >> 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 = _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(>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_10x114 >> + >> +/* Control Register for DMA transfer */ >> +#define ESDHC_DMA_SYSCTL0x40c >> +#define ESDHC_PERIPHERAL_CLK_SEL0x0008 >> +#define ESDHC_FLUSH_ASYNC_FIFO 0x0004 >> +#define ESDHC_DMA_SNOOP 0x0040 > >It looks the above 3 bit fields are not used? Yes, possibly. I'll check for more unused stuff. >> + >> +#define ESDHC_REGISTERS_MAP_SIZE0x410 >> + >> +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? Sure. Not sure why I didn't. >> +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 Ack. Best regards, Bernhard > >> +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 =
Re: [PATCH 10/11] hw/sd/sdhci: Implement Freescale eSDHC device model
On Thu, Sep 15, 2022 at 11:30 PM Bernhard Beschow wrote: > > Will allow e500 boards to access SD cards using just their own devices. > > Signed-off-by: Bernhard Beschow > --- > 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 = _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(>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_10x114 > + > +/* Control Register for DMA transfer */ > +#define ESDHC_DMA_SYSCTL0x40c > +#define ESDHC_PERIPHERAL_CLK_SEL0x0008 > +#define ESDHC_FLUSH_ASYNC_FIFO 0x0004 > +#define ESDHC_DMA_SNOOP 0x0040 It looks the above 3 bit fields are not used? > + > +#define ESDHC_REGISTERS_MAP_SIZE0x410 > + > +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); >
[PATCH 10/11] hw/sd/sdhci: Implement Freescale eSDHC device model
Will allow e500 boards to access SD cards using just their own devices. Signed-off-by: Bernhard Beschow --- 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 = _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(>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_10x114 + +/* Control Register for DMA transfer */ +#define ESDHC_DMA_SYSCTL0x40c +#define ESDHC_PERIPHERAL_CLK_SEL0x0008 +#define ESDHC_FLUSH_ASYNC_FIFO 0x0004 +#define ESDHC_DMA_SNOOP 0x0040 + +#define ESDHC_REGISTERS_MAP_SIZE0x410 + +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: +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: +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 = _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 --- */