[PATCH v1 0/3] ZynqMP / Versal: various fixes

2023-11-24 Thread Frederic Konrad
Hi,

Those are various simple fixes for ZynqMP:
  * 1: fixes a possible out of bound access in the SPI model.
  * 2: is a trivial fix for documentation url.
  * 3: is a log guest error fix for the CSU DMA.

Best Regards,
Fred

Frederic Konrad (3):
  hw/ssi/xilinx_spips: fix an out of bound access
  fix some url for amd / xilinx models
  hw/dma/xlnx_csu_dma: don't throw guest errors when stopping the SRC
DMA

 hw/dma/xlnx_csu_dma.c  | 14 +-
 hw/ssi/xilinx_spips.c  |  7 ++-
 include/hw/misc/xlnx-versal-cframe-reg.h   |  2 +-
 include/hw/misc/xlnx-versal-cfu.h  |  2 +-
 include/hw/misc/xlnx-versal-pmc-iou-slcr.h |  2 +-
 include/hw/ssi/xilinx_spips.h  |  3 +++
 include/hw/ssi/xlnx-versal-ospi.h  |  2 +-
 7 files changed, 22 insertions(+), 10 deletions(-)

-- 
2.25.1




[PATCH v1 1/3] hw/ssi/xilinx_spips: fix an out of bound access

2023-11-24 Thread Frederic Konrad
The spips, qspips, and zynqmp-qspips share the same realize function
(xilinx_spips_realize) and initialize their io memory region with different
mmio_ops passed through the class.  The size of the memory region is set to
the largest area (0x200 bytes for zynqmp-qspips) thus it is possible to write
out of s->regs[addr] in xilinx_spips_write for spips and qspips.

This fixes that wrong behavior.

Reviewed-by: Luc Michel 
Signed-off-by: Frederic Konrad 
---
 hw/ssi/xilinx_spips.c | 7 ++-
 include/hw/ssi/xilinx_spips.h | 3 +++
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
index a3955c6c50..0bdfad7e2e 100644
--- a/hw/ssi/xilinx_spips.c
+++ b/hw/ssi/xilinx_spips.c
@@ -973,6 +973,8 @@ static void xilinx_spips_write(void *opaque, hwaddr addr,
 
 DB_PRINT_L(0, "addr=" HWADDR_FMT_plx " = %x\n", addr, (unsigned)value);
 addr >>= 2;
+assert(addr < XLNX_SPIPS_R_MAX);
+
 switch (addr) {
 case R_CONFIG:
 mask = ~(R_CONFIG_RSVD | MAN_START_COM);
@@ -1299,7 +1301,7 @@ static void xilinx_spips_realize(DeviceState *dev, Error 
**errp)
 }
 
 memory_region_init_io(>iomem, OBJECT(s), xsc->reg_ops, s,
-  "spi", XLNX_ZYNQMP_SPIPS_R_MAX * 4);
+  "spi", xsc->reg_size);
 sysbus_init_mmio(sbd, >iomem);
 
 s->irqline = -1;
@@ -1435,6 +1437,7 @@ static void xilinx_qspips_class_init(ObjectClass *klass, 
void * data)
 
 dc->realize = xilinx_qspips_realize;
 xsc->reg_ops = _ops;
+xsc->reg_size = XLNX_SPIPS_R_MAX * 4;
 xsc->rx_fifo_size = RXFF_A_Q;
 xsc->tx_fifo_size = TXFF_A_Q;
 }
@@ -1450,6 +1453,7 @@ static void xilinx_spips_class_init(ObjectClass *klass, 
void *data)
 dc->vmsd = _xilinx_spips;
 
 xsc->reg_ops = _ops;
+xsc->reg_size = XLNX_SPIPS_R_MAX * 4;
 xsc->rx_fifo_size = RXFF_A;
 xsc->tx_fifo_size = TXFF_A;
 }
@@ -1464,6 +1468,7 @@ static void xlnx_zynqmp_qspips_class_init(ObjectClass 
*klass, void * data)
 dc->vmsd = _xlnx_zynqmp_qspips;
 device_class_set_props(dc, xilinx_zynqmp_qspips_properties);
 xsc->reg_ops = _zynqmp_qspips_ops;
+xsc->reg_size = XLNX_ZYNQMP_SPIPS_R_MAX * 4;
 xsc->rx_fifo_size = RXFF_A_Q;
 xsc->tx_fifo_size = TXFF_A_Q;
 }
diff --git a/include/hw/ssi/xilinx_spips.h b/include/hw/ssi/xilinx_spips.h
index 1386d5ac8f..7a754bf67a 100644
--- a/include/hw/ssi/xilinx_spips.h
+++ b/include/hw/ssi/xilinx_spips.h
@@ -33,7 +33,9 @@
 
 typedef struct XilinxSPIPS XilinxSPIPS;
 
+/* For SPIPS, QSPIPS.  */
 #define XLNX_SPIPS_R_MAX(0x100 / 4)
+/* For ZYNQMP_QSPIPS.  */
 #define XLNX_ZYNQMP_SPIPS_R_MAX (0x200 / 4)
 
 /* Bite off 4k chunks at a time */
@@ -125,6 +127,7 @@ struct XilinxSPIPSClass {
 SysBusDeviceClass parent_class;
 
 const MemoryRegionOps *reg_ops;
+uint64_t reg_size;
 
 uint32_t rx_fifo_size;
 uint32_t tx_fifo_size;
-- 
2.25.1




[PATCH v1 2/3] fix some url for amd / xilinx models

2023-11-24 Thread Frederic Konrad
It seems that the url changed a bit, and it triggers an error.  Fix the URLs so
the documentation can be reached again.

Signed-off-by: Frederic Konrad 
---
 hw/dma/xlnx_csu_dma.c  | 2 +-
 include/hw/misc/xlnx-versal-cframe-reg.h   | 2 +-
 include/hw/misc/xlnx-versal-cfu.h  | 2 +-
 include/hw/misc/xlnx-versal-pmc-iou-slcr.h | 2 +-
 include/hw/ssi/xlnx-versal-ospi.h  | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/hw/dma/xlnx_csu_dma.c b/hw/dma/xlnx_csu_dma.c
index e89089821a..531013f35a 100644
--- a/hw/dma/xlnx_csu_dma.c
+++ b/hw/dma/xlnx_csu_dma.c
@@ -33,7 +33,7 @@
 
 /*
  * Ref: UG1087 (v1.7) February 8, 2019
- * 
https://www.xilinx.com/html_docs/registers/ug1087/ug1087-zynq-ultrascale-registers.html
+ * 
https://www.xilinx.com/html_docs/registers/ug1087/ug1087-zynq-ultrascale-registers
  * CSUDMA Module section
  */
 REG32(ADDR, 0x0)
diff --git a/include/hw/misc/xlnx-versal-cframe-reg.h 
b/include/hw/misc/xlnx-versal-cframe-reg.h
index a14fbd7fe4..0091505246 100644
--- a/include/hw/misc/xlnx-versal-cframe-reg.h
+++ b/include/hw/misc/xlnx-versal-cframe-reg.h
@@ -12,7 +12,7 @@
  * 
https://www.xilinx.com/support/documentation/architecture-manuals/am011-versal-acap-trm.pdf
  *
  * [2] Versal ACAP Register Reference,
- * 
https://www.xilinx.com/htmldocs/registers/am012/am012-versal-register-reference.html
+ * 
https://docs.xilinx.com/r/en-US/am012-versal-register-reference/CFRAME_REG-Module
  */
 #ifndef HW_MISC_XLNX_VERSAL_CFRAME_REG_H
 #define HW_MISC_XLNX_VERSAL_CFRAME_REG_H
diff --git a/include/hw/misc/xlnx-versal-cfu.h 
b/include/hw/misc/xlnx-versal-cfu.h
index 86fb841053..be62bab8c8 100644
--- a/include/hw/misc/xlnx-versal-cfu.h
+++ b/include/hw/misc/xlnx-versal-cfu.h
@@ -12,7 +12,7 @@
  * 
https://www.xilinx.com/support/documentation/architecture-manuals/am011-versal-acap-trm.pdf
  *
  * [2] Versal ACAP Register Reference,
- * 
https://www.xilinx.com/htmldocs/registers/am012/am012-versal-register-reference.html
+ * 
https://docs.xilinx.com/r/en-US/am012-versal-register-reference/CFU_CSR-Module
  */
 #ifndef HW_MISC_XLNX_VERSAL_CFU_APB_H
 #define HW_MISC_XLNX_VERSAL_CFU_APB_H
diff --git a/include/hw/misc/xlnx-versal-pmc-iou-slcr.h 
b/include/hw/misc/xlnx-versal-pmc-iou-slcr.h
index f7d24c93c4..0c4a4fd66d 100644
--- a/include/hw/misc/xlnx-versal-pmc-iou-slcr.h
+++ b/include/hw/misc/xlnx-versal-pmc-iou-slcr.h
@@ -34,7 +34,7 @@
  * 
https://www.xilinx.com/support/documentation/architecture-manuals/am011-versal-acap-trm.pdf
  *
  * [2] Versal ACAP Register Reference,
- * 
https://www.xilinx.com/html_docs/registers/am012/am012-versal-register-reference.html#mod___pmc_iop_slcr.html
+ * 
https://docs.xilinx.com/r/en-US/am012-versal-register-reference/PMC_IOP_SLCR-Module
  *
  * QEMU interface:
  * + sysbus MMIO region 0: MemoryRegion for the device's registers
diff --git a/include/hw/ssi/xlnx-versal-ospi.h 
b/include/hw/ssi/xlnx-versal-ospi.h
index 5d131d351d..4ac975aa2f 100644
--- a/include/hw/ssi/xlnx-versal-ospi.h
+++ b/include/hw/ssi/xlnx-versal-ospi.h
@@ -34,7 +34,7 @@
  * 
https://www.xilinx.com/support/documentation/architecture-manuals/am011-versal-acap-trm.pdf
  *
  * [2] Versal ACAP Register Reference,
- * 
https://www.xilinx.com/html_docs/registers/am012/am012-versal-register-reference.html#mod___ospi.html
+ * 
https://docs.xilinx.com/r/en-US/am012-versal-register-reference/OSPI-Module
  *
  *
  * QEMU interface:
-- 
2.25.1




[PATCH v1 3/3] hw/dma/xlnx_csu_dma: don't throw guest errors when stopping the SRC DMA

2023-11-24 Thread Frederic Konrad
UG1087 states for the source channel that: if SIZE is programmed to 0, and the
DMA is started, the interrupts DONE and MEM_DONE will be asserted.

This implies that it is allowed for the guest to stop the source DMA by writing
a size of 0 to the SIZE register, so remove the LOG_GUEST_ERROR in that case.

While at it remove the comment marking the SIZE register as write-only.

See: 
https://docs.xilinx.com/r/en-US/ug1087-zynq-ultrascale-registers/CSUDMA_SRC_SIZE-CSUDMA-Register

Signed-off-by: Frederic Konrad 
---
 hw/dma/xlnx_csu_dma.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/hw/dma/xlnx_csu_dma.c b/hw/dma/xlnx_csu_dma.c
index 531013f35a..bc1505aade 100644
--- a/hw/dma/xlnx_csu_dma.c
+++ b/hw/dma/xlnx_csu_dma.c
@@ -39,7 +39,7 @@
 REG32(ADDR, 0x0)
 FIELD(ADDR, ADDR, 2, 30) /* wo */
 REG32(SIZE, 0x4)
-FIELD(SIZE, SIZE, 2, 27) /* wo */
+FIELD(SIZE, SIZE, 2, 27)
 FIELD(SIZE, LAST_WORD, 0, 1) /* rw, only exists in SRC */
 REG32(STATUS, 0x8)
 FIELD(STATUS, DONE_CNT, 13, 3) /* wtc */
@@ -335,10 +335,14 @@ static uint64_t addr_pre_write(RegisterInfo *reg, 
uint64_t val)
 static uint64_t size_pre_write(RegisterInfo *reg, uint64_t val)
 {
 XlnxCSUDMA *s = XLNX_CSU_DMA(reg->opaque);
+uint64_t size = val & R_SIZE_SIZE_MASK;
 
 if (s->regs[R_SIZE] != 0) {
-qemu_log_mask(LOG_GUEST_ERROR,
-  "%s: Starting DMA while already running.\n", __func__);
+if (size || s->is_dst) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Starting DMA while already running.\n",
+  __func__);
+}
 }
 
 if (!s->is_dst) {
@@ -346,7 +350,7 @@ static uint64_t size_pre_write(RegisterInfo *reg, uint64_t 
val)
 }
 
 /* Size is word aligned */
-return val & R_SIZE_SIZE_MASK;
+return size;
 }
 
 static uint64_t size_post_read(RegisterInfo *reg, uint64_t val)
-- 
2.25.1




Re: hw/display/xlinx-dp: fixing comment

2023-08-27 Thread Frederic Konrad
 Hi,
Yes that comment makes sense thanks.

Best Regards,Fred

Le samedi 26 août 2023 à 12:20:35 UTC+2, Michael Tokarev  
a écrit :  
 
 Hi!

Hopefully this address still works. If not, let's just commit Peter's comment.

Back in 2016, this commit introduced xlinx-dp.c:

commit 58ac482a66de09a7590f705e53fc6a3fb8a055e8
Author: Frederic Konrad 
Date:  Tue Jun 14 15:59:15 2016 +0100

    introduce xlnx-dp

    This is the implementation of the DisplayPort.
    It has an aux-bus to access dpcd and edid.


This commit has the following comment in it:

+static void xlnx_dp_audio_callback(void *opaque, int avail)
+{
+    /*
+    * Get some data from the DPDMA and compute these datas.
+    * Then wait for QEMU's audio subsystem to call this callback.
+    */

As it is, the commit is difficult to understand and has spelling
error in it (datas).  Is the following interpretation by Peter
Maydell correct?

    /*
    * Get the individual left and right audio streams from
    * the DPDMA, and fill the output buffer with the
    * combined stereo audio data adjusted by the volume
    * controls.
    * QEMU's audio subsystem will call this callback
    * repeatedly; we return it the data from the output
    * buffer until it is emptied, and then we will read
    * data from the DPDMA again.
    */

Thanks,

/mjt
  

Re: Support for Gaisler multicore LEONx SoCs

2022-07-08 Thread Frederic Konrad
  Hi Gregg,
AFAIK the leon3-generic can emulate the GR712RC with some little differences in 
the memorymap and / or timer / CPU count.  (You should be able to boot the 
Gaisler monocore linux with it).

About the SMP support AdaCore had a few patches for it, I'll let Fabien answer.

Regards,Fred

 Le jeudi 7 juillet 2022 à 22:30:46 UTC+2, Peter Maydell 
 a écrit :  
 
 

On Thu, 7 Jul 2022 at 20:54, Gregg Allison  
wrote:


We are considering the Gaisler GR712RC (2 core LEON3) and GR740 (4 core LEON4) 
SoCs for a new deep space mission.

Does QEMU support these two multicore configurations at present? Is there an 
effort planned to provide multicore LEONx emulation?


I've cc'd the people listed in MAINTAINERS for Leon, but as far as I cansee 
there have been no Leon-related commits for a few years, so I don'tthink this 
area of QEMU is being actively developed. We seem to havecurrently LEON2 and 
LEON3 CPU support, and one machine type, the"Leon-3 generic" machine.
thanks
-- PMM

  

RE: [PATCH v3 0/4] xlnx-zcu102: fix the display port.

2022-06-07 Thread Frederic Konrad


> -Original Message-
> From: Peter Maydell 
> Sent: 06 June 2022 11:20
> To: Frederic Konrad 
> Cc: qemu-devel@nongnu.org; qemu-...@nongnu.org;
> edgar.igles...@gmail.com; alist...@alistair23.me; Sai Pavan Boddu
> ; Edgar Iglesias ;
> fkon...@amd.com
> Subject: Re: [PATCH v3 0/4] xlnx-zcu102: fix the display port.
> 
> On Wed, 1 Jun 2022 at 18:24,  wrote:
> >
> > From: Frederic Konrad 
> >
> > Hi,
> >
> > This patch set fixes some issues with the DisplayPort for the ZCU102:
> >
> > The first patch fixes the wrong register size and thus the risk of register
> > overflow.
> >
> > The three other one add a vblank interrupt required by the linux driver:
> >   - When using the VNC graphic backend and leaving it unconnected, in the
> best
> > case the gfx_update callback is called once every 3000ms which is
> > insufficient for the driver.  This is fixed by providing a VBLANK 
> > interrupt
> > from a ptimer.
> >   - This requirement revealed two issues with the IRQ numbers and the
> > interrupt disable logic fixed by the two last patches.
> >
> > Tested by:
> >   - booting Petalinux with the framebuffer enabled.
> >   - migrating the running guest and ensure that the vblank timer still fire
> correctly.
> 
> Hi; you forgot to bump the version_id in the vmstate struct when you
> added the new field. Since that was the only problem, I've taken the
> series into target-arm.next and made that change there. I also added
> a note to the commit message that this is a migration break for the
> xlnx-zcu102 board.

Oops, thanks for the fix Peter.

Fred

> 
> thanks
> -- PMM


RE: [PATCH v2 2/4] xlnx_dp: Introduce a vblank signal

2022-05-24 Thread Frederic Konrad


> -Original Message-
> From: Peter Maydell 
> Sent: 23 May 2022 14:52
> To: Frederic Konrad 
> Cc: qemu-devel@nongnu.org; qemu-...@nongnu.org;
> edgar.igles...@gmail.com; alist...@alistair23.me; Sai Pavan Boddu
> ; Edgar Iglesias ; Sai Pavan Boddu
> ; Edgar Iglesias 
> Subject: Re: [PATCH v2 2/4] xlnx_dp: Introduce a vblank signal
> 
> [CAUTION: External Email]
> 
> On Thu, 19 May 2022 at 16:39, Frederic Konrad  wrote:
> >
> > From: Sai Pavan Boddu 
> >
> > Add a periodic timer which raises vblank at a frequency of 30Hz.
> >
> > Signed-off-by: Sai Pavan Boddu 
> > Signed-off-by: Edgar E. Iglesias 
> > Changes by fkonrad:
> >   - Switched to transaction-based ptimer API.
> >   - Added the DP_INT_VBLNK_START macro.
> > Signed-off-by: Frederic Konrad 
> > ---
> 
> 
> > @@ -107,6 +108,8 @@ struct XlnxDPState {
> >   */
> >  DPCDState *dpcd;
> >  I2CDDCState *edid;
> > +
> > +ptimer_state *vblank;
> >  };
> 
> The ptimer has internal state which needs to be considered in
> migration. This means you need to either include it in the device
> vmstate struct (there is a VMSTATE_PTIMER macro for this), or
> else set it up again in a post-load hook. Otherwise if you do
> a migration or state save/load when the timer is running then
> on resume the timer won't be running when it should.

Ah yes indeed, I forgot about that.  Since cross version migration is not 
relevant
here, the VMSTATE_PTIMER would be acceptable right?

> 
> Apologies for not noticing this in my first review.

No worries, thanks for the review :).

Fred

> 
> -- PMM


[PATCH v2 1/4] xlnx_dp: fix the wrong register size

2022-05-19 Thread Frederic Konrad via
The core and the vblend registers size are wrong, they should respectively be
0x3B0 and 0x1E0 according to:
  
https://www.xilinx.com/htmldocs/registers/ug1087/ug1087-zynq-ultrascale-registers.html.

Let's fix that and use macros when creating the mmio region.

Fixes: 58ac482a66d ("introduce xlnx-dp")
Signed-off-by: Frederic Konrad 
Reviewed-by: Edgar E. Iglesias 
---
 hw/display/xlnx_dp.c | 17 ++---
 include/hw/display/xlnx_dp.h |  9 +++--
 2 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/hw/display/xlnx_dp.c b/hw/display/xlnx_dp.c
index 9bb781e312..0378570459 100644
--- a/hw/display/xlnx_dp.c
+++ b/hw/display/xlnx_dp.c
@@ -1219,19 +1219,22 @@ static void xlnx_dp_init(Object *obj)
 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
 XlnxDPState *s = XLNX_DP(obj);
 
-memory_region_init(>container, obj, TYPE_XLNX_DP, 0xC050);
+memory_region_init(>container, obj, TYPE_XLNX_DP, DP_CONTAINER_SIZE);
 
 memory_region_init_io(>core_iomem, obj, _ops, s, TYPE_XLNX_DP
-  ".core", 0x3AF);
-memory_region_add_subregion(>container, 0x, >core_iomem);
+  ".core", sizeof(s->core_registers));
+memory_region_add_subregion(>container, DP_CORE_REG_OFFSET,
+>core_iomem);
 
 memory_region_init_io(>vblend_iomem, obj, _ops, s, TYPE_XLNX_DP
-  ".v_blend", 0x1DF);
-memory_region_add_subregion(>container, 0xA000, >vblend_iomem);
+  ".v_blend", sizeof(s->vblend_registers));
+memory_region_add_subregion(>container, DP_VBLEND_REG_OFFSET,
+>vblend_iomem);
 
 memory_region_init_io(>avbufm_iomem, obj, _ops, s, TYPE_XLNX_DP
-  ".av_buffer_manager", 0x238);
-memory_region_add_subregion(>container, 0xB000, >avbufm_iomem);
+  ".av_buffer_manager", sizeof(s->avbufm_registers));
+memory_region_add_subregion(>container, DP_AVBUF_REG_OFFSET,
+>avbufm_iomem);
 
 memory_region_init_io(>audio_iomem, obj, _ops, s, TYPE_XLNX_DP
   ".audio", sizeof(s->audio_registers));
diff --git a/include/hw/display/xlnx_dp.h b/include/hw/display/xlnx_dp.h
index 8ab4733bb8..1ef5a89ee7 100644
--- a/include/hw/display/xlnx_dp.h
+++ b/include/hw/display/xlnx_dp.h
@@ -39,10 +39,15 @@
 #define AUD_CHBUF_MAX_DEPTH (32 * KiB)
 #define MAX_QEMU_BUFFER_SIZE(4 * KiB)
 
-#define DP_CORE_REG_ARRAY_SIZE  (0x3AF >> 2)
+#define DP_CORE_REG_OFFSET  (0x)
+#define DP_CORE_REG_ARRAY_SIZE  (0x3B0 >> 2)
+#define DP_AVBUF_REG_OFFSET (0xB000)
 #define DP_AVBUF_REG_ARRAY_SIZE (0x238 >> 2)
-#define DP_VBLEND_REG_ARRAY_SIZE(0x1DF >> 2)
+#define DP_VBLEND_REG_OFFSET(0xA000)
+#define DP_VBLEND_REG_ARRAY_SIZE(0x1E0 >> 2)
+#define DP_AUDIO_REG_OFFSET (0xC000)
 #define DP_AUDIO_REG_ARRAY_SIZE (0x50 >> 2)
+#define DP_CONTAINER_SIZE   (0xC050)
 
 struct PixmanPlane {
 pixman_format_code_t format;
-- 
2.25.1




[PATCH v2 2/4] xlnx_dp: Introduce a vblank signal

2022-05-19 Thread Frederic Konrad via
From: Sai Pavan Boddu 

Add a periodic timer which raises vblank at a frequency of 30Hz.

Signed-off-by: Sai Pavan Boddu 
Signed-off-by: Edgar E. Iglesias 
Changes by fkonrad:
  - Switched to transaction-based ptimer API.
  - Added the DP_INT_VBLNK_START macro.
Signed-off-by: Frederic Konrad 
---
 hw/display/xlnx_dp.c | 27 ---
 include/hw/display/xlnx_dp.h |  3 +++
 2 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/hw/display/xlnx_dp.c b/hw/display/xlnx_dp.c
index 0378570459..2686ca0f2e 100644
--- a/hw/display/xlnx_dp.c
+++ b/hw/display/xlnx_dp.c
@@ -114,6 +114,7 @@
 #define DP_TX_N_AUD (0x032C >> 2)
 #define DP_TX_AUDIO_EXT_DATA(n) ((0x0330 + 4 * n) >> 2)
 #define DP_INT_STATUS   (0x03A0 >> 2)
+#define DP_INT_VBLNK_START  (1 << 13)
 #define DP_INT_MASK (0x03A4 >> 2)
 #define DP_INT_EN   (0x03A8 >> 2)
 #define DP_INT_DS   (0x03AC >> 2)
@@ -274,6 +275,10 @@ static const VMStateDescription vmstate_dp = {
 }
 };
 
+#define DP_VBLANK_PTIMER_POLICY (PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD | \
+ PTIMER_POLICY_CONTINUOUS_TRIGGER |\
+ PTIMER_POLICY_NO_IMMEDIATE_TRIGGER)
+
 static void xlnx_dp_update_irq(XlnxDPState *s);
 
 static uint64_t xlnx_dp_audio_read(void *opaque, hwaddr offset, unsigned size)
@@ -773,6 +778,13 @@ static void xlnx_dp_write(void *opaque, hwaddr offset, 
uint64_t value,
 break;
 case DP_TRANSMITTER_ENABLE:
 s->core_registers[offset] = value & 0x01;
+ptimer_transaction_begin(s->vblank);
+if (value & 0x1) {
+ptimer_run(s->vblank, 0);
+} else {
+ptimer_stop(s->vblank);
+}
+ptimer_transaction_commit(s->vblank);
 break;
 case DP_FORCE_SCRAMBLER_RESET:
 /*
@@ -1177,9 +1189,6 @@ static void xlnx_dp_update_display(void *opaque)
 return;
 }
 
-s->core_registers[DP_INT_STATUS] |= (1 << 13);
-xlnx_dp_update_irq(s);
-
 xlnx_dpdma_trigger_vsync_irq(s->dpdma);
 
 /*
@@ -1275,6 +1284,14 @@ static void xlnx_dp_finalize(Object *obj)
 fifo8_destroy(>rx_fifo);
 }
 
+static void vblank_hit(void *opaque)
+{
+XlnxDPState *s = XLNX_DP(opaque);
+
+s->core_registers[DP_INT_STATUS] |= DP_INT_VBLNK_START;
+xlnx_dp_update_irq(s);
+}
+
 static void xlnx_dp_realize(DeviceState *dev, Error **errp)
 {
 XlnxDPState *s = XLNX_DP(dev);
@@ -1309,6 +1326,10 @@ static void xlnx_dp_realize(DeviceState *dev, Error 
**errp)
);
 AUD_set_volume_out(s->amixer_output_stream, 0, 255, 255);
 xlnx_dp_audio_activate(s);
+s->vblank = ptimer_init(vblank_hit, s, DP_VBLANK_PTIMER_POLICY);
+ptimer_transaction_begin(s->vblank);
+ptimer_set_freq(s->vblank, 30);
+ptimer_transaction_commit(s->vblank);
 }
 
 static void xlnx_dp_reset(DeviceState *dev)
diff --git a/include/hw/display/xlnx_dp.h b/include/hw/display/xlnx_dp.h
index 1ef5a89ee7..e86a87f235 100644
--- a/include/hw/display/xlnx_dp.h
+++ b/include/hw/display/xlnx_dp.h
@@ -35,6 +35,7 @@
 #include "hw/dma/xlnx_dpdma.h"
 #include "audio/audio.h"
 #include "qom/object.h"
+#include "hw/ptimer.h"
 
 #define AUD_CHBUF_MAX_DEPTH (32 * KiB)
 #define MAX_QEMU_BUFFER_SIZE(4 * KiB)
@@ -107,6 +108,8 @@ struct XlnxDPState {
  */
 DPCDState *dpcd;
 I2CDDCState *edid;
+
+ptimer_state *vblank;
 };
 
 #define TYPE_XLNX_DP "xlnx.v-dp"
-- 
2.25.1




[PATCH v2 0/4] xlnx-zcu102: fix the display port.

2022-05-19 Thread Frederic Konrad via
Hi,

This patch set fixes some issues with the DisplayPort for the ZCU102:

The first patch fixes the wrong register size and thus the risk of register
overflow.

The three other one add a vblank interrupt required by the linux driver:
  - When using the VNC graphic backend and leaving it unconnected, in the best
case the gfx_update callback is called once every 3000ms which is
insufficient for the driver.  This is fixed by providing a VBLANK interrupt
from a ptimer.
  - This requirement revealed two issues with the IRQ numbers and the
interrupt disable logic fixed by the two last patches.

Tested by booting Petalinux with the framebuffer enabled.

Best Regards,
Fred

v1 -> v2:
  * Better use of the ptimer API by using a correct POLICY as suggested
by Peter Maydell (Patch 2).
  * Rebased on 78ac2eeb.

Frederic Konrad (2):
  xlnx_dp: fix the wrong register size
  xlnx-zynqmp: fix the irq mapping for the display port and its dma

Sai Pavan Boddu (2):
  xlnx_dp: Introduce a vblank signal
  xlnx_dp: Fix the interrupt disable logic

 hw/arm/xlnx-zynqmp.c |  4 ++--
 hw/display/xlnx_dp.c | 46 +++-
 include/hw/display/xlnx_dp.h | 12 --
 3 files changed, 47 insertions(+), 15 deletions(-)

-- 
2.25.1




[PATCH v2 3/4] xlnx_dp: Fix the interrupt disable logic

2022-05-19 Thread Frederic Konrad via
From: Sai Pavan Boddu 

Fix interrupt disable logic. Mask value 1 indicates that interrupts are
disabled.

Signed-off-by: Sai Pavan Boddu 
Reviewed-by: Edgar E. Iglesias 
Signed-off-by: Frederic Konrad 
---
 hw/display/xlnx_dp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/display/xlnx_dp.c b/hw/display/xlnx_dp.c
index 2686ca0f2e..48c0a8a661 100644
--- a/hw/display/xlnx_dp.c
+++ b/hw/display/xlnx_dp.c
@@ -888,7 +888,7 @@ static void xlnx_dp_write(void *opaque, hwaddr offset, 
uint64_t value,
 xlnx_dp_update_irq(s);
 break;
 case DP_INT_DS:
-s->core_registers[DP_INT_MASK] |= ~value;
+s->core_registers[DP_INT_MASK] |= value;
 xlnx_dp_update_irq(s);
 break;
 default:
-- 
2.25.1




[PATCH v2 4/4] xlnx-zynqmp: fix the irq mapping for the display port and its dma

2022-05-19 Thread Frederic Konrad via
When the display port has been initially implemented the device driver wasn't
using interrupts.  Now that the display port driver waits for vblank interrupt
it has been noticed that the irq mapping is wrong.  So use the value from the
linux device tree and the ultrascale+ reference manual.

Signed-off-by: Frederic Konrad 
Reviewed-by: Edgar E. Iglesias 
---
 hw/arm/xlnx-zynqmp.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
index 375309e68e..383e177a00 100644
--- a/hw/arm/xlnx-zynqmp.c
+++ b/hw/arm/xlnx-zynqmp.c
@@ -60,10 +60,10 @@
 #define SERDES_SIZE 0x2
 
 #define DP_ADDR 0xfd4a
-#define DP_IRQ  113
+#define DP_IRQ  0x77
 
 #define DPDMA_ADDR  0xfd4c
-#define DPDMA_IRQ   116
+#define DPDMA_IRQ   0x7a
 
 #define APU_ADDR0xfd5c
 #define APU_IRQ 153
-- 
2.25.1




RE: [PATCH v1 2/4] xlnx_dp: Introduce a vblank signal

2022-05-16 Thread Frederic Konrad


> -Original Message-
> From: Peter Maydell 
> Sent: 16 May 2022 10:57
> To: Frederic Konrad 
> Cc: qemu-devel@nongnu.org; alist...@alistair23.me;
> edgar.igles...@gmail.com; qemu-...@nongnu.org; Sai Pavan Boddu
> ; Edgar Iglesias ;
> fkon...@amd.com; Sai Pavan Boddu ; Edgar Iglesias
> 
> Subject: Re: [PATCH v1 2/4] xlnx_dp: Introduce a vblank signal
> 
> On Tue, 3 May 2022 at 16:27,  wrote:
> >
> > From: Sai Pavan Boddu 
> >
> > Add a periodic timer which raises vblank at a frequency of 30Hz.
> >
> > Signed-off-by: Sai Pavan Boddu 
> > Signed-off-by: Edgar E. Iglesias 
> > Changes by fkonrad:
> >   - Switched to transaction-based ptimer API.
> >   - Added the DP_INT_VBLNK_START macro.
> > Signed-off-by: Frederic Konrad 
> > ---
> 
> 
> > @@ -1309,6 +1323,10 @@ static void xlnx_dp_realize(DeviceState *dev,
> Error **errp)
> > );
> >  AUD_set_volume_out(s->amixer_output_stream, 0, 255, 255);
> >  xlnx_dp_audio_activate(s);
> > +s->vblank = ptimer_init(vblank_hit, s, PTIMER_POLICY_DEFAULT);
> > +ptimer_transaction_begin(s->vblank);
> > +ptimer_set_freq(s->vblank, 30);
> > +ptimer_transaction_commit(s->vblank);
> 
> The ptimer documentation (in include/hw/ptimer.h) says
>  * The default ptimer policy retains backward compatibility with the legacy
>  * timers. Custom policies are adjusting the default one. Consider providing
>  * a correct policy for your timer.
> 
> and goes on to describe various weird behaviours of the default
> policy. You almost certainly don't want to use PTIMER_POLICY_DEFAULT
> for a new timer -- instead figure out the behaviour you actually
> want and specify the appropriate flags.

Hi Peter,

Thanks for your feedback.

Yes, I think, I can just use CONTINUOUS_TRIGGER and NO_IMMEDIATE_TRIGGER
instead of forcing the decrementer / reload value to 1.  Would that be cleaner?

Thanks,
Fred

> 
> thanks
> -- PMM


RE: [PATCH v1 0/4] xlnx-zcu102: fix the display port.

2022-05-13 Thread Frederic Konrad
Ping

Can this be applied?  Here is the patchew link:
https://patchew.org/QEMU/20220503152545.1100386-1-fkon...@xilinx.com/

Best Regards,
Fred

> -Original Message-
> From: frederic.kon...@xilinx.com 
> Sent: 03 May 2022 16:26
> To: qemu-devel@nongnu.org
> Cc: alist...@alistair23.me; edgar.igles...@gmail.com;
> peter.mayd...@linaro.org; qemu-...@nongnu.org; Sai Pavan Boddu
> ; Edgar Iglesias ;
> fkon...@amd.com
> Subject: [PATCH v1 0/4] xlnx-zcu102: fix the display port.
> 
> From: Frederic Konrad 
> 
> Hi,
> 
> This patch set fixes some issues with the DisplayPort for the ZCU102:
> 
> The first patch fixes the wrong register size and thus the risk of register
> overflow.
> 
> The three other one add a vblank interrupt required by the linux driver:
>   - When using the VNC graphic backend and leaving it unconnected, in the
> best
> case the gfx_update callback is called once every 3000ms which is
> insufficient for the driver.  This is fixed by providing a VBLANK 
> interrupt
> from a ptimer.
>   - This requirement revealed two issues with the IRQ numbers and the
> interrupt disable logic fixed by the two last patches.
> 
> Tested by booting Petalinux with the framebuffer enabled.
> 
> Best Regards,
> Fred
> 
> Frederic Konrad (2):
>   xlnx_dp: fix the wrong register size
>   xlnx-zynqmp: fix the irq mapping for the display port and its dma
> 
> Sai Pavan Boddu (2):
>   xlnx_dp: Introduce a vblank signal
>   xlnx_dp: Fix the interrupt disable logic
> 
>  hw/arm/xlnx-zynqmp.c |  4 ++--
>  hw/display/xlnx_dp.c | 43 +++-
>  include/hw/display/xlnx_dp.h | 12 --
>  3 files changed, 44 insertions(+), 15 deletions(-)
> 
> --
> 2.25.1




RE: [PATCH v1 4/4] hw/arm: versal: Connect the CRL

2022-04-07 Thread Frederic Konrad



> -Original Message-
> From: Edgar E. Iglesias 
> Sent: 06 April 2022 18:43
> To: qemu-devel@nongnu.org
> Cc: qemu-...@nongnu.org; peter.mayd...@linaro.org;
> richard.hender...@linaro.org; alist...@alistair23.me; l...@lmichel.fr;
> f4...@amsat.org; frasse.igles...@gmail.com; Francisco Eduardo Iglesias
> ; Sai Pavan Boddu ; Frederic
> Konrad ; Edgar Iglesias ;
> edgar.igles...@amd.com
> Subject: [PATCH v1 4/4] hw/arm: versal: Connect the CRL
> 
> From: "Edgar E. Iglesias" 
> 
> Connect the CRL (Clock Reset LPD) to the Versal SoC.
> 
> Signed-off-by: Edgar E. Iglesias 
> ---
>  hw/arm/xlnx-versal.c | 54 ++--
>  include/hw/arm/xlnx-versal.h |  4 +++
>  2 files changed, 56 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
> index ebad8dbb6d..57276e1506 100644
> --- a/hw/arm/xlnx-versal.c
> +++ b/hw/arm/xlnx-versal.c
> @@ -539,6 +539,57 @@ static void versal_create_ospi(Versal *s, qemu_irq
> *pic)
>  qdev_connect_gpio_out(orgate, 0, pic[VERSAL_OSPI_IRQ]);
>  }
> 
> +static void versal_create_crl(Versal *s, qemu_irq *pic)
> +{
> +SysBusDevice *sbd;
> +int i;
> +
> +object_initialize_child(OBJECT(s), "crl", >lpd.crl,
> +TYPE_XLNX_VERSAL_CRL);
> +sbd = SYS_BUS_DEVICE(>lpd.crl);
> +
> +for (i = 0; i < ARRAY_SIZE(s->lpd.rpu.cpu); i++) {
> +g_autofree gchar *name = g_strdup_printf("cpu_r5[%d]", i);
> +
> +object_property_set_link(OBJECT(>lpd.crl),
> + name, OBJECT(>lpd.rpu.cpu[i]),
> + _abort);
> +}
> +
> +for (i = 0; i < ARRAY_SIZE(s->lpd.iou.gem); i++) {
> +g_autofree gchar *name = g_strdup_printf("gem[%d]", i);
> +
> +object_property_set_link(OBJECT(>lpd.crl),
> + name, OBJECT(>lpd.iou.gem[i]),
> + _abort);
> +}
> +
> +for (i = 0; i < ARRAY_SIZE(s->lpd.iou.adma); i++) {
> +g_autofree gchar *name = g_strdup_printf("adma[%d]", i);
> +
> +object_property_set_link(OBJECT(>lpd.crl),
> + name, OBJECT(>lpd.iou.adma[i]),
> + _abort);
> +}
> +
> +for (i = 0; i < ARRAY_SIZE(s->lpd.iou.uart); i++) {
> +g_autofree gchar *name = g_strdup_printf("uart[%d]", i);
> +
> +object_property_set_link(OBJECT(>lpd.crl),
> + name, OBJECT(>lpd.iou.uart[i]),
> + _abort);
> +}
> +
> +object_property_set_link(OBJECT(>lpd.crl),
> + "usb", OBJECT(>lpd.iou.usb),
> + _abort);
> +
> +sysbus_realize(sbd, _fatal);
> +memory_region_add_subregion(>mr_ps, MM_CRL,
> +sysbus_mmio_get_region(sbd, 0));
> +sysbus_connect_irq(sbd, 0, pic[VERSAL_CRL_IRQ]);
> +}
> +
>  /* This takes the board allocated linear DDR memory and creates aliases
>   * for each split DDR range/aperture on the Versal address map.
>   */
> @@ -622,8 +673,6 @@ static void versal_unimp(Versal *s)
> 
>  versal_unimp_area(s, "psm", >mr_ps,
>  MM_PSM_START, MM_PSM_END - MM_PSM_START);
> -versal_unimp_area(s, "crl", >mr_ps,
> -MM_CRL, MM_CRL_SIZE);
>  versal_unimp_area(s, "crf", >mr_ps,
>  MM_FPD_CRF, MM_FPD_CRF_SIZE);
>  versal_unimp_area(s, "apu", >mr_ps,
> @@ -681,6 +730,7 @@ static void versal_realize(DeviceState *dev, Error
> **errp)
>  versal_create_efuse(s, pic);
>  versal_create_pmc_iou_slcr(s, pic);
>  versal_create_ospi(s, pic);
> +versal_create_crl(s, pic);
>  versal_map_ddr(s);
>  versal_unimp(s);
> 
> diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
> index 155e8c4b8c..cbe8a19c10 100644
> --- a/include/hw/arm/xlnx-versal.h
> +++ b/include/hw/arm/xlnx-versal.h
> @@ -29,6 +29,7 @@
>  #include "hw/nvram/xlnx-versal-efuse.h"
>  #include "hw/ssi/xlnx-versal-ospi.h"
>  #include "hw/dma/xlnx_csu_dma.h"
> +#include "hw/misc/xlnx-versal-crl.h"
>  #include "hw/misc/xlnx-versal-pmc-iou-slcr.h"
> 
>  #define TYPE_XLNX_VERSAL "xlnx-versal"
> @@ -87,6 +88,8 @@ struct Versal {
>  qemu_or_irq irq_orgate;
>  XlnxXramCtrl ctrl[XLNX_VERSAL_NR_XRAM];
>  } xram;
> +
> +XlnxVersalCRL crl;
>  } lpd;
> 
>  /* The Platform Management Controller subsystem.  */
> @@ -127,6 +130,7 @@ struct Versal {
>  #define VERSAL_TIMER_NS_EL1_IRQ 14
>  #define VERSAL_TIMER_NS_EL2_IRQ 10
> 
> +#define VERSAL_CRL_IRQ 10
>  #define VERSAL_UART0_IRQ_0 18
>  #define VERSAL_UART1_IRQ_0 19
>  #define VERSAL_USB0_IRQ_0  22
> --
> 2.25.1

Reviewed-by: Frederic Konrad 




RE: [PATCH v1 3/4] hw/misc: Add a model of the Xilinx Versal CRL

2022-04-07 Thread Frederic Konrad



> -Original Message-
> From: Edgar E. Iglesias 
> Sent: 06 April 2022 18:43
> To: qemu-devel@nongnu.org
> Cc: qemu-...@nongnu.org; peter.mayd...@linaro.org;
> richard.hender...@linaro.org; alist...@alistair23.me; l...@lmichel.fr;
> f4...@amsat.org; frasse.igles...@gmail.com; Francisco Eduardo Iglesias
> ; Sai Pavan Boddu ; Frederic
> Konrad ; Edgar Iglesias ;
> edgar.igles...@amd.com
> Subject: [PATCH v1 3/4] hw/misc: Add a model of the Xilinx Versal CRL
> 
> From: "Edgar E. Iglesias" 
> 
> Add a model of the Xilinx Versal CRL.
> 
> Signed-off-by: Edgar E. Iglesias 
> ---
>  hw/misc/meson.build   |   1 +
>  hw/misc/xlnx-versal-crl.c | 421 ++
>  include/hw/misc/xlnx-versal-crl.h | 235 +
>  3 files changed, 657 insertions(+)
>  create mode 100644 hw/misc/xlnx-versal-crl.c
>  create mode 100644 include/hw/misc/xlnx-versal-crl.h
> 
> diff --git a/hw/misc/meson.build b/hw/misc/meson.build
> index 6fb69612e0..2ff05c7afa 100644
> --- a/hw/misc/meson.build
> +++ b/hw/misc/meson.build
> @@ -86,6 +86,7 @@ softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true:
> files('slavio_misc.c'))
>  softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c'))
>  specific_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-
> zynqmp-crf.c'))
>  specific_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-
> zynqmp-apu-ctrl.c'))
> +specific_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-
> crl.c'))
>  softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files(
>'xlnx-versal-xramc.c',
>'xlnx-versal-pmc-iou-slcr.c',
> diff --git a/hw/misc/xlnx-versal-crl.c b/hw/misc/xlnx-versal-crl.c
> new file mode 100644
> index 00..767106b7a3
> --- /dev/null
> +++ b/hw/misc/xlnx-versal-crl.c
> @@ -0,0 +1,421 @@
> +/*
> + * QEMU model of the Clock-Reset-LPD (CRL).
> + *
> + * Copyright (c) 2022 Advanced Micro Devices, Inc.
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + *
> + * Written by Edgar E. Iglesias 
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qapi/error.h"
> +#include "qemu/log.h"
> +#include "qemu/bitops.h"
> +#include "migration/vmstate.h"
> +#include "hw/qdev-properties.h"
> +#include "hw/sysbus.h"
> +#include "hw/irq.h"
> +#include "hw/register.h"
> +#include "hw/resettable.h"
> +
> +#include "target/arm/arm-powerctl.h"
> +#include "hw/misc/xlnx-versal-crl.h"
> +
> +#ifndef XLNX_VERSAL_CRL_ERR_DEBUG
> +#define XLNX_VERSAL_CRL_ERR_DEBUG 0
> +#endif
> +
> +static void crl_update_irq(XlnxVersalCRL *s)
> +{
> +bool pending = s->regs[R_IR_STATUS] & ~s->regs[R_IR_MASK];
> +qemu_set_irq(s->irq, pending);
> +}
> +
> +static void crl_status_postw(RegisterInfo *reg, uint64_t val64)
> +{
> +XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
> +crl_update_irq(s);
> +}
> +
> +static uint64_t crl_enable_prew(RegisterInfo *reg, uint64_t val64)
> +{
> +XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
> +uint32_t val = val64;
> +
> +s->regs[R_IR_MASK] &= ~val;
> +crl_update_irq(s);
> +return 0;
> +}
> +
> +static uint64_t crl_disable_prew(RegisterInfo *reg, uint64_t val64)
> +{
> +XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
> +uint32_t val = val64;
> +
> +s->regs[R_IR_MASK] |= val;
> +crl_update_irq(s);
> +return 0;
> +}
> +
> +static void crl_reset_dev(XlnxVersalCRL *s, DeviceState *dev,
> +  bool rst_old, bool rst_new)
> +{
> +device_cold_reset(dev);
> +}
> +
> +static void crl_reset_cpu(XlnxVersalCRL *s, ARMCPU *armcpu,
> +  bool rst_old, bool rst_new)
> +{
> +if (rst_new) {
> +arm_set_cpu_off(armcpu->mp_affinity);
> +} else {
> +arm_set_cpu_on_and_reset(armcpu->mp_affinity);
> +}
> +}
> +
> +#define REGFIELD_RESET(type, s, reg, f, new_val, dev) { \
> +bool old_f = ARRAY_FIELD_EX32((s)->regs, reg, f);   \
> +bool new_f = FIELD_EX32(new_val, reg, f);   \
> +\
> +/* Detect edges.  */\
> +if (dev && old_f != new_f) {\
> +crl_reset_ ## type(s, dev, old_f, new_f);   \
> +}   \
> +}
> +
> +static uint64_t crl_rst_r5_prew(RegisterInfo *reg, uint64_t val64)
> +{
> +XlnxVersa

RE: [PATCH v1 2/4] hw/arm: versal: Add the Cortex-R5Fs

2022-04-07 Thread Frederic Konrad



-Original Message-
From: Edgar E. Iglesias  
Sent: 06 April 2022 18:43
To: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org; peter.mayd...@linaro.org; 
richard.hender...@linaro.org; alist...@alistair23.me; l...@lmichel.fr; 
f4...@amsat.org; frasse.igles...@gmail.com; Francisco Eduardo Iglesias 
; Sai Pavan Boddu ; Frederic Konrad 
; Edgar Iglesias ; edgar.igles...@amd.com
Subject: [PATCH v1 2/4] hw/arm: versal: Add the Cortex-R5Fs

From: "Edgar E. Iglesias" 

Add the Cortex-R5Fs of the Versal RPU (Real-time Processing Unit) subsystem.

Signed-off-by: Edgar E. Iglesias 
---
 hw/arm/xlnx-versal-virt.c|  6 +++---
 hw/arm/xlnx-versal.c | 36 
 include/hw/arm/xlnx-versal.h | 10 ++
 3 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c index 
7c7baff8b7..66a2de7e13 100644
--- a/hw/arm/xlnx-versal-virt.c
+++ b/hw/arm/xlnx-versal-virt.c
@@ -721,9 +721,9 @@ static void versal_virt_machine_class_init(ObjectClass *oc, 
void *data)
 
 mc->desc = "Xilinx Versal Virtual development board";
 mc->init = versal_virt_init;
-mc->min_cpus = XLNX_VERSAL_NR_ACPUS;
-mc->max_cpus = XLNX_VERSAL_NR_ACPUS;
-mc->default_cpus = XLNX_VERSAL_NR_ACPUS;
+mc->min_cpus = XLNX_VERSAL_NR_ACPUS + XLNX_VERSAL_NR_RCPUS;
+mc->max_cpus = XLNX_VERSAL_NR_ACPUS + XLNX_VERSAL_NR_RCPUS;
+mc->default_cpus = XLNX_VERSAL_NR_ACPUS + XLNX_VERSAL_NR_RCPUS;
 mc->no_cdrom = true;
 mc->default_ram_id = "ddr";
 }
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c index 
4415ee413f..ebad8dbb6d 100644
--- a/hw/arm/xlnx-versal.c
+++ b/hw/arm/xlnx-versal.c
@@ -25,6 +25,7 @@
 #include "hw/sysbus.h"
 
 #define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
+#define XLNX_VERSAL_RCPU_TYPE ARM_CPU_TYPE_NAME("cortex-r5f")
 #define GEM_REVISION0x40070106
 
 #define VERSAL_NUM_PMC_APB_IRQS 3
@@ -130,6 +131,35 @@ static void versal_create_apu_gic(Versal *s, qemu_irq *pic)
 }
 }
 
+static void versal_create_rpu_cpus(Versal *s) {
+int i;
+
+object_initialize_child(OBJECT(s), "rpu-cluster", >lpd.rpu.cluster,
+TYPE_CPU_CLUSTER);
+qdev_prop_set_uint32(DEVICE(>lpd.rpu.cluster), "cluster-id", 1);
+
+for (i = 0; i < ARRAY_SIZE(s->lpd.rpu.cpu); i++) {
+Object *obj;
+
+object_initialize_child(OBJECT(>lpd.rpu.cluster),
+"rpu-cpu[*]", >lpd.rpu.cpu[i],
+XLNX_VERSAL_RCPU_TYPE);
+obj = OBJECT(>lpd.rpu.cpu[i]);
+object_property_set_bool(obj, "start-powered-off", true,
+ _abort);
+
+object_property_set_int(obj, "mp-affinity", 0x100 | i, _abort);
+object_property_set_int(obj, "core-count", ARRAY_SIZE(s->lpd.rpu.cpu),
+_abort);
+object_property_set_link(obj, "memory", OBJECT(>lpd.rpu.mr),
+ _abort);
+qdev_realize(DEVICE(obj), NULL, _fatal);
+}
+
+qdev_realize(DEVICE(>lpd.rpu.cluster), NULL, _fatal); }
+
 static void versal_create_uarts(Versal *s, qemu_irq *pic)  {
 int i;
@@ -638,6 +668,7 @@ static void versal_realize(DeviceState *dev, Error **errp)
 
 versal_create_apu_cpus(s);
 versal_create_apu_gic(s, pic);
+versal_create_rpu_cpus(s);
 versal_create_uarts(s, pic);
 versal_create_usbs(s, pic);
 versal_create_gems(s, pic);
@@ -659,6 +690,8 @@ static void versal_realize(DeviceState *dev, Error **errp)
 
 memory_region_add_subregion_overlap(>mr_ps, MM_OCM, >lpd.mr_ocm, 0);
 memory_region_add_subregion_overlap(>fpd.apu.mr, 0, >mr_ps, 0);
+memory_region_add_subregion_overlap(>lpd.rpu.mr, 0,
+>lpd.rpu.mr_ps_alias, 0);
 }
 
 static void versal_init(Object *obj)
@@ -666,7 +699,10 @@ static void versal_init(Object *obj)
 Versal *s = XLNX_VERSAL(obj);
 
 memory_region_init(>fpd.apu.mr, obj, "mr-apu", UINT64_MAX);
+memory_region_init(>lpd.rpu.mr, obj, "mr-rpu", UINT64_MAX);
 memory_region_init(>mr_ps, obj, "mr-ps-switch", UINT64_MAX);
+memory_region_init_alias(>lpd.rpu.mr_ps_alias, OBJECT(s),
+ "mr-rpu-ps-alias", >mr_ps, 0, 
+ UINT64_MAX);
 }
 
 static Property versal_properties[] = { diff --git 
a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h index 
d2d3028e18..155e8c4b8c 100644
--- a/include/hw/arm/xlnx-versal.h
+++ b/include/hw/arm/xlnx-versal.h
@@ -35,6 +35,7 @@
 OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
 
 #define XLNX_VERSAL_NR_ACPUS   2
+#define XLNX_VERSAL_NR_RCPUS   2
 #define XLNX_VERSAL_NR_UARTS   2
 #define XLNX_V

RE: [PATCH v1 1/4] hw/arm: versal: Create an APU CPU Cluster

2022-04-07 Thread Frederic Konrad



-Original Message-
From: Edgar E. Iglesias  
Sent: 06 April 2022 18:43
To: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org; peter.mayd...@linaro.org; 
richard.hender...@linaro.org; alist...@alistair23.me; l...@lmichel.fr; 
f4...@amsat.org; frasse.igles...@gmail.com; Francisco Eduardo Iglesias 
; Sai Pavan Boddu ; Frederic Konrad 
; Edgar Iglesias ; edgar.igles...@amd.com
Subject: [PATCH v1 1/4] hw/arm: versal: Create an APU CPU Cluster

From: "Edgar E. Iglesias" 

Create an APU CPU Cluster. This is in preparation to add the RPU.

Signed-off-by: Edgar E. Iglesias 
---
 hw/arm/xlnx-versal.c | 9 -
 include/hw/arm/xlnx-versal.h | 2 ++
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c index 
2551dfc22d..4415ee413f 100644
--- a/hw/arm/xlnx-versal.c
+++ b/hw/arm/xlnx-versal.c
@@ -34,10 +34,15 @@ static void versal_create_apu_cpus(Versal *s)  {
 int i;
 
+object_initialize_child(OBJECT(s), "apu-cluster", >fpd.apu.cluster,
+TYPE_CPU_CLUSTER);
+qdev_prop_set_uint32(DEVICE(>fpd.apu.cluster), "cluster-id", 0);
+
 for (i = 0; i < ARRAY_SIZE(s->fpd.apu.cpu); i++) {
 Object *obj;
 
-object_initialize_child(OBJECT(s), "apu-cpu[*]", >fpd.apu.cpu[i],
+object_initialize_child(OBJECT(>fpd.apu.cluster),
+"apu-cpu[*]", >fpd.apu.cpu[i],
 XLNX_VERSAL_ACPU_TYPE);
 obj = OBJECT(>fpd.apu.cpu[i]);
 if (i) {
@@ -52,6 +57,8 @@ static void versal_create_apu_cpus(Versal *s)
  _abort);
 qdev_realize(DEVICE(obj), NULL, _fatal);
 }
+
+qdev_realize(DEVICE(>fpd.apu.cluster), NULL, _fatal);
 }
 
 static void versal_create_apu_gic(Versal *s, qemu_irq *pic) diff --git 
a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h index 
0728316ec7..d2d3028e18 100644
--- a/include/hw/arm/xlnx-versal.h
+++ b/include/hw/arm/xlnx-versal.h
@@ -14,6 +14,7 @@
 
 #include "hw/sysbus.h"
 #include "hw/arm/boot.h"
+#include "hw/cpu/cluster.h"
 #include "hw/or-irq.h"
 #include "hw/sd/sdhci.h"
 #include "hw/intc/arm_gicv3.h"
@@ -49,6 +50,7 @@ struct Versal {
 struct {
 struct {
 MemoryRegion mr;
+CPUClusterState cluster;
 ARMCPU cpu[XLNX_VERSAL_NR_ACPUS];
 GICv3State gic;
 } apu;
--
2.25.1

Reviewed-by: Frederic Konrad 



Re: [Qemu-devel] [PULL 28/30] introduce xlnx-dp

2022-04-07 Thread Frederic Konrad




Le 4/7/22 à 12:32, Peter Maydell a écrit :

On Tue, 14 Jun 2016 at 15:40, Peter Maydell  wrote:


From: KONRAD Frederic 

This is the implementation of the DisplayPort.
It has an aux-bus to access dpcd and edid.

Graphic plane is connected to the channel 3.
Video plane is connected to the channel 0.
Audio stream are connected to the channels 4 and 5.


Very old patch, but Coverity has just pointed out an array
overrun in it (CID 1487260):

We define a set of offsets for V_BLEND registers, of which
the largest is this one:


+#define V_BLEND_CHROMA_KEY_COMP3(0x01DC >> 2)



+static void xlnx_dp_vblend_write(void *opaque, hwaddr offset,
+ uint64_t value, unsigned size)
+{
+XlnxDPState *s = XLNX_DP(opaque);
+bool alpha_was_enabled;
+
+DPRINTF("vblend: write @0x%" HWADDR_PRIX " = 0x%" PRIX32 "\n", offset,
+   
(uint32_t)value);
+offset = offset >> 2;
+
+switch (offset) {



+case V_BLEND_CHROMA_KEY_COMP1:
+case V_BLEND_CHROMA_KEY_COMP2:
+case V_BLEND_CHROMA_KEY_COMP3:
+s->vblend_registers[offset] = value & 0x0FFF0FFF;


We use V_BLEND_CHROMA_KEY_COMP3 as an index into the vblend_registers array...


+break;
+default:
+s->vblend_registers[offset] = value;
+break;
+}
+}



+#define DP_CORE_REG_ARRAY_SIZE  (0x3AF >> 2)
+#define DP_AVBUF_REG_ARRAY_SIZE (0x238 >> 2)
+#define DP_VBLEND_REG_ARRAY_SIZE(0x1DF >> 2)
+#define DP_AUDIO_REG_ARRAY_SIZE (0x50 >> 2)



+uint32_t vblend_registers[DP_VBLEND_REG_ARRAY_SIZE];


..but we have defined DP_VBLEND_REG_ARRAY_SIZE to 0x1DF >> 2,
which is the same as 0x1DC >> 2, and so the array size is too small.

The size of the memory region is also suspicious:

+memory_region_init_io(>vblend_iomem, obj, _ops, s, TYPE_XLNX_DP
+  ".v_blend", 0x1DF);

This is a "32-bit accesses only" region, but we have defined it with a
size that is not a multiple of 4. That looks wrong... (It also means
that rather than having an array overrun I think the actual effect
is that the guest won't be able to access the last register, because
it's not entirely within the memoryregion.)


arg, sorry for that..

I share your point, it should not be possible to access it, but using
the monitor:

(qemu) info mtree
...
fd4aa000-fd4aa1de (prio 0, i/o): xlnx.v-dp.v_blend
...

I can actually read that register (at least it doesn't complain, on an
older qemu version though):
(qemu) xp /w 0xfd4aa1dc
fd4aa1dc: 0x

So I'm not totally sure.. do you need a patch for 7.0.0?



Coverity doesn't complain about it, but the DP_CORE_REG_ARRAY_SIZE
may also have a similar problem.


I think it doesn't complain because writing to the last register doesn't
actually write into the array but update the mask register instead:

case DP_INT_DS:
s->core_registers[DP_INT_MASK] |= ~value;
xlnx_dp_update_irq(s);
break;



thanks
-- PMM


Best Regards,
Fred



[PATCH] MAINTAINERS: change Fred Konrad's email address

2022-03-30 Thread Frederic Konrad
frederic.kon...@adacore.com and kon...@adacore.com will stop working starting
2022-04-01.

Use my personal email instead.

Signed-off-by: Frederic Konrad 
---
 .mailmap| 3 ++-
 MAINTAINERS | 2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/.mailmap b/.mailmap
index 09dcd8c216..2976a675ea 100644
--- a/.mailmap
+++ b/.mailmap
@@ -56,7 +56,8 @@ Alexander Graf  
 Anthony Liguori  Anthony Liguori 
 Christian Borntraeger  
 Filip Bozuta  
-Frederic Konrad  
+Frederic Konrad  
+Frederic Konrad  
 Greg Kurz  
 Huacai Chen  
 Huacai Chen  
diff --git a/MAINTAINERS b/MAINTAINERS
index cc364afef7..68142340bd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1533,7 +1533,7 @@ F: include/hw/rtc/sun4v-rtc.h
 
 Leon3
 M: Fabien Chouteau 
-M: KONRAD Frederic 
+M: Frederic Konrad 
 S: Maintained
 F: hw/sparc/leon3.c
 F: hw/*/grlib*
-- 
2.30.1




[PATCH] hw/avr/atmega.c: use the avr51 cpu for atmega1280

2021-04-28 Thread Frederic Konrad
According to the as documentation:
 (https://sourceware.org/binutils/docs-2.36/as/AVR-Options.html)

"Instruction set avr51 is for the enhanced AVR core with exactly 128K
 program memory space (MCU types: atmega128, atmega128a, atmega1280,
 atmega1281, atmega1284, atmega1284p, atmega128rfa1, atmega128rfr2,
 atmega1284rfr2, at90can128, at90usb1286, at90usb1287, m3000)."

But when compiling a program for atmega1280 or avr51 and trying to execute
it:

$ cat > test.S << EOF
> loop:
> rjmp loop
> EOF
$ avr-gcc -nostdlib -nostartfiles -mmcu=atmega1280 test.S -o test.elf
$ qemu-system-avr -serial mon:stdio -nographic -no-reboot -M mega \
  -bios test.elf
qemu-system-avr: Current machine: Arduino Mega (ATmega1280) with 'avr6' CPU
qemu-system-avr: ELF image 'test.elf' is for 'avr51' CPU

So this fixes the atmega1280 class to use an avr51 CPU.

Signed-off-by: Frederic Konrad 
---
 hw/avr/atmega.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/avr/atmega.c b/hw/avr/atmega.c
index 44c6afebbb..e3ea5702f5 100644
--- a/hw/avr/atmega.c
+++ b/hw/avr/atmega.c
@@ -402,7 +402,7 @@ static void atmega1280_class_init(ObjectClass *oc, void 
*data)
 {
 AtmegaMcuClass *amc = ATMEGA_MCU_CLASS(oc);
 
-amc->cpu_type = AVR_CPU_TYPE_NAME("avr6");
+amc->cpu_type = AVR_CPU_TYPE_NAME("avr51");
 amc->flash_size = 128 * KiB;
 amc->eeprom_size = 4 * KiB;
 amc->sram_size = 8 * KiB;
-- 
2.30.1




[PATCH v1] target/m68k: fix gdb for m68xxx

2020-04-20 Thread frederic . konrad
From: KONRAD Frederic 

Currently "cf-core.xml" is sent to GDB when using any m68k flavor.  Thing is
it uses the "org.gnu.gdb.coldfire.core" feature name and gdb 8.3 then expects
a coldfire FPU instead of the default m68881 FPU.

This is not OK because the m68881 floats registers are 96 bits wide so it
crashes GDB with the following error message:

(gdb) target remote localhost:7960
Remote debugging using localhost:7960
warning: Register "fp0" has an unsupported size (96 bits)
warning: Register "fp1" has an unsupported size (96 bits)
...
Remote 'g' packet reply is too long (expected 148 bytes, got 180 bytes):\
  000[...]

With this patch: qemu-system-m68k -M none -cpu m68020 -s -S

(gdb) tar rem :1234
Remote debugging using :1234
warning: No executable has been specified and target does not support
determining executable automatically.  Try using the "file" command.
0x in ?? ()
(gdb) p $fp0
$1 = nan(0x)

Signed-off-by: KONRAD Frederic 
---
 configure |  2 +-
 gdb-xml/m68k-core.xml | 29 +
 target/m68k/cpu.c | 30 +-
 3 files changed, 55 insertions(+), 6 deletions(-)
 create mode 100644 gdb-xml/m68k-core.xml

diff --git a/configure b/configure
index 23b5e93..2b07b85 100755
--- a/configure
+++ b/configure
@@ -7825,7 +7825,7 @@ case "$target_name" in
   ;;
   m68k)
 bflt="yes"
-gdb_xml_files="cf-core.xml cf-fp.xml m68k-fp.xml"
+gdb_xml_files="cf-core.xml cf-fp.xml m68k-core.xml m68k-fp.xml"
 TARGET_SYSTBL_ABI=common
   ;;
   microblaze|microblazeel)
diff --git a/gdb-xml/m68k-core.xml b/gdb-xml/m68k-core.xml
new file mode 100644
index 000..5b092d2
--- /dev/null
+++ b/gdb-xml/m68k-core.xml
@@ -0,0 +1,29 @@
+
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
+  
+  
+
+
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index 9445fcd..976e624 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -297,6 +297,21 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
 dc->vmsd = _m68k_cpu;
 }
 
+static void m68k_cpu_class_init_m68k_core(ObjectClass *c, void *data)
+{
+CPUClass *cc = CPU_CLASS(c);
+
+cc->gdb_core_xml_file = "m68k-core.xml";
+}
+
+#define DEFINE_M68K_CPU_TYPE_WITH_CLASS(cpu_model, initfn, classinit)  \
+{  \
+.name = M68K_CPU_TYPE_NAME(cpu_model), \
+.instance_init = initfn,   \
+.parent = TYPE_M68K_CPU,   \
+.class_init = classinit,   \
+}
+
 #define DEFINE_M68K_CPU_TYPE(cpu_model, initfn) \
 {   \
 .name = M68K_CPU_TYPE_NAME(cpu_model),  \
@@ -314,11 +329,16 @@ static const TypeInfo m68k_cpus_type_infos[] = {
 .class_size = sizeof(M68kCPUClass),
 .class_init = m68k_cpu_class_init,
 },
-DEFINE_M68K_CPU_TYPE("m68000", m68000_cpu_initfn),
-DEFINE_M68K_CPU_TYPE("m68020", m68020_cpu_initfn),
-DEFINE_M68K_CPU_TYPE("m68030", m68030_cpu_initfn),
-DEFINE_M68K_CPU_TYPE("m68040", m68040_cpu_initfn),
-DEFINE_M68K_CPU_TYPE("m68060", m68060_cpu_initfn),
+DEFINE_M68K_CPU_TYPE_WITH_CLASS("m68000", m68000_cpu_initfn,
+m68k_cpu_class_init_m68k_core),
+DEFINE_M68K_CPU_TYPE_WITH_CLASS("m68020", m68020_cpu_initfn,
+m68k_cpu_class_init_m68k_core),
+DEFINE_M68K_CPU_TYPE_WITH_CLASS("m68030", m68030_cpu_initfn,
+m68k_cpu_class_init_m68k_core),
+DEFINE_M68K_CPU_TYPE_WITH_CLASS("m68040", m68040_cpu_initfn,
+m68k_cpu_class_init_m68k_core),
+DEFINE_M68K_CPU_TYPE_WITH_CLASS("m68060", m68060_cpu_initfn,
+m68k_cpu_class_init_m68k_core),
 DEFINE_M68K_CPU_TYPE("m5206", m5206_cpu_initfn),
 DEFINE_M68K_CPU_TYPE("m5208", m5208_cpu_initfn),
 DEFINE_M68K_CPU_TYPE("cfv4e", cfv4e_cpu_initfn),
-- 
1.8.3.1




Re: [Qemu-devel] [PATCH V3 0/7] execute code from mmio area

2017-05-05 Thread Frederic Konrad
Ping!

This is mostly reviewed maybe the 6th patch needs a little look.

Thanks,
Fred

On 04/28/2017 04:59 PM, fred.kon...@greensocs.com wrote:
> From: KONRAD Frederic 
> 
> This series allows to execute code from mmio areas.
> The main goal of this is to be able to run code for example from an SPI 
> device.
> 
> The three first patch fixes the way get_page_addr_code fills the TLB.
> 
> The sixth patch implements the mmio execution helpers: the device must
> implement the request_ptr callback of the MemoryRegion and will be notified
> when the guest wants to execute code from it.
> 
> The fouth and fifth patch introduces mmio_interface device which allows to
> dynamically map a host pointer somewhere into the memory.
> 
> The last patch implements the execution from the SPI memories in the
> xilinx_spips model.
> 
> Thanks,
> Fred
> 
> V2 -> V3:
>   * Reorder patches to allow bisection.
>   * Rebase on current master.
>   * Use an async work to invalidate the mmio region.
>   * Clear the dirty of the region before invalidating it.
> V1 -> V2:
>   * Fix the DPRINTF error.
> RFC -> V1:
>   * Use an interface (mmio-interface) to fix any reference leak issue.
> 
> KONRAD Frederic (7):
>   cputlb: cleanup get_page_addr_code to use VICTIM_TLB_HIT
>   cputlb: move get_page_addr_code
>   cputlb: fix the way get_page_addr_code fills the tlb
>   qdev: add MemoryRegion property
>   introduce mmio_interface
>   exec: allow to get a pointer for some mmio memory region
>   xilinx_spips: allow mmio execution
> 
>  cputlb.c |  82 ++---
>  hw/misc/Makefile.objs|   1 +
>  hw/misc/mmio_interface.c | 128 
> +++
>  hw/ssi/xilinx_spips.c|  74 --
>  include/exec/memory.h|  35 +++
>  include/hw/misc/mmio_interface.h |  49 +++
>  include/hw/qdev-properties.h |   2 +
>  memory.c | 111 +
>  8 files changed, 428 insertions(+), 54 deletions(-)
>  create mode 100644 hw/misc/mmio_interface.c
>  create mode 100644 include/hw/misc/mmio_interface.h
> 




Re: [Qemu-devel] [PATCH] hw: dead code removal

2017-03-21 Thread Frederic Konrad
Hi,

On 03/20/2017 07:00 PM, Anton Volkov wrote:
> Made functions *_exit in hw/ return void instead of int (they returned 0 all 
> the time)
> and removed related return value checks
> 
> Signed-off-by: Anton Volkov 
> ---
>  hw/audio/hda-codec.c  | 3 +--
>  hw/audio/intel-hda.c  | 3 +--
>  hw/audio/intel-hda.h  | 2 +-
>  hw/char/sclpconsole-lm.c  | 4 ++--
>  hw/char/sclpconsole.c | 4 ++--
>  hw/core/qdev.c| 6 +-
>  hw/s390x/event-facility.c | 6 +-
>  hw/s390x/virtio-ccw.c | 7 +++
>  hw/s390x/virtio-ccw.h | 2 +-
>  hw/usb/dev-smartcard-reader.c | 3 +--
>  include/hw/qdev-core.h| 2 +-
>  include/hw/s390x/event-facility.h | 2 +-
>  12 files changed, 16 insertions(+), 28 deletions(-)
> 
> diff --git a/hw/audio/hda-codec.c b/hw/audio/hda-codec.c
> index 52d4640..5402cd1 100644
> --- a/hw/audio/hda-codec.c
> +++ b/hw/audio/hda-codec.c
> @@ -520,7 +520,7 @@ static int hda_audio_init(HDACodecDevice *hda, const 
> struct desc_codec *desc)
>  return 0;
>  }
>  
> -static int hda_audio_exit(HDACodecDevice *hda)
> +static void hda_audio_exit(HDACodecDevice *hda)
>  {
>  HDAAudioState *a = HDA_AUDIO(hda);
>  HDAAudioStream *st;
> @@ -539,7 +539,6 @@ static int hda_audio_exit(HDACodecDevice *hda)
>  }
>  }
>  AUD_remove_card(>card);
> -return 0;
>  }
>  
>  static int hda_audio_post_load(void *opaque, int version)
> diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c
> index 537face..991c704 100644
> --- a/hw/audio/intel-hda.c
> +++ b/hw/audio/intel-hda.c
> @@ -70,7 +70,7 @@ static void hda_codec_dev_realize(DeviceState *qdev, Error 
> **errp)
>  }
>  }
>  
> -static int hda_codec_dev_exit(DeviceState *qdev)
> +static void hda_codec_dev_exit(DeviceState *qdev)
>  {
>  HDACodecDevice *dev = HDA_CODEC_DEVICE(qdev);
>  HDACodecDeviceClass *cdc = HDA_CODEC_DEVICE_GET_CLASS(dev);
> @@ -78,7 +78,6 @@ static int hda_codec_dev_exit(DeviceState *qdev)
>  if (cdc->exit) {
>  cdc->exit(dev);
>  }
> -return 0;
>  }
>  
>  HDACodecDevice *hda_codec_find(HDACodecBus *bus, uint32_t cad)
> diff --git a/hw/audio/intel-hda.h b/hw/audio/intel-hda.h
> index d784bcf..53b78da 100644
> --- a/hw/audio/intel-hda.h
> +++ b/hw/audio/intel-hda.h
> @@ -38,7 +38,7 @@ typedef struct HDACodecDeviceClass
>  DeviceClass parent_class;
>  
>  int (*init)(HDACodecDevice *dev);
> -int (*exit)(HDACodecDevice *dev);
> +void (*exit)(HDACodecDevice *dev);
>  void (*command)(HDACodecDevice *dev, uint32_t nid, uint32_t data);
>  void (*stream)(HDACodecDevice *dev, uint32_t stnr, bool running, bool 
> output);
>  } HDACodecDeviceClass;
> diff --git a/hw/char/sclpconsole-lm.c b/hw/char/sclpconsole-lm.c
> index 07d6ebd..fbe5b42 100644
> --- a/hw/char/sclpconsole-lm.c
> +++ b/hw/char/sclpconsole-lm.c
> @@ -318,9 +318,9 @@ static int console_init(SCLPEvent *event)
>  return 0;
>  }
>  
> -static int console_exit(SCLPEvent *event)
> +static void console_exit(SCLPEvent *event)
>  {
> -return 0;
> +return;
>  }

Any reason of keeping those function if they do nothing?
There is a NULL check on the DeviceClass exit callback before it's
called so maybe just drop this function?

Fred

>  
>  static void console_reset(DeviceState *dev)
> diff --git a/hw/char/sclpconsole.c b/hw/char/sclpconsole.c
> index b78f240..644f7cd 100644
> --- a/hw/char/sclpconsole.c
> +++ b/hw/char/sclpconsole.c
> @@ -246,9 +246,9 @@ static void console_reset(DeviceState *dev)
> scon->notify = false;
>  }
>  
> -static int console_exit(SCLPEvent *event)
> +static void console_exit(SCLPEvent *event)
>  {
> -return 0;
> +return;
>  }
>  
>  static Property console_properties[] = {
> diff --git a/hw/core/qdev.c b/hw/core/qdev.c
> index 1e7fb33..5415843 100644
> --- a/hw/core/qdev.c
> +++ b/hw/core/qdev.c
> @@ -238,11 +238,7 @@ static void device_unrealize(DeviceState *dev, Error 
> **errp)
>  DeviceClass *dc = DEVICE_GET_CLASS(dev);
>  
>  if (dc->exit) {
> -int rc = dc->exit(dev);
> -if (rc < 0) {
> -error_setg(errp, "Device exit failed.");
> -return;
> -}
> +dc->exit(dev);
>  }
>  }
>  
> diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c
> index 34b2faf..f7c509c 100644
> --- a/hw/s390x/event-facility.c
> +++ b/hw/s390x/event-facility.c
> @@ -413,11 +413,7 @@ static void event_unrealize(DeviceState *qdev, Error 
> **errp)
>  SCLPEvent *event = SCLP_EVENT(qdev);
>  SCLPEventClass *child = SCLP_EVENT_GET_CLASS(event);
>  if (child->exit) {
> -int rc = child->exit(event);
> -if (rc < 0) {
> -error_setg(errp, "SCLP event exit failed.");
> -return;
> -}
> +child->exit(event);
>  }
>  }
>  
> diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
> index 00b3bde..d1c4ff6 100644
> --- 

Re: [Qemu-devel] [PATCH v2 00/11] MTTCG fixups for 2.9

2017-03-06 Thread Frederic Konrad
On 03/06/2017 10:43 AM, Alex Bennée wrote:
> 
> Frederic Konrad <fred.kon...@greensocs.com> writes:
> 
>> Hi All,
>>
>> I've a strangeness with the "drop iolock" patch.
>> It seems it has an impact on the MMIO execution patch-set I'm working
>> on:
> 
> Hmm the only real change is the BQL (implicit or explict) being taken on
> entry to the mmio functions.

Yes maybe it just trigger a bug more easily..

Fred

> 
>> Basically modifying the memory tree is causing a Bad Ram Address error.
>> I wonder if this can't happen with hotplug/unplug model as well.
> 
> Isn't this all done under an RCU? I don't think any of this should have
> changed for the MTTCG patch series.
> 
>> I'll look into this.
>> Shoot if you have any evidence of why that doesn't work :).
> 
> --enable-tcg-debug will turn on more lock checking (at a performance
>   hit). You could try that.
> 
>>
>> Thanks,
>> Fred
>>
>> On 03/02/2017 08:53 PM, Alex Bennée wrote:
>>> Hi Peter,
>>>
>>> So perhaps predictably the merging of MTTCG has thrown up some issues
>>> during soft-freeze. The following patches fix up some of those:
>>>
>>> The following where in v1 and just have r-b tags:
>>>
>>>   vl/cpus: be smarter with icount and MTTCG
>>>   target/i386/cpu.h: declare TCG_GUEST_DEFAULT_MO
>>>   cpus.c: add additional error_report when !TARGET_SUPPORT_MTTCG
>>>
>>> The next change downgrades the asserts to tcg_debug_asserts. This will
>>> reduce the instances of production builds failing on non-MTTCG enabled
>>> guests. The races still need to be fixed but you now have to
>>> --enable-debug-tcg to go hunting for them:
>>>
>>>   translate: downgrade IRQ BQL asserts to tcg_debug_assert
>>>
>>> This never came up in my testing but it seems some guests can
>>> translate while doing a tlb_fill. The call to cpu_restore_state never
>>> worked before (as we are translating the block you are looking for)
>>> but by bugging out we avoid the double tb_lock().
>>>
>>>   translate-all: exit cpu_restore_state early if translating
>>>
>>> Then we have a bunch of fixes from the reports on the list. They are
>>> safe to merge but I'll leave that up to the maintainers. There may be
>>> an argument for holding these patches back until the guest is
>>> converted to be MTTCG aware and a full audit of the CPU<->HW emulation
>>> boundaries is done for each one:
>>>
>>>   sparc/sparc64: grab BQL before calling cpu_check_irqs
>>>   s390x/misc_helper.c: wrap IO instructions in BQL
>>>   target/xtensa: hold BQL for interrupt processing
>>>   target/mips/op_helper: hold BQL before calling cpu_mips_get_count
>>>
>>> Finally these are just tiny debug fixes while investigating the icount
>>> regression:
>>>
>>>   target/arm/helper: make it clear the EC field is also in hex
>>>   hw/intc/arm_gic: modernise the DPRINTF
>>>
>>> Going forward I think 1-5 are ready to be merged now. For 6-9 we
>>> should await decisions from the target maintainers. The last two are
>>> entirely up to you.
>>>
>>> It looks like the -icount regression is a poor interaction between
>>> icount timers and the BQL but this is going to require discussion with
>>> Paolo in the morning.
>>>
>>> Cheers,
>>>
>>>
>>> Alex Bennée (11):
>>>   vl/cpus: be smarter with icount and MTTCG
>>>   target/i386/cpu.h: declare TCG_GUEST_DEFAULT_MO
>>>   cpus.c: add additional error_report when !TARGET_SUPPORT_MTTCG
>>>   translate: downgrade IRQ BQL asserts to tcg_debug_assert
>>>   translate-all: exit cpu_restore_state early if translating
>>>   sparc/sparc64: grab BQL before calling cpu_check_irqs
>>>   s390x/misc_helper.c: wrap IO instructions in BQL
>>>   target/xtensa: hold BQL for interrupt processing
>>>   target/mips/op_helper: hold BQL before calling cpu_mips_get_count
>>>   target/arm/helper: make it clear the EC field is also in hex
>>>   hw/intc/arm_gic: modernise the DPRINTF
>>>
>>>  cpus.c  | 11 +++
>>>  hw/intc/arm_gic.c   | 13 +
>>>  hw/sparc/sun4m.c|  3 +++
>>>  hw/sparc64/sparc64.c|  3 +++
>>>  target/arm/helper.c |  2 +-
>>>  target/i386/cpu.h   |  3 +++
>>>  target/mips/op_helper.c | 17 ++---
>>>  target/s390x/misc_helper.c  | 21 +
>>>  target/sparc/int64_helper.c |  3 +++
>>>  target/sparc/win_helper.c   | 11 +++
>>>  target/xtensa/helper.c  |  1 +
>>>  target/xtensa/op_helper.c   |  7 +++
>>>  translate-all.c |  9 -
>>>  translate-common.c  |  3 ++-
>>>  vl.c|  7 ++-
>>>  15 files changed, 95 insertions(+), 19 deletions(-)
>>>
> 
> 
> --
> Alex Bennée
> 




Re: [Qemu-devel] [PATCH v2 00/11] MTTCG fixups for 2.9

2017-03-03 Thread Frederic Konrad
Hi All,

I've a strangeness with the "drop iolock" patch.
It seems it has an impact on the MMIO execution patch-set I'm working
on:

Basically modifying the memory tree is causing a Bad Ram Address error.
I wonder if this can't happen with hotplug/unplug model as well.

I'll look into this.
Shoot if you have any evidence of why that doesn't work :).

Thanks,
Fred

On 03/02/2017 08:53 PM, Alex Bennée wrote:
> Hi Peter,
> 
> So perhaps predictably the merging of MTTCG has thrown up some issues
> during soft-freeze. The following patches fix up some of those:
> 
> The following where in v1 and just have r-b tags:
> 
>   vl/cpus: be smarter with icount and MTTCG
>   target/i386/cpu.h: declare TCG_GUEST_DEFAULT_MO
>   cpus.c: add additional error_report when !TARGET_SUPPORT_MTTCG
> 
> The next change downgrades the asserts to tcg_debug_asserts. This will
> reduce the instances of production builds failing on non-MTTCG enabled
> guests. The races still need to be fixed but you now have to
> --enable-debug-tcg to go hunting for them:
> 
>   translate: downgrade IRQ BQL asserts to tcg_debug_assert
> 
> This never came up in my testing but it seems some guests can
> translate while doing a tlb_fill. The call to cpu_restore_state never
> worked before (as we are translating the block you are looking for)
> but by bugging out we avoid the double tb_lock().
> 
>   translate-all: exit cpu_restore_state early if translating
> 
> Then we have a bunch of fixes from the reports on the list. They are
> safe to merge but I'll leave that up to the maintainers. There may be
> an argument for holding these patches back until the guest is
> converted to be MTTCG aware and a full audit of the CPU<->HW emulation
> boundaries is done for each one:
> 
>   sparc/sparc64: grab BQL before calling cpu_check_irqs
>   s390x/misc_helper.c: wrap IO instructions in BQL
>   target/xtensa: hold BQL for interrupt processing
>   target/mips/op_helper: hold BQL before calling cpu_mips_get_count
> 
> Finally these are just tiny debug fixes while investigating the icount
> regression:
> 
>   target/arm/helper: make it clear the EC field is also in hex
>   hw/intc/arm_gic: modernise the DPRINTF
> 
> Going forward I think 1-5 are ready to be merged now. For 6-9 we
> should await decisions from the target maintainers. The last two are
> entirely up to you.
> 
> It looks like the -icount regression is a poor interaction between
> icount timers and the BQL but this is going to require discussion with
> Paolo in the morning.
> 
> Cheers,
> 
> 
> Alex Bennée (11):
>   vl/cpus: be smarter with icount and MTTCG
>   target/i386/cpu.h: declare TCG_GUEST_DEFAULT_MO
>   cpus.c: add additional error_report when !TARGET_SUPPORT_MTTCG
>   translate: downgrade IRQ BQL asserts to tcg_debug_assert
>   translate-all: exit cpu_restore_state early if translating
>   sparc/sparc64: grab BQL before calling cpu_check_irqs
>   s390x/misc_helper.c: wrap IO instructions in BQL
>   target/xtensa: hold BQL for interrupt processing
>   target/mips/op_helper: hold BQL before calling cpu_mips_get_count
>   target/arm/helper: make it clear the EC field is also in hex
>   hw/intc/arm_gic: modernise the DPRINTF
> 
>  cpus.c  | 11 +++
>  hw/intc/arm_gic.c   | 13 +
>  hw/sparc/sun4m.c|  3 +++
>  hw/sparc64/sparc64.c|  3 +++
>  target/arm/helper.c |  2 +-
>  target/i386/cpu.h   |  3 +++
>  target/mips/op_helper.c | 17 ++---
>  target/s390x/misc_helper.c  | 21 +
>  target/sparc/int64_helper.c |  3 +++
>  target/sparc/win_helper.c   | 11 +++
>  target/xtensa/helper.c  |  1 +
>  target/xtensa/op_helper.c   |  7 +++
>  translate-all.c |  9 -
>  translate-common.c  |  3 ++-
>  vl.c|  7 ++-
>  15 files changed, 95 insertions(+), 19 deletions(-)
> 




Re: [Qemu-devel] [PATCH v2 10/11] target/arm/helper: make it clear the EC field is also in hex

2017-03-03 Thread Frederic Konrad
On 03/02/2017 08:53 PM, Alex Bennée wrote:
> ..just like the rest of the displayed ESR register. Otherwise people
> might scratch their heads if a not obviously hex number is displayed
> for the EC field.
> 
> Signed-off-by: Alex Bennée 
> ---
>  target/arm/helper.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/target/arm/helper.c b/target/arm/helper.c
> index 3f4211b572..76b608f0ba 100644
> --- a/target/arm/helper.c
> +++ b/target/arm/helper.c
> @@ -6857,7 +6857,7 @@ void arm_cpu_do_interrupt(CPUState *cs)
>new_el);
>  if (qemu_loglevel_mask(CPU_LOG_INT)
>  && !excp_is_internal(cs->exception_index)) {
> -qemu_log_mask(CPU_LOG_INT, "...with ESR %x/0x%" PRIx32 "\n",
> +qemu_log_mask(CPU_LOG_INT, "...with ESR 0x%x/0x%" PRIx32 "\n",
>env->exception.syndrome >> ARM_EL_EC_SHIFT,
>env->exception.syndrome);
>  }
> 

This seems OK to me.

Reviewed-by: KONRAD Frederic 



Re: [Qemu-devel] [PATCH v2 11/11] hw/intc/arm_gic: modernise the DPRINTF

2017-03-03 Thread Frederic Konrad
Hi Alex,

On 03/02/2017 08:53 PM, Alex Bennée wrote:
> While I was debugging the icount issues I realised a bunch of the
> messages look quite similar. I've fixed this by including __func__ in
> the debug print. At the same time I move the a modern if (GATE) style
> printf which ensures the compiler can check for format string errors
> even if the code gets optimised away in the non-DEBUG_GIC case.
> 
> Signed-off-by: Alex Bennée 
> ---
>  hw/intc/arm_gic.c | 13 +
>  1 file changed, 9 insertions(+), 4 deletions(-)
> 
> diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
> index 8e5a9d8a3e..b305d9032a 100644
> --- a/hw/intc/arm_gic.c
> +++ b/hw/intc/arm_gic.c
> @@ -26,15 +26,20 @@
>  #include "qemu/log.h"
>  #include "trace.h"
>  
> -//#define DEBUG_GIC
> +/* #define DEBUG_GIC */
>  
>  #ifdef DEBUG_GIC
> -#define DPRINTF(fmt, ...) \
> -do { fprintf(stderr, "arm_gic: " fmt , ## __VA_ARGS__); } while (0)
> +#define DEBUG_GIC_GATE 1
>  #else
> -#define DPRINTF(fmt, ...) do {} while(0)
> +#define DEBUG_GIC_GATE 0
>  #endif
>  
> +#define DPRINTF(fmt, ...) do {  \
> +if (DEBUG_GIC_GATE) {   \
> +fprintf(stderr, "%s: " fmt, __func__, ## __VA_ARGS__);  \
> +}   \
> +} while (0)
> +

Seems a prefered way is using qemu_log instead of fprintf?

Thanks,
Fred

>  static const uint8_t gic_id_11mpcore[] = {
>  0x00, 0x00, 0x00, 0x00, 0x90, 0x13, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1
>  };
> 




Re: [Qemu-devel] [PATCH V2 4/7] exec: allow to get a pointer for some mmio memory region

2017-03-03 Thread Frederic Konrad
On 03/03/2017 02:44 PM, Edgar E. Iglesias wrote:
> On Fri, Feb 17, 2017 at 09:17:10PM +0100, fred.kon...@greensocs.com wrote:
>> From: KONRAD Frederic 
>>
>> This introduces a special callback which allows to run code from some MMIO
>> devices.
>>
>> SysBusDevice with a MemoryRegion which implements the request_ptr callback 
>> will
>> be notified when the guest try to execute code from their offset. Then it 
>> will
>> be able to eg: pre-load some code from an SPI device or ask a pointer from an
>> external simulator, etc..
>>
>> When the pointer or the data in it are no longer valid the device has to
>> invalidate it.
>>
>> Signed-off-by: KONRAD Frederic 
>>
>> RFC -> V1:
>>   * Use mmio-interface instead of directly creating the subregion.
> 
> Hi Fred,
> 
> 
> 
> 
>> ---
>>  cputlb.c  |  7 +++
>>  include/exec/memory.h | 35 +++
>>  memory.c  | 57 
>> +++
>>  3 files changed, 99 insertions(+)
>>
>> diff --git a/cputlb.c b/cputlb.c
>> index 846341e..9077247 100644
>> --- a/cputlb.c
>> +++ b/cputlb.c
>> @@ -545,6 +545,13 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env, 
>> target_ulong addr)
>>  if (memory_region_is_unassigned(mr)) {
>>  CPUClass *cc = CPU_GET_CLASS(cpu);
>>  
>> +if (memory_region_request_mmio_ptr(mr, addr)) {
>> +/* A MemoryRegion is potentially added so re-run the
>> + * get_page_addr_code.
>> + */
>> +return get_page_addr_code(env, addr);
>> +}
>> +
>>  if (cc->do_unassigned_access) {
>>  cc->do_unassigned_access(cpu, addr, false, true, 0, 4);
>>  } else {
>> diff --git a/include/exec/memory.h b/include/exec/memory.h
>> index 987f925..36b0eec 100644
>> --- a/include/exec/memory.h
>> +++ b/include/exec/memory.h
>> @@ -120,6 +120,15 @@ struct MemoryRegionOps {
>>  uint64_t data,
>>  unsigned size,
>>  MemTxAttrs attrs);
>> +/* Instruction execution pre-callback:
>> + * @addr is the address of the access relative to the @mr.
>> + * @size is the size of the area returned by the callback.
>> + * @offset is the location of the pointer inside @mr.
>> + *
>> + * Returns a pointer to a location which contains guest code.
>> + */
>> +void *(*request_ptr)(void *opaque, hwaddr addr, unsigned *size,
>> + unsigned *offset);
>>  
>>  enum device_endian endianness;
>>  /* Guest-visible constraints: */
>> @@ -1253,6 +1262,32 @@ void memory_global_dirty_log_stop(void);
>>  void mtree_info(fprintf_function mon_printf, void *f, bool flatview);
>>  
>>  /**
>> + * memory_region_request_mmio_ptr: request a pointer to an mmio
>> + * MemoryRegion. If it is possible map a RAM MemoryRegion with this pointer.
>> + * When the device wants to invalidate the pointer it will call
>> + * memory_region_invalidate_mmio_ptr.
>> + *
>> + * @mr: #MemoryRegion to check
>> + * @addr: address within that region
>> + *
>> + * Returns true on success, false otherwise.
>> + */
>> +bool memory_region_request_mmio_ptr(MemoryRegion *mr, hwaddr addr);
>> +
>> +/**
>> + * memory_region_invalidate_mmio_ptr: invalidate the pointer to an mmio
>> + * previously requested.
>> + * In the end that means that if something wants to execute from this area 
>> it
>> + * will need to request the pointer again.
>> + *
>> + * @mr: #MemoryRegion associated to the pointer.
>> + * @addr: address within that region
>> + * @size: size of that area.
>> + */
>> +void memory_region_invalidate_mmio_ptr(MemoryRegion *mr, hwaddr offset,
>> +   unsigned size);
>> +
>> +/**
>>   * memory_region_dispatch_read: perform a read directly to the specified
>>   * MemoryRegion.
>>   *
>> diff --git a/memory.c b/memory.c
>> index 6c58373..a605250 100644
>> --- a/memory.c
>> +++ b/memory.c
>> @@ -30,6 +30,8 @@
>>  #include "exec/ram_addr.h"
>>  #include "sysemu/kvm.h"
>>  #include "sysemu/sysemu.h"
>> +#include "hw/misc/mmio_interface.h"
>> +#include "hw/qdev-properties.h"
>>  
>>  //#define DEBUG_UNASSIGNED
>>  
>> @@ -2375,6 +2377,61 @@ void memory_listener_unregister(MemoryListener 
>> *listener)
>>  QTAILQ_REMOVE(>address_space->listeners, listener, link_as);
>>  }
>>  
>> +bool memory_region_request_mmio_ptr(MemoryRegion *mr, hwaddr addr)
>> +{
>> +void *host;
>> +unsigned size = 0;
>> +unsigned offset = 0;
>> +Object *new_interface;
>> +
>> +if (!mr || !mr->ops->request_ptr) {
>> +return false;
>> +}
>> +
>> +/*
>> + * Avoid an update if the request_ptr call
>> + * memory_region_invalidate_mmio_ptr which seems to be likely when we 
>> use
>> + * a cache.
>> + */
>> +memory_region_transaction_begin();
>> +
>> +host = 

Re: [Qemu-devel] [PATCH V2 0/7] execute code from mmio area

2017-03-03 Thread Frederic Konrad
Hi All,

Any feedback for the 4 last patches?

Thanks,
Fred

On 02/17/2017 09:17 PM, fred.kon...@greensocs.com wrote:
> From: KONRAD Frederic 
> 
> This series allows to execute code from mmio areas.
> The main goal of this is to be able to run code for example from an SPI 
> device.
> 
> The three first patch fixes the way get_page_addr_code fills the TLB.
> 
> The fourth patch implements the mmio execution helpers: the device must
> implement the request_ptr callback of the MemoryRegion and will be notified 
> when
> the guest wants to execute code from it.
> 
> The fifth patch introduces mmio_interface device which allows to dynamically
> map a host pointer somewhere into the memory.
> 
> The sixth patch implements the execution from the SPI memories in the
> xilinx_spips model.
> 
> Thanks,
> Fred
> 
> V1 -> V2:
>   * Fix the DPRINTF error.
> RFC -> V1:
>   * Use an interface (mmio-interface) to fix any reference leak issue.
> 
> KONRAD Frederic (7):
>   cputlb: cleanup get_page_addr_code to use VICTIM_TLB_HIT
>   cputlb: move get_page_addr_code
>   cputlb: fix the way get_page_addr_code fills the tlb
>   exec: allow to get a pointer for some mmio memory region
>   qdev: add MemoryRegion property
>   introduce mmio_interface
>   xilinx_spips: allow mmio execution
> 
>  cputlb.c |  81 ++---
>  hw/misc/Makefile.objs|   1 +
>  hw/misc/mmio_interface.c | 128 
> +++
>  hw/ssi/xilinx_spips.c|  74 --
>  include/exec/memory.h|  35 +++
>  include/hw/misc/mmio_interface.h |  49 +++
>  include/hw/qdev-properties.h |   2 +
>  memory.c |  57 +
>  8 files changed, 372 insertions(+), 55 deletions(-)
>  create mode 100644 hw/misc/mmio_interface.c
>  create mode 100644 include/hw/misc/mmio_interface.h
> 




Re: [Qemu-devel] [PATCH V1 3/7] cputlb: fix the way get_page_addr_code fills the tlb

2017-02-23 Thread Frederic Konrad
On 02/23/2017 01:31 AM, Richard Henderson wrote:
> On 02/17/2017 01:30 AM, fred.kon...@greensocs.com wrote:
>> From: KONRAD Frederic 
>>
>> get_page_addr_code(..) does a cpu_ldub_code to fill the tlb:
>> This can lead to some side effects if a device is mapped at this address.
>>
>> So this patch replaces the cpu_memory_ld by a tlb_fill.
>>
>> Signed-off-by: KONRAD Frederic 
>> ---
>>  cputlb.c | 6 --
>>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> Reviewed-by: Richard Henderson 
> 
> 
> r~

Thanks!
Fred




Re: [Qemu-devel] Creating a dummy PCI device

2017-02-21 Thread Frederic Konrad
Hi Peter,

This won't be easy unfortunately, at least not clean :).
The vendor_id device_id are part of the PCIDeviceClass.
So I _think_ you can't use a qom parameter for that.
But... it seems that these fields are used firstly in
pci_qdev_realize (to be checked) so maybe it's okay to change them
later before the device is realized with a parameter..

This is really hackish.. sorry.. but that's a though :).

Fred

On 02/21/2017 01:41 PM, Peter Lieven wrote:
> Am 03.02.2017 um 13:07 schrieb Peter Lieven:
>> Hi,
>>
>>
>> I have a special use case of creating a dummy PCI device with a
>> certain vendor/device ID. The device does not have to actually
>> function, it just
>>
>> has to be visible under lspci.
>>
>>
>> Any idea how to achieve this? I was thinking of modifying the edu pci
>> device to make the device/vendor ID passable via cmdline.
>>
>>
>> Don't know if thats a good idea.
>>
>>
>> Any thoughts?
> 
> anyone?
> 
> Thanks,
> Peter
> 
> 




Re: [Qemu-devel] [PATCH V1 0/7] execute code from mmio area

2017-02-17 Thread Frederic Konrad
On 02/16/2017 03:39 PM, Paolo Bonzini wrote:
> 
> 
> On 16/02/2017 15:30, fred.kon...@greensocs.com wrote:
>> From: KONRAD Frederic 
>>
>> This series allows to execute code from mmio areas.
>> The main goal of this is to be able to run code for example from an SPI 
>> device.
>>
>> The three first patch fixes the way get_page_addr_code fills the TLB.
>>
>> The fourth patch implements the mmio execution helpers: the device must
>> implement the request_ptr callback of the MemoryRegion and will be notified 
>> when
>> the guest wants to execute code from it.
>>
>> The fifth patch introduces mmio_interface device which allows to dynamically
>> map a host pointer somewhere into the memory.
>>
>> The sixth patch implements the execution from the SPI memories in the
>> xilinx_spips model.
> 
> Sorry for the stupid question, where is mmio-interface used?  Wrong
> version of patch 7 perhaps?

BTW I forgot to mention that but this mmio-interface effectively fix the
leak you mentioned on the RFC.
My testcase stresses that and I see regularly the device finalized and
I don't see the process eating up the memory.

Thanks,
Fred
> 
> Paolo
> 
>> Thanks,
>> Fred
>>
>> RFC -> V1:
>>   * Use an interface (mmio-interface) to fix any reference leak issue.
>>
>> KONRAD Frederic (7):
>>   cputlb: cleanup get_page_addr_code to use VICTIM_TLB_HIT
>>   cputlb: move get_page_addr_code
>>   cputlb: fix the way get_page_addr_code fills the tlb
>>   exec: allow to get a pointer for some mmio memory region
>>   qdev: add MemoryRegion property
>>   introduce mmio_interface
>>   xilinx_spips: allow mmio execution
>>
>>  cputlb.c |  81 ++---
>>  hw/misc/Makefile.objs|   1 +
>>  hw/misc/mmio_interface.c | 128 
>> +++
>>  hw/ssi/xilinx_spips.c|  74 --
>>  include/exec/memory.h|  35 +++
>>  include/hw/misc/mmio_interface.h |  49 +++
>>  include/hw/qdev-properties.h |   2 +
>>  memory.c |  57 +
>>  8 files changed, 372 insertions(+), 55 deletions(-)
>>  create mode 100644 hw/misc/mmio_interface.c
>>  create mode 100644 include/hw/misc/mmio_interface.h
>>




Re: [Qemu-devel] [PATCH V1 0/7] execute code from mmio area

2017-02-16 Thread Frederic Konrad
On 02/16/2017 03:39 PM, Paolo Bonzini wrote:
> 
> 
> On 16/02/2017 15:30, fred.kon...@greensocs.com wrote:
>> From: KONRAD Frederic 
>>
>> This series allows to execute code from mmio areas.
>> The main goal of this is to be able to run code for example from an SPI 
>> device.
>>
>> The three first patch fixes the way get_page_addr_code fills the TLB.
>>
>> The fourth patch implements the mmio execution helpers: the device must
>> implement the request_ptr callback of the MemoryRegion and will be notified 
>> when
>> the guest wants to execute code from it.
>>
>> The fifth patch introduces mmio_interface device which allows to dynamically
>> map a host pointer somewhere into the memory.
>>
>> The sixth patch implements the execution from the SPI memories in the
>> xilinx_spips model.
> 
> Sorry for the stupid question, where is mmio-interface used?  Wrong
> version of patch 7 perhaps?
> 

oops sorry *mmio_interface* is used in patch 4.

Thanks,
Fred

> Paolo
> 
>> Thanks,
>> Fred
>>
>> RFC -> V1:
>>   * Use an interface (mmio-interface) to fix any reference leak issue.
>>
>> KONRAD Frederic (7):
>>   cputlb: cleanup get_page_addr_code to use VICTIM_TLB_HIT
>>   cputlb: move get_page_addr_code
>>   cputlb: fix the way get_page_addr_code fills the tlb
>>   exec: allow to get a pointer for some mmio memory region
>>   qdev: add MemoryRegion property
>>   introduce mmio_interface
>>   xilinx_spips: allow mmio execution
>>
>>  cputlb.c |  81 ++---
>>  hw/misc/Makefile.objs|   1 +
>>  hw/misc/mmio_interface.c | 128 
>> +++
>>  hw/ssi/xilinx_spips.c|  74 --
>>  include/exec/memory.h|  35 +++
>>  include/hw/misc/mmio_interface.h |  49 +++
>>  include/hw/qdev-properties.h |   2 +
>>  memory.c |  57 +
>>  8 files changed, 372 insertions(+), 55 deletions(-)
>>  create mode 100644 hw/misc/mmio_interface.c
>>  create mode 100644 include/hw/misc/mmio_interface.h
>>




Re: [Qemu-devel] Asking about USB for QEMU

2017-02-10 Thread Frederic Konrad
Hi,

If I understand right:
You want to run a zynq qemu on a centos host?

On 02/09/2017 09:25 AM, Wojciech Zebrowski wrote:
> Hi
> 
> I try connect my host linux centos USB to Qemu for Xilinx Zynq solution.
> I do following step :
> 1.Check usb vendor id , product id: lsusb
> 
> 
> 
> 
> *Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hubBus 002
> Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hubBus 003 Device 001:
> ID 1d6b:0002 Linux Foundation 2.0 root hubBus 004 Device 001: ID 1d6b:0003
> Linux Foundation 3.0 root hub*
> 
> 2. I start Qemu with switch :
> 
> *-usbdevice host::*
> 
> *-usbdevice host:1d6b:0002*
> 
>  3. On Centos Host computer where Xilinx Qemu is started , i've error as :
> 
> *No 'PCI' bus found for device 'usb-ehci'*

It is highly probable that the --usbdevice command try to create a
usb-ehci device and it doesn't find any PCI bus on the machine you
choose.

> 
> What is incorrect with my command or system configuration ?
> 
> 4. I check my motherboard bridge as following:
> 
> *qemu-system-x86_64 -device help |& grep usb.*hci*

Then here I don't get it. Why are you using qemu-system-x86_64?
It will be approximately the same for qemu-system-arm though.
Only there is probably no PCI bus where to connect them.

Can you give the complete command you are using?

Fred

> 
> *name "ich9-usb-ehci1", bus PCI name *
> 
> *"ich9-usb-ehci2", bus PCI name *
> 
> *"ich9-usb-uhci1", bus PCI name *
> 
> *"ich9-usb-uhci2", bus PCI name *
> 
> *"ich9-usb-uhci3", bus PCI name *
> 
> *"ich9-usb-uhci4", bus PCI name *
> 
> *"ich9-usb-uhci5", bus PCI name *
> 
> *"ich9-usb-uhci6", bus PCI name *
> 
> *"nec-usb-xhci", bus PCI name *
> 
> *"piix3-usb-uhci", bus PCI name *
> 
> *"piix4-usb-uhci", bus PCI name *
> 
> *"usb-ehci", bus PCI name *
> 
> *"vt82c686b-usb-uhci", bus PCI*
> 
> 
> *Any advice for check ?*
> 
> 
> Best regards :
> 
> Wojciech Zebrowski
> 




Re: [Qemu-devel] [PATCH v4] nios2: Add Altera JTAG UART emulation

2017-02-09 Thread Frederic Konrad
On 02/09/2017 09:53 PM, Bystricky, Juro wrote:
> 
> 
>> On 02/09/2017 07:52 PM, Juro Bystricky wrote:
>>> JTAG UART core eliminates the need for a separate RS-232 serial
>>> connection to a host PC for character I/O.
>>
>> And how does this describe the content of this patch ? This patch adds a
>> model of JTAG UART , it doesn't eliminate anything ...
>>
> 
> The commit message explicitly says:
> "Add Altera JTAG UART emulation."
> 
> But I will amend the message with more details.
> 
>>> Hardware emulation based on:
>>> https://www.altera.com/en_US/pdfs/literature/ug/ug_embedded_ip.pdf
>>> (Please see "Register Map" on page 65)
>>>
>>> Signed-off-by: Juro Bystricky 
>>> ---
>>
>> Changelog is missing ...
> 
> I modelled this patch based on other nios2 patches, none of them contained 
> Changelog. So please elaborate.

Things after "---" disappear when commited in the git.

Thanks,
Fred

> 
> 
>>> +/*
>>> + * FIFO size can be set from 8 to 32,768 bytes.
>>> + * Only powers of two are allowed.
>>> + */
>>> +fifo_size_ok = false;
>>> +for (size = 8; size <= 32768; size *= 2) {
>>> +if (size == fifo_size) {
>>> +fifo_size_ok = true;
>>> +break;
>>> +}
>>> +}
>>
>> Isn't that like
>>
>> if (size < 8 || size > 32768 || (size & ~(1 << ffs(size
>>   error()
>>
> 
> possibly, however ffs is rejected by checkpatch as non-portable
> libc call. 
> 
> 
>>> +#define DEFAULT_FIFO_SIZE 64
>>
>> This is still not QOM property , why ?
>>
> 
> Not sure what you mean, the code has:
> 
> DEFINE_PROP_UINT32("fifo-size", AlteraJUARTState, rx_fifo_size, 
> DEFAULT_FIFO_SIZE),
> 
> 
> Thanks
> 
> Juro
> 
> 




Re: [Qemu-devel] [PATCH v4] nios2: Add Altera JTAG UART emulation

2017-02-09 Thread Frederic Konrad
Hi,

On 02/09/2017 07:52 PM, Juro Bystricky wrote:
> JTAG UART core eliminates the need for a separate RS-232 serial
> connection to a host PC for character I/O.
> 
> Hardware emulation based on:
> https://www.altera.com/en_US/pdfs/literature/ug/ug_embedded_ip.pdf
> (Please see "Register Map" on page 65)
> 
> Signed-off-by: Juro Bystricky 
> ---
>  default-configs/nios2-softmmu.mak |   1 +
>  hw/char/Makefile.objs |   1 +
>  hw/char/altera_juart.c| 288 
> ++
>  include/hw/char/altera_juart.h|  46 ++
>  4 files changed, 336 insertions(+)
>  create mode 100644 hw/char/altera_juart.c
>  create mode 100644 include/hw/char/altera_juart.h
> 
> diff --git a/default-configs/nios2-softmmu.mak 
> b/default-configs/nios2-softmmu.mak
> index 74dc70c..6159846 100644
> --- a/default-configs/nios2-softmmu.mak
> +++ b/default-configs/nios2-softmmu.mak
> @@ -4,3 +4,4 @@ CONFIG_NIOS2=y
>  CONFIG_SERIAL=y
>  CONFIG_PTIMER=y
>  CONFIG_ALTERA_TIMER=y
> +CONFIG_ALTERA_JUART=y
> diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs
> index 6ea76fe..f0d0e25 100644
> --- a/hw/char/Makefile.objs
> +++ b/hw/char/Makefile.objs
> @@ -27,5 +27,6 @@ common-obj-$(CONFIG_LM32) += lm32_juart.o
>  common-obj-$(CONFIG_LM32) += lm32_uart.o
>  common-obj-$(CONFIG_MILKYMIST) += milkymist-uart.o
>  common-obj-$(CONFIG_SCLPCONSOLE) += sclpconsole.o sclpconsole-lm.o
> +common-obj-$(CONFIG_ALTERA_JUART) += altera_juart.o
>  
>  obj-$(CONFIG_VIRTIO) += virtio-serial-bus.o
> diff --git a/hw/char/altera_juart.c b/hw/char/altera_juart.c
> new file mode 100644
> index 000..0325ddc
> --- /dev/null
> +++ b/hw/char/altera_juart.c
> @@ -0,0 +1,288 @@
> +/*
> + * QEMU model of the Altera JTAG UART.
> + *
> + * Copyright (c) 2016-2017 Intel Corporation.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + *
> + * You should have received a copy of the GNU General Public License along
> + * with this program; if not, see .
> + *
> + * The Altera JTAG UART hardware registers are described in:
> + * https://www.altera.com/en_US/pdfs/literature/ug/ug_embedded_ip.pdf
> + * (In particular "Register Map" on page 65)
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/char/altera_juart.h"
> +#include "sysemu/sysemu.h"
> +#include "qemu/error-report.h"
> +
> +/* Data register */
> +#define OFFSET_R_DATA   0
> +#define DATA_RVALID BIT(15)
> +#define DATA_RAVAIL 0x
> +
> +/* Control register */
> +#define OFFSET_R_CONTROL 4
> +#define CONTROL_RE  BIT(0)
> +#define CONTROL_WE  BIT(1)
> +#define CONTROL_RI  BIT(8)
> +#define CONTROL_WI  BIT(9)
> +#define CONTROL_AC  BIT(10)
> +#define CONTROL_WSPACE  0x
> +
> +#define CONTROL_WMASK (CONTROL_RE | CONTROL_WE | CONTROL_AC)
> +
> +#define TYPE_ALTERA_JUART "altera-juart"
> +#define ALTERA_JUART(obj) \
> +OBJECT_CHECK(AlteraJUARTState, (obj), TYPE_ALTERA_JUART)
> +
> +/*
> + * The JTAG UART core generates an interrupt when either of the individual
> + * interrupt conditions is pending and enabled.
> + */
> +static void altera_juart_update_irq(AlteraJUARTState *s)
> +{
> +unsigned int irq;
> +
> +irq = ((s->jcontrol & CONTROL_WE) && (s->jcontrol & CONTROL_WI)) ||
> +  ((s->jcontrol & CONTROL_RE) && (s->jcontrol & CONTROL_RI));
> +
> +qemu_set_irq(s->irq, irq);
> +}
> +
> +static uint64_t altera_juart_read(void *opaque, hwaddr addr, unsigned int 
> size)
> +{
> +AlteraJUARTState *s = opaque;
> +uint32_t r;
> +
> +switch (addr) {
> +case OFFSET_R_DATA:
> +r = s->rx_fifo[(s->rx_fifo_pos - s->rx_fifo_len) & (s->rx_fifo_size 
> - 1)];
> +if (s->rx_fifo_len) {
> +s->rx_fifo_len--;
> +qemu_chr_fe_accept_input(>chr);
> +s->jdata = r | DATA_RVALID | (s->rx_fifo_len << 16);
> +s->jcontrol |= CONTROL_RI;
> +} else {
> +s->jdata = 0;
> +s->jcontrol &= ~CONTROL_RI;
> +}
> +
> +altera_juart_update_irq(s);
> +return s->jdata;
> +
> +case OFFSET_R_CONTROL:
> +return s->jcontrol;
> +}
> +
> +return 0;
> +}
> +
> +static void altera_juart_write(void *opaque, hwaddr addr,
> +   uint64_t value, unsigned int size)
> +{
> +AlteraJUARTState *s = opaque;
> +unsigned char c;
> +
> +switch (addr) {
> +case OFFSET_R_DATA:
> +c = value & 0xFF;
> +/*
> + * We do not decrement the write fifo,
> + * we "tranmsmit" instanteniously, CONTROL_WI always asserted
> + */
> +s->jcontrol |= CONTROL_WI;
> +s->jdata = c;
> +qemu_chr_fe_write(>chr, , 1);
> +altera_juart_update_irq(s);
> +   

Re: [Qemu-devel] question about binary translation on qemu

2017-02-08 Thread Frederic Konrad
On 02/07/2017 02:53 PM, oussema ben khedher wrote:
> hi 
> in my academic project i needed to know how qemu exactly translate an arm 
> instruction to the host assembly (in my case x86) so if you can help me to 
> know the function in the source code of qemu that tdo this work 
> thank you
> 

Hi,

There is a lot of code involved in the whole translation:
The guest instructions are not directly translated to the host
assembly but they are first translated in some intermediate OPs
(named TCG).

This translation takes place here:
void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
In target/arm/translate.c

Fred



Re: [Qemu-devel] [PATCH V2 06/10] docs: add qemu-clock documentation

2017-02-07 Thread Frederic Konrad
On 02/07/2017 05:13 PM, Peter Maydell wrote:
> On 26 January 2017 at 09:47,   wrote:
>> From: KONRAD Frederic 
>>
>> This adds the qemu-clock documentation.
>>
>> Signed-off-by: KONRAD Frederic 
>>
>> V1 -> V2:
>>   * Fixed in accordance with the changes in the previous patches.
>> ---
>>  docs/clock.txt | 108 
>> +
>>  1 file changed, 108 insertions(+)
>>  create mode 100644 docs/clock.txt
> 
> Could we have a simple example of what you need to do if you are:
>  * a device providing a clock source of some kind

The fixed clock in patch 7 might be helpful for that.
Maybe I can just point to it in the documentation?

>  * a device that takes a clock input and has one or more
>clock outputs which are configured by that device (for
>frequency, on/off, etc)
>  * a device that consumes a clock

The CRF is doing that. Maybe I can add a simpler testcase device to
build a make check for that?

Fred

> 
> please? I think that would help make it more concrete how you
> need to use these things.
> 
> thanks
> -- PMM
> 




Re: [Qemu-devel] [RFC 4/5] exec: allow to get a pointer for some mmio memory region

2017-02-07 Thread Frederic Konrad
On 02/04/2017 02:59 PM, Frederic Konrad wrote:
> On 02/04/2017 01:41 PM, Paolo Bonzini wrote:
>>
> ...
>>>
>>> Doesn't hotplug use dynamic MemoryRegion? In which case we better
>>> make that work with MTTCG. I wonder if we can't simply handle that
>>> with a safe_work for this case?
>>
>> Hot-unplug works because the backing memory is only freed when the
>> device gets instance_finalize, so at that point the region cannot have
>> any references.
>>
>> What can go wrong is the following (from the docs):
>>
>> - the memory region's owner had a reference taken via memory_region_ref
>>   (for example by address_space_map)
>>
>> - the region is unparented, and has no owner anymore
>>
>> - when address_space_unmap is called, the reference to the memory
>>   region's owner is leaked.
> 
> true.
> 
>>
>> In your case you have phys_section_add/phys_section_destroy instead of
>> address_space_map/unmap, but the problem is the same.
>>
>> I am a bit unsure about using the same lqspi_buf for caching different
>> addresses, and about using the same buffer for MMIO execution and read.
>> What if you allocate a different buffer every time
>> lqspi_request_mmio_ptr is called (adding a char* argument to
>> lqspi_load_cache) and free the old one from the safe_work item, after a
>> global TLB flush?  Then you don't need the Notifiers which were the
>> complicated and handwavy part of my proposal.
> 
> Actually this was just because it was the way xilinx_qspi worked.
> It load 1K of SPI data and fill the buffer.
> 
> In some other case we don't want to free the pointer at all, just make
> it not accessible for execution / read.
> (BTW I'll add the read-only property to this).
> 
> What about a simple Object eg: mmio-execution-interface which has a
> MemoryRegion? Instead of creating the MemoryRegion in request_pointer,
> We create a mmio-execution-interface object which create and map the
> region on the subregion.
> Then in invalidate: we unplug the mmio-execution-interface, unref it and
> it is freed all by magic when the map doesn't need it.
> 
> This avoid the reference issue and probably the bug with MTTCG.

Does that make sense?

Thanks,
Fred

> 
> Fred
> 
>>
>> Paolo
>>
>>>
>>> BTW the tests I have seems to pass without issues.
>>>
>>>>
>>>> An alternative design could be:
>>>>
>>>> - memory_region_request_mmio_ptr returns a MemoryRegionCache instead of
>>>> a pointer, so that the device can map a subset of the device (e.g. a
>>>> single page)
>>>
>>> I'm not aware of this MemoryRegionCache yet, it seems pretty new.
>>> I'll take a look.
>>>
>>> Thanks,
>>> Fred
>>>
>>>>
>>>> - memory_region_request_mmio_ptr and MemoryRegionOps.request_ptr accept
>>>> a Notifier
>>>>
>>>> - the device adds the Notifier to a NotifierList.  Before invalidating,
>>>> it invokes the Notifier and empties the NotifierList.
>>>>
>>>> - for the TLB case, the Notifier calls tlb_flush_page.
>>>>
>>>> I like the general idea though!
>>>>
>>>> Paolo
>>>>
>>>>> +}
>>>>> +}
>>>
>>>
>>>
> 
> 




Re: [Qemu-devel] [PATCH V2 02/10] qemu-clk: allow to add a clock to a device

2017-02-07 Thread Frederic Konrad
On 02/07/2017 10:31 AM, Cédric Le Goater wrote:
> On 02/07/2017 10:22 AM, Frederic Konrad wrote:
>>> I see how these routines are used in patch 10/10. But if we were
>>> open coding device CRF_APB, I don't think we would need them at
>>> all and it would make the code a little simple IMHO.
>> What do you mean by open coding?
> 
> I mean to externalize the definition of the objects in a 
> header file. 
> 
> Then you can replace the type 'Object *' of the attribute 
> holding a reference to an instance by a non pointer type.
> 
> Anyhow, I think we need to replace object_new() by 
> object_initialize() for QOM, and so we need to expose a 
> little more the object internals. 

Ok got you.

I'll take a look.

Thanks,
Fred

> 
> Thanks,
> 
> C.
> 
> 




Re: [Qemu-devel] [PATCH V2 03/10] qemu-clk: allow to bind two clocks together

2017-02-07 Thread Frederic Konrad
On 02/06/2017 04:58 PM, Cédric Le Goater wrote:
> Hello,
> 
> On 01/26/2017 10:47 AM, fred.kon...@greensocs.com wrote:
>> From: KONRAD Frederic 
>>
>> This introduces the clock binding and the update part.
>> When the qemu_clk_rate_update(qemu_clk, int) function is called:
>>   * The clock callback is called on the qemu_clk so it can change the rate.
>>   * The qemu_clk_rate_update function is called on all the driven clock.
>>
>> Signed-off-by: KONRAD Frederic 
>>
>> V1 -> V2:
>>   * Rename qemu_clk_on_rate_update_cb to QEMUClkRateUpdateCallback and
>> move the pointer to the structure instead of having a pointer-to-function
>> type.
>> ---
>>  include/qemu/qemu-clock.h | 67 
>> +++
>>  qemu-clock.c  | 56 +++
>>  2 files changed, 123 insertions(+)
>>
>> diff --git a/include/qemu/qemu-clock.h b/include/qemu/qemu-clock.h
>> index 3e692d3..6d30299 100644
>> --- a/include/qemu/qemu-clock.h
>> +++ b/include/qemu/qemu-clock.h
>> @@ -30,12 +30,25 @@
>>  #define TYPE_CLOCK "qemu-clk"
>>  #define QEMU_CLOCK(obj) OBJECT_CHECK(struct qemu_clk, (obj), TYPE_CLOCK)
>>  
>> +typedef struct ClkList ClkList;
>> +typedef uint64_t QEMUClkRateUpdateCallback(void *opaque, uint64_t rate);
>> +
>>  typedef struct qemu_clk {
>>  /*< private >*/
>>  Object parent_obj;
>>  char *name;/* name of this clock in the device. */
>> +uint64_t in_rate;  /* rate of the clock which drive this pin. */
> 
> 
> So if this is the reference clock rate, which can be divided by 
> settings in control registers, I would call the attribute 
> 'ref_rate' or 'rate_reference' 
> 
>> +uint64_t out_rate; /* rate of this clock pin. */
> 
> and this attribute could just be 'rate' and may be if we make 
> a property out of it, we could get rid of FixedClock in patch
> 7/10.
>
> 
>> +void *opaque;
>> +QEMUClkRateUpdateCallback *cb;
> 
> If I understand correctly, the need is to be able to refresh
> the rate of a clock object depending on some settings in a 
> controller. I think we should be using a derived class and 
> an operation for it. it would look better from a QOM point 
> of view. 
> 
> Here is a possibility,
> 
> We could make 'rate' a property and use a set property handler 
> to call the derived class specific operation. This is very 
> similar to the callback but we would remove the need of  
> qemu_clk_update_rate() and use the std mechanisms already in
> place  :
> 
>   object_property_set_int() 
> 
> qemu_clk_refresh() would still be needed to propagate the 
> changes in the settings of a controller to the target clocks. 
> 
> The 'opaque' attribute, which holds the pointer to a controller 
> object, would have to be passed to the derived clock object
> with 
>   object_property_add_const_link() 
> 
> and then grabbed with 
> 
>   object_property_get_link()
> 
> in the realize function of the derived clock object, or whenever 
> it's needed, in the operation for instance.
> 
> This clearly means more code than the actual solution, but 
> that is QOM way I think.  

Yes, the big issue here is that there are several clock inputs and clock
outputs. We need to be able to bind / unbind them if there is a selector
or some such.

So a device will have more than one clock object internally in it which
are "chained" to form a clock tree.

It seems overkill to me to implement one derived object per clock
"block" in the device to get the callback.

> 
>> +QLIST_HEAD(, ClkList) bound;
>>  } *qemu_clk;
>>  
>> +struct ClkList {
>> +qemu_clk clk;
>> +QLIST_ENTRY(ClkList) node;
>> +};
>> +
> 
> Do we really need this intermediate object ? Can't we just
> put the list_entry attribute under qemu_clk ? I haven't
> tried, may be I am wrong but that would simplify the code.

Yes I think it is needed. Actually I didn't find anything which
does this differently.

> 
>>  /**
>>   * qemu_clk_device_add_clock:
>>   * @dev: the device on which the clock needs to be added.
>> @@ -59,4 +72,58 @@ void qemu_clk_device_add_clock(DeviceState *dev, qemu_clk 
>> clk,
>>   */
>>  qemu_clk qemu_clk_device_get_clock(DeviceState *dev, const char *name);
>>  
>> +/**
>> + * qemu_clk_bind_clock:
>> + * @out: the clock output.
>> + * @in: the clock input.
>> + *
>> + * Connect the clock together. This is unidirectional so a
>> + * qemu_clk_update_rate will go from @out to @in.
>> + *
>> + */
>> +void qemu_clk_bind_clock(qemu_clk out, qemu_clk in);
> 
> maybe remove the  _clock suffix. It feels redundant.

Ok.

Thanks,
Fred

> 
> Thanks,
> 
> C. 
> 
>> +
>> +/**
>> + * qemu_clk_unbind:
>> + * @out: the clock output.
>> + * @in: the clock input.
>> + *
>> + * Disconnect the clocks if they were bound together.
>> + *
>> + */
>> +void qemu_clk_unbind(qemu_clk out, qemu_clk in);
>> +
>> +/**
>> + * qemu_clk_update_rate:
>> + * @clk: the clock to update.
>> + * 

Re: [Qemu-devel] [PATCH V2 02/10] qemu-clk: allow to add a clock to a device

2017-02-07 Thread Frederic Konrad
On 02/06/2017 03:20 PM, Cédric Le Goater wrote:
> On 01/26/2017 10:47 AM, fred.kon...@greensocs.com wrote:
>> From: KONRAD Frederic 
>>
>> This allows to add a clock to a DeviceState.
>> Contrary to gpios, the clock pins are not contained in the DeviceState but
>> with the child property so they can appears in the qom-tree.
>>
>> Signed-off-by: KONRAD Frederic 
>>
>> V1 -> V2:
>>   * Rename the function use 'add' instead of 'attach'
>> ---
>>  include/qemu/qemu-clock.h | 24 +++-
>>  qemu-clock.c  | 23 +++
>>  2 files changed, 46 insertions(+), 1 deletion(-)
>>
>> diff --git a/include/qemu/qemu-clock.h b/include/qemu/qemu-clock.h
>> index e7acd68..3e692d3 100644
>> --- a/include/qemu/qemu-clock.h
>> +++ b/include/qemu/qemu-clock.h
>> @@ -33,8 +33,30 @@
>>  typedef struct qemu_clk {
>>  /*< private >*/
>>  Object parent_obj;
>> +char *name;/* name of this clock in the device. */
>>  } *qemu_clk;
>>  
>> -#endif /* QEMU_CLOCK_H */
>> +/**
>> + * qemu_clk_device_add_clock:
>> + * @dev: the device on which the clock needs to be added.
>> + * @clk: the clock which needs to be added.
>> + * @name: the name of the clock can't be NULL.
>> + *
>> + * Add @clk to device @dev as a clock named @name.
>> + *
>> + */
>> +void qemu_clk_device_add_clock(DeviceState *dev, qemu_clk clk,
>> +   const char *name);
>>  
>> +/**
>> + * qemu_clk_device_get_clock:
>> + * @dev: the device which contains the clock.
>> + * @name: the name of the clock.
>> + *
>> + * Get the clock named @name contained in the device @dev, or NULL if not 
>> found.
>> + *
>> + * Returns the clock named @name contained in @dev.
>> + */
>> +qemu_clk qemu_clk_device_get_clock(DeviceState *dev, const char *name);
>>  
>> +#endif /* QEMU_CLOCK_H */
>> diff --git a/qemu-clock.c b/qemu-clock.c
>> index ceea98d..803deb3 100644
>> --- a/qemu-clock.c
>> +++ b/qemu-clock.c
>> @@ -25,6 +25,7 @@
>>  #include "qemu/qemu-clock.h"
>>  #include "hw/hw.h"
>>  #include "qemu/log.h"
>> +#include "qapi/error.h"
>>  
>>  #ifndef DEBUG_QEMU_CLOCK
>>  #define DEBUG_QEMU_CLOCK 0
>> @@ -36,6 +37,28 @@
>>  }   
>>  \
>>  } while (0);
>>  
>> +void qemu_clk_device_add_clock(DeviceState *dev, qemu_clk clk,
>> +   const char *name)
>> +{
>> +assert(name);
>> +assert(!clk->name);
>> +object_property_add_child(OBJECT(dev), name, OBJECT(clk), _abort);
>> +clk->name = g_strdup(name);
>> +}
>> +
>> +qemu_clk qemu_clk_device_get_clock(DeviceState *dev, const char *name)
>> +{
>> +gchar *path = NULL;
>> +Object *clk;
>> +bool ambiguous;
>> +
>> +path = g_strdup_printf("%s/%s", object_get_canonical_path(OBJECT(dev)),
>> +   name);
>> +clk = object_resolve_path(path, );
>> +g_free(path);
>> +return QEMU_CLOCK(clk);
>> +}
> 
> 
> I see how these routines are used in patch 10/10. But if we were
> open coding device CRF_APB, I don't think we would need them at
> all and it would make the code a little simple IMHO.

What do you mean by open coding?

Fred
> 
> Thanks,
> 
> C.  
> 
>>  static const TypeInfo qemu_clk_info = {
>>  .name  = TYPE_CLOCK,
>>  .parent= TYPE_OBJECT,
>>
> 
> 




Re: [Qemu-devel] [PATCH V2 01/10] qemu-clk: introduce qemu-clk qom object

2017-02-07 Thread Frederic Konrad
On 02/05/2017 04:25 PM, Cédric Le Goater wrote:
> ello Frederic,

Hi Cédric,

Thanks for taking a look at this!

> 
> On 01/26/2017 10:47 AM, fred.kon...@greensocs.com wrote:
>> From: KONRAD Frederic <fred.kon...@greensocs.com>
>>
>> This introduces qemu-clk qom object.
>>
>> Signed-off-by: KONRAD Frederic <fred.kon...@greensocs.com>
>> ---
>>  Makefile.objs |  1 +
>>  include/qemu/qemu-clock.h | 40 +
>>  qemu-clock.c  | 50 
>> +++
>>  3 files changed, 91 insertions(+)
>>  create mode 100644 include/qemu/qemu-clock.h
>>  create mode 100644 qemu-clock.c
>>
>> diff --git a/Makefile.objs b/Makefile.objs
>> index 01cef86..de0219d 100644
>> --- a/Makefile.objs
>> +++ b/Makefile.objs
>> @@ -78,6 +78,7 @@ common-obj-y += backends/
>>  common-obj-$(CONFIG_SECCOMP) += qemu-seccomp.o
>>  
>>  common-obj-$(CONFIG_FDT) += device_tree.o
>> +common-obj-y += qemu-clock.o
>>  
>>  ##
>>  # qapi
>> diff --git a/include/qemu/qemu-clock.h b/include/qemu/qemu-clock.h
>> new file mode 100644
>> index 000..e7acd68
>> --- /dev/null
>> +++ b/include/qemu/qemu-clock.h
>> @@ -0,0 +1,40 @@
>> +/*
>> + * QEMU Clock
>> + *
>> + *  Copyright (C) 2016 : GreenSocs Ltd
>> + *  http://www.greensocs.com/ , email: i...@greensocs.com
>> + *
>> + *  Frederic Konrad <fred.kon...@greensocs.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation, either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License along
>> + * with this program; if not, see <http://www.gnu.org/licenses/>.
> 
> May be we could shorten the GPL v2 statement to something like :
>  
>  * This code is licensed under the GPL version 2 or later. See the
>  * COPYING file in the top-level directory.
> 
> I haven't been very good at that my self, but we could save 
> quite a few lines in qemu if files were not repeating the 
> License statement.

Well if it is really needed I can get rid of this few lines :).

> 
> 
>> + *
>> + */
>> +
>> +#ifndef QEMU_CLOCK_H
>> +#define QEMU_CLOCK_H
>> +
>> +#include "qemu/osdep.h"
>> +#include "qom/object.h"
>> +
>> +#define TYPE_CLOCK "qemu-clk"
>> +#define QEMU_CLOCK(obj) OBJECT_CHECK(struct qemu_clk, (obj), TYPE_CLOCK)
>> +
>> +typedef struct qemu_clk {
>> +/*< private >*/
>> +Object parent_obj;
>> +} *qemu_clk;
>>
> 
> CODING_STYLE says that we should use CamelCase for typedef. Also, I don't 
> think the '*' is required. What's the idea ? 

Your right, I tried to follow the gpio "style".. But maybe it's old and
we better go for the camelcase and without the pointer.

> 
>> +#endif /* QEMU_CLOCK_H */
>> +
>> +
>> diff --git a/qemu-clock.c b/qemu-clock.c
>> new file mode 100644
>> index 000..ceea98d
>> --- /dev/null
>> +++ b/qemu-clock.c
>> @@ -0,0 +1,50 @@
>> +/*
>> + * QEMU Clock
>> + *
>> + *  Copyright (C) 2016 : GreenSocs Ltd
>> + *  http://www.greensocs.com/ , email: i...@greensocs.com
>> + *
>> + *  Frederic Konrad <fred.kon...@greensocs.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation, either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License along
>> + * with this program; if not, see <http://www.gnu.org/licenses/>.

Re: [Qemu-devel] [RFC 0/5] execute code from mmio area

2017-02-04 Thread Frederic Konrad
On 02/04/2017 02:17 PM, Peter Maydell wrote:
> On 4 February 2017 at 12:52, Frederic Konrad <fred.kon...@greensocs.com> 
> wrote:
>> Is that the case that we might get a Bad RAM address error or some such
>> if we are not on a page boundary (or too small as you say)?
>> I guess this is a limitation. Mapping on a page boundary shouldn't be
>> too much restrictive.
> 
> Yeah. I really ought to look more closely at what the flow of
> execution is here, because I think how it works right now
> is a bit weird and works as much by luck as by judgement
> (we can longjump out of the middle of translating code
> right back to the cpu-exec.c loop, and in some cases
> I think what happens is that we try to translate code,
> and as part of the "load didn't work" code path we
> nestedly try to translate the same thing again which
> of course fails again, only the second time around we
> realize and longjump out.
> 
> (At the moment for linux-user mode this is causing us to
> assert about taking the tb lock twice, because we hold
> the tb lock during translation and then try to grab it
> again to do the cpu_restore_state() in the signal handler.)
> 

Yes it seems there are some scary things happening there.

Fred

> thanks
> -- PMM
> 




Re: [Qemu-devel] [RFC 4/5] exec: allow to get a pointer for some mmio memory region

2017-02-04 Thread Frederic Konrad
On 02/04/2017 01:41 PM, Paolo Bonzini wrote:
> 
...
>>
>> Doesn't hotplug use dynamic MemoryRegion? In which case we better
>> make that work with MTTCG. I wonder if we can't simply handle that
>> with a safe_work for this case?
> 
> Hot-unplug works because the backing memory is only freed when the
> device gets instance_finalize, so at that point the region cannot have
> any references.
> 
> What can go wrong is the following (from the docs):
> 
> - the memory region's owner had a reference taken via memory_region_ref
>   (for example by address_space_map)
> 
> - the region is unparented, and has no owner anymore
> 
> - when address_space_unmap is called, the reference to the memory
>   region's owner is leaked.

true.

> 
> In your case you have phys_section_add/phys_section_destroy instead of
> address_space_map/unmap, but the problem is the same.
> 
> I am a bit unsure about using the same lqspi_buf for caching different
> addresses, and about using the same buffer for MMIO execution and read.
> What if you allocate a different buffer every time
> lqspi_request_mmio_ptr is called (adding a char* argument to
> lqspi_load_cache) and free the old one from the safe_work item, after a
> global TLB flush?  Then you don't need the Notifiers which were the
> complicated and handwavy part of my proposal.

Actually this was just because it was the way xilinx_qspi worked.
It load 1K of SPI data and fill the buffer.

In some other case we don't want to free the pointer at all, just make
it not accessible for execution / read.
(BTW I'll add the read-only property to this).

What about a simple Object eg: mmio-execution-interface which has a
MemoryRegion? Instead of creating the MemoryRegion in request_pointer,
We create a mmio-execution-interface object which create and map the
region on the subregion.
Then in invalidate: we unplug the mmio-execution-interface, unref it and
it is freed all by magic when the map doesn't need it.

This avoid the reference issue and probably the bug with MTTCG.

Fred

> 
> Paolo
> 
>>
>> BTW the tests I have seems to pass without issues.
>>
>>>
>>> An alternative design could be:
>>>
>>> - memory_region_request_mmio_ptr returns a MemoryRegionCache instead of
>>> a pointer, so that the device can map a subset of the device (e.g. a
>>> single page)
>>
>> I'm not aware of this MemoryRegionCache yet, it seems pretty new.
>> I'll take a look.
>>
>> Thanks,
>> Fred
>>
>>>
>>> - memory_region_request_mmio_ptr and MemoryRegionOps.request_ptr accept
>>> a Notifier
>>>
>>> - the device adds the Notifier to a NotifierList.  Before invalidating,
>>> it invokes the Notifier and empties the NotifierList.
>>>
>>> - for the TLB case, the Notifier calls tlb_flush_page.
>>>
>>> I like the general idea though!
>>>
>>> Paolo
>>>
 +}
 +}
>>
>>
>>




Re: [Qemu-devel] [RFC 0/5] execute code from mmio area

2017-02-04 Thread Frederic Konrad
On 02/04/2017 01:33 PM, Peter Maydell wrote:
> On 3 February 2017 at 17:06,   wrote:
>> From: KONRAD Frederic 
>>
>> This patch-set allows to execute code from mmio areas.
>> The main goal of this is to be able to run code for example from an SPI 
>> device.
>>
>> The three first patch fixes the way get_page_addr_code fills the TLB.
>>
>> The fourth patch implements the mmio execution helpers: the device must
>> implement the request_ptr callback of the MemoryRegion and will be notified 
>> when
>> the guest wants to execute code from it.
>>
>> The fifth patch implements the execution from the SPI memories in the
>> xilinx_spips model.
> 
> I like the general idea, but there's an awkward issue:
> at the moment our translation system assumes that when we're
> translating code then if the first instruction in the TB
> can be read OK then we won't ever get a fault trying to
> read subsequent bytes up to the end of the page. If we
> move from "we only translate code out of whole pages of
> RAM" to "we might translate code out of devices that
> are in subpages" then this assumption gets broken.
> (The symptom would be that we would report the fault
> in the wrong place, for the PC at the start of the TB.)
> 
> thanks
> -- PMM
> 

Hi Peter,

I think I see your point.
Is that the case that we might get a Bad RAM address error or some such
if we are not on a page boundary (or too small as you say)?
I guess this is a limitation. Mapping on a page boundary shouldn't be
too much restrictive.

Thanks,
Fred



Re: [Qemu-devel] [RFC 1/5] cputlb: cleanup get_page_addr_code to use VICTIM_TLB_HIT

2017-02-04 Thread Frederic Konrad
On 02/04/2017 12:30 PM, Edgar E. Iglesias wrote:
> On Fri, Feb 03, 2017 at 06:06:33PM +0100, fred.kon...@greensocs.com wrote:
>> From: KONRAD Frederic 
>>
>> This replaces env1 and page_index variables by env and index
>> so we can use VICTIM_TLB_HIT macro later.
>>
> 
> Hi Fred,
> 
> A question, wouldn't it be more readable to add env and index arguments to 
> VICTIM_TLB_HIT?
> VICTIM_TLB_HIT could perhaps even be made a static inline?
> 
> Cheers,
> Edgar

Hi Edgar,

Well it seems the VICTIM_TLB_HIT macro is just here to hide those
variables actually.

in cputlb.c:
static bool victim_tlb_hit(CPUArchState *env, size_t mmu_idx,
   size_t index, size_t elt_ofs,
   target_ulong page)

and then:
/* Macro to call the above, with local variables from the use context.  */
#define VICTIM_TLB_HIT(TY, ADDR) \
  victim_tlb_hit(env, mmu_idx, index, offsetof(CPUTLBEntry, TY), \
 (ADDR) & TARGET_PAGE_MASK)

My point of view is clearly that it makes more difficult to read.
So if everybody agrees I can drop the macro and call directly
victim_tlb_hit.

Fred


> 
> 
>  
>> Signed-off-by: KONRAD Frederic 
>> ---
>>  cputlb.c | 18 +-
>>  1 file changed, 9 insertions(+), 9 deletions(-)
>>
>> diff --git a/cputlb.c b/cputlb.c
>> index 6c39927..665caea 100644
>> --- a/cputlb.c
>> +++ b/cputlb.c
>> @@ -457,21 +457,21 @@ static void report_bad_exec(CPUState *cpu, 
>> target_ulong addr)
>>   * is actually a ram_addr_t (in system mode; the user mode emulation
>>   * version of this function returns a guest virtual address).
>>   */
>> -tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
>> +tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr)
>>  {
>> -int mmu_idx, page_index, pd;
>> +int mmu_idx, index, pd;
>>  void *p;
>>  MemoryRegion *mr;
>> -CPUState *cpu = ENV_GET_CPU(env1);
>> +CPUState *cpu = ENV_GET_CPU(env);
>>  CPUIOTLBEntry *iotlbentry;
>>  
>> -page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
>> -mmu_idx = cpu_mmu_index(env1, true);
>> -if (unlikely(env1->tlb_table[mmu_idx][page_index].addr_code !=
>> +index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
>> +mmu_idx = cpu_mmu_index(env, true);
>> +if (unlikely(env->tlb_table[mmu_idx][index].addr_code !=
>>   (addr & TARGET_PAGE_MASK))) {
>> -cpu_ldub_code(env1, addr);
>> +cpu_ldub_code(env, addr);
>>  }
>> -iotlbentry = >iotlb[mmu_idx][page_index];
>> +iotlbentry = >iotlb[mmu_idx][index];
>>  pd = iotlbentry->addr & ~TARGET_PAGE_MASK;
>>  mr = iotlb_to_region(cpu, pd, iotlbentry->attrs);
>>  if (memory_region_is_unassigned(mr)) {
>> @@ -484,7 +484,7 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, 
>> target_ulong addr)
>>  exit(1);
>>  }
>>  }
>> -p = (void *)((uintptr_t)addr + 
>> env1->tlb_table[mmu_idx][page_index].addend);
>> +p = (void *)((uintptr_t)addr + env->tlb_table[mmu_idx][index].addend);
>>  return qemu_ram_addr_from_host_nofail(p);
>>  }
>>  
>> -- 
>> 1.8.3.1
>>




Re: [Qemu-devel] [RFC 4/5] exec: allow to get a pointer for some mmio memory region

2017-02-03 Thread Frederic Konrad
On 02/03/2017 06:26 PM, Paolo Bonzini wrote:
> 
> 
> On 03/02/2017 09:06, fred.kon...@greensocs.com wrote:
>> +host = mr->ops->request_ptr(mr->opaque, addr - mr->addr, , 
>> );
>> +
>> +if (!host || !size) {
>> +memory_region_transaction_commit();
>> +return false;
>> +}
>> +
>> +sub = g_new(MemoryRegion, 1);
>> +memory_region_init_ram_ptr(sub, OBJECT(mr), "mmio-map", size, host);
>> +memory_region_add_subregion(mr, offset, sub);
>> +memory_region_transaction_commit();
>> +return true;
>> +}
>> +
>> +void memory_region_invalidate_mmio_ptr(MemoryRegion *mr, hwaddr offset,
>> +   unsigned size)
>> +{
>> +MemoryRegionSection section = memory_region_find(mr, offset, size);
>> +
>> +if (section.mr != mr) {
>> +memory_region_del_subregion(mr, section.mr);
>> +/* memory_region_find add a ref on section.mr */
>> +memory_region_unref(section.mr);
>> +object_unparent(OBJECT(section.mr));
> 
> I think this would cause a use-after-free when using MTTCG.  In general,
> creating and dropping MemoryRegions dynamically can cause bugs that are
> nondeterministic and hard to fix without rewriting everything.

Hi Paolo,

Thanks for your comment.
Yes, I read in the docs that dynamically dropping MemoryRegions is badly
broken when we use NULL as an owner because the machine owns it.
But it seems nothing said this is the case with an owner.

But I think I see your point here:
  * memory_region_unref will unref the owner.
  * object_unparent will unref the memory region (which should be 1).
  => the region will be dropped immediately.

Doesn't hotplug use dynamic MemoryRegion? In which case we better
make that work with MTTCG. I wonder if we can't simply handle that
with a safe_work for this case?

BTW the tests I have seems to pass without issues.

> 
> An alternative design could be:
> 
> - memory_region_request_mmio_ptr returns a MemoryRegionCache instead of
> a pointer, so that the device can map a subset of the device (e.g. a
> single page)

I'm not aware of this MemoryRegionCache yet, it seems pretty new.
I'll take a look.

Thanks,
Fred

> 
> - memory_region_request_mmio_ptr and MemoryRegionOps.request_ptr accept
> a Notifier
> 
> - the device adds the Notifier to a NotifierList.  Before invalidating,
> it invokes the Notifier and empties the NotifierList.
> 
> - for the TLB case, the Notifier calls tlb_flush_page.
> 
> I like the general idea though!
> 
> Paolo
> 
>> +}
>> +}




Re: [Qemu-devel] [PATCH V2 00/10] Clock framework API.

2017-02-03 Thread Frederic Konrad
Ping!

Thanks,
Fred

On 01/26/2017 10:47 AM, fred.kon...@greensocs.com wrote:
> From: KONRAD Frederic 
> 
> Hi,
> 
> This is the second version of the clock framework API it contains:
> 
>   * The first 6 patches which introduce the framework.
>   * The 7th patch which introduces a fixed-clock model.
>   * The rest which gives an example how to model a PLL from the existing
> zynqmp-crf extracted from the qemu xilinx tree.
> 
> No specific behavior is expected yet when the CRF register set is accessed but
> the user can see for example the dp_video_ref and vpll_to_lpd rate changing in
> the monitor with the "info qtree" command when the vpll_ctrl register is
> modified.
> 
> bus: main-system-bus
>   type System
>   dev: xlnx.zynqmp_crf, id ""
> gpio-out "sysbus-irq" 1
> qemu-clk "dbg_trace" 0
> qemu-clk "dp_stc_ref" 0
> qemu-clk "dpll_to_lpd" 1250
> qemu-clk "acpu_clk" 0
> qemu-clk "pcie_ref" 0
> qemu-clk "topsw_main" 0
> qemu-clk "topsw_lsbus" 0
> qemu-clk "dp_audio_ref" 0
> qemu-clk "sata_ref" 0
> qemu-clk "dp_video_ref" 1428571
> qemu-clk "vpll_clk" 5000
> qemu-clk "apll_to_lpd" 1250
> qemu-clk "dpll_clk" 5000
> qemu-clk "gpu_ref" 0
> qemu-clk "aux_refclk" 0
> qemu-clk "video_clk" 2700
> qemu-clk "gdma_ref" 0
> qemu-clk "gt_crx_ref_clk" 0
> qemu-clk "dbg_fdp" 0
> qemu-clk "apll_clk" 5000
> qemu-clk "pss_alt_ref_clk" 0
> qemu-clk "ddr" 0
> qemu-clk "dbg_tstmp" 0
> qemu-clk "pss_ref_clk" 5000
> qemu-clk "dpdma_ref" 0
> qemu-clk "vpll_to_lpd" 1250
> mmio fd1a/010c
> 
> This series is based on the current master
> (a9e404600a9bd1e6a26431fc89e5069092e67f14).
> 
> Thanks,
> Fred
> 
> V1 -> V2:
>   * Rebased on current master.
>   * Some function renamed and documentation fixed.
> 
> RFC -> V1:
>   * Rebased on current master.
>   * The docs has been fixed.
>   * qemu_clk_init_device helper has been provided to ease the initialization
> of the devices.
> 
> KONRAD Frederic (10):
>   qemu-clk: introduce qemu-clk qom object
>   qemu-clk: allow to add a clock to a device
>   qemu-clk: allow to bind two clocks together
>   qemu-clk: introduce an init array to help the device construction
>   qdev-monitor: print the device's clock with info qtree
>   docs: add qemu-clock documentation
>   introduce fixed-clock
>   introduce zynqmp_crf
>   zynqmp: add the zynqmp_crf to the platform
>   zynqmp: add reference clock
> 
>  Makefile.objs |   1 +
>  docs/clock.txt| 108 +
>  hw/arm/xlnx-zynqmp.c  |  56 +++
>  hw/misc/Makefile.objs |   2 +
>  hw/misc/fixed-clock.c |  88 
>  hw/misc/xilinx_zynqmp_crf.c   | 968 
> ++
>  include/hw/arm/xlnx-zynqmp.h  |   8 +
>  include/hw/misc/fixed-clock.h |  30 ++
>  include/qemu/qemu-clock.h | 161 +++
>  qdev-monitor.c|   2 +
>  qemu-clock.c  | 174 
>  11 files changed, 1598 insertions(+)
>  create mode 100644 docs/clock.txt
>  create mode 100644 hw/misc/fixed-clock.c
>  create mode 100644 hw/misc/xilinx_zynqmp_crf.c
>  create mode 100644 include/hw/misc/fixed-clock.h
>  create mode 100644 include/qemu/qemu-clock.h
>  create mode 100644 qemu-clock.c
> 




Re: [Qemu-devel] implementing architectural timers using QEMU timers

2017-01-10 Thread Frederic Konrad
On 01/09/2017 04:18 PM, Max Filippov wrote:
> Hello,
> 
> I'm trying to reimplement xtensa CCOUNT (cycle counter) and
> CCOMPARE (CCOUNT-based timer interrupts) using QEMU
> timers. That is CCOUNT value is derived from the
> QEMU_CLOCK_VIRTUAL clock and CCOMPARE interrupts are
> generated from the QEMU_CLOCK_VIRTUAL timer callbacks.
> The code is here:
>   https://github.com/OSLL/qemu-xtensa/commits/xtensa-ccount
> 
> I've got the following issues doing that:
> 
> - in non-icount mode I can often read CCOUNT and get a value
>   that is greater than programmed CCOMPARE value, which
>   means that QEMU timer must have been fired at that point, but
>   no sign of timer callback being called. That is timer callback
>   invocation lags behind due time.
> 
>   Is my understanding correct that there's no hard expectations
>   that firing of QEMU timers will be correctly sequenced with
>   readings of QEMU clock?
> 
> - I thought that could be improved in -icount mode, so I tried that.
>   It is better with -icount, but it's still not 100% accurate. That is
>   I was able to observe guest reading QEMU clock value that is
>   past QEMU timer deadline before that timer callback was
>   invoked.
> 
>   That sounds like a bug to me, is it?

Did you try "sleep" icount option?

eg:
-icount 1,sleep=off

Fred

> 
> - when guest sets a timer and halts itself waiting for timer
>   interrupt with waiti opcode QEMU behaviour is very strange with
>   -icount: regardless of the programmed timeout QEMU waits for
>   about a second before it delivers interrupt, and, AFAICT,
>   interrupt delivery it is not caused by the corresponding CCOUNT
>   timer. I was able to track this issue down to the
>   qemu_clock_use_for_deadline function, i.e. always returning true
>   'fixes' that unwanted delay, but looking around the timer code
>   I've got the impression that that's not the correct fix.
> 
>   Any suggestions on how to fix that?
> 




Re: [Qemu-devel] [PATCH v2] i2c: Fix SMBus read transactions to avoid double events

2016-07-06 Thread Frederic Konrad
On 06/28/2016 09:30 PM, miny...@acm.org wrote:
> From: Corey Minyard 
> 
> Change 2293c27faddf (i2c: implement broadcast write) added broadcast
> capability to the I2C bus, but it broke SMBus read transactions.
> An SMBus read transaction does two i2c_start_transaction() calls
> without an intervening i2c_end_transfer() call.  This will
> result in i2c_start_transfer() adding the same device to the
> current_devs list twice, and then the ->event() for the same
> device gets called twice in the second call to i2c_start_transfer(),
> resulting in the smbus code getting confused.

Hi Corey,

I didn't know that we can do two i2c_start_transfer without an
end_transfert in the middle. Maybe worth a comment in the code?

Otherwise:
Reviewed-by: KONRAD Frederic 
Tested-by: KONRAD Frederic 

Thanks,
Fred

> 
> Note that this happens even with pure I2C devices when simulating
> SMBus over I2C.
> 
> This fix only scans the bus if the current set of devices is empty.
> This means that the current set of devices stays fixed until
> i2c_end_transfer() is called, which is really what you want.
> 
> This also deletes the empty check from the top of i2c_end_transfer().
> It's unnecessary, and it prevents the broadcast variable from being
> set to false at the end of the transaction if no devices were on
> the bus.
> 
> Cc: KONRAD Frederic 
> Cc: Alistair Francis 
> Cc: Peter Crosthwaite 
> Cc: Kwon 
> Cc: Peter Maydell 
> Signed-off-by: Corey Minyard 
> ---
>  hw/i2c/core.c | 28 +++-
>  1 file changed, 15 insertions(+), 13 deletions(-)
> 
> This fix should work with I2C devices as well as SMBus devices.
> 
> Sorry for not thinking it through all the way before.
> 
> diff --git a/hw/i2c/core.c b/hw/i2c/core.c
> index abb3efb..6313d31 100644
> --- a/hw/i2c/core.c
> +++ b/hw/i2c/core.c
> @@ -101,15 +101,21 @@ int i2c_start_transfer(I2CBus *bus, uint8_t address, 
> int recv)
>  bus->broadcast = true;
>  }
>  
> -QTAILQ_FOREACH(kid, >qbus.children, sibling) {
> -DeviceState *qdev = kid->child;
> -I2CSlave *candidate = I2C_SLAVE(qdev);
> -if ((candidate->address == address) || (bus->broadcast)) {
> -node = g_malloc(sizeof(struct I2CNode));
> -node->elt = candidate;
> -QLIST_INSERT_HEAD(>current_devs, node, next);
> -if (!bus->broadcast) {
> -break;
> +/*
> + * If there are already devices in the list, that means we are in
> + * the middle of a transaction and we shouldn't rescan the bus.
> + */
> +if (QLIST_EMPTY(>current_devs)) {
> +QTAILQ_FOREACH(kid, >qbus.children, sibling) {
> +DeviceState *qdev = kid->child;
> +I2CSlave *candidate = I2C_SLAVE(qdev);
> +if ((candidate->address == address) || (bus->broadcast)) {
> +node = g_malloc(sizeof(struct I2CNode));
> +node->elt = candidate;
> +QLIST_INSERT_HEAD(>current_devs, node, next);
> +if (!bus->broadcast) {
> +break;
> +}
>  }
>  }
>  }
> @@ -134,10 +140,6 @@ void i2c_end_transfer(I2CBus *bus)
>  I2CSlaveClass *sc;
>  I2CNode *node, *next;
>  
> -if (QLIST_EMPTY(>current_devs)) {
> -return;
> -}
> -
>  QLIST_FOREACH_SAFE(node, >current_devs, next, next) {
>  sc = I2C_SLAVE_GET_CLASS(node->elt);
>  if (sc->event) {
> 




Re: [Qemu-devel] [PATCH for-2.7] aux: Rename aux.[ch] to auxbus.[ch] for the benefit of Windows

2016-07-06 Thread Frederic Konrad
On 07/01/2016 02:45 PM, Peter Maydell wrote:
> On Windows 'aux.*' is a reserved name and cannot be used for
> filenames; see
>   
> https://msdn.microsoft.com/en-gb/library/windows/desktop/aa365247(v=vs.85).aspx
> 
> This prevents cloning the QEMU git repo on Windows:
> 
> C:\Java\sources\kvm> git clone https://github.com/qemu/qemu.git
> Cloning into 'qemu'...
> remote: Counting objects: 279563, done.
> remote: Total 279563 (delta 0), reused 0 (delta 0), pack-reused 279563R
> Receiving objects: 100% (279563/279563), 122.45 MiB | 3.52 MiB/s, done.
> Resolving deltas: 100% (221942/221942), done.
> Checking connectivity... done.
> error: unable to create file hw/misc/aux.c (No such file or directory)
> error: unable to create file include/hw/misc/aux.h (No such file or directory)
> Checking out files: 100% (4795/4795), done.
> fatal: unable to checkout working tree
> warning: Clone succeeded, but checkout failed.
> You can inspect what was checked out with 'git status'
> and retry the checkout with 'git checkout -f HEAD'
> 
> (bug https://bugs.launchpad.net/bugs/1595240)
> 
> Rename the offending files for the benefit of Windows.
> 
> Reported-by: Алексей Курган 
> Signed-off-by: Peter Maydell 

oops sorry for that :).

Tested-by: KONRAD Frederic 

Thanks,
Fred

> ---
>  hw/display/dpcd.c   | 2 +-
>  hw/misc/Makefile.objs   | 2 +-
>  hw/misc/{aux.c => auxbus.c} | 4 ++--
>  include/hw/display/xlnx_dp.h| 2 +-
>  include/hw/misc/{aux.h => auxbus.h} | 2 +-
>  5 files changed, 6 insertions(+), 6 deletions(-)
>  rename hw/misc/{aux.c => auxbus.c} (99%)
>  rename include/hw/misc/{aux.h => auxbus.h} (99%)
> 
> diff --git a/hw/display/dpcd.c b/hw/display/dpcd.c
> index 5a36855..ce92ff6 100644
> --- a/hw/display/dpcd.c
> +++ b/hw/display/dpcd.c
> @@ -28,7 +28,7 @@
>  
>  #include "qemu/osdep.h"
>  #include "qemu/log.h"
> -#include "hw/misc/aux.h"
> +#include "hw/misc/auxbus.h"
>  #include "hw/display/dpcd.h"
>  
>  #ifndef DEBUG_DPCD
> diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
> index 54020aa..4cfbd10 100644
> --- a/hw/misc/Makefile.objs
> +++ b/hw/misc/Makefile.objs
> @@ -51,5 +51,5 @@ obj-$(CONFIG_MIPS_ITU) += mips_itu.o
>  obj-$(CONFIG_PVPANIC) += pvpanic.o
>  obj-$(CONFIG_EDU) += edu.o
>  obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
> -obj-$(CONFIG_AUX) += aux.o
> +obj-$(CONFIG_AUX) += auxbus.o
>  obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o
> diff --git a/hw/misc/aux.c b/hw/misc/auxbus.c
> similarity index 99%
> rename from hw/misc/aux.c
> rename to hw/misc/auxbus.c
> index 25d7712..df2414b 100644
> --- a/hw/misc/aux.c
> +++ b/hw/misc/auxbus.c
> @@ -1,5 +1,5 @@
>  /*
> - * aux.c
> + * auxbus.c
>   *
>   *  Copyright 2015 : GreenSocs Ltd
>   *  http://www.greensocs.com/ , email: i...@greensocs.com
> @@ -28,7 +28,7 @@
>  
>  #include "qemu/osdep.h"
>  #include "qemu/log.h"
> -#include "hw/misc/aux.h"
> +#include "hw/misc/auxbus.h"
>  #include "hw/i2c/i2c.h"
>  #include "monitor/monitor.h"
>  
> diff --git a/include/hw/display/xlnx_dp.h b/include/hw/display/xlnx_dp.h
> index d3a03f1..ee046a5 100644
> --- a/include/hw/display/xlnx_dp.h
> +++ b/include/hw/display/xlnx_dp.h
> @@ -24,7 +24,7 @@
>  
>  #include "hw/sysbus.h"
>  #include "ui/console.h"
> -#include "hw/misc/aux.h"
> +#include "hw/misc/auxbus.h"
>  #include "hw/i2c/i2c.h"
>  #include "hw/display/dpcd.h"
>  #include "hw/i2c/i2c-ddc.h"
> diff --git a/include/hw/misc/aux.h b/include/hw/misc/auxbus.h
> similarity index 99%
> rename from include/hw/misc/aux.h
> rename to include/hw/misc/auxbus.h
> index 759c3bf..af39db7 100644
> --- a/include/hw/misc/aux.h
> +++ b/include/hw/misc/auxbus.h
> @@ -1,5 +1,5 @@
>  /*
> - * aux.h
> + * auxbus.h
>   *
>   *  Copyright (C)2014 : GreenSocs Ltd
>   *  http://www.greensocs.com/ , email: i...@greensocs.com
> 




Re: [Qemu-devel] Making all TB invalidation asynchronous (MTTCG safe_work)?

2016-02-25 Thread Frederic Konrad
Hi Alex,

We decided in Seattle to make this flag per tb (eg move it to the tb
struct).



On 24/02/2016 18:30, Alex Bennée wrote:
> Hi,
>
> So I've been working on reducing MTTCG tb_lock contention and currently
> have a tb_lock around the following code (in my cpu_exec):
>
> /* Note: we do it here to avoid a gcc bug on Mac OS X when
>doing it in tb_find_slow */
> tb_lock();
> if (tcg_ctx.tb_ctx.tb_invalidated_flag) {
> /* as some TB could have been invalidated because
>of memory exceptions while generating the code, we
>must recompute the hash index here */
> next_tb = 0;
> tcg_ctx.tb_ctx.tb_invalidated_flag = 0;
> }
> /* see if we can patch the calling TB. When the TB
>spans two pages, we cannot safely do a direct
>jump. */
> if (next_tb != 0 && tb->page_addr[1] == -1
> && !qemu_loglevel_mask(CPU_LOG_TB_NOCHAIN)) {
> tb_add_jump((TranslationBlock *)(next_tb & ~TB_EXIT_MASK),
> next_tb & TB_EXIT_MASK, tb);
> }
> tb_unlock();
>
> And this started me down the rabbit hole of the meaning of
> tcg_ctx.tb_ctx.tb_invalidated_flag. So as far as I follow there are two
> places this is set:
>
>  * We've run out of translation memory and we are throwing everything
>away (tb_alloc == NULL)
>  * We've invalidated the physical pages of some TranslationBlocks
>
> The first case there is a slightly convoluted buffer overflow handing
> code (tb_gen_code):
>
> if (unlikely(!tb)) {
>  buffer_overflow:
> /* flush must be done */
> tb_flush_safe(cpu);
> /* Don't forget to invalidate previous TB info.  */
> tcg_ctx.tb_ctx.tb_invalidated_flag = 1;
> tb_unlock();
> cpu_loop_exit(cpu);
> }
>
> Which I'm sure could be more simply handled by just queuing the safe
> tb_flush and returning a NULL tb and letting the execution loop unwind
> before resetting the translation buffers.
>
> The second case has been partially asynced by Fred:
>
> /* invalidate one TB */
> void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
> {
> CPUState *cpu;
> PageDesc *p;
> unsigned int h;
> tb_page_addr_t phys_pc;
> struct CPUDiscardTBParams *params;
>
> assert_tb_lock(); /* added by me because of bellow */
>
> /* remove the TB from the hash list */
> phys_pc = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
> h = tb_phys_hash_func(phys_pc);
> tb_hash_remove(_ctx.tb_ctx.tb_phys_hash[h], tb);
>
> /* remove the TB from the page list */
> if (tb->page_addr[0] != page_addr) {
> p = page_find(tb->page_addr[0] >> TARGET_PAGE_BITS);
> tb_page_remove(>first_tb, tb);
> invalidate_page_bitmap(p);
> }
> if (tb->page_addr[1] != -1 && tb->page_addr[1] != page_addr) {
> p = page_find(tb->page_addr[1] >> TARGET_PAGE_BITS);
> tb_page_remove(>first_tb, tb);
> invalidate_page_bitmap(p);
> }
>
> tcg_ctx.tb_ctx.tb_invalidated_flag = 1;
>
> CPU_FOREACH(cpu) {
> params = g_malloc(sizeof(struct CPUDiscardTBParams));
> params->cpu = cpu;
> params->tb = tb;
> async_run_on_cpu(cpu, cpu_discard_tb_from_jmp_cache, params);
> }
> async_run_safe_work_on_cpu(first_cpu, tb_invalidate_jmp_remove, tb);
>
> tcg_ctx.tb_ctx.tb_phys_invalidate_count++;
> }
>
> But I'm wondering why we can't defer all the page invalidation to safe
> work?
>
> I don't think it matters to the invalidating vCPU as it has to get
> to the end of its block anyway. For other vCPUs as there is no strict
> synchronisation can we not pretend what ever the operation was that
> triggered the invalidation happened just as the block ended?
>
> The final case I don't quite follow is the avoiding invalidation of
> tb_next in cpu_exec_nocache() if we have already caused a tb
> invalidation event:
>
> tb->orig_tb = tcg_ctx.tb_ctx.tb_invalidated_flag ? NULL : orig_tb;
>
> Which is later (in cpu_io_recompile):
>
> if (tb->cflags & CF_NOCACHE) {
> if (tb->orig_tb) {
> /* Invalidate original TB if this TB was generated in
>  * cpu_exec_nocache() */
> tb_phys_invalidate(tb->orig_tb, -1);
> }
> tb_free(tb);
> }
>
> My aim in all of this is to see if we can remove another flag from
> tb_ctx (one less thing to mutex access to) and make the code flow easier
> to follow. So remaining question:
>
> * Are there cases where not immediately invalidating the tb_page
>   structures would cause problems for the emulation?

Is that the same issue we might have with the memory barriers?

Fred
>
> Thanks in advance for any elucidation ;-)
>
> --
> Alex Bennée
>




Re: [Qemu-devel] [RFC PATCH 0/3] (Resend) TranslationBlock annotation mechanism

2016-01-28 Thread Frederic Konrad
Hi,

Is there a git tree with this series somewhere?
Looks nice.

Thanks,
Fred

On 14/01/2016 11:55, Peer Adelt wrote:
> Hey guys :)
>
> We have developed a generic concept to annotate TranslationBlocks during
> runtime. The initial idea was to use it for time annotation with data from
> static analysis tools. However, we have kept this approach as generic as
> possible to allow other kinds of annotation (e.g. power consumption, etc.).
>
> Our extension expects an XML file specifying the CFG of the program (similar
> to what you get from "gcc -ftree-dump-cfg"), where the edges are annotated
> with the data, that QEMU ought to accumulate during program execution. Each
> edge has a source and target context in which it is executed.
> For example: a for-loop that runs several times has its own context dependent
> edge for each iteration. We plan on making this more flexible by allowing
> to specify iterative context edges, i.e. from context n to context n+1.
>
> This approach is not limited to one target architecture but we only tested
> it for ARM and TriCore so far.
>
> To show the current state of this patch we have attached a very small example
> consisting of an ARM STM32F205 program and a timing annotation XML file (see
> reply to this letter). You can provide the XML file to QEMU with the 
> "-annotation " option. During execution, the "value_sum" field of
> the CPUState data structure will accumulate a total value of 70 (cycles).
>
> Are there any comments? Is this in general a good idea to be added to upstream
> QEMU?
>
> All the best,
> Peer
>
> Peer Adelt (3):
>   tb-annotation: Added annotation XML file parser
>   tb-annotation: Add control flow graph mapper
>   tb-annotation: Activate annotation extension
>
>  Makefile |   5 +-
>  Makefile.objs|   4 +
>  Makefile.target  |   4 +-
>  configure|  13 ++
>  include/exec/gen-icount.h|  18 +++
>  include/qom/cpu.h|   9 ++
>  include/tb-annotation/tb-annotation-parser.h |  29 +
>  include/tb-annotation/tb-annotation.h|  64 ++
>  qemu-options.hx  |   8 ++
>  tb-annotation/Makefile.objs  |   1 +
>  tb-annotation/tb-annotation-parser.c | 174 
> +++
>  tcg-runtime.c|  99 +++
>  tcg/tcg-runtime.h|   4 +
>  vl.c |  25 
>  14 files changed, 454 insertions(+), 3 deletions(-)
>  create mode 100644 include/tb-annotation/tb-annotation-parser.h
>  create mode 100644 include/tb-annotation/tb-annotation.h
>  create mode 100644 tb-annotation/Makefile.objs
>  create mode 100644 tb-annotation/tb-annotation-parser.c
>




Re: [Qemu-devel] [PATCH v2 11/16] qdev: Define qdev_get_gpio_out

2016-01-28 Thread Frederic Konrad
On 19/01/2016 23:35, Alistair Francis wrote:
> From: Peter Crosthwaite 
>
> An API similar to the existing qdev_get_gpio_in() except gets outputs.
> Useful for:
>
> 1: Implementing lightweight devices that don't want to keep pointers
> to their own GPIOs. They can get their GPIO pointers at runtime from
> QOM using this API.
>
> 2: testing or debugging code which may wish to override the
> hardware generated value of of a GPIO with a user specified value
> (E.G. interrupt injection).
>
> Signed-off-by: Peter Crosthwaite 
> Signed-off-by: Alistair Francis 
> ---
>
>  hw/core/qdev.c | 12 
>  include/hw/qdev-core.h |  2 ++
>  2 files changed, 14 insertions(+)
>
> diff --git a/hw/core/qdev.c b/hw/core/qdev.c
> index 2c7101d..308e4a1 100644
> --- a/hw/core/qdev.c
> +++ b/hw/core/qdev.c
> @@ -489,6 +489,18 @@ qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
>  return qdev_get_gpio_in_named(dev, NULL, n);
>  }
>  
> +qemu_irq qdev_get_gpio_out_named(DeviceState *dev, const char *name, int n)
> +{
> +char *propname = g_strdup_printf("%s[%d]",
> + name ? name : "unnamed-gpio-out", n);
> +return (qemu_irq)object_property_get_link(OBJECT(dev), propname, NULL);
> +}

Why don't we have the same implementation than qdev_get_gpio_in_named ?

qemu_irq qdev_get_gpio_in_named(DeviceState *dev, const char *name, int n)
{
NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);

assert(n >= 0 && n < gpio_list->num_in);
return gpio_list->in[n];
}

Thanks,
Fred
> +
> +qemu_irq qdev_get_gpio_out(DeviceState *dev, int n)
> +{
> +return qdev_get_gpio_out_named(dev, NULL, n);
> +}
> +
>  void qdev_connect_gpio_out_named(DeviceState *dev, const char *name, int n,
>   qemu_irq pin)
>  {
> diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
> index abcdee8..0a09b8a 100644
> --- a/include/hw/qdev-core.h
> +++ b/include/hw/qdev-core.h
> @@ -287,6 +287,8 @@ bool qdev_machine_modified(void);
>  
>  qemu_irq qdev_get_gpio_in(DeviceState *dev, int n);
>  qemu_irq qdev_get_gpio_in_named(DeviceState *dev, const char *name, int n);
> +qemu_irq qdev_get_gpio_out(DeviceState *dev, int n);
> +qemu_irq qdev_get_gpio_out_named(DeviceState *dev, const char *name, int n);
>  
>  void qdev_connect_gpio_out(DeviceState *dev, int n, qemu_irq pin);
>  void qdev_connect_gpio_out_named(DeviceState *dev, const char *name, int n,




Re: [Qemu-devel] [PATCH v1 00/15] data-driven device registers

2016-01-28 Thread Frederic Konrad
On 08/01/2016 11:40, Peter Maydell wrote:
> On 8 January 2016 at 00:39, Alistair Francis
>  wrote:
>> On Wed, Dec 16, 2015 at 8:33 AM, Alistair Francis
>>  wrote:
>>> On Tue, Dec 15, 2015 at 1:56 PM, Peter Maydell  
>>> wrote:
 On 15 December 2015 at 20:52, Peter Crosthwaite
  wrote:
> It needs to exist before it can be used so there is a bit of a chicken
> and egg problem there.
>> No one seems to be jumping at reviewing this. Can we just send a pull 
>> request?
> I don't necessarily require review [*]. I would like *somebody* other
> than you Xilinx folk to say "yes, I think I would use this for
> modelling devices". Otherwise all we have is "weird thing used
> only in two or three Xilinx devices and nowhere else", which I'm
> a bit reluctant to let into the tree. We already have a pretty
> wide divergence in how devices look just based on the various
> transitions from older to newer qdev/QOM/etc that are not complete.
>
> [*] by which I mean, I will review this series if you can find
> somebody else who's going to say they'd use it.
>
> thanks
> -- PMM
>

Hi Peter,

This is useful for us as well.
My point view is that it is an easy and clean way of implementing devices.
BTW we have the same mechanism to model devices in SystemC.

Thanks,
Fred





Re: [Qemu-devel] [PATCH V6 7/8] introduce xlnx-dp

2016-01-28 Thread Frederic Konrad
On 16/01/2016 02:51, Alistair Francis wrote:
> On Mon, Jan 4, 2016 at 10:25 AM,  <fred.kon...@greensocs.com> wrote:
>> From: KONRAD Frederic <fred.kon...@greensocs.com>
>>
>> This is the implementation of the DisplayPort.
>> It has an aux-bus to access dpcd and edid.
>>
>> Graphic plane is connected to the channel 3.
>> Video plane is connected to the channel 0.
>> Audio stream are connected to the channels 4 and 5.
>>
>> Signed-off-by: KONRAD Frederic <fred.kon...@greensocs.com>
>> Tested-By: Hyun Kwon <hyun.k...@xilinx.com>
>> ---
>>  hw/display/Makefile.objs |1 +
>>  hw/display/xlnx_dp.c | 1361 
>> ++
>>  include/hw/display/xlnx_dp.h |  110 
>>  3 files changed, 1472 insertions(+)
>>  create mode 100644 hw/display/xlnx_dp.c
>>  create mode 100644 include/hw/display/xlnx_dp.h
>>
>> diff --git a/hw/display/Makefile.objs b/hw/display/Makefile.objs
>> index 250a43f..3625ab2 100644
>> --- a/hw/display/Makefile.objs
>> +++ b/hw/display/Makefile.objs
>> @@ -43,3 +43,4 @@ virtio-gpu.o-libs += $(VIRGL_LIBS)
>>  virtio-gpu-3d.o-cflags := $(VIRGL_CFLAGS)
>>  virtio-gpu-3d.o-libs += $(VIRGL_LIBS)
>>  obj-$(CONFIG_DPCD) += dpcd.o
>> +obj-$(CONFIG_XLNX_ZYNQMP) += xlnx_dp.o
>> diff --git a/hw/display/xlnx_dp.c b/hw/display/xlnx_dp.c
>> new file mode 100644
>> index 000..4238d69
>> --- /dev/null
>> +++ b/hw/display/xlnx_dp.c
>> @@ -0,0 +1,1361 @@
>> +/*
>> + * xlnx_dp.c
>> + *
>> + *  Copyright (C) 2015 : GreenSocs Ltd
>> + *  http://www.greensocs.com/ , email: i...@greensocs.com
>> + *
>> + *  Developed by :
>> + *  Frederic Konrad   <fred.kon...@greensocs.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation, either version 2 of the License, or
>> + * (at your option)any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License along
>> + * with this program; if not, see <http://www.gnu.org/licenses/>.
>> + *
>> + */
>> +
>> +#include "hw/display/xlnx_dp.h"
>> +
>> +#ifndef DEBUG_DP
>> +#define DEBUG_DP 0
>> +#endif
>> +
>> +#define DPRINTF(fmt, ...) do {  
>>\
>> +if (DEBUG_DP) { 
>>\
>> +qemu_log("xlnx_dp: " fmt , ## __VA_ARGS__); 
>>\
>> +}   
>>\
>> +} while (0);
>> +
>> +/*
>> + * Register offset for DP.
>> + */
>> +#define DP_LINK_BW_SET  (0x >> 2)
>> +#define DP_LANE_COUNT_SET   (0x0004 >> 2)
>> +#define DP_ENHANCED_FRAME_EN(0x0008 >> 2)
>> +#define DP_TRAINING_PATTERN_SET (0x000C >> 2)
>> +#define DP_LINK_QUAL_PATTERN_SET(0x0010 >> 2)
>> +#define DP_SCRAMBLING_DISABLE   (0x0014 >> 2)
>> +#define DP_DOWNSPREAD_CTRL  (0x0018 >> 2)
>> +#define DP_SOFTWARE_RESET   (0x001C >> 2)
>> +#define DP_TRANSMITTER_ENABLE   (0x0080 >> 2)
>> +#define DP_MAIN_STREAM_ENABLE   (0x0084 >> 2)
>> +#define DP_FORCE_SCRAMBLER_RESET(0x00C0 >> 2)
>> +#define DP_VERSION_REGISTER (0x00F8 >> 2)
>> +#define DP_CORE_ID  (0x00FC >> 2)
>> +
>> +#define DP_AUX_COMMAND_REGISTER (0x0100 >> 2)
>> +#define AUX_ADDR_ONLY_MASK  (0x1000)
>> +#define AUX_COMMAND_MASK(0x0F00)
>> +#define AUX_COMMAND_SHIFT   (8)
>> +#define AUX_COMMAND_NBYTES  (0x000F)
>> +
>> +#define DP_AUX_WRITE_FIFO   (0x0104 >> 2)
>> +#define DP_AUX_ADDRESS  (0x0108 >> 2)
>> +#define DP_AUX_CLOCK_DIVIDER(0x010C >> 2)
>> +#define DP_TX_USER_FIFO_OVERFLOW

Re: [Qemu-devel] [PATCH V6 8/8] arm: xlnx-zynqmp: Add xlnx-dp and xlnx-dpdma

2016-01-28 Thread Frederic Konrad
On 16/01/2016 02:50, Alistair Francis wrote:
> On Mon, Jan 4, 2016 at 10:25 AM,   wrote:
>> From: KONRAD Frederic 
>>
>> This adds the DP and the DPDMA to the Zynq MP platform.
>>
>> Signed-off-by: KONRAD Frederic 
>> Reviewed-by: Peter Crosthwaite 
>> Tested-By: Hyun Kwon 
>> ---
>>  hw/arm/xlnx-zynqmp.c | 30 ++
>>  include/hw/arm/xlnx-zynqmp.h |  5 +
>>  2 files changed, 35 insertions(+)
>>
>> diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
>> index 87553bb..ce9919f 100644
>> --- a/hw/arm/xlnx-zynqmp.c
>> +++ b/hw/arm/xlnx-zynqmp.c
>> @@ -32,6 +32,12 @@
>>  #define SATA_ADDR   0xFD0C
>>  #define SATA_NUM_PORTS  2
>>
>> +#define DP_ADDR 0xfd4a
>> +#define DP_IRQ  113
>> +
>> +#define DPDMA_ADDR  0xfd4c
>> +#define DPDMA_IRQ   116
>> +
>>  static const uint64_t gem_addr[XLNX_ZYNQMP_NUM_GEMS] = {
>>  0xFF0B, 0xFF0C, 0xFF0D, 0xFF0E,
>>  };
>> @@ -112,6 +118,12 @@ static void xlnx_zynqmp_init(Object *obj)
>>  qdev_set_parent_bus(DEVICE(>sdhci[i]),
>>  sysbus_get_default());
>>  }
>> +
>> +object_initialize(>dp, sizeof(s->dp), TYPE_XLNX_DP);
>> +qdev_set_parent_bus(DEVICE(>dp), sysbus_get_default());
>> +
>> +object_initialize(>dpdma, sizeof(s->dpdma), TYPE_XLNX_DPDMA);
>> +qdev_set_parent_bus(DEVICE(>dpdma), sysbus_get_default());
>>  }
>>
>>  static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
>> @@ -286,6 +298,24 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error 
>> **errp)
>>  sysbus_connect_irq(SYS_BUS_DEVICE(>sdhci[i]), 0,
>> gic_spi[sdhci_intr[i]]);
>>  }
>> +
>> +sysbus_mmio_map(SYS_BUS_DEVICE(>dp), 0, DP_ADDR);
>> +sysbus_connect_irq(SYS_BUS_DEVICE(>dp), 0, gic_spi[DP_IRQ]);
>> +
>> +sysbus_mmio_map(SYS_BUS_DEVICE(>dpdma), 0, DPDMA_ADDR);
>> +sysbus_connect_irq(SYS_BUS_DEVICE(>dpdma), 0, gic_spi[DPDMA_IRQ]);
>> +object_property_set_bool(OBJECT(>dp), true, "realized", );
>> +if (err) {
>> +error_propagate(errp, err);
>> +return;
>> +}
>> +object_property_set_bool(OBJECT(>dpdma), true, "realized", );
>> +if (err) {
>> +error_propagate(errp, err);
>> +return;
>> +}
> Can you set the device as realized before the sysbus connections? That
> is how every other device does it.
Ok will do that.

>
>> +object_property_set_link(OBJECT(>dp), OBJECT(>dpdma), "dpdma",
>> + _abort);
>>  }
>>
>>  static Property xlnx_zynqmp_props[] = {
>> diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
>> index d116092..e683eaf 100644
>> --- a/include/hw/arm/xlnx-zynqmp.h
>> +++ b/include/hw/arm/xlnx-zynqmp.h
>> @@ -25,6 +25,8 @@
>>  #include "hw/ide/pci.h"
>>  #include "hw/ide/ahci.h"
>>  #include "hw/sd/sdhci.h"
>> +#include "hw/dma/xlnx_dpdma.h"
>> +#include "hw/display/xlnx_dp.h"
>>
>>  #define TYPE_XLNX_ZYNQMP "xlnx,zynqmp"
>>  #define XLNX_ZYNQMP(obj) OBJECT_CHECK(XlnxZynqMPState, (obj), \
>> @@ -69,6 +71,9 @@ typedef struct XlnxZynqMPState {
>>
>>  char *boot_cpu;
>>  ARMCPU *boot_cpu_ptr;
>> +
>> +XlnxDPState dp;
>> +XlnxDPDMAState dpdma;
> Can you also move these up so they are with the rest of the devices?
yes

>
> Otherwise:
>
> Reviewed-by: Alistair Francis 
>
> Thanks,
>
> Alistair
>
>>  }  XlnxZynqMPState;
>>
>>  #define XLNX_ZYNQMP_H
>> --
>> 1.9.0
>>
>>




Re: [Qemu-devel] [PATCH V6 0/8] Xilinx DisplayPort.

2016-01-28 Thread Frederic Konrad
On 16/01/2016 01:33, Alistair Francis wrote:
> On Mon, Jan 4, 2016 at 10:25 AM,   wrote:
>> From: KONRAD Frederic 
>>
>> This is the 6th version of this patch-set of the implementation of the Xilinx
>> DisplayPort and DPDMA.
>>
>> This 6th version fixes some minors issues.
>>
>> Second patch introduces an AUX bus needed by the DP to read the DPCD.
>> It's also possible to connect an I2C device on it to to I2C through AUX
>> commands. The drivers requires I2C broadcast write to be modeled as well 
>> which
>> seems to be missing currently upstream.
>>
>> The tree can be cloned at:
>> g...@git.greensocs.com:fkonrad/xilinx_dp.git branch xilinx_dp_v6_release
> I don't see a v6 branch
Should be fixed.

Thanks,
Fred
>
> Thanks,
>
> Alistair
>
>> Details of the DPDMA part:
>>  * DPDMA is implemented as a QEMU SYSBUS device.
>>  * Interrupts are implemented except the axi error and fifo.
>>
>> Details of the XILINX-DP:
>>  * DP is also implemented as a QEMU SYSBUS. Multiple memory regions are used 
>> to
>>avoid having a single big region as there are holes in the DP memory map.
>>  * An aux-bus has been implemented, it creates a memory map for aux slaves 
>> and
>>has an i2c bus (which is already implemented in QEMU).
>>  * The normal programmable i2c clock and controller implementation is missing
>>from the QEMU tree so the easiest way for us was to implement a dummy-clk
>>driver in the kernel. It's a clock which does nothing but fakes a clock 
>> such
>>that the DPDMA driver works. The patch will be send separately.
>>  * The graphic plane works on channel 3, video on channel 0 and audios on
>>channel 4 and 5.
>>
>> Thanks,
>> Fred
>>
>> V5 -> V6 changes:
>>   * globally:
>> * Rebased on current master (38a762fec63fd5c035aae29ba9a77d357e21e4a7).
>> * Fix some coding style issues.
>>
>> V4 -> V5 changes:
>>   * aux:
>> * Move the header include/hw => include/hw/misc
>>   * dpcd:
>> * Move the header hw/display => include/hw/display
>>   * i2c-ddc:
>> * Move the header hw/i2c => include/hw/i2c
>>   * xlnx_dpdma:
>> * Move the header hw/dma => include/hw/dma
>> * Fix some styles issues.
>>   * xlnx_dp:
>> * Move the header hw/display => include/hw/display
>>   * globally:
>> * Rebased on current master (c49d3411faae8ffaab8f7e5db47405a008411c10).
>>
>> V3 -> V4 changes:
>>   * xlnx_dpdma:
>> * Initialize operation_finished during reset.
>> * Add a function to trigger a VSYNC interrupt from the xlnx_dp.
>>   * xlnx_dp:
>> * Fix the default pixman format for video buffer.
>> * Remove unused buffer.
>>   * dpcd:
>> * Add the missing DPCD_LANE_X_STATUS.
>> * Set status field for all ports to avoid driver error.
>> * Use 4 lines by default.
>> * Use guest error in case of an outbound access.
>>   * i2c broadcast:
>> * Use a list of device instead of relying on broadcast field to remove 
>> duped
>>   code.
>>   * other:
>> * rebased on current master (774ee4772b6838b78741ea52d4bf26b8922244c5)
>>
>> V2 -> V3 changes:
>>   * dpcd:
>> * Add a CONFIG_DPCD.
>>   * i2c-ddc:
>> * Fill in VMSD.
>>   * aux:
>> * Remove address field.
>> * Add a CONFIG_AUX.
>>   * dpdma:
>> * Fill in VMSD.
>> * Some coding style changes.
>>   * dp:
>> * Fill in VMSD.
>> * Coding style changes.
>>
>> V1 -> V2 changes:
>>   * xlnx-zynqmp:
>> * Remove the dummy object_property_add_child(..).
>>   * dpcd:
>> * Compile only when the ZYNQMP platform is compiled.
>> * Use qemu_log instead of printf.
>> * Compile test debug traces.
>> * Remove the unused current_reg.
>> * Remove the blank realize.
>> * Use dpcd_ prefixes instead of aux_ prefixes.
>> * Add a reset callback.
>> * Add the VMSD.
>> * Add size constraint in the MemoryRegionOps structure instead of 
>> asserting.
>> * Style fixes.
>>   * aux:
>> * Compile only when the ZYNQMP platform is compiled.
>> * Remove the class init and the class for aux-slave.
>>   * dpdma:
>> * Compile only when the ZYNQMP platform is compiled.
>> * Unify per channel macro in one, simplify the switch case.
>> * Use extractXX.
>> * Make DPDMA_GBL an or'ed register.
>>   * dp:
>> * Compile only when the ZYNQMP platform is compiled.
>> * Don't look at the audio channel count.
>> * Use a third pixman plane when we do blending.
>>   * other:
>> * Drop the useless "console: add qemu_alloc_display_format." patch as
>>   suggested by Gerd.
>> * Rebase on current master (f3e3b083d4c266ea864ae3c83da49d4086857679).
>>
>> KONRAD Frederic (7):
>>   i2cbus: remove unused dev field
>>   introduce aux-bus
>>   i2c: implement broadcast write
>>   introduce dpcd module
>>   introduce xlnx-dpdma
>>   introduce xlnx-dp
>>   arm: xlnx-zynqmp: Add xlnx-dp and xlnx-dpdma
>>
>> Peter Maydell (1):
>>   hw/i2c-ddc.c: Implement DDC I2C slave
>>
>>  

Re: [Qemu-devel] [RFC v1 1/1] i2c: Factor our send() and recv() common logic

2016-01-28 Thread Frederic Konrad
On 02/11/2015 10:09, Frederic Konrad wrote:
> On 19/10/2015 06:09, Peter Crosthwaite wrote:
>> Most of the control flow logic between send and recv (error checking
>> etc) is the same. Factor this out into a common send_recv() API.
>> This is then usable by clients, where the control logic for send 
>> and receive differs only by a boolean. E.g.
>>
>> if (send)
>>i2c_send(...):
>> else
>>i2c_recv(...);
>>
>> becomes:
>>
>> i2c_send_recv(... , send);
>>
>> Signed-off-by: Peter Crosthwaite <crosthwaite.pe...@gmail.com>
>> ---
>>
>>  hw/i2c/core.c| 34 +++---
>>  include/hw/i2c/i2c.h |  1 +
>>  2 files changed, 20 insertions(+), 15 deletions(-)
>>
>> diff --git a/hw/i2c/core.c b/hw/i2c/core.c
>> index 5a64026..d4a8cbb 100644
>> --- a/hw/i2c/core.c
>> +++ b/hw/i2c/core.c
>> @@ -129,7 +129,7 @@ void i2c_end_transfer(I2CBus *bus)
>>  bus->current_dev = NULL;
>>  }
>>  
>> -int i2c_send(I2CBus *bus, uint8_t data)
>> +int i2c_send_recv(I2CBus  *bus, uint8_t *data, bool send)
> Double space here between I2CBus and *bus.
>
> Otherwise it looks ok for me.

Is everybody ok with this patch?
If it's the case I can pick it with the dpdma series.

Thanks,
Fred
> Fred
>>  {
>>  I2CSlave *dev = bus->current_dev;
>>  I2CSlaveClass *sc;
>> @@ -139,28 +139,32 @@ int i2c_send(I2CBus *bus, uint8_t data)
>>  }
>>  
>>  sc = I2C_SLAVE_GET_CLASS(dev);
>> -if (sc->send) {
>> -return sc->send(dev, data);
>> +if (send && sc->send) {
>> +return sc->send(dev, *data);
>> +} else if (!send && sc->recv) {
>> +int ret = sc->recv(dev);
>> +if (ret < 0) {
>> +return ret;
>> +} else {
>> +*data = ret;
>> +return 0;
>> +}
>>  }
>>  
>>  return -1;
>>  }
>>  
>> -int i2c_recv(I2CBus *bus)
>> +int i2c_send(I2CBus *bus, uint8_t data)
>>  {
>> -I2CSlave *dev = bus->current_dev;
>> -I2CSlaveClass *sc;
>> -
>> -if (!dev) {
>> -return -1;
>> -}
>> +return i2c_send_recv(bus, , true);
>> +}
>>  
>> -sc = I2C_SLAVE_GET_CLASS(dev);
>> -if (sc->recv) {
>> -return sc->recv(dev);
>> -}
>> +int i2c_recv(I2CBus *bus)
>> +{
>> +uint8_t data;
>> +int ret = i2c_send_recv(bus, , false);
>>  
>> -return -1;
>> +return ret < 0 ? ret : data;
>>  }
>>  
>>  void i2c_nack(I2CBus *bus)
>> diff --git a/include/hw/i2c/i2c.h b/include/hw/i2c/i2c.h
>> index 4986ebc..c4085aa 100644
>> --- a/include/hw/i2c/i2c.h
>> +++ b/include/hw/i2c/i2c.h
>> @@ -56,6 +56,7 @@ int i2c_bus_busy(I2CBus *bus);
>>  int i2c_start_transfer(I2CBus *bus, uint8_t address, int recv);
>>  void i2c_end_transfer(I2CBus *bus);
>>  void i2c_nack(I2CBus *bus);
>> +int i2c_send_recv(I2CBus *bus, uint8_t *data, bool send);
>>  int i2c_send(I2CBus *bus, uint8_t data);
>>  int i2c_recv(I2CBus *bus);
>>  
>




Re: [Qemu-devel] [PATCH V5 7/8] introduce xlnx-dp

2015-12-07 Thread Frederic Konrad
On 20/11/2015 11:06, Alistair Francis wrote:
> On Fri, Oct 16, 2015 at 7:11 PM,  <fred.kon...@greensocs.com> wrote:
>> From: KONRAD Frederic <fred.kon...@greensocs.com>
>>
>> This is the implementation of the DisplayPort.
>> It has an aux-bus to access dpcd and edid.
>>
>> Graphic plane is connected to the channel 3.
>> Video plane is connected to the channel 0.
>> Audio stream are connected to the channels 4 and 5.
> This patch doesn't pass checkpatch (I didn't test any others).
> Can you run the series through checkpatch?
>
> Also a super small nit pick, some of your line splitting doesn't line up,
> can you make sure that the function arguments and if statement conditions
> line up with the previous line.
I fixed this.

>
>> Signed-off-by: KONRAD Frederic <fred.kon...@greensocs.com>
>> Tested-By: Hyun Kwon <hyun.k...@xilinx.com>
>> ---
>>  hw/display/Makefile.objs |1 +
>>  hw/display/xlnx_dp.c | 1370 
>> ++
>>  include/hw/display/xlnx_dp.h |  110 
>>  3 files changed, 1481 insertions(+)
>>  create mode 100644 hw/display/xlnx_dp.c
>>  create mode 100644 include/hw/display/xlnx_dp.h
>>
>> diff --git a/hw/display/Makefile.objs b/hw/display/Makefile.objs
>> index 250a43f..3625ab2 100644
>> --- a/hw/display/Makefile.objs
>> +++ b/hw/display/Makefile.objs
>> @@ -43,3 +43,4 @@ virtio-gpu.o-libs += $(VIRGL_LIBS)
>>  virtio-gpu-3d.o-cflags := $(VIRGL_CFLAGS)
>>  virtio-gpu-3d.o-libs += $(VIRGL_LIBS)
>>  obj-$(CONFIG_DPCD) += dpcd.o
>> +obj-$(CONFIG_XLNX_ZYNQMP) += xlnx_dp.o
>> diff --git a/hw/display/xlnx_dp.c b/hw/display/xlnx_dp.c
>> new file mode 100644
>> index 000..e91221c
>> --- /dev/null
>> +++ b/hw/display/xlnx_dp.c
>> @@ -0,0 +1,1370 @@
>> +/*
>> + * xlnx_dp.c
>> + *
>> + *  Copyright (C) 2015 : GreenSocs Ltd
>> + *  http://www.greensocs.com/ , email: i...@greensocs.com
>> + *
>> + *  Developed by :
>> + *  Frederic Konrad   <fred.kon...@greensocs.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation, either version 2 of the License, or
>> + * (at your option)any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License along
>> + * with this program; if not, see <http://www.gnu.org/licenses/>.
>> + *
>> + */
>> +
>> +#include "hw/display/xlnx_dp.h"
>> +
>> +#ifndef DEBUG_DP
>> +#define DEBUG_DP 0
>> +#endif
>> +
>> +#define DPRINTF(fmt, ...) do {  
>>\
>> +if (DEBUG_DP) { 
>>\
>> +qemu_log("xlnx_dp: " fmt , ## __VA_ARGS__); 
>>\
>> +}   
>>\
>> +} while (0);
>> +
>> +/*
>> + * Register offset for DP.
>> + */
>> +#define DP_LINK_BW_SET  (0x >> 2)
>> +#define DP_LANE_COUNT_SET   (0x0004 >> 2)
>> +#define DP_ENHANCED_FRAME_EN(0x0008 >> 2)
>> +#define DP_TRAINING_PATTERN_SET (0x000C >> 2)
>> +#define DP_LINK_QUAL_PATTERN_SET(0x0010 >> 2)
>> +#define DP_SCRAMBLING_DISABLE   (0x0014 >> 2)
>> +#define DP_DOWNSPREAD_CTRL  (0x0018 >> 2)
>> +#define DP_SOFTWARE_RESET   (0x001C >> 2)
>> +#define DP_TRANSMITTER_ENABLE   (0x0080 >> 2)
>> +#define DP_MAIN_STREAM_ENABLE   (0x0084 >> 2)
>> +#define DP_FORCE_SCRAMBLER_RESET(0x00C0 >> 2)
>> +#define DP_VERSION_REGISTER (0x00F8 >> 2)
>> +#define DP_CORE_ID  (0x00FC >> 2)
>> +
>> +#define DP_AUX_COMMAND_REGISTER (0x0100 >> 2)
>> +#define AUX_ADDR_ONLY_MASK  (0x1000)
>> +#define AUX_COMMAND_MASK(0x0F00)
>> +#define AUX_COMMAND_SHIFT   (8)
>> +#define AUX

Re: [Qemu-devel] [PATCH V5 8/8] arm: xlnx-zynqmp: Add xlnx-dp and xlnx-dpdma

2015-11-30 Thread Frederic Konrad
On 24/11/2015 04:42, Alistair Francis wrote:
> On Mon, Nov 23, 2015 at 6:53 PM, KONRAD Frederic
>  wrote:
>>
>> Le 20/11/2015 13:21, Alistair Francis a écrit :
>>> On Fri, Oct 16, 2015 at 7:11 PM,   wrote:
 From: KONRAD Frederic 

 This adds the DP and the DPDMA to the Zynq MP platform.

 Signed-off-by: KONRAD Frederic 
 Reviewed-by: Peter Crosthwaite 
 Tested-By: Hyun Kwon 
 ---
   hw/arm/xlnx-zynqmp.c | 20 
   include/hw/arm/xlnx-zynqmp.h |  5 +
   2 files changed, 25 insertions(+)

 diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
 index b36ca3d..dfed5cd 100644
 --- a/hw/arm/xlnx-zynqmp.c
 +++ b/hw/arm/xlnx-zynqmp.c
 @@ -32,6 +32,12 @@
   #define SATA_ADDR   0xFD0C
   #define SATA_NUM_PORTS  2

 +#define DP_ADDR 0xfd4a
 +#define DP_IRQ  113
 +
 +#define DPDMA_ADDR  0xfd4c
 +#define DPDMA_IRQ   116
 +
   static const uint64_t gem_addr[XLNX_ZYNQMP_NUM_GEMS] = {
   0xFF0B, 0xFF0C, 0xFF0D, 0xFF0E,
   };
 @@ -97,6 +103,11 @@ static void xlnx_zynqmp_init(Object *obj)

   object_initialize(>sata, sizeof(s->sata), TYPE_SYSBUS_AHCI);
   qdev_set_parent_bus(DEVICE(>sata), sysbus_get_default());
 +
 +object_initialize(>dp, sizeof(s->dp), TYPE_XLNX_DP);
 +qdev_set_parent_bus(DEVICE(>dp), sysbus_get_default());
>>> New line
>>>
 +object_initialize(>dpdma, sizeof(s->dpdma), TYPE_XLNX_DPDMA);
 +qdev_set_parent_bus(DEVICE(>dpdma), sysbus_get_default());
   }

   static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
 @@ -258,6 +269,15 @@ static void xlnx_zynqmp_realize(DeviceState *dev,
 Error **errp)

   sysbus_mmio_map(SYS_BUS_DEVICE(>sata), 0, SATA_ADDR);
   sysbus_connect_irq(SYS_BUS_DEVICE(>sata), 0,
 gic_spi[SATA_INTR]);
 +
 +sysbus_mmio_map(SYS_BUS_DEVICE(>dp), 0, DP_ADDR);
 +sysbus_connect_irq(SYS_BUS_DEVICE(>dp), 0, gic_spi[DP_IRQ]);
>>> New line
>>>
 +sysbus_mmio_map(SYS_BUS_DEVICE(>dpdma), 0, DPDMA_ADDR);
 +sysbus_connect_irq(SYS_BUS_DEVICE(>dpdma), 0,
 gic_spi[DPDMA_IRQ]);
 +object_property_set_bool(OBJECT(>dp), true, "realized", );
 +object_property_set_bool(OBJECT(>dpdma), true, "realized", );
>>> Can you add something to check these errors?
>>
>> Ok.
> Thanks
>
>> BTW I'll move the I2C and AUX device out of xlnx-dp and put that here.
>> Is that ok with you?
> That should be fine. Is there a reason you are doing that? Does
> anything else need to access them?
No I don't thing anything else is accessing that. It's just a screen
specific stuff.
If it's fine like this then I don't bother changing that.

Fred

>
> Thanks,
>
> Alistair
>
>> Thanks,
>> Fred
>>
>>> Thanks,
>>>
>>> Alistair
>>>
 +object_property_set_link(OBJECT(>dp), OBJECT(>dpdma), "dpdma",
 + _abort);
   }

   static Property xlnx_zynqmp_props[] = {
 diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
 index 4005a99..5a4d6cc 100644
 --- a/include/hw/arm/xlnx-zynqmp.h
 +++ b/include/hw/arm/xlnx-zynqmp.h
 @@ -24,6 +24,8 @@
   #include "hw/char/cadence_uart.h"
   #include "hw/ide/pci.h"
   #include "hw/ide/ahci.h"
 +#include "hw/dma/xlnx_dpdma.h"
 +#include "hw/display/xlnx_dp.h"

   #define TYPE_XLNX_ZYNQMP "xlnx,zynqmp"
   #define XLNX_ZYNQMP(obj) OBJECT_CHECK(XlnxZynqMPState, (obj), \
 @@ -66,6 +68,9 @@ typedef struct XlnxZynqMPState {

   char *boot_cpu;
   ARMCPU *boot_cpu_ptr;
 +
 +XlnxDPState dp;
 +XlnxDPDMAState dpdma;
   }  XlnxZynqMPState;

   #define XLNX_ZYNQMP_H
 --
 1.9.0


>>




Re: [Qemu-devel] [RFC v1 1/1] i2c: Factor our send() and recv() common logic

2015-11-02 Thread Frederic Konrad
On 19/10/2015 06:09, Peter Crosthwaite wrote:
> Most of the control flow logic between send and recv (error checking
> etc) is the same. Factor this out into a common send_recv() API.
> This is then usable by clients, where the control logic for send 
> and receive differs only by a boolean. E.g.
>
> if (send)
>i2c_send(...):
> else
>i2c_recv(...);
>
> becomes:
>
> i2c_send_recv(... , send);
>
> Signed-off-by: Peter Crosthwaite 
> ---
>
>  hw/i2c/core.c| 34 +++---
>  include/hw/i2c/i2c.h |  1 +
>  2 files changed, 20 insertions(+), 15 deletions(-)
>
> diff --git a/hw/i2c/core.c b/hw/i2c/core.c
> index 5a64026..d4a8cbb 100644
> --- a/hw/i2c/core.c
> +++ b/hw/i2c/core.c
> @@ -129,7 +129,7 @@ void i2c_end_transfer(I2CBus *bus)
>  bus->current_dev = NULL;
>  }
>  
> -int i2c_send(I2CBus *bus, uint8_t data)
> +int i2c_send_recv(I2CBus  *bus, uint8_t *data, bool send)
Double space here between I2CBus and *bus.

Otherwise it looks ok for me.

Fred
>  {
>  I2CSlave *dev = bus->current_dev;
>  I2CSlaveClass *sc;
> @@ -139,28 +139,32 @@ int i2c_send(I2CBus *bus, uint8_t data)
>  }
>  
>  sc = I2C_SLAVE_GET_CLASS(dev);
> -if (sc->send) {
> -return sc->send(dev, data);
> +if (send && sc->send) {
> +return sc->send(dev, *data);
> +} else if (!send && sc->recv) {
> +int ret = sc->recv(dev);
> +if (ret < 0) {
> +return ret;
> +} else {
> +*data = ret;
> +return 0;
> +}
>  }
>  
>  return -1;
>  }
>  
> -int i2c_recv(I2CBus *bus)
> +int i2c_send(I2CBus *bus, uint8_t data)
>  {
> -I2CSlave *dev = bus->current_dev;
> -I2CSlaveClass *sc;
> -
> -if (!dev) {
> -return -1;
> -}
> +return i2c_send_recv(bus, , true);
> +}
>  
> -sc = I2C_SLAVE_GET_CLASS(dev);
> -if (sc->recv) {
> -return sc->recv(dev);
> -}
> +int i2c_recv(I2CBus *bus)
> +{
> +uint8_t data;
> +int ret = i2c_send_recv(bus, , false);
>  
> -return -1;
> +return ret < 0 ? ret : data;
>  }
>  
>  void i2c_nack(I2CBus *bus)
> diff --git a/include/hw/i2c/i2c.h b/include/hw/i2c/i2c.h
> index 4986ebc..c4085aa 100644
> --- a/include/hw/i2c/i2c.h
> +++ b/include/hw/i2c/i2c.h
> @@ -56,6 +56,7 @@ int i2c_bus_busy(I2CBus *bus);
>  int i2c_start_transfer(I2CBus *bus, uint8_t address, int recv);
>  void i2c_end_transfer(I2CBus *bus);
>  void i2c_nack(I2CBus *bus);
> +int i2c_send_recv(I2CBus *bus, uint8_t *data, bool send);
>  int i2c_send(I2CBus *bus, uint8_t data);
>  int i2c_recv(I2CBus *bus);
>  




Re: [Qemu-devel] [PATCH V5 2/8] introduce aux-bus

2015-10-29 Thread Frederic Konrad
On 18/10/2015 19:17, Peter Crosthwaite wrote:
> On Fri, Oct 16, 2015 at 6:41 AM,  <fred.kon...@greensocs.com> wrote:
>> From: KONRAD Frederic <fred.kon...@greensocs.com>
>>
>> This introduces a new bus: aux-bus.
>>
>> It contains an address space for aux slaves devices and a bridge to an I2C 
>> bus
>> for I2C through AUX transactions.
>>
>> Signed-off-by: KONRAD Frederic <fred.kon...@greensocs.com>
>> Tested-By: Hyun Kwon <hyun.k...@xilinx.com>
>> ---
>>  default-configs/aarch64-softmmu.mak |   1 +
>>  hw/misc/Makefile.objs   |   1 +
>>  hw/misc/aux.c   | 374 
>> 
>>  include/hw/misc/aux.h   | 125 
>>  4 files changed, 501 insertions(+)
>>  create mode 100644 hw/misc/aux.c
>>  create mode 100644 include/hw/misc/aux.h
>>
>> diff --git a/default-configs/aarch64-softmmu.mak 
>> b/default-configs/aarch64-softmmu.mak
>> index 96dd994..d3a2665 100644
>> --- a/default-configs/aarch64-softmmu.mak
>> +++ b/default-configs/aarch64-softmmu.mak
>> @@ -3,4 +3,5 @@
>>  # We support all the 32 bit boards so need all their config
>>  include arm-softmmu.mak
>>
>> +CONFIG_AUX=y
>>  CONFIG_XLNX_ZYNQMP=y
>> diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
>> index 4aa76ff..e859a4b 100644
>> --- a/hw/misc/Makefile.objs
>> +++ b/hw/misc/Makefile.objs
>> @@ -40,3 +40,4 @@ obj-$(CONFIG_STM32F2XX_SYSCFG) += stm32f2xx_syscfg.o
>>
>>  obj-$(CONFIG_PVPANIC) += pvpanic.o
>>  obj-$(CONFIG_EDU) += edu.o
>> +obj-$(CONFIG_AUX) += aux.o
>> diff --git a/hw/misc/aux.c b/hw/misc/aux.c
>> new file mode 100644
>> index 000..bf300f7
>> --- /dev/null
>> +++ b/hw/misc/aux.c
>> @@ -0,0 +1,374 @@
>> +/*
>> + * aux.c
>> + *
>> + *  Copyright 2015 : GreenSocs Ltd
>> + *  http://www.greensocs.com/ , email: i...@greensocs.com
>> + *
>> + *  Developed by :
>> + *  Frederic Konrad   <fred.kon...@greensocs.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation, either version 2 of the License, or
>> + * (at your option)any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License along
>> + * with this program; if not, see <http://www.gnu.org/licenses/>.
>> + *
>> + */
>> +
>> +/*
>> + * This is an implementation of the AUX bus for VESA Display Port v1.1a.
>> + */
>> +
>> +#include "hw/misc/aux.h"
>> +#include "hw/i2c/i2c.h"
>> +#include "monitor/monitor.h"
>> +
>> +#ifndef DEBUG_AUX
>> +#define DEBUG_AUX 0
>> +#endif
>> +
>> +#define DPRINTF(fmt, ...) do {  
>>\
>> +if (DEBUG_AUX) {
>>\
>> +qemu_log("aux: " fmt , ## __VA_ARGS__); 
>>\
>> +}   
>>\
>> +} while (0);
>> +
>> +#define TYPE_AUXTOI2C "aux-to-i2c-bridge"
>> +#define AUXTOI2C(obj) OBJECT_CHECK(AUXTOI2CState, (obj), TYPE_AUXTOI2C)
>> +
>> +#define TYPE_AUX_BUS "aux-bus"
>> +#define AUX_BUS(obj) OBJECT_CHECK(AUXBus, (obj), TYPE_AUX_BUS)
>> +
>> +static void aux_slave_dev_print(Monitor *mon, DeviceState *dev, int indent);
>> +
>> +static void aux_bus_class_init(ObjectClass *klass, void *data)
>> +{
>> +BusClass *k = BUS_CLASS(klass);
>> +
>> +/* AUXSlave has an MMIO so we need to change the way we print 
>> information
>> + * in monitor.
>> + */
>> +k->print_dev = aux_slave_dev_print;
>> +}
>> +
>> +static const TypeInfo aux_bus_info = {
>> +.name = TYPE_AUX_BUS,
>> +.parent = TYPE_BUS,
>> +.instance_size = sizeof(AUXBus),
>> +.class_init = aux_bus_class_init
>> +};
>> +
>> +AUXBus *aux_init_bus(DeviceState *parent, const char *name)
>> +{
>> +

Re: [Qemu-devel] [PATCH v3 4/5] xlnx-zynqmp: Connect the SPI devices

2015-10-29 Thread Frederic Konrad
On 29/10/2015 03:00, Peter Crosthwaite wrote:
> On Wed, Oct 28, 2015 at 10:32 AM, Alistair Francis <
> alistair.fran...@xilinx.com> wrote:
>
>> Connect the Xilinx SPI device to the ZynqMP model.
>>
>>
> "devices"
>
>
>> Signed-off-by: Alistair Francis 
>> ---
>> V3:
>>  - Expose the SPI Bus as part of the SoC device
>> V2:
>>  - Don't connect the SPI flash to the SoC
>>
>>  hw/arm/xlnx-zynqmp.c | 37 +
>>  include/hw/arm/xlnx-zynqmp.h |  4 
>>  2 files changed, 41 insertions(+)
>>
>> diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
>> index b36ca3d..5671d7a 100644
>> --- a/hw/arm/xlnx-zynqmp.c
>> +++ b/hw/arm/xlnx-zynqmp.c
>> @@ -48,6 +48,14 @@ static const int uart_intr[XLNX_ZYNQMP_NUM_UARTS] = {
>>  21, 22,
>>  };
>>
>> +static const uint64_t spi_addr[XLNX_ZYNQMP_NUM_SPIS] = {
>> +0xFF04, 0xFF05,
>> +};
>> +
>> +static const int spi_intr[XLNX_ZYNQMP_NUM_SPIS] = {
>> +19, 20,
>> +};
>> +
>>  typedef struct XlnxZynqMPGICRegion {
>>  int region_index;
>>  uint32_t address;
>> @@ -97,6 +105,12 @@ static void xlnx_zynqmp_init(Object *obj)
>>
>>  object_initialize(>sata, sizeof(s->sata), TYPE_SYSBUS_AHCI);
>>  qdev_set_parent_bus(DEVICE(>sata), sysbus_get_default());
>> +
>> +for (i = 0; i < XLNX_ZYNQMP_NUM_SPIS; i++) {
>> +object_initialize(>spi[i], sizeof(s->spi[i]),
>> +  TYPE_XILINX_SPIPS);
>> +qdev_set_parent_bus(DEVICE(>spi[i]), sysbus_get_default());
>> +}
>>  }
>>
>>  static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
>> @@ -258,6 +272,29 @@ static void xlnx_zynqmp_realize(DeviceState *dev,
>> Error **errp)
>>
>>  sysbus_mmio_map(SYS_BUS_DEVICE(>sata), 0, SATA_ADDR);
>>  sysbus_connect_irq(SYS_BUS_DEVICE(>sata), 0, gic_spi[SATA_INTR]);
>> +
>> +for (i = 0; i < XLNX_ZYNQMP_NUM_SPIS; i++) {
>> +BusState *spi_bus;
>> +char bus_name[6];
>> +
>> +object_property_set_int(OBJECT(>spi[i]), XLNX_ZYNQMP_NUM_SPIS,
>> +"num-busses", _abort);
>>
> The number of busses-per-controller is unrelated to the number of
> controllers. Setting num_busses != 1 is primarily a QSPI thing, so should
> this just default to 1? I think you can drop this setter completely.
>
>
>> +object_property_set_bool(OBJECT(>spi[i]), true, "realized",
>> );
>> +if (err) {
>> +error_propagate(errp, err);
>> +return;
>> +}
>> +
>> +sysbus_mmio_map(SYS_BUS_DEVICE(>spi[i]), 0, spi_addr[i]);
>> +sysbus_connect_irq(SYS_BUS_DEVICE(>spi[i]), 0,
>> +   gic_spi[spi_intr[i]]);
>> +
>> +snprintf(bus_name, 6, "spi%d", i);
>> +spi_bus = qdev_get_child_bus(DEVICE(>spi), bus_name);
>> +
>> +/* Add the SPI buses to the SoC child bus */
>> +QLIST_INSERT_HEAD(>child_bus, spi_bus, sibling);
>>
> Nice! That is pretty simple in the end. One, question though, what happen
> with info qtree? Do you get doubles because the bus is double parented?
>
> I think this concept also might apply to the DP/DPDMA work, where the
> display port (or AUX bus?) should be put on the SoC container. Then the
> machine model (ep108) is responsible for detecting if the user wants a
> display and connecting it. I.e. the DP controller shouldn't be doing the UI
> init.

You mean get the AUX and I2C bus here and connect the edid and the dpcd?
I can take a look.

Fred
>
>> +}
>>  }
>>
>>  static Property xlnx_zynqmp_props[] = {
>> diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
>> index 4005a99..6d1d2a9 100644
>> --- a/include/hw/arm/xlnx-zynqmp.h
>> +++ b/include/hw/arm/xlnx-zynqmp.h
>> @@ -24,6 +24,7 @@
>>  #include "hw/char/cadence_uart.h"
>>  #include "hw/ide/pci.h"
>>  #include "hw/ide/ahci.h"
>> +#include "hw/ssi/xilinx_spips.h"
>>
>>  #define TYPE_XLNX_ZYNQMP "xlnx,zynqmp"
>>  #define XLNX_ZYNQMP(obj) OBJECT_CHECK(XlnxZynqMPState, (obj), \
>> @@ -33,6 +34,8 @@
>>  #define XLNX_ZYNQMP_NUM_RPU_CPUS 2
>>  #define XLNX_ZYNQMP_NUM_GEMS 4
>>  #define XLNX_ZYNQMP_NUM_UARTS 2
>> +#define XLNX_ZYNQMP_NUM_SPIS 2
>>
>
>> +#define XLNX_ZYNQMP_NUM_SPI_FLASHES 4
>>
> NUM_SPI_FLASHES is local to ep108 so it should just be in ep108.c
>
> Regards,
> Peter
>
>
>>  #define XLNX_ZYNQMP_NUM_OCM_BANKS 4
>>  #define XLNX_ZYNQMP_OCM_RAM_0_ADDRESS 0xFFFC
>> @@ -63,6 +66,7 @@ typedef struct XlnxZynqMPState {
>>  CadenceGEMState gem[XLNX_ZYNQMP_NUM_GEMS];
>>  CadenceUARTState uart[XLNX_ZYNQMP_NUM_UARTS];
>>  SysbusAHCIState sata;
>> +XilinxSPIPS spi[XLNX_ZYNQMP_NUM_SPIS];
>>
>>  char *boot_cpu;
>>  ARMCPU *boot_cpu_ptr;
>> --
>> 2.5.0
>>
>>




Re: [Qemu-devel] [PATCH V5 0/8] Xilinx DisplayPort.

2015-10-19 Thread Frederic Konrad
On 16/10/2015 23:57, Alistair Francis wrote:
> On Fri, Oct 16, 2015 at 6:41 AM,   wrote:
>> From: KONRAD Frederic 
>>
>> This is the fifth version of this patch-set of the implementation of the 
>> Xilinx
>> DisplayPort and DPDMA.
>>
>> This fifth version moves some headers files to the right directory.
>>
>> Second patch introduces an AUX bus needed by the DP to read the DPCD.
>> It's also possible to connect an I2C device on it to to I2C through AUX
>> commands. The drivers requires I2C broadcast write to be modeled as well 
>> which
>> seems to be missing currently upstream.
>>
>> The tree can be cloned at:
>> g...@git.greensocs.com:fkonrad/xilinx_dp.git branch xilinx_dp_v5_release
> I can't seem to access this, is it public?
>
> Thanks,
>
> Alistair
oops, sorry for that.
Should be ok now.

Thanks,
Fred
>> Details of the DPDMA part:
>>  * DPDMA is implemented as a QEMU SYSBUS device.
>>  * Interrupts are implemented except the axi error and fifo.
>>
>> Details of the XILINX-DP:
>>  * DP is also implemented as a QEMU SYSBUS. Multiple memory regions are used 
>> to
>>avoid having a single big region as there are holes in the DP memory map.
>>  * An aux-bus has been implemented, it creates a memory map for aux slaves 
>> and
>>has an i2c bus (which is already implemented in QEMU).
>>  * The normal programmable i2c clock and controller implementation is missing
>>from the QEMU tree so the easiest way for us was to implement a dummy-clk
>>driver in the kernel. It's a clock which does nothing but fakes a clock 
>> such
>>that the DPDMA driver works. The patch will be send separately.
>>  * The graphic plane works on channel 3, video on channel 0 and audios on
>>channel 4 and 5.
>>
>> Thanks,
>> Fred
>>
>> V4 -> V5 changes:
>>   * aux:
>> * Move the header include/hw => include/hw/misc
>>   * dpcd:
>> * Move the header hw/display => include/hw/display
>>   * i2c-ddc:
>> * Move the header hw/i2c => include/hw/i2c
>>   * xlnx_dpdma:
>> * Move the header hw/dma => include/hw/dma
>> * Fix some styles issues.
>>   * xlnx_dp:
>> * Move the header hw/display => include/hw/display
>>   * globally:
>> * Rebased on current master (c49d3411faae8ffaab8f7e5db47405a008411c10).
>>
>> V3 -> V4 changes:
>>   * xlnx_dpdma:
>> * Initialize operation_finished during reset.
>> * Add a function to trigger a VSYNC interrupt from the xlnx_dp.
>>   * xlnx_dp:
>> * Fix the default pixman format for video buffer.
>> * Remove unused buffer.
>>   * dpcd:
>> * Add the missing DPCD_LANE_X_STATUS.
>> * Set status field for all ports to avoid driver error.
>> * Use 4 lines by default.
>> * Use guest error in case of an outbound access.
>>   * i2c broadcast:
>> * Use a list of device instead of relying on broadcast field to remove 
>> duped
>>   code.
>>   * other:
>> * rebased on current master (774ee4772b6838b78741ea52d4bf26b8922244c5)
>>
>> V2 -> V3 changes:
>>   * dpcd:
>> * Add a CONFIG_DPCD.
>>   * i2c-ddc:
>> * Fill in VMSD.
>>   * aux:
>> * Remove address field.
>> * Add a CONFIG_AUX.
>>   * dpdma:
>> * Fill in VMSD.
>> * Some coding style changes.
>>   * dp:
>> * Fill in VMSD.
>> * Coding style changes.
>>
>> V1 -> V2 changes:
>>   * xlnx-zynqmp:
>> * Remove the dummy object_property_add_child(..).
>>   * dpcd:
>> * Compile only when the ZYNQMP platform is compiled.
>> * Use qemu_log instead of printf.
>> * Compile test debug traces.
>> * Remove the unused current_reg.
>> * Remove the blank realize.
>> * Use dpcd_ prefixes instead of aux_ prefixes.
>> * Add a reset callback.
>> * Add the VMSD.
>> * Add size constraint in the MemoryRegionOps structure instead of 
>> asserting.
>> * Style fixes.
>>   * aux:
>> * Compile only when the ZYNQMP platform is compiled.
>> * Remove the class init and the class for aux-slave.
>>   * dpdma:
>> * Compile only when the ZYNQMP platform is compiled.
>> * Unify per channel macro in one, simplify the switch case.
>> * Use extractXX.
>> * Make DPDMA_GBL an or'ed register.
>>   * dp:
>> * Compile only when the ZYNQMP platform is compiled.
>> * Don't look at the audio channel count.
>> * Use a third pixman plane when we do blending.
>>   * other:
>> * Drop the useless "console: add qemu_alloc_display_format." patch as
>>   suggested by Gerd.
>> * Rebase on current master (f3e3b083d4c266ea864ae3c83da49d4086857679).
>>
>> KONRAD Frederic (7):
>>   i2cbus: remove unused dev field
>>   introduce aux-bus
>>   i2c: implement broadcast write
>>   introduce dpcd module
>>   introduce xlnx-dpdma
>>   introduce xlnx-dp
>>   arm: xlnx-zynqmp: Add xlnx-dp and xlnx-dpdma
>>
>> Peter Maydell (1):
>>   hw/i2c-ddc.c: Implement DDC I2C slave
>>
>>  default-configs/aarch64-softmmu.mak |3 +
>>  hw/arm/xlnx-zynqmp.c|   20 +
>>  

Re: [Qemu-devel] [RFC PATCH V7 00/19] Multithread TCG.

2015-10-07 Thread Frederic Konrad
Hi Claudio,

I'll rebase soon tomorrow with a bit of luck ;).

Thanks,
Fred

On 07/10/2015 14:46, Claudio Fontana wrote:
> Hello Frederic,
>
> On 11.08.2015 08:27, Frederic Konrad wrote:
>> On 11/08/2015 08:15, Benjamin Herrenschmidt wrote:
>>> On Mon, 2015-08-10 at 17:26 +0200, fred.kon...@greensocs.com wrote:
>>>> From: KONRAD Frederic <fred.kon...@greensocs.com>
>>>>
>>>> This is the 7th round of the MTTCG patch series.
>>>>
>>>>
>>>> It can be cloned from:
>>>> g...@git.greensocs.com:fkonrad/mttcg.git branch multi_tcg_v7.
> would it be possible to rebase on latest qemu? I wonder if mttcg is diverging 
> a bit too much from mainline,
> which will make it more difficult to rebase later..(Or did I get confused 
> about all these repos?)
>
> Thank you!
>
> Claudio
>
>>>> This patch-set try to address the different issues in the global picture of
>>>> MTTCG, presented on the wiki.
>>>>
>>>> == Needed patch for our work ==
>>>>
>>>> Some preliminaries are needed for our work:
>>>>   * current_cpu doesn't make sense in mttcg so a tcg_executing flag is 
>>>> added to
>>>> the CPUState.
>>> Can't you just make it a TLS ?
>> True that can be done as well. But the tcg_exec_flags has a second meaning 
>> saying
>> "you can't start executing code right now because I want to do a safe_work".
>>>>   * We need to run some work safely when all VCPUs are outside their 
>>>> execution
>>>> loop. This is done with the async_run_safe_work_on_cpu function 
>>>> introduced
>>>> in this series.
>>>>   * QemuSpin lock is introduced (on posix only yet) to allow a faster 
>>>> handling of
>>>> atomic instruction.
>>> How do you handle the memory model ? IE , ARM and PPC are OO while x86
>>> is (mostly) in order, so emulating ARM/PPC on x86 is fine but emulating
>>> x86 on ARM or PPC will lead to problems unless you generate memory
>>> barriers with every load/store ..
>> For the moment we are trying to do the first case.
>>> At least on POWER7 and later on PPC we have the possibility of setting
>>> the attribute "Strong Access Ordering" with mremap/mprotect (I dont'
>>> remember which one) which gives us x86-like memory semantics...
>>>
>>> I don't know if ARM supports something similar. On the other hand, when
>>> emulating ARM on PPC or vice-versa, we can probably get away with no
>>> barriers.
>>>
>>> Do you expose some kind of guest memory model info to the TCG backend so
>>> it can decide how to handle these things ?
>>>
>>>> == Code generation and cache ==
>>>>
>>>> As Qemu stands, there is no protection at all against two threads 
>>>> attempting to
>>>> generate code at the same time or modifying a TranslationBlock.
>>>> The "protect TBContext with tb_lock" patch address the issue of code 
>>>> generation
>>>> and makes all the tb_* function thread safe (except tb_flush).
>>>> This raised the question of one or multiple caches. We choosed to use one
>>>> unified cache because it's easier as a first step and since the structure 
>>>> of
>>>> QEMU effectively has a ‘local’ cache per CPU in the form of the jump 
>>>> cache, we
>>>> don't see the benefit of having two pools of tbs.
>>>>
>>>> == Dirty tracking ==
>>>>
>>>> Protecting the IOs:
>>>> To allows all VCPUs threads to run at the same time we need to drop the
>>>> global_mutex as soon as possible. The io access need to take the mutex. 
>>>> This is
>>>> likely to change when 
>>>> http://thread.gmane.org/gmane.comp.emulators.qemu/345258
>>>> will be upstreamed.
>>>>
>>>> Invalidation of TranslationBlocks:
>>>> We can have all VCPUs running during an invalidation. Each VCPU is able to 
>>>> clean
>>>> it's jump cache itself as it is in CPUState so that can be handled by a 
>>>> simple
>>>> call to async_run_on_cpu. However tb_invalidate also writes to the
>>>> TranslationBlock which is shared as we have only one pool.
>>>> Hence this part of invalidate requires all VCPUs to exit before it can be 
>>>> done.
>>>> Hence the async_run_safe_work_on_cpu is introduced to handle this case.
>>> What about 

Re: [Qemu-devel] [PATCH V4 6/8] Introduce xilinx dpdma.

2015-09-04 Thread Frederic Konrad

On 04/09/2015 01:34, Alistair Francis wrote:

On Thu, Sep 3, 2015 at 12:28 AM, Frederic Konrad
<fred.kon...@greensocs.com> wrote:

On 02/09/2015 23:39, Alistair Francis wrote:

On Tue, Jul 21, 2015 at 10:17 AM,  <fred.kon...@greensocs.com> wrote:

From: KONRAD Frederic <fred.kon...@greensocs.com>

This is the implementation of the DPDMA.

Signed-off-by: KONRAD Frederic <fred.kon...@greensocs.com>
---
   hw/dma/Makefile.objs |   1 +
   hw/dma/xlnx_dpdma.c  | 790
+++
   hw/dma/xlnx_dpdma.h  |  85 ++
   3 files changed, 876 insertions(+)
   create mode 100644 hw/dma/xlnx_dpdma.c
   create mode 100644 hw/dma/xlnx_dpdma.h

What are the rules with the placement of the header files? Should the
header be in the include directory instead of being here?

Probably moving headers to include/hw makes sense here..
I will change it.

Hey Fred,

Great, thanks


[...]

+
+if (xlnx_dpdma_desc_is_already_done()
+&& !xlnx_dpdma_desc_ignore_done_bit()) {

The second line of the if should be indented across.

Also, I generally think the operator should go on the first line, but
that doesn't seem worth changing throughout.

Ok I can do that.


+/* We are trying to process an already processed descriptor.
*/
+s->registers[DPDMA_EISR] |= ((1 << 25) << channel);
+xlnx_dpdma_update_irq(s);
+s->operation_finished[channel] = true;
+DPRINTF("Already processed descriptor..\n");
+break;
+}
+
+done = xlnx_dpdma_desc_is_last()
+ || xlnx_dpdma_desc_is_last_of_frame();
+
+s->operation_finished[channel] = done;
+if (s->data[channel]) {
+int64_t transfer_len =
+
xlnx_dpdma_desc_get_transfer_size();

Why is this over two lines?


Probably because of the 79~80 columns limitation.

It looks like it is less then 80 columns though.

Oh yes missed that when I replaced xilinx by xlnx in functions..
I fixed that.

Thanks,
Fred


Thanks,

Alistair


Thanks,
Fred


Functioanlly it looks fine.

Besides the header file location, which someone else will need to comment
on:

Reviewed-by: Alistair Francis <alistair.fran...@xilinx.com>
Tested-By: Hyun Kwon <hyun.k...@xilinx.com>

Thanks,

Alistair


+uint32_t line_size = xlnx_dpdma_desc_get_line_size();
+uint32_t line_stride =
xlnx_dpdma_desc_get_line_stride();
+if (xlnx_dpdma_desc_is_contiguous()) {
+source_addr[0] =
+ xlnx_dpdma_desc_get_source_address(,
0);
+while (transfer_len != 0) {
+if (dma_memory_read(_space_memory,
+source_addr[0],
+>data[channel][ptr],
+line_size)) {
+s->registers[DPDMA_ISR] |= ((1 << 12) <<
channel);
+xlnx_dpdma_update_irq(s);
+DPRINTF("Can't get data.\n");
+break;
+}
+ptr += line_size;
+transfer_len -= line_size;
+source_addr[0] += line_stride;
+}
+} else {
+DPRINTF("Source address:\n");
+int frag;
+for (frag = 0; frag < 5; frag++) {
+source_addr[frag] =
+  xlnx_dpdma_desc_get_source_address(,
frag);
+DPRINTF("Fragment %u: %" PRIx64 "\n", frag + 1,
+source_addr[frag]);
+}
+
+frag = 0;
+while ((transfer_len < 0) && (frag < 5)) {
+size_t fragment_len = DPDMA_FRAG_MAX_SZ
+- (source_addr[frag] %
DPDMA_FRAG_MAX_SZ);
+
+if (dma_memory_read(_space_memory,
+source_addr[frag],
+&(s->data[channel][ptr]),
+fragment_len)) {
+s->registers[DPDMA_ISR] |= ((1 << 12) <<
channel);
+xlnx_dpdma_update_irq(s);
+DPRINTF("Can't get data.\n");
+break;
+}
+ptr += fragment_len;
+transfer_len -= fragment_len;
+frag += 1;
+}
+}
+}
+
+if (xlnx_dpdma_desc_update_enabled()) {
+/* The descriptor need to be updated when it's completed. */
+DPRINTF("update the descriptor with the done flag set.\n");
+xlnx_dpdma_desc_set_done();
+dma_memory_write(_space_mem

Re: [Qemu-devel] [PATCH V4 1/8] i2cbus: remove unused dev field.

2015-09-04 Thread Frederic Konrad

On 01/09/2015 22:58, Alistair Francis wrote:

On Tue, Jul 21, 2015 at 10:17 AM,   wrote:

From: KONRAD Frederic 

Seems this field is not needed.

The commit message should be updated to represent the patch.

Hmmm what do you mean?
It's not precise?

Thanks,
Fred




Signed-off-by: KONRAD Frederic 

Otherwise:

Reviewed-by: Alistair Francis 

Thanks,

Alistair


---
  hw/i2c/core.c | 1 -
  1 file changed, 1 deletion(-)

diff --git a/hw/i2c/core.c b/hw/i2c/core.c
index 5a64026..e0f92de 100644
--- a/hw/i2c/core.c
+++ b/hw/i2c/core.c
@@ -13,7 +13,6 @@ struct I2CBus
  {
  BusState qbus;
  I2CSlave *current_dev;
-I2CSlave *dev;
  uint8_t saved_address;
  };

--
1.9.0







Re: [Qemu-devel] [PATCH V4 4/8] introduce dpcd module.

2015-09-04 Thread Frederic Konrad

On 02/09/2015 01:19, Alistair Francis wrote:

On Tue, Jul 21, 2015 at 10:17 AM,  <fred.kon...@greensocs.com> wrote:

From: KONRAD Frederic <fred.kon...@greensocs.com>

This introduces a DPCD module. It wires on a aux-bus and can be accessed by
driver to get lane-speed, etc.

"the driver"

Also, the commit titles are a little messy. The capitalisation should
be consistent and there shouldn't be any full stops. These should be
fixed before being committed.
Can you fix them up when you resend the patch series?


Yes ok.

Thanks,
Fred


Otherwise:

Reviewed-by: Alistair Francis <alistair.fran...@xilinx.com>
Tested-By: Hyun Kwon <hyun.k...@xilinx.com>

Thanks,

Alistair



Signed-off-by: KONRAD Frederic <fred.kon...@greensocs.com>
---
  default-configs/aarch64-softmmu.mak |   1 +
  hw/display/Makefile.objs|   1 +
  hw/display/dpcd.c   | 171 
  hw/display/dpcd.h   | 105 ++
  4 files changed, 278 insertions(+)
  create mode 100644 hw/display/dpcd.c
  create mode 100644 hw/display/dpcd.h

diff --git a/default-configs/aarch64-softmmu.mak 
b/default-configs/aarch64-softmmu.mak
index d3a2665..87165b7 100644
--- a/default-configs/aarch64-softmmu.mak
+++ b/default-configs/aarch64-softmmu.mak
@@ -4,4 +4,5 @@
  include arm-softmmu.mak

  CONFIG_AUX=y
+CONFIG_DPCD=y
  CONFIG_XLNX_ZYNQMP=y
diff --git a/hw/display/Makefile.objs b/hw/display/Makefile.objs
index dd8ea76..6d7004a 100644
--- a/hw/display/Makefile.objs
+++ b/hw/display/Makefile.objs
@@ -38,3 +38,4 @@ common-obj-$(CONFIG_QXL) += qxl.o qxl-logger.o qxl-render.o
  obj-$(CONFIG_VIRTIO) += virtio-gpu.o
  obj-$(CONFIG_VIRTIO_PCI) += virtio-gpu-pci.o
  obj-$(CONFIG_VIRTIO_VGA) += virtio-vga.o
+obj-$(CONFIG_DPCD) += dpcd.o
diff --git a/hw/display/dpcd.c b/hw/display/dpcd.c
new file mode 100644
index 000..83dd489
--- /dev/null
+++ b/hw/display/dpcd.c
@@ -0,0 +1,171 @@
+/*
+ * dpcd.c
+ *
+ *  Copyright (C) 2015 : GreenSocs Ltd
+ *  http://www.greensocs.com/ , email: i...@greensocs.com
+ *
+ *  Developed by :
+ *  Frederic Konrad   <fred.kon...@greensocs.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option)any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/*
+ * This is a simple AUX slave which emulates a connected screen.
+ */
+
+#include "hw/aux.h"
+#include "dpcd.h"
+
+#ifndef DEBUG_DPCD
+#define DEBUG_DPCD 0
+#endif
+
+#define DPRINTF(fmt, ...) do { 
\
+if (DEBUG_DPCD) {  
\
+qemu_log("dpcd: " fmt, ## __VA_ARGS__);
\
+}  
\
+} while (0);
+
+#define DPCD_READABLE_AREA  0x600
+
+struct DPCDState {
+/*< private >*/
+AUXSlave parent_obj;
+
+/*< public >*/
+/*
+ * The DCPD is 0x7 length but read as 0 after offset 0x5FF.
+ */
+uint8_t dpcd_info[DPCD_READABLE_AREA];
+
+MemoryRegion iomem;
+};
+
+static uint64_t dpcd_read(void *opaque, hwaddr offset, unsigned size)
+{
+uint8_t ret;
+DPCDState *e = DPCD(opaque);
+
+if (offset < DPCD_READABLE_AREA) {
+ret = e->dpcd_info[offset];
+} else {
+qemu_log_mask(LOG_GUEST_ERROR, "dpcd: Bad offset 0x%" HWADDR_PRIX "\n",
+   offset);
+ret = 0;
+}
+
+DPRINTF("read 0x%" PRIX8 " @0x%" HWADDR_PRIX "\n", ret, offset);
+return ret;
+}
+
+static void dpcd_write(void *opaque, hwaddr offset, uint64_t value,
+   unsigned size)
+{
+DPCDState *e = DPCD(opaque);
+
+DPRINTF("write 0x%" PRIX8 " @0x%" HWADDR_PRIX "\n", (uint8_t)value, 
offset);
+
+if (offset < DPCD_READABLE_AREA) {
+e->dpcd_info[offset] = value;
+} else {
+qemu_log_mask(LOG_GUEST_ERROR, "dpcd: Bad offset 0x%" HWADDR_PRIX "\n",
+   offset);
+}
+}
+
+static const MemoryRegionOps aux_ops = {
+.read = dpcd_read,
+.write = dpcd_write,
+.valid = {
+.min_access_size = 1,
+.max_access_size = 1,
+},
+.impl = {
+.min_access_s

Re: [Qemu-devel] [PATCH V4 2/8] Introduce AUX bus.

2015-09-04 Thread Frederic Konrad

On 02/09/2015 02:00, Alistair Francis wrote:

On Tue, Sep 1, 2015 at 2:48 PM, Alistair Francis <alistai...@gmail.com> wrote:

On Tue, Jul 21, 2015 at 10:17 AM,  <fred.kon...@greensocs.com> wrote:

From: KONRAD Frederic <fred.kon...@greensocs.com>

This introduces a new bus: aux-bus.

It contains an address space for aux slaves devices and a bridge to an I2C bus
for I2C through AUX transactions.

Signed-off-by: KONRAD Frederic <fred.kon...@greensocs.com>
---
  default-configs/aarch64-softmmu.mak |   1 +
  hw/misc/Makefile.objs   |   1 +
  hw/misc/aux.c   | 374 
  include/hw/aux.h| 125 

This file should be under the include/hw/misc sub folder

Thanks,

Alistair


Done thanks,
Fred



  4 files changed, 501 insertions(+)
  create mode 100644 hw/misc/aux.c
  create mode 100644 include/hw/aux.h

diff --git a/default-configs/aarch64-softmmu.mak 
b/default-configs/aarch64-softmmu.mak
index 96dd994..d3a2665 100644
--- a/default-configs/aarch64-softmmu.mak
+++ b/default-configs/aarch64-softmmu.mak
@@ -3,4 +3,5 @@
  # We support all the 32 bit boards so need all their config
  include arm-softmmu.mak

+CONFIG_AUX=y
  CONFIG_XLNX_ZYNQMP=y
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 4aa76ff..e859a4b 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -40,3 +40,4 @@ obj-$(CONFIG_STM32F2XX_SYSCFG) += stm32f2xx_syscfg.o

  obj-$(CONFIG_PVPANIC) += pvpanic.o
  obj-$(CONFIG_EDU) += edu.o
+obj-$(CONFIG_AUX) += aux.o
diff --git a/hw/misc/aux.c b/hw/misc/aux.c
new file mode 100644
index 000..2dc2ac8
--- /dev/null
+++ b/hw/misc/aux.c
@@ -0,0 +1,374 @@
+/*
+ * aux.c
+ *
+ *  Copyright 2015 : GreenSocs Ltd
+ *  http://www.greensocs.com/ , email: i...@greensocs.com
+ *
+ *  Developed by :
+ *  Frederic Konrad   <fred.kon...@greensocs.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option)any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/*
+ * This is an implementation of the AUX bus for VESA Display Port v1.1a.
+ */
+
+#include "hw/aux.h"
+#include "hw/i2c/i2c.h"
+#include "monitor/monitor.h"
+
+#ifndef DEBUG_AUX
+#define DEBUG_AUX 0
+#endif
+
+#define DPRINTF(fmt, ...) do { 
\
+if (DEBUG_AUX) {   
\
+qemu_log("aux: " fmt , ## __VA_ARGS__);
\
+}  
\
+} while (0);
+
+#define TYPE_AUXTOI2C "aux-to-i2c-bridge"
+#define AUXTOI2C(obj) OBJECT_CHECK(AUXTOI2CState, (obj), TYPE_AUXTOI2C)
+
+#define TYPE_AUX_BUS "aux-bus"
+#define AUX_BUS(obj) OBJECT_CHECK(AUXBus, (obj), TYPE_AUX_BUS)
+
+static void aux_slave_dev_print(Monitor *mon, DeviceState *dev, int indent);
+
+static void aux_bus_class_init(ObjectClass *klass, void *data)
+{
+BusClass *k = BUS_CLASS(klass);
+
+/* AUXSlave has an MMIO so we need to change the way we print information
+ * in monitor.
+ */
+k->print_dev = aux_slave_dev_print;
+}
+
+static const TypeInfo aux_bus_info = {
+.name = TYPE_AUX_BUS,
+.parent = TYPE_BUS,
+.instance_size = sizeof(AUXBus),
+.class_init = aux_bus_class_init
+};
+
+AUXBus *aux_init_bus(DeviceState *parent, const char *name)
+{
+AUXBus *bus;
+
+bus = AUX_BUS(qbus_create(TYPE_AUX_BUS, parent, name));
+bus->bridge = AUXTOI2C(qdev_create(BUS(bus), TYPE_AUXTOI2C));
+
+/* Memory related. */
+bus->aux_io = g_malloc(sizeof(*bus->aux_io));
+memory_region_init(bus->aux_io, OBJECT(bus), "aux-io", (1 << 20));
+address_space_init(>aux_addr_space, bus->aux_io, "aux-io");
+return bus;
+}
+
+static void aux_bus_map_device(AUXBus *bus, AUXSlave *dev, hwaddr addr)
+{
+memory_region_add_subregion(bus->aux_io, addr, dev->mmio);
+}
+
+static bool aux_bus_is_bridge(AUXBus *bus, DeviceState *dev)
+{
+return (dev == DEVICE(bus->bridge));
+}
+
+/*
+ * Make a native request on the AUX bus.
+ */

A nit pick, but your comment styles changes throughout the file.

It's not worth re-spining, but something to keep in mind in the future.


+static AUXReply aux_native_request(AUXBus *bus, AUXCommand cmd,
+

Re: [Qemu-devel] MTTCG Tasks (kvmforum summary)

2015-09-04 Thread Frederic Konrad

Hi Alex,

On 04/09/2015 09:49, Alex Bennée wrote:

Hi,

At KVM Forum I sat down with Paolo and Frederic and we came up with the
current outstanding tasks on MTTCG. This is not comprehensive but
hopefully covers the big areas. They are sorted in rough order we'd like
to get them up-streamed.

* linux-user patches (Paolo)

Paolo has already grabbed a bunch of Fred's patch set where it makes
sense on its own. They are up on the list and need review to expedite
there way into the main tree now it is open for pull requests.

See thread: 1439397664-70734-1-git-send-email-pbonz...@redhat.com

* TLB_EXCL based LL/SC patches (Alvise)

I think our consensus is these provide a good basis for the solution to
modelling our atomics within TCG. I haven't had a chance to review
Emilio's series yet which may approach this problem differently. I think
the core patches with the generic backend support make a good basis to
base development work on.

We need to iterate and review the non-MTTCG variant of the patch set
with a view to up-streaming soon.

* Signal free qemu_cpu_kick (Paolo)

I don't know much about this patch set but I assume this avoids the need
to catch signals and longjmp about just to wake up?

* RCU tb_flush (needs writing)

The idea has been floated to introduce an RCU based translation buffer
to flushes can be done lazily and the buffers dumped once all threads
have stopped using them.

I have been pondering if looking into having translation regions would
be worth looking into so we can have translation buffers for contiguous
series of pages. That way we don't have to throw away all translations
on these big events. Currently every time we roll over the translation
buffer we throw a bunch of perfectly good code away. This may or may not
be orthogonal to using RCU?

I'm still not sure tb_flush needs so much effort.
tb_flush is happening very rarely just exiting everybody seems easier..



* Memory barrier support (need RFC for discussion)

I came to KVM forum with a back of the envelope idea we could implement
one or two barrier ops (acquire/release?). Various suggestions of other
types of memory behaviour have been suggested.

I'll try to pull together an RFC patch with design outline for
discussion. It would be nice to be able to demonstrate barrier failures
in my test cases as well ;-)

* longjmp in cpu_exec

Paolo is fairly sure that if you take page faults while IRQs happening
problems will occur with cpu->interrupt_request. Does it need to take
the BQL?

I'd like to see if we can get a torture test to stress this code
although it will require IPI support in the unit tests.

* tlb_flush and dmb behaviour (am I waiting for TLB flush?)

I think this means we need explicit memory barriers to sync updates to
the tlb.

* tb_find_fast outside the lock

Currently it is a big performance win as the tb_find_fast has a lot of
contention with other threads. However there is concern it needs to be
properly protected.

* Additional review comments on the Fred's branch
  - page->code_bitmap isn't protected by lock
  - cpu_breakpoint_insert needs locks

Thoses one are OK, I didn't send all that yet.


  - check gdbstub works

* What to do about icount?

What is the impact of multi-thread on icount? Do we need to disable it
for MTTCG or can it be correct per-cpu? Can it be updated lock-step?

We need some input from the guys that use icount the most.

Cheers,

Also we might want to have everything in a branch. So rebasing the 
Atomics series
on eg: 2.4.0 + 2 Paolo's series so I can rebase MTTCG on it and pick the 
MTTCG

atomic parts can be usefull.

Thanks,
Fred



Re: [Qemu-devel] [PATCH V4 6/8] Introduce xilinx dpdma.

2015-09-03 Thread Frederic Konrad
te_irq(s);
+}
+
+} while (!done && !one_desc);
+
+return ptr;
+}
+
+void xlnx_dpdma_set_host_data_location(XlnxDPDMAState *s, uint8_t channel,
+ void *p)
+{
+if (!s) {
+qemu_log_mask(LOG_UNIMP, "DPDMA client not attached to valid DPDMA"
+  " instance\n");
+return;
+}
+
+assert(channel <= 5);
+s->data[channel] = p;
+}
+
+void xlnx_dpdma_trigger_vsync_irq(XlnxDPDMAState *s)
+{
+s->registers[DPDMA_ISR] |= (1 << 27);
+xlnx_dpdma_update_irq(s);
+}
+
+type_init(xlnx_dpdma_register_types)
diff --git a/hw/dma/xlnx_dpdma.h b/hw/dma/xlnx_dpdma.h
new file mode 100644
index 000..ae571a0
--- /dev/null
+++ b/hw/dma/xlnx_dpdma.h
@@ -0,0 +1,85 @@
+/*
+ * xlnx_dpdma.h
+ *
+ *  Copyright (C) 2015 : GreenSocs Ltd
+ *  http://www.greensocs.com/ , email: i...@greensocs.com
+ *
+ *  Developed by :
+ *  Frederic Konrad   <fred.kon...@greensocs.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef XLNX_DPDMA_H
+#define XLNX_DPDMA_H
+
+#include "hw/sysbus.h"
+#include "ui/console.h"
+#include "sysemu/dma.h"
+
+#define XLNX_DPDMA_REG_ARRAY_SIZE (0x1000 >> 2)
+
+struct XlnxDPDMAState {
+/*< private >*/
+SysBusDevice parent_obj;
+/*< public >*/
+MemoryRegion iomem;
+uint32_t registers[XLNX_DPDMA_REG_ARRAY_SIZE];
+uint8_t *data[6];
+bool operation_finished[6];
+qemu_irq irq;
+};
+
+typedef struct XlnxDPDMAState XlnxDPDMAState;
+
+#define TYPE_XLNX_DPDMA "xlnx.dpdma"
+#define XLNX_DPDMA(obj) OBJECT_CHECK(XlnxDPDMAState, (obj), TYPE_XLNX_DPDMA)
+
+/*
+ * xlnx_dpdma_start_operation: Start the operation on the specified channel. 
The
+ * DPDMA gets the current descriptor and retrieves
+ * data to the buffer specified by
+ * dpdma_set_host_data_location().
+ *
+ * Returns The number of bytes transfered by the DPDMA or 0 if an error 
occured.
+ *
+ * @s The DPDMA state.
+ * @channel The channel to start.
+ */
+size_t xlnx_dpdma_start_operation(XlnxDPDMAState *s, uint8_t channel,
+  bool one_desc);
+
+/*
+ * xlnx_dpdma_set_host_data_location: Set the location in the host memory where
+ *to store the data out from the dma
+ *channel.
+ *
+ * @s The DPDMA state.
+ * @channel The channel associated to the pointer.
+ * @p The buffer where to store the data.
+ */
+/* XXX: add a maximum size arg and send an interrupt in case of overflow. */
+void xlnx_dpdma_set_host_data_location(XlnxDPDMAState *s, uint8_t channel,
+   void *p);
+
+/*
+ * xlnx_dpdma_trigger_vsync_irq: Trigger a VSYNC IRQ when the display is
+ *   updated.
+ *
+ * @s The DPDMA state.
+ */
+void xlnx_dpdma_trigger_vsync_irq(XlnxDPDMAState *s);
+
+#endif /* !XLNX_DPDMA_H */
--
1.9.0







Re: [Qemu-devel] [PATCH 03/10] replace spinlock by QemuMutex.

2015-08-28 Thread Frederic Konrad

On 28/08/2015 16:49, Peter Maydell wrote:

On 12 August 2015 at 17:40, Paolo Bonzini pbonz...@redhat.com wrote:

From: KONRAD Frederic fred.kon...@greensocs.com

spinlock is only used in two cases:
   * cpu-exec.c: to protect TranslationBlock
   * mem_helper.c: for lock helper in target-i386 (which seems broken).

It's a pthread_mutex_t in user-mode so better using QemuMutex directly in this
case.
It allows as well to reuse tb_lock mutex of TBContext in case of multithread
TCG.

The line wrapping in this commit message (and the grammar) looks a bit off...


Signed-off-by: KONRAD Frederic fred.kon...@greensocs.com
Message-Id: 1439220437-23957-5-git-send-email-fred.kon...@greensocs.com
Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
  cpu-exec.c   | 15 +++
  include/exec/exec-all.h  |  4 ++--
  linux-user/main.c|  6 +++---
  target-i386/cpu.h|  3 +++
  target-i386/mem_helper.c | 25 ++---
  target-i386/translate.c  |  2 ++
  tcg/tcg.h|  4 
  translate-all.c  | 34 ++
  8 files changed, 73 insertions(+), 20 deletions(-)

After this commit it looks like we have no users of spinlock_t
at all. It would be good to have a followup patch which deleted
include/exec/spinlock.h.


Seems Paolo forget to pick up the following patch from the mttcg tree:
remove unused spinlock.
https://lists.gnu.org/archive/html/qemu-devel/2015-08/msg01129.html

Thanks,
Fred

Otherwise
Reviewed-by: Peter Maydell peter.mayd...@linaro.org

thanks
-- PMM





[Qemu-devel] MTTCG next version?

2015-08-26 Thread Frederic Konrad

Hi everybody,

I'm trying to do the next version of the MTTCG work:

I would like to rebase on Alvise atomic instruction branch:
  - Alvise can you rebase it on the 2.4.0 version without MTTCG support 
and then
point me to the MTTCG specific changes so I can include them in my 
tree?

I will add Paolo's linux-user and signal free qemu_cpu_kick series as well.

About tb_flush we think to do that without exiting:
  - Use two buffers for tbs.
  - Use a per tb invalidated flag.
  - when tb_flush just invalidate all tb from the buffer and swap to 
the second buffer:
VCPU which are executing code will discard their tb_jmp_cache when 
they exit

(eg: run_on_cpu).

We need also to fix emulated data barrier so tlb_flush are finished 
before the

instruction is executed. (That might be only data barrier breaks the TB).

Protecting page-code_bitmap and cpu_breakpoint_insert changes will be 
squashed in the tb_lock patch.


More tests must be done especially with gdbstub and icount.

Do that make sense?
Fred



Re: [Qemu-devel] [RFC PATCH V7 07/19] protect TBContext with tb_lock.

2015-08-14 Thread Frederic Konrad

On 12/08/2015 20:20, Alex Bennée wrote:

Frederic Konrad fred.kon...@greensocs.com writes:


On 10/08/2015 17:27, fred.kon...@greensocs.com wrote:

From: KONRAD Frederic fred.kon...@greensocs.com

This protects TBContext with tb_lock to make tb_* thread safe.

We can still have issue with tb_flush in case of multithread TCG:
An other CPU can be executing code during a flush.

This can be fixed later by making all other TCG thread exiting before calling
tb_flush().

tb_find_slow is separated into tb_find_slow and tb_find_physical as the whole
tb_find_slow doesn't require to lock the tb.

Signed-off-by: KONRAD Frederic fred.kon...@greensocs.com

Changes:

[...]
   
@@ -675,6 +710,7 @@ static inline void code_gen_alloc(size_t tb_size)

   CODE_GEN_AVG_BLOCK_SIZE;
   tcg_ctx.tb_ctx.tbs =
   g_malloc(tcg_ctx.code_gen_max_blocks * sizeof(TranslationBlock));
+qemu_mutex_init(tcg_ctx.tb_ctx.tb_lock);
   }
   
   /* Must be called before using the QEMU cpus. 'tb_size' is the size

@@ -699,16 +735,22 @@ bool tcg_enabled(void)
   return tcg_ctx.code_gen_buffer != NULL;
   }
   
-/* Allocate a new translation block. Flush the translation buffer if

-   too many translation blocks or too much generated code. */
+/*
+ * Allocate a new translation block. Flush the translation buffer if
+ * too many translation blocks or too much generated code.
+ * tb_alloc is not thread safe but tb_gen_code is protected by a mutex so this
+ * function is called only by one thread.
+ */
   static TranslationBlock *tb_alloc(target_ulong pc)
   {
-TranslationBlock *tb;
+TranslationBlock *tb = NULL;
   
   if (tcg_ctx.tb_ctx.nb_tbs = tcg_ctx.code_gen_max_blocks ||

   (tcg_ctx.code_gen_ptr - tcg_ctx.code_gen_buffer) =
tcg_ctx.code_gen_buffer_max_size) {
-return NULL;
+tb = tcg_ctx.tb_ctx.tbs[tcg_ctx.tb_ctx.nb_tbs++];
+tb-pc = pc;
+tb-cflags = 0;

Missed this wrong unreverted part which in the end doesn't do a tb_flush
when required and crashes!
Fixing that allows me to boot with jessie and virt.

\o/

Do you see crashes while it is running?

It's interesting that I've not had a problem booting jessie with virt
though - just crashes while hanging.

Are you likely to push a v8 this week (or a temp branch?) with this and
any other obvious fixes? I appreciate Paolo has given you a not-so-small
pile of review comments as well so I wasn't looking for a complete new
patch set!

here is something I did yesterday:
multi_tcg_v7_bugfixed

The patch-set is a mess and not re-based on the patch-set sent by Paolo.

Fred




Fred





Re: [Qemu-devel] [PATCH 00/10] translate-all.c thread-safety

2015-08-14 Thread Frederic Konrad

On 12/08/2015 18:40, Paolo Bonzini wrote:

Hi, this is my attempt at 1) extracting upstreamable parts out of Fred's
MTTCG,


Can you take this one as well after the replace spinlock by QemuMutex:
remove unused spinlock.

Thanks,
Fred

  and 2) documenting what's going on in user-mode MTTCG 3) fix
one bug in the process.  I couldn't find any other locking problem
from reading the code.

The final two patches are not really upstreamable because they
add some still unnecessary locks to system emulation, but I included
them to show what's going on.  With this locking logic I do not need
tb_lock to be recursive anymore.

Paolo

KONRAD Frederic (4):
   cpus: protect work list with work_mutex
   cpus: remove tcg_halt_cond global variable.
   replace spinlock by QemuMutex.
   tcg: protect TBContext with tb_lock.

Paolo Bonzini (8):
   exec-all: remove non-TCG stuff from exec-all.h header.
   cpu-exec: elide more icount code if CONFIG_USER_ONLY
   tcg: code_bitmap is not used by user-mode emulation
   tcg: comment on which functions have to be called with mmap_lock held
   tcg: add memory barriers in page_find_alloc accesses
   exec: make mmap_lock/mmap_unlock globally available
   cpu-exec: fix lock hierarchy for user-mode emulation
   tcg: comment on which functions have to be called with tb_lock held

  bsd-user/qemu.h  |   2 -
  cpu-exec.c   | 107 +--
  cpus.c   |  34 ++
  exec.c   |   4 ++
  hw/i386/kvmvapic.c   |   2 +
  include/exec/exec-all.h  |  19 +++---
  include/exec/ram_addr.h  |   1 +
  include/qom/cpu.h|   9 ++-
  include/sysemu/sysemu.h  |   3 +
  linux-user/main.c|   6 +-
  linux-user/qemu.h|   2 -
  qom/cpu.c|   1 +
  target-i386/cpu.h|   3 +
  target-i386/mem_helper.c |  25 +++-
  target-i386/translate.c  |   2 +
  tcg/tcg.h|   6 ++
  translate-all.c  | 161 +--
  17 files changed, 290 insertions(+), 97 deletions(-)






Re: [Qemu-devel] [PATCH 05/10] cpu-exec: elide more icount code if CONFIG_USER_ONLY

2015-08-13 Thread Frederic Konrad

On 12/08/2015 18:40, Paolo Bonzini wrote:

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
  cpu-exec.c | 6 ++
  1 file changed, 6 insertions(+)

What about the icount part in CPUState and the tb_start/end ?
Can't this be removed as well?

Fred


diff --git a/cpu-exec.c b/cpu-exec.c
index 599e64d..bde5fd1 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -228,6 +228,7 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, 
uint8_t *tb_ptr)
  return next_tb;
  }
  
+#if defined(CONFIG_SOFTMMU)

  /* Execute the code without caching the generated code. An interpreter
 could be used if available. */
  static void cpu_exec_nocache(CPUState *cpu, int max_cycles,
@@ -251,6 +252,7 @@ static void cpu_exec_nocache(CPUState *cpu, int max_cycles,
  tb_phys_invalidate(tb, -1);
  tb_free(tb);
  }
+#endif
  
  static TranslationBlock *tb_find_slow(CPUState *cpu,

target_ulong pc,
@@ -523,6 +525,9 @@ int cpu_exec(CPUState *cpu)
  case TB_EXIT_ICOUNT_EXPIRED:
  {
  /* Instruction counter expired.  */
+#ifdef CONFIG_USER_ONLY
+abort();
+#else
  int insns_left = cpu-icount_decr.u32;
  if (cpu-icount_extra  insns_left = 0) {
  /* Refill decrementer and continue execution.  */
@@ -542,6 +547,7 @@ int cpu_exec(CPUState *cpu)
  cpu_loop_exit(cpu);
  }
  break;
+#endif
  }
  default:
  break;





Re: [Qemu-devel] [PATCH 12/10] tcg: protect TBContext with tb_lock.

2015-08-13 Thread Frederic Konrad

On 12/08/2015 18:41, Paolo Bonzini wrote:

From: KONRAD Frederic fred.kon...@greensocs.com

This protects TBContext with tb_lock to make tb_* thread safe.

We can still have issue with tb_flush in case of multithread TCG:
another CPU can be executing code during a flush.

This can be fixed later by making all other TCG thread exiting before calling
tb_flush().

Signed-off-by: KONRAD Frederic fred.kon...@greensocs.com

Changes:
V6 - V7:
   * Drop a tb_lock in already locked restore_state_to_opc.
V5 - V6:
   * Drop a tb_lock arround tb_find_fast in cpu-exec.c.
Message-Id: 1439220437-23957-8-git-send-email-fred.kon...@greensocs.com
Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
  cpu-exec.c |  6 ++
  exec.c |  3 +++
  hw/i386/kvmvapic.c |  2 ++
  translate-all.c| 38 --
  4 files changed, 43 insertions(+), 6 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index e712c6a..89b66f5 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -241,16 +241,22 @@ static void cpu_exec_nocache(CPUState *cpu, int 
max_cycles,
  if (max_cycles  CF_COUNT_MASK)
  max_cycles = CF_COUNT_MASK;
  
+tb_lock();

  tb = tb_gen_code(cpu, orig_tb-pc, orig_tb-cs_base, orig_tb-flags,
   max_cycles | CF_NOCACHE);
tb_gen_code() calls tb_alloc() which calls tb_flush() we end in a double 
tb_lock here.
But that's probably not really important here as we want to either do a 
tb_flush

outside cpu_exec or realloc an other code buffer.

Fred

  tb-orig_tb = tcg_ctx.tb_ctx.tb_invalidated_flag ? NULL : orig_tb;
  cpu-current_tb = tb;
+tb_unlock();
+
  /* execute the generated code */
  trace_exec_tb_nocache(tb, tb-pc);
  cpu_tb_exec(cpu, tb-tc_ptr);
+
+tb_lock();
  cpu-current_tb = NULL;
  tb_phys_invalidate(tb, -1);
  tb_free(tb);
+tb_unlock();
  }
  #endif
  
diff --git a/exec.c b/exec.c

index 856a859..9083307 100644
--- a/exec.c
+++ b/exec.c
@@ -1948,6 +1948,9 @@ static void check_watchpoint(int offset, int len, 
MemTxAttrs attrs, int flags)
  wp-hitattrs = attrs;
  if (!cpu-watchpoint_hit) {
  cpu-watchpoint_hit = wp;
+
+/* Unlocked by cpu_loop_exit or cpu_resume_from_signal.  */
+tb_lock();
  tb_check_watchpoint(cpu);
  if (wp-flags  BP_STOP_BEFORE_ACCESS) {
  cpu-exception_index = EXCP_DEBUG;
diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
index c6d34b2..d823e15 100644
--- a/hw/i386/kvmvapic.c
+++ b/hw/i386/kvmvapic.c
@@ -445,6 +445,8 @@ static void patch_instruction(VAPICROMState *s, X86CPU 
*cpu, target_ulong ip)
  resume_all_vcpus();
  
  if (!kvm_enabled()) {

+/* Unlocked by cpu_resume_from_signal.  */
+tb_lock();
  cs-current_tb = NULL;
  tb_gen_code(cs, current_pc, current_cs_base, current_flags, 1);
  cpu_resume_from_signal(cs, NULL);
diff --git a/translate-all.c b/translate-all.c
index 17d3cd1..7a4f8f1 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -301,6 +301,8 @@ bool cpu_restore_state(CPUState *cpu, uintptr_t retaddr)
  {
  TranslationBlock *tb;
  
+tb_lock();

+
  tb = tb_find_pc(retaddr);
  if (tb) {
  cpu_restore_state_from_tb(cpu, tb, retaddr);
@@ -310,8 +312,12 @@ bool cpu_restore_state(CPUState *cpu, uintptr_t retaddr)
  tb_phys_invalidate(tb, -1);
  tb_free(tb);
  }
+
+tb_unlock();
  return true;
  }
+
+tb_unlock();
  return false;
  }
  
@@ -820,6 +826,8 @@ static void page_flush_tb(void)

  /* XXX: tb_flush is currently not thread safe */
  void tb_flush(CPUState *cpu)
  {
+tb_lock();
+
  #if defined(DEBUG_FLUSH)
  printf(qemu: flush code_size=%ld nb_tbs=%d avg_tb_size=%ld\n,
 (unsigned long)(tcg_ctx.code_gen_ptr - tcg_ctx.code_gen_buffer),
@@ -844,6 +852,8 @@ void tb_flush(CPUState *cpu)
  /* XXX: flush processor icache at this point if cache flush is
 expensive */
  tcg_ctx.tb_ctx.tb_flush_count++;
+
+tb_unlock();
  }
  
  #ifdef DEBUG_TB_CHECK

@@ -1151,6 +1161,7 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, 
tb_page_addr_t end,
  /* we remove all the TBs in the range [start, end[ */
  /* XXX: see if in some cases it could be faster to invalidate all
 the code */
+tb_lock();
  tb = p-first_tb;
  while (tb != NULL) {
  n = (uintptr_t)tb  3;
@@ -1218,12 +1229,13 @@ void tb_invalidate_phys_page_range(tb_page_addr_t 
start, tb_page_addr_t end,
  if (current_tb_modified) {
  /* we generate a block containing just the instruction
 modifying the memory. It will ensure that it cannot modify
-   itself */
+   itself.  cpu_resume_from_signal unlocks tb_lock.  */
  cpu-current_tb = NULL;
  tb_gen_code(cpu, current_pc, current_cs_base, current_flags, 1);
  

Re: [Qemu-devel] [PATCH 12/10] tcg: protect TBContext with tb_lock.

2015-08-13 Thread Frederic Konrad

On 13/08/2015 15:01, Paolo Bonzini wrote:

+tb_lock();
   tb = tb_gen_code(cpu, orig_tb-pc, orig_tb-cs_base, orig_tb-flags,
max_cycles | CF_NOCACHE);

tb_gen_code() calls tb_alloc() which calls tb_flush() we end in a double
tb_lock here.
But that's probably not really important here as we want to either do a
tb_flush outside cpu_exec or realloc an other code buffer.

You're right!  Honestly I haven't tested tb_flush() at all with these
patches since it's documented as broken with multiple threads.

Luckily the bug is not in the first 10 patches. :)

Fortunately this revealed my yesterday bug with tb_alloc :).

Fred


Paolo





Re: [Qemu-devel] [PATCH 11/10] tcg: comment on which functions have to be called with tb_lock held

2015-08-13 Thread Frederic Konrad

On 12/08/2015 18:41, Paolo Bonzini wrote:

softmmu requires more functions to be thread-safe, because translation
blocks can be invalidated from e.g. notdirty callbacks.  Probably the
same holds for user-mode emulation, it's just that no one has ever
tried to produce a coherent locking there.

This patch will guide the introduction of more tb_lock and tb_unlock
calls for system emulation.

Note that after this patch some (most) of the mentioned functions are
still called outside tb_lock/tb_unlock.  The next one will rectify this.

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
  exec.c  |  1 +
  include/exec/exec-all.h |  2 ++
  include/qom/cpu.h   |  3 +++
  tcg/tcg.h   |  2 ++
  translate-all.c | 35 ---
  5 files changed, 36 insertions(+), 7 deletions(-)

diff --git a/exec.c b/exec.c
index 54cd70a..856a859 100644
--- a/exec.c
+++ b/exec.c
@@ -748,6 +748,7 @@ int cpu_breakpoint_insert(CPUState *cpu, vaddr pc, int 
flags,
  {
  CPUBreakpoint *bp;
  
+/* TODO: locking (RCU?) */

  bp = g_malloc(sizeof(*bp));
  
  bp-pc = pc;

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index b3f900a..943d97a 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -74,6 +74,7 @@ typedef struct TranslationBlock TranslationBlock;
  
  void gen_intermediate_code(CPUArchState *env, struct TranslationBlock *tb);

  void gen_intermediate_code_pc(CPUArchState *env, struct TranslationBlock *tb);
+/* Called with tb_lock held.  */
  void restore_state_to_opc(CPUArchState *env, struct TranslationBlock *tb,
int pc_pos);
  
@@ -278,6 +279,7 @@ static inline void tb_set_jmp_target(TranslationBlock *tb,
  
  #endif
  
+/* Called with tb_lock held.  */

  static inline void tb_add_jump(TranslationBlock *tb, int n,
 TranslationBlock *tb_next)
  {
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 77bbff2..56b1f4d 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -285,7 +285,10 @@ struct CPUState {
  
  void *env_ptr; /* CPUArchState */

  struct TranslationBlock *current_tb;
+
+/* Protected by tb_lock.  */
  struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE];

This is temporary as a first step?


+
  struct GDBRegisterState *gdb_regs;
  int gdb_num_regs;
  int gdb_num_g_regs;
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 0ae648f..a2cad31 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -590,6 +590,7 @@ static inline bool tcg_op_buf_full(void)
  
  /* pool based memory allocation */
  
+/* tb_lock must be held for tcg_malloc_internal. */

  void *tcg_malloc_internal(TCGContext *s, int size);
  void tcg_pool_reset(TCGContext *s);
  void tcg_pool_delete(TCGContext *s);
@@ -598,6 +599,7 @@ void tb_lock(void);
  void tb_unlock(void);
  void tb_lock_reset(void);
  
+/* Called with tb_lock held.  */

  static inline void *tcg_malloc(int size)
  {
  TCGContext *s = tcg_ctx;
diff --git a/translate-all.c b/translate-all.c
index edb9cb1..17d3cd1 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -237,6 +237,7 @@ int cpu_gen_code(CPUArchState *env, TranslationBlock *tb, 
int *gen_code_size_ptr
  }
  
  /* The cpu state corresponding to 'searched_pc' is restored.

+ * Called with tb_lock held.
   */
  static int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
   uintptr_t searched_pc)
@@ -424,6 +425,7 @@ static void page_init(void)
  }
  
  /* If alloc=1:

+ * Called with tb_lock held for system emulation.
   * Called with mmap_lock held for user-mode emulation.
   */
  static PageDesc *page_find_alloc(tb_page_addr_t index, int alloc)
@@ -734,8 +736,12 @@ bool tcg_enabled(void)
  return tcg_ctx.code_gen_buffer != NULL;
  }
  
-/* Allocate a new translation block. Flush the translation buffer if

-   too many translation blocks or too much generated code. */
+/*
+ * Allocate a new translation block. Flush the translation buffer if
+ * too many translation blocks or too much generated code.
+ *
+ * Called with tb_lock held.
+ */
  static TranslationBlock *tb_alloc(target_ulong pc)
  {
There is the famous tb_flush which needs to be called with tb_lock held 
as well.

There are several place where it's called.


  TranslationBlock *tb;
@@ -751,6 +757,7 @@ static TranslationBlock *tb_alloc(target_ulong pc)
  return tb;
  }
  
+/* Called with tb_lock held.  */

  void tb_free(TranslationBlock *tb)
  {
  /* In practice this is mostly used for single use temporary TB
@@ -859,7 +866,10 @@ static void tb_invalidate_check(target_ulong address)
  }
  }
  
-/* verify that all the pages have correct rights for code */

+/* verify that all the pages have correct rights for code
+ *
+ * Called with tb_lock held.
+ */
  static void tb_page_check(void)
  {
  TranslationBlock *tb;
@@ -947,7 +957,10 @@ static inline void tb_reset_jump(TranslationBlock *tb, int 
n)
  

Re: [Qemu-devel] [PATCH 03/10] replace spinlock by QemuMutex.

2015-08-13 Thread Frederic Konrad

On 13/08/2015 15:12, Paolo Bonzini wrote:


On 13/08/2015 14:17, Frederic Konrad wrote:

diff --git a/linux-user/main.c b/linux-user/main.c
index fdee981..fd06ce9 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -107,7 +107,7 @@ static int pending_cpus;
   /* Make sure everything is in a consistent state for calling
fork().  */
   void fork_start(void)
   {
-pthread_mutex_lock(tcg_ctx.tb_ctx.tb_lock);
+qemu_mutex_lock(tcg_ctx.tb_ctx.tb_lock);
   pthread_mutex_lock(exclusive_lock);
   mmap_fork_start();
   }
@@ -129,11 +129,11 @@ void fork_end(int child)
   pthread_mutex_init(cpu_list_mutex, NULL);
   pthread_cond_init(exclusive_cond, NULL);
   pthread_cond_init(exclusive_resume, NULL);
-pthread_mutex_init(tcg_ctx.tb_ctx.tb_lock, NULL);
+qemu_mutex_init(tcg_ctx.tb_ctx.tb_lock);
   gdbserver_fork(thread_cpu);
   } else {
   pthread_mutex_unlock(exclusive_lock);
-pthread_mutex_unlock(tcg_ctx.tb_ctx.tb_lock);
+qemu_mutex_unlock(tcg_ctx.tb_ctx.tb_lock);

We might want to use tb_lock/unlock in user code as well instead of
calling directly qemu_mutex_* ?

You cannot do that because of the recursive locking assertions; the
child is not using qemu_mutex_unlock, it's using qemu_mutex_init.  So I
would have to add some kind of tb_lock_reset_after_fork() function which
is a bit ugly.


True.

Fred

@@ -676,6 +709,7 @@ static inline void code_gen_alloc(size_t tb_size)
   CODE_GEN_AVG_BLOCK_SIZE;
   tcg_ctx.tb_ctx.tbs =
   g_malloc(tcg_ctx.code_gen_max_blocks *
sizeof(TranslationBlock));
+qemu_mutex_init(tcg_ctx.tb_ctx.tb_lock);

Maybe we can initialize the mutex only for CONFIG_USER_ONLY?

It's okay, it doesn't consume system resources.

Paolo





Re: [Qemu-devel] [PATCH 02/10] cpus: remove tcg_halt_cond global variable.

2015-08-13 Thread Frederic Konrad

On 12/08/2015 18:40, Paolo Bonzini wrote:

From: KONRAD Frederic fred.kon...@greensocs.com

This removes tcg_halt_cond global variable.
We need one QemuCond per virtual cpu for multithread TCG.

Signed-off-by: KONRAD Frederic fred.kon...@greensocs.com
Message-Id: 1439220437-23957-9-git-send-email-fred.kon...@greensocs.com
[Keep tcg_halt_cond for bisectability, while making it static. - Paolo]

How does that help bisectability?

Fred

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
  cpus.c | 12 +---
  1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/cpus.c b/cpus.c
index 9224488..8884278 100644
--- a/cpus.c
+++ b/cpus.c
@@ -813,7 +813,6 @@ static unsigned iothread_requesting_mutex;
  static QemuThread io_thread;
  
  static QemuThread *tcg_cpu_thread;

-static QemuCond *tcg_halt_cond;
  
  /* cpu creation */

  static QemuCond qemu_cpu_cond;
@@ -933,15 +932,13 @@ static void qemu_wait_io_event_common(CPUState *cpu)
  cpu-thread_kicked = false;
  }
  
-static void qemu_tcg_wait_io_event(void)

+static void qemu_tcg_wait_io_event(CPUState *cpu)
  {
-CPUState *cpu;
-
  while (all_cpu_threads_idle()) {
 /* Start accounting real time to the virtual clock if the CPUs
are idle.  */
  qemu_clock_warp(QEMU_CLOCK_VIRTUAL);
-qemu_cond_wait(tcg_halt_cond, qemu_global_mutex);
+qemu_cond_wait(cpu-halt_cond, qemu_global_mutex);
  }
  
  while (iothread_requesting_mutex) {

@@ -1067,7 +1064,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
  
  /* wait for initial kick-off after machine start */

  while (first_cpu-stopped) {
-qemu_cond_wait(tcg_halt_cond, qemu_global_mutex);
+qemu_cond_wait(first_cpu-halt_cond, qemu_global_mutex);
  
  /* process any pending work */

  CPU_FOREACH(cpu) {
@@ -1088,7 +1085,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
  qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
  }
  }
-qemu_tcg_wait_io_event();
+qemu_tcg_wait_io_event(QTAILQ_FIRST(cpus));
  }
  
  return NULL;

@@ -1265,6 +1262,7 @@ void resume_all_vcpus(void)
  static void qemu_tcg_init_vcpu(CPUState *cpu)
  {
  char thread_name[VCPU_THREAD_NAME_SIZE];
+static QemuCond *tcg_halt_cond;
  
  tcg_cpu_address_space_init(cpu, cpu-as);
  





Re: [Qemu-devel] [PATCH 03/10] replace spinlock by QemuMutex.

2015-08-13 Thread Frederic Konrad

On 12/08/2015 18:40, Paolo Bonzini wrote:

From: KONRAD Frederic fred.kon...@greensocs.com

spinlock is only used in two cases:
   * cpu-exec.c: to protect TranslationBlock
   * mem_helper.c: for lock helper in target-i386 (which seems broken).

It's a pthread_mutex_t in user-mode so better using QemuMutex directly in this
case.
It allows as well to reuse tb_lock mutex of TBContext in case of multithread
TCG.

Signed-off-by: KONRAD Frederic fred.kon...@greensocs.com
Message-Id: 1439220437-23957-5-git-send-email-fred.kon...@greensocs.com
Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
  cpu-exec.c   | 15 +++
  include/exec/exec-all.h  |  4 ++--
  linux-user/main.c|  6 +++---
  target-i386/cpu.h|  3 +++
  target-i386/mem_helper.c | 25 ++---
  target-i386/translate.c  |  2 ++
  tcg/tcg.h|  4 
  translate-all.c  | 34 ++
  8 files changed, 73 insertions(+), 20 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 713540f..c680cca 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -356,9 +356,6 @@ int cpu_exec(CPUState *cpu)
  uintptr_t next_tb;
  SyncClocks sc;
  
-/* This must be volatile so it is not trashed by longjmp() */

-volatile bool have_tb_lock = false;
-
  if (cpu-halted) {
  if (!cpu_has_work(cpu)) {
  return EXCP_HALTED;
@@ -475,8 +472,7 @@ int cpu_exec(CPUState *cpu)
  cpu-exception_index = EXCP_INTERRUPT;
  cpu_loop_exit(cpu);
  }
-spin_lock(tcg_ctx.tb_ctx.tb_lock);
-have_tb_lock = true;
+tb_lock();
  tb = tb_find_fast(cpu);
  /* Note: we do it here to avoid a gcc bug on Mac OS X when
 doing it in tb_find_slow */
@@ -498,9 +494,7 @@ int cpu_exec(CPUState *cpu)
  tb_add_jump((TranslationBlock *)(next_tb  ~TB_EXIT_MASK),
  next_tb  TB_EXIT_MASK, tb);
  }
-have_tb_lock = false;
-spin_unlock(tcg_ctx.tb_ctx.tb_lock);
-
+tb_unlock();
  /* cpu_interrupt might be called while translating the
 TB, but before it is linked into a potentially
 infinite loop and becomes env-current_tb. Avoid
@@ -567,10 +561,7 @@ int cpu_exec(CPUState *cpu)
  x86_cpu = X86_CPU(cpu);
  env = x86_cpu-env;
  #endif
-if (have_tb_lock) {
-spin_unlock(tcg_ctx.tb_ctx.tb_lock);
-have_tb_lock = false;
-}
+tb_lock_reset();
  }
  } /* for(;;) */
  
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h

index 29775c0..dafd177 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -178,7 +178,7 @@ struct TranslationBlock {
  struct TranslationBlock *jmp_first;
  };
  
-#include exec/spinlock.h

+#include qemu/thread.h
  
  typedef struct TBContext TBContext;
  
@@ -188,7 +188,7 @@ struct TBContext {

  TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
  int nb_tbs;
  /* any access to the tbs or the page table must use this lock */
-spinlock_t tb_lock;
+QemuMutex tb_lock;
  
  /* statistics */

  int tb_flush_count;
diff --git a/linux-user/main.c b/linux-user/main.c
index fdee981..fd06ce9 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -107,7 +107,7 @@ static int pending_cpus;
  /* Make sure everything is in a consistent state for calling fork().  */
  void fork_start(void)
  {
-pthread_mutex_lock(tcg_ctx.tb_ctx.tb_lock);
+qemu_mutex_lock(tcg_ctx.tb_ctx.tb_lock);
  pthread_mutex_lock(exclusive_lock);
  mmap_fork_start();
  }
@@ -129,11 +129,11 @@ void fork_end(int child)
  pthread_mutex_init(cpu_list_mutex, NULL);
  pthread_cond_init(exclusive_cond, NULL);
  pthread_cond_init(exclusive_resume, NULL);
-pthread_mutex_init(tcg_ctx.tb_ctx.tb_lock, NULL);
+qemu_mutex_init(tcg_ctx.tb_ctx.tb_lock);
  gdbserver_fork(thread_cpu);
  } else {
  pthread_mutex_unlock(exclusive_lock);
-pthread_mutex_unlock(tcg_ctx.tb_ctx.tb_lock);
+qemu_mutex_unlock(tcg_ctx.tb_ctx.tb_lock);
We might want to use tb_lock/unlock in user code as well instead of 
calling directly

qemu_mutex_* ?


  }
  }
  
diff --git a/target-i386/cpu.h b/target-i386/cpu.h

index ead2832..3655ff3 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -1318,6 +1318,9 @@ static inline MemTxAttrs cpu_get_mem_attrs(CPUX86State 
*env)
  void cpu_set_mxcsr(CPUX86State *env, uint32_t val);
  void cpu_set_fpuc(CPUX86State *env, uint16_t val);
  
+/* mem_helper.c */

+void helper_lock_init(void);
+
  /* svm_helper.c */
  void cpu_svm_check_intercept_param(CPUX86State *env1, uint32_t type,
 uint64_t param);
diff 

Re: [Qemu-devel] [PATCH 02/10] cpus: remove tcg_halt_cond global variable.

2015-08-13 Thread Frederic Konrad

On 13/08/2015 15:08, Paolo Bonzini wrote:


On 13/08/2015 15:05, Frederic Konrad wrote:


This removes tcg_halt_cond global variable.
We need one QemuCond per virtual cpu for multithread TCG.

Signed-off-by: KONRAD Frederic fred.kon...@greensocs.com
Message-Id: 1439220437-23957-9-git-send-email-fred.kon...@greensocs.com
[Keep tcg_halt_cond for bisectability, while making it static. - Paolo]

How does that help bisectability?

With your patch (08/19), QEMU will only wait on first_cpu-halt_cond but
will call broadcast on cpu-halt_cond.  Here I do the opposite: I wait
on cpu-halt_cond from some random CPU, but all of them point to the
same condvar tcg_halt_cond.

Paolo

Ok got it.

Fred



Re: [Qemu-devel] [PATCH 11/10] tcg: comment on which functions have to be called with tb_lock held

2015-08-13 Thread Frederic Konrad

On 13/08/2015 14:59, Paolo Bonzini wrote:


On 13/08/2015 14:51, Frederic Konrad wrote:

diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 77bbff2..56b1f4d 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -285,7 +285,10 @@ struct CPUState {
 void *env_ptr; /* CPUArchState */
   struct TranslationBlock *current_tb;
+
+/* Protected by tb_lock.  */
   struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE];

This is temporary as a first step?

Yes, I now saw that tb_lock has a huge contention in tb_find_fast. :)

Yes it is just enormous. Makes MTTCG 2x slower than upstream :).


I've now extracted parts of your patch tcg: protect TBContext with
tb_lock into a separate tcg: move tb_find_fast outside the tb_lock
critical section that also applies to user-mode emulation.  That way I
get good scalability on Dhrystone, same as with your branch.


I guess with the whole tlb/tb flush safe? Which is theorically protecting
tb_jmp_cache (or at least let only the right thread accessing it).
The drawback of all that is I'm not sure this is faster when we have a 
lot of
context switches. For tb_flush it's not really a problem as it happen 
approximately

never but the tb_invalidate, tlb_*_flush are more regular.

Fred


Do you agree with the first 10 patches as a first step towards
upstreaming the MTTCG work?

Paolo


+
   struct GDBRegisterState *gdb_regs;
   int gdb_num_regs;
   int gdb_num_g_regs;
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 0ae648f..a2cad31 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -590,6 +590,7 @@ static inline bool tcg_op_buf_full(void)
 /* pool based memory allocation */
   +/* tb_lock must be held for tcg_malloc_internal. */
   void *tcg_malloc_internal(TCGContext *s, int size);
   void tcg_pool_reset(TCGContext *s);
   void tcg_pool_delete(TCGContext *s);
@@ -598,6 +599,7 @@ void tb_lock(void);
   void tb_unlock(void);
   void tb_lock_reset(void);
   +/* Called with tb_lock held.  */
   static inline void *tcg_malloc(int size)
   {
   TCGContext *s = tcg_ctx;
diff --git a/translate-all.c b/translate-all.c
index edb9cb1..17d3cd1 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -237,6 +237,7 @@ int cpu_gen_code(CPUArchState *env,
TranslationBlock *tb, int *gen_code_size_ptr
   }
 /* The cpu state corresponding to 'searched_pc' is restored.
+ * Called with tb_lock held.
*/
   static int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock
*tb,
uintptr_t searched_pc)
@@ -424,6 +425,7 @@ static void page_init(void)
   }
 /* If alloc=1:
+ * Called with tb_lock held for system emulation.
* Called with mmap_lock held for user-mode emulation.
*/
   static PageDesc *page_find_alloc(tb_page_addr_t index, int alloc)
@@ -734,8 +736,12 @@ bool tcg_enabled(void)
   return tcg_ctx.code_gen_buffer != NULL;
   }
   -/* Allocate a new translation block. Flush the translation buffer if
-   too many translation blocks or too much generated code. */
+/*
+ * Allocate a new translation block. Flush the translation buffer if
+ * too many translation blocks or too much generated code.
+ *
+ * Called with tb_lock held.
+ */
   static TranslationBlock *tb_alloc(target_ulong pc)
   {

There is the famous tb_flush which needs to be called with tb_lock held
as well.
There are several place where it's called.


   TranslationBlock *tb;
@@ -751,6 +757,7 @@ static TranslationBlock *tb_alloc(target_ulong pc)
   return tb;
   }
   +/* Called with tb_lock held.  */
   void tb_free(TranslationBlock *tb)
   {
   /* In practice this is mostly used for single use temporary TB
@@ -859,7 +866,10 @@ static void tb_invalidate_check(target_ulong
address)
   }
   }
   -/* verify that all the pages have correct rights for code */
+/* verify that all the pages have correct rights for code
+ *
+ * Called with tb_lock held.
+ */
   static void tb_page_check(void)
   {
   TranslationBlock *tb;
@@ -947,7 +957,10 @@ static inline void tb_reset_jump(TranslationBlock
*tb, int n)
   tb_set_jmp_target(tb, n, (uintptr_t)(tb-tc_ptr +
tb-tb_next_offset[n]));
   }
   -/* invalidate one TB */
+/* invalidate one TB
+ *
+ * Called with tb_lock held.
+ */
   void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
   {
   CPUState *cpu;
@@ -1036,7 +1049,7 @@ static void build_page_bitmap(PageDesc *p)
   }
   #endif
   -/* Called with mmap_lock held for user mode emulation.  */
+/* Called with tb_lock held, and mmap_lock too for user mode
emulation.  */
   TranslationBlock *tb_gen_code(CPUState *cpu,
 target_ulong pc, target_ulong cs_base,
 int flags, int cflags)
@@ -1234,7 +1247,9 @@ void tb_invalidate_phys_page_fast(tb_page_addr_t
start, int len)
   }
   if (!p-code_bitmap 
   ++p-code_write_count = SMC_BITMAP_USE_THRESHOLD) {
-/* build code bitmap */
+/* build code bitmap.  FIXME: writes should

Re: [Qemu-devel] [RFC PATCH V7 11/19] tcg: switch on multithread.

2015-08-13 Thread Frederic Konrad

On 13/08/2015 13:17, Paolo Bonzini wrote:


On 10/08/2015 17:27, fred.kon...@greensocs.com wrote:

+while (!cpu-exit_request) {
  qemu_clock_enable(QEMU_CLOCK_VIRTUAL,
(cpu-singlestep_enabled  SSTEP_NOTIMER) == 0);
  
@@ -1507,7 +1480,7 @@ static void tcg_exec_all(void)

  }
  }
  
-first_cpu-exit_request = 0;

+cpu-exit_request = 0;

One issue here is that when tcg_cpu_exec returns EXCP_HALTED, the
function keeps looping.  There is no need to set cpu-exit_request in
that case, since in fact there is no request pending, so the while loop
probably should be an if.

Nice catch thanks!

I missed the fact that it was running through the list of VCPUs and 
exited the

for(;;) loop.

I should rework this patch a little.. Maybe it's better to keep this 
loop and exit it

when necessary eg: when icount elapse or cpu halted.

Fred



Also, cpu-interrupt_request is not protected by any mutex, so
everything apart from the non-zero test must take the iothread mutex.

Paolo






Re: [Qemu-devel] [RFC PATCH V7 11/19] tcg: switch on multithread.

2015-08-13 Thread Frederic Konrad

On 13/08/2015 16:58, Paolo Bonzini wrote:


On 13/08/2015 16:41, Frederic Konrad wrote:

One issue here is that when tcg_cpu_exec returns EXCP_HALTED, the
function keeps looping.  There is no need to set cpu-exit_request in
that case, since in fact there is no request pending, so the while loop
probably should be an if.

Nice catch thanks!

I missed the fact that it was running through the list of VCPUs and
exited the
for(;;) loop.

I should rework this patch a little.. Maybe it's better to keep this
loop and exit it
when necessary eg: when icount elapse or cpu halted.

Yeah, I don't have a particularly strong opinion on that.  You can look
at my mttcg github branch for my rebase on top of yesterday's series.
It seems to work at least on the small GreenSoCs buildroot image.

Paolo


Their still seems to be something wrong with 
memory_region_rom_device_set_romd

or something more general.
I'm trying to find this.

Fred



Re: [Qemu-devel] [RFC PATCH V7 00/19] Multithread TCG.

2015-08-12 Thread Frederic Konrad

On 11/08/2015 15:59, Frederic Konrad wrote:

On 11/08/2015 14:45, Paolo Bonzini wrote:

On 10/08/2015 17:26, fred.kon...@greensocs.com wrote:

From: KONRAD Frederic fred.kon...@greensocs.com

This is the 7th round of the MTTCG patch series.

Thanks to look at this.

Here is a list of issues that I found:

- tb_lock usage in tb_find_fast is complicated and introduces the need
for other complicated code such as the tb_invalidate callback. Instead,
the tb locking should reuse the cpu-exec.c code for user-mode emulation,
with additional locking in the spots identified by Fred.
The reason for this is that locking around tb_find_fast just kills the 
performance.




- tb_lock uses a recursive lock, but this is not necessary.  Did I ever
say I dislike recursive mutexes? :)  The wrappers
tb_lock()/tb_unlock()/tb_lock_reset() can catch recursive locking for
us, so it's not hard to do without it.
True this is definitely not nice but seems some code eg: tb_invalidate 
are called from
different place with or without the tb_lock. We might probably be able 
to lock the

caller.



- code_bitmap is not protected by any mutex
(tb_invalidate_phys_page_fast is called with the iothread mutex taken,
but other users of code_bitmap do not use it).  Writes should be
protected by the tb_lock, reads by either tb_lock or RCU.

Yes good point I missed this one.


- memory barriers are probably requested around accesses to
-exit_request.  -thread_kicked also needs to be accessed with atomics,
because async_run_{,safe_}on_cpu can be called outside the big QEMU 
lock.


- the whole signal-based qemu_cpu_kick can just go away.  Just setting
tcg_exit_req and exit_request will kick the TCG thread.  The hairy Win32
SuspendThread/ResumeThread goes away too.  I suggest doing it now,
because proving it unnecessary is easier than proving it correct.
Just setting tcg_exit_req and exit_request and signal the 
cpu-halt_cond I guess?

BTW that affect KVM as well. Seems this mechanism is used as well with
qemu_cpu_kick_self().. Which is a little strange as it seems the SIGIPI 
trigger a

dummy signal handler?

memset(sigact, 0, sizeof(sigact));
sigact.sa_handler = dummy_signal;
sigaction(SIG_IPI, sigact, NULL);





- user-mode emulation is broken (does not compile)

- the big QEMU lock is not taken anywhere for MMIO accesses that require
it (i.e. basically all of them)

Isn't that handled by prepare_mmio_access?



- some code wants to be called _outside_ the big QEMU lock, for example
because it longjmps back to cpu_exec.  For example, I suspect that the
notdirty callbacks must be marked with 
memory_region_clear_global_locking.


Fred


I've started looking at them (and documenting the locking conventions
for functions), and I hope to post it to some git repo later this week.

Paolo


It can be cloned from:
g...@git.greensocs.com:fkonrad/mttcg.git branch multi_tcg_v7.

This patch-set try to address the different issues in the global 
picture of

MTTCG, presented on the wiki.

== Needed patch for our work ==

Some preliminaries are needed for our work:
  * current_cpu doesn't make sense in mttcg so a tcg_executing flag 
is added to

the CPUState.
  * We need to run some work safely when all VCPUs are outside their 
execution
loop. This is done with the async_run_safe_work_on_cpu function 
introduced

in this series.
  * QemuSpin lock is introduced (on posix only yet) to allow a 
faster handling of

atomic instruction.

== Code generation and cache ==

As Qemu stands, there is no protection at all against two threads 
attempting to

generate code at the same time or modifying a TranslationBlock.
The protect TBContext with tb_lock patch address the issue of code 
generation

and makes all the tb_* function thread safe (except tb_flush).
This raised the question of one or multiple caches. We choosed to 
use one
unified cache because it's easier as a first step and since the 
structure of
QEMU effectively has a ‘local’ cache per CPU in the form of the jump 
cache, we

don't see the benefit of having two pools of tbs.

== Dirty tracking ==

Protecting the IOs:
To allows all VCPUs threads to run at the same time we need to drop the
global_mutex as soon as possible. The io access need to take the 
mutex. This is
likely to change when 
http://thread.gmane.org/gmane.comp.emulators.qemu/345258

will be upstreamed.

Invalidation of TranslationBlocks:
We can have all VCPUs running during an invalidation. Each VCPU is 
able to clean
it's jump cache itself as it is in CPUState so that can be handled 
by a simple

call to async_run_on_cpu. However tb_invalidate also writes to the
TranslationBlock which is shared as we have only one pool.
Hence this part of invalidate requires all VCPUs to exit before it 
can be done.

Hence the async_run_safe_work_on_cpu is introduced to handle this case.

== Atomic instruction ==

For now only ARM on x64 is supported by using an cmpxchg instruction.
Specifically the limitation of this approach

Re: [Qemu-devel] [RFC PATCH V7 09/19] Drop global lock during TCG code execution

2015-08-12 Thread Frederic Konrad

On 12/08/2015 11:58, Paolo Bonzini wrote:


On 11/08/2015 23:34, Frederic Konrad wrote:

Also if qemu_cond_broadcast(qemu_io_proceeded_cond) is being dropped
there is no point keeping the guff around in qemu_tcg_wait_io_event.


Yes good point.

BTW this leads to high consumption of host CPU eg: 100% per VCPU thread as
the VCPUs thread are no longer waiting for qemu_io_proceeded_cond.

If the guest CPU is busy waiting, that's expected.  But if the guest CPU
is halted, it should not have 100% host CPU consumption.

Paolo

Hmm so that's definitely strange... I mean theorically it's the same as 
before?


An other thing. It seems that we need to signal the VCPU when the 
iothread take

the lock eg:

if (tcg_enabled()  qemu_thread_is_self(io_thread)) {
CPU_FOREACH(cpu) {
cpu_exit(cpu);
}
}

To make this patch working without MTTCG.

Fred



Re: [Qemu-devel] [RFC PATCH V7 16/19] translate-all: introduces tb_flush_safe.

2015-08-12 Thread Frederic Konrad

On 12/08/2015 16:09, Paolo Bonzini wrote:


On 10/08/2015 17:27, fred.kon...@greensocs.com wrote:

From: KONRAD Frederic fred.kon...@greensocs.com

tb_flush is not thread safe we definitely need to exit VCPUs to do that.
This introduces tb_flush_safe which just creates an async safe work which will
do a tb_flush later.

Signed-off-by: KONRAD Frederic fred.kon...@greensocs.com

You could also allocate a new code buffer and free the old one with
call_rcu.  This should simplify things a lot.

Paolo

Depending the size of the code buffer this might be a good idea. :).

Fred



Re: [Qemu-devel] [RFC PATCH V7 07/19] protect TBContext with tb_lock.

2015-08-12 Thread Frederic Konrad

On 10/08/2015 17:27, fred.kon...@greensocs.com wrote:

From: KONRAD Frederic fred.kon...@greensocs.com

This protects TBContext with tb_lock to make tb_* thread safe.

We can still have issue with tb_flush in case of multithread TCG:
   An other CPU can be executing code during a flush.

This can be fixed later by making all other TCG thread exiting before calling
tb_flush().

tb_find_slow is separated into tb_find_slow and tb_find_physical as the whole
tb_find_slow doesn't require to lock the tb.

Signed-off-by: KONRAD Frederic fred.kon...@greensocs.com

Changes:

[...]
  
@@ -675,6 +710,7 @@ static inline void code_gen_alloc(size_t tb_size)

  CODE_GEN_AVG_BLOCK_SIZE;
  tcg_ctx.tb_ctx.tbs =
  g_malloc(tcg_ctx.code_gen_max_blocks * sizeof(TranslationBlock));
+qemu_mutex_init(tcg_ctx.tb_ctx.tb_lock);
  }
  
  /* Must be called before using the QEMU cpus. 'tb_size' is the size

@@ -699,16 +735,22 @@ bool tcg_enabled(void)
  return tcg_ctx.code_gen_buffer != NULL;
  }
  
-/* Allocate a new translation block. Flush the translation buffer if

-   too many translation blocks or too much generated code. */
+/*
+ * Allocate a new translation block. Flush the translation buffer if
+ * too many translation blocks or too much generated code.
+ * tb_alloc is not thread safe but tb_gen_code is protected by a mutex so this
+ * function is called only by one thread.
+ */
  static TranslationBlock *tb_alloc(target_ulong pc)
  {
-TranslationBlock *tb;
+TranslationBlock *tb = NULL;
  
  if (tcg_ctx.tb_ctx.nb_tbs = tcg_ctx.code_gen_max_blocks ||

  (tcg_ctx.code_gen_ptr - tcg_ctx.code_gen_buffer) =
   tcg_ctx.code_gen_buffer_max_size) {
-return NULL;
+tb = tcg_ctx.tb_ctx.tbs[tcg_ctx.tb_ctx.nb_tbs++];
+tb-pc = pc;
+tb-cflags = 0;


Missed this wrong unreverted part which in the end doesn't do a tb_flush 
when required and crashes!

Fixing that allows me to boot with jessie and virt.

Fred



Re: [Qemu-devel] [RFC PATCH V7 09/19] Drop global lock during TCG code execution

2015-08-11 Thread Frederic Konrad

On 11/08/2015 22:12, Alex Bennée wrote:

Paolo Bonzini pbonz...@redhat.com writes:


On 10/08/2015 17:27, fred.kon...@greensocs.com wrote:

  void qemu_mutex_lock_iothread(void)
  {
-atomic_inc(iothread_requesting_mutex);
-/* In the simple case there is no need to bump the VCPU thread out of
- * TCG code execution.
- */
-if (!tcg_enabled() || qemu_in_vcpu_thread() ||
-!first_cpu || !first_cpu-thread) {
-qemu_mutex_lock(qemu_global_mutex);
-atomic_dec(iothread_requesting_mutex);
-} else {
-if (qemu_mutex_trylock(qemu_global_mutex)) {
-qemu_cpu_kick_thread(first_cpu);
-qemu_mutex_lock(qemu_global_mutex);
-}
-atomic_dec(iothread_requesting_mutex);
-qemu_cond_broadcast(qemu_io_proceeded_cond);
-}
-iothread_locked = true;

iothread_locked = true must be kept.  Otherwise... yay! :)


Also if qemu_cond_broadcast(qemu_io_proceeded_cond) is being dropped
there is no point keeping the guff around in qemu_tcg_wait_io_event.


Yes good point.

BTW this leads to high consumption of host CPU eg: 100% per VCPU thread as
the VCPUs thread are no longer waiting for qemu_io_proceeded_cond.

Fred



Re: [Qemu-devel] [RFC PATCH V7 00/19] Multithread TCG.

2015-08-11 Thread Frederic Konrad

On 11/08/2015 08:15, Benjamin Herrenschmidt wrote:

On Mon, 2015-08-10 at 17:26 +0200, fred.kon...@greensocs.com wrote:

From: KONRAD Frederic fred.kon...@greensocs.com

This is the 7th round of the MTTCG patch series.


It can be cloned from:
g...@git.greensocs.com:fkonrad/mttcg.git branch multi_tcg_v7.

This patch-set try to address the different issues in the global picture of
MTTCG, presented on the wiki.

== Needed patch for our work ==

Some preliminaries are needed for our work:
  * current_cpu doesn't make sense in mttcg so a tcg_executing flag is added to
the CPUState.

Can't you just make it a TLS ?


True that can be done as well. But the tcg_exec_flags has a second 
meaning saying

you can't start executing code right now because I want to do a safe_work.



  * We need to run some work safely when all VCPUs are outside their execution
loop. This is done with the async_run_safe_work_on_cpu function introduced
in this series.
  * QemuSpin lock is introduced (on posix only yet) to allow a faster handling 
of
atomic instruction.

How do you handle the memory model ? IE , ARM and PPC are OO while x86
is (mostly) in order, so emulating ARM/PPC on x86 is fine but emulating
x86 on ARM or PPC will lead to problems unless you generate memory
barriers with every load/store ..


For the moment we are trying to do the first case.


At least on POWER7 and later on PPC we have the possibility of setting
the attribute Strong Access Ordering with mremap/mprotect (I dont'
remember which one) which gives us x86-like memory semantics...

I don't know if ARM supports something similar. On the other hand, when
emulating ARM on PPC or vice-versa, we can probably get away with no
barriers.

Do you expose some kind of guest memory model info to the TCG backend so
it can decide how to handle these things ?


== Code generation and cache ==

As Qemu stands, there is no protection at all against two threads attempting to
generate code at the same time or modifying a TranslationBlock.
The protect TBContext with tb_lock patch address the issue of code generation
and makes all the tb_* function thread safe (except tb_flush).
This raised the question of one or multiple caches. We choosed to use one
unified cache because it's easier as a first step and since the structure of
QEMU effectively has a ‘local’ cache per CPU in the form of the jump cache, we
don't see the benefit of having two pools of tbs.

== Dirty tracking ==

Protecting the IOs:
To allows all VCPUs threads to run at the same time we need to drop the
global_mutex as soon as possible. The io access need to take the mutex. This is
likely to change when http://thread.gmane.org/gmane.comp.emulators.qemu/345258
will be upstreamed.

Invalidation of TranslationBlocks:
We can have all VCPUs running during an invalidation. Each VCPU is able to clean
it's jump cache itself as it is in CPUState so that can be handled by a simple
call to async_run_on_cpu. However tb_invalidate also writes to the
TranslationBlock which is shared as we have only one pool.
Hence this part of invalidate requires all VCPUs to exit before it can be done.
Hence the async_run_safe_work_on_cpu is introduced to handle this case.

What about the host MMU emulation ? Is that multithreaded ? It has
potential issues when doing things like dirty bit updates into guest
memory, those need to be done atomically. Also TLB invalidations on ARM
and PPC are global, so they will need to invalidate the remote SW TLBs
as well.

Do you have a mechanism to synchronize with another thread ? IE, make it
pop out of TCG if already in and prevent it from getting in ? That way
you can remotely invalidate its TLB...
Yes that's what the safe_work is doing. Ask everybody to exit prevent 
VCPUs to

resume (tcg_exec_flag) and do the work when everybody is outside cpu-exec.




== Atomic instruction ==

For now only ARM on x64 is supported by using an cmpxchg instruction.
Specifically the limitation of this approach is that it is harder to support
64bit ARM on a host architecture that is multi-core, but only supports 32 bit
cmpxchg (we believe this could be the case for some PPC cores).

Right, on the other hand 64-bit will do fine. But then x86 has 2-value
atomics nowadays, doesn't it ? And that will be hard to emulate on
anything. You might need to have some kind of global hashed lock list
used by atomics (hash the physical address) as a fallback if you don't
have a 1:1 match between host and guest capabilities.
VOS did a Slow path for atomic instruction translation series you can 
find here:

https://lists.gnu.org/archive/html/qemu-devel/2015-08/msg00971.html

Which will be used in the end.

Thanks,
Fred


Cheers,
Ben.








Re: [Qemu-devel] [RFC PATCH V7 07/19] protect TBContext with tb_lock.

2015-08-11 Thread Frederic Konrad

On 10/08/2015 18:36, Paolo Bonzini wrote:


On 10/08/2015 17:27, fred.kon...@greensocs.com wrote:

diff --git a/cpu-exec.c b/cpu-exec.c
index f3358a9..a012e9d 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -131,6 +131,8 @@ static void init_delay_params(SyncClocks *sc, const 
CPUState *cpu)
  void cpu_loop_exit(CPUState *cpu)
  {
  cpu-current_tb = NULL;
+/* Release those mutex before long jump so other thread can work. */
+tb_lock_reset();
  siglongjmp(cpu-jmp_env, 1);
  }
  
@@ -143,6 +145,8 @@ void cpu_resume_from_signal(CPUState *cpu, void *puc)

  /* XXX: restore cpu registers saved in host registers */
  
  cpu-exception_index = -1;

+/* Release those mutex before long jump so other thread can work. */
+tb_lock_reset();
  siglongjmp(cpu-jmp_env, 1);
  }
  

I think you should start easy and reuse the existing tb_lock code in
cpu-exec.c:


I think it's definitely not sufficient. Is user-mode multithread still 
working today?


diff --git a/cpu-exec.c b/cpu-exec.c
index 9305f03..2909ec2 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -307,7 +307,6 @@ static TranslationBlock *tb_find_slow(CPUState *cpu, 
target_ulong pc,
  
  tb = tb_find_physical(cpu, pc, cs_base, flags);

  if (!tb) {
-tb_lock();
  /*
   * Retry to get the TB in case a CPU just translate it to avoid having
   * duplicated TB in the pool.
@@ -316,7 +315,6 @@ static TranslationBlock *tb_find_slow(CPUState *cpu, 
target_ulong pc,
  if (!tb) {
  tb = tb_gen_code(cpu, pc, cs_base, flags, 0);
  }
-tb_unlock();
  }
  /* we add the TB in the virtual pc hash table */
  cpu-tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;
@@ -372,11 +372,6 @@ int cpu_exec(CPUState *cpu)
  uintptr_t next_tb;
  SyncClocks sc;
  
-/* This must be volatile so it is not trashed by longjmp() */

-#if defined(CONFIG_USER_ONLY)
-volatile bool have_tb_lock = false;
-#endif
-
  if (cpu-halted) {
  if (!cpu_has_work(cpu)) {
  return EXCP_HALTED;
@@ -480,10 +475,7 @@ int cpu_exec(CPUState *cpu)
  cpu-exception_index = EXCP_INTERRUPT;
  cpu_loop_exit(cpu);
  }
-#if defined(CONFIG_USER_ONLY)
-qemu_mutex_lock(tcg_ctx.tb_ctx.tb_lock);
-have_tb_lock = true;
-#endif
+tb_lock();
  tb = tb_find_fast(cpu);
  /* Note: we do it here to avoid a gcc bug on Mac OS X when
 doing it in tb_find_slow */
@@ -505,10 +497,7 @@ int cpu_exec(CPUState *cpu)
  tb_add_jump((TranslationBlock *)(next_tb  ~TB_EXIT_MASK),
  next_tb  TB_EXIT_MASK, tb);
  }
-#if defined(CONFIG_USER_ONLY)
-have_tb_lock = false;
-qemu_mutex_unlock(tcg_ctx.tb_ctx.tb_lock);
-#endif
+tb_unlock();
  /* cpu_interrupt might be called while translating the
 TB, but before it is linked into a potentially
 infinite loop and becomes env-current_tb. Avoid
@@ -575,12 +564,7 @@ int cpu_exec(CPUState *cpu)
  x86_cpu = X86_CPU(cpu);
  env = x86_cpu-env;
  #endif
-#if defined(CONFIG_USER_ONLY)
-if (have_tb_lock) {
-qemu_mutex_unlock(tcg_ctx.tb_ctx.tb_lock);
-have_tb_lock = false;
-}
-#endif
+tb_lock_reset();
  }
  } /* for(;;) */
  


Optimizations should then come on top.


diff --git a/target-arm/translate.c b/target-arm/translate.c
index 69ac18c..960c75e 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -11166,6 +11166,8 @@ static inline void 
gen_intermediate_code_internal(ARMCPU *cpu,
  
  dc-tb = tb;
  
+tb_lock();

This locks twice, I think?  Both cpu_restore_state_from_tb and
tb_gen_code (which calls cpu_gen_code) take the lock.  How does it work?



Yes it's recursive we might not need that though. I probably locked too 
much some

function.

Thanks,
Fred

+
  dc-is_jmp = DISAS_NEXT;
  dc-pc = pc_start;
  dc-singlestep_enabled = cs-singlestep_enabled;
@@ -11506,6 +11508,7 @@ done_generating:
  tb-size = dc-pc - pc_start;
  tb-icount = num_insns;
  }
+tb_unlock();
  }
  
+/* tb_lock must be help for tcg_malloc_internal. */

Held, not help.

Paolo






Re: [Qemu-devel] [RFC PATCH V7 09/19] Drop global lock during TCG code execution

2015-08-11 Thread Frederic Konrad

On 10/08/2015 18:15, Paolo Bonzini wrote:


On 10/08/2015 17:27, fred.kon...@greensocs.com wrote:

  void qemu_mutex_lock_iothread(void)
  {
-atomic_inc(iothread_requesting_mutex);
-/* In the simple case there is no need to bump the VCPU thread out of
- * TCG code execution.
- */
-if (!tcg_enabled() || qemu_in_vcpu_thread() ||
-!first_cpu || !first_cpu-thread) {
-qemu_mutex_lock(qemu_global_mutex);
-atomic_dec(iothread_requesting_mutex);
-} else {
-if (qemu_mutex_trylock(qemu_global_mutex)) {
-qemu_cpu_kick_thread(first_cpu);
-qemu_mutex_lock(qemu_global_mutex);
-}
-atomic_dec(iothread_requesting_mutex);
-qemu_cond_broadcast(qemu_io_proceeded_cond);
-}
-iothread_locked = true;

iothread_locked = true must be kept.  Otherwise... yay! :)


oops :).



@@ -125,8 +128,10 @@ void tlb_flush_page(CPUState *cpu, target_ulong addr)
 can be detected */
  void tlb_protect_code(ram_addr_t ram_addr)
  {
+qemu_mutex_lock_iothread();
  cpu_physical_memory_test_and_clear_dirty(ram_addr, TARGET_PAGE_SIZE,
   DIRTY_MEMORY_CODE);
+qemu_mutex_unlock_iothread();
  }
  

Not needed anymore.


diff --git a/target-i386/misc_helper.c b/target-i386/misc_helper.c
index 52c5d65..55f63bf 100644
--- a/target-i386/misc_helper.c
+++ b/target-i386/misc_helper.c

None of this is needed anymore either! :)


+/*
+ * Some device's reset needs to grab the global_mutex. So just release it
+ * here.
+ */
+qemu_mutex_unlock_iothread();
  /* reset all devices */
  QTAILQ_FOREACH_SAFE(re, reset_handlers, entry, nre) {
  re-func(re-opaque);
  }
+qemu_mutex_lock_iothread();

Should never have been true?  (And, I think, it was pointed out in a
previous version too).

I had a double lock with the reset handler from vexpress-a15. I don't really
remember why. But I hacked that. It's fixed now :)

Thanks,
Fred


Paolo






Re: [Qemu-devel] [RFC PATCH V7 02/19] cpus: add tcg_exec_flag.

2015-08-11 Thread Frederic Konrad

On 11/08/2015 12:53, Paolo Bonzini wrote:


On 10/08/2015 17:27, fred.kon...@greensocs.com wrote:

@@ -583,5 +587,6 @@ int cpu_exec(CPUState *cpu)
  
  /* fail safe : never use current_cpu outside cpu_exec() */

  current_cpu = NULL;
+tcg_cpu_allow_execution(cpu);

I don't think this is correct; safe_work_pending() is a much clearer
test.  I'll revert locally to the previous version to play more with the
code.

Paolo


Yes definitely but we might have a race if we just use safe_work_pending().

Fred



  return ret;
  }
diff --git a/include/qom/cpu.h b/include/qom/cpu.h





Re: [Qemu-devel] [RFC PATCH V7 00/19] Multithread TCG.

2015-08-11 Thread Frederic Konrad

On 11/08/2015 14:45, Paolo Bonzini wrote:

On 10/08/2015 17:26, fred.kon...@greensocs.com wrote:

From: KONRAD Frederic fred.kon...@greensocs.com

This is the 7th round of the MTTCG patch series.

Thanks to look at this.

Here is a list of issues that I found:

- tb_lock usage in tb_find_fast is complicated and introduces the need
for other complicated code such as the tb_invalidate callback.  Instead,
the tb locking should reuse the cpu-exec.c code for user-mode emulation,
with additional locking in the spots identified by Fred.
The reason for this is that locking around tb_find_fast just kills the 
performance.




- tb_lock uses a recursive lock, but this is not necessary.  Did I ever
say I dislike recursive mutexes? :)  The wrappers
tb_lock()/tb_unlock()/tb_lock_reset() can catch recursive locking for
us, so it's not hard to do without it.
True this is definitely not nice but seems some code eg: tb_invalidate 
are called from
different place with or without the tb_lock. We might probably be able 
to lock the

caller.



- code_bitmap is not protected by any mutex
(tb_invalidate_phys_page_fast is called with the iothread mutex taken,
but other users of code_bitmap do not use it).  Writes should be
protected by the tb_lock, reads by either tb_lock or RCU.

Yes good point I missed this one.


- memory barriers are probably requested around accesses to
-exit_request.  -thread_kicked also needs to be accessed with atomics,
because async_run_{,safe_}on_cpu can be called outside the big QEMU lock.

- the whole signal-based qemu_cpu_kick can just go away.  Just setting
tcg_exit_req and exit_request will kick the TCG thread.  The hairy Win32
SuspendThread/ResumeThread goes away too.  I suggest doing it now,
because proving it unnecessary is easier than proving it correct.
Just setting tcg_exit_req and exit_request and signal the cpu-halt_cond 
I guess?



- user-mode emulation is broken (does not compile)

- the big QEMU lock is not taken anywhere for MMIO accesses that require
it (i.e. basically all of them)

Isn't that handled by prepare_mmio_access?



- some code wants to be called _outside_ the big QEMU lock, for example
because it longjmps back to cpu_exec.  For example, I suspect that the
notdirty callbacks must be marked with memory_region_clear_global_locking.


Fred


I've started looking at them (and documenting the locking conventions
for functions), and I hope to post it to some git repo later this week.

Paolo


It can be cloned from:
g...@git.greensocs.com:fkonrad/mttcg.git branch multi_tcg_v7.

This patch-set try to address the different issues in the global picture of
MTTCG, presented on the wiki.

== Needed patch for our work ==

Some preliminaries are needed for our work:
  * current_cpu doesn't make sense in mttcg so a tcg_executing flag is added to
the CPUState.
  * We need to run some work safely when all VCPUs are outside their execution
loop. This is done with the async_run_safe_work_on_cpu function introduced
in this series.
  * QemuSpin lock is introduced (on posix only yet) to allow a faster handling 
of
atomic instruction.

== Code generation and cache ==

As Qemu stands, there is no protection at all against two threads attempting to
generate code at the same time or modifying a TranslationBlock.
The protect TBContext with tb_lock patch address the issue of code generation
and makes all the tb_* function thread safe (except tb_flush).
This raised the question of one or multiple caches. We choosed to use one
unified cache because it's easier as a first step and since the structure of
QEMU effectively has a ‘local’ cache per CPU in the form of the jump cache, we
don't see the benefit of having two pools of tbs.

== Dirty tracking ==

Protecting the IOs:
To allows all VCPUs threads to run at the same time we need to drop the
global_mutex as soon as possible. The io access need to take the mutex. This is
likely to change when http://thread.gmane.org/gmane.comp.emulators.qemu/345258
will be upstreamed.

Invalidation of TranslationBlocks:
We can have all VCPUs running during an invalidation. Each VCPU is able to clean
it's jump cache itself as it is in CPUState so that can be handled by a simple
call to async_run_on_cpu. However tb_invalidate also writes to the
TranslationBlock which is shared as we have only one pool.
Hence this part of invalidate requires all VCPUs to exit before it can be done.
Hence the async_run_safe_work_on_cpu is introduced to handle this case.

== Atomic instruction ==

For now only ARM on x64 is supported by using an cmpxchg instruction.
Specifically the limitation of this approach is that it is harder to support
64bit ARM on a host architecture that is multi-core, but only supports 32 bit
cmpxchg (we believe this could be the case for some PPC cores).  For now this
case is not correctly handled. The existing atomic patch will attempt to execute
the 64 bit cmpxchg functionality in a non thread safe fashion. Our intention is
to provide a new 

  1   2   3   >