All of lore.kernel.org
 help / color / mirror / Atom feed
From: Rahul Singh <rahul.singh@arm.com>
To: xen-devel@lists.xenproject.org
Cc: bertrand.marquis@arm.com, rahul.singh@arm.com,
	Stefano Stabellini <sstabellini@kernel.org>,
	Julien Grall <julien@xen.org>,
	Volodymyr Babchuk <Volodymyr_Babchuk@epam.com>
Subject: [PATCH v1 06/14] xen/arm: Add support for PCI ecam operations
Date: Thu, 19 Aug 2021 13:02:46 +0100	[thread overview]
Message-ID: <1dc8286db35ced8281587135cfa582ea44b0185f.1629366665.git.rahul.singh@arm.com> (raw)
In-Reply-To: <cover.1629366665.git.rahul.singh@arm.com>
In-Reply-To: <cover.1629366665.git.rahul.singh@arm.com>

Add support for PCI ecam operations to access the PCI
configuration space.

Signed-off-by: Rahul Singh <rahul.singh@arm.com>
---
 xen/arch/arm/pci/Makefile           |  1 +
 xen/arch/arm/pci/ecam.c             | 63 +++++++++++++++++++++++++++++
 xen/arch/arm/pci/pci-access.c       | 53 ++++++++++++++++++++++++
 xen/arch/arm/pci/pci-host-common.c  | 13 +++++-
 xen/arch/arm/pci/pci-host-generic.c |  8 +++-
 xen/include/asm-arm/pci.h           | 32 +++++++++++++++
 6 files changed, 167 insertions(+), 3 deletions(-)
 create mode 100644 xen/arch/arm/pci/ecam.c

diff --git a/xen/arch/arm/pci/Makefile b/xen/arch/arm/pci/Makefile
index f3d97f859e..6f32fbbe67 100644
--- a/xen/arch/arm/pci/Makefile
+++ b/xen/arch/arm/pci/Makefile
@@ -2,3 +2,4 @@ obj-y += pci.o
 obj-y += pci-access.o
 obj-y += pci-host-generic.o
 obj-y += pci-host-common.o
+obj-y += ecam.o
diff --git a/xen/arch/arm/pci/ecam.c b/xen/arch/arm/pci/ecam.c
new file mode 100644
index 0000000000..91c691b41f
--- /dev/null
+++ b/xen/arch/arm/pci/ecam.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2021 Arm Ltd.
+ *
+ * Based on Linux drivers/pci/ecam.c
+ * Copyright 2016 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that 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 <xen/pci.h>
+#include <xen/sched.h>
+
+/*
+ * Function to implement the pci_ops ->map_bus method.
+ */
+void __iomem *pci_ecam_map_bus(struct pci_host_bridge *bridge,
+                                      uint32_t sbdf, uint32_t where)
+{
+    const struct pci_config_window *cfg = bridge->sysdata;
+    unsigned int devfn_shift = cfg->ops->bus_shift - 8;
+    void __iomem *base;
+
+    pci_sbdf_t sbdf_t = (pci_sbdf_t) sbdf ;
+    unsigned int busn = sbdf_t.bus;
+
+    if ( busn < cfg->busn_start || busn > cfg->busn_end )
+        return NULL;
+
+    busn -= cfg->busn_start;
+    base = cfg->win + (busn << cfg->ops->bus_shift);
+
+    return base + (PCI_DEVFN(sbdf_t.dev, sbdf_t.fn) << devfn_shift) + where;
+}
+
+/* ECAM ops */
+const struct pci_ecam_ops pci_generic_ecam_ops = {
+    .bus_shift  = 20,
+    .pci_ops    = {
+        .map_bus                = pci_ecam_map_bus,
+        .read                   = pci_generic_config_read,
+        .write                  = pci_generic_config_write,
+    }
+};
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/arch/arm/pci/pci-access.c b/xen/arch/arm/pci/pci-access.c
index b938047c03..f39f6a3a38 100644
--- a/xen/arch/arm/pci/pci-access.c
+++ b/xen/arch/arm/pci/pci-access.c
@@ -15,6 +15,59 @@
  */
 
 #include <xen/pci.h>
+#include <asm/io.h>
+
+int pci_generic_config_read(struct pci_host_bridge *bridge, uint32_t sbdf,
+                            uint32_t reg, uint32_t len, uint32_t *value)
+{
+    void __iomem *addr = bridge->ops->map_bus(bridge, sbdf, reg);
+    if (!addr) {
+        *value = ~0;
+        return -ENODEV;
+    }
+
+    switch (len)
+    {
+    case 1:
+        *value = readb(addr);
+        break;
+    case 2:
+        *value = readw(addr);
+        break;
+    case 4:
+        *value = readl(addr);
+        break;
+    default:
+        BUG();
+    }
+
+    return 0;
+}
+
+int pci_generic_config_write(struct pci_host_bridge *bridge, uint32_t sbdf,
+                            uint32_t reg, uint32_t len, uint32_t value)
+{
+    void __iomem *addr = bridge->ops->map_bus(bridge, sbdf, reg);
+    if (!addr)
+        return -ENODEV;
+
+    switch (len)
+    {
+    case 1:
+        writeb(value, addr);
+        break;
+    case 2:
+        writew(value, addr);
+        break;
+    case 4:
+        writel(value, addr);
+        break;
+    default:
+        BUG();
+    }
+
+    return 0;
+}
 
 static uint32_t pci_config_read(pci_sbdf_t sbdf, unsigned int reg,
                                 unsigned int len)
diff --git a/xen/arch/arm/pci/pci-host-common.c b/xen/arch/arm/pci/pci-host-common.c
index 9dd9b02271..c582527e92 100644
--- a/xen/arch/arm/pci/pci-host-common.c
+++ b/xen/arch/arm/pci/pci-host-common.c
@@ -68,6 +68,7 @@ static void pci_ecam_free(struct pci_config_window *cfg)
 }
 
 static struct pci_config_window *gen_pci_init(struct dt_device_node *dev,
+                                              const struct pci_ecam_ops *ops,
                                               int ecam_reg_idx)
 {
     int err;
@@ -96,6 +97,7 @@ static struct pci_config_window *gen_pci_init(struct dt_device_node *dev,
 
     cfg->phys_addr = addr;
     cfg->size = size;
+    cfg->ops = ops;
 
     /*
      * On 64-bit systems, we do a single ioremap for the whole config space
@@ -111,6 +113,13 @@ static struct pci_config_window *gen_pci_init(struct dt_device_node *dev,
     printk("ECAM at [mem %lx-%lx] for [bus %x-%x] \n",cfg->phys_addr,
             cfg->phys_addr + cfg->size - 1, cfg->busn_start, cfg->busn_end);
 
+    if ( ops->init )
+    {
+        err = ops->init(cfg);
+        if (err)
+            goto err_exit;
+    }
+
     return cfg;
 
 err_exit_remap:
@@ -216,6 +225,7 @@ static int pci_bus_find_domain_nr(struct dt_device_node *dev)
 }
 
 int pci_host_common_probe(struct dt_device_node *dev,
+                          const struct pci_ecam_ops *ops,
                           int ecam_reg_idx)
 {
     struct pci_host_bridge *bridge;
@@ -227,7 +237,7 @@ int pci_host_common_probe(struct dt_device_node *dev,
         return -ENOMEM;
 
     /* Parse and map our Configuration Space windows */
-    cfg = gen_pci_init(dev, ecam_reg_idx);
+    cfg = gen_pci_init(dev, ops, ecam_reg_idx);
     if ( !cfg )
     {
         err = -ENOMEM;
@@ -236,6 +246,7 @@ int pci_host_common_probe(struct dt_device_node *dev,
 
     bridge->dt_node = dev;
     bridge->sysdata = cfg;
+    bridge->ops = &ops->pci_ops;
     bridge->bus_start = cfg->busn_start;
     bridge->bus_end = cfg->busn_end;
 
diff --git a/xen/arch/arm/pci/pci-host-generic.c b/xen/arch/arm/pci/pci-host-generic.c
index 13d0f7f999..2d652e8910 100644
--- a/xen/arch/arm/pci/pci-host-generic.c
+++ b/xen/arch/arm/pci/pci-host-generic.c
@@ -23,20 +23,24 @@
 #include <asm/pci.h>
 
 static const struct dt_device_match gen_pci_dt_match[] = {
-    { .compatible = "pci-host-ecam-generic" },
+    { .compatible = "pci-host-ecam-generic",
+      .data =       &pci_generic_ecam_ops },
+
     { },
 };
 
 static int gen_pci_dt_init(struct dt_device_node *dev, const void *data)
 {
     const struct dt_device_match *of_id;
+    const struct pci_ecam_ops *ops;
 
     of_id = dt_match_node(gen_pci_dt_match, dev->dev.of_node);
+    ops = (struct pci_ecam_ops *) of_id->data;
 
     printk(XENLOG_INFO "Found PCI host bridge %s compatible:%s \n",
            dt_node_full_name(dev), of_id->compatible);
 
-    return pci_host_common_probe(dev, 0);
+    return pci_host_common_probe(dev, ops, 0);
 }
 
 DT_DEVICE_START(pci_gen, "PCI HOST GENERIC", DEVICE_PCI)
diff --git a/xen/include/asm-arm/pci.h b/xen/include/asm-arm/pci.h
index 58a51e724e..22866244d2 100644
--- a/xen/include/asm-arm/pci.h
+++ b/xen/include/asm-arm/pci.h
@@ -37,6 +37,7 @@ struct pci_config_window {
     uint8_t         busn_start;
     uint8_t         busn_end;
     void __iomem    *win;
+    const struct    pci_ecam_ops *ops;
 };
 
 /*
@@ -50,10 +51,41 @@ struct pci_host_bridge {
     u8 bus_start;                    /* Bus start of this bridge. */
     u8 bus_end;                      /* Bus end of this bridge. */
     void *sysdata;                   /* Pointer to the config space window*/
+    const struct pci_ops *ops;
 };
 
+struct pci_ops {
+    void __iomem *(*map_bus)(struct pci_host_bridge *bridge, uint32_t sbdf,
+                             uint32_t offset);
+    int (*read)(struct pci_host_bridge *bridge, uint32_t sbdf,
+                uint32_t reg, uint32_t len, uint32_t *value);
+    int (*write)(struct pci_host_bridge *bridge, uint32_t sbdf,
+                 uint32_t reg, uint32_t len, uint32_t value);
+};
+
+/*
+ * struct to hold pci ops and bus shift of the config window
+ * for a PCI controller.
+ */
+struct pci_ecam_ops {
+    unsigned int            bus_shift;
+    struct pci_ops          pci_ops;
+    int (*init)(struct pci_config_window *);
+};
+
+/* Default ECAM ops */
+extern const struct pci_ecam_ops pci_generic_ecam_ops;
+
 int pci_host_common_probe(struct dt_device_node *dev,
+                          const struct pci_ecam_ops *ops,
                           int ecam_reg_idx);
+int pci_generic_config_read(struct pci_host_bridge *bridge, uint32_t sbdf,
+                            uint32_t reg, uint32_t len, uint32_t *value);
+int pci_generic_config_write(struct pci_host_bridge *bridge, uint32_t sbdf,
+                            uint32_t reg, uint32_t len, uint32_t value);
+void __iomem *pci_ecam_map_bus(struct pci_host_bridge *bridge,
+                               uint32_t sbdf, uint32_t where);
+
 #else   /*!CONFIG_HAS_PCI*/
 
 struct arch_pci_dev { };
-- 
2.17.1



  parent reply	other threads:[~2021-08-19 12:07 UTC|newest]

Thread overview: 98+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-19 12:02 [PATCH v1 00/14] PCI devices passthrough on Arm Rahul Singh
2021-08-19 12:02 ` [PATCH v1 01/14] xen/pci: Refactor MSI code that implements MSI functionality within XEN Rahul Singh
2021-08-19 12:18   ` Julien Grall
2021-08-19 14:16     ` Rahul Singh
2021-09-07 10:01       ` Julien Grall
2021-08-24 15:53   ` Jan Beulich
2021-08-31 12:31     ` Rahul Singh
2021-08-31 13:00       ` Jan Beulich
2021-08-26 13:23   ` Daniel P. Smith
2021-08-19 12:02 ` [PATCH v1 02/14] xen/pci: solve compilation error on ARM with HAS_PCI enabled Rahul Singh
2021-08-19 12:28   ` Julien Grall
2021-08-20 10:30     ` Rahul Singh
2021-08-20 11:37       ` Julien Grall
2021-08-20 11:55         ` Jan Beulich
2021-08-20 12:10           ` Julien Grall
2021-08-20  7:01   ` Jan Beulich
2021-08-20 11:21     ` Rahul Singh
2021-09-09 13:16   ` Julien Grall
2021-08-19 12:02 ` [PATCH v1 03/14] xen/pci: solve compilation error on ARM with ACPI && HAS_PCI Rahul Singh
2021-08-20  7:06   ` Jan Beulich
2021-08-20 11:41     ` Rahul Singh
2021-08-20 11:54       ` Jan Beulich
2021-09-09  1:11         ` Stefano Stabellini
2021-09-10 10:22           ` Rahul Singh
2021-08-19 12:02 ` [PATCH v1 04/14] xen/arm: Add support for PCI init to initialize the PCI driver Rahul Singh
2021-09-07  8:20   ` Julien Grall
2021-09-10 10:47     ` Rahul Singh
2021-09-09  1:16   ` Stefano Stabellini
2021-09-10 10:32     ` Rahul Singh
2021-08-19 12:02 ` [PATCH v1 05/14] xen/arm: PCI host bridge discovery within XEN on ARM Rahul Singh
2021-09-07  9:05   ` Julien Grall
2021-09-10 11:22     ` Rahul Singh
2021-09-10 11:53       ` Julien Grall
2021-09-09 22:54   ` Stefano Stabellini
2021-09-10 11:53     ` Rahul Singh
2021-09-13 14:52   ` Oleksandr Andrushchenko
2021-09-13 20:23     ` Stefano Stabellini
2021-09-14  4:35       ` Oleksandr Andrushchenko
2021-09-14  7:53   ` Oleksandr Andrushchenko
2021-08-19 12:02 ` Rahul Singh [this message]
2021-09-09 11:32   ` [PATCH v1 06/14] xen/arm: Add support for PCI ecam operations Julien Grall
2021-09-14  8:13     ` Rahul Singh
2021-09-09 23:21   ` Stefano Stabellini
2021-09-14 11:13     ` Rahul Singh
2021-09-14 23:06       ` Stefano Stabellini
2021-09-15 16:38         ` Rahul Singh
2021-09-15 20:45           ` Stefano Stabellini
2021-09-16 16:51             ` Rahul Singh
2021-08-19 12:02 ` [PATCH v1 07/14] xen/arm: Add support for Xilinx ZynqMP PCI host controller Rahul Singh
2021-09-09 23:34   ` Stefano Stabellini
2021-09-10 12:01     ` Rahul Singh
2021-09-13 14:46       ` Oleksandr Andrushchenko
2021-09-13 21:02         ` Stefano Stabellini
2021-09-14  4:31           ` Oleksandr Andrushchenko
2021-09-17  7:39             ` Rahul Singh
2021-08-19 12:02 ` [PATCH v1 08/14] xen:arm: Implement pci access functions Rahul Singh
2021-09-09 23:41   ` Stefano Stabellini
2021-09-14 16:05     ` Rahul Singh
2021-09-14 22:40       ` Stefano Stabellini
2021-09-15  7:54       ` Oleksandr Andrushchenko
2021-09-15 10:47         ` Rahul Singh
2021-08-19 12:02 ` [PATCH v1 09/14] xen/arm: Add cmdline boot option "pci=on" Rahul Singh
2021-08-19 12:09   ` Jan Beulich
2021-08-19 12:31   ` Julien Grall
2021-08-20 12:19     ` Rahul Singh
2021-08-20 14:34       ` Julien Grall
2021-08-20 14:37         ` Jan Beulich
2021-09-09 23:46           ` Stefano Stabellini
2021-09-09 23:48   ` Stefano Stabellini
2021-08-19 12:02 ` [PATCH v1 10/14] xen/arm: Discovering PCI devices and add the PCI devices in XEN Rahul Singh
2021-08-19 12:35   ` Julien Grall
2021-08-19 13:40     ` Jan Beulich
2021-08-20 13:05     ` Rahul Singh
2021-08-19 12:02 ` [PATCH v1 11/14] xen/arm: Enable the existing x86 virtual PCI support for ARM Rahul Singh
2021-08-24 16:09   ` Jan Beulich
2021-08-25  5:44     ` Oleksandr Andrushchenko
2021-08-25  6:35       ` Jan Beulich
2021-09-09 13:50   ` Julien Grall
2021-09-16 10:46     ` Rahul Singh
2021-09-10  0:26   ` Stefano Stabellini
2021-09-16 11:01     ` Rahul Singh
2021-09-16 20:26       ` Stefano Stabellini
2021-09-21 13:49         ` Rahul Singh
2021-09-21 21:38           ` Stefano Stabellini
2021-08-19 12:02 ` [PATCH v1 12/14] arm/libxl: Emulated PCI device tree node in libxl Rahul Singh
2021-08-19 13:00   ` Julien Grall
2021-08-20 16:03     ` Rahul Singh
2021-09-09 13:59       ` Julien Grall
2021-09-16 16:16         ` Rahul Singh
2021-09-10  0:51   ` Stefano Stabellini
2021-09-16 16:35     ` Rahul Singh
2021-08-19 12:02 ` [PATCH v1 13/14] xen/arm: Fixed error when PCI device is assigned to guest Rahul Singh
2021-08-19 12:12   ` Jan Beulich
2021-08-19 12:40     ` Julien Grall
2021-08-20 17:01     ` Rahul Singh
2021-08-19 12:02 ` [PATCH v1 14/14] xen/arm: Add linux,pci-domain property for hwdom if not available Rahul Singh
2021-09-10  1:00   ` Stefano Stabellini
2021-09-16 16:36     ` Rahul Singh

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=1dc8286db35ced8281587135cfa582ea44b0185f.1629366665.git.rahul.singh@arm.com \
    --to=rahul.singh@arm.com \
    --cc=Volodymyr_Babchuk@epam.com \
    --cc=bertrand.marquis@arm.com \
    --cc=julien@xen.org \
    --cc=sstabellini@kernel.org \
    --cc=xen-devel@lists.xenproject.org \
    /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.