Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/1447382/?format=api
{ "id": 1447382, "url": "http://patchwork.ozlabs.org/api/patches/1447382/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20210304144651.310037-8-alistair.francis@wdc.com/", "project": { "id": 14, "url": "http://patchwork.ozlabs.org/api/projects/14/?format=api", "name": "QEMU Development", "link_name": "qemu-devel", "list_id": "qemu-devel.nongnu.org", "list_email": "qemu-devel@nongnu.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20210304144651.310037-8-alistair.francis@wdc.com>", "list_archive_url": null, "date": "2021-03-04T14:46:39", "name": "[PULL,v2,07/19] hw/ssi: Add SiFive SPI controller support", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "3458f8f324ffce95b6d9504071c79d9af90d151c", "submitter": { "id": 74007, "url": "http://patchwork.ozlabs.org/api/people/74007/?format=api", "name": "Alistair Francis", "email": "alistair.francis@wdc.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20210304144651.310037-8-alistair.francis@wdc.com/mbox/", "series": [ { "id": 232161, "url": "http://patchwork.ozlabs.org/api/series/232161/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=232161", "date": "2021-03-04T14:46:33", "name": "[PULL,v2,01/19] target/riscv: Declare csr_ops[] with a known size", "version": 2, "mbox": "http://patchwork.ozlabs.org/series/232161/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/1447382/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/1447382/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@bilbo.ozlabs.org", "Authentication-Results": [ "ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=<UNKNOWN>)", "ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n unprotected) header.d=wdc.com header.i=@wdc.com header.a=rsa-sha256\n header.s=dkim.wdc.com header.b=VBVf30VJ;\n\tdkim-atps=neutral" ], "Received": [ "from lists.gnu.org (lists.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 4Drv3N3Sbgz9sSC\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 5 Mar 2021 01:52:16 +1100 (AEDT)", "from localhost ([::1]:39786 helo=lists1p.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>)\n\tid 1lHpKo-0005XA-FD\n\tfor incoming@patchwork.ozlabs.org; Thu, 04 Mar 2021 09:52:14 -0500", "from eggs.gnu.org ([2001:470:142:3::10]:60314)\n by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1)\n (envelope-from <prvs=690dc056c=alistair.francis@wdc.com>)\n id 1lHpH7-0001lv-V2\n for qemu-devel@nongnu.org; Thu, 04 Mar 2021 09:48:25 -0500", "from esa1.hgst.iphmx.com ([68.232.141.245]:44460)\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1)\n (envelope-from <prvs=690dc056c=alistair.francis@wdc.com>)\n id 1lHpH4-0007uj-Rj\n for qemu-devel@nongnu.org; Thu, 04 Mar 2021 09:48:25 -0500", "from uls-op-cesaip02.wdc.com (HELO uls-op-cesaep02.wdc.com)\n ([199.255.45.15])\n by ob1.hgst.iphmx.com with ESMTP; 04 Mar 2021 22:48:10 +0800", "from uls-op-cesaip01.wdc.com ([10.248.3.36])\n by uls-op-cesaep02.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 04 Mar 2021 06:29:23 -0800", "from cnf008142.ad.shared (HELO alistair-risc6-laptop.hgst.com)\n ([10.86.48.109])\n by uls-op-cesaip01.wdc.com with ESMTP; 04 Mar 2021 06:48:10 -0800" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=simple/simple;\n d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com;\n t=1614869302; x=1646405302;\n h=from:to:cc:subject:date:message-id:in-reply-to:\n references:mime-version:content-transfer-encoding;\n bh=+lGZXaoYx3pMRxNzsM4PxWtHjJ9efR3jQix8AS/sB7g=;\n b=VBVf30VJ5LgCpneDC2ANy7nE9gGd6X4JjGwQiZBO/SUKse5jxTqR2VVT\n Un55DnDSWvsotvg78hu4ta3aQPQdByUCJjYuIWjM1Ll1nvOse+Wi7wZaM\n SdPaCqAaBV9n+cBEfNYrZ6OdIfTeHCGgv05V9v9lsyuDsVRqJeLjHDOuX\n w/SEqqA1xrvWK7srlHB9EV3lou/2X1usls2c3qCDM6yzOq/dQkrbXKzh7\n Rg/N/J+2/4L/n5V+e9XbSjGH1A5Ebf/xp6iXFmXoPtj1y6YFhc7m5S8h3\n rubBKtwj6NyyRJ6iXEs7c24g/M6FJd4ovAlb7qddUsufH5Hb3I/EQPE1i A==;", "IronPort-SDR": [ "\n MDhPpw039h6goC0y25tWJRwythRZPzXPb00i8Ng9wi2UkahAEif39960bSLcqRcAy3TPiaIk6q\n KmwTH/qPkp9UvHAjMtpYSI2f8G4dBSpf4j13NQvYv0IkrAg6gwLxTLK/CcxJixnBkKN1CEfHdN\n tShHyjdqWBq1UfmklkU5oG/X5zVn4N4d2SiOB3XldbW+B8zXitIyv4u8PyhQJAR8n3RbDhYB25\n 7f7erkKvKUf8apP9A8p+I5XV/g2tj3e1Vy2Acbpp5MInmjsvXRJ/rvovtCzamd4MxJCSK0mbN7\n 4R4=", "\n +bFldTdUIFRD28HOGJT2+TDF7ux+R0wq1NeVlF0t6hyTcuh2HDDaX2906wUOJ1Avp0HHoBoA22\n u8xZeRvfowon2tGMWRBMGXoI1X/C15MBKLaHLJ2zzhVaoo00j3W97lZ+tig8ZrneMpE5ggCl+g\n MwmRV+1z774FnyQA9cPoUe7FDHDVwzBM73fEgmHm8XojuuvqY1C/vonclxaIlkycps8I+6+ddD\n nmQMPKsFQ5nQHc2zzL8M08uBB5xm4fOoaBk3/islVk/CQY7/+OaklVhdzivYENzvb2D1/HiPkc\n krlDPxqKTSdCkObyWvX5a3C/", "\n B69Vd/JDsr8qoE78AdFkfo/j1yiEjOVlMOenww4c+Jo9zcjoSDWGMLTPkaF4CanqcxGWre7pWP\n X4XpBN0DNtNs7JucVMGQmp/yWfmveOtnEZz2Z/H8euWkuYfg5OEQeT0sznCjoWfuzo9PDoHaqB\n L1UquYvpwFWscZqIqwwrKAQJeEaDrnxHekUQNzOzbcFmuyJI6odLzfwWUH1om6UZm+d34r/pmd\n Xzqu6Zvu2N5d3ieonpFHrxyUYdCM6h6+4cpzm5vzABm7xb3Lzlo5yZsMTMHEMyDy3gr/NnFRfj\n tV0=" ], "X-IronPort-AV": "E=Sophos;i=\"5.81,222,1610380800\"; d=\"scan'208\";a=\"271984408\"", "WDCIronportException": "Internal", "From": "Alistair Francis <alistair.francis@wdc.com>", "To": "peter.maydell@linaro.org", "Subject": "[PULL v2 07/19] hw/ssi: Add SiFive SPI controller support", "Date": "Thu, 4 Mar 2021 09:46:39 -0500", "Message-Id": "<20210304144651.310037-8-alistair.francis@wdc.com>", "X-Mailer": "git-send-email 2.30.1", "In-Reply-To": "<20210304144651.310037-1-alistair.francis@wdc.com>", "References": "<20210304144651.310037-1-alistair.francis@wdc.com>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "Received-SPF": "pass client-ip=68.232.141.245;\n envelope-from=prvs=690dc056c=alistair.francis@wdc.com;\n helo=esa1.hgst.iphmx.com", "X-Spam_score_int": "-27", "X-Spam_score": "-2.8", "X-Spam_bar": "--", "X-Spam_report": "(-2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1,\n DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,\n RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_PASS=-0.001,\n SPF_PASS=-0.001 autolearn=ham autolearn_force=no", "X-Spam_action": "no action", "X-BeenThere": "qemu-devel@nongnu.org", "X-Mailman-Version": "2.1.23", "Precedence": "list", "List-Id": "<qemu-devel.nongnu.org>", "List-Unsubscribe": "<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>", "List-Archive": "<https://lists.nongnu.org/archive/html/qemu-devel>", "List-Post": "<mailto:qemu-devel@nongnu.org>", "List-Help": "<mailto:qemu-devel-request@nongnu.org?subject=help>", "List-Subscribe": "<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>", "Cc": "alistair23@gmail.com, Bin Meng <bin.meng@windriver.com>,\n Alistair Francis <alistair.francis@wdc.com>, qemu-devel@nongnu.org", "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org", "Sender": "\"Qemu-devel\"\n <qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>" }, "content": "From: Bin Meng <bin.meng@windriver.com>\n\nThis adds the SiFive SPI controller model for the FU540 SoC.\nThe direct memory-mapped SPI flash mode is unsupported.\n\nSigned-off-by: Bin Meng <bin.meng@windriver.com>\nReviewed-by: Alistair Francis <alistair.francis@wdc.com>\nMessage-id: 20210126060007.12904-4-bmeng.cn@gmail.com\nSigned-off-by: Alistair Francis <alistair.francis@wdc.com>\n---\n include/hw/ssi/sifive_spi.h | 47 +++++\n hw/ssi/sifive_spi.c | 358 ++++++++++++++++++++++++++++++++++++\n hw/ssi/Kconfig | 4 +\n hw/ssi/meson.build | 1 +\n 4 files changed, 410 insertions(+)\n create mode 100644 include/hw/ssi/sifive_spi.h\n create mode 100644 hw/ssi/sifive_spi.c", "diff": "diff --git a/include/hw/ssi/sifive_spi.h b/include/hw/ssi/sifive_spi.h\nnew file mode 100644\nindex 0000000000..47d0d6a47c\n--- /dev/null\n+++ b/include/hw/ssi/sifive_spi.h\n@@ -0,0 +1,47 @@\n+/*\n+ * QEMU model of the SiFive SPI Controller\n+ *\n+ * Copyright (c) 2021 Wind River Systems, Inc.\n+ *\n+ * Author:\n+ * Bin Meng <bin.meng@windriver.com>\n+ *\n+ * This program is free software; you can redistribute it and/or modify it\n+ * under the terms and conditions of the GNU General Public License,\n+ * version 2 or later, as published by the Free Software Foundation.\n+ *\n+ * This program is distributed in the hope it will be useful, but WITHOUT\n+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\n+ * more details.\n+ *\n+ * You should have received a copy of the GNU General Public License along with\n+ * this program. If not, see <http://www.gnu.org/licenses/>.\n+ */\n+\n+#ifndef HW_SIFIVE_SPI_H\n+#define HW_SIFIVE_SPI_H\n+\n+#define SIFIVE_SPI_REG_NUM (0x78 / 4)\n+\n+#define TYPE_SIFIVE_SPI \"sifive.spi\"\n+#define SIFIVE_SPI(obj) OBJECT_CHECK(SiFiveSPIState, (obj), TYPE_SIFIVE_SPI)\n+\n+typedef struct SiFiveSPIState {\n+ SysBusDevice parent_obj;\n+\n+ MemoryRegion mmio;\n+ qemu_irq irq;\n+\n+ uint32_t num_cs;\n+ qemu_irq *cs_lines;\n+\n+ SSIBus *spi;\n+\n+ Fifo8 tx_fifo;\n+ Fifo8 rx_fifo;\n+\n+ uint32_t regs[SIFIVE_SPI_REG_NUM];\n+} SiFiveSPIState;\n+\n+#endif /* HW_SIFIVE_SPI_H */\ndiff --git a/hw/ssi/sifive_spi.c b/hw/ssi/sifive_spi.c\nnew file mode 100644\nindex 0000000000..0c9ebca3c8\n--- /dev/null\n+++ b/hw/ssi/sifive_spi.c\n@@ -0,0 +1,358 @@\n+/*\n+ * QEMU model of the SiFive SPI Controller\n+ *\n+ * Copyright (c) 2021 Wind River Systems, Inc.\n+ *\n+ * Author:\n+ * Bin Meng <bin.meng@windriver.com>\n+ *\n+ * This program is free software; you can redistribute it and/or modify it\n+ * under the terms and conditions of the GNU General Public License,\n+ * version 2 or later, as published by the Free Software Foundation.\n+ *\n+ * This program is distributed in the hope it will be useful, but WITHOUT\n+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\n+ * more details.\n+ *\n+ * You should have received a copy of the GNU General Public License along with\n+ * this program. If not, see <http://www.gnu.org/licenses/>.\n+ */\n+\n+#include \"qemu/osdep.h\"\n+#include \"hw/irq.h\"\n+#include \"hw/qdev-properties.h\"\n+#include \"hw/sysbus.h\"\n+#include \"hw/ssi/ssi.h\"\n+#include \"sysemu/sysemu.h\"\n+#include \"qemu/fifo8.h\"\n+#include \"qemu/log.h\"\n+#include \"qemu/module.h\"\n+#include \"hw/ssi/sifive_spi.h\"\n+\n+#define R_SCKDIV (0x00 / 4)\n+#define R_SCKMODE (0x04 / 4)\n+#define R_CSID (0x10 / 4)\n+#define R_CSDEF (0x14 / 4)\n+#define R_CSMODE (0x18 / 4)\n+#define R_DELAY0 (0x28 / 4)\n+#define R_DELAY1 (0x2C / 4)\n+#define R_FMT (0x40 / 4)\n+#define R_TXDATA (0x48 / 4)\n+#define R_RXDATA (0x4C / 4)\n+#define R_TXMARK (0x50 / 4)\n+#define R_RXMARK (0x54 / 4)\n+#define R_FCTRL (0x60 / 4)\n+#define R_FFMT (0x64 / 4)\n+#define R_IE (0x70 / 4)\n+#define R_IP (0x74 / 4)\n+\n+#define FMT_DIR (1 << 3)\n+\n+#define TXDATA_FULL (1 << 31)\n+#define RXDATA_EMPTY (1 << 31)\n+\n+#define IE_TXWM (1 << 0)\n+#define IE_RXWM (1 << 1)\n+\n+#define IP_TXWM (1 << 0)\n+#define IP_RXWM (1 << 1)\n+\n+#define FIFO_CAPACITY 8\n+\n+static void sifive_spi_txfifo_reset(SiFiveSPIState *s)\n+{\n+ fifo8_reset(&s->tx_fifo);\n+\n+ s->regs[R_TXDATA] &= ~TXDATA_FULL;\n+ s->regs[R_IP] &= ~IP_TXWM;\n+}\n+\n+static void sifive_spi_rxfifo_reset(SiFiveSPIState *s)\n+{\n+ fifo8_reset(&s->rx_fifo);\n+\n+ s->regs[R_RXDATA] |= RXDATA_EMPTY;\n+ s->regs[R_IP] &= ~IP_RXWM;\n+}\n+\n+static void sifive_spi_update_cs(SiFiveSPIState *s)\n+{\n+ int i;\n+\n+ for (i = 0; i < s->num_cs; i++) {\n+ if (s->regs[R_CSDEF] & (1 << i)) {\n+ qemu_set_irq(s->cs_lines[i], !(s->regs[R_CSMODE]));\n+ }\n+ }\n+}\n+\n+static void sifive_spi_update_irq(SiFiveSPIState *s)\n+{\n+ int level;\n+\n+ if (fifo8_num_used(&s->tx_fifo) < s->regs[R_TXMARK]) {\n+ s->regs[R_IP] |= IP_TXWM;\n+ } else {\n+ s->regs[R_IP] &= ~IP_TXWM;\n+ }\n+\n+ if (fifo8_num_used(&s->rx_fifo) > s->regs[R_RXMARK]) {\n+ s->regs[R_IP] |= IP_RXWM;\n+ } else {\n+ s->regs[R_IP] &= ~IP_RXWM;\n+ }\n+\n+ level = s->regs[R_IP] & s->regs[R_IE] ? 1 : 0;\n+ qemu_set_irq(s->irq, level);\n+}\n+\n+static void sifive_spi_reset(DeviceState *d)\n+{\n+ SiFiveSPIState *s = SIFIVE_SPI(d);\n+\n+ memset(s->regs, 0, sizeof(s->regs));\n+\n+ /* The reset value is high for all implemented CS pins */\n+ s->regs[R_CSDEF] = (1 << s->num_cs) - 1;\n+\n+ /* Populate register with their default value */\n+ s->regs[R_SCKDIV] = 0x03;\n+ s->regs[R_DELAY0] = 0x1001;\n+ s->regs[R_DELAY1] = 0x01;\n+\n+ sifive_spi_txfifo_reset(s);\n+ sifive_spi_rxfifo_reset(s);\n+\n+ sifive_spi_update_cs(s);\n+ sifive_spi_update_irq(s);\n+}\n+\n+static void sifive_spi_flush_txfifo(SiFiveSPIState *s)\n+{\n+ uint8_t tx;\n+ uint8_t rx;\n+\n+ while (!fifo8_is_empty(&s->tx_fifo)) {\n+ tx = fifo8_pop(&s->tx_fifo);\n+ rx = ssi_transfer(s->spi, tx);\n+\n+ if (!fifo8_is_full(&s->rx_fifo)) {\n+ if (!(s->regs[R_FMT] & FMT_DIR)) {\n+ fifo8_push(&s->rx_fifo, rx);\n+ }\n+ }\n+ }\n+}\n+\n+static bool sifive_spi_is_bad_reg(hwaddr addr, bool allow_reserved)\n+{\n+ bool bad;\n+\n+ switch (addr) {\n+ /* reserved offsets */\n+ case 0x08:\n+ case 0x0C:\n+ case 0x1C:\n+ case 0x20:\n+ case 0x24:\n+ case 0x30:\n+ case 0x34:\n+ case 0x38:\n+ case 0x3C:\n+ case 0x44:\n+ case 0x58:\n+ case 0x5C:\n+ case 0x68:\n+ case 0x6C:\n+ bad = allow_reserved ? false : true;\n+ break;\n+ default:\n+ bad = false;\n+ }\n+\n+ if (addr >= (SIFIVE_SPI_REG_NUM << 2)) {\n+ bad = true;\n+ }\n+\n+ return bad;\n+}\n+\n+static uint64_t sifive_spi_read(void *opaque, hwaddr addr, unsigned int size)\n+{\n+ SiFiveSPIState *s = opaque;\n+ uint32_t r;\n+\n+ if (sifive_spi_is_bad_reg(addr, true)) {\n+ qemu_log_mask(LOG_GUEST_ERROR, \"%s: bad read at address 0x%\"\n+ HWADDR_PRIx \"\\n\", __func__, addr);\n+ return 0;\n+ }\n+\n+ addr >>= 2;\n+ switch (addr) {\n+ case R_TXDATA:\n+ if (fifo8_is_full(&s->tx_fifo)) {\n+ return TXDATA_FULL;\n+ }\n+ r = 0;\n+ break;\n+\n+ case R_RXDATA:\n+ if (fifo8_is_empty(&s->rx_fifo)) {\n+ return RXDATA_EMPTY;\n+ }\n+ r = fifo8_pop(&s->rx_fifo);\n+ break;\n+\n+ default:\n+ r = s->regs[addr];\n+ break;\n+ }\n+\n+ sifive_spi_update_irq(s);\n+\n+ return r;\n+}\n+\n+static void sifive_spi_write(void *opaque, hwaddr addr,\n+ uint64_t val64, unsigned int size)\n+{\n+ SiFiveSPIState *s = opaque;\n+ uint32_t value = val64;\n+\n+ if (sifive_spi_is_bad_reg(addr, false)) {\n+ qemu_log_mask(LOG_GUEST_ERROR, \"%s: bad write at addr=0x%\"\n+ HWADDR_PRIx \" value=0x%x\\n\", __func__, addr, value);\n+ return;\n+ }\n+\n+ addr >>= 2;\n+ switch (addr) {\n+ case R_CSID:\n+ if (value >= s->num_cs) {\n+ qemu_log_mask(LOG_GUEST_ERROR, \"%s: invalid csid %d\\n\",\n+ __func__, value);\n+ } else {\n+ s->regs[R_CSID] = value;\n+ sifive_spi_update_cs(s);\n+ }\n+ break;\n+\n+ case R_CSDEF:\n+ if (value >= (1 << s->num_cs)) {\n+ qemu_log_mask(LOG_GUEST_ERROR, \"%s: invalid csdef %x\\n\",\n+ __func__, value);\n+ } else {\n+ s->regs[R_CSDEF] = value;\n+ }\n+ break;\n+\n+ case R_CSMODE:\n+ if (value > 3) {\n+ qemu_log_mask(LOG_GUEST_ERROR, \"%s: invalid csmode %x\\n\",\n+ __func__, value);\n+ } else {\n+ s->regs[R_CSMODE] = value;\n+ sifive_spi_update_cs(s);\n+ }\n+ break;\n+\n+ case R_TXDATA:\n+ if (!fifo8_is_full(&s->tx_fifo)) {\n+ fifo8_push(&s->tx_fifo, (uint8_t)value);\n+ sifive_spi_flush_txfifo(s);\n+ }\n+ break;\n+\n+ case R_RXDATA:\n+ case R_IP:\n+ qemu_log_mask(LOG_GUEST_ERROR,\n+ \"%s: invalid write to read-only reigster 0x%\"\n+ HWADDR_PRIx \" with 0x%x\\n\", __func__, addr << 2, value);\n+ break;\n+\n+ case R_TXMARK:\n+ case R_RXMARK:\n+ if (value >= FIFO_CAPACITY) {\n+ qemu_log_mask(LOG_GUEST_ERROR, \"%s: invalid watermark %d\\n\",\n+ __func__, value);\n+ } else {\n+ s->regs[addr] = value;\n+ }\n+ break;\n+\n+ case R_FCTRL:\n+ case R_FFMT:\n+ qemu_log_mask(LOG_UNIMP,\n+ \"%s: direct-map flash interface unimplemented\\n\",\n+ __func__);\n+ break;\n+\n+ default:\n+ s->regs[addr] = value;\n+ break;\n+ }\n+\n+ sifive_spi_update_irq(s);\n+}\n+\n+static const MemoryRegionOps sifive_spi_ops = {\n+ .read = sifive_spi_read,\n+ .write = sifive_spi_write,\n+ .endianness = DEVICE_LITTLE_ENDIAN,\n+ .valid = {\n+ .min_access_size = 4,\n+ .max_access_size = 4\n+ }\n+};\n+\n+static void sifive_spi_realize(DeviceState *dev, Error **errp)\n+{\n+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);\n+ SiFiveSPIState *s = SIFIVE_SPI(dev);\n+ int i;\n+\n+ s->spi = ssi_create_bus(dev, \"spi\");\n+ sysbus_init_irq(sbd, &s->irq);\n+\n+ s->cs_lines = g_new0(qemu_irq, s->num_cs);\n+ for (i = 0; i < s->num_cs; i++) {\n+ sysbus_init_irq(sbd, &s->cs_lines[i]);\n+ }\n+\n+ memory_region_init_io(&s->mmio, OBJECT(s), &sifive_spi_ops, s,\n+ TYPE_SIFIVE_SPI, 0x1000);\n+ sysbus_init_mmio(sbd, &s->mmio);\n+\n+ fifo8_create(&s->tx_fifo, FIFO_CAPACITY);\n+ fifo8_create(&s->rx_fifo, FIFO_CAPACITY);\n+}\n+\n+static Property sifive_spi_properties[] = {\n+ DEFINE_PROP_UINT32(\"num-cs\", SiFiveSPIState, num_cs, 1),\n+ DEFINE_PROP_END_OF_LIST(),\n+};\n+\n+static void sifive_spi_class_init(ObjectClass *klass, void *data)\n+{\n+ DeviceClass *dc = DEVICE_CLASS(klass);\n+\n+ device_class_set_props(dc, sifive_spi_properties);\n+ dc->reset = sifive_spi_reset;\n+ dc->realize = sifive_spi_realize;\n+}\n+\n+static const TypeInfo sifive_spi_info = {\n+ .name = TYPE_SIFIVE_SPI,\n+ .parent = TYPE_SYS_BUS_DEVICE,\n+ .instance_size = sizeof(SiFiveSPIState),\n+ .class_init = sifive_spi_class_init,\n+};\n+\n+static void sifive_spi_register_types(void)\n+{\n+ type_register_static(&sifive_spi_info);\n+}\n+\n+type_init(sifive_spi_register_types)\ndiff --git a/hw/ssi/Kconfig b/hw/ssi/Kconfig\nindex 9e54a0c8dd..7d90a02181 100644\n--- a/hw/ssi/Kconfig\n+++ b/hw/ssi/Kconfig\n@@ -2,6 +2,10 @@ config PL022\n bool\n select SSI\n \n+config SIFIVE_SPI\n+ bool\n+ select SSI\n+\n config SSI\n bool\n \ndiff --git a/hw/ssi/meson.build b/hw/ssi/meson.build\nindex dee00c0da6..3d6bc82ab1 100644\n--- a/hw/ssi/meson.build\n+++ b/hw/ssi/meson.build\n@@ -2,6 +2,7 @@ softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_smc.c'))\n softmmu_ss.add(when: 'CONFIG_MSF2', if_true: files('mss-spi.c'))\n softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_fiu.c'))\n softmmu_ss.add(when: 'CONFIG_PL022', if_true: files('pl022.c'))\n+softmmu_ss.add(when: 'CONFIG_SIFIVE_SPI', if_true: files('sifive_spi.c'))\n softmmu_ss.add(when: 'CONFIG_SSI', if_true: files('ssi.c'))\n softmmu_ss.add(when: 'CONFIG_STM32F2XX_SPI', if_true: files('stm32f2xx_spi.c'))\n softmmu_ss.add(when: 'CONFIG_XILINX_SPI', if_true: files('xilinx_spi.c'))\n", "prefixes": [ "PULL", "v2", "07/19" ] }