Re: [PATCH 10/11] hw/sd/sdhci: Implement Freescale eSDHC device model

2022-09-16 Thread Bernhard Beschow
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

2022-09-16 Thread 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?

> +
> +#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

2022-09-15 Thread Bernhard Beschow
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 --- */