Re: [PATCH 13/24] hw/misc/aspeed_xdma: Add AST2600 support

2021-04-07 Thread Eddie James
On Wed, 2021-04-07 at 19:16 +0200, Cédric Le Goater wrote:
> When we introduced support for the AST2600 SoC, the XDMA controller
> was forgotten. It went unnoticed because it's not used under
> emulation.
> But the register layout being different, the reset procedure is bogus
> and this breaks kexec.
> 
> Add a AspeedXDMAClass to take into account the register differences.

Thanks Cedric!

Reviewed-by: Eddie James 

> 
> Cc: Eddie James 
> Signed-off-by: Cédric Le Goater 
> ---
>  include/hw/misc/aspeed_xdma.h |  17 -
>  hw/arm/aspeed_ast2600.c   |   3 +-
>  hw/arm/aspeed_soc.c   |   3 +-
>  hw/misc/aspeed_xdma.c | 124 +++-
> --
>  4 files changed, 121 insertions(+), 26 deletions(-)
> 
> diff --git a/include/hw/misc/aspeed_xdma.h
> b/include/hw/misc/aspeed_xdma.h
> index a2dea96984f3..b1478fd1c681 100644
> --- a/include/hw/misc/aspeed_xdma.h
> +++ b/include/hw/misc/aspeed_xdma.h
> @@ -13,7 +13,10 @@
>  #include "qom/object.h"
>  
>  #define TYPE_ASPEED_XDMA "aspeed.xdma"
> -OBJECT_DECLARE_SIMPLE_TYPE(AspeedXDMAState, ASPEED_XDMA)
> +#define TYPE_ASPEED_2400_XDMA TYPE_ASPEED_XDMA "-ast2400"
> +#define TYPE_ASPEED_2500_XDMA TYPE_ASPEED_XDMA "-ast2500"
> +#define TYPE_ASPEED_2600_XDMA TYPE_ASPEED_XDMA "-ast2600"
> +OBJECT_DECLARE_TYPE(AspeedXDMAState, AspeedXDMAClass, ASPEED_XDMA)
>  
>  #define ASPEED_XDMA_NUM_REGS (ASPEED_XDMA_REG_SIZE /
> sizeof(uint32_t))
>  #define ASPEED_XDMA_REG_SIZE 0x7C
> @@ -28,4 +31,16 @@ struct AspeedXDMAState {
>  uint32_t regs[ASPEED_XDMA_NUM_REGS];
>  };
>  
> +struct AspeedXDMAClass {
> +SysBusDeviceClass parent_class;
> +
> +uint8_t cmdq_endp;
> +uint8_t cmdq_wrp;
> +uint8_t cmdq_rdp;
> +uint8_t intr_ctrl;
> +uint32_t intr_ctrl_mask;
> +uint8_t intr_status;
> +uint32_t intr_complete;
> +};
> +
>  #endif /* ASPEED_XDMA_H */
> diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
> index e0fbb020c770..c60824bfeecb 100644
> --- a/hw/arm/aspeed_ast2600.c
> +++ b/hw/arm/aspeed_ast2600.c
> @@ -187,7 +187,8 @@ static void aspeed_soc_ast2600_init(Object *obj)
>  object_initialize_child(obj, "mii[*]", >mii[i],
> TYPE_ASPEED_MII);
>  }
>  
> -object_initialize_child(obj, "xdma", >xdma,
> TYPE_ASPEED_XDMA);
> +snprintf(typename, sizeof(typename), TYPE_ASPEED_XDMA "-%s",
> socname);
> +object_initialize_child(obj, "xdma", >xdma, typename);
>  
>  snprintf(typename, sizeof(typename), "aspeed.gpio-%s", socname);
>  object_initialize_child(obj, "gpio", >gpio, typename);
> diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
> index 8ed29113f79f..4a95d27d9d63 100644
> --- a/hw/arm/aspeed_soc.c
> +++ b/hw/arm/aspeed_soc.c
> @@ -199,7 +199,8 @@ static void aspeed_soc_init(Object *obj)
>  TYPE_FTGMAC100);
>  }
>  
> -object_initialize_child(obj, "xdma", >xdma,
> TYPE_ASPEED_XDMA);
> +snprintf(typename, sizeof(typename), TYPE_ASPEED_XDMA "-%s",
> socname);
> +object_initialize_child(obj, "xdma", >xdma, typename);
>  
>  snprintf(typename, sizeof(typename), "aspeed.gpio-%s", socname);
>  object_initialize_child(obj, "gpio", >gpio, typename);
> diff --git a/hw/misc/aspeed_xdma.c b/hw/misc/aspeed_xdma.c
> index 533d237e3ce2..1c21577c98c9 100644
> --- a/hw/misc/aspeed_xdma.c
> +++ b/hw/misc/aspeed_xdma.c
> @@ -30,6 +30,19 @@
>  #define  XDMA_IRQ_ENG_STAT_US_COMP BIT(4)
>  #define  XDMA_IRQ_ENG_STAT_DS_COMP BIT(5)
>  #define  XDMA_IRQ_ENG_STAT_RESET   0xF800
> +
> +#define XDMA_AST2600_BMC_CMDQ_ADDR   0x14
> +#define XDMA_AST2600_BMC_CMDQ_ENDP   0x18
> +#define XDMA_AST2600_BMC_CMDQ_WRP0x1c
> +#define XDMA_AST2600_BMC_CMDQ_RDP0x20
> +#define XDMA_AST2600_IRQ_CTRL0x38
> +#define  XDMA_AST2600_IRQ_CTRL_US_COMPBIT(16)
> +#define  XDMA_AST2600_IRQ_CTRL_DS_COMPBIT(17)
> +#define  XDMA_AST2600_IRQ_CTRL_W_MASK 0x017003FF
> +#define XDMA_AST2600_IRQ_STATUS  0x3c
> +#define  XDMA_AST2600_IRQ_STATUS_US_COMP  BIT(16)
> +#define  XDMA_AST2600_IRQ_STATUS_DS_COMP  BIT(17)
> +
>  #define XDMA_MEM_SIZE  0x1000
>  
>  #define TO_REG(addr) ((addr) / sizeof(uint32_t))
> @@ -52,56 +65,48 @@ static void aspeed_xdma_write(void *opaque,
> hwaddr addr, uint64_t val,
>  unsigned int idx;
>  uint32_t val32 = (uint32_t)val;
>  AspeedXDMAState *xdma = opaque;
> +AspeedXDMAClass *axc = ASPEED_XDMA_GET_CLASS(xdma);
>  
>  if (

Re: [Qemu-devel] [RFC v2] hw/sd/aspeed_sdhci: New device

2019-08-20 Thread Eddie James


On 8/19/19 1:41 AM, Cédric Le Goater wrote:

On 15/08/2019 22:13, Eddie James wrote:

On 8/15/19 3:05 AM, Cédric Le Goater wrote:

Hello Eddie,

On 14/08/2019 22:27, Eddie James wrote:

The Aspeed SOCs have two SD/MMC controllers. Add a device that
encapsulates both of these controllers and models the Aspeed-specific
registers and behavior.

Tested by reading from mmcblk0 in Linux:
qemu-system-arm -machine romulus-bmc -nographic -serial mon:stdio \
   -drive file=_tmp/flash-romulus,format=raw,if=mtd \
   -device sd-card,drive=sd0 -drive file=_tmp/kernel,format=raw,if=sd

Signed-off-by: Eddie James 
---
This patch applies on top of Cedric's set of recent Aspeed changes. Therefore,
I'm sending as an RFC rather than a patch.

yes. we can worked that out when the patch is reviewed. You can base on
mainline when ready. My tree serves as an overall test base.


Changes since v1:
   - Move slot realize code into the Aspeed SDHCI realize function
   - Fix interrupt handling by creating input irqs and connecting them to the
     slot irqs.
   - Removed card device creation code

I think all the code is here but it needs some more reshuffling :)
   The raspi machine is a good source for modelling pratices.


   hw/arm/aspeed.c  |   1 -
   hw/arm/aspeed_soc.c  |  24 ++
   hw/sd/Makefile.objs  |   1 +
   hw/sd/aspeed_sdhci.c | 190 
+++
   include/hw/arm/aspeed_soc.h  |   3 +
   include/hw/sd/aspeed_sdhci.h |  35 
   6 files changed, 253 insertions(+), 1 deletion(-)
   create mode 100644 hw/sd/aspeed_sdhci.c
   create mode 100644 include/hw/sd/aspeed_sdhci.h

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 2574425..aeed5b6 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -480,7 +480,6 @@ static void aspeed_machine_class_init(ObjectClass *oc, void 
*data)
   mc->desc = board->desc;
   mc->init = aspeed_machine_init;
   mc->max_cpus = ASPEED_CPUS_NUM;
-    mc->no_sdcard = 1;
   mc->no_floppy = 1;
   mc->no_cdrom = 1;
   mc->no_parallel = 1;
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index 8df96f2..a12f14a 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -22,6 +22,7 @@
   #include "qemu/error-report.h"
   #include "hw/i2c/aspeed_i2c.h"
   #include "net/net.h"
+#include "sysemu/blockdev.h"

I would expect block devices to be handled at the machine level in
aspeed.c, like the flash devices are. Something like :


OK, I did have that in v1 but Peter mentioned it was typically done at the 
command line?

yes, indeed. This works also and this is less code which is even better.


I guess it can go in aspeed.c too.

Well, let's do without if we can.

We might be able to get rid of aspeed_board_init_flashes() now.

We should start writing a QEMU cookbook page on the OpenBMC wiki to
document the Aspeed machine command line.





  /* Create and plug in the SD cards */
  for (i = 0; i < ASPEED_SDHCI_NUM_SLOTS; i++) {
  BusState *bus;
  DriveInfo *di = drive_get_next(IF_SD);
  BlockBackend *blk = di ? blk_by_legacy_dinfo(di) : NULL;
  DeviceState *carddev;

  bus = qdev_get_child_bus(DEVICE(>soc), "sd-bus");
  if (!bus) {
  error_report("No SD bus found for SD card %d", i);
  exit(1);
  }
  carddev = qdev_create(bus, TYPE_SD_CARD);
  qdev_prop_set_drive(carddev, "drive", blk, _fatal);
  object_property_set_bool(OBJECT(carddev), true, "realized",
   _fatal);
  }


     #define ASPEED_SOC_IOMEM_SIZE   0x0020
   @@ -62,6 +63,7 @@ static const hwaddr aspeed_soc_ast2500_memmap[] = {
   [ASPEED_XDMA]   = 0x1E6E7000,
   [ASPEED_ADC]    = 0x1E6E9000,
   [ASPEED_SRAM]   = 0x1E72,
+    [ASPEED_SDHCI]  = 0x1E74,
   [ASPEED_GPIO]   = 0x1E78,
   [ASPEED_RTC]    = 0x1E781000,
   [ASPEED_TIMER1] = 0x1E782000,
@@ -100,6 +102,7 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
   [ASPEED_XDMA]   = 0x1E6E7000,
   [ASPEED_ADC]    = 0x1E6E9000,
   [ASPEED_VIDEO]  = 0x1E70,
+    [ASPEED_SDHCI]  = 0x1E74,
   [ASPEED_GPIO]   = 0x1E78,
   [ASPEED_RTC]    = 0x1E781000,
   [ASPEED_TIMER1] = 0x1E782000,
@@ -146,6 +149,7 @@ static const int aspeed_soc_ast2400_irqmap[] = {
   [ASPEED_ETH1]   = 2,
   [ASPEED_ETH2]   = 3,
   [ASPEED_XDMA]   = 6,
+    [ASPEED_SDHCI]  = 26,
   };
     #define aspeed_soc_ast2500_irqmap aspeed_soc_ast2400_irqmap
@@ -163,6 +167,7 @@ static const int aspeed_soc_ast2600_irqmap[] = {
   [ASPEED_SDMC]   = 0,
   [ASPEED_SCU]    = 12,
   [ASPEED_XDMA]   = 6,
+    [ASPEED_SDHCI]  = 43,
   [ASPEED_ADC]    = 46,
   [ASPEED_GPIO]   = 40,
   [ASPEED_RTC]    = 13,
@@ -350,6 +355,15 @@ static void aspeed_soc_init(Object *obj)
 

[Qemu-devel] [RFC v3] hw/sd/aspeed_sdhci: New device

2019-08-20 Thread Eddie James
The Aspeed SOCs have two SD/MMC controllers. Add a device that
encapsulates both of these controllers and models the Aspeed-specific
registers and behavior.

Tested by reading from mmcblk0 in Linux:
qemu-system-arm -machine romulus-bmc -nographic \
 -drive file=flash-romulus,format=raw,if=mtd \
 -device sd-card,drive=sd0 -drive file=_tmp/kernel,format=raw,if=sd

Signed-off-by: Eddie James 
---
This patch applies on top of Cedric's set of recent Aspeed changes.
Therefore, I'm sending as an RFC rather than a patch for review.

Changes since v2:
 - Do the memory mapping at the SOC level
 - Add guest errors for out-of-bounds access to the SDHCI regs
 - Remove unnecessary blockdev include in aspeed_soc.c
 - Better naming for SDHCI objects.

Changes since v1:
 - Move slot realize code into the Aspeed SDHCI realize function
 - Fix interrupt handling by creating input irqs and connecting them to the
   slot irqs.
 - Removed card device creation code
 hw/arm/aspeed.c  |   1 -
 hw/arm/aspeed_soc.c  |  28 +++
 hw/sd/Makefile.objs  |   1 +
 hw/sd/aspeed_sdhci.c | 194 +++
 include/hw/arm/aspeed_soc.h  |   3 +
 include/hw/sd/aspeed_sdhci.h |  34 
 6 files changed, 260 insertions(+), 1 deletion(-)
 create mode 100644 hw/sd/aspeed_sdhci.c
 create mode 100644 include/hw/sd/aspeed_sdhci.h

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 2574425..aeed5b6 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -480,7 +480,6 @@ static void aspeed_machine_class_init(ObjectClass *oc, void 
*data)
 mc->desc = board->desc;
 mc->init = aspeed_machine_init;
 mc->max_cpus = ASPEED_CPUS_NUM;
-mc->no_sdcard = 1;
 mc->no_floppy = 1;
 mc->no_cdrom = 1;
 mc->no_parallel = 1;
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index c9f6e01..292751e 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -62,6 +62,7 @@ static const hwaddr aspeed_soc_ast2500_memmap[] = {
 [ASPEED_XDMA]   = 0x1E6E7000,
 [ASPEED_ADC]= 0x1E6E9000,
 [ASPEED_SRAM]   = 0x1E72,
+[ASPEED_SDHCI]  = 0x1E74,
 [ASPEED_GPIO]   = 0x1E78,
 [ASPEED_RTC]= 0x1E781000,
 [ASPEED_TIMER1] = 0x1E782000,
@@ -102,6 +103,7 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
 [ASPEED_XDMA]  = 0x1E6E7000,
 [ASPEED_ADC]   = 0x1E6E9000,
 [ASPEED_VIDEO] = 0x1E70,
+[ASPEED_SDHCI] = 0x1E74,
 [ASPEED_GPIO]  = 0x1E78,
 [ASPEED_GPIO_1_8V] = 0x1E780800,
 [ASPEED_RTC]   = 0x1E781000,
@@ -147,6 +149,7 @@ static const int aspeed_soc_ast2400_irqmap[] = {
 [ASPEED_ETH1]   = 2,
 [ASPEED_ETH2]   = 3,
 [ASPEED_XDMA]   = 6,
+[ASPEED_SDHCI]  = 26,
 };
 
 #define aspeed_soc_ast2500_irqmap aspeed_soc_ast2400_irqmap
@@ -185,6 +188,7 @@ static const int aspeed_soc_ast2600_irqmap[] = {
 [ASPEED_ETH2]  = 3,
 [ASPEED_FSI1]  = 100,
 [ASPEED_FSI2]  = 101,
+[ASPEED_SDHCI] = 43,
 };
 
 static const AspeedSoCInfo aspeed_socs[] = {
@@ -357,6 +361,15 @@ static void aspeed_soc_init(Object *obj)
 sysbus_init_child_obj(obj, "fsi[*]", OBJECT(>fsi[0]),
   sizeof(s->fsi[0]), TYPE_ASPEED_FSI);
 }
+
+sysbus_init_child_obj(obj, "sdc", OBJECT(>sdhci), sizeof(s->sdhci),
+  TYPE_ASPEED_SDHCI);
+
+/* Init sd card slot class here so that they're under the correct parent */
+for (i = 0; i < ASPEED_SDHCI_NUM_SLOTS; ++i) {
+sysbus_init_child_obj(obj, "sdhci[*]", OBJECT(>sdhci.slots[i]),
+  sizeof(s->sdhci.slots[i]), TYPE_SYSBUS_SDHCI);
+}
 }
 
 /*
@@ -698,6 +711,21 @@ static void aspeed_soc_realize(DeviceState *dev, Error 
**errp)
 sysbus_connect_irq(SYS_BUS_DEVICE(>fsi[0]), 0,
aspeed_soc_get_irq(s, ASPEED_FSI1));
 }
+
+/* SDHCI */
+object_property_set_bool(OBJECT(>sdhci), true, "realized", );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+for (i = 0; i < ASPEED_SDHCI_NUM_SLOTS; ++i) {
+sysbus_mmio_map(SYS_BUS_DEVICE(>sdhci.slots[i]), 0,
+sc->info->memmap[ASPEED_SDHCI] + ((i + 1) * 0x100));
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(>sdhci), 0,
+sc->info->memmap[ASPEED_SDHCI]);
+sysbus_connect_irq(SYS_BUS_DEVICE(>sdhci), 0,
+   aspeed_soc_get_irq(s, ASPEED_SDHCI));
 }
 static Property aspeed_soc_properties[] = {
 DEFINE_PROP_UINT32("num-cpus", AspeedSoCState, num_cpus, 0),
diff --git a/hw/sd/Makefile.objs b/hw/sd/Makefile.objs
index 0665727..a884c23 100644
--- a/hw/sd/Makefile.objs
+++ b/hw/sd/Makefile.objs
@@ -8,3 +8,4 @@ obj-$(CONFIG_MILKYMIST) += milkymist-memcard.o
 obj-$(CONFIG_OMAP) += omap_mmc.o
 obj-$(CONFIG_PXA2XX) += pxa2xx_mmci.o
 

Re: [Qemu-devel] [RFC v2] hw/sd/aspeed_sdhci: New device

2019-08-15 Thread Eddie James


On 8/15/19 3:13 PM, Eddie James wrote:


On 8/15/19 3:05 AM, Cédric Le Goater wrote:

Hello Eddie,

On 14/08/2019 22:27, Eddie James wrote:


+    sdhci->slots[0].capareg = (uint64_t)(uint32_t)val;
+    break;
+    case ASPEED_SDHCI_SDIO_148:
+    sdhci->slots[0].maxcurr = (uint64_t)(uint32_t)val;
+    break;
+    case ASPEED_SDHCI_SDIO_240:
+    sdhci->slots[1].capareg = (uint64_t)(uint32_t)val;
+    break;
+    case ASPEED_SDHCI_SDIO_248:
+    sdhci->slots[1].maxcurr = (uint64_t)(uint32_t)val;
+    break;

I think these regs are readonly.



Well the actual regs at slot + 0x40/0x48 are indeed, but not the 
Aspeed-specific ones that mirror there. I think the idea is that 
Aspeed-specific code can set it's capabilities differently if desired. 
This may prevent the use of alias regions here.



Actually I could be wrong after reading the specs again. It's a little 
confusing. I'm fine with making it read-only anyway, I doubt there will 
be any code that needs to write it.









+    default:
+    if (addr < ASPEED_SDHCI_REG_SIZE) {
+    sdhci->regs[TO_REG(addr)] = (uint32_t)val;
+    }
+    }
+}
+
+static const MemoryRegionOps aspeed_sdhci_ops = {
+    .read = aspeed_sdhci_read,
+    .write = aspeed_sdhci_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid.min_access_size = 4, 


Re: [Qemu-devel] [RFC v2] hw/sd/aspeed_sdhci: New device

2019-08-15 Thread Eddie James



On 8/15/19 3:05 AM, Cédric Le Goater wrote:

Hello Eddie,

On 14/08/2019 22:27, Eddie James wrote:

The Aspeed SOCs have two SD/MMC controllers. Add a device that
encapsulates both of these controllers and models the Aspeed-specific
registers and behavior.

Tested by reading from mmcblk0 in Linux:
qemu-system-arm -machine romulus-bmc -nographic -serial mon:stdio \
  -drive file=_tmp/flash-romulus,format=raw,if=mtd \
  -device sd-card,drive=sd0 -drive file=_tmp/kernel,format=raw,if=sd

Signed-off-by: Eddie James 
---
This patch applies on top of Cedric's set of recent Aspeed changes. Therefore,
I'm sending as an RFC rather than a patch.

yes. we can worked that out when the patch is reviewed. You can base on
mainline when ready. My tree serves as an overall test base.


Changes since v1:
  - Move slot realize code into the Aspeed SDHCI realize function
  - Fix interrupt handling by creating input irqs and connecting them to the
slot irqs.
  - Removed card device creation code

I think all the code is here but it needs some more reshuffling :)
  
The raspi machine is a good source for modelling pratices.



  hw/arm/aspeed.c  |   1 -
  hw/arm/aspeed_soc.c  |  24 ++
  hw/sd/Makefile.objs  |   1 +
  hw/sd/aspeed_sdhci.c | 190 +++
  include/hw/arm/aspeed_soc.h  |   3 +
  include/hw/sd/aspeed_sdhci.h |  35 
  6 files changed, 253 insertions(+), 1 deletion(-)
  create mode 100644 hw/sd/aspeed_sdhci.c
  create mode 100644 include/hw/sd/aspeed_sdhci.h

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 2574425..aeed5b6 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -480,7 +480,6 @@ static void aspeed_machine_class_init(ObjectClass *oc, void 
*data)
  mc->desc = board->desc;
  mc->init = aspeed_machine_init;
  mc->max_cpus = ASPEED_CPUS_NUM;
-mc->no_sdcard = 1;
  mc->no_floppy = 1;
  mc->no_cdrom = 1;
  mc->no_parallel = 1;
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index 8df96f2..a12f14a 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -22,6 +22,7 @@
  #include "qemu/error-report.h"
  #include "hw/i2c/aspeed_i2c.h"
  #include "net/net.h"
+#include "sysemu/blockdev.h"

I would expect block devices to be handled at the machine level in
aspeed.c, like the flash devices are. Something like :



OK, I did have that in v1 but Peter mentioned it was typically done at 
the command line? I guess it can go in aspeed.c too.





 /* Create and plug in the SD cards */
 for (i = 0; i < ASPEED_SDHCI_NUM_SLOTS; i++) {
 BusState *bus;
 DriveInfo *di = drive_get_next(IF_SD);
 BlockBackend *blk = di ? blk_by_legacy_dinfo(di) : NULL;
 DeviceState *carddev;

 bus = qdev_get_child_bus(DEVICE(>soc), "sd-bus");
 if (!bus) {
 error_report("No SD bus found for SD card %d", i);
 exit(1);
 }
 carddev = qdev_create(bus, TYPE_SD_CARD);
 qdev_prop_set_drive(carddev, "drive", blk, _fatal);
 object_property_set_bool(OBJECT(carddev), true, "realized",
  _fatal);
 }

  
  #define ASPEED_SOC_IOMEM_SIZE   0x0020
  
@@ -62,6 +63,7 @@ static const hwaddr aspeed_soc_ast2500_memmap[] = {

  [ASPEED_XDMA]   = 0x1E6E7000,
  [ASPEED_ADC]= 0x1E6E9000,
  [ASPEED_SRAM]   = 0x1E72,
+[ASPEED_SDHCI]  = 0x1E74,
  [ASPEED_GPIO]   = 0x1E78,
  [ASPEED_RTC]= 0x1E781000,
  [ASPEED_TIMER1] = 0x1E782000,
@@ -100,6 +102,7 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
  [ASPEED_XDMA]   = 0x1E6E7000,
  [ASPEED_ADC]= 0x1E6E9000,
  [ASPEED_VIDEO]  = 0x1E70,
+[ASPEED_SDHCI]  = 0x1E74,
  [ASPEED_GPIO]   = 0x1E78,
  [ASPEED_RTC]= 0x1E781000,
  [ASPEED_TIMER1] = 0x1E782000,
@@ -146,6 +149,7 @@ static const int aspeed_soc_ast2400_irqmap[] = {
  [ASPEED_ETH1]   = 2,
  [ASPEED_ETH2]   = 3,
  [ASPEED_XDMA]   = 6,
+[ASPEED_SDHCI]  = 26,
  };
  
  #define aspeed_soc_ast2500_irqmap aspeed_soc_ast2400_irqmap

@@ -163,6 +167,7 @@ static const int aspeed_soc_ast2600_irqmap[] = {
  [ASPEED_SDMC]   = 0,
  [ASPEED_SCU]= 12,
  [ASPEED_XDMA]   = 6,
+[ASPEED_SDHCI]  = 43,
  [ASPEED_ADC]= 46,
  [ASPEED_GPIO]   = 40,
  [ASPEED_RTC]= 13,
@@ -350,6 +355,15 @@ static void aspeed_soc_init(Object *obj)
  sysbus_init_child_obj(obj, "fsi[*]", OBJECT(>fsi[0]),
sizeof(s->fsi[0]), TYPE_ASPEED_FSI);
  }
+
+sysbus_init_child_obj(obj, "sdhci", OBJECT(>sdhci), sizeof(s->sdhci),
+  TYPE_ASPEED_SDHCI);

This is the Aspeed SD host interface. May be we should call it sdhost ?

I suppose this is our "sd-bus" device ?


+/* 

[Qemu-devel] [RFC v2] hw/sd/aspeed_sdhci: New device

2019-08-14 Thread Eddie James
The Aspeed SOCs have two SD/MMC controllers. Add a device that
encapsulates both of these controllers and models the Aspeed-specific
registers and behavior.

Tested by reading from mmcblk0 in Linux:
qemu-system-arm -machine romulus-bmc -nographic -serial mon:stdio \
 -drive file=_tmp/flash-romulus,format=raw,if=mtd \
 -device sd-card,drive=sd0 -drive file=_tmp/kernel,format=raw,if=sd

Signed-off-by: Eddie James 
---
This patch applies on top of Cedric's set of recent Aspeed changes. Therefore,
I'm sending as an RFC rather than a patch.

Changes since v1:
 - Move slot realize code into the Aspeed SDHCI realize function
 - Fix interrupt handling by creating input irqs and connecting them to the
   slot irqs.
 - Removed card device creation code

 hw/arm/aspeed.c  |   1 -
 hw/arm/aspeed_soc.c  |  24 ++
 hw/sd/Makefile.objs  |   1 +
 hw/sd/aspeed_sdhci.c | 190 +++
 include/hw/arm/aspeed_soc.h  |   3 +
 include/hw/sd/aspeed_sdhci.h |  35 
 6 files changed, 253 insertions(+), 1 deletion(-)
 create mode 100644 hw/sd/aspeed_sdhci.c
 create mode 100644 include/hw/sd/aspeed_sdhci.h

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 2574425..aeed5b6 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -480,7 +480,6 @@ static void aspeed_machine_class_init(ObjectClass *oc, void 
*data)
 mc->desc = board->desc;
 mc->init = aspeed_machine_init;
 mc->max_cpus = ASPEED_CPUS_NUM;
-mc->no_sdcard = 1;
 mc->no_floppy = 1;
 mc->no_cdrom = 1;
 mc->no_parallel = 1;
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index 8df96f2..a12f14a 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -22,6 +22,7 @@
 #include "qemu/error-report.h"
 #include "hw/i2c/aspeed_i2c.h"
 #include "net/net.h"
+#include "sysemu/blockdev.h"
 
 #define ASPEED_SOC_IOMEM_SIZE   0x0020
 
@@ -62,6 +63,7 @@ static const hwaddr aspeed_soc_ast2500_memmap[] = {
 [ASPEED_XDMA]   = 0x1E6E7000,
 [ASPEED_ADC]= 0x1E6E9000,
 [ASPEED_SRAM]   = 0x1E72,
+[ASPEED_SDHCI]  = 0x1E74,
 [ASPEED_GPIO]   = 0x1E78,
 [ASPEED_RTC]= 0x1E781000,
 [ASPEED_TIMER1] = 0x1E782000,
@@ -100,6 +102,7 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
 [ASPEED_XDMA]   = 0x1E6E7000,
 [ASPEED_ADC]= 0x1E6E9000,
 [ASPEED_VIDEO]  = 0x1E70,
+[ASPEED_SDHCI]  = 0x1E74,
 [ASPEED_GPIO]   = 0x1E78,
 [ASPEED_RTC]= 0x1E781000,
 [ASPEED_TIMER1] = 0x1E782000,
@@ -146,6 +149,7 @@ static const int aspeed_soc_ast2400_irqmap[] = {
 [ASPEED_ETH1]   = 2,
 [ASPEED_ETH2]   = 3,
 [ASPEED_XDMA]   = 6,
+[ASPEED_SDHCI]  = 26,
 };
 
 #define aspeed_soc_ast2500_irqmap aspeed_soc_ast2400_irqmap
@@ -163,6 +167,7 @@ static const int aspeed_soc_ast2600_irqmap[] = {
 [ASPEED_SDMC]   = 0,
 [ASPEED_SCU]= 12,
 [ASPEED_XDMA]   = 6,
+[ASPEED_SDHCI]  = 43,
 [ASPEED_ADC]= 46,
 [ASPEED_GPIO]   = 40,
 [ASPEED_RTC]= 13,
@@ -350,6 +355,15 @@ static void aspeed_soc_init(Object *obj)
 sysbus_init_child_obj(obj, "fsi[*]", OBJECT(>fsi[0]),
   sizeof(s->fsi[0]), TYPE_ASPEED_FSI);
 }
+
+sysbus_init_child_obj(obj, "sdhci", OBJECT(>sdhci), sizeof(s->sdhci),
+  TYPE_ASPEED_SDHCI);
+
+/* Init sd card slot class here so that they're under the correct parent */
+for (i = 0; i < ASPEED_SDHCI_NUM_SLOTS; ++i) {
+sysbus_init_child_obj(obj, "sdhci_slot[*]", OBJECT(>sdhci.slots[i]),
+  sizeof(s->sdhci.slots[i]), TYPE_SYSBUS_SDHCI);
+}
 }
 
 /*
@@ -680,6 +694,16 @@ static void aspeed_soc_realize(DeviceState *dev, Error 
**errp)
 sysbus_connect_irq(SYS_BUS_DEVICE(>fsi[0]), 0,
aspeed_soc_get_irq(s, ASPEED_FSI1));
 }
+
+/* SD/SDIO - set the reg address so slot memory mapping can be set up */
+s->sdhci.ioaddr = sc->info->memmap[ASPEED_SDHCI];
+object_property_set_bool(OBJECT(>sdhci), true, "realized", );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+sysbus_connect_irq(SYS_BUS_DEVICE(>sdhci), 0,
+   aspeed_soc_get_irq(s, ASPEED_SDHCI));
 }
 static Property aspeed_soc_properties[] = {
 DEFINE_PROP_UINT32("num-cpus", AspeedSoCState, num_cpus, 0),
diff --git a/hw/sd/Makefile.objs b/hw/sd/Makefile.objs
index 0665727..a884c23 100644
--- a/hw/sd/Makefile.objs
+++ b/hw/sd/Makefile.objs
@@ -8,3 +8,4 @@ obj-$(CONFIG_MILKYMIST) += milkymist-memcard.o
 obj-$(CONFIG_OMAP) += omap_mmc.o
 obj-$(CONFIG_PXA2XX) += pxa2xx_mmci.o
 obj-$(CONFIG_RASPI) += bcm2835_sdhost.o
+obj-$(CONFIG_ASPEED_SOC) += aspeed_sdhci.o
diff --git a/hw/sd/aspeed_sdhci.c b/hw/sd/aspeed_sdhci.c
new file mode 100644
index 000..

Re: [Qemu-devel] [PATCH] hw/sd/aspeed_sdhci: New device

2019-08-06 Thread Eddie James



On 8/5/19 9:31 AM, Peter Maydell wrote:

On Wed, 26 Jun 2019 at 19:43, Eddie James  wrote:

The Aspeed SOCs have two SD/MMC controllers. Add a device that
encapsulates both of these controllers and models the Aspeed-specific
registers and behavior.

Both controllers use a single HW interrupt. In order to trigger that
interrupt, a function pointer was added to the generic SDHCI structure.
This function (if the pointer is set) is called when the SDHCI model
changes it's interrupt status, allowing the user (the Aspeed SDHCI
model in this case) to set it's own interrupt.

This goes on top of Cedric's set of Aspeed changes.

Tested, booted, and read from /dev/mmcblk0 and /dev/mmcblk1:
./arm-softmmu/qemu-system-arm -M ast2500-evb -nographic \
  -drive file=flash-romulus,format=raw,if=mtd \
  -drive file=,format=raw,if=sd \
  -drive file=,format=raw,if=sd \
  -kernel zImage \
  -dtb aspeed-ast2500-evb.dtb \
  -initrd romulus.cpio.lzma \
  -d trace:sdhci* -no-reboot

Signed-off-by: Eddie James 

(Apologies for the rather delayed review -- combination of the
4.1 release work, and hoping one of the other Aspeed developers
would get to it.)



No problem, thanks for the review!






  #define aspeed_soc_ast2500_irqmap aspeed_soc_ast2400_irqmap
@@ -378,6 +381,16 @@ static void aspeed_soc_init(Object *obj)
  sysbus_init_child_obj(obj, "fsi[*]", OBJECT(>fsi[0]),
sizeof(s->fsi[0]), TYPE_ASPEED_FSI);
  }
+
+sysbus_init_child_obj(obj, "sdhci", OBJECT(>sdhci), sizeof(s->sdhci),
+  TYPE_ASPEED_SDHCI);
+
+for (i = 0; i < ASPEED_SDHCI_NUM_SLOTS; ++i) {
+sysbus_init_child_obj(obj, "sdhci_slot[*]",
+  OBJECT(>sdhci.slots[i].sdhci),
+  sizeof(s->sdhci.slots[i].sdhci),
+  TYPE_SYSBUS_SDHCI);
+}

This seems a bit odd. Why does the SoC init the slots[i].sdhci
objects, rather than letting the TYPE_ASPEED_SDHCI object itself
take care of initializing and realizing its own child objects?



I couldn't get it to work with the actual sdhci objects underneath the 
Aspeed object. Qemu wouldn't start with an sd card drive in the command 
line. I'm thinking it can't find the actual sdhci objects if they're not 
on that parent bus?






  }

  static void aspeed_soc_realize(DeviceState *dev, Error **errp)
@@ -699,6 +712,60 @@ static void aspeed_soc_realize(DeviceState *dev, Error 
**errp)
  sysbus_connect_irq(SYS_BUS_DEVICE(>fsi[0]), 0,
 aspeed_soc_get_irq(s, ASPEED_FSI1));
  }
+
+/* SD/SDIO */
+for (i = 0; i < ASPEED_SDHCI_NUM_SLOTS; i++) {
+hwaddr hci_addr = sc->info->memmap[ASPEED_SDHCI] + (0x100 * (i + 1));
+DriveInfo *di;
+BlockBackend *blk;
+DeviceState *card;
+
+/*
+ * Compatible with:
+ * - SD Host Controller Specification Version 2.0
+ * - SDIO Specification Version 2.0
+ * - MMC Specification Version 4.3
+ */
+object_property_set_int(OBJECT(>sdhci.slots[i].sdhci), 2,
+"sd-spec-version", );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+
+object_property_set_uint(OBJECT(>sdhci.slots[i].sdhci),
+ ASPEED_SDHCI_CAPABILITIES, "capareg", );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+
+object_property_set_bool(OBJECT(>sdhci.slots[i].sdhci), true,
+ "realized", );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+
+sysbus_mmio_map(SYS_BUS_DEVICE(>sdhci.slots[i].sdhci), 0, hci_addr);
+
+di = drive_get_next(IF_SD);
+blk = di ? blk_by_legacy_dinfo(di) : NULL;
+card = qdev_create(qdev_get_child_bus(DEVICE(>sdhci.slots[i].sdhci),
+  "sd-bus"), TYPE_SD_CARD);
+qdev_prop_set_drive(card, "drive", blk, _fatal);
+object_property_set_bool(OBJECT(card), true, "realized", _fatal);

Code at the SoC level shouldn't be calling drive_get_next() or
creating SD card objects directly itself -- it should leave this
up to either the board code or to the command line.



OK.





+}
+
+object_property_set_bool(OBJECT(>sdhci), true, "realized", );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(>sdhci), 0,
+sc->info->memmap[ASPEED_SDHCI]);
+sysbus_connect_irq(SYS_BUS_DEVICE(>sdhci), 0,
+   aspeed_soc_get_irq(s, ASPEED_SDHCI));
  }
  static Property aspeed_soc_properties[] = {
  DEFINE_PROP_UINT32("num-cpus", AspeedSoCStat

[Qemu-devel] [PATCH] hw/sd/aspeed_sdhci: New device

2019-06-26 Thread Eddie James
The Aspeed SOCs have two SD/MMC controllers. Add a device that
encapsulates both of these controllers and models the Aspeed-specific
registers and behavior.

Both controllers use a single HW interrupt. In order to trigger that
interrupt, a function pointer was added to the generic SDHCI structure.
This function (if the pointer is set) is called when the SDHCI model
changes it's interrupt status, allowing the user (the Aspeed SDHCI
model in this case) to set it's own interrupt.

This goes on top of Cedric's set of Aspeed changes.

Tested, booted, and read from /dev/mmcblk0 and /dev/mmcblk1:
./arm-softmmu/qemu-system-arm -M ast2500-evb -nographic \
 -drive file=flash-romulus,format=raw,if=mtd \
 -drive file=,format=raw,if=sd \
 -drive file=,format=raw,if=sd \
 -kernel zImage \
 -dtb aspeed-ast2500-evb.dtb \
 -initrd romulus.cpio.lzma \
 -d trace:sdhci* -no-reboot

Signed-off-by: Eddie James 
---
 hw/arm/aspeed.c  |   1 -
 hw/arm/aspeed_soc.c  |  67 ++
 hw/sd/Makefile.objs  |   1 +
 hw/sd/aspeed_sdhci.c | 163 +++
 hw/sd/sdhci.c|   8 ++-
 include/hw/arm/aspeed_soc.h  |   3 +
 include/hw/sd/aspeed_sdhci.h |  39 +++
 include/hw/sd/sdhci.h|   1 +
 8 files changed, 281 insertions(+), 2 deletions(-)
 create mode 100644 hw/sd/aspeed_sdhci.c
 create mode 100644 include/hw/sd/aspeed_sdhci.h

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 5fee2f5..fbec946 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -422,7 +422,6 @@ static void aspeed_machine_class_init(ObjectClass *oc, void 
*data)
 mc->desc = board->desc;
 mc->init = aspeed_machine_init;
 mc->max_cpus = ASPEED_CPUS_NUM;
-mc->no_sdcard = 1;
 mc->no_floppy = 1;
 mc->no_cdrom = 1;
 mc->no_parallel = 1;
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index 1bbbdae..1378498 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -22,6 +22,7 @@
 #include "qemu/error-report.h"
 #include "hw/i2c/aspeed_i2c.h"
 #include "net/net.h"
+#include "sysemu/blockdev.h"
 
 #define ASPEED_SOC_IOMEM_SIZE   0x0020
 
@@ -62,6 +63,7 @@ static const hwaddr aspeed_soc_ast2500_memmap[] = {
 [ASPEED_XDMA]   = 0x1E6E7000,
 [ASPEED_ADC]= 0x1E6E9000,
 [ASPEED_SRAM]   = 0x1E72,
+[ASPEED_SDHCI]  = 0x1E74,
 [ASPEED_GPIO]   = 0x1E78,
 [ASPEED_RTC]= 0x1E781000,
 [ASPEED_TIMER1] = 0x1E782000,
@@ -142,6 +144,7 @@ static const int aspeed_soc_ast2400_irqmap[] = {
 [ASPEED_ETH1]   = 2,
 [ASPEED_ETH2]   = 3,
 [ASPEED_XDMA]   = 6,
+[ASPEED_SDHCI]  = 26,
 };
 
 #define aspeed_soc_ast2500_irqmap aspeed_soc_ast2400_irqmap
@@ -378,6 +381,16 @@ static void aspeed_soc_init(Object *obj)
 sysbus_init_child_obj(obj, "fsi[*]", OBJECT(>fsi[0]),
   sizeof(s->fsi[0]), TYPE_ASPEED_FSI);
 }
+
+sysbus_init_child_obj(obj, "sdhci", OBJECT(>sdhci), sizeof(s->sdhci),
+  TYPE_ASPEED_SDHCI);
+
+for (i = 0; i < ASPEED_SDHCI_NUM_SLOTS; ++i) {
+sysbus_init_child_obj(obj, "sdhci_slot[*]",
+  OBJECT(>sdhci.slots[i].sdhci),
+  sizeof(s->sdhci.slots[i].sdhci),
+  TYPE_SYSBUS_SDHCI);
+}
 }
 
 static void aspeed_soc_realize(DeviceState *dev, Error **errp)
@@ -699,6 +712,60 @@ static void aspeed_soc_realize(DeviceState *dev, Error 
**errp)
 sysbus_connect_irq(SYS_BUS_DEVICE(>fsi[0]), 0,
aspeed_soc_get_irq(s, ASPEED_FSI1));
 }
+
+/* SD/SDIO */
+for (i = 0; i < ASPEED_SDHCI_NUM_SLOTS; i++) {
+hwaddr hci_addr = sc->info->memmap[ASPEED_SDHCI] + (0x100 * (i + 1));
+DriveInfo *di;
+BlockBackend *blk;
+DeviceState *card;
+
+/*
+ * Compatible with:
+ * - SD Host Controller Specification Version 2.0
+ * - SDIO Specification Version 2.0
+ * - MMC Specification Version 4.3
+ */
+object_property_set_int(OBJECT(>sdhci.slots[i].sdhci), 2,
+"sd-spec-version", );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+
+object_property_set_uint(OBJECT(>sdhci.slots[i].sdhci),
+ ASPEED_SDHCI_CAPABILITIES, "capareg", );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+
+object_property_set_bool(OBJECT(>sdhci.slots[i].sdhci), true,
+ "realized", );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+
+sysbus_mmio_map(SYS_BUS_DEVICE(>sdhci.slots[i].sdhci), 0, hci_addr

[Qemu-devel] [PATCH v2] hw: misc: Add Aspeed XDMA device

2019-06-11 Thread Eddie James
The XDMA engine embedded in the Aspeed SOCs performs PCI DMA operations
between the SOC (acting as a BMC) and a host processor in a server.

The XDMA engine exists on the AST2400, AST2500, and AST2600 SOCs, so
enable it for all of those. Add trace events on the important register
writes in the XDMA engine.

Signed-off-by: Eddie James 
---
Changes since v1:
 - add trace events
 - minor cleanup

This patch is based on Cedric's big Aspeed update:
http://patchwork.ozlabs.org/cover/1105343/

 hw/arm/aspeed_soc.c   |  19 +
 hw/misc/Makefile.objs |   1 +
 hw/misc/aspeed_xdma.c | 165 ++
 hw/misc/trace-events  |   3 +
 include/hw/arm/aspeed_soc.h   |   3 +
 include/hw/misc/aspeed_xdma.h |  30 
 6 files changed, 221 insertions(+)
 create mode 100644 hw/misc/aspeed_xdma.c
 create mode 100644 include/hw/misc/aspeed_xdma.h

diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index 0a0ab87..6901697 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -31,6 +31,7 @@ static const hwaddr aspeed_soc_ast2400_memmap[] = {
 [ASPEED_VIC]= 0x1E6C,
 [ASPEED_SDMC]   = 0x1E6E,
 [ASPEED_SCU]= 0x1E6E2000,
+[ASPEED_XDMA]   = 0x1E6E7000,
 [ASPEED_ADC]= 0x1E6E9000,
 [ASPEED_SRAM]   = 0x1E72,
 [ASPEED_GPIO]   = 0x1E78,
@@ -57,6 +58,7 @@ static const hwaddr aspeed_soc_ast2500_memmap[] = {
 [ASPEED_VIC]= 0x1E6C,
 [ASPEED_SDMC]   = 0x1E6E,
 [ASPEED_SCU]= 0x1E6E2000,
+[ASPEED_XDMA]   = 0x1E6E7000,
 [ASPEED_ADC]= 0x1E6E9000,
 [ASPEED_SRAM]   = 0x1E72,
 [ASPEED_GPIO]   = 0x1E78,
@@ -90,6 +92,7 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
 [ASPEED_VIC]= 0x1E6C,
 [ASPEED_SDMC]   = 0x1E6E,
 [ASPEED_SCU]= 0x1E6E2000,
+[ASPEED_XDMA]   = 0x1E6E7000,
 [ASPEED_ADC]= 0x1E6E9000,
 [ASPEED_SRAM]   = 0x1E72,
 [ASPEED_GPIO]   = 0x1E78,
@@ -137,6 +140,7 @@ static const int aspeed_soc_ast2400_irqmap[] = {
 [ASPEED_I2C]= 12,
 [ASPEED_ETH1]   = 2,
 [ASPEED_ETH2]   = 3,
+[ASPEED_XDMA]   = 6,
 };
 
 #define aspeed_soc_ast2500_irqmap aspeed_soc_ast2400_irqmap
@@ -174,6 +178,7 @@ static const int aspeed_soc_ast2600_irqmap[] = {
 [ASPEED_ETH2]   = 3,
 [ASPEED_FSI1]   = 100,
 [ASPEED_FSI2]   = 101,
+[ASPEED_XDMA]   = 6,
 };
 
 static const char *aspeed_soc_ast2400_typenames[] = { "aspeed.smc.spi" };
@@ -359,6 +364,9 @@ static void aspeed_soc_init(Object *obj)
 sysbus_init_child_obj(obj, "fsi[*]", OBJECT(>fsi[0]),
   sizeof(s->fsi[0]), TYPE_ASPEED_FSI);
 }
+
+sysbus_init_child_obj(obj, "xdma", OBJECT(>xdma), sizeof(s->xdma),
+  TYPE_ASPEED_XDMA);
 }
 
 static void aspeed_soc_realize(DeviceState *dev, Error **errp)
@@ -662,6 +670,17 @@ static void aspeed_soc_realize(DeviceState *dev, Error 
**errp)
 sysbus_connect_irq(SYS_BUS_DEVICE(>fsi[0]), 0,
aspeed_soc_get_irq(s, ASPEED_FSI1));
 }
+
+/* XDMA */
+object_property_set_bool(OBJECT(>xdma), true, "realized", );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(>xdma), 0,
+sc->info->memmap[ASPEED_XDMA]);
+sysbus_connect_irq(SYS_BUS_DEVICE(>xdma), 0,
+   aspeed_soc_get_irq(s, ASPEED_XDMA));
 }
 
 static void aspeed_soc_class_init(ObjectClass *oc, void *data)
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index d33c1c6..dc2b9c3 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -78,6 +78,7 @@ obj-$(CONFIG_PVPANIC) += pvpanic.o
 obj-$(CONFIG_AUX) += auxbus.o
 obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o aspeed_sdmc.o aspeed_ibt.o
 obj-$(CONFIG_ASPEED_SOC) += aspeed_pwm.o aspeed_lpc.o aspeed_fsi.o
+obj-$(CONFIG_ASPEED_SOC) += aspeed_xdma.o
 obj-$(CONFIG_MSF2) += msf2-sysreg.o
 obj-$(CONFIG_NRF51_SOC) += nrf51_rng.o
 
diff --git a/hw/misc/aspeed_xdma.c b/hw/misc/aspeed_xdma.c
new file mode 100644
index 000..eebd4ad
--- /dev/null
+++ b/hw/misc/aspeed_xdma.c
@@ -0,0 +1,165 @@
+/*
+ * ASPEED XDMA Controller
+ * Eddie James 
+ *
+ * Copyright (C) 2019 IBM Corp
+ * SPDX-License-Identifer: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qemu/error-report.h"
+#include "hw/misc/aspeed_xdma.h"
+#include "qapi/error.h"
+
+#include "trace.h"
+
+#define XDMA_BMC_CMDQ_ADDR 0x10
+#define XDMA_BMC_CMDQ_ENDP 0x14
+#define XDMA_BMC_CMDQ_WRP  0x18
+#define  XDMA_BMC_CMDQ_W_MASK  0x0003
+#define XDMA_BMC_CMDQ_RDP  0x1C
+#define  XDMA_BMC_CMDQ_RDP_MAGIC   0xEE882266
+#define XDMA_IRQ_ENG_CTRL  0x20
+#define  XDMA_IRQ_ENG_CTRL_US_COMP BIT(4)
+#define  XDMA_IRQ_ENG_CTRL_DS_COMP BIT(5)

Re: [Qemu-devel] [PATCH] hw: misc: Add Aspeed XDMA device

2019-06-10 Thread Eddie James



On 6/6/19 6:34 PM, Philippe Mathieu-Daudé wrote:

Hi Eddie,

On 6/4/19 12:09 AM, Eddie James wrote:

The XDMA engine embedded in the Aspeed SOCs performs PCI DMA operations
between the SOC (acting as a BMC) and a host processor in a server.

If I got your model correctly, it does no DMA operation but simply
answer correctly to the BMC, and set 'operation done' IRQ with no delay.
So this is a dummy device. Then it would be more useful having ignored
DMA ops traced with trace-events.



Thats correct. Good idea, I will add some tracing.





The XDMA engine exists on the AST2400, AST2500, and AST2600 SOCs, so
enable it for all of those.

Signed-off-by: Eddie James 
---
  hw/arm/aspeed_soc.c   |  14 
  hw/misc/Makefile.objs |   2 +-
  hw/misc/aspeed_xdma.c | 156 ++
  include/hw/arm/aspeed_soc.h   |   2 +
  include/hw/misc/aspeed_xdma.h |  31 +
  5 files changed, 204 insertions(+), 1 deletion(-)
  create mode 100644 hw/misc/aspeed_xdma.c
  create mode 100644 include/hw/misc/aspeed_xdma.h

diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index faff42b..b25bb18 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -31,6 +31,7 @@
  #define ASPEED_SOC_VIC_BASE 0x1E6C
  #define ASPEED_SOC_SDMC_BASE0x1E6E
  #define ASPEED_SOC_SCU_BASE 0x1E6E2000
+#define ASPEED_SOC_XDMA_BASE0x1E6E7000
  #define ASPEED_SOC_SRAM_BASE0x1E72
  #define ASPEED_SOC_TIMER_BASE   0x1E782000
  #define ASPEED_SOC_WDT_BASE 0x1E785000
@@ -159,6 +160,9 @@ static void aspeed_soc_init(Object *obj)
  
  sysbus_init_child_obj(obj, "ftgmac100", OBJECT(>ftgmac100),

sizeof(s->ftgmac100), TYPE_FTGMAC100);
+
+sysbus_init_child_obj(obj, "xdma", OBJECT(>xdma), sizeof(s->xdma),
+  TYPE_ASPEED_XDMA);
  }
  
  static void aspeed_soc_realize(DeviceState *dev, Error **errp)

@@ -298,6 +302,16 @@ static void aspeed_soc_realize(DeviceState *dev, Error 
**errp)
  sysbus_mmio_map(SYS_BUS_DEVICE(>ftgmac100), 0, ASPEED_SOC_ETH1_BASE);
  sysbus_connect_irq(SYS_BUS_DEVICE(>ftgmac100), 0,
 qdev_get_gpio_in(DEVICE(>vic), 2));
+
+/* XDMA */
+object_property_set_bool(OBJECT(>xdma), true, "realized", );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(>xdma), 0, ASPEED_SOC_XDMA_BASE);
+sysbus_connect_irq(SYS_BUS_DEVICE(>xdma), 0,
+   qdev_get_gpio_in(DEVICE(>vic), 6));
  }
  
  static void aspeed_soc_class_init(ObjectClass *oc, void *data)

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 77b9df9..a4483af 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -74,7 +74,7 @@ obj-$(CONFIG_ARMSSE_MHU) += armsse-mhu.o
  
  obj-$(CONFIG_PVPANIC) += pvpanic.o

  obj-$(CONFIG_AUX) += auxbus.o
-obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o aspeed_sdmc.o
+obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o aspeed_sdmc.o aspeed_xdma.o
  obj-$(CONFIG_MSF2) += msf2-sysreg.o
  obj-$(CONFIG_NRF51_SOC) += nrf51_rng.o
  
diff --git a/hw/misc/aspeed_xdma.c b/hw/misc/aspeed_xdma.c

new file mode 100644
index 000..fe3a32e
--- /dev/null
+++ b/hw/misc/aspeed_xdma.c
@@ -0,0 +1,156 @@
+/*
+ * ASPEED XDMA Controller
+ * Eddie James 
+ *
+ * Copyright (C) 2019 IBM Corp
+ * SPDX-License-Identifer: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qemu/error-report.h"
+#include "hw/misc/aspeed_xdma.h"
+#include "qapi/error.h"
+
+#define XDMA_BMC_CMDQ_ADDR 0x10
+#define XDMA_BMC_CMDQ_ENDP 0x14
+#define XDMA_BMC_CMDQ_WRP  0x18
+#define  XDMA_BMC_CMDQ_W_MASK  0x0003
+#define XDMA_BMC_CMDQ_RDP  0x1C
+#define  XDMA_BMC_CMDQ_RDP_MAGIC   0xEE882266
+#define XDMA_IRQ_ENG_CTRL  0x20
+#define  XDMA_IRQ_ENG_CTRL_US_COMP BIT(4)
+#define  XDMA_IRQ_ENG_CTRL_DS_COMP BIT(5)
+#define  XDMA_IRQ_ENG_CTRL_W_MASK  0xBFEFF07F
+#define XDMA_IRQ_ENG_STAT  0x24
+#define  XDMA_IRQ_ENG_STAT_US_COMP BIT(4)
+#define  XDMA_IRQ_ENG_STAT_DS_COMP BIT(5)
+#define  XDMA_IRQ_ENG_STAT_RESET   0xF800
+
+#define TO_REG(addr) ((addr) / sizeof(uint32_t))
+
+static uint64_t aspeed_xdma_read(void *opaque, hwaddr addr, unsigned int size)
+{
+uint32_t val = 0;
+AspeedXDMAState *xdma = opaque;
+
+if (addr < ASPEED_XDMA_REG_SIZE) {
+val = xdma->regs[TO_REG(addr)];
+}
+
+return (uint64_t)val;
+}
+
+static void aspeed_xdma_write(void *opaque, hwaddr addr, uint64_t val,
+  unsigned int size)
+{
+unsigned int idx;
+uint32_t val32 = (uint32_t)val;
+AspeedXDMAState *xdma = opaque;
+
+if (addr >= ASPEED_XDMA_REG_SIZE) {
+return;
+}
+
+switch (addr) {
+case XDMA_BMC_CMDQ_ENDP:
+xdma-&

Re: [Qemu-devel] [PATCH] hw: misc: Add Aspeed XDMA device

2019-06-06 Thread Eddie James



On 6/6/19 1:16 AM, Cédric Le Goater wrote:

Hello Eddie,

On 04/06/2019 00:09, Eddie James wrote:

The XDMA engine embedded in the Aspeed SOCs performs PCI DMA operations
between the SOC (acting as a BMC) and a host processor in a server.

The XDMA engine exists on the AST2400, AST2500, and AST2600 SOCs, so
enable it for all of those.

Signed-off-by: Eddie James 

This looks correct to me. It's sufficient to exercise the BMC driver.

However, we will need to rebase on an Aspeed patchset I sent earlier :

http://patchwork.ozlabs.org/cover/1105343/

I can do that and include the patch in my tree for the moment.



I built and tested the model on your tree, so let me know if you want me 
to send that patch instead?






For my understanding, how can we interact with the model and pretend
there is a host side ?



I have an application that can test the driver here: 
https://github.com/eddiejames/xdma-test


But as you say there is no host side; the operations don't copy any 
memory anywhere. Joel suggested adding some way to copy and check some 
dummy memory contents, but I haven't looked into that yet.



Thanks,

Eddie




Thanks,

C.


---
  hw/arm/aspeed_soc.c   |  14 
  hw/misc/Makefile.objs |   2 +-
  hw/misc/aspeed_xdma.c | 156 ++
  include/hw/arm/aspeed_soc.h   |   2 +
  include/hw/misc/aspeed_xdma.h |  31 +
  5 files changed, 204 insertions(+), 1 deletion(-)
  create mode 100644 hw/misc/aspeed_xdma.c
  create mode 100644 include/hw/misc/aspeed_xdma.h

diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index faff42b..b25bb18 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -31,6 +31,7 @@
  #define ASPEED_SOC_VIC_BASE 0x1E6C
  #define ASPEED_SOC_SDMC_BASE0x1E6E
  #define ASPEED_SOC_SCU_BASE 0x1E6E2000
+#define ASPEED_SOC_XDMA_BASE0x1E6E7000
  #define ASPEED_SOC_SRAM_BASE0x1E72
  #define ASPEED_SOC_TIMER_BASE   0x1E782000
  #define ASPEED_SOC_WDT_BASE 0x1E785000
@@ -159,6 +160,9 @@ static void aspeed_soc_init(Object *obj)
  
  sysbus_init_child_obj(obj, "ftgmac100", OBJECT(>ftgmac100),

sizeof(s->ftgmac100), TYPE_FTGMAC100);
+
+sysbus_init_child_obj(obj, "xdma", OBJECT(>xdma), sizeof(s->xdma),
+  TYPE_ASPEED_XDMA);
  }
  
  static void aspeed_soc_realize(DeviceState *dev, Error **errp)

@@ -298,6 +302,16 @@ static void aspeed_soc_realize(DeviceState *dev, Error 
**errp)
  sysbus_mmio_map(SYS_BUS_DEVICE(>ftgmac100), 0, ASPEED_SOC_ETH1_BASE);
  sysbus_connect_irq(SYS_BUS_DEVICE(>ftgmac100), 0,
 qdev_get_gpio_in(DEVICE(>vic), 2));
+
+/* XDMA */
+object_property_set_bool(OBJECT(>xdma), true, "realized", );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(>xdma), 0, ASPEED_SOC_XDMA_BASE);
+sysbus_connect_irq(SYS_BUS_DEVICE(>xdma), 0,
+   qdev_get_gpio_in(DEVICE(>vic), 6));
  }
  
  static void aspeed_soc_class_init(ObjectClass *oc, void *data)

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 77b9df9..a4483af 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -74,7 +74,7 @@ obj-$(CONFIG_ARMSSE_MHU) += armsse-mhu.o
  
  obj-$(CONFIG_PVPANIC) += pvpanic.o

  obj-$(CONFIG_AUX) += auxbus.o
-obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o aspeed_sdmc.o
+obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o aspeed_sdmc.o aspeed_xdma.o
  obj-$(CONFIG_MSF2) += msf2-sysreg.o
  obj-$(CONFIG_NRF51_SOC) += nrf51_rng.o
  
diff --git a/hw/misc/aspeed_xdma.c b/hw/misc/aspeed_xdma.c

new file mode 100644
index 000..fe3a32e
--- /dev/null
+++ b/hw/misc/aspeed_xdma.c
@@ -0,0 +1,156 @@
+/*
+ * ASPEED XDMA Controller
+ * Eddie James 
+ *
+ * Copyright (C) 2019 IBM Corp
+ * SPDX-License-Identifer: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qemu/error-report.h"
+#include "hw/misc/aspeed_xdma.h"
+#include "qapi/error.h"
+
+#define XDMA_BMC_CMDQ_ADDR 0x10
+#define XDMA_BMC_CMDQ_ENDP 0x14
+#define XDMA_BMC_CMDQ_WRP  0x18
+#define  XDMA_BMC_CMDQ_W_MASK  0x0003
+#define XDMA_BMC_CMDQ_RDP  0x1C
+#define  XDMA_BMC_CMDQ_RDP_MAGIC   0xEE882266
+#define XDMA_IRQ_ENG_CTRL  0x20
+#define  XDMA_IRQ_ENG_CTRL_US_COMP BIT(4)
+#define  XDMA_IRQ_ENG_CTRL_DS_COMP BIT(5)
+#define  XDMA_IRQ_ENG_CTRL_W_MASK  0xBFEFF07F
+#define XDMA_IRQ_ENG_STAT  0x24
+#define  XDMA_IRQ_ENG_STAT_US_COMP BIT(4)
+#define  XDMA_IRQ_ENG_STAT_DS_COMP BIT(5)
+#define  XDMA_IRQ_ENG_STAT_RESET   0xF800
+
+#define TO_REG(addr) ((addr) / sizeof(uint32_t))
+
+static uint64_t aspeed_xdma_read(void *opaque, hwaddr addr, unsigned int size)
+{
+uint32_t val = 0;
+AspeedXDMAState *xdma = opaque;
+
+ 

[Qemu-devel] [PATCH] hw: misc: Add Aspeed XDMA device

2019-06-03 Thread Eddie James
The XDMA engine embedded in the Aspeed SOCs performs PCI DMA operations
between the SOC (acting as a BMC) and a host processor in a server.

The XDMA engine exists on the AST2400, AST2500, and AST2600 SOCs, so
enable it for all of those.

Signed-off-by: Eddie James 
---
 hw/arm/aspeed_soc.c   |  14 
 hw/misc/Makefile.objs |   2 +-
 hw/misc/aspeed_xdma.c | 156 ++
 include/hw/arm/aspeed_soc.h   |   2 +
 include/hw/misc/aspeed_xdma.h |  31 +
 5 files changed, 204 insertions(+), 1 deletion(-)
 create mode 100644 hw/misc/aspeed_xdma.c
 create mode 100644 include/hw/misc/aspeed_xdma.h

diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index faff42b..b25bb18 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -31,6 +31,7 @@
 #define ASPEED_SOC_VIC_BASE 0x1E6C
 #define ASPEED_SOC_SDMC_BASE0x1E6E
 #define ASPEED_SOC_SCU_BASE 0x1E6E2000
+#define ASPEED_SOC_XDMA_BASE0x1E6E7000
 #define ASPEED_SOC_SRAM_BASE0x1E72
 #define ASPEED_SOC_TIMER_BASE   0x1E782000
 #define ASPEED_SOC_WDT_BASE 0x1E785000
@@ -159,6 +160,9 @@ static void aspeed_soc_init(Object *obj)
 
 sysbus_init_child_obj(obj, "ftgmac100", OBJECT(>ftgmac100),
   sizeof(s->ftgmac100), TYPE_FTGMAC100);
+
+sysbus_init_child_obj(obj, "xdma", OBJECT(>xdma), sizeof(s->xdma),
+  TYPE_ASPEED_XDMA);
 }
 
 static void aspeed_soc_realize(DeviceState *dev, Error **errp)
@@ -298,6 +302,16 @@ static void aspeed_soc_realize(DeviceState *dev, Error 
**errp)
 sysbus_mmio_map(SYS_BUS_DEVICE(>ftgmac100), 0, ASPEED_SOC_ETH1_BASE);
 sysbus_connect_irq(SYS_BUS_DEVICE(>ftgmac100), 0,
qdev_get_gpio_in(DEVICE(>vic), 2));
+
+/* XDMA */
+object_property_set_bool(OBJECT(>xdma), true, "realized", );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(>xdma), 0, ASPEED_SOC_XDMA_BASE);
+sysbus_connect_irq(SYS_BUS_DEVICE(>xdma), 0,
+   qdev_get_gpio_in(DEVICE(>vic), 6));
 }
 
 static void aspeed_soc_class_init(ObjectClass *oc, void *data)
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 77b9df9..a4483af 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -74,7 +74,7 @@ obj-$(CONFIG_ARMSSE_MHU) += armsse-mhu.o
 
 obj-$(CONFIG_PVPANIC) += pvpanic.o
 obj-$(CONFIG_AUX) += auxbus.o
-obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o aspeed_sdmc.o
+obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o aspeed_sdmc.o aspeed_xdma.o
 obj-$(CONFIG_MSF2) += msf2-sysreg.o
 obj-$(CONFIG_NRF51_SOC) += nrf51_rng.o
 
diff --git a/hw/misc/aspeed_xdma.c b/hw/misc/aspeed_xdma.c
new file mode 100644
index 000..fe3a32e
--- /dev/null
+++ b/hw/misc/aspeed_xdma.c
@@ -0,0 +1,156 @@
+/*
+ * ASPEED XDMA Controller
+ * Eddie James 
+ *
+ * Copyright (C) 2019 IBM Corp
+ * SPDX-License-Identifer: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qemu/error-report.h"
+#include "hw/misc/aspeed_xdma.h"
+#include "qapi/error.h"
+
+#define XDMA_BMC_CMDQ_ADDR 0x10
+#define XDMA_BMC_CMDQ_ENDP 0x14
+#define XDMA_BMC_CMDQ_WRP  0x18
+#define  XDMA_BMC_CMDQ_W_MASK  0x0003
+#define XDMA_BMC_CMDQ_RDP  0x1C
+#define  XDMA_BMC_CMDQ_RDP_MAGIC   0xEE882266
+#define XDMA_IRQ_ENG_CTRL  0x20
+#define  XDMA_IRQ_ENG_CTRL_US_COMP BIT(4)
+#define  XDMA_IRQ_ENG_CTRL_DS_COMP BIT(5)
+#define  XDMA_IRQ_ENG_CTRL_W_MASK  0xBFEFF07F
+#define XDMA_IRQ_ENG_STAT  0x24
+#define  XDMA_IRQ_ENG_STAT_US_COMP BIT(4)
+#define  XDMA_IRQ_ENG_STAT_DS_COMP BIT(5)
+#define  XDMA_IRQ_ENG_STAT_RESET   0xF800
+
+#define TO_REG(addr) ((addr) / sizeof(uint32_t))
+
+static uint64_t aspeed_xdma_read(void *opaque, hwaddr addr, unsigned int size)
+{
+uint32_t val = 0;
+AspeedXDMAState *xdma = opaque;
+
+if (addr < ASPEED_XDMA_REG_SIZE) {
+val = xdma->regs[TO_REG(addr)];
+}
+
+return (uint64_t)val;
+}
+
+static void aspeed_xdma_write(void *opaque, hwaddr addr, uint64_t val,
+  unsigned int size)
+{
+unsigned int idx;
+uint32_t val32 = (uint32_t)val;
+AspeedXDMAState *xdma = opaque;
+
+if (addr >= ASPEED_XDMA_REG_SIZE) {
+return;
+}
+
+switch (addr) {
+case XDMA_BMC_CMDQ_ENDP:
+xdma->regs[TO_REG(addr)] = val32 & XDMA_BMC_CMDQ_W_MASK;
+break;
+case XDMA_BMC_CMDQ_WRP:
+idx = TO_REG(addr);
+xdma->regs[idx] = val32 & XDMA_BMC_CMDQ_W_MASK;
+xdma->regs[TO_REG(XDMA_BMC_CMDQ_RDP)] = xdma->regs[idx];
+
+if (xdma->bmc_cmdq_readp_set) {
+xdma->bmc_cmdq_readp_set = 0;
+} else {
+xdma->regs[TO_RE