From patchwork Tue Oct 18 21:55:11 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Logan Gunthorpe X-Patchwork-Id: 9383561 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id C6303600CA for ; Wed, 19 Oct 2016 03:45:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B45462970A for ; Wed, 19 Oct 2016 03:45:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A8A392982B; Wed, 19 Oct 2016 03:45:25 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id BC08C2970A for ; Wed, 19 Oct 2016 03:45:24 +0000 (UTC) Received: from localhost ([::1]:45343 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bwhoi-00088z-2C for patchwork-qemu-devel@patchwork.kernel.org; Tue, 18 Oct 2016 23:45:24 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46691) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bwcxZ-0004Aw-9r for qemu-devel@nongnu.org; Tue, 18 Oct 2016 18:34:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bwcxV-0005rg-C3 for qemu-devel@nongnu.org; Tue, 18 Oct 2016 18:34:13 -0400 Received: from ale.deltatee.com ([207.54.116.67]:54614) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1bwcxV-0005pZ-6A; Tue, 18 Oct 2016 18:34:09 -0400 Received: from cgy1-donard.priv.deltatee.com ([172.16.1.31] helo=cgy1-donard.pmc-sierra.internal) by ale.deltatee.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.84_2) (envelope-from ) id 1bwcMa-0000Of-F2; Tue, 18 Oct 2016 15:56:01 -0600 Received: from gunthorp by cgy1-donard.pmc-sierra.internal with local (Exim 4.84) (envelope-from ) id 1bwcMZ-0005PS-7c; Tue, 18 Oct 2016 15:55:59 -0600 From: Logan Gunthorpe To: Kevin Wolf , Max Reitz , "Michael S. Tsirkin" , Marcel Apfelbaum Date: Tue, 18 Oct 2016 15:55:11 -0600 Message-Id: <1476827711-20758-1-git-send-email-logang@deltatee.com> X-Mailer: git-send-email 2.1.4 X-SA-Exim-Connect-IP: 172.16.1.31 X-SA-Exim-Rcpt-To: kwolf@redhat.com, mreitz@redhat.com, mst@redhat.com, marcel@redhat.com, qemu-devel@nongnu.org, qemu-block@nongnu.org, sbates@raithlin.com, logang@deltatee.com X-SA-Exim-Mail-From: gunthorp@cgy1-donard.priv.deltatee.com X-SA-Exim-Version: 4.2.1 (built Mon, 26 Dec 2011 16:24:06 +0000) X-SA-Exim-Scanned: Yes (on ale.deltatee.com) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 207.54.116.67 X-Mailman-Approved-At: Tue, 18 Oct 2016 23:44:54 -0400 Subject: [Qemu-devel] [PATCH] Added iopmem device emulation X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Logan Gunthorpe , qemu-devel@nongnu.org, qemu-block@nongnu.org, Stephen Bates Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP An iopmem device is one which exposes volatile or non-volatile memory mapped directly to a BAR region. One purpose is to provide buffers to do peer to peer transfers on the bus. As such this device uses QEMU's drive backing store to simulate non-volatile memory and provides through a mapped BAR window. This patch creates an emulated device which helps to test and debug the kernel driver for iopmem while hardware availability is poor. A kernel patch for a driver is being prepared simultaneously. Signed-off-by: Logan Gunthorpe Signed-off-by: Stephen Bates --- default-configs/pci.mak | 1 + hw/block/Makefile.objs | 1 + hw/block/iopmem.c | 141 +++++++++++++++++++++++++++++++++++++++++++++++ include/hw/pci/pci_ids.h | 2 + 4 files changed, 145 insertions(+) create mode 100644 hw/block/iopmem.c diff --git a/default-configs/pci.mak b/default-configs/pci.mak index fff7ce3..aef2b35 100644 --- a/default-configs/pci.mak +++ b/default-configs/pci.mak @@ -39,3 +39,4 @@ CONFIG_VGA=y CONFIG_VGA_PCI=y CONFIG_IVSHMEM=$(CONFIG_EVENTFD) CONFIG_ROCKER=y +CONFIG_IOPMEM_PCI=y diff --git a/hw/block/Makefile.objs b/hw/block/Makefile.objs index d4c3ab7..1c8044b 100644 --- a/hw/block/Makefile.objs +++ b/hw/block/Makefile.objs @@ -8,6 +8,7 @@ common-obj-$(CONFIG_XEN_BACKEND) += xen_disk.o common-obj-$(CONFIG_ECC) += ecc.o common-obj-$(CONFIG_ONENAND) += onenand.o common-obj-$(CONFIG_NVME_PCI) += nvme.o +common-obj-$(CONFIG_IOPMEM_PCI) += iopmem.o obj-$(CONFIG_SH4) += tc58128.o diff --git a/hw/block/iopmem.c b/hw/block/iopmem.c new file mode 100644 index 0000000..9c2d716 --- /dev/null +++ b/hw/block/iopmem.c @@ -0,0 +1,141 @@ +/* + * QEMU iopmem Controller + * + * Copyright (c) 2016, Microsemi Corporation + * + * Written by Logan Gunthorpe + * + * This code is licensed under the GNU GPL v2 or later. + */ + + +/** + * Usage: add options: + * -drive file=,if=none,id= + * -device iopmem,drive=,id= + */ + +#include "qemu/osdep.h" +#include "hw/pci/pci.h" +#include "sysemu/block-backend.h" + +typedef struct IoPmemCtrl { + PCIDevice parent_obj; + MemoryRegion iomem; + BlockBackend *blk; + uint64_t size; +} IoPmemCtrl; + +#define TYPE_IOPMEM "iopmem" +#define IOPMEM(obj) \ + OBJECT_CHECK(IoPmemCtrl, (obj), TYPE_IOPMEM) + +static uint64_t iopmem_bar_read(void *opaque, hwaddr addr, unsigned size) +{ + IoPmemCtrl *ipm = (IoPmemCtrl *)opaque; + uint64_t val; + + blk_pread(ipm->blk, addr, &val, size); + + return val; +} + +static void iopmem_bar_write(void *opaque, hwaddr addr, uint64_t data, + unsigned size) +{ + IoPmemCtrl *ipm = (IoPmemCtrl *)opaque; + + if (addr & 3) { + return; + } + + blk_pwrite(ipm->blk, addr, &data, size, 0); +} + +static const MemoryRegionOps iopmem_bar_ops = { + .read = iopmem_bar_read, + .write = iopmem_bar_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .impl = { + .min_access_size = 4, + .max_access_size = 8, + }, +}; + +static int iopmem_init(PCIDevice *pci_dev) +{ + IoPmemCtrl *ipm = IOPMEM(pci_dev); + + if (!ipm->blk) { + return -1; + } + + ipm->size = blk_getlength(ipm->blk); + + pci_config_set_prog_interface(pci_dev->config, 0x2); + pci_config_set_class(pci_dev->config, PCI_CLASS_STORAGE_OTHER); + pcie_endpoint_cap_init(&ipm->parent_obj, 0x80); + + memory_region_init_io(&ipm->iomem, OBJECT(ipm), &iopmem_bar_ops, ipm, + "iopmem", ipm->size); + + pci_register_bar(&ipm->parent_obj, 4, + PCI_BASE_ADDRESS_SPACE_MEMORY | + PCI_BASE_ADDRESS_MEM_PREFETCH | + PCI_BASE_ADDRESS_MEM_TYPE_64, + &ipm->iomem); + + return 0; +} + +static void iopmem_exit(PCIDevice *pci_dev) +{ + IoPmemCtrl *ipm = IOPMEM(pci_dev); + + if (ipm->blk) { + blk_flush(ipm->blk); + } +} + +static Property iopmem_props[] = { + DEFINE_PROP_DRIVE("drive", IoPmemCtrl, blk), + DEFINE_PROP_END_OF_LIST(), +}; + +static const VMStateDescription iopmem_vmstate = { + .name = "iopmem", + .unmigratable = 1, +}; + +static void iopmem_class_init(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PCIDeviceClass *pc = PCI_DEVICE_CLASS(oc); + + pc->init = iopmem_init; + pc->exit = iopmem_exit; + pc->class_id = PCI_CLASS_STORAGE_OTHER; + pc->vendor_id = PCI_VENDOR_ID_PMC_SIERRA; + pc->device_id = 0xf115; + pc->revision = 2; + pc->is_express = 1; + + set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); + dc->desc = "Non-Volatile IO Memory Storage"; + dc->props = iopmem_props; + dc->vmsd = &iopmem_vmstate; +} + +static const TypeInfo iopmem_info = { + .name = "iopmem", + .parent = TYPE_PCI_DEVICE, + .instance_size = sizeof(IoPmemCtrl), + .class_init = iopmem_class_init, +}; + +static void iopmem_register_types(void) +{ + type_register_static(&iopmem_info); +} + +type_init(iopmem_register_types) diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h index d77ca60..e7046e1 100644 --- a/include/hw/pci/pci_ids.h +++ b/include/hw/pci/pci_ids.h @@ -113,6 +113,8 @@ #define PCI_VENDOR_ID_MARVELL 0x11ab +#define PCI_VENDOR_ID_PMC_SIERRA 0x11f8 + #define PCI_VENDOR_ID_ENSONIQ 0x1274 #define PCI_DEVICE_ID_ENSONIQ_ES1370 0x5000