All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Xu <peterx@redhat.com>
To: kvm@vger.kernel.org
Cc: jan.kiszka@web.de, agordeev@redhat.com, drjones@redhat.com,
	rkrcmar@redhat.com, pbonzini@redhat.com, peterx@redhat.com
Subject: [kvm-unit-tests PATCH 11/14] pci: edu: introduce pci-edu helpers
Date: Fri, 14 Oct 2016 20:40:49 +0800	[thread overview]
Message-ID: <1476448852-30062-12-git-send-email-peterx@redhat.com> (raw)
In-Reply-To: <1476448852-30062-1-git-send-email-peterx@redhat.com>

QEMU edu device is a pci device that is originally written for
educational purpose, however it also suits for IOMMU unit test. Adding
helpers for this specific device to implement the device logic.

The device supports lots of functions, here only DMA operation is
supported.

The spec of the device can be found at:

  https://github.com/qemu/qemu/blob/master/docs/specs/edu.txt

Signed-off-by: Peter Xu <peterx@redhat.com>
---
 lib/pci-edu.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/pci-edu.h |  29 +++++++++++++
 2 files changed, 157 insertions(+)
 create mode 100644 lib/pci-edu.c
 create mode 100644 lib/pci-edu.h

diff --git a/lib/pci-edu.c b/lib/pci-edu.c
new file mode 100644
index 0000000..4d1a5ab
--- /dev/null
+++ b/lib/pci-edu.c
@@ -0,0 +1,128 @@
+/*
+ * Edu PCI device.
+ *
+ * Copyright (C) 2016 Red Hat, Inc.
+ *
+ * Authors:
+ *   Peter Xu <peterx@redhat.com>,
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2 or
+ * later.
+ */
+
+#include "pci-edu.h"
+
+#define  PCI_VENDOR_ID_QEMU              (0x1234)
+#define  PCI_DEVICE_ID_EDU               (0x11e8)
+
+/* The only bar used by EDU device */
+#define EDU_BAR_MEM                 (0)
+#define EDU_MAGIC                   (0xed)
+#define EDU_VERSION                 (0x100)
+#define EDU_DMA_BUF_SIZE            (1 << 20)
+#define EDU_INPUT_BUF_SIZE          (256)
+
+#define EDU_REG_ID                  (0x0)
+#define EDU_REG_ALIVE               (0x4)
+#define EDU_REG_FACTORIAL           (0x8)
+#define EDU_REG_STATUS              (0x20)
+#define EDU_REG_DMA_SRC             (0x80)
+#define EDU_REG_DMA_DST             (0x88)
+#define EDU_REG_DMA_COUNT           (0x90)
+#define EDU_REG_DMA_CMD             (0x98)
+
+#define EDU_CMD_DMA_START           (0x01)
+#define EDU_CMD_DMA_FROM            (0x02)
+#define EDU_CMD_DMA_TO              (0x00)
+
+#define EDU_STATUS_FACTORIAL        (0x1)
+#define EDU_STATUS_INT_ENABLE       (0x80)
+
+#define EDU_DMA_START               (0x40000)
+#define EDU_DMA_SIZE_MAX            (4096)
+
+uint64_t edu_reg_readq(pci_edu_dev_t *dev, int reg)
+{
+	return *(volatile uint64_t *)(dev->pci_dev.pci_bar[EDU_BAR_MEM] + reg);
+}
+
+uint32_t edu_reg_read(pci_edu_dev_t *dev, int reg)
+{
+	return *(volatile uint32_t *)(dev->pci_dev.pci_bar[EDU_BAR_MEM] + reg);
+}
+
+void edu_reg_writeq(pci_edu_dev_t *dev, int reg, uint64_t val)
+{
+	*(volatile uint64_t *)(dev->pci_dev.pci_bar[EDU_BAR_MEM] + reg) = val;
+}
+
+void edu_reg_write(pci_edu_dev_t *dev, int reg, uint32_t val)
+{
+	*(volatile uint32_t *)(dev->pci_dev.pci_bar[EDU_BAR_MEM] + reg) = val;
+}
+
+/* Return true if alive */
+bool edu_check_alive(pci_edu_dev_t *dev)
+{
+	static uint32_t live_count = 1;
+	uint32_t value;
+
+	edu_reg_write(dev, EDU_REG_ALIVE, live_count++);
+	value = edu_reg_read(dev, EDU_REG_ALIVE);
+	return (live_count - 1 == ~value);
+}
+
+int edu_init(pci_edu_dev_t *dev)
+{
+	int ret;
+
+	ret = pci_dev_init(&dev->pci_dev, PCI_VENDOR_ID_QEMU,
+			   PCI_DEVICE_ID_EDU);
+	if (ret)
+		return ret;
+
+	if (!edu_check_alive(dev)) {
+		printf("edu device not alive!\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+uint32_t edu_status(pci_edu_dev_t *dev)
+{
+	return edu_reg_read(dev, EDU_REG_STATUS);
+}
+
+void edu_dma(pci_edu_dev_t *dev, iova_t iova,
+	     size_t size, int dev_offset, pci_dma_dir_t dir)
+{
+	uint64_t from, to;
+	uint32_t cmd = EDU_CMD_DMA_START;
+
+	assert(size <= EDU_DMA_SIZE_MAX);
+	assert(dev_offset < EDU_DMA_SIZE_MAX &&
+	       dev_offset >= 0);
+
+	printf("edu device DMA start %s addr %p size 0x%lu off 0x%x\n",
+	       dir == PCI_DMA_FROM_DEVICE ? "FROM" : "TO",
+	       (void *)iova, size, dev_offset);
+
+	if (dir == PCI_DMA_FROM_DEVICE) {
+		from = dev_offset + EDU_DMA_START;
+		to = iova;
+		cmd |= EDU_CMD_DMA_FROM;
+	} else {
+		from = iova;
+		to = EDU_DMA_START + dev_offset;
+		cmd |= EDU_CMD_DMA_TO;
+	}
+
+	edu_reg_writeq(dev, EDU_REG_DMA_SRC, from);
+	edu_reg_writeq(dev, EDU_REG_DMA_DST, to);
+	edu_reg_writeq(dev, EDU_REG_DMA_COUNT, size);
+	edu_reg_write(dev, EDU_REG_DMA_CMD, cmd);
+
+	/* Wait until DMA finished */
+	while (edu_reg_read(dev, EDU_REG_DMA_CMD) & EDU_CMD_DMA_START);
+}
diff --git a/lib/pci-edu.h b/lib/pci-edu.h
new file mode 100644
index 0000000..6b7dbfd
--- /dev/null
+++ b/lib/pci-edu.h
@@ -0,0 +1,29 @@
+/*
+ * Edu PCI device header.
+ *
+ * Copyright (C) 2016 Red Hat, Inc.
+ *
+ * Authors:
+ *   Peter Xu <peterx@redhat.com>,
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2 or
+ * later.
+ *
+ * Edu device is a virtualized device in QEMU. Please refer to
+ * docs/specs/edu.txt in QEMU repository for EDU device manual.
+ */
+#ifndef __PCI_EDU_H__
+#define __PCI_EDU_H__
+
+#include "pci.h"
+
+struct pci_edu_dev {
+	pci_dev pci_dev;
+};
+typedef struct pci_edu_dev pci_edu_dev_t;
+
+int edu_init(pci_edu_dev_t *dev);
+void edu_dma(pci_edu_dev_t *dev, iova_t iova,
+	     size_t size, int dev_offset, pci_dma_dir_t dir);
+
+#endif
-- 
2.7.4


  parent reply	other threads:[~2016-10-14 12:41 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-10-14 12:40 [kvm-unit-tests RFC PATCH 00/14] VT-d unit test Peter Xu
2016-10-14 12:40 ` [kvm-unit-tests PATCH 01/14] x86: vm: allow multiple init for vm setup Peter Xu
2016-10-20  8:17   ` Andrew Jones
2016-10-20  8:24     ` Peter Xu
2016-10-20  8:41       ` Andrew Jones
2016-10-20  8:55         ` Peter Xu
2016-10-20  9:39           ` Andrew Jones
2016-10-20 11:01             ` Peter Xu
2016-10-14 12:40 ` [kvm-unit-tests PATCH 02/14] x86: smp: allow multiple init for smp setup Peter Xu
2016-10-19 20:23   ` Radim Krčmář
2016-10-20  1:27     ` Peter Xu
2016-10-20  8:20   ` Andrew Jones
2016-10-20  8:27     ` Peter Xu
2016-10-14 12:40 ` [kvm-unit-tests PATCH 03/14] x86: intel-iommu: add vt-d init test Peter Xu
2016-10-20  9:30   ` Andrew Jones
2016-10-21  9:52     ` Peter Xu
2016-10-21 12:18       ` Andrew Jones
2016-10-24  6:36         ` Peter Xu
2016-10-14 12:40 ` [kvm-unit-tests PATCH 04/14] pci: refactor init process to pci_dev_init() Peter Xu
2016-10-20 10:02   ` Andrew Jones
2016-10-24  7:00     ` Peter Xu
2016-10-14 12:40 ` [kvm-unit-tests PATCH 05/14] page: add page alignment checker Peter Xu
2016-10-20 12:23   ` Andrew Jones
2016-10-20 12:30     ` Andrew Jones
2016-10-24  9:58       ` Peter Xu
2016-10-14 12:40 ` [kvm-unit-tests PATCH 06/14] util: move MAX/MIN macro into util.h Peter Xu
2016-10-20 12:28   ` Andrew Jones
2016-10-24 10:02     ` Peter Xu
2016-10-14 12:40 ` [kvm-unit-tests PATCH 07/14] vm/page: provide PGDIR_OFFSET() macro Peter Xu
2016-10-20 12:40   ` Andrew Jones
2016-10-14 12:40 ` [kvm-unit-tests PATCH 08/14] x86: pci: add pci_config_{read|write}[bw]() helpers Peter Xu
2016-10-20 12:43   ` Andrew Jones
2016-10-24 10:08     ` Peter Xu
2016-10-14 12:40 ` [kvm-unit-tests PATCH 09/14] pci: provide pci_set_master() Peter Xu
2016-10-20 12:49   ` Andrew Jones
2016-10-24 10:11     ` Peter Xu
2016-10-14 12:40 ` [kvm-unit-tests PATCH 10/14] pci: add bdf helpers Peter Xu
2016-10-20 12:55   ` Andrew Jones
2016-10-24 14:44     ` Peter Xu
2016-10-14 12:40 ` Peter Xu [this message]
2016-10-20 13:19   ` [kvm-unit-tests PATCH 11/14] pci: edu: introduce pci-edu helpers Andrew Jones
2016-10-25  3:34     ` Peter Xu
2016-10-25 10:43       ` Andrew Jones
2016-10-25 11:33         ` Peter Xu
2016-10-14 12:40 ` [kvm-unit-tests PATCH 12/14] x86: intel-iommu: add dmar test Peter Xu
2016-10-19 20:33   ` Radim Krčmář
2016-10-20  5:41     ` Peter Xu
2016-10-14 12:40 ` [kvm-unit-tests PATCH 13/14] pci: add msi support for 32/64bit address Peter Xu
2016-10-20 13:30   ` Andrew Jones
2016-10-25  6:21     ` Peter Xu
2016-10-14 12:40 ` [kvm-unit-tests PATCH 14/14] x86: intel-iommu: add IR test Peter Xu
2016-10-20 13:45   ` Andrew Jones
2016-10-25  6:52     ` Peter Xu
2016-10-19 20:21 ` [kvm-unit-tests RFC PATCH 00/14] VT-d unit test Radim Krčmář
2016-10-20  6:05   ` Peter Xu
2016-10-20 11:08     ` Radim Krčmář
2016-10-20 11:23       ` Peter Xu
2016-10-20 11:28       ` Peter Xu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1476448852-30062-12-git-send-email-peterx@redhat.com \
    --to=peterx@redhat.com \
    --cc=agordeev@redhat.com \
    --cc=drjones@redhat.com \
    --cc=jan.kiszka@web.de \
    --cc=kvm@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=rkrcmar@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.