All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/9] hw/riscv: sifive_u: Add missing SPI support
@ 2021-01-26  5:59 Bin Meng
  2021-01-26  5:59 ` [PATCH v3 1/9] hw/block: m25p80: Add ISSI SPI flash support Bin Meng
                   ` (8 more replies)
  0 siblings, 9 replies; 23+ messages in thread
From: Bin Meng @ 2021-01-26  5:59 UTC (permalink / raw)
  To: Alistair Francis, qemu-riscv, qemu-devel; +Cc: Bin Meng

From: Bin Meng <bin.meng@windriver.com>

This adds the missing SPI support to the `sifive_u` machine in the QEMU
mainline. With this series, upstream U-Boot for the SiFive HiFive Unleashed
board can boot on QEMU `sifive_u` out of the box. This allows users to
develop and test the recommended RISC-V boot flow with a real world use
case: ZSBL (in QEMU) loads U-Boot SPL from SD card or SPI flash to L2LIM,
then U-Boot SPL loads the payload from SD card or SPI flash that is a
combination of OpenSBI fw_dynamic firmware and U-Boot proper.

The m25p80 model is updated to support ISSI flash series. A bunch of
ssi-sd issues are fixed, and writing to SD card in SPI mode is supported.

Note the ssi-sd changes are split out of this series in v3, so that all
patches in v3 can go via Alistair's riscv tree.

Part of the ssi-sd changes are now in qemu/master. The remaining patches
are http://patchwork.ozlabs.org/project/qemu-devel/list/?series=226136
that will go via Philippe's sd tree.

reST documentation for RISC-V is added. Currently only `sifive_u`
machine is documented, but more to come.

Changes in v3:
- Simplify flush txfifo logic
- Convert sifive_u.rst from UTF-8 to ASCII

Changes in v2:
- Mention QPI (Quad Peripheral Interface) mode is not supported
- Log guest error when trying to write reserved registers
- Log guest error when trying to access out-of-bounds registers
- log guest error when writing to reserved bits for chip select
  registers and watermark registers
- Log unimplemented warning when trying to write direct-map flash
  interface registers
- Add test tx fifo full logic in sifive_spi_read(), hence remove
  setting the tx fifo full flag in sifive_spi_write().
- Populate register with their default value
- Correct the "connects" typo in the commit message
- Mention in the commit message that <reg> property does not populate
  the second group which represents the memory mapped address of the
  SPI flash
- Correct the "connects" typo in the commit message
- Correct several typos in sifive_u.rst
- Update doc to mention U-Boot v2021.01

Bin Meng (9):
  hw/block: m25p80: Add ISSI SPI flash support
  hw/block: m25p80: Add various ISSI flash information
  hw/ssi: Add SiFive SPI controller support
  hw/riscv: sifive_u: Add QSPI0 controller and connect a flash
  hw/riscv: sifive_u: Add QSPI2 controller and connect an SD card
  hw/riscv: sifive_u: Change SIFIVE_U_GEM_IRQ to decimal value
  docs/system: Sort targets in alphabetical order
  docs/system: Add RISC-V documentation
  docs/system: riscv: Add documentation for sifive_u machine

 docs/system/riscv/sifive_u.rst | 336 +++++++++++++++++++++++++++++++
 docs/system/target-riscv.rst   |  72 +++++++
 docs/system/targets.rst        |  20 +-
 include/hw/riscv/sifive_u.h    |   9 +-
 include/hw/ssi/sifive_spi.h    |  47 +++++
 hw/block/m25p80.c              |  57 +++++-
 hw/riscv/sifive_u.c            |  91 +++++++++
 hw/ssi/sifive_spi.c            | 358 +++++++++++++++++++++++++++++++++
 hw/riscv/Kconfig               |   3 +
 hw/ssi/Kconfig                 |   4 +
 hw/ssi/meson.build             |   1 +
 11 files changed, 989 insertions(+), 9 deletions(-)
 create mode 100644 docs/system/riscv/sifive_u.rst
 create mode 100644 docs/system/target-riscv.rst
 create mode 100644 include/hw/ssi/sifive_spi.h
 create mode 100644 hw/ssi/sifive_spi.c

-- 
2.25.1



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

* [PATCH v3 1/9] hw/block: m25p80: Add ISSI SPI flash support
  2021-01-26  5:59 [PATCH v3 0/9] hw/riscv: sifive_u: Add missing SPI support Bin Meng
@ 2021-01-26  5:59 ` Bin Meng
  2021-01-28 20:56     ` Alistair Francis
  2021-01-26  6:00 ` [PATCH v3 2/9] hw/block: m25p80: Add various ISSI flash information Bin Meng
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 23+ messages in thread
From: Bin Meng @ 2021-01-26  5:59 UTC (permalink / raw)
  To: Alistair Francis, qemu-riscv, qemu-devel; +Cc: Bin Meng

From: Bin Meng <bin.meng@windriver.com>

This adds the ISSI SPI flash support. The number of dummy cycles in
fast read, fast read dual output and fast read quad output commands
is currently using the default 8. Likewise, the same default value
is used for fast read dual/quad I/O command. Per the datasheet [1],
the number of dummy cycles is configurable, but this is not modeled
at present.

For flash whose size is larger than 16 MiB, the sequence of 3-byte
address along with EXTADD bit in the bank address register (BAR) is
not supported. We assume that guest software always uses op codes
with 4-byte address sequence. Fortunately, this is the case for both
U-Boot and Linux spi-nor drivers.

QPI (Quad Peripheral Interface) that supports 2-cycle instruction
has different default values for dummy cycles of fast read family
commands, and is unsupported at the time being.

[1] http://www.issi.com/WW/pdf/25LP-WP256.pdf

Signed-off-by: Bin Meng <bin.meng@windriver.com>

---

(no changes since v2)

Changes in v2:
- Mention QPI (Quad Peripheral Interface) mode is not supported

 hw/block/m25p80.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 43 insertions(+), 1 deletion(-)

diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index b744a58d1c..217c130f56 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -412,6 +412,7 @@ typedef enum {
     MAN_NUMONYX,
     MAN_WINBOND,
     MAN_SST,
+    MAN_ISSI,
     MAN_GENERIC,
 } Manufacturer;
 
@@ -487,6 +488,8 @@ static inline Manufacturer get_man(Flash *s)
         return MAN_MACRONIX;
     case 0xBF:
         return MAN_SST;
+    case 0x9D:
+        return MAN_ISSI;
     default:
         return MAN_GENERIC;
     }
@@ -706,6 +709,9 @@ static void complete_collecting_data(Flash *s)
         case MAN_SPANSION:
             s->quad_enable = !!(s->data[1] & 0x02);
             break;
+        case MAN_ISSI:
+            s->quad_enable = extract32(s->data[0], 6, 1);
+            break;
         case MAN_MACRONIX:
             s->quad_enable = extract32(s->data[0], 6, 1);
             if (s->len > 1) {
@@ -895,6 +901,19 @@ static void decode_fast_read_cmd(Flash *s)
                                     SPANSION_DUMMY_CLK_LEN
                                     );
         break;
+    case MAN_ISSI:
+        /*
+         * The Fast Read instruction code is followed by address bytes and
+         * dummy cycles, transmitted via the SI line.
+         *
+         * The number of dummy cycles is configurable but this is currently
+         * unmodeled, hence the default value 8 is used.
+         *
+         * QPI (Quad Peripheral Interface) mode has different default value
+         * of dummy cycles, but this is unsupported at the time being.
+         */
+        s->needed_bytes += 1;
+        break;
     default:
         break;
     }
@@ -934,6 +953,16 @@ static void decode_dio_read_cmd(Flash *s)
             break;
         }
         break;
+    case MAN_ISSI:
+        /*
+         * The Fast Read Dual I/O instruction code is followed by address bytes
+         * and dummy cycles, transmitted via the IO1 and IO0 line.
+         *
+         * The number of dummy cycles is configurable but this is currently
+         * unmodeled, hence the default value 4 is used.
+         */
+        s->needed_bytes += 1;
+        break;
     default:
         break;
     }
@@ -974,6 +1003,19 @@ static void decode_qio_read_cmd(Flash *s)
             break;
         }
         break;
+    case MAN_ISSI:
+        /*
+         * The Fast Read Quad I/O instruction code is followed by address bytes
+         * and dummy cycles, transmitted via the IO3, IO2, IO1 and IO0 line.
+         *
+         * The number of dummy cycles is configurable but this is currently
+         * unmodeled, hence the default value 6 is used.
+         *
+         * QPI (Quad Peripheral Interface) mode has different default value
+         * of dummy cycles, but this is unsupported at the time being.
+         */
+        s->needed_bytes += 3;
+        break;
     default:
         break;
     }
@@ -1132,7 +1174,7 @@ static void decode_new_cmd(Flash *s, uint32_t value)
 
     case RDSR:
         s->data[0] = (!!s->write_enable) << 1;
-        if (get_man(s) == MAN_MACRONIX) {
+        if (get_man(s) == MAN_MACRONIX || get_man(s) == MAN_ISSI) {
             s->data[0] |= (!!s->quad_enable) << 6;
         }
         if (get_man(s) == MAN_SST) {
-- 
2.25.1



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

* [PATCH v3 2/9] hw/block: m25p80: Add various ISSI flash information
  2021-01-26  5:59 [PATCH v3 0/9] hw/riscv: sifive_u: Add missing SPI support Bin Meng
  2021-01-26  5:59 ` [PATCH v3 1/9] hw/block: m25p80: Add ISSI SPI flash support Bin Meng
@ 2021-01-26  6:00 ` Bin Meng
  2021-01-26  6:00 ` [PATCH v3 3/9] hw/ssi: Add SiFive SPI controller support Bin Meng
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 23+ messages in thread
From: Bin Meng @ 2021-01-26  6:00 UTC (permalink / raw)
  To: Alistair Francis, qemu-riscv, qemu-devel; +Cc: Bin Meng

From: Bin Meng <bin.meng@windriver.com>

This updates the flash information table to include various ISSI
flashes that are supported by upstream U-Boot and Linux kernel.

Signed-off-by: Bin Meng <bin.meng@windriver.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
---

(no changes since v1)

 hw/block/m25p80.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index 217c130f56..4bf8aa8158 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -210,6 +210,19 @@ static const FlashPartInfo known_devices[] = {
     { INFO("640s33b",     0x898913,      0,  64 << 10, 128, 0) },
     { INFO("n25q064",     0x20ba17,      0,  64 << 10, 128, 0) },
 
+    /* ISSI */
+    { INFO("is25lq040b",  0x9d4013,      0,  64 << 10,   8, ER_4K) },
+    { INFO("is25lp080d",  0x9d6014,      0,  64 << 10,  16, ER_4K) },
+    { INFO("is25lp016d",  0x9d6015,      0,  64 << 10,  32, ER_4K) },
+    { INFO("is25lp032",   0x9d6016,      0,  64 << 10,  64, ER_4K) },
+    { INFO("is25lp064",   0x9d6017,      0,  64 << 10, 128, ER_4K) },
+    { INFO("is25lp128",   0x9d6018,      0,  64 << 10, 256, ER_4K) },
+    { INFO("is25lp256",   0x9d6019,      0,  64 << 10, 512, ER_4K) },
+    { INFO("is25wp032",   0x9d7016,      0,  64 << 10,  64, ER_4K) },
+    { INFO("is25wp064",   0x9d7017,      0,  64 << 10, 128, ER_4K) },
+    { INFO("is25wp128",   0x9d7018,      0,  64 << 10, 256, ER_4K) },
+    { INFO("is25wp256",   0x9d7019,      0,  64 << 10, 512, ER_4K) },
+
     /* Macronix */
     { INFO("mx25l2005a",  0xc22012,      0,  64 << 10,   4, ER_4K) },
     { INFO("mx25l4005a",  0xc22013,      0,  64 << 10,   8, ER_4K) },
-- 
2.25.1



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

* [PATCH v3 3/9] hw/ssi: Add SiFive SPI controller support
  2021-01-26  5:59 [PATCH v3 0/9] hw/riscv: sifive_u: Add missing SPI support Bin Meng
  2021-01-26  5:59 ` [PATCH v3 1/9] hw/block: m25p80: Add ISSI SPI flash support Bin Meng
  2021-01-26  6:00 ` [PATCH v3 2/9] hw/block: m25p80: Add various ISSI flash information Bin Meng
@ 2021-01-26  6:00 ` Bin Meng
  2021-01-26  7:34   ` Philippe Mathieu-Daudé
  2021-02-09  1:38     ` Alistair Francis
  2021-01-26  6:00 ` [PATCH v3 4/9] hw/riscv: sifive_u: Add QSPI0 controller and connect a flash Bin Meng
                   ` (5 subsequent siblings)
  8 siblings, 2 replies; 23+ messages in thread
From: Bin Meng @ 2021-01-26  6:00 UTC (permalink / raw)
  To: Alistair Francis, qemu-riscv, qemu-devel; +Cc: Bin Meng

From: Bin Meng <bin.meng@windriver.com>

This adds the SiFive SPI controller model for the FU540 SoC.
The direct memory-mapped SPI flash mode is unsupported.

Signed-off-by: Bin Meng <bin.meng@windriver.com>

---

Changes in v3:
- Simplify flush txfifo logic

Changes in v2:
- Log guest error when trying to write reserved registers
- Log guest error when trying to access out-of-bounds registers
- log guest error when writing to reserved bits for chip select
  registers and watermark registers
- Log unimplemented warning when trying to write direct-map flash
  interface registers
- Add test tx fifo full logic in sifive_spi_read(), hence remove
  setting the tx fifo full flag in sifive_spi_write().
- Populate register with their default value

 include/hw/ssi/sifive_spi.h |  47 +++++
 hw/ssi/sifive_spi.c         | 358 ++++++++++++++++++++++++++++++++++++
 hw/ssi/Kconfig              |   4 +
 hw/ssi/meson.build          |   1 +
 4 files changed, 410 insertions(+)
 create mode 100644 include/hw/ssi/sifive_spi.h
 create mode 100644 hw/ssi/sifive_spi.c

diff --git a/include/hw/ssi/sifive_spi.h b/include/hw/ssi/sifive_spi.h
new file mode 100644
index 0000000000..47d0d6a47c
--- /dev/null
+++ b/include/hw/ssi/sifive_spi.h
@@ -0,0 +1,47 @@
+/*
+ * QEMU model of the SiFive SPI Controller
+ *
+ * Copyright (c) 2021 Wind River Systems, Inc.
+ *
+ * Author:
+ *   Bin Meng <bin.meng@windriver.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef HW_SIFIVE_SPI_H
+#define HW_SIFIVE_SPI_H
+
+#define SIFIVE_SPI_REG_NUM  (0x78 / 4)
+
+#define TYPE_SIFIVE_SPI "sifive.spi"
+#define SIFIVE_SPI(obj) OBJECT_CHECK(SiFiveSPIState, (obj), TYPE_SIFIVE_SPI)
+
+typedef struct SiFiveSPIState {
+    SysBusDevice parent_obj;
+
+    MemoryRegion mmio;
+    qemu_irq irq;
+
+    uint32_t num_cs;
+    qemu_irq *cs_lines;
+
+    SSIBus *spi;
+
+    Fifo8 tx_fifo;
+    Fifo8 rx_fifo;
+
+    uint32_t regs[SIFIVE_SPI_REG_NUM];
+} SiFiveSPIState;
+
+#endif /* HW_SIFIVE_SPI_H */
diff --git a/hw/ssi/sifive_spi.c b/hw/ssi/sifive_spi.c
new file mode 100644
index 0000000000..0c9ebca3c8
--- /dev/null
+++ b/hw/ssi/sifive_spi.c
@@ -0,0 +1,358 @@
+/*
+ * QEMU model of the SiFive SPI Controller
+ *
+ * Copyright (c) 2021 Wind River Systems, Inc.
+ *
+ * Author:
+ *   Bin Meng <bin.meng@windriver.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+#include "hw/sysbus.h"
+#include "hw/ssi/ssi.h"
+#include "sysemu/sysemu.h"
+#include "qemu/fifo8.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "hw/ssi/sifive_spi.h"
+
+#define R_SCKDIV        (0x00 / 4)
+#define R_SCKMODE       (0x04 / 4)
+#define R_CSID          (0x10 / 4)
+#define R_CSDEF         (0x14 / 4)
+#define R_CSMODE        (0x18 / 4)
+#define R_DELAY0        (0x28 / 4)
+#define R_DELAY1        (0x2C / 4)
+#define R_FMT           (0x40 / 4)
+#define R_TXDATA        (0x48 / 4)
+#define R_RXDATA        (0x4C / 4)
+#define R_TXMARK        (0x50 / 4)
+#define R_RXMARK        (0x54 / 4)
+#define R_FCTRL         (0x60 / 4)
+#define R_FFMT          (0x64 / 4)
+#define R_IE            (0x70 / 4)
+#define R_IP            (0x74 / 4)
+
+#define FMT_DIR         (1 << 3)
+
+#define TXDATA_FULL     (1 << 31)
+#define RXDATA_EMPTY    (1 << 31)
+
+#define IE_TXWM         (1 << 0)
+#define IE_RXWM         (1 << 1)
+
+#define IP_TXWM         (1 << 0)
+#define IP_RXWM         (1 << 1)
+
+#define FIFO_CAPACITY   8
+
+static void sifive_spi_txfifo_reset(SiFiveSPIState *s)
+{
+    fifo8_reset(&s->tx_fifo);
+
+    s->regs[R_TXDATA] &= ~TXDATA_FULL;
+    s->regs[R_IP] &= ~IP_TXWM;
+}
+
+static void sifive_spi_rxfifo_reset(SiFiveSPIState *s)
+{
+    fifo8_reset(&s->rx_fifo);
+
+    s->regs[R_RXDATA] |= RXDATA_EMPTY;
+    s->regs[R_IP] &= ~IP_RXWM;
+}
+
+static void sifive_spi_update_cs(SiFiveSPIState *s)
+{
+    int i;
+
+    for (i = 0; i < s->num_cs; i++) {
+        if (s->regs[R_CSDEF] & (1 << i)) {
+            qemu_set_irq(s->cs_lines[i], !(s->regs[R_CSMODE]));
+        }
+    }
+}
+
+static void sifive_spi_update_irq(SiFiveSPIState *s)
+{
+    int level;
+
+    if (fifo8_num_used(&s->tx_fifo) < s->regs[R_TXMARK]) {
+        s->regs[R_IP] |= IP_TXWM;
+    } else {
+        s->regs[R_IP] &= ~IP_TXWM;
+    }
+
+    if (fifo8_num_used(&s->rx_fifo) > s->regs[R_RXMARK]) {
+        s->regs[R_IP] |= IP_RXWM;
+    } else {
+        s->regs[R_IP] &= ~IP_RXWM;
+    }
+
+    level = s->regs[R_IP] & s->regs[R_IE] ? 1 : 0;
+    qemu_set_irq(s->irq, level);
+}
+
+static void sifive_spi_reset(DeviceState *d)
+{
+    SiFiveSPIState *s = SIFIVE_SPI(d);
+
+    memset(s->regs, 0, sizeof(s->regs));
+
+    /* The reset value is high for all implemented CS pins */
+    s->regs[R_CSDEF] = (1 << s->num_cs) - 1;
+
+    /* Populate register with their default value */
+    s->regs[R_SCKDIV] = 0x03;
+    s->regs[R_DELAY0] = 0x1001;
+    s->regs[R_DELAY1] = 0x01;
+
+    sifive_spi_txfifo_reset(s);
+    sifive_spi_rxfifo_reset(s);
+
+    sifive_spi_update_cs(s);
+    sifive_spi_update_irq(s);
+}
+
+static void sifive_spi_flush_txfifo(SiFiveSPIState *s)
+{
+    uint8_t tx;
+    uint8_t rx;
+
+    while (!fifo8_is_empty(&s->tx_fifo)) {
+        tx = fifo8_pop(&s->tx_fifo);
+        rx = ssi_transfer(s->spi, tx);
+
+        if (!fifo8_is_full(&s->rx_fifo)) {
+            if (!(s->regs[R_FMT] & FMT_DIR)) {
+                fifo8_push(&s->rx_fifo, rx);
+            }
+        }
+    }
+}
+
+static bool sifive_spi_is_bad_reg(hwaddr addr, bool allow_reserved)
+{
+    bool bad;
+
+    switch (addr) {
+    /* reserved offsets */
+    case 0x08:
+    case 0x0C:
+    case 0x1C:
+    case 0x20:
+    case 0x24:
+    case 0x30:
+    case 0x34:
+    case 0x38:
+    case 0x3C:
+    case 0x44:
+    case 0x58:
+    case 0x5C:
+    case 0x68:
+    case 0x6C:
+        bad = allow_reserved ? false : true;
+        break;
+    default:
+        bad = false;
+    }
+
+    if (addr >= (SIFIVE_SPI_REG_NUM << 2)) {
+        bad = true;
+    }
+
+    return bad;
+}
+
+static uint64_t sifive_spi_read(void *opaque, hwaddr addr, unsigned int size)
+{
+    SiFiveSPIState *s = opaque;
+    uint32_t r;
+
+    if (sifive_spi_is_bad_reg(addr, true)) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: bad read at address 0x%"
+                      HWADDR_PRIx "\n", __func__, addr);
+        return 0;
+    }
+
+    addr >>= 2;
+    switch (addr) {
+    case R_TXDATA:
+        if (fifo8_is_full(&s->tx_fifo)) {
+            return TXDATA_FULL;
+        }
+        r = 0;
+        break;
+
+    case R_RXDATA:
+        if (fifo8_is_empty(&s->rx_fifo)) {
+            return RXDATA_EMPTY;
+        }
+        r = fifo8_pop(&s->rx_fifo);
+        break;
+
+    default:
+        r = s->regs[addr];
+        break;
+    }
+
+    sifive_spi_update_irq(s);
+
+    return r;
+}
+
+static void sifive_spi_write(void *opaque, hwaddr addr,
+                             uint64_t val64, unsigned int size)
+{
+    SiFiveSPIState *s = opaque;
+    uint32_t value = val64;
+
+    if (sifive_spi_is_bad_reg(addr, false)) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: bad write at addr=0x%"
+                      HWADDR_PRIx " value=0x%x\n", __func__, addr, value);
+        return;
+    }
+
+    addr >>= 2;
+    switch (addr) {
+    case R_CSID:
+        if (value >= s->num_cs) {
+            qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid csid %d\n",
+                          __func__, value);
+        } else {
+            s->regs[R_CSID] = value;
+            sifive_spi_update_cs(s);
+        }
+        break;
+
+    case R_CSDEF:
+        if (value >= (1 << s->num_cs)) {
+            qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid csdef %x\n",
+                          __func__, value);
+        } else {
+            s->regs[R_CSDEF] = value;
+        }
+        break;
+
+    case R_CSMODE:
+        if (value > 3) {
+            qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid csmode %x\n",
+                          __func__, value);
+        } else {
+            s->regs[R_CSMODE] = value;
+            sifive_spi_update_cs(s);
+        }
+        break;
+
+    case R_TXDATA:
+        if (!fifo8_is_full(&s->tx_fifo)) {
+            fifo8_push(&s->tx_fifo, (uint8_t)value);
+            sifive_spi_flush_txfifo(s);
+        }
+        break;
+
+    case R_RXDATA:
+    case R_IP:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "%s: invalid write to read-only reigster 0x%"
+                      HWADDR_PRIx " with 0x%x\n", __func__, addr << 2, value);
+        break;
+
+    case R_TXMARK:
+    case R_RXMARK:
+        if (value >= FIFO_CAPACITY) {
+            qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid watermark %d\n",
+                          __func__, value);
+        } else {
+            s->regs[addr] = value;
+        }
+        break;
+
+    case R_FCTRL:
+    case R_FFMT:
+        qemu_log_mask(LOG_UNIMP,
+                      "%s: direct-map flash interface unimplemented\n",
+                      __func__);
+        break;
+
+    default:
+        s->regs[addr] = value;
+        break;
+    }
+
+    sifive_spi_update_irq(s);
+}
+
+static const MemoryRegionOps sifive_spi_ops = {
+    .read = sifive_spi_read,
+    .write = sifive_spi_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .valid = {
+        .min_access_size = 4,
+        .max_access_size = 4
+    }
+};
+
+static void sifive_spi_realize(DeviceState *dev, Error **errp)
+{
+    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+    SiFiveSPIState *s = SIFIVE_SPI(dev);
+    int i;
+
+    s->spi = ssi_create_bus(dev, "spi");
+    sysbus_init_irq(sbd, &s->irq);
+
+    s->cs_lines = g_new0(qemu_irq, s->num_cs);
+    for (i = 0; i < s->num_cs; i++) {
+        sysbus_init_irq(sbd, &s->cs_lines[i]);
+    }
+
+    memory_region_init_io(&s->mmio, OBJECT(s), &sifive_spi_ops, s,
+                          TYPE_SIFIVE_SPI, 0x1000);
+    sysbus_init_mmio(sbd, &s->mmio);
+
+    fifo8_create(&s->tx_fifo, FIFO_CAPACITY);
+    fifo8_create(&s->rx_fifo, FIFO_CAPACITY);
+}
+
+static Property sifive_spi_properties[] = {
+    DEFINE_PROP_UINT32("num-cs", SiFiveSPIState, num_cs, 1),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void sifive_spi_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    device_class_set_props(dc, sifive_spi_properties);
+    dc->reset = sifive_spi_reset;
+    dc->realize = sifive_spi_realize;
+}
+
+static const TypeInfo sifive_spi_info = {
+    .name           = TYPE_SIFIVE_SPI,
+    .parent         = TYPE_SYS_BUS_DEVICE,
+    .instance_size  = sizeof(SiFiveSPIState),
+    .class_init     = sifive_spi_class_init,
+};
+
+static void sifive_spi_register_types(void)
+{
+    type_register_static(&sifive_spi_info);
+}
+
+type_init(sifive_spi_register_types)
diff --git a/hw/ssi/Kconfig b/hw/ssi/Kconfig
index 9e54a0c8dd..7d90a02181 100644
--- a/hw/ssi/Kconfig
+++ b/hw/ssi/Kconfig
@@ -2,6 +2,10 @@ config PL022
     bool
     select SSI
 
+config SIFIVE_SPI
+    bool
+    select SSI
+
 config SSI
     bool
 
diff --git a/hw/ssi/meson.build b/hw/ssi/meson.build
index dee00c0da6..3d6bc82ab1 100644
--- a/hw/ssi/meson.build
+++ b/hw/ssi/meson.build
@@ -2,6 +2,7 @@ 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_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'))
 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'))
-- 
2.25.1



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

* [PATCH v3 4/9] hw/riscv: sifive_u: Add QSPI0 controller and connect a flash
  2021-01-26  5:59 [PATCH v3 0/9] hw/riscv: sifive_u: Add missing SPI support Bin Meng
                   ` (2 preceding siblings ...)
  2021-01-26  6:00 ` [PATCH v3 3/9] hw/ssi: Add SiFive SPI controller support Bin Meng
@ 2021-01-26  6:00 ` Bin Meng
  2021-01-26  6:00 ` [PATCH v3 5/9] hw/riscv: sifive_u: Add QSPI2 controller and connect an SD card Bin Meng
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 23+ messages in thread
From: Bin Meng @ 2021-01-26  6:00 UTC (permalink / raw)
  To: Alistair Francis, qemu-riscv, qemu-devel; +Cc: Bin Meng

From: Bin Meng <bin.meng@windriver.com>

This adds the QSPI0 controller to the SoC, and connects an ISSI
25WP256 flash to it. The generation of corresponding device tree
source fragment is also added.

Since the direct memory-mapped mode is not supported by the SiFive
SPI model, the <reg> property does not populate the second group
which represents the memory mapped address of the SPI flash.

With this commit, upstream U-Boot for the SiFive HiFive Unleashed
board can boot on QEMU 'sifive_u' out of the box. This allows users
to develop and test the recommended RISC-V boot flow with a real
world use case: ZSBL (in QEMU) loads U-Boot SPL from SPI flash to
L2LIM, then U-Boot SPL loads the payload from SPI flash that is
combined with OpenSBI fw_dynamic firmware and U-Boot proper.

Specify machine property `msel` to 6 to allow booting from the SPI
flash. U-Boot spl is directly loaded via `-bios`, and subsequent
payload is stored in the SPI flash image. Example command line:

$ qemu-system-riscv64 -nographic -M sifive_u,msel=6 -smp 5 -m 8G \
    -bios u-boot-spl.bin -drive file=spi-nor.img,if=mtd

Signed-off-by: Bin Meng <bin.meng@windriver.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

---

(no changes since v2)

Changes in v2:
- Correct the "connects" typo in the commit message
- Mention in the commit message that <reg> property does not populate
  the second group which represents the memory mapped address of the
  SPI flash

 include/hw/riscv/sifive_u.h |  4 +++
 hw/riscv/sifive_u.c         | 52 +++++++++++++++++++++++++++++++++++++
 hw/riscv/Kconfig            |  2 ++
 3 files changed, 58 insertions(+)

diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index a9f7b4a084..8824b7c031 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -26,6 +26,7 @@
 #include "hw/gpio/sifive_gpio.h"
 #include "hw/misc/sifive_u_otp.h"
 #include "hw/misc/sifive_u_prci.h"
+#include "hw/ssi/sifive_spi.h"
 
 #define TYPE_RISCV_U_SOC "riscv.sifive.u.soc"
 #define RISCV_U_SOC(obj) \
@@ -45,6 +46,7 @@ typedef struct SiFiveUSoCState {
     SIFIVEGPIOState gpio;
     SiFiveUOTPState otp;
     SiFivePDMAState dma;
+    SiFiveSPIState spi0;
     CadenceGEMState gem;
 
     uint32_t serial;
@@ -82,6 +84,7 @@ enum {
     SIFIVE_U_DEV_UART0,
     SIFIVE_U_DEV_UART1,
     SIFIVE_U_DEV_GPIO,
+    SIFIVE_U_DEV_QSPI0,
     SIFIVE_U_DEV_OTP,
     SIFIVE_U_DEV_DMC,
     SIFIVE_U_DEV_FLASH0,
@@ -120,6 +123,7 @@ enum {
     SIFIVE_U_PDMA_IRQ5 = 28,
     SIFIVE_U_PDMA_IRQ6 = 29,
     SIFIVE_U_PDMA_IRQ7 = 30,
+    SIFIVE_U_QSPI0_IRQ = 51,
     SIFIVE_U_GEM_IRQ = 0x35
 };
 
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 59b61cea01..43a0e983d2 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -15,6 +15,7 @@
  * 5) OTP (One-Time Programmable) memory with stored serial number
  * 6) GEM (Gigabit Ethernet Controller) and management block
  * 7) DMA (Direct Memory Access Controller)
+ * 8) SPI0 connected to an SPI flash
  *
  * This board currently generates devicetree dynamically that indicates at least
  * two harts and up to five harts.
@@ -44,6 +45,7 @@
 #include "hw/char/serial.h"
 #include "hw/cpu/cluster.h"
 #include "hw/misc/unimp.h"
+#include "hw/ssi/ssi.h"
 #include "target/riscv/cpu.h"
 #include "hw/riscv/riscv_hart.h"
 #include "hw/riscv/sifive_u.h"
@@ -74,6 +76,7 @@ static const struct MemmapEntry {
     [SIFIVE_U_DEV_PRCI] =     { 0x10000000,     0x1000 },
     [SIFIVE_U_DEV_UART0] =    { 0x10010000,     0x1000 },
     [SIFIVE_U_DEV_UART1] =    { 0x10011000,     0x1000 },
+    [SIFIVE_U_DEV_QSPI0] =    { 0x10040000,     0x1000 },
     [SIFIVE_U_DEV_GPIO] =     { 0x10060000,     0x1000 },
     [SIFIVE_U_DEV_OTP] =      { 0x10070000,     0x1000 },
     [SIFIVE_U_DEV_GEM] =      { 0x10090000,     0x2000 },
@@ -342,6 +345,32 @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
                             "sifive,fu540-c000-ccache");
     g_free(nodename);
 
+    nodename = g_strdup_printf("/soc/spi@%lx",
+        (long)memmap[SIFIVE_U_DEV_QSPI0].base);
+    qemu_fdt_add_subnode(fdt, nodename);
+    qemu_fdt_setprop_cell(fdt, nodename, "#size-cells", 0);
+    qemu_fdt_setprop_cell(fdt, nodename, "#address-cells", 1);
+    qemu_fdt_setprop_cells(fdt, nodename, "clocks",
+        prci_phandle, PRCI_CLK_TLCLK);
+    qemu_fdt_setprop_cell(fdt, nodename, "interrupts", SIFIVE_U_QSPI0_IRQ);
+    qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
+    qemu_fdt_setprop_cells(fdt, nodename, "reg",
+        0x0, memmap[SIFIVE_U_DEV_QSPI0].base,
+        0x0, memmap[SIFIVE_U_DEV_QSPI0].size);
+    qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,spi0");
+    g_free(nodename);
+
+    nodename = g_strdup_printf("/soc/spi@%lx/flash@0",
+        (long)memmap[SIFIVE_U_DEV_QSPI0].base);
+    qemu_fdt_add_subnode(fdt, nodename);
+    qemu_fdt_setprop_cell(fdt, nodename, "spi-rx-bus-width", 4);
+    qemu_fdt_setprop_cell(fdt, nodename, "spi-tx-bus-width", 4);
+    qemu_fdt_setprop(fdt, nodename, "m25p,fast-read", NULL, 0);
+    qemu_fdt_setprop_cell(fdt, nodename, "spi-max-frequency", 50000000);
+    qemu_fdt_setprop_cell(fdt, nodename, "reg", 0);
+    qemu_fdt_setprop_string(fdt, nodename, "compatible", "jedec,spi-nor");
+    g_free(nodename);
+
     phy_phandle = phandle++;
     nodename = g_strdup_printf("/soc/ethernet@%lx",
         (long)memmap[SIFIVE_U_DEV_GEM].base);
@@ -439,6 +468,9 @@ static void sifive_u_machine_init(MachineState *machine)
     int i;
     uint32_t fdt_load_addr;
     uint64_t kernel_entry;
+    DriveInfo *dinfo;
+    DeviceState *flash_dev;
+    qemu_irq flash_cs;
 
     /* Initialize SoC */
     object_initialize_child(OBJECT(machine), "soc", &s->soc, TYPE_RISCV_U_SOC);
@@ -571,6 +603,19 @@ static void sifive_u_machine_init(MachineState *machine)
     riscv_rom_copy_firmware_info(machine, memmap[SIFIVE_U_DEV_MROM].base,
                                  memmap[SIFIVE_U_DEV_MROM].size,
                                  sizeof(reset_vec), kernel_entry);
+
+    /* Connect an SPI flash to SPI0 */
+    flash_dev = qdev_new("is25wp256");
+    dinfo = drive_get_next(IF_MTD);
+    if (dinfo) {
+        qdev_prop_set_drive_err(flash_dev, "drive",
+                                blk_by_legacy_dinfo(dinfo),
+                                &error_fatal);
+    }
+    qdev_realize_and_unref(flash_dev, BUS(s->soc.spi0.spi), &error_fatal);
+
+    flash_cs = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->soc.spi0), 1, flash_cs);
 }
 
 static bool sifive_u_machine_get_start_in_flash(Object *obj, Error **errp)
@@ -680,6 +725,7 @@ static void sifive_u_soc_instance_init(Object *obj)
     object_initialize_child(obj, "gem", &s->gem, TYPE_CADENCE_GEM);
     object_initialize_child(obj, "gpio", &s->gpio, TYPE_SIFIVE_GPIO);
     object_initialize_child(obj, "pdma", &s->dma, TYPE_SIFIVE_PDMA);
+    object_initialize_child(obj, "spi0", &s->spi0, TYPE_SIFIVE_SPI);
 }
 
 static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
@@ -827,6 +873,12 @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
 
     create_unimplemented_device("riscv.sifive.u.l2cc",
         memmap[SIFIVE_U_DEV_L2CC].base, memmap[SIFIVE_U_DEV_L2CC].size);
+
+    sysbus_realize(SYS_BUS_DEVICE(&s->spi0), errp);
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi0), 0,
+                    memmap[SIFIVE_U_DEV_QSPI0].base);
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi0), 0,
+                       qdev_get_gpio_in(DEVICE(s->plic), SIFIVE_U_QSPI0_IRQ));
 }
 
 static Property sifive_u_soc_props[] = {
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
index facb0cbacc..6330297b4e 100644
--- a/hw/riscv/Kconfig
+++ b/hw/riscv/Kconfig
@@ -52,9 +52,11 @@ config SIFIVE_U
     select SIFIVE_GPIO
     select SIFIVE_PDMA
     select SIFIVE_PLIC
+    select SIFIVE_SPI
     select SIFIVE_UART
     select SIFIVE_U_OTP
     select SIFIVE_U_PRCI
+    select SSI_M25P80
     select UNIMP
 
 config SPIKE
-- 
2.25.1



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

* [PATCH v3 5/9] hw/riscv: sifive_u: Add QSPI2 controller and connect an SD card
  2021-01-26  5:59 [PATCH v3 0/9] hw/riscv: sifive_u: Add missing SPI support Bin Meng
                   ` (3 preceding siblings ...)
  2021-01-26  6:00 ` [PATCH v3 4/9] hw/riscv: sifive_u: Add QSPI0 controller and connect a flash Bin Meng
@ 2021-01-26  6:00 ` Bin Meng
  2021-01-26  6:00 ` [PATCH v3 6/9] hw/riscv: sifive_u: Change SIFIVE_U_GEM_IRQ to decimal value Bin Meng
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 23+ messages in thread
From: Bin Meng @ 2021-01-26  6:00 UTC (permalink / raw)
  To: Alistair Francis, qemu-riscv, qemu-devel; +Cc: Bin Meng

From: Bin Meng <bin.meng@windriver.com>

This adds the QSPI2 controller to the SoC, and connects an SD
card to it. The generation of corresponding device tree source
fragment is also added.

Specify machine property `msel` to 11 to boot the same upstream
U-Boot SPL and payload image for the SiFive HiFive Unleashed board.
Note subsequent payload is stored in the SD card image.

$ qemu-system-riscv64 -nographic -M sifive_u,msel=11 -smp 5 -m 8G \
    -bios u-boot-spl.bin -drive file=sdcard.img,if=sd

Signed-off-by: Bin Meng <bin.meng@windriver.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

---

(no changes since v2)

Changes in v2:
- Correct the "connects" typo in the commit message

 include/hw/riscv/sifive_u.h |  3 +++
 hw/riscv/sifive_u.c         | 43 +++++++++++++++++++++++++++++++++++--
 hw/riscv/Kconfig            |  1 +
 3 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index 8824b7c031..de1464a2ce 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -47,6 +47,7 @@ typedef struct SiFiveUSoCState {
     SiFiveUOTPState otp;
     SiFivePDMAState dma;
     SiFiveSPIState spi0;
+    SiFiveSPIState spi2;
     CadenceGEMState gem;
 
     uint32_t serial;
@@ -85,6 +86,7 @@ enum {
     SIFIVE_U_DEV_UART1,
     SIFIVE_U_DEV_GPIO,
     SIFIVE_U_DEV_QSPI0,
+    SIFIVE_U_DEV_QSPI2,
     SIFIVE_U_DEV_OTP,
     SIFIVE_U_DEV_DMC,
     SIFIVE_U_DEV_FLASH0,
@@ -99,6 +101,7 @@ enum {
     SIFIVE_U_L2CC_IRQ2 = 3,
     SIFIVE_U_UART0_IRQ = 4,
     SIFIVE_U_UART1_IRQ = 5,
+    SIFIVE_U_QSPI2_IRQ = 6,
     SIFIVE_U_GPIO_IRQ0 = 7,
     SIFIVE_U_GPIO_IRQ1 = 8,
     SIFIVE_U_GPIO_IRQ2 = 9,
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 43a0e983d2..6c1158a848 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -16,6 +16,7 @@
  * 6) GEM (Gigabit Ethernet Controller) and management block
  * 7) DMA (Direct Memory Access Controller)
  * 8) SPI0 connected to an SPI flash
+ * 9) SPI2 connected to an SD card
  *
  * This board currently generates devicetree dynamically that indicates at least
  * two harts and up to five harts.
@@ -77,6 +78,7 @@ static const struct MemmapEntry {
     [SIFIVE_U_DEV_UART0] =    { 0x10010000,     0x1000 },
     [SIFIVE_U_DEV_UART1] =    { 0x10011000,     0x1000 },
     [SIFIVE_U_DEV_QSPI0] =    { 0x10040000,     0x1000 },
+    [SIFIVE_U_DEV_QSPI2] =    { 0x10050000,     0x1000 },
     [SIFIVE_U_DEV_GPIO] =     { 0x10060000,     0x1000 },
     [SIFIVE_U_DEV_OTP] =      { 0x10070000,     0x1000 },
     [SIFIVE_U_DEV_GEM] =      { 0x10090000,     0x2000 },
@@ -345,6 +347,31 @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
                             "sifive,fu540-c000-ccache");
     g_free(nodename);
 
+    nodename = g_strdup_printf("/soc/spi@%lx",
+        (long)memmap[SIFIVE_U_DEV_QSPI2].base);
+    qemu_fdt_add_subnode(fdt, nodename);
+    qemu_fdt_setprop_cell(fdt, nodename, "#size-cells", 0);
+    qemu_fdt_setprop_cell(fdt, nodename, "#address-cells", 1);
+    qemu_fdt_setprop_cells(fdt, nodename, "clocks",
+        prci_phandle, PRCI_CLK_TLCLK);
+    qemu_fdt_setprop_cell(fdt, nodename, "interrupts", SIFIVE_U_QSPI2_IRQ);
+    qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
+    qemu_fdt_setprop_cells(fdt, nodename, "reg",
+        0x0, memmap[SIFIVE_U_DEV_QSPI2].base,
+        0x0, memmap[SIFIVE_U_DEV_QSPI2].size);
+    qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,spi0");
+    g_free(nodename);
+
+    nodename = g_strdup_printf("/soc/spi@%lx/mmc@0",
+        (long)memmap[SIFIVE_U_DEV_QSPI2].base);
+    qemu_fdt_add_subnode(fdt, nodename);
+    qemu_fdt_setprop(fdt, nodename, "disable-wp", NULL, 0);
+    qemu_fdt_setprop_cells(fdt, nodename, "voltage-ranges", 3300, 3300);
+    qemu_fdt_setprop_cell(fdt, nodename, "spi-max-frequency", 20000000);
+    qemu_fdt_setprop_cell(fdt, nodename, "reg", 0);
+    qemu_fdt_setprop_string(fdt, nodename, "compatible", "mmc-spi-slot");
+    g_free(nodename);
+
     nodename = g_strdup_printf("/soc/spi@%lx",
         (long)memmap[SIFIVE_U_DEV_QSPI0].base);
     qemu_fdt_add_subnode(fdt, nodename);
@@ -469,8 +496,8 @@ static void sifive_u_machine_init(MachineState *machine)
     uint32_t fdt_load_addr;
     uint64_t kernel_entry;
     DriveInfo *dinfo;
-    DeviceState *flash_dev;
-    qemu_irq flash_cs;
+    DeviceState *flash_dev, *sd_dev;
+    qemu_irq flash_cs, sd_cs;
 
     /* Initialize SoC */
     object_initialize_child(OBJECT(machine), "soc", &s->soc, TYPE_RISCV_U_SOC);
@@ -616,6 +643,12 @@ static void sifive_u_machine_init(MachineState *machine)
 
     flash_cs = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
     sysbus_connect_irq(SYS_BUS_DEVICE(&s->soc.spi0), 1, flash_cs);
+
+    /* Connect an SD card to SPI2 */
+    sd_dev = ssi_create_peripheral(s->soc.spi2.spi, "ssi-sd");
+
+    sd_cs = qdev_get_gpio_in_named(sd_dev, SSI_GPIO_CS, 0);
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->soc.spi2), 1, sd_cs);
 }
 
 static bool sifive_u_machine_get_start_in_flash(Object *obj, Error **errp)
@@ -726,6 +759,7 @@ static void sifive_u_soc_instance_init(Object *obj)
     object_initialize_child(obj, "gpio", &s->gpio, TYPE_SIFIVE_GPIO);
     object_initialize_child(obj, "pdma", &s->dma, TYPE_SIFIVE_PDMA);
     object_initialize_child(obj, "spi0", &s->spi0, TYPE_SIFIVE_SPI);
+    object_initialize_child(obj, "spi2", &s->spi2, TYPE_SIFIVE_SPI);
 }
 
 static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
@@ -879,6 +913,11 @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
                     memmap[SIFIVE_U_DEV_QSPI0].base);
     sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi0), 0,
                        qdev_get_gpio_in(DEVICE(s->plic), SIFIVE_U_QSPI0_IRQ));
+    sysbus_realize(SYS_BUS_DEVICE(&s->spi2), errp);
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi2), 0,
+                    memmap[SIFIVE_U_DEV_QSPI2].base);
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi2), 0,
+                       qdev_get_gpio_in(DEVICE(s->plic), SIFIVE_U_QSPI2_IRQ));
 }
 
 static Property sifive_u_soc_props[] = {
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
index 6330297b4e..d139074b02 100644
--- a/hw/riscv/Kconfig
+++ b/hw/riscv/Kconfig
@@ -57,6 +57,7 @@ config SIFIVE_U
     select SIFIVE_U_OTP
     select SIFIVE_U_PRCI
     select SSI_M25P80
+    select SSI_SD
     select UNIMP
 
 config SPIKE
-- 
2.25.1



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

* [PATCH v3 6/9] hw/riscv: sifive_u: Change SIFIVE_U_GEM_IRQ to decimal value
  2021-01-26  5:59 [PATCH v3 0/9] hw/riscv: sifive_u: Add missing SPI support Bin Meng
                   ` (4 preceding siblings ...)
  2021-01-26  6:00 ` [PATCH v3 5/9] hw/riscv: sifive_u: Add QSPI2 controller and connect an SD card Bin Meng
@ 2021-01-26  6:00 ` Bin Meng
  2021-01-26  6:00 ` [PATCH v3 7/9] docs/system: Sort targets in alphabetical order Bin Meng
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 23+ messages in thread
From: Bin Meng @ 2021-01-26  6:00 UTC (permalink / raw)
  To: Alistair Francis, qemu-riscv, qemu-devel; +Cc: Bin Meng

From: Bin Meng <bin.meng@windriver.com>

All other peripherals' IRQs are in the format of decimal value.
Change SIFIVE_U_GEM_IRQ to be consistent.

Signed-off-by: Bin Meng <bin.meng@windriver.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---

(no changes since v1)

 include/hw/riscv/sifive_u.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index de1464a2ce..2656b39808 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -127,7 +127,7 @@ enum {
     SIFIVE_U_PDMA_IRQ6 = 29,
     SIFIVE_U_PDMA_IRQ7 = 30,
     SIFIVE_U_QSPI0_IRQ = 51,
-    SIFIVE_U_GEM_IRQ = 0x35
+    SIFIVE_U_GEM_IRQ = 53
 };
 
 enum {
-- 
2.25.1



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

* [PATCH v3 7/9] docs/system: Sort targets in alphabetical order
  2021-01-26  5:59 [PATCH v3 0/9] hw/riscv: sifive_u: Add missing SPI support Bin Meng
                   ` (5 preceding siblings ...)
  2021-01-26  6:00 ` [PATCH v3 6/9] hw/riscv: sifive_u: Change SIFIVE_U_GEM_IRQ to decimal value Bin Meng
@ 2021-01-26  6:00 ` Bin Meng
  2021-01-26  6:00 ` [PATCH v3 8/9] docs/system: Add RISC-V documentation Bin Meng
  2021-01-26  6:00 ` [PATCH v3 9/9] docs/system: riscv: Add documentation for sifive_u machine Bin Meng
  8 siblings, 0 replies; 23+ messages in thread
From: Bin Meng @ 2021-01-26  6:00 UTC (permalink / raw)
  To: Alistair Francis, qemu-riscv, qemu-devel; +Cc: Bin Meng

From: Bin Meng <bin.meng@windriver.com>

Signed-off-by: Bin Meng <bin.meng@windriver.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---

(no changes since v1)

 docs/system/targets.rst | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/docs/system/targets.rst b/docs/system/targets.rst
index 560783644d..564cea9a9b 100644
--- a/docs/system/targets.rst
+++ b/docs/system/targets.rst
@@ -7,16 +7,21 @@ various targets are mentioned in the following sections.
 
 Contents:
 
+..
+   This table of contents should be kept sorted alphabetically
+   by the title text of each file, which isn't the same ordering
+   as an alphabetical sort by filename.
+
 .. toctree::
 
-   target-i386
+   target-arm
+   target-avr
+   target-m68k
+   target-mips
    target-ppc
+   target-rx
+   target-s390x
    target-sparc
    target-sparc64
-   target-mips
-   target-arm
-   target-m68k
+   target-i386
    target-xtensa
-   target-s390x
-   target-rx
-   target-avr
-- 
2.25.1



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

* [PATCH v3 8/9] docs/system: Add RISC-V documentation
  2021-01-26  5:59 [PATCH v3 0/9] hw/riscv: sifive_u: Add missing SPI support Bin Meng
                   ` (6 preceding siblings ...)
  2021-01-26  6:00 ` [PATCH v3 7/9] docs/system: Sort targets in alphabetical order Bin Meng
@ 2021-01-26  6:00 ` Bin Meng
  2021-01-26  6:00 ` [PATCH v3 9/9] docs/system: riscv: Add documentation for sifive_u machine Bin Meng
  8 siblings, 0 replies; 23+ messages in thread
From: Bin Meng @ 2021-01-26  6:00 UTC (permalink / raw)
  To: Alistair Francis, qemu-riscv, qemu-devel; +Cc: Bin Meng

From: Bin Meng <bin.meng@windriver.com>

Add RISC-V system emulator documentation for generic information.
`Board-specific documentation` and `RISC-V CPU features` are only
a placeholder and will be added in the future.

Signed-off-by: Bin Meng <bin.meng@windriver.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---

(no changes since v1)

 docs/system/target-riscv.rst | 62 ++++++++++++++++++++++++++++++++++++
 docs/system/targets.rst      |  1 +
 2 files changed, 63 insertions(+)
 create mode 100644 docs/system/target-riscv.rst

diff --git a/docs/system/target-riscv.rst b/docs/system/target-riscv.rst
new file mode 100644
index 0000000000..9f4b7586e5
--- /dev/null
+++ b/docs/system/target-riscv.rst
@@ -0,0 +1,62 @@
+.. _RISC-V-System-emulator:
+
+RISC-V System emulator
+======================
+
+QEMU can emulate both 32-bit and 64-bit RISC-V CPUs. Use the
+``qemu-system-riscv64`` executable to simulate a 64-bit RISC-V machine,
+``qemu-system-riscv32`` executable to simulate a 32-bit RISC-V machine.
+
+QEMU has generally good support for RISC-V guests. It has support for
+several different machines. The reason we support so many is that
+RISC-V hardware is much more widely varying than x86 hardware. RISC-V
+CPUs are generally built into "system-on-chip" (SoC) designs created by
+many different companies with different devices, and these SoCs are
+then built into machines which can vary still further even if they use
+the same SoC.
+
+For most boards the CPU type is fixed (matching what the hardware has),
+so typically you don't need to specify the CPU type by hand, except for
+special cases like the ``virt`` board.
+
+Choosing a board model
+----------------------
+
+For QEMU's RISC-V system emulation, you must specify which board
+model you want to use with the ``-M`` or ``--machine`` option;
+there is no default.
+
+Because RISC-V systems differ so much and in fundamental ways, typically
+operating system or firmware images intended to run on one machine
+will not run at all on any other. This is often surprising for new
+users who are used to the x86 world where every system looks like a
+standard PC. (Once the kernel has booted, most user space software
+cares much less about the detail of the hardware.)
+
+If you already have a system image or a kernel that works on hardware
+and you want to boot with QEMU, check whether QEMU lists that machine
+in its ``-machine help`` output. If it is listed, then you can probably
+use that board model. If it is not listed, then unfortunately your image
+will almost certainly not boot on QEMU. (You might be able to
+extract the file system and use that with a different kernel which
+boots on a system that QEMU does emulate.)
+
+If you don't care about reproducing the idiosyncrasies of a particular
+bit of hardware, such as small amount of RAM, no PCI or other hard
+disk, etc., and just want to run Linux, the best option is to use the
+``virt`` board. This is a platform which doesn't correspond to any
+real hardware and is designed for use in virtual machines. You'll
+need to compile Linux with a suitable configuration for running on
+the ``virt`` board. ``virt`` supports PCI, virtio, recent CPUs and
+large amounts of RAM. It also supports 64-bit CPUs.
+
+Board-specific documentation
+----------------------------
+
+Unfortunately many of the RISC-V boards QEMU supports are currently
+undocumented; you can get a complete list by running
+``qemu-system-riscv64 --machine help``, or
+``qemu-system-riscv32 --machine help``.
+
+RISC-V CPU features
+-------------------
diff --git a/docs/system/targets.rst b/docs/system/targets.rst
index 564cea9a9b..75ed1087fd 100644
--- a/docs/system/targets.rst
+++ b/docs/system/targets.rst
@@ -19,6 +19,7 @@ Contents:
    target-m68k
    target-mips
    target-ppc
+   target-riscv
    target-rx
    target-s390x
    target-sparc
-- 
2.25.1



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

* [PATCH v3 9/9] docs/system: riscv: Add documentation for sifive_u machine
  2021-01-26  5:59 [PATCH v3 0/9] hw/riscv: sifive_u: Add missing SPI support Bin Meng
                   ` (7 preceding siblings ...)
  2021-01-26  6:00 ` [PATCH v3 8/9] docs/system: Add RISC-V documentation Bin Meng
@ 2021-01-26  6:00 ` Bin Meng
  2021-01-27  5:51     ` Palmer Dabbelt
  8 siblings, 1 reply; 23+ messages in thread
From: Bin Meng @ 2021-01-26  6:00 UTC (permalink / raw)
  To: Alistair Francis, qemu-riscv, qemu-devel; +Cc: Bin Meng

From: Bin Meng <bin.meng@windriver.com>

This adds detailed documentation for RISC-V `sifive_u` machine,
including the following information:

- Supported devices
- Hardware configuration information
- Boot options
- Machine-specific options
- Running Linux kernel
- Running VxWorks kernel
- Running U-Boot, and with an alternate configuration

Signed-off-by: Bin Meng <bin.meng@windriver.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

---

Changes in v3:
- Convert sifive_u.rst from UTF-8 to ASCII

Changes in v2:
- Correct several typos in sifive_u.rst
- Update doc to mention U-Boot v2021.01

 docs/system/riscv/sifive_u.rst | 336 +++++++++++++++++++++++++++++++++
 docs/system/target-riscv.rst   |  10 +
 2 files changed, 346 insertions(+)
 create mode 100644 docs/system/riscv/sifive_u.rst

diff --git a/docs/system/riscv/sifive_u.rst b/docs/system/riscv/sifive_u.rst
new file mode 100644
index 0000000000..98e7562848
--- /dev/null
+++ b/docs/system/riscv/sifive_u.rst
@@ -0,0 +1,336 @@
+SiFive HiFive Unleashed (``sifive_u``)
+======================================
+
+SiFive HiFive Unleashed Development Board is the ultimate RISC-V development
+board featuring the Freedom U540 multi-core RISC-V processor.
+
+Supported devices
+-----------------
+
+The ``sifive_u`` machine supports the following devices:
+
+ * 1 E51 / E31 core
+ * Up to 4 U54 / U34 cores
+ * Core Level Interruptor (CLINT)
+ * Platform-Level Interrupt Controller (PLIC)
+ * Power, Reset, Clock, Interrupt (PRCI)
+ * L2 Loosely Integrated Memory (L2-LIM)
+ * DDR memory controller
+ * 2 UARTs
+ * 1 GEM Ethernet controller
+ * 1 GPIO controller
+ * 1 One-Time Programmable (OTP) memory with stored serial number
+ * 1 DMA controller
+ * 2 QSPI controllers
+ * 1 ISSI 25WP256 flash
+ * 1 SD card in SPI mode
+
+Please note the real world HiFive Unleashed board has a fixed configuration of
+1 E51 core and 4 U54 core combination and the RISC-V core boots in 64-bit mode.
+With QEMU, one can create a machine with 1 E51 core and up to 4 U54 cores. It
+is also possible to create a 32-bit variant with the same peripherals except
+that the RISC-V cores are replaced by the 32-bit ones (E31 and U34), to help
+testing of 32-bit guest software.
+
+Hardware configuration information
+----------------------------------
+
+The ``sifive_u`` machine automatically generates a device tree blob ("dtb")
+which it passes to the guest. This provides information about the addresses,
+interrupt lines and other configuration of the various devices in the system.
+Guest software should discover the devices that are present in the generated
+DTB instead of using a DTB for the real hardware, as some of the devices are
+not modeled by QEMU and trying to access these devices may cause unexpected
+behavior.
+
+Boot options
+------------
+
+The ``sifive_u`` machine can start using the standard -kernel functionality
+for loading a Linux kernel, a VxWorks kernel, a modified U-Boot bootloader
+(S-mode) or ELF executable with the default OpenSBI firmware image as the
+-bios. It also supports booting the unmodified U-Boot bootloader using the
+standard -bios functionality.
+
+Machine-specific options
+------------------------
+
+The following machine-specific options are supported:
+
+- serial=nnn
+
+  The board serial number. When not given, the default serial number 1 is used.
+
+  SiFive reserves the first 1 KiB of the 16 KiB OTP memory for internal use.
+  The current usage is only used to store the serial number of the board at
+  offset 0xfc. U-Boot reads the serial number from the OTP memory, and uses
+  it to generate a unique MAC address to be programmed to the on-chip GEM
+  Ethernet controller. When multiple QEMU ``sifive_u`` machines are created
+  and connected to the same subnet, they all have the same MAC address hence
+  it creates an unusable network. In such scenario, user should give different
+  values to serial= when creating different ``sifive_u`` machines.
+
+- start-in-flash
+
+  When given, QEMU's ROM codes jump to QSPI memory-mapped flash directly.
+  Otherwise QEMU will jump to DRAM or L2LIM depending on the msel= value.
+  When not given, it defaults to direct DRAM booting.
+
+- msel=[6|11]
+
+  Mode Select (MSEL[3:0]) pins value, used to control where to boot from.
+
+  The FU540 SoC supports booting from several sources, which are controlled
+  using the Mode Select pins on the chip. Typically, the boot process runs
+  through several stages before it begins execution of user-provided programs.
+  These stages typically include the following:
+
+  1. Zeroth Stage Boot Loader (ZSBL), which is contained in an on-chip mask
+     ROM and provided by QEMU. Note QEMU implemented ROM codes are not the
+     same as what is programmed in the hardware. The QEMU one is a simplified
+     version, but it provides the same functionality as the hardware.
+  2. First Stage Boot Loader (FSBL), which brings up PLLs and DDR memory.
+     This is U-Boot SPL.
+  3. Second Stage Boot Loader (SSBL), which further initializes additional
+     peripherals as needed. This is U-Boot proper combined with an OpenSBI
+     fw_dynamic firmware image.
+
+  msel=6 means FSBL and SSBL are both on the QSPI flash. msel=11 means FSBL
+  and SSBL are both on the SD card.
+
+Running Linux kernel
+--------------------
+
+Linux mainline v5.10 release is tested at the time of writing. To build a
+Linux mainline kernel that can be booted by the ``sifive_u`` machine in
+64-bit mode, simply configure the kernel using the defconfig configuration:
+
+.. code-block:: bash
+
+  $ export ARCH=riscv
+  $ export CROSS_COMPILE=riscv64-linux-
+  $ make defconfig
+  $ make
+
+To boot the newly built Linux kernel in QEMU with the ``sifive_u`` machine:
+
+.. code-block:: bash
+
+  $ qemu-system-riscv64 -M sifive_u -smp 5 -m 2G \
+      -display none -serial stdio \
+      -kernel arch/riscv/boot/Image \
+      -initrd /path/to/rootfs.ext4 \
+      -append "root=/dev/ram"
+
+To build a Linux mainline kernel that can be booted by the ``sifive_u`` machine
+in 32-bit mode, use the rv32_defconfig configuration. A patch is required to
+fix the 32-bit boot issue for Linux kernel v5.10.
+
+.. code-block:: bash
+
+  $ export ARCH=riscv
+  $ export CROSS_COMPILE=riscv64-linux-
+  $ curl https://patchwork.kernel.org/project/linux-riscv/patch/20201219001356.2887782-1-atish.patra@wdc.com/mbox/ > riscv.patch
+  $ git am riscv.patch
+  $ make rv32_defconfig
+  $ make
+
+Replace ``qemu-system-riscv64`` with ``qemu-system-riscv32`` in the command
+line above to boot the 32-bit Linux kernel. A rootfs image containing 32-bit
+applications shall be used in order for kernel to boot to user space.
+
+Running VxWorks kernel
+----------------------
+
+VxWorks 7 SR0650 release is tested at the time of writing. To build a 64-bit
+VxWorks mainline kernel that can be booted by the ``sifive_u`` machine, simply
+create a VxWorks source build project based on the sifive_generic BSP, and a
+VxWorks image project to generate the bootable VxWorks image, by following the
+BSP documentation instructions.
+
+A pre-built 64-bit VxWorks 7 image for HiFive Unleashed board is available as
+part of the VxWorks SDK for testing as well. Instructions to download the SDK:
+
+.. code-block:: bash
+
+  $ wget https://labs.windriver.com/downloads/wrsdk-vxworks7-sifive-hifive-1.01.tar.bz2
+  $ tar xvf wrsdk-vxworks7-sifive-hifive-1.01.tar.bz2
+  $ ls bsps/sifive_generic_1_0_0_0/uboot/uVxWorks
+
+To boot the VxWorks kernel in QEMU with the ``sifive_u`` machine, use:
+
+.. code-block:: bash
+
+  $ qemu-system-riscv64 -M sifive_u -smp 5 -m 2G \
+      -display none -serial stdio \
+      -nic tap,ifname=tap0,script=no,downscript=no \
+      -kernel /path/to/vxWorks \
+      -append "gem(0,0)host:vxWorks h=192.168.200.1 e=192.168.200.2:ffffff00 u=target pw=vxTarget f=0x01"
+
+It is also possible to test 32-bit VxWorks on the ``sifive_u`` machine. Create
+a 32-bit project to build the 32-bit VxWorks image, and use exact the same
+command line options with ``qemu-system-riscv32``.
+
+Running U-Boot
+--------------
+
+U-Boot mainline v2021.01 release is tested at the time of writing. To build a
+U-Boot mainline bootloader that can be booted by the ``sifive_u`` machine, use
+the sifive_fu540_defconfig with similar commands as described above for Linux:
+
+.. code-block:: bash
+
+  $ export CROSS_COMPILE=riscv64-linux-
+  $ export OPENSBI=/path/to/opensbi-riscv64-generic-fw_dynamic.bin
+  $ make sifive_fu540_defconfig
+
+You will get spl/u-boot-spl.bin and u-boot.itb file in the build tree.
+
+To start U-Boot using the ``sifive_u`` machine, prepare an SPI flash image, or
+SD card image that is properly partitioned and populated with correct contents.
+genimage_ can be used to generate these images.
+
+A sample configuration file for a 128 MiB SD card image is:
+
+.. code-block:: bash
+
+  $ cat genimage_sdcard.cfg
+  image sdcard.img {
+          size = 128M
+
+          hdimage {
+                  gpt = true
+          }
+
+          partition u-boot-spl {
+                  image = "u-boot-spl.bin"
+                  offset = 17K
+                  partition-type-uuid = 5B193300-FC78-40CD-8002-E86C45580B47
+          }
+
+          partition u-boot {
+                  image = "u-boot.itb"
+                  offset = 1041K
+                  partition-type-uuid = 2E54B353-1271-4842-806F-E436D6AF6985
+          }
+  }
+
+SPI flash image has slightly different partition offsets, and the size has to
+be 32 MiB to match the ISSI 25WP256 flash on the real board:
+
+.. code-block:: bash
+
+  $ cat genimage_spi-nor.cfg
+  image spi-nor.img {
+          size = 32M
+
+          hdimage {
+                  gpt = true
+          }
+
+          partition u-boot-spl {
+                  image = "u-boot-spl.bin"
+                  offset = 20K
+                  partition-type-uuid = 5B193300-FC78-40CD-8002-E86C45580B47
+          }
+
+          partition u-boot {
+                  image = "u-boot.itb"
+                  offset = 1044K
+                  partition-type-uuid = 2E54B353-1271-4842-806F-E436D6AF6985
+          }
+  }
+
+Assume U-Boot binaries are put in the same directory as the config file,
+we can generate the image by:
+
+.. code-block:: bash
+
+  $ genimage --config genimage_<boot_src>.cfg --inputpath .
+
+Boot U-Boot from SD card, by specifying msel=11 and pass the SD card image
+to QEMU ``sifive_u`` machine:
+
+.. code-block:: bash
+
+  $ qemu-system-riscv64 -M sifive_u,msel=11 -smp 5 -m 8G \
+      -display none -serial stdio \
+      -bios /path/to/u-boot-spl.bin \
+      -drive file=/path/to/sdcard.img,if=sd
+
+Changing msel= value to 6, allows booting U-Boot from the SPI flash:
+
+.. code-block:: bash
+
+  $ qemu-system-riscv64 -M sifive_u,msel=6 -smp 5 -m 8G \
+      -display none -serial stdio \
+      -bios /path/to/u-boot-spl.bin \
+      -drive file=/path/to/spi-nor.img,if=mtd
+
+Note when testing U-Boot, QEMU automatically generated device tree blob is
+not used because U-Boot itself embeds device tree blobs for U-Boot SPL and
+U-Boot proper. Hence the number of cores and size of memory have to match
+the real hardware, ie: 5 cores (-smp 5) and 8 GiB memory (-m 8G).
+
+Above use case is to run upstream U-Boot for the SiFive HiFive Unleashed
+board on QEMU ``sifive_u`` machine out of the box. This allows users to
+develop and test the recommended RISC-V boot flow with a real world use
+case: ZSBL (in QEMU) loads U-Boot SPL from SD card or SPI flash to L2LIM,
+then U-Boot SPL loads the combined payload image of OpenSBI fw_dynamic
+firmware and U-Boot proper. However sometimes we want to have a quick test
+of booting U-Boot on QEMU without the needs of preparing the SPI flash or
+SD card images, an alternate way can be used, which is to create a U-Boot
+S-mode image by modifying the configuration of U-Boot:
+
+.. code-block:: bash
+
+  $ make menuconfig
+
+then manually select the following configuration in U-Boot:
+
+  Device Tree Control > Provider of DTB for DT Control > Prior Stage bootloader DTB
+
+This lets U-Boot to use the QEMU generated device tree blob. During the build,
+a build error will be seen below:
+
+.. code-block:: none
+
+  MKIMAGE u-boot.img
+  ./tools/mkimage: Can't open arch/riscv/dts/hifive-unleashed-a00.dtb: No such file or directory
+  ./tools/mkimage: failed to build FIT
+  make: *** [Makefile:1440: u-boot.img] Error 1
+
+The above errors can be safely ignored as we don't run U-Boot SPL under QEMU
+in this alternate configuration.
+
+Boot the 64-bit U-Boot S-mode image directly:
+
+.. code-block:: bash
+
+  $ qemu-system-riscv64 -M sifive_u -smp 5 -m 2G \
+      -display none -serial stdio \
+      -kernel /path/to/u-boot.bin
+
+It's possible to create a 32-bit U-Boot S-mode image as well.
+
+.. code-block:: bash
+
+  $ export CROSS_COMPILE=riscv64-linux-
+  $ make sifive_fu540_defconfig
+  $ make menuconfig
+
+then manually update the following configuration in U-Boot:
+
+  Device Tree Control > Provider of DTB for DT Control > Prior Stage bootloader DTB
+  RISC-V architecture > Base ISA > RV32I
+  Boot images > Text Base > 0x80400000
+
+Use the same command line options to boot the 32-bit U-Boot S-mode image:
+
+.. code-block:: bash
+
+  $ qemu-system-riscv32 -M sifive_u -smp 5 -m 2G \
+      -display none -serial stdio \
+      -kernel /path/to/u-boot.bin
+
+.. _genimage: https://github.com/pengutronix/genimage
diff --git a/docs/system/target-riscv.rst b/docs/system/target-riscv.rst
index 9f4b7586e5..94d99c4c82 100644
--- a/docs/system/target-riscv.rst
+++ b/docs/system/target-riscv.rst
@@ -58,5 +58,15 @@ undocumented; you can get a complete list by running
 ``qemu-system-riscv64 --machine help``, or
 ``qemu-system-riscv32 --machine help``.
 
+..
+   This table of contents should be kept sorted alphabetically
+   by the title text of each file, which isn't the same ordering
+   as an alphabetical sort by filename.
+
+.. toctree::
+   :maxdepth: 1
+
+   riscv/sifive_u
+
 RISC-V CPU features
 -------------------
-- 
2.25.1



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

* Re: [PATCH v3 3/9] hw/ssi: Add SiFive SPI controller support
  2021-01-26  6:00 ` [PATCH v3 3/9] hw/ssi: Add SiFive SPI controller support Bin Meng
@ 2021-01-26  7:34   ` Philippe Mathieu-Daudé
  2021-02-09  1:44       ` Alistair Francis
  2021-02-09  1:38     ` Alistair Francis
  1 sibling, 1 reply; 23+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-01-26  7:34 UTC (permalink / raw)
  To: Bin Meng, Alistair Francis, qemu-riscv, qemu-devel; +Cc: Bin Meng

On 1/26/21 7:00 AM, Bin Meng wrote:
> From: Bin Meng <bin.meng@windriver.com>
> 
> This adds the SiFive SPI controller model for the FU540 SoC.
> The direct memory-mapped SPI flash mode is unsupported.
> 
> Signed-off-by: Bin Meng <bin.meng@windriver.com>
> 
> ---
> 
> Changes in v3:
> - Simplify flush txfifo logic
> 
> Changes in v2:
> - Log guest error when trying to write reserved registers
> - Log guest error when trying to access out-of-bounds registers
> - log guest error when writing to reserved bits for chip select
>   registers and watermark registers
> - Log unimplemented warning when trying to write direct-map flash
>   interface registers
> - Add test tx fifo full logic in sifive_spi_read(), hence remove
>   setting the tx fifo full flag in sifive_spi_write().
> - Populate register with their default value
> 
>  include/hw/ssi/sifive_spi.h |  47 +++++
>  hw/ssi/sifive_spi.c         | 358 ++++++++++++++++++++++++++++++++++++
>  hw/ssi/Kconfig              |   4 +
>  hw/ssi/meson.build          |   1 +
>  4 files changed, 410 insertions(+)
>  create mode 100644 include/hw/ssi/sifive_spi.h
>  create mode 100644 hw/ssi/sifive_spi.c

Missing MAINTAINERS entry (if there are no other comments on
this series, maybe the maintainer can directly add one).


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

* Re: [PATCH v3 9/9] docs/system: riscv: Add documentation for sifive_u machine
  2021-01-26  6:00 ` [PATCH v3 9/9] docs/system: riscv: Add documentation for sifive_u machine Bin Meng
@ 2021-01-27  5:51     ` Palmer Dabbelt
  0 siblings, 0 replies; 23+ messages in thread
From: Palmer Dabbelt @ 2021-01-27  5:51 UTC (permalink / raw)
  To: bmeng.cn; +Cc: qemu-riscv, bin.meng, Alistair Francis, qemu-devel

On Mon, 25 Jan 2021 22:00:07 PST (-0800), bmeng.cn@gmail.com wrote:
> From: Bin Meng <bin.meng@windriver.com>
>
> This adds detailed documentation for RISC-V `sifive_u` machine,
> including the following information:
>
> - Supported devices
> - Hardware configuration information
> - Boot options
> - Machine-specific options
> - Running Linux kernel
> - Running VxWorks kernel
> - Running U-Boot, and with an alternate configuration
>
> Signed-off-by: Bin Meng <bin.meng@windriver.com>
> Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
>
> ---
>
> Changes in v3:
> - Convert sifive_u.rst from UTF-8 to ASCII
>
> Changes in v2:
> - Correct several typos in sifive_u.rst
> - Update doc to mention U-Boot v2021.01
>
>  docs/system/riscv/sifive_u.rst | 336 +++++++++++++++++++++++++++++++++
>  docs/system/target-riscv.rst   |  10 +
>  2 files changed, 346 insertions(+)
>  create mode 100644 docs/system/riscv/sifive_u.rst
>
> diff --git a/docs/system/riscv/sifive_u.rst b/docs/system/riscv/sifive_u.rst
> new file mode 100644
> index 0000000000..98e7562848
> --- /dev/null
> +++ b/docs/system/riscv/sifive_u.rst
> @@ -0,0 +1,336 @@
> +SiFive HiFive Unleashed (``sifive_u``)
> +======================================
> +
> +SiFive HiFive Unleashed Development Board is the ultimate RISC-V development
> +board featuring the Freedom U540 multi-core RISC-V processor.
> +
> +Supported devices
> +-----------------
> +
> +The ``sifive_u`` machine supports the following devices:
> +
> + * 1 E51 / E31 core
> + * Up to 4 U54 / U34 cores
> + * Core Level Interruptor (CLINT)
> + * Platform-Level Interrupt Controller (PLIC)
> + * Power, Reset, Clock, Interrupt (PRCI)
> + * L2 Loosely Integrated Memory (L2-LIM)
> + * DDR memory controller
> + * 2 UARTs
> + * 1 GEM Ethernet controller
> + * 1 GPIO controller
> + * 1 One-Time Programmable (OTP) memory with stored serial number
> + * 1 DMA controller
> + * 2 QSPI controllers
> + * 1 ISSI 25WP256 flash
> + * 1 SD card in SPI mode
> +
> +Please note the real world HiFive Unleashed board has a fixed configuration of
> +1 E51 core and 4 U54 core combination and the RISC-V core boots in 64-bit mode.
> +With QEMU, one can create a machine with 1 E51 core and up to 4 U54 cores. It
> +is also possible to create a 32-bit variant with the same peripherals except
> +that the RISC-V cores are replaced by the 32-bit ones (E31 and U34), to help
> +testing of 32-bit guest software.
> +
> +Hardware configuration information
> +----------------------------------
> +
> +The ``sifive_u`` machine automatically generates a device tree blob ("dtb")
> +which it passes to the guest. This provides information about the addresses,
> +interrupt lines and other configuration of the various devices in the system.
> +Guest software should discover the devices that are present in the generated
> +DTB instead of using a DTB for the real hardware, as some of the devices are
> +not modeled by QEMU and trying to access these devices may cause unexpected
> +behavior.
> +
> +Boot options
> +------------
> +
> +The ``sifive_u`` machine can start using the standard -kernel functionality
> +for loading a Linux kernel, a VxWorks kernel, a modified U-Boot bootloader
> +(S-mode) or ELF executable with the default OpenSBI firmware image as the
> +-bios. It also supports booting the unmodified U-Boot bootloader using the
> +standard -bios functionality.
> +
> +Machine-specific options
> +------------------------
> +
> +The following machine-specific options are supported:
> +
> +- serial=nnn
> +
> +  The board serial number. When not given, the default serial number 1 is used.
> +
> +  SiFive reserves the first 1 KiB of the 16 KiB OTP memory for internal use.
> +  The current usage is only used to store the serial number of the board at
> +  offset 0xfc. U-Boot reads the serial number from the OTP memory, and uses
> +  it to generate a unique MAC address to be programmed to the on-chip GEM
> +  Ethernet controller. When multiple QEMU ``sifive_u`` machines are created
> +  and connected to the same subnet, they all have the same MAC address hence
> +  it creates an unusable network. In such scenario, user should give different
> +  values to serial= when creating different ``sifive_u`` machines.
> +
> +- start-in-flash
> +
> +  When given, QEMU's ROM codes jump to QSPI memory-mapped flash directly.
> +  Otherwise QEMU will jump to DRAM or L2LIM depending on the msel= value.
> +  When not given, it defaults to direct DRAM booting.
> +
> +- msel=[6|11]
> +
> +  Mode Select (MSEL[3:0]) pins value, used to control where to boot from.
> +
> +  The FU540 SoC supports booting from several sources, which are controlled
> +  using the Mode Select pins on the chip. Typically, the boot process runs
> +  through several stages before it begins execution of user-provided programs.
> +  These stages typically include the following:
> +
> +  1. Zeroth Stage Boot Loader (ZSBL), which is contained in an on-chip mask
> +     ROM and provided by QEMU. Note QEMU implemented ROM codes are not the
> +     same as what is programmed in the hardware. The QEMU one is a simplified
> +     version, but it provides the same functionality as the hardware.
> +  2. First Stage Boot Loader (FSBL), which brings up PLLs and DDR memory.
> +     This is U-Boot SPL.
> +  3. Second Stage Boot Loader (SSBL), which further initializes additional
> +     peripherals as needed. This is U-Boot proper combined with an OpenSBI
> +     fw_dynamic firmware image.
> +
> +  msel=6 means FSBL and SSBL are both on the QSPI flash. msel=11 means FSBL
> +  and SSBL are both on the SD card.
> +
> +Running Linux kernel
> +--------------------
> +
> +Linux mainline v5.10 release is tested at the time of writing. To build a
> +Linux mainline kernel that can be booted by the ``sifive_u`` machine in
> +64-bit mode, simply configure the kernel using the defconfig configuration:
> +
> +.. code-block:: bash
> +
> +  $ export ARCH=riscv
> +  $ export CROSS_COMPILE=riscv64-linux-
> +  $ make defconfig
> +  $ make
> +
> +To boot the newly built Linux kernel in QEMU with the ``sifive_u`` machine:
> +
> +.. code-block:: bash
> +
> +  $ qemu-system-riscv64 -M sifive_u -smp 5 -m 2G \
> +      -display none -serial stdio \
> +      -kernel arch/riscv/boot/Image \
> +      -initrd /path/to/rootfs.ext4 \
> +      -append "root=/dev/ram"
> +
> +To build a Linux mainline kernel that can be booted by the ``sifive_u`` machine
> +in 32-bit mode, use the rv32_defconfig configuration. A patch is required to
> +fix the 32-bit boot issue for Linux kernel v5.10.
> +
> +.. code-block:: bash
> +
> +  $ export ARCH=riscv
> +  $ export CROSS_COMPILE=riscv64-linux-
> +  $ curl https://patchwork.kernel.org/project/linux-riscv/patch/20201219001356.2887782-1-atish.patra@wdc.com/mbox/ > riscv.patch
> +  $ git am riscv.patch
> +  $ make rv32_defconfig
> +  $ make
> +
> +Replace ``qemu-system-riscv64`` with ``qemu-system-riscv32`` in the command
> +line above to boot the 32-bit Linux kernel. A rootfs image containing 32-bit
> +applications shall be used in order for kernel to boot to user space.
> +
> +Running VxWorks kernel
> +----------------------
> +
> +VxWorks 7 SR0650 release is tested at the time of writing. To build a 64-bit
> +VxWorks mainline kernel that can be booted by the ``sifive_u`` machine, simply
> +create a VxWorks source build project based on the sifive_generic BSP, and a
> +VxWorks image project to generate the bootable VxWorks image, by following the
> +BSP documentation instructions.
> +
> +A pre-built 64-bit VxWorks 7 image for HiFive Unleashed board is available as
> +part of the VxWorks SDK for testing as well. Instructions to download the SDK:
> +
> +.. code-block:: bash
> +
> +  $ wget https://labs.windriver.com/downloads/wrsdk-vxworks7-sifive-hifive-1.01.tar.bz2
> +  $ tar xvf wrsdk-vxworks7-sifive-hifive-1.01.tar.bz2
> +  $ ls bsps/sifive_generic_1_0_0_0/uboot/uVxWorks
> +
> +To boot the VxWorks kernel in QEMU with the ``sifive_u`` machine, use:
> +
> +.. code-block:: bash
> +
> +  $ qemu-system-riscv64 -M sifive_u -smp 5 -m 2G \
> +      -display none -serial stdio \
> +      -nic tap,ifname=tap0,script=no,downscript=no \
> +      -kernel /path/to/vxWorks \
> +      -append "gem(0,0)host:vxWorks h=192.168.200.1 e=192.168.200.2:ffffff00 u=target pw=vxTarget f=0x01"
> +
> +It is also possible to test 32-bit VxWorks on the ``sifive_u`` machine. Create
> +a 32-bit project to build the 32-bit VxWorks image, and use exact the same
> +command line options with ``qemu-system-riscv32``.
> +
> +Running U-Boot
> +--------------
> +
> +U-Boot mainline v2021.01 release is tested at the time of writing. To build a
> +U-Boot mainline bootloader that can be booted by the ``sifive_u`` machine, use
> +the sifive_fu540_defconfig with similar commands as described above for Linux:
> +
> +.. code-block:: bash
> +
> +  $ export CROSS_COMPILE=riscv64-linux-
> +  $ export OPENSBI=/path/to/opensbi-riscv64-generic-fw_dynamic.bin
> +  $ make sifive_fu540_defconfig
> +
> +You will get spl/u-boot-spl.bin and u-boot.itb file in the build tree.
> +
> +To start U-Boot using the ``sifive_u`` machine, prepare an SPI flash image, or
> +SD card image that is properly partitioned and populated with correct contents.
> +genimage_ can be used to generate these images.
> +
> +A sample configuration file for a 128 MiB SD card image is:
> +
> +.. code-block:: bash
> +
> +  $ cat genimage_sdcard.cfg
> +  image sdcard.img {
> +          size = 128M
> +
> +          hdimage {
> +                  gpt = true
> +          }
> +
> +          partition u-boot-spl {
> +                  image = "u-boot-spl.bin"
> +                  offset = 17K
> +                  partition-type-uuid = 5B193300-FC78-40CD-8002-E86C45580B47
> +          }
> +
> +          partition u-boot {
> +                  image = "u-boot.itb"
> +                  offset = 1041K
> +                  partition-type-uuid = 2E54B353-1271-4842-806F-E436D6AF6985
> +          }
> +  }
> +
> +SPI flash image has slightly different partition offsets, and the size has to
> +be 32 MiB to match the ISSI 25WP256 flash on the real board:
> +
> +.. code-block:: bash
> +
> +  $ cat genimage_spi-nor.cfg
> +  image spi-nor.img {
> +          size = 32M
> +
> +          hdimage {
> +                  gpt = true
> +          }
> +
> +          partition u-boot-spl {
> +                  image = "u-boot-spl.bin"
> +                  offset = 20K
> +                  partition-type-uuid = 5B193300-FC78-40CD-8002-E86C45580B47
> +          }
> +
> +          partition u-boot {
> +                  image = "u-boot.itb"
> +                  offset = 1044K
> +                  partition-type-uuid = 2E54B353-1271-4842-806F-E436D6AF6985
> +          }
> +  }
> +
> +Assume U-Boot binaries are put in the same directory as the config file,
> +we can generate the image by:
> +
> +.. code-block:: bash
> +
> +  $ genimage --config genimage_<boot_src>.cfg --inputpath .
> +
> +Boot U-Boot from SD card, by specifying msel=11 and pass the SD card image
> +to QEMU ``sifive_u`` machine:
> +
> +.. code-block:: bash
> +
> +  $ qemu-system-riscv64 -M sifive_u,msel=11 -smp 5 -m 8G \
> +      -display none -serial stdio \
> +      -bios /path/to/u-boot-spl.bin \
> +      -drive file=/path/to/sdcard.img,if=sd
> +
> +Changing msel= value to 6, allows booting U-Boot from the SPI flash:
> +
> +.. code-block:: bash
> +
> +  $ qemu-system-riscv64 -M sifive_u,msel=6 -smp 5 -m 8G \
> +      -display none -serial stdio \
> +      -bios /path/to/u-boot-spl.bin \
> +      -drive file=/path/to/spi-nor.img,if=mtd
> +
> +Note when testing U-Boot, QEMU automatically generated device tree blob is
> +not used because U-Boot itself embeds device tree blobs for U-Boot SPL and
> +U-Boot proper. Hence the number of cores and size of memory have to match
> +the real hardware, ie: 5 cores (-smp 5) and 8 GiB memory (-m 8G).
> +
> +Above use case is to run upstream U-Boot for the SiFive HiFive Unleashed
> +board on QEMU ``sifive_u`` machine out of the box. This allows users to
> +develop and test the recommended RISC-V boot flow with a real world use
> +case: ZSBL (in QEMU) loads U-Boot SPL from SD card or SPI flash to L2LIM,
> +then U-Boot SPL loads the combined payload image of OpenSBI fw_dynamic
> +firmware and U-Boot proper. However sometimes we want to have a quick test
> +of booting U-Boot on QEMU without the needs of preparing the SPI flash or
> +SD card images, an alternate way can be used, which is to create a U-Boot
> +S-mode image by modifying the configuration of U-Boot:
> +
> +.. code-block:: bash
> +
> +  $ make menuconfig
> +
> +then manually select the following configuration in U-Boot:
> +
> +  Device Tree Control > Provider of DTB for DT Control > Prior Stage bootloader DTB
> +
> +This lets U-Boot to use the QEMU generated device tree blob. During the build,
> +a build error will be seen below:
> +
> +.. code-block:: none
> +
> +  MKIMAGE u-boot.img
> +  ./tools/mkimage: Can't open arch/riscv/dts/hifive-unleashed-a00.dtb: No such file or directory
> +  ./tools/mkimage: failed to build FIT
> +  make: *** [Makefile:1440: u-boot.img] Error 1
> +
> +The above errors can be safely ignored as we don't run U-Boot SPL under QEMU
> +in this alternate configuration.
> +
> +Boot the 64-bit U-Boot S-mode image directly:
> +
> +.. code-block:: bash
> +
> +  $ qemu-system-riscv64 -M sifive_u -smp 5 -m 2G \
> +      -display none -serial stdio \
> +      -kernel /path/to/u-boot.bin
> +
> +It's possible to create a 32-bit U-Boot S-mode image as well.
> +
> +.. code-block:: bash
> +
> +  $ export CROSS_COMPILE=riscv64-linux-
> +  $ make sifive_fu540_defconfig
> +  $ make menuconfig
> +
> +then manually update the following configuration in U-Boot:
> +
> +  Device Tree Control > Provider of DTB for DT Control > Prior Stage bootloader DTB
> +  RISC-V architecture > Base ISA > RV32I
> +  Boot images > Text Base > 0x80400000
> +
> +Use the same command line options to boot the 32-bit U-Boot S-mode image:
> +
> +.. code-block:: bash
> +
> +  $ qemu-system-riscv32 -M sifive_u -smp 5 -m 2G \
> +      -display none -serial stdio \
> +      -kernel /path/to/u-boot.bin
> +
> +.. _genimage: https://github.com/pengutronix/genimage
> diff --git a/docs/system/target-riscv.rst b/docs/system/target-riscv.rst
> index 9f4b7586e5..94d99c4c82 100644
> --- a/docs/system/target-riscv.rst
> +++ b/docs/system/target-riscv.rst
> @@ -58,5 +58,15 @@ undocumented; you can get a complete list by running
>  ``qemu-system-riscv64 --machine help``, or
>  ``qemu-system-riscv32 --machine help``.
>
> +..
> +   This table of contents should be kept sorted alphabetically
> +   by the title text of each file, which isn't the same ordering
> +   as an alphabetical sort by filename.
> +
> +.. toctree::
> +   :maxdepth: 1
> +
> +   riscv/sifive_u
> +
>  RISC-V CPU features
>  -------------------

Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>

Thanks!


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

* Re: [PATCH v3 9/9] docs/system: riscv: Add documentation for sifive_u machine
@ 2021-01-27  5:51     ` Palmer Dabbelt
  0 siblings, 0 replies; 23+ messages in thread
From: Palmer Dabbelt @ 2021-01-27  5:51 UTC (permalink / raw)
  To: bmeng.cn; +Cc: Alistair Francis, qemu-riscv, qemu-devel, bin.meng

On Mon, 25 Jan 2021 22:00:07 PST (-0800), bmeng.cn@gmail.com wrote:
> From: Bin Meng <bin.meng@windriver.com>
>
> This adds detailed documentation for RISC-V `sifive_u` machine,
> including the following information:
>
> - Supported devices
> - Hardware configuration information
> - Boot options
> - Machine-specific options
> - Running Linux kernel
> - Running VxWorks kernel
> - Running U-Boot, and with an alternate configuration
>
> Signed-off-by: Bin Meng <bin.meng@windriver.com>
> Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
>
> ---
>
> Changes in v3:
> - Convert sifive_u.rst from UTF-8 to ASCII
>
> Changes in v2:
> - Correct several typos in sifive_u.rst
> - Update doc to mention U-Boot v2021.01
>
>  docs/system/riscv/sifive_u.rst | 336 +++++++++++++++++++++++++++++++++
>  docs/system/target-riscv.rst   |  10 +
>  2 files changed, 346 insertions(+)
>  create mode 100644 docs/system/riscv/sifive_u.rst
>
> diff --git a/docs/system/riscv/sifive_u.rst b/docs/system/riscv/sifive_u.rst
> new file mode 100644
> index 0000000000..98e7562848
> --- /dev/null
> +++ b/docs/system/riscv/sifive_u.rst
> @@ -0,0 +1,336 @@
> +SiFive HiFive Unleashed (``sifive_u``)
> +======================================
> +
> +SiFive HiFive Unleashed Development Board is the ultimate RISC-V development
> +board featuring the Freedom U540 multi-core RISC-V processor.
> +
> +Supported devices
> +-----------------
> +
> +The ``sifive_u`` machine supports the following devices:
> +
> + * 1 E51 / E31 core
> + * Up to 4 U54 / U34 cores
> + * Core Level Interruptor (CLINT)
> + * Platform-Level Interrupt Controller (PLIC)
> + * Power, Reset, Clock, Interrupt (PRCI)
> + * L2 Loosely Integrated Memory (L2-LIM)
> + * DDR memory controller
> + * 2 UARTs
> + * 1 GEM Ethernet controller
> + * 1 GPIO controller
> + * 1 One-Time Programmable (OTP) memory with stored serial number
> + * 1 DMA controller
> + * 2 QSPI controllers
> + * 1 ISSI 25WP256 flash
> + * 1 SD card in SPI mode
> +
> +Please note the real world HiFive Unleashed board has a fixed configuration of
> +1 E51 core and 4 U54 core combination and the RISC-V core boots in 64-bit mode.
> +With QEMU, one can create a machine with 1 E51 core and up to 4 U54 cores. It
> +is also possible to create a 32-bit variant with the same peripherals except
> +that the RISC-V cores are replaced by the 32-bit ones (E31 and U34), to help
> +testing of 32-bit guest software.
> +
> +Hardware configuration information
> +----------------------------------
> +
> +The ``sifive_u`` machine automatically generates a device tree blob ("dtb")
> +which it passes to the guest. This provides information about the addresses,
> +interrupt lines and other configuration of the various devices in the system.
> +Guest software should discover the devices that are present in the generated
> +DTB instead of using a DTB for the real hardware, as some of the devices are
> +not modeled by QEMU and trying to access these devices may cause unexpected
> +behavior.
> +
> +Boot options
> +------------
> +
> +The ``sifive_u`` machine can start using the standard -kernel functionality
> +for loading a Linux kernel, a VxWorks kernel, a modified U-Boot bootloader
> +(S-mode) or ELF executable with the default OpenSBI firmware image as the
> +-bios. It also supports booting the unmodified U-Boot bootloader using the
> +standard -bios functionality.
> +
> +Machine-specific options
> +------------------------
> +
> +The following machine-specific options are supported:
> +
> +- serial=nnn
> +
> +  The board serial number. When not given, the default serial number 1 is used.
> +
> +  SiFive reserves the first 1 KiB of the 16 KiB OTP memory for internal use.
> +  The current usage is only used to store the serial number of the board at
> +  offset 0xfc. U-Boot reads the serial number from the OTP memory, and uses
> +  it to generate a unique MAC address to be programmed to the on-chip GEM
> +  Ethernet controller. When multiple QEMU ``sifive_u`` machines are created
> +  and connected to the same subnet, they all have the same MAC address hence
> +  it creates an unusable network. In such scenario, user should give different
> +  values to serial= when creating different ``sifive_u`` machines.
> +
> +- start-in-flash
> +
> +  When given, QEMU's ROM codes jump to QSPI memory-mapped flash directly.
> +  Otherwise QEMU will jump to DRAM or L2LIM depending on the msel= value.
> +  When not given, it defaults to direct DRAM booting.
> +
> +- msel=[6|11]
> +
> +  Mode Select (MSEL[3:0]) pins value, used to control where to boot from.
> +
> +  The FU540 SoC supports booting from several sources, which are controlled
> +  using the Mode Select pins on the chip. Typically, the boot process runs
> +  through several stages before it begins execution of user-provided programs.
> +  These stages typically include the following:
> +
> +  1. Zeroth Stage Boot Loader (ZSBL), which is contained in an on-chip mask
> +     ROM and provided by QEMU. Note QEMU implemented ROM codes are not the
> +     same as what is programmed in the hardware. The QEMU one is a simplified
> +     version, but it provides the same functionality as the hardware.
> +  2. First Stage Boot Loader (FSBL), which brings up PLLs and DDR memory.
> +     This is U-Boot SPL.
> +  3. Second Stage Boot Loader (SSBL), which further initializes additional
> +     peripherals as needed. This is U-Boot proper combined with an OpenSBI
> +     fw_dynamic firmware image.
> +
> +  msel=6 means FSBL and SSBL are both on the QSPI flash. msel=11 means FSBL
> +  and SSBL are both on the SD card.
> +
> +Running Linux kernel
> +--------------------
> +
> +Linux mainline v5.10 release is tested at the time of writing. To build a
> +Linux mainline kernel that can be booted by the ``sifive_u`` machine in
> +64-bit mode, simply configure the kernel using the defconfig configuration:
> +
> +.. code-block:: bash
> +
> +  $ export ARCH=riscv
> +  $ export CROSS_COMPILE=riscv64-linux-
> +  $ make defconfig
> +  $ make
> +
> +To boot the newly built Linux kernel in QEMU with the ``sifive_u`` machine:
> +
> +.. code-block:: bash
> +
> +  $ qemu-system-riscv64 -M sifive_u -smp 5 -m 2G \
> +      -display none -serial stdio \
> +      -kernel arch/riscv/boot/Image \
> +      -initrd /path/to/rootfs.ext4 \
> +      -append "root=/dev/ram"
> +
> +To build a Linux mainline kernel that can be booted by the ``sifive_u`` machine
> +in 32-bit mode, use the rv32_defconfig configuration. A patch is required to
> +fix the 32-bit boot issue for Linux kernel v5.10.
> +
> +.. code-block:: bash
> +
> +  $ export ARCH=riscv
> +  $ export CROSS_COMPILE=riscv64-linux-
> +  $ curl https://patchwork.kernel.org/project/linux-riscv/patch/20201219001356.2887782-1-atish.patra@wdc.com/mbox/ > riscv.patch
> +  $ git am riscv.patch
> +  $ make rv32_defconfig
> +  $ make
> +
> +Replace ``qemu-system-riscv64`` with ``qemu-system-riscv32`` in the command
> +line above to boot the 32-bit Linux kernel. A rootfs image containing 32-bit
> +applications shall be used in order for kernel to boot to user space.
> +
> +Running VxWorks kernel
> +----------------------
> +
> +VxWorks 7 SR0650 release is tested at the time of writing. To build a 64-bit
> +VxWorks mainline kernel that can be booted by the ``sifive_u`` machine, simply
> +create a VxWorks source build project based on the sifive_generic BSP, and a
> +VxWorks image project to generate the bootable VxWorks image, by following the
> +BSP documentation instructions.
> +
> +A pre-built 64-bit VxWorks 7 image for HiFive Unleashed board is available as
> +part of the VxWorks SDK for testing as well. Instructions to download the SDK:
> +
> +.. code-block:: bash
> +
> +  $ wget https://labs.windriver.com/downloads/wrsdk-vxworks7-sifive-hifive-1.01.tar.bz2
> +  $ tar xvf wrsdk-vxworks7-sifive-hifive-1.01.tar.bz2
> +  $ ls bsps/sifive_generic_1_0_0_0/uboot/uVxWorks
> +
> +To boot the VxWorks kernel in QEMU with the ``sifive_u`` machine, use:
> +
> +.. code-block:: bash
> +
> +  $ qemu-system-riscv64 -M sifive_u -smp 5 -m 2G \
> +      -display none -serial stdio \
> +      -nic tap,ifname=tap0,script=no,downscript=no \
> +      -kernel /path/to/vxWorks \
> +      -append "gem(0,0)host:vxWorks h=192.168.200.1 e=192.168.200.2:ffffff00 u=target pw=vxTarget f=0x01"
> +
> +It is also possible to test 32-bit VxWorks on the ``sifive_u`` machine. Create
> +a 32-bit project to build the 32-bit VxWorks image, and use exact the same
> +command line options with ``qemu-system-riscv32``.
> +
> +Running U-Boot
> +--------------
> +
> +U-Boot mainline v2021.01 release is tested at the time of writing. To build a
> +U-Boot mainline bootloader that can be booted by the ``sifive_u`` machine, use
> +the sifive_fu540_defconfig with similar commands as described above for Linux:
> +
> +.. code-block:: bash
> +
> +  $ export CROSS_COMPILE=riscv64-linux-
> +  $ export OPENSBI=/path/to/opensbi-riscv64-generic-fw_dynamic.bin
> +  $ make sifive_fu540_defconfig
> +
> +You will get spl/u-boot-spl.bin and u-boot.itb file in the build tree.
> +
> +To start U-Boot using the ``sifive_u`` machine, prepare an SPI flash image, or
> +SD card image that is properly partitioned and populated with correct contents.
> +genimage_ can be used to generate these images.
> +
> +A sample configuration file for a 128 MiB SD card image is:
> +
> +.. code-block:: bash
> +
> +  $ cat genimage_sdcard.cfg
> +  image sdcard.img {
> +          size = 128M
> +
> +          hdimage {
> +                  gpt = true
> +          }
> +
> +          partition u-boot-spl {
> +                  image = "u-boot-spl.bin"
> +                  offset = 17K
> +                  partition-type-uuid = 5B193300-FC78-40CD-8002-E86C45580B47
> +          }
> +
> +          partition u-boot {
> +                  image = "u-boot.itb"
> +                  offset = 1041K
> +                  partition-type-uuid = 2E54B353-1271-4842-806F-E436D6AF6985
> +          }
> +  }
> +
> +SPI flash image has slightly different partition offsets, and the size has to
> +be 32 MiB to match the ISSI 25WP256 flash on the real board:
> +
> +.. code-block:: bash
> +
> +  $ cat genimage_spi-nor.cfg
> +  image spi-nor.img {
> +          size = 32M
> +
> +          hdimage {
> +                  gpt = true
> +          }
> +
> +          partition u-boot-spl {
> +                  image = "u-boot-spl.bin"
> +                  offset = 20K
> +                  partition-type-uuid = 5B193300-FC78-40CD-8002-E86C45580B47
> +          }
> +
> +          partition u-boot {
> +                  image = "u-boot.itb"
> +                  offset = 1044K
> +                  partition-type-uuid = 2E54B353-1271-4842-806F-E436D6AF6985
> +          }
> +  }
> +
> +Assume U-Boot binaries are put in the same directory as the config file,
> +we can generate the image by:
> +
> +.. code-block:: bash
> +
> +  $ genimage --config genimage_<boot_src>.cfg --inputpath .
> +
> +Boot U-Boot from SD card, by specifying msel=11 and pass the SD card image
> +to QEMU ``sifive_u`` machine:
> +
> +.. code-block:: bash
> +
> +  $ qemu-system-riscv64 -M sifive_u,msel=11 -smp 5 -m 8G \
> +      -display none -serial stdio \
> +      -bios /path/to/u-boot-spl.bin \
> +      -drive file=/path/to/sdcard.img,if=sd
> +
> +Changing msel= value to 6, allows booting U-Boot from the SPI flash:
> +
> +.. code-block:: bash
> +
> +  $ qemu-system-riscv64 -M sifive_u,msel=6 -smp 5 -m 8G \
> +      -display none -serial stdio \
> +      -bios /path/to/u-boot-spl.bin \
> +      -drive file=/path/to/spi-nor.img,if=mtd
> +
> +Note when testing U-Boot, QEMU automatically generated device tree blob is
> +not used because U-Boot itself embeds device tree blobs for U-Boot SPL and
> +U-Boot proper. Hence the number of cores and size of memory have to match
> +the real hardware, ie: 5 cores (-smp 5) and 8 GiB memory (-m 8G).
> +
> +Above use case is to run upstream U-Boot for the SiFive HiFive Unleashed
> +board on QEMU ``sifive_u`` machine out of the box. This allows users to
> +develop and test the recommended RISC-V boot flow with a real world use
> +case: ZSBL (in QEMU) loads U-Boot SPL from SD card or SPI flash to L2LIM,
> +then U-Boot SPL loads the combined payload image of OpenSBI fw_dynamic
> +firmware and U-Boot proper. However sometimes we want to have a quick test
> +of booting U-Boot on QEMU without the needs of preparing the SPI flash or
> +SD card images, an alternate way can be used, which is to create a U-Boot
> +S-mode image by modifying the configuration of U-Boot:
> +
> +.. code-block:: bash
> +
> +  $ make menuconfig
> +
> +then manually select the following configuration in U-Boot:
> +
> +  Device Tree Control > Provider of DTB for DT Control > Prior Stage bootloader DTB
> +
> +This lets U-Boot to use the QEMU generated device tree blob. During the build,
> +a build error will be seen below:
> +
> +.. code-block:: none
> +
> +  MKIMAGE u-boot.img
> +  ./tools/mkimage: Can't open arch/riscv/dts/hifive-unleashed-a00.dtb: No such file or directory
> +  ./tools/mkimage: failed to build FIT
> +  make: *** [Makefile:1440: u-boot.img] Error 1
> +
> +The above errors can be safely ignored as we don't run U-Boot SPL under QEMU
> +in this alternate configuration.
> +
> +Boot the 64-bit U-Boot S-mode image directly:
> +
> +.. code-block:: bash
> +
> +  $ qemu-system-riscv64 -M sifive_u -smp 5 -m 2G \
> +      -display none -serial stdio \
> +      -kernel /path/to/u-boot.bin
> +
> +It's possible to create a 32-bit U-Boot S-mode image as well.
> +
> +.. code-block:: bash
> +
> +  $ export CROSS_COMPILE=riscv64-linux-
> +  $ make sifive_fu540_defconfig
> +  $ make menuconfig
> +
> +then manually update the following configuration in U-Boot:
> +
> +  Device Tree Control > Provider of DTB for DT Control > Prior Stage bootloader DTB
> +  RISC-V architecture > Base ISA > RV32I
> +  Boot images > Text Base > 0x80400000
> +
> +Use the same command line options to boot the 32-bit U-Boot S-mode image:
> +
> +.. code-block:: bash
> +
> +  $ qemu-system-riscv32 -M sifive_u -smp 5 -m 2G \
> +      -display none -serial stdio \
> +      -kernel /path/to/u-boot.bin
> +
> +.. _genimage: https://github.com/pengutronix/genimage
> diff --git a/docs/system/target-riscv.rst b/docs/system/target-riscv.rst
> index 9f4b7586e5..94d99c4c82 100644
> --- a/docs/system/target-riscv.rst
> +++ b/docs/system/target-riscv.rst
> @@ -58,5 +58,15 @@ undocumented; you can get a complete list by running
>  ``qemu-system-riscv64 --machine help``, or
>  ``qemu-system-riscv32 --machine help``.
>
> +..
> +   This table of contents should be kept sorted alphabetically
> +   by the title text of each file, which isn't the same ordering
> +   as an alphabetical sort by filename.
> +
> +.. toctree::
> +   :maxdepth: 1
> +
> +   riscv/sifive_u
> +
>  RISC-V CPU features
>  -------------------

Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>

Thanks!


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

* Re: [PATCH v3 1/9] hw/block: m25p80: Add ISSI SPI flash support
  2021-01-26  5:59 ` [PATCH v3 1/9] hw/block: m25p80: Add ISSI SPI flash support Bin Meng
@ 2021-01-28 20:56     ` Alistair Francis
  0 siblings, 0 replies; 23+ messages in thread
From: Alistair Francis @ 2021-01-28 20:56 UTC (permalink / raw)
  To: Bin Meng
  Cc: open list:RISC-V, Bin Meng, Alistair Francis,
	qemu-devel@nongnu.org Developers

On Mon, Jan 25, 2021 at 10:01 PM Bin Meng <bmeng.cn@gmail.com> wrote:
>
> From: Bin Meng <bin.meng@windriver.com>
>
> This adds the ISSI SPI flash support. The number of dummy cycles in
> fast read, fast read dual output and fast read quad output commands
> is currently using the default 8. Likewise, the same default value
> is used for fast read dual/quad I/O command. Per the datasheet [1],
> the number of dummy cycles is configurable, but this is not modeled
> at present.
>
> For flash whose size is larger than 16 MiB, the sequence of 3-byte
> address along with EXTADD bit in the bank address register (BAR) is
> not supported. We assume that guest software always uses op codes
> with 4-byte address sequence. Fortunately, this is the case for both
> U-Boot and Linux spi-nor drivers.
>
> QPI (Quad Peripheral Interface) that supports 2-cycle instruction
> has different default values for dummy cycles of fast read family
> commands, and is unsupported at the time being.
>
> [1] http://www.issi.com/WW/pdf/25LP-WP256.pdf
>
> Signed-off-by: Bin Meng <bin.meng@windriver.com>

Acked-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

>
> ---
>
> (no changes since v2)
>
> Changes in v2:
> - Mention QPI (Quad Peripheral Interface) mode is not supported
>
>  hw/block/m25p80.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 43 insertions(+), 1 deletion(-)
>
> diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
> index b744a58d1c..217c130f56 100644
> --- a/hw/block/m25p80.c
> +++ b/hw/block/m25p80.c
> @@ -412,6 +412,7 @@ typedef enum {
>      MAN_NUMONYX,
>      MAN_WINBOND,
>      MAN_SST,
> +    MAN_ISSI,
>      MAN_GENERIC,
>  } Manufacturer;
>
> @@ -487,6 +488,8 @@ static inline Manufacturer get_man(Flash *s)
>          return MAN_MACRONIX;
>      case 0xBF:
>          return MAN_SST;
> +    case 0x9D:
> +        return MAN_ISSI;
>      default:
>          return MAN_GENERIC;
>      }
> @@ -706,6 +709,9 @@ static void complete_collecting_data(Flash *s)
>          case MAN_SPANSION:
>              s->quad_enable = !!(s->data[1] & 0x02);
>              break;
> +        case MAN_ISSI:
> +            s->quad_enable = extract32(s->data[0], 6, 1);
> +            break;
>          case MAN_MACRONIX:
>              s->quad_enable = extract32(s->data[0], 6, 1);
>              if (s->len > 1) {
> @@ -895,6 +901,19 @@ static void decode_fast_read_cmd(Flash *s)
>                                      SPANSION_DUMMY_CLK_LEN
>                                      );
>          break;
> +    case MAN_ISSI:
> +        /*
> +         * The Fast Read instruction code is followed by address bytes and
> +         * dummy cycles, transmitted via the SI line.
> +         *
> +         * The number of dummy cycles is configurable but this is currently
> +         * unmodeled, hence the default value 8 is used.
> +         *
> +         * QPI (Quad Peripheral Interface) mode has different default value
> +         * of dummy cycles, but this is unsupported at the time being.
> +         */
> +        s->needed_bytes += 1;
> +        break;
>      default:
>          break;
>      }
> @@ -934,6 +953,16 @@ static void decode_dio_read_cmd(Flash *s)
>              break;
>          }
>          break;
> +    case MAN_ISSI:
> +        /*
> +         * The Fast Read Dual I/O instruction code is followed by address bytes
> +         * and dummy cycles, transmitted via the IO1 and IO0 line.
> +         *
> +         * The number of dummy cycles is configurable but this is currently
> +         * unmodeled, hence the default value 4 is used.
> +         */
> +        s->needed_bytes += 1;
> +        break;
>      default:
>          break;
>      }
> @@ -974,6 +1003,19 @@ static void decode_qio_read_cmd(Flash *s)
>              break;
>          }
>          break;
> +    case MAN_ISSI:
> +        /*
> +         * The Fast Read Quad I/O instruction code is followed by address bytes
> +         * and dummy cycles, transmitted via the IO3, IO2, IO1 and IO0 line.
> +         *
> +         * The number of dummy cycles is configurable but this is currently
> +         * unmodeled, hence the default value 6 is used.
> +         *
> +         * QPI (Quad Peripheral Interface) mode has different default value
> +         * of dummy cycles, but this is unsupported at the time being.
> +         */
> +        s->needed_bytes += 3;
> +        break;
>      default:
>          break;
>      }
> @@ -1132,7 +1174,7 @@ static void decode_new_cmd(Flash *s, uint32_t value)
>
>      case RDSR:
>          s->data[0] = (!!s->write_enable) << 1;
> -        if (get_man(s) == MAN_MACRONIX) {
> +        if (get_man(s) == MAN_MACRONIX || get_man(s) == MAN_ISSI) {
>              s->data[0] |= (!!s->quad_enable) << 6;
>          }
>          if (get_man(s) == MAN_SST) {
> --
> 2.25.1
>
>


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

* Re: [PATCH v3 1/9] hw/block: m25p80: Add ISSI SPI flash support
@ 2021-01-28 20:56     ` Alistair Francis
  0 siblings, 0 replies; 23+ messages in thread
From: Alistair Francis @ 2021-01-28 20:56 UTC (permalink / raw)
  To: Bin Meng
  Cc: Alistair Francis, open list:RISC-V,
	qemu-devel@nongnu.org Developers, Bin Meng

On Mon, Jan 25, 2021 at 10:01 PM Bin Meng <bmeng.cn@gmail.com> wrote:
>
> From: Bin Meng <bin.meng@windriver.com>
>
> This adds the ISSI SPI flash support. The number of dummy cycles in
> fast read, fast read dual output and fast read quad output commands
> is currently using the default 8. Likewise, the same default value
> is used for fast read dual/quad I/O command. Per the datasheet [1],
> the number of dummy cycles is configurable, but this is not modeled
> at present.
>
> For flash whose size is larger than 16 MiB, the sequence of 3-byte
> address along with EXTADD bit in the bank address register (BAR) is
> not supported. We assume that guest software always uses op codes
> with 4-byte address sequence. Fortunately, this is the case for both
> U-Boot and Linux spi-nor drivers.
>
> QPI (Quad Peripheral Interface) that supports 2-cycle instruction
> has different default values for dummy cycles of fast read family
> commands, and is unsupported at the time being.
>
> [1] http://www.issi.com/WW/pdf/25LP-WP256.pdf
>
> Signed-off-by: Bin Meng <bin.meng@windriver.com>

Acked-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

>
> ---
>
> (no changes since v2)
>
> Changes in v2:
> - Mention QPI (Quad Peripheral Interface) mode is not supported
>
>  hw/block/m25p80.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 43 insertions(+), 1 deletion(-)
>
> diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
> index b744a58d1c..217c130f56 100644
> --- a/hw/block/m25p80.c
> +++ b/hw/block/m25p80.c
> @@ -412,6 +412,7 @@ typedef enum {
>      MAN_NUMONYX,
>      MAN_WINBOND,
>      MAN_SST,
> +    MAN_ISSI,
>      MAN_GENERIC,
>  } Manufacturer;
>
> @@ -487,6 +488,8 @@ static inline Manufacturer get_man(Flash *s)
>          return MAN_MACRONIX;
>      case 0xBF:
>          return MAN_SST;
> +    case 0x9D:
> +        return MAN_ISSI;
>      default:
>          return MAN_GENERIC;
>      }
> @@ -706,6 +709,9 @@ static void complete_collecting_data(Flash *s)
>          case MAN_SPANSION:
>              s->quad_enable = !!(s->data[1] & 0x02);
>              break;
> +        case MAN_ISSI:
> +            s->quad_enable = extract32(s->data[0], 6, 1);
> +            break;
>          case MAN_MACRONIX:
>              s->quad_enable = extract32(s->data[0], 6, 1);
>              if (s->len > 1) {
> @@ -895,6 +901,19 @@ static void decode_fast_read_cmd(Flash *s)
>                                      SPANSION_DUMMY_CLK_LEN
>                                      );
>          break;
> +    case MAN_ISSI:
> +        /*
> +         * The Fast Read instruction code is followed by address bytes and
> +         * dummy cycles, transmitted via the SI line.
> +         *
> +         * The number of dummy cycles is configurable but this is currently
> +         * unmodeled, hence the default value 8 is used.
> +         *
> +         * QPI (Quad Peripheral Interface) mode has different default value
> +         * of dummy cycles, but this is unsupported at the time being.
> +         */
> +        s->needed_bytes += 1;
> +        break;
>      default:
>          break;
>      }
> @@ -934,6 +953,16 @@ static void decode_dio_read_cmd(Flash *s)
>              break;
>          }
>          break;
> +    case MAN_ISSI:
> +        /*
> +         * The Fast Read Dual I/O instruction code is followed by address bytes
> +         * and dummy cycles, transmitted via the IO1 and IO0 line.
> +         *
> +         * The number of dummy cycles is configurable but this is currently
> +         * unmodeled, hence the default value 4 is used.
> +         */
> +        s->needed_bytes += 1;
> +        break;
>      default:
>          break;
>      }
> @@ -974,6 +1003,19 @@ static void decode_qio_read_cmd(Flash *s)
>              break;
>          }
>          break;
> +    case MAN_ISSI:
> +        /*
> +         * The Fast Read Quad I/O instruction code is followed by address bytes
> +         * and dummy cycles, transmitted via the IO3, IO2, IO1 and IO0 line.
> +         *
> +         * The number of dummy cycles is configurable but this is currently
> +         * unmodeled, hence the default value 6 is used.
> +         *
> +         * QPI (Quad Peripheral Interface) mode has different default value
> +         * of dummy cycles, but this is unsupported at the time being.
> +         */
> +        s->needed_bytes += 3;
> +        break;
>      default:
>          break;
>      }
> @@ -1132,7 +1174,7 @@ static void decode_new_cmd(Flash *s, uint32_t value)
>
>      case RDSR:
>          s->data[0] = (!!s->write_enable) << 1;
> -        if (get_man(s) == MAN_MACRONIX) {
> +        if (get_man(s) == MAN_MACRONIX || get_man(s) == MAN_ISSI) {
>              s->data[0] |= (!!s->quad_enable) << 6;
>          }
>          if (get_man(s) == MAN_SST) {
> --
> 2.25.1
>
>


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

* Re: [PATCH v3 3/9] hw/ssi: Add SiFive SPI controller support
  2021-01-26  6:00 ` [PATCH v3 3/9] hw/ssi: Add SiFive SPI controller support Bin Meng
@ 2021-02-09  1:38     ` Alistair Francis
  2021-02-09  1:38     ` Alistair Francis
  1 sibling, 0 replies; 23+ messages in thread
From: Alistair Francis @ 2021-02-09  1:38 UTC (permalink / raw)
  To: Bin Meng
  Cc: open list:RISC-V, Bin Meng, Alistair Francis,
	qemu-devel@nongnu.org Developers

On Mon, Jan 25, 2021 at 10:03 PM Bin Meng <bmeng.cn@gmail.com> wrote:
>
> From: Bin Meng <bin.meng@windriver.com>
>
> This adds the SiFive SPI controller model for the FU540 SoC.
> The direct memory-mapped SPI flash mode is unsupported.
>
> Signed-off-by: Bin Meng <bin.meng@windriver.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

>
> ---
>
> Changes in v3:
> - Simplify flush txfifo logic
>
> Changes in v2:
> - Log guest error when trying to write reserved registers
> - Log guest error when trying to access out-of-bounds registers
> - log guest error when writing to reserved bits for chip select
>   registers and watermark registers
> - Log unimplemented warning when trying to write direct-map flash
>   interface registers
> - Add test tx fifo full logic in sifive_spi_read(), hence remove
>   setting the tx fifo full flag in sifive_spi_write().
> - Populate register with their default value
>
>  include/hw/ssi/sifive_spi.h |  47 +++++
>  hw/ssi/sifive_spi.c         | 358 ++++++++++++++++++++++++++++++++++++
>  hw/ssi/Kconfig              |   4 +
>  hw/ssi/meson.build          |   1 +
>  4 files changed, 410 insertions(+)
>  create mode 100644 include/hw/ssi/sifive_spi.h
>  create mode 100644 hw/ssi/sifive_spi.c
>
> diff --git a/include/hw/ssi/sifive_spi.h b/include/hw/ssi/sifive_spi.h
> new file mode 100644
> index 0000000000..47d0d6a47c
> --- /dev/null
> +++ b/include/hw/ssi/sifive_spi.h
> @@ -0,0 +1,47 @@
> +/*
> + * QEMU model of the SiFive SPI Controller
> + *
> + * Copyright (c) 2021 Wind River Systems, Inc.
> + *
> + * Author:
> + *   Bin Meng <bin.meng@windriver.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2 or later, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef HW_SIFIVE_SPI_H
> +#define HW_SIFIVE_SPI_H
> +
> +#define SIFIVE_SPI_REG_NUM  (0x78 / 4)
> +
> +#define TYPE_SIFIVE_SPI "sifive.spi"
> +#define SIFIVE_SPI(obj) OBJECT_CHECK(SiFiveSPIState, (obj), TYPE_SIFIVE_SPI)
> +
> +typedef struct SiFiveSPIState {
> +    SysBusDevice parent_obj;
> +
> +    MemoryRegion mmio;
> +    qemu_irq irq;
> +
> +    uint32_t num_cs;
> +    qemu_irq *cs_lines;
> +
> +    SSIBus *spi;
> +
> +    Fifo8 tx_fifo;
> +    Fifo8 rx_fifo;
> +
> +    uint32_t regs[SIFIVE_SPI_REG_NUM];
> +} SiFiveSPIState;
> +
> +#endif /* HW_SIFIVE_SPI_H */
> diff --git a/hw/ssi/sifive_spi.c b/hw/ssi/sifive_spi.c
> new file mode 100644
> index 0000000000..0c9ebca3c8
> --- /dev/null
> +++ b/hw/ssi/sifive_spi.c
> @@ -0,0 +1,358 @@
> +/*
> + * QEMU model of the SiFive SPI Controller
> + *
> + * Copyright (c) 2021 Wind River Systems, Inc.
> + *
> + * Author:
> + *   Bin Meng <bin.meng@windriver.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2 or later, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/irq.h"
> +#include "hw/qdev-properties.h"
> +#include "hw/sysbus.h"
> +#include "hw/ssi/ssi.h"
> +#include "sysemu/sysemu.h"
> +#include "qemu/fifo8.h"
> +#include "qemu/log.h"
> +#include "qemu/module.h"
> +#include "hw/ssi/sifive_spi.h"
> +
> +#define R_SCKDIV        (0x00 / 4)
> +#define R_SCKMODE       (0x04 / 4)
> +#define R_CSID          (0x10 / 4)
> +#define R_CSDEF         (0x14 / 4)
> +#define R_CSMODE        (0x18 / 4)
> +#define R_DELAY0        (0x28 / 4)
> +#define R_DELAY1        (0x2C / 4)
> +#define R_FMT           (0x40 / 4)
> +#define R_TXDATA        (0x48 / 4)
> +#define R_RXDATA        (0x4C / 4)
> +#define R_TXMARK        (0x50 / 4)
> +#define R_RXMARK        (0x54 / 4)
> +#define R_FCTRL         (0x60 / 4)
> +#define R_FFMT          (0x64 / 4)
> +#define R_IE            (0x70 / 4)
> +#define R_IP            (0x74 / 4)
> +
> +#define FMT_DIR         (1 << 3)
> +
> +#define TXDATA_FULL     (1 << 31)
> +#define RXDATA_EMPTY    (1 << 31)
> +
> +#define IE_TXWM         (1 << 0)
> +#define IE_RXWM         (1 << 1)
> +
> +#define IP_TXWM         (1 << 0)
> +#define IP_RXWM         (1 << 1)
> +
> +#define FIFO_CAPACITY   8
> +
> +static void sifive_spi_txfifo_reset(SiFiveSPIState *s)
> +{
> +    fifo8_reset(&s->tx_fifo);
> +
> +    s->regs[R_TXDATA] &= ~TXDATA_FULL;
> +    s->regs[R_IP] &= ~IP_TXWM;
> +}
> +
> +static void sifive_spi_rxfifo_reset(SiFiveSPIState *s)
> +{
> +    fifo8_reset(&s->rx_fifo);
> +
> +    s->regs[R_RXDATA] |= RXDATA_EMPTY;
> +    s->regs[R_IP] &= ~IP_RXWM;
> +}
> +
> +static void sifive_spi_update_cs(SiFiveSPIState *s)
> +{
> +    int i;
> +
> +    for (i = 0; i < s->num_cs; i++) {
> +        if (s->regs[R_CSDEF] & (1 << i)) {
> +            qemu_set_irq(s->cs_lines[i], !(s->regs[R_CSMODE]));
> +        }
> +    }
> +}
> +
> +static void sifive_spi_update_irq(SiFiveSPIState *s)
> +{
> +    int level;
> +
> +    if (fifo8_num_used(&s->tx_fifo) < s->regs[R_TXMARK]) {
> +        s->regs[R_IP] |= IP_TXWM;
> +    } else {
> +        s->regs[R_IP] &= ~IP_TXWM;
> +    }
> +
> +    if (fifo8_num_used(&s->rx_fifo) > s->regs[R_RXMARK]) {
> +        s->regs[R_IP] |= IP_RXWM;
> +    } else {
> +        s->regs[R_IP] &= ~IP_RXWM;
> +    }
> +
> +    level = s->regs[R_IP] & s->regs[R_IE] ? 1 : 0;
> +    qemu_set_irq(s->irq, level);
> +}
> +
> +static void sifive_spi_reset(DeviceState *d)
> +{
> +    SiFiveSPIState *s = SIFIVE_SPI(d);
> +
> +    memset(s->regs, 0, sizeof(s->regs));
> +
> +    /* The reset value is high for all implemented CS pins */
> +    s->regs[R_CSDEF] = (1 << s->num_cs) - 1;
> +
> +    /* Populate register with their default value */
> +    s->regs[R_SCKDIV] = 0x03;
> +    s->regs[R_DELAY0] = 0x1001;
> +    s->regs[R_DELAY1] = 0x01;
> +
> +    sifive_spi_txfifo_reset(s);
> +    sifive_spi_rxfifo_reset(s);
> +
> +    sifive_spi_update_cs(s);
> +    sifive_spi_update_irq(s);
> +}
> +
> +static void sifive_spi_flush_txfifo(SiFiveSPIState *s)
> +{
> +    uint8_t tx;
> +    uint8_t rx;
> +
> +    while (!fifo8_is_empty(&s->tx_fifo)) {
> +        tx = fifo8_pop(&s->tx_fifo);
> +        rx = ssi_transfer(s->spi, tx);
> +
> +        if (!fifo8_is_full(&s->rx_fifo)) {
> +            if (!(s->regs[R_FMT] & FMT_DIR)) {
> +                fifo8_push(&s->rx_fifo, rx);
> +            }
> +        }
> +    }
> +}
> +
> +static bool sifive_spi_is_bad_reg(hwaddr addr, bool allow_reserved)
> +{
> +    bool bad;
> +
> +    switch (addr) {
> +    /* reserved offsets */
> +    case 0x08:
> +    case 0x0C:
> +    case 0x1C:
> +    case 0x20:
> +    case 0x24:
> +    case 0x30:
> +    case 0x34:
> +    case 0x38:
> +    case 0x3C:
> +    case 0x44:
> +    case 0x58:
> +    case 0x5C:
> +    case 0x68:
> +    case 0x6C:
> +        bad = allow_reserved ? false : true;
> +        break;
> +    default:
> +        bad = false;
> +    }
> +
> +    if (addr >= (SIFIVE_SPI_REG_NUM << 2)) {
> +        bad = true;
> +    }
> +
> +    return bad;
> +}
> +
> +static uint64_t sifive_spi_read(void *opaque, hwaddr addr, unsigned int size)
> +{
> +    SiFiveSPIState *s = opaque;
> +    uint32_t r;
> +
> +    if (sifive_spi_is_bad_reg(addr, true)) {
> +        qemu_log_mask(LOG_GUEST_ERROR, "%s: bad read at address 0x%"
> +                      HWADDR_PRIx "\n", __func__, addr);
> +        return 0;
> +    }
> +
> +    addr >>= 2;
> +    switch (addr) {
> +    case R_TXDATA:
> +        if (fifo8_is_full(&s->tx_fifo)) {
> +            return TXDATA_FULL;
> +        }
> +        r = 0;
> +        break;
> +
> +    case R_RXDATA:
> +        if (fifo8_is_empty(&s->rx_fifo)) {
> +            return RXDATA_EMPTY;
> +        }
> +        r = fifo8_pop(&s->rx_fifo);
> +        break;
> +
> +    default:
> +        r = s->regs[addr];
> +        break;
> +    }
> +
> +    sifive_spi_update_irq(s);
> +
> +    return r;
> +}
> +
> +static void sifive_spi_write(void *opaque, hwaddr addr,
> +                             uint64_t val64, unsigned int size)
> +{
> +    SiFiveSPIState *s = opaque;
> +    uint32_t value = val64;
> +
> +    if (sifive_spi_is_bad_reg(addr, false)) {
> +        qemu_log_mask(LOG_GUEST_ERROR, "%s: bad write at addr=0x%"
> +                      HWADDR_PRIx " value=0x%x\n", __func__, addr, value);
> +        return;
> +    }
> +
> +    addr >>= 2;
> +    switch (addr) {
> +    case R_CSID:
> +        if (value >= s->num_cs) {
> +            qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid csid %d\n",
> +                          __func__, value);
> +        } else {
> +            s->regs[R_CSID] = value;
> +            sifive_spi_update_cs(s);
> +        }
> +        break;
> +
> +    case R_CSDEF:
> +        if (value >= (1 << s->num_cs)) {
> +            qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid csdef %x\n",
> +                          __func__, value);
> +        } else {
> +            s->regs[R_CSDEF] = value;
> +        }
> +        break;
> +
> +    case R_CSMODE:
> +        if (value > 3) {
> +            qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid csmode %x\n",
> +                          __func__, value);
> +        } else {
> +            s->regs[R_CSMODE] = value;
> +            sifive_spi_update_cs(s);
> +        }
> +        break;
> +
> +    case R_TXDATA:
> +        if (!fifo8_is_full(&s->tx_fifo)) {
> +            fifo8_push(&s->tx_fifo, (uint8_t)value);
> +            sifive_spi_flush_txfifo(s);
> +        }
> +        break;
> +
> +    case R_RXDATA:
> +    case R_IP:
> +        qemu_log_mask(LOG_GUEST_ERROR,
> +                      "%s: invalid write to read-only reigster 0x%"
> +                      HWADDR_PRIx " with 0x%x\n", __func__, addr << 2, value);
> +        break;
> +
> +    case R_TXMARK:
> +    case R_RXMARK:
> +        if (value >= FIFO_CAPACITY) {
> +            qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid watermark %d\n",
> +                          __func__, value);
> +        } else {
> +            s->regs[addr] = value;
> +        }
> +        break;
> +
> +    case R_FCTRL:
> +    case R_FFMT:
> +        qemu_log_mask(LOG_UNIMP,
> +                      "%s: direct-map flash interface unimplemented\n",
> +                      __func__);
> +        break;
> +
> +    default:
> +        s->regs[addr] = value;
> +        break;
> +    }
> +
> +    sifive_spi_update_irq(s);
> +}
> +
> +static const MemoryRegionOps sifive_spi_ops = {
> +    .read = sifive_spi_read,
> +    .write = sifive_spi_write,
> +    .endianness = DEVICE_LITTLE_ENDIAN,
> +    .valid = {
> +        .min_access_size = 4,
> +        .max_access_size = 4
> +    }
> +};
> +
> +static void sifive_spi_realize(DeviceState *dev, Error **errp)
> +{
> +    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
> +    SiFiveSPIState *s = SIFIVE_SPI(dev);
> +    int i;
> +
> +    s->spi = ssi_create_bus(dev, "spi");
> +    sysbus_init_irq(sbd, &s->irq);
> +
> +    s->cs_lines = g_new0(qemu_irq, s->num_cs);
> +    for (i = 0; i < s->num_cs; i++) {
> +        sysbus_init_irq(sbd, &s->cs_lines[i]);
> +    }
> +
> +    memory_region_init_io(&s->mmio, OBJECT(s), &sifive_spi_ops, s,
> +                          TYPE_SIFIVE_SPI, 0x1000);
> +    sysbus_init_mmio(sbd, &s->mmio);
> +
> +    fifo8_create(&s->tx_fifo, FIFO_CAPACITY);
> +    fifo8_create(&s->rx_fifo, FIFO_CAPACITY);
> +}
> +
> +static Property sifive_spi_properties[] = {
> +    DEFINE_PROP_UINT32("num-cs", SiFiveSPIState, num_cs, 1),
> +    DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void sifive_spi_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +
> +    device_class_set_props(dc, sifive_spi_properties);
> +    dc->reset = sifive_spi_reset;
> +    dc->realize = sifive_spi_realize;
> +}
> +
> +static const TypeInfo sifive_spi_info = {
> +    .name           = TYPE_SIFIVE_SPI,
> +    .parent         = TYPE_SYS_BUS_DEVICE,
> +    .instance_size  = sizeof(SiFiveSPIState),
> +    .class_init     = sifive_spi_class_init,
> +};
> +
> +static void sifive_spi_register_types(void)
> +{
> +    type_register_static(&sifive_spi_info);
> +}
> +
> +type_init(sifive_spi_register_types)
> diff --git a/hw/ssi/Kconfig b/hw/ssi/Kconfig
> index 9e54a0c8dd..7d90a02181 100644
> --- a/hw/ssi/Kconfig
> +++ b/hw/ssi/Kconfig
> @@ -2,6 +2,10 @@ config PL022
>      bool
>      select SSI
>
> +config SIFIVE_SPI
> +    bool
> +    select SSI
> +
>  config SSI
>      bool
>
> diff --git a/hw/ssi/meson.build b/hw/ssi/meson.build
> index dee00c0da6..3d6bc82ab1 100644
> --- a/hw/ssi/meson.build
> +++ b/hw/ssi/meson.build
> @@ -2,6 +2,7 @@ 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_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'))
>  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'))
> --
> 2.25.1
>
>


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

* Re: [PATCH v3 3/9] hw/ssi: Add SiFive SPI controller support
@ 2021-02-09  1:38     ` Alistair Francis
  0 siblings, 0 replies; 23+ messages in thread
From: Alistair Francis @ 2021-02-09  1:38 UTC (permalink / raw)
  To: Bin Meng
  Cc: Alistair Francis, open list:RISC-V,
	qemu-devel@nongnu.org Developers, Bin Meng

On Mon, Jan 25, 2021 at 10:03 PM Bin Meng <bmeng.cn@gmail.com> wrote:
>
> From: Bin Meng <bin.meng@windriver.com>
>
> This adds the SiFive SPI controller model for the FU540 SoC.
> The direct memory-mapped SPI flash mode is unsupported.
>
> Signed-off-by: Bin Meng <bin.meng@windriver.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

>
> ---
>
> Changes in v3:
> - Simplify flush txfifo logic
>
> Changes in v2:
> - Log guest error when trying to write reserved registers
> - Log guest error when trying to access out-of-bounds registers
> - log guest error when writing to reserved bits for chip select
>   registers and watermark registers
> - Log unimplemented warning when trying to write direct-map flash
>   interface registers
> - Add test tx fifo full logic in sifive_spi_read(), hence remove
>   setting the tx fifo full flag in sifive_spi_write().
> - Populate register with their default value
>
>  include/hw/ssi/sifive_spi.h |  47 +++++
>  hw/ssi/sifive_spi.c         | 358 ++++++++++++++++++++++++++++++++++++
>  hw/ssi/Kconfig              |   4 +
>  hw/ssi/meson.build          |   1 +
>  4 files changed, 410 insertions(+)
>  create mode 100644 include/hw/ssi/sifive_spi.h
>  create mode 100644 hw/ssi/sifive_spi.c
>
> diff --git a/include/hw/ssi/sifive_spi.h b/include/hw/ssi/sifive_spi.h
> new file mode 100644
> index 0000000000..47d0d6a47c
> --- /dev/null
> +++ b/include/hw/ssi/sifive_spi.h
> @@ -0,0 +1,47 @@
> +/*
> + * QEMU model of the SiFive SPI Controller
> + *
> + * Copyright (c) 2021 Wind River Systems, Inc.
> + *
> + * Author:
> + *   Bin Meng <bin.meng@windriver.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2 or later, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef HW_SIFIVE_SPI_H
> +#define HW_SIFIVE_SPI_H
> +
> +#define SIFIVE_SPI_REG_NUM  (0x78 / 4)
> +
> +#define TYPE_SIFIVE_SPI "sifive.spi"
> +#define SIFIVE_SPI(obj) OBJECT_CHECK(SiFiveSPIState, (obj), TYPE_SIFIVE_SPI)
> +
> +typedef struct SiFiveSPIState {
> +    SysBusDevice parent_obj;
> +
> +    MemoryRegion mmio;
> +    qemu_irq irq;
> +
> +    uint32_t num_cs;
> +    qemu_irq *cs_lines;
> +
> +    SSIBus *spi;
> +
> +    Fifo8 tx_fifo;
> +    Fifo8 rx_fifo;
> +
> +    uint32_t regs[SIFIVE_SPI_REG_NUM];
> +} SiFiveSPIState;
> +
> +#endif /* HW_SIFIVE_SPI_H */
> diff --git a/hw/ssi/sifive_spi.c b/hw/ssi/sifive_spi.c
> new file mode 100644
> index 0000000000..0c9ebca3c8
> --- /dev/null
> +++ b/hw/ssi/sifive_spi.c
> @@ -0,0 +1,358 @@
> +/*
> + * QEMU model of the SiFive SPI Controller
> + *
> + * Copyright (c) 2021 Wind River Systems, Inc.
> + *
> + * Author:
> + *   Bin Meng <bin.meng@windriver.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2 or later, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/irq.h"
> +#include "hw/qdev-properties.h"
> +#include "hw/sysbus.h"
> +#include "hw/ssi/ssi.h"
> +#include "sysemu/sysemu.h"
> +#include "qemu/fifo8.h"
> +#include "qemu/log.h"
> +#include "qemu/module.h"
> +#include "hw/ssi/sifive_spi.h"
> +
> +#define R_SCKDIV        (0x00 / 4)
> +#define R_SCKMODE       (0x04 / 4)
> +#define R_CSID          (0x10 / 4)
> +#define R_CSDEF         (0x14 / 4)
> +#define R_CSMODE        (0x18 / 4)
> +#define R_DELAY0        (0x28 / 4)
> +#define R_DELAY1        (0x2C / 4)
> +#define R_FMT           (0x40 / 4)
> +#define R_TXDATA        (0x48 / 4)
> +#define R_RXDATA        (0x4C / 4)
> +#define R_TXMARK        (0x50 / 4)
> +#define R_RXMARK        (0x54 / 4)
> +#define R_FCTRL         (0x60 / 4)
> +#define R_FFMT          (0x64 / 4)
> +#define R_IE            (0x70 / 4)
> +#define R_IP            (0x74 / 4)
> +
> +#define FMT_DIR         (1 << 3)
> +
> +#define TXDATA_FULL     (1 << 31)
> +#define RXDATA_EMPTY    (1 << 31)
> +
> +#define IE_TXWM         (1 << 0)
> +#define IE_RXWM         (1 << 1)
> +
> +#define IP_TXWM         (1 << 0)
> +#define IP_RXWM         (1 << 1)
> +
> +#define FIFO_CAPACITY   8
> +
> +static void sifive_spi_txfifo_reset(SiFiveSPIState *s)
> +{
> +    fifo8_reset(&s->tx_fifo);
> +
> +    s->regs[R_TXDATA] &= ~TXDATA_FULL;
> +    s->regs[R_IP] &= ~IP_TXWM;
> +}
> +
> +static void sifive_spi_rxfifo_reset(SiFiveSPIState *s)
> +{
> +    fifo8_reset(&s->rx_fifo);
> +
> +    s->regs[R_RXDATA] |= RXDATA_EMPTY;
> +    s->regs[R_IP] &= ~IP_RXWM;
> +}
> +
> +static void sifive_spi_update_cs(SiFiveSPIState *s)
> +{
> +    int i;
> +
> +    for (i = 0; i < s->num_cs; i++) {
> +        if (s->regs[R_CSDEF] & (1 << i)) {
> +            qemu_set_irq(s->cs_lines[i], !(s->regs[R_CSMODE]));
> +        }
> +    }
> +}
> +
> +static void sifive_spi_update_irq(SiFiveSPIState *s)
> +{
> +    int level;
> +
> +    if (fifo8_num_used(&s->tx_fifo) < s->regs[R_TXMARK]) {
> +        s->regs[R_IP] |= IP_TXWM;
> +    } else {
> +        s->regs[R_IP] &= ~IP_TXWM;
> +    }
> +
> +    if (fifo8_num_used(&s->rx_fifo) > s->regs[R_RXMARK]) {
> +        s->regs[R_IP] |= IP_RXWM;
> +    } else {
> +        s->regs[R_IP] &= ~IP_RXWM;
> +    }
> +
> +    level = s->regs[R_IP] & s->regs[R_IE] ? 1 : 0;
> +    qemu_set_irq(s->irq, level);
> +}
> +
> +static void sifive_spi_reset(DeviceState *d)
> +{
> +    SiFiveSPIState *s = SIFIVE_SPI(d);
> +
> +    memset(s->regs, 0, sizeof(s->regs));
> +
> +    /* The reset value is high for all implemented CS pins */
> +    s->regs[R_CSDEF] = (1 << s->num_cs) - 1;
> +
> +    /* Populate register with their default value */
> +    s->regs[R_SCKDIV] = 0x03;
> +    s->regs[R_DELAY0] = 0x1001;
> +    s->regs[R_DELAY1] = 0x01;
> +
> +    sifive_spi_txfifo_reset(s);
> +    sifive_spi_rxfifo_reset(s);
> +
> +    sifive_spi_update_cs(s);
> +    sifive_spi_update_irq(s);
> +}
> +
> +static void sifive_spi_flush_txfifo(SiFiveSPIState *s)
> +{
> +    uint8_t tx;
> +    uint8_t rx;
> +
> +    while (!fifo8_is_empty(&s->tx_fifo)) {
> +        tx = fifo8_pop(&s->tx_fifo);
> +        rx = ssi_transfer(s->spi, tx);
> +
> +        if (!fifo8_is_full(&s->rx_fifo)) {
> +            if (!(s->regs[R_FMT] & FMT_DIR)) {
> +                fifo8_push(&s->rx_fifo, rx);
> +            }
> +        }
> +    }
> +}
> +
> +static bool sifive_spi_is_bad_reg(hwaddr addr, bool allow_reserved)
> +{
> +    bool bad;
> +
> +    switch (addr) {
> +    /* reserved offsets */
> +    case 0x08:
> +    case 0x0C:
> +    case 0x1C:
> +    case 0x20:
> +    case 0x24:
> +    case 0x30:
> +    case 0x34:
> +    case 0x38:
> +    case 0x3C:
> +    case 0x44:
> +    case 0x58:
> +    case 0x5C:
> +    case 0x68:
> +    case 0x6C:
> +        bad = allow_reserved ? false : true;
> +        break;
> +    default:
> +        bad = false;
> +    }
> +
> +    if (addr >= (SIFIVE_SPI_REG_NUM << 2)) {
> +        bad = true;
> +    }
> +
> +    return bad;
> +}
> +
> +static uint64_t sifive_spi_read(void *opaque, hwaddr addr, unsigned int size)
> +{
> +    SiFiveSPIState *s = opaque;
> +    uint32_t r;
> +
> +    if (sifive_spi_is_bad_reg(addr, true)) {
> +        qemu_log_mask(LOG_GUEST_ERROR, "%s: bad read at address 0x%"
> +                      HWADDR_PRIx "\n", __func__, addr);
> +        return 0;
> +    }
> +
> +    addr >>= 2;
> +    switch (addr) {
> +    case R_TXDATA:
> +        if (fifo8_is_full(&s->tx_fifo)) {
> +            return TXDATA_FULL;
> +        }
> +        r = 0;
> +        break;
> +
> +    case R_RXDATA:
> +        if (fifo8_is_empty(&s->rx_fifo)) {
> +            return RXDATA_EMPTY;
> +        }
> +        r = fifo8_pop(&s->rx_fifo);
> +        break;
> +
> +    default:
> +        r = s->regs[addr];
> +        break;
> +    }
> +
> +    sifive_spi_update_irq(s);
> +
> +    return r;
> +}
> +
> +static void sifive_spi_write(void *opaque, hwaddr addr,
> +                             uint64_t val64, unsigned int size)
> +{
> +    SiFiveSPIState *s = opaque;
> +    uint32_t value = val64;
> +
> +    if (sifive_spi_is_bad_reg(addr, false)) {
> +        qemu_log_mask(LOG_GUEST_ERROR, "%s: bad write at addr=0x%"
> +                      HWADDR_PRIx " value=0x%x\n", __func__, addr, value);
> +        return;
> +    }
> +
> +    addr >>= 2;
> +    switch (addr) {
> +    case R_CSID:
> +        if (value >= s->num_cs) {
> +            qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid csid %d\n",
> +                          __func__, value);
> +        } else {
> +            s->regs[R_CSID] = value;
> +            sifive_spi_update_cs(s);
> +        }
> +        break;
> +
> +    case R_CSDEF:
> +        if (value >= (1 << s->num_cs)) {
> +            qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid csdef %x\n",
> +                          __func__, value);
> +        } else {
> +            s->regs[R_CSDEF] = value;
> +        }
> +        break;
> +
> +    case R_CSMODE:
> +        if (value > 3) {
> +            qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid csmode %x\n",
> +                          __func__, value);
> +        } else {
> +            s->regs[R_CSMODE] = value;
> +            sifive_spi_update_cs(s);
> +        }
> +        break;
> +
> +    case R_TXDATA:
> +        if (!fifo8_is_full(&s->tx_fifo)) {
> +            fifo8_push(&s->tx_fifo, (uint8_t)value);
> +            sifive_spi_flush_txfifo(s);
> +        }
> +        break;
> +
> +    case R_RXDATA:
> +    case R_IP:
> +        qemu_log_mask(LOG_GUEST_ERROR,
> +                      "%s: invalid write to read-only reigster 0x%"
> +                      HWADDR_PRIx " with 0x%x\n", __func__, addr << 2, value);
> +        break;
> +
> +    case R_TXMARK:
> +    case R_RXMARK:
> +        if (value >= FIFO_CAPACITY) {
> +            qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid watermark %d\n",
> +                          __func__, value);
> +        } else {
> +            s->regs[addr] = value;
> +        }
> +        break;
> +
> +    case R_FCTRL:
> +    case R_FFMT:
> +        qemu_log_mask(LOG_UNIMP,
> +                      "%s: direct-map flash interface unimplemented\n",
> +                      __func__);
> +        break;
> +
> +    default:
> +        s->regs[addr] = value;
> +        break;
> +    }
> +
> +    sifive_spi_update_irq(s);
> +}
> +
> +static const MemoryRegionOps sifive_spi_ops = {
> +    .read = sifive_spi_read,
> +    .write = sifive_spi_write,
> +    .endianness = DEVICE_LITTLE_ENDIAN,
> +    .valid = {
> +        .min_access_size = 4,
> +        .max_access_size = 4
> +    }
> +};
> +
> +static void sifive_spi_realize(DeviceState *dev, Error **errp)
> +{
> +    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
> +    SiFiveSPIState *s = SIFIVE_SPI(dev);
> +    int i;
> +
> +    s->spi = ssi_create_bus(dev, "spi");
> +    sysbus_init_irq(sbd, &s->irq);
> +
> +    s->cs_lines = g_new0(qemu_irq, s->num_cs);
> +    for (i = 0; i < s->num_cs; i++) {
> +        sysbus_init_irq(sbd, &s->cs_lines[i]);
> +    }
> +
> +    memory_region_init_io(&s->mmio, OBJECT(s), &sifive_spi_ops, s,
> +                          TYPE_SIFIVE_SPI, 0x1000);
> +    sysbus_init_mmio(sbd, &s->mmio);
> +
> +    fifo8_create(&s->tx_fifo, FIFO_CAPACITY);
> +    fifo8_create(&s->rx_fifo, FIFO_CAPACITY);
> +}
> +
> +static Property sifive_spi_properties[] = {
> +    DEFINE_PROP_UINT32("num-cs", SiFiveSPIState, num_cs, 1),
> +    DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void sifive_spi_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +
> +    device_class_set_props(dc, sifive_spi_properties);
> +    dc->reset = sifive_spi_reset;
> +    dc->realize = sifive_spi_realize;
> +}
> +
> +static const TypeInfo sifive_spi_info = {
> +    .name           = TYPE_SIFIVE_SPI,
> +    .parent         = TYPE_SYS_BUS_DEVICE,
> +    .instance_size  = sizeof(SiFiveSPIState),
> +    .class_init     = sifive_spi_class_init,
> +};
> +
> +static void sifive_spi_register_types(void)
> +{
> +    type_register_static(&sifive_spi_info);
> +}
> +
> +type_init(sifive_spi_register_types)
> diff --git a/hw/ssi/Kconfig b/hw/ssi/Kconfig
> index 9e54a0c8dd..7d90a02181 100644
> --- a/hw/ssi/Kconfig
> +++ b/hw/ssi/Kconfig
> @@ -2,6 +2,10 @@ config PL022
>      bool
>      select SSI
>
> +config SIFIVE_SPI
> +    bool
> +    select SSI
> +
>  config SSI
>      bool
>
> diff --git a/hw/ssi/meson.build b/hw/ssi/meson.build
> index dee00c0da6..3d6bc82ab1 100644
> --- a/hw/ssi/meson.build
> +++ b/hw/ssi/meson.build
> @@ -2,6 +2,7 @@ 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_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'))
>  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'))
> --
> 2.25.1
>
>


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

* Re: [PATCH v3 3/9] hw/ssi: Add SiFive SPI controller support
  2021-01-26  7:34   ` Philippe Mathieu-Daudé
@ 2021-02-09  1:44       ` Alistair Francis
  0 siblings, 0 replies; 23+ messages in thread
From: Alistair Francis @ 2021-02-09  1:44 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, Palmer Dabbelt
  Cc: Bin Meng, open list:RISC-V, Bin Meng, Alistair Francis,
	qemu-devel@nongnu.org Developers

On Mon, Jan 25, 2021 at 11:34 PM Philippe Mathieu-Daudé <f4bug@amsat.org> wrote:
>
> On 1/26/21 7:00 AM, Bin Meng wrote:
> > From: Bin Meng <bin.meng@windriver.com>
> >
> > This adds the SiFive SPI controller model for the FU540 SoC.
> > The direct memory-mapped SPI flash mode is unsupported.
> >
> > Signed-off-by: Bin Meng <bin.meng@windriver.com>
> >
> > ---
> >
> > Changes in v3:
> > - Simplify flush txfifo logic
> >
> > Changes in v2:
> > - Log guest error when trying to write reserved registers
> > - Log guest error when trying to access out-of-bounds registers
> > - log guest error when writing to reserved bits for chip select
> >   registers and watermark registers
> > - Log unimplemented warning when trying to write direct-map flash
> >   interface registers
> > - Add test tx fifo full logic in sifive_spi_read(), hence remove
> >   setting the tx fifo full flag in sifive_spi_write().
> > - Populate register with their default value
> >
> >  include/hw/ssi/sifive_spi.h |  47 +++++
> >  hw/ssi/sifive_spi.c         | 358 ++++++++++++++++++++++++++++++++++++
> >  hw/ssi/Kconfig              |   4 +
> >  hw/ssi/meson.build          |   1 +
> >  4 files changed, 410 insertions(+)
> >  create mode 100644 include/hw/ssi/sifive_spi.h
> >  create mode 100644 hw/ssi/sifive_spi.c
>
> Missing MAINTAINERS entry (if there are no other comments on
> this series, maybe the maintainer can directly add one).

Yep, I'm adding this section to the RISC-V machines:

diff --git a/MAINTAINERS b/MAINTAINERS
index 8d8b0bf966..c347d49bd2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1359,6 +1359,15 @@ F: include/hw/misc/mchp_pfsoc_dmc.h
F: include/hw/misc/mchp_pfsoc_ioscb.h
F: include/hw/misc/mchp_pfsoc_sysreg.h

+SiFive Machines
+M: Alistair Francis <Alistair.Francis@wdc.com>
+M: Bin Meng <bin.meng@windriver.com>
+M: Palmer Dabbelt <palmer@dabbelt.com>
+L: qemu-riscv@nongnu.org
+S: Supported
+F: hw/*/*sifive*.c
+F: include/hw/*/*sifive*.h
+
RX Machines
-----------
rx-gdbsim


Can I get an Ack from you Bin that you are ok with that?

@Palmer Dabbelt let me know if you would prefer something else.

Alistair

>


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

* Re: [PATCH v3 3/9] hw/ssi: Add SiFive SPI controller support
@ 2021-02-09  1:44       ` Alistair Francis
  0 siblings, 0 replies; 23+ messages in thread
From: Alistair Francis @ 2021-02-09  1:44 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, Palmer Dabbelt
  Cc: Bin Meng, Alistair Francis, open list:RISC-V,
	qemu-devel@nongnu.org Developers, Bin Meng

On Mon, Jan 25, 2021 at 11:34 PM Philippe Mathieu-Daudé <f4bug@amsat.org> wrote:
>
> On 1/26/21 7:00 AM, Bin Meng wrote:
> > From: Bin Meng <bin.meng@windriver.com>
> >
> > This adds the SiFive SPI controller model for the FU540 SoC.
> > The direct memory-mapped SPI flash mode is unsupported.
> >
> > Signed-off-by: Bin Meng <bin.meng@windriver.com>
> >
> > ---
> >
> > Changes in v3:
> > - Simplify flush txfifo logic
> >
> > Changes in v2:
> > - Log guest error when trying to write reserved registers
> > - Log guest error when trying to access out-of-bounds registers
> > - log guest error when writing to reserved bits for chip select
> >   registers and watermark registers
> > - Log unimplemented warning when trying to write direct-map flash
> >   interface registers
> > - Add test tx fifo full logic in sifive_spi_read(), hence remove
> >   setting the tx fifo full flag in sifive_spi_write().
> > - Populate register with their default value
> >
> >  include/hw/ssi/sifive_spi.h |  47 +++++
> >  hw/ssi/sifive_spi.c         | 358 ++++++++++++++++++++++++++++++++++++
> >  hw/ssi/Kconfig              |   4 +
> >  hw/ssi/meson.build          |   1 +
> >  4 files changed, 410 insertions(+)
> >  create mode 100644 include/hw/ssi/sifive_spi.h
> >  create mode 100644 hw/ssi/sifive_spi.c
>
> Missing MAINTAINERS entry (if there are no other comments on
> this series, maybe the maintainer can directly add one).

Yep, I'm adding this section to the RISC-V machines:

diff --git a/MAINTAINERS b/MAINTAINERS
index 8d8b0bf966..c347d49bd2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1359,6 +1359,15 @@ F: include/hw/misc/mchp_pfsoc_dmc.h
F: include/hw/misc/mchp_pfsoc_ioscb.h
F: include/hw/misc/mchp_pfsoc_sysreg.h

+SiFive Machines
+M: Alistair Francis <Alistair.Francis@wdc.com>
+M: Bin Meng <bin.meng@windriver.com>
+M: Palmer Dabbelt <palmer@dabbelt.com>
+L: qemu-riscv@nongnu.org
+S: Supported
+F: hw/*/*sifive*.c
+F: include/hw/*/*sifive*.h
+
RX Machines
-----------
rx-gdbsim


Can I get an Ack from you Bin that you are ok with that?

@Palmer Dabbelt let me know if you would prefer something else.

Alistair

>


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

* Re: [PATCH v3 3/9] hw/ssi: Add SiFive SPI controller support
  2021-02-09  1:44       ` Alistair Francis
@ 2021-02-09  1:46         ` Bin Meng
  -1 siblings, 0 replies; 23+ messages in thread
From: Bin Meng @ 2021-02-09  1:46 UTC (permalink / raw)
  To: Alistair Francis
  Cc: open list:RISC-V, Bin Meng, Philippe Mathieu-Daudé,
	qemu-devel@nongnu.org Developers, Alistair Francis,
	Palmer Dabbelt

On Tue, Feb 9, 2021 at 9:44 AM Alistair Francis <alistair23@gmail.com> wrote:
>
> On Mon, Jan 25, 2021 at 11:34 PM Philippe Mathieu-Daudé <f4bug@amsat.org> wrote:
> >
> > On 1/26/21 7:00 AM, Bin Meng wrote:
> > > From: Bin Meng <bin.meng@windriver.com>
> > >
> > > This adds the SiFive SPI controller model for the FU540 SoC.
> > > The direct memory-mapped SPI flash mode is unsupported.
> > >
> > > Signed-off-by: Bin Meng <bin.meng@windriver.com>
> > >
> > > ---
> > >
> > > Changes in v3:
> > > - Simplify flush txfifo logic
> > >
> > > Changes in v2:
> > > - Log guest error when trying to write reserved registers
> > > - Log guest error when trying to access out-of-bounds registers
> > > - log guest error when writing to reserved bits for chip select
> > >   registers and watermark registers
> > > - Log unimplemented warning when trying to write direct-map flash
> > >   interface registers
> > > - Add test tx fifo full logic in sifive_spi_read(), hence remove
> > >   setting the tx fifo full flag in sifive_spi_write().
> > > - Populate register with their default value
> > >
> > >  include/hw/ssi/sifive_spi.h |  47 +++++
> > >  hw/ssi/sifive_spi.c         | 358 ++++++++++++++++++++++++++++++++++++
> > >  hw/ssi/Kconfig              |   4 +
> > >  hw/ssi/meson.build          |   1 +
> > >  4 files changed, 410 insertions(+)
> > >  create mode 100644 include/hw/ssi/sifive_spi.h
> > >  create mode 100644 hw/ssi/sifive_spi.c
> >
> > Missing MAINTAINERS entry (if there are no other comments on
> > this series, maybe the maintainer can directly add one).
>
> Yep, I'm adding this section to the RISC-V machines:
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 8d8b0bf966..c347d49bd2 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1359,6 +1359,15 @@ F: include/hw/misc/mchp_pfsoc_dmc.h
> F: include/hw/misc/mchp_pfsoc_ioscb.h
> F: include/hw/misc/mchp_pfsoc_sysreg.h
>
> +SiFive Machines
> +M: Alistair Francis <Alistair.Francis@wdc.com>
> +M: Bin Meng <bin.meng@windriver.com>
> +M: Palmer Dabbelt <palmer@dabbelt.com>
> +L: qemu-riscv@nongnu.org
> +S: Supported
> +F: hw/*/*sifive*.c
> +F: include/hw/*/*sifive*.h
> +
> RX Machines
> -----------
> rx-gdbsim
>
>
> Can I get an Ack from you Bin that you are ok with that?
>

Acked-by: Bin Meng <bin.meng@windriver.com>

> @Palmer Dabbelt let me know if you would prefer something else.
>

Regards,
Bin


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

* Re: [PATCH v3 3/9] hw/ssi: Add SiFive SPI controller support
@ 2021-02-09  1:46         ` Bin Meng
  0 siblings, 0 replies; 23+ messages in thread
From: Bin Meng @ 2021-02-09  1:46 UTC (permalink / raw)
  To: Alistair Francis
  Cc: Philippe Mathieu-Daudé,
	Palmer Dabbelt, Alistair Francis, open list:RISC-V,
	qemu-devel@nongnu.org Developers, Bin Meng

On Tue, Feb 9, 2021 at 9:44 AM Alistair Francis <alistair23@gmail.com> wrote:
>
> On Mon, Jan 25, 2021 at 11:34 PM Philippe Mathieu-Daudé <f4bug@amsat.org> wrote:
> >
> > On 1/26/21 7:00 AM, Bin Meng wrote:
> > > From: Bin Meng <bin.meng@windriver.com>
> > >
> > > This adds the SiFive SPI controller model for the FU540 SoC.
> > > The direct memory-mapped SPI flash mode is unsupported.
> > >
> > > Signed-off-by: Bin Meng <bin.meng@windriver.com>
> > >
> > > ---
> > >
> > > Changes in v3:
> > > - Simplify flush txfifo logic
> > >
> > > Changes in v2:
> > > - Log guest error when trying to write reserved registers
> > > - Log guest error when trying to access out-of-bounds registers
> > > - log guest error when writing to reserved bits for chip select
> > >   registers and watermark registers
> > > - Log unimplemented warning when trying to write direct-map flash
> > >   interface registers
> > > - Add test tx fifo full logic in sifive_spi_read(), hence remove
> > >   setting the tx fifo full flag in sifive_spi_write().
> > > - Populate register with their default value
> > >
> > >  include/hw/ssi/sifive_spi.h |  47 +++++
> > >  hw/ssi/sifive_spi.c         | 358 ++++++++++++++++++++++++++++++++++++
> > >  hw/ssi/Kconfig              |   4 +
> > >  hw/ssi/meson.build          |   1 +
> > >  4 files changed, 410 insertions(+)
> > >  create mode 100644 include/hw/ssi/sifive_spi.h
> > >  create mode 100644 hw/ssi/sifive_spi.c
> >
> > Missing MAINTAINERS entry (if there are no other comments on
> > this series, maybe the maintainer can directly add one).
>
> Yep, I'm adding this section to the RISC-V machines:
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 8d8b0bf966..c347d49bd2 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1359,6 +1359,15 @@ F: include/hw/misc/mchp_pfsoc_dmc.h
> F: include/hw/misc/mchp_pfsoc_ioscb.h
> F: include/hw/misc/mchp_pfsoc_sysreg.h
>
> +SiFive Machines
> +M: Alistair Francis <Alistair.Francis@wdc.com>
> +M: Bin Meng <bin.meng@windriver.com>
> +M: Palmer Dabbelt <palmer@dabbelt.com>
> +L: qemu-riscv@nongnu.org
> +S: Supported
> +F: hw/*/*sifive*.c
> +F: include/hw/*/*sifive*.h
> +
> RX Machines
> -----------
> rx-gdbsim
>
>
> Can I get an Ack from you Bin that you are ok with that?
>

Acked-by: Bin Meng <bin.meng@windriver.com>

> @Palmer Dabbelt let me know if you would prefer something else.
>

Regards,
Bin


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

* Re: [PATCH v3 3/9] hw/ssi: Add SiFive SPI controller support
  2021-02-09  1:44       ` Alistair Francis
@ 2021-02-09  1:53         ` Palmer Dabbelt
  -1 siblings, 0 replies; 23+ messages in thread
From: Palmer Dabbelt @ 2021-02-09  1:53 UTC (permalink / raw)
  To: alistair23
  Cc: qemu-riscv, bin.meng, f4bug, qemu-devel, Alistair Francis, bmeng.cn

On Mon, 08 Feb 2021 17:44:17 PST (-0800), alistair23@gmail.com wrote:
> On Mon, Jan 25, 2021 at 11:34 PM Philippe Mathieu-Daudé <f4bug@amsat.org> wrote:
>>
>> On 1/26/21 7:00 AM, Bin Meng wrote:
>> > From: Bin Meng <bin.meng@windriver.com>
>> >
>> > This adds the SiFive SPI controller model for the FU540 SoC.
>> > The direct memory-mapped SPI flash mode is unsupported.
>> >
>> > Signed-off-by: Bin Meng <bin.meng@windriver.com>
>> >
>> > ---
>> >
>> > Changes in v3:
>> > - Simplify flush txfifo logic
>> >
>> > Changes in v2:
>> > - Log guest error when trying to write reserved registers
>> > - Log guest error when trying to access out-of-bounds registers
>> > - log guest error when writing to reserved bits for chip select
>> >   registers and watermark registers
>> > - Log unimplemented warning when trying to write direct-map flash
>> >   interface registers
>> > - Add test tx fifo full logic in sifive_spi_read(), hence remove
>> >   setting the tx fifo full flag in sifive_spi_write().
>> > - Populate register with their default value
>> >
>> >  include/hw/ssi/sifive_spi.h |  47 +++++
>> >  hw/ssi/sifive_spi.c         | 358 ++++++++++++++++++++++++++++++++++++
>> >  hw/ssi/Kconfig              |   4 +
>> >  hw/ssi/meson.build          |   1 +
>> >  4 files changed, 410 insertions(+)
>> >  create mode 100644 include/hw/ssi/sifive_spi.h
>> >  create mode 100644 hw/ssi/sifive_spi.c
>>
>> Missing MAINTAINERS entry (if there are no other comments on
>> this series, maybe the maintainer can directly add one).
>
> Yep, I'm adding this section to the RISC-V machines:
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 8d8b0bf966..c347d49bd2 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1359,6 +1359,15 @@ F: include/hw/misc/mchp_pfsoc_dmc.h
> F: include/hw/misc/mchp_pfsoc_ioscb.h
> F: include/hw/misc/mchp_pfsoc_sysreg.h
>
> +SiFive Machines
> +M: Alistair Francis <Alistair.Francis@wdc.com>
> +M: Bin Meng <bin.meng@windriver.com>
> +M: Palmer Dabbelt <palmer@dabbelt.com>
> +L: qemu-riscv@nongnu.org
> +S: Supported
> +F: hw/*/*sifive*.c
> +F: include/hw/*/*sifive*.h
> +
> RX Machines
> -----------
> rx-gdbsim
>
>
> Can I get an Ack from you Bin that you are ok with that?
>
> @Palmer Dabbelt let me know if you would prefer something else.

Sorry, I hadn't seen this go by.

Acked-by: Palmer Dabbelt <palmerdabbelt@google.com>

Thanks!

>
> Alistair
>
>>


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

* Re: [PATCH v3 3/9] hw/ssi: Add SiFive SPI controller support
@ 2021-02-09  1:53         ` Palmer Dabbelt
  0 siblings, 0 replies; 23+ messages in thread
From: Palmer Dabbelt @ 2021-02-09  1:53 UTC (permalink / raw)
  To: alistair23
  Cc: f4bug, bmeng.cn, Alistair Francis, qemu-riscv, qemu-devel, bin.meng

On Mon, 08 Feb 2021 17:44:17 PST (-0800), alistair23@gmail.com wrote:
> On Mon, Jan 25, 2021 at 11:34 PM Philippe Mathieu-Daudé <f4bug@amsat.org> wrote:
>>
>> On 1/26/21 7:00 AM, Bin Meng wrote:
>> > From: Bin Meng <bin.meng@windriver.com>
>> >
>> > This adds the SiFive SPI controller model for the FU540 SoC.
>> > The direct memory-mapped SPI flash mode is unsupported.
>> >
>> > Signed-off-by: Bin Meng <bin.meng@windriver.com>
>> >
>> > ---
>> >
>> > Changes in v3:
>> > - Simplify flush txfifo logic
>> >
>> > Changes in v2:
>> > - Log guest error when trying to write reserved registers
>> > - Log guest error when trying to access out-of-bounds registers
>> > - log guest error when writing to reserved bits for chip select
>> >   registers and watermark registers
>> > - Log unimplemented warning when trying to write direct-map flash
>> >   interface registers
>> > - Add test tx fifo full logic in sifive_spi_read(), hence remove
>> >   setting the tx fifo full flag in sifive_spi_write().
>> > - Populate register with their default value
>> >
>> >  include/hw/ssi/sifive_spi.h |  47 +++++
>> >  hw/ssi/sifive_spi.c         | 358 ++++++++++++++++++++++++++++++++++++
>> >  hw/ssi/Kconfig              |   4 +
>> >  hw/ssi/meson.build          |   1 +
>> >  4 files changed, 410 insertions(+)
>> >  create mode 100644 include/hw/ssi/sifive_spi.h
>> >  create mode 100644 hw/ssi/sifive_spi.c
>>
>> Missing MAINTAINERS entry (if there are no other comments on
>> this series, maybe the maintainer can directly add one).
>
> Yep, I'm adding this section to the RISC-V machines:
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 8d8b0bf966..c347d49bd2 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1359,6 +1359,15 @@ F: include/hw/misc/mchp_pfsoc_dmc.h
> F: include/hw/misc/mchp_pfsoc_ioscb.h
> F: include/hw/misc/mchp_pfsoc_sysreg.h
>
> +SiFive Machines
> +M: Alistair Francis <Alistair.Francis@wdc.com>
> +M: Bin Meng <bin.meng@windriver.com>
> +M: Palmer Dabbelt <palmer@dabbelt.com>
> +L: qemu-riscv@nongnu.org
> +S: Supported
> +F: hw/*/*sifive*.c
> +F: include/hw/*/*sifive*.h
> +
> RX Machines
> -----------
> rx-gdbsim
>
>
> Can I get an Ack from you Bin that you are ok with that?
>
> @Palmer Dabbelt let me know if you would prefer something else.

Sorry, I hadn't seen this go by.

Acked-by: Palmer Dabbelt <palmerdabbelt@google.com>

Thanks!

>
> Alistair
>
>>


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

end of thread, other threads:[~2021-02-09  1:54 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-26  5:59 [PATCH v3 0/9] hw/riscv: sifive_u: Add missing SPI support Bin Meng
2021-01-26  5:59 ` [PATCH v3 1/9] hw/block: m25p80: Add ISSI SPI flash support Bin Meng
2021-01-28 20:56   ` Alistair Francis
2021-01-28 20:56     ` Alistair Francis
2021-01-26  6:00 ` [PATCH v3 2/9] hw/block: m25p80: Add various ISSI flash information Bin Meng
2021-01-26  6:00 ` [PATCH v3 3/9] hw/ssi: Add SiFive SPI controller support Bin Meng
2021-01-26  7:34   ` Philippe Mathieu-Daudé
2021-02-09  1:44     ` Alistair Francis
2021-02-09  1:44       ` Alistair Francis
2021-02-09  1:46       ` Bin Meng
2021-02-09  1:46         ` Bin Meng
2021-02-09  1:53       ` Palmer Dabbelt
2021-02-09  1:53         ` Palmer Dabbelt
2021-02-09  1:38   ` Alistair Francis
2021-02-09  1:38     ` Alistair Francis
2021-01-26  6:00 ` [PATCH v3 4/9] hw/riscv: sifive_u: Add QSPI0 controller and connect a flash Bin Meng
2021-01-26  6:00 ` [PATCH v3 5/9] hw/riscv: sifive_u: Add QSPI2 controller and connect an SD card Bin Meng
2021-01-26  6:00 ` [PATCH v3 6/9] hw/riscv: sifive_u: Change SIFIVE_U_GEM_IRQ to decimal value Bin Meng
2021-01-26  6:00 ` [PATCH v3 7/9] docs/system: Sort targets in alphabetical order Bin Meng
2021-01-26  6:00 ` [PATCH v3 8/9] docs/system: Add RISC-V documentation Bin Meng
2021-01-26  6:00 ` [PATCH v3 9/9] docs/system: riscv: Add documentation for sifive_u machine Bin Meng
2021-01-27  5:51   ` Palmer Dabbelt
2021-01-27  5:51     ` Palmer Dabbelt

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