DO NOT MERGE

This patch contains test code for programming stream tables for PCIe devices
seen by DOM0. This change can be used on top of [1].

[1] [RFC v2 0/7] SMMUv3 driver and the supporting framework
---
 xen/arch/arm/physdev.c                | 41 +++++++++++++++++++++++++++++++++--
 xen/drivers/passthrough/arm/smmu-v3.c | 36 ++++++++++++++++++++++++++++++
 xen/include/asm-arm/device.h          |  5 +++--
 3 files changed, 78 insertions(+), 4 deletions(-)

diff --git a/xen/arch/arm/physdev.c b/xen/arch/arm/physdev.c
index e91355f..18a5786 100644
--- a/xen/arch/arm/physdev.c
+++ b/xen/arch/arm/physdev.c
@@ -8,13 +8,50 @@
 #include <xen/lib.h>
 #include <xen/errno.h>
 #include <xen/sched.h>
+#include <xen/guest_access.h>
 #include <asm/hypercall.h>
 
 
+extern void acpi_setup_smmu_for_test(struct domain *d, u16 seg, u8 bus, u8 
devfn);
+
 int do_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
 {
-    gdprintk(XENLOG_DEBUG, "PHYSDEVOP cmd=%d: not implemented\n", cmd);
-    return -ENOSYS;
+    int ret = 0;
+
+    switch (cmd )
+    {
+    case PHYSDEVOP_pci_device_add: {
+        struct physdev_pci_device_add add;
+        struct pci_dev_info pdev_info;
+
+        ret = -EFAULT;
+        if ( copy_from_guest(&add, arg, 1) != 0 )
+            break;
+
+        pdev_info.is_extfn = !!(add.flags & XEN_PCI_DEV_EXTFN);
+        if ( add.flags & XEN_PCI_DEV_VIRTFN )
+        {
+            pdev_info.is_virtfn = 1;
+            pdev_info.physfn.bus = add.physfn.bus;
+            pdev_info.physfn.devfn = add.physfn.devfn;
+        }
+        else
+            pdev_info.is_virtfn = 0;
+
+        gdprintk(XENLOG_DEBUG, "PHYSDEVOP cmd=%d: domain:%d seg:%d bus:%d \
+                devfn:%d\n", cmd, hardware_domain->domain_id, add.seg, \
+               add.bus, add.devfn);
+        acpi_setup_smmu_for_test(hardware_domain, add.seg, add.bus, add.devfn);
+        break;
+    }
+
+    default:
+        gdprintk(XENLOG_DEBUG, "PHYSDEVOP cmd=%d: not implemented\n", cmd);
+        ret = -ENOSYS;
+       break;
+    }
+
+    return ret;
 }
 
 /*
diff --git a/xen/drivers/passthrough/arm/smmu-v3.c 
b/xen/drivers/passthrough/arm/smmu-v3.c
index 0bbf0cd..f5b5d77 100644
--- a/xen/drivers/passthrough/arm/smmu-v3.c
+++ b/xen/drivers/passthrough/arm/smmu-v3.c
@@ -46,6 +46,7 @@
 #include <asm/io.h>
 #include <asm/platform.h>
 #include <xen/acpi.h>
+#include <acpi/acpi_iort.h>
 
 typedef paddr_t phys_addr_t;
 typedef paddr_t dma_addr_t;
@@ -3410,3 +3411,38 @@ ACPI_DEVICE_START(asmmuv3, "ARM SMMU V3", DEVICE_IOMMU)
 ACPI_DEVICE_END
 
 #endif
+
+void acpi_setup_smmu_for_test(struct domain *d, u16 seg, u8 bus, u8 devfn)
+{
+       struct pci_dev pci_device;
+       struct device *device;
+       struct arm_smmu_device *smmu;
+
+       arm_smmu_iommu_domain_init(d);
+       memset(&pci_device, 0, sizeof(struct pci_dev));
+       device = &(pci_device.dev);
+
+       pci_device.domain = d;
+       *(u16*) &pci_device.seg = seg;
+       *(u8*) &pci_device.bus = bus;
+       *(u8*) &pci_device.devfn = devfn;
+
+       pci_device.dev.type = DEV_PCI;
+       printk("%d %d %d \n",pci_device.seg,pci_device.bus,pci_device.devfn);
+
+       iort_iommu_configure(device);
+
+       if (device->iommu_fwspec) {
+               printk("num-ids: %d\n", device->iommu_fwspec->num_ids);
+               printk("fwnode: 0x%p\n", device->iommu_fwspec->iommu_fwnode);
+               smmu = arm_smmu_get_by_fwnode( 
device->iommu_fwspec->iommu_fwnode);
+               printk("smmu-device-node: 0x%p\n",smmu);
+               arm_smmu_assign_dev(d, 0, device, 0);
+       } else {
+               printk("Failed to initialize fw_spec\n");
+       }
+
+
+       printk("%s called %d\n", __func__, __LINE__);
+}
+
diff --git a/xen/include/asm-arm/device.h b/xen/include/asm-arm/device.h
index 4eef9ce..57c114b 100644
--- a/xen/include/asm-arm/device.h
+++ b/xen/include/asm-arm/device.h
@@ -8,6 +8,7 @@ enum device_type
 {
     DEV_DT,
     DEV_ACPI,
+    DEV_PCI,
 };
 
 struct dev_archdata {
@@ -32,8 +33,8 @@ typedef struct device device_t;
 #include <xen/device_tree.h>
 
 /* TODO: Correctly implement dev_is_pci when PCI is supported on ARM */
-#define dev_is_pci(dev) ((void)(dev), 0)
-#define dev_is_dt(dev)  ((dev->type == DEV_DT)
+#define dev_is_pci(dev) (dev->type == DEV_PCI)
+#define dev_is_dt(dev)  (dev->type == DEV_DT)
 
 enum device_class
 {
-- 
Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc. 
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux 
Foundation Collaborative Project.


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

Reply via email to