All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] hw/dma/pl330: Add memory region to replace default
@ 2021-08-16  6:46 Wen, Jianxian
  2021-08-16  9:19 ` Philippe Mathieu-Daudé
  0 siblings, 1 reply; 2+ messages in thread
From: Wen, Jianxian @ 2021-08-16  6:46 UTC (permalink / raw)
  To: peter.maydell, i.mitsyanko, edgar.iglesias, alistair
  Cc: qemu-arm, Liu, Renwei, qemu-devel, Li, Chunming

L330 needs a memory region which can connect with SMMU IOMMU region to support SMMU translate.

Signed-off-by: Jianxian Wen <jianxian.wen@verisilicon.com>
---
Changes v1 -> v2 (after review of Peter Maydell):
 - Use the dma_memory_read/dma_memory_write functions, update function AddressSpace* parameter.

 hw/arm/exynos4210.c  |  3 +++
 hw/arm/xilinx_zynq.c |  2 ++
 hw/dma/pl330.c       | 20 ++++++++++++++++----
 3 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
index 5c7a51b..af0e482 100644
--- a/hw/arm/exynos4210.c
+++ b/hw/arm/exynos4210.c
@@ -171,8 +171,11 @@ static DeviceState *pl330_create(uint32_t base, qemu_or_irq *orgate,
     SysBusDevice *busdev;
     DeviceState *dev;
     int i;
+    MemoryRegion *sysmem = get_system_memory();
 
     dev = qdev_new("pl330");
+    object_property_set_link(OBJECT(dev), "memory",
+                                    OBJECT(sysmem), &error_fatal);
     qdev_prop_set_uint8(dev, "num_events", nevents);
     qdev_prop_set_uint8(dev, "num_chnls",  8);
     qdev_prop_set_uint8(dev, "num_periph_req",  nreq);
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
index 245af81..e0b3a73 100644
--- a/hw/arm/xilinx_zynq.c
+++ b/hw/arm/xilinx_zynq.c
@@ -312,6 +312,8 @@ static void zynq_init(MachineState *machine)
     sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[39-IRQ_OFFSET]);
 
     dev = qdev_new("pl330");
+    object_property_set_link(OBJECT(dev), "memory",
+                                    OBJECT(address_space_mem), &error_fatal);
     qdev_prop_set_uint8(dev, "num_chnls",  8);
     qdev_prop_set_uint8(dev, "num_periph_req",  4);
     qdev_prop_set_uint8(dev, "num_events",  16);
diff --git a/hw/dma/pl330.c b/hw/dma/pl330.c
index 944ba29..b8a4448 100644
--- a/hw/dma/pl330.c
+++ b/hw/dma/pl330.c
@@ -269,6 +269,9 @@ struct PL330State {
     uint8_t num_faulting;
     uint8_t periph_busy[PL330_PERIPH_NUM];
 
+    /* Memory region that DMA operation access */
+    MemoryRegion *mem_mr;
+    AddressSpace mem_as;
 };
 
 #define TYPE_PL330 "pl330"
@@ -1108,7 +1111,7 @@ static inline const PL330InsnDesc *pl330_fetch_insn(PL330Chan *ch)
     uint8_t opcode;
     int i;
 
-    dma_memory_read(&address_space_memory, ch->pc, &opcode, 1);
+    dma_memory_read(&ch->parent->mem_as, ch->pc, &opcode, 1);
     for (i = 0; insn_desc[i].size; i++) {
         if ((opcode & insn_desc[i].opmask) == insn_desc[i].opcode) {
             return &insn_desc[i];
@@ -1122,7 +1125,7 @@ static inline void pl330_exec_insn(PL330Chan *ch, const PL330InsnDesc *insn)
     uint8_t buf[PL330_INSN_MAXSIZE];
 
     assert(insn->size <= PL330_INSN_MAXSIZE);
-    dma_memory_read(&address_space_memory, ch->pc, buf, insn->size);
+    dma_memory_read(&ch->parent->mem_as, ch->pc, buf, insn->size);
     insn->exec(ch, buf[0], &buf[1], insn->size - 1);
 }
 
@@ -1186,7 +1189,7 @@ static int pl330_exec_cycle(PL330Chan *channel)
     if (q != NULL && q->len <= pl330_fifo_num_free(&s->fifo)) {
         int len = q->len - (q->addr & (q->len - 1));
 
-        dma_memory_read(&address_space_memory, q->addr, buf, len);
+        dma_memory_read(&s->mem_as, q->addr, buf, len);
         trace_pl330_exec_cycle(q->addr, len);
         if (trace_event_get_state_backends(TRACE_PL330_HEXDUMP)) {
             pl330_hexdump(buf, len);
@@ -1217,7 +1220,7 @@ static int pl330_exec_cycle(PL330Chan *channel)
             fifo_res = pl330_fifo_get(&s->fifo, buf, len, q->tag);
         }
         if (fifo_res == PL330_FIFO_OK || q->z) {
-            dma_memory_write(&address_space_memory, q->addr, buf, len);
+            dma_memory_write(&s->mem_as, q->addr, buf, len);
             trace_pl330_exec_cycle(q->addr, len);
             if (trace_event_get_state_backends(TRACE_PL330_HEXDUMP)) {
                 pl330_hexdump(buf, len);
@@ -1562,6 +1565,12 @@ static void pl330_realize(DeviceState *dev, Error **errp)
                           "dma", PL330_IOMEM_SIZE);
     sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
 
+    if (!s->mem_mr) {
+        error_setg(errp, "'mem_mr' link is not set");
+        return;
+    }
+    address_space_init(&s->mem_as, s->mem_mr, TYPE_PL330 "-memory");
+
     s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, pl330_exec_cycle_timer, s);
 
     s->cfg[0] = (s->mgr_ns_at_rst ? 0x4 : 0) |
@@ -1656,6 +1665,9 @@ static Property pl330_properties[] = {
     DEFINE_PROP_UINT8("rd_q_dep", PL330State, rd_q_dep, 16),
     DEFINE_PROP_UINT16("data_buffer_dep", PL330State, data_buffer_dep, 256),
 
+    DEFINE_PROP_LINK("memory", PL330State, mem_mr,
+                     TYPE_MEMORY_REGION, MemoryRegion *),
+
     DEFINE_PROP_END_OF_LIST(),
 };
 
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH v2] hw/dma/pl330: Add memory region to replace default
  2021-08-16  6:46 [PATCH v2] hw/dma/pl330: Add memory region to replace default Wen, Jianxian
@ 2021-08-16  9:19 ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 2+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-08-16  9:19 UTC (permalink / raw)
  To: Wen, Jianxian, peter.maydell, i.mitsyanko, edgar.iglesias, alistair
  Cc: qemu-arm, Liu, Renwei, qemu-devel, Li, Chunming

Hi Jianxian,

On 8/16/21 8:46 AM, Wen, Jianxian wrote:
> L330 needs a memory region which can connect with SMMU IOMMU region to support SMMU translate.
> 
> Signed-off-by: Jianxian Wen <jianxian.wen@verisilicon.com>
> ---
> Changes v1 -> v2 (after review of Peter Maydell):
>  - Use the dma_memory_read/dma_memory_write functions, update function AddressSpace* parameter.
> 
>  hw/arm/exynos4210.c  |  3 +++
>  hw/arm/xilinx_zynq.c |  2 ++
>  hw/dma/pl330.c       | 20 ++++++++++++++++----
>  3 files changed, 21 insertions(+), 4 deletions(-)
> 
> diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
> index 5c7a51b..af0e482 100644
> --- a/hw/arm/exynos4210.c
> +++ b/hw/arm/exynos4210.c
> @@ -171,8 +171,11 @@ static DeviceState *pl330_create(uint32_t base, qemu_or_irq *orgate,
>      SysBusDevice *busdev;
>      DeviceState *dev;
>      int i;
> +    MemoryRegion *sysmem = get_system_memory();
>  
>      dev = qdev_new("pl330");
> +    object_property_set_link(OBJECT(dev), "memory",
> +                                    OBJECT(sysmem), &error_fatal);

Incorrect style alignment. Maybe simply:

       object_property_set_link(OBJECT(dev), "memory",
                                OBJECT(get_system_memory()),
                                &error_fatal);

>      qdev_prop_set_uint8(dev, "num_events", nevents);
>      qdev_prop_set_uint8(dev, "num_chnls",  8);
>      qdev_prop_set_uint8(dev, "num_periph_req",  nreq);
> diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
> index 245af81..e0b3a73 100644
> --- a/hw/arm/xilinx_zynq.c
> +++ b/hw/arm/xilinx_zynq.c
> @@ -312,6 +312,8 @@ static void zynq_init(MachineState *machine)
>      sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[39-IRQ_OFFSET]);
>  
>      dev = qdev_new("pl330");
> +    object_property_set_link(OBJECT(dev), "memory",
> +                                    OBJECT(address_space_mem), &error_fatal);

Incorrect style alignment.

>      qdev_prop_set_uint8(dev, "num_chnls",  8);
>      qdev_prop_set_uint8(dev, "num_periph_req",  4);
>      qdev_prop_set_uint8(dev, "num_events",  16);
> diff --git a/hw/dma/pl330.c b/hw/dma/pl330.c
> index 944ba29..b8a4448 100644
> --- a/hw/dma/pl330.c
> +++ b/hw/dma/pl330.c
> @@ -269,6 +269,9 @@ struct PL330State {
>      uint8_t num_faulting;
>      uint8_t periph_busy[PL330_PERIPH_NUM];
>  
> +    /* Memory region that DMA operation access */
> +    MemoryRegion *mem_mr;
> +    AddressSpace mem_as;
>  };
>  
>  #define TYPE_PL330 "pl330"
> @@ -1108,7 +1111,7 @@ static inline const PL330InsnDesc *pl330_fetch_insn(PL330Chan *ch)
>      uint8_t opcode;
>      int i;
>  
> -    dma_memory_read(&address_space_memory, ch->pc, &opcode, 1);
> +    dma_memory_read(&ch->parent->mem_as, ch->pc, &opcode, 1);
>      for (i = 0; insn_desc[i].size; i++) {
>          if ((opcode & insn_desc[i].opmask) == insn_desc[i].opcode) {
>              return &insn_desc[i];
> @@ -1122,7 +1125,7 @@ static inline void pl330_exec_insn(PL330Chan *ch, const PL330InsnDesc *insn)
>      uint8_t buf[PL330_INSN_MAXSIZE];
>  
>      assert(insn->size <= PL330_INSN_MAXSIZE);
> -    dma_memory_read(&address_space_memory, ch->pc, buf, insn->size);
> +    dma_memory_read(&ch->parent->mem_as, ch->pc, buf, insn->size);
>      insn->exec(ch, buf[0], &buf[1], insn->size - 1);
>  }
>  
> @@ -1186,7 +1189,7 @@ static int pl330_exec_cycle(PL330Chan *channel)
>      if (q != NULL && q->len <= pl330_fifo_num_free(&s->fifo)) {
>          int len = q->len - (q->addr & (q->len - 1));
>  
> -        dma_memory_read(&address_space_memory, q->addr, buf, len);
> +        dma_memory_read(&s->mem_as, q->addr, buf, len);
>          trace_pl330_exec_cycle(q->addr, len);
>          if (trace_event_get_state_backends(TRACE_PL330_HEXDUMP)) {
>              pl330_hexdump(buf, len);
> @@ -1217,7 +1220,7 @@ static int pl330_exec_cycle(PL330Chan *channel)
>              fifo_res = pl330_fifo_get(&s->fifo, buf, len, q->tag);
>          }
>          if (fifo_res == PL330_FIFO_OK || q->z) {
> -            dma_memory_write(&address_space_memory, q->addr, buf, len);
> +            dma_memory_write(&s->mem_as, q->addr, buf, len);
>              trace_pl330_exec_cycle(q->addr, len);
>              if (trace_event_get_state_backends(TRACE_PL330_HEXDUMP)) {
>                  pl330_hexdump(buf, len);
> @@ -1562,6 +1565,12 @@ static void pl330_realize(DeviceState *dev, Error **errp)
>                            "dma", PL330_IOMEM_SIZE);
>      sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
>  
> +    if (!s->mem_mr) {
> +        error_setg(errp, "'mem_mr' link is not set");

You use DEFINE_PROP_LINK("memory", ...) below, so use 'memory' in
the error message.

> +        return;
> +    }
> +    address_space_init(&s->mem_as, s->mem_mr, TYPE_PL330 "-memory");

I'd rather not name an address space with '-memory' suffix (I'd expect
a MemoryRegion instead). The last argument is just a description in the
monitor (info mtree *).

>      s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, pl330_exec_cycle_timer, s);
>  
>      s->cfg[0] = (s->mgr_ns_at_rst ? 0x4 : 0) |
> @@ -1656,6 +1665,9 @@ static Property pl330_properties[] = {
>      DEFINE_PROP_UINT8("rd_q_dep", PL330State, rd_q_dep, 16),
>      DEFINE_PROP_UINT16("data_buffer_dep", PL330State, data_buffer_dep, 256),
>  
> +    DEFINE_PROP_LINK("memory", PL330State, mem_mr,
> +                     TYPE_MEMORY_REGION, MemoryRegion *),
> +
>      DEFINE_PROP_END_OF_LIST(),
>  };


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-08-16  9:20 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-16  6:46 [PATCH v2] hw/dma/pl330: Add memory region to replace default Wen, Jianxian
2021-08-16  9:19 ` Philippe Mathieu-Daudé

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.