Re: [PATCH v2] m25p80: Improve error when the backend file size does not match the device

2022-11-16 Thread Francisco Iglesias
On [2022 Nov 15] Tue 16:10:00, Cédric Le Goater wrote:
> Currently, when a block backend is attached to a m25p80 device and the
> associated file size does not match the flash model, QEMU complains
> with the error message "failed to read the initial flash content".
> This is confusing for the user.
> 
> Use blk_check_size_and_read_all() instead of blk_pread() to improve
> the reported error.
> 
> Signed-off-by: Cédric Le Goater 

Reviewed-by: Francisco Iglesias 

> ---
>  hw/block/m25p80.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
> index 02adc87527..68a757abf3 100644
> --- a/hw/block/m25p80.c
> +++ b/hw/block/m25p80.c
> @@ -24,6 +24,7 @@
>  #include "qemu/osdep.h"
>  #include "qemu/units.h"
>  #include "sysemu/block-backend.h"
> +#include "hw/block/block.h"
>  #include "hw/qdev-properties.h"
>  #include "hw/qdev-properties-system.h"
>  #include "hw/ssi/ssi.h"
> @@ -1614,8 +1615,7 @@ static void m25p80_realize(SSIPeripheral *ss, Error 
> **errp)
>  trace_m25p80_binding(s);
>  s->storage = blk_blockalign(s->blk, s->size);
>  
> -if (blk_pread(s->blk, 0, s->size, s->storage, 0) < 0) {
> -error_setg(errp, "failed to read the initial flash content");
> +if (!blk_check_size_and_read_all(s->blk, s->storage, s->size, errp)) 
> {
>  return;
>  }
>  } else {
> -- 
> 2.38.1
> 



Re: [PATCH v3 1/8] m25p80: Add basic support for the SFDP command

2022-07-22 Thread Francisco Iglesias
On [2022 Jul 22] Fri 08:35:55, Cédric Le Goater wrote:
> JEDEC STANDARD JESD216 for Serial Flash Discovery Parameters (SFDP)
> provides a mean to describe the features of a serial flash device
> using a set of internal parameter tables.
> 
> This is the initial framework for the RDSFDP command giving access to
> a private SFDP area under the flash. This area now needs to be
> populated with the flash device characteristics, using a new
> 'sfdp_read' handler under FlashPartInfo.
> 
> Signed-off-by: Cédric Le Goater 

Reviewed-by: Francisco Iglesias 

> ---
>  hw/block/m25p80_sfdp.h | 18 ++
>  hw/block/m25p80.c  | 27 +++
>  MAINTAINERS|  2 +-
>  hw/block/trace-events  |  1 +
>  4 files changed, 47 insertions(+), 1 deletion(-)
>  create mode 100644 hw/block/m25p80_sfdp.h
> 
> diff --git a/hw/block/m25p80_sfdp.h b/hw/block/m25p80_sfdp.h
> new file mode 100644
> index ..230b07ef3308
> --- /dev/null
> +++ b/hw/block/m25p80_sfdp.h
> @@ -0,0 +1,18 @@
> +/*
> + * M25P80 SFDP
> + *
> + * Copyright (c) 2020, IBM Corporation.
> + *
> + * This code is licensed under the GPL version 2 or later. See the
> + * COPYING file in the top-level directory.
> + */
> +
> +#ifndef HW_M25P80_SFDP_H
> +#define HW_M25P80_SFDP_H
> +
> +/*
> + * SFDP area has a 3 bytes address space.
> + */
> +#define M25P80_SFDP_MAX_SIZE  (1 << 24)
> +
> +#endif
> diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
> index a8d2519141f7..abdc4c0b0da7 100644
> --- a/hw/block/m25p80.c
> +++ b/hw/block/m25p80.c
> @@ -35,6 +35,7 @@
>  #include "qapi/error.h"
>  #include "trace.h"
>  #include "qom/object.h"
> +#include "m25p80_sfdp.h"
>  
>  /* 16 MiB max in 3 byte address mode */
>  #define MAX_3BYTES_SIZE 0x100
> @@ -72,6 +73,7 @@ typedef struct FlashPartInfo {
>   * This field inform how many die is in the chip.
>   */
>  uint8_t die_cnt;
> +uint8_t (*sfdp_read)(uint32_t sfdp_addr);
>  } FlashPartInfo;
>  
>  /* adapted from linux */
> @@ -355,6 +357,7 @@ typedef enum {
>  BULK_ERASE = 0xc7,
>  READ_FSR = 0x70,
>  RDCR = 0x15,
> +RDSFDP = 0x5a,
>  
>  READ = 0x03,
>  READ4 = 0x13,
> @@ -421,6 +424,7 @@ typedef enum {
>  STATE_COLLECTING_DATA,
>  STATE_COLLECTING_VAR_LEN_DATA,
>  STATE_READING_DATA,
> +STATE_READING_SFDP,
>  } CMDState;
>  
>  typedef enum {
> @@ -679,6 +683,8 @@ static inline int get_addr_length(Flash *s)
>  }
>  
> switch (s->cmd_in_progress) {
> +   case RDSFDP:
> +   return 3;
> case PP4:
> case PP4_4:
> case QPP_4:
> @@ -823,6 +829,11 @@ static void complete_collecting_data(Flash *s)
>" by device\n");
>  }
>  break;
> +
> +case RDSFDP:
> +s->state = STATE_READING_SFDP;
> +break;
> +
>  default:
>  break;
>  }
> @@ -1431,6 +1442,16 @@ static void decode_new_cmd(Flash *s, uint32_t value)
>  qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Unknown cmd %x\n", 
> value);
>  }
>  break;
> +case RDSFDP:
> +if (s->pi->sfdp_read) {
> +s->needed_bytes = get_addr_length(s) + 1; /* SFDP addr + dummy */
> +s->pos = 0;
> +s->len = 0;
> +s->state = STATE_COLLECTING_DATA;
> +break;
> +}
> +/* Fallthrough */
> +
>  default:
>  s->pos = 0;
>  s->len = 1;
> @@ -1538,6 +1559,12 @@ static uint32_t m25p80_transfer8(SSIPeripheral *ss, 
> uint32_t tx)
>  }
>  }
>  break;
> +case STATE_READING_SFDP:
> +assert(s->pi->sfdp_read);
> +r = s->pi->sfdp_read(s->cur_addr);
> +trace_m25p80_read_sfdp(s, s->cur_addr, (uint8_t)r);
> +s->cur_addr = (s->cur_addr + 1) & (M25P80_SFDP_MAX_SIZE - 1);
> +break;
>  
>  default:
>  case STATE_IDLE:
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 6af9cd985cea..92f232f01e3c 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1915,7 +1915,7 @@ SSI
>  M: Alistair Francis 
>  S: Maintained
>  F: hw/ssi/*
> -F: hw/block/m25p80.c
> +F: hw/block/m25p80*
>  F: include/hw/ssi/ssi.h
>  X: hw/ssi/xilinx_*
>  F: tests/qtest/m25p80-test.c
> diff --git a/hw/block/trace-events b/hw/block/trace-events
> index d86b53520cc5..2c45a62bd59c 100644
> --- a/hw/block/trace-events
> +++ b/hw/block/trace-events
> @@ -80,5 +80,6 @@ m25p80_page_program(

Re: [PATCH 16/21] hw/net/can/versal: Prefer object_initialize_child over object_initialize

2024-02-23 Thread Francisco Iglesias

On 2024-02-16 12:03, Philippe Mathieu-Daudé wrote:

When the QOM parent is available, prefer object_initialize_child()
over object_initialize(), since it create the parent relationship.

Signed-off-by: Philippe Mathieu-Daudé 


Reviewed-by: Francisco Iglesias 



---
  hw/net/can/xlnx-versal-canfd.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/net/can/xlnx-versal-canfd.c b/hw/net/can/xlnx-versal-canfd.c
index 47a14cfe63..f8e4bd75e4 100644
--- a/hw/net/can/xlnx-versal-canfd.c
+++ b/hw/net/can/xlnx-versal-canfd.c
@@ -1900,7 +1900,7 @@ static int canfd_populate_regarray(XlnxVersalCANFDState 
*s,
  int index = rae[i].addr / 4;
  RegisterInfo *r = &s->reg_info[index];
  
-object_initialize(r, sizeof(*r), TYPE_REGISTER);

+object_initialize_child(OBJECT(s), "reg[*]", r, TYPE_REGISTER);
  
  *r = (RegisterInfo) {

  .data = &s->regs[index],




Re: [QEMU][PATCH v2] ssi: xilinx_spips: Skip update of cs and fifo releated to spips in gqspi

2019-10-17 Thread Francisco Iglesias
Hi Sai,

On [2019 Oct 17] Thu 15:47:54, Sai Pavan Boddu wrote:
> GQSPI handles chip selects and fifos in a different way compared to
> spips. So skip update of cs and fifos related to spips in gqspi mode.
> 
> Signed-off-by: Sai Pavan Boddu 
> ---
> Changes for V2:
> Just skip update of spips cs and fifos
> Update commit message accordingly
> 
>  hw/ssi/xilinx_spips.c | 7 +++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
> index a309c71..27154b0 100644
> --- a/hw/ssi/xilinx_spips.c
> +++ b/hw/ssi/xilinx_spips.c
> @@ -1022,6 +1022,13 @@ static void xilinx_spips_write(void *opaque, hwaddr 
> addr,
>  }
>  s->regs[addr] = (s->regs[addr] & ~mask) | (value & mask);
>  no_reg_update:
> +/* In GQSPI mode skip update of CS and fifo's related to spips */
> +if (object_dynamic_cast(OBJECT(s), TYPE_XLNX_ZYNQMP_QSPIPS)) {
> +XlnxZynqMPQSPIPS *ss = XLNX_ZYNQMP_QSPIPS(s);
> +if (ARRAY_FIELD_EX32(ss->regs, GQSPI_SELECT, GENERIC_QSPI_EN)) {
> +return;
> +}
> +}

Above corrects the issue for the zynqmp but not for the other two models
(below functions shouldn't be called when writing the mentioned config
regs for them either), would it be ok for you to expand to the switch
cases you had in v1 (into the switch in this function and return after
updating the reg values)? (the correction will then spawn all three
models)

Best regards,
Francisco Iglesias

>  xilinx_spips_update_cs_lines(s);
>  xilinx_spips_check_flush(s);
>  xilinx_spips_update_cs_lines(s);
> -- 
> 2.7.4
> 
> 



Re: [PATCH v3] ssi: xilinx_spips: Skip spi bus update for few register writes

2019-10-18 Thread Francisco Iglesias
Hi Sai,

On [2019 Oct 18] Fri 14:39:04, Sai Pavan Boddu wrote:
> Few of the register writes need not update the spi bus state, so just
> return after reg write. Added few more dummy register offsets which need
> the same behaviour.
> 
> Signed-off-by: Sai Pavan Boddu 
> ---
> Changes for V2:
>   Just skip update of spips cs and fifos
>   Update commit message accordingly
> Changes for V3:
>   Avoid checking for zynqmp qspi
>   Skip spi bus update for few of the registers
> 
>  hw/ssi/xilinx_spips.c | 12 
>  1 file changed, 12 insertions(+)
> 
> diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
> index a309c71..c23de47 100644
> --- a/hw/ssi/xilinx_spips.c
> +++ b/hw/ssi/xilinx_spips.c
> @@ -109,6 +109,7 @@
>  #define R_GPIO  (0x30 / 4)
>  #define R_LPBK_DLY_ADJ  (0x38 / 4)
>  #define R_LPBK_DLY_ADJ_RESET (0x33)
> +#define R_IOU_TAPDLY_BYPASS (0x3C / 4)
>  #define R_TXD1  (0x80 / 4)
>  #define R_TXD2  (0x84 / 4)
>  #define R_TXD3  (0x88 / 4)
> @@ -139,6 +140,8 @@
>  #define R_LQSPI_STS (0xA4 / 4)
>  #define LQSPI_STS_WR_RECVD  (1 << 1)
>  
> +#define R_DUMMY_CYCLE_EN(0xC8 / 4)
> +#define R_ECO   (0xF8 / 4)
>  #define R_MOD_ID(0xFC / 4)
>  
>  #define R_GQSPI_SELECT  (0x144 / 4)
> @@ -1022,6 +1025,15 @@ static void xilinx_spips_write(void *opaque, hwaddr 
> addr,
>  }
>  s->regs[addr] = (s->regs[addr] & ~mask) | (value & mask);
>  no_reg_update:
> +/* Skip SPI bus update for below registers writes */
> +switch (addr) {
> +case R_GPIO:
> +case R_LPBK_DLY_ADJ:
> +case R_IOU_TAPDLY_BYPASS:
> +case R_DUMMY_CYCLE_EN:
> +case R_ECO:

Would it be ok for you to move above cases into the switch case above in
this same function instead? (And add a reg write before returning) This
way all registers are handled at the same place (switch case).

Best regards,
Francisco Iglesias

> +return;
> +}
>  xilinx_spips_update_cs_lines(s);
>  xilinx_spips_check_flush(s);
>  xilinx_spips_update_cs_lines(s);
> -- 
> 2.7.4
> 



Re: [QEMU][PATCH v4] ssi: xilinx_spips: Skip spi bus update for a few register writes

2019-10-21 Thread Francisco Iglesias
On [2019 Oct 21] Mon 20:11:51, Sai Pavan Boddu wrote:
Hi Sai,

> A few of the register writes need not update the spi bus state, so just

s/of the/configuration/

> return after reg write. Added few more dummy register offsets which need

s/reg/register/

> the same behaviour.

I apologize but I forgot to mention that below are not dummy registers
(they are configuration registers). Would it be ok for you to remove the
last (second) sentence above? 

The patch looks ok to me after that! (Also tested it!)

Best regards,
Francisco Iglesias

> 
> Signed-off-by: Sai Pavan Boddu 
> ---
> Changes for V2:
>   Just skip update of spips cs and fifos
>   Update commit message accordingly
> Changes for V3:
>   Avoid checking for zynqmp qspi
>   Skip spi bus update for few of the registers
> Changes for V4:
>   Move the register list to existing switch case above.
> 
>  hw/ssi/xilinx_spips.c | 22 ++
>  1 file changed, 18 insertions(+), 4 deletions(-)
> 
> diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
> index a309c71..0d6c2e1 100644
> --- a/hw/ssi/xilinx_spips.c
> +++ b/hw/ssi/xilinx_spips.c
> @@ -109,6 +109,7 @@
>  #define R_GPIO  (0x30 / 4)
>  #define R_LPBK_DLY_ADJ  (0x38 / 4)
>  #define R_LPBK_DLY_ADJ_RESET (0x33)
> +#define R_IOU_TAPDLY_BYPASS (0x3C / 4)
>  #define R_TXD1  (0x80 / 4)
>  #define R_TXD2  (0x84 / 4)
>  #define R_TXD3  (0x88 / 4)
> @@ -139,6 +140,8 @@
>  #define R_LQSPI_STS (0xA4 / 4)
>  #define LQSPI_STS_WR_RECVD  (1 << 1)
>  
> +#define R_DUMMY_CYCLE_EN(0xC8 / 4)
> +#define R_ECO   (0xF8 / 4)
>  #define R_MOD_ID(0xFC / 4)
>  
>  #define R_GQSPI_SELECT  (0x144 / 4)
> @@ -970,6 +973,7 @@ static void xilinx_spips_write(void *opaque, hwaddr addr,
>  {
>  int mask = ~0;
>  XilinxSPIPS *s = opaque;
> +bool try_flush = true;
>  
>  DB_PRINT_L(0, "addr=" TARGET_FMT_plx " = %x\n", addr, (unsigned)value);
>  addr >>= 2;
> @@ -1019,13 +1023,23 @@ static void xilinx_spips_write(void *opaque, hwaddr 
> addr,
>  tx_data_bytes(&s->tx_fifo, (uint32_t)value, 3,
>s->regs[R_CONFIG] & R_CONFIG_ENDIAN);
>  goto no_reg_update;
> +/* Skip SPI bus update for below registers writes */
> +case R_GPIO:
> +case R_LPBK_DLY_ADJ:
> +case R_IOU_TAPDLY_BYPASS:
> +case R_DUMMY_CYCLE_EN:
> +case R_ECO:
> +try_flush = false;
> +break;
>  }
>  s->regs[addr] = (s->regs[addr] & ~mask) | (value & mask);
>  no_reg_update:
> -xilinx_spips_update_cs_lines(s);
> -xilinx_spips_check_flush(s);
> -xilinx_spips_update_cs_lines(s);
> -xilinx_spips_update_ixr(s);
> +if (try_flush) {
> +xilinx_spips_update_cs_lines(s);
> +xilinx_spips_check_flush(s);
> +xilinx_spips_update_cs_lines(s);
> +xilinx_spips_update_ixr(s);
> +}
>  }
>  
>  static const MemoryRegionOps spips_ops = {
> -- 
> 2.7.4
> 



[PATCH] xilinx_spips: Correct the number of dummy cycles for the FAST_READ_4 cmd

2020-02-18 Thread Francisco Iglesias
From: Francisco Iglesias 

Correct the number of dummy cycles required by the FAST_READ_4 command (to
be eight, one dummy byte).

Fixes: ef06ca3946 ("xilinx_spips: Add support for RX discard and RX drain")
Suggested-by: Cédric Le Goater 
Signed-off-by: Francisco Iglesias 
---
 hw/ssi/xilinx_spips.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
index 6c9ef59779..c57850a505 100644
--- a/hw/ssi/xilinx_spips.c
+++ b/hw/ssi/xilinx_spips.c
@@ -576,11 +576,11 @@ static int xilinx_spips_num_dummies(XilinxQSPIPS *qs, 
uint8_t command)
 case FAST_READ:
 case DOR:
 case QOR:
+case FAST_READ_4:
 case DOR_4:
 case QOR_4:
 return 1;
 case DIOR:
-case FAST_READ_4:
 case DIOR_4:
 return 2;
 case QIOR:
-- 
2.11.0




Re: [PATCH 3/3] aspeed/smc: Fix number of dummy cycles for FAST_READ_4 command

2020-02-18 Thread Francisco Iglesias
Hi Cédric,

On [2020 Feb 04] Tue 08:45:11, Cédric Le Goater wrote:
> On 2/3/20 7:09 PM, Guenter Roeck wrote:
> > The Linux kernel recently started using FAST_READ_4 commands.
> > This results in flash read failures. At the same time, the m25p80
> > emulation is seen to read 8 more bytes than expected. Adjusting the
> > expected number of dummy cycles to match FAST_READ fixes the problem.
> 
> Which machine are you using for these tests ? the AST2500 evb using
> the w25q256 flash model ? 
> 
> Any how, it looks correct. 
> 
> Reviewed-by: Cédric Le Goater 
> Fixes: f95c4bffdc4c ("aspeed/smc: snoop SPI transfers to fake dummy cycles")
> 
> I think commit ef06ca3946e2 ("xilinx_spips: Add support for RX discard 
> and RX drain") needs a similar fix. Adding Francisco.

Yes, I agree that a similar fix is needed in the xilinx_spips aswell, I just
provided a patch. Thank you for the notification!

Best regards,
Francisco Iglesias

> 
> Thanks,
> 
> C. 
> 
> 
> > Signed-off-by: Guenter Roeck 
> > ---
> >  hw/ssi/aspeed_smc.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
> > index f0c7bbbad3..61e8fa57d3 100644
> > --- a/hw/ssi/aspeed_smc.c
> > +++ b/hw/ssi/aspeed_smc.c
> > @@ -762,11 +762,11 @@ static int aspeed_smc_num_dummies(uint8_t command)
> >  case FAST_READ:
> >  case DOR:
> >  case QOR:
> > +case FAST_READ_4:
> >  case DOR_4:
> >  case QOR_4:
> >  return 1;
> >  case DIOR:
> > -case FAST_READ_4:
> >  case DIOR_4:
> >  return 2;
> >  case QIOR:
> > 
> 



[Qemu-devel] [PATCH] memory: Correct access mask generation in access_with_adjusted_size

2019-08-12 Thread Francisco Iglesias
Also consider the requested transaction size when generating the access
mask (so that only the requested bytes are returned when those are less
than the memory region's minimum access size).

Signed-off-by: Francisco Iglesias 
---
 memory.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/memory.c b/memory.c
index 5d8c9a9234..56a2510836 100644
--- a/memory.c
+++ b/memory.c
@@ -563,7 +563,7 @@ static MemTxResult access_with_adjusted_size(hwaddr addr,
 
 /* FIXME: support unaligned access? */
 access_size = MAX(MIN(size, access_size_max), access_size_min);
-access_mask = MAKE_64BIT_MASK(0, access_size * 8);
+access_mask = MAKE_64BIT_MASK(0, MIN(size, access_size) * 8);
 if (memory_region_big_endian(mr)) {
 for (i = 0; i < size; i += access_size) {
 r |= access_fn(mr, addr + i, value, access_size,
-- 
2.11.0




[PATCH v1 2/9] hw/arm/xlnx-versal: Connect Versal's PMC SLCR

2021-11-17 Thread Francisco Iglesias
Connect Versal's PMC SLCR (system-level control registers) model.

Signed-off-by: Francisco Iglesias 
---
 hw/arm/xlnx-versal.c | 18 ++
 include/hw/arm/xlnx-versal.h |  6 ++
 2 files changed, 24 insertions(+)

diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
index b2705b6925..08e250945f 100644
--- a/hw/arm/xlnx-versal.c
+++ b/hw/arm/xlnx-versal.c
@@ -369,6 +369,23 @@ static void versal_create_efuse(Versal *s, qemu_irq *pic)
 sysbus_connect_irq(SYS_BUS_DEVICE(ctrl), 0, pic[VERSAL_EFUSE_IRQ]);
 }
 
+static void versal_create_pmc_iou_slcr(Versal *s, qemu_irq *pic)
+{
+SysBusDevice *sbd;
+
+object_initialize_child(OBJECT(s), "versal-pmc-iou-slcr", &s->pmc.iou.slcr,
+TYPE_XILINX_VERSAL_PMC_IOU_SLCR);
+
+sbd = SYS_BUS_DEVICE(&s->pmc.iou.slcr);
+sysbus_realize(sbd, &error_fatal);
+
+memory_region_add_subregion(&s->mr_ps, MM_PMC_PMC_IOU_SLCR,
+sysbus_mmio_get_region(sbd, 0));
+
+sysbus_connect_irq(sbd, 0, pic[VERSAL_PMC_IOU_SLCR_IRQ]);
+}
+
+
 /* This takes the board allocated linear DDR memory and creates aliases
  * for each split DDR range/aperture on the Versal address map.
  */
@@ -459,6 +476,7 @@ static void versal_realize(DeviceState *dev, Error **errp)
 versal_create_xrams(s, pic);
 versal_create_bbram(s, pic);
 versal_create_efuse(s, pic);
+versal_create_pmc_iou_slcr(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 895ba12c61..729c093dfc 100644
--- a/include/hw/arm/xlnx-versal.h
+++ b/include/hw/arm/xlnx-versal.h
@@ -26,6 +26,7 @@
 #include "hw/misc/xlnx-versal-xramc.h"
 #include "hw/nvram/xlnx-bbram.h"
 #include "hw/nvram/xlnx-versal-efuse.h"
+#include "hw/misc/xlnx-versal-pmc-iou-slcr.h"
 
 #define TYPE_XLNX_VERSAL "xlnx-versal"
 OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
@@ -78,6 +79,7 @@ struct Versal {
 struct {
 struct {
 SDHCIState sd[XLNX_VERSAL_NR_SDS];
+XlnxVersalPmcIouSlcr slcr;
 } iou;
 
 XlnxZynqMPRTC rtc;
@@ -113,6 +115,7 @@ struct Versal {
 #define VERSAL_XRAM_IRQ_0  79
 #define VERSAL_BBRAM_APB_IRQ_0 121
 #define VERSAL_RTC_APB_ERR_IRQ 121
+#define VERSAL_PMC_IOU_SLCR_IRQ121
 #define VERSAL_SD0_IRQ_0   126
 #define VERSAL_EFUSE_IRQ   139
 #define VERSAL_RTC_ALARM_IRQ   142
@@ -178,6 +181,9 @@ struct Versal {
 #define MM_FPD_FPD_APU  0xfd5c
 #define MM_FPD_FPD_APU_SIZE 0x100
 
+#define MM_PMC_PMC_IOU_SLCR 0xf106
+#define MM_PMC_PMC_IOU_SLCR_SIZE0x1
+
 #define MM_PMC_SD0  0xf104U
 #define MM_PMC_SD0_SIZE 0x1
 #define MM_PMC_BBRAM_CTRL   0xf11f
-- 
2.11.0




[PATCH v1 1/9] hw/misc: Add a model of Versal's PMC SLCR

2021-11-17 Thread Francisco Iglesias
Add a model of Versal's PMC SLCR (system-level control registers).

Signed-off-by: Francisco Iglesias 
Signed-off-by: Edgar E. Iglesias 
---
 hw/misc/meson.build|5 +-
 hw/misc/xlnx-versal-pmc-iou-slcr.c | 1437 
 include/hw/misc/xlnx-versal-pmc-iou-slcr.h |   51 +
 3 files changed, 1492 insertions(+), 1 deletion(-)
 create mode 100644 hw/misc/xlnx-versal-pmc-iou-slcr.c
 create mode 100644 include/hw/misc/xlnx-versal-pmc-iou-slcr.h

diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index 3f41a3a5b2..e82628a618 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -84,7 +84,10 @@ softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files(
 ))
 softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
 softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c'))
-softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: 
files('xlnx-versal-xramc.c'))
+softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files(
+  'xlnx-versal-xramc.c',
+  'xlnx-versal-pmc-iou-slcr.c',
+))
 softmmu_ss.add(when: 'CONFIG_STM32F2XX_SYSCFG', if_true: 
files('stm32f2xx_syscfg.c'))
 softmmu_ss.add(when: 'CONFIG_STM32F4XX_SYSCFG', if_true: 
files('stm32f4xx_syscfg.c'))
 softmmu_ss.add(when: 'CONFIG_STM32F4XX_EXTI', if_true: 
files('stm32f4xx_exti.c'))
diff --git a/hw/misc/xlnx-versal-pmc-iou-slcr.c 
b/hw/misc/xlnx-versal-pmc-iou-slcr.c
new file mode 100644
index 00..bd33017963
--- /dev/null
+++ b/hw/misc/xlnx-versal-pmc-iou-slcr.c
@@ -0,0 +1,1437 @@
+/*
+ * QEMU model of Versal's PMC IOU SLCR (system level control registers)
+ *
+ * Copyright (c) 2021 Xilinx Inc.
+ * Written by Edgar E. Iglesias 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "hw/register.h"
+#include "hw/irq.h"
+#include "qemu/bitops.h"
+#include "qemu/log.h"
+#include "migration/vmstate.h"
+#include "hw/qdev-properties.h"
+#include "hw/misc/xlnx-versal-pmc-iou-slcr.h"
+
+#ifndef XILINX_VERSAL_PMC_IOU_SLCR_ERR_DEBUG
+#define XILINX_VERSAL_PMC_IOU_SLCR_ERR_DEBUG 0
+#endif
+
+REG32(MIO_PIN_0, 0x0)
+FIELD(MIO_PIN_0, L3_SEL, 7, 3)
+FIELD(MIO_PIN_0, L2_SEL, 5, 2)
+FIELD(MIO_PIN_0, L1_SEL, 3, 2)
+FIELD(MIO_PIN_0, L0_SEL, 1, 2)
+REG32(MIO_PIN_1, 0x4)
+FIELD(MIO_PIN_1, L3_SEL, 7, 3)
+FIELD(MIO_PIN_1, L2_SEL, 5, 2)
+FIELD(MIO_PIN_1, L1_SEL, 3, 2)
+FIELD(MIO_PIN_1, L0_SEL, 1, 2)
+REG32(MIO_PIN_2, 0x8)
+FIELD(MIO_PIN_2, L3_SEL, 7, 3)
+FIELD(MIO_PIN_2, L2_SEL, 5, 2)
+FIELD(MIO_PIN_2, L1_SEL, 3, 2)
+FIELD(MIO_PIN_2, L0_SEL, 1, 2)
+REG32(MIO_PIN_3, 0xc)
+FIELD(MIO_PIN_3, L3_SEL, 7, 3)
+FIELD(MIO_PIN_3, L2_SEL, 5, 2)
+FIELD(MIO_PIN_3, L1_SEL, 3, 2)
+FIELD(MIO_PIN_3, L0_SEL, 1, 2)
+REG32(MIO_PIN_4, 0x10)
+FIELD(MIO_PIN_4, L3_SEL, 7, 3)
+FIELD(MIO_PIN_4, L2_SEL, 5, 2)
+FIELD(MIO_PIN_4, L1_SEL, 3, 2)
+FIELD(MIO_PIN_4, L0_SEL, 1, 2)
+REG32(MIO_PIN_5, 0x14)
+FIELD(MIO_PIN_5, L3_SEL, 7, 3)
+FIELD(MIO_PIN_5, L2_SEL, 5, 2)
+FIELD(MIO_PIN_5, L1_SEL, 3, 2)
+FIELD(MIO_PIN_5, L0_SEL, 1, 2)
+REG32(MIO_PIN_6, 0x18)
+FIELD(MIO_PIN_6, L3_SEL, 7, 3)
+FIELD(MIO_PIN_6, L2_SEL, 5, 2)
+FIELD(MIO_PIN_6, L1_SEL, 3, 2)
+FIELD(MIO_PIN_6, L0_SEL, 1, 2)
+REG32(MIO_PIN_7, 0x1c)
+FIELD(MIO_PIN_7, L3_SEL, 7, 3)
+FIELD(MIO_PIN_7, L2_SEL, 5, 2)
+FIELD(MIO_PIN_7, L1_SEL, 3, 2)
+FIELD(MIO_PIN_7, L0_SEL, 1, 2)
+REG32(MIO_PIN_8, 0x20)
+FIELD(MIO_PIN_8, L3_SEL, 7, 3)
+FIELD(MIO_PIN_8, L2_SEL, 5, 2)
+FIELD(MIO_PIN_8, L1_SEL, 3, 2)
+FIELD(MIO_PIN_8, L0_SEL, 1, 2)
+REG32(MIO_PIN_9, 0x24)
+FIELD(MIO_PIN_9, L3_SEL, 7, 3)

[PATCH v1 3/9] include/hw/dma/xlnx_csu_dma: Include ptimer.h and stream.h in the header

2021-11-17 Thread Francisco Iglesias
Include ptimer.h and stream.h in the header for being able to build and
reuse the DMA model (the first usage of StreamSink, StreamCanPushNotifyFn
and ptimer_state is in the header).

Signed-off-by: Francisco Iglesias 
---
 include/hw/dma/xlnx_csu_dma.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/hw/dma/xlnx_csu_dma.h b/include/hw/dma/xlnx_csu_dma.h
index 9e9dc551e9..8c39e46f58 100644
--- a/include/hw/dma/xlnx_csu_dma.h
+++ b/include/hw/dma/xlnx_csu_dma.h
@@ -21,6 +21,9 @@
 #ifndef XLNX_CSU_DMA_H
 #define XLNX_CSU_DMA_H
 
+#include "hw/ptimer.h"
+#include "hw/stream.h"
+
 #define TYPE_XLNX_CSU_DMA "xlnx.csu_dma"
 
 #define XLNX_CSU_DMA_R_MAX (0x2c / 4)
-- 
2.11.0




[PATCH v1 9/9] hw/arm/xlnx-versal-virt: Connect mt35xu01g flashes to the OSPI

2021-11-17 Thread Francisco Iglesias
Connect Micron Xccela mt35xu01g flashes to the OSPI flash memory
controller.

Signed-off-by: Francisco Iglesias 
---
 hw/arm/xlnx-versal-virt.c | 23 +++
 1 file changed, 23 insertions(+)

diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
index d2f55e29b6..f2f12a781e 100644
--- a/hw/arm/xlnx-versal-virt.c
+++ b/hw/arm/xlnx-versal-virt.c
@@ -25,6 +25,8 @@
 #define TYPE_XLNX_VERSAL_VIRT_MACHINE MACHINE_TYPE_NAME("xlnx-versal-virt")
 OBJECT_DECLARE_SIMPLE_TYPE(VersalVirt, XLNX_VERSAL_VIRT_MACHINE)
 
+#define XLNX_VERSAL_NUM_OSPI_FLASH 4
+
 struct VersalVirt {
 MachineState parent_obj;
 
@@ -690,6 +692,27 @@ static void versal_virt_init(MachineState *machine)
 exit(EXIT_FAILURE);
 }
 }
+
+for (i = 0; i < XLNX_VERSAL_NUM_OSPI_FLASH; i++) {
+BusState *spi_bus;
+DeviceState *flash_dev;
+qemu_irq cs_line;
+DriveInfo *dinfo = drive_get_next(IF_MTD);
+
+spi_bus = qdev_get_child_bus(DEVICE(&s->soc.pmc.iou.ospi), "spi0");
+
+flash_dev = qdev_new("mt35xu01g");
+if (dinfo) {
+qdev_prop_set_drive_err(flash_dev, "drive",
+blk_by_legacy_dinfo(dinfo), &error_fatal);
+}
+qdev_realize_and_unref(flash_dev, spi_bus, &error_fatal);
+
+cs_line = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
+
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->soc.pmc.iou.ospi),
+   i + 1, cs_line);
+}
 }
 
 static void versal_virt_machine_instance_init(Object *obj)
-- 
2.11.0




[PATCH v1 4/9] hw/dma: Add the DMA control interface

2021-11-17 Thread Francisco Iglesias
Add an interface for controlling DMA models that are reused with other
models. This allows a controlling model to start transfers through the
DMA while reusing the DMA's handling of transfer state and completion
signaling.

Signed-off-by: Francisco Iglesias 
---
 hw/dma/dma-ctrl.c | 31 
 hw/dma/meson.build|  1 +
 include/hw/dma/dma-ctrl.h | 74 +++
 3 files changed, 106 insertions(+)
 create mode 100644 hw/dma/dma-ctrl.c
 create mode 100644 include/hw/dma/dma-ctrl.h

diff --git a/hw/dma/dma-ctrl.c b/hw/dma/dma-ctrl.c
new file mode 100644
index 00..4a9b68dac1
--- /dev/null
+++ b/hw/dma/dma-ctrl.c
@@ -0,0 +1,31 @@
+/*
+ * DMA control interface.
+ *
+ * Copyright (c) 2021 Xilinx Inc.
+ * Written by Francisco Iglesias 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include "qemu/osdep.h"
+#include "exec/hwaddr.h"
+#include "hw/dma/dma-ctrl.h"
+
+void dma_ctrl_read_with_notify(DmaCtrl *dma_ctrl, hwaddr addr, uint32_t len,
+   DmaCtrlNotify *notify, bool start_dma)
+{
+DmaCtrlClass *dcc =  DMA_CTRL_GET_CLASS(dma_ctrl);
+dcc->read(dma_ctrl, addr, len, notify, start_dma);
+}
+
+static const TypeInfo dma_ctrl_info = {
+.name  = TYPE_DMA_CTRL,
+.parent= TYPE_INTERFACE,
+.class_size = sizeof(DmaCtrlClass),
+};
+
+static void dma_ctrl_register_types(void)
+{
+type_register_static(&dma_ctrl_info);
+}
+
+type_init(dma_ctrl_register_types)
diff --git a/hw/dma/meson.build b/hw/dma/meson.build
index f3f0661bc3..c0bc134046 100644
--- a/hw/dma/meson.build
+++ b/hw/dma/meson.build
@@ -14,3 +14,4 @@ softmmu_ss.add(when: 'CONFIG_PXA2XX', if_true: 
files('pxa2xx_dma.c'))
 softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_dma.c'))
 softmmu_ss.add(when: 'CONFIG_SIFIVE_PDMA', if_true: files('sifive_pdma.c'))
 softmmu_ss.add(when: 'CONFIG_XLNX_CSU_DMA', if_true: files('xlnx_csu_dma.c'))
+common_ss.add(when: 'CONFIG_XILINX_AXI', if_true: files('dma-ctrl.c'))
diff --git a/include/hw/dma/dma-ctrl.h b/include/hw/dma/dma-ctrl.h
new file mode 100644
index 00..498469395f
--- /dev/null
+++ b/include/hw/dma/dma-ctrl.h
@@ -0,0 +1,74 @@
+/*
+ * DMA control interface.
+ *
+ * Copyright (c) 2021 Xilinx Inc.
+ * Written by Francisco Iglesias 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#ifndef HW_DMA_CTRL_H
+#define HW_DMA_CTRL_H
+
+#include "qemu-common.h"
+#include "hw/hw.h"
+#include "qom/object.h"
+
+#define TYPE_DMA_CTRL "dma-ctrl"
+
+#define DMA_CTRL_CLASS(klass) \
+ OBJECT_CLASS_CHECK(DmaCtrlClass, (klass), TYPE_DMA_CTRL)
+#define DMA_CTRL_GET_CLASS(obj) \
+OBJECT_GET_CLASS(DmaCtrlClass, (obj), TYPE_DMA_CTRL)
+#define DMA_CTRL(obj) \
+ INTERFACE_CHECK(DmaCtrl, (obj), TYPE_DMA_CTRL)
+
+typedef void (*dmactrl_notify_fn)(void *opaque);
+
+typedef struct DmaCtrlNotify {
+void *opaque;
+dmactrl_notify_fn cb;
+} DmaCtrlNotify;
+
+typedef struct DmaCtrl {
+Object Parent;
+} DmaCtrl;
+
+typedef struct DmaCtrlClass {
+InterfaceClass parent;
+
+/*
+ * read: Start a read transfer on the DMA implementing the DMA control
+ * interface
+ *
+ * @dma_ctrl: the DMA implementing this interface
+ * @addr: the address to read
+ * @len: the amount of bytes to read at 'addr'
+ * @notify: the structure containg a callback to call and opaque pointer
+ * to pass the callback when the transfer has been completed
+ * @start_dma: true for starting the DMA transfer and false for just
+ * refilling and proceding an already started transfer
+ */
+void (*read)(DmaCtrl *dma_ctrl, hwaddr addr, uint32_t len,
+ DmaCtrlNotify *notify, bool start_dma);
+} DmaCtrlClass;
+
+/*
+ * Start a read transfer on a DMA implementing the DMA control interface.
+ * The DMA will notify the caller that 'len' bytes have been read at 'addr'
+ * through the callback in the DmaCtrlNotify structure. For allowing refilling
+ * an already started transfer the DMA notifies the caller before considering
+ * the transfer done (e.g. before setting done flags, generating IRQs and
+ * modifying other relevant internal device state).
+ *
+ * @dma_ctrl: the DMA implementing this interface
+ * @addr: the address to read
+ * @len: the amount of bytes to read at 'addr'
+ * @notify: the structure containing a callback to call and opaque pointer
+ * to pass the callback when the transfer has been completed
+ * @start_dma: true for starting the DMA transfer and false for just
+ * refilling and proceding an already started transfer
+ */
+void dma_ctrl_read_with_notify(DmaCtrl *dma_ctrl, hwaddr addr, uint32_t len,
+   DmaCtrlNotify *notify, bool start_dma);
+
+#endif /* HW_DMA_CTRL_H */
-- 
2.11.0




[PATCH v1 5/9] hw/dma/xlnx_csu_dma: Implement the DMA control interface

2021-11-17 Thread Francisco Iglesias
Implement the DMA control interface for allowing control of DMA operations
from inside models that contain instances of (and reuse) the Xilinx CSU
DMA.

Signed-off-by: Francisco Iglesias 
---
 hw/dma/xlnx_csu_dma.c | 32 
 include/hw/dma/xlnx_csu_dma.h |  4 
 2 files changed, 36 insertions(+)

diff --git a/hw/dma/xlnx_csu_dma.c b/hw/dma/xlnx_csu_dma.c
index 896bb3574d..9ed6e82225 100644
--- a/hw/dma/xlnx_csu_dma.c
+++ b/hw/dma/xlnx_csu_dma.c
@@ -277,6 +277,11 @@ static uint32_t xlnx_csu_dma_advance(XlnxCSUDMA *s, 
uint32_t len)
 s->regs[R_ADDR_MSB] = dst >> 32;
 }
 
+/* Notify dma-ctrl clients when the transfer has been completed */
+if (size == 0 && s->dma_ctrl_notify) {
+s->dma_ctrl_notify(s->dma_ctrl_opaque);
+}
+
 if (size == 0) {
 xlnx_csu_dma_done(s);
 }
@@ -472,6 +477,29 @@ static uint64_t addr_msb_pre_write(RegisterInfo *reg, 
uint64_t val)
 return val & R_ADDR_MSB_ADDR_MSB_MASK;
 }
 
+static void xlnx_csu_dma_dma_ctrl_read(DmaCtrl *dma_ctrl, hwaddr addr,
+ uint32_t len, DmaCtrlNotify *notify,
+ bool start_dma)
+{
+XlnxCSUDMA *s = XLNX_CSU_DMA(dma_ctrl);
+RegisterInfo *reg = &s->regs_info[R_SIZE];
+uint64_t we = MAKE_64BIT_MASK(0, 4 * 8);
+
+s->regs[R_ADDR] = addr;
+s->regs[R_ADDR_MSB] = (uint64_t)addr >> 32;
+
+if (notify) {
+s->dma_ctrl_notify = notify->cb;
+s->dma_ctrl_opaque = notify->opaque;
+}
+
+if (start_dma) {
+register_write(reg, len, we, object_get_typename(OBJECT(s)), false);
+} else {
+s->regs[R_SIZE] = len;
+}
+}
+
 static const RegisterAccessInfo *xlnx_csu_dma_regs_info[] = {
 #define DMACH_REGINFO(NAME, snd)  \
 (const RegisterAccessInfo []) {   \
@@ -696,6 +724,7 @@ static void xlnx_csu_dma_class_init(ObjectClass *klass, 
void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
 StreamSinkClass *ssc = STREAM_SINK_CLASS(klass);
+DmaCtrlClass *dcc = DMA_CTRL_CLASS(klass);
 
 dc->reset = xlnx_csu_dma_reset;
 dc->realize = xlnx_csu_dma_realize;
@@ -704,6 +733,8 @@ static void xlnx_csu_dma_class_init(ObjectClass *klass, 
void *data)
 
 ssc->push = xlnx_csu_dma_stream_push;
 ssc->can_push = xlnx_csu_dma_stream_can_push;
+
+dcc->read = xlnx_csu_dma_dma_ctrl_read;
 }
 
 static void xlnx_csu_dma_init(Object *obj)
@@ -731,6 +762,7 @@ static const TypeInfo xlnx_csu_dma_info = {
 .instance_init = xlnx_csu_dma_init,
 .interfaces = (InterfaceInfo[]) {
 { TYPE_STREAM_SINK },
+{ TYPE_DMA_CTRL },
 { }
 }
 };
diff --git a/include/hw/dma/xlnx_csu_dma.h b/include/hw/dma/xlnx_csu_dma.h
index 8c39e46f58..f7f086593c 100644
--- a/include/hw/dma/xlnx_csu_dma.h
+++ b/include/hw/dma/xlnx_csu_dma.h
@@ -23,6 +23,7 @@
 
 #include "hw/ptimer.h"
 #include "hw/stream.h"
+#include "hw/dma/dma-ctrl.h"
 
 #define TYPE_XLNX_CSU_DMA "xlnx.csu_dma"
 
@@ -45,6 +46,9 @@ typedef struct XlnxCSUDMA {
 StreamCanPushNotifyFn notify;
 void *notify_opaque;
 
+dmactrl_notify_fn dma_ctrl_notify;
+void *dma_ctrl_opaque;
+
 uint32_t regs[XLNX_CSU_DMA_R_MAX];
 RegisterInfo regs_info[XLNX_CSU_DMA_R_MAX];
 } XlnxCSUDMA;
-- 
2.11.0




[PATCH v1 8/9] hw/block/m25p80: Add support for Micron Xccela flash mt35xu01g

2021-11-17 Thread Francisco Iglesias
Add support for Micron Xccela flash mt35xu01g.

Signed-off-by: Francisco Iglesias 
---
 hw/block/m25p80.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index b77503dc84..c6bf3c6bfa 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -255,6 +255,8 @@ static const FlashPartInfo known_devices[] = {
 { INFO("n25q512a",0x20ba20,  0,  64 << 10, 1024, ER_4K) },
 { INFO("n25q512ax3",  0x20ba20,  0x1000,  64 << 10, 1024, ER_4K) },
 { INFO("mt25ql512ab", 0x20ba20, 0x1044, 64 << 10, 1024, ER_4K | ER_32K) },
+{ INFO_STACKED("mt35xu01g", 0x2c5b1b, 0x104100, 128 << 10, 1024,
+   ER_4K | ER_32K, 2) },
 { INFO_STACKED("n25q00",0x20ba21, 0x1000, 64 << 10, 2048, ER_4K, 4) },
 { INFO_STACKED("n25q00a",   0x20bb21, 0x1000, 64 << 10, 2048, ER_4K, 4) },
 { INFO_STACKED("mt25ql01g", 0x20ba21, 0x1040, 64 << 10, 2048, ER_4K, 2) },
-- 
2.11.0




[PATCH v1 7/9] hw/arm/xlnx-versal: Connect the OSPI flash memory controller model

2021-11-17 Thread Francisco Iglesias
Connect the OSPI flash memory controller model (including the source and
destination DMA).

Signed-off-by: Francisco Iglesias 
---
 hw/arm/xlnx-versal.c | 89 
 include/hw/arm/xlnx-versal.h | 18 +
 2 files changed, 107 insertions(+)

diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
index 08e250945f..f8e94a50fd 100644
--- a/hw/arm/xlnx-versal.c
+++ b/hw/arm/xlnx-versal.c
@@ -24,6 +24,7 @@
 
 #define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
 #define GEM_REVISION0x40070106
+#define NUM_OSPI_IRQ_LINES 3
 
 static void versal_create_apu_cpus(Versal *s)
 {
@@ -385,6 +386,93 @@ static void versal_create_pmc_iou_slcr(Versal *s, qemu_irq 
*pic)
 sysbus_connect_irq(sbd, 0, pic[VERSAL_PMC_IOU_SLCR_IRQ]);
 }
 
+static void versal_create_ospi(Versal *s, qemu_irq *pic)
+{
+SysBusDevice *sbd;
+MemoryRegion *mr_dac;
+
+memory_region_init(&s->pmc.iou.lospi_mr, OBJECT(s),
+   "versal-lospi_mr" , MM_PMC_OSPI_DAC_SIZE);
+
+object_initialize_child(OBJECT(s), "versal-ospi", &s->pmc.iou.ospi,
+TYPE_XILINX_VERSAL_OSPI);
+
+mr_dac = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->pmc.iou.ospi), 1);
+memory_region_add_subregion(&s->pmc.iou.lospi_mr, 0x0, mr_dac);
+
+/* Create the OSPI destination DMA */
+object_initialize_child(OBJECT(s), "versal-ospi-dma-dst",
+&s->pmc.iou.ospi_dma_dst,
+TYPE_XLNX_CSU_DMA);
+
+object_property_set_link(OBJECT(&s->pmc.iou.ospi_dma_dst),
+"dma", OBJECT(get_system_memory()),
+ &error_abort);
+
+sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi_dma_dst);
+sysbus_realize(sbd, &error_fatal);
+
+memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DMA_DST,
+sysbus_mmio_get_region(sbd, 0));
+
+sysbus_connect_irq(SYS_BUS_DEVICE(sbd), 0, pic[VERSAL_OSPI_IRQ]);
+
+/* Create the OSPI source DMA */
+object_initialize_child(OBJECT(s), "versal-ospi-dma-src",
+&s->pmc.iou.ospi_dma_src,
+TYPE_XLNX_CSU_DMA);
+
+object_property_set_bool(OBJECT(&s->pmc.iou.ospi_dma_src), "is-dst",
+ false, &error_abort);
+
+object_property_set_link(OBJECT(&s->pmc.iou.ospi_dma_src),
+"dma", OBJECT(mr_dac), &error_abort);
+
+object_property_set_link(OBJECT(&s->pmc.iou.ospi_dma_src),
+"stream-connected-dma",
+ OBJECT(&s->pmc.iou.ospi_dma_dst),
+ &error_abort);
+
+sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi_dma_src);
+sysbus_realize(sbd, &error_fatal);
+
+memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DMA_SRC,
+sysbus_mmio_get_region(sbd, 0));
+
+/* Create the OSPI */
+object_property_set_link(OBJECT(&s->pmc.iou.ospi), "dma-src",
+ OBJECT(&s->pmc.iou.ospi_dma_src), &error_abort);
+
+sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi);
+sysbus_realize(sbd, &error_fatal);
+
+memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI,
+sysbus_mmio_get_region(sbd, 0));
+
+memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DAC,
+&s->pmc.iou.lospi_mr);
+
+/* ospi_mux_sel */
+qdev_connect_gpio_out(DEVICE(&s->pmc.iou.slcr), 3,
+  qdev_get_gpio_in(DEVICE(&s->pmc.iou.ospi), 0));
+
+/* OSPI irq */
+object_initialize_child(OBJECT(s), "ospi-irq",
+&s->pmc.iou.ospi_irq, TYPE_OR_IRQ);
+object_property_set_int(OBJECT(&s->pmc.iou.ospi_irq),
+"num-lines", NUM_OSPI_IRQ_LINES, &error_fatal);
+qdev_realize(DEVICE(&s->pmc.iou.ospi_irq), NULL, &error_fatal);
+
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi), 0,
+   qdev_get_gpio_in(DEVICE(&s->pmc.iou.ospi_irq), 0));
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi_dma_src), 0,
+   qdev_get_gpio_in(DEVICE(&s->pmc.iou.ospi_irq), 1));
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi_dma_dst), 0,
+   qdev_get_gpio_in(DEVICE(&s->pmc.iou.ospi_irq), 2));
+
+qdev_connect_gpio_out(DEVICE(&s->pmc.iou.ospi_irq), 0,
+  pic[VERSAL_OSPI_IRQ]);
+}
 
 /* This takes the board allocated linear DDR memory and creates aliases
  * for each split DDR range/aperture on the Versal address map.
@@ -477,6 +565,7 @@ static void versal_realize(DeviceSta

[PATCH v1 6/9] hw/ssi: Add a model of Xilinx Versal's OSPI flash memory controller

2021-11-17 Thread Francisco Iglesias
Add a model of Xilinx Versal's OSPI flash memory controller.

Signed-off-by: Francisco Iglesias 
---
 hw/ssi/meson.build|1 +
 hw/ssi/xlnx-versal-ospi.c | 1892 +
 include/hw/ssi/xlnx-versal-ospi.h |   86 ++
 3 files changed, 1979 insertions(+)
 create mode 100644 hw/ssi/xlnx-versal-ospi.c
 create mode 100644 include/hw/ssi/xlnx-versal-ospi.h

diff --git a/hw/ssi/meson.build b/hw/ssi/meson.build
index 3d6bc82ab1..0ded9cd092 100644
--- a/hw/ssi/meson.build
+++ b/hw/ssi/meson.build
@@ -7,5 +7,6 @@ softmmu_ss.add(when: 'CONFIG_SSI', if_true: files('ssi.c'))
 softmmu_ss.add(when: 'CONFIG_STM32F2XX_SPI', if_true: files('stm32f2xx_spi.c'))
 softmmu_ss.add(when: 'CONFIG_XILINX_SPI', if_true: files('xilinx_spi.c'))
 softmmu_ss.add(when: 'CONFIG_XILINX_SPIPS', if_true: files('xilinx_spips.c'))
+softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: 
files('xlnx-versal-ospi.c'))
 softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('imx_spi.c'))
 softmmu_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_spi.c'))
diff --git a/hw/ssi/xlnx-versal-ospi.c b/hw/ssi/xlnx-versal-ospi.c
new file mode 100644
index 00..c02fc143de
--- /dev/null
+++ b/hw/ssi/xlnx-versal-ospi.c
@@ -0,0 +1,1892 @@
+/*
+ * QEMU model of Xilinx Versal's OSPI controller.
+ *
+ * Copyright (c) 2021 Xilinx Inc.
+ * Written by Francisco Iglesias 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "migration/vmstate.h"
+#include "hw/qdev-properties.h"
+#include "qemu/bitops.h"
+#include "qemu/log.h"
+#include "hw/irq.h"
+#include "hw/ssi/xlnx-versal-ospi.h"
+
+#ifndef XILINX_VERSAL_OSPI_ERR_DEBUG
+#define XILINX_VERSAL_OSPI_ERR_DEBUG 0
+#endif
+
+REG32(CONFIG_REG, 0x0)
+FIELD(CONFIG_REG, IDLE_FLD, 31, 1)
+FIELD(CONFIG_REG, DUAL_BYTE_OPCODE_EN_FLD, 30, 1)
+FIELD(CONFIG_REG, CRC_ENABLE_FLD, 29, 1)
+FIELD(CONFIG_REG, CONFIG_RESV2_FLD, 26, 3)
+FIELD(CONFIG_REG, PIPELINE_PHY_FLD, 25, 1)
+FIELD(CONFIG_REG, ENABLE_DTR_PROTOCOL_FLD, 24, 1)
+FIELD(CONFIG_REG, ENABLE_AHB_DECODER_FLD, 23, 1)
+FIELD(CONFIG_REG, MSTR_BAUD_DIV_FLD, 19, 4)
+FIELD(CONFIG_REG, ENTER_XIP_MODE_IMM_FLD, 18, 1)
+FIELD(CONFIG_REG, ENTER_XIP_MODE_FLD, 17, 1)
+FIELD(CONFIG_REG, ENB_AHB_ADDR_REMAP_FLD, 16, 1)
+FIELD(CONFIG_REG, ENB_DMA_IF_FLD, 15, 1)
+FIELD(CONFIG_REG, WR_PROT_FLASH_FLD, 14, 1)
+FIELD(CONFIG_REG, PERIPH_CS_LINES_FLD, 10, 4)
+FIELD(CONFIG_REG, PERIPH_SEL_DEC_FLD, 9, 1)
+FIELD(CONFIG_REG, ENB_LEGACY_IP_MODE_FLD, 8, 1)
+FIELD(CONFIG_REG, ENB_DIR_ACC_CTLR_FLD, 7, 1)
+FIELD(CONFIG_REG, RESET_CFG_FLD, 6, 1)
+FIELD(CONFIG_REG, RESET_PIN_FLD, 5, 1)
+FIELD(CONFIG_REG, HOLD_PIN_FLD, 4, 1)
+FIELD(CONFIG_REG, PHY_MODE_ENABLE_FLD, 3, 1)
+FIELD(CONFIG_REG, SEL_CLK_PHASE_FLD, 2, 1)
+FIELD(CONFIG_REG, SEL_CLK_POL_FLD, 1, 1)
+FIELD(CONFIG_REG, ENB_SPI_FLD, 0, 1)
+REG32(DEV_INSTR_RD_CONFIG_REG, 0x4)
+FIELD(DEV_INSTR_RD_CONFIG_REG, RD_INSTR_RESV5_FLD, 29, 3)
+FIELD(DEV_INSTR_RD_CONFIG_REG, DUMMY_RD_CLK_CYCLES_FLD, 24, 5)
+FIELD(DEV_INSTR_RD_CONFIG_REG, RD_INSTR_RESV4_FLD, 21, 3)
+FIELD(DEV_INSTR_RD_CONFIG_REG, MODE_BIT_ENABLE_FLD, 20, 1)
+FIELD(DEV_INSTR_RD_CONFIG_REG, RD_INSTR_RESV3_FLD, 18, 2)
+FIELD(DEV_INSTR_RD_CONFIG_REG, DATA_XFER_TYPE_EXT_MODE_FLD, 16, 2)
+FIELD(DEV_INSTR_RD_CONFIG_REG, RD_INSTR_RESV2_FLD, 14, 2)
+FIELD(DEV_INSTR_RD_CONFIG_REG, ADDR_XFER_TYPE_STD_MODE_FLD, 12, 2)
+FIELD(DEV_INSTR_RD_CONFIG_REG, PRED_DIS_FLD, 11, 1)
+FIELD(DEV_INSTR_RD_CONFIG_REG, DDR_EN_FLD, 10, 1)
+FIELD(DEV_INSTR_RD_CONFIG_REG, INSTR_TYPE_FLD, 8, 2)
+FIELD(DEV_IN

[PATCH v1 0/9] Xilinx Versal's PMC SLCR and OSPI support

2021-11-17 Thread Francisco Iglesias
Hi,

This series attempts to add support for Xilinx Versal's PMC SLCR
(system-level control registers) and OSPI flash memory controller to
Xilinx Versal virt machine.

The series start with adding a model of Versal's PMC SLCR and connecting
the model to the Versal virt machine. The series then adds a couple of
headers into the xlnx_csu_dma.h needed for building and reusing it later
with the OSPI. The series thereafter introduces a DMA control interface
and implements the interface in the xlnx_csu_dma for being able to reuse
and control the DMA with the OSPI controller. Thereafter a model of
Versal's OSPI controller is added and connected to the Versal virt
machine. The series then ends with adding initial support for the Micron
Xccelera mt35xu01g flash and flashes of this type are connected to the
OSPI in the Versal virt machine.

Best regards,
Francisco Iglesias

Francisco Iglesias (9):
  hw/misc: Add a model of Versal's PMC SLCR
  hw/arm/xlnx-versal: Connect Versal's PMC SLCR
  include/hw/dma/xlnx_csu_dma: Include ptimer.h and stream.h in the
header
  hw/dma: Add the DMA control interface
  hw/dma/xlnx_csu_dma: Implement the DMA control interface
  hw/ssi: Add a model of Xilinx Versal's OSPI flash memory controller
  hw/arm/xlnx-versal: Connect the OSPI flash memory controller model
  hw/block/m25p80: Add support for Micron Xccela flash mt35xu01g
  hw/arm/xlnx-versal-virt: Connect mt35xu01g flashes to the OSPI

 hw/arm/xlnx-versal-virt.c  |   23 +
 hw/arm/xlnx-versal.c   |  107 ++
 hw/block/m25p80.c  |2 +
 hw/dma/dma-ctrl.c  |   31 +
 hw/dma/meson.build |1 +
 hw/dma/xlnx_csu_dma.c  |   32 +
 hw/misc/meson.build|5 +-
 hw/misc/xlnx-versal-pmc-iou-slcr.c | 1437 +
 hw/ssi/meson.build |1 +
 hw/ssi/xlnx-versal-ospi.c  | 1892 
 include/hw/arm/xlnx-versal.h   |   24 +
 include/hw/dma/dma-ctrl.h  |   74 ++
 include/hw/dma/xlnx_csu_dma.h  |7 +
 include/hw/misc/xlnx-versal-pmc-iou-slcr.h |   51 +
 include/hw/ssi/xlnx-versal-ospi.h  |   86 ++
 15 files changed, 3772 insertions(+), 1 deletion(-)
 create mode 100644 hw/dma/dma-ctrl.c
 create mode 100644 hw/misc/xlnx-versal-pmc-iou-slcr.c
 create mode 100644 hw/ssi/xlnx-versal-ospi.c
 create mode 100644 include/hw/dma/dma-ctrl.h
 create mode 100644 include/hw/misc/xlnx-versal-pmc-iou-slcr.h
 create mode 100644 include/hw/ssi/xlnx-versal-ospi.h

-- 
2.11.0




Re: [PATCH v1 9/9] hw/arm/xlnx-versal-virt: Connect mt35xu01g flashes to the OSPI

2021-11-23 Thread Francisco Iglesias
Hi Edgar,

Thank you for having a look at the series! I made the updates in v2!

Best regards,
Francisco Iglesias

On [2021 Nov 19] Fri 18:16:23, Edgar E. Iglesias wrote:
> On Wed, Nov 17, 2021 at 02:18:41PM +0000, Francisco Iglesias wrote:
> > Connect Micron Xccela mt35xu01g flashes to the OSPI flash memory
> > controller.
> > 
> > Signed-off-by: Francisco Iglesias 
> > ---
> >  hw/arm/xlnx-versal-virt.c | 23 +++
> >  1 file changed, 23 insertions(+)
> > 
> > diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
> > index d2f55e29b6..f2f12a781e 100644
> > --- a/hw/arm/xlnx-versal-virt.c
> > +++ b/hw/arm/xlnx-versal-virt.c
> > @@ -25,6 +25,8 @@
> >  #define TYPE_XLNX_VERSAL_VIRT_MACHINE MACHINE_TYPE_NAME("xlnx-versal-virt")
> >  OBJECT_DECLARE_SIMPLE_TYPE(VersalVirt, XLNX_VERSAL_VIRT_MACHINE)
> >  
> > +#define XLNX_VERSAL_NUM_OSPI_FLASH 4
> > +
> >  struct VersalVirt {
> >  MachineState parent_obj;
> >  
> > @@ -690,6 +692,27 @@ static void versal_virt_init(MachineState *machine)
> >  exit(EXIT_FAILURE);
> >  }
> >  }
> > +
> > +for (i = 0; i < XLNX_VERSAL_NUM_OSPI_FLASH; i++) {
> > +BusState *spi_bus;
> > +DeviceState *flash_dev;
> > +qemu_irq cs_line;
> > +DriveInfo *dinfo = drive_get_next(IF_MTD);
> 
> There's a patch from Markus on the list that is getting rid of
> drive_get_next(), we'll need to merge with that at some point...
> 
> 
> 
> 
> > +
> > +spi_bus = qdev_get_child_bus(DEVICE(&s->soc.pmc.iou.ospi), "spi0");
> > +
> > +flash_dev = qdev_new("mt35xu01g");
> > +if (dinfo) {
> > +qdev_prop_set_drive_err(flash_dev, "drive",
> > +blk_by_legacy_dinfo(dinfo), 
> > &error_fatal);
> > +}
> > +qdev_realize_and_unref(flash_dev, spi_bus, &error_fatal);
> > +
> > +cs_line = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
> > +
> > +sysbus_connect_irq(SYS_BUS_DEVICE(&s->soc.pmc.iou.ospi),
> > +   i + 1, cs_line);
> > +}
> >  }
> >  
> >  static void versal_virt_machine_instance_init(Object *obj)
> > -- 
> > 2.11.0
> > 



[PATCH v2 05/10] hw/dma/xlnx_csu_dma: Implement the DMA control interface

2021-11-23 Thread Francisco Iglesias
Implement the DMA control interface for allowing control of DMA operations
from inside models that contain instances of (and reuse) the Xilinx CSU
DMA.

Signed-off-by: Francisco Iglesias 
Reviewed-by: Edgar E. Iglesias 
---
 hw/dma/xlnx_csu_dma.c | 32 
 include/hw/dma/xlnx_csu_dma.h |  4 
 2 files changed, 36 insertions(+)

diff --git a/hw/dma/xlnx_csu_dma.c b/hw/dma/xlnx_csu_dma.c
index 896bb3574d..9ed6e82225 100644
--- a/hw/dma/xlnx_csu_dma.c
+++ b/hw/dma/xlnx_csu_dma.c
@@ -277,6 +277,11 @@ static uint32_t xlnx_csu_dma_advance(XlnxCSUDMA *s, 
uint32_t len)
 s->regs[R_ADDR_MSB] = dst >> 32;
 }
 
+/* Notify dma-ctrl clients when the transfer has been completed */
+if (size == 0 && s->dma_ctrl_notify) {
+s->dma_ctrl_notify(s->dma_ctrl_opaque);
+}
+
 if (size == 0) {
 xlnx_csu_dma_done(s);
 }
@@ -472,6 +477,29 @@ static uint64_t addr_msb_pre_write(RegisterInfo *reg, 
uint64_t val)
 return val & R_ADDR_MSB_ADDR_MSB_MASK;
 }
 
+static void xlnx_csu_dma_dma_ctrl_read(DmaCtrl *dma_ctrl, hwaddr addr,
+ uint32_t len, DmaCtrlNotify *notify,
+ bool start_dma)
+{
+XlnxCSUDMA *s = XLNX_CSU_DMA(dma_ctrl);
+RegisterInfo *reg = &s->regs_info[R_SIZE];
+uint64_t we = MAKE_64BIT_MASK(0, 4 * 8);
+
+s->regs[R_ADDR] = addr;
+s->regs[R_ADDR_MSB] = (uint64_t)addr >> 32;
+
+if (notify) {
+s->dma_ctrl_notify = notify->cb;
+s->dma_ctrl_opaque = notify->opaque;
+}
+
+if (start_dma) {
+register_write(reg, len, we, object_get_typename(OBJECT(s)), false);
+} else {
+s->regs[R_SIZE] = len;
+}
+}
+
 static const RegisterAccessInfo *xlnx_csu_dma_regs_info[] = {
 #define DMACH_REGINFO(NAME, snd)  \
 (const RegisterAccessInfo []) {   \
@@ -696,6 +724,7 @@ static void xlnx_csu_dma_class_init(ObjectClass *klass, 
void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
 StreamSinkClass *ssc = STREAM_SINK_CLASS(klass);
+DmaCtrlClass *dcc = DMA_CTRL_CLASS(klass);
 
 dc->reset = xlnx_csu_dma_reset;
 dc->realize = xlnx_csu_dma_realize;
@@ -704,6 +733,8 @@ static void xlnx_csu_dma_class_init(ObjectClass *klass, 
void *data)
 
 ssc->push = xlnx_csu_dma_stream_push;
 ssc->can_push = xlnx_csu_dma_stream_can_push;
+
+dcc->read = xlnx_csu_dma_dma_ctrl_read;
 }
 
 static void xlnx_csu_dma_init(Object *obj)
@@ -731,6 +762,7 @@ static const TypeInfo xlnx_csu_dma_info = {
 .instance_init = xlnx_csu_dma_init,
 .interfaces = (InterfaceInfo[]) {
 { TYPE_STREAM_SINK },
+{ TYPE_DMA_CTRL },
 { }
 }
 };
diff --git a/include/hw/dma/xlnx_csu_dma.h b/include/hw/dma/xlnx_csu_dma.h
index 8c39e46f58..f7f086593c 100644
--- a/include/hw/dma/xlnx_csu_dma.h
+++ b/include/hw/dma/xlnx_csu_dma.h
@@ -23,6 +23,7 @@
 
 #include "hw/ptimer.h"
 #include "hw/stream.h"
+#include "hw/dma/dma-ctrl.h"
 
 #define TYPE_XLNX_CSU_DMA "xlnx.csu_dma"
 
@@ -45,6 +46,9 @@ typedef struct XlnxCSUDMA {
 StreamCanPushNotifyFn notify;
 void *notify_opaque;
 
+dmactrl_notify_fn dma_ctrl_notify;
+void *dma_ctrl_opaque;
+
 uint32_t regs[XLNX_CSU_DMA_R_MAX];
 RegisterInfo regs_info[XLNX_CSU_DMA_R_MAX];
 } XlnxCSUDMA;
-- 
2.11.0




[PATCH v2 06/10] hw/ssi: Add a model of Xilinx Versal's OSPI flash memory controller

2021-11-23 Thread Francisco Iglesias
Add a model of Xilinx Versal's OSPI flash memory controller.

Signed-off-by: Francisco Iglesias 
Reviewed-by: Edgar E. Iglesias 
---
 hw/ssi/meson.build|1 +
 hw/ssi/xlnx-versal-ospi.c | 1892 +
 include/hw/ssi/xlnx-versal-ospi.h |   86 ++
 3 files changed, 1979 insertions(+)
 create mode 100644 hw/ssi/xlnx-versal-ospi.c
 create mode 100644 include/hw/ssi/xlnx-versal-ospi.h

diff --git a/hw/ssi/meson.build b/hw/ssi/meson.build
index 3d6bc82ab1..0ded9cd092 100644
--- a/hw/ssi/meson.build
+++ b/hw/ssi/meson.build
@@ -7,5 +7,6 @@ softmmu_ss.add(when: 'CONFIG_SSI', if_true: files('ssi.c'))
 softmmu_ss.add(when: 'CONFIG_STM32F2XX_SPI', if_true: files('stm32f2xx_spi.c'))
 softmmu_ss.add(when: 'CONFIG_XILINX_SPI', if_true: files('xilinx_spi.c'))
 softmmu_ss.add(when: 'CONFIG_XILINX_SPIPS', if_true: files('xilinx_spips.c'))
+softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: 
files('xlnx-versal-ospi.c'))
 softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('imx_spi.c'))
 softmmu_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_spi.c'))
diff --git a/hw/ssi/xlnx-versal-ospi.c b/hw/ssi/xlnx-versal-ospi.c
new file mode 100644
index 00..c02fc143de
--- /dev/null
+++ b/hw/ssi/xlnx-versal-ospi.c
@@ -0,0 +1,1892 @@
+/*
+ * QEMU model of Xilinx Versal's OSPI controller.
+ *
+ * Copyright (c) 2021 Xilinx Inc.
+ * Written by Francisco Iglesias 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "migration/vmstate.h"
+#include "hw/qdev-properties.h"
+#include "qemu/bitops.h"
+#include "qemu/log.h"
+#include "hw/irq.h"
+#include "hw/ssi/xlnx-versal-ospi.h"
+
+#ifndef XILINX_VERSAL_OSPI_ERR_DEBUG
+#define XILINX_VERSAL_OSPI_ERR_DEBUG 0
+#endif
+
+REG32(CONFIG_REG, 0x0)
+FIELD(CONFIG_REG, IDLE_FLD, 31, 1)
+FIELD(CONFIG_REG, DUAL_BYTE_OPCODE_EN_FLD, 30, 1)
+FIELD(CONFIG_REG, CRC_ENABLE_FLD, 29, 1)
+FIELD(CONFIG_REG, CONFIG_RESV2_FLD, 26, 3)
+FIELD(CONFIG_REG, PIPELINE_PHY_FLD, 25, 1)
+FIELD(CONFIG_REG, ENABLE_DTR_PROTOCOL_FLD, 24, 1)
+FIELD(CONFIG_REG, ENABLE_AHB_DECODER_FLD, 23, 1)
+FIELD(CONFIG_REG, MSTR_BAUD_DIV_FLD, 19, 4)
+FIELD(CONFIG_REG, ENTER_XIP_MODE_IMM_FLD, 18, 1)
+FIELD(CONFIG_REG, ENTER_XIP_MODE_FLD, 17, 1)
+FIELD(CONFIG_REG, ENB_AHB_ADDR_REMAP_FLD, 16, 1)
+FIELD(CONFIG_REG, ENB_DMA_IF_FLD, 15, 1)
+FIELD(CONFIG_REG, WR_PROT_FLASH_FLD, 14, 1)
+FIELD(CONFIG_REG, PERIPH_CS_LINES_FLD, 10, 4)
+FIELD(CONFIG_REG, PERIPH_SEL_DEC_FLD, 9, 1)
+FIELD(CONFIG_REG, ENB_LEGACY_IP_MODE_FLD, 8, 1)
+FIELD(CONFIG_REG, ENB_DIR_ACC_CTLR_FLD, 7, 1)
+FIELD(CONFIG_REG, RESET_CFG_FLD, 6, 1)
+FIELD(CONFIG_REG, RESET_PIN_FLD, 5, 1)
+FIELD(CONFIG_REG, HOLD_PIN_FLD, 4, 1)
+FIELD(CONFIG_REG, PHY_MODE_ENABLE_FLD, 3, 1)
+FIELD(CONFIG_REG, SEL_CLK_PHASE_FLD, 2, 1)
+FIELD(CONFIG_REG, SEL_CLK_POL_FLD, 1, 1)
+FIELD(CONFIG_REG, ENB_SPI_FLD, 0, 1)
+REG32(DEV_INSTR_RD_CONFIG_REG, 0x4)
+FIELD(DEV_INSTR_RD_CONFIG_REG, RD_INSTR_RESV5_FLD, 29, 3)
+FIELD(DEV_INSTR_RD_CONFIG_REG, DUMMY_RD_CLK_CYCLES_FLD, 24, 5)
+FIELD(DEV_INSTR_RD_CONFIG_REG, RD_INSTR_RESV4_FLD, 21, 3)
+FIELD(DEV_INSTR_RD_CONFIG_REG, MODE_BIT_ENABLE_FLD, 20, 1)
+FIELD(DEV_INSTR_RD_CONFIG_REG, RD_INSTR_RESV3_FLD, 18, 2)
+FIELD(DEV_INSTR_RD_CONFIG_REG, DATA_XFER_TYPE_EXT_MODE_FLD, 16, 2)
+FIELD(DEV_INSTR_RD_CONFIG_REG, RD_INSTR_RESV2_FLD, 14, 2)
+FIELD(DEV_INSTR_RD_CONFIG_REG, ADDR_XFER_TYPE_STD_MODE_FLD, 12, 2)
+FIELD(DEV_INSTR_RD_CONFIG_REG, PRED_DIS_FLD, 11, 1)
+FIELD(DEV_INSTR_RD_CONFIG_REG, DDR_EN_FLD, 10, 1)
+FIELD(DEV_INSTR_RD_CONFIG_REG, INS

[PATCH v2 04/10] hw/dma: Add the DMA control interface

2021-11-23 Thread Francisco Iglesias
Add an interface for controlling DMA models that are reused with other
models. This allows a controlling model to start transfers through the
DMA while reusing the DMA's handling of transfer state and completion
signaling.

Signed-off-by: Francisco Iglesias 
Reviewed-by: Edgar E. Iglesias 
---
 hw/dma/dma-ctrl.c | 31 
 hw/dma/meson.build|  1 +
 include/hw/dma/dma-ctrl.h | 74 +++
 3 files changed, 106 insertions(+)
 create mode 100644 hw/dma/dma-ctrl.c
 create mode 100644 include/hw/dma/dma-ctrl.h

diff --git a/hw/dma/dma-ctrl.c b/hw/dma/dma-ctrl.c
new file mode 100644
index 00..4a9b68dac1
--- /dev/null
+++ b/hw/dma/dma-ctrl.c
@@ -0,0 +1,31 @@
+/*
+ * DMA control interface.
+ *
+ * Copyright (c) 2021 Xilinx Inc.
+ * Written by Francisco Iglesias 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include "qemu/osdep.h"
+#include "exec/hwaddr.h"
+#include "hw/dma/dma-ctrl.h"
+
+void dma_ctrl_read_with_notify(DmaCtrl *dma_ctrl, hwaddr addr, uint32_t len,
+   DmaCtrlNotify *notify, bool start_dma)
+{
+DmaCtrlClass *dcc =  DMA_CTRL_GET_CLASS(dma_ctrl);
+dcc->read(dma_ctrl, addr, len, notify, start_dma);
+}
+
+static const TypeInfo dma_ctrl_info = {
+.name  = TYPE_DMA_CTRL,
+.parent= TYPE_INTERFACE,
+.class_size = sizeof(DmaCtrlClass),
+};
+
+static void dma_ctrl_register_types(void)
+{
+type_register_static(&dma_ctrl_info);
+}
+
+type_init(dma_ctrl_register_types)
diff --git a/hw/dma/meson.build b/hw/dma/meson.build
index f3f0661bc3..c0bc134046 100644
--- a/hw/dma/meson.build
+++ b/hw/dma/meson.build
@@ -14,3 +14,4 @@ softmmu_ss.add(when: 'CONFIG_PXA2XX', if_true: 
files('pxa2xx_dma.c'))
 softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_dma.c'))
 softmmu_ss.add(when: 'CONFIG_SIFIVE_PDMA', if_true: files('sifive_pdma.c'))
 softmmu_ss.add(when: 'CONFIG_XLNX_CSU_DMA', if_true: files('xlnx_csu_dma.c'))
+common_ss.add(when: 'CONFIG_XILINX_AXI', if_true: files('dma-ctrl.c'))
diff --git a/include/hw/dma/dma-ctrl.h b/include/hw/dma/dma-ctrl.h
new file mode 100644
index 00..498469395f
--- /dev/null
+++ b/include/hw/dma/dma-ctrl.h
@@ -0,0 +1,74 @@
+/*
+ * DMA control interface.
+ *
+ * Copyright (c) 2021 Xilinx Inc.
+ * Written by Francisco Iglesias 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#ifndef HW_DMA_CTRL_H
+#define HW_DMA_CTRL_H
+
+#include "qemu-common.h"
+#include "hw/hw.h"
+#include "qom/object.h"
+
+#define TYPE_DMA_CTRL "dma-ctrl"
+
+#define DMA_CTRL_CLASS(klass) \
+ OBJECT_CLASS_CHECK(DmaCtrlClass, (klass), TYPE_DMA_CTRL)
+#define DMA_CTRL_GET_CLASS(obj) \
+OBJECT_GET_CLASS(DmaCtrlClass, (obj), TYPE_DMA_CTRL)
+#define DMA_CTRL(obj) \
+ INTERFACE_CHECK(DmaCtrl, (obj), TYPE_DMA_CTRL)
+
+typedef void (*dmactrl_notify_fn)(void *opaque);
+
+typedef struct DmaCtrlNotify {
+void *opaque;
+dmactrl_notify_fn cb;
+} DmaCtrlNotify;
+
+typedef struct DmaCtrl {
+Object Parent;
+} DmaCtrl;
+
+typedef struct DmaCtrlClass {
+InterfaceClass parent;
+
+/*
+ * read: Start a read transfer on the DMA implementing the DMA control
+ * interface
+ *
+ * @dma_ctrl: the DMA implementing this interface
+ * @addr: the address to read
+ * @len: the amount of bytes to read at 'addr'
+ * @notify: the structure containg a callback to call and opaque pointer
+ * to pass the callback when the transfer has been completed
+ * @start_dma: true for starting the DMA transfer and false for just
+ * refilling and proceding an already started transfer
+ */
+void (*read)(DmaCtrl *dma_ctrl, hwaddr addr, uint32_t len,
+ DmaCtrlNotify *notify, bool start_dma);
+} DmaCtrlClass;
+
+/*
+ * Start a read transfer on a DMA implementing the DMA control interface.
+ * The DMA will notify the caller that 'len' bytes have been read at 'addr'
+ * through the callback in the DmaCtrlNotify structure. For allowing refilling
+ * an already started transfer the DMA notifies the caller before considering
+ * the transfer done (e.g. before setting done flags, generating IRQs and
+ * modifying other relevant internal device state).
+ *
+ * @dma_ctrl: the DMA implementing this interface
+ * @addr: the address to read
+ * @len: the amount of bytes to read at 'addr'
+ * @notify: the structure containing a callback to call and opaque pointer
+ * to pass the callback when the transfer has been completed
+ * @start_dma: true for starting the DMA transfer and false for just
+ * refilling and proceding an already started transfer
+ */
+void dma_ctrl_read_with_notify(DmaCtrl *dma_ctrl, hwaddr addr, uint32_t len,
+   DmaCtrlNotify *notify, bool start_dma);
+
+#endif /* HW_DMA_CTRL_H */
-- 
2.11.0




[PATCH v2 03/10] include/hw/dma/xlnx_csu_dma: Include ptimer.h and stream.h in the header

2021-11-23 Thread Francisco Iglesias
Include ptimer.h and stream.h in the header for being able to build and
reuse the DMA model (the first usage of StreamSink, StreamCanPushNotifyFn
and ptimer_state is in the header).

Signed-off-by: Francisco Iglesias 
---
 include/hw/dma/xlnx_csu_dma.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/hw/dma/xlnx_csu_dma.h b/include/hw/dma/xlnx_csu_dma.h
index 9e9dc551e9..8c39e46f58 100644
--- a/include/hw/dma/xlnx_csu_dma.h
+++ b/include/hw/dma/xlnx_csu_dma.h
@@ -21,6 +21,9 @@
 #ifndef XLNX_CSU_DMA_H
 #define XLNX_CSU_DMA_H
 
+#include "hw/ptimer.h"
+#include "hw/stream.h"
+
 #define TYPE_XLNX_CSU_DMA "xlnx.csu_dma"
 
 #define XLNX_CSU_DMA_R_MAX (0x2c / 4)
-- 
2.11.0




[PATCH v2 09/10] hw/arm/xlnx-versal-virt: Connect mt35xu01g flashes to the OSPI

2021-11-23 Thread Francisco Iglesias
Connect Micron Xccela mt35xu01g flashes to the OSPI flash memory
controller.

Signed-off-by: Francisco Iglesias 
---
 hw/arm/xlnx-versal-virt.c | 23 +++
 1 file changed, 23 insertions(+)

diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
index d2f55e29b6..47f5914e5d 100644
--- a/hw/arm/xlnx-versal-virt.c
+++ b/hw/arm/xlnx-versal-virt.c
@@ -25,6 +25,8 @@
 #define TYPE_XLNX_VERSAL_VIRT_MACHINE MACHINE_TYPE_NAME("xlnx-versal-virt")
 OBJECT_DECLARE_SIMPLE_TYPE(VersalVirt, XLNX_VERSAL_VIRT_MACHINE)
 
+#define XLNX_VERSAL_NUM_OSPI_FLASH 4
+
 struct VersalVirt {
 MachineState parent_obj;
 
@@ -690,6 +692,27 @@ static void versal_virt_init(MachineState *machine)
 exit(EXIT_FAILURE);
 }
 }
+
+for (i = 0; i < XLNX_VERSAL_NUM_OSPI_FLASH; i++) {
+BusState *spi_bus;
+DeviceState *flash_dev;
+qemu_irq cs_line;
+DriveInfo *dinfo = drive_get(IF_MTD, 0, i);
+
+spi_bus = qdev_get_child_bus(DEVICE(&s->soc.pmc.iou.ospi), "spi0");
+
+flash_dev = qdev_new("mt35xu01g");
+if (dinfo) {
+qdev_prop_set_drive_err(flash_dev, "drive",
+blk_by_legacy_dinfo(dinfo), &error_fatal);
+}
+qdev_realize_and_unref(flash_dev, spi_bus, &error_fatal);
+
+cs_line = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
+
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->soc.pmc.iou.ospi),
+   i + 1, cs_line);
+}
 }
 
 static void versal_virt_machine_instance_init(Object *obj)
-- 
2.11.0




[PATCH v2 08/10] hw/block/m25p80: Add support for Micron Xccela flash mt35xu01g

2021-11-23 Thread Francisco Iglesias
Add support for Micron Xccela flash mt35xu01g.

Signed-off-by: Francisco Iglesias 
Reviewed-by: Edgar E. Iglesias 
---
 hw/block/m25p80.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index b77503dc84..c6bf3c6bfa 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -255,6 +255,8 @@ static const FlashPartInfo known_devices[] = {
 { INFO("n25q512a",0x20ba20,  0,  64 << 10, 1024, ER_4K) },
 { INFO("n25q512ax3",  0x20ba20,  0x1000,  64 << 10, 1024, ER_4K) },
 { INFO("mt25ql512ab", 0x20ba20, 0x1044, 64 << 10, 1024, ER_4K | ER_32K) },
+{ INFO_STACKED("mt35xu01g", 0x2c5b1b, 0x104100, 128 << 10, 1024,
+   ER_4K | ER_32K, 2) },
 { INFO_STACKED("n25q00",0x20ba21, 0x1000, 64 << 10, 2048, ER_4K, 4) },
 { INFO_STACKED("n25q00a",   0x20bb21, 0x1000, 64 << 10, 2048, ER_4K, 4) },
 { INFO_STACKED("mt25ql01g", 0x20ba21, 0x1040, 64 << 10, 2048, ER_4K, 2) },
-- 
2.11.0




[PATCH v2 10/10] MAINTAINERS: Add an entry for Xilinx Versal OSPI

2021-11-23 Thread Francisco Iglesias
List myself as maintainer for the Xilinx Versal OSPI controller.

Signed-off-by: Francisco Iglesias 
---
 MAINTAINERS | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index d3879aa3c1..8c2b01a282 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -963,6 +963,12 @@ F: hw/display/dpcd.c
 F: include/hw/display/dpcd.h
 F: docs/system/arm/xlnx-versal-virt.rst
 
+Xilinx Versal OSPI
+M: Francisco Iglesias 
+S: Maintained
+F: hw/ssi/xlnx-versal-ospi.c
+F: include/hw/ssi/xlnx-versal-ospi.h
+
 ARM ACPI Subsystem
 M: Shannon Zhao 
 L: qemu-...@nongnu.org
-- 
2.11.0




[PATCH v2 07/10] hw/arm/xlnx-versal: Connect the OSPI flash memory controller model

2021-11-23 Thread Francisco Iglesias
Connect the OSPI flash memory controller model (including the source and
destination DMA).

Signed-off-by: Francisco Iglesias 
---
 hw/arm/xlnx-versal.c | 87 
 include/hw/arm/xlnx-versal.h | 20 ++
 2 files changed, 107 insertions(+)

diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
index 08e250945f..20c82bff01 100644
--- a/hw/arm/xlnx-versal.c
+++ b/hw/arm/xlnx-versal.c
@@ -24,6 +24,7 @@
 
 #define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
 #define GEM_REVISION0x40070106
+#define NUM_OSPI_IRQ_LINES 3
 
 static void versal_create_apu_cpus(Versal *s)
 {
@@ -385,6 +386,91 @@ static void versal_create_pmc_iou_slcr(Versal *s, qemu_irq 
*pic)
 sysbus_connect_irq(sbd, 0, pic[VERSAL_PMC_IOU_SLCR_IRQ]);
 }
 
+static void versal_create_ospi(Versal *s, qemu_irq *pic)
+{
+SysBusDevice *sbd;
+MemoryRegion *mr_dac;
+
+memory_region_init(&s->pmc.iou.ospi.linear_mr, OBJECT(s),
+   "versal-ospi-linear-mr" , MM_PMC_OSPI_DAC_SIZE);
+
+object_initialize_child(OBJECT(s), "versal-ospi", &s->pmc.iou.ospi.ospi,
+TYPE_XILINX_VERSAL_OSPI);
+
+mr_dac = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi), 1);
+memory_region_add_subregion(&s->pmc.iou.ospi.linear_mr, 0x0, mr_dac);
+
+/* Create the OSPI destination DMA */
+object_initialize_child(OBJECT(s), "versal-ospi-dma-dst",
+&s->pmc.iou.ospi.dma_dst,
+TYPE_XLNX_CSU_DMA);
+
+object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_dst),
+"dma", OBJECT(get_system_memory()),
+ &error_abort);
+
+sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_dst);
+sysbus_realize(sbd, &error_fatal);
+
+memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DMA_DST,
+sysbus_mmio_get_region(sbd, 0));
+
+/* Create the OSPI source DMA */
+object_initialize_child(OBJECT(s), "versal-ospi-dma-src",
+&s->pmc.iou.ospi.dma_src,
+TYPE_XLNX_CSU_DMA);
+
+object_property_set_bool(OBJECT(&s->pmc.iou.ospi.dma_src), "is-dst",
+ false, &error_abort);
+
+object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_src),
+"dma", OBJECT(mr_dac), &error_abort);
+
+object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_src),
+"stream-connected-dma",
+ OBJECT(&s->pmc.iou.ospi.dma_dst),
+ &error_abort);
+
+sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_src);
+sysbus_realize(sbd, &error_fatal);
+
+memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DMA_SRC,
+sysbus_mmio_get_region(sbd, 0));
+
+/* Realize the OSPI */
+object_property_set_link(OBJECT(&s->pmc.iou.ospi.ospi), "dma-src",
+ OBJECT(&s->pmc.iou.ospi.dma_src), &error_abort);
+
+sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi);
+sysbus_realize(sbd, &error_fatal);
+
+memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI,
+sysbus_mmio_get_region(sbd, 0));
+
+memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DAC,
+&s->pmc.iou.ospi.linear_mr);
+
+/* ospi_mux_sel */
+qdev_connect_gpio_out(DEVICE(&s->pmc.iou.slcr), 3,
+  qdev_get_gpio_in(DEVICE(&s->pmc.iou.ospi.ospi), 0));
+
+/* OSPI irq */
+object_initialize_child(OBJECT(s), "ospi-irq",
+&s->pmc.iou.ospi.irq, TYPE_OR_IRQ);
+object_property_set_int(OBJECT(&s->pmc.iou.ospi.irq),
+"num-lines", NUM_OSPI_IRQ_LINES, &error_fatal);
+qdev_realize(DEVICE(&s->pmc.iou.ospi.irq), NULL, &error_fatal);
+
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi), 0,
+   qdev_get_gpio_in(DEVICE(&s->pmc.iou.ospi.irq), 0));
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_src), 0,
+   qdev_get_gpio_in(DEVICE(&s->pmc.iou.ospi.irq), 1));
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_dst), 0,
+   qdev_get_gpio_in(DEVICE(&s->pmc.iou.ospi.irq), 2));
+
+qdev_connect_gpio_out(DEVICE(&s->pmc.iou.ospi.irq), 0,
+  pic[VERSAL_OSPI_IRQ]);
+}
 
 /* This takes the board allocated linear DDR memory and creates aliases
  * for each split DDR range/aperture on the Versal address map.
@@ 

[PATCH v2 00/10] Xilinx Versal's PMC SLCR and OSPI support

2021-11-23 Thread Francisco Iglesias
Hi,

This series attempts to add support for Xilinx Versal's PMC SLCR
(system-level control registers) and OSPI flash memory controller to
Xilinx Versal virt machine.

The series start with adding a model of Versal's PMC SLCR and connecting
the model to the Versal virt machine. The series then adds a couple of
headers into the xlnx_csu_dma.h needed for building and reusing it later
with the OSPI. The series thereafter introduces a DMA control interface
and implements the interface in the xlnx_csu_dma for being able to reuse
and control the DMA with the OSPI controller. Thereafter a model of
Versal's OSPI controller is added and connected to the Versal virt
machine. The series then ends with adding initial support for the Micron
Xccelera mt35xu01g flash and flashes of this type are connected to the
OSPI in the Versal virt machine.

Best regards,
Francisco Iglesias

Changelog:
v1 -> v2
  * Correct the reset in the PMC SLCR model
  * Create a sub structure for the OSPI in the Versal structure (in patch:
"hw/arm/xlnx-versal: Connect the OSPI flash memory controller model")
  * Change to use 'drive_get' instead of 'drive_get_next' (in patch:
"hw/arm/xlnx-versal-virt: Connect mt35xu01g flashes to the OSPI")
  * Add a maintainers patch and list myself as maintainer for the OSPI
controller


Francisco Iglesias (10):
  hw/misc: Add a model of Versal's PMC SLCR
  hw/arm/xlnx-versal: Connect Versal's PMC SLCR
  include/hw/dma/xlnx_csu_dma: Include ptimer.h and stream.h in the
header
  hw/dma: Add the DMA control interface
  hw/dma/xlnx_csu_dma: Implement the DMA control interface
  hw/ssi: Add a model of Xilinx Versal's OSPI flash memory controller
  hw/arm/xlnx-versal: Connect the OSPI flash memory controller model
  hw/block/m25p80: Add support for Micron Xccela flash mt35xu01g
  hw/arm/xlnx-versal-virt: Connect mt35xu01g flashes to the OSPI
  MAINTAINERS: Add an entry for Xilinx Versal OSPI

 MAINTAINERS|6 +
 hw/arm/xlnx-versal-virt.c  |   23 +
 hw/arm/xlnx-versal.c   |  105 ++
 hw/block/m25p80.c  |2 +
 hw/dma/dma-ctrl.c  |   31 +
 hw/dma/meson.build |1 +
 hw/dma/xlnx_csu_dma.c  |   32 +
 hw/misc/meson.build|5 +-
 hw/misc/xlnx-versal-pmc-iou-slcr.c | 1445 +
 hw/ssi/meson.build |1 +
 hw/ssi/xlnx-versal-ospi.c  | 1892 
 include/hw/arm/xlnx-versal.h   |   26 +
 include/hw/dma/dma-ctrl.h  |   74 ++
 include/hw/dma/xlnx_csu_dma.h  |7 +
 include/hw/misc/xlnx-versal-pmc-iou-slcr.h |   51 +
 include/hw/ssi/xlnx-versal-ospi.h  |   86 ++
 16 files changed, 3786 insertions(+), 1 deletion(-)
 create mode 100644 hw/dma/dma-ctrl.c
 create mode 100644 hw/misc/xlnx-versal-pmc-iou-slcr.c
 create mode 100644 hw/ssi/xlnx-versal-ospi.c
 create mode 100644 include/hw/dma/dma-ctrl.h
 create mode 100644 include/hw/misc/xlnx-versal-pmc-iou-slcr.h
 create mode 100644 include/hw/ssi/xlnx-versal-ospi.h

-- 
2.11.0




[PATCH v2 02/10] hw/arm/xlnx-versal: Connect Versal's PMC SLCR

2021-11-23 Thread Francisco Iglesias
Connect Versal's PMC SLCR (system-level control registers) model.

Signed-off-by: Francisco Iglesias 
Reviewed-by: Edgar E. Iglesias 
---
 hw/arm/xlnx-versal.c | 18 ++
 include/hw/arm/xlnx-versal.h |  6 ++
 2 files changed, 24 insertions(+)

diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
index b2705b6925..08e250945f 100644
--- a/hw/arm/xlnx-versal.c
+++ b/hw/arm/xlnx-versal.c
@@ -369,6 +369,23 @@ static void versal_create_efuse(Versal *s, qemu_irq *pic)
 sysbus_connect_irq(SYS_BUS_DEVICE(ctrl), 0, pic[VERSAL_EFUSE_IRQ]);
 }
 
+static void versal_create_pmc_iou_slcr(Versal *s, qemu_irq *pic)
+{
+SysBusDevice *sbd;
+
+object_initialize_child(OBJECT(s), "versal-pmc-iou-slcr", &s->pmc.iou.slcr,
+TYPE_XILINX_VERSAL_PMC_IOU_SLCR);
+
+sbd = SYS_BUS_DEVICE(&s->pmc.iou.slcr);
+sysbus_realize(sbd, &error_fatal);
+
+memory_region_add_subregion(&s->mr_ps, MM_PMC_PMC_IOU_SLCR,
+sysbus_mmio_get_region(sbd, 0));
+
+sysbus_connect_irq(sbd, 0, pic[VERSAL_PMC_IOU_SLCR_IRQ]);
+}
+
+
 /* This takes the board allocated linear DDR memory and creates aliases
  * for each split DDR range/aperture on the Versal address map.
  */
@@ -459,6 +476,7 @@ static void versal_realize(DeviceState *dev, Error **errp)
 versal_create_xrams(s, pic);
 versal_create_bbram(s, pic);
 versal_create_efuse(s, pic);
+versal_create_pmc_iou_slcr(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 895ba12c61..729c093dfc 100644
--- a/include/hw/arm/xlnx-versal.h
+++ b/include/hw/arm/xlnx-versal.h
@@ -26,6 +26,7 @@
 #include "hw/misc/xlnx-versal-xramc.h"
 #include "hw/nvram/xlnx-bbram.h"
 #include "hw/nvram/xlnx-versal-efuse.h"
+#include "hw/misc/xlnx-versal-pmc-iou-slcr.h"
 
 #define TYPE_XLNX_VERSAL "xlnx-versal"
 OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
@@ -78,6 +79,7 @@ struct Versal {
 struct {
 struct {
 SDHCIState sd[XLNX_VERSAL_NR_SDS];
+XlnxVersalPmcIouSlcr slcr;
 } iou;
 
 XlnxZynqMPRTC rtc;
@@ -113,6 +115,7 @@ struct Versal {
 #define VERSAL_XRAM_IRQ_0  79
 #define VERSAL_BBRAM_APB_IRQ_0 121
 #define VERSAL_RTC_APB_ERR_IRQ 121
+#define VERSAL_PMC_IOU_SLCR_IRQ121
 #define VERSAL_SD0_IRQ_0   126
 #define VERSAL_EFUSE_IRQ   139
 #define VERSAL_RTC_ALARM_IRQ   142
@@ -178,6 +181,9 @@ struct Versal {
 #define MM_FPD_FPD_APU  0xfd5c
 #define MM_FPD_FPD_APU_SIZE 0x100
 
+#define MM_PMC_PMC_IOU_SLCR 0xf106
+#define MM_PMC_PMC_IOU_SLCR_SIZE0x1
+
 #define MM_PMC_SD0  0xf104U
 #define MM_PMC_SD0_SIZE 0x1
 #define MM_PMC_BBRAM_CTRL   0xf11f
-- 
2.11.0




[PATCH v2 01/10] hw/misc: Add a model of Versal's PMC SLCR

2021-11-23 Thread Francisco Iglesias
Add a model of Versal's PMC SLCR (system-level control registers).

Signed-off-by: Francisco Iglesias 
Signed-off-by: Edgar E. Iglesias 
---
 hw/misc/meson.build|5 +-
 hw/misc/xlnx-versal-pmc-iou-slcr.c | 1445 
 include/hw/misc/xlnx-versal-pmc-iou-slcr.h |   51 +
 3 files changed, 1500 insertions(+), 1 deletion(-)
 create mode 100644 hw/misc/xlnx-versal-pmc-iou-slcr.c
 create mode 100644 include/hw/misc/xlnx-versal-pmc-iou-slcr.h

diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index 3f41a3a5b2..e82628a618 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -84,7 +84,10 @@ softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files(
 ))
 softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
 softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c'))
-softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: 
files('xlnx-versal-xramc.c'))
+softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files(
+  'xlnx-versal-xramc.c',
+  'xlnx-versal-pmc-iou-slcr.c',
+))
 softmmu_ss.add(when: 'CONFIG_STM32F2XX_SYSCFG', if_true: 
files('stm32f2xx_syscfg.c'))
 softmmu_ss.add(when: 'CONFIG_STM32F4XX_SYSCFG', if_true: 
files('stm32f4xx_syscfg.c'))
 softmmu_ss.add(when: 'CONFIG_STM32F4XX_EXTI', if_true: 
files('stm32f4xx_exti.c'))
diff --git a/hw/misc/xlnx-versal-pmc-iou-slcr.c 
b/hw/misc/xlnx-versal-pmc-iou-slcr.c
new file mode 100644
index 00..1d141b4013
--- /dev/null
+++ b/hw/misc/xlnx-versal-pmc-iou-slcr.c
@@ -0,0 +1,1445 @@
+/*
+ * QEMU model of Versal's PMC IOU SLCR (system level control registers)
+ *
+ * Copyright (c) 2021 Xilinx Inc.
+ * Written by Edgar E. Iglesias 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "hw/register.h"
+#include "hw/irq.h"
+#include "qemu/bitops.h"
+#include "qemu/log.h"
+#include "migration/vmstate.h"
+#include "hw/qdev-properties.h"
+#include "hw/misc/xlnx-versal-pmc-iou-slcr.h"
+
+#ifndef XILINX_VERSAL_PMC_IOU_SLCR_ERR_DEBUG
+#define XILINX_VERSAL_PMC_IOU_SLCR_ERR_DEBUG 0
+#endif
+
+REG32(MIO_PIN_0, 0x0)
+FIELD(MIO_PIN_0, L3_SEL, 7, 3)
+FIELD(MIO_PIN_0, L2_SEL, 5, 2)
+FIELD(MIO_PIN_0, L1_SEL, 3, 2)
+FIELD(MIO_PIN_0, L0_SEL, 1, 2)
+REG32(MIO_PIN_1, 0x4)
+FIELD(MIO_PIN_1, L3_SEL, 7, 3)
+FIELD(MIO_PIN_1, L2_SEL, 5, 2)
+FIELD(MIO_PIN_1, L1_SEL, 3, 2)
+FIELD(MIO_PIN_1, L0_SEL, 1, 2)
+REG32(MIO_PIN_2, 0x8)
+FIELD(MIO_PIN_2, L3_SEL, 7, 3)
+FIELD(MIO_PIN_2, L2_SEL, 5, 2)
+FIELD(MIO_PIN_2, L1_SEL, 3, 2)
+FIELD(MIO_PIN_2, L0_SEL, 1, 2)
+REG32(MIO_PIN_3, 0xc)
+FIELD(MIO_PIN_3, L3_SEL, 7, 3)
+FIELD(MIO_PIN_3, L2_SEL, 5, 2)
+FIELD(MIO_PIN_3, L1_SEL, 3, 2)
+FIELD(MIO_PIN_3, L0_SEL, 1, 2)
+REG32(MIO_PIN_4, 0x10)
+FIELD(MIO_PIN_4, L3_SEL, 7, 3)
+FIELD(MIO_PIN_4, L2_SEL, 5, 2)
+FIELD(MIO_PIN_4, L1_SEL, 3, 2)
+FIELD(MIO_PIN_4, L0_SEL, 1, 2)
+REG32(MIO_PIN_5, 0x14)
+FIELD(MIO_PIN_5, L3_SEL, 7, 3)
+FIELD(MIO_PIN_5, L2_SEL, 5, 2)
+FIELD(MIO_PIN_5, L1_SEL, 3, 2)
+FIELD(MIO_PIN_5, L0_SEL, 1, 2)
+REG32(MIO_PIN_6, 0x18)
+FIELD(MIO_PIN_6, L3_SEL, 7, 3)
+FIELD(MIO_PIN_6, L2_SEL, 5, 2)
+FIELD(MIO_PIN_6, L1_SEL, 3, 2)
+FIELD(MIO_PIN_6, L0_SEL, 1, 2)
+REG32(MIO_PIN_7, 0x1c)
+FIELD(MIO_PIN_7, L3_SEL, 7, 3)
+FIELD(MIO_PIN_7, L2_SEL, 5, 2)
+FIELD(MIO_PIN_7, L1_SEL, 3, 2)
+FIELD(MIO_PIN_7, L0_SEL, 1, 2)
+REG32(MIO_PIN_8, 0x20)
+FIELD(MIO_PIN_8, L3_SEL, 7, 3)
+FIELD(MIO_PIN_8, L2_SEL, 5, 2)
+FIELD(MIO_PIN_8, L1_SEL, 3, 2)
+FIELD(MIO_PIN_8, L0_SEL, 1, 2)
+REG32(MIO_PIN_9, 0x24)
+FIELD(MIO_PIN_9, L3_SEL, 7, 3)

[PATCH v3 01/10] hw/misc: Add a model of Versal's PMC SLCR

2021-11-24 Thread Francisco Iglesias
Add a model of Versal's PMC SLCR (system-level control registers).

Signed-off-by: Francisco Iglesias 
Signed-off-by: Edgar E. Iglesias 
Acked-by: Edgar E. Iglesias 
---
 hw/misc/meson.build|5 +-
 hw/misc/xlnx-versal-pmc-iou-slcr.c | 1445 
 include/hw/misc/xlnx-versal-pmc-iou-slcr.h |   51 +
 3 files changed, 1500 insertions(+), 1 deletion(-)
 create mode 100644 hw/misc/xlnx-versal-pmc-iou-slcr.c
 create mode 100644 include/hw/misc/xlnx-versal-pmc-iou-slcr.h

diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index 3f41a3a5b2..e82628a618 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -84,7 +84,10 @@ softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files(
 ))
 softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
 softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c'))
-softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: 
files('xlnx-versal-xramc.c'))
+softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files(
+  'xlnx-versal-xramc.c',
+  'xlnx-versal-pmc-iou-slcr.c',
+))
 softmmu_ss.add(when: 'CONFIG_STM32F2XX_SYSCFG', if_true: 
files('stm32f2xx_syscfg.c'))
 softmmu_ss.add(when: 'CONFIG_STM32F4XX_SYSCFG', if_true: 
files('stm32f4xx_syscfg.c'))
 softmmu_ss.add(when: 'CONFIG_STM32F4XX_EXTI', if_true: 
files('stm32f4xx_exti.c'))
diff --git a/hw/misc/xlnx-versal-pmc-iou-slcr.c 
b/hw/misc/xlnx-versal-pmc-iou-slcr.c
new file mode 100644
index 00..1d141b4013
--- /dev/null
+++ b/hw/misc/xlnx-versal-pmc-iou-slcr.c
@@ -0,0 +1,1445 @@
+/*
+ * QEMU model of Versal's PMC IOU SLCR (system level control registers)
+ *
+ * Copyright (c) 2021 Xilinx Inc.
+ * Written by Edgar E. Iglesias 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "hw/register.h"
+#include "hw/irq.h"
+#include "qemu/bitops.h"
+#include "qemu/log.h"
+#include "migration/vmstate.h"
+#include "hw/qdev-properties.h"
+#include "hw/misc/xlnx-versal-pmc-iou-slcr.h"
+
+#ifndef XILINX_VERSAL_PMC_IOU_SLCR_ERR_DEBUG
+#define XILINX_VERSAL_PMC_IOU_SLCR_ERR_DEBUG 0
+#endif
+
+REG32(MIO_PIN_0, 0x0)
+FIELD(MIO_PIN_0, L3_SEL, 7, 3)
+FIELD(MIO_PIN_0, L2_SEL, 5, 2)
+FIELD(MIO_PIN_0, L1_SEL, 3, 2)
+FIELD(MIO_PIN_0, L0_SEL, 1, 2)
+REG32(MIO_PIN_1, 0x4)
+FIELD(MIO_PIN_1, L3_SEL, 7, 3)
+FIELD(MIO_PIN_1, L2_SEL, 5, 2)
+FIELD(MIO_PIN_1, L1_SEL, 3, 2)
+FIELD(MIO_PIN_1, L0_SEL, 1, 2)
+REG32(MIO_PIN_2, 0x8)
+FIELD(MIO_PIN_2, L3_SEL, 7, 3)
+FIELD(MIO_PIN_2, L2_SEL, 5, 2)
+FIELD(MIO_PIN_2, L1_SEL, 3, 2)
+FIELD(MIO_PIN_2, L0_SEL, 1, 2)
+REG32(MIO_PIN_3, 0xc)
+FIELD(MIO_PIN_3, L3_SEL, 7, 3)
+FIELD(MIO_PIN_3, L2_SEL, 5, 2)
+FIELD(MIO_PIN_3, L1_SEL, 3, 2)
+FIELD(MIO_PIN_3, L0_SEL, 1, 2)
+REG32(MIO_PIN_4, 0x10)
+FIELD(MIO_PIN_4, L3_SEL, 7, 3)
+FIELD(MIO_PIN_4, L2_SEL, 5, 2)
+FIELD(MIO_PIN_4, L1_SEL, 3, 2)
+FIELD(MIO_PIN_4, L0_SEL, 1, 2)
+REG32(MIO_PIN_5, 0x14)
+FIELD(MIO_PIN_5, L3_SEL, 7, 3)
+FIELD(MIO_PIN_5, L2_SEL, 5, 2)
+FIELD(MIO_PIN_5, L1_SEL, 3, 2)
+FIELD(MIO_PIN_5, L0_SEL, 1, 2)
+REG32(MIO_PIN_6, 0x18)
+FIELD(MIO_PIN_6, L3_SEL, 7, 3)
+FIELD(MIO_PIN_6, L2_SEL, 5, 2)
+FIELD(MIO_PIN_6, L1_SEL, 3, 2)
+FIELD(MIO_PIN_6, L0_SEL, 1, 2)
+REG32(MIO_PIN_7, 0x1c)
+FIELD(MIO_PIN_7, L3_SEL, 7, 3)
+FIELD(MIO_PIN_7, L2_SEL, 5, 2)
+FIELD(MIO_PIN_7, L1_SEL, 3, 2)
+FIELD(MIO_PIN_7, L0_SEL, 1, 2)
+REG32(MIO_PIN_8, 0x20)
+FIELD(MIO_PIN_8, L3_SEL, 7, 3)
+FIELD(MIO_PIN_8, L2_SEL, 5, 2)
+FIELD(MIO_PIN_8, L1_SEL, 3, 2)
+FIELD(MIO_PIN_8, L0_SEL, 1, 2)
+REG32(MIO_PIN_9, 0x24

[PATCH v3 04/10] hw/dma: Add the DMA control interface

2021-11-24 Thread Francisco Iglesias
Add an interface for controlling DMA models that are reused with other
models. This allows a controlling model to start transfers through the
DMA while reusing the DMA's handling of transfer state and completion
signaling.

Signed-off-by: Francisco Iglesias 
Reviewed-by: Edgar E. Iglesias 
---
 hw/dma/dma-ctrl.c | 31 
 hw/dma/meson.build|  1 +
 include/hw/dma/dma-ctrl.h | 74 +++
 3 files changed, 106 insertions(+)
 create mode 100644 hw/dma/dma-ctrl.c
 create mode 100644 include/hw/dma/dma-ctrl.h

diff --git a/hw/dma/dma-ctrl.c b/hw/dma/dma-ctrl.c
new file mode 100644
index 00..4a9b68dac1
--- /dev/null
+++ b/hw/dma/dma-ctrl.c
@@ -0,0 +1,31 @@
+/*
+ * DMA control interface.
+ *
+ * Copyright (c) 2021 Xilinx Inc.
+ * Written by Francisco Iglesias 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include "qemu/osdep.h"
+#include "exec/hwaddr.h"
+#include "hw/dma/dma-ctrl.h"
+
+void dma_ctrl_read_with_notify(DmaCtrl *dma_ctrl, hwaddr addr, uint32_t len,
+   DmaCtrlNotify *notify, bool start_dma)
+{
+DmaCtrlClass *dcc =  DMA_CTRL_GET_CLASS(dma_ctrl);
+dcc->read(dma_ctrl, addr, len, notify, start_dma);
+}
+
+static const TypeInfo dma_ctrl_info = {
+.name  = TYPE_DMA_CTRL,
+.parent= TYPE_INTERFACE,
+.class_size = sizeof(DmaCtrlClass),
+};
+
+static void dma_ctrl_register_types(void)
+{
+type_register_static(&dma_ctrl_info);
+}
+
+type_init(dma_ctrl_register_types)
diff --git a/hw/dma/meson.build b/hw/dma/meson.build
index f3f0661bc3..c0bc134046 100644
--- a/hw/dma/meson.build
+++ b/hw/dma/meson.build
@@ -14,3 +14,4 @@ softmmu_ss.add(when: 'CONFIG_PXA2XX', if_true: 
files('pxa2xx_dma.c'))
 softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_dma.c'))
 softmmu_ss.add(when: 'CONFIG_SIFIVE_PDMA', if_true: files('sifive_pdma.c'))
 softmmu_ss.add(when: 'CONFIG_XLNX_CSU_DMA', if_true: files('xlnx_csu_dma.c'))
+common_ss.add(when: 'CONFIG_XILINX_AXI', if_true: files('dma-ctrl.c'))
diff --git a/include/hw/dma/dma-ctrl.h b/include/hw/dma/dma-ctrl.h
new file mode 100644
index 00..498469395f
--- /dev/null
+++ b/include/hw/dma/dma-ctrl.h
@@ -0,0 +1,74 @@
+/*
+ * DMA control interface.
+ *
+ * Copyright (c) 2021 Xilinx Inc.
+ * Written by Francisco Iglesias 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#ifndef HW_DMA_CTRL_H
+#define HW_DMA_CTRL_H
+
+#include "qemu-common.h"
+#include "hw/hw.h"
+#include "qom/object.h"
+
+#define TYPE_DMA_CTRL "dma-ctrl"
+
+#define DMA_CTRL_CLASS(klass) \
+ OBJECT_CLASS_CHECK(DmaCtrlClass, (klass), TYPE_DMA_CTRL)
+#define DMA_CTRL_GET_CLASS(obj) \
+OBJECT_GET_CLASS(DmaCtrlClass, (obj), TYPE_DMA_CTRL)
+#define DMA_CTRL(obj) \
+ INTERFACE_CHECK(DmaCtrl, (obj), TYPE_DMA_CTRL)
+
+typedef void (*dmactrl_notify_fn)(void *opaque);
+
+typedef struct DmaCtrlNotify {
+void *opaque;
+dmactrl_notify_fn cb;
+} DmaCtrlNotify;
+
+typedef struct DmaCtrl {
+Object Parent;
+} DmaCtrl;
+
+typedef struct DmaCtrlClass {
+InterfaceClass parent;
+
+/*
+ * read: Start a read transfer on the DMA implementing the DMA control
+ * interface
+ *
+ * @dma_ctrl: the DMA implementing this interface
+ * @addr: the address to read
+ * @len: the amount of bytes to read at 'addr'
+ * @notify: the structure containg a callback to call and opaque pointer
+ * to pass the callback when the transfer has been completed
+ * @start_dma: true for starting the DMA transfer and false for just
+ * refilling and proceding an already started transfer
+ */
+void (*read)(DmaCtrl *dma_ctrl, hwaddr addr, uint32_t len,
+ DmaCtrlNotify *notify, bool start_dma);
+} DmaCtrlClass;
+
+/*
+ * Start a read transfer on a DMA implementing the DMA control interface.
+ * The DMA will notify the caller that 'len' bytes have been read at 'addr'
+ * through the callback in the DmaCtrlNotify structure. For allowing refilling
+ * an already started transfer the DMA notifies the caller before considering
+ * the transfer done (e.g. before setting done flags, generating IRQs and
+ * modifying other relevant internal device state).
+ *
+ * @dma_ctrl: the DMA implementing this interface
+ * @addr: the address to read
+ * @len: the amount of bytes to read at 'addr'
+ * @notify: the structure containing a callback to call and opaque pointer
+ * to pass the callback when the transfer has been completed
+ * @start_dma: true for starting the DMA transfer and false for just
+ * refilling and proceding an already started transfer
+ */
+void dma_ctrl_read_with_notify(DmaCtrl *dma_ctrl, hwaddr addr, uint32_t len,
+   DmaCtrlNotify *notify, bool start_dma);
+
+#endif /* HW_DMA_CTRL_H */
-- 
2.11.0




[PATCH v3 08/10] hw/block/m25p80: Add support for Micron Xccela flash mt35xu01g

2021-11-24 Thread Francisco Iglesias
Add support for Micron Xccela flash mt35xu01g.

Signed-off-by: Francisco Iglesias 
Reviewed-by: Edgar E. Iglesias 
---
 hw/block/m25p80.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index b77503dc84..c6bf3c6bfa 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -255,6 +255,8 @@ static const FlashPartInfo known_devices[] = {
 { INFO("n25q512a",0x20ba20,  0,  64 << 10, 1024, ER_4K) },
 { INFO("n25q512ax3",  0x20ba20,  0x1000,  64 << 10, 1024, ER_4K) },
 { INFO("mt25ql512ab", 0x20ba20, 0x1044, 64 << 10, 1024, ER_4K | ER_32K) },
+{ INFO_STACKED("mt35xu01g", 0x2c5b1b, 0x104100, 128 << 10, 1024,
+   ER_4K | ER_32K, 2) },
 { INFO_STACKED("n25q00",0x20ba21, 0x1000, 64 << 10, 2048, ER_4K, 4) },
 { INFO_STACKED("n25q00a",   0x20bb21, 0x1000, 64 << 10, 2048, ER_4K, 4) },
 { INFO_STACKED("mt25ql01g", 0x20ba21, 0x1040, 64 << 10, 2048, ER_4K, 2) },
-- 
2.11.0




[PATCH v3 05/10] hw/dma/xlnx_csu_dma: Implement the DMA control interface

2021-11-24 Thread Francisco Iglesias
Implement the DMA control interface for allowing control of DMA operations
from inside models that contain instances of (and reuse) the Xilinx CSU
DMA.

Signed-off-by: Francisco Iglesias 
Reviewed-by: Edgar E. Iglesias 
---
 hw/dma/xlnx_csu_dma.c | 32 
 include/hw/dma/xlnx_csu_dma.h |  4 
 2 files changed, 36 insertions(+)

diff --git a/hw/dma/xlnx_csu_dma.c b/hw/dma/xlnx_csu_dma.c
index 896bb3574d..9ed6e82225 100644
--- a/hw/dma/xlnx_csu_dma.c
+++ b/hw/dma/xlnx_csu_dma.c
@@ -277,6 +277,11 @@ static uint32_t xlnx_csu_dma_advance(XlnxCSUDMA *s, 
uint32_t len)
 s->regs[R_ADDR_MSB] = dst >> 32;
 }
 
+/* Notify dma-ctrl clients when the transfer has been completed */
+if (size == 0 && s->dma_ctrl_notify) {
+s->dma_ctrl_notify(s->dma_ctrl_opaque);
+}
+
 if (size == 0) {
 xlnx_csu_dma_done(s);
 }
@@ -472,6 +477,29 @@ static uint64_t addr_msb_pre_write(RegisterInfo *reg, 
uint64_t val)
 return val & R_ADDR_MSB_ADDR_MSB_MASK;
 }
 
+static void xlnx_csu_dma_dma_ctrl_read(DmaCtrl *dma_ctrl, hwaddr addr,
+ uint32_t len, DmaCtrlNotify *notify,
+ bool start_dma)
+{
+XlnxCSUDMA *s = XLNX_CSU_DMA(dma_ctrl);
+RegisterInfo *reg = &s->regs_info[R_SIZE];
+uint64_t we = MAKE_64BIT_MASK(0, 4 * 8);
+
+s->regs[R_ADDR] = addr;
+s->regs[R_ADDR_MSB] = (uint64_t)addr >> 32;
+
+if (notify) {
+s->dma_ctrl_notify = notify->cb;
+s->dma_ctrl_opaque = notify->opaque;
+}
+
+if (start_dma) {
+register_write(reg, len, we, object_get_typename(OBJECT(s)), false);
+} else {
+s->regs[R_SIZE] = len;
+}
+}
+
 static const RegisterAccessInfo *xlnx_csu_dma_regs_info[] = {
 #define DMACH_REGINFO(NAME, snd)  \
 (const RegisterAccessInfo []) {   \
@@ -696,6 +724,7 @@ static void xlnx_csu_dma_class_init(ObjectClass *klass, 
void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
 StreamSinkClass *ssc = STREAM_SINK_CLASS(klass);
+DmaCtrlClass *dcc = DMA_CTRL_CLASS(klass);
 
 dc->reset = xlnx_csu_dma_reset;
 dc->realize = xlnx_csu_dma_realize;
@@ -704,6 +733,8 @@ static void xlnx_csu_dma_class_init(ObjectClass *klass, 
void *data)
 
 ssc->push = xlnx_csu_dma_stream_push;
 ssc->can_push = xlnx_csu_dma_stream_can_push;
+
+dcc->read = xlnx_csu_dma_dma_ctrl_read;
 }
 
 static void xlnx_csu_dma_init(Object *obj)
@@ -731,6 +762,7 @@ static const TypeInfo xlnx_csu_dma_info = {
 .instance_init = xlnx_csu_dma_init,
 .interfaces = (InterfaceInfo[]) {
 { TYPE_STREAM_SINK },
+{ TYPE_DMA_CTRL },
 { }
 }
 };
diff --git a/include/hw/dma/xlnx_csu_dma.h b/include/hw/dma/xlnx_csu_dma.h
index 28806628b1..18cb45a024 100644
--- a/include/hw/dma/xlnx_csu_dma.h
+++ b/include/hw/dma/xlnx_csu_dma.h
@@ -25,6 +25,7 @@
 #include "hw/register.h"
 #include "hw/ptimer.h"
 #include "hw/stream.h"
+#include "hw/dma/dma-ctrl.h"
 
 #define TYPE_XLNX_CSU_DMA "xlnx.csu_dma"
 
@@ -47,6 +48,9 @@ typedef struct XlnxCSUDMA {
 StreamCanPushNotifyFn notify;
 void *notify_opaque;
 
+dmactrl_notify_fn dma_ctrl_notify;
+void *dma_ctrl_opaque;
+
 uint32_t regs[XLNX_CSU_DMA_R_MAX];
 RegisterInfo regs_info[XLNX_CSU_DMA_R_MAX];
 } XlnxCSUDMA;
-- 
2.11.0




[PATCH v3 03/10] include/hw/dma/xlnx_csu_dma: Add in missing includes in the header

2021-11-24 Thread Francisco Iglesias
Add in the missing includes in the header for being able to build the DMA
model when reusing it.

Signed-off-by: Francisco Iglesias 
---
 include/hw/dma/xlnx_csu_dma.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/include/hw/dma/xlnx_csu_dma.h b/include/hw/dma/xlnx_csu_dma.h
index 9e9dc551e9..28806628b1 100644
--- a/include/hw/dma/xlnx_csu_dma.h
+++ b/include/hw/dma/xlnx_csu_dma.h
@@ -21,6 +21,11 @@
 #ifndef XLNX_CSU_DMA_H
 #define XLNX_CSU_DMA_H
 
+#include "hw/sysbus.h"
+#include "hw/register.h"
+#include "hw/ptimer.h"
+#include "hw/stream.h"
+
 #define TYPE_XLNX_CSU_DMA "xlnx.csu_dma"
 
 #define XLNX_CSU_DMA_R_MAX (0x2c / 4)
-- 
2.11.0




[PATCH v3 07/10] hw/arm/xlnx-versal: Connect the OSPI flash memory controller model

2021-11-24 Thread Francisco Iglesias
Connect the OSPI flash memory controller model (including the source and
destination DMA).

Signed-off-by: Francisco Iglesias 
Reviewed-by: Edgar E. Iglesias 
---
 hw/arm/xlnx-versal.c | 87 
 include/hw/arm/xlnx-versal.h | 20 ++
 2 files changed, 107 insertions(+)

diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
index 08e250945f..20c82bff01 100644
--- a/hw/arm/xlnx-versal.c
+++ b/hw/arm/xlnx-versal.c
@@ -24,6 +24,7 @@
 
 #define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
 #define GEM_REVISION0x40070106
+#define NUM_OSPI_IRQ_LINES 3
 
 static void versal_create_apu_cpus(Versal *s)
 {
@@ -385,6 +386,91 @@ static void versal_create_pmc_iou_slcr(Versal *s, qemu_irq 
*pic)
 sysbus_connect_irq(sbd, 0, pic[VERSAL_PMC_IOU_SLCR_IRQ]);
 }
 
+static void versal_create_ospi(Versal *s, qemu_irq *pic)
+{
+SysBusDevice *sbd;
+MemoryRegion *mr_dac;
+
+memory_region_init(&s->pmc.iou.ospi.linear_mr, OBJECT(s),
+   "versal-ospi-linear-mr" , MM_PMC_OSPI_DAC_SIZE);
+
+object_initialize_child(OBJECT(s), "versal-ospi", &s->pmc.iou.ospi.ospi,
+TYPE_XILINX_VERSAL_OSPI);
+
+mr_dac = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi), 1);
+memory_region_add_subregion(&s->pmc.iou.ospi.linear_mr, 0x0, mr_dac);
+
+/* Create the OSPI destination DMA */
+object_initialize_child(OBJECT(s), "versal-ospi-dma-dst",
+&s->pmc.iou.ospi.dma_dst,
+TYPE_XLNX_CSU_DMA);
+
+object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_dst),
+"dma", OBJECT(get_system_memory()),
+ &error_abort);
+
+sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_dst);
+sysbus_realize(sbd, &error_fatal);
+
+memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DMA_DST,
+sysbus_mmio_get_region(sbd, 0));
+
+/* Create the OSPI source DMA */
+object_initialize_child(OBJECT(s), "versal-ospi-dma-src",
+&s->pmc.iou.ospi.dma_src,
+TYPE_XLNX_CSU_DMA);
+
+object_property_set_bool(OBJECT(&s->pmc.iou.ospi.dma_src), "is-dst",
+ false, &error_abort);
+
+object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_src),
+"dma", OBJECT(mr_dac), &error_abort);
+
+object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_src),
+"stream-connected-dma",
+ OBJECT(&s->pmc.iou.ospi.dma_dst),
+ &error_abort);
+
+sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_src);
+sysbus_realize(sbd, &error_fatal);
+
+memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DMA_SRC,
+sysbus_mmio_get_region(sbd, 0));
+
+/* Realize the OSPI */
+object_property_set_link(OBJECT(&s->pmc.iou.ospi.ospi), "dma-src",
+ OBJECT(&s->pmc.iou.ospi.dma_src), &error_abort);
+
+sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi);
+sysbus_realize(sbd, &error_fatal);
+
+memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI,
+sysbus_mmio_get_region(sbd, 0));
+
+memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DAC,
+&s->pmc.iou.ospi.linear_mr);
+
+/* ospi_mux_sel */
+qdev_connect_gpio_out(DEVICE(&s->pmc.iou.slcr), 3,
+  qdev_get_gpio_in(DEVICE(&s->pmc.iou.ospi.ospi), 0));
+
+/* OSPI irq */
+object_initialize_child(OBJECT(s), "ospi-irq",
+&s->pmc.iou.ospi.irq, TYPE_OR_IRQ);
+object_property_set_int(OBJECT(&s->pmc.iou.ospi.irq),
+"num-lines", NUM_OSPI_IRQ_LINES, &error_fatal);
+qdev_realize(DEVICE(&s->pmc.iou.ospi.irq), NULL, &error_fatal);
+
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi), 0,
+   qdev_get_gpio_in(DEVICE(&s->pmc.iou.ospi.irq), 0));
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_src), 0,
+   qdev_get_gpio_in(DEVICE(&s->pmc.iou.ospi.irq), 1));
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_dst), 0,
+   qdev_get_gpio_in(DEVICE(&s->pmc.iou.ospi.irq), 2));
+
+qdev_connect_gpio_out(DEVICE(&s->pmc.iou.ospi.irq), 0,
+  pic[VERSAL_OSPI_IRQ]);
+}
 
 /* This takes the board allocated linear DDR memory and creates aliases
  * for each split DDR range/ape

Re: [PATCH v2 03/10] include/hw/dma/xlnx_csu_dma: Include ptimer.h and stream.h in the header

2021-11-24 Thread Francisco Iglesias
Hi Philippe,

On [2021 Nov 23] Tue 11:45:45, Philippe Mathieu-Daudé wrote:
> On 11/23/21 11:34, Francisco Iglesias wrote:
> > Include ptimer.h and stream.h in the header for being able to build and
> > reuse the DMA model (the first usage of StreamSink, StreamCanPushNotifyFn
> > and ptimer_state is in the header).
> > 
> > Signed-off-by: Francisco Iglesias 
> > ---
> >  include/hw/dma/xlnx_csu_dma.h | 3 +++
> >  1 file changed, 3 insertions(+)
> > 
> > diff --git a/include/hw/dma/xlnx_csu_dma.h b/include/hw/dma/xlnx_csu_dma.h
> > index 9e9dc551e9..8c39e46f58 100644
> > --- a/include/hw/dma/xlnx_csu_dma.h
> > +++ b/include/hw/dma/xlnx_csu_dma.h
> > @@ -21,6 +21,9 @@
> >  #ifndef XLNX_CSU_DMA_H
> >  #define XLNX_CSU_DMA_H
> >  
> > +#include "hw/ptimer.h"
> 
> Yes, but arguably ptimer_state should be forward
> declared in "include/qemu/typedefs.h" IMO.
> 
> > +#include "hw/stream.h"
> 
> OK but you forgot these:

Thank you for reviewing! I updated and added in to also include sysbus.h and
register.h from the list below in v3! (memory.h looks to be included through
sysbus.h and memattrs.h through memory.h)

Best regards,
Francisco Iglesias

> 
> include/hw/sysbus.h (SysBusDevice)
> include/exec/memory.h (MemoryRegion)
> include/exec/memattrs.h (MemTxAttrs)
> include/exec/memory.h (AddressSpace)
> include/hw/register.h (RegisterInfo)
> 



[PATCH v3 00/10] Xilinx Versal's PMC SLCR and OSPI support

2021-11-24 Thread Francisco Iglesias
Hi,

This series attempts to add support for Xilinx Versal's PMC SLCR
(system-level control registers) and OSPI flash memory controller to
Xilinx Versal virt machine.

The series start with adding a model of Versal's PMC SLCR and connecting
the model to the Versal virt machine. The series then adds a couple of
headers into the xlnx_csu_dma.h needed for building and reusing it later
with the OSPI. The series thereafter introduces a DMA control interface
and implements the interface in the xlnx_csu_dma for being able to reuse
and control the DMA with the OSPI controller. Thereafter a model of
Versal's OSPI controller is added and connected to the Versal virt
machine. The series then ends with adding initial support for the Micron
Xccelera mt35xu01g flash and flashes of this type are connected to the
OSPI in the Versal virt machine.

Best regards,
Francisco Iglesias

Changelog:
v2 -> v3
  * Correct and also include hw/sysbus.h and hw/register.h into
xlnx_csu_dma.h (patch: "include/hw/dma/xlnx_csu_dma: Add in missing
includes in the header")

v1 -> v2
  * Correct the reset in the PMC SLCR model
  * Create a sub structure for the OSPI in the Versal structure (in patch:
"hw/arm/xlnx-versal: Connect the OSPI flash memory controller model")
  * Change to use 'drive_get' instead of 'drive_get_next' (in patch:
"hw/arm/xlnx-versal-virt: Connect mt35xu01g flashes to the OSPI")
  * Add a maintainers patch and list myself as maintainer for the OSPI
controller


Francisco Iglesias (10):
  hw/misc: Add a model of Versal's PMC SLCR
  hw/arm/xlnx-versal: Connect Versal's PMC SLCR
  include/hw/dma/xlnx_csu_dma: Add in missing includes in the header
  hw/dma: Add the DMA control interface
  hw/dma/xlnx_csu_dma: Implement the DMA control interface
  hw/ssi: Add a model of Xilinx Versal's OSPI flash memory controller
  hw/arm/xlnx-versal: Connect the OSPI flash memory controller model
  hw/block/m25p80: Add support for Micron Xccela flash mt35xu01g
  hw/arm/xlnx-versal-virt: Connect mt35xu01g flashes to the OSPI
  MAINTAINERS: Add an entry for Xilinx Versal OSPI

 MAINTAINERS|6 +
 hw/arm/xlnx-versal-virt.c  |   23 +
 hw/arm/xlnx-versal.c   |  105 ++
 hw/block/m25p80.c  |2 +
 hw/dma/dma-ctrl.c  |   31 +
 hw/dma/meson.build |1 +
 hw/dma/xlnx_csu_dma.c  |   32 +
 hw/misc/meson.build|5 +-
 hw/misc/xlnx-versal-pmc-iou-slcr.c | 1445 +
 hw/ssi/meson.build |1 +
 hw/ssi/xlnx-versal-ospi.c  | 1892 
 include/hw/arm/xlnx-versal.h   |   26 +
 include/hw/dma/dma-ctrl.h  |   74 ++
 include/hw/dma/xlnx_csu_dma.h  |9 +
 include/hw/misc/xlnx-versal-pmc-iou-slcr.h |   51 +
 include/hw/ssi/xlnx-versal-ospi.h  |   86 ++
 16 files changed, 3788 insertions(+), 1 deletion(-)
 create mode 100644 hw/dma/dma-ctrl.c
 create mode 100644 hw/misc/xlnx-versal-pmc-iou-slcr.c
 create mode 100644 hw/ssi/xlnx-versal-ospi.c
 create mode 100644 include/hw/dma/dma-ctrl.h
 create mode 100644 include/hw/misc/xlnx-versal-pmc-iou-slcr.h
 create mode 100644 include/hw/ssi/xlnx-versal-ospi.h

-- 
2.11.0




[PATCH v3 02/10] hw/arm/xlnx-versal: Connect Versal's PMC SLCR

2021-11-24 Thread Francisco Iglesias
Connect Versal's PMC SLCR (system-level control registers) model.

Signed-off-by: Francisco Iglesias 
Reviewed-by: Edgar E. Iglesias 
---
 hw/arm/xlnx-versal.c | 18 ++
 include/hw/arm/xlnx-versal.h |  6 ++
 2 files changed, 24 insertions(+)

diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
index b2705b6925..08e250945f 100644
--- a/hw/arm/xlnx-versal.c
+++ b/hw/arm/xlnx-versal.c
@@ -369,6 +369,23 @@ static void versal_create_efuse(Versal *s, qemu_irq *pic)
 sysbus_connect_irq(SYS_BUS_DEVICE(ctrl), 0, pic[VERSAL_EFUSE_IRQ]);
 }
 
+static void versal_create_pmc_iou_slcr(Versal *s, qemu_irq *pic)
+{
+SysBusDevice *sbd;
+
+object_initialize_child(OBJECT(s), "versal-pmc-iou-slcr", &s->pmc.iou.slcr,
+TYPE_XILINX_VERSAL_PMC_IOU_SLCR);
+
+sbd = SYS_BUS_DEVICE(&s->pmc.iou.slcr);
+sysbus_realize(sbd, &error_fatal);
+
+memory_region_add_subregion(&s->mr_ps, MM_PMC_PMC_IOU_SLCR,
+sysbus_mmio_get_region(sbd, 0));
+
+sysbus_connect_irq(sbd, 0, pic[VERSAL_PMC_IOU_SLCR_IRQ]);
+}
+
+
 /* This takes the board allocated linear DDR memory and creates aliases
  * for each split DDR range/aperture on the Versal address map.
  */
@@ -459,6 +476,7 @@ static void versal_realize(DeviceState *dev, Error **errp)
 versal_create_xrams(s, pic);
 versal_create_bbram(s, pic);
 versal_create_efuse(s, pic);
+versal_create_pmc_iou_slcr(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 895ba12c61..729c093dfc 100644
--- a/include/hw/arm/xlnx-versal.h
+++ b/include/hw/arm/xlnx-versal.h
@@ -26,6 +26,7 @@
 #include "hw/misc/xlnx-versal-xramc.h"
 #include "hw/nvram/xlnx-bbram.h"
 #include "hw/nvram/xlnx-versal-efuse.h"
+#include "hw/misc/xlnx-versal-pmc-iou-slcr.h"
 
 #define TYPE_XLNX_VERSAL "xlnx-versal"
 OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
@@ -78,6 +79,7 @@ struct Versal {
 struct {
 struct {
 SDHCIState sd[XLNX_VERSAL_NR_SDS];
+XlnxVersalPmcIouSlcr slcr;
 } iou;
 
 XlnxZynqMPRTC rtc;
@@ -113,6 +115,7 @@ struct Versal {
 #define VERSAL_XRAM_IRQ_0  79
 #define VERSAL_BBRAM_APB_IRQ_0 121
 #define VERSAL_RTC_APB_ERR_IRQ 121
+#define VERSAL_PMC_IOU_SLCR_IRQ121
 #define VERSAL_SD0_IRQ_0   126
 #define VERSAL_EFUSE_IRQ   139
 #define VERSAL_RTC_ALARM_IRQ   142
@@ -178,6 +181,9 @@ struct Versal {
 #define MM_FPD_FPD_APU  0xfd5c
 #define MM_FPD_FPD_APU_SIZE 0x100
 
+#define MM_PMC_PMC_IOU_SLCR 0xf106
+#define MM_PMC_PMC_IOU_SLCR_SIZE0x1
+
 #define MM_PMC_SD0  0xf104U
 #define MM_PMC_SD0_SIZE 0x1
 #define MM_PMC_BBRAM_CTRL   0xf11f
-- 
2.11.0




[PATCH v3 06/10] hw/ssi: Add a model of Xilinx Versal's OSPI flash memory controller

2021-11-24 Thread Francisco Iglesias
Add a model of Xilinx Versal's OSPI flash memory controller.

Signed-off-by: Francisco Iglesias 
Reviewed-by: Edgar E. Iglesias 
---
 hw/ssi/meson.build|1 +
 hw/ssi/xlnx-versal-ospi.c | 1892 +
 include/hw/ssi/xlnx-versal-ospi.h |   86 ++
 3 files changed, 1979 insertions(+)
 create mode 100644 hw/ssi/xlnx-versal-ospi.c
 create mode 100644 include/hw/ssi/xlnx-versal-ospi.h

diff --git a/hw/ssi/meson.build b/hw/ssi/meson.build
index 3d6bc82ab1..0ded9cd092 100644
--- a/hw/ssi/meson.build
+++ b/hw/ssi/meson.build
@@ -7,5 +7,6 @@ softmmu_ss.add(when: 'CONFIG_SSI', if_true: files('ssi.c'))
 softmmu_ss.add(when: 'CONFIG_STM32F2XX_SPI', if_true: files('stm32f2xx_spi.c'))
 softmmu_ss.add(when: 'CONFIG_XILINX_SPI', if_true: files('xilinx_spi.c'))
 softmmu_ss.add(when: 'CONFIG_XILINX_SPIPS', if_true: files('xilinx_spips.c'))
+softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: 
files('xlnx-versal-ospi.c'))
 softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('imx_spi.c'))
 softmmu_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_spi.c'))
diff --git a/hw/ssi/xlnx-versal-ospi.c b/hw/ssi/xlnx-versal-ospi.c
new file mode 100644
index 00..c02fc143de
--- /dev/null
+++ b/hw/ssi/xlnx-versal-ospi.c
@@ -0,0 +1,1892 @@
+/*
+ * QEMU model of Xilinx Versal's OSPI controller.
+ *
+ * Copyright (c) 2021 Xilinx Inc.
+ * Written by Francisco Iglesias 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "migration/vmstate.h"
+#include "hw/qdev-properties.h"
+#include "qemu/bitops.h"
+#include "qemu/log.h"
+#include "hw/irq.h"
+#include "hw/ssi/xlnx-versal-ospi.h"
+
+#ifndef XILINX_VERSAL_OSPI_ERR_DEBUG
+#define XILINX_VERSAL_OSPI_ERR_DEBUG 0
+#endif
+
+REG32(CONFIG_REG, 0x0)
+FIELD(CONFIG_REG, IDLE_FLD, 31, 1)
+FIELD(CONFIG_REG, DUAL_BYTE_OPCODE_EN_FLD, 30, 1)
+FIELD(CONFIG_REG, CRC_ENABLE_FLD, 29, 1)
+FIELD(CONFIG_REG, CONFIG_RESV2_FLD, 26, 3)
+FIELD(CONFIG_REG, PIPELINE_PHY_FLD, 25, 1)
+FIELD(CONFIG_REG, ENABLE_DTR_PROTOCOL_FLD, 24, 1)
+FIELD(CONFIG_REG, ENABLE_AHB_DECODER_FLD, 23, 1)
+FIELD(CONFIG_REG, MSTR_BAUD_DIV_FLD, 19, 4)
+FIELD(CONFIG_REG, ENTER_XIP_MODE_IMM_FLD, 18, 1)
+FIELD(CONFIG_REG, ENTER_XIP_MODE_FLD, 17, 1)
+FIELD(CONFIG_REG, ENB_AHB_ADDR_REMAP_FLD, 16, 1)
+FIELD(CONFIG_REG, ENB_DMA_IF_FLD, 15, 1)
+FIELD(CONFIG_REG, WR_PROT_FLASH_FLD, 14, 1)
+FIELD(CONFIG_REG, PERIPH_CS_LINES_FLD, 10, 4)
+FIELD(CONFIG_REG, PERIPH_SEL_DEC_FLD, 9, 1)
+FIELD(CONFIG_REG, ENB_LEGACY_IP_MODE_FLD, 8, 1)
+FIELD(CONFIG_REG, ENB_DIR_ACC_CTLR_FLD, 7, 1)
+FIELD(CONFIG_REG, RESET_CFG_FLD, 6, 1)
+FIELD(CONFIG_REG, RESET_PIN_FLD, 5, 1)
+FIELD(CONFIG_REG, HOLD_PIN_FLD, 4, 1)
+FIELD(CONFIG_REG, PHY_MODE_ENABLE_FLD, 3, 1)
+FIELD(CONFIG_REG, SEL_CLK_PHASE_FLD, 2, 1)
+FIELD(CONFIG_REG, SEL_CLK_POL_FLD, 1, 1)
+FIELD(CONFIG_REG, ENB_SPI_FLD, 0, 1)
+REG32(DEV_INSTR_RD_CONFIG_REG, 0x4)
+FIELD(DEV_INSTR_RD_CONFIG_REG, RD_INSTR_RESV5_FLD, 29, 3)
+FIELD(DEV_INSTR_RD_CONFIG_REG, DUMMY_RD_CLK_CYCLES_FLD, 24, 5)
+FIELD(DEV_INSTR_RD_CONFIG_REG, RD_INSTR_RESV4_FLD, 21, 3)
+FIELD(DEV_INSTR_RD_CONFIG_REG, MODE_BIT_ENABLE_FLD, 20, 1)
+FIELD(DEV_INSTR_RD_CONFIG_REG, RD_INSTR_RESV3_FLD, 18, 2)
+FIELD(DEV_INSTR_RD_CONFIG_REG, DATA_XFER_TYPE_EXT_MODE_FLD, 16, 2)
+FIELD(DEV_INSTR_RD_CONFIG_REG, RD_INSTR_RESV2_FLD, 14, 2)
+FIELD(DEV_INSTR_RD_CONFIG_REG, ADDR_XFER_TYPE_STD_MODE_FLD, 12, 2)
+FIELD(DEV_INSTR_RD_CONFIG_REG, PRED_DIS_FLD, 11, 1)
+FIELD(DEV_INSTR_RD_CONFIG_REG, DDR_EN_FLD, 10, 1)
+FIELD(DEV_INSTR_RD_CONFIG_REG, INS

[PATCH v3 10/10] MAINTAINERS: Add an entry for Xilinx Versal OSPI

2021-11-24 Thread Francisco Iglesias
List myself as maintainer for the Xilinx Versal OSPI controller.

Signed-off-by: Francisco Iglesias 
Reviewed-by: Edgar E. Iglesias 
---
 MAINTAINERS | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index d3879aa3c1..8c2b01a282 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -963,6 +963,12 @@ F: hw/display/dpcd.c
 F: include/hw/display/dpcd.h
 F: docs/system/arm/xlnx-versal-virt.rst
 
+Xilinx Versal OSPI
+M: Francisco Iglesias 
+S: Maintained
+F: hw/ssi/xlnx-versal-ospi.c
+F: include/hw/ssi/xlnx-versal-ospi.h
+
 ARM ACPI Subsystem
 M: Shannon Zhao 
 L: qemu-...@nongnu.org
-- 
2.11.0




[PATCH v3 09/10] hw/arm/xlnx-versal-virt: Connect mt35xu01g flashes to the OSPI

2021-11-24 Thread Francisco Iglesias
Connect Micron Xccela mt35xu01g flashes to the OSPI flash memory
controller.

Signed-off-by: Francisco Iglesias 
Reviewed-by: Edgar E. Iglesias 
---
 hw/arm/xlnx-versal-virt.c | 23 +++
 1 file changed, 23 insertions(+)

diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
index d2f55e29b6..47f5914e5d 100644
--- a/hw/arm/xlnx-versal-virt.c
+++ b/hw/arm/xlnx-versal-virt.c
@@ -25,6 +25,8 @@
 #define TYPE_XLNX_VERSAL_VIRT_MACHINE MACHINE_TYPE_NAME("xlnx-versal-virt")
 OBJECT_DECLARE_SIMPLE_TYPE(VersalVirt, XLNX_VERSAL_VIRT_MACHINE)
 
+#define XLNX_VERSAL_NUM_OSPI_FLASH 4
+
 struct VersalVirt {
 MachineState parent_obj;
 
@@ -690,6 +692,27 @@ static void versal_virt_init(MachineState *machine)
 exit(EXIT_FAILURE);
 }
 }
+
+for (i = 0; i < XLNX_VERSAL_NUM_OSPI_FLASH; i++) {
+BusState *spi_bus;
+DeviceState *flash_dev;
+qemu_irq cs_line;
+DriveInfo *dinfo = drive_get(IF_MTD, 0, i);
+
+spi_bus = qdev_get_child_bus(DEVICE(&s->soc.pmc.iou.ospi), "spi0");
+
+flash_dev = qdev_new("mt35xu01g");
+if (dinfo) {
+qdev_prop_set_drive_err(flash_dev, "drive",
+blk_by_legacy_dinfo(dinfo), &error_fatal);
+}
+qdev_realize_and_unref(flash_dev, spi_bus, &error_fatal);
+
+cs_line = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
+
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->soc.pmc.iou.ospi),
+   i + 1, cs_line);
+}
 }
 
 static void versal_virt_machine_instance_init(Object *obj)
-- 
2.11.0




Re: [PATCH 02/12] aspeed: Introduce a boot_rom region at the machine level

2023-05-08 Thread Francisco Iglesias
On [2023 May 08] Mon 09:58:49, Cédric Le Goater wrote:
> This should also avoid Coverity to report a memory leak warning when
> the QEMU process exits. See CID 1508061.
> 
> Signed-off-by: Cédric Le Goater 

Reviewed-by: Francisco Iglesias 

> ---
>  hw/arm/aspeed.c | 12 ++--
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> index 0b29028fe1..b654513f35 100644
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -40,6 +40,7 @@ struct AspeedMachineState {
>  /* Public */
>  
>  AspeedSoCState soc;
> +MemoryRegion boot_rom;
>  bool mmio_exec;
>  char *fmc_model;
>  char *spi_model;
> @@ -275,15 +276,15 @@ static void write_boot_rom(BlockBackend *blk, hwaddr 
> addr, size_t rom_size,
>   * Create a ROM and copy the flash contents at the expected address
>   * (0x0). Boots faster than execute-in-place.
>   */
> -static void aspeed_install_boot_rom(AspeedSoCState *soc, BlockBackend *blk,
> +static void aspeed_install_boot_rom(AspeedMachineState *bmc, BlockBackend 
> *blk,
>  uint64_t rom_size)
>  {
> -MemoryRegion *boot_rom = g_new(MemoryRegion, 1);
> +AspeedSoCState *soc = &bmc->soc;
>  
> -memory_region_init_rom(boot_rom, NULL, "aspeed.boot_rom", rom_size,
> +memory_region_init_rom(&bmc->boot_rom, NULL, "aspeed.boot_rom", rom_size,
> &error_abort);
>  memory_region_add_subregion_overlap(&soc->spi_boot_container, 0,
> -boot_rom, 1);
> +&bmc->boot_rom, 1);
>  write_boot_rom(blk, ASPEED_SOC_SPI_BOOT_ADDR, rom_size, &error_abort);
>  }
>  
> @@ -431,8 +432,7 @@ static void aspeed_machine_init(MachineState *machine)
>  
>  if (mtd0) {
>  uint64_t rom_size = memory_region_size(&bmc->soc.spi_boot);
> -aspeed_install_boot_rom(&bmc->soc, blk_by_legacy_dinfo(mtd0),
> -rom_size);
> +aspeed_install_boot_rom(bmc, blk_by_legacy_dinfo(mtd0), 
> rom_size);
>  }
>  }
>  
> -- 
> 2.40.0
> 
> 



Re: [PATCH 01/12] aspeed/hace: Initialize g_autofree pointer

2023-05-08 Thread Francisco Iglesias
On [2023 May 08] Mon 09:58:48, Cédric Le Goater wrote:
> As mentioned in docs/devel/style.rst "Automatic memory deallocation":
> 
> * Variables declared with g_auto* MUST always be initialized,
>   otherwise the cleanup function will use uninitialized stack memory
> 
> This avoids QEMU to coredump when running the "hash test" command
> under Zephyr.
> 
> Cc: Steven Lee 
> Cc: Joel Stanley 
> Fixes: c5475b3f9a ("hw: Model ASPEED's Hash and Crypto Engine")
> Reviewed-by: Alex Bennée 
> Reviewed-by: Thomas Huth 
> Message-Id: <20230421131547.2177449-1-...@kaod.org>
> Signed-off-by: Cédric Le Goater 

Reviewed-by: Francisco Iglesias 

> ---
>  hw/misc/aspeed_hace.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
> index 12a761f1f5..b07506ec04 100644
> --- a/hw/misc/aspeed_hace.c
> +++ b/hw/misc/aspeed_hace.c
> @@ -189,7 +189,7 @@ static void do_hash_operation(AspeedHACEState *s, int 
> algo, bool sg_mode,
>bool acc_mode)
>  {
>  struct iovec iov[ASPEED_HACE_MAX_SG];
> -g_autofree uint8_t *digest_buf;
> +g_autofree uint8_t *digest_buf = NULL;
>  size_t digest_len = 0;
>  int niov = 0;
>  int i;
> -- 
> 2.40.0
> 
> 



Re: [PATCH] hw/net: Move xilinx_ethlite.c to the target-independent source set

2023-05-08 Thread Francisco Iglesias
On [2023 May 08] Mon 14:03:14, Thomas Huth wrote:
> Now that the tswap() functions are available for target-independent
> code, too, we can move xilinx_ethlite.c from specific_ss to softmmu_ss
> to avoid that we have to compile this file multiple times.
> 
> Signed-off-by: Thomas Huth 

Reviewed-by: Francisco Iglesias 

> ---
>  hw/net/xilinx_ethlite.c | 2 +-
>  hw/net/meson.build  | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c
> index 99c22819ea..89f4f3b254 100644
> --- a/hw/net/xilinx_ethlite.c
> +++ b/hw/net/xilinx_ethlite.c
> @@ -25,7 +25,7 @@
>  #include "qemu/osdep.h"
>  #include "qemu/module.h"
>  #include "qom/object.h"
> -#include "cpu.h" /* FIXME should not use tswap* */
> +#include "exec/tswap.h"
>  #include "hw/sysbus.h"
>  #include "hw/irq.h"
>  #include "hw/qdev-properties.h"
> diff --git a/hw/net/meson.build b/hw/net/meson.build
> index e2be0654a1..a7860c5efe 100644
> --- a/hw/net/meson.build
> +++ b/hw/net/meson.build
> @@ -43,7 +43,7 @@ softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: 
> files('npcm7xx_emc.c'))
>  softmmu_ss.add(when: 'CONFIG_ETRAXFS', if_true: files('etraxfs_eth.c'))
>  softmmu_ss.add(when: 'CONFIG_COLDFIRE', if_true: files('mcf_fec.c'))
>  specific_ss.add(when: 'CONFIG_PSERIES', if_true: files('spapr_llan.c'))
> -specific_ss.add(when: 'CONFIG_XILINX_ETHLITE', if_true: 
> files('xilinx_ethlite.c'))
> +softmmu_ss.add(when: 'CONFIG_XILINX_ETHLITE', if_true: 
> files('xilinx_ethlite.c'))
>  
>  softmmu_ss.add(when: 'CONFIG_VIRTIO_NET', if_true: files('net_rx_pkt.c'))
>  specific_ss.add(when: 'CONFIG_VIRTIO_NET', if_true: files('virtio-net.c'))
> -- 
> 2.31.1
> 
> 



Re: [PATCH v4] hw: m25p80: add WP# pin and SRWD bit for write protection

2022-06-22 Thread Francisco Iglesias
On [2022 Jun 21] Tue 13:24:27, Iris Chen wrote:
> From: Iris Chen 
> 
> Signed-off-by: Iris Chen 

Reviewed-by: Francisco Iglesias 

> ---
> Fixed .needed for subsection and suggestions from Francisco 
> 
>  hw/block/m25p80.c | 82 ++-
>  1 file changed, 67 insertions(+), 15 deletions(-)
> 
> diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
> index 81ba3da4df..3045dda53b 100644
> --- a/hw/block/m25p80.c
> +++ b/hw/block/m25p80.c
> @@ -472,11 +472,13 @@ struct Flash {
>  uint8_t spansion_cr2v;
>  uint8_t spansion_cr3v;
>  uint8_t spansion_cr4v;
> +bool wp_level;
>  bool write_enable;
>  bool four_bytes_address_mode;
>  bool reset_enable;
>  bool quad_enable;
>  bool aai_enable;
> +bool status_register_write_disabled;
>  uint8_t ear;
>  
>  int64_t dirty_page;
> @@ -723,6 +725,8 @@ static void complete_collecting_data(Flash *s)
>  flash_erase(s, s->cur_addr, s->cmd_in_progress);
>  break;
>  case WRSR:
> +s->status_register_write_disabled = extract32(s->data[0], 7, 1);
> +
>  switch (get_man(s)) {
>  case MAN_SPANSION:
>  s->quad_enable = !!(s->data[1] & 0x02);
> @@ -1165,22 +1169,34 @@ static void decode_new_cmd(Flash *s, uint32_t value)
>  break;
>  
>  case WRSR:
> -if (s->write_enable) {
> -switch (get_man(s)) {
> -case MAN_SPANSION:
> -s->needed_bytes = 2;
> -s->state = STATE_COLLECTING_DATA;
> -break;
> -case MAN_MACRONIX:
> -s->needed_bytes = 2;
> -s->state = STATE_COLLECTING_VAR_LEN_DATA;
> -break;
> -default:
> -s->needed_bytes = 1;
> -s->state = STATE_COLLECTING_DATA;
> -}
> -s->pos = 0;
> +/*
> + * If WP# is low and status_register_write_disabled is high,
> + * status register writes are disabled.
> + * This is also called "hardware protected mode" (HPM). All other
> + * combinations of the two states are called "software protected 
> mode"
> + * (SPM), and status register writes are permitted.
> + */
> +if ((s->wp_level == 0 && s->status_register_write_disabled)
> +|| !s->write_enable) {
> +qemu_log_mask(LOG_GUEST_ERROR,
> +  "M25P80: Status register write is disabled!\n");
> +break;
> +}
> +
> +switch (get_man(s)) {
> +case MAN_SPANSION:
> +s->needed_bytes = 2;
> +s->state = STATE_COLLECTING_DATA;
> +break;
> +case MAN_MACRONIX:
> +s->needed_bytes = 2;
> +s->state = STATE_COLLECTING_VAR_LEN_DATA;
> +break;
> +default:
> +s->needed_bytes = 1;
> +s->state = STATE_COLLECTING_DATA;
>  }
> +s->pos = 0;
>  break;
>  
>  case WRDI:
> @@ -1195,6 +1211,8 @@ static void decode_new_cmd(Flash *s, uint32_t value)
>  
>  case RDSR:
>  s->data[0] = (!!s->write_enable) << 1;
> +s->data[0] |= (!!s->status_register_write_disabled) << 7;
> +
>  if (get_man(s) == MAN_MACRONIX || get_man(s) == MAN_ISSI) {
>  s->data[0] |= (!!s->quad_enable) << 6;
>  }
> @@ -1484,6 +1502,14 @@ static uint32_t m25p80_transfer8(SSIPeripheral *ss, 
> uint32_t tx)
>  return r;
>  }
>  
> +static void m25p80_write_protect_pin_irq_handler(void *opaque, int n, int 
> level)
> +{
> +Flash *s = M25P80(opaque);
> +/* WP# is just a single pin. */
> +assert(n == 0);
> +s->wp_level = !!level;
> +}
> +
>  static void m25p80_realize(SSIPeripheral *ss, Error **errp)
>  {
>  Flash *s = M25P80(ss);
> @@ -1515,12 +1541,18 @@ static void m25p80_realize(SSIPeripheral *ss, Error 
> **errp)
>  s->storage = blk_blockalign(NULL, s->size);
>  memset(s->storage, 0xFF, s->size);
>  }
> +
> +qdev_init_gpio_in_named(DEVICE(s),
> +m25p80_write_protect_pin_irq_handler, "WP#", 1);
>  }
>  
>  static void m25p80_reset(DeviceState *d)
>  {
>  Flash *s = M25P80(d);
>  
> +s->wp_level = true;
> +s->status_register_write_disabled = false;
> +
>  reset_memory(s);
>  }
>  
> @@ -1587,6 +1619,25 @@ static const VMSt

Re: [PATCH v4] hw: m25p80: add WP# pin and SRWD bit for write protection

2022-06-28 Thread Francisco Iglesias
On [2022 Jun 28] Tue 17:52:50, Cédric Le Goater wrote:
> Alistair, Francisco,
> 
> On 6/22/22 11:45, Francisco Iglesias wrote:
> > On [2022 Jun 21] Tue 13:24:27, Iris Chen wrote:
> > > From: Iris Chen 
> > > 
> > > Signed-off-by: Iris Chen 
> > 
> > Reviewed-by: Francisco Iglesias 
> 
> I am planning to include this patch in the next aspeed PR if that's
> OK with you.

Sounds good to me Cédric!

Best regards,
Francisco

> 
> Thanks,
> 
> C.
> 
> > 
> > > ---
> > > Fixed .needed for subsection and suggestions from Francisco
> > > 
> > >   hw/block/m25p80.c | 82 ++-
> > >   1 file changed, 67 insertions(+), 15 deletions(-)
> > > 
> > > diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
> > > index 81ba3da4df..3045dda53b 100644
> > > --- a/hw/block/m25p80.c
> > > +++ b/hw/block/m25p80.c
> > > @@ -472,11 +472,13 @@ struct Flash {
> > >   uint8_t spansion_cr2v;
> > >   uint8_t spansion_cr3v;
> > >   uint8_t spansion_cr4v;
> > > +bool wp_level;
> > >   bool write_enable;
> > >   bool four_bytes_address_mode;
> > >   bool reset_enable;
> > >   bool quad_enable;
> > >   bool aai_enable;
> > > +bool status_register_write_disabled;
> > >   uint8_t ear;
> > >   int64_t dirty_page;
> > > @@ -723,6 +725,8 @@ static void complete_collecting_data(Flash *s)
> > >   flash_erase(s, s->cur_addr, s->cmd_in_progress);
> > >   break;
> > >   case WRSR:
> > > +s->status_register_write_disabled = extract32(s->data[0], 7, 1);
> > > +
> > >   switch (get_man(s)) {
> > >   case MAN_SPANSION:
> > >   s->quad_enable = !!(s->data[1] & 0x02);
> > > @@ -1165,22 +1169,34 @@ static void decode_new_cmd(Flash *s, uint32_t 
> > > value)
> > >   break;
> > >   case WRSR:
> > > -if (s->write_enable) {
> > > -switch (get_man(s)) {
> > > -case MAN_SPANSION:
> > > -s->needed_bytes = 2;
> > > -s->state = STATE_COLLECTING_DATA;
> > > -break;
> > > -case MAN_MACRONIX:
> > > -s->needed_bytes = 2;
> > > -s->state = STATE_COLLECTING_VAR_LEN_DATA;
> > > -break;
> > > -default:
> > > -s->needed_bytes = 1;
> > > -s->state = STATE_COLLECTING_DATA;
> > > -}
> > > -s->pos = 0;
> > > +/*
> > > + * If WP# is low and status_register_write_disabled is high,
> > > + * status register writes are disabled.
> > > + * This is also called "hardware protected mode" (HPM). All other
> > > + * combinations of the two states are called "software protected 
> > > mode"
> > > + * (SPM), and status register writes are permitted.
> > > + */
> > > +if ((s->wp_level == 0 && s->status_register_write_disabled)
> > > +|| !s->write_enable) {
> > > +qemu_log_mask(LOG_GUEST_ERROR,
> > > +  "M25P80: Status register write is 
> > > disabled!\n");
> > > +break;
> > > +}
> > > +
> > > +switch (get_man(s)) {
> > > +case MAN_SPANSION:
> > > +s->needed_bytes = 2;
> > > +s->state = STATE_COLLECTING_DATA;
> > > +break;
> > > +case MAN_MACRONIX:
> > > +s->needed_bytes = 2;
> > > +s->state = STATE_COLLECTING_VAR_LEN_DATA;
> > > +break;
> > > +default:
> > > +s->needed_bytes = 1;
> > > +s->state = STATE_COLLECTING_DATA;
> > >   }
> > > +s->pos = 0;
> > >   break;
> > >   case WRDI:
> > > @@ -1195,6 +1211,8 @@ static void decode_new_cmd(Flash *s, uint32_t value)
> > >   case RDSR:
> > >   s->data[0] = (!!s->write_enable) << 1;
> > > +s->data[0] |= (!!s->status_register_write_disabled) << 7;
> > > +
> > >   if (get_m

Re: [PATCH 1/2] hw: m25p80: Add Block Protect and Top Bottom bits for write protect

2022-07-01 Thread Francisco Iglesias
SR_BP3_BIT6) {
> +s->block_protect3 = extract32(s->data[0], 6, 1);
> +}
>  
>  switch (get_man(s)) {
>  case MAN_SPANSION:
> @@ -1213,6 +1249,15 @@ static void decode_new_cmd(Flash *s, uint32_t value)
>  case RDSR:
>  s->data[0] = (!!s->write_enable) << 1;
>  s->data[0] |= (!!s->status_register_write_disabled) << 7;
> +s->data[0] |= (!!s->block_protect0) << 2;
> +s->data[0] |= (!!s->block_protect1) << 3;
> +s->data[0] |= (!!s->block_protect2) << 4;
> +if (s->pi->flags & SNOR_F_HAS_SR_TB) {
> +s->data[0] |= (!!s->top_bottom_bit) << 5;
> +}
> +if (s->pi->flags & SNOR_F_HAS_SR_BP3_BIT6) {
> +s->data[0] |= (!!s->block_protect3) << 6;
> +}
>  
>  if (get_man(s) == MAN_MACRONIX || get_man(s) == MAN_ISSI) {
>  s->data[0] |= (!!s->quad_enable) << 6;
> @@ -1553,6 +1598,11 @@ static void m25p80_reset(DeviceState *d)
>  
>  s->wp_level = true;
>  s->status_register_write_disabled = false;
> +s->block_protect0 = false;
> +s->block_protect1 = false;
> +s->block_protect2 = false;
> +s->block_protect3 = false;
> +s->top_bottom_bit = false;

We need to place above ones in a subsection in the vmstate (similar to the your
previous patch).

Looks good to me otherwise!

Thanks!
Best regards,
Francisco Iglesias

>  
>  reset_memory(s);
>  }
> -- 
> 2.30.2
> 
> 



Re: [PATCH 1/2] hw: m25p80: Add Block Protect and Top Bottom bits for write protect

2022-07-01 Thread Francisco Iglesias
On [2022 Jul 01] Fri 14:23:17, Cédric Le Goater wrote:
> On 7/1/22 13:40, Francisco Iglesias wrote:
> > Hi Iris,
> > 
> > Looks good, a couple of minor comments below!
> > 
> > On [2022 Jun 27] Mon 11:52:33, Iris Chen wrote:
> > > Signed-off-by: Iris Chen 
> > > ---
> > >   hw/block/m25p80.c | 74 +++
> > >   1 file changed, 62 insertions(+), 12 deletions(-)
> > > 
> > > diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
> > > index 50b523e5b1..0156a70f5e 100644
> > > --- a/hw/block/m25p80.c
> > > +++ b/hw/block/m25p80.c
> > > @@ -38,21 +38,19 @@
> > >   #include "trace.h"
> > >   #include "qom/object.h"
> > > -/* Fields for FlashPartInfo->flags */
> > > -
> > > -/* erase capabilities */
> > > -#define ER_4K 1
> > > -#define ER_32K 2
> > > -/* set to allow the page program command to write 0s back to 1. Useful 
> > > for
> > > - * modelling EEPROM with SPI flash command set
> > > - */
> > > -#define EEPROM 0x100
> > > -
> > >   /* 16 MiB max in 3 byte address mode */
> > >   #define MAX_3BYTES_SIZE 0x100
> > > -
> > >   #define SPI_NOR_MAX_ID_LEN 6
> > > +/* Fields for FlashPartInfo->flags */
> > > +enum spi_nor_option_flags {
> > 
> > (A suggestion is to s/nor/flash/ above (and s/SNOR_F_//  below) since there
> > looks to be nand flashes as W25N01GV using the protocol to).
> > 
> > > +ER_4K  = BIT(0),
> > > +ER_32K = BIT(1),
> > > +EEPROM = BIT(2),
> > > +SNOR_F_HAS_SR_TB   = BIT(3),
> > > +SNOR_F_HAS_SR_BP3_BIT6 = BIT(4),
> > > +};
> > > +
> > >   typedef struct FlashPartInfo {
> > >   const char *part_name;
> > >   /*
> > > @@ -253,7 +251,8 @@ static const FlashPartInfo known_devices[] = {
> > >   { INFO("n25q512a11",  0x20bb20,  0,  64 << 10, 1024, ER_4K) },
> > >   { INFO("n25q512a13",  0x20ba20,  0,  64 << 10, 1024, ER_4K) },
> > >   { INFO("n25q128", 0x20ba18,  0,  64 << 10, 256, 0) },
> > > -{ INFO("n25q256a",0x20ba19,  0,  64 << 10, 512, ER_4K) },
> > > +{ INFO("n25q256a",0x20ba19,  0,  64 << 10, 512,
> > > +   ER_4K | SNOR_F_HAS_SR_BP3_BIT6 | SNOR_F_HAS_SR_TB) },
> > >   { INFO("n25q512a",0x20ba20,  0,  64 << 10, 1024, ER_4K) },
> > >   { INFO("n25q512ax3",  0x20ba20,  0x1000,  64 << 10, 1024, ER_4K) },
> > >   { INFO("mt25ql512ab", 0x20ba20, 0x1044, 64 << 10, 1024, ER_4K | 
> > > ER_32K) },
> > > @@ -480,6 +479,11 @@ struct Flash {
> > >   bool reset_enable;
> > >   bool quad_enable;
> > >   bool aai_enable;
> > > +bool block_protect0;
> > > +bool block_protect1;
> > > +bool block_protect2;
> > > +bool block_protect3;
> > > +bool top_bottom_bit;
> > >   bool status_register_write_disabled;
> > >   uint8_t ear;
> > > @@ -630,6 +634,29 @@ void flash_write8(Flash *s, uint32_t addr, uint8_t 
> > > data)
> > >   qemu_log_mask(LOG_GUEST_ERROR, "M25P80: write with write 
> > > protect!\n");
> > >   return;
> > >   }
> > > +uint32_t block_protect_value = (s->block_protect3 << 3) |
> > > +   (s->block_protect2 << 2) |
> > > +   (s->block_protect1 << 1) |
> > > +   (s->block_protect0 << 0);
> > > +
> > > + uint32_t num_protected_sectors = 1 << (block_protect_value - 1);
> > > + uint32_t sector = addr / s->pi->sector_size;
> > > +
> > > + /* top_bottom_bit == 0 means TOP */
> > 
> > Indentation needs minor fixing on above lines, also the declarations should
> > be at the top of the function.
> 

Hi Cédric,

> I agree in that case it would be better to have at the top
> but checkpatch does not complain. What's the rule ?
> 

Below is taken from docs/devel/style.rst:

"
Declarations


Mixed declarations (interleaving statements and declarations within
blocks) are generally not allowed; declarations should be at the beginning
of blocks.

Every n

Re: [QEMU][PATCH v4 1/4] MAINTAINERS: Include canfd tests under Xilinx CAN

2023-04-25 Thread Francisco Iglesias
On [2023 Apr 24] Mon 23:34:30, Vikram Garhwal wrote:
> Signed-off-by: Vikram Garhwal 
> Reviewed-by: Peter Maydell 

Reviewed-by: Francisco Iglesias 

> ---
>  MAINTAINERS | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 24154f5721..c3dbacb615 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1809,7 +1809,7 @@ M: Francisco Iglesias 
>  S: Maintained
>  F: hw/net/can/xlnx-*
>  F: include/hw/net/xlnx-*
> -F: tests/qtest/xlnx-can-test*
> +F: tests/qtest/xlnx-can*-test*
>  
>  EDU
>  M: Jiri Slaby 
> -- 
> 2.17.1
> 



Re: [QEMU][PATCH v4 3/4] xlnx-versal: Connect Xilinx VERSAL CANFD controllers

2023-04-25 Thread Francisco Iglesias
 clocknames, sizeof(clocknames));


> +
> +qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
> +   GIC_FDT_IRQ_TYPE_SPI, irqs[i],
> +   GIC_FDT_IRQ_FLAGS_LEVEL_HI);
> +qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
> + 2, addrs[i], 2, size[i]);
> +qemu_fdt_setprop_string(s->fdt, name, "compatible",


> +"xlnx,versal-canfd");

And here we can swap above line with (kernel compatible):

"xlnx,canfd-2.0");

After changing above the linux kernel will find the devices:

...
[1.791998] CAN device driver interface
[1.732791] xilinx_can ff06.canfd can0: reg_base=0x(ptrval) 
irq=28 clock=2500, tx buffers: actual 32, using 1
[1.734668] xilinx_can ff07.canfd can1: reg_base=0x(ptrval) 
irq=29 clock=2500, tx buffers: actual 32, using 1
...

...
#  ip a
...
2: can0:  mtu 16 qdisc noop qlen 10
link/[280] 
3: can1:  mtu 16 qdisc noop qlen 10
link/[280] 
...

Looks good otherwise!

Best regards,
Francisco Iglesias


> +
> +g_free(name);
> +}
> +}
> +
>  static void fdt_add_fixed_link_nodes(VersalVirt *s, char *gemname,
>   uint32_t phandle)
>  {
> @@ -639,12 +668,17 @@ static void versal_virt_init(MachineState *machine)
>  TYPE_XLNX_VERSAL);
>  object_property_set_link(OBJECT(&s->soc), "ddr", OBJECT(machine->ram),
>   &error_abort);
> +object_property_set_link(OBJECT(&s->soc), "canbus0", 
> OBJECT(s->canbus[0]),
> + &error_abort);
> +object_property_set_link(OBJECT(&s->soc), "canbus1", 
> OBJECT(s->canbus[1]),
> + &error_abort);
>  sysbus_realize(SYS_BUS_DEVICE(&s->soc), &error_fatal);
>  
>  fdt_create(s);
>  create_virtio_regions(s);
>  fdt_add_gem_nodes(s);
>  fdt_add_uart_nodes(s);
> +fdt_add_canfd_nodes(s);
>  fdt_add_gic_nodes(s);
>  fdt_add_timer_nodes(s);
>  fdt_add_zdma_nodes(s);
> @@ -712,6 +746,20 @@ static void versal_virt_init(MachineState *machine)
>  
>  static void versal_virt_machine_instance_init(Object *obj)
>  {
> +VersalVirt *s = XLNX_VERSAL_VIRT_MACHINE(obj);
> +
> +/*
> + * User can set canbus0 and canbus1 properties to can-bus object and 
> connect
> + * to socketcan(optional) interface via command line.
> + */
> +object_property_add_link(obj, "canbus0", TYPE_CAN_BUS,
> + (Object **)&s->canbus[0],
> + object_property_allow_set_link,
> + 0);
> +object_property_add_link(obj, "canbus1", TYPE_CAN_BUS,
> + (Object **)&s->canbus[1],
> + object_property_allow_set_link,
> + 0);
>  }
>  
>  static void versal_virt_machine_class_init(ObjectClass *oc, void *data)
> diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
> index 69b1b99e93..1594dd6c5c 100644
> --- a/hw/arm/xlnx-versal.c
> +++ b/hw/arm/xlnx-versal.c
> @@ -184,6 +184,38 @@ static void versal_create_uarts(Versal *s, qemu_irq *pic)
>  }
>  }
>  
> +static void versal_create_canfds(Versal *s, qemu_irq *pic)
> +{
> +int i;
> +uint32_t irqs[] = { VERSAL_CANFD0_IRQ_0, VERSAL_CANFD1_IRQ_0};
> +uint64_t addrs[] = { MM_CANFD0, MM_CANFD1 };
> +
> +for (i = 0; i < ARRAY_SIZE(s->lpd.iou.canfd); i++) {
> +char *name = g_strdup_printf("canfd%d", i);
> +SysBusDevice *sbd;
> +MemoryRegion *mr;
> +
> +object_initialize_child(OBJECT(s), name, &s->lpd.iou.canfd[i],
> +TYPE_XILINX_CANFD);
> +sbd = SYS_BUS_DEVICE(&s->lpd.iou.canfd[i]);
> +
> +object_property_set_int(OBJECT(&s->lpd.iou.canfd[i]), "ext_clk_freq",
> +XLNX_VERSAL_CANFD_REF_CLK , &error_abort);
> +
> +object_property_set_link(OBJECT(&s->lpd.iou.canfd[i]), "canfdbus",
> + OBJECT(s->lpd.iou.canbus[i]),
> + &error_abort);
> +
> +sysbus_realize(sbd, &error_fatal);
> +
> +mr = sysbus_mmio_get_region(sbd, 0);
> +memory_region_add_subregion(&s->mr_ps, addrs[i], mr);
> +
> +sysbus_connect_irq(sbd, 0, pic[irqs[i]]);
> +g_fre

Re: [PATCH] hw/nvram: Avoid unnecessary Xilinx eFuse backstore write

2023-04-26 Thread Francisco Iglesias
On [2023 Apr 26] Wed 14:16:07, Tong Ho wrote:
> Add a check in the bit-set operation to write the backstore
> only if the affected bit is 0 before.
> 
> With this in place, there will be no need for callers to
> do the checking in order to avoid unnecessary writes.
> 
> Signed-off-by: Tong Ho 

Reviewed-by: Francisco Iglesias 

> ---
>  hw/nvram/xlnx-efuse.c | 11 +--
>  1 file changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/nvram/xlnx-efuse.c b/hw/nvram/xlnx-efuse.c
> index fdfffaab99..655c40b8d1 100644
> --- a/hw/nvram/xlnx-efuse.c
> +++ b/hw/nvram/xlnx-efuse.c
> @@ -143,6 +143,8 @@ static bool efuse_ro_bits_find(XlnxEFuse *s, uint32_t k)
>  
>  bool xlnx_efuse_set_bit(XlnxEFuse *s, unsigned int bit)
>  {
> +uint32_t set, *row;
> +
>  if (efuse_ro_bits_find(s, bit)) {
>  g_autofree char *path = object_get_canonical_path(OBJECT(s));
>  
> @@ -152,8 +154,13 @@ bool xlnx_efuse_set_bit(XlnxEFuse *s, unsigned int bit)
>  return false;
>  }
>  
> -s->fuse32[bit / 32] |= 1 << (bit % 32);
> -efuse_bdrv_sync(s, bit);
> +/* Avoid back-end write unless there is a real update */
> +row = &s->fuse32[bit / 32];
> +set = 1 << (bit % 32);
> +if (!(set & *row)) {
> +*row |= set;
> +efuse_bdrv_sync(s, bit);
> +}
>  return true;
>  }
>  
> -- 
> 2.25.1
> 



Re: [QEMU][PATCH v4 2/4] hw/net/can: Introduce Xilinx Versal CANFD controller

2023-05-02 Thread Francisco Iglesias
Hi Vikram,

A few comments below and some suggestions!


On [2023 Apr 24] Mon 23:34:31, Vikram Garhwal wrote:
> The Xilinx Versal CANFD controller is developed based on SocketCAN, QEMU CAN 
> bus
> implementation. Bus connection and socketCAN connection for each CAN module
> can be set through command lines.
> 
> Signed-off-by: Vikram Garhwal 
> ---
>  hw/net/can/meson.build |1 +
>  hw/net/can/trace-events|7 +
>  hw/net/can/xlnx-versal-canfd.c | 2115 
>  include/hw/net/xlnx-versal-canfd.h |   87 ++
>  4 files changed, 2210 insertions(+)
>  create mode 100644 hw/net/can/xlnx-versal-canfd.c
>  create mode 100644 include/hw/net/xlnx-versal-canfd.h
> 
> diff --git a/hw/net/can/meson.build b/hw/net/can/meson.build
> index 8fabbd9ee6..8d85201cb0 100644
> --- a/hw/net/can/meson.build
> +++ b/hw/net/can/meson.build
> @@ -5,3 +5,4 @@ softmmu_ss.add(when: 'CONFIG_CAN_PCI', if_true: 
> files('can_mioe3680_pci.c'))
>  softmmu_ss.add(when: 'CONFIG_CAN_CTUCANFD', if_true: files('ctucan_core.c'))
>  softmmu_ss.add(when: 'CONFIG_CAN_CTUCANFD_PCI', if_true: 
> files('ctucan_pci.c'))
>  softmmu_ss.add(when: 'CONFIG_XLNX_ZYNQMP', if_true: 
> files('xlnx-zynqmp-can.c'))
> +softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: 
> files('xlnx-versal-canfd.c'))
> diff --git a/hw/net/can/trace-events b/hw/net/can/trace-events
> index 8346a98ab5..de64ac1b31 100644
> --- a/hw/net/can/trace-events
> +++ b/hw/net/can/trace-events
> @@ -7,3 +7,10 @@ xlnx_can_filter_mask_pre_write(uint8_t filter_num, uint32_t 
> value) "Filter%d MAS
>  xlnx_can_tx_data(uint32_t id, uint8_t dlc, uint8_t db0, uint8_t db1, uint8_t 
> db2, uint8_t db3, uint8_t db4, uint8_t db5, uint8_t db6, uint8_t db7) "Frame: 
> ID: 0x%08x DLC: 0x%02x DATA: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 
> 0x%02x"
>  xlnx_can_rx_data(uint32_t id, uint32_t dlc, uint8_t db0, uint8_t db1, 
> uint8_t db2, uint8_t db3, uint8_t db4, uint8_t db5, uint8_t db6, uint8_t db7) 
> "Frame: ID: 0x%08x DLC: 0x%02x DATA: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 
> 0x%02x 0x%02x 0x%02x"
>  xlnx_can_rx_discard(uint32_t status) "Controller is not enabled for bus 
> communication. Status Register: 0x%08x"
> +
> +# xlnx-versal-canfd.c
> +xlnx_canfd_update_irq(char *path, uint32_t isr, uint32_t ier, uint32_t irq) 
> "%s: ISR: 0x%08x IER: 0x%08x IRQ: 0x%08x"
> +xlnx_canfd_rx_fifo_filter_reject(char *path, uint32_t id, uint8_t dlc) "%s: 
> Frame: ID: 0x%08x DLC: 0x%02x"
> +xlnx_canfd_rx_data(char *path, uint32_t id, uint8_t dlc, uint8_t flags) "%s: 
> Frame: ID: 0x%08x DLC: 0x%02x CANFD Flag: 0x%02x"
> +xlnx_canfd_tx_data(char *path, uint32_t id, uint8_t dlc, uint8_t flgas) "%s: 
> Frame: ID: 0x%08x DLC: 0x%02x CANFD Flag: 0x%02x"
> +xlnx_canfd_reset(char *path, uint32_t val) "%s: Resetting controller with 
> value = 0x%08x"
> diff --git a/hw/net/can/xlnx-versal-canfd.c b/hw/net/can/xlnx-versal-canfd.c
> new file mode 100644
> index 00..fb6fa54698
> --- /dev/null
> +++ b/hw/net/can/xlnx-versal-canfd.c
> @@ -0,0 +1,2115 @@
> +/*
> + * QEMU model of the Xilinx Versal CANFD device.
> + *
> + * This implementation is based on the following datasheet:
> + * https://docs.xilinx.com/v/u/2.0-English/pg223-canfd
> + *
> + * Copyright (c) 2022 AMD Inc.
> + *
> + * Written-by: Vikram Garhwal 
> + *
> + * Based on QEMU CANFD Device emulation implemented by Jin Yang, Deniz Eren 
> and
> + * Pavel Pisa
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a 
> copy
> + * of this software and associated documentation files (the "Software"), to 
> deal
> + * in the Software without restriction, including without limitation the 
> rights
> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> + * copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
> FROM,
> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> + * THE SOFTWARE.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/sysbus.h"
> +#include "hw/irq.h"
> +#include "hw/register.h"
> +#include "qapi/error.h"
> +#include "qemu/bitops.h"
> +#include "qemu/log.h"
> +#include "qemu/cutils.h"
> +#include "qemu/event_notifier.h"
> +#include "hw/qdev-properties.h"
> +#include "qom/object_interfaces.h"
> +#include "migration/vmstate.h"
> +#include "hw/net/xlnx-versal-canfd.h"
> +#include "trace.h"
> 

Re: [PATCH 01/12] util/fifo8: Fix typo in fifo8_push_all() description

2023-05-22 Thread Francisco Iglesias
On [2023 May 22] Mon 17:31:33, Philippe Mathieu-Daudé wrote:
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Francisco Iglesias 

> ---
>  include/qemu/fifo8.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/include/qemu/fifo8.h b/include/qemu/fifo8.h
> index 28bf2cee57..16be02f361 100644
> --- a/include/qemu/fifo8.h
> +++ b/include/qemu/fifo8.h
> @@ -46,7 +46,7 @@ void fifo8_push(Fifo8 *fifo, uint8_t data);
>   * fifo8_push_all:
>   * @fifo: FIFO to push to
>   * @data: data to push
> - * @size: number of bytes to push
> + * @num: number of bytes to push
>   *
>   * Push a byte array to the FIFO. Behaviour is undefined if the FIFO is full.
>   * Clients are responsible for checking the space left in the FIFO using
> -- 
> 2.38.1
> 
> 



Re: [PATCH 02/12] util/fifo8: Allow fifo8_pop_buf() to not populate popped length

2023-05-22 Thread Francisco Iglesias
On [2023 May 22] Mon 17:31:34, Philippe Mathieu-Daudé wrote:
> There might be cases where we know the number of bytes we can
> pop from the FIFO, or we simply don't care how many bytes is
> returned. Allow fifo8_pop_buf() to take a NULL numptr.
> 
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Francisco Iglesias 


> ---
>  include/qemu/fifo8.h | 10 +-
>  util/fifo8.c | 12 
>  2 files changed, 13 insertions(+), 9 deletions(-)
> 
> diff --git a/include/qemu/fifo8.h b/include/qemu/fifo8.h
> index 16be02f361..d0d02bc73d 100644
> --- a/include/qemu/fifo8.h
> +++ b/include/qemu/fifo8.h
> @@ -71,7 +71,7 @@ uint8_t fifo8_pop(Fifo8 *fifo);
>   * fifo8_pop_buf:
>   * @fifo: FIFO to pop from
>   * @max: maximum number of bytes to pop
> - * @num: actual number of returned bytes
> + * @numptr: pointer filled with number of bytes returned (can be NULL)
>   *
>   * Pop a number of elements from the FIFO up to a maximum of max. The buffer
>   * containing the popped data is returned. This buffer points directly into
> @@ -82,16 +82,16 @@ uint8_t fifo8_pop(Fifo8 *fifo);
>   * around in the ring buffer; in this case only a contiguous part of the data
>   * is returned.
>   *
> - * The number of valid bytes returned is populated in *num; will always 
> return
> - * at least 1 byte. max must not be 0 or greater than the number of bytes in
> - * the FIFO.
> + * The number of valid bytes returned is populated in *numptr; will always
> + * return at least 1 byte. max must not be 0 or greater than the number of
> + * bytes in the FIFO.
>   *
>   * Clients are responsible for checking the availability of requested data
>   * using fifo8_num_used().
>   *
>   * Returns: A pointer to popped data.
>   */
> -const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *num);
> +const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr);
>  
>  /**
>   * fifo8_reset:
> diff --git a/util/fifo8.c b/util/fifo8.c
> index d4d1c135e0..032e985440 100644
> --- a/util/fifo8.c
> +++ b/util/fifo8.c
> @@ -66,16 +66,20 @@ uint8_t fifo8_pop(Fifo8 *fifo)
>  return ret;
>  }
>  
> -const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *num)
> +const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr)
>  {
>  uint8_t *ret;
> +uint32_t num;
>  
>  assert(max > 0 && max <= fifo->num);
> -*num = MIN(fifo->capacity - fifo->head, max);
> +num = MIN(fifo->capacity - fifo->head, max);
>  ret = &fifo->data[fifo->head];
> -fifo->head += *num;
> +fifo->head += num;
>  fifo->head %= fifo->capacity;
> -fifo->num -= *num;
> +fifo->num -= num;
> +if (numptr) {
> +*numptr = num;
> +}
>  return ret;
>  }
>  
> -- 
> 2.38.1
> 
> 



Re: [PATCH 03/12] util/fifo8: Introduce fifo8_peek_buf()

2023-05-22 Thread Francisco Iglesias
On [2023 May 22] Mon 17:31:35, Philippe Mathieu-Daudé wrote:
> To be able to poke at FIFO content without popping it,
> introduce the fifo8_peek_buf() method by factoring
> common content from fifo8_pop_buf().
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  include/qemu/fifo8.h | 26 ++
>  util/fifo8.c | 22 ++
>  2 files changed, 44 insertions(+), 4 deletions(-)
> 
> diff --git a/include/qemu/fifo8.h b/include/qemu/fifo8.h
> index d0d02bc73d..7acf6d1347 100644
> --- a/include/qemu/fifo8.h
> +++ b/include/qemu/fifo8.h
> @@ -93,6 +93,32 @@ uint8_t fifo8_pop(Fifo8 *fifo);
>   */
>  const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr);
>  
> +/**
> + * fifo8_peek_buf:
> + * @fifo: FIFO to poke from
> + * @max: maximum number of bytes to pop
> + * @numptr: pointer filled with number of bytes returned (can be NULL)
> + *
> + * Pop a number of elements from the FIFO up to a maximum of max. The buffer

s/Pop/Peek into/

> + * containing the popped data is returned. This buffer points directly into

s/popped data/data peeked into/

If above sounds good:

Reviewed-by: Francisco Iglesias 


> + * the FIFO backing store and data is invalidated once any of the fifo8_* 
> APIs
> + * are called on the FIFO.

(Above sounds as if it happens automatically to me but I'm not english native,
a suggestion could be to put something as below "clients are responsible for
tracking this")

> + *
> + * The function may return fewer bytes than requested when the data wraps
> + * around in the ring buffer; in this case only a contiguous part of the data
> + * is returned.
> + *
> + * The number of valid bytes returned is populated in *numptr; will always
> + * return at least 1 byte. max must not be 0 or greater than the number of
> + * bytes in the FIFO.
> + *
> + * Clients are responsible for checking the availability of requested data
> + * using fifo8_num_used().
> + *
> + * Returns: A pointer to peekable data.
> + */
> +const uint8_t *fifo8_peek_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr);
> +
>  /**
>   * fifo8_reset:
>   * @fifo: FIFO to reset
> diff --git a/util/fifo8.c b/util/fifo8.c
> index 032e985440..e12477843e 100644
> --- a/util/fifo8.c
> +++ b/util/fifo8.c
> @@ -66,7 +66,8 @@ uint8_t fifo8_pop(Fifo8 *fifo)
>  return ret;
>  }
>  
> -const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr)
> +static const uint8_t *fifo8_peekpop_buf(Fifo8 *fifo, uint32_t max,
> +uint32_t *numptr, bool do_pop)
>  {
>  uint8_t *ret;
>  uint32_t num;
> @@ -74,15 +75,28 @@ const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, 
> uint32_t *numptr)
>  assert(max > 0 && max <= fifo->num);
>  num = MIN(fifo->capacity - fifo->head, max);
>  ret = &fifo->data[fifo->head];
> -fifo->head += num;
> -fifo->head %= fifo->capacity;
> -fifo->num -= num;
> +
> +if (do_pop) {
> +fifo->head += num;
> +fifo->head %= fifo->capacity;
> +fifo->num -= num;
> +}
>  if (numptr) {
>  *numptr = num;
>  }
>  return ret;
>  }
>  
> +const uint8_t *fifo8_peek_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr)
> +{
> +return fifo8_peekpop_buf(fifo, max, numptr, false);
> +}
> +
> +const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr)
> +{
> +return fifo8_peekpop_buf(fifo, max, numptr, true);
> +}
> +
>  void fifo8_reset(Fifo8 *fifo)
>  {
>  fifo->num = 0;
> -- 
> 2.38.1
> 
> 



Re: [QEMU][PATCH v5 3/4] xlnx-versal: Connect Xilinx VERSAL CANFD controllers

2023-05-22 Thread Francisco Iglesias
On [2023 May 19] Fri 13:36:57, Vikram Garhwal wrote:
> Connect CANFD0 and CANFD1 on the Versal-virt machine and update 
> xlnx-versal-virt
> document with CANFD command line examples.
> 
> Signed-off-by: Vikram Garhwal 
> Reviewed-by: Peter Maydell 

Reviewed-by: Francisco Iglesias 

> ---
>  docs/system/arm/xlnx-versal-virt.rst | 31 
>  hw/arm/xlnx-versal-virt.c| 53 
>  hw/arm/xlnx-versal.c | 37 +++
>  include/hw/arm/xlnx-versal.h | 12 +++
>  4 files changed, 133 insertions(+)
> 
> diff --git a/docs/system/arm/xlnx-versal-virt.rst 
> b/docs/system/arm/xlnx-versal-virt.rst
> index 92ad10d2da..d2d1b26692 100644
> --- a/docs/system/arm/xlnx-versal-virt.rst
> +++ b/docs/system/arm/xlnx-versal-virt.rst
> @@ -34,6 +34,7 @@ Implemented devices:
>  - DDR memory
>  - BBRAM (36 bytes of Battery-backed RAM)
>  - eFUSE (3072 bytes of one-time field-programmable bit array)
> +- 2 CANFDs
>  
>  QEMU does not yet model any other devices, including the PL and the AI 
> Engine.
>  
> @@ -224,3 +225,33 @@ To use a different index value, N, from default of 1, 
> add:
>  
>Better yet, do not use actual product data when running guest image
>on this Xilinx Versal Virt board.
> +
> +Using CANFDs for Versal Virt
> +""""""""""""""""""""""""""""
> +Versal CANFD controller is developed based on SocketCAN and QEMU CAN bus
> +implementation. Bus connection and socketCAN connection for each CAN module
> +can be set through command lines.
> +
> +To connect both CANFD0 and CANFD1 on the same bus:
> +
> +.. code-block:: bash
> +
> +-object can-bus,id=canbus -machine canbus0=canbus -machine canbus1=canbus
> +
> +To connect CANFD0 and CANFD1 to separate buses:
> +
> +.. code-block:: bash
> +
> +-object can-bus,id=canbus0 -object can-bus,id=canbus1 \
> +-machine canbus0=canbus0 -machine canbus1=canbus1
> +
> +The SocketCAN interface can connect to a Physical or a Virtual CAN 
> interfaces on
> +the host machine. Please check this document to learn about CAN interface on
> +Linux: docs/system/devices/can.rst
> +
> +To connect CANFD0 and CANFD1 to host machine's CAN interface can0:
> +
> +.. code-block:: bash
> +
> +-object can-bus,id=canbus -machine canbus0=canbus -machine canbus1=canbus
> +-object can-host-socketcan,id=canhost0,if=can0,canbus=canbus
> diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
> index 668a9d65a4..1ee2b8697f 100644
> --- a/hw/arm/xlnx-versal-virt.c
> +++ b/hw/arm/xlnx-versal-virt.c
> @@ -40,9 +40,11 @@ struct VersalVirt {
>  uint32_t clk_25Mhz;
>  uint32_t usb;
>  uint32_t dwc;
> +uint32_t canfd[2];
>  } phandle;
>  struct arm_boot_info binfo;
>  
> +CanBusState *canbus[XLNX_VERSAL_NR_CANFD];
>  struct {
>  bool secure;
>  } cfg;
> @@ -235,6 +237,38 @@ static void fdt_add_uart_nodes(VersalVirt *s)
>  }
>  }
>  
> +static void fdt_add_canfd_nodes(VersalVirt *s)
> +{
> +uint64_t addrs[] = { MM_CANFD1, MM_CANFD0 };
> +uint32_t size[] = { MM_CANFD1_SIZE, MM_CANFD0_SIZE };
> +unsigned int irqs[] = { VERSAL_CANFD1_IRQ_0, VERSAL_CANFD0_IRQ_0 };
> +const char clocknames[] = "can_clk\0s_axi_aclk";
> +int i;
> +
> +/* Create and connect CANFD0 and CANFD1 nodes to canbus0. */
> +for (i = 0; i < ARRAY_SIZE(addrs); i++) {
> +char *name = g_strdup_printf("/canfd@%" PRIx64, addrs[i]);
> +qemu_fdt_add_subnode(s->fdt, name);
> +
> +qemu_fdt_setprop_cell(s->fdt, name, "rx-fifo-depth", 0x40);
> +qemu_fdt_setprop_cell(s->fdt, name, "tx-mailbox-count", 0x20);
> +
> +qemu_fdt_setprop_cells(s->fdt, name, "clocks",
> +   s->phandle.clk_25Mhz, s->phandle.clk_25Mhz);
> +qemu_fdt_setprop(s->fdt, name, "clock-names",
> + clocknames, sizeof(clocknames));
> +qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
> +   GIC_FDT_IRQ_TYPE_SPI, irqs[i],
> +   GIC_FDT_IRQ_FLAGS_LEVEL_HI);
> +qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
> + 2, addrs[i], 2, size[i]);
> +qemu_fdt_setprop_string(s->fdt, name, "compatible",
> +"xlnx,canfd-2.0");
> +
> +g_free(name);
&

Re: [QEMU][PATCH v5 2/4] hw/net/can: Introduce Xilinx Versal CANFD controller

2023-05-24 Thread Francisco Iglesias
 *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
> FROM,
> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> + * THE SOFTWARE.
> + */
> +
> +#ifndef HW_CANFD_XILINX_H
> +#define HW_CANFD_XILINX_H
> +
> +#include "hw/register.h"
> +#include "hw/ptimer.h"
> +#include "net/can_emu.h"
> +#include "hw/qdev-clock.h"
> +
> +#define TYPE_XILINX_CANFD "xlnx.versal-canfd"
> +
> +OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalCANFDState, XILINX_CANFD)
> +
> +#define NUM_REGS_PER_MSG_SPACE 18 /* 1 ID + 1 DLC + 16 Data(DW0 - DW15) 
> regs. */
> +#define MAX_NUM_RX 64
> +#define OFFSET_RX1_DW15(0x4144 / 4)
> +#define CANFD_TIMER_MAX0xUL
> +#define CANFD_DEFAULT_CLOCK(24 * 1000 * 1000)

s/24/25/

With above changes:

Reviewed-by: Francisco Iglesias 

> +
> +#define XLNX_VERSAL_CANFD_R_MAX (OFFSET_RX1_DW15 + \
> +((MAX_NUM_RX - 1) * NUM_REGS_PER_MSG_SPACE) + 1)
> +
> +typedef struct XlnxVersalCANFDState {
> +SysBusDeviceparent_obj;
> +MemoryRegioniomem;
> +
> +qemu_irqirq_canfd_int;
> +qemu_irqirq_addr_err;
> +
> +RegisterInforeg_info[XLNX_VERSAL_CANFD_R_MAX];
> +RegisterAccessInfo  *tx_regs;
> +RegisterAccessInfo  *rx0_regs;
> +RegisterAccessInfo  *rx1_regs;
> +RegisterAccessInfo  *af_regs;
> +RegisterAccessInfo  *txe_regs;
> +RegisterAccessInfo  *rx_mailbox_regs;
> +RegisterAccessInfo  *af_mask_regs_mailbox;
> +
> +uint32_tregs[XLNX_VERSAL_CANFD_R_MAX];
> +
> +ptimer_state*canfd_timer;
> +
> +CanBusClientState   bus_client;
> +CanBusState *canfdbus;
> +
> +struct {
> +uint8_t rx0_fifo;
> +uint8_t rx1_fifo;
> +uint8_t tx_fifo;
> +boolenable_rx_fifo1;
> +uint32_text_clk_freq;
> +   } cfg;
> +
> +} XlnxVersalCANFDState;
> +
> +typedef struct tx_ready_reg_info {
> +uint32_t can_id;
> +uint32_t reg_num;
> +} tx_ready_reg_info;
> +
> +#endif
> -- 
> 2.17.1
> 



Re: [PATCH] hw/arm/xlnx-zynqmp: fix unsigned error when checking the RPUs number

2023-05-24 Thread Francisco Iglesias
On [2023 May 24] Wed 16:37:14, Clément Chigot wrote:
> When passing --smp with a number lower than XLNX_ZYNQMP_NUM_APU_CPUS,
> the expression (ms->smp.cpus - XLNX_ZYNQMP_NUM_APU_CPUS) will result
> in a positive number as ms->smp.cpus is a unsigned int.
> This will raise the following error afterwards, as Qemu will try to
> instantiate some additional RPUs.
>   | $ qemu-system-aarch64 --smp 1 -M xlnx-zcu102
>   | **
>   | ERROR:../src/tcg/tcg.c:777:tcg_register_thread:
>   |   assertion failed: (n < tcg_max_ctxs)
> 
> Signed-off-by: Clément Chigot 

Reviewed-by: Francisco Iglesias 
Tested-by: Francisco Iglesias 

> ---
>  hw/arm/xlnx-zynqmp.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
> index 335cfc417d..5905a33015 100644
> --- a/hw/arm/xlnx-zynqmp.c
> +++ b/hw/arm/xlnx-zynqmp.c
> @@ -213,7 +213,7 @@ static void xlnx_zynqmp_create_rpu(MachineState *ms, 
> XlnxZynqMPState *s,
> const char *boot_cpu, Error **errp)
>  {
>  int i;
> -int num_rpus = MIN(ms->smp.cpus - XLNX_ZYNQMP_NUM_APU_CPUS,
> +int num_rpus = MIN((int)(ms->smp.cpus - XLNX_ZYNQMP_NUM_APU_CPUS),
> XLNX_ZYNQMP_NUM_RPU_CPUS);
>  
>  if (num_rpus <= 0) {
> -- 
> 2.25.1
> 
> 



Re: [PATCH v2 10/10] contrib/gitdm: add group map for AMD

2023-03-13 Thread Francisco Iglesias




On 2023-03-10 19:03, Alex Bennée wrote:

AMD recently acquired Xilinx and contributors have been transitioning
their emails across.
 > Signed-off-by: Alex Bennée 


Reviewed-by: Francisco Iglesias 


Cc: Vikram Garhwal 
Cc: Francisco Iglesias 
Cc: Stefano Stabellini 
Cc: Sai Pavan Boddu 
Cc: Tong Ho 
---
  contrib/gitdm/domain-map| 1 -
  contrib/gitdm/group-map-amd | 8 
  gitdm.config| 1 +
  3 files changed, 9 insertions(+), 1 deletion(-)
  create mode 100644 contrib/gitdm/group-map-amd

diff --git a/contrib/gitdm/domain-map b/contrib/gitdm/domain-map
index ee0804b6ed..79fd65b077 100644
--- a/contrib/gitdm/domain-map
+++ b/contrib/gitdm/domain-map
@@ -50,6 +50,5 @@ virtuozzo.com   Virtuozzo
  vrull.euVRULL
  wdc.com Western Digital
  windriver.com   Wind River
-xilinx.com  Xilinx
  yadro.com   YADRO
  yandex-team.ru  Yandex
diff --git a/contrib/gitdm/group-map-amd b/contrib/gitdm/group-map-amd
new file mode 100644
index 00..bda4239a8a
--- /dev/null
+++ b/contrib/gitdm/group-map-amd
@@ -0,0 +1,8 @@
+# AMD acquired Xilinx and contributors have been slowly updating emails
+
+edgar.igles...@xilinx.com
+fnu.vik...@xilinx.com
+francisco.igles...@xilinx.com
+sai.pavan.bo...@xilinx.com
+stefano.stabell...@xilinx.com
+tong...@xilinx.com
diff --git a/gitdm.config b/gitdm.config
index 6908ddbd19..c9d961dd23 100644
--- a/gitdm.config
+++ b/gitdm.config
@@ -32,6 +32,7 @@ EmailMap contrib/gitdm/domain-map
  #
  
  GroupMap contrib/gitdm/group-map-alibaba Alibaba

+GroupMap contrib/gitdm/group-map-amd AMD
  GroupMap contrib/gitdm/group-map-cadence Cadence Design Systems
  GroupMap contrib/gitdm/group-map-codeweavers CodeWeavers
  GroupMap contrib/gitdm/group-map-facebook Facebook




Re: [PATCH 2/4] aspeed/smc: Dump address offset in trace events

2021-10-05 Thread Francisco Iglesias
On [2021 Oct 04] Mon 17:46:33, Cédric Le Goater wrote:
> The register index is currently printed and this is confusing.
> 
> Signed-off-by: Cédric Le Goater 

Reviewed-by: Francisco Iglesias 

> ---
>  hw/ssi/aspeed_smc.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
> index 7129341c129e..8a988c167604 100644
> --- a/hw/ssi/aspeed_smc.c
> +++ b/hw/ssi/aspeed_smc.c
> @@ -728,7 +728,7 @@ static uint64_t aspeed_smc_read(void *opaque, hwaddr 
> addr, unsigned int size)
>   addr < R_SEG_ADDR0 + asc->max_peripherals) ||
>  (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + asc->max_peripherals)) {
>  
> -trace_aspeed_smc_read(addr, size, s->regs[addr]);
> +trace_aspeed_smc_read(addr << 2, size, s->regs[addr]);
>  
>  return s->regs[addr];
>  } else {
> @@ -1029,10 +1029,10 @@ static void aspeed_smc_write(void *opaque, hwaddr 
> addr, uint64_t data,
>  AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
>  uint32_t value = data;
>  
> -addr >>= 2;
> -
>  trace_aspeed_smc_write(addr, size, data);
>  
> +addr >>= 2;
> +
>  if (addr == s->r_conf ||
>  (addr >= s->r_timings &&
>   addr < s->r_timings + asc->nregs_timings) ||
> -- 
> 2.31.1
> 
> 



Re: [PATCH 1/4] aspeed/wdt: Add trace events

2021-10-05 Thread Francisco Iglesias
On [2021 Oct 04] Mon 17:46:32, Cédric Le Goater wrote:
> Signed-off-by: Cédric Le Goater 

Reviewed-by: Francisco Iglesias 

> ---
>  hw/watchdog/wdt_aspeed.c | 5 +
>  hw/watchdog/trace-events | 4 
>  2 files changed, 9 insertions(+)
> 
> diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
> index 69c37af9a6e9..146ffcd71301 100644
> --- a/hw/watchdog/wdt_aspeed.c
> +++ b/hw/watchdog/wdt_aspeed.c
> @@ -19,6 +19,7 @@
>  #include "hw/sysbus.h"
>  #include "hw/watchdog/wdt_aspeed.h"
>  #include "migration/vmstate.h"
> +#include "trace.h"
>  
>  #define WDT_STATUS  (0x00 / 4)
>  #define WDT_RELOAD_VALUE(0x04 / 4)
> @@ -60,6 +61,8 @@ static uint64_t aspeed_wdt_read(void *opaque, hwaddr 
> offset, unsigned size)
>  {
>  AspeedWDTState *s = ASPEED_WDT(opaque);
>  
> +trace_aspeed_wdt_read(offset, size);
> +
>  offset >>= 2;
>  
>  switch (offset) {
> @@ -140,6 +143,8 @@ static void aspeed_wdt_write(void *opaque, hwaddr offset, 
> uint64_t data,
>  AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(s);
>  bool enable;
>  
> +trace_aspeed_wdt_write(offset, size, data);
> +
>  offset >>= 2;
>  
>  switch (offset) {
> diff --git a/hw/watchdog/trace-events b/hw/watchdog/trace-events
> index c3bafbffa911..e7523e22aaf2 100644
> --- a/hw/watchdog/trace-events
> +++ b/hw/watchdog/trace-events
> @@ -5,3 +5,7 @@ cmsdk_apb_watchdog_read(uint64_t offset, uint64_t data, 
> unsigned size) "CMSDK AP
>  cmsdk_apb_watchdog_write(uint64_t offset, uint64_t data, unsigned size) 
> "CMSDK APB watchdog write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
>  cmsdk_apb_watchdog_reset(void) "CMSDK APB watchdog: reset"
>  cmsdk_apb_watchdog_lock(uint32_t lock) "CMSDK APB watchdog: lock %" PRIu32
> +
> +# wdt-aspeed.c
> +aspeed_wdt_read(uint64_t addr, uint32_t size) "@0x%" PRIx64 " size=%d"
> +aspeed_wdt_write(uint64_t addr, uint32_t size, uint64_t data) "@0x%" PRIx64 
> " size=%d value=0x%"PRIx64
> -- 
> 2.31.1
> 
> 



Re: [PATCH v1 3/6] hw/misc: Add a model of the Xilinx ZynqMP CRF

2022-01-31 Thread Francisco Iglesias
= 0xfeffc0f8,
> +},{ .name = "DP_VIDEO_REF_CTRL",  .addr = A_DP_VIDEO_REF_CTRL,
> +.reset = 0x1002300,
> +.rsvd = 0xfec0c0f8,
> +},{ .name = "DP_AUDIO_REF_CTRL",  .addr = A_DP_AUDIO_REF_CTRL,
> +.reset = 0x1032300,
> +.rsvd = 0xfec0c0f8,
> +},{ .name = "DP_STC_REF_CTRL",  .addr = A_DP_STC_REF_CTRL,
> +.reset = 0x1203200,
> +.rsvd = 0xfec0c0f8,
> +},{ .name = "DDR_CTRL",  .addr = A_DDR_CTRL,
> +.reset = 0x1000500,
> +.rsvd = 0xfeffc0f8,
> +},{ .name = "GPU_REF_CTRL",  .addr = A_GPU_REF_CTRL,
> +.reset = 0x1500,
> +.rsvd = 0xf8ffc0f8,
> +},{ .name = "SATA_REF_CTRL",  .addr = A_SATA_REF_CTRL,
> +.reset = 0x1001600,
> +.rsvd = 0xfeffc0f8,
> +},{ .name = "PCIE_REF_CTRL",  .addr = A_PCIE_REF_CTRL,
> +.reset = 0x1500,
> +.rsvd = 0xfeffc0f8,
> +},{ .name = "GDMA_REF_CTRL",  .addr = A_GDMA_REF_CTRL,
> +.reset = 0x1000500,
> +.rsvd = 0xfeffc0f8,
> +},{ .name = "DPDMA_REF_CTRL",  .addr = A_DPDMA_REF_CTRL,
> +.reset = 0x1000500,
> +.rsvd = 0xfeffc0f8,
> +},{ .name = "TOPSW_MAIN_CTRL",  .addr = A_TOPSW_MAIN_CTRL,
> +.reset = 0x1000400,
> +.rsvd = 0xfeffc0f8,
> +},{ .name = "TOPSW_LSBUS_CTRL",  .addr = A_TOPSW_LSBUS_CTRL,
> +.reset = 0x1000800,
> +.rsvd = 0xfeffc0f8,
> +},{ .name = "DBG_TSTMP_CTRL",  .addr = A_DBG_TSTMP_CTRL,
> +.reset = 0xa00,
> +.rsvd = 0xc0f8,
> +},
> +{   .name = "RST_FPD_TOP",  .addr = A_RST_FPD_TOP,
> +.reset = 0xf9ffe,
> +.rsvd = 0xf06001,
> +},{ .name = "RST_FPD_APU",  .addr = A_RST_FPD_APU,
> +.reset = 0x3d0f,
> +.rsvd = 0xc2f0,
> +.pre_write = rst_fpd_apu_prew,
> +},{ .name = "RST_DDR_SS",  .addr = A_RST_DDR_SS,
> +.reset = 0xf,
> +.rsvd = 0xf3,
> +}
> +};
> +
> +static void crf_reset_enter(Object *obj, ResetType type)
> +{
> +XlnxZynqMPCRF *s = XILINX_CRF(obj);
> +unsigned int i;
> +
> +for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
> +register_reset(&s->regs_info[i]);
> +}
> +}
> +
> +static void crf_reset_hold(Object *obj)
> +{
> +XlnxZynqMPCRF *s = XILINX_CRF(obj);
> +ir_update_irq(s);
> +}
> +
> +static const MemoryRegionOps crf_ops = {
> +.read = register_read_memory,
> +.write = register_write_memory,
> +.endianness = DEVICE_LITTLE_ENDIAN,
> +.valid = {
> +.min_access_size = 4,
> +.max_access_size = 4,
> +},
> +};
> +
> +static void crf_init(Object *obj)
> +{
> +XlnxZynqMPCRF *s = XILINX_CRF(obj);
> +SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
> +
> +s->reg_array =
> +register_init_block32(DEVICE(obj), crf_regs_info,
> +  ARRAY_SIZE(crf_regs_info),
> +  s->regs_info, s->regs,
> +  &crf_ops,
> +  XILINX_CRF_ERR_DEBUG,
> +  CRF_R_MAX * 4);
> +sysbus_init_mmio(sbd, &s->reg_array->mem);
> +sysbus_init_irq(sbd, &s->irq_ir);
> +}
> +
> +static void crf_finalize(Object *obj)
> +{
> +XlnxZynqMPCRF *s = XILINX_CRF(obj);
> +register_finalize_block(s->reg_array);
> +}
> +
> +static const VMStateDescription vmstate_crf = {
> +.name = TYPE_XLNX_ZYNQMP_CRF,
> +.version_id = 1,
> +.minimum_version_id = 1,
> +.minimum_version_id_old = 1,
> +.fields = (VMStateField[]) {
> +VMSTATE_UINT32_ARRAY(regs, XlnxZynqMPCRF, CRF_R_MAX),
> +VMSTATE_END_OF_LIST(),
> +}
> +};
> +
> +static void crf_class_init(ObjectClass *klass, void *data)
> +{
> +ResettableClass *rc = RESETTABLE_CLASS(klass);
> +DeviceClass *dc = DEVICE_CLASS(klass);
> +
> +dc->vmsd = &vmstate_crf;
> +rc->phases.enter = crf_reset_enter;
> +rc->phases.hold = crf_reset_hold;
> +}
> +
> +static const TypeInfo crf_info = {
> +.name  = TYPE_XLNX_ZYNQMP_CRF,
> +.parent= TYPE_SYS_BUS_DEVICE,
> +.instance_size = sizeof(XlnxZynqMPCRF),
> +.class_init= crf_class_init,
> +.instance_init = crf_init,
> +.instance_finalize = crf_finalize,
> +.interfaces= (InterfaceInfo[]) {
> +{ }

We can remove above 'interfaces'. With above removed and include guards
added:

Reviewed-by: Francisco Iglesias 

Best regards,
Francisco Iglesias

> +},
> +};
> +
> +static void crf_register_types(void)
> +{
> +type_register_static(&crf_info);
> +}
> +
> +type_init(crf_register_types)
> diff --git a/hw/misc/meson.build b/hw/misc/meson.build
> index 6dcbe044f3..1927f13a5e 100644
> --- a/hw/misc/meson.build
> +++ b/hw/misc/meson.build
> @@ -84,6 +84,7 @@ softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files(
>  ))
>  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'))
>  softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files(
>'xlnx-versal-xramc.c',
>'xlnx-versal-pmc-iou-slcr.c',
> -- 
> 2.25.1
> 



Re: [PATCH v1 4/6] hw/arm/xlnx-zynqmp: Connect the ZynqMP CRF

2022-01-31 Thread Francisco Iglesias
On Mon, Jan 31, 2022 at 12:12:04AM +0100, Edgar E. Iglesias wrote:
> From: "Edgar E. Iglesias" 
> 
> Connect the ZynqMP CRF - Clock Reset FPD device.
> 
> Signed-off-by: Edgar E. Iglesias 

Reviewed-by: Francisco Iglesias 

> ---
>  include/hw/arm/xlnx-zynqmp.h |  2 ++
>  hw/arm/xlnx-zynqmp.c | 16 
>  2 files changed, 18 insertions(+)
> 
> diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
> index 99ceb8a609..d5a3ad3df2 100644
> --- a/include/hw/arm/xlnx-zynqmp.h
> +++ b/include/hw/arm/xlnx-zynqmp.h
> @@ -38,6 +38,7 @@
>  #include "hw/dma/xlnx_csu_dma.h"
>  #include "hw/nvram/xlnx-bbram.h"
>  #include "hw/nvram/xlnx-zynqmp-efuse.h"
> +#include "hw/misc/xlnx-zynqmp-crf.h"
>  
>  #define TYPE_XLNX_ZYNQMP "xlnx-zynqmp"
>  OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
> @@ -122,6 +123,7 @@ struct XlnxZynqMPState {
>  XlnxZDMA gdma[XLNX_ZYNQMP_NUM_GDMA_CH];
>  XlnxZDMA adma[XLNX_ZYNQMP_NUM_ADMA_CH];
>  XlnxCSUDMA qspi_dma;
> +XlnxZynqMPCRF crf;
>  
>  char *boot_cpu;
>  ARMCPU *boot_cpu_ptr;
> diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
> index ba44e95899..857d3c9636 100644
> --- a/hw/arm/xlnx-zynqmp.c
> +++ b/hw/arm/xlnx-zynqmp.c
> @@ -51,6 +51,9 @@
>  #define QSPI_IRQ15
>  #define QSPI_DMA_ADDR   0xff0f0800
>  
> +#define CRF_ADDR0xfd1a
> +#define CRF_IRQ 120
> +
>  #define SERDES_ADDR 0xfd40
>  #define SERDES_SIZE 0x2
>  
> @@ -279,6 +282,18 @@ static void xlnx_zynqmp_create_efuse(XlnxZynqMPState *s, 
> qemu_irq *gic)
>  sysbus_connect_irq(sbd, 0, gic[EFUSE_IRQ]);
>  }
>  
> +static void xlnx_zynqmp_create_crf(XlnxZynqMPState *s, qemu_irq *gic)
> +{
> +SysBusDevice *sbd;
> +
> +object_initialize_child(OBJECT(s), "crf", &s->crf, TYPE_XLNX_ZYNQMP_CRF);
> +sbd = SYS_BUS_DEVICE(&s->crf);
> +
> +sysbus_realize(sbd, &error_fatal);
> +sysbus_mmio_map(sbd, 0, CRF_ADDR);
> +sysbus_connect_irq(sbd, 0, gic[CRF_IRQ]);
> +}
> +
>  static void xlnx_zynqmp_create_unimp_mmio(XlnxZynqMPState *s)
>  {
>  static const struct UnimpInfo {
> @@ -682,6 +697,7 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error 
> **errp)
>  
>  xlnx_zynqmp_create_bbram(s, gic_spi);
>  xlnx_zynqmp_create_efuse(s, gic_spi);
> +xlnx_zynqmp_create_crf(s, gic_spi);
>  xlnx_zynqmp_create_unimp_mmio(s);
>  
>  for (i = 0; i < XLNX_ZYNQMP_NUM_GDMA_CH; i++) {
> -- 
> 2.25.1
> 



Re: [PATCH v1 5/6] hw/misc: Add a model of the Xilinx ZynqMP APU Control

2022-01-31 Thread Francisco Iglesias
 {
> +.read = register_read_memory,
> +.write = register_write_memory,
> +.endianness = DEVICE_LITTLE_ENDIAN,
> +.valid = {
> +.min_access_size = 4,
> +.max_access_size = 4,
> +}
> +};
> +
> +static void zynqmp_apu_handle_wfi(void *opaque, int irq, int level)
> +{
> +XlnxZynqMPAPUCtrl *s = XLNX_ZYNQMP_APU(opaque);
> +
> +s->cpu_in_wfi = deposit32(s->cpu_in_wfi, irq, 1, level);
> +update_wfi_out(s);
> +}
> +
> +static void zynqmp_apu_init(Object *obj)
> +{
> +XlnxZynqMPAPUCtrl *s = XLNX_ZYNQMP_APU(obj);
> +int i;
> +
> +s->reg_array =
> +register_init_block32(DEVICE(obj), zynqmp_apu_regs_info,
> +  ARRAY_SIZE(zynqmp_apu_regs_info),
> +  s->regs_info, s->regs,
> +  &zynqmp_apu_ops,
> +  XILINX_ZYNQMP_APU_ERR_DEBUG,
> +  APU_R_MAX * 4);
> +sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->reg_array->mem);
> +sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq_imr);
> +
> +for (i = 0; i < NUM_CPUS; ++i) {
> +g_autofree gchar *prop_name = g_strdup_printf("cpu%d", i);
> +object_property_add_link(obj, prop_name, TYPE_ARM_CPU,

Indentation needs a minor correction on the lines below.

> + (Object **)&s->cpus[i],
> + qdev_prop_allow_set_link_before_realize,
> + OBJ_PROP_LINK_STRONG);
> +}
> +
> +/* wfi_out is used to connect to PMU GPIs. */
> +qdev_init_gpio_out_named(DEVICE(obj), s->wfi_out, "wfi_out", 4);
> +/* CPU_POWER_STATUS is used to connect to INTC redirect. */
> +qdev_init_gpio_out_named(DEVICE(obj), s->cpu_power_status,
> + "CPU_POWER_STATUS", 4);
> +/* wfi_in is used as input from CPUs as wfi request. */
> +qdev_init_gpio_in_named(DEVICE(obj), zynqmp_apu_handle_wfi, "wfi_in", 4);
> +}
> +
> +static void zynqmp_apu_finalize(Object *obj)
> +{
> +XlnxZynqMPAPUCtrl *s = XLNX_ZYNQMP_APU(obj);
> +register_finalize_block(s->reg_array);
> +}
> +
> +static const VMStateDescription vmstate_zynqmp_apu = {
> +.name = TYPE_XLNX_ZYNQMP_APU_CTRL,
> +.version_id = 1,
> +.minimum_version_id = 1,
> +.minimum_version_id_old = 1,
> +.fields = (VMStateField[]) {
> +VMSTATE_UINT32_ARRAY(regs, XlnxZynqMPAPUCtrl, APU_R_MAX),
> +VMSTATE_END_OF_LIST(),
> +}
> +};
> +
> +static void zynqmp_apu_class_init(ObjectClass *klass, void *data)
> +{
> +ResettableClass *rc = RESETTABLE_CLASS(klass);
> +DeviceClass *dc = DEVICE_CLASS(klass);
> +
> +dc->vmsd = &vmstate_zynqmp_apu;
> +
> +rc->phases.enter = zynqmp_apu_reset_enter;
> +rc->phases.hold = zynqmp_apu_reset_hold;
> +}
> +
> +static const TypeInfo zynqmp_apu_info = {
> +.name  = TYPE_XLNX_ZYNQMP_APU_CTRL,
> +.parent= TYPE_SYS_BUS_DEVICE,
> +.instance_size = sizeof(XlnxZynqMPAPUCtrl),
> +.class_init= zynqmp_apu_class_init,
> +.instance_init = zynqmp_apu_init,
> +.instance_finalize = zynqmp_apu_finalize,
> +.interfaces= (InterfaceInfo[]) {
> +{ }

Interfaces can be removed above. 

Best regards,
Francisco Iglesias

> +},
> +};
> +
> +static void zynqmp_apu_register_types(void)
> +{
> +type_register_static(&zynqmp_apu_info);
> +}
> +
> +type_init(zynqmp_apu_register_types)
> diff --git a/hw/misc/meson.build b/hw/misc/meson.build
> index 1927f13a5e..cf9d4cc618 100644
> --- a/hw/misc/meson.build
> +++ b/hw/misc/meson.build
> @@ -85,6 +85,7 @@ softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files(
>  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'))
>  softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files(
>'xlnx-versal-xramc.c',
>'xlnx-versal-pmc-iou-slcr.c',
> -- 
> 2.25.1
> 



Re: [PATCH v1 1/6] hw/arm/xlnx-zynqmp: Add unimplemented SERDES area

2022-01-31 Thread Francisco Iglesias
On Mon, Jan 31, 2022 at 12:12:01AM +0100, Edgar E. Iglesias wrote:
> From: "Edgar E. Iglesias" 
> 
> Add unimplemented SERDES area.
> 
> Signed-off-by: Edgar E. Iglesias 

Reviewed-by: Francisco Iglesias 

> ---
>  include/hw/arm/xlnx-zynqmp.h | 2 +-
>  hw/arm/xlnx-zynqmp.c | 4 
>  2 files changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
> index 062e637fe4..99ceb8a609 100644
> --- a/include/hw/arm/xlnx-zynqmp.h
> +++ b/include/hw/arm/xlnx-zynqmp.h
> @@ -84,7 +84,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
>  /*
>   * Unimplemented mmio regions needed to boot some images.
>   */
> -#define XLNX_ZYNQMP_NUM_UNIMP_AREAS 1
> +#define XLNX_ZYNQMP_NUM_UNIMP_AREAS 2
>  
>  struct XlnxZynqMPState {
>  /*< private >*/
> diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
> index 17305fe7b7..ba44e95899 100644
> --- a/hw/arm/xlnx-zynqmp.c
> +++ b/hw/arm/xlnx-zynqmp.c
> @@ -51,6 +51,9 @@
>  #define QSPI_IRQ15
>  #define QSPI_DMA_ADDR   0xff0f0800
>  
> +#define SERDES_ADDR 0xfd40
> +#define SERDES_SIZE 0x2
> +
>  #define DP_ADDR 0xfd4a
>  #define DP_IRQ  113
>  
> @@ -284,6 +287,7 @@ static void xlnx_zynqmp_create_unimp_mmio(XlnxZynqMPState 
> *s)
>  hwaddr size;
>  } unimp_areas[ARRAY_SIZE(s->mr_unimp)] = {
>  { .name = "apu", APU_ADDR, APU_SIZE },
> +{ .name = "serdes", SERDES_ADDR, SERDES_SIZE },
>  };
>  unsigned int nr;
>  
> -- 
> 2.25.1
> 



Re: [PATCH v1 6/6] hw/arm/xlnx-zynqmp: Connect the ZynqMP APU Control

2022-01-31 Thread Francisco Iglesias
On Mon, Jan 31, 2022 at 12:12:06AM +0100, Edgar E. Iglesias wrote:
> From: "Edgar E. Iglesias" 
> 
> Connect the ZynqMP APU Control device.
> 
> Signed-off-by: Edgar E. Iglesias 

Reviewed-by: Francisco Iglesias 

> ---
>  include/hw/arm/xlnx-zynqmp.h |  4 +++-
>  hw/arm/xlnx-zynqmp.c | 25 +++--
>  2 files changed, 26 insertions(+), 3 deletions(-)
> 
> diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
> index d5a3ad3df2..05cd2128f3 100644
> --- a/include/hw/arm/xlnx-zynqmp.h
> +++ b/include/hw/arm/xlnx-zynqmp.h
> @@ -38,6 +38,7 @@
>  #include "hw/dma/xlnx_csu_dma.h"
>  #include "hw/nvram/xlnx-bbram.h"
>  #include "hw/nvram/xlnx-zynqmp-efuse.h"
> +#include "hw/misc/xlnx-zynqmp-apu-ctrl.h"
>  #include "hw/misc/xlnx-zynqmp-crf.h"
>  
>  #define TYPE_XLNX_ZYNQMP "xlnx-zynqmp"
> @@ -85,7 +86,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
>  /*
>   * Unimplemented mmio regions needed to boot some images.
>   */
> -#define XLNX_ZYNQMP_NUM_UNIMP_AREAS 2
> +#define XLNX_ZYNQMP_NUM_UNIMP_AREAS 1
>  
>  struct XlnxZynqMPState {
>  /*< private >*/
> @@ -123,6 +124,7 @@ struct XlnxZynqMPState {
>  XlnxZDMA gdma[XLNX_ZYNQMP_NUM_GDMA_CH];
>  XlnxZDMA adma[XLNX_ZYNQMP_NUM_ADMA_CH];
>  XlnxCSUDMA qspi_dma;
> +XlnxZynqMPAPUCtrl apu_ctrl;
>  XlnxZynqMPCRF crf;
>  
>  char *boot_cpu;
> diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
> index 857d3c9636..21c411cd77 100644
> --- a/hw/arm/xlnx-zynqmp.c
> +++ b/hw/arm/xlnx-zynqmp.c
> @@ -64,7 +64,7 @@
>  #define DPDMA_IRQ   116
>  
>  #define APU_ADDR0xfd5c
> -#define APU_SIZE0x100
> +#define APU_IRQ 153
>  
>  #define IPI_ADDR0xFF30
>  #define IPI_IRQ 64
> @@ -282,6 +282,27 @@ static void xlnx_zynqmp_create_efuse(XlnxZynqMPState *s, 
> qemu_irq *gic)
>  sysbus_connect_irq(sbd, 0, gic[EFUSE_IRQ]);
>  }
>  
> +static void xlnx_zynqmp_create_apu_ctrl(XlnxZynqMPState *s, qemu_irq *gic)
> +{
> +SysBusDevice *sbd;
> +int i;
> +
> +object_initialize_child(OBJECT(s), "apu-ctrl", &s->apu_ctrl,
> +TYPE_XLNX_ZYNQMP_APU_CTRL);
> +sbd = SYS_BUS_DEVICE(&s->apu_ctrl);
> +
> +for (i = 0; i < XLNX_ZYNQMP_NUM_APU_CPUS; i++) {
> +g_autofree gchar *name = g_strdup_printf("cpu%d", i);
> +
> +object_property_set_link(OBJECT(&s->apu_ctrl), name,
> + OBJECT(&s->apu_cpu[i]), &error_abort);
> +}
> +
> +sysbus_realize(sbd, &error_fatal);
> +sysbus_mmio_map(sbd, 0, APU_ADDR);
> +sysbus_connect_irq(sbd, 0, gic[APU_IRQ]);
> +}
> +
>  static void xlnx_zynqmp_create_crf(XlnxZynqMPState *s, qemu_irq *gic)
>  {
>  SysBusDevice *sbd;
> @@ -301,7 +322,6 @@ static void xlnx_zynqmp_create_unimp_mmio(XlnxZynqMPState 
> *s)
>  hwaddr base;
>  hwaddr size;
>  } unimp_areas[ARRAY_SIZE(s->mr_unimp)] = {
> -{ .name = "apu", APU_ADDR, APU_SIZE },
>  { .name = "serdes", SERDES_ADDR, SERDES_SIZE },
>  };
>  unsigned int nr;
> @@ -697,6 +717,7 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error 
> **errp)
>  
>  xlnx_zynqmp_create_bbram(s, gic_spi);
>  xlnx_zynqmp_create_efuse(s, gic_spi);
> +xlnx_zynqmp_create_apu_ctrl(s, gic_spi);
>  xlnx_zynqmp_create_crf(s, gic_spi);
>  xlnx_zynqmp_create_unimp_mmio(s);
>  
> -- 
> 2.25.1
> 



[PATCH v1] hw/arm/xlnx-zynqmp: 'Or' the QSPI / QSPI DMA IRQs

2022-02-03 Thread Francisco Iglesias
'Or' the IRQs coming from the QSPI and QSPI DMA models. This is done for
avoiding the situation where one of the models incorrectly deasserts an
interrupt asserted from the other model (which will result in that the IRQ
is lost and will not reach guest SW).

Signed-off-by: Francisco Iglesias 
---

Hi,

I noted this after receiving a review comment (from Peter Maydell) on a similar
issue on the Versal machine while working on the OSPI series.

Best regards,
Francisco Iglesias


 include/hw/arm/xlnx-zynqmp.h |  2 ++
 hw/arm/xlnx-zynqmp.c | 14 --
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
index 062e637fe4..9424f81c37 100644
--- a/include/hw/arm/xlnx-zynqmp.h
+++ b/include/hw/arm/xlnx-zynqmp.h
@@ -38,6 +38,7 @@
 #include "hw/dma/xlnx_csu_dma.h"
 #include "hw/nvram/xlnx-bbram.h"
 #include "hw/nvram/xlnx-zynqmp-efuse.h"
+#include "hw/or-irq.h"
 
 #define TYPE_XLNX_ZYNQMP "xlnx-zynqmp"
 OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
@@ -122,6 +123,7 @@ struct XlnxZynqMPState {
 XlnxZDMA gdma[XLNX_ZYNQMP_NUM_GDMA_CH];
 XlnxZDMA adma[XLNX_ZYNQMP_NUM_ADMA_CH];
 XlnxCSUDMA qspi_dma;
+qemu_or_irq qspi_irq_orgate;
 
 char *boot_cpu;
 ARMCPU *boot_cpu_ptr;
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
index 1c52a575aa..5fbf38c466 100644
--- a/hw/arm/xlnx-zynqmp.c
+++ b/hw/arm/xlnx-zynqmp.c
@@ -50,6 +50,7 @@
 #define LQSPI_ADDR  0xc000
 #define QSPI_IRQ15
 #define QSPI_DMA_ADDR   0xff0f0800
+#define NUM_QSPI_IRQ_LINES  2
 
 #define DP_ADDR 0xfd4a
 #define DP_IRQ  113
@@ -362,6 +363,8 @@ static void xlnx_zynqmp_init(Object *obj)
 }
 
 object_initialize_child(obj, "qspi-dma", &s->qspi_dma, TYPE_XLNX_CSU_DMA);
+object_initialize_child(obj, "qspi-irq-orgate",
+&s->qspi_irq_orgate, TYPE_OR_IRQ);
 }
 
 static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
@@ -709,6 +712,11 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error 
**errp)
gic_spi[adma_ch_intr[i]]);
 }
 
+object_property_set_int(OBJECT(&s->qspi_irq_orgate),
+"num-lines", NUM_QSPI_IRQ_LINES, &error_fatal);
+qdev_realize(DEVICE(&s->qspi_irq_orgate), NULL, &error_fatal);
+qdev_connect_gpio_out(DEVICE(&s->qspi_irq_orgate), 0, gic_spi[QSPI_IRQ]);
+
 if (!object_property_set_link(OBJECT(&s->qspi_dma), "dma",
   OBJECT(system_memory), errp)) {
 return;
@@ -718,7 +726,8 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error 
**errp)
 }
 
 sysbus_mmio_map(SYS_BUS_DEVICE(&s->qspi_dma), 0, QSPI_DMA_ADDR);
-sysbus_connect_irq(SYS_BUS_DEVICE(&s->qspi_dma), 0, gic_spi[QSPI_IRQ]);
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->qspi_dma), 0,
+   qdev_get_gpio_in(DEVICE(&s->qspi_irq_orgate), 0));
 
 if (!object_property_set_link(OBJECT(&s->qspi), "stream-connected-dma",
   OBJECT(&s->qspi_dma), errp)) {
@@ -729,7 +738,8 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error 
**errp)
 }
 sysbus_mmio_map(SYS_BUS_DEVICE(&s->qspi), 0, QSPI_ADDR);
 sysbus_mmio_map(SYS_BUS_DEVICE(&s->qspi), 1, LQSPI_ADDR);
-sysbus_connect_irq(SYS_BUS_DEVICE(&s->qspi), 0, gic_spi[QSPI_IRQ]);
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->qspi), 0,
+   qdev_get_gpio_in(DEVICE(&s->qspi_irq_orgate), 1));
 
 for (i = 0; i < XLNX_ZYNQMP_NUM_QSPI_BUS; i++) {
 g_autofree gchar *bus_name = g_strdup_printf("qspi%d", i);
-- 
2.11.0




Re: [PATCH v5 12/12] docs/devel: Add documentation for the DMA control interface

2022-01-14 Thread Francisco Iglesias
On [2022 Jan 07] Fri 16:07:17, Peter Maydell wrote:
> On Tue, 14 Dec 2021 at 11:04, Francisco Iglesias
>  wrote:
> >
> > Also, since being the author, list myself as maintainer for the file.
> >
> > Signed-off-by: Francisco Iglesias 
> 
> 
> > +DmaCtrlIfClass
> > +--
> > +
> > +The ``DmaCtrlIfClass`` contains the interface methods that can be
> > +implemented by a DMA engine.
> > +
> > +.. code-block:: c
> > +
> > +typedef struct DmaCtrlIfClass {
> > +InterfaceClass parent;
> > +
> > +/*
> > + * read: Start a read transfer on the DMA engine implementing the 
> > DMA
> > + * control interface
> > + *
> > + * @dma_ctrl: the DMA engine implementing this interface
> > + * @addr: the address to read
> > + * @len: the number of bytes to read at 'addr'
> > + */
> 
> The prototype seems to be missing here.
> 
> > +} DmaCtrlIfClass;
> > +
> > +
> > +dma_ctrl_if_read
> > +
> > +
> > +The ``dma_ctrl_if_read`` function is used from a model embedding the DMA 
> > engine
> > +for starting DMA read transfers.
> > +
> > +.. code-block:: c
> > +
> > +/*
> > + * Start a read transfer on a DMA engine implementing the DMA control
> > + * interface.
> > + *
> > + * @dma_ctrl: the DMA engine implementing this interface
> > + * @addr: the address to read
> > + * @len: the number of bytes to read at 'addr'
> > + */
> > +void dma_ctrl_if_read(DmaCtrlIf *dma, hwaddr addr, uint32_t len);

Hi Peter,

> 
> The method says it "starts" the transfer. How does the thing on the
> end of the DMA control interface find out when the transfer completes,
> or if there were any errors ?

Yes, I can see that above is not clear enough at the moment, I'll attemp to
improve and fix this in v6! I'll also correct the other issues you found in the
series!

Thank you very much for reviewing again!

Best regards,
Francisco

> 
> thanks
> -- PMM



[PATCH v6 01/12] hw/misc: Add a model of Versal's PMC SLCR

2022-01-14 Thread Francisco Iglesias
Add a model of Versal's PMC SLCR (system-level control registers).

Signed-off-by: Francisco Iglesias 
Signed-off-by: Edgar E. Iglesias 
Reviewed-by: Peter Maydell 
---
 hw/misc/meson.build|5 +-
 hw/misc/xlnx-versal-pmc-iou-slcr.c | 1446 
 include/hw/misc/xlnx-versal-pmc-iou-slcr.h |   78 ++
 3 files changed, 1528 insertions(+), 1 deletion(-)
 create mode 100644 hw/misc/xlnx-versal-pmc-iou-slcr.c
 create mode 100644 include/hw/misc/xlnx-versal-pmc-iou-slcr.h

diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index 3f41a3a5b2..e82628a618 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -84,7 +84,10 @@ softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files(
 ))
 softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
 softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c'))
-softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: 
files('xlnx-versal-xramc.c'))
+softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files(
+  'xlnx-versal-xramc.c',
+  'xlnx-versal-pmc-iou-slcr.c',
+))
 softmmu_ss.add(when: 'CONFIG_STM32F2XX_SYSCFG', if_true: 
files('stm32f2xx_syscfg.c'))
 softmmu_ss.add(when: 'CONFIG_STM32F4XX_SYSCFG', if_true: 
files('stm32f4xx_syscfg.c'))
 softmmu_ss.add(when: 'CONFIG_STM32F4XX_EXTI', if_true: 
files('stm32f4xx_exti.c'))
diff --git a/hw/misc/xlnx-versal-pmc-iou-slcr.c 
b/hw/misc/xlnx-versal-pmc-iou-slcr.c
new file mode 100644
index 00..07b7ebc217
--- /dev/null
+++ b/hw/misc/xlnx-versal-pmc-iou-slcr.c
@@ -0,0 +1,1446 @@
+/*
+ * QEMU model of Versal's PMC IOU SLCR (system level control registers)
+ *
+ * Copyright (c) 2021 Xilinx Inc.
+ * Written by Edgar E. Iglesias 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "hw/register.h"
+#include "hw/irq.h"
+#include "qemu/bitops.h"
+#include "qemu/log.h"
+#include "migration/vmstate.h"
+#include "hw/qdev-properties.h"
+#include "hw/misc/xlnx-versal-pmc-iou-slcr.h"
+
+#ifndef XILINX_VERSAL_PMC_IOU_SLCR_ERR_DEBUG
+#define XILINX_VERSAL_PMC_IOU_SLCR_ERR_DEBUG 0
+#endif
+
+REG32(MIO_PIN_0, 0x0)
+FIELD(MIO_PIN_0, L3_SEL, 7, 3)
+FIELD(MIO_PIN_0, L2_SEL, 5, 2)
+FIELD(MIO_PIN_0, L1_SEL, 3, 2)
+FIELD(MIO_PIN_0, L0_SEL, 1, 2)
+REG32(MIO_PIN_1, 0x4)
+FIELD(MIO_PIN_1, L3_SEL, 7, 3)
+FIELD(MIO_PIN_1, L2_SEL, 5, 2)
+FIELD(MIO_PIN_1, L1_SEL, 3, 2)
+FIELD(MIO_PIN_1, L0_SEL, 1, 2)
+REG32(MIO_PIN_2, 0x8)
+FIELD(MIO_PIN_2, L3_SEL, 7, 3)
+FIELD(MIO_PIN_2, L2_SEL, 5, 2)
+FIELD(MIO_PIN_2, L1_SEL, 3, 2)
+FIELD(MIO_PIN_2, L0_SEL, 1, 2)
+REG32(MIO_PIN_3, 0xc)
+FIELD(MIO_PIN_3, L3_SEL, 7, 3)
+FIELD(MIO_PIN_3, L2_SEL, 5, 2)
+FIELD(MIO_PIN_3, L1_SEL, 3, 2)
+FIELD(MIO_PIN_3, L0_SEL, 1, 2)
+REG32(MIO_PIN_4, 0x10)
+FIELD(MIO_PIN_4, L3_SEL, 7, 3)
+FIELD(MIO_PIN_4, L2_SEL, 5, 2)
+FIELD(MIO_PIN_4, L1_SEL, 3, 2)
+FIELD(MIO_PIN_4, L0_SEL, 1, 2)
+REG32(MIO_PIN_5, 0x14)
+FIELD(MIO_PIN_5, L3_SEL, 7, 3)
+FIELD(MIO_PIN_5, L2_SEL, 5, 2)
+FIELD(MIO_PIN_5, L1_SEL, 3, 2)
+FIELD(MIO_PIN_5, L0_SEL, 1, 2)
+REG32(MIO_PIN_6, 0x18)
+FIELD(MIO_PIN_6, L3_SEL, 7, 3)
+FIELD(MIO_PIN_6, L2_SEL, 5, 2)
+FIELD(MIO_PIN_6, L1_SEL, 3, 2)
+FIELD(MIO_PIN_6, L0_SEL, 1, 2)
+REG32(MIO_PIN_7, 0x1c)
+FIELD(MIO_PIN_7, L3_SEL, 7, 3)
+FIELD(MIO_PIN_7, L2_SEL, 5, 2)
+FIELD(MIO_PIN_7, L1_SEL, 3, 2)
+FIELD(MIO_PIN_7, L0_SEL, 1, 2)
+REG32(MIO_PIN_8, 0x20)
+FIELD(MIO_PIN_8, L3_SEL, 7, 3)
+FIELD(MIO_PIN_8, L2_SEL, 5, 2)
+FIELD(MIO_PIN_8, L1_SEL, 3, 2)
+FIELD(MIO_PIN_8, L0_SEL, 1, 2)
+REG32(MIO_PIN_9, 0x24

[PATCH v6 03/12] hw/arm/xlnx-versal: Connect Versal's PMC SLCR

2022-01-14 Thread Francisco Iglesias
Connect Versal's PMC SLCR (system-level control registers) model.

Signed-off-by: Francisco Iglesias 
---
 hw/arm/xlnx-versal.c | 71 +++-
 include/hw/arm/xlnx-versal.h |  5 
 2 files changed, 75 insertions(+), 1 deletion(-)

diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
index fefd00b57c..c8c0c102c7 100644
--- a/hw/arm/xlnx-versal.c
+++ b/hw/arm/xlnx-versal.c
@@ -21,11 +21,13 @@
 #include "kvm_arm.h"
 #include "hw/misc/unimp.h"
 #include "hw/arm/xlnx-versal.h"
+#include "qemu/log.h"
+#include "hw/sysbus.h"
 
 #define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
 #define GEM_REVISION0x40070106
 
-#define VERSAL_NUM_PMC_APB_IRQS 2
+#define VERSAL_NUM_PMC_APB_IRQS 3
 
 static void versal_create_apu_cpus(Versal *s)
 {
@@ -271,6 +273,7 @@ static void versal_create_pmc_apb_irq_orgate(Versal *s, 
qemu_irq *pic)
  * models:
  *  - RTC
  *  - BBRAM
+ *  - PMC SLCR
  */
 object_initialize_child(OBJECT(s), "pmc-apb-irq-orgate",
 &s->pmc.apb_irq_orgate, TYPE_OR_IRQ);
@@ -392,6 +395,23 @@ static void versal_create_efuse(Versal *s, qemu_irq *pic)
 sysbus_connect_irq(SYS_BUS_DEVICE(ctrl), 0, pic[VERSAL_EFUSE_IRQ]);
 }
 
+static void versal_create_pmc_iou_slcr(Versal *s, qemu_irq *pic)
+{
+SysBusDevice *sbd;
+
+object_initialize_child(OBJECT(s), "versal-pmc-iou-slcr", &s->pmc.iou.slcr,
+TYPE_XILINX_VERSAL_PMC_IOU_SLCR);
+
+sbd = SYS_BUS_DEVICE(&s->pmc.iou.slcr);
+sysbus_realize(sbd, &error_fatal);
+
+memory_region_add_subregion(&s->mr_ps, MM_PMC_PMC_IOU_SLCR,
+sysbus_mmio_get_region(sbd, 0));
+
+sysbus_connect_irq(sbd, 0,
+   qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 2));
+}
+
 /* This takes the board allocated linear DDR memory and creates aliases
  * for each split DDR range/aperture on the Versal address map.
  */
@@ -448,8 +468,31 @@ static void versal_unimp_area(Versal *s, const char *name,
 memory_region_add_subregion(mr, base, mr_dev);
 }
 
+static void versal_unimp_sd_emmc_sel(void *opaque, int n, int level)
+{
+qemu_log_mask(LOG_UNIMP,
+  "Selecting between enabling SD mode or eMMC mode on "
+  "controller %d is not yet implemented\n", n);
+}
+
+static void versal_unimp_qspi_ospi_mux_sel(void *opaque, int n, int level)
+{
+qemu_log_mask(LOG_UNIMP,
+  "Selecting between enabling the QSPI or OSPI linear address "
+  "region is not yet implemented\n");
+}
+
+static void versal_unimp_irq_parity_imr(void *opaque, int n, int level)
+{
+qemu_log_mask(LOG_UNIMP,
+  "PMC SLCR parity interrupt behaviour "
+  "is not yet implemented\n");
+}
+
 static void versal_unimp(Versal *s)
 {
+qemu_irq gpio_in;
+
 versal_unimp_area(s, "psm", &s->mr_ps,
 MM_PSM_START, MM_PSM_END - MM_PSM_START);
 versal_unimp_area(s, "crl", &s->mr_ps,
@@ -464,6 +507,31 @@ static void versal_unimp(Versal *s)
 MM_IOU_SCNTR, MM_IOU_SCNTR_SIZE);
 versal_unimp_area(s, "iou-scntr-seucre", &s->mr_ps,
 MM_IOU_SCNTRS, MM_IOU_SCNTRS_SIZE);
+
+qdev_init_gpio_in_named(DEVICE(s), versal_unimp_sd_emmc_sel,
+"sd-emmc-sel-dummy", 2);
+qdev_init_gpio_in_named(DEVICE(s), versal_unimp_qspi_ospi_mux_sel,
+"qspi-ospi-mux-sel-dummy", 1);
+qdev_init_gpio_in_named(DEVICE(s), versal_unimp_irq_parity_imr,
+"irq-parity-imr-dummy", 1);
+
+gpio_in = qdev_get_gpio_in_named(DEVICE(s), "sd-emmc-sel-dummy", 0);
+qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), "sd-emmc-sel", 0,
+gpio_in);
+
+gpio_in = qdev_get_gpio_in_named(DEVICE(s), "sd-emmc-sel-dummy", 1);
+qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), "sd-emmc-sel", 1,
+gpio_in);
+
+gpio_in = qdev_get_gpio_in_named(DEVICE(s), "qspi-ospi-mux-sel-dummy", 0);
+qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr),
+"qspi-ospi-mux-sel", 0,
+gpio_in);
+
+gpio_in = qdev_get_gpio_in_named(DEVICE(s), "irq-parity-imr-dummy", 0);
+qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr),
+SYSBUS_DEVICE_GPIO_IRQ, 0,
+gpio_in);
 }
 
 static void versal_realize(DeviceState *dev, Error **errp)
@@ -483,6 +551,7 @@ static void 

[PATCH v6 02/12] hw/arm/xlnx-versal: 'Or' the interrupts from the BBRAM and RTC models

2022-01-14 Thread Francisco Iglesias
Add an orgate and 'or' the interrupts from the BBRAM and RTC models.

Signed-off-by: Francisco Iglesias 
Reviewed-by: Peter Maydell 
---
 hw/arm/xlnx-versal-virt.c|  2 +-
 hw/arm/xlnx-versal.c | 28 ++--
 include/hw/arm/xlnx-versal.h |  5 +++--
 3 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
index 0c5edc898e..8ea9979710 100644
--- a/hw/arm/xlnx-versal-virt.c
+++ b/hw/arm/xlnx-versal-virt.c
@@ -365,7 +365,7 @@ static void fdt_add_bbram_node(VersalVirt *s)
 qemu_fdt_add_subnode(s->fdt, name);
 
 qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
-   GIC_FDT_IRQ_TYPE_SPI, VERSAL_BBRAM_APB_IRQ_0,
+   GIC_FDT_IRQ_TYPE_SPI, VERSAL_PMC_APB_IRQ,
GIC_FDT_IRQ_FLAGS_LEVEL_HI);
 qemu_fdt_setprop(s->fdt, name, "interrupt-names",
  interrupt_names, sizeof(interrupt_names));
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
index b2705b6925..fefd00b57c 100644
--- a/hw/arm/xlnx-versal.c
+++ b/hw/arm/xlnx-versal.c
@@ -25,6 +25,8 @@
 #define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
 #define GEM_REVISION0x40070106
 
+#define VERSAL_NUM_PMC_APB_IRQS 2
+
 static void versal_create_apu_cpus(Versal *s)
 {
 int i;
@@ -260,6 +262,25 @@ static void versal_create_sds(Versal *s, qemu_irq *pic)
 }
 }
 
+static void versal_create_pmc_apb_irq_orgate(Versal *s, qemu_irq *pic)
+{
+DeviceState *orgate;
+
+/*
+ * The VERSAL_PMC_APB_IRQ is an 'or' of the interrupts from the following
+ * models:
+ *  - RTC
+ *  - BBRAM
+ */
+object_initialize_child(OBJECT(s), "pmc-apb-irq-orgate",
+&s->pmc.apb_irq_orgate, TYPE_OR_IRQ);
+orgate = DEVICE(&s->pmc.apb_irq_orgate);
+object_property_set_int(OBJECT(orgate),
+"num-lines", VERSAL_NUM_PMC_APB_IRQS, 
&error_fatal);
+qdev_realize(orgate, NULL, &error_fatal);
+qdev_connect_gpio_out(orgate, 0, pic[VERSAL_PMC_APB_IRQ]);
+}
+
 static void versal_create_rtc(Versal *s, qemu_irq *pic)
 {
 SysBusDevice *sbd;
@@ -277,7 +298,8 @@ static void versal_create_rtc(Versal *s, qemu_irq *pic)
  * TODO: Connect the ALARM and SECONDS interrupts once our RTC model
  * supports them.
  */
-sysbus_connect_irq(sbd, 1, pic[VERSAL_RTC_APB_ERR_IRQ]);
+sysbus_connect_irq(sbd, 1,
+   qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 0));
 }
 
 static void versal_create_xrams(Versal *s, qemu_irq *pic)
@@ -328,7 +350,8 @@ static void versal_create_bbram(Versal *s, qemu_irq *pic)
 sysbus_realize(sbd, &error_fatal);
 memory_region_add_subregion(&s->mr_ps, MM_PMC_BBRAM_CTRL,
 sysbus_mmio_get_region(sbd, 0));
-sysbus_connect_irq(sbd, 0, pic[VERSAL_BBRAM_APB_IRQ_0]);
+sysbus_connect_irq(sbd, 0,
+   qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 1));
 }
 
 static void versal_realize_efuse_part(Versal *s, Object *dev, hwaddr base)
@@ -455,6 +478,7 @@ static void versal_realize(DeviceState *dev, Error **errp)
 versal_create_gems(s, pic);
 versal_create_admas(s, pic);
 versal_create_sds(s, pic);
+versal_create_pmc_apb_irq_orgate(s, pic);
 versal_create_rtc(s, pic);
 versal_create_xrams(s, pic);
 versal_create_bbram(s, pic);
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
index 895ba12c61..62fb6f0a68 100644
--- a/include/hw/arm/xlnx-versal.h
+++ b/include/hw/arm/xlnx-versal.h
@@ -85,6 +85,8 @@ struct Versal {
 XlnxEFuse efuse;
 XlnxVersalEFuseCtrl efuse_ctrl;
 XlnxVersalEFuseCache efuse_cache;
+
+qemu_or_irq apb_irq_orgate;
 } pmc;
 
 struct {
@@ -111,8 +113,7 @@ struct Versal {
 #define VERSAL_GEM1_WAKE_IRQ_0 59
 #define VERSAL_ADMA_IRQ_0  60
 #define VERSAL_XRAM_IRQ_0  79
-#define VERSAL_BBRAM_APB_IRQ_0 121
-#define VERSAL_RTC_APB_ERR_IRQ 121
+#define VERSAL_PMC_APB_IRQ 121
 #define VERSAL_SD0_IRQ_0   126
 #define VERSAL_EFUSE_IRQ   139
 #define VERSAL_RTC_ALARM_IRQ   142
-- 
2.11.0




[PATCH v6 05/12] hw/dma: Add the DMA control interface

2022-01-14 Thread Francisco Iglesias
An option on real hardware when embedding a DMA engine into a peripheral
is to make the peripheral control the engine through a custom DMA control
(hardware) interface between the two. Software drivers in this scenario
configure and trigger DMA operations through the controlling peripheral's
register API (for example, writing a specific bit in a register could
propagate down to a transfer start signal on the DMA control interface).
At the same time the status, results and interrupts for the transfer might
still be intended to be read and caught through the DMA engine's register
API (and signals).

This patch adds a QEMU DMA control interface that can be used for
modelling above scenario. Through this new interface a peripheral model
embedding a DMA engine model will be able to directly initiate transfers
through the DMA. At the same time the transfer state, result and
completion signaling will be read and caught through the DMA engine
model's register API and signaling.

Signed-off-by: Francisco Iglesias 
---
 hw/dma/dma-ctrl-if.c | 30 +++
 hw/dma/meson.build   |  1 +
 include/hw/dma/dma-ctrl-if.h | 58 
 3 files changed, 89 insertions(+)
 create mode 100644 hw/dma/dma-ctrl-if.c
 create mode 100644 include/hw/dma/dma-ctrl-if.h

diff --git a/hw/dma/dma-ctrl-if.c b/hw/dma/dma-ctrl-if.c
new file mode 100644
index 00..895edac277
--- /dev/null
+++ b/hw/dma/dma-ctrl-if.c
@@ -0,0 +1,30 @@
+/*
+ * DMA control interface.
+ *
+ * Copyright (c) 2021 Xilinx Inc.
+ * Written by Francisco Iglesias 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include "qemu/osdep.h"
+#include "exec/hwaddr.h"
+#include "hw/dma/dma-ctrl-if.h"
+
+MemTxResult dma_ctrl_if_read(DmaCtrlIf *dma, hwaddr addr, uint32_t len)
+{
+DmaCtrlIfClass *dcic =  DMA_CTRL_IF_GET_CLASS(dma);
+return dcic->read(dma, addr, len);
+}
+
+static const TypeInfo dma_ctrl_if_info = {
+.name  = TYPE_DMA_CTRL_IF,
+.parent= TYPE_INTERFACE,
+.class_size = sizeof(DmaCtrlIfClass),
+};
+
+static void dma_ctrl_if_register_types(void)
+{
+type_register_static(&dma_ctrl_if_info);
+}
+
+type_init(dma_ctrl_if_register_types)
diff --git a/hw/dma/meson.build b/hw/dma/meson.build
index f3f0661bc3..c43c067856 100644
--- a/hw/dma/meson.build
+++ b/hw/dma/meson.build
@@ -14,3 +14,4 @@ softmmu_ss.add(when: 'CONFIG_PXA2XX', if_true: 
files('pxa2xx_dma.c'))
 softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_dma.c'))
 softmmu_ss.add(when: 'CONFIG_SIFIVE_PDMA', if_true: files('sifive_pdma.c'))
 softmmu_ss.add(when: 'CONFIG_XLNX_CSU_DMA', if_true: files('xlnx_csu_dma.c'))
+common_ss.add(when: 'CONFIG_XILINX_AXI', if_true: files('dma-ctrl-if.c'))
diff --git a/include/hw/dma/dma-ctrl-if.h b/include/hw/dma/dma-ctrl-if.h
new file mode 100644
index 00..0662149e14
--- /dev/null
+++ b/include/hw/dma/dma-ctrl-if.h
@@ -0,0 +1,58 @@
+/*
+ * DMA control interface.
+ *
+ * Copyright (c) 2021 Xilinx Inc.
+ * Written by Francisco Iglesias 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#ifndef HW_DMA_CTRL_IF_H
+#define HW_DMA_CTRL_IF_H
+
+#include "hw/hw.h"
+#include "exec/memory.h"
+#include "qom/object.h"
+
+#define TYPE_DMA_CTRL_IF "dma-ctrl-if"
+typedef struct DmaCtrlIfClass DmaCtrlIfClass;
+DECLARE_CLASS_CHECKERS(DmaCtrlIfClass, DMA_CTRL_IF,
+   TYPE_DMA_CTRL_IF)
+
+#define DMA_CTRL_IF(obj) \
+ INTERFACE_CHECK(DmaCtrlIf, (obj), TYPE_DMA_CTRL_IF)
+
+typedef struct DmaCtrlIf {
+Object Parent;
+} DmaCtrlIf;
+
+typedef struct DmaCtrlIfClass {
+InterfaceClass parent;
+
+/*
+ * read: Start a read transfer on the DMA engine implementing the DMA
+ * control interface
+ *
+ * @dma_ctrl: the DMA engine implementing this interface
+ * @addr: the address to read
+ * @len: the number of bytes to read at 'addr'
+ *
+ * @return a MemTxResult indicating whether the operation succeeded ('len'
+ * bytes were read) or failed.
+ */
+MemTxResult (*read)(DmaCtrlIf *dma, hwaddr addr, uint32_t len);
+} DmaCtrlIfClass;
+
+/*
+ * Start a read transfer on a DMA engine implementing the DMA control
+ * interface.
+ *
+ * @dma_ctrl: the DMA engine implementing this interface
+ * @addr: the address to read
+ * @len: the number of bytes to read at 'addr'
+ *
+ * @return a MemTxResult indicating whether the operation succeeded ('len'
+ * bytes were read) or failed.
+ */
+MemTxResult dma_ctrl_if_read(DmaCtrlIf *dma, hwaddr addr, uint32_t len);
+
+#endif /* HW_DMA_CTRL_IF_H */
-- 
2.11.0




[PATCH v6 09/12] hw/block/m25p80: Add support for Micron Xccela flash mt35xu01g

2022-01-14 Thread Francisco Iglesias
Add support for Micron Xccela flash mt35xu01g.

Signed-off-by: Francisco Iglesias 
Reviewed-by: Edgar E. Iglesias 
---
 hw/block/m25p80.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index b77503dc84..c6bf3c6bfa 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -255,6 +255,8 @@ static const FlashPartInfo known_devices[] = {
 { INFO("n25q512a",0x20ba20,  0,  64 << 10, 1024, ER_4K) },
 { INFO("n25q512ax3",  0x20ba20,  0x1000,  64 << 10, 1024, ER_4K) },
 { INFO("mt25ql512ab", 0x20ba20, 0x1044, 64 << 10, 1024, ER_4K | ER_32K) },
+{ INFO_STACKED("mt35xu01g", 0x2c5b1b, 0x104100, 128 << 10, 1024,
+   ER_4K | ER_32K, 2) },
 { INFO_STACKED("n25q00",0x20ba21, 0x1000, 64 << 10, 2048, ER_4K, 4) },
 { INFO_STACKED("n25q00a",   0x20bb21, 0x1000, 64 << 10, 2048, ER_4K, 4) },
 { INFO_STACKED("mt25ql01g", 0x20ba21, 0x1040, 64 << 10, 2048, ER_4K, 2) },
-- 
2.11.0




[PATCH v6 04/12] include/hw/dma/xlnx_csu_dma: Add in missing includes in the header

2022-01-14 Thread Francisco Iglesias
Add in the missing includes in the header for being able to build the DMA
model when reusing it.

Signed-off-by: Francisco Iglesias 
Reviewed-by: Peter Maydell 
---
 include/hw/dma/xlnx_csu_dma.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/include/hw/dma/xlnx_csu_dma.h b/include/hw/dma/xlnx_csu_dma.h
index 9e9dc551e9..28806628b1 100644
--- a/include/hw/dma/xlnx_csu_dma.h
+++ b/include/hw/dma/xlnx_csu_dma.h
@@ -21,6 +21,11 @@
 #ifndef XLNX_CSU_DMA_H
 #define XLNX_CSU_DMA_H
 
+#include "hw/sysbus.h"
+#include "hw/register.h"
+#include "hw/ptimer.h"
+#include "hw/stream.h"
+
 #define TYPE_XLNX_CSU_DMA "xlnx.csu_dma"
 
 #define XLNX_CSU_DMA_R_MAX (0x2c / 4)
-- 
2.11.0




[PATCH v6 11/12] MAINTAINERS: Add an entry for Xilinx Versal OSPI

2022-01-14 Thread Francisco Iglesias
List myself as maintainer for the Xilinx Versal OSPI controller.

Signed-off-by: Francisco Iglesias 
Reviewed-by: Edgar E. Iglesias 
Reviewed-by: Peter Maydell 
---
 MAINTAINERS | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 6ccdec7f02..0e31569d65 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -963,6 +963,12 @@ F: hw/display/dpcd.c
 F: include/hw/display/dpcd.h
 F: docs/system/arm/xlnx-versal-virt.rst
 
+Xilinx Versal OSPI
+M: Francisco Iglesias 
+S: Maintained
+F: hw/ssi/xlnx-versal-ospi.c
+F: include/hw/ssi/xlnx-versal-ospi.h
+
 ARM ACPI Subsystem
 M: Shannon Zhao 
 L: qemu-...@nongnu.org
-- 
2.11.0




[PATCH v6 06/12] hw/dma/xlnx_csu_dma: Implement the DMA control interface

2022-01-14 Thread Francisco Iglesias
Implement the DMA control interface for allowing direct control of DMA
operations from inside peripheral models embedding (and reusing) the
Xilinx CSU DMA.

Signed-off-by: Francisco Iglesias 
---
 hw/dma/xlnx_csu_dma.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/hw/dma/xlnx_csu_dma.c b/hw/dma/xlnx_csu_dma.c
index 896bb3574d..58860d9f19 100644
--- a/hw/dma/xlnx_csu_dma.c
+++ b/hw/dma/xlnx_csu_dma.c
@@ -30,6 +30,7 @@
 #include "hw/stream.h"
 #include "hw/register.h"
 #include "hw/dma/xlnx_csu_dma.h"
+#include "hw/dma/dma-ctrl-if.h"
 
 /*
  * Ref: UG1087 (v1.7) February 8, 2019
@@ -472,6 +473,21 @@ static uint64_t addr_msb_pre_write(RegisterInfo *reg, 
uint64_t val)
 return val & R_ADDR_MSB_ADDR_MSB_MASK;
 }
 
+static MemTxResult xlnx_csu_dma_dma_ctrl_if_read(DmaCtrlIf *dma, hwaddr addr,
+ uint32_t len)
+{
+XlnxCSUDMA *s = XLNX_CSU_DMA(dma);
+RegisterInfo *reg = &s->regs_info[R_SIZE];
+uint64_t we = MAKE_64BIT_MASK(0, 4 * 8);
+
+s->regs[R_ADDR] = addr;
+s->regs[R_ADDR_MSB] = (uint64_t)addr >> 32;
+
+register_write(reg, len, we, object_get_typename(OBJECT(s)), false);
+
+return (s->regs[R_SIZE] == 0) ? MEMTX_OK : MEMTX_ERROR;
+}
+
 static const RegisterAccessInfo *xlnx_csu_dma_regs_info[] = {
 #define DMACH_REGINFO(NAME, snd)  \
 (const RegisterAccessInfo []) {   \
@@ -696,6 +712,7 @@ static void xlnx_csu_dma_class_init(ObjectClass *klass, 
void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
 StreamSinkClass *ssc = STREAM_SINK_CLASS(klass);
+DmaCtrlIfClass *dcic = DMA_CTRL_IF_CLASS(klass);
 
 dc->reset = xlnx_csu_dma_reset;
 dc->realize = xlnx_csu_dma_realize;
@@ -704,6 +721,8 @@ static void xlnx_csu_dma_class_init(ObjectClass *klass, 
void *data)
 
 ssc->push = xlnx_csu_dma_stream_push;
 ssc->can_push = xlnx_csu_dma_stream_can_push;
+
+dcic->read = xlnx_csu_dma_dma_ctrl_if_read;
 }
 
 static void xlnx_csu_dma_init(Object *obj)
@@ -731,6 +750,7 @@ static const TypeInfo xlnx_csu_dma_info = {
 .instance_init = xlnx_csu_dma_init,
 .interfaces = (InterfaceInfo[]) {
 { TYPE_STREAM_SINK },
+{ TYPE_DMA_CTRL_IF },
 { }
 }
 };
-- 
2.11.0




[PATCH v6 07/12] hw/ssi: Add a model of Xilinx Versal's OSPI flash memory controller

2022-01-14 Thread Francisco Iglesias
Add a model of Xilinx Versal's OSPI flash memory controller.

Signed-off-by: Francisco Iglesias 
---
 hw/ssi/meson.build|1 +
 hw/ssi/xlnx-versal-ospi.c | 1856 +
 include/hw/ssi/xlnx-versal-ospi.h |  111 +++
 3 files changed, 1968 insertions(+)
 create mode 100644 hw/ssi/xlnx-versal-ospi.c
 create mode 100644 include/hw/ssi/xlnx-versal-ospi.h

diff --git a/hw/ssi/meson.build b/hw/ssi/meson.build
index 3d6bc82ab1..0ded9cd092 100644
--- a/hw/ssi/meson.build
+++ b/hw/ssi/meson.build
@@ -7,5 +7,6 @@ softmmu_ss.add(when: 'CONFIG_SSI', if_true: files('ssi.c'))
 softmmu_ss.add(when: 'CONFIG_STM32F2XX_SPI', if_true: files('stm32f2xx_spi.c'))
 softmmu_ss.add(when: 'CONFIG_XILINX_SPI', if_true: files('xilinx_spi.c'))
 softmmu_ss.add(when: 'CONFIG_XILINX_SPIPS', if_true: files('xilinx_spips.c'))
+softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: 
files('xlnx-versal-ospi.c'))
 softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('imx_spi.c'))
 softmmu_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_spi.c'))
diff --git a/hw/ssi/xlnx-versal-ospi.c b/hw/ssi/xlnx-versal-ospi.c
new file mode 100644
index 00..20f46b3692
--- /dev/null
+++ b/hw/ssi/xlnx-versal-ospi.c
@@ -0,0 +1,1856 @@
+/*
+ * QEMU model of Xilinx Versal's OSPI controller.
+ *
+ * Copyright (c) 2021 Xilinx Inc.
+ * Written by Francisco Iglesias 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "migration/vmstate.h"
+#include "hw/qdev-properties.h"
+#include "qemu/bitops.h"
+#include "qemu/log.h"
+#include "hw/irq.h"
+#include "hw/ssi/xlnx-versal-ospi.h"
+
+#ifndef XILINX_VERSAL_OSPI_ERR_DEBUG
+#define XILINX_VERSAL_OSPI_ERR_DEBUG 0
+#endif
+
+REG32(CONFIG_REG, 0x0)
+FIELD(CONFIG_REG, IDLE_FLD, 31, 1)
+FIELD(CONFIG_REG, DUAL_BYTE_OPCODE_EN_FLD, 30, 1)
+FIELD(CONFIG_REG, CRC_ENABLE_FLD, 29, 1)
+FIELD(CONFIG_REG, CONFIG_RESV2_FLD, 26, 3)
+FIELD(CONFIG_REG, PIPELINE_PHY_FLD, 25, 1)
+FIELD(CONFIG_REG, ENABLE_DTR_PROTOCOL_FLD, 24, 1)
+FIELD(CONFIG_REG, ENABLE_AHB_DECODER_FLD, 23, 1)
+FIELD(CONFIG_REG, MSTR_BAUD_DIV_FLD, 19, 4)
+FIELD(CONFIG_REG, ENTER_XIP_MODE_IMM_FLD, 18, 1)
+FIELD(CONFIG_REG, ENTER_XIP_MODE_FLD, 17, 1)
+FIELD(CONFIG_REG, ENB_AHB_ADDR_REMAP_FLD, 16, 1)
+FIELD(CONFIG_REG, ENB_DMA_IF_FLD, 15, 1)
+FIELD(CONFIG_REG, WR_PROT_FLASH_FLD, 14, 1)
+FIELD(CONFIG_REG, PERIPH_CS_LINES_FLD, 10, 4)
+FIELD(CONFIG_REG, PERIPH_SEL_DEC_FLD, 9, 1)
+FIELD(CONFIG_REG, ENB_LEGACY_IP_MODE_FLD, 8, 1)
+FIELD(CONFIG_REG, ENB_DIR_ACC_CTLR_FLD, 7, 1)
+FIELD(CONFIG_REG, RESET_CFG_FLD, 6, 1)
+FIELD(CONFIG_REG, RESET_PIN_FLD, 5, 1)
+FIELD(CONFIG_REG, HOLD_PIN_FLD, 4, 1)
+FIELD(CONFIG_REG, PHY_MODE_ENABLE_FLD, 3, 1)
+FIELD(CONFIG_REG, SEL_CLK_PHASE_FLD, 2, 1)
+FIELD(CONFIG_REG, SEL_CLK_POL_FLD, 1, 1)
+FIELD(CONFIG_REG, ENB_SPI_FLD, 0, 1)
+REG32(DEV_INSTR_RD_CONFIG_REG, 0x4)
+FIELD(DEV_INSTR_RD_CONFIG_REG, RD_INSTR_RESV5_FLD, 29, 3)
+FIELD(DEV_INSTR_RD_CONFIG_REG, DUMMY_RD_CLK_CYCLES_FLD, 24, 5)
+FIELD(DEV_INSTR_RD_CONFIG_REG, RD_INSTR_RESV4_FLD, 21, 3)
+FIELD(DEV_INSTR_RD_CONFIG_REG, MODE_BIT_ENABLE_FLD, 20, 1)
+FIELD(DEV_INSTR_RD_CONFIG_REG, RD_INSTR_RESV3_FLD, 18, 2)
+FIELD(DEV_INSTR_RD_CONFIG_REG, DATA_XFER_TYPE_EXT_MODE_FLD, 16, 2)
+FIELD(DEV_INSTR_RD_CONFIG_REG, RD_INSTR_RESV2_FLD, 14, 2)
+FIELD(DEV_INSTR_RD_CONFIG_REG, ADDR_XFER_TYPE_STD_MODE_FLD, 12, 2)
+FIELD(DEV_INSTR_RD_CONFIG_REG, PRED_DIS_FLD, 11, 1)
+FIELD(DEV_INSTR_RD_CONFIG_REG, DDR_EN_FLD, 10, 1)
+FIELD(DEV_INSTR_RD_CONFIG_REG, INSTR_TYPE_FLD, 8, 2)
+FIELD(DEV_IN

[PATCH v6 08/12] hw/arm/xlnx-versal: Connect the OSPI flash memory controller model

2022-01-14 Thread Francisco Iglesias
Connect the OSPI flash memory controller model (including the source and
destination DMA).

Signed-off-by: Francisco Iglesias 
Reviewed-by: Peter Maydell 
---
 hw/arm/xlnx-versal.c | 93 
 include/hw/arm/xlnx-versal.h | 20 ++
 2 files changed, 113 insertions(+)

diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
index c8c0c102c7..ab58bebfd2 100644
--- a/hw/arm/xlnx-versal.c
+++ b/hw/arm/xlnx-versal.c
@@ -28,6 +28,7 @@
 #define GEM_REVISION0x40070106
 
 #define VERSAL_NUM_PMC_APB_IRQS 3
+#define NUM_OSPI_IRQ_LINES 3
 
 static void versal_create_apu_cpus(Versal *s)
 {
@@ -412,6 +413,97 @@ static void versal_create_pmc_iou_slcr(Versal *s, qemu_irq 
*pic)
qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 2));
 }
 
+static void versal_create_ospi(Versal *s, qemu_irq *pic)
+{
+SysBusDevice *sbd;
+MemoryRegion *mr_dac;
+qemu_irq ospi_mux_sel;
+DeviceState *orgate;
+
+memory_region_init(&s->pmc.iou.ospi.linear_mr, OBJECT(s),
+   "versal-ospi-linear-mr" , MM_PMC_OSPI_DAC_SIZE);
+
+object_initialize_child(OBJECT(s), "versal-ospi", &s->pmc.iou.ospi.ospi,
+TYPE_XILINX_VERSAL_OSPI);
+
+mr_dac = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi), 1);
+memory_region_add_subregion(&s->pmc.iou.ospi.linear_mr, 0x0, mr_dac);
+
+/* Create the OSPI destination DMA */
+object_initialize_child(OBJECT(s), "versal-ospi-dma-dst",
+&s->pmc.iou.ospi.dma_dst,
+TYPE_XLNX_CSU_DMA);
+
+object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_dst),
+"dma", OBJECT(get_system_memory()),
+ &error_abort);
+
+sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_dst);
+sysbus_realize(sbd, &error_fatal);
+
+memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DMA_DST,
+sysbus_mmio_get_region(sbd, 0));
+
+/* Create the OSPI source DMA */
+object_initialize_child(OBJECT(s), "versal-ospi-dma-src",
+&s->pmc.iou.ospi.dma_src,
+TYPE_XLNX_CSU_DMA);
+
+object_property_set_bool(OBJECT(&s->pmc.iou.ospi.dma_src), "is-dst",
+ false, &error_abort);
+
+object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_src),
+"dma", OBJECT(mr_dac), &error_abort);
+
+object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_src),
+"stream-connected-dma",
+ OBJECT(&s->pmc.iou.ospi.dma_dst),
+ &error_abort);
+
+sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_src);
+sysbus_realize(sbd, &error_fatal);
+
+memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DMA_SRC,
+sysbus_mmio_get_region(sbd, 0));
+
+/* Realize the OSPI */
+object_property_set_link(OBJECT(&s->pmc.iou.ospi.ospi), "dma-src",
+ OBJECT(&s->pmc.iou.ospi.dma_src), &error_abort);
+
+sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi);
+sysbus_realize(sbd, &error_fatal);
+
+memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI,
+sysbus_mmio_get_region(sbd, 0));
+
+memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DAC,
+&s->pmc.iou.ospi.linear_mr);
+
+/* ospi_mux_sel */
+ospi_mux_sel = qdev_get_gpio_in_named(DEVICE(&s->pmc.iou.ospi.ospi),
+  "ospi-mux-sel", 0);
+qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), "ospi-mux-sel", 0,
+ospi_mux_sel);
+
+/* OSPI irq */
+object_initialize_child(OBJECT(s), "ospi-irq-orgate",
+&s->pmc.iou.ospi.irq_orgate, TYPE_OR_IRQ);
+object_property_set_int(OBJECT(&s->pmc.iou.ospi.irq_orgate),
+"num-lines", NUM_OSPI_IRQ_LINES, &error_fatal);
+
+orgate = DEVICE(&s->pmc.iou.ospi.irq_orgate);
+qdev_realize(orgate, NULL, &error_fatal);
+
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi), 0,
+   qdev_get_gpio_in(orgate, 0));
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_src), 0,
+   qdev_get_gpio_in(orgate, 1));
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_dst), 0,
+   qdev_get_gpio_in(orgate, 2));
+
+qdev_connect_gpio_out(orgate, 0, pic[VERSAL_OSPI_IRQ]);
+}
+
 /* T

[PATCH v6 10/12] hw/arm/xlnx-versal-virt: Connect mt35xu01g flashes to the OSPI

2022-01-14 Thread Francisco Iglesias
Connect Micron Xccela mt35xu01g flashes to the OSPI flash memory
controller.

Signed-off-by: Francisco Iglesias 
Reviewed-by: Edgar E. Iglesias 
Reviewed-by: Peter Maydell 
---
 hw/arm/xlnx-versal-virt.c | 23 +++
 1 file changed, 23 insertions(+)

diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
index 8ea9979710..3f56ae28ee 100644
--- a/hw/arm/xlnx-versal-virt.c
+++ b/hw/arm/xlnx-versal-virt.c
@@ -25,6 +25,8 @@
 #define TYPE_XLNX_VERSAL_VIRT_MACHINE MACHINE_TYPE_NAME("xlnx-versal-virt")
 OBJECT_DECLARE_SIMPLE_TYPE(VersalVirt, XLNX_VERSAL_VIRT_MACHINE)
 
+#define XLNX_VERSAL_NUM_OSPI_FLASH 4
+
 struct VersalVirt {
 MachineState parent_obj;
 
@@ -691,6 +693,27 @@ static void versal_virt_init(MachineState *machine)
 exit(EXIT_FAILURE);
 }
 }
+
+for (i = 0; i < XLNX_VERSAL_NUM_OSPI_FLASH; i++) {
+BusState *spi_bus;
+DeviceState *flash_dev;
+qemu_irq cs_line;
+DriveInfo *dinfo = drive_get(IF_MTD, 0, i);
+
+spi_bus = qdev_get_child_bus(DEVICE(&s->soc.pmc.iou.ospi), "spi0");
+
+flash_dev = qdev_new("mt35xu01g");
+if (dinfo) {
+qdev_prop_set_drive_err(flash_dev, "drive",
+blk_by_legacy_dinfo(dinfo), &error_fatal);
+}
+qdev_realize_and_unref(flash_dev, spi_bus, &error_fatal);
+
+cs_line = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
+
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->soc.pmc.iou.ospi),
+   i + 1, cs_line);
+}
 }
 
 static void versal_virt_machine_instance_init(Object *obj)
-- 
2.11.0




[PATCH v6 12/12] docs/devel: Add documentation for the DMA control interface

2022-01-14 Thread Francisco Iglesias
Also, since being the author, list myself as maintainer for the file.

Signed-off-by: Francisco Iglesias 
---
 MAINTAINERS|   1 +
 docs/devel/dma-ctrl-if.rst | 243 +
 docs/devel/index.rst   |   1 +
 3 files changed, 245 insertions(+)
 create mode 100644 docs/devel/dma-ctrl-if.rst

diff --git a/MAINTAINERS b/MAINTAINERS
index 0e31569d65..5736ce0675 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -968,6 +968,7 @@ M: Francisco Iglesias 
 S: Maintained
 F: hw/ssi/xlnx-versal-ospi.c
 F: include/hw/ssi/xlnx-versal-ospi.h
+F: docs/devel/dma-ctrl-if.rst
 
 ARM ACPI Subsystem
 M: Shannon Zhao 
diff --git a/docs/devel/dma-ctrl-if.rst b/docs/devel/dma-ctrl-if.rst
new file mode 100644
index 00..15ef6491cd
--- /dev/null
+++ b/docs/devel/dma-ctrl-if.rst
@@ -0,0 +1,243 @@
+DMA control interface
+=
+
+About the DMA control interface
+---
+
+DMA engines embedded in peripherals can end up being controlled in
+different ways on real hardware. One possible way is to allow software
+drivers to access the DMA engine's register API and to allow the drivers
+to configure and control DMA transfers through the API. A model of a DMA
+engine in QEMU that is embedded and (re)used in this manner does not need
+to implement the DMA control interface.
+
+Another option on real hardware is to allow the peripheral embedding the
+DMA engine to control the engine through a custom hardware DMA control
+interface between the two. Software drivers in this scenario configure and
+trigger DMA operations through the controlling peripheral's register API
+(for example, writing a specific bit in a register could propagate down to
+a transfer start signal on the DMA control interface). At the same time
+the status, result and interrupts for the transfer might still be intended
+to be read and caught through the DMA engine's register API (and
+signals).
+
+::
+
+Hardware example
+   ++
+   ||
+   | Peripheral |
+   ||
+   ++
+/\
+||   DMA control IF (custom)
+\/
+   ++
+   | Peripheral |
+   |DMA |
+   ++
+
+Figure 1. A peripheral controlling its embedded DMA engine through a
+custom DMA control interface
+
+The above scenario can be modelled in QEMU by implementing this DMA control
+interface in the DMA engine model. This will allow a peripheral embedding
+the DMA engine to initiate DMA transfers through the engine using the
+interface. At the same time the status, result and interrupts for the
+transfer can be read and caught through the DMA engine's register API and
+signals. An example implementation and usage of the DMA control interface
+can be found in the Xilinx CSU DMA model and Xilinx Versal's OSPI model.
+
+::
+
+Memory address
+(register API)
+  0xf101   +-+
+   | |
+   | Versal  |
+   |  OSPI   |
+   | |
+   +-+
+   /\
+   ||  DMA control IF
+   \/
+  0xf1011000   +-+
+   | |
+   | CSU DMA |
+   |  (src)  |
+   | |
+   +-+
+
+Figure 2. Xilinx Versal's OSPI controls and initiates transfers on its
+CSU source DMA through a DMA control interface
+
+DMA control interface files
+---
+
+``include/hw/dma/dma-ctrl-if.h``
+``hw/dma/dma-ctrl-if.c``
+
+DmaCtrlIfClass
+--
+
+The ``DmaCtrlIfClass`` contains the interface methods that can be
+implemented by a DMA engine.
+
+.. code-block:: c
+
+typedef struct DmaCtrlIfClass {
+InterfaceClass parent;
+
+/*
+ * read: Start a read transfer on the DMA engine implementing the DMA
+ * control interface
+ *
+ * @dma_ctrl: the DMA engine implementing this interface
+ * @addr: the address to read
+ * @len: the number of bytes to read at 'addr'
+ *
+ * @return a MemTxResult indicating whether the operation succeeded 
('len'
+ * bytes were read) or failed.
+ */
+MemTxResult (*read)(DmaCtrlIf *dma, hwaddr addr, uint32_t len);
+} DmaCtrlIfClass;
+
+
+dma_ctrl_if_read
+
+
+The ``dma_ctrl_if_read`` function is used from a model embedding the DMA engine
+for starting DMA read transfers.
+
+.. code-block:: c
+
+/*
+ * Start a read transfer on a DMA engine implementing the DMA control
+ * interface.
+ *
+ * @dma_ctrl: the DMA engine implementing this interface
+ * @

[PATCH v6 00/12] Xilinx Versal's PMC SLCR and OSPI support

2022-01-14 Thread Francisco Iglesias
Hi,

This series attempts to add support for Xilinx Versal's PMC SLCR
(system-level control registers) and OSPI flash memory controller to
Xilinx Versal virt machine.

The series start with adding a model of Versal's PMC SLCR and connecting
the model to the Versal virt machine. The series then adds a couple of
headers into the xlnx_csu_dma.h needed for building and reusing it later
with the OSPI. The series thereafter introduces a DMA control interface
and implements the interface in the xlnx_csu_dma for being able to reuse
and control the DMA with the OSPI controller. Thereafter a model of
Versal's OSPI controller is added and connected to the Versal virt
machine. The series then ends with adding initial support for the Micron
Xccelera mt35xu01g flash and flashes of this type are connected to the
OSPI in the Versal virt machine.

Best regards,
Francisco Iglesias

Changelog:
v5 -> v6:
  * Corrected unimplemented log messages (patch: "hw/arm/xlnx-versal: Connect
Versal's PMC SLCR")
  * Modify dma_ctrl_if_read to return a MemTxResult carrying the result of the
read operation
  * Updated (and corrected) documentation

v4 -> v5
  * Use named GPIOs for "sd-emmc-sel", "qspi-ospi-mux-sel", "ospi-mux-sel"
in the PMC SLCR model
  * Add a QEMU interface comment for the PMC SLCR model.
  * Switch to use OBJECT_DECLARE_SIMPLE_TYPE in both "xlnx-versal-ospi.h"
and "xlnx-versal-pmc-iou-slcr.h"
  * Create a new patch 'or'ing the interrupts from the BBRAM and RTC model
  * 'Or' the interrupt from the PMC SLCR with the BBRAM and RTC interrupt
inside 'xlnx-versal.c'
  * Connect other not yet implemented PMC SLCR GPIOs to unimplemented messages
  * Reworked and simplified the DMA control interface by removing the
notifier and refill mechanism
  * Corrected various typos and grammatical errors in the DMA control
interface documentation and comments
  * Updated the DMA control interface documentation to describe the new
simplified implementation
  * Use ldl_le_p and ldq_le_p in the OSPI model (and remove the OSPIRdData
union). Also assert in the locations that we are not overruning the
new bytes buffer.
  * Correct the single_cs function in the OSPI model (both comment and output)
  * Correct a typo in a comment inside ospi_do_indirect_write
(s/boundery/boundary/)
  * Remove an unecesary assert in the OSPI model
  * Add a QEMU interface comment for the OSPI model.
  * Rename the OSPI irq in 'xlnx-versal.c' to include 'orgate' in the name for
clarifying

v3 -> v4
  * Correct indentation (patch: "hw/arm/xlnx-versal: Connect Versal's PMC
SLCR")

  * Rename to include "If" in names related to the DMA control interface
  * In dma-ctrl-if.h:
- Don't include qemu-common.h
- Use DECLARE_CLASS_CHECKERS dma-ctrl.h
  * Add a docs/devel documentation patch for the DMA control interface
  * Improve git messages on the dma-ctrl-if patches


v2 -> v3
  * Correct and also include hw/sysbus.h and hw/register.h into
xlnx_csu_dma.h (patch: "include/hw/dma/xlnx_csu_dma: Add in missing
includes in the header")

v1 -> v2
  * Correct the reset in the PMC SLCR model
  * Create a sub structure for the OSPI in the Versal structure (in patch:
"hw/arm/xlnx-versal: Connect the OSPI flash memory controller model")
  * Change to use 'drive_get' instead of 'drive_get_next' (in patch:
"hw/arm/xlnx-versal-virt: Connect mt35xu01g flashes to the OSPI")
  * Add a maintainers patch and list myself as maintainer for the OSPI
controller


Francisco Iglesias (12):
  hw/misc: Add a model of Versal's PMC SLCR
  hw/arm/xlnx-versal: 'Or' the interrupts from the BBRAM and RTC models
  hw/arm/xlnx-versal: Connect Versal's PMC SLCR
  include/hw/dma/xlnx_csu_dma: Add in missing includes in the header
  hw/dma: Add the DMA control interface
  hw/dma/xlnx_csu_dma: Implement the DMA control interface
  hw/ssi: Add a model of Xilinx Versal's OSPI flash memory controller
  hw/arm/xlnx-versal: Connect the OSPI flash memory controller model
  hw/block/m25p80: Add support for Micron Xccela flash mt35xu01g
  hw/arm/xlnx-versal-virt: Connect mt35xu01g flashes to the OSPI
  MAINTAINERS: Add an entry for Xilinx Versal OSPI
  docs/devel: Add documentation for the DMA control interface

 MAINTAINERS|7 +
 docs/devel/dma-ctrl-if.rst |  243 
 docs/devel/index.rst   |1 +
 hw/arm/xlnx-versal-virt.c  |   25 +-
 hw/arm/xlnx-versal.c   |  190 ++-
 hw/block/m25p80.c  |2 +
 hw/dma/dma-ctrl-if.c   |   30 +
 hw/dma/meson.build |1 +
 hw/dma/xlnx_csu_dma.c

Re: [PATCH v6 07/12] hw/ssi: Add a model of Xilinx Versal's OSPI flash memory controller

2022-01-21 Thread Francisco Iglesias
Hi Luc,

All the suggestions and corrections look good to me so brought them in in
v7!

Thank you very much reviewing!

Best regards,
Francisco Iglesias


On [2022 Jan 18] Tue 22:46:32, Luc Michel wrote:
> Hi Francisco,
> 
> Impressive beast :-) Nicely done. Maybe I would have split it in a
> couple of commits to ease review. Also, you can use 
> 
> [diff]
> orderFile = scripts/git.orderfile
> 
> as a local config in your QEMU git so that files are placed in a
> sensible order (.h files will come first), which ease a bit the
> reviewing process.
> 
> See my remarks below. My biggest concern is about the tx_sram fifo.
> The rest are small suggestions here and there.
> 
> On 15:28 Fri 14 Jan , Francisco Iglesias wrote:
> [snip]
> > +
> > +static int ospi_stig_membank_rd_bytes(XlnxVersalOspi *s)
> > +{
> > +int rd_data_fld = ARRAY_FIELD_EX32(s->regs, FLASH_COMMAND_CTRL_MEM_REG,
> > +   NB_OF_STIG_READ_BYTES_FLD);
> > +int sizes[6] = { 16, 32, 64, 128, 256, 512 };
> 
> static const int sizes[6]
> 
> (or return (rd_data_fld < 6) ? (1 << (4 + rd_data_fld)) : 0; )
> 
> > +return (rd_data_fld < 6) ? sizes[rd_data_fld] : 0;
> > +}
> > +
> [snip]
> > +
> > +static void ospi_ahb_decoder_enable_cs(XlnxVersalOspi *s, hwaddr addr)
> > +{
> > +int cs = ospi_ahb_decoder_cs(s, addr);
> > +
> > +if (cs >= 0) {
> > +for (int i = 0; i < s->num_cs; i++) {
> > +if (cs == i) {
> > +qemu_set_irq(s->cs_lines[i], 0);
> > +} else {
> > +qemu_set_irq(s->cs_lines[i], 1);
> > +}
> 
> Maybe `qemu_set_irq(s->cs_lines[i], cs != i);` instead of the if/else?
> 
> > +}
> > +}
> > +}
> > +
> [snip]
> > +
> > +static void ospi_stig_fill_membank(XlnxVersalOspi *s)
> > +{
> > +int num_rd_bytes = ospi_stig_membank_rd_bytes(s);
> > +int idx = num_rd_bytes - 8; /* first of last 8 */
> > +int i;
> > +
> > +for (i = 0; i < num_rd_bytes; i++) {
> > +s->stig_membank[i] = fifo8_pop(&s->rx_fifo);
> > +}
> > +
> 
> Even though ospi_stig_membank_rd_bytes is safe, I would add a
> 
> g_assert((idx + 4) < ARRAY_SIZE(s->stig_membank));
> 
> here, to be future proof :-)
> 
> > +/* Fill in lower upper regs */
> > +s->regs[R_FLASH_RD_DATA_LOWER_REG] = ldl_le_p(&s->stig_membank[idx]);
> > +s->regs[R_FLASH_RD_DATA_UPPER_REG] = ldl_le_p(&s->stig_membank[idx + 
> > 4]);
> > +}
> > +
> [snip]
> > +
> > +static void ospi_tx_sram_write(XlnxVersalOspi *s, uint64_t value,
> > +   unsigned int size)
> > +{
> > +int i;
> > +for (i = 0; i < size; i++) {
> > +fifo8_push(&s->tx_sram, value >> 8 * i);
> 
> By tracing the callers of this function, it seems that `size' is the
> size of an MMIO access. But you don't seem to check if the tx_sram fifo
> can accept `size' elements (the fifo8_push doc stats it is undefined
> behaviour to push on a full fifo).
> 
> > +}
> > +}
> > +
> > +
> > +static void ospi_indac_write(void *opaque, uint64_t value, unsigned int 
> > size)
> > +{
> > +XlnxVersalOspi *s = XILINX_VERSAL_OSPI(opaque);
> > +
> > +if (s->ind_write_disabled) {
> > +g_assert_not_reached();
> > +}
> 
> g_assert(!s->ind_write_disabled);
> 
> > +
> > +if (!ospi_ind_op_completed(s->wr_ind_op)) {
> > +    ospi_tx_sram_write(s, value, size);
> > +ospi_do_indirect_write(s);
> > +} else {
> > +qemu_log_mask(LOG_GUEST_ERROR,
> > +"OSPI wr into indac area while no ongoing indac wr\n");
> > +}
> > +}
> > +
> [snip]
> > diff --git a/include/hw/ssi/xlnx-versal-ospi.h 
> > b/include/hw/ssi/xlnx-versal-ospi.h
> > new file mode 100644
> > index 00..c454ff3016
> > --- /dev/null
> > +++ b/include/hw/ssi/xlnx-versal-ospi.h
> > @@ -0,0 +1,111 @@
> > +/*
> > + * Header file for the Xilinx Versal's OSPI controller
> > + *
> > + * Copyright (C) 2021 Xilinx Inc
> > + * Written by Francisco Iglesias 
> > + *
> > + * Permission is hereby granted, free of charge, to any person obtaining a 
> > copy
> > + * of this software and associated documentation files (the "Software"), 
> > to deal
> > + * in the

Re: [PATCH v6 05/12] hw/dma: Add the DMA control interface

2022-01-21 Thread Francisco Iglesias
On [2022 Jan 18] Tue 23:01:42, Luc Michel wrote:
> Hi Francisco!
> 
> On 15:28 Fri 14 Jan , Francisco Iglesias wrote:
> > An option on real hardware when embedding a DMA engine into a peripheral
> > is to make the peripheral control the engine through a custom DMA control
> > (hardware) interface between the two. Software drivers in this scenario
> > configure and trigger DMA operations through the controlling peripheral's
> > register API (for example, writing a specific bit in a register could
> > propagate down to a transfer start signal on the DMA control interface).
> > At the same time the status, results and interrupts for the transfer might
> > still be intended to be read and caught through the DMA engine's register
> > API (and signals).
> 
> I understand the goal you trying to achieve here. Having a generic
> interface between a peripheral and the internal DMA it's using for its
> memory transfers.
> 
> I wonder however how much this scenario can be generalized. I see that
> you have only one method in this interface, which is basically "perform
> a DMA transaction". Given the method's parameters, the peripheral can
> indicate what address/length it wants to read.
> 
> IIUC this is well suited to your case (the OSPI controller), because
> other DMA parameters are configured by other means (DMA or OSPI
> registers I guess).
> 
> But how much this will suite the next use case for this interface? Will
> the embedded DMA be configured the same way? Maybe the method will also
> require e.g., the destination buffer address?
> 
> My feeling is that this interface is quite ad-hoc for your case. It is
> either going to stay really simple as it is now, and won't necessarily
> fit the next similar use case, or is going to get pretty complicated to
> cover all cases. For an added value I'm not sure I can see because the
> pair "peripheral - DMA" seems tightly coupled to me. Do you foresee a
> case where you want to be able to e.g., instantiate DMA B instead of DMA
> A for the same controller?
> 
> I think you could have basically the same code by having a pointer to
> your XlnxCSUDMA object (instead of the iface) in the OSPI struct, and a
> function like xlnx_csu_dma_start_transfer declared in xlnx_csu_dma.h,
> having the same behaviour as dma_ctrl_if_read.
> 

Hi Luc,

> Maybe I'm wrong and you actually foresee cases where the genericity this
> interface gives is what you want? What do you think?

I see your point! Lets go with what you proposed above instead then! v7 will
have taken that direction!

Thank you again for reviewing!

Best regards,
Francisco Iglesias

> 
> Luc
> 
> > 
> > This patch adds a QEMU DMA control interface that can be used for
> > modelling above scenario. Through this new interface a peripheral model
> > embedding a DMA engine model will be able to directly initiate transfers
> > through the DMA. At the same time the transfer state, result and
> > completion signaling will be read and caught through the DMA engine
> > model's register API and signaling.
> > 
> > Signed-off-by: Francisco Iglesias 
> > ---
> >  hw/dma/dma-ctrl-if.c | 30 +++
> >  hw/dma/meson.build   |  1 +
> >  include/hw/dma/dma-ctrl-if.h | 58 
> > 
> >  3 files changed, 89 insertions(+)
> >  create mode 100644 hw/dma/dma-ctrl-if.c
> >  create mode 100644 include/hw/dma/dma-ctrl-if.h
> > 
> > diff --git a/hw/dma/dma-ctrl-if.c b/hw/dma/dma-ctrl-if.c
> > new file mode 100644
> > index 00..895edac277
> > --- /dev/null
> > +++ b/hw/dma/dma-ctrl-if.c
> > @@ -0,0 +1,30 @@
> > +/*
> > + * DMA control interface.
> > + *
> > + * Copyright (c) 2021 Xilinx Inc.
> > + * Written by Francisco Iglesias 
> > + *
> > + * SPDX-License-Identifier: GPL-2.0-or-later
> > + */
> > +#include "qemu/osdep.h"
> > +#include "exec/hwaddr.h"
> > +#include "hw/dma/dma-ctrl-if.h"
> > +
> > +MemTxResult dma_ctrl_if_read(DmaCtrlIf *dma, hwaddr addr, uint32_t len)
> > +{
> > +DmaCtrlIfClass *dcic =  DMA_CTRL_IF_GET_CLASS(dma);
> > +return dcic->read(dma, addr, len);
> > +}
> > +
> > +static const TypeInfo dma_ctrl_if_info = {
> > +.name  = TYPE_DMA_CTRL_IF,
> > +.parent= TYPE_INTERFACE,
> > +.class_size = sizeof(DmaCtrlIfClass),
> > +};
> > +
> > +static void dma_ctrl_if_register_types(void)
> > +{
> > +type_register_static(&dma_ctrl_if_info);
&

[PATCH v7 03/10] hw/arm/xlnx-versal: Connect Versal's PMC SLCR

2022-01-21 Thread Francisco Iglesias
Connect Versal's PMC SLCR (system-level control registers) model.

Signed-off-by: Francisco Iglesias 
Reviewed-by: Luc Michel 
---
 include/hw/arm/xlnx-versal.h |  5 
 hw/arm/xlnx-versal.c | 71 +++-
 2 files changed, 75 insertions(+), 1 deletion(-)

diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
index 62fb6f0a68..811df73350 100644
--- a/include/hw/arm/xlnx-versal.h
+++ b/include/hw/arm/xlnx-versal.h
@@ -26,6 +26,7 @@
 #include "hw/misc/xlnx-versal-xramc.h"
 #include "hw/nvram/xlnx-bbram.h"
 #include "hw/nvram/xlnx-versal-efuse.h"
+#include "hw/misc/xlnx-versal-pmc-iou-slcr.h"
 
 #define TYPE_XLNX_VERSAL "xlnx-versal"
 OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
@@ -78,6 +79,7 @@ struct Versal {
 struct {
 struct {
 SDHCIState sd[XLNX_VERSAL_NR_SDS];
+XlnxVersalPmcIouSlcr slcr;
 } iou;
 
 XlnxZynqMPRTC rtc;
@@ -179,6 +181,9 @@ struct Versal {
 #define MM_FPD_FPD_APU  0xfd5c
 #define MM_FPD_FPD_APU_SIZE 0x100
 
+#define MM_PMC_PMC_IOU_SLCR 0xf106
+#define MM_PMC_PMC_IOU_SLCR_SIZE0x1
+
 #define MM_PMC_SD0  0xf104U
 #define MM_PMC_SD0_SIZE 0x1
 #define MM_PMC_BBRAM_CTRL   0xf11f
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
index fefd00b57c..c8c0c102c7 100644
--- a/hw/arm/xlnx-versal.c
+++ b/hw/arm/xlnx-versal.c
@@ -21,11 +21,13 @@
 #include "kvm_arm.h"
 #include "hw/misc/unimp.h"
 #include "hw/arm/xlnx-versal.h"
+#include "qemu/log.h"
+#include "hw/sysbus.h"
 
 #define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
 #define GEM_REVISION0x40070106
 
-#define VERSAL_NUM_PMC_APB_IRQS 2
+#define VERSAL_NUM_PMC_APB_IRQS 3
 
 static void versal_create_apu_cpus(Versal *s)
 {
@@ -271,6 +273,7 @@ static void versal_create_pmc_apb_irq_orgate(Versal *s, 
qemu_irq *pic)
  * models:
  *  - RTC
  *  - BBRAM
+ *  - PMC SLCR
  */
 object_initialize_child(OBJECT(s), "pmc-apb-irq-orgate",
 &s->pmc.apb_irq_orgate, TYPE_OR_IRQ);
@@ -392,6 +395,23 @@ static void versal_create_efuse(Versal *s, qemu_irq *pic)
 sysbus_connect_irq(SYS_BUS_DEVICE(ctrl), 0, pic[VERSAL_EFUSE_IRQ]);
 }
 
+static void versal_create_pmc_iou_slcr(Versal *s, qemu_irq *pic)
+{
+SysBusDevice *sbd;
+
+object_initialize_child(OBJECT(s), "versal-pmc-iou-slcr", &s->pmc.iou.slcr,
+TYPE_XILINX_VERSAL_PMC_IOU_SLCR);
+
+sbd = SYS_BUS_DEVICE(&s->pmc.iou.slcr);
+sysbus_realize(sbd, &error_fatal);
+
+memory_region_add_subregion(&s->mr_ps, MM_PMC_PMC_IOU_SLCR,
+sysbus_mmio_get_region(sbd, 0));
+
+sysbus_connect_irq(sbd, 0,
+   qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 2));
+}
+
 /* This takes the board allocated linear DDR memory and creates aliases
  * for each split DDR range/aperture on the Versal address map.
  */
@@ -448,8 +468,31 @@ static void versal_unimp_area(Versal *s, const char *name,
 memory_region_add_subregion(mr, base, mr_dev);
 }
 
+static void versal_unimp_sd_emmc_sel(void *opaque, int n, int level)
+{
+qemu_log_mask(LOG_UNIMP,
+  "Selecting between enabling SD mode or eMMC mode on "
+  "controller %d is not yet implemented\n", n);
+}
+
+static void versal_unimp_qspi_ospi_mux_sel(void *opaque, int n, int level)
+{
+qemu_log_mask(LOG_UNIMP,
+  "Selecting between enabling the QSPI or OSPI linear address "
+  "region is not yet implemented\n");
+}
+
+static void versal_unimp_irq_parity_imr(void *opaque, int n, int level)
+{
+qemu_log_mask(LOG_UNIMP,
+  "PMC SLCR parity interrupt behaviour "
+  "is not yet implemented\n");
+}
+
 static void versal_unimp(Versal *s)
 {
+qemu_irq gpio_in;
+
 versal_unimp_area(s, "psm", &s->mr_ps,
 MM_PSM_START, MM_PSM_END - MM_PSM_START);
 versal_unimp_area(s, "crl", &s->mr_ps,
@@ -464,6 +507,31 @@ static void versal_unimp(Versal *s)
 MM_IOU_SCNTR, MM_IOU_SCNTR_SIZE);
 versal_unimp_area(s, "iou-scntr-seucre", &s->mr_ps,
 MM_IOU_SCNTRS, MM_IOU_SCNTRS_SIZE);
+
+qdev_init_gpio_in_named(DEVICE(s), versal_unimp_sd_emmc_sel,
+"sd-emmc-sel-dummy", 2);
+qdev_init_gpio_in_named(DEVICE(s), versal_unimp_qspi_ospi_mux_sel,
+"qspi-ospi-mux-sel-dummy", 1);
+qdev_init_gpio_in_named(DEVICE(s), versal_unimp_irq_parity_imr,
+

[PATCH v7 10/10] MAINTAINERS: Add an entry for Xilinx Versal OSPI

2022-01-21 Thread Francisco Iglesias
List myself as maintainer for the Xilinx Versal OSPI controller.

Signed-off-by: Francisco Iglesias 
Reviewed-by: Edgar E. Iglesias 
Reviewed-by: Peter Maydell 
---
 MAINTAINERS | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index e4b3a4bcdf..6797a270e4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -958,6 +958,12 @@ F: hw/display/dpcd.c
 F: include/hw/display/dpcd.h
 F: docs/system/arm/xlnx-versal-virt.rst
 
+Xilinx Versal OSPI
+M: Francisco Iglesias 
+S: Maintained
+F: hw/ssi/xlnx-versal-ospi.c
+F: include/hw/ssi/xlnx-versal-ospi.h
+
 ARM ACPI Subsystem
 M: Shannon Zhao 
 L: qemu-...@nongnu.org
-- 
2.11.0




[PATCH v7 01/10] hw/misc: Add a model of Versal's PMC SLCR

2022-01-21 Thread Francisco Iglesias
Add a model of Versal's PMC SLCR (system-level control registers).

Signed-off-by: Francisco Iglesias 
Signed-off-by: Edgar E. Iglesias 
Reviewed-by: Peter Maydell 
Reviewed-by: Luc Michel 
---
 include/hw/misc/xlnx-versal-pmc-iou-slcr.h |   78 ++
 hw/misc/xlnx-versal-pmc-iou-slcr.c | 1446 
 hw/misc/meson.build|5 +-
 3 files changed, 1528 insertions(+), 1 deletion(-)
 create mode 100644 include/hw/misc/xlnx-versal-pmc-iou-slcr.h
 create mode 100644 hw/misc/xlnx-versal-pmc-iou-slcr.c

diff --git a/include/hw/misc/xlnx-versal-pmc-iou-slcr.h 
b/include/hw/misc/xlnx-versal-pmc-iou-slcr.h
new file mode 100644
index 00..ab4e4b4f18
--- /dev/null
+++ b/include/hw/misc/xlnx-versal-pmc-iou-slcr.h
@@ -0,0 +1,78 @@
+/*
+ * Header file for the Xilinx Versal's PMC IOU SLCR
+ *
+ * Copyright (C) 2021 Xilinx Inc
+ * Written by Edgar E. Iglesias 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/*
+ * This is a model of Xilinx Versal's PMC I/O Peripheral Control and Status
+ * module documented in Versal's Technical Reference manual [1] and the Versal
+ * ACAP Register reference [2].
+ *
+ * References:
+ *
+ * [1] Versal ACAP Technical Reference Manual,
+ * 
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
+ *
+ * QEMU interface:
+ * + sysbus MMIO region 0: MemoryRegion for the device's registers
+ * + sysbus IRQ 0: PMC (AXI and APB) parity error interrupt detected by the PMC
+ *   I/O peripherals.
+ * + sysbus IRQ 1: Device interrupt.
+ * + Named GPIO output "sd-emmc-sel[0]": Enables 0: SD mode or 1: eMMC mode on
+ *   SD/eMMC controller 0.
+ * + Named GPIO output "sd-emmc-sel[1]": Enables 0: SD mode or 1: eMMC mode on
+ *   SD/eMMC controller 1.
+ * + Named GPIO output "qspi-ospi-mux-sel": Selects 0: QSPI linear region or 1:
+ *   OSPI linear region.
+ * + Named GPIO output "ospi-mux-sel": Selects 0: OSPI Indirect access mode or
+ *   1: OSPI direct access mode.
+ */
+
+#ifndef XILINX_VERSAL_PMC_IOU_SLCR_H
+#define XILINX_VERSAL_PMC_IOU_SLCR_H
+
+#include "hw/register.h"
+
+#define TYPE_XILINX_VERSAL_PMC_IOU_SLCR "xlnx.versal-pmc-iou-slcr"
+
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalPmcIouSlcr, XILINX_VERSAL_PMC_IOU_SLCR)
+
+#define XILINX_VERSAL_PMC_IOU_SLCR_R_MAX (0x828 / 4 + 1)
+
+struct XlnxVersalPmcIouSlcr {
+SysBusDevice parent_obj;
+MemoryRegion iomem;
+qemu_irq irq_parity_imr;
+qemu_irq irq_imr;
+qemu_irq sd_emmc_sel[2];
+qemu_irq qspi_ospi_mux_sel;
+qemu_irq ospi_mux_sel;
+
+uint32_t regs[XILINX_VERSAL_PMC_IOU_SLCR_R_MAX];
+RegisterInfo regs_info[XILINX_VERSAL_PMC_IOU_SLCR_R_MAX];
+};
+
+#endif /* XILINX_VERSAL_PMC_IOU_SLCR_H */
diff --git a/hw/misc/xlnx-versal-pmc-iou-slcr.c 
b/hw/misc/xlnx-versal-pmc-iou-slcr.c
new file mode 100644
index 00..07b7ebc217
--- /dev/null
+++ b/hw/misc/xlnx-versal-pmc-iou-slcr.c
@@ -0,0 +1,1446 @@
+/*
+ * QEMU model of Versal's PMC IOU SLCR (system level control registers)
+ *
+ * Copyright (c) 2021 Xilinx Inc.
+ * Written by Edgar E. Iglesias 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial 

[PATCH v7 04/10] include/hw/dma/xlnx_csu_dma: Add in missing includes in the header

2022-01-21 Thread Francisco Iglesias
Add in the missing includes in the header for being able to build the DMA
model when reusing it.

Signed-off-by: Francisco Iglesias 
Reviewed-by: Peter Maydell 
Reviewed-by: Luc Michel 
---
 include/hw/dma/xlnx_csu_dma.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/include/hw/dma/xlnx_csu_dma.h b/include/hw/dma/xlnx_csu_dma.h
index 9e9dc551e9..28806628b1 100644
--- a/include/hw/dma/xlnx_csu_dma.h
+++ b/include/hw/dma/xlnx_csu_dma.h
@@ -21,6 +21,11 @@
 #ifndef XLNX_CSU_DMA_H
 #define XLNX_CSU_DMA_H
 
+#include "hw/sysbus.h"
+#include "hw/register.h"
+#include "hw/ptimer.h"
+#include "hw/stream.h"
+
 #define TYPE_XLNX_CSU_DMA "xlnx.csu_dma"
 
 #define XLNX_CSU_DMA_R_MAX (0x2c / 4)
-- 
2.11.0




[PATCH v7 06/10] hw/ssi: Add a model of Xilinx Versal's OSPI flash memory controller

2022-01-21 Thread Francisco Iglesias
Add a model of Xilinx Versal's OSPI flash memory controller.

Signed-off-by: Francisco Iglesias 
---
 include/hw/ssi/xlnx-versal-ospi.h |  111 +++
 hw/ssi/xlnx-versal-ospi.c | 1853 +
 hw/ssi/meson.build|1 +
 3 files changed, 1965 insertions(+)
 create mode 100644 include/hw/ssi/xlnx-versal-ospi.h
 create mode 100644 hw/ssi/xlnx-versal-ospi.c

diff --git a/include/hw/ssi/xlnx-versal-ospi.h 
b/include/hw/ssi/xlnx-versal-ospi.h
new file mode 100644
index 00..14d1263497
--- /dev/null
+++ b/include/hw/ssi/xlnx-versal-ospi.h
@@ -0,0 +1,111 @@
+/*
+ * Header file for the Xilinx Versal's OSPI controller
+ *
+ * Copyright (C) 2021 Xilinx Inc
+ * Written by Francisco Iglesias 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/*
+ * This is a model of Xilinx Versal's Octal SPI flash memory controller
+ * documented in Versal's Technical Reference manual [1] and the Versal ACAP
+ * Register reference [2].
+ *
+ * References:
+ *
+ * [1] Versal ACAP Technical Reference Manual,
+ * 
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
+ *
+ *
+ * QEMU interface:
+ * + sysbus MMIO region 0: MemoryRegion for the device's registers
+ * + sysbus MMIO region 1: MemoryRegion for flash memory linear address space
+ *   (data transfer).
+ * + sysbus IRQ 0: Device interrupt.
+ * + Named GPIO input "ospi-mux-sel": 0: enables indirect access mode
+ *   and 1: enables direct access mode.
+ * + Property "dac-with-indac": Allow both direct accesses and indirect
+ *   accesses simultaneously.
+ * + Property "indac-write-disabled": Disable indirect access writes.
+ */
+
+#ifndef XILINX_VERSAL_OSPI_H
+#define XILINX_VERSAL_OSPI_H
+
+#include "hw/register.h"
+#include "hw/ssi/ssi.h"
+#include "qemu/fifo8.h"
+#include "hw/dma/xlnx_csu_dma.h"
+
+#define TYPE_XILINX_VERSAL_OSPI "xlnx.versal-ospi"
+
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalOspi, XILINX_VERSAL_OSPI)
+
+#define XILINX_VERSAL_OSPI_R_MAX (0xfc / 4 + 1)
+
+/*
+ * Indirect operations
+ */
+typedef struct IndOp {
+uint32_t flash_addr;
+uint32_t num_bytes;
+uint32_t done_bytes;
+bool completed;
+} IndOp;
+
+struct XlnxVersalOspi {
+SysBusDevice parent_obj;
+
+MemoryRegion iomem;
+MemoryRegion iomem_dac;
+
+uint8_t num_cs;
+qemu_irq *cs_lines;
+
+SSIBus *spi;
+
+Fifo8 rx_fifo;
+Fifo8 tx_fifo;
+
+Fifo8 rx_sram;
+Fifo8 tx_sram;
+
+qemu_irq irq;
+
+XlnxCSUDMA *dma_src;
+bool ind_write_disabled;
+bool dac_with_indac;
+bool dac_enable;
+bool src_dma_inprog;
+
+IndOp rd_ind_op[2];
+IndOp wr_ind_op[2];
+
+uint32_t regs[XILINX_VERSAL_OSPI_R_MAX];
+RegisterInfo regs_info[XILINX_VERSAL_OSPI_R_MAX];
+
+/* Maximum inferred membank size is 512 bytes */
+uint8_t stig_membank[512];
+};
+
+#endif /* XILINX_VERSAL_OSPI_H */
diff --git a/hw/ssi/xlnx-versal-ospi.c b/hw/ssi/xlnx-versal-ospi.c
new file mode 100644
index 00..2718b4a12c
--- /dev/null
+++ b/hw/ssi/xlnx-versal-ospi.c
@@ -0,0 +1,1853 @@
+/*
+ * QEMU model of Xilinx Versal's OSPI controller.
+ *
+ * Copyright (c) 2021 Xilinx Inc.
+ * Written by Francisco Iglesias 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the fol

[PATCH v7 08/10] hw/block/m25p80: Add support for Micron Xccela flash mt35xu01g

2022-01-21 Thread Francisco Iglesias
Add support for Micron Xccela flash mt35xu01g.

Signed-off-by: Francisco Iglesias 
Reviewed-by: Edgar E. Iglesias 
---
 hw/block/m25p80.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index b77503dc84..c6bf3c6bfa 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -255,6 +255,8 @@ static const FlashPartInfo known_devices[] = {
 { INFO("n25q512a",0x20ba20,  0,  64 << 10, 1024, ER_4K) },
 { INFO("n25q512ax3",  0x20ba20,  0x1000,  64 << 10, 1024, ER_4K) },
 { INFO("mt25ql512ab", 0x20ba20, 0x1044, 64 << 10, 1024, ER_4K | ER_32K) },
+{ INFO_STACKED("mt35xu01g", 0x2c5b1b, 0x104100, 128 << 10, 1024,
+   ER_4K | ER_32K, 2) },
 { INFO_STACKED("n25q00",0x20ba21, 0x1000, 64 << 10, 2048, ER_4K, 4) },
 { INFO_STACKED("n25q00a",   0x20bb21, 0x1000, 64 << 10, 2048, ER_4K, 4) },
 { INFO_STACKED("mt25ql01g", 0x20ba21, 0x1040, 64 << 10, 2048, ER_4K, 2) },
-- 
2.11.0




[PATCH v7 05/10] hw/dma/xlnx_csu_dma: Support starting a read transfer through a class method

2022-01-21 Thread Francisco Iglesias
An option on real hardware when embedding a DMA engine into a peripheral
is to make the peripheral control the engine through a custom DMA control
(hardware) interface between the two. Software drivers in this scenario
configure and trigger DMA operations through the controlling peripheral's
register API (for example, writing a specific bit in a register could
propagate down to a transfer start signal on the DMA control interface).
At the same time the status, results and interrupts for the transfer might
still be intended to be read and caught through the DMA engine's register
API (and signals).

This patch adds a class 'read' method for allowing to start read transfers
from peripherals embedding and controlling the Xilinx CSU DMA engine as in
above scenario.

Signed-off-by: Francisco Iglesias 
---
 include/hw/dma/xlnx_csu_dma.h | 19 +--
 hw/dma/xlnx_csu_dma.c | 17 +
 2 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/include/hw/dma/xlnx_csu_dma.h b/include/hw/dma/xlnx_csu_dma.h
index 28806628b1..922ab80eb6 100644
--- a/include/hw/dma/xlnx_csu_dma.h
+++ b/include/hw/dma/xlnx_csu_dma.h
@@ -51,7 +51,22 @@ typedef struct XlnxCSUDMA {
 RegisterInfo regs_info[XLNX_CSU_DMA_R_MAX];
 } XlnxCSUDMA;
 
-#define XLNX_CSU_DMA(obj) \
-OBJECT_CHECK(XlnxCSUDMA, (obj), TYPE_XLNX_CSU_DMA)
+OBJECT_DECLARE_TYPE(XlnxCSUDMA, XlnxCSUDMAClass, XLNX_CSU_DMA)
+
+struct XlnxCSUDMAClass {
+SysBusDeviceClass parent_class;
+
+/*
+ * read: Start a read transfer on a Xilinx CSU DMA engine
+ *
+ * @s: the Xilinx CSU DMA engine to start the transfer on
+ * @addr: the address to read
+ * @len: the number of bytes to read at 'addr'
+ *
+ * @return a MemTxResult indicating whether the operation succeeded ('len'
+ * bytes were read) or failed.
+ */
+MemTxResult (*read)(XlnxCSUDMA *s, hwaddr addr, uint32_t len);
+};
 
 #endif
diff --git a/hw/dma/xlnx_csu_dma.c b/hw/dma/xlnx_csu_dma.c
index 896bb3574d..095f954476 100644
--- a/hw/dma/xlnx_csu_dma.c
+++ b/hw/dma/xlnx_csu_dma.c
@@ -472,6 +472,20 @@ static uint64_t addr_msb_pre_write(RegisterInfo *reg, 
uint64_t val)
 return val & R_ADDR_MSB_ADDR_MSB_MASK;
 }
 
+static MemTxResult xlnx_csu_dma_class_read(XlnxCSUDMA *s, hwaddr addr,
+   uint32_t len)
+{
+RegisterInfo *reg = &s->regs_info[R_SIZE];
+uint64_t we = MAKE_64BIT_MASK(0, 4 * 8);
+
+s->regs[R_ADDR] = addr;
+s->regs[R_ADDR_MSB] = (uint64_t)addr >> 32;
+
+register_write(reg, len, we, object_get_typename(OBJECT(s)), false);
+
+return (s->regs[R_SIZE] == 0) ? MEMTX_OK : MEMTX_ERROR;
+}
+
 static const RegisterAccessInfo *xlnx_csu_dma_regs_info[] = {
 #define DMACH_REGINFO(NAME, snd)  \
 (const RegisterAccessInfo []) {   \
@@ -696,6 +710,7 @@ static void xlnx_csu_dma_class_init(ObjectClass *klass, 
void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
 StreamSinkClass *ssc = STREAM_SINK_CLASS(klass);
+XlnxCSUDMAClass *xcdc = XLNX_CSU_DMA_CLASS(klass);
 
 dc->reset = xlnx_csu_dma_reset;
 dc->realize = xlnx_csu_dma_realize;
@@ -704,6 +719,8 @@ static void xlnx_csu_dma_class_init(ObjectClass *klass, 
void *data)
 
 ssc->push = xlnx_csu_dma_stream_push;
 ssc->can_push = xlnx_csu_dma_stream_can_push;
+
+xcdc->read = xlnx_csu_dma_class_read;
 }
 
 static void xlnx_csu_dma_init(Object *obj)
-- 
2.11.0




[PATCH v7 07/10] hw/arm/xlnx-versal: Connect the OSPI flash memory controller model

2022-01-21 Thread Francisco Iglesias
Connect the OSPI flash memory controller model (including the source and
destination DMA).

Signed-off-by: Francisco Iglesias 
Reviewed-by: Peter Maydell 
---
 include/hw/arm/xlnx-versal.h | 20 ++
 hw/arm/xlnx-versal.c | 93 
 2 files changed, 113 insertions(+)

diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
index 811df73350..1b5ad4de80 100644
--- a/include/hw/arm/xlnx-versal.h
+++ b/include/hw/arm/xlnx-versal.h
@@ -26,6 +26,8 @@
 #include "hw/misc/xlnx-versal-xramc.h"
 #include "hw/nvram/xlnx-bbram.h"
 #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-pmc-iou-slcr.h"
 
 #define TYPE_XLNX_VERSAL "xlnx-versal"
@@ -80,6 +82,14 @@ struct Versal {
 struct {
 SDHCIState sd[XLNX_VERSAL_NR_SDS];
 XlnxVersalPmcIouSlcr slcr;
+
+struct {
+XlnxVersalOspi ospi;
+XlnxCSUDMA dma_src;
+XlnxCSUDMA dma_dst;
+MemoryRegion linear_mr;
+qemu_or_irq irq_orgate;
+} ospi;
 } iou;
 
 XlnxZynqMPRTC rtc;
@@ -116,6 +126,7 @@ struct Versal {
 #define VERSAL_ADMA_IRQ_0  60
 #define VERSAL_XRAM_IRQ_0  79
 #define VERSAL_PMC_APB_IRQ 121
+#define VERSAL_OSPI_IRQ124
 #define VERSAL_SD0_IRQ_0   126
 #define VERSAL_EFUSE_IRQ   139
 #define VERSAL_RTC_ALARM_IRQ   142
@@ -184,6 +195,15 @@ struct Versal {
 #define MM_PMC_PMC_IOU_SLCR 0xf106
 #define MM_PMC_PMC_IOU_SLCR_SIZE0x1
 
+#define MM_PMC_OSPI 0xf101
+#define MM_PMC_OSPI_SIZE0x1
+
+#define MM_PMC_OSPI_DAC 0xc000
+#define MM_PMC_OSPI_DAC_SIZE0x2000
+
+#define MM_PMC_OSPI_DMA_DST 0xf1011800
+#define MM_PMC_OSPI_DMA_SRC 0xf1011000
+
 #define MM_PMC_SD0  0xf104U
 #define MM_PMC_SD0_SIZE 0x1
 #define MM_PMC_BBRAM_CTRL   0xf11f
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
index c8c0c102c7..ab58bebfd2 100644
--- a/hw/arm/xlnx-versal.c
+++ b/hw/arm/xlnx-versal.c
@@ -28,6 +28,7 @@
 #define GEM_REVISION0x40070106
 
 #define VERSAL_NUM_PMC_APB_IRQS 3
+#define NUM_OSPI_IRQ_LINES 3
 
 static void versal_create_apu_cpus(Versal *s)
 {
@@ -412,6 +413,97 @@ static void versal_create_pmc_iou_slcr(Versal *s, qemu_irq 
*pic)
qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 2));
 }
 
+static void versal_create_ospi(Versal *s, qemu_irq *pic)
+{
+SysBusDevice *sbd;
+MemoryRegion *mr_dac;
+qemu_irq ospi_mux_sel;
+DeviceState *orgate;
+
+memory_region_init(&s->pmc.iou.ospi.linear_mr, OBJECT(s),
+   "versal-ospi-linear-mr" , MM_PMC_OSPI_DAC_SIZE);
+
+object_initialize_child(OBJECT(s), "versal-ospi", &s->pmc.iou.ospi.ospi,
+TYPE_XILINX_VERSAL_OSPI);
+
+mr_dac = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi), 1);
+memory_region_add_subregion(&s->pmc.iou.ospi.linear_mr, 0x0, mr_dac);
+
+/* Create the OSPI destination DMA */
+object_initialize_child(OBJECT(s), "versal-ospi-dma-dst",
+&s->pmc.iou.ospi.dma_dst,
+TYPE_XLNX_CSU_DMA);
+
+object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_dst),
+"dma", OBJECT(get_system_memory()),
+ &error_abort);
+
+sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_dst);
+sysbus_realize(sbd, &error_fatal);
+
+memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DMA_DST,
+sysbus_mmio_get_region(sbd, 0));
+
+/* Create the OSPI source DMA */
+object_initialize_child(OBJECT(s), "versal-ospi-dma-src",
+&s->pmc.iou.ospi.dma_src,
+TYPE_XLNX_CSU_DMA);
+
+object_property_set_bool(OBJECT(&s->pmc.iou.ospi.dma_src), "is-dst",
+ false, &error_abort);
+
+object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_src),
+"dma", OBJECT(mr_dac), &error_abort);
+
+object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_src),
+"stream-connected-dma",
+ OBJECT(&s->pmc.iou.ospi.dma_dst),
+ &error_abort);
+
+sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_src);
+sysbus_realize(sbd, &error_fatal);
+
+memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DMA_SRC,
+sys

[PATCH v7 09/10] hw/arm/xlnx-versal-virt: Connect mt35xu01g flashes to the OSPI

2022-01-21 Thread Francisco Iglesias
Connect Micron Xccela mt35xu01g flashes to the OSPI flash memory
controller.

Signed-off-by: Francisco Iglesias 
Reviewed-by: Edgar E. Iglesias 
Reviewed-by: Peter Maydell 
---
 hw/arm/xlnx-versal-virt.c | 23 +++
 1 file changed, 23 insertions(+)

diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
index 8ea9979710..3f56ae28ee 100644
--- a/hw/arm/xlnx-versal-virt.c
+++ b/hw/arm/xlnx-versal-virt.c
@@ -25,6 +25,8 @@
 #define TYPE_XLNX_VERSAL_VIRT_MACHINE MACHINE_TYPE_NAME("xlnx-versal-virt")
 OBJECT_DECLARE_SIMPLE_TYPE(VersalVirt, XLNX_VERSAL_VIRT_MACHINE)
 
+#define XLNX_VERSAL_NUM_OSPI_FLASH 4
+
 struct VersalVirt {
 MachineState parent_obj;
 
@@ -691,6 +693,27 @@ static void versal_virt_init(MachineState *machine)
 exit(EXIT_FAILURE);
 }
 }
+
+for (i = 0; i < XLNX_VERSAL_NUM_OSPI_FLASH; i++) {
+BusState *spi_bus;
+DeviceState *flash_dev;
+qemu_irq cs_line;
+DriveInfo *dinfo = drive_get(IF_MTD, 0, i);
+
+spi_bus = qdev_get_child_bus(DEVICE(&s->soc.pmc.iou.ospi), "spi0");
+
+flash_dev = qdev_new("mt35xu01g");
+if (dinfo) {
+qdev_prop_set_drive_err(flash_dev, "drive",
+blk_by_legacy_dinfo(dinfo), &error_fatal);
+}
+qdev_realize_and_unref(flash_dev, spi_bus, &error_fatal);
+
+cs_line = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
+
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->soc.pmc.iou.ospi),
+   i + 1, cs_line);
+}
 }
 
 static void versal_virt_machine_instance_init(Object *obj)
-- 
2.11.0




[PATCH v7 00/10] Xilinx Versal's PMC SLCR and OSPI support

2022-01-21 Thread Francisco Iglesias
Hi,

This series attempts to add support for Xilinx Versal's PMC SLCR
(system-level control registers) and OSPI flash memory controller to
Xilinx Versal virt machine.

The series start with adding a model of Versal's PMC SLCR and connecting
the model to the Versal virt machine. The series then adds a couple of
headers into the xlnx_csu_dma.h needed for building and reusing it later
with the OSPI. The series thereafter introduces a DMA control interface
and implements the interface in the xlnx_csu_dma for being able to reuse
and control the DMA with the OSPI controller. Thereafter a model of
Versal's OSPI controller is added and connected to the Versal virt
machine. The series then ends with adding initial support for the Micron
Xccelera mt35xu01g flash and flashes of this type are connected to the
OSPI in the Versal virt machine.

Best regards,
Francisco Iglesias

Changelog:
v6 -> v7:
  * Remove the DMA control interface
  * Add a class read method to the Xilinx CSU DMA and start read transfers from
OSPI model through this method (replacing the DMA control interface)

v5 -> v6:
  * Corrected unimplemented log messages (patch: "hw/arm/xlnx-versal: Connect
Versal's PMC SLCR")
  * Modify dma_ctrl_if_read to return a MemTxResult carrying the result of the
read operation
  * Updated (and corrected) documentation

v4 -> v5
  * Use named GPIOs for "sd-emmc-sel", "qspi-ospi-mux-sel", "ospi-mux-sel"
in the PMC SLCR model
  * Add a QEMU interface comment for the PMC SLCR model.
  * Switch to use OBJECT_DECLARE_SIMPLE_TYPE in both "xlnx-versal-ospi.h"
and "xlnx-versal-pmc-iou-slcr.h"
  * Create a new patch 'or'ing the interrupts from the BBRAM and RTC model
  * 'Or' the interrupt from the PMC SLCR with the BBRAM and RTC interrupt
inside 'xlnx-versal.c'
  * Connect other not yet implemented PMC SLCR GPIOs to unimplemented messages
  * Reworked and simplified the DMA control interface by removing the
notifier and refill mechanism
  * Corrected various typos and grammatical errors in the DMA control
interface documentation and comments
  * Updated the DMA control interface documentation to describe the new
simplified implementation
  * Use ldl_le_p and ldq_le_p in the OSPI model (and remove the OSPIRdData
union). Also assert in the locations that we are not overruning the
new bytes buffer.
  * Correct the single_cs function in the OSPI model (both comment and output)
  * Correct a typo in a comment inside ospi_do_indirect_write
(s/boundery/boundary/)
  * Remove an unecesary assert in the OSPI model
  * Add a QEMU interface comment for the OSPI model.
  * Rename the OSPI irq in 'xlnx-versal.c' to include 'orgate' in the name for
clarifying

v3 -> v4
  * Correct indentation (patch: "hw/arm/xlnx-versal: Connect Versal's PMC
SLCR")

  * Rename to include "If" in names related to the DMA control interface
  * In dma-ctrl-if.h:
- Don't include qemu-common.h
- Use DECLARE_CLASS_CHECKERS dma-ctrl.h
  * Add a docs/devel documentation patch for the DMA control interface
  * Improve git messages on the dma-ctrl-if patches


v2 -> v3
  * Correct and also include hw/sysbus.h and hw/register.h into
xlnx_csu_dma.h (patch: "include/hw/dma/xlnx_csu_dma: Add in missing
includes in the header")

v1 -> v2
  * Correct the reset in the PMC SLCR model
  * Create a sub structure for the OSPI in the Versal structure (in patch:
"hw/arm/xlnx-versal: Connect the OSPI flash memory controller model")
  * Change to use 'drive_get' instead of 'drive_get_next' (in patch:
"hw/arm/xlnx-versal-virt: Connect mt35xu01g flashes to the OSPI")
  * Add a maintainers patch and list myself as maintainer for the OSPI
controller


Francisco Iglesias (10):
  hw/misc: Add a model of Versal's PMC SLCR
  hw/arm/xlnx-versal: 'Or' the interrupts from the BBRAM and RTC models
  hw/arm/xlnx-versal: Connect Versal's PMC SLCR
  include/hw/dma/xlnx_csu_dma: Add in missing includes in the header
  hw/dma/xlnx_csu_dma: Support starting a read transfer through a class
method
  hw/ssi: Add a model of Xilinx Versal's OSPI flash memory controller
  hw/arm/xlnx-versal: Connect the OSPI flash memory controller model
  hw/block/m25p80: Add support for Micron Xccela flash mt35xu01g
  hw/arm/xlnx-versal-virt: Connect mt35xu01g flashes to the OSPI
  MAINTAINERS: Add an entry for Xilinx Versal OSPI

 include/hw/arm/xlnx-versal.h   |   30 +-
 include/hw/dma/xlnx_csu_dma.h  |   24 +-
 include/hw/misc/xlnx-versal-pmc-iou-slcr.h |   78 ++
 include/hw/ssi/xlnx-versal-ospi.h  |  111 ++
 hw/arm/xlnx-versal-virt.c  |   25 +-
 hw/arm/xlnx-versal.c   |  190 ++-
 hw/block/m25p80.c 

[PATCH v7 02/10] hw/arm/xlnx-versal: 'Or' the interrupts from the BBRAM and RTC models

2022-01-21 Thread Francisco Iglesias
Add an orgate and 'or' the interrupts from the BBRAM and RTC models.

Signed-off-by: Francisco Iglesias 
Reviewed-by: Peter Maydell 
Reviewed-by: Luc Michel 
---
 include/hw/arm/xlnx-versal.h |  5 +++--
 hw/arm/xlnx-versal-virt.c|  2 +-
 hw/arm/xlnx-versal.c | 28 ++--
 3 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
index 895ba12c61..62fb6f0a68 100644
--- a/include/hw/arm/xlnx-versal.h
+++ b/include/hw/arm/xlnx-versal.h
@@ -85,6 +85,8 @@ struct Versal {
 XlnxEFuse efuse;
 XlnxVersalEFuseCtrl efuse_ctrl;
 XlnxVersalEFuseCache efuse_cache;
+
+qemu_or_irq apb_irq_orgate;
 } pmc;
 
 struct {
@@ -111,8 +113,7 @@ struct Versal {
 #define VERSAL_GEM1_WAKE_IRQ_0 59
 #define VERSAL_ADMA_IRQ_0  60
 #define VERSAL_XRAM_IRQ_0  79
-#define VERSAL_BBRAM_APB_IRQ_0 121
-#define VERSAL_RTC_APB_ERR_IRQ 121
+#define VERSAL_PMC_APB_IRQ 121
 #define VERSAL_SD0_IRQ_0   126
 #define VERSAL_EFUSE_IRQ   139
 #define VERSAL_RTC_ALARM_IRQ   142
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
index 0c5edc898e..8ea9979710 100644
--- a/hw/arm/xlnx-versal-virt.c
+++ b/hw/arm/xlnx-versal-virt.c
@@ -365,7 +365,7 @@ static void fdt_add_bbram_node(VersalVirt *s)
 qemu_fdt_add_subnode(s->fdt, name);
 
 qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
-   GIC_FDT_IRQ_TYPE_SPI, VERSAL_BBRAM_APB_IRQ_0,
+   GIC_FDT_IRQ_TYPE_SPI, VERSAL_PMC_APB_IRQ,
GIC_FDT_IRQ_FLAGS_LEVEL_HI);
 qemu_fdt_setprop(s->fdt, name, "interrupt-names",
  interrupt_names, sizeof(interrupt_names));
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
index b2705b6925..fefd00b57c 100644
--- a/hw/arm/xlnx-versal.c
+++ b/hw/arm/xlnx-versal.c
@@ -25,6 +25,8 @@
 #define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
 #define GEM_REVISION0x40070106
 
+#define VERSAL_NUM_PMC_APB_IRQS 2
+
 static void versal_create_apu_cpus(Versal *s)
 {
 int i;
@@ -260,6 +262,25 @@ static void versal_create_sds(Versal *s, qemu_irq *pic)
 }
 }
 
+static void versal_create_pmc_apb_irq_orgate(Versal *s, qemu_irq *pic)
+{
+DeviceState *orgate;
+
+/*
+ * The VERSAL_PMC_APB_IRQ is an 'or' of the interrupts from the following
+ * models:
+ *  - RTC
+ *  - BBRAM
+ */
+object_initialize_child(OBJECT(s), "pmc-apb-irq-orgate",
+&s->pmc.apb_irq_orgate, TYPE_OR_IRQ);
+orgate = DEVICE(&s->pmc.apb_irq_orgate);
+object_property_set_int(OBJECT(orgate),
+"num-lines", VERSAL_NUM_PMC_APB_IRQS, 
&error_fatal);
+qdev_realize(orgate, NULL, &error_fatal);
+qdev_connect_gpio_out(orgate, 0, pic[VERSAL_PMC_APB_IRQ]);
+}
+
 static void versal_create_rtc(Versal *s, qemu_irq *pic)
 {
 SysBusDevice *sbd;
@@ -277,7 +298,8 @@ static void versal_create_rtc(Versal *s, qemu_irq *pic)
  * TODO: Connect the ALARM and SECONDS interrupts once our RTC model
  * supports them.
  */
-sysbus_connect_irq(sbd, 1, pic[VERSAL_RTC_APB_ERR_IRQ]);
+sysbus_connect_irq(sbd, 1,
+   qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 0));
 }
 
 static void versal_create_xrams(Versal *s, qemu_irq *pic)
@@ -328,7 +350,8 @@ static void versal_create_bbram(Versal *s, qemu_irq *pic)
 sysbus_realize(sbd, &error_fatal);
 memory_region_add_subregion(&s->mr_ps, MM_PMC_BBRAM_CTRL,
 sysbus_mmio_get_region(sbd, 0));
-sysbus_connect_irq(sbd, 0, pic[VERSAL_BBRAM_APB_IRQ_0]);
+sysbus_connect_irq(sbd, 0,
+   qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 1));
 }
 
 static void versal_realize_efuse_part(Versal *s, Object *dev, hwaddr base)
@@ -455,6 +478,7 @@ static void versal_realize(DeviceState *dev, Error **errp)
 versal_create_gems(s, pic);
 versal_create_admas(s, pic);
 versal_create_sds(s, pic);
+versal_create_pmc_apb_irq_orgate(s, pic);
 versal_create_rtc(s, pic);
 versal_create_xrams(s, pic);
 versal_create_bbram(s, pic);
-- 
2.11.0




Re: [PATCH v7 00/10] Xilinx Versal's PMC SLCR and OSPI support

2022-01-27 Thread Francisco Iglesias
On Thu, Jan 27, 2022 at 05:27:55PM +, Peter Maydell wrote:
> On Fri, 21 Jan 2022 at 16:11, Francisco Iglesias
>  wrote:
> >
> > Hi,
> >
> > This series attempts to add support for Xilinx Versal's PMC SLCR
> > (system-level control registers) and OSPI flash memory controller to
> > Xilinx Versal virt machine.
> >
> > The series start with adding a model of Versal's PMC SLCR and connecting
> > the model to the Versal virt machine. The series then adds a couple of
> > headers into the xlnx_csu_dma.h needed for building and reusing it later
> > with the OSPI. The series thereafter introduces a DMA control interface
> > and implements the interface in the xlnx_csu_dma for being able to reuse
> > and control the DMA with the OSPI controller. Thereafter a model of
> > Versal's OSPI controller is added and connected to the Versal virt
> > machine. The series then ends with adding initial support for the Micron
> > Xccelera mt35xu01g flash and flashes of this type are connected to the
> > OSPI in the Versal virt machine.
> 
> 

Hi Peter,

> Applied to target-arm.next, thanks. (I fixed the indent issue
> Luc noticed in patch 6.)

Thanks a lot for above Peter! :) Also, thank you everybody for taking the
time to review and providing me great feedback! 

Best regards,
Francisco Iglesias

> 
> -- PMM



Re: [PATCH v3] hw: m25p80: allow write_enable latch get/set

2022-05-13 Thread Francisco Iglesias
On [2022 May 12] Thu 22:50:22, Iris Chen via wrote:
> The write_enable latch property is not currently exposed.
> This commit makes it a modifiable property.
> 
> Signed-off-by: Iris Chen 
> ---
> v3: Addressed comments by Peter and Cedric.
> v2: Ran ./scripts/checkpatch.pl on the patch and added a description. Fixed 
> comments regarding DEFINE_PROP_BOOL.
> 
>  hw/block/m25p80.c  |  1 +
>  tests/qtest/aspeed_gpio-test.c | 40 +++
>  tests/qtest/aspeed_smc-test.c  | 43 ++
>  tests/qtest/libqtest.c | 24 +++
>  tests/qtest/libqtest.h | 22 +
>  5 files changed, 98 insertions(+), 32 deletions(-)
> 
> diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
> index 430d1298a8..4283b990af 100644
> --- a/hw/block/m25p80.c
> +++ b/hw/block/m25p80.c
> @@ -1558,6 +1558,7 @@ static int m25p80_pre_save(void *opaque)
>  
>  static Property m25p80_properties[] = {
>  /* This is default value for Micron flash */
> +DEFINE_PROP_BOOL("write-enable", Flash, write_enable, false),

Reviewed-by: Francisco Iglesias 

>  DEFINE_PROP_UINT32("nonvolatile-cfg", Flash, nonvolatile_cfg, 0x8FFF),
>  DEFINE_PROP_UINT8("spansion-cr1nv", Flash, spansion_cr1nv, 0x0),
>  DEFINE_PROP_UINT8("spansion-cr2nv", Flash, spansion_cr2nv, 0x8),
> diff --git a/tests/qtest/aspeed_gpio-test.c b/tests/qtest/aspeed_gpio-test.c
> index c1003f2d1b..bac63e8742 100644
> --- a/tests/qtest/aspeed_gpio-test.c
> +++ b/tests/qtest/aspeed_gpio-test.c
> @@ -28,30 +28,6 @@
>  #include "qapi/qmp/qdict.h"
>  #include "libqtest-single.h"
>  
> -static bool qom_get_bool(QTestState *s, const char *path, const char 
> *property)
> -{
> -QDict *r;
> -bool b;
> -
> -r = qtest_qmp(s, "{ 'execute': 'qom-get', 'arguments': "
> - "{ 'path': %s, 'property': %s } }", path, property);
> -b = qdict_get_bool(r, "return");
> -qobject_unref(r);
> -
> -return b;
> -}
> -
> -static void qom_set_bool(QTestState *s, const char *path, const char 
> *property,
> - bool value)
> -{
> -QDict *r;
> -
> -r = qtest_qmp(s, "{ 'execute': 'qom-set', 'arguments': "
> - "{ 'path': %s, 'property': %s, 'value': %i } }",
> - path, property, value);
> -qobject_unref(r);
> -}
> -
>  static void test_set_colocated_pins(const void *data)
>  {
>  QTestState *s = (QTestState *)data;
> @@ -60,14 +36,14 @@ static void test_set_colocated_pins(const void *data)
>   * gpioV4-7 occupy bits within a single 32-bit value, so we want to make
>   * sure that modifying one doesn't affect the other.
>   */
> -qom_set_bool(s, "/machine/soc/gpio", "gpioV4", true);
> -qom_set_bool(s, "/machine/soc/gpio", "gpioV5", false);
> -qom_set_bool(s, "/machine/soc/gpio", "gpioV6", true);
> -qom_set_bool(s, "/machine/soc/gpio", "gpioV7", false);
> -g_assert(qom_get_bool(s, "/machine/soc/gpio", "gpioV4"));
> -g_assert(!qom_get_bool(s, "/machine/soc/gpio", "gpioV5"));
> -g_assert(qom_get_bool(s, "/machine/soc/gpio", "gpioV6"));
> -g_assert(!qom_get_bool(s, "/machine/soc/gpio", "gpioV7"));
> +qtest_qom_set_bool(s, "/machine/soc/gpio", "gpioV4", true);
> +qtest_qom_set_bool(s, "/machine/soc/gpio", "gpioV5", false);
> +qtest_qom_set_bool(s, "/machine/soc/gpio", "gpioV6", true);
> +qtest_qom_set_bool(s, "/machine/soc/gpio", "gpioV7", false);
> +g_assert(qtest_qom_get_bool(s, "/machine/soc/gpio", "gpioV4"));
> +g_assert(!qtest_qom_get_bool(s, "/machine/soc/gpio", "gpioV5"));
> +g_assert(qtest_qom_get_bool(s, "/machine/soc/gpio", "gpioV6"));
> +g_assert(!qtest_qom_get_bool(s, "/machine/soc/gpio", "gpioV7"));
>  }
>  
>  int main(int argc, char **argv)
> diff --git a/tests/qtest/aspeed_smc-test.c b/tests/qtest/aspeed_smc-test.c
> index 87b40a0ef1..ec233315e6 100644
> --- a/tests/qtest/aspeed_smc-test.c
> +++ b/tests/qtest/aspeed_smc-test.c
> @@ -26,6 +26,7 @@
>  #include "qemu/osdep.h"
>  #include "qemu/bswap.h"
>  #include "libqtest-single.h"
> +#include &quo

Re: [PATCH] ptimer: Rename PTIMER_POLICY_DEFAULT to PTIMER_POLICY_LEGACY

2022-05-16 Thread Francisco Iglesias
os4210_pwm.c
> index 220088120ee..02924a9e5b3 100644
> --- a/hw/timer/exynos4210_pwm.c
> +++ b/hw/timer/exynos4210_pwm.c
> @@ -400,7 +400,7 @@ static void exynos4210_pwm_init(Object *obj)
>  sysbus_init_irq(dev, &s->timer[i].irq);
>  s->timer[i].ptimer = ptimer_init(exynos4210_pwm_tick,
>   &s->timer[i],
> - PTIMER_POLICY_DEFAULT);
> + PTIMER_POLICY_LEGACY);
>  s->timer[i].id = i;
>  s->timer[i].parent = s;
>  }
> diff --git a/hw/timer/grlib_gptimer.c b/hw/timer/grlib_gptimer.c
> index d5118901097..5c4923c1e09 100644
> --- a/hw/timer/grlib_gptimer.c
> +++ b/hw/timer/grlib_gptimer.c
> @@ -383,7 +383,7 @@ static void grlib_gptimer_realize(DeviceState *dev, Error 
> **errp)
>  
>  timer->unit   = unit;
>  timer->ptimer = ptimer_init(grlib_gptimer_hit, timer,
> -PTIMER_POLICY_DEFAULT);
> +PTIMER_POLICY_LEGACY);
>  timer->id = i;
>  
>  /* One IRQ line for each timer */
> diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
> index ebd58254d15..2bf8c754b21 100644
> --- a/hw/timer/imx_epit.c
> +++ b/hw/timer/imx_epit.c
> @@ -347,9 +347,9 @@ static void imx_epit_realize(DeviceState *dev, Error 
> **errp)
>0x1000);
>  sysbus_init_mmio(sbd, &s->iomem);
>  
> -s->timer_reload = ptimer_init(imx_epit_reload, s, PTIMER_POLICY_DEFAULT);
> +s->timer_reload = ptimer_init(imx_epit_reload, s, PTIMER_POLICY_LEGACY);
>  
> -s->timer_cmp = ptimer_init(imx_epit_cmp, s, PTIMER_POLICY_DEFAULT);
> +s->timer_cmp = ptimer_init(imx_epit_cmp, s, PTIMER_POLICY_LEGACY);
>  }
>  
>  static void imx_epit_class_init(ObjectClass *klass, void *data)
> diff --git a/hw/timer/imx_gpt.c b/hw/timer/imx_gpt.c
> index 5c0d9a269ce..80b83026399 100644
> --- a/hw/timer/imx_gpt.c
> +++ b/hw/timer/imx_gpt.c
> @@ -505,7 +505,7 @@ static void imx_gpt_realize(DeviceState *dev, Error 
> **errp)
>0x1000);
>  sysbus_init_mmio(sbd, &s->iomem);
>  
> -s->timer = ptimer_init(imx_gpt_timeout, s, PTIMER_POLICY_DEFAULT);
> +s->timer = ptimer_init(imx_gpt_timeout, s, PTIMER_POLICY_LEGACY);
>  }
>  
>  static void imx_gpt_class_init(ObjectClass *klass, void *data)
> diff --git a/hw/timer/mss-timer.c b/hw/timer/mss-timer.c
> index fe0ca905f3c..ee7438f1684 100644
> --- a/hw/timer/mss-timer.c
> +++ b/hw/timer/mss-timer.c
> @@ -232,7 +232,7 @@ static void mss_timer_init(Object *obj)
>  for (i = 0; i < NUM_TIMERS; i++) {
>  struct Msf2Timer *st = &t->timers[i];
>  
> -st->ptimer = ptimer_init(timer_hit, st, PTIMER_POLICY_DEFAULT);
> +st->ptimer = ptimer_init(timer_hit, st, PTIMER_POLICY_LEGACY);
>  ptimer_transaction_begin(st->ptimer);
>  ptimer_set_freq(st->ptimer, t->freq_hz);
>  ptimer_transaction_commit(st->ptimer);
> diff --git a/hw/timer/sh_timer.c b/hw/timer/sh_timer.c
> index c72c327bfaf..77889397669 100644
> --- a/hw/timer/sh_timer.c
> +++ b/hw/timer/sh_timer.c
> @@ -239,7 +239,7 @@ static void *sh_timer_init(uint32_t freq, int feat, 
> qemu_irq irq)
>  s->enabled = 0;
>  s->irq = irq;
>  
> -s->timer = ptimer_init(sh_timer_tick, s, PTIMER_POLICY_DEFAULT);
> +s->timer = ptimer_init(sh_timer_tick, s, PTIMER_POLICY_LEGACY);
>  
>  sh_timer_write(s, OFFSET_TCOR >> 2, s->tcor);
>  sh_timer_write(s, OFFSET_TCNT >> 2, s->tcnt);
> diff --git a/hw/timer/slavio_timer.c b/hw/timer/slavio_timer.c
> index 90fdce4c442..8c4f6eb06b6 100644
> --- a/hw/timer/slavio_timer.c
> +++ b/hw/timer/slavio_timer.c
> @@ -405,7 +405,7 @@ static void slavio_timer_init(Object *obj)
>  tc->timer_index = i;
>  
>  s->cputimer[i].timer = ptimer_init(slavio_timer_irq, tc,
> -   PTIMER_POLICY_DEFAULT);
> +   PTIMER_POLICY_LEGACY);
>  ptimer_transaction_begin(s->cputimer[i].timer);
>  ptimer_set_period(s->cputimer[i].timer, TIMER_PERIOD);
>  ptimer_transaction_commit(s->cputimer[i].timer);
> diff --git a/hw/timer/xilinx_timer.c b/hw/timer/xilinx_timer.c
> index 1eb927eb847..c7f17cd6460 100644
> --- a/hw/timer/xilinx_timer.c
> +++ b/hw/timer/xilinx_timer.c
> @@ -223,7 +223,7 @@ static void xilinx_timer_realize(DeviceState *dev, Error 
> **errp)
>  
>  xt->parent = t;
>  xt->nr = i;
> -xt->ptimer = ptimer_init(timer_hit, xt, PTIMER_POLICY_DEFAULT);
> +xt->ptimer = ptimer_init(timer_hit, xt, PTIMER_POLICY_LEGACY);
>  ptimer_transaction_begin(xt->ptimer);
>  ptimer_set_freq(xt->ptimer, t->freq_hz);
>  ptimer_transaction_commit(xt->ptimer);
> diff --git a/tests/unit/ptimer-test.c b/tests/unit/ptimer-test.c
> index 9176b96c1ce..22ef1ccb3a0 100644
> --- a/tests/unit/ptimer-test.c
> +++ b/tests/unit/ptimer-test.c
> @@ -768,7 +768,7 @@ static void add_ptimer_tests(uint8_t policy)
>  char policy_name[256] = "";
>  char *tmp;
>  
> -if (policy == PTIMER_POLICY_DEFAULT) {
> +if (policy == PTIMER_POLICY_LEGACY) {
>  g_sprintf(policy_name, "default");

Hi Peter,

It might be that above is clearer after this patch with "legacy" but since
it will break the automatic code changing sed command, with or without the
change:

Reviewed-by: Francisco Iglesias 

Best regards,
Francisco Iglesias

>  }
>  
> @@ -862,7 +862,7 @@ static void add_ptimer_tests(uint8_t policy)
>  static void add_all_ptimer_policies_comb_tests(void)
>  {
>  int last_policy = PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT;
> -int policy = PTIMER_POLICY_DEFAULT;
> +int policy = PTIMER_POLICY_LEGACY;
>  
>  for (; policy < (last_policy << 1); policy++) {
>  if ((policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT) &&
> -- 
> 2.25.1
> 



Re: [PATCH v2 5/5] speed/sdhci: Add trace events

2021-10-20 Thread Francisco Iglesias
Hi Cedric,

On the subject s/speed/aspeed/. Otherwise:

Reviewed-by: Francisco Iglesias 

/BR

On [2021 Oct 18] Mon 15:26:09, Cédric Le Goater wrote:
> Signed-off-by: Cédric Le Goater 
> ---
>  hw/sd/aspeed_sdhci.c | 5 +
>  hw/sd/trace-events   | 4 
>  2 files changed, 9 insertions(+)
> 
> diff --git a/hw/sd/aspeed_sdhci.c b/hw/sd/aspeed_sdhci.c
> index 3299844de6dc..df1bdf1fa4ed 100644
> --- a/hw/sd/aspeed_sdhci.c
> +++ b/hw/sd/aspeed_sdhci.c
> @@ -14,6 +14,7 @@
>  #include "hw/irq.h"
>  #include "migration/vmstate.h"
>  #include "hw/qdev-properties.h"
> +#include "trace.h"
>  
>  #define ASPEED_SDHCI_INFO0x00
>  #define  ASPEED_SDHCI_INFO_SLOT1 (1 << 17)
> @@ -60,6 +61,8 @@ static uint64_t aspeed_sdhci_read(void *opaque, hwaddr 
> addr, unsigned int size)
>  }
>  }
>  
> +trace_aspeed_sdhci_read(addr, size, (uint64_t) val);
> +
>  return (uint64_t)val;
>  }
>  
> @@ -68,6 +71,8 @@ static void aspeed_sdhci_write(void *opaque, hwaddr addr, 
> uint64_t val,
>  {
>  AspeedSDHCIState *sdhci = opaque;
>  
> +trace_aspeed_sdhci_write(addr, size, val);
> +
>  switch (addr) {
>  case ASPEED_SDHCI_INFO:
>  /* The RESET bit automatically clears. */
> diff --git a/hw/sd/trace-events b/hw/sd/trace-events
> index 3cc2ef89ba6b..94a00557b26f 100644
> --- a/hw/sd/trace-events
> +++ b/hw/sd/trace-events
> @@ -68,3 +68,7 @@ pl181_fifo_push(uint32_t data) "FIFO push 0x%08" PRIx32
>  pl181_fifo_pop(uint32_t data) "FIFO pop 0x%08" PRIx32
>  pl181_fifo_transfer_complete(void) "FIFO transfer complete"
>  pl181_data_engine_idle(void) "data engine idle"
> +
> +# aspeed_sdhci.c
> +aspeed_sdhci_read(uint64_t addr, uint32_t size, uint64_t data) "@0x%" PRIx64 
> " size %u: 0x%" PRIx64
> +aspeed_sdhci_write(uint64_t addr, uint32_t size, uint64_t data) "@0x%" 
> PRIx64 " size %u: 0x%" PRIx64
> -- 
> 2.31.1
> 
> 



  1   2   3   4   5   6   >