Re: [PATCH v2 2/3] hw/ssi: Add Nuvoton PSPI Module

2023-02-08 Thread Hao Wu
Thanks for pointing that out. I'll send another version to fix that.

On Tue, Feb 7, 2023 at 11:48 PM Philippe Mathieu-Daudé 
wrote:

> On 7/2/23 20:45, Hao Wu wrote:
> > Nuvoton's PSPI is a general purpose SPI module which enables
> > connections to SPI-based peripheral devices.
> >
> > Signed-off-by: Hao Wu 
> > Reviewed-by: Chris Rauer 
> > Reviewed-by: Philippe Mathieu-Daude 
> > ---
> >   MAINTAINERS|   6 +-
> >   hw/ssi/meson.build |   2 +-
> >   hw/ssi/npcm_pspi.c | 221 +
> >   hw/ssi/trace-events|   5 +
> >   include/hw/ssi/npcm_pspi.h |  53 +
> >   5 files changed, 283 insertions(+), 4 deletions(-)
> >   create mode 100644 hw/ssi/npcm_pspi.c
> >   create mode 100644 include/hw/ssi/npcm_pspi.h
>
>
> > +static const MemoryRegionOps npcm_pspi_ctrl_ops = {
> > +.read = npcm_pspi_ctrl_read,
> > +.write = npcm_pspi_ctrl_write,
> > +.endianness = DEVICE_LITTLE_ENDIAN,
> > +.valid = {
> > +.min_access_size = 1,
> > +.max_access_size = 4,
>
> You said in v1 "The datasheet suggests it's either 8-bit or
> 16-bit accesses.", so we want max_access_size = 2 here, right?
>
> > +.unaligned = false,
> > +},
> > +.impl = {
> > +.min_access_size = 2,
> > +.max_access_size = 2,
> > +.unaligned = false,
> > +},
> > +};
>
>
>


Re: [PATCH v2 2/3] hw/ssi: Add Nuvoton PSPI Module

2023-02-07 Thread Philippe Mathieu-Daudé

On 7/2/23 20:45, Hao Wu wrote:

Nuvoton's PSPI is a general purpose SPI module which enables
connections to SPI-based peripheral devices.

Signed-off-by: Hao Wu 
Reviewed-by: Chris Rauer 
Reviewed-by: Philippe Mathieu-Daude 
---
  MAINTAINERS|   6 +-
  hw/ssi/meson.build |   2 +-
  hw/ssi/npcm_pspi.c | 221 +
  hw/ssi/trace-events|   5 +
  include/hw/ssi/npcm_pspi.h |  53 +
  5 files changed, 283 insertions(+), 4 deletions(-)
  create mode 100644 hw/ssi/npcm_pspi.c
  create mode 100644 include/hw/ssi/npcm_pspi.h




+static const MemoryRegionOps npcm_pspi_ctrl_ops = {
+.read = npcm_pspi_ctrl_read,
+.write = npcm_pspi_ctrl_write,
+.endianness = DEVICE_LITTLE_ENDIAN,
+.valid = {
+.min_access_size = 1,
+.max_access_size = 4,


You said in v1 "The datasheet suggests it's either 8-bit or
16-bit accesses.", so we want max_access_size = 2 here, right?


+.unaligned = false,
+},
+.impl = {
+.min_access_size = 2,
+.max_access_size = 2,
+.unaligned = false,
+},
+};






[PATCH v2 2/3] hw/ssi: Add Nuvoton PSPI Module

2023-02-07 Thread Hao Wu
Nuvoton's PSPI is a general purpose SPI module which enables
connections to SPI-based peripheral devices.

Signed-off-by: Hao Wu 
Reviewed-by: Chris Rauer 
Reviewed-by: Philippe Mathieu-Daude 
---
 MAINTAINERS|   6 +-
 hw/ssi/meson.build |   2 +-
 hw/ssi/npcm_pspi.c | 221 +
 hw/ssi/trace-events|   5 +
 include/hw/ssi/npcm_pspi.h |  53 +
 5 files changed, 283 insertions(+), 4 deletions(-)
 create mode 100644 hw/ssi/npcm_pspi.c
 create mode 100644 include/hw/ssi/npcm_pspi.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 347936e41c..1e2a711373 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -803,9 +803,9 @@ M: Tyrone Ting 
 M: Hao Wu 
 L: qemu-...@nongnu.org
 S: Supported
-F: hw/*/npcm7xx*
-F: include/hw/*/npcm7xx*
-F: tests/qtest/npcm7xx*
+F: hw/*/npcm*
+F: include/hw/*/npcm*
+F: tests/qtest/npcm*
 F: pc-bios/npcm7xx_bootrom.bin
 F: roms/vbootrom
 F: docs/system/arm/nuvoton.rst
diff --git a/hw/ssi/meson.build b/hw/ssi/meson.build
index 702aa5e4df..904a47161a 100644
--- a/hw/ssi/meson.build
+++ b/hw/ssi/meson.build
@@ -1,6 +1,6 @@
 softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_smc.c'))
 softmmu_ss.add(when: 'CONFIG_MSF2', if_true: files('mss-spi.c'))
-softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_fiu.c'))
+softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_fiu.c', 
'npcm_pspi.c'))
 softmmu_ss.add(when: 'CONFIG_PL022', if_true: files('pl022.c'))
 softmmu_ss.add(when: 'CONFIG_SIFIVE_SPI', if_true: files('sifive_spi.c'))
 softmmu_ss.add(when: 'CONFIG_SSI', if_true: files('ssi.c'))
diff --git a/hw/ssi/npcm_pspi.c b/hw/ssi/npcm_pspi.c
new file mode 100644
index 00..1fd865d04e
--- /dev/null
+++ b/hw/ssi/npcm_pspi.c
@@ -0,0 +1,221 @@
+/*
+ * Nuvoton NPCM Peripheral SPI Module (PSPI)
+ *
+ * Copyright 2023 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "qemu/osdep.h"
+
+#include "hw/irq.h"
+#include "hw/registerfields.h"
+#include "hw/ssi/npcm_pspi.h"
+#include "migration/vmstate.h"
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qemu/units.h"
+
+#include "trace.h"
+
+REG16(PSPI_DATA, 0x0)
+REG16(PSPI_CTL1, 0x2)
+FIELD(PSPI_CTL1, SPIEN, 0,  1)
+FIELD(PSPI_CTL1, MOD,   2,  1)
+FIELD(PSPI_CTL1, EIR,   5,  1)
+FIELD(PSPI_CTL1, EIW,   6,  1)
+FIELD(PSPI_CTL1, SCM,   7,  1)
+FIELD(PSPI_CTL1, SCIDL, 8,  1)
+FIELD(PSPI_CTL1, SCDV,  9,  7)
+REG16(PSPI_STAT, 0x4)
+FIELD(PSPI_STAT, BSY,  0,  1)
+FIELD(PSPI_STAT, RBF,  1,  1)
+
+static void npcm_pspi_update_irq(NPCMPSPIState *s)
+{
+int level = 0;
+
+/* Only fire IRQ when the module is enabled. */
+if (FIELD_EX16(s->regs[R_PSPI_CTL1], PSPI_CTL1, SPIEN)) {
+/* Update interrupt as BSY is cleared. */
+if ((!FIELD_EX16(s->regs[R_PSPI_STAT], PSPI_STAT, BSY)) &&
+FIELD_EX16(s->regs[R_PSPI_CTL1], PSPI_CTL1, EIW)) {
+level = 1;
+}
+
+/* Update interrupt as RBF is set. */
+if (FIELD_EX16(s->regs[R_PSPI_STAT], PSPI_STAT, RBF) &&
+FIELD_EX16(s->regs[R_PSPI_CTL1], PSPI_CTL1, EIR)) {
+level = 1;
+}
+}
+qemu_set_irq(s->irq, level);
+}
+
+static uint16_t npcm_pspi_read_data(NPCMPSPIState *s)
+{
+uint16_t value = s->regs[R_PSPI_DATA];
+
+/* Clear stat bits as the value are read out. */
+s->regs[R_PSPI_STAT] = 0;
+
+return value;
+}
+
+static void npcm_pspi_write_data(NPCMPSPIState *s, uint16_t data)
+{
+uint16_t value = 0;
+
+if (FIELD_EX16(s->regs[R_PSPI_CTL1], PSPI_CTL1, MOD)) {
+value = ssi_transfer(s->spi, extract16(data, 8, 8)) << 8;
+}
+value |= ssi_transfer(s->spi, extract16(data, 0, 8));
+s->regs[R_PSPI_DATA] = value;
+
+/* Mark data as available */
+s->regs[R_PSPI_STAT] = R_PSPI_STAT_BSY_MASK | R_PSPI_STAT_RBF_MASK;
+}
+
+/* Control register read handler. */
+static uint64_t npcm_pspi_ctrl_read(void *opaque, hwaddr addr,
+unsigned int size)
+{
+NPCMPSPIState *s = opaque;
+uint16_t value;
+
+switch (addr) {
+case A_PSPI_DATA:
+value = npcm_pspi_read_data(s);
+break;
+
+case A_PSPI_CTL1:
+value = s->regs[R_PSPI_CTL1];
+break;
+
+case A_PSPI_STAT:
+value = s->regs[R_PSPI_STAT];
+break;
+
+default:
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: write to invalid offset