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 04/14] pci: refactor init process to pci_dev_init()
Date: Fri, 14 Oct 2016 20:40:42 +0800 [thread overview]
Message-ID: <1476448852-30062-5-git-send-email-peterx@redhat.com> (raw)
In-Reply-To: <1476448852-30062-1-git-send-email-peterx@redhat.com>
pci_find_dev() is not sufficient for further tests for Intel IOMMU. This
patch introduced pci_dev struct, as a abstract of a specific PCI device.
All the rest of current PCI APIs are changed to leverage the pci_dev
struct.
x86/vmexit.c is the only user of the old PCI APIs. Changing it to use
the new ones.
(Indentation is fixed from using 4 spaces into tab in pci.c)
Signed-off-by: Peter Xu <peterx@redhat.com>
---
lib/pci.c | 75 +++++++++++++++++++++++++++++++++++++++++-------------------
lib/pci.h | 29 ++++++++++++++++++-----
x86/vmexit.c | 22 ++++--------------
3 files changed, 80 insertions(+), 46 deletions(-)
diff --git a/lib/pci.c b/lib/pci.c
index 0058d70..ef0b02a 100644
--- a/lib/pci.c
+++ b/lib/pci.c
@@ -7,37 +7,66 @@
#include "pci.h"
#include "asm/pci.h"
-/* Scan bus look for a specific device. Only bus 0 scanned for now. */
-pcidevaddr_t pci_find_dev(uint16_t vendor_id, uint16_t device_id)
+/*
+ * Scan bus look for a specific device. Only bus 0 scanned for now.
+ * After the scan, a pci_dev is returned with correct BAR information.
+ */
+int pci_dev_init(pci_dev *dev, uint16_t vendor_id, uint16_t device_id)
+{
+ unsigned i;
+ uint32_t id;
+
+ memset(dev, 0, sizeof(*dev));
+
+ for (i = 0; i < PCI_DEVFN_MAX; ++i) {
+ id = pci_config_read(i, 0);
+ if ((id & 0xFFFF) == vendor_id && (id >> 16) == device_id)
+ break;
+ }
+
+ if (i == PCI_DEVFN_MAX) {
+ printf("PCI: failed init dev (vendor: 0x%04x, "
+ "device: 0x%04x)\n", vendor_id, device_id);
+ return -1;
+ }
+
+ dev->pci_addr = i;
+ for (i = 0; i < PCI_BAR_NUM; i++) {
+ if (!pci_bar_is_valid(dev, i))
+ continue;
+ dev->pci_bar[i] = pci_bar_addr(dev, i);
+ printf("PCI: init dev 0x%04x BAR %d [%s] addr 0x%lx\n",
+ dev->pci_addr, i, pci_bar_is_memory(dev, i) ?
+ "MEM" : "IO", dev->pci_bar[i]);
+ }
+ dev->inited = true;
+
+ return 0;
+}
+
+static inline uint32_t pci_config_read_bar(pci_dev *dev, int n)
{
- unsigned dev;
- for (dev = 0; dev < 256; ++dev) {
- uint32_t id = pci_config_read(dev, 0);
- if ((id & 0xFFFF) == vendor_id && (id >> 16) == device_id) {
- return dev;
- }
- }
- return PCIDEVADDR_INVALID;
+ return pci_config_read(dev->pci_addr,
+ PCI_BASE_ADDRESS_0 + n * 4);
}
-unsigned long pci_bar_addr(pcidevaddr_t dev, int bar_num)
+phys_addr_t pci_bar_addr(pci_dev *dev, int bar_num)
{
- uint32_t bar = pci_config_read(dev, PCI_BASE_ADDRESS_0 + bar_num * 4);
- if (bar & PCI_BASE_ADDRESS_SPACE_IO) {
- return bar & PCI_BASE_ADDRESS_IO_MASK;
- } else {
- return bar & PCI_BASE_ADDRESS_MEM_MASK;
- }
+ uint32_t bar = pci_config_read_bar(dev, bar_num);
+ if (bar & PCI_BASE_ADDRESS_SPACE_IO) {
+ return bar & PCI_BASE_ADDRESS_IO_MASK;
+ } else {
+ return bar & PCI_BASE_ADDRESS_MEM_MASK;
+ }
}
-bool pci_bar_is_memory(pcidevaddr_t dev, int bar_num)
+bool pci_bar_is_memory(pci_dev *dev, int bar_num)
{
- uint32_t bar = pci_config_read(dev, PCI_BASE_ADDRESS_0 + bar_num * 4);
- return !(bar & PCI_BASE_ADDRESS_SPACE_IO);
+ uint32_t bar = pci_config_read_bar(dev, bar_num);
+ return !(bar & PCI_BASE_ADDRESS_SPACE_IO);
}
-bool pci_bar_is_valid(pcidevaddr_t dev, int bar_num)
+bool pci_bar_is_valid(pci_dev *dev, int bar_num)
{
- uint32_t bar = pci_config_read(dev, PCI_BASE_ADDRESS_0 + bar_num * 4);
- return bar;
+ return pci_config_read_bar(dev, bar_num);
}
diff --git a/lib/pci.h b/lib/pci.h
index 9160cfb..b8755ff 100644
--- a/lib/pci.h
+++ b/lib/pci.h
@@ -14,10 +14,21 @@ typedef uint16_t pcidevaddr_t;
enum {
PCIDEVADDR_INVALID = 0xffff,
};
-pcidevaddr_t pci_find_dev(uint16_t vendor_id, uint16_t device_id);
-unsigned long pci_bar_addr(pcidevaddr_t dev, int bar_num);
-bool pci_bar_is_memory(pcidevaddr_t dev, int bar_num);
-bool pci_bar_is_valid(pcidevaddr_t dev, int bar_num);
+
+#define PCI_BAR_NUM (6)
+#define PCI_DEVFN_MAX (256)
+
+struct pci_dev {
+ bool inited;
+ uint16_t pci_addr;
+ phys_addr_t pci_bar[PCI_BAR_NUM];
+};
+typedef struct pci_dev pci_dev;
+
+int pci_dev_init(pci_dev *dev, uint16_t vendor_id, uint16_t device_id);
+phys_addr_t pci_bar_addr(pci_dev *dev, int bar_num);
+bool pci_bar_is_memory(pci_dev *dev, int bar_num);
+bool pci_bar_is_valid(pci_dev *dev, int bar_num);
/*
* pci-testdev is a driver for the pci-testdev qemu pci device. The
@@ -27,8 +38,6 @@ bool pci_bar_is_valid(pcidevaddr_t dev, int bar_num);
#define PCI_VENDOR_ID_REDHAT 0x1b36
#define PCI_DEVICE_ID_REDHAT_TEST 0x0005
-#define PCI_TESTDEV_NUM_BARS 2
-
struct pci_test_dev_hdr {
uint8_t test;
uint8_t width;
@@ -39,4 +48,12 @@ struct pci_test_dev_hdr {
uint8_t name[];
};
+enum pci_dma_dir {
+ PCI_DMA_FROM_DEVICE = 0,
+ PCI_DMA_TO_DEVICE,
+};
+typedef enum pci_dma_dir pci_dma_dir_t;
+
+typedef uint64_t iova_t;
+
#endif /* PCI_H */
diff --git a/x86/vmexit.c b/x86/vmexit.c
index c2e1e49..908d2dc 100644
--- a/x86/vmexit.c
+++ b/x86/vmexit.c
@@ -371,8 +371,7 @@ int main(int ac, char **av)
{
struct fadt_descriptor_rev1 *fadt;
int i;
- unsigned long membar = 0;
- pcidevaddr_t pcidev;
+ pci_dev dev;
smp_init();
setup_vm();
@@ -385,21 +384,10 @@ int main(int ac, char **av)
pm_tmr_blk = fadt->pm_tmr_blk;
printf("PM timer port is %x\n", pm_tmr_blk);
- pcidev = pci_find_dev(PCI_VENDOR_ID_REDHAT, PCI_DEVICE_ID_REDHAT_TEST);
- if (pcidev != PCIDEVADDR_INVALID) {
- for (i = 0; i < PCI_TESTDEV_NUM_BARS; i++) {
- if (!pci_bar_is_valid(pcidev, i)) {
- continue;
- }
- if (pci_bar_is_memory(pcidev, i)) {
- membar = pci_bar_addr(pcidev, i);
- pci_test.memaddr = ioremap(membar, PAGE_SIZE);
- } else {
- pci_test.iobar = pci_bar_addr(pcidev, i);
- }
- }
- printf("pci-testdev at 0x%x membar %lx iobar %x\n",
- pcidev, membar, pci_test.iobar);
+ if (!pci_dev_init(&dev, PCI_VENDOR_ID_REDHAT,
+ PCI_DEVICE_ID_REDHAT_TEST)) {
+ pci_test.memaddr = ioremap(dev.pci_bar[0], PAGE_SIZE);
+ pci_test.iobar = dev.pci_bar[1];
}
for (i = 0; i < ARRAY_SIZE(tests); ++i)
--
2.7.4
next prev 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 ` Peter Xu [this message]
2016-10-20 10:02 ` [kvm-unit-tests PATCH 04/14] pci: refactor init process to pci_dev_init() 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 ` [kvm-unit-tests PATCH 11/14] pci: edu: introduce pci-edu helpers Peter Xu
2016-10-20 13:19 ` 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-5-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.